aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--dist/changes-5.10.0188
-rw-r--r--dist/changes-5.10.1109
-rw-r--r--examples/quick/customitems/painteditem/textballoon.cpp15
-rw-r--r--examples/quick/demos/stocqt/content/StockChart.qml67
-rw-r--r--examples/quick/demos/stocqt/content/StockListModel.qml117
-rw-r--r--examples/quick/demos/stocqt/content/StockModel.qml58
-rw-r--r--examples/quick/demos/stocqt/content/StockSettingsPanel.qml12
-rw-r--r--examples/quick/demos/stocqt/content/data/AAPL.csv147
-rw-r--r--examples/quick/demos/stocqt/content/data/ADSK.csv148
-rw-r--r--examples/quick/demos/stocqt/content/data/AMD.csv148
-rw-r--r--examples/quick/demos/stocqt/content/data/AMZN.csv147
-rw-r--r--examples/quick/demos/stocqt/content/data/CSCO.csv148
-rw-r--r--examples/quick/demos/stocqt/content/data/EA.csv148
-rw-r--r--examples/quick/demos/stocqt/content/data/EBAY.csv148
-rw-r--r--examples/quick/demos/stocqt/content/data/FB.csv148
-rw-r--r--examples/quick/demos/stocqt/content/data/GOOG.csv148
-rw-r--r--examples/quick/demos/stocqt/content/data/GOOGL.csv148
-rw-r--r--examples/quick/demos/stocqt/content/data/INTC.csv147
-rw-r--r--examples/quick/demos/stocqt/content/data/MSFT.csv148
-rw-r--r--examples/quick/demos/stocqt/content/data/NCLH.csv148
-rw-r--r--examples/quick/demos/stocqt/content/data/NFLX.csv148
-rw-r--r--examples/quick/demos/stocqt/content/data/NTAP.csv148
-rw-r--r--examples/quick/demos/stocqt/content/data/NVDA.csv148
-rw-r--r--examples/quick/demos/stocqt/content/data/PYPL.csv148
-rw-r--r--examples/quick/demos/stocqt/content/data/QCOM.csv147
-rw-r--r--examples/quick/demos/stocqt/content/data/TSLA.csv148
-rw-r--r--examples/quick/demos/stocqt/content/data/TXN.csv148
-rw-r--r--examples/quick/demos/stocqt/doc/images/qtquick-demo-stocqt.pngbin48945 -> 27425 bytes
-rw-r--r--examples/quick/demos/stocqt/doc/src/stocqt.qdoc13
-rw-r--r--examples/quick/demos/stocqt/stocqt.qrc20
-rw-r--r--examples/quick/imageelements/animatedimage.qml116
-rw-r--r--examples/quick/imageelements/content/Uniflow_steam_engine.gifbin0 -> 45328 bytes
-rw-r--r--examples/quick/imageelements/imageelements.qml1
-rw-r--r--examples/quick/imageelements/imageelements.qrc2
-rw-r--r--examples/quick/quick.pro1
-rw-r--r--examples/quick/quickwidgets/qquickviewcomparison/fbitem.h8
-rw-r--r--examples/quick/quickwidgets/qquickviewcomparison/main.cpp20
-rw-r--r--examples/quick/quickwidgets/qquickviewcomparison/mainwindow.cpp8
-rw-r--r--examples/quick/quickwidgets/qquickviewcomparison/mainwindow.h3
-rw-r--r--examples/quick/quickwidgets/quickwidget/main.cpp24
-rw-r--r--examples/quick/rendercontrol/main.cpp16
-rw-r--r--examples/quick/rendercontrol/window_multithreaded.cpp4
-rw-r--r--examples/quick/rendercontrol/window_multithreaded.h12
-rw-r--r--examples/quick/rendercontrol/window_singlethreaded.cpp48
-rw-r--r--examples/quick/rendercontrol/window_singlethreaded.h10
-rw-r--r--examples/quick/scenegraph/customgeometry/beziercurve.cpp6
-rw-r--r--examples/quick/scenegraph/graph/noisynode.cpp3
-rw-r--r--examples/quick/scenegraph/graph/shaders/line.fsh2
-rw-r--r--examples/quick/scenegraph/graph/shaders/noisy.fsh2
-rw-r--r--examples/quick/scenegraph/rendernode/main.cpp16
-rw-r--r--examples/quick/scenegraph/rendernode/softwarerenderer.cpp7
-rw-r--r--examples/quick/scenegraph/sgengine/window.cpp11
-rw-r--r--examples/quick/scenegraph/shared/logorenderer.cpp4
-rw-r--r--examples/quick/scenegraph/textureinsgnode/main.qml2
-rw-r--r--examples/quick/scenegraph/textureinthread/main.qml2
-rw-r--r--examples/quick/scenegraph/twotextureproviders/main.qml2
-rw-r--r--examples/quick/shapes/content/clippedtigers.qml137
-rw-r--r--examples/quick/shapes/content/interactive.qml285
-rw-r--r--examples/quick/shapes/content/item10.qml174
-rw-r--r--examples/quick/shapes/content/item11.qml115
-rw-r--r--examples/quick/shapes/content/item12.qml113
-rw-r--r--examples/quick/shapes/content/item13.qml97
-rw-r--r--examples/quick/shapes/content/item14.qml91
-rw-r--r--examples/quick/shapes/content/item15.qml113
-rw-r--r--examples/quick/shapes/content/item17.qml77
-rw-r--r--examples/quick/shapes/content/item2.qml153
-rw-r--r--examples/quick/shapes/content/item3.qml98
-rw-r--r--examples/quick/shapes/content/item4.qml86
-rw-r--r--examples/quick/shapes/content/item5.qml89
-rw-r--r--examples/quick/shapes/content/item6.qml89
-rw-r--r--examples/quick/shapes/content/item7.qml95
-rw-r--r--examples/quick/shapes/content/item8.qml93
-rw-r--r--examples/quick/shapes/content/item9.qml100
-rw-r--r--examples/quick/shapes/content/main.qml65
-rw-r--r--examples/quick/shapes/content/sampling.qml186
-rw-r--r--examples/quick/shapes/content/shapegallery.qml196
-rw-r--r--examples/quick/shapes/content/tapableTriangle.qml102
-rw-r--r--examples/quick/shapes/content/tiger.qml3715
-rw-r--r--examples/quick/shapes/doc/images/qml-shapes-example.pngbin0 -> 49261 bytes
-rw-r--r--examples/quick/shapes/doc/src/shapes.qdoc39
-rw-r--r--examples/quick/shapes/main.cpp51
-rw-r--r--examples/quick/shapes/shapes.pro30
-rw-r--r--examples/quick/shapes/shapes.qrc32
-rw-r--r--examples/quick/shared/LauncherList.qml11
-rw-r--r--examples/quick/shared/shared.h5
-rw-r--r--examples/quick/textureprovider/main.cpp4
-rw-r--r--examples/quick/window/CurrentScreen.qml11
-rw-r--r--src/3rdparty/masm/assembler/MacroAssembler.h2
-rw-r--r--src/3rdparty/masm/assembler/MacroAssemblerARM64.h9
-rw-r--r--src/3rdparty/masm/assembler/MacroAssemblerARMv7.h11
-rw-r--r--src/3rdparty/masm/assembler/MacroAssemblerX86_64.h64
-rw-r--r--src/3rdparty/masm/assembler/X86Assembler.h42
-rw-r--r--src/3rdparty/masm/masm-defs.pri1
-rw-r--r--src/3rdparty/masm/stubs/WTFStubs.cpp5
-rw-r--r--src/3rdparty/masm/yarr/YarrPattern.cpp2
-rw-r--r--src/imports/builtins/builtins.qmltypes5
-rw-r--r--src/imports/folderlistmodel/fileinfothread.cpp5
-rw-r--r--src/imports/folderlistmodel/fileinfothread_p.h2
-rw-r--r--src/imports/folderlistmodel/plugin.cpp8
-rw-r--r--src/imports/folderlistmodel/plugins.qmltypes15
-rw-r--r--src/imports/folderlistmodel/qquickfolderlistmodel.cpp69
-rw-r--r--src/imports/folderlistmodel/qquickfolderlistmodel.h7
-rw-r--r--src/imports/handlers/handlers.pro11
-rw-r--r--src/imports/handlers/plugin.cpp88
-rw-r--r--src/imports/handlers/plugins.qmltypes308
-rw-r--r--src/imports/handlers/qmldir5
-rw-r--r--src/imports/imports.pro3
-rw-r--r--src/imports/layouts/plugin.cpp2
-rw-r--r--src/imports/layouts/qquicklayout.cpp61
-rw-r--r--src/imports/layouts/qquicklayout_p.h22
-rw-r--r--src/imports/layouts/qquicklayoutstyleinfo_p.h6
-rw-r--r--src/imports/layouts/qquicklinearlayout.cpp2
-rw-r--r--src/imports/layouts/qquicklinearlayout_p.h22
-rw-r--r--src/imports/layouts/qquickstacklayout.cpp7
-rw-r--r--src/imports/layouts/qquickstacklayout_p.h16
-rw-r--r--src/imports/localstorage/plugin.cpp97
-rw-r--r--src/imports/models/plugin.cpp2
-rw-r--r--src/imports/particles/plugin.cpp2
-rw-r--r--src/imports/qtquick2/plugin.cpp2
-rw-r--r--src/imports/qtquick2/plugins.qmltypes58
-rw-r--r--src/imports/settings/plugin.cpp2
-rw-r--r--src/imports/settings/qqmlsettings.cpp19
-rw-r--r--src/imports/shapes/plugin.cpp82
-rw-r--r--src/imports/shapes/plugins.qmltypes150
-rw-r--r--src/imports/shapes/qmldir4
-rw-r--r--src/imports/shapes/qquicknvprfunctions.cpp281
-rw-r--r--src/imports/shapes/qquicknvprfunctions_p.h400
-rw-r--r--src/imports/shapes/qquicknvprfunctions_p_p.h70
-rw-r--r--src/imports/shapes/qquickshape.cpp1607
-rw-r--r--src/imports/shapes/qquickshape_p.h376
-rw-r--r--src/imports/shapes/qquickshape_p_p.h231
-rw-r--r--src/imports/shapes/qquickshapegenericrenderer.cpp1006
-rw-r--r--src/imports/shapes/qquickshapegenericrenderer_p.h392
-rw-r--r--src/imports/shapes/qquickshapenvprrenderer.cpp1001
-rw-r--r--src/imports/shapes/qquickshapenvprrenderer_p.h237
-rw-r--r--src/imports/shapes/qquickshapesoftwarerenderer.cpp282
-rw-r--r--src/imports/shapes/qquickshapesoftwarerenderer_p.h135
-rw-r--r--src/imports/shapes/qtquickshapesplugin.qrc20
-rw-r--r--src/imports/shapes/shaders/blit.frag9
-rw-r--r--src/imports/shapes/shaders/blit.vert12
-rw-r--r--src/imports/shapes/shaders/blit_core.frag13
-rw-r--r--src/imports/shapes/shaders/blit_core.vert14
-rw-r--r--src/imports/shapes/shaders/conicalgradient.frag19
-rw-r--r--src/imports/shapes/shaders/conicalgradient.vert13
-rw-r--r--src/imports/shapes/shaders/conicalgradient_core.frag22
-rw-r--r--src/imports/shapes/shaders/conicalgradient_core.vert15
-rw-r--r--src/imports/shapes/shaders/lineargradient.frag9
-rw-r--r--src/imports/shapes/shaders/lineargradient.vert15
-rw-r--r--src/imports/shapes/shaders/lineargradient_core.frag12
-rw-r--r--src/imports/shapes/shaders/lineargradient_core.vert17
-rw-r--r--src/imports/shapes/shaders/radialgradient.frag25
-rw-r--r--src/imports/shapes/shaders/radialgradient.vert13
-rw-r--r--src/imports/shapes/shaders/radialgradient_core.frag29
-rw-r--r--src/imports/shapes/shaders/radialgradient_core.vert15
-rw-r--r--src/imports/shapes/shapes.pro33
-rw-r--r--src/imports/sharedimage/plugins.qmltypes11
-rw-r--r--src/imports/sharedimage/qsharedimageloader.cpp9
-rw-r--r--src/imports/sharedimage/qsharedimageloader_p.h4
-rw-r--r--src/imports/sharedimage/sharedimageprovider.cpp2
-rw-r--r--src/imports/statemachine/plugin.cpp2
-rw-r--r--src/imports/statemachine/signaltransition.cpp6
-rw-r--r--src/imports/statemachine/signaltransition.h14
-rw-r--r--src/imports/statemachine/timeouttransition.h2
-rw-r--r--src/imports/testlib/SignalSpy.qml2
-rw-r--r--src/imports/testlib/TestCase.qml138
-rw-r--r--src/imports/testlib/main.cpp9
-rw-r--r--src/imports/testlib/plugins.qmltypes12
-rw-r--r--src/imports/window/plugin.cpp2
-rw-r--r--src/imports/window/plugins.qmltypes33
-rw-r--r--src/imports/xmllistmodel/plugin.cpp2
-rw-r--r--src/imports/xmllistmodel/qqmlxmllistmodel.cpp9
-rw-r--r--src/particles/qquickangledirection.cpp6
-rw-r--r--src/particles/qquickcustomaffector.cpp2
-rw-r--r--src/particles/qquickcustomparticle.cpp4
-rw-r--r--src/particles/qquickellipseextruder.cpp6
-rw-r--r--src/particles/qquickimageparticle.cpp71
-rw-r--r--src/particles/qquicklineextruder.cpp6
-rw-r--r--src/particles/qquickmaskextruder.cpp3
-rw-r--r--src/particles/qquickparticleemitter.cpp7
-rw-r--r--src/particles/qquickparticleextruder.cpp6
-rw-r--r--src/particles/qquickparticlesystem.cpp2
-rw-r--r--src/particles/qquickpointdirection.cpp6
-rw-r--r--src/particles/qquickrectangleextruder.cpp16
-rw-r--r--src/particles/qquicktargetdirection.cpp7
-rw-r--r--src/particles/qquicktrailemitter.cpp7
-rw-r--r--src/particles/qquickv4particledata.cpp96
-rw-r--r--src/particles/qquickv4particledata_p.h2
-rw-r--r--src/particles/qquickwander.cpp13
-rw-r--r--src/plugins/plugins.pro3
-rw-r--r--src/plugins/qmltooling/packetprotocol/packetprotocol.pro3
-rw-r--r--src/plugins/qmltooling/packetprotocol/qqmldebugpacket_p.h (renamed from src/plugins/qmltooling/shared/qqmldebugpacket.h)3
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qmldbg_debugger.pro5
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp4
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.h10
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp83
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h5
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp31
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugger.h12
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp17
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp57
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp8
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h14
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp2
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro3
-rw-r--r--src/plugins/qmltooling/qmldbg_inspector/qqmlinspectorservice.cpp8
-rw-r--r--src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp16
-rw-r--r--src/plugins/qmltooling/qmldbg_local/qlocalclientconnectionfactory.h2
-rw-r--r--src/plugins/qmltooling/qmldbg_local/qmldbg_local.pro7
-rw-r--r--src/plugins/qmltooling/qmldbg_messages/qdebugmessageservice.cpp3
-rw-r--r--src/plugins/qmltooling/qmldbg_messages/qmldbg_messages.pro4
-rw-r--r--src/plugins/qmltooling/qmldbg_native/qmldbg_native.pro4
-rw-r--r--src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp2
-rw-r--r--src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.h18
-rw-r--r--src/plugins/qmltooling/qmldbg_nativedebugger/qmldbg_nativedebugger.pro4
-rw-r--r--src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp168
-rw-r--r--src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.h10
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qmldbg_profiler.pro5
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp11
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.h12
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp2
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.h2
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp17
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h26
-rw-r--r--src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h2
-rw-r--r--src/plugins/qmltooling/qmldbg_quickprofiler/qmldbg_quickprofiler.pro3
-rw-r--r--src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.cpp3
-rw-r--r--src/plugins/qmltooling/qmldbg_server/qmldbg_server.pro8
-rw-r--r--src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp27
-rw-r--r--src/plugins/qmltooling/qmldbg_tcp/qmldbg_tcp.pro7
-rw-r--r--src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp17
-rw-r--r--src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnectionfactory.h2
-rw-r--r--src/plugins/qmltooling/qmltooling.pro27
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials.cpp4
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp2
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12engine_p_p.h1
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12layer_p.h1
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12renderer.cpp12
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12renderloop.cpp3
-rw-r--r--src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp2
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvglayer.h1
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgrenderloop.cpp1
-rw-r--r--src/qml/compiler/compiler.pri27
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp481
-rw-r--r--src/qml/compiler/qqmlirbuilder_p.h48
-rw-r--r--src/qml/compiler/qqmlpropertycachecreator.cpp2
-rw-r--r--src/qml/compiler/qqmlpropertycachecreator_p.h38
-rw-r--r--src/qml/compiler/qqmlpropertyvalidator.cpp5
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp81
-rw-r--r--src/qml/compiler/qqmltypecompiler_p.h4
-rw-r--r--src/qml/compiler/qv4bytecodegenerator.cpp225
-rw-r--r--src/qml/compiler/qv4bytecodegenerator_p.h282
-rw-r--r--src/qml/compiler/qv4codegen.cpp3941
-rw-r--r--src/qml/compiler/qv4codegen_p.h761
-rw-r--r--src/qml/compiler/qv4compileddata.cpp129
-rw-r--r--src/qml/compiler/qv4compileddata_p.h460
-rw-r--r--src/qml/compiler/qv4compiler.cpp187
-rw-r--r--src/qml/compiler/qv4compiler_p.h37
-rw-r--r--src/qml/compiler/qv4compilercontext.cpp82
-rw-r--r--src/qml/compiler/qv4compilercontext_p.h290
-rw-r--r--src/qml/compiler/qv4compilercontrolflow_p.h467
-rw-r--r--src/qml/compiler/qv4compilerscanfunctions.cpp479
-rw-r--r--src/qml/compiler/qv4compilerscanfunctions_p.h160
-rw-r--r--src/qml/compiler/qv4instr_moth.cpp590
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h1240
-rw-r--r--src/qml/compiler/qv4isel_moth.cpp1522
-rw-r--r--src/qml/compiler/qv4isel_moth_p.h240
-rw-r--r--src/qml/compiler/qv4isel_p.cpp446
-rw-r--r--src/qml/compiler/qv4isel_p.h218
-rw-r--r--src/qml/compiler/qv4isel_util_p.h241
-rw-r--r--src/qml/compiler/qv4jsir.cpp1001
-rw-r--r--src/qml/compiler/qv4jsir_p.h1790
-rw-r--r--src/qml/compiler/qv4ssa.cpp5848
-rw-r--r--src/qml/compiler/qv4ssa_p.h472
-rw-r--r--src/qml/configure.json21
-rw-r--r--src/qml/debugger/debugger.pri16
-rw-r--r--src/qml/debugger/qqmlabstractprofileradapter_p.h4
-rw-r--r--src/qml/debugger/qqmlconfigurabledebugservice_p.h (renamed from src/plugins/qmltooling/shared/qqmlconfigurabledebugservice.h)15
-rw-r--r--src/qml/debugger/qqmldebug.cpp2
-rw-r--r--src/qml/debugger/qqmldebug.h2
-rw-r--r--src/qml/debugger/qqmldebugconnector_p.h4
-rw-r--r--src/qml/debugger/qqmldebugpluginmanager_p.h6
-rw-r--r--src/qml/debugger/qqmldebugserver_p.h (renamed from src/plugins/qmltooling/shared/qqmldebugserver.h)12
-rw-r--r--src/qml/debugger/qqmldebugserverconnection_p.h (renamed from src/plugins/qmltooling/shared/qqmldebugserverconnection.h)9
-rw-r--r--src/qml/debugger/qqmldebugservice_p.h6
-rw-r--r--src/qml/debugger/qqmldebugserviceinterfaces_p.h20
-rw-r--r--src/qml/debugger/qqmldebugstatesdelegate_p.h2
-rw-r--r--src/qml/debugger/qqmlmemoryprofiler_p.h2
-rw-r--r--src/qml/debugger/qqmlprofiler_p.h185
-rw-r--r--src/qml/debugger/qqmlprofilerdefinitions_p.h27
-rw-r--r--src/qml/doc/qtqml.qdocconf2
-rw-r--r--src/qml/doc/snippets/code/src_script_qjsengine.cpp2
-rw-r--r--src/qml/doc/src/cppintegration/data.qdoc23
-rw-r--r--src/qml/doc/src/cppintegration/definetypes.qdoc3
-rw-r--r--src/qml/doc/src/cppintegration/extending-tutorial.qdoc19
-rw-r--r--src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc12
-rw-r--r--src/qml/doc/src/cppintegration/topic.qdoc2
-rw-r--r--src/qml/doc/src/cppintegration/warning.qdocinc6
-rw-r--r--src/qml/doc/src/javascript/functionlist.qdoc1
-rw-r--r--src/qml/doc/src/javascript/hostenvironment.qdoc13
-rw-r--r--src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc38
-rw-r--r--src/qml/doc/src/qmllanguageref/syntax/propertybinding.qdoc20
-rw-r--r--src/qml/jit/jit.pri22
-rw-r--r--src/qml/jit/qv4assembler.cpp2464
-rw-r--r--src/qml/jit/qv4assembler_p.h1760
-rw-r--r--src/qml/jit/qv4binop.cpp665
-rw-r--r--src/qml/jit/qv4binop_p.h256
-rw-r--r--src/qml/jit/qv4isel_masm.cpp1676
-rw-r--r--src/qml/jit/qv4isel_masm_p.h313
-rw-r--r--src/qml/jit/qv4jit.cpp1309
-rw-r--r--src/qml/jit/qv4jit_p.h265
-rw-r--r--src/qml/jit/qv4regalloc.cpp1971
-rw-r--r--src/qml/jit/qv4regalloc_p.h140
-rw-r--r--src/qml/jit/qv4targetplatform_p.h707
-rw-r--r--src/qml/jit/qv4unop.cpp166
-rw-r--r--src/qml/jsapi/qjsengine.cpp72
-rw-r--r--src/qml/jsapi/qjsengine.h11
-rw-r--r--src/qml/jsapi/qjsvalue.cpp50
-rw-r--r--src/qml/jsapi/qjsvalue.h6
-rw-r--r--src/qml/jsruntime/jsruntime.pri18
-rw-r--r--src/qml/jsruntime/qv4argumentsobject.cpp175
-rw-r--r--src/qml/jsruntime/qv4argumentsobject_p.h53
-rw-r--r--src/qml/jsruntime/qv4arraybuffer.cpp99
-rw-r--r--src/qml/jsruntime/qv4arraybuffer_p.h12
-rw-r--r--src/qml/jsruntime/qv4arraydata.cpp248
-rw-r--r--src/qml/jsruntime/qv4arraydata_p.h169
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp676
-rw-r--r--src/qml/jsruntime/qv4arrayobject_p.h52
-rw-r--r--src/qml/jsruntime/qv4booleanobject.cpp56
-rw-r--r--src/qml/jsruntime/qv4booleanobject_p.h8
-rw-r--r--src/qml/jsruntime/qv4context.cpp524
-rw-r--r--src/qml/jsruntime/qv4context_p.h250
-rw-r--r--src/qml/jsruntime/qv4dataview.cpp154
-rw-r--r--src/qml/jsruntime/qv4dataview_p.h35
-rw-r--r--src/qml/jsruntime/qv4dateobject.cpp872
-rw-r--r--src/qml/jsruntime/qv4dateobject_p.h108
-rw-r--r--src/qml/jsruntime/qv4debugging_p.h2
-rw-r--r--src/qml/jsruntime/qv4engine.cpp309
-rw-r--r--src/qml/jsruntime/qv4engine_p.h157
-rw-r--r--src/qml/jsruntime/qv4enginebase_p.h32
-rw-r--r--src/qml/jsruntime/qv4errorobject.cpp114
-rw-r--r--src/qml/jsruntime/qv4errorobject_p.h34
-rw-r--r--src/qml/jsruntime/qv4function.cpp87
-rw-r--r--src/qml/jsruntime/qv4function_p.h36
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp396
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h118
-rw-r--r--src/qml/jsruntime/qv4global_p.h34
-rw-r--r--src/qml/jsruntime/qv4globalobject.cpp158
-rw-r--r--src/qml/jsruntime/qv4globalobject_p.h24
-rw-r--r--src/qml/jsruntime/qv4identifier.cpp18
-rw-r--r--src/qml/jsruntime/qv4identifier_p.h102
-rw-r--r--src/qml/jsruntime/qv4identifiertable_p.h4
-rw-r--r--src/qml/jsruntime/qv4include.cpp40
-rw-r--r--src/qml/jsruntime/qv4include_p.h2
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp121
-rw-r--r--src/qml/jsruntime/qv4internalclass_p.h13
-rw-r--r--src/qml/jsruntime/qv4jscall_p.h139
-rw-r--r--src/qml/jsruntime/qv4jsonobject.cpp82
-rw-r--r--src/qml/jsruntime/qv4jsonobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4lookup.cpp960
-rw-r--r--src/qml/jsruntime/qv4lookup_p.h115
-rw-r--r--src/qml/jsruntime/qv4managed_p.h16
-rw-r--r--src/qml/jsruntime/qv4mathobject.cpp106
-rw-r--r--src/qml/jsruntime/qv4mathobject_p.h38
-rw-r--r--src/qml/jsruntime/qv4memberdata.cpp15
-rw-r--r--src/qml/jsruntime/qv4memberdata_p.h37
-rw-r--r--src/qml/jsruntime/qv4numberobject.cpp205
-rw-r--r--src/qml/jsruntime/qv4numberobject_p.h22
-rw-r--r--src/qml/jsruntime/qv4object.cpp495
-rw-r--r--src/qml/jsruntime/qv4object_p.h188
-rw-r--r--src/qml/jsruntime/qv4objectiterator.cpp10
-rw-r--r--src/qml/jsruntime/qv4objectiterator_p.h6
-rw-r--r--src/qml/jsruntime/qv4objectproto.cpp511
-rw-r--r--src/qml/jsruntime/qv4objectproto_p.h57
-rw-r--r--src/qml/jsruntime/qv4persistent.cpp21
-rw-r--r--src/qml/jsruntime/qv4persistent_p.h4
-rw-r--r--src/qml/jsruntime/qv4profiling_p.h35
-rw-r--r--src/qml/jsruntime/qv4property_p.h15
-rw-r--r--src/qml/jsruntime/qv4qmlcontext.cpp80
-rw-r--r--src/qml/jsruntime/qv4qmlcontext_p.h23
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp437
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper_p.h45
-rw-r--r--src/qml/jsruntime/qv4regexp.cpp30
-rw-r--r--src/qml/jsruntime/qv4regexp_p.h16
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp241
-rw-r--r--src/qml/jsruntime/qv4regexpobject_p.h67
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp755
-rw-r--r--src/qml/jsruntime/qv4runtime_p.h15
-rw-r--r--src/qml/jsruntime/qv4runtimeapi_p.h99
-rw-r--r--src/qml/jsruntime/qv4runtimecodegen.cpp80
-rw-r--r--src/qml/jsruntime/qv4runtimecodegen_p.h82
-rw-r--r--src/qml/jsruntime/qv4scopedvalue_p.h79
-rw-r--r--src/qml/jsruntime/qv4script.cpp105
-rw-r--r--src/qml/jsruntime/qv4script_p.h57
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp164
-rw-r--r--src/qml/jsruntime/qv4sequenceobject_p.h9
-rw-r--r--src/qml/jsruntime/qv4sparsearray.cpp2
-rw-r--r--src/qml/jsruntime/qv4sparsearray_p.h2
-rw-r--r--src/qml/jsruntime/qv4string.cpp111
-rw-r--r--src/qml/jsruntime/qv4string_p.h91
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp525
-rw-r--r--src/qml/jsruntime/qv4stringobject_p.h60
-rw-r--r--src/qml/jsruntime/qv4typedarray.cpp211
-rw-r--r--src/qml/jsruntime/qv4typedarray_p.h37
-rw-r--r--src/qml/jsruntime/qv4value.cpp119
-rw-r--r--src/qml/jsruntime/qv4value_p.h442
-rw-r--r--src/qml/jsruntime/qv4variantobject.cpp40
-rw-r--r--src/qml/jsruntime/qv4variantobject_p.h12
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp1435
-rw-r--r--src/qml/jsruntime/qv4vme_moth_p.h19
-rw-r--r--src/qml/memory/memory.pri3
-rw-r--r--src/qml/memory/qv4heap_p.h74
-rw-r--r--src/qml/memory/qv4mm.cpp366
-rw-r--r--src/qml/memory/qv4mm_p.h85
-rw-r--r--src/qml/memory/qv4mmdefs_p.h100
-rw-r--r--src/qml/memory/qv4writebarrier_p.h (renamed from src/qml/jit/qv4unop_p.h)63
-rw-r--r--src/qml/parser/qqmljs.g85
-rw-r--r--src/qml/parser/qqmljsast.cpp17
-rw-r--r--src/qml/parser/qqmljsast_p.h105
-rw-r--r--src/qml/parser/qqmljsastfwd_p.h2
-rw-r--r--src/qml/parser/qqmljsastvisitor_p.h4
-rw-r--r--src/qml/parser/qqmljsgrammar.cpp2130
-rw-r--r--src/qml/parser/qqmljsgrammar_p.h294
-rw-r--r--src/qml/parser/qqmljskeywords_p.h11
-rw-r--r--src/qml/parser/qqmljslexer.cpp3
-rw-r--r--src/qml/parser/qqmljslexer_p.h1
-rw-r--r--src/qml/parser/qqmljsparser.cpp421
-rw-r--r--src/qml/parser/qqmljsparser_p.h5
-rw-r--r--src/qml/qml.pro6
-rw-r--r--src/qml/qml/ftw/qhashedstring_p.h4
-rw-r--r--src/qml/qml/qqml.h54
-rw-r--r--src/qml/qml/qqmlapplicationengine.h6
-rw-r--r--src/qml/qml/qqmlbinding.cpp122
-rw-r--r--src/qml/qml/qqmlbinding_p.h17
-rw-r--r--src/qml/qml/qqmlboundsignal.cpp45
-rw-r--r--src/qml/qml/qqmlcomponent.cpp126
-rw-r--r--src/qml/qml/qqmlcomponent.h18
-rw-r--r--src/qml/qml/qqmlcomponent_p.h7
-rw-r--r--src/qml/qml/qqmlcontext.cpp80
-rw-r--r--src/qml/qml/qqmlcontext.h9
-rw-r--r--src/qml/qml/qqmlcontext_p.h6
-rw-r--r--src/qml/qml/qqmlcustomparser.cpp22
-rw-r--r--src/qml/qml/qqmldelayedcallqueue.cpp44
-rw-r--r--src/qml/qml/qqmldelayedcallqueue_p.h5
-rw-r--r--src/qml/qml/qqmlengine.cpp61
-rw-r--r--src/qml/qml/qqmlengine.h7
-rw-r--r--src/qml/qml/qqmlengine_p.h18
-rw-r--r--src/qml/qml/qqmlerror.cpp2
-rw-r--r--src/qml/qml/qqmlexpression.cpp16
-rw-r--r--src/qml/qml/qqmlexpression.h6
-rw-r--r--src/qml/qml/qqmlexpression_p.h2
-rw-r--r--src/qml/qml/qqmlextensionplugin.h2
-rw-r--r--src/qml/qml/qqmlfileselector.h2
-rw-r--r--src/qml/qml/qqmlglobal.cpp2
-rw-r--r--src/qml/qml/qqmlglobal_p.h17
-rw-r--r--src/qml/qml/qqmlimport.cpp66
-rw-r--r--src/qml/qml/qqmlimport_p.h17
-rw-r--r--src/qml/qml/qqmljavascriptexpression.cpp63
-rw-r--r--src/qml/qml/qqmljavascriptexpression_p.h21
-rw-r--r--src/qml/qml/qqmllist.cpp10
-rw-r--r--src/qml/qml/qqmllist.h34
-rw-r--r--src/qml/qml/qqmllistwrapper.cpp13
-rw-r--r--src/qml/qml/qqmllistwrapper_p.h4
-rw-r--r--src/qml/qml/qqmllocale.cpp388
-rw-r--r--src/qml/qml/qqmllocale_p.h86
-rw-r--r--src/qml/qml/qqmlmetatype.cpp229
-rw-r--r--src/qml/qml/qqmlmetatype_p.h11
-rw-r--r--src/qml/qml/qqmlnotifier.cpp2
-rw-r--r--src/qml/qml/qqmlnotifier_p.h5
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp33
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h10
-rw-r--r--src/qml/qml/qqmlplatform.cpp6
-rw-r--r--src/qml/qml/qqmlplatform_p.h2
-rw-r--r--src/qml/qml/qqmlprivate.h5
-rw-r--r--src/qml/qml/qqmlpropertycache.cpp24
-rw-r--r--src/qml/qml/qqmlpropertycache_p.h72
-rw-r--r--src/qml/qml/qqmltypeloader.cpp98
-rw-r--r--src/qml/qml/qqmltypeloader_p.h22
-rw-r--r--src/qml/qml/qqmltypenamecache.cpp5
-rw-r--r--src/qml/qml/qqmltypenamecache_p.h4
-rw-r--r--src/qml/qml/qqmltypewrapper.cpp147
-rw-r--r--src/qml/qml/qqmltypewrapper_p.h31
-rw-r--r--src/qml/qml/qqmlvaluetypeproxybinding.cpp5
-rw-r--r--src/qml/qml/qqmlvaluetypeproxybinding_p.h1
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp58
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper_p.h5
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp81
-rw-r--r--src/qml/qml/qqmlvmemetaobject_p.h8
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp437
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp778
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions_p.h118
-rw-r--r--src/qml/qml/v8/qv4domerrors_p.h3
-rw-r--r--src/qml/qml/v8/qv8engine.cpp16
-rw-r--r--src/qml/qml/v8/qv8engine_p.h20
-rw-r--r--src/qml/qtqmlglobal.h2
-rw-r--r--src/qml/types/qqmlconnections.cpp5
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp157
-rw-r--r--src/qml/types/qqmldelegatemodel_p_p.h17
-rw-r--r--src/qml/types/qqmllistmodel.cpp466
-rw-r--r--src/qml/types/qqmllistmodel_p.h26
-rw-r--r--src/qml/types/qqmllistmodel_p_p.h29
-rw-r--r--src/qml/types/qqmllistmodelworkeragent.cpp89
-rw-r--r--src/qml/types/qqmllistmodelworkeragent_p.h27
-rw-r--r--src/qml/types/qquickpackage.cpp2
-rw-r--r--src/qml/types/qquickworkerscript.cpp81
-rw-r--r--src/qml/types/qquickworkerscript_p.h2
-rw-r--r--src/qml/util/qqmladaptormodel.cpp102
-rw-r--r--src/qml/util/qqmlpropertymap.cpp14
-rw-r--r--src/qml/util/qqmlpropertymap.h8
-rw-r--r--src/qmldebug/qmldebug.pro16
-rw-r--r--src/qmldebug/qqmldebugmessageclient.cpp95
-rw-r--r--src/qmldebug/qqmldebugmessageclient_p.h87
-rw-r--r--src/qmldebug/qqmlenginecontrolclient.cpp31
-rw-r--r--src/qmldebug/qqmlprofilerclient.cpp509
-rw-r--r--src/qmldebug/qqmlprofilerclient_p.h62
-rw-r--r--src/qmldebug/qqmlprofilerclient_p_p.h61
-rw-r--r--src/qmldebug/qqmlprofilerevent.cpp273
-rw-r--r--src/qmldebug/qqmlprofilerevent_p.h355
-rw-r--r--src/qmldebug/qqmlprofilereventlocation.cpp56
-rw-r--r--src/qmldebug/qqmlprofilereventlocation_p.h121
-rw-r--r--src/qmldebug/qqmlprofilereventreceiver_p.h74
-rw-r--r--src/qmldebug/qqmlprofilereventtype.cpp92
-rw-r--r--src/qmldebug/qqmlprofilereventtype_p.h126
-rw-r--r--src/qmldebug/qqmlprofilertypedevent.cpp226
-rw-r--r--src/qmldebug/qqmlprofilertypedevent_p.h76
-rw-r--r--src/qmldevtools/qmldevtools.pro1
-rw-r--r--src/qmltest/doc/qtqmltest.qdocconf42
-rw-r--r--src/qmltest/doc/src/qtquicktest-index.qdoc185
-rw-r--r--src/qmltest/qmltest.pro4
-rw-r--r--src/qmltest/quicktest.cpp244
-rw-r--r--src/qmltest/quicktest.h23
-rw-r--r--src/qmltest/quicktestevent.cpp19
-rw-r--r--src/qmltest/quicktestevent_p.h2
-rw-r--r--src/qmltest/quicktestresult.cpp41
-rw-r--r--src/quick/accessible/qaccessiblequickitem.cpp3
-rw-r--r--src/quick/accessible/qaccessiblequickitem_p.h70
-rw-r--r--src/quick/configure.json9
-rw-r--r--src/quick/designer/qqmldesignermetaobject.cpp2
-rw-r--r--src/quick/designer/qquickdesignersupport.cpp5
-rw-r--r--src/quick/doc/images/declarative-arcrotation.pngbin0 -> 4315 bytes
-rw-r--r--src/quick/doc/images/pathitem-code-example.pngbin0 -> 5989 bytes
-rw-r--r--src/quick/doc/images/pointDistanceThreshold.pngbin0 -> 8661 bytes
-rw-r--r--src/quick/doc/images/pointDistanceThreshold.svg217
-rw-r--r--src/quick/doc/images/shape-radial-gradient.pngbin0 -> 16523 bytes
-rw-r--r--src/quick/doc/images/touchpoint-metrics.svg580
-rw-r--r--src/quick/doc/images/touchpoints-pinchhandler.pngbin0 -> 46937 bytes
-rw-r--r--src/quick/doc/images/visualpath-code-example.pngbin0 -> 844 bytes
-rw-r--r--src/quick/doc/qtquick.qdocconf8
-rw-r--r--src/quick/doc/snippets/pointerHandlers/dragHandler.qml60
-rw-r--r--src/quick/doc/snippets/pointerHandlers/dragHandlerDifferentTarget.qml72
-rw-r--r--src/quick/doc/snippets/pointerHandlers/dragHandlerNullTarget.qml70
-rw-r--r--src/quick/doc/snippets/pointerHandlers/pinchHandler.qml60
-rw-r--r--src/quick/doc/snippets/pointerHandlers/pinchHandlerDifferentTarget.qml69
-rw-r--r--src/quick/doc/snippets/pointerHandlers/pinchHandlerNullTarget.qml70
-rw-r--r--src/quick/doc/snippets/pointerHandlers/pointHandler.qml79
-rw-r--r--src/quick/doc/snippets/qml/layerblending.qml2
-rw-r--r--src/quick/doc/snippets/qml/layout-simple.qml74
-rw-r--r--src/quick/doc/snippets/qml/opacitymask.qml2
-rw-r--r--src/quick/doc/snippets/qml/path/arcrotation.qml62
-rw-r--r--src/quick/doc/src/concepts/layouts/qtquicklayouts-overview.qdoc25
-rw-r--r--src/quick/doc/src/concepts/pointerhandlers/qtquickhandlers-index.qdoc73
-rw-r--r--src/quick/doc/src/concepts/pointerhandlers/qtquickhandlers.qdoc44
-rw-r--r--src/quick/doc/src/qmltypereference.qdoc4
-rw-r--r--src/quick/handlers/handlers.pri22
-rw-r--r--src/quick/handlers/qquickdraghandler.cpp254
-rw-r--r--src/quick/handlers/qquickdraghandler_p.h137
-rw-r--r--src/quick/handlers/qquickhandlersmodule.cpp106
-rw-r--r--src/quick/handlers/qquickhandlersmodule_p.h (renamed from src/qmldebug/qqmleventlocation_p.h)27
-rw-r--r--src/quick/handlers/qquickmultipointhandler.cpp315
-rw-r--r--src/quick/handlers/qquickmultipointhandler_p.h118
-rw-r--r--src/quick/handlers/qquickpinchhandler.cpp490
-rw-r--r--src/quick/handlers/qquickpinchhandler_p.h173
-rw-r--r--src/quick/handlers/qquickpointerdevicehandler.cpp196
-rw-r--r--src/quick/handlers/qquickpointerdevicehandler_p.h96
-rw-r--r--src/quick/handlers/qquickpointerhandler.cpp425
-rw-r--r--src/quick/handlers/qquickpointerhandler_p.h157
-rw-r--r--src/quick/handlers/qquickpointhandler.cpp161
-rw-r--r--src/quick/handlers/qquickpointhandler_p.h81
-rw-r--r--src/quick/handlers/qquicksinglepointhandler.cpp475
-rw-r--r--src/quick/handlers/qquicksinglepointhandler_p.h154
-rw-r--r--src/quick/handlers/qquicktaphandler.cpp371
-rw-r--r--src/quick/handlers/qquicktaphandler_p.h132
-rw-r--r--src/quick/items/context2d/qquickcanvasitem.cpp18
-rw-r--r--src/quick/items/context2d/qquickcanvasitem_p.h18
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp1127
-rw-r--r--src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp16
-rw-r--r--src/quick/items/context2d/qquickcontext2dtexture_p.h18
-rw-r--r--src/quick/items/context2d/qquickcontext2dtile_p.h2
-rw-r--r--src/quick/items/items.pri12
-rw-r--r--src/quick/items/qquickanchors.cpp14
-rw-r--r--src/quick/items/qquickanchors_p_p.h22
-rw-r--r--src/quick/items/qquickanimatedimage.cpp27
-rw-r--r--src/quick/items/qquickanimatedimage_p.h12
-rw-r--r--src/quick/items/qquickanimatedimage_p_p.h3
-rw-r--r--src/quick/items/qquickanimatedsprite_p.h4
-rw-r--r--src/quick/items/qquickborderimage_p.h10
-rw-r--r--src/quick/items/qquickdrag.cpp4
-rw-r--r--src/quick/items/qquickdroparea_p.h8
-rw-r--r--src/quick/items/qquickevents.cpp1032
-rw-r--r--src/quick/items/qquickevents_p_p.h192
-rw-r--r--src/quick/items/qquickflickable.cpp129
-rw-r--r--src/quick/items/qquickflickable_p.h29
-rw-r--r--src/quick/items/qquickflickable_p_p.h5
-rw-r--r--src/quick/items/qquickflipable.cpp4
-rw-r--r--src/quick/items/qquickflipable_p.h2
-rw-r--r--src/quick/items/qquickframebufferobject.cpp2
-rw-r--r--src/quick/items/qquickframebufferobject.h12
-rw-r--r--src/quick/items/qquickgenericshadereffect.cpp3
-rw-r--r--src/quick/items/qquickgridview.cpp3
-rw-r--r--src/quick/items/qquickimage.cpp35
-rw-r--r--src/quick/items/qquickimage_p.h16
-rw-r--r--src/quick/items/qquickimage_p_p.h2
-rw-r--r--src/quick/items/qquickimagebase.cpp65
-rw-r--r--src/quick/items/qquickimagebase_p.h5
-rw-r--r--src/quick/items/qquickimagebase_p_p.h4
-rw-r--r--src/quick/items/qquickimplicitsizeitem.cpp26
-rw-r--r--src/quick/items/qquickimplicitsizeitem_p.h8
-rw-r--r--src/quick/items/qquickimplicitsizeitem_p_p.h3
-rw-r--r--src/quick/items/qquickitem.cpp368
-rw-r--r--src/quick/items/qquickitem.h23
-rw-r--r--src/quick/items/qquickitem_p.h70
-rw-r--r--src/quick/items/qquickitemanimation.cpp4
-rw-r--r--src/quick/items/qquickitemanimation_p.h6
-rw-r--r--src/quick/items/qquickitemchangelistener_p.h1
-rw-r--r--src/quick/items/qquickitemgrabresult.h2
-rw-r--r--src/quick/items/qquickitemsmodule.cpp30
-rw-r--r--src/quick/items/qquickitemview_p_p.h2
-rw-r--r--src/quick/items/qquickloader.cpp14
-rw-r--r--src/quick/items/qquickloader_p.h4
-rw-r--r--src/quick/items/qquickloader_p_p.h14
-rw-r--r--src/quick/items/qquickmousearea.cpp11
-rw-r--r--src/quick/items/qquickmousearea_p.h30
-rw-r--r--src/quick/items/qquickmousearea_p_p.h3
-rw-r--r--src/quick/items/qquickmultipointtoucharea.cpp5
-rw-r--r--src/quick/items/qquickmultipointtoucharea_p.h20
-rw-r--r--src/quick/items/qquickopenglshadereffect.cpp35
-rw-r--r--src/quick/items/qquickopenglshadereffectnode.cpp27
-rw-r--r--src/quick/items/qquickopenglshadereffectnode_p.h10
-rw-r--r--src/quick/items/qquickpainteditem.h14
-rw-r--r--src/quick/items/qquickpathview_p_p.h1
-rw-r--r--src/quick/items/qquickpincharea.cpp4
-rw-r--r--src/quick/items/qquickpincharea_p.h10
-rw-r--r--src/quick/items/qquickpositioners.cpp9
-rw-r--r--src/quick/items/qquickpositioners_p.h23
-rw-r--r--src/quick/items/qquickpositioners_p_p.h13
-rw-r--r--src/quick/items/qquickrectangle.cpp12
-rw-r--r--src/quick/items/qquickrectangle_p.h2
-rw-r--r--src/quick/items/qquickrectangle_p_p.h15
-rw-r--r--src/quick/items/qquickrendercontrol.cpp4
-rw-r--r--src/quick/items/qquickrendercontrol.h6
-rw-r--r--src/quick/items/qquickrepeater_p.h8
-rw-r--r--src/quick/items/qquickrepeater_p_p.h2
-rw-r--r--src/quick/items/qquickscreen.cpp48
-rw-r--r--src/quick/items/qquickscreen_p.h9
-rw-r--r--src/quick/items/qquickshadereffect.cpp2
-rw-r--r--src/quick/items/qquickshadereffectmesh_p.h6
-rw-r--r--src/quick/items/qquickshadereffectsource.cpp42
-rw-r--r--src/quick/items/qquickshadereffectsource_p.h18
-rw-r--r--src/quick/items/qquicksprite.cpp5
-rw-r--r--src/quick/items/qquicksprite_p.h2
-rw-r--r--src/quick/items/qquickspriteengine.cpp11
-rw-r--r--src/quick/items/qquickspriteengine_p.h7
-rw-r--r--src/quick/items/qquickspritesequence_p.h2
-rw-r--r--src/quick/items/qquickstateoperations.cpp6
-rw-r--r--src/quick/items/qquickstateoperations_p.h46
-rw-r--r--src/quick/items/qquicktext.cpp114
-rw-r--r--src/quick/items/qquicktext_p.h26
-rw-r--r--src/quick/items/qquicktext_p_p.h10
-rw-r--r--src/quick/items/qquicktextcontrol_p.h4
-rw-r--r--src/quick/items/qquicktextedit.cpp135
-rw-r--r--src/quick/items/qquicktextedit_p.h45
-rw-r--r--src/quick/items/qquicktextedit_p_p.h25
-rw-r--r--src/quick/items/qquicktextinput.cpp35
-rw-r--r--src/quick/items/qquicktextinput_p.h36
-rw-r--r--src/quick/items/qquicktextinput_p_p.h11
-rw-r--r--src/quick/items/qquicktextutil_p.h16
-rw-r--r--src/quick/items/qquicktranslate_p.h8
-rw-r--r--src/quick/items/qquickview.cpp12
-rw-r--r--src/quick/items/qquickview.h6
-rw-r--r--src/quick/items/qquickwindow.cpp774
-rw-r--r--src/quick/items/qquickwindow.h51
-rw-r--r--src/quick/items/qquickwindow_p.h36
-rw-r--r--src/quick/items/qquickwindowattached.cpp4
-rw-r--r--src/quick/items/qquickwindowmodule.cpp3
-rw-r--r--src/quick/items/qquickwindowmodule_p.h6
-rw-r--r--src/quick/qtquick2.cpp4
-rw-r--r--src/quick/quick.pro1
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp12
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp10
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode_p.h2
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarelayer_p.h1
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp2
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp8
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp26
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp2
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp1
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp6
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp174
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h (renamed from src/quick/scenegraph/util/qsgdistancefieldutil_p.h)76
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp246
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgcompressedtexture_p.h (renamed from src/qml/jit/qv4registerinfo_p.h)112
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgktxhandler.cpp186
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgktxhandler_p.h78
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgpkmhandler.cpp119
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgpkmhandler_p.h70
-rw-r--r--src/quick/scenegraph/compressedtexture/qsgtexturefilehandler_p.h82
-rw-r--r--src/quick/scenegraph/coreapi/qsgabstractrenderer.h2
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp40
-rw-r--r--src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h8
-rw-r--r--src/quick/scenegraph/coreapi/qsggeometry.cpp13
-rw-r--r--src/quick/scenegraph/coreapi/qsgmaterial.cpp5
-rw-r--r--src/quick/scenegraph/coreapi/qsgnode.cpp8
-rw-r--r--src/quick/scenegraph/coreapi/qsgnode.h9
-rw-r--r--src/quick/scenegraph/coreapi/qsgrenderer.cpp22
-rw-r--r--src/quick/scenegraph/coreapi/qsgrenderer_p.h6
-rw-r--r--src/quick/scenegraph/coreapi/qsgrendernode.cpp27
-rw-r--r--src/quick/scenegraph/coreapi/qsgshaderrewriter.cpp1
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer.cpp6
-rw-r--r--src/quick/scenegraph/qsgadaptationlayer_p.h8
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp29
-rw-r--r--src/quick/scenegraph/qsgcontext_p.h5
-rw-r--r--src/quick/scenegraph/qsgcontextplugin.cpp21
-rw-r--r--src/quick/scenegraph/qsgcontextplugin_p.h2
-rw-r--r--src/quick/scenegraph/qsgdefaultcontext.cpp28
-rw-r--r--src/quick/scenegraph/qsgdefaultcontext_p.h2
-rw-r--r--src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp20
-rw-r--r--src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h2
-rw-r--r--src/quick/scenegraph/qsgdefaultglyphnode_p.cpp24
-rw-r--r--src/quick/scenegraph/qsgdefaultinternalimagenode.cpp6
-rw-r--r--src/quick/scenegraph/qsgdefaultinternalrectanglenode.cpp6
-rw-r--r--src/quick/scenegraph/qsgdefaultlayer.cpp22
-rw-r--r--src/quick/scenegraph/qsgdefaultlayer_p.h46
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext.cpp46
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext_p.h3
-rw-r--r--src/quick/scenegraph/qsgdefaultspritenode.cpp6
-rw-r--r--src/quick/scenegraph/qsgdistancefieldglyphnode.cpp16
-rw-r--r--src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp68
-rw-r--r--src/quick/scenegraph/qsgdistancefieldglyphnode_p.h2
-rw-r--r--src/quick/scenegraph/qsgrenderloop.cpp4
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp140
-rw-r--r--src/quick/scenegraph/qsgwindowsrenderloop.cpp4
-rw-r--r--src/quick/scenegraph/scenegraph.pri24
-rw-r--r--src/quick/scenegraph/util/qsgatlastexture.cpp323
-rw-r--r--src/quick/scenegraph/util/qsgatlastexture_p.h88
-rw-r--r--src/quick/scenegraph/util/qsgdistancefieldutil.cpp115
-rw-r--r--src/quick/scenegraph/util/qsgengine.h2
-rw-r--r--src/quick/scenegraph/util/qsgflatcolormaterial.cpp6
-rw-r--r--src/quick/scenegraph/util/qsgimagenode.cpp11
-rw-r--r--src/quick/scenegraph/util/qsgsimplematerial.cpp16
-rw-r--r--src/quick/scenegraph/util/qsgsimplematerial.h2
-rw-r--r--src/quick/scenegraph/util/qsgtexture.cpp26
-rw-r--r--src/quick/scenegraph/util/qsgtexture.h3
-rw-r--r--src/quick/scenegraph/util/qsgtexture_p.h4
-rw-r--r--src/quick/scenegraph/util/qsgtexturematerial.cpp14
-rw-r--r--src/quick/scenegraph/util/qsgtexturereader.cpp108
-rw-r--r--src/quick/scenegraph/util/qsgtexturereader_p.h86
-rw-r--r--src/quick/scenegraph/util/qsgvertexcolormaterial.cpp6
-rw-r--r--src/quick/util/qquickanimation.cpp4
-rw-r--r--src/quick/util/qquickanimation_p.h16
-rw-r--r--src/quick/util/qquickanimation_p_p.h2
-rw-r--r--src/quick/util/qquickanimatorjob.cpp25
-rw-r--r--src/quick/util/qquickanimatorjob_p.h1
-rw-r--r--src/quick/util/qquickglobal.cpp68
-rw-r--r--src/quick/util/qquickimageprovider.cpp22
-rw-r--r--src/quick/util/qquickimageprovider.h1
-rw-r--r--src/quick/util/qquickpath.cpp423
-rw-r--r--src/quick/util/qquickpath_p.h78
-rw-r--r--src/quick/util/qquickpath_p_p.h5
-rw-r--r--src/quick/util/qquickpixmapcache.cpp87
-rw-r--r--src/quick/util/qquickprofiler_p.h9
-rw-r--r--src/quick/util/qquickpropertychanges.cpp4
-rw-r--r--src/quick/util/qquickshortcut_p.h8
-rw-r--r--src/quick/util/qquickstate.cpp6
-rw-r--r--src/quick/util/qquickstate_p.h2
-rw-r--r--src/quick/util/qquicksvgparser.cpp8
-rw-r--r--src/quick/util/qquicksvgparser_p.h7
-rw-r--r--src/quick/util/qquickvaluetypes.cpp23
-rw-r--r--src/quick/util/qquickvaluetypes_p.h8
-rw-r--r--src/quick/util/util.pri2
-rw-r--r--src/quickwidgets/qquickwidget.cpp9
-rw-r--r--src/quickwidgets/qquickwidget.h5
-rw-r--r--src/quickwidgets/qquickwidget_p.h6
-rw-r--r--src/src.pro8
-rw-r--r--tests/auto/auto.pro3
-rw-r--r--tests/auto/bic/data/QtQml.5.10.0.linux-gcc-amd64.txt5889
-rw-r--r--tests/auto/bic/data/QtQuick.5.10.0.linux-gcc-amd64.txt10978
-rw-r--r--tests/auto/bic/data/QtQuickTest.5.10.0.linux-gcc-amd64.txt19193
-rw-r--r--tests/auto/bic/data/QtQuickWidgets.5.10.0.linux-gcc-amd64.txt21831
-rw-r--r--tests/auto/cmake/CMakeLists.txt11
-rw-r--r--tests/auto/cmake/qtquickcompiler/CMakeLists.txt14
-rw-r--r--tests/auto/cmake/qtquickcompiler/main.cpp9
-rw-r--r--tests/auto/cmake/qtquickcompiler/main.qml4
-rw-r--r--tests/auto/cmake/qtquickcompiler/qqc_test.qrc6
-rw-r--r--tests/auto/particles/qquickimageparticle/BLACKLIST16
-rw-r--r--tests/auto/particles/qquickspritegoal/BLACKLIST3
-rw-r--r--tests/auto/qml/bindingdependencyapi/bindingdependencyapi.pro11
-rw-r--r--tests/auto/qml/bindingdependencyapi/tst_bindingdependencyapi.cpp360
-rw-r--r--tests/auto/qml/debugger/debugger.pro3
-rw-r--r--tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro2
-rw-r--r--tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp84
-rw-r--r--tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro1
-rw-r--r--tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro1
-rw-r--r--tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/qqmldebuggingenabler.pro2
-rw-r--r--tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp153
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro2
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp534
-rw-r--r--tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro1
-rw-r--r--tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp3
-rw-r--r--tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess.pro4
-rw-r--r--tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/qqmldebugprocess.pro14
-rw-r--r--tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/tst_qqmldebugprocess.cpp126
-rw-r--r--tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.cpp39
-rw-r--r--tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.pro11
-rw-r--r--tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro2
-rw-r--r--tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp24
-rw-r--r--tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro4
-rw-r--r--tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp86
-rw-r--r--tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro4
-rw-r--r--tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp106
-rw-r--r--tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro2
-rw-r--r--tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp26
-rw-r--r--tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro2
-rw-r--r--tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp83
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/data/controlFromJS.qml7
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/data/exit.qml2
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/data/qstr.qml9
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro3
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp760
-rw-r--r--tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp37
-rw-r--r--tests/auto/qml/debugger/shared/debugutil.cpp241
-rw-r--r--tests/auto/qml/debugger/shared/debugutil.pri11
-rw-r--r--tests/auto/qml/debugger/shared/debugutil_p.h84
-rw-r--r--tests/auto/qml/debugger/shared/qqmldebugprocess.cpp245
-rw-r--r--tests/auto/qml/debugger/shared/qqmldebugprocess_p.h99
-rw-r--r--tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp2
-rw-r--r--tests/auto/qml/ecmascripttests/TestExpectations148
m---------tests/auto/qml/ecmascripttests/test2620
-rwxr-xr-xtests/auto/qml/ecmascripttests/test262.py4
-rw-r--r--tests/auto/qml/ecmascripttests/tst_ecmascripttests.cpp36
-rw-r--r--tests/auto/qml/qjsengine/tst_qjsengine.cpp29
-rw-r--r--tests/auto/qml/qjsonbinding/qjsonbinding.pro1
-rw-r--r--tests/auto/qml/qjsvalue/tst_qjsvalue.cpp4
-rw-r--r--tests/auto/qml/qml.pro20
-rw-r--r--tests/auto/qml/qmlcachegen/qmlcachegen.pro6
-rw-r--r--tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp87
-rw-r--r--tests/auto/qml/qmlcachegen/worker.js3
-rw-r--r--tests/auto/qml/qmlcachegen/worker.qml12
-rw-r--r--tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp50
-rw-r--r--tests/auto/qml/qmlmin/qmlmin.pro6
-rw-r--r--tests/auto/qml/qmlmin/tst_qmlmin.cpp2
-rw-r--r--tests/auto/qml/qmlplugindump/data/dumper/CompositeSingleton/Singleton.qml (renamed from tests/auto/qml/qmlplugindump/tests/dumper/CompositeSingleton/Singleton.qml)0
-rw-r--r--tests/auto/qml/qmlplugindump/data/dumper/CompositeSingleton/qmldir (renamed from tests/auto/qml/qmlplugindump/tests/dumper/CompositeSingleton/qmldir)0
-rw-r--r--tests/auto/qml/qmlplugindump/qmlplugindump.pro6
-rw-r--r--tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp13
-rw-r--r--tests/auto/qml/qqmlapplicationengine/qqmlapplicationengine.pro6
-rw-r--r--tests/auto/qml/qqmlbinding/data/bindingOverwriting.qml13
-rw-r--r--tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp16
-rw-r--r--tests/auto/qml/qqmlchangeset/tst_qqmlchangeset.cpp29
-rw-r--r--tests/auto/qml/qqmlcomponent/qqmlcomponent.pro1
-rw-r--r--tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp2
-rw-r--r--tests/auto/qml/qqmlconnections/data/connection-no-signal-name.qml15
-rw-r--r--tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp10
-rw-r--r--tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp29
-rw-r--r--tests/auto/qml/qqmlecmascript/data/assignDate.1.qml25
-rw-r--r--tests/auto/qml/qqmlecmascript/data/assignDate.2.qml17
-rw-r--r--tests/auto/qml/qqmlecmascript/data/assignDate.3.qml29
-rw-r--r--tests/auto/qml/qqmlecmascript/data/assignDate.4.qml29
-rw-r--r--tests/auto/qml/qqmlecmascript/data/assignDate.5.qml37
-rw-r--r--tests/auto/qml/qqmlecmascript/data/assignDate.6.qml33
-rw-r--r--tests/auto/qml/qqmlecmascript/data/assignDate.qml19
-rw-r--r--tests/auto/qml/qqmlecmascript/data/dynamicString.qml2
-rw-r--r--tests/auto/qml/qqmlecmascript/data/nonNotifyableConstant.qml5
-rw-r--r--tests/auto/qml/qqmlecmascript/data/sequenceSort.qml14
-rw-r--r--tests/auto/qml/qqmlecmascript/qqmlecmascript.pro1
-rw-r--r--tests/auto/qml/qqmlecmascript/testtypes.cpp24
-rw-r--r--tests/auto/qml/qqmlecmascript/testtypes.h7
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp314
-rw-r--r--tests/auto/qml/qqmlengine/data/GroupedPropertiesRevisionComponent1.qml10
-rw-r--r--tests/auto/qml/qqmlengine/data/GroupedPropertiesRevisionComponent2.qml10
-rw-r--r--tests/auto/qml/qqmlengine/data/testGroupedPropertiesRevision.1.qml7
-rw-r--r--tests/auto/qml/qqmlengine/data/testGroupedPropertiesRevision.2.qml7
-rw-r--r--tests/auto/qml/qqmlengine/qqmlengine.pro5
-rw-r--r--tests/auto/qml/qqmlengine/tst_qqmlengine.cpp19
-rw-r--r--tests/auto/qml/qqmlextensionplugin/tst_qqmlextensionplugin.cpp2
-rw-r--r--tests/auto/qml/qqmlinstantiator/qqmlinstantiator.pro1
-rw-r--r--tests/auto/qml/qqmlinstantiator/stringmodel.h4
-rw-r--r--tests/auto/qml/qqmlitemmodels/qtestmodel.h2
-rw-r--r--tests/auto/qml/qqmllanguage/data/TypeWithEnum.qml28
-rw-r--r--tests/auto/qml/qqmllanguage/data/circularSingleton.qml6
-rw-r--r--tests/auto/qml/qqmllanguage/data/cppnamespace.qml1
-rw-r--r--tests/auto/qml/qqmllanguage/data/instanceOf/CustomMouseArea.qml6
-rw-r--r--tests/auto/qml/qqmllanguage/data/instanceOf/CustomRectangle.qml4
-rw-r--r--tests/auto/qml/qqmllanguage/data/instanceOf/CustomRectangleWithProp.qml6
-rw-r--r--tests/auto/qml/qqmllanguage/data/instanceOf/qmldir2
-rw-r--r--tests/auto/qml/qqmllanguage/data/instanceof_qtqml.qml13
-rw-r--r--tests/auto/qml/qqmllanguage/data/instanceof_qtqml_qualified.qml13
-rw-r--r--tests/auto/qml/qqmllanguage/data/instanceof_qtquick.qml14
-rw-r--r--tests/auto/qml/qqmllanguage/data/instanceof_qtquick_composite.qml26
-rw-r--r--tests/auto/qml/qqmllanguage/data/instanceof_qtquick_composite_qualified.qml27
-rw-r--r--tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.1.errors.txt1
-rw-r--r--tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.1.qml9
-rw-r--r--tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.2.errors.txt1
-rw-r--r--tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.2.qml9
-rw-r--r--tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.3.errors.txt1
-rw-r--r--tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.3.qml9
-rw-r--r--tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.4.errors.txt1
-rw-r--r--tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.4.qml9
-rw-r--r--tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/NonSingletonType.qml5
-rw-r--r--tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/SingletonType.qml5
-rw-r--r--tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/qmldir4
-rw-r--r--tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/test.js1
-rw-r--r--tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.1.errors.txt1
-rw-r--r--tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.1.qml9
-rw-r--r--tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.2.errors.txt1
-rw-r--r--tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.2.qml9
-rw-r--r--tests/auto/qml/qqmllanguage/data/mixedModuleWithSelfImport.qml3
-rw-r--r--tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyInternalType.qml2
-rw-r--r--tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyPublicType.qml4
-rw-r--r--tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyPublicTypeWithExplicitImport.qml5
-rw-r--r--tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/qmldir3
-rw-r--r--tests/auto/qml/qqmllanguage/data/registeredCompositeTypeWithEnum.qml1
-rw-r--r--tests/auto/qml/qqmllanguage/data/scopedEnum.qml21
-rw-r--r--tests/auto/qml/qqmllanguage/data/scopedEnumList.errors.txt1
-rw-r--r--tests/auto/qml/qqmllanguage/data/scopedEnumList.qml10
-rw-r--r--tests/auto/qml/qqmllanguage/data/singleton/circular/MySingleton.qml12
-rw-r--r--tests/auto/qml/qqmllanguage/data/singleton/circular/qmldir1
-rw-r--r--tests/auto/qml/qqmllanguage/data/usingTypeWithEnum.qml8
-rw-r--r--tests/auto/qml/qqmllanguage/qqmllanguage.pro1
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.cpp2
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.h18
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp311
-rw-r--r--tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp32
-rw-r--r--tests/auto/qml/qqmllistmodelworkerscript/tst_qqmllistmodelworkerscript.cpp8
-rw-r--r--tests/auto/qml/qqmllocale/tst_qqmllocale.cpp8
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/invalidStrictModule.pro12
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/qmldir2
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro1
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp6
-rw-r--r--tests/auto/qml/qqmlnotifier/tst_qqmlnotifier.cpp6
-rw-r--r--tests/auto/qml/qqmlqt/tst_qqmlqt.cpp5
-rw-r--r--tests/auto/qml/qqmltranslation/data/TranslationChangeBase.qml5
-rw-r--r--tests/auto/qml/qqmltranslation/data/translationChange.qml10
-rw-r--r--tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp46
-rw-r--r--tests/auto/qml/qqmlxmlhttprequest/data/send_data.11.expectbin0 -> 223 bytes
-rw-r--r--tests/auto/qml/qqmlxmlhttprequest/data/send_data.11.qml23
-rw-r--r--tests/auto/qml/qqmlxmlhttprequest/qqmlxmlhttprequest.pro1
-rw-r--r--tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp3
-rw-r--r--tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp16
-rw-r--r--tests/auto/qml/qwidgetsinqml/qwidgetsinqml.pro7
-rw-r--r--tests/auto/qml/qwidgetsinqml/tst_qwidgetsinqml.cpp283
-rw-r--r--tests/auto/qmltest-blacklist/shortcut/shortcut.pro1
-rw-r--r--tests/auto/qmltest-blacklist/shortcut/tst_shortcut.qml58
-rw-r--r--tests/auto/qmltest/BLACKLIST16
-rw-r--r--tests/auto/qmltest/animatedimage/animatedimage.pro1
-rw-r--r--tests/auto/qmltest/animations/animations.pro1
-rw-r--r--tests/auto/qmltest/borderimage/borderimage.pro1
-rw-r--r--tests/auto/qmltest/buttonclick/buttonclick.pro1
-rw-r--r--tests/auto/qmltest/createbenchmark/createbenchmark.pro1
-rw-r--r--tests/auto/qmltest/events/events.pro1
-rw-r--r--tests/auto/qmltest/events/tst_touch.qml18
-rw-r--r--tests/auto/qmltest/fontloader/fontloader.pro1
-rw-r--r--tests/auto/qmltest/gradient/gradient.pro1
-rw-r--r--tests/auto/qmltest/image/car.ktxbin0 -> 11908 bytes
-rw-r--r--tests/auto/qmltest/image/image.pro1
-rw-r--r--tests/auto/qmltest/image/logo.pkmbin0 -> 32784 bytes
-rw-r--r--tests/auto/qmltest/image/tst_image.qml19
-rw-r--r--tests/auto/qmltest/itemgrabber/itemgrabber.pro1
-rw-r--r--tests/auto/qmltest/itemgrabber/tst_itemgrabber.qml12
-rw-r--r--tests/auto/qmltest/layout/layout.pro1
-rw-r--r--tests/auto/qmltest/listmodel/listmodel.pro1
-rw-r--r--tests/auto/qmltest/listmodel/tst_listmodel.qml56
-rw-r--r--tests/auto/qmltest/listview/BLACKLIST3
-rw-r--r--tests/auto/qmltest/listview/listview.pro1
-rw-r--r--tests/auto/qmltest/listview/tst_listview.qml13
-rw-r--r--tests/auto/qmltest/objectmodel/objectmodel.pro1
-rw-r--r--tests/auto/qmltest/pathview/pathview.pro1
-rw-r--r--tests/auto/qmltest/pixel/pixel.pro1
-rw-r--r--tests/auto/qmltest/positioners/positioners.pro1
-rw-r--r--tests/auto/qmltest/qmltest.pro44
-rw-r--r--tests/auto/qmltest/qqmlbinding/qqmlbinding.pro1
-rw-r--r--tests/auto/qmltest/qtbug46798/qtbug46798.pro1
-rw-r--r--tests/auto/qmltest/rectangle/rectangle.pro1
-rw-r--r--tests/auto/qmltest/selftests/BLACKLIST13
-rw-r--r--tests/auto/qmltest/selftests/selftests.pro1
-rw-r--r--tests/auto/qmltest/selftests/tst_grabImage.qml62
-rw-r--r--tests/auto/qmltest/selftests/tst_selftests.qml10
-rw-r--r--tests/auto/qmltest/shadersource/BLACKLIST3
-rw-r--r--tests/auto/qmltest/shadersource/shadersource.pro1
-rw-r--r--tests/auto/qmltest/shadersource/tst_DynamicallyCreatedSource.qml4
-rw-r--r--tests/auto/qmltest/stability/stability.pro1
-rw-r--r--tests/auto/qmltest/statemachine/statemachine.pro1
-rw-r--r--tests/auto/qmltest/text/text.pro1
-rw-r--r--tests/auto/qmltest/textedit/BLACKLIST6
-rw-r--r--tests/auto/qmltest/textedit/textedit.pro1
-rw-r--r--tests/auto/qmltest/textinput/textinput.pro1
-rw-r--r--tests/auto/qmltest/window/window.pro1
-rw-r--r--tests/auto/quick/drawingmodes/tst_drawingmodes.cpp34
-rw-r--r--tests/auto/quick/examples/tst_examples.cpp2
-rw-r--r--tests/auto/quick/nodes/tst_nodestest.cpp12
-rw-r--r--tests/auto/quick/nokeywords/tst_nokeywords.cpp1
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/FlashAnimation.qml45
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/Slider.qml121
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/TapHandlerButton.qml94
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/data/flickableWithHandlers.qml151
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/flickableinterop.pro15
-rw-r--r--tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp566
-rw-r--r--tests/auto/quick/pointerhandlers/multipointtoucharea_interop/data/pinchDragMPTA.qml108
-rw-r--r--tests/auto/quick/pointerhandlers/multipointtoucharea_interop/multipointtoucharea_interop.pro15
-rw-r--r--tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp287
-rw-r--r--tests/auto/quick/pointerhandlers/pointerhandlers.pro11
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/data/DragAnywhereSlider.qml126
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/data/FlashAnimation.qml45
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/data/Slider.qml125
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/data/draggables.qml60
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/data/multipleSliders.qml67
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/data/reparenting.qml60
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/data/simpleTapAndDragHandlers.qml112
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/qquickdraghandler.pro21
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp487
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpointerhandler/data/singleitem.qml28
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpointerhandler/qquickpointerhandler.pro16
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpointerhandler/tst_qquickpointerhandler.cpp580
-rw-r--r--tests/auto/quick/pointerhandlers/qquicktaphandler/data/Button.qml87
-rw-r--r--tests/auto/quick/pointerhandlers/qquicktaphandler/data/FlashAnimation.qml45
-rw-r--r--tests/auto/quick/pointerhandlers/qquicktaphandler/data/buttonOverrideHandler.qml46
-rw-r--r--tests/auto/quick/pointerhandlers/qquicktaphandler/data/buttons.qml53
-rw-r--r--tests/auto/quick/pointerhandlers/qquicktaphandler/qquicktaphandler.pro16
-rw-r--r--tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp627
-rw-r--r--tests/auto/quick/qquickanimatedsprite/BLACKLIST3
-rw-r--r--tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp2
-rw-r--r--tests/auto/quick/qquickanimations/BLACKLIST34
-rw-r--r--tests/auto/quick/qquickanimations/tst_qquickanimations.cpp27
-rw-r--r--tests/auto/quick/qquickapplication/data/tst_platformname.qml6
-rw-r--r--tests/auto/quick/qquickapplication/qquickapplication.pro3
-rw-r--r--tests/auto/quick/qquickapplication/tst_qquickapplication.cpp21
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml4
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_imagedata.qml4
-rw-r--r--tests/auto/quick/qquickcanvasitem/qquickcanvasitem.pro2
-rw-r--r--tests/auto/quick/qquickcanvasitem/tst_qquickcanvasitem.cpp27
-rw-r--r--tests/auto/quick/qquickflickable/BLACKLIST3
-rw-r--r--tests/auto/quick/qquickflickable/data/nestedStopAtBounds.qml3
-rw-r--r--tests/auto/quick/qquickflickable/tst_qquickflickable.cpp156
-rw-r--r--tests/auto/quick/qquickframebufferobject/BLACKLIST7
-rw-r--r--tests/auto/quick/qquickgridview/tst_qquickgridview.cpp4
-rw-r--r--tests/auto/quick/qquickimage/BLACKLIST4
-rw-r--r--tests/auto/quick/qquickimage/data/pattern.pkmbin0 -> 2064 bytes
-rw-r--r--tests/auto/quick/qquickimage/tst_qquickimage.cpp85
-rw-r--r--tests/auto/quick/qquickitem/BLACKLIST2
-rw-r--r--tests/auto/quick/qquickitem/tst_qquickitem.cpp7
-rw-r--r--tests/auto/quick/qquickitem2/tst_qquickitem.cpp16
-rw-r--r--tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp81
-rw-r--r--tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml35
-rw-r--r--tests/auto/quick/qquicklistview/BLACKLIST3
-rw-r--r--tests/auto/quick/qquicklistview/data/flickBothDirections.qml1
-rw-r--r--tests/auto/quick/qquicklistview/randomsortmodel.cpp5
-rw-r--r--tests/auto/quick/qquicklistview/tst_qquicklistview.cpp2
-rw-r--r--tests/auto/quick/qquickloader/BLACKLIST4
-rw-r--r--tests/auto/quick/qquickloader/data/bindings.qml71
-rw-r--r--tests/auto/quick/qquickloader/data/parentErrors.qml47
-rw-r--r--tests/auto/quick/qquickloader/qquickloader.pro1
-rw-r--r--tests/auto/quick/qquickloader/tst_qquickloader.cpp330
-rw-r--r--tests/auto/quick/qquickmousearea/BLACKLIST3
-rw-r--r--tests/auto/quick/qquickmousearea/data/mask.qml63
-rw-r--r--tests/auto/quick/qquickmousearea/qquickmousearea.pro2
-rw-r--r--tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp72
-rw-r--r--tests/auto/quick/qquickopenglinfo/BLACKLIST3
-rw-r--r--tests/auto/quick/qquickpainteditem/BLACKLIST27
-rw-r--r--tests/auto/quick/qquickpath/data/anglearc.qml12
-rw-r--r--tests/auto/quick/qquickpath/tst_qquickpath.cpp40
-rw-r--r--tests/auto/quick/qquickpathview/tst_qquickpathview.cpp4
-rw-r--r--tests/auto/quick/qquickpixmapcache/qquickpixmapcache.pro1
-rw-r--r--tests/auto/quick/qquickrectangle/data/gradient-multiple.qml30
-rw-r--r--tests/auto/quick/qquickrectangle/data/gradient-separate.qml20
-rw-r--r--tests/auto/quick/qquickrectangle/tst_qquickrectangle.cpp63
-rw-r--r--tests/auto/quick/qquickscreen/tst_qquickscreen.cpp3
-rw-r--r--tests/auto/quick/qquickshape/BLACKLIST8
-rw-r--r--tests/auto/quick/qquickshape/data/pathitem1.qml5
-rw-r--r--tests/auto/quick/qquickshape/data/pathitem2.qml7
-rw-r--r--tests/auto/quick/qquickshape/data/pathitem3.pngbin0 -> 5214 bytes
-rw-r--r--tests/auto/quick/qquickshape/data/pathitem3.qml33
-rw-r--r--tests/auto/quick/qquickshape/data/pathitem4.pngbin0 -> 5713 bytes
-rw-r--r--tests/auto/quick/qquickshape/data/pathitem4.qml56
-rw-r--r--tests/auto/quick/qquickshape/data/pathitem5.pngbin0 -> 9377 bytes
-rw-r--r--tests/auto/quick/qquickshape/data/pathitem5.qml37
-rw-r--r--tests/auto/quick/qquickshape/data/pathitem6.pngbin0 -> 11024 bytes
-rw-r--r--tests/auto/quick/qquickshape/data/pathitem6.qml35
-rw-r--r--tests/auto/quick/qquickshape/qquickshape.pro35
-rw-r--r--tests/auto/quick/qquickshape/tst_qquickshape.cpp304
-rw-r--r--tests/auto/quick/qquicktext/qquicktext.pro1
-rw-r--r--tests/auto/quick/qquicktext/tst_qquicktext.cpp62
-rw-r--r--tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp4
-rw-r--r--tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp4
-rw-r--r--tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp3
-rw-r--r--tests/auto/quick/qquickwindow/BLACKLIST3
-rw-r--r--tests/auto/quick/qquickwindow/tst_qquickwindow.cpp591
-rw-r--r--tests/auto/quick/quick.pro5
-rw-r--r--tests/auto/quick/rendernode/tst_rendernode.cpp14
-rw-r--r--tests/auto/quick/scenegraph/tst_scenegraph.cpp97
-rw-r--r--tests/auto/quick/shared/viewtestutil.cpp8
-rw-r--r--tests/auto/quick/touchmouse/BLACKLIST3
-rw-r--r--tests/auto/quick/touchmouse/tst_touchmouse.cpp29
-rw-r--r--tests/auto/quicktest/quicktest.pro3
-rw-r--r--tests/auto/quicktest/quicktestmainwithsetup/data/tst_setup.qml (renamed from tests/auto/qmltest/tst_qmltest.cpp)15
-rw-r--r--tests/auto/quicktest/quicktestmainwithsetup/quicktestmainwithsetup.pro12
-rw-r--r--tests/auto/quicktest/quicktestmainwithsetup/tst_quicktestmainwithsetup.cpp (renamed from tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/plugin.cpp)34
-rw-r--r--tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp43
-rw-r--r--tests/auto/shared/util.pri1
-rw-r--r--tests/benchmarks/qml/creation/tst_creation.cpp20
-rw-r--r--tests/benchmarks/qml/holistic/testtypes.h5
-rw-r--r--tests/benchmarks/qml/painting/paintbenchmark.cpp3
-rw-r--r--tests/manual/imagehandler/large.svg462
-rw-r--r--tests/manual/imagehandler/main.qml96
-rw-r--r--tests/manual/mousearea/main.cpp55
-rw-r--r--tests/manual/mousearea/main.qml46
-rw-r--r--tests/manual/mousearea/mousearea.pro7
-rw-r--r--tests/manual/mousearea/plainMouseArea.qml52
-rw-r--r--tests/manual/mousearea/qml.qrc6
-rw-r--r--tests/manual/pointer/content/FakeFlickable.qml97
-rw-r--r--tests/manual/pointer/content/FlashAnimation.qml45
-rw-r--r--tests/manual/pointer/content/MomentumAnimation.qml59
-rw-r--r--tests/manual/pointer/content/MouseAreaButton.qml74
-rw-r--r--tests/manual/pointer/content/MouseAreaSlider.qml107
-rw-r--r--tests/manual/pointer/content/MouseFeedbackSprite.qml79
-rw-r--r--tests/manual/pointer/content/MptaButton.qml75
-rw-r--r--tests/manual/pointer/content/MultiButton.qml73
-rw-r--r--tests/manual/pointer/content/ScrollBar.qml148
-rw-r--r--tests/manual/pointer/content/Slider.qml123
-rw-r--r--tests/manual/pointer/content/TapHandlerButton.qml72
-rw-r--r--tests/manual/pointer/content/TouchpointFeedbackSprite.qml73
-rw-r--r--tests/manual/pointer/fakeFlickable.qml105
-rw-r--r--tests/manual/pointer/flickableWithHandlers.qml96
-rw-r--r--tests/manual/pointer/flingAnimation.qml127
-rw-r--r--tests/manual/pointer/joystick.qml76
-rw-r--r--tests/manual/pointer/main.cpp55
-rw-r--r--tests/manual/pointer/main.qml74
-rw-r--r--tests/manual/pointer/map.qml71
-rw-r--r--tests/manual/pointer/map2.qml79
-rw-r--r--tests/manual/pointer/mixer.qml60
-rw-r--r--tests/manual/pointer/multibuttons.qml84
-rw-r--r--tests/manual/pointer/photosurface.qml163
-rw-r--r--tests/manual/pointer/pinchDragFlingMPTA.qml86
-rw-r--r--tests/manual/pointer/pinchHandler.qml176
-rw-r--r--tests/manual/pointer/pointer.pro7
-rw-r--r--tests/manual/pointer/qml.qrc43
-rw-r--r--tests/manual/pointer/resources/arrowhead.pngbin0 -> 883 bytes
-rw-r--r--tests/manual/pointer/resources/balloon.pngbin0 -> 3759 bytes
-rw-r--r--tests/manual/pointer/resources/fighter.pngbin0 -> 9669 bytes
-rw-r--r--tests/manual/pointer/resources/fingersprite.pngbin0 -> 6792 bytes
-rw-r--r--tests/manual/pointer/resources/grabbing-location.svg1
-rw-r--r--tests/manual/pointer/resources/joystick-outer-case-pov.jpgbin0 -> 50687 bytes
-rw-r--r--tests/manual/pointer/resources/map.svgzbin0 -> 27956 bytes
-rw-r--r--tests/manual/pointer/resources/missile.pngbin0 -> 2305 bytes
-rw-r--r--tests/manual/pointer/resources/mixer-knob.pngbin0 -> 7821 bytes
-rw-r--r--tests/manual/pointer/resources/mouse.pngbin0 -> 1919 bytes
-rw-r--r--tests/manual/pointer/resources/mouse_left.pngbin0 -> 740 bytes
-rw-r--r--tests/manual/pointer/resources/mouse_middle.pngbin0 -> 558 bytes
-rw-r--r--tests/manual/pointer/resources/mouse_right.pngbin0 -> 906 bytes
-rw-r--r--tests/manual/pointer/resources/redball.pngbin0 -> 10002 bytes
-rw-r--r--tests/manual/pointer/singlePointHandlerProperties.qml152
-rw-r--r--tests/manual/pointer/tapHandler.qml177
-rw-r--r--tests/manual/pointer/tapWithModifiers.qml46
-rw-r--r--tests/manual/quickwidgetviewer/main.cpp91
-rw-r--r--tests/manual/quickwidgetviewer/quickwidgetviewer.pro4
-rw-r--r--tests/manual/scenegraph_lancelot/data/shape/shape_arc.qml112
-rw-r--r--tests/manual/scenegraph_lancelot/data/shape/shape_arc_fill.qml112
-rw-r--r--tests/manual/scenegraph_lancelot/data/shape/shape_cubic.qml35
-rw-r--r--tests/manual/scenegraph_lancelot/data/shape/shape_linear_gradient.qml33
-rw-r--r--tests/manual/scenegraph_lancelot/data/shape/shape_lines.qml92
-rw-r--r--tests/manual/scenegraph_lancelot/data/shape/shape_quad.qml34
-rw-r--r--tests/manual/scenegraph_lancelot/data/shape/shape_spread.qml35
-rw-r--r--tests/manual/scenegraph_lancelot/data/text/text_advance_bidi_ltr.qml56
-rw-r--r--tests/manual/scenegraph_lancelot/data/text/text_advance_hebrew.qml54
-rw-r--r--tests/manual/scenegraph_lancelot/data/text/text_advance_latin.qml55
-rw-r--r--tests/manual/scenegraph_lancelot/data/text/text_advance_multiline.qml55
-rw-r--r--tests/manual/scenegraph_lancelot/data/text/text_advance_multiparagraph.qml39
-rw-r--r--tests/manual/scenegraph_lancelot/data/text/text_advance_multiparagraph_multifontsizes.qml39
-rw-r--r--tests/manual/scenegraph_lancelot/data/text/text_bengali_noshaping.qml15
-rw-r--r--tests/manual/scenegraph_lancelot/data/text/text_latin_noshaping.qml15
-rw-r--r--tests/manual/scenegraph_lancelot/data/text/text_nokerning_latin.qml16
-rw-r--r--tests/manual/shapestest/main.cpp57
-rw-r--r--tests/manual/shapestest/shapestest.pro6
-rw-r--r--tests/manual/shapestest/shapestest.qml452
-rw-r--r--tests/manual/shapestest/shapestest.qrc5
-rw-r--r--tests/manual/touch/mpta-crosshairs.qml1
-rw-r--r--tests/manual/v4/fact.2.js2
-rw-r--r--tests/manual/v4/typedarrays.js4
-rw-r--r--tools/qml/main.cpp4
-rw-r--r--tools/qml/qml.pro11
-rw-r--r--tools/qmlcachegen/Qt5QuickCompilerConfig.cmake73
-rw-r--r--tools/qmlcachegen/generateloader.cpp392
-rw-r--r--tools/qmlcachegen/qmlcache.prf20
-rw-r--r--tools/qmlcachegen/qmlcachegen.cpp265
-rw-r--r--tools/qmlcachegen/qmlcachegen.pro17
-rw-r--r--tools/qmlcachegen/qtquickcompiler.prf86
-rw-r--r--tools/qmlcachegen/resourcefilemapper.cpp169
-rw-r--r--tools/qmlcachegen/resourcefilemapper.h50
-rw-r--r--tools/qmlcachegen/resourcefilter.cpp183
-rw-r--r--tools/qmleasing/qmleasing.pro9
-rw-r--r--tools/qmlimportscanner/main.cpp4
-rw-r--r--tools/qmlimportscanner/qmlimportscanner.pro9
-rw-r--r--tools/qmljs/qmljs.cpp151
-rw-r--r--tools/qmljs/qmljs.pro9
-rw-r--r--tools/qmllint/qmllint.pro9
-rw-r--r--tools/qmlmin/main.cpp10
-rw-r--r--tools/qmlmin/qmlmin.pro9
-rw-r--r--tools/qmlplugindump/main.cpp1
-rw-r--r--tools/qmlplugindump/qmlplugindump.pro9
-rw-r--r--tools/qmlprofiler/qmlprofiler.pro9
-rw-r--r--tools/qmlprofiler/qmlprofilerapplication.cpp61
-rw-r--r--tools/qmlprofiler/qmlprofilerapplication.h6
-rw-r--r--tools/qmlprofiler/qmlprofilerclient.cpp141
-rw-r--r--tools/qmlprofiler/qmlprofilerclient.h21
-rw-r--r--tools/qmlprofiler/qmlprofilerdata.cpp737
-rw-r--r--tools/qmlprofiler/qmlprofilerdata.h23
-rw-r--r--tools/qmlscene/main.cpp116
-rw-r--r--tools/qmlscene/qmlscene.pro11
-rw-r--r--tools/qmltestrunner/qmltestrunner.pro9
-rw-r--r--tools/qmltime/qmltime.pro10
1218 files changed, 129912 insertions, 40951 deletions
diff --git a/.qmake.conf b/.qmake.conf
index 62944bc6fb..31a134c4cc 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -1,4 +1,4 @@
load(qt_build_config)
CONFIG += warning_clean
-MODULE_VERSION = 5.9.5
+MODULE_VERSION = 5.11.0
diff --git a/dist/changes-5.10.0 b/dist/changes-5.10.0
new file mode 100644
index 0000000000..e98bc8e4d9
--- /dev/null
+++ b/dist/changes-5.10.0
@@ -0,0 +1,188 @@
+Qt 5.10 introduces many new features and improvements as well as bugfixes
+over the 5.9.x series. For more details, refer to the online documentation
+included in this distribution. The documentation is also available online:
+
+http://doc.qt.io/qt-5/index.html
+
+The Qt version 5.10 series is binary compatible with the 5.9.x series.
+Applications compiled for 5.9 will continue to run with 5.10.
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+https://bugreports.qt.io/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+****************************************************************************
+* General *
+****************************************************************************
+
+ - Added the QtQuick.Shapes plugin providing the Shape and ShapePath
+ types for rendering geometry-based stroked and filled paths.
+ Various types of Path existed already for defining movement trajectories
+ in PathView, but now they can be rendered too.
+ * PathLine, PathQuad, PathCubic, PathArc, PathCurve, and PathSvg
+ * Fill: solid color, linear, radial or conical gradients
+ * Stroke: colored and dashed lines
+ * Uses GL_NV_path_rendering on recent nVidia GPUs
+
+ - Added the Qt.labs.handlers plugin, providing a Tech Preview version
+ of Pointer Handlers. These are intended as an improved way of handling
+ gestures and events from pointing devices (mouse, touchpad, and
+ touchscreen so far; stylus devices are coming in a future release).
+ Properties acceptedButtons, acceptedModifiers, acceptedDevices, and
+ acceptedPointerTypes enable scoping their reaction for specific use
+ cases, but by default, they work equally well with mouse (as applicable)
+ and touch devices. So far we have four of them available in QML:
+ * TapHandler is for detecting clicks and taps, double-clicks,
+ multi-clicks and taps, and long presses.
+ * DragHandler provides a way of declaring an Item draggable, and also
+ has properties which can be used for bindings to achieve
+ less-mainstream use cases.
+ * PinchHandler can react to a pinch gesture using two or more fingers
+ (as configured via properties) or to a native pinch gesture from the OS.
+ Declaring an instance inside an Item is enough to support pinching to
+ scale, rotate and move that Item; and it also has properties available
+ for bindings to enable other use cases.
+ * PointHandler does not directly manipulate an Item, but just provides
+ information about individual touchpoints or the mouse, for binding
+ purposes. It is intended mainly for interactive feedback, orthogonal
+ to whichever Handler or Item currently has the exclusive grab.
+ Along with this, control over grabbing has gotten more fine-grained:
+ the grabPermissions property in a Pointer Handler sets rules for how
+ Pointer Handlers and Items negotiate for the exclusive grab; and some
+ Pointer Handlers are able to handle some kinds of interaction with a new
+ type of grab, the passive grab. There are several new logging categories
+ you can enable to see how event delivery is done, the grab transitions,
+ and so on.
+
+ As usual with Tech Preview material, we reserve the right to change it
+ substantially in future releases.
+
+****************************************************************************
+* Library *
+****************************************************************************
+
+QmlTest
+-------
+
+ - The returned object from TestCase::grabImage now has 'width', 'height',
+ and 'size' properties for additional verification. In addition, there is
+ a save() method to be able to persist the grabbed image to disk (for
+ diagnostics purposes, for example).
+
+Qt Quick
+--------
+
+ - [QTBUG-58945] Added the properties ShaderEffectSource.samples and
+ Item.layer.samples to allow requesting MSAA rendering of an item
+ subtree, without enabling multisampling for the entire scene.
+ - [QTBUG-59462] Added support for samplerExternalOES sampler type in
+ ShaderEffect
+ - [QTBUG-60268] Added Qt.platform.pluginName property.
+ - [QTBUG-60268] Selecting software as default renderer moved from build
+ time to run time
+ - Resizing is done by setSize() in a couple of places, such that
+ the widthChanged() and heightChanged() are emitted after both
+ properties are updated.
+
+ - Flickable:
+ * [QTBUG-38515] Added a boundsMovement property that allows disabling
+ the default bounce effect and implementing custom edge effects.
+
+ - Item Views:
+ * [QTBUG-34576] ListView velocities remain correct during index-based
+ programmatic scrolling
+
+ - Important Behavior Change:
+ * [QTCREATORBUG-15000] The implicitWidthChanged2 and
+ implicitHeightChanged2 signals of QQuickImplicitSizeItem have been
+ removed. Although these were undocumented and hence private API, any
+ applications currently using them should use the public
+ implicitWidthChanged and implicitHeightChanged signals.
+
+ - Item:
+ * Add QQuickItem::size() and document QQuickItem::setSize().
+ * When subclassing QQuickItem, you should call setAcceptTouchEvents(true)
+ if you need the item to receive touch events. It will be required later on.
+ * Added a ItemEnabledHasChanged value to the ItemChange enum.
+ QQuickItem::itemChange(ItemEnabledHasChanged) gets called when the
+ item's effective enabled state has changed. The new enabled state is
+ stored in ItemChangeData::boolValue.
+
+ - Window:
+ * It is now possible to set the default render type of text-like
+ elements globally via the QQuickWindow::setTextRenderType() function.
+ If you were using the (undocumented) QT_QUICK_DEFAULT_TEXT_RENDER_TYPE
+ macro when building Qt Quick for the same purpose, note that the macro
+ value needs now to be set to the "NativeTextRendering" value, instead
+ of "NativeRendering".
+
+ - Screen:
+ * Added manufacturer, model and serial number.
+
+ - TextEdit:
+ * Added tabStopDistance property
+
+ - Text:
+ * [QTBUG-56728] Added "advance" property to Text element.
+ * [QTBUG-56728] Added "font.preferShaping" property to Text, TextEdit
+ and TextInput. This makes it possible to improve performance at the
+ expense of some cosmetic font features.
+ * [QTBUG-56728] Added "kerning" property to the font type to support
+ disabling kerning on text.
+ * [QTBUG-61984] Fixed an issue when the family of an application font
+ was hardcoded and applied to text before the font itself was loaded.
+
+ - Image:
+ * [QTBUG-59872][QTBUG-29451] Allow direct loading of pkm texture files
+ into Image. For example: Image { source: "myImage.pkm" }
+
+ - QtTest:
+ * [QTBUG-53381] Added keySequence() function in TestCase.
+
+QtQml
+-----
+
+ - [QTBUG-58493] "const" variable declarations are now available in JS as
+ well as QML mode.
+ - [QTBUG-58493] "const" variable declarations now require an initializer,
+ bringing them closer to the required spec behavior.
+ - [QTBUG-58493] "const" variable declarations now throw a SyntaxError if
+ multiple attempts to declare the same variable name are found. Note that
+ "const" is still not fully spec-compliant (i.e. reassignment at runtime
+ is not disallowed).
+ - Object.assign from the ES6 specification is now implemented.
+ - Number now contains the MAX_SAFE_INTEGER, MIN_SAFE_INTEGER, isInteger
+ and isSafeInteger properties from the ES6 specification.
+ - [QTBUG-24799] The instanceof keyword in JavaScript has been extended to
+ work on QML types and instances. This means that you are now able to use
+ it to verify that a var is indeed the type you expect (e.g. someVar
+ instanceof Rectangle).
+ - [QTBUG-54961] Support C++11 scoped enums in QML. These can now be
+ accessed as <TypeName>.<EnumName>.<EnumValue>
+ - The QML engine can now emit informational messages (in the
+ "qt.qml.binding.removal" logging category) whenever a binding is lost
+ due to an imperative assignment. This can be used to debug issues due to
+ broken bindings.
+ - [QTBUG-61599] Allow sending binary data, encoded as ArrayBuffer objects,
+ via XMLHttpRequest's send() method.
+ - [QTBUG-14861] Enums can now be declared directly in QML.
+ - [QTBUG-63464] Fix Number.isNaN() returning incorrect values with some
+ glibc versions.
+ - [QTBUG-52515] Qt.platform.os returns "qnx" when running on QNX
+ platforms.
+ - [QTBUG-60133] std::vector and QVector are now on par with QList as a
+ Q_INVOKABLE return type and as a property type
+
+ - QQmlEngine:
+ * [QTBUG-15602] Added retranslate() slot and QEvent::LanguageChange
+ support to refresh bindings when changing the language at runtime.
+
+qmlscene
+--------
+ - Added --core-profile option to request that type of OpenGL context
+ - Added --apptype option to set the application class (like the qml
+ runtime tool already had)
diff --git a/dist/changes-5.10.1 b/dist/changes-5.10.1
new file mode 100644
index 0000000000..cbd9869476
--- /dev/null
+++ b/dist/changes-5.10.1
@@ -0,0 +1,109 @@
+Qt 5.10.1 is a bug-fix release. It maintains both forward and backward
+compatibility (source and binary) with Qt 5.10.0.
+
+For more details, refer to the online documentation included in this
+distribution. The documentation is also available online:
+
+http://doc.qt.io/qt-5/index.html
+
+The Qt version 5.10 series is binary compatible with the 5.9.x series.
+Applications compiled for 5.9 will continue to run with 5.10.
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+https://bugreports.qt.io/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+This release contains all fixes included in the Qt 5.9.4 release.
+
+****************************************************************************
+* Important Behavior Changes *
+****************************************************************************
+
+* A type that can be used for object declaration in QML must start with an
+ uppercase letter (this has always been the convention). Registration of
+ type names beginning with lowercase characters is now explicitly disallowed.
+
+****************************************************************************
+* Qt 5.10.1 Changes *
+****************************************************************************
+
+QtQml
+-----
+
+ - [QTBUG-65924] Fixed namespaced builds with -no-qml-debug
+ - [QTBUG-65624] Fixed a crash with simple qsTr() bindings on var properties
+ - [QTBUG-36773] A qmldir file can be provided via a custom schema
+ - [QTBUG-64798] Property alias syntax error no longer causes a crash
+ - [QTBUG-44153] Fixed a crash when a property alias points to a deleted object
+ - [QTBUG-47321][QTBUG-51995][QTBUG-60344] We now avoid temporarily invalid
+ bindings (such as "Cannot read property of null") while unloading a Loader
+ - [QTBUG-66067] Fixed a bug with negative-valued enum values in singletons
+
+ - QML profiler:
+ * [QTBUG-64674] Re-enabled QML memory profiling
+ * [QTBUG-65190] QML profiler tracks signals globally to prevent duplication
+
+ - Platform Specific Changes:
+ * Fixed compilation on QNX 7.0
+ * Enabled x86-64 JIT for QNX
+ * Enabled ARM64 JIT for QNX
+
+QtQuick
+-------
+
+ - [QTBUG-50992] Fixed bugs related to deferred property bindings to avoid
+ item view delegate objects being destroyed during incubation or failing
+ to be created. This fixes a lot of related bugs in QtQuick Controls 2.
+ - [QTBUG-64548][QTBUG-62990][QTBUG-64367] Shortcut works in QQuickWidget
+ and QQuickRenderControl scenes
+ - [QTBUG-65789] An Image with an SVG source uses the SVG renderer to do
+ animorphic scaling sharply
+ - [QTBUG-64616] Fixed a bug with TextInput validators allowing invalid characters
+ - [QTBUG-52944] When a Loader loads a Window, its transient parent will now
+ be set to the Loader's window (i.e. the window manager should place it on top).
+ - Improved support for compressed textures
+
+ - Software rendering:
+ * [QTBUG-62867] Fixed bad clipping caused by incorrect background coordinates
+
+ - Item Views:
+ * [QTBUG-49218] Fixed an off-by-one layout error in GridView
+ * [QTBUG-64311] Fixed the removal transition animation when the last item
+ of a GridView or ListView is removed
+
+ - Shapes:
+ * [QTBUG-64951] Some rendering performance improvements; added
+ qt.shape.time.sync logging category
+ * [QTBUG-65173] Shapes work correctly in static builds
+ * [QTBUG-63105] Invisible Shapes can be used with OpacityMask and other
+ Qt Graphical Effects
+
+ - Pointer Handlers:
+ * [QTBUG-64692] Pointer Handlers receive events in the reverse of
+ declaration order, just as Items receive events in top-down Z order
+ * [QTBUG-65003] TapHandler consistently emits the canceled signal when
+ its passive or exclusive grab is taken over by another handler or item
+ * [QTBUG-64848] One pinch gesture cannot pinch two PinchHandlers at the
+ same time; to that end, we now test the target item's bounds correctly
+ when delivering native gesture events from trackpads
+ * A Pointer Handler with only a passive grab cannot prevent delivery to
+ other handlers by accepting all the points in the pointer event.
+ This enables Handlers to cooperatively modify behavior of existing controls.
+ * TapHandler.gesturePolicy is now DragThreshold by default (rather than
+ ReleaseWithinBounds), because this makes it easier for a TapHandler to
+ add additional onTapped behavior to existing controls. The reason is
+ that the DragThreshold policy only requires a passive grab, not an exclusive
+ grab, so it doesn't interfere with the pre-existing event delivery.
+ * Fixed a bug with target item translation in DragHandler
+ * Added plugins.qmltyles so that syntax highlighting and completion work
+ in Qt Creator
+ * Various improvements in the tests/manual/pointer manual tests
+
+ - Platform Specific Changes:
+ * [QTBUG-61882][QTBUG-65519] Fixed rendering of emoji on macOS
+ * [QTBUG-65663] Fixed re-rendering of window when dragged to a screen
+ with a different devicePixelRatio on macOS
diff --git a/examples/quick/customitems/painteditem/textballoon.cpp b/examples/quick/customitems/painteditem/textballoon.cpp
index 1713cc762f..bd8248e65e 100644
--- a/examples/quick/customitems/painteditem/textballoon.cpp
+++ b/examples/quick/customitems/painteditem/textballoon.cpp
@@ -67,23 +67,24 @@ void TextBalloon::paint(QPainter *painter)
painter->setPen(Qt::NoPen);
painter->setRenderHint(QPainter::Antialiasing);
- painter->drawRoundedRect(0, 0, boundingRect().width(), boundingRect().height() - 10, 10, 10);
+ QSizeF itemSize = size();
+ painter->drawRoundedRect(0, 0, itemSize.width(), itemSize.height() - 10, 10, 10);
if (rightAligned)
{
const QPointF points[3] = {
- QPointF(boundingRect().width() - 10.0, boundingRect().height() - 10.0),
- QPointF(boundingRect().width() - 20.0, boundingRect().height()),
- QPointF(boundingRect().width() - 30.0, boundingRect().height() - 10.0),
+ QPointF(itemSize.width() - 10.0, itemSize.height() - 10.0),
+ QPointF(itemSize.width() - 20.0, itemSize.height()),
+ QPointF(itemSize.width() - 30.0, itemSize.height() - 10.0),
};
painter->drawConvexPolygon(points, 3);
}
else
{
const QPointF points[3] = {
- QPointF(10.0, boundingRect().height() - 10.0),
- QPointF(20.0, boundingRect().height()),
- QPointF(30.0, boundingRect().height() - 10.0),
+ QPointF(10.0, itemSize.height() - 10.0),
+ QPointF(20.0, itemSize.height()),
+ QPointF(30.0, itemSize.height() - 10.0),
};
painter->drawConvexPolygon(points, 3);
}
diff --git a/examples/quick/demos/stocqt/content/StockChart.qml b/examples/quick/demos/stocqt/content/StockChart.qml
index e32e699c50..0af06a8d54 100644
--- a/examples/quick/demos/stocqt/content/StockChart.qml
+++ b/examples/quick/demos/stocqt/content/StockChart.qml
@@ -64,40 +64,30 @@ Rectangle {
property real gridStep: gridSize ? (canvas.width - canvas.tickMargin) / gridSize : canvas.xGridStep
function update() {
- endDate = new Date();
- if (chart.activeChart === "year") {
- chart.startDate = new Date(chart.endDate.getFullYear() - 1,
- chart.endDate.getMonth(),
- chart.endDate.getDate());
- chart.gridSize = 12;
- }
- else if (chart.activeChart === "month") {
- chart.startDate = new Date(chart.endDate.getFullYear(),
- chart.endDate.getMonth() - 1,
- chart.endDate.getDate());
+ endDate = new Date(stockModel.newest);
+ if (chart.activeChart === "month") {
+ chart.startDate = new Date(stockModel.newest.getFullYear(),
+ stockModel.newest.getMonth() - 1,
+ stockModel.newest.getDate());
gridSize = 4;
}
- else if (chart.activeChart === "week") {
- chart.startDate = new Date(chart.endDate.getFullYear(),
- chart.endDate.getMonth(),
- chart.endDate.getDate() - 7);
- gridSize = 0;
+ else if (chart.activeChart === "quarter") {
+ chart.startDate = new Date(stockModel.newest.getFullYear(),
+ stockModel.newest.getMonth() - 3,
+ stockModel.newest.getDate());
+ gridSize = 3;
}
else if (chart.activeChart === "halfyear") {
- chart.startDate = new Date(chart.endDate.getFullYear(),
- chart.endDate.getMonth() - 6,
- chart.endDate.getDate());
+ chart.startDate = new Date(stockModel.newest.getFullYear(),
+ stockModel.newest.getMonth() - 6,
+ stockModel.newest.getDate());
gridSize = 6;
}
- else if (chart.activeChart === "quarter") {
- chart.startDate = new Date(chart.endDate.getFullYear(),
- chart.endDate.getMonth() - 3,
- chart.endDate.getDate());
- gridSize = 3;
- }
else {
- chart.startDate = new Date(2005, 3, 25);
- gridSize = 4;
+ chart.startDate = new Date(stockModel.newest.getFullYear(),
+ stockModel.newest.getMonth(),
+ stockModel.newest.getDate() - 7);
+ gridSize = 0;
}
canvas.requestPaint();
@@ -130,7 +120,7 @@ Rectangle {
Button {
id: quarterlyButton
- text: "3M"
+ text: "3 Months"
buttonEnabled: chart.activeChart === "quarter"
onClicked: {
chart.activeChart = "quarter";
@@ -140,31 +130,13 @@ Rectangle {
Button {
id: halfYearlyButton
- text: "6M"
+ text: "6 Months"
buttonEnabled: chart.activeChart === "halfyear"
onClicked: {
chart.activeChart = "halfyear";
chart.update();
}
}
- Button {
- id: yearButton
- text: "Year"
- buttonEnabled: chart.activeChart === "year"
- onClicked: {
- chart.activeChart = "year";
- chart.update();
- }
- }
- Button {
- id: maxButton
- text: "Max"
- buttonEnabled: chart.activeChart === "max"
- onClicked: {
- chart.activeChart = "max";
- chart.update();
- }
- }
Canvas {
id: canvas
@@ -355,7 +327,6 @@ Rectangle {
onPaint: {
numPoints = stockModel.indexOf(chart.startDate);
-
if (chart.gridSize == 0)
chart.gridSize = numPoints
diff --git a/examples/quick/demos/stocqt/content/StockListModel.qml b/examples/quick/demos/stocqt/content/StockListModel.qml
index 948edc41cc..2f697f5644 100644
--- a/examples/quick/demos/stocqt/content/StockListModel.qml
+++ b/examples/quick/demos/stocqt/content/StockListModel.qml
@@ -47,7 +47,6 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-
import QtQuick 2.0
ListModel {
@@ -60,30 +59,14 @@ ListModel {
}
}
- function requestUrl(stockId) {
- var endDate = new Date(""); // today
- var startDate = new Date()
- startDate.setDate(startDate.getDate() - 5);
-
- var request = "http://ichart.finance.yahoo.com/table.csv?";
- request += "s=" + stockId;
- request += "&g=d";
- request += "&a=" + startDate.getMonth();
- request += "&b=" + startDate.getDate();
- request += "&c=" + startDate.getFullYear();
- request += "&d=" + endDate.getMonth();
- request += "&e=" + endDate.getDate();
- request += "&f=" + endDate.getFullYear();
- request += "&g=d";
- request += "&ignore=.csv";
- return request;
- }
-
function getCloseValue(index) {
- var req = requestUrl(get(index).stockId);
- if (!req)
- return;
+ var endDate = new Date(); // today
+ var startDate = new Date();
+ endDate.setDate(startDate.getDate() - 1);
+ startDate.setDate(endDate.getDate() - 7);
+
+ var req = "data/" + get(index).stockId + ".csv"
var xhr = new XMLHttpRequest;
@@ -97,12 +80,14 @@ ListModel {
if (records.length > 0 && xhr.status == 200) {
var r = records[1].split(',');
var today = parseFloat(r[4]);
+
if (!isNaN(today))
setProperty(index, "value", today.toFixed(2));
if (records.length > 2) {
r = records[2].split(',');
var yesterday = parseFloat(r[4]);
var change = today - yesterday;
+
if (change >= 0.0)
setProperty(index, "change", "+" + change.toFixed(2));
else
@@ -122,102 +107,24 @@ ListModel {
// Uncomment to test invalid entries
// ListElement {name: "The Qt Company"; stockId: "TQTC"; value: "999.0"; change: "0.0"; changePercentage: "0.0"}
- // Data from http://www.nasdaq.com/quotes/nasdaq-100-stocks.aspx
- ListElement {name: "Activision Blizzard Inc."; stockId: "ATVI"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Adobe Systems Inc."; stockId: "ADBE"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Akamai Technologies Inc."; stockId: "AKAM"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Alexion Pharmaceuticals Inc."; stockId: "ALXN"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Alphabet Inc."; stockId: "GOOG"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Alphabet Inc."; stockId: "GOOGL"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
+ // Offline data downloaded using the url, https://www.quandl.com/api/v3/datasets/WIKI/<stockId>.csv.
+ ListElement {name: "Advanced Micro Devices Inc."; stockId: "AMD"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
ListElement {name: "Amazon.com Inc."; stockId: "AMZN"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "American Airlines Group Inc."; stockId: "AAL"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Amgen Inc."; stockId: "AMGN"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Analog Devices Inc."; stockId: "ADI"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
ListElement {name: "Apple Inc."; stockId: "AAPL"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Applied Materials Inc."; stockId: "AMAT"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
ListElement {name: "Autodesk Inc."; stockId: "ADSK"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Automatic Data Processing Inc."; stockId: "ADP"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Baidu Inc."; stockId: "BIDU"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Bed Bath & Beyond Inc."; stockId: "BBBY"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Biogen Inc."; stockId: "BIIB"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "BioMarin Pharmaceutical Inc."; stockId: "BMRN"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Broadcom Limited"; stockId: "AVGO"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "CA Inc."; stockId: "CA"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Celgene Corp."; stockId: "CELG"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Cerner Corp."; stockId: "CERN"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Charter Communications Inc."; stockId: "CHTR"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Check Point Software Technologies Ltd."; stockId: "CHKP"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
ListElement {name: "Cisco Systems Inc."; stockId: "CSCO"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Citrix Systems Inc."; stockId: "CTXS"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Cognizant Technology Solutions Corp."; stockId: "CTSH"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Comcast Corp."; stockId: "CMCSA"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Costco Wholesale Corp."; stockId: "COST"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Ctrip.com International Ltd."; stockId: "CTRP"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Discovery Communications Inc."; stockId: "DISCA"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Discovery Communications Inc."; stockId: "DISCK"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "DISH Network Corp."; stockId: "DISH"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Dollar Tree Inc."; stockId: "DLTR"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
ListElement {name: "eBay Inc."; stockId: "EBAY"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
ListElement {name: "Electronic Arts Inc."; stockId: "EA"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Endo International Plc"; stockId: "ENDP"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
ListElement {name: "Intel Corp."; stockId: "INTC"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Intuit Inc."; stockId: "INTU"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Intuitive Surgical Inc."; stockId: "ISRG"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "JD.com Inc."; stockId: "JD"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "KLA-Tencor Corp."; stockId: "KLAC"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Lam Research Corp."; stockId: "LRCX"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Liberty Global Plc"; stockId: "LBTYA"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Liberty Global Plc"; stockId: "LBTYK"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Liberty Interactive Corp."; stockId: "LVNTA"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Liberty Interactive Corp."; stockId: "QVCA"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Liberty Media Corp."; stockId: "LMCA"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Liberty Media Corp."; stockId: "LMCK"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Linear Technology Corp."; stockId: "LLTC"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Marriott International"; stockId: "MAR"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Mattel Inc."; stockId: "MAT"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Maxim Integrated Products Inc."; stockId: "MXIM"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Micron Technology Inc."; stockId: "MU"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
ListElement {name: "Microsoft Corp."; stockId: "MSFT"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Mondelez International Inc."; stockId: "MDLZ"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Monster Beverage Corp."; stockId: "MNST"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Mylan N.V."; stockId: "MYL"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
ListElement {name: "NetApp Inc."; stockId: "NTAP"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
ListElement {name: "Netflix Inc."; stockId: "NFLX"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
ListElement {name: "Norwegian Cruise Line Holdings Ltd."; stockId: "NCLH"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
ListElement {name: "NVIDIA Corp."; stockId: "NVDA"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "NXP Semiconductors N.V."; stockId: "NXPI"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "O'Reilly Automotive Inc."; stockId: "ORLY"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "PACCAR Inc."; stockId: "PCAR"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Paychex Inc."; stockId: "PAYX"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
ListElement {name: "PayPal Holdings Inc."; stockId: "PYPL"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
ListElement {name: "QUALCOMM Inc."; stockId: "QCOM"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Regeneron Pharmaceuticals Inc."; stockId: "REGN"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Ross Stores Inc."; stockId: "ROST"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "SanDisk Corp."; stockId: "SNDK"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "SBA Communications Corp."; stockId: "SBAC"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Seagate Technology PLC"; stockId: "STX"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Sirius XM Holdings Inc."; stockId: "SIRI"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Skyworks Solutions Inc."; stockId: "SWKS"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Starbucks Corp."; stockId: "SBUX"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Stericycle Inc."; stockId: "SRCL"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Symantec Corp."; stockId: "SYMC"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "T-Mobile US Inc."; stockId: "TMUS"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
ListElement {name: "Tesla Motors Inc."; stockId: "TSLA"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
ListElement {name: "Texas Instruments Inc."; stockId: "TXN"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "The Kraft Heinz Company"; stockId: "KHC"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "The Priceline Group Inc."; stockId: "PCLN"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Tractor Supply Company"; stockId: "TSCO"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "TripAdvisor Inc."; stockId: "TRIP"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Twenty-First Century Fox Inc."; stockId: "FOX"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Twenty-First Century Fox Inc."; stockId: "FOXA"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Ulta Salon Cosmetics & Fragrance Inc."; stockId: "ULTA"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Verisk Analytics Inc."; stockId: "VRSK"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Vertex Pharmaceuticals Inc."; stockId: "VRTX"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Viacom Inc."; stockId: "VIAB"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Vodafone Group Plc"; stockId: "VOD"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Walgreens Boots Alliance Inc."; stockId: "WBA"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Western Digital Corp."; stockId: "WDC"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Whole Foods Market Inc."; stockId: "WFM"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Xilinx Inc."; stockId: "XLNX"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
- ListElement {name: "Yahoo! Inc."; stockId: "YHOO"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
+ ListElement {name: "Facebook Inc."; stockId: "FB"; value: "0.0"; change: "0.0"; changePercentage: "0.0"}
}
+
diff --git a/examples/quick/demos/stocqt/content/StockModel.qml b/examples/quick/demos/stocqt/content/StockModel.qml
index 5352992789..9e3a815c11 100644
--- a/examples/quick/demos/stocqt/content/StockModel.qml
+++ b/examples/quick/demos/stocqt/content/StockModel.qml
@@ -54,7 +54,8 @@ ListModel {
id: model
property string stockId: ""
property string stockName: ""
- property string stockDataCycle: "d"
+ property var newest
+ property var oldest
property bool ready: false
property real stockPrice: 0.0
property real stockPriceChanged: 0.0
@@ -65,10 +66,10 @@ ListModel {
if (model.count == 0)
return -1;
- var newest = new Date(model.get(0).date);
- var oldest = new Date(model.get(model.count - 1).date);
if (newest <= date)
- return -1;
+ date = new Date(newest.getYear(),
+ newest.getMonth(),
+ newest.getDate() - 7);
if (oldest >= date)
return model.count - 1;
@@ -81,46 +82,14 @@ ListModel {
currDiff = Math.abs(d.getTime() - date.getTime());
if (currDiff < bestDiff) {
bestDiff = currDiff;
- retval = i;
+ retval = i + 1;
}
if (currDiff > bestDiff)
return retval;
}
-
return -1;
}
- function requestUrl() {
- if (stockId === "")
- return;
-
- var startDate = new Date(2011, 4, 25);
-
- var endDate = new Date(); //today
-
- if (stockDataCycle !== "d" && stockDataCycle !== "w" && stockDataCycle !== "m")
- stockDataCycle = "d";
-
- /*
- Fetch stock data from yahoo finance:
- url: http://ichart.finance.yahoo.com/table.csv?s=NOK&a=5&b=11&c=2010&d=7&e=23&f=2010&g=d&ignore=.csv
- s:stock name/id, a:start day, b:start month, c:start year default: 25 April 1995, oldest c= 1962
- d:end day, e:end month, f:end year, default:today (data only available 3 days before today)
- g:data cycle(d daily, w weekly, m monthly, v Dividend)
- */
- var request = "http://ichart.finance.yahoo.com/table.csv?";
- request += "s=" + stockId;
- request += "&a=" + startDate.getMonth();
- request += "&b=" + startDate.getDate();
- request += "&c=" + startDate.getFullYear();
- request += "&d=" + endDate.getMonth();
- request += "&e=" + endDate.getDate();
- request += "&f=" + endDate.getFullYear();
- request += "&g=" + stockDataCycle;
- request += "&ignore=.csv";
- return request;
- }
-
function createStockPrice(r) {
return {
"date": r[0],
@@ -129,13 +98,17 @@ ListModel {
"low":r[3],
"close":r[4],
"volume":r[5],
- "adjusted":r[6]
};
}
function updateStock() {
- var req = requestUrl();
+ if (stockId === "")
+ return;
+ var startDate = new Date(2011, 4, 25);
+ var endDate = new Date(); //today
+
+ var req = "data/" + stockId + ".csv"
if (!req)
return;
@@ -149,18 +122,19 @@ ListModel {
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.LOADING || xhr.readyState === XMLHttpRequest.DONE) {
var records = xhr.responseText.split('\n');
-
for (;i < records.length; i++ ) {
var r = records[i].split(',');
- if (r.length === 7)
+ if (r.length >= 6)
model.append(createStockPrice(r));
}
if (xhr.readyState === XMLHttpRequest.DONE) {
if (model.count > 0) {
model.ready = true;
- model.stockPrice = model.get(0).adjusted;
+ model.stockPrice = model.get(0).close;
model.stockPriceChanged = model.count > 1 ? (Math.round((model.stockPrice - model.get(1).close) * 100) / 100) : 0;
+ newest = new Date(model.get(0).date);
+ oldest = new Date(model.get(model.count - 1).date);
} else {
model.stockPrice = 0;
model.stockPriceChanged = 0;
diff --git a/examples/quick/demos/stocqt/content/StockSettingsPanel.qml b/examples/quick/demos/stocqt/content/StockSettingsPanel.qml
index 086eb2e8b6..48a77d8495 100644
--- a/examples/quick/demos/stocqt/content/StockSettingsPanel.qml
+++ b/examples/quick/demos/stocqt/content/StockSettingsPanel.qml
@@ -56,10 +56,10 @@ Rectangle {
id: root
color: "transparent"
- property bool drawOpenPrice: openButton.buttonEnabled
- property bool drawClosePrice: closeButton.buttonEnabled
- property bool drawHighPrice: highButton.buttonEnabled
- property bool drawLowPrice: lowButton.buttonEnabled
+ property bool drawOpenPrice: false
+ property bool drawClosePrice: false
+ property bool drawHighPrice: true
+ property bool drawLowPrice: true
property string openColor: "#face20"
property string closeColor: "#14aaff"
@@ -95,6 +95,7 @@ Rectangle {
CheckBox {
id: openButton
buttonEnabled: false
+ onButtonEnabledChanged: drawOpenPrice = buttonEnabled
Layout.rightMargin: 10
}
@@ -114,6 +115,7 @@ Rectangle {
CheckBox {
id: closeButton
buttonEnabled: false
+ onButtonEnabledChanged: drawClosePrice = buttonEnabled
Layout.rightMargin: 10
}
@@ -133,6 +135,7 @@ Rectangle {
CheckBox {
id: highButton
buttonEnabled: true
+ onButtonEnabledChanged: drawHighPrice = buttonEnabled
Layout.rightMargin: 10
}
@@ -153,6 +156,7 @@ Rectangle {
CheckBox {
id: lowButton
buttonEnabled: true
+ onButtonEnabledChanged: drawLowPrice = buttonEnabled
Layout.rightMargin: 10
}
}
diff --git a/examples/quick/demos/stocqt/content/data/AAPL.csv b/examples/quick/demos/stocqt/content/data/AAPL.csv
new file mode 100644
index 0000000000..de56baa19a
--- /dev/null
+++ b/examples/quick/demos/stocqt/content/data/AAPL.csv
@@ -0,0 +1,147 @@
+Date,Open,High,Low,Close,Volume,Ex-Dividend,Split Ratio,Adj. Open,Adj. High,Adj. Low,Adj. Close,Adj. Volume
+2017-12-29,170.52,170.59,169.22,169.23,25643711.0,0.0,1.0,170.52,170.59,169.22,169.23,25643711.0
+2017-12-28,171.0,171.85,170.48,171.08,15997739.0,0.0,1.0,171.0,171.85,170.48,171.08,15997739.0
+2017-12-27,170.1,170.78,169.71,170.6,21672062.0,0.0,1.0,170.1,170.78,169.71,170.6,21672062.0
+2017-12-26,170.8,171.47,169.679,170.57,32968167.0,0.0,1.0,170.8,171.47,169.679,170.57,32968167.0
+2017-12-22,174.68,175.424,174.5,175.01,16052615.0,0.0,1.0,174.68,175.424,174.5,175.01,16052615.0
+2017-12-21,174.17,176.02,174.1,175.01,20356826.0,0.0,1.0,174.17,176.02,174.1,175.01,20356826.0
+2017-12-20,174.87,175.42,173.25,174.35,23000392.0,0.0,1.0,174.87,175.42,173.25,174.35,23000392.0
+2017-12-19,175.03,175.39,174.09,174.54,27078872.0,0.0,1.0,175.03,175.39,174.09,174.54,27078872.0
+2017-12-18,174.88,177.2,174.86,176.42,28831533.0,0.0,1.0,174.88,177.2,174.86,176.42,28831533.0
+2017-12-15,173.63,174.17,172.46,173.87,37054632.0,0.0,1.0,173.63,174.17,172.46,173.87,37054632.0
+2017-12-14,172.4,173.13,171.65,172.22,20219307.0,0.0,1.0,172.4,173.13,171.65,172.22,20219307.0
+2017-12-13,172.5,173.54,172.0,172.27,23142242.0,0.0,1.0,172.5,173.54,172.0,172.27,23142242.0
+2017-12-12,172.15,172.39,171.461,171.7,18945457.0,0.0,1.0,172.15,172.39,171.461,171.7,18945457.0
+2017-12-11,169.2,172.89,168.79,172.67,33092051.0,0.0,1.0,169.2,172.89,168.79,172.67,33092051.0
+2017-12-08,170.49,171.0,168.82,169.37,23096872.0,0.0,1.0,170.49,171.0,168.82,169.37,23096872.0
+2017-12-07,169.03,170.44,168.91,169.452,24469613.0,0.0,1.0,169.03,170.44,168.91,169.452,24469613.0
+2017-12-06,167.5,170.2047,166.46,169.01,28224357.0,0.0,1.0,167.5,170.2047,166.46,169.01,28224357.0
+2017-12-05,169.06,171.52,168.4,169.64,27008428.0,0.0,1.0,169.06,171.52,168.4,169.64,27008428.0
+2017-12-04,172.48,172.62,169.63,169.8,32115052.0,0.0,1.0,172.48,172.62,169.63,169.8,32115052.0
+2017-12-01,169.95,171.67,168.5,171.05,39590080.0,0.0,1.0,169.95,171.67,168.5,171.05,39590080.0
+2017-11-30,170.43,172.14,168.44,171.85,40172368.0,0.0,1.0,170.43,172.14,168.44,171.85,40172368.0
+2017-11-29,172.63,172.92,167.16,169.48,40788324.0,0.0,1.0,172.63,172.92,167.16,169.48,40788324.0
+2017-11-28,174.3,174.87,171.86,173.07,25468442.0,0.0,1.0,174.3,174.87,171.86,173.07,25468442.0
+2017-11-27,175.05,175.08,173.34,174.09,20536313.0,0.0,1.0,175.05,175.08,173.34,174.09,20536313.0
+2017-11-24,175.1,175.5,174.6459,174.97,14026519.0,0.0,1.0,175.1,175.5,174.6459,174.97,14026519.0
+2017-11-22,173.36,175.0,173.05,174.96,24997274.0,0.0,1.0,173.36,175.0,173.05,174.96,24997274.0
+2017-11-21,170.78,173.7,170.78,173.14,24875471.0,0.0,1.0,170.78,173.7,170.78,173.14,24875471.0
+2017-11-20,170.29,170.56,169.56,169.98,15974387.0,0.0,1.0,170.29,170.56,169.56,169.98,15974387.0
+2017-11-17,171.04,171.39,169.64,170.15,21665811.0,0.0,1.0,171.04,171.39,169.64,170.15,21665811.0
+2017-11-16,171.18,171.87,170.3,171.1,23497326.0,0.0,1.0,171.18,171.87,170.3,171.1,23497326.0
+2017-11-15,169.97,170.3197,168.38,169.08,28702351.0,0.0,1.0,169.97,170.3197,168.38,169.08,28702351.0
+2017-11-14,173.04,173.48,171.18,171.34,23588451.0,0.0,1.0,173.04,173.48,171.18,171.34,23588451.0
+2017-11-13,173.5,174.5,173.4,173.97,16828025.0,0.0,1.0,173.5,174.5,173.4,173.97,16828025.0
+2017-11-10,175.11,175.38,174.27,174.67,25061183.0,0.0,1.0,175.11,175.38,174.27,174.67,25061183.0
+2017-11-09,175.11,176.095,173.14,175.88,28636531.0,0.0,1.0,175.11,176.095,173.14,175.88,28636531.0
+2017-11-07,173.91,175.25,173.6,174.81,23910914.0,0.0,1.0,173.91,175.25,173.6,174.81,23910914.0
+2017-11-06,172.365,174.99,171.72,174.25,34242566.0,0.0,1.0,172.365,174.99,171.72,174.25,34242566.0
+2017-11-03,174.0,174.26,171.12,172.5,58683826.0,0.0,1.0,174.0,174.26,171.12,172.5,58683826.0
+2017-11-02,167.64,168.5,165.28,168.11,32710040.0,0.0,1.0,167.64,168.5,165.28,168.11,32710040.0
+2017-11-01,169.87,169.94,165.61,166.89,33100847.0,0.0,1.0,169.87,169.94,165.61,166.89,33100847.0
+2017-10-31,167.9,169.6499,166.94,169.04,35474672.0,0.0,1.0,167.9,169.6499,166.94,169.04,35474672.0
+2017-10-30,163.89,168.07,163.72,166.72,43923292.0,0.0,1.0,163.89,168.07,163.72,166.72,43923292.0
+2017-10-27,159.29,163.6,158.7,163.05,43904150.0,0.0,1.0,159.29,163.6,158.7,163.05,43904150.0
+2017-10-26,157.23,157.8295,156.78,157.41,16751691.0,0.0,1.0,157.23,157.8295,156.78,157.41,16751691.0
+2017-10-25,156.91,157.55,155.27,156.405,20126554.0,0.0,1.0,156.91,157.55,155.27,156.405,20126554.0
+2017-10-24,156.29,157.42,156.2,157.1,17137731.0,0.0,1.0,156.29,157.42,156.2,157.1,17137731.0
+2017-10-23,156.89,157.69,155.5,156.17,21654461.0,0.0,1.0,156.89,157.69,155.5,156.17,21654461.0
+2017-10-20,156.61,157.75,155.96,156.16,23612246.0,0.0,1.0,156.61,157.75,155.96,156.16,23612246.0
+2017-10-19,156.75,157.08,155.02,155.98,42111326.0,0.0,1.0,156.75,157.08,155.02,155.98,42111326.0
+2017-10-18,160.42,160.71,159.6,159.76,16158659.0,0.0,1.0,160.42,160.71,159.6,159.76,16158659.0
+2017-10-17,159.78,160.87,159.23,160.47,18816438.0,0.0,1.0,159.78,160.87,159.23,160.47,18816438.0
+2017-10-16,157.9,160.0,157.65,159.88,23894630.0,0.0,1.0,157.9,160.0,157.65,159.88,23894630.0
+2017-10-13,156.73,157.28,156.41,156.99,16287608.0,0.0,1.0,156.73,157.28,156.41,156.99,16287608.0
+2017-10-12,156.35,157.37,155.7299,156.0,16045720.0,0.0,1.0,156.35,157.37,155.7299,156.0,16045720.0
+2017-10-11,155.97,156.98,155.75,156.55,16607693.0,0.0,1.0,155.97,156.98,155.75,156.55,16607693.0
+2017-10-10,156.055,158.0,155.1,155.9,15456331.0,0.0,1.0,156.055,158.0,155.1,155.9,15456331.0
+2017-10-09,155.81,156.73,155.485,155.84,16200129.0,0.0,1.0,155.81,156.73,155.485,155.84,16200129.0
+2017-10-06,154.97,155.49,154.56,155.3,16423749.0,0.0,1.0,154.97,155.49,154.56,155.3,16423749.0
+2017-10-05,154.18,155.44,154.05,155.39,21032800.0,0.0,1.0,154.18,155.44,154.05,155.39,21032800.0
+2017-10-04,153.63,153.86,152.46,153.4508,19844177.0,0.0,1.0,153.63,153.86,152.46,153.4508,19844177.0
+2017-10-03,154.01,155.09,153.91,154.48,16146388.0,0.0,1.0,154.01,155.09,153.91,154.48,16146388.0
+2017-10-02,154.26,154.45,152.72,153.81,18524860.0,0.0,1.0,154.26,154.45,152.72,153.81,18524860.0
+2017-09-29,153.21,154.13,152.0,154.12,25856530.0,0.0,1.0,153.21,154.13,152.0,154.12,25856530.0
+2017-09-28,153.89,154.28,152.7,153.28,21896592.0,0.0,1.0,153.89,154.28,152.7,153.28,21896592.0
+2017-09-27,153.8,154.7189,153.54,154.23,24959552.0,0.0,1.0,153.8,154.7189,153.54,154.23,24959552.0
+2017-09-26,151.78,153.92,151.69,153.14,35470985.0,0.0,1.0,151.78,153.92,151.69,153.14,35470985.0
+2017-09-25,149.99,151.83,149.16,150.55,43922334.0,0.0,1.0,149.99,151.83,149.16,150.55,43922334.0
+2017-09-22,152.02,152.27,150.56,151.89,46114424.0,0.0,1.0,152.02,152.27,150.56,151.89,46114424.0
+2017-09-21,155.8,155.8,152.75,153.39,36643382.0,0.0,1.0,155.8,155.8,152.75,153.39,36643382.0
+2017-09-20,157.9,158.26,153.83,156.07,51693239.0,0.0,1.0,157.9,158.26,153.83,156.07,51693239.0
+2017-09-19,159.51,159.77,158.44,158.73,20347352.0,0.0,1.0,159.51,159.77,158.44,158.73,20347352.0
+2017-09-18,160.11,160.5,157.995,158.67,27939718.0,0.0,1.0,160.11,160.5,157.995,158.67,27939718.0
+2017-09-15,158.47,160.97,158.0,159.88,48203642.0,0.0,1.0,158.47,160.97,158.0,159.88,48203642.0
+2017-09-14,158.99,159.4,158.09,158.28,23073646.0,0.0,1.0,158.99,159.4,158.09,158.28,23073646.0
+2017-09-13,159.87,159.96,157.91,159.65,44393752.0,0.0,1.0,159.87,159.96,157.91,159.65,44393752.0
+2017-09-12,162.61,163.96,158.77,160.82,71139119.0,0.0,1.0,162.61,163.96,158.77,160.82,71139119.0
+2017-09-11,160.5,162.05,159.89,161.5,31028926.0,0.0,1.0,160.5,162.05,159.89,161.5,31028926.0
+2017-09-08,160.86,161.15,158.53,158.63,28183159.0,0.0,1.0,160.86,161.15,158.53,158.63,28183159.0
+2017-09-07,162.09,162.24,160.36,161.26,21722995.0,0.0,1.0,162.09,162.24,160.36,161.26,21722995.0
+2017-09-06,162.71,162.99,160.52,161.91,21179047.0,0.0,1.0,162.71,162.99,160.52,161.91,21179047.0
+2017-09-05,163.75,164.25,160.56,162.08,29317054.0,0.0,1.0,163.75,164.25,160.56,162.08,29317054.0
+2017-09-01,164.8,164.94,163.63,164.05,16508568.0,0.0,1.0,164.8,164.94,163.63,164.05,16508568.0
+2017-08-31,163.64,164.52,163.48,164.0,26412439.0,0.0,1.0,163.64,164.52,163.48,164.0,26412439.0
+2017-08-30,163.8,163.89,162.61,163.35,26973946.0,0.0,1.0,163.8,163.89,162.61,163.35,26973946.0
+2017-08-29,160.1,163.12,160.0,162.91,29307862.0,0.0,1.0,160.1,163.12,160.0,162.91,29307862.0
+2017-08-28,160.14,162.0,159.93,161.47,25279674.0,0.0,1.0,160.14,162.0,159.93,161.47,25279674.0
+2017-08-25,159.65,160.56,159.27,159.86,25015218.0,0.0,1.0,159.65,160.56,159.27,159.86,25015218.0
+2017-08-24,160.43,160.74,158.55,159.27,19029621.0,0.0,1.0,160.43,160.74,158.55,159.27,19029621.0
+2017-08-23,159.07,160.47,158.88,159.98,19198189.0,0.0,1.0,159.07,160.47,158.88,159.98,19198189.0
+2017-08-22,158.23,160.0,158.02,159.78,21297812.0,0.0,1.0,158.23,160.0,158.02,159.78,21297812.0
+2017-08-21,157.5,157.89,155.1101,157.21,26145653.0,0.0,1.0,157.5,157.89,155.1101,157.21,26145653.0
+2017-08-18,157.86,159.5,156.72,157.5,27012525.0,0.0,1.0,157.86,159.5,156.72,157.5,27012525.0
+2017-08-17,160.52,160.71,157.84,157.87,26925694.0,0.0,1.0,160.52,160.71,157.84,157.87,26925694.0
+2017-08-16,161.94,162.51,160.15,160.95,27321761.0,0.0,1.0,161.94,162.51,160.15,160.95,27321761.0
+2017-08-15,160.66,162.195,160.14,161.6,27936774.0,0.0,1.0,160.66,162.195,160.14,161.6,27936774.0
+2017-08-14,159.32,160.21,158.75,159.85,21754810.0,0.0,1.0,159.32,160.21,158.75,159.85,21754810.0
+2017-08-11,156.6,158.5728,156.07,157.48,25943187.0,0.0,1.0,156.6,158.5728,156.07,157.48,25943187.0
+2017-08-10,159.9,160.0,154.63,155.27,39081017.0,0.63,1.0,159.9,160.0,154.63,155.27,39081017.0
+2017-08-09,159.26,161.27,159.11,161.06,25640394.0,0.0,1.0,158.61642206543,160.61829955099,158.46702822322,160.40914817191,25640394.0
+2017-08-08,158.6,161.83,158.27,160.08,35775675.0,0.0,1.0,157.95908915972,161.1760365619,157.63042270686,159.43310840282,35775675.0
+2017-08-04,156.07,157.4,155.69,156.39,20349532.0,0.0,1.0,155.43931302117,156.76393842207,155.06084862091,155.75801988454,20349532.0
+2017-08-03,157.05,157.21,155.02,155.57,26000738.0,0.0,1.0,156.41535279025,156.57470622194,154.39355612572,154.94133354715,26000738.0
+2017-08-02,159.28,159.75,156.16,157.14,69222793.0,0.0,1.0,158.63634124439,159.10444194997,155.52894932649,156.50498909557,69222793.0
+2017-08-01,149.1,150.22,148.41,150.05,24725526.0,0.0,1.0,148.4974791533,149.61295317511,147.81026747915,149.44364015394,24725526.0
+2017-07-31,149.9,150.33,148.13,148.85,19422655.0,0.0,1.0,149.29424631174,149.7225086594,147.5313989737,148.24848941629,19422655.0
+2017-07-28,149.89,150.23,149.19,149.5,16832947.0,0.0,1.0,149.28428672226,149.62291276459,148.58711545863,148.89586273252,16832947.0
+2017-07-27,153.75,153.99,147.3,150.56,32175875.0,0.0,1.0,153.12868826171,153.36771840924,146.70475304682,149.95157921745,32175875.0
+2017-07-26,153.35,153.93,153.06,153.46,15172136.0,0.0,1.0,152.73030468249,153.30796087235,152.44147658756,152.83986016677,15172136.0
+2017-07-25,151.8,153.84,151.8,152.74,18612649.0,0.0,1.0,151.18656831302,153.21832456703,151.18656831302,152.12276972418,18612649.0
+2017-07-24,150.58,152.44,149.9,152.09,21122730.0,0.0,1.0,149.97149839641,151.82398203977,149.29424631174,151.47539640795,21122730.0
+2017-07-21,149.99,150.44,148.88,150.27,24671002.0,0.0,1.0,149.38388261706,149.83206414368,148.27836818473,149.66275112251,24671002.0
+2017-07-20,151.5,151.74,150.19,150.34,17053326.0,0.0,1.0,150.88778062861,151.12681077614,149.58307440667,149.73246824888,17053326.0
+2017-07-19,150.48,151.42,149.95,151.02,20615419.0,0.0,1.0,149.8719025016,150.80810391276,149.34404425914,150.40972033355,20615419.0
+2017-07-18,149.2,150.13,148.67,150.08,17713795.0,0.0,1.0,148.59707504811,149.52331686979,148.06921680564,149.47351892239,17713795.0
+2017-07-17,148.82,150.9,148.57,149.56,23243713.0,0.0,1.0,148.21861064785,150.29020525978,147.96962091084,148.9556202694,23243713.0
+2017-07-14,147.97,149.33,147.33,149.04,19961788.0,0.0,1.0,147.37204554201,148.72654971135,146.73463181527,148.43772161642,19961788.0
+2017-07-13,145.5,148.49,145.44,147.77,24922788.0,0.0,1.0,144.91202694035,147.889944195,144.85226940346,147.17285375241,24922788.0
+2017-07-12,145.87,146.18,144.82,145.74,23617964.0,0.0,1.0,145.28053175112,145.58927902502,144.23477485568,145.15105708788,23617964.0
+2017-07-11,144.73,145.85,144.38,145.53,18311156.0,0.0,1.0,144.14513855035,145.26061257216,143.79655291854,144.94190570879,18311156.0
+2017-07-10,144.11,145.95,143.37,145.06,21030466.0,0.0,1.0,143.52764400257,145.36020846697,142.79063438101,144.47380500321,21030466.0
+2017-07-07,142.9,144.75,142.9,144.18,18505351.0,0.0,1.0,142.32253367543,144.16505772931,142.32253367543,143.59736112893,18505351.0
+2017-07-06,143.02,143.5,142.41,142.73,23374374.0,0.0,1.0,142.4420487492,142.92010904426,141.83451379089,142.15322065427,23374374.0
+2017-07-05,143.69,144.79,142.7237,144.09,20758795.0,0.0,1.0,143.10934124439,144.20489608724,142.14694611289,143.5077248236,20758795.0
+2017-07-03,144.88,145.3001,143.1,143.5,14276812.0,0.0,1.0,144.29453239256,144.71293474663,142.52172546504,142.92010904426,14276812.0
+2017-06-30,144.45,144.96,143.78,144.02,22328979.0,0.0,1.0,143.8662700449,144.3742091084,143.19897754971,143.43800769724,22328979.0
+2017-06-29,144.71,145.13,142.28,143.68,31116980.0,0.0,1.0,144.12521937139,144.54352212957,141.70503912765,143.09938165491,31116980.0
+2017-06-28,144.49,146.11,143.1601,145.83,21915939.0,0.0,1.0,143.90610840282,145.51956189865,142.58158259782,145.2406933932,21915939.0
+2017-06-27,145.01,146.16,143.62,143.74,24423643.0,0.0,1.0,144.4240070558,145.56935984606,143.03962411802,143.15913919179,24423643.0
+2017-06-26,147.17,148.28,145.38,145.82,25524661.0,0.0,1.0,146.57527838358,147.68079281591,144.79251186658,145.23073380372,25524661.0
+2017-06-23,145.13,147.16,145.11,146.35,25997976.0,0.0,1.0,144.54352212957,146.5653187941,144.52360295061,145.75859204618,25997976.0
+2017-06-22,145.77,146.7,145.1199,145.63,18673365.0,0.0,1.0,145.18093585632,146.107177678,144.5334629442,145.04150160359,18673365.0
+2017-06-21,145.52,146.0693,144.61,145.87,21064679.0,0.0,1.0,144.93194611931,145.47902636947,144.02562347659,145.28053175112,21064679.0
+2017-06-20,146.87,146.87,144.94,145.01,24572170.0,0.0,1.0,146.27649069917,146.27649069917,144.35428992944,144.4240070558,24572170.0
+2017-06-19,143.66,146.74,143.66,146.34,31449132.0,0.0,1.0,143.07946247595,146.14701603592,143.07946247595,145.7486324567,31449132.0
+2017-06-16,143.78,144.5,142.2,142.27,49180748.0,0.0,1.0,143.19897754971,143.9160679923,141.6253624118,141.69507953817,49180748.0
+2017-06-15,143.32,144.4798,142.21,144.29,31348832.0,0.0,1.0,142.74083643361,143.89594962155,141.63532200128,143.70691661321,31348832.0
+2017-06-14,147.5,147.5,143.84,145.16,31224203.0,0.0,1.0,146.90394483643,146.90394483643,143.25873508659,144.57340089801,31224203.0
+2017-06-13,147.16,147.45,145.15,146.59,33749154.0,0.0,1.0,146.5653187941,146.85414688903,144.56344130853,145.99762219371,33749154.0
+2017-06-12,145.74,146.09,142.51,145.32,71563614.0,0.0,1.0,145.15105708788,145.49964271969,141.9341096857,144.7327543297,71563614.0
+2017-06-09,155.19,155.19,146.02,148.98,64176149.0,0.0,1.0,154.56286914689,154.56286914689,145.42992559333,148.37796407954,64176149.0
+2017-06-08,155.25,155.54,154.4,154.99,20771367.0,0.0,1.0,154.62262668377,154.9114547787,153.77606157793,154.36367735728,20771367.0
+2017-06-07,155.02,155.98,154.48,155.37,20678772.0,0.0,1.0,154.39355612572,155.34967671584,153.85573829378,154.74214175754,20678772.0
+2017-06-06,153.9,155.81,153.78,154.45,26249630.0,0.0,1.0,153.27808210391,155.18036369468,153.15856703015,153.82585952534,26249630.0
+2017-06-05,154.34,154.45,153.46,153.93,24803858.0,0.0,1.0,153.71630404105,153.82585952534,152.83986016677,153.30796087235,24803858.0
+2017-06-02,153.58,155.45,152.89,155.45,27285861.0,0.0,1.0,152.95937524054,154.82181847338,152.27216356639,154.82181847338,27285861.0
+2017-06-01,153.17,153.33,152.22,153.18,16180143.0,0.0,1.0,152.55103207184,152.71038550353,151.6048710712,152.56099166132,16180143.0
diff --git a/examples/quick/demos/stocqt/content/data/ADSK.csv b/examples/quick/demos/stocqt/content/data/ADSK.csv
new file mode 100644
index 0000000000..704fa3f32a
--- /dev/null
+++ b/examples/quick/demos/stocqt/content/data/ADSK.csv
@@ -0,0 +1,148 @@
+Date,Open,High,Low,Close,Volume,Ex-Dividend,Split Ratio,Adj. Open,Adj. High,Adj. Low,Adj. Close,Adj. Volume
+2017-12-29,105.04,105.65,104.5301,104.83,1042328.0,0.0,1.0,105.04,105.65,104.5301,104.83,1042328.0
+2017-12-28,104.66,105.22,104.2,105.07,860725.0,0.0,1.0,104.66,105.22,104.2,105.07,860725.0
+2017-12-27,103.97,105.199,103.48,104.58,959904.0,0.0,1.0,103.97,105.199,103.48,104.58,959904.0
+2017-12-26,103.45,104.15,103.19,103.8,1307823.0,0.0,1.0,103.45,104.15,103.19,103.8,1307823.0
+2017-12-22,104.85,104.85,103.78,103.89,1411598.0,0.0,1.0,104.85,104.85,103.78,103.89,1411598.0
+2017-12-21,105.58,105.6699,103.65,104.43,3901415.0,0.0,1.0,105.58,105.6699,103.65,104.43,3901415.0
+2017-12-20,106.02,106.02,104.19,105.03,2502489.0,0.0,1.0,106.02,106.02,104.19,105.03,2502489.0
+2017-12-19,107.24,107.84,105.37,105.39,1807167.0,0.0,1.0,107.24,107.84,105.37,105.39,1807167.0
+2017-12-18,108.66,109.43,107.28,107.48,2305840.0,0.0,1.0,108.66,109.43,107.28,107.48,2305840.0
+2017-12-15,106.55,108.93,106.47,108.4,2434779.0,0.0,1.0,106.55,108.93,106.47,108.4,2434779.0
+2017-12-14,105.95,107.12,105.95,106.25,1479116.0,0.0,1.0,105.95,107.12,105.95,106.25,1479116.0
+2017-12-13,107.03,107.89,105.51,106.02,1924569.0,0.0,1.0,107.03,107.89,105.51,106.02,1924569.0
+2017-12-12,106.32,107.98,105.58,106.33,1987461.0,0.0,1.0,106.32,107.98,105.58,106.33,1987461.0
+2017-12-11,106.87,107.95,106.15,106.83,2270028.0,0.0,1.0,106.87,107.95,106.15,106.83,2270028.0
+2017-12-08,109.6,110.17,106.69,107.16,3094512.0,0.0,1.0,109.6,110.17,106.69,107.16,3094512.0
+2017-12-07,106.2,110.18,106.0,109.61,3028608.0,0.0,1.0,106.2,110.18,106.0,109.61,3028608.0
+2017-12-06,105.73,107.83,105.73,106.92,1678616.0,0.0,1.0,105.73,107.83,105.73,106.92,1678616.0
+2017-12-05,107.91,109.49,106.55,106.59,2983741.0,0.0,1.0,107.91,109.49,106.55,106.59,2983741.0
+2017-12-04,108.0,108.69,105.16,107.95,3940444.0,0.0,1.0,108.0,108.69,105.16,107.95,3940444.0
+2017-12-01,108.81,110.12,106.29,107.06,4905374.0,0.0,1.0,108.81,110.12,106.29,107.06,4905374.0
+2017-11-30,109.64,111.579,106.54,109.7,8408815.0,0.0,1.0,109.64,111.579,106.54,109.7,8408815.0
+2017-11-29,114.03,114.46,106.2,109.34,19333560.0,0.0,1.0,114.03,114.46,106.2,109.34,19333560.0
+2017-11-28,130.76,131.1,127.49,129.95,3683510.0,0.0,1.0,130.76,131.1,127.49,129.95,3683510.0
+2017-11-27,130.19,130.92,129.26,130.24,2248835.0,0.0,1.0,130.19,130.92,129.26,130.24,2248835.0
+2017-11-24,127.74,129.54,127.65,129.5,1013550.0,0.0,1.0,127.74,129.54,127.65,129.5,1013550.0
+2017-11-22,128.01,128.685,126.835,127.77,1467080.0,0.0,1.0,128.01,128.685,126.835,127.77,1467080.0
+2017-11-21,127.13,128.17,126.97,127.71,1567056.0,0.0,1.0,127.13,128.17,126.97,127.71,1567056.0
+2017-11-20,127.51,128.28,126.11,126.28,1711322.0,0.0,1.0,127.51,128.28,126.11,126.28,1711322.0
+2017-11-17,127.49,127.92,125.87,127.49,1458953.0,0.0,1.0,127.49,127.92,125.87,127.49,1458953.0
+2017-11-16,124.79,127.0,124.64,127.0,1525137.0,0.0,1.0,124.79,127.0,124.64,127.0,1525137.0
+2017-11-15,123.87,125.01,122.44,124.02,1439532.0,0.0,1.0,123.87,125.01,122.44,124.02,1439532.0
+2017-11-14,124.4,124.82,123.16,123.87,1221703.0,0.0,1.0,124.4,124.82,123.16,123.87,1221703.0
+2017-11-13,124.34,125.02,122.685,124.64,1132264.0,0.0,1.0,124.34,125.02,122.685,124.64,1132264.0
+2017-11-10,121.95,123.32,121.31,123.11,929375.0,0.0,1.0,121.95,123.32,121.31,123.11,929375.0
+2017-11-09,122.9,123.09,120.01,122.4,1455225.0,0.0,1.0,122.9,123.09,120.01,122.4,1455225.0
+2017-11-07,124.26,124.54,122.61,123.4,803631.0,0.0,1.0,124.26,124.54,122.61,123.4,803631.0
+2017-11-06,125.0,125.09,123.19,123.82,994672.0,0.0,1.0,125.0,125.09,123.19,123.82,994672.0
+2017-11-03,124.5,125.5,124.1101,124.85,1308745.0,0.0,1.0,124.5,125.5,124.1101,124.85,1308745.0
+2017-11-02,125.5,125.65,123.51,124.72,1732421.0,0.0,1.0,125.5,125.65,123.51,124.72,1732421.0
+2017-11-01,125.63,126.44,123.4,124.78,1612432.0,0.0,1.0,125.63,126.44,123.4,124.78,1612432.0
+2017-10-31,124.28,125.01,123.42,124.96,1836559.0,0.0,1.0,124.28,125.01,123.42,124.96,1836559.0
+2017-10-30,123.04,124.28,121.9,123.91,1606533.0,0.0,1.0,123.04,124.28,121.9,123.91,1606533.0
+2017-10-27,121.61,123.97,121.4,123.58,1503302.0,0.0,1.0,121.61,123.97,121.4,123.58,1503302.0
+2017-10-26,120.21,121.95,119.46,121.35,893806.0,0.0,1.0,120.21,121.95,119.46,121.35,893806.0
+2017-10-25,119.0,120.25,118.05,119.94,1064033.0,0.0,1.0,119.0,120.25,118.05,119.94,1064033.0
+2017-10-24,118.96,119.61,117.9,119.29,1306666.0,0.0,1.0,118.96,119.61,117.9,119.29,1306666.0
+2017-10-23,120.99,121.72,118.73,118.99,1484003.0,0.0,1.0,120.99,121.72,118.73,118.99,1484003.0
+2017-10-20,119.98,121.88,119.7,120.81,1570159.0,0.0,1.0,119.98,121.88,119.7,120.81,1570159.0
+2017-10-19,119.0,119.32,117.57,119.29,1087574.0,0.0,1.0,119.0,119.32,117.57,119.29,1087574.0
+2017-10-18,118.5,118.86,117.7834,118.54,998575.0,0.0,1.0,118.5,118.86,117.7834,118.54,998575.0
+2017-10-17,119.35,119.7599,118.06,118.72,1179973.0,0.0,1.0,119.35,119.7599,118.06,118.72,1179973.0
+2017-10-16,119.69,119.97,118.67,119.2,1176704.0,0.0,1.0,119.69,119.97,118.67,119.2,1176704.0
+2017-10-13,119.77,119.77,118.4498,119.63,1226925.0,0.0,1.0,119.77,119.77,118.4498,119.63,1226925.0
+2017-10-12,118.55,119.84,118.51,118.99,1226381.0,0.0,1.0,118.55,119.84,118.51,118.99,1226381.0
+2017-10-11,117.02,118.66,116.93,118.57,1072510.0,0.0,1.0,117.02,118.66,116.93,118.57,1072510.0
+2017-10-10,117.22,117.53,116.32,117.05,916721.0,0.0,1.0,117.22,117.53,116.32,117.05,916721.0
+2017-10-09,116.8,117.52,116.64,117.14,847005.0,0.0,1.0,116.8,117.52,116.64,117.14,847005.0
+2017-10-06,116.18,117.61,115.81,116.96,1718039.0,0.0,1.0,116.18,117.61,115.81,116.96,1718039.0
+2017-10-05,114.5,116.83,113.9,116.54,1578348.0,0.0,1.0,114.5,116.83,113.9,116.54,1578348.0
+2017-10-04,113.79,114.07,112.35,114.05,1120483.0,0.0,1.0,113.79,114.07,112.35,114.05,1120483.0
+2017-10-03,112.39,113.73,111.67,113.63,1039855.0,0.0,1.0,112.39,113.73,111.67,113.63,1039855.0
+2017-10-02,110.6915,113.76,110.68,112.47,1957433.0,0.0,1.0,110.6915,113.76,110.68,112.47,1957433.0
+2017-09-29,111.25,112.76,111.0,112.26,2013739.0,0.0,1.0,111.25,112.76,111.0,112.26,2013739.0
+2017-09-28,111.4,111.96,110.52,111.45,1335191.0,0.0,1.0,111.4,111.96,110.52,111.45,1335191.0
+2017-09-27,110.21,113.47,110.21,111.96,1717796.0,0.0,1.0,110.21,113.47,110.21,111.96,1717796.0
+2017-09-26,110.59,111.38,108.83,110.61,1579054.0,0.0,1.0,110.59,111.38,108.83,110.61,1579054.0
+2017-09-25,111.67,111.83,108.65,109.82,2015979.0,0.0,1.0,111.67,111.83,108.65,109.82,2015979.0
+2017-09-22,111.68,112.82,111.64,111.78,944731.0,0.0,1.0,111.68,112.82,111.64,111.78,944731.0
+2017-09-21,112.82,113.0,111.37,112.29,1148893.0,0.0,1.0,112.82,113.0,111.37,112.29,1148893.0
+2017-09-20,113.07,113.339,111.35,112.73,1686485.0,0.0,1.0,113.07,113.339,111.35,112.73,1686485.0
+2017-09-19,113.77,114.06,112.97,113.08,1945388.0,0.0,1.0,113.77,114.06,112.97,113.08,1945388.0
+2017-09-18,113.74,114.66,112.87,113.84,2020868.0,0.0,1.0,113.74,114.66,112.87,113.84,2020868.0
+2017-09-15,115.62,115.62,113.88,114.3,6185403.0,0.0,1.0,115.62,115.62,113.88,114.3,6185403.0
+2017-09-14,115.62,116.14,114.5,115.48,1625113.0,0.0,1.0,115.62,116.14,114.5,115.48,1625113.0
+2017-09-13,116.04,116.5,115.25,116.18,1269826.0,0.0,1.0,116.04,116.5,115.25,116.18,1269826.0
+2017-09-12,116.35,116.99,114.98,116.16,1523756.0,0.0,1.0,116.35,116.99,114.98,116.16,1523756.0
+2017-09-11,112.98,117.125,112.22,116.48,2279670.0,0.0,1.0,112.98,117.125,112.22,116.48,2279670.0
+2017-09-08,114.17,115.72,114.1,114.44,2650236.0,0.0,1.0,114.17,115.72,114.1,114.44,2650236.0
+2017-09-07,114.14,114.465,113.19,114.05,1705693.0,0.0,1.0,114.14,114.465,113.19,114.05,1705693.0
+2017-09-06,114.4,114.78,112.65,113.79,2328344.0,0.0,1.0,114.4,114.78,112.65,113.79,2328344.0
+2017-09-05,113.46,114.81,112.52,113.77,3089055.0,0.0,1.0,113.46,114.81,112.52,113.77,3089055.0
+2017-09-01,114.63,115.62,113.65,113.71,1521113.0,0.0,1.0,114.63,115.62,113.65,113.71,1521113.0
+2017-08-31,113.63,114.7,112.815,114.46,1442442.0,0.0,1.0,113.63,114.7,112.815,114.46,1442442.0
+2017-08-30,111.27,113.67,110.61,113.29,1439951.0,0.0,1.0,111.27,113.67,110.61,113.29,1439951.0
+2017-08-29,109.65,111.895,109.25,111.27,1798166.0,0.0,1.0,109.65,111.895,109.25,111.27,1798166.0
+2017-08-28,115.06,115.14,110.01,111.48,3591870.0,0.0,1.0,115.06,115.14,110.01,111.48,3591870.0
+2017-08-25,115.0,119.73,113.54,114.97,7085626.0,0.0,1.0,115.0,119.73,113.54,114.97,7085626.0
+2017-08-24,110.58,111.25,109.04,110.61,2948237.0,0.0,1.0,110.58,111.25,109.04,110.61,2948237.0
+2017-08-23,110.91,111.34,110.05,110.65,1631213.0,0.0,1.0,110.91,111.34,110.05,110.65,1631213.0
+2017-08-22,110.31,112.235,109.77,111.01,1705576.0,0.0,1.0,110.31,112.235,109.77,111.01,1705576.0
+2017-08-21,108.37,110.3,108.37,109.75,1265606.0,0.0,1.0,108.37,110.3,108.37,109.75,1265606.0
+2017-08-18,107.86,110.1,107.19,108.56,1145061.0,0.0,1.0,107.86,110.1,107.19,108.56,1145061.0
+2017-08-17,110.07,110.82,107.73,107.89,1715092.0,0.0,1.0,110.07,110.82,107.73,107.89,1715092.0
+2017-08-16,110.36,110.93,109.36,110.49,1312081.0,0.0,1.0,110.36,110.93,109.36,110.49,1312081.0
+2017-08-15,109.02,110.1,108.12,109.8,1258345.0,0.0,1.0,109.02,110.1,108.12,109.8,1258345.0
+2017-08-14,109.2,110.0,108.01,108.9,1634486.0,0.0,1.0,109.2,110.0,108.01,108.9,1634486.0
+2017-08-11,105.75,108.7577,105.1,108.01,1422869.0,0.0,1.0,105.75,108.7577,105.1,108.01,1422869.0
+2017-08-10,106.56,107.54,104.77,104.98,1842203.0,0.0,1.0,106.56,107.54,104.77,104.98,1842203.0
+2017-08-09,107.69,107.96,106.54,107.45,1115478.0,0.0,1.0,107.69,107.96,106.54,107.45,1115478.0
+2017-08-08,109.38,110.27,108.0,108.35,1080202.0,0.0,1.0,109.38,110.27,108.0,108.35,1080202.0
+2017-08-07,108.67,111.0,108.4,109.82,1491115.0,0.0,1.0,108.67,111.0,108.4,109.82,1491115.0
+2017-08-04,108.35,109.04,107.56,108.39,1481357.0,0.0,1.0,108.35,109.04,107.56,108.39,1481357.0
+2017-08-03,107.95,108.5,105.6,107.88,2249989.0,0.0,1.0,107.95,108.5,105.6,107.88,2249989.0
+2017-08-02,111.08,111.38,107.28,109.13,1756009.0,0.0,1.0,111.08,111.38,107.28,109.13,1756009.0
+2017-08-01,111.27,112.59,111.1,111.38,1304376.0,0.0,1.0,111.27,112.59,111.1,111.38,1304376.0
+2017-07-31,111.65,112.315,109.78,110.79,1356552.0,0.0,1.0,111.65,112.315,109.78,110.79,1356552.0
+2017-07-28,110.6,112.2754,110.3326,111.5,939043.0,0.0,1.0,110.6,112.2754,110.3326,111.5,939043.0
+2017-07-27,114.97,115.25,109.32,111.52,2357620.0,0.0,1.0,114.97,115.25,109.32,111.52,2357620.0
+2017-07-26,112.5,114.1,112.41,114.08,1882057.0,0.0,1.0,112.5,114.1,112.41,114.08,1882057.0
+2017-07-25,110.91,112.4,110.2,112.26,1337115.0,0.0,1.0,110.91,112.4,110.2,112.26,1337115.0
+2017-07-24,109.59,110.89,109.335,110.81,1050047.0,0.0,1.0,109.59,110.89,109.335,110.81,1050047.0
+2017-07-21,109.41,110.54,109.08,109.75,1100700.0,0.0,1.0,109.41,110.54,109.08,109.75,1100700.0
+2017-07-20,109.72,110.5,108.88,109.91,1259425.0,0.0,1.0,109.72,110.5,108.88,109.91,1259425.0
+2017-07-19,108.5,110.5,108.47,110.25,2034611.0,0.0,1.0,108.5,110.5,108.47,110.25,2034611.0
+2017-07-18,106.67,107.85,106.23,107.7,862647.0,0.0,1.0,106.67,107.85,106.23,107.7,862647.0
+2017-07-17,108.9,109.0,106.56,106.94,1175554.0,0.0,1.0,108.9,109.0,106.56,106.94,1175554.0
+2017-07-14,107.46,108.91,107.01,108.74,1479526.0,0.0,1.0,107.46,108.91,107.01,108.74,1479526.0
+2017-07-13,107.49,108.5,106.38,107.07,1411266.0,0.0,1.0,107.49,108.5,106.38,107.07,1411266.0
+2017-07-12,105.61,107.08,104.76,106.68,2612888.0,0.0,1.0,105.61,107.08,104.76,106.68,2612888.0
+2017-07-11,103.47,104.73,102.98,104.3,1450669.0,0.0,1.0,103.47,104.73,102.98,104.3,1450669.0
+2017-07-10,103.33,104.185,102.38,103.74,1191783.0,0.0,1.0,103.33,104.185,102.38,103.74,1191783.0
+2017-07-07,102.29,104.28,102.29,103.32,1666452.0,0.0,1.0,102.29,104.28,102.29,103.32,1666452.0
+2017-07-06,101.59,103.11,100.794,102.05,2593456.0,0.0,1.0,101.59,103.11,100.794,102.05,2593456.0
+2017-07-05,99.37,103.04,99.22,102.6,2759895.0,0.0,1.0,99.37,103.04,99.22,102.6,2759895.0
+2017-07-03,101.32,101.82,99.32,99.36,1454229.0,0.0,1.0,101.32,101.82,99.32,99.36,1454229.0
+2017-06-30,102.32,102.37,100.75,100.82,1659031.0,0.0,1.0,102.32,102.37,100.75,100.82,1659031.0
+2017-06-29,103.57,103.8105,100.0,101.39,2333399.0,0.0,1.0,103.57,103.8105,100.0,101.39,2333399.0
+2017-06-28,103.69,104.86,101.54,104.28,1640245.0,0.0,1.0,103.69,104.86,101.54,104.28,1640245.0
+2017-06-27,105.58,106.45,102.5,102.92,2215375.0,0.0,1.0,105.58,106.45,102.5,102.92,2215375.0
+2017-06-26,107.76,109.07,105.31,106.12,1870235.0,0.0,1.0,107.76,109.07,105.31,106.12,1870235.0
+2017-06-23,106.4,108.76,105.3,107.71,3598155.0,0.0,1.0,106.4,108.76,105.3,107.71,3598155.0
+2017-06-22,105.72,107.26,104.55,106.78,2327303.0,0.0,1.0,105.72,107.26,104.55,106.78,2327303.0
+2017-06-21,105.88,106.56,104.82,105.69,2641503.0,0.0,1.0,105.88,106.56,104.82,105.69,2641503.0
+2017-06-20,106.01,107.11,104.3,104.93,1946595.0,0.0,1.0,106.01,107.11,104.3,104.93,1946595.0
+2017-06-19,105.6,106.7,105.16,106.16,2432063.0,0.0,1.0,105.6,106.7,105.16,106.16,2432063.0
+2017-06-16,105.5,105.92,103.63,104.88,2536983.0,0.0,1.0,105.5,105.92,103.63,104.88,2536983.0
+2017-06-15,104.77,106.04,103.48,105.58,1740903.0,0.0,1.0,104.77,106.04,103.48,105.58,1740903.0
+2017-06-14,108.52,108.65,105.0232,106.2,1953219.0,0.0,1.0,108.52,108.65,105.0232,106.2,1953219.0
+2017-06-13,107.6,108.24,105.17,107.55,2257865.0,0.0,1.0,107.6,108.24,105.17,107.55,2257865.0
+2017-06-12,104.21,108.62,100.7,107.44,5005477.0,0.0,1.0,104.21,108.62,100.7,107.44,5005477.0
+2017-06-09,111.16,111.6999,103.62,105.95,3011163.0,0.0,1.0,111.16,111.6999,103.62,105.95,3011163.0
+2017-06-08,111.51,111.95,110.2,111.12,2006959.0,0.0,1.0,111.51,111.95,110.2,111.12,2006959.0
+2017-06-07,111.38,112.08,110.6,111.17,2010213.0,0.0,1.0,111.38,112.08,110.6,111.17,2010213.0
+2017-06-06,110.4,112.27,110.19,111.45,1505270.0,0.0,1.0,110.4,112.27,110.19,111.45,1505270.0
+2017-06-05,112.74,113.14,110.23,110.88,3933494.0,0.0,1.0,112.74,113.14,110.23,110.88,3933494.0
+2017-06-02,113.78,113.88,111.76,112.91,2213075.0,0.0,1.0,113.78,113.88,111.76,112.91,2213075.0
+2017-06-01,111.72,113.12,110.94,113.03,2318445.0,0.0,1.0,111.72,113.12,110.94,113.03,2318445.0
diff --git a/examples/quick/demos/stocqt/content/data/AMD.csv b/examples/quick/demos/stocqt/content/data/AMD.csv
new file mode 100644
index 0000000000..62c33c6faa
--- /dev/null
+++ b/examples/quick/demos/stocqt/content/data/AMD.csv
@@ -0,0 +1,148 @@
+Date,Open,High,Low,Close,Volume,Ex-Dividend,Split Ratio,Adj. Open,Adj. High,Adj. Low,Adj. Close,Adj. Volume
+2017-12-29,10.57,10.58,10.27,10.28,26321111.0,0.0,1.0,10.57,10.58,10.27,10.28,26321111.0
+2017-12-28,10.57,10.64,10.43,10.55,18345480.0,0.0,1.0,10.57,10.64,10.43,10.55,18345480.0
+2017-12-27,10.45,10.74,10.4,10.53,22780900.0,0.0,1.0,10.45,10.74,10.4,10.53,22780900.0
+2017-12-26,10.38,10.579,10.34,10.46,20362897.0,0.0,1.0,10.38,10.579,10.34,10.46,20362897.0
+2017-12-22,10.75,10.77,10.2,10.54,50572874.0,0.0,1.0,10.75,10.77,10.2,10.54,50572874.0
+2017-12-21,10.98,11.0793,10.87,10.89,21645217.0,0.0,1.0,10.98,11.0793,10.87,10.89,21645217.0
+2017-12-20,11.1,11.18,10.8,10.98,31053753.0,0.0,1.0,11.1,11.18,10.8,10.98,31053753.0
+2017-12-19,11.0,11.19,10.87,10.95,43445290.0,0.0,1.0,11.0,11.19,10.87,10.95,43445290.0
+2017-12-18,10.6,11.0,10.51,10.98,62789226.0,0.0,1.0,10.6,11.0,10.51,10.98,62789226.0
+2017-12-15,10.13,10.32,10.02,10.3,42459234.0,0.0,1.0,10.13,10.32,10.02,10.3,42459234.0
+2017-12-14,10.1,10.17,9.96,10.13,26491754.0,0.0,1.0,10.1,10.17,9.96,10.13,26491754.0
+2017-12-13,9.97,10.21,9.95,10.11,41201508.0,0.0,1.0,9.97,10.21,9.95,10.11,41201508.0
+2017-12-12,10.13,10.14,9.88,9.9,35843064.0,0.0,1.0,10.13,10.14,9.88,9.9,35843064.0
+2017-12-11,9.97,10.16,9.96,10.16,29359732.0,0.0,1.0,9.97,10.16,9.96,10.16,29359732.0
+2017-12-08,10.15,10.2,9.92,9.94,34582737.0,0.0,1.0,10.15,10.2,9.92,9.94,34582737.0
+2017-12-07,10.0705,10.19,9.95,10.04,32273896.0,0.0,1.0,10.0705,10.19,9.95,10.04,32273896.0
+2017-12-06,9.9,10.05,9.71,10.0,38351614.0,0.0,1.0,9.9,10.05,9.71,10.0,38351614.0
+2017-12-05,9.89,10.34,9.7,9.91,66840417.0,0.0,1.0,9.89,10.34,9.7,9.91,66840417.0
+2017-12-04,10.85,10.86,9.82,10.03,95608827.0,0.0,1.0,10.85,10.86,9.82,10.03,95608827.0
+2017-12-01,10.81,10.97,10.53,10.7201,41932685.0,0.0,1.0,10.81,10.97,10.53,10.7201,41932685.0
+2017-11-30,10.87,11.03,10.76,10.89,42311007.0,0.0,1.0,10.87,11.03,10.76,10.89,42311007.0
+2017-11-29,11.08,11.17,10.73,10.825,63028757.0,0.0,1.0,11.08,11.17,10.73,10.825,63028757.0
+2017-11-28,11.45,11.54,11.0,11.17,65088197.0,0.0,1.0,11.45,11.54,11.0,11.17,65088197.0
+2017-11-27,11.34,11.74,11.3358,11.55,41565129.0,0.0,1.0,11.34,11.74,11.3358,11.55,41565129.0
+2017-11-24,11.38,11.42,11.3,11.38,11033178.0,0.0,1.0,11.38,11.42,11.3,11.38,11033178.0
+2017-11-22,11.41,11.49,11.3,11.37,23686100.0,0.0,1.0,11.41,11.49,11.3,11.37,23686100.0
+2017-11-21,11.421,11.49,11.24,11.4,31469531.0,0.0,1.0,11.421,11.49,11.24,11.4,31469531.0
+2017-11-20,11.47,11.505,11.19,11.34,35827552.0,0.0,1.0,11.47,11.505,11.19,11.34,35827552.0
+2017-11-17,11.3,11.75,11.28,11.38,56245136.0,0.0,1.0,11.3,11.75,11.28,11.38,56245136.0
+2017-11-16,11.13,11.32,11.13,11.25,30814936.0,0.0,1.0,11.13,11.32,11.13,11.25,30814936.0
+2017-11-15,11.01,11.13,10.77,11.07,33326871.0,0.0,1.0,11.01,11.13,10.77,11.07,33326871.0
+2017-11-14,11.03,11.26,11.0,11.12,36254723.0,0.0,1.0,11.03,11.26,11.0,11.12,36254723.0
+2017-11-13,11.18,11.2,10.92,11.09,53925999.0,0.0,1.0,11.18,11.2,10.92,11.09,53925999.0
+2017-11-10,11.22,11.43,11.115,11.26,50022529.0,0.0,1.0,11.22,11.43,11.115,11.26,50022529.0
+2017-11-09,11.25,11.35,11.03,11.12,75698460.0,0.0,1.0,11.25,11.35,11.03,11.12,75698460.0
+2017-11-07,11.94,12.27,11.92,12.05,66232713.0,0.0,1.0,11.94,12.27,11.92,12.05,66232713.0
+2017-11-06,12.04,12.09,11.64,11.93,95719936.0,0.0,1.0,12.04,12.09,11.64,11.93,95719936.0
+2017-11-03,10.95,11.13,10.82,11.12,43989491.0,0.0,1.0,10.95,11.13,10.82,11.12,43989491.0
+2017-11-02,10.87,10.99,10.66,10.85,47509725.0,0.0,1.0,10.87,10.99,10.66,10.85,47509725.0
+2017-11-01,11.25,11.29,10.72,10.8,66416610.0,0.0,1.0,11.25,11.29,10.72,10.8,66416610.0
+2017-10-31,10.76,11.31,10.69,10.985,78118243.0,0.0,1.0,10.76,11.31,10.69,10.985,78118243.0
+2017-10-30,11.255,11.42,10.65,10.89,136725037.0,0.0,1.0,11.255,11.42,10.65,10.89,136725037.0
+2017-10-27,12.17,12.19,11.35,11.84,115163241.0,0.0,1.0,12.17,12.19,11.35,11.84,115163241.0
+2017-10-26,12.45,12.46,12.0,12.005,86725366.0,0.0,1.0,12.45,12.46,12.0,12.005,86725366.0
+2017-10-25,12.95,13.13,12.29,12.33,165686209.0,0.0,1.0,12.95,13.13,12.29,12.33,165686209.0
+2017-10-24,14.2,14.36,14.15,14.25,60340437.0,0.0,1.0,14.2,14.36,14.15,14.25,60340437.0
+2017-10-23,13.94,14.19,13.8999,14.1,49438627.0,0.0,1.0,13.94,14.19,13.8999,14.1,49438627.0
+2017-10-20,14.03,14.09,13.8,13.81,31624215.0,0.0,1.0,14.03,14.09,13.8,13.81,31624215.0
+2017-10-19,13.85,14.04,13.69,13.95,33600243.0,0.0,1.0,13.85,14.04,13.69,13.95,33600243.0
+2017-10-18,14.2,14.279,13.76,14.07,38868463.0,0.0,1.0,14.2,14.279,13.76,14.07,38868463.0
+2017-10-17,14.24,14.345,14.135,14.16,28695155.0,0.0,1.0,14.24,14.345,14.135,14.16,28695155.0
+2017-10-16,14.25,14.35,14.12,14.26,33684147.0,0.0,1.0,14.25,14.35,14.12,14.26,33684147.0
+2017-10-13,14.32,14.41,14.12,14.22,37160693.0,0.0,1.0,14.32,14.41,14.12,14.22,37160693.0
+2017-10-12,13.85,14.37,13.81,14.2,69313327.0,0.0,1.0,13.85,14.37,13.81,14.2,69313327.0
+2017-10-11,13.62,13.96,13.61,13.88,38017847.0,0.0,1.0,13.62,13.96,13.61,13.88,38017847.0
+2017-10-10,13.72,13.79,13.44,13.7,43046193.0,0.0,1.0,13.72,13.79,13.44,13.7,43046193.0
+2017-10-09,13.26,13.83,13.26,13.47,53748724.0,0.0,1.0,13.26,13.83,13.26,13.47,53748724.0
+2017-10-06,13.22,13.39,13.18,13.23,27939491.0,0.0,1.0,13.22,13.39,13.18,13.23,27939491.0
+2017-10-05,13.38,13.46,13.21,13.34,34409933.0,0.0,1.0,13.38,13.46,13.21,13.34,34409933.0
+2017-10-04,13.31,13.5,13.15,13.31,41814144.0,0.0,1.0,13.31,13.5,13.15,13.31,41814144.0
+2017-10-03,12.73,13.48,12.7,13.42,84656340.0,0.0,1.0,12.73,13.48,12.7,13.42,84656340.0
+2017-10-02,12.8,12.85,12.62,12.71,34256219.0,0.0,1.0,12.8,12.85,12.62,12.71,34256219.0
+2017-09-29,12.765,12.82,12.6,12.75,33358815.0,0.0,1.0,12.765,12.82,12.6,12.75,33358815.0
+2017-09-28,12.76,12.84,12.55,12.74,35439338.0,0.0,1.0,12.76,12.84,12.55,12.74,35439338.0
+2017-09-27,12.65,12.87,12.5,12.74,59391214.0,0.0,1.0,12.65,12.87,12.5,12.74,59391214.0
+2017-09-26,12.85,12.93,12.43,12.45,67417625.0,0.0,1.0,12.85,12.93,12.43,12.45,67417625.0
+2017-09-25,13.25,13.28,12.49,12.61,83429167.0,0.0,1.0,13.25,13.28,12.49,12.61,83429167.0
+2017-09-22,13.2,13.4,13.12,13.3,49752570.0,0.0,1.0,13.2,13.4,13.12,13.3,49752570.0
+2017-09-21,14.0,14.24,13.32,13.41,164802839.0,0.0,1.0,14.0,14.24,13.32,13.41,164802839.0
+2017-09-20,13.07,13.8,12.8,13.76,82385985.0,0.0,1.0,13.07,13.8,12.8,13.76,82385985.0
+2017-09-19,13.25,13.29,12.88,13.12,64693928.0,0.0,1.0,13.25,13.29,12.88,13.12,64693928.0
+2017-09-18,12.77,13.3,12.74,13.08,82647358.0,0.0,1.0,12.77,13.3,12.74,13.08,82647358.0
+2017-09-15,12.33,12.66,12.31,12.52,49576344.0,0.0,1.0,12.33,12.66,12.31,12.52,49576344.0
+2017-09-14,12.15,12.46,12.11,12.26,36903301.0,0.0,1.0,12.15,12.46,12.11,12.26,36903301.0
+2017-09-13,12.22,12.36,12.12,12.22,36978783.0,0.0,1.0,12.22,12.36,12.12,12.22,36978783.0
+2017-09-12,12.66,12.68,12.213,12.3,54029549.0,0.0,1.0,12.66,12.68,12.213,12.3,54029549.0
+2017-09-11,12.46,12.74,12.4001,12.55,42904404.0,0.0,1.0,12.46,12.74,12.4001,12.55,42904404.0
+2017-09-08,12.5712,12.61,12.035,12.25,60503832.0,0.0,1.0,12.5712,12.61,12.035,12.25,60503832.0
+2017-09-07,12.84,12.94,12.6,12.63,35467788.0,0.0,1.0,12.84,12.94,12.6,12.63,35467788.0
+2017-09-06,13.02,13.08,12.75,12.85,33828656.0,0.0,1.0,13.02,13.08,12.75,12.85,33828656.0
+2017-09-05,12.88,13.18,12.65,12.92,51359359.0,0.0,1.0,12.88,13.18,12.65,12.92,51359359.0
+2017-09-01,13.12,13.485,13.04,13.19,52901453.0,0.0,1.0,13.12,13.485,13.04,13.19,52901453.0
+2017-08-31,12.82,13.16,12.79,13.0,51056961.0,0.0,1.0,12.82,13.16,12.79,13.0,51056961.0
+2017-08-30,12.19,12.68,12.16,12.67,43434380.0,0.0,1.0,12.19,12.68,12.16,12.67,43434380.0
+2017-08-29,12.0,12.18,11.93,12.15,33290113.0,0.0,1.0,12.0,12.18,11.93,12.15,33290113.0
+2017-08-28,12.53,12.55,12.16,12.23,35078317.0,0.0,1.0,12.53,12.55,12.16,12.23,35078317.0
+2017-08-25,12.51,12.57,12.25,12.425,29543318.0,0.0,1.0,12.51,12.57,12.25,12.425,29543318.0
+2017-08-24,12.69,12.71,12.39,12.505,37056907.0,0.0,1.0,12.69,12.71,12.39,12.505,37056907.0
+2017-08-23,12.0,12.535,11.95,12.48,43429439.0,0.0,1.0,12.0,12.535,11.95,12.48,43429439.0
+2017-08-22,12.2,12.33,12.1,12.175,38705808.0,0.0,1.0,12.2,12.33,12.1,12.175,38705808.0
+2017-08-21,12.42,12.42,11.86,12.05,58620489.0,0.0,1.0,12.42,12.42,11.86,12.05,58620489.0
+2017-08-18,12.43,12.555,12.25,12.376,37172947.0,0.0,1.0,12.43,12.555,12.25,12.376,37172947.0
+2017-08-17,12.46,12.65,12.32,12.34,46960411.0,0.0,1.0,12.46,12.65,12.32,12.34,46960411.0
+2017-08-16,13.17,13.19,12.52,12.63,64171662.0,0.0,1.0,13.17,13.19,12.52,12.63,64171662.0
+2017-08-15,13.01,13.14,12.75,13.02,57447725.0,0.0,1.0,13.01,13.14,12.75,13.02,57447725.0
+2017-08-14,12.58,12.845,12.58,12.76,63873137.0,0.0,1.0,12.58,12.845,12.58,12.76,63873137.0
+2017-08-11,12.04,12.39,11.88,12.23,63319050.0,0.0,1.0,12.04,12.39,11.88,12.23,63319050.0
+2017-08-10,12.7,12.92,12.11,12.12,80131441.0,0.0,1.0,12.7,12.92,12.11,12.12,80131441.0
+2017-08-09,12.76,12.89,12.54,12.83,58571682.0,0.0,1.0,12.76,12.89,12.54,12.83,58571682.0
+2017-08-08,13.48,13.55,13.08,13.11,46548040.0,0.0,1.0,13.48,13.55,13.08,13.11,46548040.0
+2017-08-07,13.33,13.57,13.27,13.43,57203474.0,0.0,1.0,13.33,13.57,13.27,13.43,57203474.0
+2017-08-04,13.2,13.36,13.02,13.12,63954775.0,0.0,1.0,13.2,13.36,13.02,13.12,63954775.0
+2017-08-03,13.42,13.52,13.08,13.24,51720273.0,0.0,1.0,13.42,13.52,13.08,13.24,51720273.0
+2017-08-02,13.81,13.93,13.12,13.37,67062121.0,0.0,1.0,13.81,13.93,13.12,13.37,67062121.0
+2017-08-01,13.72,13.86,13.45,13.71,48273874.0,0.0,1.0,13.72,13.86,13.45,13.71,48273874.0
+2017-07-31,14.09,14.22,13.47,13.61,68653763.0,0.0,1.0,14.09,14.22,13.47,13.61,68653763.0
+2017-07-28,13.845,14.1,13.68,13.95,66352470.0,0.0,1.0,13.845,14.1,13.68,13.95,66352470.0
+2017-07-27,14.99,15.04,13.7,14.12,129095996.0,0.0,1.0,14.99,15.04,13.7,14.12,129095996.0
+2017-07-26,15.13,15.65,14.4,14.76,234655935.0,0.0,1.0,15.13,15.65,14.4,14.76,234655935.0
+2017-07-25,14.2895,14.32,13.87,14.11,76089789.0,0.0,1.0,14.2895,14.32,13.87,14.11,76089789.0
+2017-07-24,14.0,14.44,13.97,14.16,70306709.0,0.0,1.0,14.0,14.44,13.97,14.16,70306709.0
+2017-07-21,13.7,14.05,13.62,13.88,50836269.0,0.0,1.0,13.7,14.05,13.62,13.88,50836269.0
+2017-07-20,13.61,13.89,13.45,13.8,47328081.0,0.0,1.0,13.61,13.89,13.45,13.8,47328081.0
+2017-07-19,13.62,13.74,13.41,13.55,51511044.0,0.0,1.0,13.62,13.74,13.41,13.55,51511044.0
+2017-07-18,13.29,13.53,13.15,13.48,77823247.0,0.0,1.0,13.29,13.53,13.15,13.48,77823247.0
+2017-07-17,14.03,14.12,13.51,13.8,70594469.0,0.0,1.0,14.03,14.12,13.51,13.8,70594469.0
+2017-07-14,13.46,13.93,13.32,13.92,81515312.0,0.0,1.0,13.46,13.93,13.32,13.92,81515312.0
+2017-07-13,14.33,14.49,13.43,13.53,110860494.0,0.0,1.0,14.33,14.49,13.43,13.53,110860494.0
+2017-07-12,14.17,14.39,13.96,14.29,78011028.0,0.0,1.0,14.17,14.39,13.96,14.29,78011028.0
+2017-07-11,13.77,14.099,13.62,13.89,70760527.0,0.0,1.0,13.77,14.099,13.62,13.89,70760527.0
+2017-07-10,13.61,13.88,13.27,13.81,77940920.0,0.0,1.0,13.61,13.88,13.27,13.81,77940920.0
+2017-07-07,13.27,13.745,13.18,13.36,88021133.0,0.0,1.0,13.27,13.745,13.18,13.36,88021133.0
+2017-07-06,12.94,13.32,12.665,13.02,88418322.0,0.0,1.0,12.94,13.32,12.665,13.02,88418322.0
+2017-07-05,12.36,13.21,12.32,13.19,98729984.0,0.0,1.0,12.36,13.21,12.32,13.19,98729984.0
+2017-07-03,12.57,12.73,12.13,12.15,39888247.0,0.0,1.0,12.57,12.73,12.13,12.15,39888247.0
+2017-06-30,12.57,12.83,12.36,12.48,58976478.0,0.0,1.0,12.57,12.83,12.36,12.48,58976478.0
+2017-06-29,13.06,13.15,12.45,12.6,86658774.0,0.0,1.0,13.06,13.15,12.45,12.6,86658774.0
+2017-06-28,13.65,13.7,13.09,13.23,84591176.0,0.0,1.0,13.65,13.7,13.09,13.23,84591176.0
+2017-06-27,13.76,14.04,13.37,13.395,88742270.0,0.0,1.0,13.76,14.04,13.37,13.395,88742270.0
+2017-06-26,14.39,14.49,13.84,14.08,100078492.0,0.0,1.0,14.39,14.49,13.84,14.08,100078492.0
+2017-06-23,14.15,14.67,13.9,14.15,151603584.0,0.0,1.0,14.15,14.67,13.9,14.15,151603584.0
+2017-06-22,14.1,14.5,13.56,14.3708,147959418.0,0.0,1.0,14.1,14.5,13.56,14.3708,147959418.0
+2017-06-21,13.36,14.01,13.13,13.98,187161633.0,0.0,1.0,13.36,14.01,13.13,13.98,187161633.0
+2017-06-20,12.19,12.93,12.18,12.64,116319537.0,0.0,1.0,12.19,12.93,12.18,12.64,116319537.0
+2017-06-19,11.63,12.12,11.62,11.93,61268773.0,0.0,1.0,11.63,12.12,11.62,11.93,61268773.0
+2017-06-16,11.66,11.83,11.28,11.44,58774371.0,0.0,1.0,11.66,11.83,11.28,11.44,58774371.0
+2017-06-15,11.34,11.58,11.21,11.5,60332254.0,0.0,1.0,11.34,11.58,11.21,11.5,60332254.0
+2017-06-14,11.91,12.05,11.65,11.76,51454208.0,0.0,1.0,11.91,12.05,11.65,11.76,51454208.0
+2017-06-13,12.33,12.48,11.67,11.96,86585397.0,0.0,1.0,12.33,12.48,11.67,11.96,86585397.0
+2017-06-12,11.75,12.35,11.47,12.085,123725528.0,0.0,1.0,11.75,12.35,11.47,12.085,123725528.0
+2017-06-09,13.1,13.4,11.63,12.28,165174160.0,0.0,1.0,13.1,13.4,11.63,12.28,165174160.0
+2017-06-08,12.81,12.91,12.4,12.9,87201152.0,0.0,1.0,12.81,12.91,12.4,12.9,87201152.0
+2017-06-07,12.42,12.96,12.2348,12.38,149171943.0,0.0,1.0,12.42,12.96,12.2348,12.38,149171943.0
+2017-06-06,11.27,12.24,11.24,12.02,113010266.0,0.0,1.0,11.27,12.24,11.24,12.02,113010266.0
+2017-06-05,10.84,11.34,10.8,11.24,64357671.0,0.0,1.0,10.84,11.34,10.8,11.24,64357671.0
+2017-06-02,10.93,10.96,10.565,10.9,42838855.0,0.0,1.0,10.93,10.96,10.565,10.9,42838855.0
+2017-06-01,11.25,11.285,10.81,10.93,47175511.0,0.0,1.0,11.25,11.285,10.81,10.93,47175511.0
diff --git a/examples/quick/demos/stocqt/content/data/AMZN.csv b/examples/quick/demos/stocqt/content/data/AMZN.csv
new file mode 100644
index 0000000000..f6fea4d2c8
--- /dev/null
+++ b/examples/quick/demos/stocqt/content/data/AMZN.csv
@@ -0,0 +1,147 @@
+Date,Open,High,Low,Close,Volume,Ex-Dividend,Split Ratio,Adj. Open,Adj. High,Adj. Low,Adj. Close,Adj. Volume
+2017-12-29,1182.35,1184.0,1167.5,1169.47,2625283.0,0.0,1.0,1182.35,1184.0,1167.5,1169.47,2625283.0
+2017-12-28,1189.0,1190.1,1184.38,1186.1,1803460.0,0.0,1.0,1189.0,1190.1,1184.38,1186.1,1803460.0
+2017-12-27,1179.91,1187.29,1175.61,1182.26,1779382.0,0.0,1.0,1179.91,1187.29,1175.61,1182.26,1779382.0
+2017-12-26,1168.36,1178.32,1160.55,1176.76,1964871.0,0.0,1.0,1168.36,1178.32,1160.55,1176.76,1964871.0
+2017-12-22,1172.08,1174.62,1167.83,1168.36,1553997.0,0.0,1.0,1172.08,1174.62,1167.83,1168.36,1553997.0
+2017-12-21,1175.9,1179.17,1167.64,1174.76,2042448.0,0.0,1.0,1175.9,1179.17,1167.64,1174.76,2042448.0
+2017-12-20,1190.5,1191.0,1176.0,1177.62,2318916.0,0.0,1.0,1190.5,1191.0,1176.0,1177.62,2318916.0
+2017-12-19,1189.15,1192.97,1179.14,1187.38,2555235.0,0.0,1.0,1189.15,1192.97,1179.14,1187.38,2555235.0
+2017-12-18,1187.37,1194.78,1180.91,1190.58,2767271.0,0.0,1.0,1187.37,1194.78,1180.91,1190.58,2767271.0
+2017-12-15,1179.03,1182.75,1169.33,1179.14,4539895.0,0.0,1.0,1179.03,1182.75,1169.33,1179.14,4539895.0
+2017-12-14,1163.71,1177.93,1162.45,1174.26,3069993.0,0.0,1.0,1163.71,1177.93,1162.45,1174.26,3069993.0
+2017-12-13,1170.0,1170.87,1160.27,1164.13,2555053.0,0.0,1.0,1170.0,1170.87,1160.27,1164.13,2555053.0
+2017-12-12,1166.51,1173.6,1161.61,1165.08,2197697.0,0.0,1.0,1166.51,1173.6,1161.61,1165.08,2197697.0
+2017-12-11,1164.6,1169.9,1157.0,1168.92,2257922.0,0.0,1.0,1164.6,1169.9,1157.0,1168.92,2257922.0
+2017-12-08,1170.4,1172.79,1157.1,1162.0,2957785.0,0.0,1.0,1170.4,1172.79,1157.1,1162.0,2957785.0
+2017-12-07,1156.59,1163.19,1151.0,1159.79,2408323.0,0.0,1.0,1156.59,1163.19,1151.0,1159.79,2408323.0
+2017-12-06,1137.99,1155.89,1136.08,1152.35,2756730.0,0.0,1.0,1137.99,1155.89,1136.08,1152.35,2756730.0
+2017-12-05,1128.26,1159.27,1124.74,1141.57,4033184.0,0.0,1.0,1128.26,1159.27,1124.74,1141.57,4033184.0
+2017-12-04,1173.85,1175.2,1128.0,1133.95,5872358.0,0.0,1.0,1173.85,1175.2,1128.0,1133.95,5872358.0
+2017-12-01,1172.05,1179.65,1152.0,1162.35,4070722.0,0.0,1.0,1172.05,1179.65,1152.0,1162.35,4070722.0
+2017-11-30,1167.1,1178.57,1160.0,1176.75,4406535.0,0.0,1.0,1167.1,1178.57,1160.0,1176.75,4406535.0
+2017-11-29,1194.8,1194.8,1145.19,1161.27,9179567.0,0.0,1.0,1194.8,1194.8,1145.19,1161.27,9179567.0
+2017-11-28,1204.88,1205.34,1188.52,1193.6,4463476.0,0.0,1.0,1204.88,1205.34,1188.52,1193.6,4463476.0
+2017-11-27,1202.66,1213.41,1191.15,1195.83,6701343.0,0.0,1.0,1202.66,1213.41,1191.15,1195.83,6701343.0
+2017-11-24,1160.7,1186.84,1160.7,1186.0,3526582.0,0.0,1.0,1160.7,1186.84,1160.7,1186.0,3526582.0
+2017-11-22,1141.0,1160.27,1141.0,1156.16,3516336.0,0.0,1.0,1141.0,1160.27,1141.0,1156.16,3516336.0
+2017-11-21,1132.86,1140.0,1128.2,1139.49,2449503.0,0.0,1.0,1132.86,1140.0,1128.2,1139.49,2449503.0
+2017-11-20,1129.77,1133.42,1122.55,1126.31,2134381.0,0.0,1.0,1129.77,1133.42,1122.55,1126.31,2134381.0
+2017-11-17,1138.28,1138.8,1125.81,1129.88,2333554.0,0.0,1.0,1138.28,1138.8,1125.81,1129.88,2333554.0
+2017-11-16,1130.16,1138.16,1130.05,1137.29,2190456.0,0.0,1.0,1130.16,1138.16,1130.05,1137.29,2190456.0
+2017-11-15,1127.01,1131.75,1121.63,1126.69,3897230.0,0.0,1.0,1127.01,1131.75,1121.63,1126.69,3897230.0
+2017-11-14,1130.11,1138.0,1123.89,1136.84,3042295.0,0.0,1.0,1130.11,1138.0,1123.89,1136.84,3042295.0
+2017-11-13,1123.0,1139.9,1122.34,1129.17,2897563.0,0.0,1.0,1123.0,1139.9,1122.34,1129.17,2897563.0
+2017-11-10,1126.1,1131.75,1124.06,1125.35,2162985.0,0.0,1.0,1126.1,1131.75,1124.06,1125.35,2162985.0
+2017-11-09,1125.96,1129.62,1115.77,1129.13,3661411.0,0.0,1.0,1125.96,1129.62,1115.77,1129.13,3661411.0
+2017-11-07,1124.74,1130.6,1117.5,1123.17,2623474.0,0.0,1.0,1124.74,1130.6,1117.5,1123.17,2623474.0
+2017-11-06,1109.15,1125.41,1108.77,1120.66,3313857.0,0.0,1.0,1109.15,1125.41,1108.77,1120.66,3313857.0
+2017-11-03,1091.15,1112.68,1088.52,1111.6,3685172.0,0.0,1.0,1091.15,1112.68,1088.52,1111.6,3685172.0
+2017-11-02,1097.81,1101.94,1086.87,1094.22,3658748.0,0.0,1.0,1097.81,1101.94,1086.87,1094.22,3658748.0
+2017-11-01,1105.4,1108.97,1096.74,1103.68,3723680.0,0.0,1.0,1105.4,1108.97,1096.74,1103.68,3723680.0
+2017-10-31,1109.0,1110.54,1101.12,1105.28,3428461.0,0.0,1.0,1109.0,1110.54,1101.12,1105.28,3428461.0
+2017-10-30,1095.01,1122.79,1093.56,1110.85,6516639.0,0.0,1.0,1095.01,1122.79,1093.56,1110.85,6516639.0
+2017-10-27,1058.14,1105.58,1050.55,1100.95,16360527.0,0.0,1.0,1058.14,1105.58,1050.55,1100.95,16360527.0
+2017-10-26,980.33,982.9,968.55,972.43,3670282.0,0.0,1.0,980.33,982.9,968.55,972.43,3670282.0
+2017-10-25,978.0,984.44,966.24,972.91,2969295.0,0.0,1.0,978.0,984.44,966.24,972.91,2969295.0
+2017-10-24,969.0,979.85,965.0,975.9,2666782.0,0.0,1.0,969.0,979.85,965.0,975.9,2666782.0
+2017-10-23,986.73,986.775,962.5,966.3,3465469.0,0.0,1.0,986.73,986.775,962.5,966.3,3465469.0
+2017-10-20,993.53,994.62,982.0,982.91,2294145.0,0.0,1.0,993.53,994.62,982.0,982.91,2294145.0
+2017-10-19,990.0,991.05,980.24,986.61,3040066.0,0.0,1.0,990.0,991.05,980.24,986.61,3040066.0
+2017-10-18,1009.27,1022.31,996.55,997.0,2477357.0,0.0,1.0,1009.27,1022.31,996.55,997.0,2477357.0
+2017-10-17,1005.59,1011.47,1004.38,1009.13,2307075.0,0.0,1.0,1005.59,1011.47,1004.38,1009.13,2307075.0
+2017-10-16,1008.44,1009.57,1001.04,1006.34,1991556.0,0.0,1.0,1008.44,1009.57,1001.04,1006.34,1991556.0
+2017-10-13,1007.0,1007.77,1001.03,1002.94,2399403.0,0.0,1.0,1007.0,1007.77,1001.03,1002.94,2399403.0
+2017-10-12,996.81,1008.44,992.4,1000.93,4056172.0,0.0,1.0,996.81,1008.44,992.4,1000.93,4056172.0
+2017-10-11,991.27,995.5,986.695,995.0,2310872.0,0.0,1.0,991.27,995.5,986.695,995.0,2310872.0
+2017-10-10,996.67,997.95,980.099,987.2,3062820.0,0.0,1.0,996.67,997.95,980.099,987.2,3062820.0
+2017-10-09,993.24,998.5,987.5,990.99,2927994.0,0.0,1.0,993.24,998.5,987.5,990.99,2927994.0
+2017-10-06,975.64,995.75,975.64,989.58,3719840.0,0.0,1.0,975.64,995.75,975.64,989.58,3719840.0
+2017-10-05,970.0,981.51,969.64,980.85,3119487.0,0.0,1.0,970.0,981.51,969.64,980.85,3119487.0
+2017-10-04,954.21,967.79,954.05,965.45,2460721.0,0.0,1.0,954.21,967.79,954.05,965.45,2460721.0
+2017-10-03,958.0,963.69,950.37,957.1,2643484.0,0.0,1.0,958.0,963.69,950.37,957.1,2643484.0
+2017-10-02,964.0,967.305,952.1201,959.19,2415846.0,0.0,1.0,964.0,967.305,952.1201,959.19,2415846.0
+2017-09-29,960.11,964.83,958.375,961.35,2411643.0,0.0,1.0,960.11,964.83,958.375,961.35,2411643.0
+2017-09-28,951.86,959.7,950.101,956.4,2512567.0,0.0,1.0,951.86,959.7,950.101,956.4,2512567.0
+2017-09-27,948.0,955.3,943.3,950.87,3111263.0,0.0,1.0,948.0,955.3,943.3,950.87,3111263.0
+2017-09-26,945.49,948.63,931.75,938.6,3464183.0,0.0,1.0,945.49,948.63,931.75,938.6,3464183.0
+2017-09-25,949.31,949.42,932.89,939.79,5065542.0,0.0,1.0,949.31,949.42,932.89,939.79,5065542.0
+2017-09-22,961.01,965.61,954.42,955.1,2602418.0,0.0,1.0,961.01,965.61,954.42,955.1,2602418.0
+2017-09-21,971.31,971.7,962.02,964.65,2252940.0,0.0,1.0,971.31,971.7,962.02,964.65,2252940.0
+2017-09-20,971.79,974.81,962.1626,973.21,2727355.0,0.0,1.0,971.79,974.81,962.1626,973.21,2727355.0
+2017-09-19,977.25,978.24,967.46,969.86,2614059.0,0.0,1.0,977.25,978.24,967.46,969.86,2614059.0
+2017-09-18,990.4,992.7922,968.17,974.19,3376772.0,0.0,1.0,990.4,992.7922,968.17,974.19,3376772.0
+2017-09-15,993.01,996.25,984.03,986.79,3697742.0,0.0,1.0,993.01,996.25,984.03,986.79,3697742.0
+2017-09-14,996.8,998.56,987.74,992.21,3788472.0,0.0,1.0,996.8,998.56,987.74,992.21,3788472.0
+2017-09-13,983.97,1000.0,979.42,999.6,3314978.0,0.0,1.0,983.97,1000.0,979.42,999.6,3314978.0
+2017-09-12,983.27,984.6718,975.517,982.58,2444699.0,0.0,1.0,983.27,984.6718,975.517,982.58,2444699.0
+2017-09-11,974.46,981.94,974.22,977.96,2134582.0,0.0,1.0,974.46,981.94,974.22,977.96,2134582.0
+2017-09-08,979.1,979.88,963.47,965.9,2578269.0,0.0,1.0,979.1,979.88,963.47,965.9,2578269.0
+2017-09-07,974.0,980.59,972.55,979.47,2536000.0,0.0,1.0,974.0,980.59,972.55,979.47,2536000.0
+2017-09-06,968.32,971.84,960.6,967.8,2106605.0,0.0,1.0,968.32,971.84,960.6,967.8,2106605.0
+2017-09-05,975.4,976.7699,960.37,965.27,2875228.0,0.0,1.0,975.4,976.7699,960.37,965.27,2875228.0
+2017-09-01,984.2,984.5,976.875,978.25,2423132.0,0.0,1.0,984.2,984.5,976.875,978.25,2423132.0
+2017-08-31,974.7,981.0,972.76,980.6,3280945.0,0.0,1.0,974.7,981.0,972.76,980.6,3280945.0
+2017-08-30,958.44,969.41,956.9062,967.59,2860718.0,0.0,1.0,958.44,969.41,956.9062,967.59,2860718.0
+2017-08-29,940.0,956.0,936.33,954.06,2853972.0,0.0,1.0,940.0,956.0,936.33,954.06,2853972.0
+2017-08-28,946.54,953.0,942.25,946.02,2529087.0,0.0,1.0,946.54,953.0,942.25,946.02,2529087.0
+2017-08-25,956.0,957.621,944.1,945.26,3292776.0,0.0,1.0,956.0,957.621,944.1,945.26,3292776.0
+2017-08-24,957.42,959.0,941.14,952.45,5086748.0,0.0,1.0,957.42,959.0,941.14,952.45,5086748.0
+2017-08-23,959.38,962.0,954.2,958.0,2590245.0,0.0,1.0,959.38,962.0,954.2,958.0,2590245.0
+2017-08-22,955.52,967.93,955.495,966.9,2718261.0,0.0,1.0,955.52,967.93,955.495,966.9,2718261.0
+2017-08-21,957.57,961.2,945.46,953.29,3008450.0,0.0,1.0,957.57,961.2,945.46,953.29,3008450.0
+2017-08-18,961.4,965.43,954.65,958.47,3248677.0,0.0,1.0,961.4,965.43,954.65,958.47,3248677.0
+2017-08-17,977.84,977.84,960.32,960.57,3396045.0,0.0,1.0,977.84,977.84,960.32,960.57,3396045.0
+2017-08-16,981.65,986.4605,973.22,978.18,3096051.0,0.0,1.0,981.65,986.4605,973.22,978.18,3096051.0
+2017-08-15,988.9,991.74,982.0,982.74,2513139.0,0.0,1.0,988.9,991.74,982.0,982.74,2513139.0
+2017-08-14,978.41,985.5,976.19,983.3,3008007.0,0.0,1.0,978.41,985.5,976.19,983.3,3008007.0
+2017-08-11,960.0,970.39,951.38,967.99,3431423.0,0.0,1.0,960.0,970.39,951.38,967.99,3431423.0
+2017-08-10,976.295,979.86,954.68,956.92,5560388.0,0.0,1.0,976.295,979.86,954.68,956.92,5560388.0
+2017-08-09,982.6,988.0,975.27,982.01,3434077.0,0.0,1.0,982.6,988.0,975.27,982.01,3434077.0
+2017-08-08,994.35,996.28,985.79,989.84,2847527.0,0.0,1.0,994.35,996.28,985.79,989.84,2847527.0
+2017-08-04,989.68,991.672,982.0,987.58,2704026.0,0.0,1.0,989.68,991.672,982.0,987.58,2704026.0
+2017-08-03,999.47,999.5,984.59,986.92,3203134.0,0.0,1.0,999.47,999.5,984.59,986.92,3203134.0
+2017-08-02,1001.77,1003.21,981.73,995.89,4017780.0,0.0,1.0,1001.77,1003.21,981.73,995.89,4017780.0
+2017-08-01,996.11,1006.4,991.58,996.19,4421395.0,0.0,1.0,996.11,1006.4,991.58,996.19,4421395.0
+2017-07-31,1019.05,1019.05,987.02,987.78,7246638.0,0.0,1.0,1019.05,1019.05,987.02,987.78,7246638.0
+2017-07-28,1012.14,1032.85,1001.0,1020.04,7624498.0,0.0,1.0,1012.14,1032.85,1001.0,1020.04,7624498.0
+2017-07-27,1069.55,1083.31,1040.18,1046.0,9905158.0,0.0,1.0,1069.55,1083.31,1040.18,1046.0,9905158.0
+2017-07-26,1043.2,1053.2,1043.2,1052.8,2828980.0,0.0,1.0,1043.2,1053.2,1043.2,1052.8,2828980.0
+2017-07-25,1038.05,1043.33,1032.48,1039.87,2432328.0,0.0,1.0,1038.05,1043.33,1032.48,1039.87,2432328.0
+2017-07-24,1028.34,1043.01,1027.43,1038.95,3212499.0,0.0,1.0,1028.34,1043.01,1027.43,1038.95,3212499.0
+2017-07-21,1021.28,1026.1,1011.0,1025.67,2677517.0,0.0,1.0,1021.28,1026.1,1011.0,1025.67,2677517.0
+2017-07-20,1031.59,1034.97,1022.52,1028.7,2964341.0,0.0,1.0,1031.59,1034.97,1022.52,1028.7,2964341.0
+2017-07-19,1025.0,1031.59,1022.5,1026.87,2936902.0,0.0,1.0,1025.0,1031.59,1022.5,1026.87,2936902.0
+2017-07-18,1006.0,1026.03,1004.0,1024.38,3957892.0,0.0,1.0,1006.0,1026.03,1004.0,1024.38,3957892.0
+2017-07-17,1004.69,1014.75,1003.81,1010.04,3636801.0,0.0,1.0,1004.69,1014.75,1003.81,1010.04,3636801.0
+2017-07-14,1002.4,1004.45,996.89,1001.81,2066362.0,0.0,1.0,1002.4,1004.45,996.89,1001.81,2066362.0
+2017-07-13,1004.62,1006.88,995.9,999.855,2864533.0,0.0,1.0,1004.62,1006.88,995.9,999.855,2864533.0
+2017-07-12,1000.65,1008.55,998.1,1006.51,3491988.0,0.0,1.0,1000.65,1008.55,998.1,1006.51,3491988.0
+2017-07-11,993.0,995.99,983.72,994.13,2947479.0,0.0,1.0,993.0,995.99,983.72,994.13,2947479.0
+2017-07-10,985.0,999.4392,983.5,996.47,3462884.0,0.0,1.0,985.0,999.4392,983.5,996.47,3462884.0
+2017-07-07,969.55,980.11,969.14,978.76,2582645.0,0.0,1.0,969.55,980.11,969.14,978.76,2582645.0
+2017-07-06,964.66,974.4,959.02,965.14,3229378.0,0.0,1.0,964.66,974.4,959.02,965.14,3229378.0
+2017-07-05,961.53,975.0,955.25,971.4,3587645.0,0.0,1.0,961.53,975.0,955.25,971.4,3587645.0
+2017-07-03,972.79,974.49,951.0001,953.66,2908267.0,0.0,1.0,972.79,974.49,951.0001,953.66,2908267.0
+2017-06-30,980.12,983.47,967.61,968.0,3309138.0,0.0,1.0,980.12,983.47,967.61,968.0,3309138.0
+2017-06-29,979.0,987.56,965.25,975.93,4246765.0,0.0,1.0,979.0,987.56,965.25,975.93,4246765.0
+2017-06-28,978.55,990.68,969.21,990.33,3708638.0,0.0,1.0,978.55,990.68,969.21,990.33,3708638.0
+2017-06-27,990.69,998.8,976.0,976.78,3735360.0,0.0,1.0,990.69,998.8,976.0,976.78,3735360.0
+2017-06-26,1008.5,1009.8,992.0,993.98,3347195.0,0.0,1.0,1008.5,1009.8,992.0,993.98,3347195.0
+2017-06-23,1002.54,1004.62,998.02,1003.74,2645973.0,0.0,1.0,1002.54,1004.62,998.02,1003.74,2645973.0
+2017-06-22,1002.23,1006.96,997.2,1001.3,2221035.0,0.0,1.0,1002.23,1006.96,997.2,1001.3,2221035.0
+2017-06-21,998.7,1002.72,992.6518,1002.23,2892563.0,0.0,1.0,998.7,1002.72,992.6518,1002.23,2892563.0
+2017-06-20,998.0,1004.88,992.02,992.59,4040990.0,0.0,1.0,998.0,1004.88,992.02,992.59,4040990.0
+2017-06-19,1017.0,1017.0,989.9,995.17,4967600.0,0.0,1.0,1017.0,1017.0,989.9,995.17,4967600.0
+2017-06-16,996.0,999.75,982.0,987.71,11314754.0,0.0,1.0,996.0,999.75,982.0,987.71,11314754.0
+2017-06-15,958.7,965.73,950.86,964.17,5202147.0,0.0,1.0,958.7,965.73,950.86,964.17,5202147.0
+2017-06-14,988.59,990.34,966.71,976.47,3943670.0,0.0,1.0,988.59,990.34,966.71,976.47,3943670.0
+2017-06-13,977.99,984.5,966.1,980.79,4533933.0,0.0,1.0,977.99,984.5,966.1,980.79,4533933.0
+2017-06-12,967.0,975.95,945.0,964.83,9393802.0,0.0,1.0,967.0,975.95,945.0,964.83,9393802.0
+2017-06-09,1012.5,1012.99,927.0,978.31,7548854.0,0.0,1.0,1012.5,1012.99,927.0,978.31,7548854.0
+2017-06-08,1012.06,1013.61,1006.11,1009.94,2724408.0,0.0,1.0,1012.06,1013.61,1006.11,1009.94,2724408.0
+2017-06-07,1005.95,1010.25,1002.0,1010.07,2779551.0,0.0,1.0,1005.95,1010.25,1002.0,1010.07,2779551.0
+2017-06-06,1012.0,1016.5,1001.25,1002.97,3298378.0,0.0,1.0,1012.0,1016.5,1001.25,1002.97,3298378.0
+2017-06-05,1007.23,1013.21,1003.51,1011.34,2676857.0,0.0,1.0,1007.23,1013.21,1003.51,1011.34,2676857.0
+2017-06-02,998.99,1008.48,995.67,1006.73,3714954.0,0.0,1.0,998.99,1008.48,995.67,1006.73,3714954.0
+2017-06-01,998.59,998.99,991.37,995.95,2384298.0,0.0,1.0,998.59,998.99,991.37,995.95,2384298.0
diff --git a/examples/quick/demos/stocqt/content/data/CSCO.csv b/examples/quick/demos/stocqt/content/data/CSCO.csv
new file mode 100644
index 0000000000..0c4b9b05c9
--- /dev/null
+++ b/examples/quick/demos/stocqt/content/data/CSCO.csv
@@ -0,0 +1,148 @@
+Date,Open,High,Low,Close,Volume,Ex-Dividend,Split Ratio,Adj. Open,Adj. High,Adj. Low,Adj. Close,Adj. Volume
+2017-12-29,38.41,38.62,38.3,38.3,12359455.0,0.0,1.0,38.41,38.62,38.3,38.3,12359455.0
+2017-12-28,38.73,38.73,38.45,38.59,8662664.0,0.0,1.0,38.73,38.73,38.45,38.59,8662664.0
+2017-12-27,38.54,38.65,38.45,38.56,10262927.0,0.0,1.0,38.54,38.65,38.45,38.56,10262927.0
+2017-12-26,38.55,38.68,38.36,38.48,8148042.0,0.0,1.0,38.55,38.68,38.36,38.48,8148042.0
+2017-12-22,38.52,38.74,38.47,38.55,11120656.0,0.0,1.0,38.52,38.74,38.47,38.55,11120656.0
+2017-12-21,38.88,38.995,38.49,38.53,16188471.0,0.0,1.0,38.88,38.995,38.49,38.53,16188471.0
+2017-12-20,38.49,38.8,38.21,38.74,18701741.0,0.0,1.0,38.49,38.8,38.21,38.74,18701741.0
+2017-12-19,38.66,38.86,38.28,38.3,18478762.0,0.0,1.0,38.66,38.86,38.28,38.3,18478762.0
+2017-12-18,38.48,38.89,38.3,38.48,21036306.0,0.0,1.0,38.48,38.89,38.3,38.48,21036306.0
+2017-12-15,38.01,38.28,37.7,38.19,36491640.0,0.0,1.0,38.01,38.28,37.7,38.19,36491640.0
+2017-12-14,38.2,38.27,37.855,37.9,16556403.0,0.0,1.0,38.2,38.27,37.855,37.9,16556403.0
+2017-12-13,38.09,38.37,38.0,38.15,19934529.0,0.0,1.0,38.09,38.37,38.0,38.15,19934529.0
+2017-12-12,37.79,38.1,37.56,37.91,16451320.0,0.0,1.0,37.79,38.1,37.56,37.91,16451320.0
+2017-12-11,37.59,38.04,37.57,37.96,15619388.0,0.0,1.0,37.59,38.04,37.57,37.96,15619388.0
+2017-12-08,37.59,37.69,37.42,37.61,13777371.0,0.0,1.0,37.59,37.69,37.42,37.61,13777371.0
+2017-12-07,37.26,37.78,37.26,37.4,15189086.0,0.0,1.0,37.26,37.78,37.26,37.4,15189086.0
+2017-12-06,37.37,37.72,37.25,37.41,16312845.0,0.0,1.0,37.37,37.72,37.25,37.41,16312845.0
+2017-12-05,37.74,37.82,37.17,37.31,22743474.0,0.0,1.0,37.74,37.82,37.17,37.31,22743474.0
+2017-12-04,37.81,37.99,37.54,37.72,29006129.0,0.0,1.0,37.81,37.99,37.54,37.72,29006129.0
+2017-12-01,37.09,37.66,36.73,37.6,26851147.0,0.0,1.0,37.09,37.66,36.73,37.6,26851147.0
+2017-11-30,37.62,37.8,37.3,37.3,28692862.0,0.0,1.0,37.62,37.8,37.3,37.3,28692862.0
+2017-11-29,37.75,38.025,37.23,37.48,36640805.0,0.0,1.0,37.75,38.025,37.23,37.48,36640805.0
+2017-11-28,37.0,37.8,36.98,37.73,30097816.0,0.0,1.0,37.0,37.8,36.98,37.73,30097816.0
+2017-11-27,36.51,37.09,36.5,36.87,20667352.0,0.0,1.0,36.51,37.09,36.5,36.87,20667352.0
+2017-11-24,36.41,36.57,36.32,36.49,6155294.0,0.0,1.0,36.41,36.57,36.32,36.49,6155294.0
+2017-11-22,36.7,36.715,36.36,36.45,16650130.0,0.0,1.0,36.7,36.715,36.36,36.45,16650130.0
+2017-11-21,36.75,36.97,36.58,36.65,23986203.0,0.0,1.0,36.75,36.97,36.58,36.65,23986203.0
+2017-11-20,35.93,36.54,35.93,36.5,26376364.0,0.0,1.0,35.93,36.54,35.93,36.5,26376364.0
+2017-11-17,35.9,36.32,35.81,35.9,27106406.0,0.0,1.0,35.9,36.32,35.81,35.9,27106406.0
+2017-11-16,36.04,36.67,35.83,35.88,59861205.0,0.0,1.0,36.04,36.67,35.83,35.88,59861205.0
+2017-11-15,33.97,34.31,33.75,34.11,27797071.0,0.0,1.0,33.97,34.31,33.75,34.11,27797071.0
+2017-11-14,33.86,34.16,33.8,34.04,15540925.0,0.0,1.0,33.86,34.16,33.8,34.04,15540925.0
+2017-11-13,33.86,34.21,33.83,33.95,15608341.0,0.0,1.0,33.86,34.21,33.83,33.95,15608341.0
+2017-11-10,34.06,34.09,33.67,33.99,19003147.0,0.0,1.0,34.06,34.09,33.67,33.99,19003147.0
+2017-11-09,34.29,34.32,33.871,34.05,16266161.0,0.0,1.0,34.29,34.32,33.871,34.05,16266161.0
+2017-11-07,34.32,34.48,34.2147,34.4,10980008.0,0.0,1.0,34.32,34.48,34.2147,34.4,10980008.0
+2017-11-06,34.37,34.56,34.26,34.41,12725467.0,0.0,1.0,34.37,34.56,34.26,34.41,12725467.0
+2017-11-03,34.28,34.49,34.0269,34.47,13293171.0,0.0,1.0,34.28,34.49,34.0269,34.47,13293171.0
+2017-11-02,34.55,34.64,34.16,34.21,19647242.0,0.0,1.0,34.55,34.64,34.16,34.21,19647242.0
+2017-11-01,34.29,34.75,34.28,34.62,21831973.0,0.0,1.0,34.29,34.75,34.28,34.62,21831973.0
+2017-10-31,33.98,34.24,33.96,34.15,13544441.0,0.0,1.0,33.98,34.24,33.96,34.15,13544441.0
+2017-10-30,34.32,34.38,33.8244,34.04,18241531.0,0.0,1.0,34.32,34.38,33.8244,34.04,18241531.0
+2017-10-27,34.15,34.62,34.09,34.43,20237956.0,0.0,1.0,34.15,34.62,34.09,34.43,20237956.0
+2017-10-26,34.41,34.51,34.07,34.27,14541155.0,0.0,1.0,34.41,34.51,34.07,34.27,14541155.0
+2017-10-25,34.73,34.73,34.163,34.3,17012218.0,0.0,1.0,34.73,34.73,34.163,34.3,17012218.0
+2017-10-24,34.4,34.675,34.25,34.58,15273905.0,0.0,1.0,34.4,34.675,34.25,34.58,15273905.0
+2017-10-23,34.45,34.68,34.27,34.35,22490134.0,0.0,1.0,34.45,34.68,34.27,34.35,22490134.0
+2017-10-20,34.02,34.39,34.01,34.25,24055347.0,0.0,1.0,34.02,34.39,34.01,34.25,24055347.0
+2017-10-19,33.51,33.89,33.45,33.75,12928532.0,0.0,1.0,33.51,33.89,33.45,33.75,12928532.0
+2017-10-18,33.72,33.75,33.44,33.55,9739887.0,0.0,1.0,33.72,33.75,33.44,33.55,9739887.0
+2017-10-17,33.59,33.67,33.46,33.6,8633089.0,0.0,1.0,33.59,33.67,33.46,33.6,8633089.0
+2017-10-16,33.6,33.64,33.47,33.54,10469019.0,0.0,1.0,33.6,33.64,33.47,33.54,10469019.0
+2017-10-13,33.4,33.57,33.323,33.47,13451108.0,0.0,1.0,33.4,33.57,33.323,33.47,13451108.0
+2017-10-12,33.26,33.46,33.17,33.26,17811160.0,0.0,1.0,33.26,33.46,33.17,33.26,17811160.0
+2017-10-11,33.38,33.63,33.25,33.59,12353462.0,0.0,1.0,33.38,33.63,33.25,33.59,12353462.0
+2017-10-10,33.88,33.91,33.47,33.55,17978700.0,0.0,1.0,33.88,33.91,33.47,33.55,17978700.0
+2017-10-09,33.77,33.89,33.61,33.76,8684822.0,0.0,1.0,33.77,33.89,33.61,33.76,8684822.0
+2017-10-06,33.65,33.78,33.5247,33.75,13438950.0,0.0,1.0,33.65,33.78,33.5247,33.75,13438950.0
+2017-10-05,33.58,33.67,33.41,33.59,14301206.0,0.0,1.0,33.58,33.67,33.41,33.59,14301206.0
+2017-10-04,33.53,33.56,33.29,33.44,14606016.0,0.29,1.0,33.53,33.56,33.29,33.44,14606016.0
+2017-10-03,33.72,33.9,33.61,33.85,13159079.0,0.0,1.0,33.430085976875,33.608538393122,33.321031722502,33.558968277498,13159079.0
+2017-10-02,33.61,33.77,33.52,33.75,16443224.0,0.0,1.0,33.321031722502,33.479656092499,33.231805514379,33.45982804625,16443224.0
+2017-09-29,33.31,33.67,33.24,33.63,14419404.0,0.0,1.0,33.023611028758,33.380515861251,32.954212866884,33.340859768752,14419404.0
+2017-09-28,33.22,33.46,33.22,33.35,14689819.0,0.0,1.0,32.934384820634,33.17232137563,32.934384820634,33.063267121257,14689819.0
+2017-09-27,33.78,33.92,33.3037,33.48,21687593.0,0.0,1.0,33.489570115624,33.628366439371,33.017365194189,33.19214942188,21687593.0
+2017-09-26,33.76,34.1,33.67,33.76,25835270.0,0.0,1.0,33.469742069374,33.806818855618,33.380515861251,33.469742069374,25835270.0
+2017-09-25,33.31,33.84,33.2,33.72,30475969.0,0.0,1.0,33.023611028758,33.549054254373,32.914556774385,33.430085976875,30475969.0
+2017-09-22,32.66,33.53,32.64,33.37,27904695.0,0.0,1.0,32.379199525645,33.241719537504,32.359371479395,33.083095167507,27904695.0
+2017-09-21,32.72,32.9,32.5,32.7,19762651.0,0.0,1.0,32.438683664394,32.61713608064,32.220575155648,32.418855618144,19762651.0
+2017-09-20,32.55,32.75,32.39,32.6,18701702.0,0.0,1.0,32.270145271272,32.468425733768,32.111520901275,32.319715386896,18701702.0
+2017-09-19,32.46,32.65,32.395,32.49,12424056.0,0.0,1.0,32.180919063149,32.36928550252,32.116477912837,32.210661132523,12424056.0
+2017-09-18,32.43,32.66,32.26,32.52,17035443.0,0.0,1.0,32.151176993774,32.379199525645,31.982638600652,32.240403201897,17035443.0
+2017-09-15,32.2,32.5,32.12,32.44,27708447.0,0.0,1.0,31.923154461903,32.220575155648,31.843842276905,32.161091016899,27708447.0
+2017-09-14,31.91,32.22,31.91,32.19,17711003.0,0.0,1.0,31.635647791284,31.942982508153,31.635647791284,31.913240438779,17711003.0
+2017-09-13,32.34,32.39,31.96,32.18,21872095.0,0.0,1.0,32.061950785651,32.111520901275,31.685217906908,31.903326415654,21872095.0
+2017-09-12,32.3,32.47,32.19,32.41,18510454.0,0.0,1.0,32.022294693151,32.190833086273,31.913240438779,32.131348947524,18510454.0
+2017-09-11,31.71,32.3,31.67,32.205,21365590.0,0.0,1.0,31.437367328787,32.022294693151,31.397711236288,31.928111473466,21365590.0
+2017-09-08,31.68,31.78,31.46,31.48,15115756.0,0.0,1.0,31.407625259413,31.506765490661,31.189516750667,31.209344796917,15115756.0
+2017-09-07,31.96,31.97,31.74,31.76,14611809.0,0.0,1.0,31.685217906908,31.695131930033,31.467109398162,31.486937444412,14611809.0
+2017-09-06,31.75,31.91,31.63,31.87,16380030.0,0.0,1.0,31.477023421287,31.635647791284,31.358055143789,31.595991698784,16380030.0
+2017-09-05,32.15,32.245,31.455,31.62,24327663.0,0.0,1.0,31.873584346279,31.967767565965,31.184559739105,31.348141120664,24327663.0
+2017-09-01,32.22,32.345,32.03,32.32,14661162.0,0.0,1.0,31.942982508153,32.066907797213,31.754616068782,32.042122739401,14661162.0
+2017-08-31,32.1,32.34,31.99,32.21,27138172.0,0.0,1.0,31.824014230655,32.061950785651,31.714959976282,31.933068485028,27138172.0
+2017-08-30,31.47,32.2,31.42,31.99,23028578.0,0.0,1.0,31.199430773792,31.923154461903,31.149860658168,31.714959976282,23028578.0
+2017-08-29,31.26,31.6299,31.19,31.48,16192694.0,0.0,1.0,30.991236288171,31.357956003558,30.921838126297,31.209344796917,16192694.0
+2017-08-28,31.6,31.66,31.41,31.54,12747867.0,0.0,1.0,31.328313074414,31.387797213163,31.139946635043,31.268828935666,12747867.0
+2017-08-25,31.39,31.8,31.36,31.44,19351094.0,0.0,1.0,31.120118588793,31.526593536911,31.090376519419,31.169688704417,19351094.0
+2017-08-24,30.95,31.4,30.9,31.24,21867401.0,0.0,1.0,30.683901571302,31.130032611918,30.634331455677,30.971408241921,21867401.0
+2017-08-23,31.21,31.4,30.91,30.92,22269978.0,0.0,1.0,30.941666172547,31.130032611918,30.644245478802,30.654159501927,22269978.0
+2017-08-22,30.85,31.33,30.75,31.27,24438367.0,0.0,1.0,30.584761340053,31.060634450044,30.485621108805,31.001150311296,24438367.0
+2017-08-21,30.37,30.795,30.36,30.68,24025228.0,0.0,1.0,30.108888230062,30.530234212867,30.098974206937,30.416222946932,24025228.0
+2017-08-18,31.0,31.06,30.36,30.37,34622147.0,0.0,1.0,30.733471686926,30.792955825674,30.098974206937,30.108888230062,34622147.0
+2017-08-17,31.49,31.77,30.85,31.04,51557052.0,0.0,1.0,31.219258820042,31.496851467536,30.584761340053,30.773127779425,51557052.0
+2017-08-16,32.1,32.4652,32.06,32.34,27088237.0,0.0,1.0,31.824014230655,32.186074355173,31.784358138156,32.061950785651,27088237.0
+2017-08-15,31.85,32.21,31.84,32.09,24406258.0,0.0,1.0,31.576163652535,31.933068485028,31.56624962941,31.81410020753,24406258.0
+2017-08-14,31.69,31.89,31.56,31.84,21605411.0,0.0,1.0,31.417539282538,31.615819745034,31.288656981915,31.56624962941,21605411.0
+2017-08-11,31.23,31.545,31.04,31.47,20521935.0,0.0,1.0,30.961494218796,31.273785947228,30.773127779425,31.199430773792,20521935.0
+2017-08-10,31.56,31.56,31.0,31.0,22748854.0,0.0,1.0,31.288656981915,31.288656981915,30.733471686926,30.733471686926,22748854.0
+2017-08-09,31.55,31.675,31.36,31.62,15931711.0,0.0,1.0,31.27874295879,31.402668247851,31.090376519419,31.348141120664,15931711.0
+2017-08-08,31.75,32.0,31.6,31.67,13632423.0,0.0,1.0,31.477023421287,31.724873999407,31.328313074414,31.397711236288,13632423.0
+2017-08-07,31.79,31.8799,31.69,31.84,11730203.0,0.0,1.0,31.516679513786,31.605806581678,31.417539282538,31.56624962941,11730203.0
+2017-08-04,31.67,31.91,31.58,31.8,16322686.0,0.0,1.0,31.397711236288,31.635647791284,31.308485028165,31.526593536911,16322686.0
+2017-08-03,31.59,31.72,31.43,31.56,13884046.0,0.0,1.0,31.31839905129,31.447281351912,31.159774681293,31.288656981915,13884046.0
+2017-08-02,31.57,31.57,31.25,31.52,15797711.0,0.0,1.0,31.29857100504,31.29857100504,30.981322265046,31.249000889416,15797711.0
+2017-08-01,31.59,31.66,31.43,31.65,12727298.0,0.0,1.0,31.31839905129,31.387797213163,31.159774681293,31.377883190039,12727298.0
+2017-07-31,31.54,31.59,31.37,31.45,18534978.0,0.0,1.0,31.268828935666,31.31839905129,31.100290542544,31.179602727542,18534978.0
+2017-07-28,31.45,31.6,31.26,31.52,15509841.0,0.0,1.0,31.179602727542,31.328313074414,30.991236288171,31.249000889416,15509841.0
+2017-07-27,31.73,31.7502,31.21,31.57,21224338.0,0.0,1.0,31.457195375037,31.477221701749,30.941666172547,31.29857100504,21224338.0
+2017-07-26,32.12,32.225,31.51,31.66,21472799.0,0.0,1.0,31.843842276905,31.947939519715,31.239086866291,31.387797213163,21472799.0
+2017-07-25,31.9,32.25,31.88,32.12,14848920.0,0.0,1.0,31.625733768159,31.972724577527,31.605905721909,31.843842276905,14848920.0
+2017-07-24,31.86,31.925,31.66,31.86,15232167.0,0.0,1.0,31.58607767566,31.650518825971,31.387797213163,31.58607767566,15232167.0
+2017-07-21,31.86,32.03,31.705,31.84,13271427.0,0.0,1.0,31.58607767566,31.754616068782,31.432410317225,31.56624962941,13271427.0
+2017-07-20,31.91,32.05,31.76,31.86,15917114.0,0.0,1.0,31.635647791284,31.774444115031,31.486937444412,31.58607767566,15917114.0
+2017-07-19,31.51,32.05,31.46,31.9,21369697.0,0.0,1.0,31.239086866291,31.774444115031,31.189516750667,31.625733768159,21369697.0
+2017-07-18,31.41,31.51,31.17,31.51,15366450.0,0.0,1.0,31.139946635043,31.239086866291,30.902010080047,31.239086866291,15366450.0
+2017-07-17,31.5,31.635,31.45,31.5,16012951.0,0.0,1.0,31.229172843166,31.363012155351,31.179602727542,31.229172843166,16012951.0
+2017-07-14,31.37,31.45,31.27,31.42,13261554.0,0.0,1.0,31.100290542544,31.179602727542,31.001150311296,31.149860658168,13261554.0
+2017-07-13,31.26,31.28,31.08,31.27,15870454.0,0.0,1.0,30.991236288171,31.01106433442,30.812783871924,31.001150311296,15870454.0
+2017-07-12,31.25,31.44,31.145,31.16,18428809.0,0.0,1.0,30.981322265046,31.169688704417,30.877225022235,30.892096056923,18428809.0
+2017-07-11,31.05,31.12,30.86,31.09,12253478.0,0.0,1.0,30.78304180255,30.852439964423,30.594675363178,30.822697895049,12253478.0
+2017-07-10,30.88,31.09,30.82,30.98,15193572.0,0.0,1.0,30.614503409428,30.822697895049,30.555019270679,30.713643640676,15193572.0
+2017-07-07,30.76,31.07,30.75,30.9,15221015.0,0.0,1.0,30.49553513193,30.802869848799,30.485621108805,30.634331455677,15221015.0
+2017-07-06,30.99,31.02,30.67,30.725,20456451.0,0.0,1.0,30.723557663801,30.753299733175,30.406308923807,30.460836050993,20456451.0
+2017-07-05,30.85,31.27,30.73,31.11,23391894.0,0.29,1.0,30.584761340053,31.001150311296,30.465793062556,30.842525941299,23391894.0
+2017-07-03,31.09,31.64,31.03,31.33,14111474.0,0.0,1.0,30.538029666082,31.078264993079,30.479094903137,30.773768717863,14111474.0
+2017-06-30,31.79,31.79,31.3,31.3,22981379.0,0.0,1.0,31.225601900442,31.225601900442,30.74430133639,30.74430133639,22981379.0
+2017-06-29,31.79,32.025,31.25,31.41,26891695.0,0.0,1.0,31.225601900442,31.456429721977,30.695189033936,30.852348401789,26891695.0
+2017-06-28,31.78,32.275,31.76,32.08,17587686.0,0.0,1.0,31.215779439951,31.701991234249,31.196134518969,31.510453254677,17587686.0
+2017-06-27,32.09,32.26,31.76,31.76,23092594.0,0.0,1.0,31.520275715168,31.687257543512,31.196134518969,31.196134518969,23092594.0
+2017-06-26,32.22,32.5,32.18,32.24,21409287.0,0.0,1.0,31.647967701549,31.922996595293,31.608677859586,31.667612622531,21409287.0
+2017-06-23,31.85,32.3,31.75,32.1,23006424.0,0.0,1.0,31.284536663387,31.726547385476,31.186312058479,31.530098175659,23006424.0
+2017-06-22,31.91,32.0,31.7,31.85,19194637.0,0.0,1.0,31.343471426332,31.43187357075,31.137199756024,31.284536663387,19194637.0
+2017-06-21,31.73,31.87,31.51,31.84,20103067.0,0.0,1.0,31.166667137497,31.304181584369,30.950573006698,31.274714202896,20103067.0
+2017-06-20,31.94,32.16,31.84,31.85,17859664.0,0.0,1.0,31.372938807805,31.589032938604,31.274714202896,31.284536663387,17859664.0
+2017-06-19,31.77,32.02,31.581,31.99,16753701.0,0.0,1.0,31.20595697946,31.451518491732,31.020312476183,31.422051110259,16753701.0
+2017-06-16,31.61,31.64,31.2,31.6201,33785850.0,0.0,1.0,31.048797611607,31.078264993079,30.646076731481,31.058718296702,33785850.0
+2017-06-15,31.25,31.64,31.22,31.5801,19110962.0,0.0,1.0,30.695189033936,31.078264993079,30.665721652463,31.019428454739,19110962.0
+2017-06-14,31.87,31.97,31.33,31.6,24850713.0,0.0,1.0,31.304181584369,31.402406189278,30.773768717863,31.038975151116,24850713.0
+2017-06-13,31.3,31.8,31.28,31.7,27251001.0,0.0,1.0,30.74430133639,31.235424360933,30.724656415408,31.137199756024,27251001.0
+2017-06-12,31.34,31.64,31.15,31.245,24330382.0,0.0,1.0,30.783591178353,31.078264993079,30.596964429027,30.69027780369,24330382.0
+2017-06-09,31.64,31.83,31.085,31.37,25031675.0,0.0,1.0,31.078264993079,31.264891742406,30.533118435836,30.813058559826,25031675.0
+2017-06-08,31.53,31.81,31.52,31.615,19877271.0,0.0,1.0,30.97021792768,31.245246821424,30.960395467189,31.053708841852,19877271.0
+2017-06-07,31.61,31.72,31.44,31.61,14417549.0,0.0,1.0,31.048797611607,31.156844677006,30.881815783262,31.048797611607,14417549.0
+2017-06-06,31.75,31.76,31.5,31.56,15987734.0,0.0,1.0,31.186312058479,31.196134518969,30.940750546207,30.999685309152,15987734.0
+2017-06-05,32.05,32.05,31.57,31.76,15581429.0,0.0,1.0,31.480985873204,31.480985873204,31.009507769643,31.196134518969,15581429.0
+2017-06-02,31.93,32.06,31.68,31.98,19978713.0,0.0,1.0,31.363116347314,31.490808333695,31.117554835043,31.412228649768,19978713.0
+2017-06-01,31.52,31.82,31.47,31.82,15397418.0,0.0,1.0,30.960395467189,31.255069281915,30.911283164735,31.255069281915,15397418.0
diff --git a/examples/quick/demos/stocqt/content/data/EA.csv b/examples/quick/demos/stocqt/content/data/EA.csv
new file mode 100644
index 0000000000..ad6a60fc7b
--- /dev/null
+++ b/examples/quick/demos/stocqt/content/data/EA.csv
@@ -0,0 +1,148 @@
+Date,Open,High,Low,Close,Volume,Ex-Dividend,Split Ratio,Adj. Open,Adj. High,Adj. Low,Adj. Close,Adj. Volume
+2017-12-29,105.29,105.68,104.39,105.06,2033331.0,0.0,1.0,105.29,105.68,104.39,105.06,2033331.0
+2017-12-28,105.29,105.55,104.55,105.31,1431096.0,0.0,1.0,105.29,105.55,104.55,105.31,1431096.0
+2017-12-27,105.4,106.44,104.58,105.23,2427713.0,0.0,1.0,105.4,106.44,104.58,105.23,2427713.0
+2017-12-26,105.66,106.02,104.65,105.06,1685265.0,0.0,1.0,105.66,106.02,104.65,105.06,1685265.0
+2017-12-22,108.31,108.31,105.675,106.02,2401349.0,0.0,1.0,108.31,108.31,105.675,106.02,2401349.0
+2017-12-21,107.88,108.735,107.78,107.97,2784216.0,0.0,1.0,107.88,108.735,107.78,107.97,2784216.0
+2017-12-20,107.5,108.87,107.15,108.45,2642416.0,0.0,1.0,107.5,108.87,107.15,108.45,2642416.0
+2017-12-19,107.42,107.7558,106.69,107.0,1985332.0,0.0,1.0,107.42,107.7558,106.69,107.0,1985332.0
+2017-12-18,109.89,110.0,106.56,107.34,4241871.0,0.0,1.0,109.89,110.0,106.56,107.34,4241871.0
+2017-12-15,107.77,109.68,106.63,109.28,5755867.0,0.0,1.0,107.77,109.68,106.63,109.28,5755867.0
+2017-12-14,105.2,107.62,104.7,106.42,2580582.0,0.0,1.0,105.2,107.62,104.7,106.42,2580582.0
+2017-12-13,107.71,108.31,105.22,105.54,3730504.0,0.0,1.0,107.71,108.31,105.22,105.54,3730504.0
+2017-12-12,108.0,108.92,107.02,107.66,3512468.0,0.0,1.0,108.0,108.92,107.02,107.66,3512468.0
+2017-12-11,105.61,108.16,105.0,107.92,3271833.0,0.0,1.0,105.61,108.16,105.0,107.92,3271833.0
+2017-12-08,104.49,106.4,104.42,105.27,3194502.0,0.0,1.0,104.49,106.4,104.42,105.27,3194502.0
+2017-12-07,103.23,105.6,102.75,104.37,3486643.0,0.0,1.0,103.23,105.6,102.75,104.37,3486643.0
+2017-12-06,102.96,103.92,100.41,103.18,4441608.0,0.0,1.0,102.96,103.92,100.41,103.18,4441608.0
+2017-12-05,100.55,105.1926,99.63,103.38,4454836.0,0.0,1.0,100.55,105.1926,99.63,103.38,4454836.0
+2017-12-04,105.53,105.875,100.68,100.83,6476227.0,0.0,1.0,105.53,105.875,100.68,100.83,6476227.0
+2017-12-01,105.86,106.87,103.95,106.02,3810130.0,0.0,1.0,105.86,106.87,103.95,106.02,3810130.0
+2017-11-30,106.11,106.5,105.06,106.35,5338599.0,0.0,1.0,106.11,106.5,105.06,106.35,5338599.0
+2017-11-29,109.21,109.39,104.95,105.49,5484734.0,0.0,1.0,109.21,109.39,104.95,105.49,5484734.0
+2017-11-28,106.99,110.52,106.74,109.47,5362601.0,0.0,1.0,106.99,110.52,106.74,109.47,5362601.0
+2017-11-27,107.86,108.285,106.79,106.99,2398540.0,0.0,1.0,107.86,108.285,106.79,106.99,2398540.0
+2017-11-24,107.66,108.58,107.59,107.94,1306290.0,0.0,1.0,107.66,108.58,107.59,107.94,1306290.0
+2017-11-22,108.04,108.44,106.61,107.32,2512190.0,0.0,1.0,108.04,108.44,106.61,107.32,2512190.0
+2017-11-21,107.78,108.7699,107.54,107.71,3089096.0,0.0,1.0,107.78,108.7699,107.54,107.71,3089096.0
+2017-11-20,108.28,108.45,106.75,107.64,5948591.0,0.0,1.0,108.28,108.45,106.75,107.64,5948591.0
+2017-11-17,108.99,109.55,107.5,108.82,8476713.0,0.0,1.0,108.99,109.55,107.5,108.82,8476713.0
+2017-11-16,111.85,113.13,111.21,111.6,2308873.0,0.0,1.0,111.85,113.13,111.21,111.6,2308873.0
+2017-11-15,112.72,112.87,110.52,111.48,2483272.0,0.0,1.0,112.72,112.87,110.52,111.48,2483272.0
+2017-11-14,110.6,113.9,110.39,112.27,3554816.0,0.0,1.0,110.6,113.9,110.39,112.27,3554816.0
+2017-11-13,112.0,113.24,111.19,112.01,3157879.0,0.0,1.0,112.0,113.24,111.19,112.01,3157879.0
+2017-11-10,111.26,112.83,110.82,112.75,2515313.0,0.0,1.0,111.26,112.83,110.82,112.75,2515313.0
+2017-11-09,112.99,113.3,110.94,111.89,3331403.0,0.0,1.0,112.99,113.3,110.94,111.89,3331403.0
+2017-11-07,112.29,112.72,110.08,111.7,2671700.0,0.0,1.0,112.29,112.72,110.08,111.7,2671700.0
+2017-11-06,112.99,113.5,110.76,112.46,3571671.0,0.0,1.0,112.99,113.5,110.76,112.46,3571671.0
+2017-11-03,113.47,113.76,112.57,113.2,2859092.0,0.0,1.0,113.47,113.76,112.57,113.2,2859092.0
+2017-11-02,114.35,114.52,112.6,112.69,3405672.0,0.0,1.0,114.35,114.52,112.6,112.69,3405672.0
+2017-11-01,116.0,116.6,111.28,114.47,9639100.0,0.0,1.0,116.0,116.6,111.28,114.47,9639100.0
+2017-10-31,118.125,119.84,116.37,119.6,4762517.0,0.0,1.0,118.125,119.84,116.37,119.6,4762517.0
+2017-10-30,117.13,117.77,116.64,117.58,2599653.0,0.0,1.0,117.13,117.77,116.64,117.58,2599653.0
+2017-10-27,116.83,117.55,115.41,116.89,2883562.0,0.0,1.0,116.83,117.55,115.41,116.89,2883562.0
+2017-10-26,115.07,117.06,115.02,115.83,2443955.0,0.0,1.0,115.07,117.06,115.02,115.83,2443955.0
+2017-10-25,113.2,114.88,112.59,114.56,2963441.0,0.0,1.0,113.2,114.88,112.59,114.56,2963441.0
+2017-10-24,113.68,114.72,112.763,113.39,1847039.0,0.0,1.0,113.68,114.72,112.763,113.39,1847039.0
+2017-10-23,113.81,114.43,112.73,113.68,2060904.0,0.0,1.0,113.81,114.43,112.73,113.68,2060904.0
+2017-10-20,113.6,114.28,113.15,113.62,1921562.0,0.0,1.0,113.6,114.28,113.15,113.62,1921562.0
+2017-10-19,112.0,113.08,111.12,113.07,3023265.0,0.0,1.0,112.0,113.08,111.12,113.07,3023265.0
+2017-10-18,113.41,113.75,110.31,113.16,9671971.0,0.0,1.0,113.41,113.75,110.31,113.16,9671971.0
+2017-10-17,117.2,118.15,115.63,115.98,3116041.0,0.0,1.0,117.2,118.15,115.63,115.98,3116041.0
+2017-10-16,118.81,119.0,117.05,117.48,2581184.0,0.0,1.0,118.81,119.0,117.05,117.48,2581184.0
+2017-10-13,117.76,118.92,117.55,118.62,1883150.0,0.0,1.0,117.76,118.92,117.55,118.62,1883150.0
+2017-10-12,115.97,117.78,115.7701,117.14,2031131.0,0.0,1.0,115.97,117.78,115.7701,117.14,2031131.0
+2017-10-11,117.33,118.0,115.52,116.05,2917782.0,0.0,1.0,117.33,118.0,115.52,116.05,2917782.0
+2017-10-10,119.03,119.49,116.71,117.82,1511975.0,0.0,1.0,119.03,119.49,116.71,117.82,1511975.0
+2017-10-09,119.24,119.3,117.67,118.62,1513237.0,0.0,1.0,119.24,119.3,117.67,118.62,1513237.0
+2017-10-06,119.03,120.29,118.44,120.09,1503375.0,0.0,1.0,119.03,120.29,118.44,120.09,1503375.0
+2017-10-05,118.63,119.75,117.93,119.52,1430493.0,0.0,1.0,118.63,119.75,117.93,119.52,1430493.0
+2017-10-04,117.52,118.75,116.41,118.56,1587004.0,0.0,1.0,117.52,118.75,116.41,118.56,1587004.0
+2017-10-03,117.92,118.1,116.76,117.96,1227392.0,0.0,1.0,117.92,118.1,116.76,117.96,1227392.0
+2017-10-02,118.89,119.72,116.94,117.95,1822193.0,0.0,1.0,118.89,119.72,116.94,117.95,1822193.0
+2017-09-29,116.71,118.17,116.3,118.06,1730832.0,0.0,1.0,116.71,118.17,116.3,118.06,1730832.0
+2017-09-28,115.82,116.79,115.24,116.61,1395076.0,0.0,1.0,115.82,116.79,115.24,116.61,1395076.0
+2017-09-27,115.4,116.65,115.4,115.97,1728987.0,0.0,1.0,115.4,116.65,115.4,115.97,1728987.0
+2017-09-26,114.5,114.67,112.833,113.92,2886349.0,0.0,1.0,114.5,114.67,112.833,113.92,2886349.0
+2017-09-25,118.05,118.29,112.85,114.2,4019941.0,0.0,1.0,118.05,118.29,112.85,114.2,4019941.0
+2017-09-22,117.46,120.18,117.15,118.5,2074145.0,0.0,1.0,117.46,120.18,117.15,118.5,2074145.0
+2017-09-21,120.49,120.49,117.82,118.02,1857324.0,0.0,1.0,120.49,120.49,117.82,118.02,1857324.0
+2017-09-20,120.77,121.4,118.74,120.34,2290740.0,0.0,1.0,120.77,121.4,118.74,120.34,2290740.0
+2017-09-19,120.25,121.2,119.37,120.21,2147853.0,0.0,1.0,120.25,121.2,119.37,120.21,2147853.0
+2017-09-18,119.5,120.87,119.5,119.96,2562195.0,0.0,1.0,119.5,120.87,119.5,119.96,2562195.0
+2017-09-15,119.29,119.915,117.75,119.42,3161686.0,0.0,1.0,119.29,119.915,117.75,119.42,3161686.0
+2017-09-14,118.74,119.66,117.71,119.19,2453409.0,0.0,1.0,118.74,119.66,117.71,119.19,2453409.0
+2017-09-13,119.86,120.45,119.0,119.6,2468517.0,0.0,1.0,119.86,120.45,119.0,119.6,2468517.0
+2017-09-12,121.61,122.125,118.675,120.41,2568453.0,0.0,1.0,121.61,122.125,118.675,120.41,2568453.0
+2017-09-11,119.88,121.35,119.28,121.19,2184608.0,0.0,1.0,119.88,121.35,119.28,121.19,2184608.0
+2017-09-08,119.99,120.16,117.71,118.28,2334882.0,0.0,1.0,119.99,120.16,117.71,118.28,2334882.0
+2017-09-07,117.2,119.1,116.59,118.93,1717120.0,0.0,1.0,117.2,119.1,116.59,118.93,1717120.0
+2017-09-06,118.77,119.15,116.47,117.0,1711537.0,0.0,1.0,118.77,119.15,116.47,117.0,1711537.0
+2017-09-05,118.8,119.3,116.32,118.21,2269814.0,0.0,1.0,118.8,119.3,116.32,118.21,2269814.0
+2017-09-01,121.27,121.77,118.51,119.31,2696421.0,0.0,1.0,121.27,121.77,118.51,119.31,2696421.0
+2017-08-31,122.0,122.79,120.94,121.5,2580446.0,0.0,1.0,122.0,122.79,120.94,121.5,2580446.0
+2017-08-30,119.42,122.08,119.065,121.97,2097613.0,0.0,1.0,119.42,122.08,119.065,121.97,2097613.0
+2017-08-29,117.47,119.43,117.2201,119.23,1223068.0,0.0,1.0,117.47,119.43,117.2201,119.23,1223068.0
+2017-08-28,117.52,119.04,116.95,118.73,1756217.0,0.0,1.0,117.52,119.04,116.95,118.73,1756217.0
+2017-08-25,118.19,118.71,115.71,116.93,2155476.0,0.0,1.0,118.19,118.71,115.71,116.93,2155476.0
+2017-08-24,118.49,118.92,116.0,117.82,1303354.0,0.0,1.0,118.49,118.92,116.0,117.82,1303354.0
+2017-08-23,118.65,119.37,117.55,118.18,1235965.0,0.0,1.0,118.65,119.37,117.55,118.18,1235965.0
+2017-08-22,117.28,120.45,117.22,119.03,2476188.0,0.0,1.0,117.28,120.45,117.22,119.03,2476188.0
+2017-08-21,116.85,117.4,116.12,116.84,1479440.0,0.0,1.0,116.85,117.4,116.12,116.84,1479440.0
+2017-08-18,116.0,117.84,115.46,116.88,1906661.0,0.0,1.0,116.0,117.84,115.46,116.88,1906661.0
+2017-08-17,119.19,119.4745,116.46,116.47,1755405.0,0.0,1.0,119.19,119.4745,116.46,116.47,1755405.0
+2017-08-16,117.49,119.59,117.03,119.25,2039136.0,0.0,1.0,117.49,119.59,117.03,119.25,2039136.0
+2017-08-15,117.23,117.62,116.58,117.43,1036988.0,0.0,1.0,117.23,117.62,116.58,117.43,1036988.0
+2017-08-14,116.71,118.0,116.4,117.11,2858947.0,0.0,1.0,116.71,118.0,116.4,117.11,2858947.0
+2017-08-11,113.74,115.98,113.51,115.45,1541337.0,0.0,1.0,113.74,115.98,113.51,115.45,1541337.0
+2017-08-10,115.41,115.715,113.69,113.99,2591680.0,0.0,1.0,115.41,115.715,113.69,113.99,2591680.0
+2017-08-09,115.55,116.84,114.75,116.11,1572284.0,0.0,1.0,115.55,116.84,114.75,116.11,1572284.0
+2017-08-08,116.5,117.13,116.02,116.5,1298672.0,0.0,1.0,116.5,117.13,116.02,116.5,1298672.0
+2017-08-07,117.6,117.96,116.49,116.96,1878689.0,0.0,1.0,117.6,117.96,116.49,116.96,1878689.0
+2017-08-04,119.15,119.18,116.9,117.22,2329950.0,0.0,1.0,119.15,119.18,116.9,117.22,2329950.0
+2017-08-03,117.38,119.23,116.98,118.85,2807213.0,0.0,1.0,117.38,119.23,116.98,118.85,2807213.0
+2017-08-02,117.11,117.42,113.83,116.83,3035692.0,0.0,1.0,117.11,117.42,113.83,116.83,3035692.0
+2017-08-01,117.57,117.65,116.44,116.92,2434299.0,0.0,1.0,117.57,117.65,116.44,116.92,2434299.0
+2017-07-31,119.05,119.25,116.5,116.74,2874265.0,0.0,1.0,119.05,119.25,116.5,116.74,2874265.0
+2017-07-28,114.0,118.75,113.5,118.25,4996998.0,0.0,1.0,114.0,118.75,113.5,118.25,4996998.0
+2017-07-27,119.01,120.25,116.06,117.6,8804997.0,0.0,1.0,119.01,120.25,116.06,117.6,8804997.0
+2017-07-26,115.46,118.11,115.19,118.0,4476211.0,0.0,1.0,115.46,118.11,115.19,118.0,4476211.0
+2017-07-25,113.97,114.52,113.31,113.66,2731441.0,0.0,1.0,113.97,114.52,113.31,113.66,2731441.0
+2017-07-24,112.22,113.97,112.22,113.75,2719644.0,0.0,1.0,112.22,113.97,112.22,113.75,2719644.0
+2017-07-21,111.5,112.91,111.27,112.22,2412908.0,0.0,1.0,111.5,112.91,111.27,112.22,2412908.0
+2017-07-20,111.61,112.18,110.38,111.97,2137684.0,0.0,1.0,111.61,112.18,110.38,111.97,2137684.0
+2017-07-19,110.43,111.65,109.81,111.58,2306302.0,0.0,1.0,110.43,111.65,109.81,111.58,2306302.0
+2017-07-18,110.0,110.93,109.48,110.28,1902014.0,0.0,1.0,110.0,110.93,109.48,110.28,1902014.0
+2017-07-17,109.02,110.43,108.715,109.44,1600888.0,0.0,1.0,109.02,110.43,108.715,109.44,1600888.0
+2017-07-14,109.61,110.34,108.75,108.99,1319830.0,0.0,1.0,109.61,110.34,108.75,108.99,1319830.0
+2017-07-13,110.83,111.61,108.92,108.98,1705243.0,0.0,1.0,110.83,111.61,108.92,108.98,1705243.0
+2017-07-12,109.5,110.9,109.05,110.68,1929711.0,0.0,1.0,109.5,110.9,109.05,110.68,1929711.0
+2017-07-11,107.63,109.71,107.1001,108.42,2254636.0,0.0,1.0,107.63,109.71,107.1001,108.42,2254636.0
+2017-07-10,107.84,108.69,107.01,107.84,1829832.0,0.0,1.0,107.84,108.69,107.01,107.84,1829832.0
+2017-07-07,106.28,108.47,105.54,107.45,2113210.0,0.0,1.0,106.28,108.47,105.54,107.45,2113210.0
+2017-07-06,106.06,107.12,105.5,105.75,2418406.0,0.0,1.0,106.06,107.12,105.5,105.75,2418406.0
+2017-07-05,105.95,107.31,105.35,106.76,2790438.0,0.0,1.0,105.95,107.31,105.35,106.76,2790438.0
+2017-07-03,106.51,107.0,105.21,105.42,1656433.0,0.0,1.0,106.51,107.0,105.21,105.42,1656433.0
+2017-06-30,107.1,107.56,105.65,105.72,3193822.0,0.0,1.0,107.1,107.56,105.65,105.72,3193822.0
+2017-06-29,108.16,108.72,105.47,106.68,3801546.0,0.0,1.0,108.16,108.72,105.47,106.68,3801546.0
+2017-06-28,108.7,109.2,106.74,108.81,3666366.0,0.0,1.0,108.7,109.2,106.74,108.81,3666366.0
+2017-06-27,111.35,111.93,108.13,108.32,3051541.0,0.0,1.0,111.35,111.93,108.13,108.32,3051541.0
+2017-06-26,111.0,112.64,110.375,111.86,2433287.0,0.0,1.0,111.0,112.64,110.375,111.86,2433287.0
+2017-06-23,112.51,112.95,110.77,110.83,5488299.0,0.0,1.0,112.51,112.95,110.77,110.83,5488299.0
+2017-06-22,113.51,113.52,111.36,112.62,2233674.0,0.0,1.0,113.51,113.52,111.36,112.62,2233674.0
+2017-06-21,114.33,114.69,111.83,113.17,3048981.0,0.0,1.0,114.33,114.69,111.83,113.17,3048981.0
+2017-06-20,113.43,115.12,113.29,113.47,2694325.0,0.0,1.0,113.43,115.12,113.29,113.47,2694325.0
+2017-06-19,111.18,113.86,111.18,113.65,2863975.0,0.0,1.0,111.18,113.86,111.18,113.65,2863975.0
+2017-06-16,110.72,112.51,110.07,110.51,9457081.0,0.0,1.0,110.72,112.51,110.07,110.51,9457081.0
+2017-06-15,108.24,111.03,107.32,110.53,3062302.0,0.0,1.0,108.24,111.03,107.32,110.53,3062302.0
+2017-06-14,110.16,111.11,108.68,110.02,2161626.0,0.0,1.0,110.16,111.11,108.68,110.02,2161626.0
+2017-06-13,110.33,110.96,108.08,109.98,2727219.0,0.0,1.0,110.33,110.96,108.08,109.98,2727219.0
+2017-06-12,109.3,111.175,105.54,108.9,5802602.0,0.0,1.0,109.3,111.175,105.54,108.9,5802602.0
+2017-06-09,114.84,115.36,107.03,110.46,5712259.0,0.0,1.0,114.84,115.36,107.03,110.46,5712259.0
+2017-06-08,116.04,116.04,113.24,114.29,3268285.0,0.0,1.0,116.04,116.04,113.24,114.29,3268285.0
+2017-06-07,114.84,115.54,114.23,115.37,2466012.0,0.0,1.0,114.84,115.54,114.23,115.37,2466012.0
+2017-06-06,114.54,115.39,113.59,113.69,2492255.0,0.0,1.0,114.54,115.39,113.59,113.69,2492255.0
+2017-06-05,114.68,115.13,114.19,114.69,1858473.0,0.0,1.0,114.68,115.13,114.19,114.69,1858473.0
+2017-06-02,113.85,114.54,113.2,114.52,1867350.0,0.0,1.0,113.85,114.54,113.2,114.52,1867350.0
+2017-06-01,113.96,114.94,113.175,113.87,2226980.0,0.0,1.0,113.96,114.94,113.175,113.87,2226980.0
diff --git a/examples/quick/demos/stocqt/content/data/EBAY.csv b/examples/quick/demos/stocqt/content/data/EBAY.csv
new file mode 100644
index 0000000000..9254489791
--- /dev/null
+++ b/examples/quick/demos/stocqt/content/data/EBAY.csv
@@ -0,0 +1,148 @@
+Date,Open,High,Low,Close,Volume,Ex-Dividend,Split Ratio,Adj. Open,Adj. High,Adj. Low,Adj. Close,Adj. Volume
+2017-12-29,37.82,38.03,37.65,37.74,4476821.0,0.0,1.0,37.82,38.03,37.65,37.74,4476821.0
+2017-12-28,37.46,37.93,37.4501,37.92,3379374.0,0.0,1.0,37.46,37.93,37.4501,37.92,3379374.0
+2017-12-27,38.07,38.08,37.56,37.61,4091574.0,0.0,1.0,38.07,38.08,37.56,37.61,4091574.0
+2017-12-26,37.79,38.01,37.605,37.94,4493535.0,0.0,1.0,37.79,38.01,37.605,37.94,4493535.0
+2017-12-22,37.69,37.905,37.53,37.76,7145144.0,0.0,1.0,37.69,37.905,37.53,37.76,7145144.0
+2017-12-21,38.11,38.24,37.77,37.81,9594664.0,0.0,1.0,38.11,38.24,37.77,37.81,9594664.0
+2017-12-20,37.87,38.1,37.745,37.93,6480341.0,0.0,1.0,37.87,38.1,37.745,37.93,6480341.0
+2017-12-19,38.15,38.23,37.72,37.82,7711342.0,0.0,1.0,38.15,38.23,37.72,37.82,7711342.0
+2017-12-18,38.5,38.66,38.12,38.18,7566184.0,0.0,1.0,38.5,38.66,38.12,38.18,7566184.0
+2017-12-15,37.72,38.42,37.39,38.37,12791334.0,0.0,1.0,37.72,38.42,37.39,38.37,12791334.0
+2017-12-14,37.41,37.77,37.41,37.6,5346581.0,0.0,1.0,37.41,37.77,37.41,37.6,5346581.0
+2017-12-13,37.46,37.64,37.33,37.4,5742256.0,0.0,1.0,37.46,37.64,37.33,37.4,5742256.0
+2017-12-12,37.44,37.49,37.1,37.44,6223963.0,0.0,1.0,37.44,37.49,37.1,37.44,6223963.0
+2017-12-11,37.51,37.69,37.32,37.52,6245593.0,0.0,1.0,37.51,37.69,37.32,37.52,6245593.0
+2017-12-08,37.25,37.99,37.16,37.65,12217992.0,0.0,1.0,37.25,37.99,37.16,37.65,12217992.0
+2017-12-07,36.72,37.15,36.5,36.85,7364150.0,0.0,1.0,36.72,37.15,36.5,36.85,7364150.0
+2017-12-06,36.64,36.91,36.36,36.83,8813063.0,0.0,1.0,36.64,36.91,36.36,36.83,8813063.0
+2017-12-05,35.94,37.19,35.75,36.81,18630500.0,0.0,1.0,35.94,37.19,35.75,36.81,18630500.0
+2017-12-04,35.58,36.08,35.38,35.7,11046784.0,0.0,1.0,35.58,36.08,35.38,35.7,11046784.0
+2017-12-01,34.38,35.25,34.31,35.2,11236547.0,0.0,1.0,34.38,35.25,34.31,35.2,11236547.0
+2017-11-30,34.48,35.19,34.4612,34.67,16173978.0,0.0,1.0,34.48,35.19,34.4612,34.67,16173978.0
+2017-11-29,35.42,35.45,33.945,34.38,21446119.0,0.0,1.0,35.42,35.45,33.945,34.38,21446119.0
+2017-11-28,35.99,36.2,35.42,35.5,10191191.0,0.0,1.0,35.99,36.2,35.42,35.5,10191191.0
+2017-11-27,35.88,36.2,35.7905,35.99,6981252.0,0.0,1.0,35.88,36.2,35.7905,35.99,6981252.0
+2017-11-24,36.07,36.11,35.7,35.84,3123070.0,0.0,1.0,36.07,36.11,35.7,35.84,3123070.0
+2017-11-22,36.05,36.195,35.84,35.94,4563054.0,0.0,1.0,36.05,36.195,35.84,35.94,4563054.0
+2017-11-21,35.72,36.11,35.56,35.96,5807385.0,0.0,1.0,35.72,36.11,35.56,35.96,5807385.0
+2017-11-20,35.62,35.97,35.42,35.53,5964478.0,0.0,1.0,35.62,35.97,35.42,35.53,5964478.0
+2017-11-17,35.64,35.71,35.31,35.58,7458295.0,0.0,1.0,35.64,35.71,35.31,35.58,7458295.0
+2017-11-16,35.37,35.815,35.32,35.62,7632669.0,0.0,1.0,35.37,35.815,35.32,35.62,7632669.0
+2017-11-15,35.03,35.47,34.79,35.3,7871444.0,0.0,1.0,35.03,35.47,34.79,35.3,7871444.0
+2017-11-14,35.71,35.79,35.18,35.22,10858859.0,0.0,1.0,35.71,35.79,35.18,35.22,10858859.0
+2017-11-13,35.7,36.1,35.32,35.85,7047371.0,0.0,1.0,35.7,36.1,35.32,35.85,7047371.0
+2017-11-10,35.51,36.045,35.34,35.97,8276878.0,0.0,1.0,35.51,36.045,35.34,35.97,8276878.0
+2017-11-09,36.26,36.36,35.21,35.69,16766871.0,0.0,1.0,36.26,36.36,35.21,35.69,16766871.0
+2017-11-07,37.6,37.6,37.1,37.41,5564092.0,0.0,1.0,37.6,37.6,37.1,37.41,5564092.0
+2017-11-06,37.38,37.61,37.3,37.37,4338972.0,0.0,1.0,37.38,37.61,37.3,37.37,4338972.0
+2017-11-03,37.44,37.545,37.11,37.5,5708840.0,0.0,1.0,37.44,37.545,37.11,37.5,5708840.0
+2017-11-02,37.49,37.5,36.995,37.4,5341879.0,0.0,1.0,37.49,37.5,36.995,37.4,5341879.0
+2017-11-01,37.85,38.09,37.435,37.54,7052554.0,0.0,1.0,37.85,38.09,37.435,37.54,7052554.0
+2017-10-31,37.11,37.68,37.02,37.64,6678430.0,0.0,1.0,37.11,37.68,37.02,37.64,6678430.0
+2017-10-30,36.86,37.13,36.74,37.0,7988838.0,0.0,1.0,36.86,37.13,36.74,37.0,7988838.0
+2017-10-27,37.07,37.36,36.635,36.8,10660803.0,0.0,1.0,37.07,37.36,36.635,36.8,10660803.0
+2017-10-26,36.74,37.24,36.72,36.9,7622668.0,0.0,1.0,36.74,37.24,36.72,36.9,7622668.0
+2017-10-25,36.66,36.92,36.45,36.68,7839488.0,0.0,1.0,36.66,36.92,36.45,36.68,7839488.0
+2017-10-24,36.51,37.03,36.51,36.74,8439952.0,0.0,1.0,36.51,37.03,36.51,36.74,8439952.0
+2017-10-23,37.66,37.85,36.74,36.83,10318056.0,0.0,1.0,37.66,37.85,36.74,36.83,10318056.0
+2017-10-20,37.34,37.86,37.3,37.61,14821200.0,0.0,1.0,37.34,37.86,37.3,37.61,14821200.0
+2017-10-19,36.48,37.49,36.19,37.29,28992713.0,0.0,1.0,36.48,37.49,36.19,37.29,28992713.0
+2017-10-18,37.68,38.22,37.54,37.97,13424086.0,0.0,1.0,37.68,38.22,37.54,37.97,13424086.0
+2017-10-17,37.76,37.84,37.42,37.49,11904108.0,0.0,1.0,37.76,37.84,37.42,37.49,11904108.0
+2017-10-16,38.29,38.5,37.725,37.77,8645585.0,0.0,1.0,38.29,38.5,37.725,37.77,8645585.0
+2017-10-13,38.35,38.53,38.16,38.35,9392998.0,0.0,1.0,38.35,38.53,38.16,38.35,9392998.0
+2017-10-12,38.31,38.5,38.055,38.09,10020870.0,0.0,1.0,38.31,38.5,38.055,38.09,10020870.0
+2017-10-11,38.85,38.98,38.17,38.31,10841024.0,0.0,1.0,38.85,38.98,38.17,38.31,10841024.0
+2017-10-10,39.02,39.275,38.77,38.84,5998658.0,0.0,1.0,39.02,39.275,38.77,38.84,5998658.0
+2017-10-09,38.8,39.265,38.8,38.99,4982743.0,0.0,1.0,38.8,39.265,38.8,38.99,4982743.0
+2017-10-06,39.05,39.08,38.67,38.81,6947721.0,0.0,1.0,39.05,39.08,38.67,38.81,6947721.0
+2017-10-05,38.76,39.035,38.675,38.99,5155812.0,0.0,1.0,38.76,39.035,38.675,38.99,5155812.0
+2017-10-04,38.8,38.83,38.5,38.66,5590600.0,0.0,1.0,38.8,38.83,38.5,38.66,5590600.0
+2017-10-03,38.78,39.05,38.485,38.71,5103669.0,0.0,1.0,38.78,39.05,38.485,38.71,5103669.0
+2017-10-02,38.51,38.78,38.37,38.73,7220120.0,0.0,1.0,38.51,38.78,38.37,38.73,7220120.0
+2017-09-29,37.73,38.6,37.71,38.46,9573477.0,0.0,1.0,37.73,38.6,37.71,38.46,9573477.0
+2017-09-28,37.44,37.96,37.44,37.73,7683377.0,0.0,1.0,37.44,37.96,37.44,37.73,7683377.0
+2017-09-27,38.03,38.29,37.76,38.05,9331736.0,0.0,1.0,38.03,38.29,37.76,38.05,9331736.0
+2017-09-26,37.85,38.19,37.75,37.85,5348200.0,0.0,1.0,37.85,38.19,37.75,37.85,5348200.0
+2017-09-25,38.22,38.31,37.54,37.78,7053896.0,0.0,1.0,38.22,38.31,37.54,37.78,7053896.0
+2017-09-22,38.13,38.31,38.05,38.29,4851365.0,0.0,1.0,38.13,38.31,38.05,38.29,4851365.0
+2017-09-21,38.55,38.67,38.19,38.25,5673772.0,0.0,1.0,38.55,38.67,38.19,38.25,5673772.0
+2017-09-20,38.67,38.87,38.21,38.54,5703686.0,0.0,1.0,38.67,38.87,38.21,38.54,5703686.0
+2017-09-19,38.5,38.75,38.32,38.59,5131286.0,0.0,1.0,38.5,38.75,38.32,38.59,5131286.0
+2017-09-18,38.3,38.665,38.18,38.39,5127823.0,0.0,1.0,38.3,38.665,38.18,38.39,5127823.0
+2017-09-15,38.27,38.865,38.07,38.4,10869179.0,0.0,1.0,38.27,38.865,38.07,38.4,10869179.0
+2017-09-14,38.24,38.585,38.13,38.31,6478656.0,0.0,1.0,38.24,38.585,38.13,38.31,6478656.0
+2017-09-13,38.0,38.5,38.0,38.27,4960915.0,0.0,1.0,38.0,38.5,38.0,38.27,4960915.0
+2017-09-12,38.07,38.3,37.98,38.18,4170327.0,0.0,1.0,38.07,38.3,37.98,38.18,4170327.0
+2017-09-11,38.04,38.26,38.0,38.09,5945142.0,0.0,1.0,38.04,38.26,38.0,38.09,5945142.0
+2017-09-08,38.04,38.3,37.725,37.79,9052735.0,0.0,1.0,38.04,38.3,37.725,37.79,9052735.0
+2017-09-07,36.95,38.19,36.84,38.01,13980230.0,0.0,1.0,36.95,38.19,36.84,38.01,13980230.0
+2017-09-06,36.08,36.98,36.08,36.76,12653446.0,0.0,1.0,36.08,36.98,36.08,36.76,12653446.0
+2017-09-05,36.19,36.48,35.77,36.09,6296438.0,0.0,1.0,36.19,36.48,35.77,36.09,6296438.0
+2017-09-01,36.2,36.58,36.14,36.35,5037396.0,0.0,1.0,36.2,36.58,36.14,36.35,5037396.0
+2017-08-31,35.85,36.32,35.821,36.13,8522717.0,0.0,1.0,35.85,36.32,35.821,36.13,8522717.0
+2017-08-30,35.14,35.955,35.1,35.69,8205167.0,0.0,1.0,35.14,35.955,35.1,35.69,8205167.0
+2017-08-29,34.48,35.315,34.42,35.2,7089389.0,0.0,1.0,34.48,35.315,34.42,35.2,7089389.0
+2017-08-28,34.75,34.9,34.66,34.81,5005834.0,0.0,1.0,34.75,34.9,34.66,34.81,5005834.0
+2017-08-25,34.98,35.07,34.56,34.68,6720164.0,0.0,1.0,34.98,35.07,34.56,34.68,6720164.0
+2017-08-24,34.86,35.04,34.51,34.88,5638387.0,0.0,1.0,34.86,35.04,34.51,34.88,5638387.0
+2017-08-23,34.62,34.98,34.51,34.89,6295975.0,0.0,1.0,34.62,34.98,34.51,34.89,6295975.0
+2017-08-22,34.37,34.81,34.31,34.81,6144284.0,0.0,1.0,34.37,34.81,34.31,34.81,6144284.0
+2017-08-21,35.13,35.13,34.09,34.24,7592681.0,0.0,1.0,35.13,35.13,34.09,34.24,7592681.0
+2017-08-18,34.83,35.14,34.75,34.79,8521640.0,0.0,1.0,34.83,35.14,34.75,34.79,8521640.0
+2017-08-17,35.5,35.5,34.8,34.85,6290987.0,0.0,1.0,35.5,35.5,34.8,34.85,6290987.0
+2017-08-16,35.23,35.48,35.07,35.36,3809705.0,0.0,1.0,35.23,35.48,35.07,35.36,3809705.0
+2017-08-15,35.24,35.42,35.12,35.25,4487094.0,0.0,1.0,35.24,35.42,35.12,35.25,4487094.0
+2017-08-14,35.44,35.45,34.88,35.2,6932178.0,0.0,1.0,35.44,35.45,34.88,35.2,6932178.0
+2017-08-11,35.16,35.32,34.76,35.05,7688311.0,0.0,1.0,35.16,35.32,34.76,35.05,7688311.0
+2017-08-10,35.95,35.9845,34.88,35.0,12151126.0,0.0,1.0,35.95,35.9845,34.88,35.0,12151126.0
+2017-08-09,36.13,36.225,35.72,36.08,7540671.0,0.0,1.0,36.13,36.225,35.72,36.08,7540671.0
+2017-08-08,35.96,36.64,35.89,36.36,9441402.0,0.0,1.0,35.96,36.64,35.89,36.36,9441402.0
+2017-08-07,35.61,36.15,35.38,36.11,5309161.0,0.0,1.0,35.61,36.15,35.38,36.11,5309161.0
+2017-08-04,35.86,35.86,35.55,35.62,5036090.0,0.0,1.0,35.86,35.86,35.55,35.62,5036090.0
+2017-08-03,35.97,35.98,35.57,35.71,5592728.0,0.0,1.0,35.97,35.98,35.57,35.71,5592728.0
+2017-08-02,35.69,35.95,35.42,35.9,6395959.0,0.0,1.0,35.69,35.95,35.42,35.9,6395959.0
+2017-08-01,35.82,36.02,35.75,35.91,4598532.0,0.0,1.0,35.82,36.02,35.75,35.91,4598532.0
+2017-07-31,36.09,36.13,35.65,35.73,6117033.0,0.0,1.0,36.09,36.13,35.65,35.73,6117033.0
+2017-07-28,36.08,36.21,35.73,35.94,7097225.0,0.0,1.0,36.08,36.21,35.73,35.94,7097225.0
+2017-07-27,37.09,37.265,35.54,36.17,15261765.0,0.0,1.0,37.09,37.265,35.54,36.17,15261765.0
+2017-07-26,36.36,37.07,36.36,37.04,10987896.0,0.0,1.0,36.36,37.07,36.36,37.04,10987896.0
+2017-07-25,36.33,36.485,36.06,36.32,6191010.0,0.0,1.0,36.33,36.485,36.06,36.32,6191010.0
+2017-07-24,36.45,36.73,36.22,36.39,9661599.0,0.0,1.0,36.45,36.73,36.22,36.39,9661599.0
+2017-07-21,36.2,36.9,36.05,36.61,22131224.0,0.0,1.0,36.2,36.9,36.05,36.61,22131224.0
+2017-07-20,37.17,37.48,37.0,37.18,13467628.0,0.0,1.0,37.17,37.48,37.0,37.18,13467628.0
+2017-07-19,36.95,37.26,36.645,37.08,8510278.0,0.0,1.0,36.95,37.26,36.645,37.08,8510278.0
+2017-07-18,36.94,36.94,36.57,36.8,12755207.0,0.0,1.0,36.94,36.94,36.57,36.8,12755207.0
+2017-07-17,37.03,37.17,36.57,37.05,8151725.0,0.0,1.0,37.03,37.17,36.57,37.05,8151725.0
+2017-07-14,36.91,37.2,36.83,37.08,9654192.0,0.0,1.0,36.91,37.2,36.83,37.08,9654192.0
+2017-07-13,36.61,37.13,36.26,36.5,12877614.0,0.0,1.0,36.61,37.13,36.26,36.5,12877614.0
+2017-07-12,35.53,36.2,35.53,36.03,13411174.0,0.0,1.0,35.53,36.2,35.53,36.03,13411174.0
+2017-07-11,34.97,35.45,34.89,35.19,8306962.0,0.0,1.0,34.97,35.45,34.89,35.19,8306962.0
+2017-07-10,34.31,35.14,34.28,35.04,8695234.0,0.0,1.0,34.31,35.14,34.28,35.04,8695234.0
+2017-07-07,34.02,34.55,34.01,34.23,6747508.0,0.0,1.0,34.02,34.55,34.01,34.23,6747508.0
+2017-07-06,34.39,34.5,33.95,34.03,8551358.0,0.0,1.0,34.39,34.5,33.95,34.03,8551358.0
+2017-07-05,34.73,34.86,34.505,34.72,7381884.0,0.0,1.0,34.73,34.86,34.505,34.72,7381884.0
+2017-07-03,35.15,35.305,34.55,34.6,4517402.0,0.0,1.0,35.15,35.305,34.55,34.6,4517402.0
+2017-06-30,34.78,35.07,34.52,34.92,10561065.0,0.0,1.0,34.78,35.07,34.52,34.92,10561065.0
+2017-06-29,35.3,35.3,34.09,34.51,8166989.0,0.0,1.0,35.3,35.3,34.09,34.51,8166989.0
+2017-06-28,35.0,35.33,34.615,35.31,4791632.0,0.0,1.0,35.0,35.33,34.615,35.31,4791632.0
+2017-06-27,35.0,35.32,34.85,34.91,8598433.0,0.0,1.0,35.0,35.32,34.85,34.91,8598433.0
+2017-06-26,35.89,35.97,35.0,35.09,6634019.0,0.0,1.0,35.89,35.97,35.0,35.09,6634019.0
+2017-06-23,35.12,35.735,34.96,35.58,8872359.0,0.0,1.0,35.12,35.735,34.96,35.58,8872359.0
+2017-06-22,34.99,35.285,34.84,35.12,5120718.0,0.0,1.0,34.99,35.285,34.84,35.12,5120718.0
+2017-06-21,35.0,35.12,34.75,34.96,5400949.0,0.0,1.0,35.0,35.12,34.75,34.96,5400949.0
+2017-06-20,34.74,35.34,34.74,34.93,10506559.0,0.0,1.0,34.74,35.34,34.74,34.93,10506559.0
+2017-06-19,34.12,34.99,34.0,34.9,5760279.0,0.0,1.0,34.12,34.99,34.0,34.9,5760279.0
+2017-06-16,33.92,34.32,33.91,33.96,9640312.0,0.0,1.0,33.92,34.32,33.91,33.96,9640312.0
+2017-06-15,34.26,34.29,33.89,34.09,5344405.0,0.0,1.0,34.26,34.29,33.89,34.09,5344405.0
+2017-06-14,34.63,34.73,34.11,34.5,6371265.0,0.0,1.0,34.63,34.73,34.11,34.5,6371265.0
+2017-06-13,34.21,34.55,34.08,34.47,7302410.0,0.0,1.0,34.21,34.55,34.08,34.47,7302410.0
+2017-06-12,34.7,34.77,33.975,34.15,12807616.0,0.0,1.0,34.7,34.77,33.975,34.15,12807616.0
+2017-06-09,36.25,36.5,34.69,34.94,10974043.0,0.0,1.0,36.25,36.5,34.69,34.94,10974043.0
+2017-06-08,36.07,36.315,35.865,36.14,8767604.0,0.0,1.0,36.07,36.315,35.865,36.14,8767604.0
+2017-06-07,35.65,35.87,35.56,35.77,5280007.0,0.0,1.0,35.65,35.87,35.56,35.77,5280007.0
+2017-06-06,35.41,35.805,35.35,35.47,5463513.0,0.0,1.0,35.41,35.805,35.35,35.47,5463513.0
+2017-06-05,36.02,36.02,35.39,35.55,5946671.0,0.0,1.0,36.02,36.02,35.39,35.55,5946671.0
+2017-06-02,34.92,35.44,34.61,35.32,6843000.0,0.0,1.0,34.92,35.44,34.61,35.32,6843000.0
+2017-06-01,34.44,34.89,34.2,34.79,6463818.0,0.0,1.0,34.44,34.89,34.2,34.79,6463818.0
diff --git a/examples/quick/demos/stocqt/content/data/FB.csv b/examples/quick/demos/stocqt/content/data/FB.csv
new file mode 100644
index 0000000000..d9ebf9eeba
--- /dev/null
+++ b/examples/quick/demos/stocqt/content/data/FB.csv
@@ -0,0 +1,148 @@
+Date,Open,High,Low,Close,Volume,Ex-Dividend,Split Ratio,Adj. Open,Adj. High,Adj. Low,Adj. Close,Adj. Volume
+2017-12-29,178.0,178.85,176.46,176.46,10028758.0,0.0,1.0,178.0,178.85,176.46,176.46,10028758.0
+2017-12-28,177.95,178.9367,177.68,177.92,11008996.0,0.0,1.0,177.95,178.9367,177.68,177.92,11008996.0
+2017-12-27,176.55,178.44,176.26,177.62,9296258.0,0.0,1.0,176.55,178.44,176.26,177.62,9296258.0
+2017-12-26,176.63,177.0,174.67,175.99,8726829.0,0.0,1.0,176.63,177.0,174.67,175.99,8726829.0
+2017-12-22,177.14,177.53,176.23,177.2,8462491.0,0.0,1.0,177.14,177.53,176.23,177.2,8462491.0
+2017-12-21,177.94,178.68,177.05,177.45,11050969.0,0.0,1.0,177.94,178.68,177.05,177.45,11050969.0
+2017-12-20,179.81,179.81,177.36,177.89,11754823.0,0.0,1.0,179.81,179.81,177.36,177.89,11754823.0
+2017-12-19,179.95,180.08,178.22,179.51,14769239.0,0.0,1.0,179.95,180.08,178.22,179.51,14769239.0
+2017-12-18,181.01,181.3,179.75,180.82,17014337.0,0.0,1.0,181.01,181.3,179.75,180.82,17014337.0
+2017-12-15,179.02,180.4934,178.36,180.18,26225100.0,0.0,1.0,179.02,180.4934,178.36,180.18,26225100.0
+2017-12-14,178.29,180.3601,177.68,178.39,13393757.0,0.0,1.0,178.29,180.3601,177.68,178.39,13393757.0
+2017-12-13,177.3,179.16,177.25,178.3,14406776.0,0.0,1.0,177.3,179.16,177.25,178.3,14406776.0
+2017-12-12,178.6,179.18,176.6,176.96,16675275.0,0.0,1.0,178.6,179.18,176.6,176.96,16675275.0
+2017-12-11,179.3,180.22,178.8,179.04,12630207.0,0.0,1.0,179.3,180.22,178.8,179.04,12630207.0
+2017-12-08,181.53,182.28,178.7401,179.0,19377310.0,0.0,1.0,181.53,182.28,178.7401,179.0,19377310.0
+2017-12-07,175.8,180.39,175.8,180.14,19588217.0,0.0,1.0,175.8,180.39,175.8,180.14,19588217.0
+2017-12-06,172.5,176.77,171.9,176.06,20059293.0,0.0,1.0,172.5,176.77,171.9,176.06,20059293.0
+2017-12-05,170.45,175.38,169.01,172.83,20028656.0,0.0,1.0,170.45,175.38,169.01,172.83,20028656.0
+2017-12-04,176.29,176.57,170.79,171.47,24184006.0,0.0,1.0,176.29,176.57,170.79,171.47,24184006.0
+2017-12-01,176.03,177.48,172.34,175.1,19824531.0,0.0,1.0,176.03,177.48,172.34,175.1,19824531.0
+2017-11-30,176.85,178.275,175.2,177.18,24613431.0,0.0,1.0,176.85,178.275,175.2,177.18,24613431.0
+2017-11-29,181.89,181.97,174.0,175.13,41651953.0,0.0,1.0,181.89,181.97,174.0,175.13,41651953.0
+2017-11-28,183.51,184.25,182.09,182.42,13761926.0,0.0,1.0,183.51,184.25,182.09,182.42,13761926.0
+2017-11-27,182.56,183.73,181.99,183.03,12249740.0,0.0,1.0,182.56,183.73,181.99,183.03,12249740.0
+2017-11-24,180.4,183.15,180.29,182.78,9426010.0,0.0,1.0,180.4,183.15,180.29,182.78,9426010.0
+2017-11-22,181.3,181.73,180.44,180.87,10238140.0,0.0,1.0,181.3,181.73,180.44,180.87,10238140.0
+2017-11-21,179.15,181.89,178.99,181.86,14409305.0,0.0,1.0,179.15,181.89,178.99,181.86,14409305.0
+2017-11-20,178.87,179.5,178.1,178.74,9476502.0,0.0,1.0,178.87,179.5,178.1,178.74,9476502.0
+2017-11-17,179.3,179.98,178.9,179.0,12722802.0,0.0,1.0,179.3,179.98,178.9,179.0,12722802.0
+2017-11-16,178.76,179.83,178.5,179.59,14655982.0,0.0,1.0,178.76,179.83,178.5,179.59,14655982.0
+2017-11-15,176.66,178.57,176.4,177.95,10131051.0,0.0,1.0,176.66,178.57,176.4,177.95,10131051.0
+2017-11-14,178.13,178.97,177.18,178.07,9465112.0,0.0,1.0,178.13,178.97,177.18,178.07,9465112.0
+2017-11-13,177.5,179.04,177.3,178.77,9431449.0,0.0,1.0,177.5,179.04,177.3,178.77,9431449.0
+2017-11-10,178.35,179.0999,177.96,178.46,10933405.0,0.0,1.0,178.35,179.0999,177.96,178.46,10933405.0
+2017-11-09,178.31,179.4,177.09,179.3,12460345.0,0.0,1.0,178.31,179.4,177.09,179.3,12460345.0
+2017-11-07,180.5,180.7478,178.96,180.25,12679885.0,0.0,1.0,180.5,180.7478,178.96,180.25,12679885.0
+2017-11-06,178.56,180.45,178.31,180.17,13065077.0,0.0,1.0,178.56,180.45,178.31,180.17,13065077.0
+2017-11-03,179.29,179.86,176.71,178.92,17572587.0,0.0,1.0,179.29,179.86,176.71,178.92,17572587.0
+2017-11-02,180.63,181.94,177.34,178.92,35119841.0,0.0,1.0,180.63,181.94,177.34,178.92,35119841.0
+2017-11-01,182.36,182.9,180.57,182.66,28922959.0,0.0,1.0,182.36,182.9,180.57,182.66,28922959.0
+2017-10-31,180.57,180.8,178.94,180.06,19766043.0,0.0,1.0,180.57,180.8,178.94,180.06,19766043.0
+2017-10-30,179.26,180.69,177.61,179.87,24179258.0,0.0,1.0,179.26,180.69,177.61,179.87,24179258.0
+2017-10-27,174.15,178.21,173.9,177.88,29867490.0,0.0,1.0,174.15,178.21,173.9,177.88,29867490.0
+2017-10-26,171.38,172.285,170.39,170.63,10932929.0,0.0,1.0,171.38,172.285,170.39,170.63,10932929.0
+2017-10-25,171.9,172.25,168.89,170.6,15095603.0,0.0,1.0,171.9,172.25,168.89,170.6,15095603.0
+2017-10-24,172.3,173.24,171.5,171.8,11629341.0,0.0,1.0,172.3,173.24,171.5,171.8,11629341.0
+2017-10-23,175.2,175.34,171.25,171.27,13622072.0,0.0,1.0,175.2,175.34,171.25,171.27,13622072.0
+2017-10-20,175.5,175.88,174.63,174.98,11861307.0,0.0,1.0,175.5,175.88,174.63,174.98,11861307.0
+2017-10-19,174.93,176.03,172.63,174.56,13602869.0,0.0,1.0,174.93,176.03,172.63,174.56,13602869.0
+2017-10-18,176.65,176.74,175.75,176.03,12655492.0,0.0,1.0,176.65,176.74,175.75,176.03,12655492.0
+2017-10-17,174.71,176.13,174.36,176.11,15381990.0,0.0,1.0,174.71,176.13,174.36,176.11,15381990.0
+2017-10-16,174.49,175.0,174.06,174.52,11225293.0,0.0,1.0,174.49,175.0,174.06,174.52,11225293.0
+2017-10-13,173.45,174.65,173.2,173.74,13305724.0,0.0,1.0,173.45,174.65,173.2,173.74,13305724.0
+2017-10-12,172.61,173.85,172.29,172.55,10312488.0,0.0,1.0,172.61,173.85,172.29,172.55,10312488.0
+2017-10-11,171.95,172.78,171.4,172.74,11023310.0,0.0,1.0,171.95,172.78,171.4,172.74,11023310.0
+2017-10-10,173.0,173.2,170.8,171.59,11231234.0,0.0,1.0,173.0,173.2,170.8,171.59,11231234.0
+2017-10-09,172.7,174.88,172.0,172.5,14472612.0,0.0,1.0,172.7,174.88,172.0,172.5,14472612.0
+2017-10-06,170.25,172.37,169.75,172.23,12670089.0,0.0,1.0,170.25,172.37,169.75,172.23,12670089.0
+2017-10-05,169.18,171.31,168.6,171.24,14013869.0,0.0,1.0,169.18,171.31,168.6,171.24,14013869.0
+2017-10-04,169.83,170.67,168.29,168.42,11829323.0,0.0,1.0,169.83,170.67,168.29,168.42,11829323.0
+2017-10-03,169.3,170.73,169.2,169.96,8054219.0,0.0,1.0,169.3,170.73,169.2,169.96,8054219.0
+2017-10-02,171.39,171.87,168.75,169.47,13104304.0,0.0,1.0,171.39,171.87,168.75,169.47,13104304.0
+2017-09-29,168.83,171.66,168.81,170.81,15114619.0,0.0,1.0,168.83,171.66,168.81,170.81,15114619.0
+2017-09-28,167.94,169.0696,167.16,168.73,12084865.0,0.0,1.0,167.94,169.0696,167.16,168.73,12084865.0
+2017-09-27,165.9,168.34,165.57,167.68,18963276.0,0.0,1.0,165.9,168.34,165.57,167.68,18963276.0
+2017-09-26,164.5,165.5,162.78,164.21,22866403.0,0.0,1.0,164.5,165.5,162.78,164.21,22866403.0
+2017-09-25,169.24,169.3,161.56,162.87,40538994.0,0.0,1.0,169.24,169.3,161.56,162.87,40538994.0
+2017-09-22,170.21,171.73,169.22,170.54,11835708.0,0.0,1.0,170.21,171.73,169.22,170.54,11835708.0
+2017-09-21,171.69,172.27,170.01,171.11,11054545.0,0.0,1.0,171.69,172.27,170.01,171.11,11054545.0
+2017-09-20,172.5,173.05,170.7,172.17,11899057.0,0.0,1.0,172.5,173.05,170.7,172.17,11899057.0
+2017-09-19,170.62,172.56,170.36,172.52,12911661.0,0.0,1.0,170.62,172.56,170.36,172.52,12911661.0
+2017-09-18,171.99,172.07,169.34,170.01,12785437.0,0.0,1.0,171.99,172.07,169.34,170.01,12785437.0
+2017-09-15,170.88,172.34,170.26,171.58,15468473.0,0.0,1.0,170.88,172.34,170.26,171.58,15468473.0
+2017-09-14,172.26,172.28,170.5,170.96,15496424.0,0.0,1.0,172.26,172.28,170.5,170.96,15496424.0
+2017-09-13,173.01,173.17,172.06,173.05,8908633.0,0.0,1.0,173.01,173.17,172.06,173.05,8908633.0
+2017-09-12,173.76,174.0,171.75,172.96,11051768.0,0.0,1.0,173.76,174.0,171.75,172.96,11051768.0
+2017-09-11,172.4,173.89,172.2,173.51,12183568.0,0.0,1.0,172.4,173.89,172.2,173.51,12183568.0
+2017-09-08,173.09,173.49,170.8,170.95,10936358.0,0.0,1.0,173.09,173.49,170.8,170.95,10936358.0
+2017-09-07,171.94,173.3067,170.27,173.21,17922494.0,0.0,1.0,171.94,173.3067,170.27,173.21,17922494.0
+2017-09-06,170.91,172.48,169.57,172.09,13659317.0,0.0,1.0,170.91,172.48,169.57,172.09,13659317.0
+2017-09-05,171.27,172.3875,169.55,170.72,13175866.0,0.0,1.0,171.27,172.3875,169.55,170.72,13175866.0
+2017-09-01,172.4,172.915,171.31,172.02,11614185.0,0.0,1.0,172.4,172.915,171.31,172.02,11614185.0
+2017-08-31,170.4,172.145,170.06,172.0,16873901.0,0.0,1.0,170.4,172.145,170.06,172.0,16873901.0
+2017-08-30,168.17,170.18,167.63,169.92,10850005.0,0.0,1.0,168.17,170.18,167.63,169.92,10850005.0
+2017-08-29,165.25,168.425,165.0,168.05,10992617.0,0.0,1.0,165.25,168.425,165.0,168.05,10992617.0
+2017-08-28,166.91,167.7,166.33,167.24,8360380.0,0.0,1.0,166.91,167.7,166.33,167.24,8360380.0
+2017-08-25,167.86,168.38,166.18,166.32,12391910.0,0.0,1.0,167.86,168.38,166.18,166.32,12391910.0
+2017-08-24,168.88,169.29,166.41,167.74,13552865.0,0.0,1.0,168.88,169.29,166.41,167.74,13552865.0
+2017-08-23,168.84,169.36,168.2,168.71,9756817.0,0.0,1.0,168.84,169.36,168.2,168.71,9756817.0
+2017-08-22,168.28,169.87,167.15,169.64,11333260.0,0.0,1.0,168.28,169.87,167.15,169.64,11333260.0
+2017-08-21,167.16,168.0,165.82,167.78,11880823.0,0.0,1.0,167.16,168.0,165.82,167.78,11880823.0
+2017-08-18,166.84,168.67,166.21,167.41,14933261.0,0.0,1.0,166.84,168.67,166.21,167.41,14933261.0
+2017-08-17,169.34,169.86,166.85,166.91,16791591.0,0.0,1.0,169.34,169.86,166.85,166.91,16791591.0
+2017-08-16,171.25,171.38,169.24,170.0,15580549.0,0.0,1.0,171.25,171.38,169.24,170.0,15580549.0
+2017-08-15,171.49,171.5,170.01,171.0,8621787.0,0.0,1.0,171.49,171.5,170.01,171.0,8621787.0
+2017-08-14,170.09,171.08,169.29,170.75,12786286.0,0.0,1.0,170.09,171.08,169.29,170.75,12786286.0
+2017-08-11,167.95,168.82,166.85,168.08,13664032.0,0.0,1.0,167.95,168.82,166.85,168.08,13664032.0
+2017-08-10,170.06,170.59,166.85,167.4,20353485.0,0.0,1.0,170.06,170.59,166.85,167.4,20353485.0
+2017-08-09,169.98,171.45,169.56,171.18,10597084.0,0.0,1.0,169.98,171.45,169.56,171.18,10597084.0
+2017-08-08,171.88,173.05,170.62,171.23,13813683.0,0.0,1.0,171.88,173.05,170.62,171.23,13813683.0
+2017-08-07,169.95,172.06,169.66,171.98,12504157.0,0.0,1.0,169.95,172.06,169.66,171.98,12504157.0
+2017-08-04,168.97,170.06,168.69,169.62,10360774.0,0.0,1.0,168.97,170.06,168.69,169.62,10360774.0
+2017-08-03,169.3,169.7,168.25,168.59,10316246.0,0.0,1.0,169.3,169.7,168.25,168.59,10316246.0
+2017-08-02,170.3,170.55,166.91,169.25,17061845.0,0.0,1.0,170.3,170.55,166.91,169.25,17061845.0
+2017-08-01,169.82,170.47,169.05,169.86,14051379.0,0.0,1.0,169.82,170.47,169.05,169.86,14051379.0
+2017-07-31,172.0,172.72,168.55,169.25,25157896.0,0.0,1.0,172.0,172.72,168.55,169.25,25157896.0
+2017-07-28,169.07,173.43,169.05,172.45,24036502.0,0.0,1.0,169.07,173.43,169.05,172.45,24036502.0
+2017-07-27,174.7,175.49,167.5,170.44,68065163.0,0.0,1.0,174.7,175.49,167.5,170.44,68065163.0
+2017-07-26,166.01,166.01,164.1,165.61,24081060.0,0.0,1.0,166.01,166.01,164.1,165.61,24081060.0
+2017-07-25,165.01,165.54,163.8619,165.28,15164613.0,0.0,1.0,165.01,165.54,163.8619,165.28,15164613.0
+2017-07-24,164.64,166.17,164.31,166.0,16595460.0,0.0,1.0,164.64,166.17,164.31,166.0,16595460.0
+2017-07-21,164.16,165.05,163.75,164.43,14494667.0,0.0,1.0,164.16,165.05,163.75,164.43,14494667.0
+2017-07-20,164.8,165.0,162.81,164.53,18293111.0,0.0,1.0,164.8,165.0,162.81,164.53,18293111.0
+2017-07-19,163.59,165.7,163.17,164.14,25915988.0,0.0,1.0,163.59,165.7,163.17,164.14,25915988.0
+2017-07-18,159.66,163.73,159.42,162.86,23621711.0,0.0,1.0,159.66,163.73,159.42,162.86,23621711.0
+2017-07-17,160.25,160.78,158.81,159.73,12567935.0,0.0,1.0,160.25,160.78,158.81,159.73,12567935.0
+2017-07-14,160.13,160.32,159.3254,159.97,16172560.0,0.0,1.0,160.13,160.32,159.3254,159.97,16172560.0
+2017-07-13,158.74,159.78,158.4227,159.26,13839891.0,0.0,1.0,158.74,159.78,158.4227,159.26,13839891.0
+2017-07-12,156.49,159.16,156.2,158.9,22483868.0,0.0,1.0,156.49,159.16,156.2,158.9,22483868.0
+2017-07-11,153.37,155.4225,152.91,155.27,13208251.0,0.0,1.0,153.37,155.4225,152.91,155.27,13208251.0
+2017-07-10,151.69,153.98,151.51,153.5,13296447.0,0.0,1.0,151.69,153.98,151.51,153.5,13296447.0
+2017-07-07,149.25,151.99,149.19,151.44,13229352.0,0.0,1.0,149.25,151.99,149.19,151.44,13229352.0
+2017-07-06,149.03,150.04,148.0,148.82,14788811.0,0.0,1.0,149.03,150.04,148.0,148.82,14788811.0
+2017-07-05,149.0,150.85,148.13,150.34,14037692.0,0.0,1.0,149.0,150.85,148.13,150.34,14037692.0
+2017-07-03,151.72,152.15,147.8,148.43,13860113.0,0.0,1.0,151.72,152.15,147.8,148.43,13860113.0
+2017-06-30,151.9,151.92,150.06,150.98,14540013.0,0.0,1.0,151.9,151.92,150.06,150.98,14540013.0
+2017-06-29,152.28,152.5,148.9175,151.04,23771610.0,0.0,1.0,152.28,152.5,148.9175,151.04,23771610.0
+2017-06-28,150.92,153.47,149.86,153.24,16621566.0,0.0,1.0,150.92,153.47,149.86,153.24,16621566.0
+2017-06-27,152.84,153.31,150.39,150.58,19274022.0,0.0,1.0,152.84,153.31,150.39,150.58,19274022.0
+2017-06-26,156.25,156.5,153.1954,153.59,17934289.0,0.0,1.0,156.25,156.5,153.1954,153.59,17934289.0
+2017-06-23,152.72,155.2,152.65,155.07,16192249.0,0.0,1.0,152.72,155.2,152.65,155.07,16192249.0
+2017-06-22,153.01,154.55,152.91,153.4,12783958.0,0.0,1.0,153.01,154.55,152.91,153.4,12783958.0
+2017-06-21,152.36,154.08,151.88,153.91,14760242.0,0.0,1.0,152.36,154.08,151.88,153.91,14760242.0
+2017-06-20,152.88,153.84,152.21,152.25,14557895.0,0.0,1.0,152.88,153.84,152.21,152.25,14557895.0
+2017-06-19,151.71,153.57,151.71,152.87,18678807.0,0.0,1.0,151.71,153.57,151.71,152.87,18678807.0
+2017-06-16,149.59,150.83,148.6,150.64,22169800.0,0.0,1.0,149.59,150.83,148.6,150.64,22169800.0
+2017-06-15,147.67,150.0366,146.3747,149.8,18877305.0,0.0,1.0,147.67,150.0366,146.3747,149.8,18877305.0
+2017-06-14,151.26,152.4,149.05,150.25,20552981.0,0.0,1.0,151.26,152.4,149.05,150.25,20552981.0
+2017-06-13,150.15,151.18,148.9,150.68,20316202.0,0.0,1.0,150.15,151.18,148.9,150.68,20316202.0
+2017-06-12,148.17,149.195,144.56,148.44,33238543.0,0.0,1.0,148.17,149.195,144.56,148.44,33238543.0
+2017-06-09,154.77,155.59,146.61,149.63,35256368.0,0.0,1.0,154.77,155.59,146.61,149.63,35256368.0
+2017-06-08,154.08,154.73,153.1,154.71,17539521.0,0.0,1.0,154.08,154.73,153.1,154.71,17539521.0
+2017-06-07,153.27,153.75,152.34,153.12,11822136.0,0.0,1.0,153.27,153.75,152.34,153.12,11822136.0
+2017-06-06,153.41,154.52,152.48,152.81,13291727.0,0.0,1.0,153.41,154.52,152.48,152.81,13291727.0
+2017-06-05,153.64,154.7088,153.41,153.63,12279871.0,0.0,1.0,153.64,154.7088,153.41,153.63,12279871.0
+2017-06-02,151.85,153.63,151.3,153.61,16787255.0,0.0,1.0,151.85,153.63,151.3,153.61,16787255.0
+2017-06-01,151.75,152.29,150.3,151.53,14459173.0,0.0,1.0,151.75,152.29,150.3,151.53,14459173.0
diff --git a/examples/quick/demos/stocqt/content/data/GOOG.csv b/examples/quick/demos/stocqt/content/data/GOOG.csv
new file mode 100644
index 0000000000..bde72eafe9
--- /dev/null
+++ b/examples/quick/demos/stocqt/content/data/GOOG.csv
@@ -0,0 +1,148 @@
+Date,Open,High,Low,Close,Volume,Ex-Dividend,Split Ratio,Adj. Open,Adj. High,Adj. Low,Adj. Close,Adj. Volume
+2017-12-29,1046.72,1049.7,1044.9,1046.4,867943.0,0.0,1.0,1046.72,1049.7,1044.9,1046.4,867943.0
+2017-12-28,1051.6,1054.75,1044.77,1048.14,829623.0,0.0,1.0,1051.6,1054.75,1044.77,1048.14,829623.0
+2017-12-27,1057.39,1058.37,1048.05,1049.37,1214775.0,0.0,1.0,1057.39,1058.37,1048.05,1049.37,1214775.0
+2017-12-26,1058.07,1060.12,1050.2,1056.74,756324.0,0.0,1.0,1058.07,1060.12,1050.2,1056.74,756324.0
+2017-12-22,1061.11,1064.2,1059.44,1060.12,734566.0,0.0,1.0,1061.11,1064.2,1059.44,1060.12,734566.0
+2017-12-21,1064.95,1069.33,1061.79,1063.63,974594.0,0.0,1.0,1064.95,1069.33,1061.79,1063.63,974594.0
+2017-12-20,1071.78,1073.38,1061.52,1064.95,1266115.0,0.0,1.0,1071.78,1073.38,1061.52,1064.95,1266115.0
+2017-12-19,1075.2,1076.84,1063.55,1070.68,1254615.0,0.0,1.0,1075.2,1076.84,1063.55,1070.68,1254615.0
+2017-12-18,1066.08,1078.49,1062.0,1077.14,1531522.0,0.0,1.0,1066.08,1078.49,1062.0,1077.14,1531522.0
+2017-12-15,1054.61,1067.62,1049.5,1064.19,3142760.0,0.0,1.0,1054.61,1067.62,1049.5,1064.19,3142760.0
+2017-12-14,1045.0,1058.5,1043.11,1049.15,1545616.0,0.0,1.0,1045.0,1058.5,1043.11,1049.15,1545616.0
+2017-12-13,1046.12,1046.66,1038.38,1040.61,1207286.0,0.0,1.0,1046.12,1046.66,1038.38,1040.61,1207286.0
+2017-12-12,1039.63,1050.31,1033.69,1040.48,1269883.0,0.0,1.0,1039.63,1050.31,1033.69,1040.48,1269883.0
+2017-12-11,1035.5,1043.8,1032.05,1041.1,1119052.0,0.0,1.0,1035.5,1043.8,1032.05,1041.1,1119052.0
+2017-12-08,1037.49,1042.05,1032.52,1037.05,1277894.0,0.0,1.0,1037.49,1042.05,1032.52,1037.05,1277894.0
+2017-12-07,1020.43,1034.24,1018.07,1030.93,1387107.0,0.0,1.0,1020.43,1034.24,1018.07,1030.93,1387107.0
+2017-12-06,1001.5,1024.97,1001.14,1018.38,1254837.0,0.0,1.0,1001.5,1024.97,1001.14,1018.38,1254837.0
+2017-12-05,995.94,1020.61,988.28,1005.15,2023376.0,0.0,1.0,995.94,1020.61,988.28,1005.15,2023376.0
+2017-12-04,1012.66,1016.1,995.57,998.68,1891408.0,0.0,1.0,1012.66,1016.1,995.57,998.68,1891408.0
+2017-12-01,1015.8,1022.49,1002.02,1010.17,1895786.0,0.0,1.0,1015.8,1022.49,1002.02,1010.17,1895786.0
+2017-11-30,1022.37,1028.49,1015.0,1021.41,1684292.0,0.0,1.0,1022.37,1028.49,1015.0,1021.41,1684292.0
+2017-11-29,1042.68,1044.08,1015.65,1021.66,2414465.0,0.0,1.0,1042.68,1044.08,1015.65,1021.66,2414465.0
+2017-11-28,1055.09,1062.38,1040.0,1047.41,1341000.0,0.0,1.0,1055.09,1062.38,1040.0,1047.41,1341000.0
+2017-11-27,1040.0,1055.46,1038.44,1054.21,1284354.0,0.0,1.0,1040.0,1055.46,1038.44,1054.21,1284354.0
+2017-11-24,1035.87,1043.18,1035.0,1040.61,536958.0,0.0,1.0,1035.87,1043.18,1035.0,1040.61,536958.0
+2017-11-22,1035.0,1039.71,1031.43,1035.96,716661.0,0.0,1.0,1035.0,1039.71,1031.43,1035.96,716661.0
+2017-11-21,1023.31,1035.11,1022.66,1034.49,1083715.0,0.0,1.0,1023.31,1035.11,1022.66,1034.49,1083715.0
+2017-11-20,1020.26,1022.61,1017.5,1018.38,894844.0,0.0,1.0,1020.26,1022.61,1017.5,1018.38,894844.0
+2017-11-17,1034.01,1034.42,1017.75,1019.09,1350144.0,0.0,1.0,1034.01,1034.42,1017.75,1019.09,1350144.0
+2017-11-16,1022.52,1035.92,1022.52,1032.5,1117578.0,0.0,1.0,1022.52,1035.92,1022.52,1032.5,1117578.0
+2017-11-15,1019.21,1024.09,1015.42,1020.91,859951.0,0.0,1.0,1019.21,1024.09,1015.42,1020.91,859951.0
+2017-11-14,1022.59,1026.81,1014.15,1026.0,947273.0,0.0,1.0,1022.59,1026.81,1014.15,1026.0,947273.0
+2017-11-13,1023.42,1031.58,1022.57,1025.75,878969.0,0.0,1.0,1023.42,1031.58,1022.57,1025.75,878969.0
+2017-11-10,1026.46,1030.76,1025.28,1028.07,719227.0,0.0,1.0,1026.46,1030.76,1025.28,1028.07,719227.0
+2017-11-09,1033.99,1033.99,1019.67,1031.26,1236903.0,0.0,1.0,1033.99,1033.99,1019.67,1031.26,1236903.0
+2017-11-07,1027.27,1033.97,1025.13,1033.33,1089887.0,0.0,1.0,1027.27,1033.97,1025.13,1033.33,1089887.0
+2017-11-06,1028.99,1034.87,1025.0,1025.9,1119131.0,0.0,1.0,1028.99,1034.87,1025.0,1025.9,1119131.0
+2017-11-03,1022.11,1032.65,1020.31,1032.48,1058037.0,0.0,1.0,1022.11,1032.65,1020.31,1032.48,1058037.0
+2017-11-02,1021.76,1028.09,1013.01,1025.58,1008190.0,0.0,1.0,1021.76,1028.09,1013.01,1025.58,1008190.0
+2017-11-01,1017.21,1029.67,1016.95,1025.5,1360900.0,0.0,1.0,1017.21,1029.67,1016.95,1025.5,1360900.0
+2017-10-31,1015.22,1024.0,1010.42,1016.64,1324961.0,0.0,1.0,1015.22,1024.0,1010.42,1016.64,1324961.0
+2017-10-30,1014.0,1024.97,1007.5,1017.11,2074619.0,0.0,1.0,1014.0,1024.97,1007.5,1017.11,2074619.0
+2017-10-27,1009.19,1048.39,1008.2,1019.27,5125791.0,0.0,1.0,1009.19,1048.39,1008.2,1019.27,5125791.0
+2017-10-26,980.0,987.6,972.2,972.56,1660850.0,0.0,1.0,980.0,987.6,972.2,972.56,1660850.0
+2017-10-25,968.37,976.09,960.5201,973.33,1162606.0,0.0,1.0,968.37,976.09,960.5201,973.33,1162606.0
+2017-10-24,970.0,972.23,961.0,970.54,1155231.0,0.0,1.0,970.0,972.23,961.0,970.54,1155231.0
+2017-10-23,989.52,989.52,966.12,968.45,1431886.0,0.0,1.0,989.52,989.52,966.12,968.45,1431886.0
+2017-10-20,989.44,991.0,984.58,988.2,1120038.0,0.0,1.0,989.44,991.0,984.58,988.2,1120038.0
+2017-10-19,986.0,988.88,978.39,984.45,1282755.0,0.0,1.0,986.0,988.88,978.39,984.45,1282755.0
+2017-10-18,991.77,996.72,986.9747,992.81,1022521.0,0.0,1.0,991.77,996.72,986.9747,992.81,1022521.0
+2017-10-17,990.29,996.44,988.59,992.18,1266399.0,0.0,1.0,990.29,996.44,988.59,992.18,1266399.0
+2017-10-16,992.1,993.9065,984.0,992.0,900751.0,0.0,1.0,992.1,993.9065,984.0,992.0,900751.0
+2017-10-13,992.0,997.21,989.0,989.68,1143907.0,0.0,1.0,992.0,997.21,989.0,989.68,1143907.0
+2017-10-12,987.45,994.12,985.0,987.83,1259082.0,0.0,1.0,987.45,994.12,985.0,987.83,1259082.0
+2017-10-11,973.72,990.71,972.25,989.25,1663731.0,0.0,1.0,973.72,990.71,972.25,989.25,1663731.0
+2017-10-10,980.0,981.57,966.0801,972.6,956419.0,0.0,1.0,980.0,981.57,966.0801,972.6,956419.0
+2017-10-09,980.0,985.425,976.11,977.0,886700.0,0.0,1.0,980.0,985.425,976.11,977.0,886700.0
+2017-10-06,966.7,979.46,963.36,978.89,1142699.0,0.0,1.0,966.7,979.46,963.36,978.89,1142699.0
+2017-10-05,955.49,970.91,955.18,969.96,1202101.0,0.0,1.0,955.49,970.91,955.18,969.96,1202101.0
+2017-10-04,957.0,960.39,950.69,951.68,881380.0,0.0,1.0,957.0,960.39,950.69,951.68,881380.0
+2017-10-03,954.0,958.0,949.14,957.79,881562.0,0.0,1.0,954.0,958.0,949.14,957.79,881562.0
+2017-10-02,959.98,962.54,947.84,953.27,1222026.0,0.0,1.0,959.98,962.54,947.84,953.27,1222026.0
+2017-09-29,952.0,959.7864,951.51,959.11,1533133.0,0.0,1.0,952.0,959.7864,951.51,959.11,1533133.0
+2017-09-28,941.36,950.69,940.55,949.5,959648.0,0.0,1.0,941.36,950.69,940.55,949.5,959648.0
+2017-09-27,927.74,949.9,927.74,944.49,2202959.0,0.0,1.0,927.74,949.9,927.74,944.49,2202959.0
+2017-09-26,923.72,930.82,921.14,924.86,1652848.0,0.0,1.0,923.72,930.82,921.14,924.86,1652848.0
+2017-09-25,925.45,926.4,909.7,920.97,1822881.0,0.0,1.0,925.45,926.4,909.7,920.97,1822881.0
+2017-09-22,927.75,934.73,926.48,928.53,1038551.0,0.0,1.0,927.75,934.73,926.48,928.53,1038551.0
+2017-09-21,933.0,936.53,923.83,932.45,1207656.0,0.0,1.0,933.0,936.53,923.83,932.45,1207656.0
+2017-09-20,922.98,933.88,922.0,931.58,1518166.0,0.0,1.0,922.98,933.88,922.0,931.58,1518166.0
+2017-09-19,917.42,922.4199,912.55,921.81,902415.0,0.0,1.0,917.42,922.4199,912.55,921.81,902415.0
+2017-09-18,920.01,922.08,910.6,915.0,1263456.0,0.0,1.0,920.01,922.08,910.6,915.0,1263456.0
+2017-09-15,924.66,926.49,916.36,920.29,2475031.0,0.0,1.0,924.66,926.49,916.36,920.29,2475031.0
+2017-09-14,931.25,932.77,924.0,925.11,1389012.0,0.0,1.0,931.25,932.77,924.0,925.11,1389012.0
+2017-09-13,930.66,937.25,929.86,935.09,1066051.0,0.0,1.0,930.66,937.25,929.86,935.09,1066051.0
+2017-09-12,932.59,933.48,923.861,932.07,1120449.0,0.0,1.0,932.59,933.48,923.861,932.07,1120449.0
+2017-09-11,934.25,938.38,926.92,929.08,1247138.0,0.0,1.0,934.25,938.38,926.92,929.08,1247138.0
+2017-09-08,936.49,936.99,924.88,926.5,993832.0,0.0,1.0,936.49,936.99,924.88,926.5,993832.0
+2017-09-07,931.73,936.41,923.62,935.95,1200257.0,0.0,1.0,931.73,936.41,923.62,935.95,1200257.0
+2017-09-06,930.15,930.915,919.27,927.81,1468808.0,0.0,1.0,930.15,930.915,919.27,927.81,1468808.0
+2017-09-05,933.08,937.0,921.96,928.45,1202163.0,0.0,1.0,933.08,937.0,921.96,928.45,1202163.0
+2017-09-01,941.13,942.48,935.15,937.34,913404.0,0.0,1.0,941.13,942.48,935.15,937.34,913404.0
+2017-08-31,931.76,941.98,931.76,939.33,1553301.0,0.0,1.0,931.76,941.98,931.76,939.33,1553301.0
+2017-08-30,920.05,930.819,919.65,929.57,1282093.0,0.0,1.0,920.05,930.819,919.65,929.57,1282093.0
+2017-08-29,905.1,923.33,905.0,921.29,1180160.0,0.0,1.0,905.1,923.33,905.0,921.29,1180160.0
+2017-08-28,916.0,919.245,911.87,913.81,1072467.0,0.0,1.0,916.0,919.245,911.87,913.81,1072467.0
+2017-08-25,923.49,925.555,915.5,915.89,1040693.0,0.0,1.0,923.49,925.555,915.5,915.89,1040693.0
+2017-08-24,928.66,930.84,915.5,921.28,1218875.0,0.0,1.0,928.66,930.84,915.5,921.28,1218875.0
+2017-08-23,921.93,929.93,919.36,927.0,1077809.0,0.0,1.0,921.93,929.93,919.36,927.0,1077809.0
+2017-08-22,912.72,925.86,911.4751,924.69,1145571.0,0.0,1.0,912.72,925.86,911.4751,924.69,1145571.0
+2017-08-21,910.0,913.0,903.4,906.66,932903.0,0.0,1.0,910.0,913.0,903.4,906.66,932903.0
+2017-08-18,910.31,915.275,907.1543,910.67,1333572.0,0.0,1.0,910.31,915.275,907.1543,910.67,1333572.0
+2017-08-17,925.78,926.86,910.98,910.98,1218963.0,0.0,1.0,925.78,926.86,910.98,910.98,1218963.0
+2017-08-16,925.29,932.7,923.445,926.96,988604.0,0.0,1.0,925.29,932.7,923.445,926.96,988604.0
+2017-08-15,924.23,926.5499,919.82,922.22,873070.0,0.0,1.0,924.23,926.5499,919.82,922.22,873070.0
+2017-08-14,922.53,924.668,918.19,922.67,1047828.0,0.0,1.0,922.53,924.668,918.19,922.67,1047828.0
+2017-08-11,907.97,917.78,905.58,914.39,1190458.0,0.0,1.0,907.97,917.78,905.58,914.39,1190458.0
+2017-08-10,917.55,919.26,906.13,907.24,1722296.0,0.0,1.0,917.55,919.26,906.13,907.24,1722296.0
+2017-08-09,920.61,925.98,917.2501,922.9,1169431.0,0.0,1.0,920.61,925.98,917.2501,922.9,1169431.0
+2017-08-08,927.09,935.814,925.6095,926.79,1039394.0,0.0,1.0,927.09,935.814,925.6095,926.79,1039394.0
+2017-08-07,929.06,931.7,926.5,929.36,1012296.0,0.0,1.0,929.06,931.7,926.5,929.36,1012296.0
+2017-08-04,926.75,930.3068,923.03,927.96,1019159.0,0.0,1.0,926.75,930.3068,923.03,927.96,1019159.0
+2017-08-03,930.34,932.24,922.24,923.65,1179126.0,0.0,1.0,930.34,932.24,922.24,923.65,1179126.0
+2017-08-02,928.61,932.6,916.68,930.39,1816343.0,0.0,1.0,928.61,932.6,916.68,930.39,1816343.0
+2017-08-01,932.38,937.447,929.26,930.83,1211553.0,0.0,1.0,932.38,937.447,929.26,930.83,1211553.0
+2017-07-31,941.89,943.59,926.04,930.5,1952716.0,0.0,1.0,941.89,943.59,926.04,930.5,1952716.0
+2017-07-28,929.4,943.83,927.5,941.53,1775076.0,0.0,1.0,929.4,943.83,927.5,941.53,1775076.0
+2017-07-27,951.78,951.78,920.0,934.09,3095263.0,0.0,1.0,951.78,951.78,920.0,934.09,3095263.0
+2017-07-26,954.68,955.0,942.2788,947.8,2056013.0,0.0,1.0,954.68,955.0,942.2788,947.8,2056013.0
+2017-07-25,953.81,959.7,945.4,950.7,4626086.0,0.0,1.0,953.81,959.7,945.4,950.7,4626086.0
+2017-07-24,972.22,986.2,970.77,980.34,2634669.0,0.0,1.0,972.22,986.2,970.77,980.34,2634669.0
+2017-07-21,962.25,973.23,960.15,972.92,1665103.0,0.0,1.0,962.25,973.23,960.15,972.92,1665103.0
+2017-07-20,975.0,975.9,961.51,968.15,1577103.0,0.0,1.0,975.0,975.9,961.51,968.15,1577103.0
+2017-07-19,967.84,973.04,964.03,970.89,1212814.0,0.0,1.0,967.84,973.04,964.03,970.89,1212814.0
+2017-07-18,953.0,968.04,950.6,965.4,1131130.0,0.0,1.0,953.0,968.04,950.6,965.4,1131130.0
+2017-07-17,957.0,960.74,949.2407,953.42,1141026.0,0.0,1.0,957.0,960.74,949.2407,953.42,1141026.0
+2017-07-14,952.0,956.91,948.005,955.99,1017632.0,0.0,1.0,952.0,956.91,948.005,955.99,1017632.0
+2017-07-13,946.29,954.45,943.01,947.16,1291782.0,0.0,1.0,946.29,954.45,943.01,947.16,1291782.0
+2017-07-12,938.68,946.3,934.47,943.83,1505982.0,0.0,1.0,938.68,946.3,934.47,943.83,1505982.0
+2017-07-11,929.54,931.43,922.0,930.09,1093281.0,0.0,1.0,929.54,931.43,922.0,930.09,1093281.0
+2017-07-10,921.77,930.38,919.59,928.8,1189085.0,0.0,1.0,921.77,930.38,919.59,928.8,1189085.0
+2017-07-07,908.85,921.54,908.85,918.59,1588034.0,0.0,1.0,908.85,921.54,908.85,918.59,1588034.0
+2017-07-06,904.12,914.9444,899.7,906.69,1409533.0,0.0,1.0,904.12,914.9444,899.7,906.69,1409533.0
+2017-07-05,901.76,914.51,898.5,911.94,1743497.0,0.0,1.0,901.76,914.51,898.5,911.94,1743497.0
+2017-07-03,912.18,913.94,894.79,898.7,1710189.0,0.0,1.0,912.18,913.94,894.79,898.7,1710189.0
+2017-06-30,926.05,926.05,908.31,908.73,2035931.0,0.0,1.0,926.05,926.05,908.31,908.73,2035931.0
+2017-06-29,929.92,931.26,910.62,917.79,3248393.0,0.0,1.0,929.92,931.26,910.62,917.79,3248393.0
+2017-06-28,929.0,942.75,916.0,940.49,2712222.0,0.0,1.0,929.0,942.75,916.0,940.49,2712222.0
+2017-06-27,942.46,948.29,926.85,927.33,2553771.0,0.0,1.0,942.46,948.29,926.85,927.33,2553771.0
+2017-06-26,969.9,973.31,950.79,952.27,1581031.0,0.0,1.0,969.9,973.31,950.79,952.27,1581031.0
+2017-06-23,956.83,966.0,954.2,965.59,1394008.0,0.0,1.0,956.83,966.0,954.2,965.59,1394008.0
+2017-06-22,958.7,960.72,954.55,957.09,940373.0,0.0,1.0,958.7,960.72,954.55,957.09,940373.0
+2017-06-21,953.64,960.1,950.76,959.45,1192342.0,0.0,1.0,953.64,960.1,950.76,959.45,1192342.0
+2017-06-20,957.52,961.62,950.01,950.63,1111840.0,0.0,1.0,957.52,961.62,950.01,950.63,1111840.0
+2017-06-19,949.96,959.99,949.05,957.37,1494191.0,0.0,1.0,949.96,959.99,949.05,957.37,1494191.0
+2017-06-16,940.0,942.04,931.595,939.78,2921393.0,0.0,1.0,940.0,942.04,931.595,939.78,2921393.0
+2017-06-15,933.97,943.339,924.44,942.31,2055953.0,0.0,1.0,933.97,943.339,924.44,942.31,2055953.0
+2017-06-14,959.92,961.15,942.25,950.76,1477033.0,0.0,1.0,959.92,961.15,942.25,950.76,1477033.0
+2017-06-13,951.91,959.98,944.09,953.4,1995350.0,0.0,1.0,951.91,959.98,944.09,953.4,1995350.0
+2017-06-12,939.56,949.355,915.2328,942.9,3731589.0,0.0,1.0,939.56,949.355,915.2328,942.9,3731589.0
+2017-06-09,984.5,984.5,935.63,949.83,3270248.0,0.0,1.0,984.5,984.5,935.63,949.83,3270248.0
+2017-06-08,982.35,984.57,977.2,983.41,1451232.0,0.0,1.0,982.35,984.57,977.2,983.41,1451232.0
+2017-06-07,979.65,984.15,975.77,981.08,1429834.0,0.0,1.0,979.65,984.15,975.77,981.08,1429834.0
+2017-06-06,983.16,988.25,975.14,976.57,1796904.0,0.0,1.0,983.16,988.25,975.14,976.57,1796904.0
+2017-06-05,976.55,986.91,975.1,983.68,1221971.0,0.0,1.0,976.55,986.91,975.1,983.68,1221971.0
+2017-06-02,969.46,975.88,966.0,975.6,1717212.0,0.0,1.0,969.46,975.88,966.0,975.6,1717212.0
+2017-06-01,968.95,971.5,960.01,966.95,1403200.0,0.0,1.0,968.95,971.5,960.01,966.95,1403200.0
diff --git a/examples/quick/demos/stocqt/content/data/GOOGL.csv b/examples/quick/demos/stocqt/content/data/GOOGL.csv
new file mode 100644
index 0000000000..883f78e5f5
--- /dev/null
+++ b/examples/quick/demos/stocqt/content/data/GOOGL.csv
@@ -0,0 +1,148 @@
+Date,Open,High,Low,Close,Volume,Ex-Dividend,Split Ratio,Adj. Open,Adj. High,Adj. Low,Adj. Close,Adj. Volume
+2017-12-29,1055.49,1058.05,1052.7,1053.4,1156357.0,0.0,1.0,1055.49,1058.05,1052.7,1053.4,1156357.0
+2017-12-28,1062.25,1064.84,1053.38,1055.95,982285.0,0.0,1.0,1062.25,1064.84,1053.38,1055.95,982285.0
+2017-12-27,1066.6,1068.27,1058.38,1060.2,1027634.0,0.0,1.0,1066.6,1068.27,1058.38,1060.2,1027634.0
+2017-12-26,1068.64,1068.86,1058.64,1065.85,914574.0,0.0,1.0,1068.64,1068.86,1058.64,1065.85,914574.0
+2017-12-22,1070.0,1071.72,1067.64,1068.86,860800.0,0.0,1.0,1070.0,1071.72,1067.64,1068.86,860800.0
+2017-12-21,1075.39,1077.52,1069.0,1070.85,1211012.0,0.0,1.0,1075.39,1077.52,1069.0,1070.85,1211012.0
+2017-12-20,1080.92,1081.23,1068.6,1073.56,1429035.0,0.0,1.0,1080.92,1081.23,1068.6,1073.56,1429035.0
+2017-12-19,1083.02,1084.97,1072.27,1079.78,1287930.0,0.0,1.0,1083.02,1084.97,1072.27,1079.78,1287930.0
+2017-12-18,1076.45,1086.49,1070.37,1085.09,1482768.0,0.0,1.0,1076.45,1086.49,1070.37,1085.09,1482768.0
+2017-12-15,1063.78,1075.25,1060.09,1072.0,3080738.0,0.0,1.0,1063.78,1075.25,1060.09,1072.0,3080738.0
+2017-12-14,1055.49,1067.08,1053.6,1057.47,1531504.0,0.0,1.0,1055.49,1067.08,1053.6,1057.47,1531504.0
+2017-12-13,1052.08,1055.48,1046.58,1051.39,1369580.0,0.0,1.0,1052.08,1055.48,1046.58,1051.39,1369580.0
+2017-12-12,1050.0,1062.5,1044.87,1048.77,1684977.0,0.0,1.0,1050.0,1062.5,1044.87,1048.77,1684977.0
+2017-12-11,1051.11,1056.0,1044.12,1051.97,1096997.0,0.0,1.0,1051.11,1056.0,1044.12,1051.97,1096997.0
+2017-12-08,1051.81,1056.42,1045.86,1049.38,1479665.0,0.0,1.0,1051.81,1056.42,1045.86,1049.38,1479665.0
+2017-12-07,1036.07,1048.92,1035.36,1044.57,1437448.0,0.0,1.0,1036.07,1048.92,1035.36,1044.57,1437448.0
+2017-12-06,1016.52,1039.58,1015.31,1032.72,1369276.0,0.0,1.0,1016.52,1039.58,1015.31,1032.72,1369276.0
+2017-12-05,1010.99,1036.68,1002.32,1019.6,1927802.0,0.0,1.0,1010.99,1036.68,1002.32,1019.6,1927802.0
+2017-12-04,1027.8,1031.34,1009.22,1011.87,1896325.0,0.0,1.0,1027.8,1031.34,1009.22,1011.87,1896325.0
+2017-12-01,1030.41,1037.24,1016.9,1025.07,1850541.0,0.0,1.0,1030.41,1037.24,1016.9,1025.07,1850541.0
+2017-11-30,1039.94,1044.14,1030.07,1036.17,2190379.0,0.0,1.0,1039.94,1044.14,1030.07,1036.17,2190379.0
+2017-11-29,1056.18,1058.77,1029.65,1037.38,2737664.0,0.0,1.0,1056.18,1058.77,1029.65,1037.38,2737664.0
+2017-11-28,1073.99,1080.0,1054.54,1063.29,1694098.0,0.0,1.0,1073.99,1080.0,1054.54,1063.29,1694098.0
+2017-11-27,1058.57,1073.04,1054.77,1072.01,1708195.0,0.0,1.0,1058.57,1073.04,1054.77,1072.01,1708195.0
+2017-11-24,1054.39,1060.07,1051.92,1056.52,825342.0,0.0,1.0,1054.39,1060.07,1051.92,1056.52,825342.0
+2017-11-22,1051.16,1055.43,1047.25,1051.92,721498.0,0.0,1.0,1051.16,1055.43,1047.25,1051.92,721498.0
+2017-11-21,1040.04,1050.39,1039.14,1050.3,1075568.0,0.0,1.0,1040.04,1050.39,1039.14,1050.3,1075568.0
+2017-11-20,1036.0,1038.7,1032.68,1034.66,850423.0,0.0,1.0,1036.0,1038.7,1032.68,1034.66,850423.0
+2017-11-17,1049.8,1051.0,1033.73,1035.89,1286044.0,0.0,1.0,1049.8,1051.0,1033.73,1035.89,1286044.0
+2017-11-16,1038.75,1051.76,1038.0,1048.47,1125995.0,0.0,1.0,1038.75,1051.76,1038.0,1048.47,1125995.0
+2017-11-15,1035.0,1039.63,1030.76,1036.41,900695.0,0.0,1.0,1035.0,1039.63,1030.76,1036.41,900695.0
+2017-11-14,1037.72,1042.3,1029.33,1041.64,982782.0,0.0,1.0,1037.72,1042.3,1029.33,1041.64,982782.0
+2017-11-13,1040.8,1048.74,1039.26,1041.2,914852.0,0.0,1.0,1040.8,1048.74,1039.26,1041.2,914852.0
+2017-11-10,1043.87,1046.63,1041.22,1044.15,955500.0,0.0,1.0,1043.87,1046.63,1041.22,1044.15,955500.0
+2017-11-09,1048.0,1050.88,1035.85,1047.72,1776722.0,0.0,1.0,1048.0,1050.88,1035.85,1047.72,1776722.0
+2017-11-07,1049.65,1053.41,1043.0,1052.39,1254965.0,0.0,1.0,1049.65,1053.41,1043.0,1052.39,1254965.0
+2017-11-06,1049.1,1052.59,1042.0,1042.68,897897.0,0.0,1.0,1049.1,1052.59,1042.0,1042.68,897897.0
+2017-11-03,1042.75,1050.66,1037.65,1049.99,1370874.0,0.0,1.0,1042.75,1050.66,1037.65,1049.99,1370874.0
+2017-11-02,1039.99,1045.52,1028.66,1042.97,1233333.0,0.0,1.0,1039.99,1045.52,1028.66,1042.97,1233333.0
+2017-11-01,1036.32,1047.86,1034.0,1042.6,2105729.0,0.0,1.0,1036.32,1047.86,1034.0,1042.6,2105729.0
+2017-10-31,1033.0,1041.0,1026.3,1033.04,1490660.0,0.0,1.0,1033.0,1041.0,1026.3,1033.04,1490660.0
+2017-10-30,1029.16,1039.83,1022.33,1033.13,2245352.0,0.0,1.0,1029.16,1039.83,1022.33,1033.13,2245352.0
+2017-10-27,1030.99,1063.62,1026.85,1033.67,5139945.0,0.0,1.0,1030.99,1063.62,1026.85,1033.67,5139945.0
+2017-10-26,998.47,1006.51,990.47,991.42,1827682.0,0.0,1.0,998.47,1006.51,990.47,991.42,1827682.0
+2017-10-25,986.27,994.43,977.722,991.46,1368042.0,0.0,1.0,986.27,994.43,977.722,991.46,1368042.0
+2017-10-24,986.5,989.26,977.08,988.49,1416283.0,0.0,1.0,986.5,989.26,977.08,988.49,1416283.0
+2017-10-23,1005.18,1005.79,983.1,985.54,1623580.0,0.0,1.0,1005.18,1005.79,983.1,985.54,1623580.0
+2017-10-20,1007.05,1008.65,1002.27,1005.07,1568454.0,0.0,1.0,1007.05,1008.65,1002.27,1005.07,1568454.0
+2017-10-19,1004.75,1007.32,997.3,1001.84,1677021.0,0.0,1.0,1004.75,1007.32,997.3,1001.84,1677021.0
+2017-10-18,1011.05,1016.31,1005.32,1012.74,1270218.0,0.0,1.0,1011.05,1016.31,1005.32,1012.74,1270218.0
+2017-10-17,1007.44,1014.56,1006.05,1011.0,991412.0,0.0,1.0,1007.44,1014.56,1006.05,1011.0,991412.0
+2017-10-16,1009.63,1012.0,1001.52,1009.35,1066744.0,0.0,1.0,1009.63,1012.0,1001.52,1009.35,1066744.0
+2017-10-13,1009.11,1014.76,1007.06,1007.87,1308881.0,0.0,1.0,1009.11,1014.76,1007.06,1007.87,1308881.0
+2017-10-12,1003.84,1011.54,1001.1,1005.65,1521137.0,0.0,1.0,1003.84,1011.54,1001.1,1005.65,1521137.0
+2017-10-11,989.04,1007.56,987.94,1005.65,1748443.0,0.0,1.0,989.04,1007.56,987.94,1005.65,1748443.0
+2017-10-10,995.3,997.47,981.11,987.8,1158864.0,0.0,1.0,995.3,997.47,981.11,987.8,1158864.0
+2017-10-09,995.0,1000.46,991.5,992.31,1151035.0,0.0,1.0,995.0,1000.46,991.5,992.31,1151035.0
+2017-10-06,980.0,994.26,978.51,993.64,1490744.0,0.0,1.0,980.0,994.26,978.51,993.64,1490744.0
+2017-10-05,972.79,986.5085,970.27,985.19,1627255.0,0.0,1.0,972.79,986.5085,970.27,985.19,1627255.0
+2017-10-04,971.76,974.4,965.61,966.78,896531.0,0.0,1.0,971.76,974.4,965.61,966.78,896531.0
+2017-10-03,967.56,972.44,962.705,972.08,1080312.0,0.0,1.0,967.56,972.44,962.705,972.08,1080312.0
+2017-10-02,975.65,977.74,961.95,967.47,1466444.0,0.0,1.0,975.65,977.74,961.95,967.47,1466444.0
+2017-09-29,966.0,975.81,966.0,973.72,1906445.0,0.0,1.0,966.0,975.81,966.0,973.72,1906445.0
+2017-09-28,956.25,966.18,955.55,964.81,1347750.0,0.0,1.0,956.25,966.18,955.55,964.81,1347750.0
+2017-09-27,942.74,965.43,941.95,959.9,2313498.0,0.0,1.0,942.74,965.43,941.95,959.9,2313498.0
+2017-09-26,936.69,944.08,935.12,937.43,1618182.0,0.0,1.0,936.69,944.08,935.12,937.43,1618182.0
+2017-09-25,939.45,939.75,924.5101,934.28,1847436.0,0.0,1.0,939.45,939.75,924.5101,934.28,1847436.0
+2017-09-22,942.77,950.0,940.835,943.26,1067617.0,0.0,1.0,942.77,950.0,940.835,943.26,1067617.0
+2017-09-21,948.13,952.8,939.38,947.55,1302726.0,0.0,1.0,948.13,952.8,939.38,947.55,1302726.0
+2017-09-20,937.73,950.0,937.5,947.54,1896919.0,0.0,1.0,937.73,950.0,937.5,947.54,1896919.0
+2017-09-19,933.41,937.94,926.66,936.86,1217430.0,0.0,1.0,933.41,937.94,926.66,936.86,1217430.0
+2017-09-18,935.01,936.86,925.4,929.75,1445532.0,0.0,1.0,935.01,936.86,925.4,929.75,1445532.0
+2017-09-15,940.09,941.75,931.25,935.29,1940047.0,0.0,1.0,940.09,941.75,931.25,935.29,1940047.0
+2017-09-14,946.0,948.03,938.356,940.13,1415168.0,0.0,1.0,946.0,948.03,938.356,940.13,1415168.0
+2017-09-13,945.5,952.85,944.74,950.44,1092849.0,0.0,1.0,945.5,952.85,944.74,950.44,1092849.0
+2017-09-12,946.92,948.085,937.5,946.65,1245767.0,0.0,1.0,946.92,948.085,937.5,946.65,1245767.0
+2017-09-11,947.2,952.68,941.0,943.29,1317796.0,0.0,1.0,947.2,952.68,941.0,943.29,1317796.0
+2017-09-08,949.7,950.7,940.01,941.41,996449.0,0.0,1.0,949.7,950.7,940.01,941.41,996449.0
+2017-09-07,944.25,950.4965,937.53,949.89,1103286.0,0.0,1.0,944.25,950.4965,937.53,949.89,1103286.0
+2017-09-06,943.87,944.5,932.68,942.02,1375952.0,0.0,1.0,943.87,944.5,932.68,942.02,1375952.0
+2017-09-05,946.86,951.3854,935.6,941.48,1455058.0,0.0,1.0,946.86,951.3854,935.6,941.48,1455058.0
+2017-09-01,957.47,958.33,950.28,951.99,1034769.0,0.0,1.0,957.47,958.33,950.28,951.99,1034769.0
+2017-08-31,946.3,957.195,946.25,955.24,1672387.0,0.0,1.0,946.3,957.195,946.25,955.24,1672387.0
+2017-08-30,935.67,945.86,934.05,943.63,1112814.0,0.0,1.0,935.67,945.86,934.05,943.63,1112814.0
+2017-08-29,919.95,938.19,919.31,935.75,1144834.0,0.0,1.0,919.95,938.19,919.31,935.75,1144834.0
+2017-08-28,931.88,934.85,926.11,928.13,1025199.0,0.0,1.0,931.88,934.85,926.11,928.13,1025199.0
+2017-08-25,939.21,940.73,930.1,930.5,1169101.0,0.0,1.0,939.21,940.73,930.1,930.5,1169101.0
+2017-08-24,943.71,946.31,930.74,936.89,1249098.0,0.0,1.0,943.71,946.31,930.74,936.89,1249098.0
+2017-08-23,937.0,945.425,935.24,942.58,1126487.0,0.0,1.0,937.0,945.425,935.24,942.58,1126487.0
+2017-08-22,926.96,941.9617,926.17,940.4,1711377.0,0.0,1.0,926.96,941.9617,926.17,940.4,1711377.0
+2017-08-21,925.77,928.25,918.6,920.87,1292624.0,0.0,1.0,925.77,928.25,918.6,920.87,1292624.0
+2017-08-18,926.98,931.02,923.45,926.18,1327288.0,0.0,1.0,926.98,931.02,923.45,926.18,1327288.0
+2017-08-17,942.95,943.81,927.64,927.66,1653779.0,0.0,1.0,942.95,943.81,927.64,927.66,1653779.0
+2017-08-16,941.25,949.9,940.0391,944.27,1329301.0,0.0,1.0,941.25,949.9,940.0391,944.27,1329301.0
+2017-08-15,941.03,943.07,936.64,938.08,1006064.0,0.0,1.0,941.03,943.07,936.64,938.08,1006064.0
+2017-08-14,939.07,941.04,934.485,938.93,1140212.0,0.0,1.0,939.07,941.04,934.485,938.93,1140212.0
+2017-08-11,923.71,933.36,921.22,930.09,1589808.0,0.0,1.0,923.71,933.36,921.22,930.09,1589808.0
+2017-08-10,935.0,936.3,921.7768,923.59,2657279.0,0.0,1.0,935.0,936.3,921.7768,923.59,2657279.0
+2017-08-09,938.45,943.76,933.92,940.08,1360604.0,0.0,1.0,938.45,943.76,933.92,940.08,1360604.0
+2017-08-08,944.29,952.49,942.48,944.19,1438418.0,0.0,1.0,944.29,952.49,942.48,944.19,1438418.0
+2017-08-07,947.52,948.96,943.5,945.75,1405132.0,0.0,1.0,947.52,948.96,943.5,945.75,1405132.0
+2017-08-04,943.95,947.54,939.795,945.79,1192871.0,0.0,1.0,943.95,947.54,939.795,945.79,1192871.0
+2017-08-03,949.1,950.0,939.44,940.3,1028591.0,0.0,1.0,949.1,950.0,939.44,940.3,1028591.0
+2017-08-02,948.37,949.1,932.521,947.64,2019979.0,0.0,1.0,948.37,949.1,932.521,947.64,2019979.0
+2017-08-01,947.81,954.49,944.96,946.56,1205799.0,0.0,1.0,947.81,954.49,944.96,946.56,1205799.0
+2017-07-31,960.0,961.1925,941.725,945.5,2268160.0,0.0,1.0,960.0,961.1925,941.725,945.5,2268160.0
+2017-07-28,947.99,961.79,945.31,958.33,1795477.0,0.0,1.0,947.99,961.79,945.31,958.33,1795477.0
+2017-07-27,969.18,969.52,937.06,952.51,3685905.0,0.0,1.0,969.18,969.52,937.06,952.51,3685905.0
+2017-07-26,972.78,973.95,960.23,965.31,2166225.0,0.0,1.0,972.78,973.95,960.23,965.31,2166225.0
+2017-07-25,970.7,976.73,963.8,969.03,5793414.0,0.0,1.0,970.7,976.73,963.8,969.03,5793414.0
+2017-07-24,994.1,1006.19,990.2728,998.31,3053176.0,0.0,1.0,994.1,1006.19,990.2728,998.31,3053176.0
+2017-07-21,989.0,995.11,984.17,993.84,1412108.0,0.0,1.0,989.0,995.11,984.17,993.84,1412108.0
+2017-07-20,997.0,998.68,984.62,992.19,1410290.0,0.0,1.0,997.0,998.68,984.62,992.19,1410290.0
+2017-07-19,990.01,995.6,987.01,992.77,1392709.0,0.0,1.0,990.01,995.6,987.01,992.77,1392709.0
+2017-07-18,973.36,990.85,972.04,986.95,1398920.0,0.0,1.0,973.36,990.85,972.04,986.95,1398920.0
+2017-07-17,976.32,983.35,970.8,975.96,1644618.0,0.0,1.0,976.32,983.35,970.8,975.96,1644618.0
+2017-07-14,974.0,977.54,970.15,976.91,1048240.0,0.0,1.0,974.0,977.54,970.15,976.91,1048240.0
+2017-07-13,970.8,978.7,964.8,968.7175,1519987.0,0.0,1.0,970.8,978.7,964.8,968.7175,1519987.0
+2017-07-12,960.86,969.63,957.04,967.66,1589548.0,0.0,1.0,960.86,969.63,957.04,967.66,1589548.0
+2017-07-11,950.52,954.89,945.12,953.53,1444540.0,0.0,1.0,950.52,954.89,945.12,953.53,1444540.0
+2017-07-10,941.95,953.13,941.95,951.0,1409850.0,0.0,1.0,941.95,953.13,941.95,951.0,1409850.0
+2017-07-07,930.985,944.66,929.79,940.81,1614080.0,0.0,1.0,930.985,944.66,929.79,940.81,1614080.0
+2017-07-06,925.0,936.14,919.85,927.69,1941822.0,0.0,1.0,925.0,936.14,919.85,927.69,1941822.0
+2017-07-05,924.2,936.29,918.6305,932.26,2054927.0,0.0,1.0,924.2,936.29,918.6305,932.26,2054927.0
+2017-07-03,933.22,934.24,915.31,919.46,1694587.0,0.0,1.0,933.22,934.24,915.31,919.46,1694587.0
+2017-06-30,943.99,944.9995,929.61,929.68,2185444.0,0.0,1.0,943.99,944.9995,929.61,929.68,2185444.0
+2017-06-29,951.35,951.66,929.6,937.82,3182331.0,0.0,1.0,951.35,951.66,929.6,937.82,3182331.0
+2017-06-28,950.66,963.24,936.16,961.01,2713366.0,0.0,1.0,950.66,963.24,936.16,961.01,2713366.0
+2017-06-27,961.6,967.22,947.09,948.09,2428048.0,0.0,1.0,961.6,967.22,947.09,948.09,2428048.0
+2017-06-26,990.0,993.99,970.33,972.09,1505655.0,0.0,1.0,990.0,993.99,970.33,972.09,1505655.0
+2017-06-23,975.5,986.62,974.46,986.09,1439728.0,0.0,1.0,975.5,986.62,974.46,986.09,1439728.0
+2017-06-22,976.87,980.5,973.3148,976.62,940086.0,0.0,1.0,976.87,980.5,973.3148,976.62,940086.0
+2017-06-21,970.79,979.67,969.16,978.59,1141315.0,0.0,1.0,970.79,979.67,969.16,978.59,1141315.0
+2017-06-20,975.31,980.79,968.2,968.99,1273013.0,0.0,1.0,975.31,980.79,968.2,968.99,1273013.0
+2017-06-19,969.65,979.3,968.2,975.22,1449343.0,0.0,1.0,969.65,979.3,968.2,975.22,1449343.0
+2017-06-16,957.91,959.95,948.7,958.62,2484914.0,0.0,1.0,957.91,959.95,948.7,958.62,2484914.0
+2017-06-15,948.02,960.6775,940.37,960.18,2349212.0,0.0,1.0,948.02,960.6775,940.37,960.18,2349212.0
+2017-06-14,975.5,979.7,959.5103,967.93,1489046.0,0.0,1.0,975.5,979.7,959.5103,967.93,1489046.0
+2017-06-13,972.04,977.91,962.01,970.5,1992456.0,0.0,1.0,972.04,977.91,962.01,970.5,1992456.0
+2017-06-12,958.72,968.0,936.795,961.81,4167184.0,0.0,1.0,958.72,968.0,936.795,961.81,4167184.0
+2017-06-09,1005.49,1005.5,953.37,970.12,3613964.0,0.0,1.0,1005.49,1005.5,953.37,970.12,3613964.0
+2017-06-08,1004.23,1005.6,996.62,1004.28,1657881.0,0.0,1.0,1004.23,1005.6,996.62,1004.28,1657881.0
+2017-06-07,998.82,1003.91,995.81,1001.59,1348198.0,0.0,1.0,998.82,1003.91,995.81,1001.59,1348198.0
+2017-06-06,1003.31,1008.61,994.8,996.68,1517356.0,0.0,1.0,1003.31,1008.61,994.8,996.68,1517356.0
+2017-06-05,997.89,1007.4,995.45,1003.88,1353264.0,0.0,1.0,997.89,1007.4,995.45,1003.88,1353264.0
+2017-06-02,988.59,996.48,987.07,996.12,1719720.0,0.0,1.0,988.59,996.48,987.07,996.12,1719720.0
+2017-06-01,990.96,993.14,981.29,988.29,1295552.0,0.0,1.0,990.96,993.14,981.29,988.29,1295552.0
diff --git a/examples/quick/demos/stocqt/content/data/INTC.csv b/examples/quick/demos/stocqt/content/data/INTC.csv
new file mode 100644
index 0000000000..9e762ffb43
--- /dev/null
+++ b/examples/quick/demos/stocqt/content/data/INTC.csv
@@ -0,0 +1,147 @@
+Date,Open,High,Low,Close,Volume,Ex-Dividend,Split Ratio,Adj. Open,Adj. High,Adj. Low,Adj. Close,Adj. Volume
+2017-12-29,46.21,46.49,46.09,46.16,17136416.0,0.0,1.0,46.21,46.49,46.09,46.16,17136416.0
+2017-12-28,46.36,46.36,45.95,46.22,9279766.0,0.0,1.0,46.36,46.36,45.95,46.22,9279766.0
+2017-12-27,46.11,46.36,46.0,46.11,12412977.0,0.0,1.0,46.11,46.36,46.0,46.11,12412977.0
+2017-12-26,46.28,46.47,45.95,46.08,15477747.0,0.0,1.0,46.28,46.47,45.95,46.08,15477747.0
+2017-12-22,46.33,47.02,46.02,46.7,33404280.0,0.0,1.0,46.33,47.02,46.02,46.7,33404280.0
+2017-12-21,47.54,47.59,46.56,46.76,42113273.0,0.0,1.0,47.54,47.59,46.56,46.76,42113273.0
+2017-12-20,47.47,47.64,46.66,47.56,39536777.0,0.0,1.0,47.47,47.64,46.66,47.56,39536777.0
+2017-12-19,46.3,47.26,45.89,47.04,39973826.0,0.0,1.0,46.3,47.26,45.89,47.04,39973826.0
+2017-12-18,45.15,46.35,45.04,46.26,49305190.0,0.0,1.0,45.15,46.35,45.04,46.26,49305190.0
+2017-12-15,43.4,44.84,43.07,44.56,44377039.0,0.0,1.0,43.4,44.84,43.07,44.56,44377039.0
+2017-12-14,43.43,43.57,43.015,43.26,18871565.0,0.0,1.0,43.43,43.57,43.015,43.26,18871565.0
+2017-12-13,43.65,43.66,43.24,43.34,21055298.0,0.0,1.0,43.65,43.66,43.24,43.34,21055298.0
+2017-12-12,43.47,43.62,43.08,43.33,15571482.0,0.0,1.0,43.47,43.62,43.08,43.33,15571482.0
+2017-12-11,43.28,43.78,43.25,43.66,18840783.0,0.0,1.0,43.28,43.78,43.25,43.66,18840783.0
+2017-12-08,43.35,43.58,43.11,43.35,22833083.0,0.0,1.0,43.35,43.58,43.11,43.35,22833083.0
+2017-12-07,43.46,43.6,42.78,43.08,31193561.0,0.0,1.0,43.46,43.6,42.78,43.08,31193561.0
+2017-12-06,43.14,43.72,42.67,43.45,24497550.0,0.0,1.0,43.14,43.72,42.67,43.45,24497550.0
+2017-12-05,44.6,44.9,43.23,43.44,30112131.0,0.0,1.0,44.6,44.9,43.23,43.44,30112131.0
+2017-12-04,45.02,45.3,44.33,44.49,26829460.0,0.0,1.0,45.02,45.3,44.33,44.49,26829460.0
+2017-12-01,44.73,44.84,43.53,44.68,26393385.0,0.0,1.0,44.73,44.84,43.53,44.68,26393385.0
+2017-11-30,44.36,45.2,44.33,44.84,32735416.0,0.0,1.0,44.36,45.2,44.33,44.84,32735416.0
+2017-11-29,44.85,45.09,43.77,43.95,26246867.0,0.0,1.0,44.85,45.09,43.77,43.95,26246867.0
+2017-11-28,44.65,44.84,44.32,44.73,19084500.0,0.0,1.0,44.65,44.84,44.32,44.73,19084500.0
+2017-11-27,44.42,44.61,44.2736,44.49,17187942.0,0.0,1.0,44.42,44.61,44.2736,44.49,17187942.0
+2017-11-24,44.55,44.775,44.43,44.75,6465615.0,0.0,1.0,44.55,44.775,44.43,44.75,6465615.0
+2017-11-22,44.94,44.95,44.535,44.65,19191241.0,0.0,1.0,44.94,44.95,44.535,44.65,19191241.0
+2017-11-21,44.72,45.22,44.71,44.94,20730988.0,0.0,1.0,44.72,45.22,44.71,44.94,20730988.0
+2017-11-20,44.73,45.115,44.5,44.62,22162614.0,0.0,1.0,44.73,45.115,44.5,44.62,22162614.0
+2017-11-17,45.5,45.62,44.62,44.63,62637555.0,0.0,1.0,45.5,45.62,44.62,44.63,62637555.0
+2017-11-16,45.63,46.07,45.46,45.65,21446297.0,0.0,1.0,45.63,46.07,45.46,45.65,21446297.0
+2017-11-15,45.39,45.805,45.1725,45.46,16781344.0,0.0,1.0,45.39,45.805,45.1725,45.46,16781344.0
+2017-11-14,45.7,45.92,45.32,45.86,20747874.0,0.0,1.0,45.7,45.92,45.32,45.86,20747874.0
+2017-11-13,45.26,45.94,45.25,45.75,18923183.0,0.0,1.0,45.26,45.94,45.25,45.75,18923183.0
+2017-11-10,46.04,46.09,45.38,45.58,23953470.0,0.0,1.0,46.04,46.09,45.38,45.58,23953470.0
+2017-11-09,46.05,46.39,45.65,46.3,24830309.0,0.0,1.0,46.05,46.39,45.65,46.3,24830309.0
+2017-11-07,46.7,47.09,46.39,46.78,23074092.0,0.0,1.0,46.7,47.09,46.39,46.78,23074092.0
+2017-11-06,46.6,46.74,46.09,46.7,31865449.0,0.273,1.0,46.329167819811,46.468354160901,45.822131862985,46.428586634875,31865449.0
+2017-11-03,47.2,47.3,45.6,46.34,38647115.0,0.0,1.0,46.652955722779,46.751796730667,45.071499596583,45.802923054949,38647115.0
+2017-11-02,46.61,47.23,46.213,47.1,37260192.0,0.0,1.0,46.069793776245,46.682608025146,45.677394974932,46.554114714892,37260192.0
+2017-11-01,45.97,46.71,45.59,46.71,47077781.0,0.0,1.0,45.437211325766,46.168634784132,45.061615495795,46.168634784132,47077781.0
+2017-10-31,45.2,45.8,44.65,45.49,46206973.0,0.0,1.0,44.676135565035,45.269181612358,44.132510021655,44.962774487908,46206973.0
+2017-10-30,44.48,45.19,43.88,44.37,46012316.0,0.0,1.0,43.964480308246,44.666251464246,43.371434260923,43.85575519957,46012316.0
+2017-10-27,43.3,45.0,43.1,44.4,88413551.0,0.0,1.0,42.798156415177,44.47845354926,42.600474399402,43.885407501937,88413551.0
+2017-10-26,40.91,41.575,40.71,41.35,35618913.0,0.0,1.0,40.435856326672,41.093149029122,40.238174310897,40.870756761376,35618913.0
+2017-10-25,40.89,41.055,40.49,40.78,23079947.0,0.0,1.0,40.416088125094,40.579175788108,40.020724093545,40.307363016418,23079947.0
+2017-10-24,41.0,41.05,40.72,40.95,18616857.0,0.0,1.0,40.52481323377,40.574233737714,40.248058411686,40.475392729827,18616857.0
+2017-10-23,40.55,41.04,40.395,40.83,28306520.0,0.0,1.0,40.080028698278,40.564349636925,39.926825136052,40.356783520362,28306520.0
+2017-10-20,40.33,40.45,40.1,40.43,17556315.0,0.0,1.0,39.862578480926,39.98118769039,39.635244162785,39.961419488813,17556315.0
+2017-10-19,39.88,40.33,39.83,40.09,18541779.0,0.0,1.0,39.417793945433,39.862578480926,39.368373441489,39.625360061996,18541779.0
+2017-10-18,39.8,40.29,39.6,40.25,20592939.0,0.0,1.0,39.338721139123,39.823042077771,39.141039123349,39.783505674616,20592939.0
+2017-10-17,39.56,39.865,39.37,39.79,15300505.0,0.0,1.0,39.101502720194,39.40296779425,38.913704805208,39.328837038335,15300505.0
+2017-10-16,39.71,39.79,39.44,39.76,12448746.0,0.0,1.0,39.249764232025,39.328837038335,38.982893510729,39.299184735968,12448746.0
+2017-10-13,39.44,39.81,39.28,39.67,16611521.0,0.0,1.0,38.982893510729,39.348605239912,38.82474789811,39.21022782887,16611521.0
+2017-10-12,39.35,39.39,38.98,39.19,18236204.0,0.0,1.0,38.893936603631,38.933473006786,38.528224874448,38.735790991011,18236204.0
+2017-10-11,39.48,39.67,39.06,39.3,30452182.0,0.0,1.0,39.022429913884,39.21022782887,38.607297680758,38.844516099687,30452182.0
+2017-10-10,39.93,39.95,39.38,39.65,29838331.0,0.0,1.0,39.467214449377,39.486982650954,38.923588905997,39.190459627292,29838331.0
+2017-10-09,39.68,39.88,39.52,39.86,18372360.0,0.0,1.0,39.220111929659,39.417793945433,39.061966317039,39.398025743856,18372360.0
+2017-10-06,39.6,39.89,39.42,39.63,18063051.0,0.0,1.0,39.141039123349,39.427678046222,38.963125309152,39.170691425715,18063051.0
+2017-10-05,39.5,39.65,39.21,39.53,17588371.0,0.0,1.0,39.042198115462,39.190459627292,38.755559192589,39.071850417828,17588371.0
+2017-10-04,39.39,39.4,38.8606,39.34,27900633.0,0.0,1.0,38.933473006786,38.943357107574,38.410208711031,38.884052502842,27900633.0
+2017-10-03,38.95,39.7,38.95,39.38,33266885.0,0.0,1.0,38.498572572082,39.239880131236,38.498572572082,38.923588905997,33266885.0
+2017-10-02,38.12,39.09,38.08,39.04,36985170.0,0.0,1.0,37.678192206618,38.636949983124,37.638655803463,38.58752947918,36985170.0
+2017-09-29,37.84,38.15,37.7,38.08,22617651.0,0.0,1.0,37.401437384533,37.707844508984,37.263059973491,37.638655803463,22617651.0
+2017-09-28,37.32,37.88,37.29,37.83,20601061.0,0.0,1.0,36.88746414352,37.440973787688,36.857811841153,37.391553283745,20601061.0
+2017-09-27,37.62,37.69,37.1,37.54,25457387.0,0.0,1.0,37.183987167181,37.253175872702,36.670013926168,37.104914360872,25457387.0
+2017-09-26,37.21,37.64,37.0,37.47,29198356.0,0.0,1.0,36.778739034844,37.203755368759,36.57117291828,37.035725655351,29198356.0
+2017-09-25,37.05,37.23,36.85,37.16,22158905.0,0.0,1.0,36.620593422224,36.798507236421,36.42291140645,36.7293185309,22158905.0
+2017-09-22,36.95,37.22,36.95,37.18,20928369.0,0.0,1.0,36.521752414337,36.788623135632,36.521752414337,36.749086732477,20928369.0
+2017-09-21,36.99,37.27,36.85,37.2,20175216.0,0.0,1.0,36.561288817492,36.838043639576,36.42291140645,36.768854934055,20175216.0
+2017-09-20,37.23,37.29,36.655,37.07,23127098.0,0.0,1.0,36.798507236421,36.857811841153,36.230171441069,36.640361623802,23127098.0
+2017-09-19,37.2,37.295,37.02,37.23,21823446.0,0.0,1.0,36.768854934055,36.862753891548,36.590941119858,36.798507236421,21823446.0
+2017-09-18,37.0,37.33,36.8,37.0,19083499.0,0.0,1.0,36.57117291828,36.897348244308,36.373490902506,36.57117291828,19083499.0
+2017-09-15,36.55,37.08,36.22,37.0,32109972.0,0.0,1.0,36.126388382788,36.65024572459,35.80021305676,36.57117291828,32109972.0
+2017-09-14,36.19,36.695,36.16,36.48,17902903.0,0.0,1.0,35.770560754394,36.269707844224,35.740908452028,36.057199677267,17902903.0
+2017-09-13,36.0,36.4,35.97,36.33,15069601.0,0.0,1.0,35.582762839408,35.978126870957,35.553110537042,35.908938165436,15069601.0
+2017-09-12,35.88,36.34,35.74,36.09,19061818.0,0.0,1.0,35.464153629943,35.918822266225,35.325776218901,35.671719746507,19061818.0
+2017-09-11,35.49,36.0,35.14,35.77,18895979.0,0.0,1.0,35.078673699183,35.582762839408,34.732730171578,35.355428521267,18895979.0
+2017-09-08,35.42,35.54,35.08,35.19,13881093.0,0.0,1.0,35.009484993662,35.128094203127,34.673425566845,34.782150675521,13881093.0
+2017-09-07,35.88,35.95,35.33,35.54,16045217.0,0.0,1.0,35.464153629943,35.533342335464,34.920528086563,35.128094203127,16045217.0
+2017-09-06,35.22,35.94,35.11,35.76,26811090.0,0.0,1.0,34.811802977888,35.523458234676,34.703077869212,35.345544420479,26811090.0
+2017-09-05,35.02,35.33,34.93,35.02,18665229.0,0.0,1.0,34.614120962113,34.920528086563,34.525164055014,34.614120962113,18665229.0
+2017-09-01,35.24,35.39,35.07,35.085,12713069.0,0.0,1.0,34.831571179465,34.979832691296,34.663541466057,34.67836761724,12713069.0
+2017-08-31,34.94,35.18,34.87,35.07,15959145.0,0.0,1.0,34.535048155803,34.772266574733,34.465859450282,34.663541466057,15959145.0
+2017-08-30,34.75,34.96,34.63,34.89,18230633.0,0.0,1.0,34.347250240817,34.554816357381,34.228641031353,34.48562765186,18230633.0
+2017-08-29,34.51,34.75,34.455,34.73,15605382.0,0.0,1.0,34.110031821888,34.347250240817,34.05566926755,34.32748203924,15605382.0
+2017-08-28,34.78,34.8,34.59,34.65,20463229.0,0.0,1.0,34.376902543184,34.396670744761,34.189104628198,34.24840923293,20463229.0
+2017-08-25,34.82,34.93,34.58,34.67,14126663.0,0.0,1.0,34.416438946339,34.525164055014,34.179220527409,34.268177434508,14126663.0
+2017-08-24,34.7,34.89,34.55,34.71,13495890.0,0.0,1.0,34.297829736874,34.48562765186,34.149568225043,34.307713837663,13495890.0
+2017-08-23,34.54,34.81,34.38,34.66,19439392.0,0.0,1.0,34.139684124254,34.40655484555,33.981538511635,34.258293333719,19439392.0
+2017-08-22,35.02,35.19,34.62,34.65,25496798.0,0.0,1.0,34.614120962113,34.782150675521,34.218756930564,34.24840923293,25496798.0
+2017-08-21,35.09,35.28,34.7,34.92,25642017.0,0.0,1.0,34.683309667634,34.87110758262,34.297829736874,34.515279954226,25642017.0
+2017-08-18,35.29,35.31,34.99,35.01,15556756.0,0.0,1.0,34.880991683409,34.900759884986,34.584468659747,34.604236861324,15556756.0
+2017-08-17,35.6,35.68,35.17,35.17,18464078.0,0.0,1.0,35.187398807859,35.266471614169,34.762382473944,34.762382473944,18464078.0
+2017-08-16,35.98,36.07,35.56,35.82,21319536.0,0.0,1.0,35.562994637831,35.651951544929,35.147862404704,35.404849025211,21319536.0
+2017-08-15,36.3,36.32,35.815,36.0,20630421.0,0.0,1.0,35.87928586307,35.899054064647,35.399906974817,35.582762839408,20630421.0
+2017-08-14,36.12,36.47,36.08,36.34,16255600.0,0.0,1.0,35.701372048873,36.047315576478,35.661835645718,35.918822266225,16255600.0
+2017-08-11,36.26,36.4,35.79,35.87,18697159.0,0.0,1.0,35.839749459915,35.978126870957,35.375196722845,35.454269529155,18697159.0
+2017-08-10,36.4,36.56,36.11,36.12,22414962.0,0.0,1.0,35.978126870957,36.136272483577,35.691487948084,35.701372048873,22414962.0
+2017-08-09,36.28,36.66,36.02,36.59,22596679.0,0.0,1.0,35.859517661492,36.235113491464,35.602531040985,36.165924785943,22596679.0
+2017-08-08,36.37,36.7,36.3,36.41,21067835.0,0.0,1.0,35.948474568591,36.274649894619,35.87928586307,35.988010971746,21067835.0
+2017-08-04,36.45,36.56,36.1,36.3,20312844.0,0.0,1.0,36.027547374901,36.136272483577,35.681603847295,35.87928586307,20312844.0
+2017-08-03,36.55,36.59,36.15,36.49,26377878.0,0.273,1.0,36.126388382788,36.165924785943,35.731024351239,36.067083778056,26377878.0
+2017-08-02,36.33,36.67,36.055,36.64,34502824.0,0.0,1.0,35.642280381273,35.975844249416,35.372486076158,35.946412143404,34502824.0
+2017-08-01,35.66,36.43,35.57,36.35,37556349.0,0.0,1.0,34.984963346992,35.740387401316,34.896667028954,35.661901785282,37556349.0
+2017-07-31,35.47,35.74,35.32,35.47,26748090.0,0.0,1.0,34.798560008912,35.063448963025,34.651399478849,34.798560008912,26748090.0
+2017-07-28,35.13,35.86,35.0,35.31,35538732.0,0.0,1.0,34.464996140769,35.181177387076,34.337457014714,34.641588776845,35538732.0
+2017-07-27,34.78,35.25,34.67,34.97,39239149.0,0.0,1.0,34.121621570622,34.582724564819,34.013703848576,34.308024908702,39239149.0
+2017-07-26,34.7,34.97,34.59,34.75,15400452.0,0.0,1.0,34.043135954588,34.308024908702,33.935218232542,34.092189464609,15400452.0
+2017-07-25,34.55,34.735,34.4,34.67,17569006.0,0.0,1.0,33.895975424525,34.077473411603,33.748814894462,34.013703848576,17569006.0
+2017-07-24,34.73,34.8,34.38,34.5,15114242.0,0.0,1.0,34.072568060601,34.14124297463,33.729193490454,33.846921914504,15114242.0
+2017-07-21,34.54,34.82,34.395,34.73,21682999.0,0.0,1.0,33.886164722521,34.160864378639,33.74390954346,34.072568060601,21682999.0
+2017-07-20,34.54,34.84,34.475,34.75,16643270.0,0.0,1.0,33.886164722521,34.180485782647,33.822395159494,34.092189464609,16643270.0
+2017-07-19,34.68,34.68,34.46,34.56,15923372.0,0.0,1.0,34.02351455058,34.02351455058,33.807679106487,33.905786126529,15923372.0
+2017-07-18,34.43,34.58,34.25,34.53,14031968.0,0.0,1.0,33.778247000475,33.925407530538,33.601654364399,33.876354020517,14031968.0
+2017-07-17,34.74,34.74,34.36,34.47,20910434.0,0.0,1.0,34.082378762605,34.082378762605,33.709572086445,33.817489808492,20910434.0
+2017-07-14,34.48,34.71,34.265,34.68,16039785.0,0.0,1.0,33.827300510496,34.052946656592,33.616370417405,34.02351455058,16039785.0
+2017-07-13,34.33,34.4,34.12,34.24,14978889.0,0.0,1.0,33.680139980433,33.748814894462,33.474115238344,33.591843662395,14978889.0
+2017-07-12,34.28,34.39,33.94,34.25,23430086.0,0.0,1.0,33.631086470412,33.739004192458,33.297522602269,33.601654364399,23430086.0
+2017-07-11,33.64,33.93,33.4311,33.92,24800985.0,0.0,1.0,33.003201542143,33.287711900264,32.798255977275,33.27790119826,24800985.0
+2017-07-10,33.25,33.74,33.23,33.65,26781949.0,0.0,1.0,32.620584163979,33.101308562185,32.60096275997,33.013012244147,26781949.0
+2017-07-07,33.7,34.12,33.7,33.88,17702383.0,0.0,1.0,33.062065754168,33.474115238344,33.062065754168,33.238658390243,17702383.0
+2017-07-06,34.12,34.29,33.56,33.63,20161025.0,0.0,1.0,33.474115238344,33.640897172416,32.924715926109,32.993390840138,20161025.0
+2017-07-05,33.52,34.43,33.485,34.34,29307289.0,0.0,1.0,32.885473118092,33.778247000475,32.851135661077,33.689950682437,29307289.0
+2017-07-03,33.51,34.03,33.43,33.46,12676069.0,0.0,1.0,32.875662416088,33.385818920307,32.797176800054,32.826608906067,12676069.0
+2017-06-30,33.87,33.93,33.535,33.74,23636451.0,0.0,1.0,33.228847688239,33.287711900264,32.900189171098,33.101308562185,23636451.0
+2017-06-29,33.92,34.1,33.34,33.54,24613002.0,0.0,1.0,33.27790119826,33.454493834336,32.708880482016,32.905094522101,24613002.0
+2017-06-28,33.77,34.24,33.74,34.2,25777730.0,0.0,1.0,33.130740668197,33.591843662395,33.101308562185,33.552600854378,25777730.0
+2017-06-27,34.0,34.145,33.65,33.65,26891930.0,0.0,1.0,33.356386814294,33.498641993355,33.013012244147,33.013012244147,26891930.0
+2017-06-26,34.26,34.51,34.03,34.07,18379220.0,0.0,1.0,33.611465066403,33.856732616508,33.385818920307,33.425061728323,18379220.0
+2017-06-23,34.21,34.55,34.095,34.19,24381873.0,0.0,1.0,33.562411556382,33.895975424525,33.449588483334,33.542790152374,24381873.0
+2017-06-22,34.56,34.63,34.29,34.36,23744016.0,0.0,1.0,33.905786126529,33.974461040559,33.640897172416,33.709572086445,23744016.0
+2017-06-21,34.33,34.6,34.09,34.58,26338267.0,0.0,1.0,33.680139980433,33.945028934546,33.444683132332,33.925407530538,26338267.0
+2017-06-20,35.45,35.45,34.84,34.86,21024240.0,0.0,1.0,34.778938604904,34.778938604904,34.180485782647,34.200107186655,21024240.0
+2017-06-19,35.61,35.61,35.32,35.51,20336817.0,0.0,1.0,34.935909836971,34.935909836971,34.651399478849,34.837802816929,20336817.0
+2017-06-16,35.28,35.33,35.01,35.21,28353654.0,0.0,1.0,34.612156670832,34.661210180853,34.347267716719,34.543481756803,28353654.0
+2017-06-15,35.21,35.48,35.14,35.31,19954738.0,0.0,1.0,34.543481756803,34.808370710916,34.474806842773,34.641588776845,19954738.0
+2017-06-14,35.99,36.05,35.22,35.53,19001268.0,0.0,1.0,35.308716513131,35.367580725156,34.553292458807,34.857424220937,19001268.0
+2017-06-13,35.68,35.95,35.53,35.88,20398500.0,0.0,1.0,35.004584751,35.269473705114,34.857424220937,35.200798791084,20398500.0
+2017-06-12,35.59,36.01,35.41,35.73,27374877.0,0.0,1.0,34.916288432962,35.328337917139,34.739695796887,35.053638261021,27374877.0
+2017-06-09,36.5,36.56,35.31,35.71,32858966.0,0.0,1.0,35.809062315345,35.86792652737,34.641588776845,35.034016857013,32858966.0
+2017-06-08,36.34,36.53,36.16,36.48,16202388.0,0.0,1.0,35.652091083278,35.838494421358,35.475498447202,35.789440911337,16202388.0
+2017-06-07,36.13,36.57,36.1,36.26,16521287.0,0.0,1.0,35.446066341189,35.877737229374,35.416634235177,35.573605467244,16521287.0
+2017-06-06,36.16,36.45,35.98,36.13,18153646.0,0.0,1.0,35.475498447202,35.760008805324,35.298905811126,35.446066341189,18153646.0
+2017-06-05,36.3,36.5,36.2,36.34,11288983.0,0.0,1.0,35.612848275261,35.809062315345,35.514741255219,35.652091083278,11288983.0
+2017-06-02,36.27,36.33,36.0,36.32,18902927.0,0.0,1.0,35.583416169248,35.642280381273,35.318527215135,35.632469679269,18902927.0
+2017-06-01,36.12,36.13,35.8,36.12,17288864.0,0.0,1.0,35.436255639185,35.446066341189,35.122313175051,35.436255639185,17288864.0
diff --git a/examples/quick/demos/stocqt/content/data/MSFT.csv b/examples/quick/demos/stocqt/content/data/MSFT.csv
new file mode 100644
index 0000000000..056639e4c2
--- /dev/null
+++ b/examples/quick/demos/stocqt/content/data/MSFT.csv
@@ -0,0 +1,148 @@
+Date,Open,High,Low,Close,Volume,Ex-Dividend,Split Ratio,Adj. Open,Adj. High,Adj. Low,Adj. Close,Adj. Volume
+2017-12-29,85.63,86.05,85.5,85.54,18162779.0,0.0,1.0,85.63,86.05,85.5,85.54,18162779.0
+2017-12-28,85.9,85.93,85.55,85.72,9872795.0,0.0,1.0,85.9,85.93,85.55,85.72,9872795.0
+2017-12-27,85.65,85.98,85.215,85.71,13000828.0,0.0,1.0,85.65,85.98,85.215,85.71,13000828.0
+2017-12-26,85.31,85.5346,85.03,85.4,9737412.0,0.0,1.0,85.31,85.5346,85.03,85.4,9737412.0
+2017-12-22,85.4,85.63,84.92,85.51,14033977.0,0.0,1.0,85.4,85.63,84.92,85.51,14033977.0
+2017-12-21,86.05,86.1,85.4,85.5,16638402.0,0.0,1.0,86.05,86.1,85.4,85.5,16638402.0
+2017-12-20,86.2,86.3,84.71,85.52,23425009.0,0.0,1.0,86.2,86.3,84.71,85.52,23425009.0
+2017-12-19,86.35,86.35,85.27,85.83,23241979.0,0.0,1.0,86.35,86.35,85.27,85.83,23241979.0
+2017-12-18,87.12,87.4999,86.23,86.38,21551076.0,0.0,1.0,87.12,87.4999,86.23,86.38,21551076.0
+2017-12-15,85.26,87.09,84.88,86.85,52430167.0,0.0,1.0,85.26,87.09,84.88,86.85,52430167.0
+2017-12-14,85.43,85.8739,84.53,84.69,19080106.0,0.0,1.0,85.43,85.8739,84.53,84.69,19080106.0
+2017-12-13,85.74,86.0,85.17,85.35,21307911.0,0.0,1.0,85.74,86.0,85.17,85.35,21307911.0
+2017-12-12,85.31,86.05,85.08,85.58,23534946.0,0.0,1.0,85.31,86.05,85.08,85.58,23534946.0
+2017-12-11,84.29,85.37,84.12,85.23,19909119.0,0.0,1.0,84.29,85.37,84.12,85.23,19909119.0
+2017-12-08,83.63,84.58,83.33,84.16,23825056.0,0.0,1.0,83.63,84.58,83.33,84.16,23825056.0
+2017-12-07,82.54,82.8,82.0,82.49,20378114.0,0.0,1.0,82.54,82.8,82.0,82.49,20378114.0
+2017-12-06,81.55,83.14,81.43,82.78,24821403.0,0.0,1.0,81.55,83.14,81.43,82.78,24821403.0
+2017-12-05,81.34,82.68,80.9801,81.59,25512120.0,0.0,1.0,81.34,82.68,80.9801,81.59,25512120.0
+2017-12-04,84.42,84.4299,80.7,81.08,37977732.0,0.0,1.0,84.42,84.4299,80.7,81.08,37977732.0
+2017-12-01,83.6,84.81,83.22,84.26,29113662.0,0.0,1.0,83.6,84.81,83.22,84.26,29113662.0
+2017-11-30,83.51,84.52,83.34,84.17,32074914.0,0.0,1.0,83.51,84.52,83.34,84.17,32074914.0
+2017-11-29,84.71,84.9172,83.175,83.34,26401761.0,0.0,1.0,84.71,84.9172,83.175,83.34,26401761.0
+2017-11-28,84.07,85.06,84.02,84.88,21162639.0,0.0,1.0,84.07,85.06,84.02,84.88,21162639.0
+2017-11-27,83.31,83.98,83.3,83.87,17603760.0,0.0,1.0,83.31,83.98,83.3,83.87,17603760.0
+2017-11-24,83.01,83.43,82.78,83.26,7425503.0,0.0,1.0,83.01,83.43,82.78,83.26,7425503.0
+2017-11-22,83.83,83.9,83.04,83.11,20213704.0,0.0,1.0,83.83,83.9,83.04,83.11,20213704.0
+2017-11-21,82.74,83.84,82.74,83.72,21033981.0,0.0,1.0,82.74,83.84,82.74,83.72,21033981.0
+2017-11-20,82.4,82.59,82.25,82.53,16072495.0,0.0,1.0,82.4,82.59,82.25,82.53,16072495.0
+2017-11-17,83.12,83.12,82.24,82.4,21715498.0,0.0,1.0,83.12,83.12,82.24,82.4,21715498.0
+2017-11-16,83.1,83.42,82.94,83.2,20659209.0,0.0,1.0,83.1,83.42,82.94,83.2,20659209.0
+2017-11-15,83.47,83.69,82.69,82.98,19097333.0,0.42,1.0,83.47,83.69,82.69,82.98,19097333.0
+2017-11-14,83.5,84.1,82.98,84.05,18604034.0,0.0,1.0,83.079496402878,83.676474820144,82.562115107914,83.626726618705,18604034.0
+2017-11-13,83.66,83.94,83.46,83.93,14080820.0,0.0,1.0,83.238690647482,83.51728057554,83.039697841727,83.507330935252,14080820.0
+2017-11-10,83.79,84.095,83.23,83.87,19340435.0,0.0,1.0,83.368035971223,83.6715,82.810856115108,83.447633093525,19340435.0
+2017-11-09,84.11,84.27,82.9,84.09,20924172.0,0.0,1.0,83.686424460432,83.845618705036,82.482517985612,83.666525179856,20924172.0
+2017-11-07,84.77,84.9,83.93,84.27,17152583.0,0.0,1.0,84.343100719424,84.472446043165,83.507330935252,83.845618705036,17152583.0
+2017-11-06,84.2,84.7,84.0825,84.47,19039847.0,0.0,1.0,83.775971223022,84.27345323741,83.65906294964,84.044611510791,19039847.0
+2017-11-03,84.08,84.54,83.4,84.14,17569120.0,0.0,1.0,83.656575539568,84.114258992806,82.98,83.716273381295,17569120.0
+2017-11-02,83.35,84.46,83.12,84.05,23822964.0,0.0,1.0,82.930251798561,84.034661870504,82.701410071942,83.626726618705,23822964.0
+2017-11-01,83.68,83.76,82.88,83.18,22039635.0,0.0,1.0,83.258589928058,83.33818705036,82.462618705036,82.761107913669,22039635.0
+2017-10-31,84.36,84.36,83.11,83.18,26728947.0,0.0,1.0,83.935165467626,83.935165467626,82.691460431655,82.761107913669,26728947.0
+2017-10-30,83.7,84.325,83.105,83.89,31291801.0,0.0,1.0,83.278489208633,83.900341726619,82.686485611511,83.467532374101,31291801.0
+2017-10-27,84.37,86.2,83.61,83.81,70877350.0,0.0,1.0,83.945115107914,85.765899280576,83.188942446043,83.387935251799,70877350.0
+2017-10-26,79.2,79.42,78.75,78.76,29181652.0,0.0,1.0,78.801151079137,79.020043165468,78.353417266187,78.363366906475,29181652.0
+2017-10-25,78.58,79.1,78.01,78.63,19714512.0,0.0,1.0,78.184273381295,78.701654676259,77.617143884892,78.234021582734,19714512.0
+2017-10-24,78.9,79.2,78.46,78.86,16613928.0,0.0,1.0,78.502661870504,78.801151079137,78.064877697842,78.462863309353,16613928.0
+2017-10-23,78.99,79.34,78.76,78.83,20479731.0,0.0,1.0,78.592208633094,78.940446043165,78.363366906475,78.433014388489,20479731.0
+2017-10-20,78.32,78.97,78.22,78.81,22517092.0,0.0,1.0,77.925582733813,78.572309352518,77.826086330935,78.413115107914,22517092.0
+2017-10-19,77.57,77.93,77.35,77.91,14982129.0,0.0,1.0,77.17935971223,77.53754676259,76.960467625899,77.517647482014,14982129.0
+2017-10-18,77.67,77.85,77.37,77.61,13147124.0,0.0,1.0,77.278856115108,77.457949640288,76.980366906475,77.219158273381,13147124.0
+2017-10-17,77.47,77.62,77.25,77.59,15953665.0,0.0,1.0,77.079863309353,77.229107913669,76.860971223022,77.199258992806,15953665.0
+2017-10-16,77.42,77.81,77.35,77.65,12331147.0,0.0,1.0,77.030115107914,77.418151079137,76.960467625899,77.258956834532,12331147.0
+2017-10-13,77.59,77.87,77.29,77.49,15250772.0,0.0,1.0,77.199258992806,77.477848920863,76.900769784173,77.099762589928,15250772.0
+2017-10-12,76.49,77.29,76.37,77.12,16778148.0,0.0,1.0,76.104798561151,76.900769784173,75.985402877698,76.731625899281,16778148.0
+2017-10-11,76.36,76.46,75.95,76.42,14780652.0,0.0,1.0,75.97545323741,76.074949640288,75.567517985612,76.035151079137,14780652.0
+2017-10-10,76.33,76.63,76.14,76.29,13734627.0,0.0,1.0,75.945604316547,76.24409352518,75.756561151079,75.905805755396,13734627.0
+2017-10-09,75.97,76.55,75.86,76.29,11364275.0,0.0,1.0,75.587417266187,76.164496402878,75.477971223022,75.905805755396,11364275.0
+2017-10-06,75.67,76.03,75.54,76.0,13692791.0,0.0,1.0,75.288928057554,75.647115107914,75.159582733813,75.61726618705,13692791.0
+2017-10-05,75.22,76.12,74.96,75.97,20656238.0,0.0,1.0,74.841194244604,75.736661870504,74.582503597122,75.587417266187,20656238.0
+2017-10-04,74.0,74.72,73.71,74.69,13287346.0,0.0,1.0,73.627338129496,74.343712230216,73.338798561151,74.313863309353,13287346.0
+2017-10-03,74.67,74.88,74.195,74.26,11935853.0,0.0,1.0,74.293964028777,74.50290647482,73.821356115108,73.886028776978,11935853.0
+2017-10-02,74.71,75.01,74.295,74.61,15210338.0,0.0,1.0,74.333762589928,74.632251798561,73.920852517986,74.23426618705,15210338.0
+2017-09-29,73.94,74.535,73.88,74.49,16700435.0,0.0,1.0,73.56764028777,74.159643884892,73.507942446043,74.114870503597,16700435.0
+2017-09-28,73.54,73.97,73.31,73.87,10814063.0,0.0,1.0,73.169654676259,73.597489208633,72.94081294964,73.497992805755,10814063.0
+2017-09-27,73.55,74.17,73.17,73.85,18934048.0,0.0,1.0,73.179604316547,73.796482014388,72.801517985612,73.47809352518,18934048.0
+2017-09-26,73.67,73.81,72.99,73.26,17105469.0,0.0,1.0,73.299,73.438294964029,72.622424460432,72.891064748201,17105469.0
+2017-09-25,74.09,74.25,72.92,73.26,23502422.0,0.0,1.0,73.716884892086,73.876079136691,72.552776978417,72.891064748201,23502422.0
+2017-09-22,73.99,74.51,73.85,74.41,13969937.0,0.0,1.0,73.617388489209,74.134769784173,73.47809352518,74.035273381295,13969937.0
+2017-09-21,75.11,75.24,74.11,74.21,19038998.0,0.0,1.0,74.731748201439,74.86109352518,73.736784172662,73.83628057554,19038998.0
+2017-09-20,75.35,75.55,74.31,74.94,20415084.0,0.0,1.0,74.970539568345,75.169532374101,73.935776978417,74.562604316547,20415084.0
+2017-09-19,75.21,75.71,75.01,75.44,15606870.0,0.0,1.0,74.831244604317,75.328726618705,74.632251798561,75.060086330935,15606870.0
+2017-09-18,75.23,75.97,75.04,75.16,22730355.0,0.0,1.0,74.851143884892,75.587417266187,74.662100719424,74.781496402878,22730355.0
+2017-09-15,74.83,75.39,74.07,75.31,37901927.0,0.0,1.0,74.453158273381,75.010338129496,73.696985611511,74.930741007194,37901927.0
+2017-09-14,75.0,75.49,74.52,74.77,15373384.0,0.0,1.0,74.622302158273,75.109834532374,74.14471942446,74.393460431655,15373384.0
+2017-09-13,74.93,75.23,74.55,75.21,12998629.0,0.0,1.0,74.552654676259,74.851143884892,74.174568345324,74.831244604317,12998629.0
+2017-09-12,74.76,75.24,74.37,74.68,14003880.0,0.0,1.0,74.383510791367,74.86109352518,73.995474820144,74.303913669065,14003880.0
+2017-09-11,74.31,74.945,74.31,74.76,17428067.0,0.0,1.0,73.935776978417,74.567579136691,73.935776978417,74.383510791367,17428067.0
+2017-09-08,74.33,74.44,73.84,73.98,14474383.0,0.0,1.0,73.955676258993,74.065122302158,73.468143884892,73.607438848921,14474383.0
+2017-09-07,73.68,74.6,73.6,74.34,17165518.0,0.0,1.0,73.308949640288,74.224316546763,73.229352517986,73.965625899281,17165518.0
+2017-09-06,73.74,74.04,73.35,73.4,15945136.0,0.0,1.0,73.368647482014,73.667136690647,72.980611510791,73.03035971223,15945136.0
+2017-09-05,73.34,73.89,72.98,73.61,21432599.0,0.0,1.0,72.970661870504,73.517892086331,72.612474820144,73.239302158273,21432599.0
+2017-09-01,74.71,74.74,73.64,73.94,21593192.0,0.0,1.0,74.333762589928,74.363611510791,73.269151079137,73.56764028777,21593192.0
+2017-08-31,74.03,74.96,73.8,74.77,26688077.0,0.0,1.0,73.65718705036,74.582503597122,73.428345323741,74.393460431655,26688077.0
+2017-08-30,73.01,74.2099,72.8293,74.01,16826094.0,0.0,1.0,72.642323741007,73.836181079137,72.462533741007,73.637287769784,16826094.0
+2017-08-29,72.25,73.16,72.05,73.05,11325418.0,0.0,1.0,71.886151079137,72.791568345324,71.687158273381,72.682122302158,11325418.0
+2017-08-28,73.06,73.09,72.55,72.83,14112777.0,0.0,1.0,72.692071942446,72.721920863309,72.18464028777,72.463230215827,14112777.0
+2017-08-25,72.86,73.35,72.48,72.82,12574503.0,0.0,1.0,72.493079136691,72.980611510791,72.114992805755,72.45328057554,12574503.0
+2017-08-24,72.74,72.86,72.07,72.69,15980144.0,0.0,1.0,72.373683453237,72.493079136691,71.707057553957,72.323935251799,15980144.0
+2017-08-23,72.96,73.15,72.53,72.72,13586784.0,0.0,1.0,72.592575539568,72.781618705036,72.164741007194,72.353784172662,13586784.0
+2017-08-22,72.35,73.24,72.35,73.16,14183146.0,0.0,1.0,71.985647482014,72.871165467626,71.985647482014,72.791568345324,14183146.0
+2017-08-21,72.47,72.48,71.7,72.15,17656716.0,0.0,1.0,72.105043165468,72.114992805755,71.338920863309,71.786654676259,17656716.0
+2017-08-18,72.27,72.84,71.93,72.49,18215276.0,0.0,1.0,71.906050359712,72.473179856115,71.567762589928,72.124942446043,18215276.0
+2017-08-17,73.58,73.87,72.4,72.4,21834250.0,0.0,1.0,73.20945323741,73.497992805755,72.035395683453,72.035395683453,21834250.0
+2017-08-16,73.34,74.1,73.17,73.65,17814317.0,0.0,1.0,72.970661870504,73.726834532374,72.801517985612,73.279100719424,17814317.0
+2017-08-15,73.59,73.59,73.04,73.22,17791179.0,0.39,1.0,73.219402877698,73.219402877698,72.672172661871,72.85126618705,17791179.0
+2017-08-14,73.06,73.72,72.95,73.59,19756773.0,0.0,1.0,72.306935302621,72.960132363936,72.198069125735,72.831472336707,19756773.0
+2017-08-11,71.61,72.7,71.28,72.5,21121250.0,0.0,1.0,70.87188115276,71.950645996448,70.545282622102,71.752707493019,21121250.0
+2017-08-10,71.9,72.19,71.35,71.41,23153711.0,0.0,1.0,71.158891982732,71.445902812704,70.614561098302,70.673942649331,23153711.0
+2017-08-09,72.25,72.51,72.05,72.47,20401071.0,0.0,1.0,71.505284363733,71.762604418191,71.307345860304,71.723016717505,20401071.0
+2017-08-08,72.09,73.13,71.75,72.79,21446993.0,0.0,1.0,71.34693356099,72.376213778821,71.01043810516,72.039718322991,21446993.0
+2017-08-07,72.8,72.9,72.26,72.4,18582345.0,0.0,1.0,72.049615248163,72.148584499877,71.515181288904,71.653738241305,18582345.0
+2017-08-04,72.4,73.04,72.24,72.68,22412719.0,0.0,1.0,71.653738241305,72.287141452278,71.495387438562,71.930852146105,22412719.0
+2017-08-03,72.19,72.44,71.845,72.15,17937522.0,0.0,1.0,71.445902812704,71.693325941991,71.104458894289,71.406315112019,17937522.0
+2017-08-02,72.55,72.56,71.445,72.26,26405096.0,0.0,1.0,71.802192118877,71.812089044048,70.708581887431,71.515181288904,26405096.0
+2017-08-01,73.1,73.42,72.49,72.58,19060885.0,0.0,1.0,72.346523003306,72.663224608793,71.742810567848,71.831882894391,19060885.0
+2017-07-31,73.3,73.44,72.41,72.72,23151962.0,0.0,1.0,72.544461506735,72.683018459136,71.663635166476,71.970439846791,23151962.0
+2017-07-28,72.67,73.31,72.54,73.04,17472880.0,0.0,1.0,71.920955220934,72.554358431907,71.792295193705,72.287141452278,17472880.0
+2017-07-27,73.76,74.42,72.32,73.16,35518251.0,0.0,1.0,72.999720064622,73.652917125938,71.574562839933,72.405904554335,35518251.0
+2017-07-26,74.34,74.38,73.81,74.05,15850344.0,0.0,1.0,73.573741724566,73.613329425252,73.049204690479,73.286730894594,15850344.0
+2017-07-25,73.8,74.31,73.5,74.19,21522189.0,0.0,1.0,73.039307765308,73.544050949052,72.742400010164,73.425287846995,21522189.0
+2017-07-24,73.53,73.75,73.13,73.6,20836422.0,0.0,1.0,72.772090785679,72.989823139451,72.376213778821,72.841369261879,20836422.0
+2017-07-21,73.45,74.29,73.17,73.79,45302930.0,0.0,1.0,72.692915384307,73.524257098709,72.415801479507,73.029410840136,45302930.0
+2017-07-20,74.18,74.3,73.28,74.24,34174677.0,0.0,1.0,73.415390921823,73.53415402388,72.524667656392,73.474772472852,34174677.0
+2017-07-19,73.5,74.04,73.45,73.86,21769229.0,0.0,1.0,72.742400010164,73.276833969423,72.692915384307,73.098689316337,21769229.0
+2017-07-18,73.09,73.39,72.66,73.3,26150272.0,0.0,1.0,72.336626078135,72.633533833278,71.911058295763,72.544461506735,26150272.0
+2017-07-17,72.8,73.45,72.72,73.35,21481069.0,0.0,1.0,72.049615248163,72.692915384307,71.970439846791,72.593946132593,21481069.0
+2017-07-14,72.24,73.27,71.96,72.78,25689303.0,0.0,1.0,71.495387438562,72.514770731221,71.218273533761,72.02982139782,25689303.0
+2017-07-13,71.5,72.0399,71.31,71.77,20149208.0,0.0,1.0,70.763014975874,71.297349965881,70.574973397617,71.030231955503,20149208.0
+2017-07-12,70.69,71.28,70.55,71.15,17382861.0,0.0,1.0,69.961364036987,70.545282622102,69.822807084586,70.416622594873,17382861.0
+2017-07-11,70.0,70.68,69.75,69.99,16880205.0,0.0,1.0,69.278476200157,69.951467111815,69.03105307087,69.268579274985,16880205.0
+2017-07-10,69.46,70.25,69.2,69.98,14903400.0,0.0,1.0,68.744042240898,69.525899329443,68.486722186441,69.258682349814,14903400.0
+2017-07-07,68.7,69.84,68.7,69.46,15897154.0,0.0,1.0,67.991875927868,69.120125397413,67.991875927868,68.744042240898,15897154.0
+2017-07-06,68.27,68.78,68.12,68.57,20776555.0,0.0,1.0,67.566308145496,68.07105132924,67.417854267924,67.863215900639,20776555.0
+2017-07-05,68.255,69.44,68.22,69.08,20174523.0,0.0,1.0,67.551462757738,68.724248390555,67.516823519638,68.367959084383,20174523.0
+2017-07-03,69.33,69.6,68.02,68.17,16164331.0,0.0,1.0,68.615382213669,68.882599193299,67.318885016209,67.467338893781,16164331.0
+2017-06-30,68.78,69.38,68.74,68.93,23039328.0,0.0,1.0,68.07105132924,68.664866839527,68.031463628554,68.219505206811,23039328.0
+2017-06-29,69.38,69.49,68.09,68.49,28231562.0,0.0,1.0,68.664866839527,68.773733016413,67.388163492409,67.784040499267,28231562.0
+2017-06-28,69.21,69.841,68.79,69.8,25226070.0,0.0,1.0,68.496619111612,69.12111508993,68.080948254411,69.080537696728,25226070.0
+2017-06-27,70.11,70.18,69.18,69.21,24862560.0,0.0,1.0,69.387342377043,69.456620853243,68.466928336098,68.496619111612,24862560.0
+2017-06-26,71.4,71.71,70.445,70.53,19308122.0,0.0,1.0,70.66404572416,70.970850404475,69.718889370286,69.803013234243,19308122.0
+2017-06-23,70.09,71.25,69.92,71.21,23176418.0,0.0,1.0,69.3675485267,70.515591846588,69.199300798785,70.476004145902,23176418.0
+2017-06-22,70.54,70.59,69.71,70.26,22222851.0,0.0,1.0,69.812910159415,69.862394785272,68.991465370184,69.535796254614,22222851.0
+2017-06-21,70.21,70.62,69.94,70.27,19190623.0,0.0,1.0,69.486311628757,69.892085560787,69.219094649128,69.545693179786,19190623.0
+2017-06-20,70.82,70.87,69.87,69.91,20775590.0,0.0,1.0,70.090024064216,70.139508690073,69.149816172928,69.189403873614,20775590.0
+2017-06-19,70.5,70.945,70.35,70.87,23146852.0,0.0,1.0,69.773322458729,70.213735628859,69.624868581157,70.139508690073,23146852.0
+2017-06-16,69.73,70.0252,69.22,70.0,46911637.0,0.0,1.0,69.011259220527,69.303416451589,68.506516036783,69.278476200157,46911637.0
+2017-06-15,69.27,70.21,68.8,69.9,25701569.0,0.0,1.0,68.556000662641,69.486311628757,68.090845179582,69.179506948442,25701569.0
+2017-06-14,70.91,71.1,69.43,70.27,25271276.0,0.0,1.0,70.179096390759,70.367137969016,68.714351465384,69.545693179786,25271276.0
+2017-06-13,70.02,70.82,69.96,70.65,24815455.0,0.0,1.0,69.298270050499,70.090024064216,69.238888499471,69.921776336301,24815455.0
+2017-06-12,69.25,69.94,68.13,69.78,47363986.0,0.0,1.0,68.536206812298,69.219094649128,67.427751193095,69.060743846385,47363986.0
+2017-06-09,72.035,72.08,68.59,70.32,48619420.0,0.0,1.0,71.292500472547,71.337036635818,67.883009750982,69.595177805643,48619420.0
+2017-06-08,72.51,72.52,71.5,71.945,23982410.0,0.0,1.0,71.762604418191,71.772501343362,70.763014975874,71.203428146004,23982410.0
+2017-06-07,72.635,72.77,71.95,72.39,21895156.0,0.0,1.0,71.886315982834,72.019924472648,71.20837660859,71.643841316133,21895156.0
+2017-06-06,72.3,72.62,72.27,72.52,31220057.0,0.0,1.0,71.55476898959,71.871470595077,71.525078214076,71.772501343362,31220057.0
+2017-06-05,71.97,72.89,71.81,72.28,29507429.0,0.0,1.0,71.228170458932,72.138687574706,71.069819656189,71.534975139247,29507429.0
+2017-06-02,70.44,71.86,70.24,71.76,34586054.0,0.0,1.0,69.7139409077,71.119304282046,69.516002404271,71.020335030332,34586054.0
+2017-06-01,70.24,70.61,69.451,70.1,21066468.0,0.0,1.0,69.516002404271,69.882188635615,68.735135008244,69.377445451871,21066468.0
diff --git a/examples/quick/demos/stocqt/content/data/NCLH.csv b/examples/quick/demos/stocqt/content/data/NCLH.csv
new file mode 100644
index 0000000000..3827fd20ad
--- /dev/null
+++ b/examples/quick/demos/stocqt/content/data/NCLH.csv
@@ -0,0 +1,148 @@
+Date,Open,High,Low,Close,Volume,Ex-Dividend,Split Ratio,Adj. Open,Adj. High,Adj. Low,Adj. Close,Adj. Volume
+2017-12-29,53.45,53.96,53.2,53.25,889909.0,0.0,1.0,53.45,53.96,53.2,53.25,889909.0
+2017-12-28,54.01,54.03,53.34,53.61,1186989.0,0.0,1.0,54.01,54.03,53.34,53.61,1186989.0
+2017-12-27,53.95,54.19,53.7,54.0,792700.0,0.0,1.0,53.95,54.19,53.7,54.0,792700.0
+2017-12-26,53.93,54.25,53.65,53.73,906947.0,0.0,1.0,53.93,54.25,53.65,53.73,906947.0
+2017-12-22,54.325,54.47,53.72,54.03,1251857.0,0.0,1.0,54.325,54.47,53.72,54.03,1251857.0
+2017-12-21,54.9,55.31,54.01,54.14,1346967.0,0.0,1.0,54.9,55.31,54.01,54.14,1346967.0
+2017-12-20,55.74,56.41,54.74,54.82,1797666.0,0.0,1.0,55.74,56.41,54.74,54.82,1797666.0
+2017-12-19,55.14,56.05,55.02,55.59,1592622.0,0.0,1.0,55.14,56.05,55.02,55.59,1592622.0
+2017-12-18,54.51,55.355,54.5,54.98,2094664.0,0.0,1.0,54.51,55.355,54.5,54.98,2094664.0
+2017-12-15,53.14,54.3,52.58,54.0,6275489.0,0.0,1.0,53.14,54.3,52.58,54.0,6275489.0
+2017-12-14,53.16,53.46,52.7,52.81,1433280.0,0.0,1.0,53.16,53.46,52.7,52.81,1433280.0
+2017-12-13,53.93,53.93,53.09,53.16,1222815.0,0.0,1.0,53.93,53.93,53.09,53.16,1222815.0
+2017-12-12,54.64,54.64,53.55,53.65,1640536.0,0.0,1.0,54.64,54.64,53.55,53.65,1640536.0
+2017-12-11,54.75,55.37,54.33,54.72,1492003.0,0.0,1.0,54.75,55.37,54.33,54.72,1492003.0
+2017-12-08,54.74,55.57,54.36,55.03,1249849.0,0.0,1.0,54.74,55.57,54.36,55.03,1249849.0
+2017-12-07,54.5,54.62,54.08,54.34,1093747.0,0.0,1.0,54.5,54.62,54.08,54.34,1093747.0
+2017-12-06,54.49,54.8,53.7,54.31,1161732.0,0.0,1.0,54.49,54.8,53.7,54.31,1161732.0
+2017-12-05,55.53,55.67,54.265,54.33,938087.0,0.0,1.0,55.53,55.67,54.265,54.33,938087.0
+2017-12-04,55.68,56.84,55.3,55.41,2507341.0,0.0,1.0,55.68,56.84,55.3,55.41,2507341.0
+2017-12-01,53.94,54.91,53.675,54.81,1314538.0,0.0,1.0,53.94,54.91,53.675,54.81,1314538.0
+2017-11-30,54.0,54.69,52.36,54.16,3452181.0,0.0,1.0,54.0,54.69,52.36,54.16,3452181.0
+2017-11-29,55.48,56.21,55.12,55.29,1637536.0,0.0,1.0,55.48,56.21,55.12,55.29,1637536.0
+2017-11-28,55.62,55.83,54.92,55.31,1759104.0,0.0,1.0,55.62,55.83,54.92,55.31,1759104.0
+2017-11-27,55.55,56.03,55.47,55.61,1224822.0,0.0,1.0,55.55,56.03,55.47,55.61,1224822.0
+2017-11-24,55.41,55.74,55.01,55.5,550824.0,0.0,1.0,55.41,55.74,55.01,55.5,550824.0
+2017-11-22,55.42,56.0,55.11,55.31,1270402.0,0.0,1.0,55.42,56.0,55.11,55.31,1270402.0
+2017-11-21,54.93,55.88,54.8,55.48,2014071.0,0.0,1.0,54.93,55.88,54.8,55.48,2014071.0
+2017-11-20,54.78,55.09,54.28,54.69,2306354.0,0.0,1.0,54.78,55.09,54.28,54.69,2306354.0
+2017-11-17,54.12,54.9,53.69,54.84,3943455.0,0.0,1.0,54.12,54.9,53.69,54.84,3943455.0
+2017-11-16,53.85,54.3,53.5,53.97,6186166.0,0.0,1.0,53.85,54.3,53.5,53.97,6186166.0
+2017-11-15,55.09,55.19,54.58,55.07,1345399.0,0.0,1.0,55.09,55.19,54.58,55.07,1345399.0
+2017-11-14,55.08,55.22,54.1,55.1,1301048.0,0.0,1.0,55.08,55.22,54.1,55.1,1301048.0
+2017-11-13,54.91,55.34,54.65,55.27,1717783.0,0.0,1.0,54.91,55.34,54.65,55.27,1717783.0
+2017-11-10,55.75,56.06,54.07,55.23,2272543.0,0.0,1.0,55.75,56.06,54.07,55.23,2272543.0
+2017-11-09,55.74,58.27,55.29,56.89,3115303.0,0.0,1.0,55.74,58.27,55.29,56.89,3115303.0
+2017-11-07,56.55,57.37,54.97,55.36,1793433.0,0.0,1.0,56.55,57.37,54.97,55.36,1793433.0
+2017-11-06,55.0,56.12,54.905,55.26,1518782.0,0.0,1.0,55.0,56.12,54.905,55.26,1518782.0
+2017-11-03,54.91,55.09,54.53,55.03,922980.0,0.0,1.0,54.91,55.09,54.53,55.03,922980.0
+2017-11-02,54.27,55.17,54.205,54.91,2134024.0,0.0,1.0,54.27,55.17,54.205,54.91,2134024.0
+2017-11-01,56.06,56.1,54.04,54.2,2246546.0,0.0,1.0,56.06,56.1,54.04,54.2,2246546.0
+2017-10-31,54.82,55.98,54.715,55.75,1441239.0,0.0,1.0,54.82,55.98,54.715,55.75,1441239.0
+2017-10-30,55.29,55.67,54.67,54.8,972388.0,0.0,1.0,55.29,55.67,54.67,54.8,972388.0
+2017-10-27,54.8,56.28,54.49,55.64,2308873.0,0.0,1.0,54.8,56.28,54.49,55.64,2308873.0
+2017-10-26,54.8,55.25,54.53,54.92,1373500.0,0.0,1.0,54.8,55.25,54.53,54.92,1373500.0
+2017-10-25,54.67,55.19,54.38,54.79,2407822.0,0.0,1.0,54.67,55.19,54.38,54.79,2407822.0
+2017-10-24,53.63,54.78,53.5,54.66,2467749.0,0.0,1.0,53.63,54.78,53.5,54.66,2467749.0
+2017-10-23,53.76,54.1014,53.531,53.72,1984765.0,0.0,1.0,53.76,54.1014,53.531,53.72,1984765.0
+2017-10-20,54.87,54.94,53.45,53.73,3459633.0,0.0,1.0,54.87,54.94,53.45,53.73,3459633.0
+2017-10-19,56.4,56.52,53.8,54.17,7936900.0,0.0,1.0,56.4,56.52,53.8,54.17,7936900.0
+2017-10-18,58.45,58.45,57.13,57.47,4187580.0,0.0,1.0,58.45,58.45,57.13,57.47,4187580.0
+2017-10-17,58.69,59.0,58.44,58.61,2360423.0,0.0,1.0,58.69,59.0,58.44,58.61,2360423.0
+2017-10-16,58.83,59.15,58.4,58.92,2088445.0,0.0,1.0,58.83,59.15,58.4,58.92,2088445.0
+2017-10-13,59.43,59.6,58.22,58.74,3925398.0,0.0,1.0,59.43,59.6,58.22,58.74,3925398.0
+2017-10-12,58.56,59.3,58.43,58.86,29345290.0,0.0,1.0,58.56,59.3,58.43,58.86,29345290.0
+2017-10-11,59.15,59.42,58.58,58.8,2721843.0,0.0,1.0,59.15,59.42,58.58,58.8,2721843.0
+2017-10-10,59.19,59.535,58.985,59.16,2658838.0,0.0,1.0,59.19,59.535,58.985,59.16,2658838.0
+2017-10-09,58.75,59.66,58.71,58.89,2211669.0,0.0,1.0,58.75,59.66,58.71,58.89,2211669.0
+2017-10-06,58.25,59.4,58.25,58.84,3026934.0,0.0,1.0,58.25,59.4,58.25,58.84,3026934.0
+2017-10-05,58.01,58.54,57.53,58.41,7767820.0,0.0,1.0,58.01,58.54,57.53,58.41,7767820.0
+2017-10-04,54.58,56.2,54.53,55.98,1566581.0,0.0,1.0,54.58,56.2,54.53,55.98,1566581.0
+2017-10-03,54.46,55.11,54.03,54.73,1212466.0,0.0,1.0,54.46,55.11,54.03,54.73,1212466.0
+2017-10-02,53.94,54.53,53.6,54.42,1111899.0,0.0,1.0,53.94,54.53,53.6,54.42,1111899.0
+2017-09-29,53.46,54.15,52.44,54.05,2508346.0,0.0,1.0,53.46,54.15,52.44,54.05,2508346.0
+2017-09-28,52.52,53.93,51.99,53.65,2527667.0,0.0,1.0,52.52,53.93,51.99,53.65,2527667.0
+2017-09-27,54.99,55.04,52.74,52.83,1960663.0,0.0,1.0,54.99,55.04,52.74,52.83,1960663.0
+2017-09-26,54.46,55.68,54.26,54.89,2549545.0,0.0,1.0,54.46,55.68,54.26,54.89,2549545.0
+2017-09-25,53.74,54.11,53.23,53.6,1422751.0,0.0,1.0,53.74,54.11,53.23,53.6,1422751.0
+2017-09-22,54.09,54.81,53.75,54.02,1392579.0,0.0,1.0,54.09,54.81,53.75,54.02,1392579.0
+2017-09-21,54.54,54.83,53.95,54.4,1231315.0,0.0,1.0,54.54,54.83,53.95,54.4,1231315.0
+2017-09-20,55.36,55.42,53.71,54.36,2204298.0,0.0,1.0,55.36,55.42,53.71,54.36,2204298.0
+2017-09-19,56.27,56.27,55.29,55.46,1504249.0,0.0,1.0,56.27,56.27,55.29,55.46,1504249.0
+2017-09-18,56.7,57.21,56.28,56.35,1455687.0,0.0,1.0,56.7,57.21,56.28,56.35,1455687.0
+2017-09-15,56.55,56.74,55.28,56.74,3808399.0,0.0,1.0,56.55,56.74,55.28,56.74,3808399.0
+2017-09-14,57.35,58.58,57.25,57.72,1354813.0,0.0,1.0,57.35,58.58,57.25,57.72,1354813.0
+2017-09-13,56.94,57.84,56.75,57.79,1399743.0,0.0,1.0,56.94,57.84,56.75,57.79,1399743.0
+2017-09-12,56.92,57.22,56.41,57.2,1019670.0,0.0,1.0,56.92,57.22,56.41,57.2,1019670.0
+2017-09-11,56.19,58.2,56.0,56.65,2870913.0,0.0,1.0,56.19,58.2,56.0,56.65,2870913.0
+2017-09-08,55.84,56.98,55.01,55.12,1537947.0,0.0,1.0,55.84,56.98,55.01,55.12,1537947.0
+2017-09-07,57.0,57.43,55.77,55.86,1642298.0,0.0,1.0,57.0,57.43,55.77,55.86,1642298.0
+2017-09-06,56.53,57.17,55.91,57.12,1961468.0,0.0,1.0,56.53,57.17,55.91,57.12,1961468.0
+2017-09-05,58.51,58.54,55.3,56.69,2810897.0,0.0,1.0,58.51,58.54,55.3,56.69,2810897.0
+2017-09-01,59.62,60.0,58.48,58.54,1159890.0,0.0,1.0,59.62,60.0,58.48,58.54,1159890.0
+2017-08-31,58.42,59.5,58.41,59.46,1792821.0,0.0,1.0,58.42,59.5,58.41,59.46,1792821.0
+2017-08-30,57.53,58.8,57.25,58.22,1430195.0,0.0,1.0,57.53,58.8,57.25,58.22,1430195.0
+2017-08-29,57.43,57.74,56.47,57.64,1532747.0,0.0,1.0,57.43,57.74,56.47,57.64,1532747.0
+2017-08-28,57.98,58.03,57.48,57.88,878613.0,0.0,1.0,57.98,58.03,57.48,57.88,878613.0
+2017-08-25,57.99,58.0,57.58,57.72,1934962.0,0.0,1.0,57.99,58.0,57.58,57.72,1934962.0
+2017-08-24,57.33,57.905,57.29,57.73,1495111.0,0.0,1.0,57.33,57.905,57.29,57.73,1495111.0
+2017-08-23,56.53,57.91,56.53,57.15,1903662.0,0.0,1.0,56.53,57.91,56.53,57.15,1903662.0
+2017-08-22,56.01,57.03,56.01,56.9,1072763.0,0.0,1.0,56.01,57.03,56.01,56.9,1072763.0
+2017-08-21,55.81,56.15,55.59,55.86,980583.0,0.0,1.0,55.81,56.15,55.59,55.86,980583.0
+2017-08-18,56.33,56.33,55.26,55.78,1424778.0,0.0,1.0,56.33,56.33,55.26,55.78,1424778.0
+2017-08-17,57.98,58.07,56.01,56.18,2067539.0,0.0,1.0,57.98,58.07,56.01,56.18,2067539.0
+2017-08-16,57.8,58.41,57.44,57.9,1434593.0,0.0,1.0,57.8,58.41,57.44,57.9,1434593.0
+2017-08-15,57.61,58.56,57.22,57.45,2822548.0,0.0,1.0,57.61,58.56,57.22,57.45,2822548.0
+2017-08-14,57.14,57.83,57.01,57.46,2619908.0,0.0,1.0,57.14,57.83,57.01,57.46,2619908.0
+2017-08-11,54.75,57.17,54.15,56.77,12874815.0,0.0,1.0,54.75,57.17,54.15,56.77,12874815.0
+2017-08-10,58.04,58.16,56.9,57.07,1656606.0,0.0,1.0,58.04,58.16,56.9,57.07,1656606.0
+2017-08-09,58.88,58.99,58.05,58.36,2075241.0,0.0,1.0,58.88,58.99,58.05,58.36,2075241.0
+2017-08-08,59.05,61.48,58.85,59.42,5341341.0,0.0,1.0,59.05,61.48,58.85,59.42,5341341.0
+2017-08-07,57.15,57.62,56.49,56.65,2833326.0,0.0,1.0,57.15,57.62,56.49,56.65,2833326.0
+2017-08-04,56.47,57.48,56.27,56.9,1265045.0,0.0,1.0,56.47,57.48,56.27,56.9,1265045.0
+2017-08-03,55.77,56.96,55.77,56.25,1152770.0,0.0,1.0,55.77,56.96,55.77,56.25,1152770.0
+2017-08-02,56.89,57.25,55.45,55.84,1255978.0,0.0,1.0,56.89,57.25,55.45,55.84,1255978.0
+2017-08-01,56.49,57.25,56.15,56.91,2486095.0,0.0,1.0,56.49,57.25,56.15,56.91,2486095.0
+2017-07-31,55.45,55.73,54.975,55.07,886281.0,0.0,1.0,55.45,55.73,54.975,55.07,886281.0
+2017-07-28,54.71,55.26,54.39,55.21,983892.0,0.0,1.0,54.71,55.26,54.39,55.21,983892.0
+2017-07-27,55.7,55.85,54.29,55.11,1201890.0,0.0,1.0,55.7,55.85,54.29,55.11,1201890.0
+2017-07-26,56.0,56.01,55.2,55.65,631774.0,0.0,1.0,56.0,56.01,55.2,55.65,631774.0
+2017-07-25,55.9,56.36,55.43,55.75,998410.0,0.0,1.0,55.9,56.36,55.43,55.75,998410.0
+2017-07-24,55.3,55.77,55.04,55.73,1082025.0,0.0,1.0,55.3,55.77,55.04,55.73,1082025.0
+2017-07-21,54.9,55.23,54.7645,55.07,658226.0,0.0,1.0,54.9,55.23,54.7645,55.07,658226.0
+2017-07-20,54.53,55.33,54.33,55.05,972645.0,0.0,1.0,54.53,55.33,54.33,55.05,972645.0
+2017-07-19,54.27,54.51,54.09,54.38,688376.0,0.0,1.0,54.27,54.51,54.09,54.38,688376.0
+2017-07-18,54.22,54.44,53.71,54.18,620018.0,0.0,1.0,54.22,54.44,53.71,54.18,620018.0
+2017-07-17,53.51,54.45,53.16,54.13,1062125.0,0.0,1.0,53.51,54.45,53.16,54.13,1062125.0
+2017-07-14,54.43,54.48,53.4,53.47,923880.0,0.0,1.0,54.43,54.48,53.4,53.47,923880.0
+2017-07-13,54.12,54.49,53.65,54.24,1061017.0,0.0,1.0,54.12,54.49,53.65,54.24,1061017.0
+2017-07-12,54.32,54.64,53.58,54.09,1174740.0,0.0,1.0,54.32,54.64,53.58,54.09,1174740.0
+2017-07-11,53.79,54.3,53.4,53.96,780957.0,0.0,1.0,53.79,54.3,53.4,53.96,780957.0
+2017-07-10,54.53,55.09,53.663,54.03,1253838.0,0.0,1.0,54.53,55.09,53.663,54.03,1253838.0
+2017-07-07,54.2,55.04,54.2,54.68,950235.0,0.0,1.0,54.2,55.04,54.2,54.68,950235.0
+2017-07-06,55.06,55.06,53.925,54.06,1550796.0,0.0,1.0,55.06,55.06,53.925,54.06,1550796.0
+2017-07-05,54.52,55.75,54.495,55.41,973694.0,0.0,1.0,54.52,55.75,54.495,55.41,973694.0
+2017-07-03,54.63,55.21,54.38,54.55,496186.0,0.0,1.0,54.63,55.21,54.38,54.55,496186.0
+2017-06-30,54.96,55.0,54.27,54.29,1025663.0,0.0,1.0,54.96,55.0,54.27,54.29,1025663.0
+2017-06-29,55.16,55.33,54.08,54.42,844905.0,0.0,1.0,55.16,55.33,54.08,54.42,844905.0
+2017-06-28,54.18,55.73,54.18,55.28,1012373.0,0.0,1.0,54.18,55.73,54.18,55.28,1012373.0
+2017-06-27,55.01,55.29,53.84,53.86,1517157.0,0.0,1.0,55.01,55.29,53.84,53.86,1517157.0
+2017-06-26,54.82,56.12,54.82,55.31,1225716.0,0.0,1.0,54.82,56.12,54.82,55.31,1225716.0
+2017-06-23,55.57,55.87,54.74,54.81,2188845.0,0.0,1.0,55.57,55.87,54.74,54.81,2188845.0
+2017-06-22,55.01,56.26,54.9,55.46,2613554.0,0.0,1.0,55.01,56.26,54.9,55.46,2613554.0
+2017-06-21,53.24,55.23,53.2,54.9,2426566.0,0.0,1.0,53.24,55.23,53.2,54.9,2426566.0
+2017-06-20,53.51,53.92,52.95,53.1,1059158.0,0.0,1.0,53.51,53.92,52.95,53.1,1059158.0
+2017-06-19,53.2,53.84,53.06,53.63,1036571.0,0.0,1.0,53.2,53.84,53.06,53.63,1036571.0
+2017-06-16,52.71,53.01,52.09,52.9,2348629.0,0.0,1.0,52.71,53.01,52.09,52.9,2348629.0
+2017-06-15,51.61,52.95,51.61,52.91,1146075.0,0.0,1.0,51.61,52.95,51.61,52.91,1146075.0
+2017-06-14,51.99,52.74,51.7,52.17,1432854.0,0.0,1.0,51.99,52.74,51.7,52.17,1432854.0
+2017-06-13,50.78,52.23,50.77,51.84,1457083.0,0.0,1.0,50.78,52.23,50.77,51.84,1457083.0
+2017-06-12,50.98,51.26,49.52,50.42,2050208.0,0.0,1.0,50.98,51.26,49.52,50.42,2050208.0
+2017-06-09,51.97,52.31,50.8,51.13,2214803.0,0.0,1.0,51.97,52.31,50.8,51.13,2214803.0
+2017-06-08,50.93,52.1,50.68,51.79,2046748.0,0.0,1.0,50.93,52.1,50.68,51.79,2046748.0
+2017-06-07,50.08,50.81,49.75,50.79,1934974.0,0.0,1.0,50.08,50.81,49.75,50.79,1934974.0
+2017-06-06,50.0,50.6,49.66,49.72,2199861.0,0.0,1.0,50.0,50.6,49.66,49.72,2199861.0
+2017-06-05,51.17,51.17,50.07,50.31,1580004.0,0.0,1.0,51.17,51.17,50.07,50.31,1580004.0
+2017-06-02,51.16,51.64,50.97,51.16,1166461.0,0.0,1.0,51.16,51.64,50.97,51.16,1166461.0
+2017-06-01,50.23,51.1,49.98,50.93,1713508.0,0.0,1.0,50.23,51.1,49.98,50.93,1713508.0
diff --git a/examples/quick/demos/stocqt/content/data/NFLX.csv b/examples/quick/demos/stocqt/content/data/NFLX.csv
new file mode 100644
index 0000000000..d7a667843c
--- /dev/null
+++ b/examples/quick/demos/stocqt/content/data/NFLX.csv
@@ -0,0 +1,148 @@
+Date,Open,High,Low,Close,Volume,Ex-Dividend,Split Ratio,Adj. Open,Adj. High,Adj. Low,Adj. Close,Adj. Volume
+2017-12-29,192.51,193.95,191.22,191.96,5158845.0,0.0,1.0,192.51,193.95,191.22,191.96,5158845.0
+2017-12-28,187.18,194.49,186.85,192.71,10080261.0,0.0,1.0,187.18,194.49,186.85,192.71,10080261.0
+2017-12-27,187.8,188.1,185.22,186.24,3932094.0,0.0,1.0,187.8,188.1,185.22,186.24,3932094.0
+2017-12-26,189.78,189.94,186.4,187.76,3032707.0,0.0,1.0,189.78,189.94,186.4,187.76,3032707.0
+2017-12-22,188.33,190.95,186.8,189.94,3760922.0,0.0,1.0,188.33,190.95,186.8,189.94,3760922.0
+2017-12-21,189.44,190.95,187.58,188.62,3522551.0,0.0,1.0,189.44,190.95,187.58,188.62,3522551.0
+2017-12-20,187.94,189.11,185.26,188.82,5814609.0,0.0,1.0,187.94,189.11,185.26,188.82,5814609.0
+2017-12-19,190.18,190.2981,185.75,187.02,6526555.0,0.0,1.0,190.18,190.2981,185.75,187.02,6526555.0
+2017-12-18,191.2,191.65,188.9,190.42,4944337.0,0.0,1.0,191.2,191.65,188.9,190.42,4944337.0
+2017-12-15,189.61,191.43,188.01,190.12,7048874.0,0.0,1.0,189.61,191.43,188.01,190.12,7048874.0
+2017-12-14,187.98,192.64,187.2,189.56,7677048.0,0.0,1.0,187.98,192.64,187.2,189.56,7677048.0
+2017-12-13,186.1,188.69,185.41,187.86,4653749.0,0.0,1.0,186.1,188.69,185.41,187.86,4653749.0
+2017-12-12,186.01,187.85,184.8183,185.73,4135595.0,0.0,1.0,186.01,187.85,184.8183,185.73,4135595.0
+2017-12-11,187.85,189.42,185.91,186.22,5131319.0,0.0,1.0,187.85,189.42,185.91,186.22,5131319.0
+2017-12-08,186.5,189.42,186.3,188.54,4909440.0,0.0,1.0,186.5,189.42,186.3,188.54,4909440.0
+2017-12-07,185.71,187.34,183.22,185.2,4543492.0,0.0,1.0,185.71,187.34,183.22,185.2,4543492.0
+2017-12-06,183.38,186.4844,182.88,185.3,5006257.0,0.0,1.0,183.38,186.4844,182.88,185.3,5006257.0
+2017-12-05,183.5,188.14,181.19,184.21,5547802.0,0.0,1.0,183.5,188.14,181.19,184.21,5547802.0
+2017-12-04,189.36,189.72,178.38,184.04,9137873.0,0.0,1.0,189.36,189.72,178.38,184.04,9137873.0
+2017-12-01,186.99,189.8,185.0,186.82,6163366.0,0.0,1.0,186.99,189.8,185.0,186.82,6163366.0
+2017-11-30,190.31,190.86,186.68,187.58,6499326.0,0.0,1.0,190.31,190.86,186.68,187.58,6499326.0
+2017-11-29,198.91,199.029,184.32,188.15,13905339.0,0.0,1.0,198.91,199.029,184.32,188.15,13905339.0
+2017-11-28,195.34,199.68,194.01,199.18,6942358.0,0.0,1.0,195.34,199.68,194.01,199.18,6942358.0
+2017-11-27,195.56,195.85,194.0,195.05,3186677.0,0.0,1.0,195.56,195.85,194.0,195.05,3186677.0
+2017-11-24,196.65,196.9,195.33,195.75,2160300.0,0.0,1.0,196.65,196.9,195.33,195.75,2160300.0
+2017-11-22,196.58,196.75,193.63,196.32,5879771.0,0.0,1.0,196.58,196.75,193.63,196.32,5879771.0
+2017-11-21,195.04,197.52,194.971,196.23,4598017.0,0.0,1.0,195.04,197.52,194.971,196.23,4598017.0
+2017-11-20,193.3,194.32,191.9,194.1,3727412.0,0.0,1.0,193.3,194.32,191.9,194.1,3727412.0
+2017-11-17,195.74,195.95,192.65,193.2,3753775.0,0.0,1.0,195.74,195.95,192.65,193.2,3753775.0
+2017-11-16,194.33,197.7,193.75,195.51,5655042.0,0.0,1.0,194.33,197.7,193.75,195.51,5655042.0
+2017-11-15,194.54,195.42,191.53,192.12,4162712.0,0.0,1.0,194.54,195.42,191.53,192.12,4162712.0
+2017-11-14,193.64,195.88,193.0,195.71,3408535.0,0.0,1.0,193.64,195.88,193.0,195.71,3408535.0
+2017-11-13,191.12,196.05,191.0,195.08,4598005.0,0.0,1.0,191.12,196.05,191.0,195.08,4598005.0
+2017-11-10,191.61,192.59,189.5,192.02,6609739.0,0.0,1.0,191.61,192.59,189.5,192.02,6609739.0
+2017-11-09,194.46,194.49,190.81,193.9,5839579.0,0.0,1.0,194.46,194.49,190.81,193.9,5839579.0
+2017-11-07,200.0,200.61,194.8,195.89,6413310.0,0.0,1.0,200.0,200.61,194.8,195.89,6413310.0
+2017-11-06,200.0,202.48,198.09,200.13,5834857.0,0.0,1.0,200.0,202.48,198.09,200.13,5834857.0
+2017-11-03,199.8,200.55,197.99,200.01,3643216.0,0.0,1.0,199.8,200.55,197.99,200.01,3643216.0
+2017-11-02,197.45,199.44,197.0901,199.32,3578289.0,0.0,1.0,197.45,199.44,197.0901,199.32,3578289.0
+2017-11-01,197.24,199.199,196.0,198.0,4983343.0,0.0,1.0,197.24,199.199,196.0,198.0,4983343.0
+2017-10-31,198.21,198.59,195.218,196.43,5437925.0,0.0,1.0,198.21,198.59,195.218,196.43,5437925.0
+2017-10-30,199.62,201.099,197.0721,198.37,5412277.0,0.0,1.0,199.62,201.099,197.0721,198.37,5412277.0
+2017-10-27,197.2,200.65,196.22,199.54,8088364.0,0.0,1.0,197.2,200.65,196.22,199.54,8088364.0
+2017-10-26,194.66,197.61,194.08,195.21,5101258.0,0.0,1.0,194.66,197.61,194.08,195.21,5101258.0
+2017-10-25,195.38,197.055,193.01,193.77,5231713.0,0.0,1.0,195.38,197.055,193.01,193.77,5231713.0
+2017-10-24,192.75,196.735,191.4,196.02,6985460.0,0.0,1.0,192.75,196.735,191.4,196.02,6985460.0
+2017-10-23,194.17,194.8999,191.0346,192.47,6952997.0,0.0,1.0,194.17,194.8999,191.0346,192.47,6952997.0
+2017-10-20,195.9,196.38,193.77,194.16,5907121.0,0.0,1.0,195.9,196.38,193.77,194.16,5907121.0
+2017-10-19,193.01,195.25,191.16,195.13,7007447.0,0.0,1.0,193.01,195.25,191.16,195.13,7007447.0
+2017-10-18,199.99,200.01,194.25,195.54,11133883.0,0.0,1.0,199.99,200.01,194.25,195.54,11133883.0
+2017-10-17,200.11,204.38,197.77,199.48,23819054.0,0.0,1.0,200.11,204.38,197.77,199.48,23819054.0
+2017-10-16,201.95,202.83,197.86,202.68,18103086.0,0.0,1.0,201.95,202.83,197.86,202.68,18103086.0
+2017-10-13,199.7,200.8199,197.1866,199.49,11929816.0,0.0,1.0,199.7,200.8199,197.1866,199.49,11929816.0
+2017-10-12,196.75,198.62,194.71,195.86,7723224.0,0.0,1.0,196.75,198.62,194.71,195.86,7723224.0
+2017-10-11,195.57,196.2199,193.81,194.95,5544715.0,0.0,1.0,195.57,196.2199,193.81,194.95,5544715.0
+2017-10-10,197.85,198.3,192.1,195.08,6179012.0,0.0,1.0,197.85,198.3,192.1,195.08,6179012.0
+2017-10-09,199.1,199.4,196.56,196.87,6912140.0,0.0,1.0,199.1,199.4,196.56,196.87,6912140.0
+2017-10-06,194.3,198.92,192.05,198.02,15096222.0,0.0,1.0,194.3,198.92,192.05,198.02,15096222.0
+2017-10-05,185.65,194.49,184.49,194.39,19270032.0,0.0,1.0,185.65,194.49,184.49,194.39,19270032.0
+2017-10-04,181.41,186.7,181.25,184.45,9170855.0,0.0,1.0,181.41,186.7,181.25,184.45,9170855.0
+2017-10-03,177.65,179.7,177.55,179.19,3903112.0,0.0,1.0,177.65,179.7,177.55,179.19,3903112.0
+2017-10-02,182.11,182.8,176.58,177.01,7316345.0,0.0,1.0,182.11,182.8,176.58,177.01,7316345.0
+2017-09-29,180.73,182.9,180.65,181.35,4193999.0,0.0,1.0,180.73,182.9,180.65,181.35,4193999.0
+2017-09-28,181.25,181.95,179.36,180.7,4064507.0,0.0,1.0,181.25,181.95,179.36,180.7,4064507.0
+2017-09-27,181.01,183.34,180.7,181.97,4963152.0,0.0,1.0,181.01,183.34,180.7,181.97,4963152.0
+2017-09-26,180.7,180.95,176.55,179.38,5572599.0,0.0,1.0,180.7,180.95,176.55,179.38,5572599.0
+2017-09-25,186.46,186.55,177.7,178.55,9322531.0,0.0,1.0,186.46,186.55,177.7,178.55,9322531.0
+2017-09-22,188.4,189.85,186.39,187.35,5420227.0,0.0,1.0,188.4,189.85,186.39,187.35,5420227.0
+2017-09-21,185.82,189.95,184.51,188.78,7113489.0,0.0,1.0,185.82,189.95,184.51,188.78,7113489.0
+2017-09-20,186.1,186.5,183.2,185.51,4473036.0,0.0,1.0,186.1,186.5,183.2,185.51,4473036.0
+2017-09-19,184.98,186.23,184.17,185.68,4951465.0,0.0,1.0,184.98,186.23,184.17,185.68,4951465.0
+2017-09-18,183.61,185.45,182.73,184.62,5318130.0,0.0,1.0,183.61,185.45,182.73,184.62,5318130.0
+2017-09-15,182.73,184.93,181.43,182.1,5442089.0,0.0,1.0,182.73,184.93,181.43,182.1,5442089.0
+2017-09-14,183.25,185.2882,182.07,182.63,4469985.0,0.0,1.0,183.25,185.2882,182.07,182.63,4469985.0
+2017-09-13,184.07,184.4995,182.55,183.64,4303277.0,0.0,1.0,184.07,184.4995,182.55,183.64,4303277.0
+2017-09-12,182.55,185.33,180.6435,185.15,6606688.0,0.0,1.0,182.55,185.33,180.6435,185.15,6606688.0
+2017-09-11,178.1,182.47,178.03,181.74,5936476.0,0.0,1.0,178.1,182.47,178.03,181.74,5936476.0
+2017-09-08,178.45,180.39,176.25,176.42,4577777.0,0.0,1.0,178.45,180.39,176.25,176.42,4577777.0
+2017-09-07,178.8,180.35,177.1,179.0,5938152.0,0.0,1.0,178.8,180.35,177.1,179.0,5938152.0
+2017-09-06,175.25,179.46,173.73,179.25,8695383.0,0.0,1.0,175.25,179.46,173.73,179.25,8695383.0
+2017-09-05,173.4,175.88,172.44,174.52,4580903.0,0.0,1.0,173.4,175.88,172.44,174.52,4580903.0
+2017-09-01,175.55,176.48,173.92,174.74,3781453.0,0.0,1.0,175.55,176.48,173.92,174.74,3781453.0
+2017-08-31,175.45,176.24,173.86,174.71,6886143.0,0.0,1.0,175.45,176.24,173.86,174.71,6886143.0
+2017-08-30,169.5,174.85,169.37,174.69,7985196.0,0.0,1.0,169.5,174.85,169.37,174.69,7985196.0
+2017-08-29,165.0,169.68,164.73,168.81,4573282.0,0.0,1.0,165.0,169.68,164.73,168.81,4573282.0
+2017-08-28,166.43,168.67,165.6,167.12,3619575.0,0.0,1.0,166.43,168.67,165.6,167.12,3619575.0
+2017-08-25,168.58,168.75,165.5,165.95,4045626.0,0.0,1.0,168.58,168.75,165.5,165.95,4045626.0
+2017-08-24,169.86,171.2363,166.15,168.13,5270931.0,0.0,1.0,169.86,171.2363,166.15,168.13,5270931.0
+2017-08-23,168.35,169.64,166.7,169.06,4616656.0,0.0,1.0,168.35,169.64,166.7,169.06,4616656.0
+2017-08-22,167.76,169.93,167.04,169.34,4857816.0,0.0,1.0,167.76,169.93,167.04,169.34,4857816.0
+2017-08-21,166.91,168.99,164.23,166.76,6303314.0,0.0,1.0,166.91,168.99,164.23,166.76,6303314.0
+2017-08-18,165.95,169.97,165.8,166.54,7363750.0,0.0,1.0,165.95,169.97,165.8,166.54,7363750.0
+2017-08-17,169.23,170.58,165.72,166.09,5161920.0,0.0,1.0,169.23,170.58,165.72,166.09,5161920.0
+2017-08-16,167.5,170.5,166.25,169.98,6916579.0,0.0,1.0,167.5,170.5,166.25,169.98,6916579.0
+2017-08-15,171.53,171.88,168.25,168.5,5470271.0,0.0,1.0,171.53,171.88,168.25,168.5,5470271.0
+2017-08-14,169.8,172.45,168.8,171.0,7377962.0,0.0,1.0,169.8,172.45,168.8,171.0,7377962.0
+2017-08-11,169.86,172.58,169.0,171.4,4972045.0,0.0,1.0,169.86,172.58,169.0,171.4,4972045.0
+2017-08-10,174.03,174.45,167.6,169.14,9539473.0,0.0,1.0,174.03,174.45,167.6,169.14,9539473.0
+2017-08-09,171.43,175.96,170.01,175.78,9573608.0,0.0,1.0,171.43,175.96,170.01,175.78,9573608.0
+2017-08-08,181.37,181.91,177.45,178.36,4806525.0,0.0,1.0,181.37,181.91,177.45,178.36,4806525.0
+2017-08-07,181.0,182.27,179.1,181.33,4470746.0,0.0,1.0,181.0,182.27,179.1,181.33,4470746.0
+2017-08-04,179.6,181.0,178.5,180.27,4446148.0,0.0,1.0,179.6,181.0,178.5,180.27,4446148.0
+2017-08-03,180.53,181.2248,178.02,179.23,4596187.0,0.0,1.0,180.53,181.2248,178.02,179.23,4596187.0
+2017-08-02,182.22,182.57,177.8149,180.74,5713517.0,0.0,1.0,182.22,182.57,177.8149,180.74,5713517.0
+2017-08-01,182.49,184.62,181.43,182.03,5003248.0,0.0,1.0,182.49,184.62,181.43,182.03,5003248.0
+2017-07-31,184.26,184.9738,180.65,181.66,4776740.0,0.0,1.0,184.26,184.9738,180.65,181.66,4776740.0
+2017-07-28,182.0,185.03,181.18,184.04,6166404.0,0.0,1.0,182.0,185.03,181.18,184.04,6166404.0
+2017-07-27,189.89,190.0,179.38,182.68,11013995.0,0.0,1.0,189.89,190.0,179.38,182.68,11013995.0
+2017-07-26,187.7,189.7043,187.51,189.08,4354866.0,0.0,1.0,187.7,189.7043,187.51,189.08,4354866.0
+2017-07-25,187.79,188.66,185.81,186.97,5357533.0,0.0,1.0,187.79,188.66,185.81,186.97,5357533.0
+2017-07-24,188.685,190.25,187.01,187.91,8646192.0,0.0,1.0,188.685,190.25,187.01,187.91,8646192.0
+2017-07-21,182.72,191.5,182.71,188.54,9215232.0,0.0,1.0,182.72,191.5,182.71,188.54,9215232.0
+2017-07-20,183.84,185.92,182.7,183.6,7688768.0,0.0,1.0,183.84,185.92,182.7,183.6,7688768.0
+2017-07-19,182.97,187.17,181.75,183.86,17149580.0,0.0,1.0,182.97,187.17,181.75,183.86,17149580.0
+2017-07-18,176.12,185.0,174.24,183.6,40126110.0,0.0,1.0,176.12,185.0,174.24,183.6,40126110.0
+2017-07-17,162.91,163.55,160.0201,161.7,12299024.0,0.0,1.0,162.91,163.55,160.0201,161.7,12299024.0
+2017-07-14,159.3,161.35,157.97,161.12,5412128.0,0.0,1.0,159.3,161.35,157.97,161.12,5412128.0
+2017-07-13,158.51,160.13,156.98,158.17,6666000.0,0.0,1.0,158.51,160.13,156.98,158.17,6666000.0
+2017-07-12,155.77,158.8,155.77,158.75,8095303.0,0.0,1.0,155.77,158.8,155.77,158.75,8095303.0
+2017-07-11,152.37,155.23,151.55,154.33,4824579.0,0.0,1.0,152.37,155.23,151.55,154.33,4824579.0
+2017-07-10,150.34,153.23,149.65,152.67,5113353.0,0.0,1.0,150.34,153.23,149.65,152.67,5113353.0
+2017-07-07,146.65,150.75,146.65,150.18,5490809.0,0.0,1.0,146.65,150.75,146.65,150.18,5490809.0
+2017-07-06,146.13,147.27,144.25,146.25,5253871.0,0.0,1.0,146.13,147.27,144.25,146.25,5253871.0
+2017-07-05,146.58,148.26,145.58,147.61,4469163.0,0.0,1.0,146.58,148.26,145.58,147.61,4469163.0
+2017-07-03,149.8,150.45,145.8,146.17,3907790.0,0.0,1.0,149.8,150.45,145.8,146.17,3907790.0
+2017-06-30,149.76,150.71,148.42,149.41,5164844.0,0.0,1.0,149.76,150.71,148.42,149.41,5164844.0
+2017-06-29,152.82,152.82,148.0,150.09,7106930.0,0.0,1.0,152.82,152.82,148.0,150.09,7106930.0
+2017-06-28,151.64,154.2,150.12,153.41,5522740.0,0.0,1.0,151.64,154.2,150.12,153.41,5522740.0
+2017-06-27,156.62,156.9775,150.7197,151.03,7386827.0,0.0,1.0,156.62,156.9775,150.7197,151.03,7386827.0
+2017-06-26,158.78,159.97,156.56,157.5,5951060.0,0.0,1.0,158.78,159.97,156.56,157.5,5951060.0
+2017-06-23,155.01,158.19,153.76,158.03,6086644.0,0.0,1.0,155.01,158.19,153.76,158.03,6086644.0
+2017-06-22,155.13,155.2,153.7,154.89,3735995.0,0.0,1.0,155.13,155.2,153.7,154.89,3735995.0
+2017-06-21,152.5,155.38,152.26,155.03,5783436.0,0.0,1.0,152.5,155.38,152.26,155.03,5783436.0
+2017-06-20,153.68,154.5,151.4,152.05,4850911.0,0.0,1.0,153.68,154.5,151.4,152.05,4850911.0
+2017-06-19,154.29,155.58,152.41,153.4,6461866.0,0.0,1.0,154.29,155.58,152.41,153.4,6461866.0
+2017-06-16,151.45,153.53,150.39,152.38,6751799.0,0.0,1.0,151.45,153.53,150.39,152.38,6751799.0
+2017-06-15,149.44,152.56,147.3,151.76,6976720.0,0.0,1.0,149.44,152.56,147.3,151.76,6976720.0
+2017-06-14,154.34,155.615,150.28,152.2,6364572.0,0.0,1.0,154.34,155.615,150.28,152.2,6364572.0
+2017-06-13,154.38,155.68,150.13,152.72,8379437.0,0.0,1.0,154.38,155.68,150.13,152.72,8379437.0
+2017-06-12,155.3,155.53,148.31,151.44,14045559.0,0.0,1.0,155.3,155.53,148.31,151.44,14045559.0
+2017-06-09,166.27,166.27,154.5,158.03,10255110.0,0.0,1.0,166.27,166.27,154.5,158.03,10255110.0
+2017-06-08,166.12,166.87,164.84,165.88,3666393.0,0.0,1.0,166.12,166.87,164.84,165.88,3666393.0
+2017-06-07,165.6,166.4,164.4086,165.61,3285592.0,0.0,1.0,165.6,166.4,164.4086,165.61,3285592.0
+2017-06-06,164.95,166.82,164.51,165.17,4325459.0,0.0,1.0,164.95,166.82,164.51,165.17,4325459.0
+2017-06-05,165.49,165.5,163.43,165.06,3830296.0,0.0,1.0,165.49,165.5,163.43,165.06,3830296.0
+2017-06-02,163.42,165.36,162.8,165.18,4217679.0,0.0,1.0,163.42,165.36,162.8,165.18,4217679.0
+2017-06-01,163.52,163.9316,161.7,162.99,3869808.0,0.0,1.0,163.52,163.9316,161.7,162.99,3869808.0
diff --git a/examples/quick/demos/stocqt/content/data/NTAP.csv b/examples/quick/demos/stocqt/content/data/NTAP.csv
new file mode 100644
index 0000000000..dcceae9ac7
--- /dev/null
+++ b/examples/quick/demos/stocqt/content/data/NTAP.csv
@@ -0,0 +1,148 @@
+Date,Open,High,Low,Close,Volume,Ex-Dividend,Split Ratio,Adj. Open,Adj. High,Adj. Low,Adj. Close,Adj. Volume
+2017-12-29,55.8,55.94,55.26,55.32,1287431.0,0.0,1.0,55.8,55.94,55.26,55.32,1287431.0
+2017-12-28,56.25,56.45,55.39,55.8,904513.0,0.0,1.0,56.25,56.45,55.39,55.8,904513.0
+2017-12-27,55.9,56.19,55.76,56.15,961107.0,0.0,1.0,55.9,56.19,55.76,56.15,961107.0
+2017-12-26,56.2,56.3,55.64,55.86,875796.0,0.0,1.0,56.2,56.3,55.64,55.86,875796.0
+2017-12-22,56.19,56.49,56.16,56.3,1019859.0,0.0,1.0,56.19,56.49,56.16,56.3,1019859.0
+2017-12-21,57.09,57.17,56.13,56.21,2342109.0,0.0,1.0,57.09,57.17,56.13,56.21,2342109.0
+2017-12-20,58.42,58.44,56.88,57.04,1872565.0,0.0,1.0,58.42,58.44,56.88,57.04,1872565.0
+2017-12-19,57.71,58.125,57.47,57.91,3065092.0,0.0,1.0,57.71,58.125,57.47,57.91,3065092.0
+2017-12-18,57.76,58.13,57.43,57.73,2009903.0,0.0,1.0,57.76,58.13,57.43,57.73,2009903.0
+2017-12-15,57.29,57.88,57.26,57.27,4421855.0,0.0,1.0,57.29,57.88,57.26,57.27,4421855.0
+2017-12-14,57.89,58.16,57.25,57.37,2368380.0,0.0,1.0,57.89,58.16,57.25,57.37,2368380.0
+2017-12-13,57.95,58.32,57.71,57.78,2930515.0,0.0,1.0,57.95,58.32,57.71,57.78,2930515.0
+2017-12-12,58.67,58.82,57.76,57.8,2540225.0,0.0,1.0,58.67,58.82,57.76,57.8,2540225.0
+2017-12-11,58.09,58.99,58.0,58.58,2795677.0,0.0,1.0,58.09,58.99,58.0,58.58,2795677.0
+2017-12-08,57.9,58.63,57.475,58.26,3376794.0,0.0,1.0,57.9,58.63,57.475,58.26,3376794.0
+2017-12-07,57.21,57.82,56.72,57.53,2822878.0,0.0,1.0,57.21,57.82,56.72,57.53,2822878.0
+2017-12-06,56.14,57.275,55.92,57.21,3139341.0,0.0,1.0,56.14,57.275,55.92,57.21,3139341.0
+2017-12-05,55.97,56.56,55.62,56.14,2585323.0,0.0,1.0,55.97,56.56,55.62,56.14,2585323.0
+2017-12-04,56.72,58.11,55.92,55.93,4249052.0,0.0,1.0,56.72,58.11,55.92,55.93,4249052.0
+2017-12-01,55.59,56.51,54.93,56.41,4054006.0,0.0,1.0,55.59,56.51,54.93,56.41,4054006.0
+2017-11-30,56.79,57.75,56.5,56.51,4294760.0,0.0,1.0,56.79,57.75,56.5,56.51,4294760.0
+2017-11-29,56.67,57.18,56.08,56.23,2628942.0,0.0,1.0,56.67,57.18,56.08,56.23,2628942.0
+2017-11-28,56.15,56.91,56.08,56.8,2472780.0,0.0,1.0,56.15,56.91,56.08,56.8,2472780.0
+2017-11-27,56.0,56.32,55.205,56.23,2818463.0,0.0,1.0,56.0,56.32,55.205,56.23,2818463.0
+2017-11-24,56.1,56.55,56.0,56.41,1533554.0,0.0,1.0,56.1,56.55,56.0,56.41,1533554.0
+2017-11-22,55.0,56.1,54.69,56.05,2732890.0,0.0,1.0,55.0,56.1,54.69,56.05,2732890.0
+2017-11-21,54.55,55.5,54.44,55.08,3438391.0,0.0,1.0,54.55,55.5,54.44,55.08,3438391.0
+2017-11-20,52.5,54.81,52.46,54.73,4364375.0,0.0,1.0,52.5,54.81,52.46,54.73,4364375.0
+2017-11-17,53.03,54.72,52.5,52.95,5601447.0,0.0,1.0,53.03,54.72,52.5,52.95,5601447.0
+2017-11-16,51.41,53.89,51.31,53.11,12798497.0,0.0,1.0,51.41,53.89,51.31,53.11,12798497.0
+2017-11-15,45.45,46.09,45.24,45.82,3834732.0,0.0,1.0,45.45,46.09,45.24,45.82,3834732.0
+2017-11-14,45.95,46.14,45.59,45.62,2122392.0,0.0,1.0,45.95,46.14,45.59,45.62,2122392.0
+2017-11-13,46.21,46.62,45.93,46.0,2314390.0,0.0,1.0,46.21,46.62,45.93,46.0,2314390.0
+2017-11-10,46.19,46.7,46.1,46.34,1641852.0,0.0,1.0,46.19,46.7,46.1,46.34,1641852.0
+2017-11-09,46.15,47.2,45.93,46.3,3559622.0,0.0,1.0,46.15,47.2,45.93,46.3,3559622.0
+2017-11-07,45.0,45.07,44.41,44.65,1904133.0,0.0,1.0,45.0,45.07,44.41,44.65,1904133.0
+2017-11-06,44.07,45.12,44.02,45.005,2541032.0,0.0,1.0,44.07,45.12,44.02,45.005,2541032.0
+2017-11-03,44.39,44.485,43.91,44.24,2055137.0,0.0,1.0,44.39,44.485,43.91,44.24,2055137.0
+2017-11-02,44.55,44.605,43.94,44.25,2109252.0,0.0,1.0,44.55,44.605,43.94,44.25,2109252.0
+2017-11-01,44.74,44.9,44.4,44.53,1937032.0,0.0,1.0,44.74,44.9,44.4,44.53,1937032.0
+2017-10-31,43.71,44.57,43.56,44.42,2462916.0,0.0,1.0,43.71,44.57,43.56,44.42,2462916.0
+2017-10-30,43.74,43.95,43.24,43.52,2050846.0,0.0,1.0,43.74,43.95,43.24,43.52,2050846.0
+2017-10-27,44.52,44.52,43.86,44.01,1818983.0,0.0,1.0,44.52,44.52,43.86,44.01,1818983.0
+2017-10-26,43.92,44.675,43.82,44.42,1567088.0,0.0,1.0,43.92,44.675,43.82,44.42,1567088.0
+2017-10-25,44.66,44.66,43.665,43.71,3428810.0,0.0,1.0,44.66,44.66,43.665,43.71,3428810.0
+2017-10-24,44.7,45.03,44.65,44.82,2477689.0,0.0,1.0,44.7,45.03,44.65,44.82,2477689.0
+2017-10-23,44.92,45.14,44.66,44.74,2719135.0,0.0,1.0,44.92,45.14,44.66,44.74,2719135.0
+2017-10-20,44.57,45.03,44.39,44.56,2540716.0,0.0,1.0,44.57,45.03,44.39,44.56,2540716.0
+2017-10-19,44.37,44.505,43.91,44.26,2253612.0,0.0,1.0,44.37,44.505,43.91,44.26,2253612.0
+2017-10-18,44.32,44.64,44.08,44.62,2523179.0,0.0,1.0,44.32,44.64,44.08,44.62,2523179.0
+2017-10-17,43.29,44.11,43.29,44.08,1760179.0,0.0,1.0,43.29,44.11,43.29,44.08,1760179.0
+2017-10-16,43.83,43.939,43.65,43.72,1433772.0,0.0,1.0,43.83,43.939,43.65,43.72,1433772.0
+2017-10-13,43.65,44.22,43.615,43.63,1840650.0,0.0,1.0,43.65,44.22,43.615,43.63,1840650.0
+2017-10-12,43.38,43.59,42.99,43.42,3223379.0,0.0,1.0,43.38,43.59,42.99,43.42,3223379.0
+2017-10-11,43.54,43.9399,43.29,43.51,1654470.0,0.0,1.0,43.54,43.9399,43.29,43.51,1654470.0
+2017-10-10,44.36,44.52,43.57,43.66,3930121.0,0.0,1.0,44.36,44.52,43.57,43.66,3930121.0
+2017-10-09,44.42,44.815,44.25,44.37,2039538.0,0.0,1.0,44.42,44.815,44.25,44.37,2039538.0
+2017-10-06,44.34,44.63,44.05,44.43,1778991.0,0.0,1.0,44.34,44.63,44.05,44.43,1778991.0
+2017-10-05,44.28,44.565,44.17,44.55,2957479.0,0.2,1.0,44.28,44.565,44.17,44.55,2957479.0
+2017-10-04,44.19,44.54,44.17,44.46,2875404.0,0.0,1.0,43.992502793296,44.340938547486,43.972592178771,44.261296089385,2875404.0
+2017-10-03,44.07,44.52,43.75,44.39,2905694.0,0.0,1.0,43.873039106145,44.321027932961,43.554469273743,44.191608938547,2905694.0
+2017-10-02,43.89,44.1,43.71,44.0,3186168.0,0.0,1.0,43.693843575419,43.902905027933,43.514648044693,43.803351955307,3186168.0
+2017-09-29,43.7,43.975,43.39,43.76,1866218.0,0.0,1.0,43.50469273743,43.778463687151,43.196078212291,43.564424581006,1866218.0
+2017-09-28,43.95,44.045,43.52,43.84,2195811.0,0.0,1.0,43.753575418994,43.848150837989,43.325497206704,43.644067039106,2195811.0
+2017-09-27,43.98,44.47,43.56,44.17,2566121.0,0.0,1.0,43.783441340782,44.271251396648,43.365318435754,43.972592178771,2566121.0
+2017-09-26,43.0,43.82,42.875,43.76,3262283.0,0.0,1.0,42.80782122905,43.624156424581,42.683379888268,43.564424581006,3262283.0
+2017-09-25,42.17,43.085,42.11,42.7,2486787.0,0.0,1.0,41.981530726257,42.892441340782,41.921798882682,42.509162011173,2486787.0
+2017-09-22,41.77,42.6,41.7,42.55,1820422.0,0.0,1.0,41.583318435754,42.409608938547,41.513631284916,42.359832402235,1820422.0
+2017-09-21,41.75,42.04,41.64,41.86,2621389.0,0.0,1.0,41.563407821229,41.852111731844,41.453899441341,41.672916201117,2621389.0
+2017-09-20,41.72,41.91,41.22,41.7,2878107.0,0.0,1.0,41.533541899441,41.72269273743,41.035776536313,41.513631284916,2878107.0
+2017-09-19,41.79,42.32,41.3,41.71,5252863.0,0.0,1.0,41.603229050279,42.130860335196,41.115418994413,41.523586592179,5252863.0
+2017-09-18,41.04,41.16,40.51,40.63,2686167.0,0.0,1.0,40.856581005587,40.976044692737,40.32894972067,40.448413407821,2686167.0
+2017-09-15,40.72,41.06,40.33,41.03,3537425.0,0.0,1.0,40.538011173184,40.876491620112,40.149754189944,40.846625698324,3537425.0
+2017-09-14,40.17,40.69,39.95,40.65,2799617.0,0.0,1.0,39.990469273743,40.508145251397,39.771452513966,40.468324022346,2799617.0
+2017-09-13,39.82,40.54,39.55,40.28,3019737.0,0.0,1.0,39.642033519553,40.358815642458,39.373240223464,40.099977653631,3019737.0
+2017-09-12,39.62,40.24,39.16,39.93,4031681.0,0.0,1.0,39.442927374302,40.060156424581,38.984983240223,39.751541899441,4031681.0
+2017-09-11,38.91,39.56,38.8,39.46,2798378.0,0.0,1.0,38.736100558659,39.383195530726,38.626592178771,39.283642458101,2798378.0
+2017-09-08,38.61,38.835,38.3799,38.63,2715485.0,0.0,1.0,38.437441340782,38.66143575419,38.20836972067,38.457351955307,2715485.0
+2017-09-07,38.9,38.9,38.12,38.69,2541004.0,0.0,1.0,38.726145251397,38.726145251397,37.949631284916,38.517083798883,2541004.0
+2017-09-06,38.09,38.97,37.855,38.85,3720730.0,0.0,1.0,37.919765363128,38.795832402235,37.685815642458,38.676368715084,3720730.0
+2017-09-05,38.49,38.74,37.55,37.98,2318304.0,0.0,1.0,38.317977653631,38.566860335196,37.38217877095,37.81025698324,2318304.0
+2017-09-01,38.82,38.9,38.56,38.65,1784904.0,0.0,1.0,38.646502793296,38.726145251397,38.387664804469,38.477262569832,1784904.0
+2017-08-31,38.46,38.6975,38.07,38.66,2576968.0,0.0,1.0,38.288111731844,38.52455027933,37.899854748603,38.487217877095,2576968.0
+2017-08-30,37.98,38.26,37.84,38.22,1625130.0,0.0,1.0,37.81025698324,38.089005586592,37.670882681564,38.049184357542,1625130.0
+2017-08-29,37.92,38.315,37.89,38.03,1437800.0,0.0,1.0,37.750525139665,38.143759776536,37.720659217877,37.860033519553,1437800.0
+2017-08-28,38.73,38.81,38.18,38.34,1448478.0,0.0,1.0,38.556905027933,38.636547486034,38.009363128492,38.168648044693,1448478.0
+2017-08-25,38.97,38.99,38.52,38.54,1868152.0,0.0,1.0,38.795832402235,38.81574301676,38.347843575419,38.367754189944,1868152.0
+2017-08-24,38.76,38.93,38.51,38.81,2128753.0,0.0,1.0,38.586770949721,38.756011173184,38.337888268156,38.636547486034,2128753.0
+2017-08-23,38.49,38.95,38.35,38.6792,2625700.0,0.0,1.0,38.317977653631,38.775921787709,38.178603351955,38.506332067039,2625700.0
+2017-08-22,39.17,39.21,38.59,38.7,3834442.0,0.0,1.0,38.994938547486,39.034759776536,38.417530726257,38.527039106145,3834442.0
+2017-08-21,39.76,39.87,38.51,38.95,4371303.0,0.0,1.0,39.582301675978,39.691810055866,38.337888268156,38.775921787709,4371303.0
+2017-08-18,39.62,39.87,39.26,39.35,4934878.0,0.0,1.0,39.442927374302,39.691810055866,39.084536312849,39.174134078212,4934878.0
+2017-08-17,40.37,41.49,39.475,39.56,11599368.0,0.0,1.0,40.189575418994,41.304569832402,39.298575418994,39.383195530726,11599368.0
+2017-08-16,42.0,42.549,42.0,42.41,3481046.0,0.0,1.0,41.812290502793,42.358836871508,41.812290502793,42.220458100559,3481046.0
+2017-08-15,42.96,43.05,41.97,41.97,3781136.0,0.0,1.0,42.768,42.857597765363,41.782424581006,41.782424581006,3781136.0
+2017-08-14,42.37,42.53,41.75,42.03,3763330.0,0.0,1.0,42.180636871508,42.339921787709,41.563407821229,41.842156424581,3763330.0
+2017-08-11,41.44,41.85,41.23,41.49,1407483.0,0.0,1.0,41.254793296089,41.662960893855,41.045731843575,41.304569832402,1407483.0
+2017-08-10,42.01,42.23,41.23,41.29,2117207.0,0.0,1.0,41.822245810056,42.041262569832,41.045731843575,41.105463687151,2117207.0
+2017-08-09,42.49,42.61,42.18,42.24,1538691.0,0.0,1.0,42.300100558659,42.41956424581,41.99148603352,42.051217877095,1538691.0
+2017-08-08,42.66,43.16,42.52,42.69,1901300.0,0.0,1.0,42.469340782123,42.967106145251,42.329966480447,42.499206703911,1901300.0
+2017-08-07,42.83,42.8843,42.44,42.74,1611901.0,0.0,1.0,42.638581005587,42.692638324022,42.250324022346,42.548983240223,1611901.0
+2017-08-04,43.07,43.11,42.61,42.74,1871097.0,0.0,1.0,42.877508379888,42.917329608939,42.41956424581,42.548983240223,1871097.0
+2017-08-03,43.34,43.34,42.74,42.91,2350321.0,0.0,1.0,43.146301675978,43.146301675978,42.548983240223,42.718223463687,2350321.0
+2017-08-02,43.65,43.79,43.04,43.41,1460145.0,0.0,1.0,43.454916201117,43.594290502793,42.847642458101,43.215988826816,1460145.0
+2017-08-01,43.72,43.83,43.16,43.55,2576291.0,0.0,1.0,43.524603351955,43.634111731844,42.967106145251,43.355363128492,2576291.0
+2017-07-31,43.67,43.82,43.11,43.42,2360992.0,0.0,1.0,43.474826815642,43.624156424581,42.917329608939,43.225944134078,2360992.0
+2017-07-28,43.66,43.86,43.09,43.49,2581751.0,0.0,1.0,43.46487150838,43.663977653631,42.897418994413,43.295631284916,2581751.0
+2017-07-27,44.32,44.97,43.65,44.0197,4149229.0,0.0,1.0,44.121921787709,44.769016759777,43.454916201117,43.822963910615,4149229.0
+2017-07-26,44.87,44.87,44.025,44.36,3272594.0,0.0,1.0,44.669463687151,44.669463687151,43.828240223464,44.16174301676,3272594.0
+2017-07-25,44.58,44.94,44.21,44.76,3495184.0,0.0,1.0,44.380759776536,44.739150837989,44.012413407821,44.559955307263,3495184.0
+2017-07-24,44.4,45.23,44.4,44.86,2877601.0,0.0,1.0,44.20156424581,45.027854748603,44.20156424581,44.659508379888,2877601.0
+2017-07-21,44.56,45.24,44.18,44.76,4496318.0,0.0,1.0,44.360849162011,45.037810055866,43.982547486034,44.559955307263,4496318.0
+2017-07-20,44.18,44.69,44.09,44.6,3563323.0,0.0,1.0,43.982547486034,44.490268156425,43.89294972067,44.400670391061,3563323.0
+2017-07-19,43.88,44.5299,43.83,44.16,3618018.0,0.0,1.0,43.683888268156,44.330883687151,43.634111731844,43.962636871508,3618018.0
+2017-07-18,43.25,43.88,43.18,43.77,3030714.0,0.0,1.0,43.056703910615,43.683888268156,42.987016759777,43.574379888268,3030714.0
+2017-07-17,43.2,43.76,43.0,43.62,5253442.0,0.0,1.0,43.006927374302,43.564424581006,42.80782122905,43.42505027933,5253442.0
+2017-07-14,42.04,43.9,42.0,43.64,8405233.0,0.0,1.0,41.852111731844,43.703798882682,41.812290502793,43.444960893855,8405233.0
+2017-07-13,40.17,41.5,40.04,41.38,3940472.0,0.0,1.0,39.990469273743,41.314525139665,39.86105027933,41.195061452514,3940472.0
+2017-07-12,39.45,40.19,39.1701,40.17,2597317.0,0.0,1.0,39.273687150838,40.010379888268,38.995038100559,39.990469273743,2597317.0
+2017-07-11,38.55,39.11,38.51,39.07,2155200.0,0.0,1.0,38.377709497207,38.935206703911,38.337888268156,38.89538547486,2155200.0
+2017-07-10,38.5,38.91,38.35,38.57,2273543.0,0.0,1.0,38.327932960894,38.736100558659,38.178603351955,38.397620111732,2273543.0
+2017-07-07,38.44,38.83,38.32,38.64,1883863.0,0.0,1.0,38.268201117318,38.656458100559,38.148737430168,38.46730726257,1883863.0
+2017-07-06,39.33,39.39,38.2,38.3,2510853.0,0.0,1.0,39.154223463687,39.213955307263,38.029273743017,38.128826815642,2510853.0
+2017-07-05,39.55,40.25,39.475,39.66,2484571.0,0.2,1.0,39.373240223464,40.070111731844,39.298575418994,39.482748603352,2484571.0
+2017-07-03,40.44,40.5,39.53,39.57,1568751.0,0.0,1.0,40.057259245348,40.116691380726,39.155871858768,39.195493282354,1568751.0
+2017-06-30,40.18,40.38,39.73,40.05,3859273.0,0.0,1.0,39.799719992039,39.997827109969,39.353978976698,39.670950365385,3859273.0
+2017-06-29,40.28,40.38,39.55,40.1,3177050.0,0.0,1.0,39.898773551004,39.997827109969,39.175682570561,39.720477144867,3177050.0
+2017-06-28,39.8,40.59,39.6,40.41,2635603.0,0.0,1.0,39.423316467973,40.205839583795,39.225209350044,40.027543177658,2635603.0
+2017-06-27,40.14,40.35,39.62,39.63,2705421.0,0.0,1.0,39.760098568453,39.968111042279,39.245020061837,39.254925417733,2705421.0
+2017-06-26,39.87,40.515,39.87,40.29,3251780.0,0.0,1.0,39.492653959248,40.131549414571,39.492653959248,39.9086789069,3251780.0
+2017-06-23,39.13,40.07,39.01,39.87,4505252.0,0.0,1.0,38.759657622909,39.690761077178,38.640793352152,39.492653959248,4505252.0
+2017-06-22,38.59,39.36,38.58,39.11,3042690.0,0.0,1.0,38.2247684045,38.987480808528,38.214863048603,38.739846911116,3042690.0
+2017-06-21,38.36,38.86,38.3501,38.61,2462900.0,0.0,1.0,37.996945218881,38.492213013704,37.987138916543,38.244579116292,2462900.0
+2017-06-20,38.27,38.65,38.25,38.26,2206944.0,0.0,1.0,37.907797015812,38.284200539878,37.887986304019,37.897891659916,2206944.0
+2017-06-19,38.17,38.495,38.04,38.42,2487716.0,0.0,1.0,37.808743456848,38.130667523483,37.679973830193,38.056377354259,2487716.0
+2017-06-16,37.94,38.11,37.78,37.98,2238387.0,0.0,1.0,37.580920271229,37.749311321469,37.422434576885,37.620541694815,2238387.0
+2017-06-15,37.72,38.1,37.43,37.97,2208659.0,0.0,1.0,37.363002441506,37.739405965572,37.075747120508,37.610636338918,2208659.0
+2017-06-14,38.94,39.01,37.78,38.1,2849570.0,0.0,1.0,38.571455860876,38.640793352152,37.422434576885,37.739405965572,2849570.0
+2017-06-13,38.95,39.37,38.7,38.93,2827824.0,0.0,1.0,38.581361216773,38.997386164425,38.333727319361,38.56155050498,2827824.0
+2017-06-12,39.14,39.66,38.65,38.86,4222954.0,0.0,1.0,38.769562978806,39.284641485422,38.284200539878,38.492213013704,4222954.0
+2017-06-09,39.87,40.395,39.13,39.52,2961902.0,0.0,1.0,39.492653959248,40.012685143813,38.759657622909,39.145966502872,2961902.0
+2017-06-08,39.21,40.12,39.09,40.01,3552505.0,0.0,1.0,38.838900470081,39.74028785666,38.720036199323,39.631328941799,3552505.0
+2017-06-07,38.86,39.57,38.71,39.27,2414656.0,0.0,1.0,38.492213013704,39.195493282354,38.343632675257,38.89833260546,2414656.0
+2017-06-06,38.7,39.23,38.67,38.7,2459220.0,0.0,1.0,38.333727319361,38.858711181874,38.304011251671,38.333727319361,2459220.0
+2017-06-05,39.19,39.7,38.95,38.98,2387428.0,0.0,1.0,38.819089758288,39.324262909008,38.581361216773,38.611077284462,2387428.0
+2017-06-02,39.51,39.75,39.24,39.41,3121583.0,0.0,1.0,39.136061146975,39.373789688491,38.86861653777,39.037007588011,3121583.0
+2017-06-01,39.85,40.25,39.54,39.61,3933108.0,0.0,1.0,39.472843247455,39.869057483314,39.165777214665,39.23511470594,3933108.0
diff --git a/examples/quick/demos/stocqt/content/data/NVDA.csv b/examples/quick/demos/stocqt/content/data/NVDA.csv
new file mode 100644
index 0000000000..c37a25ae5b
--- /dev/null
+++ b/examples/quick/demos/stocqt/content/data/NVDA.csv
@@ -0,0 +1,148 @@
+Date,Open,High,Low,Close,Volume,Ex-Dividend,Split Ratio,Adj. Open,Adj. High,Adj. Low,Adj. Close,Adj. Volume
+2017-12-29,198.46,198.46,193.5,193.5,6896330.0,0.0,1.0,198.46,198.46,193.5,193.5,6896330.0
+2017-12-28,198.13,199.38,197.1514,197.4,5978211.0,0.0,1.0,198.13,199.38,197.1514,197.4,5978211.0
+2017-12-27,196.9,199.97,196.31,197.17,8097374.0,0.0,1.0,196.9,199.97,196.31,197.17,8097374.0
+2017-12-26,193.03,197.75,191.82,197.44,8821296.0,0.0,1.0,193.03,197.75,191.82,197.44,8821296.0
+2017-12-22,194.4,195.65,191.25,195.27,11613423.0,0.0,1.0,194.4,195.65,191.25,195.27,11613423.0
+2017-12-21,196.94,197.95,195.55,195.89,7458634.0,0.0,1.0,196.94,197.95,195.55,195.89,7458634.0
+2017-12-20,197.7,198.07,194.55,196.8,7185318.0,0.0,1.0,197.7,198.07,194.55,196.8,7185318.0
+2017-12-19,197.52,197.73,194.96,196.11,9217358.0,0.0,1.0,197.52,197.73,194.96,196.11,9217358.0
+2017-12-18,193.2,198.02,192.0,197.9,11730697.0,0.0,1.0,193.2,198.02,192.0,197.9,11730697.0
+2017-12-15,188.251,192.38,185.62,191.56,16090200.0,0.0,1.0,188.251,192.38,185.62,191.56,16090200.0
+2017-12-14,185.92,189.34,184.6,186.47,10871746.0,0.0,1.0,185.92,189.34,184.6,186.47,10871746.0
+2017-12-13,192.5,192.55,185.88,186.18,13744496.0,0.0,1.0,192.5,192.55,185.88,186.18,13744496.0
+2017-12-12,192.9,193.84,189.89,190.84,11296559.0,0.0,1.0,192.9,193.84,189.89,190.84,11296559.0
+2017-12-11,192.06,194.78,191.42,194.66,9106693.0,0.0,1.0,192.06,194.78,191.42,194.66,9106693.0
+2017-12-08,194.01,194.78,191.15,191.49,11483868.0,0.0,1.0,194.01,194.78,191.15,191.49,11483868.0
+2017-12-07,191.96,193.6,190.12,191.99,13190983.0,0.0,1.0,191.96,193.6,190.12,191.99,13190983.0
+2017-12-06,185.7,190.14,184.84,189.26,11464458.0,0.0,1.0,185.7,190.14,184.84,189.26,11464458.0
+2017-12-05,182.4,192.7,180.58,187.74,24480558.0,0.0,1.0,182.4,192.7,180.58,187.74,24480558.0
+2017-12-04,200.05,200.3,184.5,186.66,27080405.0,0.0,1.0,200.05,200.3,184.5,186.66,27080405.0
+2017-12-01,199.31,200.13,192.47,197.68,16352946.0,0.0,1.0,199.31,200.13,192.47,197.68,16352946.0
+2017-11-30,199.2,202.68,196.65,200.71,20144301.0,0.0,1.0,199.2,202.68,196.65,200.71,20144301.0
+2017-11-29,210.01,210.1226,191.23,196.42,34731979.0,0.0,1.0,210.01,210.1226,191.23,196.42,34731979.0
+2017-11-28,214.35,214.73,208.24,210.71,12677148.0,0.0,1.0,214.35,214.73,208.24,210.71,12677148.0
+2017-11-27,217.31,217.36,214.01,214.14,10477983.0,0.0,1.0,217.31,217.36,214.01,214.14,10477983.0
+2017-11-24,215.59,217.0,214.6,216.96,4517982.0,0.0,1.0,215.59,217.0,214.6,216.96,4517982.0
+2017-11-22,217.0,217.0,213.61,214.93,8766814.0,0.0,1.0,217.0,217.0,213.61,214.93,8766814.0
+2017-11-21,215.69,216.52,214.4,216.05,9858634.0,0.0,1.0,215.69,216.52,214.4,216.05,9858634.0
+2017-11-20,211.99,214.57,210.5,214.08,9828414.0,0.0,1.0,211.99,214.57,210.5,214.08,9828414.0
+2017-11-17,213.92,215.35,210.75,211.36,12702474.0,0.0,1.0,213.92,215.35,210.75,211.36,12702474.0
+2017-11-16,212.98,214.2,211.25,211.61,9947915.0,0.0,1.0,212.98,214.2,211.25,211.61,9947915.0
+2017-11-15,211.95,212.0,207.8,209.98,12427082.0,0.0,1.0,211.95,212.0,207.8,209.98,12427082.0
+2017-11-14,213.0,214.8,211.23,214.18,13101484.0,0.0,1.0,213.0,214.8,211.23,214.18,13101484.0
+2017-11-13,216.14,217.17,212.01,212.63,14398431.0,0.0,1.0,216.14,217.17,212.01,212.63,14398431.0
+2017-11-10,213.08,218.67,211.63,216.14,31197127.0,0.0,1.0,213.08,218.67,211.63,216.14,31197127.0
+2017-11-09,205.27,206.33,200.37,205.32,20123846.0,0.0,1.0,205.27,206.33,200.37,205.32,20123846.0
+2017-11-07,210.55,212.9,210.0556,212.03,10580672.0,0.0,1.0,210.55,212.9,210.0556,212.03,10580672.0
+2017-11-06,207.2,209.98,206.7,209.63,9693716.0,0.0,1.0,207.2,209.98,206.7,209.63,9693716.0
+2017-11-03,207.2,208.69,205.341,208.69,8777981.0,0.0,1.0,207.2,208.69,205.341,208.69,8777981.0
+2017-11-02,206.0,207.81,203.65,205.94,8480413.0,0.0,1.0,206.0,207.81,203.65,205.94,8480413.0
+2017-11-01,209.35,209.97,204.6,207.2,12385654.0,0.0,1.0,209.35,209.97,204.6,207.2,12385654.0
+2017-10-31,205.13,207.89,204.9,206.81,10179802.0,0.0,1.0,205.13,207.89,204.9,206.81,10179802.0
+2017-10-30,201.86,206.0899,201.22,203.84,12522329.0,0.0,1.0,201.86,206.0899,201.22,203.84,12522329.0
+2017-10-27,197.8,201.87,196.75,201.86,14174171.0,0.0,1.0,197.8,201.87,196.75,201.86,14174171.0
+2017-10-26,194.78,196.16,193.81,195.69,7892651.0,0.0,1.0,194.78,196.16,193.81,195.69,7892651.0
+2017-10-25,197.08,199.22,191.17,193.66,20588601.0,0.0,1.0,197.08,199.22,191.17,193.66,20588601.0
+2017-10-24,196.99,198.75,195.94,198.68,9820462.0,0.0,1.0,196.99,198.75,195.94,198.68,9820462.0
+2017-10-23,197.78,198.85,195.8,196.62,10592416.0,0.0,1.0,197.78,198.85,195.8,196.62,10592416.0
+2017-10-20,198.49,199.59,196.54,196.9,11006029.0,0.0,1.0,198.49,199.59,196.54,196.9,11006029.0
+2017-10-19,194.44,198.0,192.4501,197.8,14156573.0,0.0,1.0,194.44,198.0,192.4501,197.8,14156573.0
+2017-10-18,198.11,198.14,193.32,197.58,14066925.0,0.0,1.0,198.11,198.14,193.32,197.58,14066925.0
+2017-10-17,197.09,198.9,196.35,197.75,11482547.0,0.0,1.0,197.09,198.9,196.35,197.75,11482547.0
+2017-10-16,195.8,198.048,193.24,197.93,14279032.0,0.0,1.0,195.8,198.048,193.24,197.93,14279032.0
+2017-10-13,193.55,195.0,191.65,194.59,15626525.0,0.0,1.0,193.55,195.0,191.65,194.59,15626525.0
+2017-10-12,191.08,193.09,189.9301,191.03,13036890.0,0.0,1.0,191.08,193.09,189.9301,191.03,13036890.0
+2017-10-11,189.6,191.0,187.74,190.94,13051762.0,0.0,1.0,189.6,191.0,187.74,190.94,13051762.0
+2017-10-10,191.43,192.95,187.26,188.88,24261445.0,0.0,1.0,191.43,192.95,187.26,188.88,24261445.0
+2017-10-09,182.79,186.73,182.03,185.39,13986610.0,0.0,1.0,182.79,186.73,182.03,185.39,13986610.0
+2017-10-06,179.65,181.84,179.0,181.3,7911087.0,0.0,1.0,179.65,181.84,179.0,181.3,7911087.0
+2017-10-05,181.86,182.0,179.56,180.77,10830438.0,0.0,1.0,181.86,182.0,179.56,180.77,10830438.0
+2017-10-04,179.62,181.77,178.14,180.87,10621386.0,0.0,1.0,179.62,181.77,178.14,180.87,10621386.0
+2017-10-03,179.25,180.58,177.58,179.37,9678430.0,0.0,1.0,179.25,180.58,177.58,179.37,9678430.0
+2017-10-02,180.8,181.98,177.0,179.0,12475560.0,0.0,1.0,180.8,181.98,177.0,179.0,12475560.0
+2017-09-29,179.08,179.73,177.25,178.77,14936876.0,0.0,1.0,179.08,179.73,177.25,178.77,14936876.0
+2017-09-28,176.02,176.18,173.76,175.68,10801464.0,0.0,1.0,176.02,176.18,173.76,175.68,10801464.0
+2017-09-27,175.62,176.27,172.75,175.73,17602299.0,0.0,1.0,175.62,176.27,172.75,175.73,17602299.0
+2017-09-26,176.45,178.68,170.35,171.96,27542805.0,0.0,1.0,176.45,178.68,170.35,171.96,27542805.0
+2017-09-25,177.75,177.8,170.16,171.0,21628235.0,0.0,1.0,177.75,177.8,170.16,171.0,21628235.0
+2017-09-22,180.3,182.31,178.6,179.0,12196947.0,0.0,1.0,180.3,182.31,178.6,179.0,12196947.0
+2017-09-21,181.64,182.7,177.61,180.7799,26631321.0,0.0,1.0,181.64,182.7,177.61,180.7799,26631321.0
+2017-09-20,187.5,189.42,184.21,185.84,16435216.0,0.0,1.0,187.5,189.42,184.21,185.84,16435216.0
+2017-09-19,185.51,189.85,184.615,187.35,21631434.0,0.0,1.0,185.51,189.85,184.615,187.35,21631434.0
+2017-09-18,185.14,191.2,184.86,187.55,41601951.0,0.0,1.0,185.14,191.2,184.86,187.55,41601951.0
+2017-09-15,172.86,180.11,172.65,180.11,33338633.0,0.0,1.0,172.86,180.11,172.65,180.11,33338633.0
+2017-09-14,168.79,172.56,167.8,169.4,12728431.0,0.0,1.0,168.79,172.56,167.8,169.4,12728431.0
+2017-09-13,168.59,171.54,167.28,170.37,14340105.0,0.0,1.0,168.59,171.54,167.28,170.37,14340105.0
+2017-09-12,170.0,170.0,166.97,169.61,10155905.0,0.0,1.0,170.0,170.0,166.97,169.61,10155905.0
+2017-09-11,165.54,169.4325,165.32,169.0,13934287.0,0.0,1.0,165.54,169.4325,165.32,169.0,13934287.0
+2017-09-08,166.11,166.71,162.71,163.69,12365074.0,0.0,1.0,166.11,166.71,162.71,163.69,12365074.0
+2017-09-07,166.49,167.89,164.95,166.58,8731886.0,0.0,1.0,166.49,167.89,164.95,166.58,8731886.0
+2017-09-06,167.24,167.8,164.4,165.81,9800559.0,0.0,1.0,167.24,167.8,164.4,165.81,9800559.0
+2017-09-05,168.38,168.5843,163.5625,165.91,17358768.0,0.0,1.0,168.38,168.5843,163.5625,165.91,17358768.0
+2017-09-01,169.95,171.9,169.6,170.46,11017001.0,0.0,1.0,169.95,171.9,169.6,170.46,11017001.0
+2017-08-31,166.5,169.6,166.2,169.44,15022660.0,0.0,1.0,166.5,169.6,166.2,169.44,15022660.0
+2017-08-30,165.5,166.13,164.27,165.68,9469680.0,0.0,1.0,165.5,166.13,164.27,165.68,9469680.0
+2017-08-29,162.59,165.58,162.261,164.7,7992338.0,0.0,1.0,162.59,165.58,162.261,164.7,7992338.0
+2017-08-28,164.58,165.1,162.33,164.97,9568908.0,0.0,1.0,164.58,165.1,162.33,164.97,9568908.0
+2017-08-25,166.17,166.58,163.55,163.81,8753208.0,0.0,1.0,166.17,166.58,163.55,163.81,8753208.0
+2017-08-24,167.1,167.28,164.12,165.19,11592997.0,0.0,1.0,167.1,167.28,164.12,165.19,11592997.0
+2017-08-23,161.2,166.25,160.85,165.8,14421053.0,0.0,1.0,161.2,166.25,160.85,165.8,14421053.0
+2017-08-22,160.49,162.79,159.71,162.51,11084658.0,0.14,1.0,160.49,162.79,159.71,162.51,11084658.0
+2017-08-21,162.49,162.95,157.37,159.12,15203637.0,0.0,1.0,162.35013771903,162.80974177682,157.23454472794,158.98303842607,15203637.0
+2017-08-18,163.67,164.36,159.64,161.5,14883408.0,0.0,1.0,163.52912204119,164.21852812788,159.50259083923,161.36098985552,14883408.0
+2017-08-17,164.81,165.5,161.38,161.47,12937916.0,0.0,1.0,164.66814079311,165.3575468798,161.24109314479,161.33101567784,12937916.0
+2017-08-16,167.59,168.54,163.84,165.15,14788247.0,0.0,1.0,167.44574792499,168.39493021826,163.69897571472,165.00784814018,14788247.0
+2017-08-15,168.61,169.67,165.59,166.98,18980198.0,0.0,1.0,168.46486996619,169.52395757762,165.44746941285,166.83627297879,18980198.0
+2017-08-14,159.67,168.55,159.2,168.4,31674266.0,0.0,1.0,159.53256501691,168.40492161082,159.06296956655,168.25505072241,31674266.0
+2017-08-11,157.14,159.0,152.91,155.95,37272782.0,0.0,1.0,157.00474269905,158.86314171534,152.77838364587,155.81576698432,37272782.0
+2017-08-10,172.16,172.66,164.33,164.74,26065538.0,0.0,1.0,172.01181432524,172.51138395327,164.1885539502,164.59820104519,26065538.0
+2017-08-09,168.43,172.21,167.67,172.11,13060514.0,0.0,1.0,168.28502490009,172.06177128804,167.52567906548,171.96185736243,13060514.0
+2017-08-08,173.89,174.56,168.71,170.3,18632853.0,0.0,1.0,173.74032523824,174.40974853981,168.56478389179,170.15341530895,18632853.0
+2017-08-07,168.39,172.37,168.0,172.25,17743004.0,0.0,1.0,168.24505932985,172.22163356901,167.85539501998,172.10173685828,17743004.0
+2017-08-04,167.4,170.07,166.48,167.21,14653397.0,0.0,1.0,167.25591146634,169.92361328005,166.33670335075,167.06607500769,14653397.0
+2017-08-03,164.37,166.63,163.68,166.48,10926536.0,0.0,1.0,164.22851952044,166.48657423916,163.53911343375,166.33670335075,10926536.0
+2017-08-02,165.75,165.91,161.27,164.39,11565556.0,0.0,1.0,165.60733169382,165.76719397479,161.13118782662,164.24850230556,11565556.0
+2017-08-01,162.125,164.56,161.0,164.49,10606575.0,0.0,1.0,161.98545189056,164.4183559791,160.86142022748,164.34841623117,10606575.0
+2017-07-31,164.94,166.4,160.62,162.51,13800261.0,0.0,1.0,164.7980288964,166.25677221027,160.48174731018,162.37012050415,13800261.0
+2017-07-28,160.29,165.38,159.28,164.39,12776296.0,0.0,1.0,160.15203135567,165.23765016907,159.14290070704,164.24850230556,12776296.0
+2017-07-27,168.27,168.74,157.56,161.74,18888931.0,0.0,1.0,168.12516261912,168.59475806947,157.4243811866,161.60078327698,18888931.0
+2017-07-26,167.68,169.927,165.85,167.26,15755026.0,0.0,1.0,167.53567045804,169.78073636643,165.70724561943,167.11603197049,15755026.0
+2017-07-25,165.22,165.93,163.581,165.35,12002860.0,0.0,1.0,165.0777878881,165.78717675991,163.4401986474,165.20767599139,12002860.0
+2017-07-24,168.39,168.78,165.72,166.15,15868676.0,0.0,1.0,168.24505932985,168.63472363972,165.57735751614,166.00698739625,15868676.0
+2017-07-21,166.67,169.3,166.09,168.1,15886110.0,0.0,1.0,166.52653980941,169.15427605287,165.94703904089,167.95530894559,15886110.0
+2017-07-20,165.93,167.51,163.9121,167.48,17258237.0,0.0,1.0,165.78717675991,167.36581678451,163.77101365509,167.33584260682,17258237.0
+2017-07-19,166.33,167.4,164.61,165.1,17014089.0,0.0,1.0,166.18683246234,167.25591146634,164.4683129419,164.95789117737,17014089.0
+2017-07-18,161.78,166.55,161.3,165.96,19123179.0,0.0,1.0,161.64074884722,166.40664309868,161.1611620043,165.8171509376,19123179.0
+2017-07-17,166.33,167.5,161.75,164.25,22936328.0,0.0,1.0,166.18683246234,167.35582539195,161.61077466954,164.10862280971,22936328.0
+2017-07-14,161.29,165.01,161.01,164.95,23349534.0,0.0,1.0,161.15117061174,164.86796864433,160.87141162004,164.80802028896,23349534.0
+2017-07-13,163.0,166.3,158.75,160.63,34123997.0,0.0,1.0,162.85969873962,166.15685828466,158.61335690132,160.49173870274,34123997.0
+2017-07-12,158.3,163.0,156.56,162.51,28283476.0,0.0,1.0,158.16374423609,162.85969873962,156.42524193053,162.37012050415,28283476.0
+2017-07-11,153.85,156.19,152.15,155.88,18744156.0,0.0,1.0,153.71757454657,156.05556040578,152.01903781125,155.7458272364,18744156.0
+2017-07-10,149.74,154.0,148.6842,153.7,23720137.0,0.0,1.0,149.61111220412,153.86744543498,148.55622097756,153.56770365816,23720137.0
+2017-07-07,145.78,147.5,144.85,146.76,16258515.0,0.0,1.0,145.65452075008,147.37304027052,144.72532124193,146.63367722103,16258515.0
+2017-07-06,141.87,145.3799,139.76,143.48,18383056.0,0.0,1.0,141.74788625884,145.25476513372,139.63970242853,143.35650046111,18383056.0
+2017-07-05,141.9,144.22,141.13,143.05,20226442.0,0.0,1.0,141.77786043652,144.09586351061,141.00852320935,142.926870581,20226442.0
+2017-07-03,145.05,145.6537,138.58,139.33,17722284.0,0.0,1.0,144.92514909314,145.52832946204,138.46071810636,139.21007254842,17722284.0
+2017-06-30,147.38,147.93,143.5,144.56,17992137.0,0.0,1.0,147.25314355979,147.80267015063,143.37648324623,144.43557085767,17992137.0
+2017-06-29,150.6,150.72,144.08,146.68,26334702.0,0.0,1.0,150.47037196434,150.59026867507,143.95598401476,146.55374608054,26334702.0
+2017-06-28,149.32,151.94,145.75,151.75,24660291.0,0.0,1.0,149.19147371657,151.80921856748,145.62454657239,151.61938210882,24660291.0
+2017-06-27,151.44,151.79,146.35,146.58,24850612.0,0.0,1.0,151.30964893944,151.65934767907,146.22403012604,146.45383215493,24850612.0
+2017-06-26,155.16,156.6,148.33,152.15,26418557.0,0.0,1.0,155.02644697203,156.46520750077,148.20232585306,152.01903781125,26418557.0
+2017-06-23,158.68,159.32,153.22,154.11,24565502.0,0.0,1.0,158.5434171534,159.18286627728,153.08811681525,153.97735075315,24565502.0
+2017-06-22,159.8,160.34,157.4,158.37,11596308.0,0.0,1.0,159.6624531202,160.20198831848,157.26451890563,158.23368398401,11596308.0
+2017-06-21,158.21,159.62,155.7,159.47,16945632.0,0.0,1.0,158.07382170304,159.4826080541,155.5659821703,159.33273716569,16945632.0
+2017-06-20,159.03,161.74,156.92,157.09,27169647.0,0.0,1.0,158.89311589302,161.60078327698,156.78493206271,156.95478573624,27169647.0
+2017-06-19,153.41,157.53,153.26,157.32,19260255.0,0.0,1.0,153.2779532739,157.39440700891,153.12808238549,157.18458776514,19260255.0
+2017-06-16,152.76,154.7,150.24,151.62,22554327.0,0.0,1.0,152.62851275745,154.56684291423,150.11068183215,151.48949400553,22554327.0
+2017-06-15,146.96,153.6,146.5,152.37,23883179.0,0.0,1.0,146.83350507224,153.46778973255,146.37390101445,152.23884844759,23883179.0
+2017-06-14,151.52,154.06,148.5,151.72,29431459.0,0.0,1.0,151.38958007993,153.92739379035,148.37217952659,151.58940793114,29431459.0
+2017-06-13,154.4,154.77,145.65,151.4,41488612.0,0.0,1.0,154.26710113741,154.63678266216,145.52463264679,151.2696833692,41488612.0
+2017-06-12,145.88,151.7,142.11,149.97,41793262.0,0.0,1.0,145.75443467568,151.56942514602,141.9876796803,149.84091423302,41793262.0
+2017-06-09,164.74,168.5,142.75,149.6,91979374.0,0.0,1.0,164.59820104519,168.35496464802,142.62712880418,149.47123270827,91979374.0
+2017-06-08,153.46,160.0,151.79,159.952,28475455.0,0.0,1.0,153.3279102367,159.86228097141,151.65934767907,159.81432228712,28475455.0
+2017-06-07,148.33,149.88,147.7,149.12,15057318.0,0.0,1.0,148.20232585306,149.75099169997,147.57286812173,148.99164586536,15057318.0
+2017-06-06,147.82,149.69,146.8,147.34,18743334.0,0.0,1.0,147.69276483246,149.56115524132,146.67364279127,147.21317798955,18743334.0
+2017-06-05,142.98,148.53,142.51,148.01,20311623.0,0.0,1.0,142.85693083308,148.40215370427,142.38733538272,147.88260129112,20311623.0
+2017-06-02,144.24,145.3,143.4,143.64,12140804.0,0.0,1.0,144.11584629573,145.17493390716,143.27656932063,143.51636274208,12140804.0
+2017-06-01,144.99,145.03,142.52,144.2499,12462061.0,0.0,1.0,144.86520073778,144.90516630802,142.39732677528,144.12573777436,12462061.0
diff --git a/examples/quick/demos/stocqt/content/data/PYPL.csv b/examples/quick/demos/stocqt/content/data/PYPL.csv
new file mode 100644
index 0000000000..53034c65d2
--- /dev/null
+++ b/examples/quick/demos/stocqt/content/data/PYPL.csv
@@ -0,0 +1,148 @@
+Date,Open,High,Low,Close,Volume,Ex-Dividend,Split Ratio,Adj. Open,Adj. High,Adj. Low,Adj. Close,Adj. Volume
+2017-12-29,73.92,74.53,73.58,73.62,4396182.0,0.0,1.0,73.92,74.53,73.58,73.62,4396182.0
+2017-12-28,74.96,75.0,73.86,74.17,3363964.0,0.0,1.0,74.96,75.0,73.86,74.17,3363964.0
+2017-12-27,74.25,74.93,74.0,74.59,4226467.0,0.0,1.0,74.25,74.93,74.0,74.59,4226467.0
+2017-12-26,73.29,74.34,72.63,74.27,4683371.0,0.0,1.0,73.29,74.34,72.63,74.27,4683371.0
+2017-12-22,73.8,74.04,72.9,73.89,3570969.0,0.0,1.0,73.8,74.04,72.9,73.89,3570969.0
+2017-12-21,74.19,74.47,73.8,74.02,4556474.0,0.0,1.0,74.19,74.47,73.8,74.02,4556474.0
+2017-12-20,74.64,74.9,73.76,74.0,5964055.0,0.0,1.0,74.64,74.9,73.76,74.0,5964055.0
+2017-12-19,75.39,75.39,73.91,74.5,7430435.0,0.0,1.0,75.39,75.39,73.91,74.5,7430435.0
+2017-12-18,76.3,76.35,75.2,75.32,8034166.0,0.0,1.0,76.3,76.35,75.2,75.32,8034166.0
+2017-12-15,74.82,75.87,73.51,75.65,10935788.0,0.0,1.0,74.82,75.87,73.51,75.65,10935788.0
+2017-12-14,74.5,75.53,74.2,74.26,7453419.0,0.0,1.0,74.5,75.53,74.2,74.26,7453419.0
+2017-12-13,74.08,75.42,73.77,74.09,7037486.0,0.0,1.0,74.08,75.42,73.77,74.09,7037486.0
+2017-12-12,73.45,74.31,73.0,73.62,5947690.0,0.0,1.0,73.45,74.31,73.0,73.62,5947690.0
+2017-12-11,72.96,73.68,72.56,73.29,5786918.0,0.0,1.0,72.96,73.68,72.56,73.29,5786918.0
+2017-12-08,74.71,74.71,72.6,72.91,8130594.0,0.0,1.0,74.71,74.71,72.6,72.91,8130594.0
+2017-12-07,73.25,74.069,73.25,73.69,7547591.0,0.0,1.0,73.25,74.069,73.25,73.69,7547591.0
+2017-12-06,70.89,73.2,70.83,73.14,9188317.0,0.0,1.0,70.89,73.2,70.83,73.14,9188317.0
+2017-12-05,69.81,72.75,69.61,71.2,15818651.0,0.0,1.0,69.81,72.75,69.61,71.2,15818651.0
+2017-12-04,75.59,75.7439,68.61,70.97,26157704.0,0.0,1.0,75.59,75.7439,68.61,70.97,26157704.0
+2017-12-01,75.22,76.44,74.26,75.2999,13310272.0,0.0,1.0,75.22,76.44,74.26,75.2999,13310272.0
+2017-11-30,73.77,75.87,73.54,75.73,15737916.0,0.0,1.0,73.77,75.87,73.54,75.73,15737916.0
+2017-11-29,77.95,77.98,71.67,73.25,24981118.0,0.0,1.0,77.95,77.98,71.67,73.25,24981118.0
+2017-11-28,77.95,78.23,77.2435,77.79,8570920.0,0.0,1.0,77.95,78.23,77.2435,77.79,8570920.0
+2017-11-27,78.63,79.385,77.71,77.84,6745449.0,0.0,1.0,78.63,79.385,77.71,77.84,6745449.0
+2017-11-24,77.81,78.9,77.7,78.57,4305618.0,0.0,1.0,77.81,78.9,77.7,78.57,4305618.0
+2017-11-22,77.9,77.99,76.62,77.57,7975445.0,0.0,1.0,77.9,77.99,76.62,77.57,7975445.0
+2017-11-21,77.09,78.43,76.85,77.77,10283504.0,0.0,1.0,77.09,78.43,76.85,77.77,10283504.0
+2017-11-20,76.6,77.32,75.88,76.01,6799610.0,0.0,1.0,76.6,77.32,75.88,76.01,6799610.0
+2017-11-17,78.01,78.01,75.8,76.38,11771514.0,0.0,1.0,78.01,78.01,75.8,76.38,11771514.0
+2017-11-16,75.5,77.94,75.28,77.7,12154083.0,0.0,1.0,75.5,77.94,75.28,77.7,12154083.0
+2017-11-15,74.3,74.4,73.1853,73.43,5780290.0,0.0,1.0,74.3,74.4,73.1853,73.43,5780290.0
+2017-11-14,74.1,74.82,73.62,74.49,5426087.0,0.0,1.0,74.1,74.82,73.62,74.49,5426087.0
+2017-11-13,73.61,74.29,73.34,74.03,5821794.0,0.0,1.0,73.61,74.29,73.34,74.03,5821794.0
+2017-11-10,73.77,74.14,73.56,73.99,5703206.0,0.0,1.0,73.77,74.14,73.56,73.99,5703206.0
+2017-11-09,74.02,74.2,72.41,74.1,8526645.0,0.0,1.0,74.02,74.2,72.41,74.1,8526645.0
+2017-11-07,75.17,75.45,74.19,74.41,6855004.0,0.0,1.0,75.17,75.45,74.19,74.41,6855004.0
+2017-11-06,73.72,74.76,73.42,74.74,10052359.0,0.0,1.0,73.72,74.76,73.42,74.74,10052359.0
+2017-11-03,72.37,73.41,71.94,73.39,6714105.0,0.0,1.0,72.37,73.41,71.94,73.39,6714105.0
+2017-11-02,72.46,72.7755,72.01,72.25,4518557.0,0.0,1.0,72.46,72.7755,72.01,72.25,4518557.0
+2017-11-01,72.78,72.99,71.69,72.38,6576235.0,0.0,1.0,72.78,72.99,71.69,72.38,6576235.0
+2017-10-31,71.34,72.74,71.11,72.56,7478157.0,0.0,1.0,71.34,72.74,71.11,72.56,7478157.0
+2017-10-30,71.45,71.54,70.53,71.15,6911407.0,0.0,1.0,71.45,71.54,70.53,71.15,6911407.0
+2017-10-27,71.72,71.79,70.58,71.06,9192172.0,0.0,1.0,71.72,71.79,70.58,71.06,9192172.0
+2017-10-26,71.46,72.07,71.04,71.34,7967791.0,0.0,1.0,71.46,72.07,71.04,71.34,7967791.0
+2017-10-25,69.94,71.42,69.85,71.02,11908785.0,0.0,1.0,69.94,71.42,69.85,71.02,11908785.0
+2017-10-24,69.73,70.565,69.67,70.21,12057648.0,0.0,1.0,69.73,70.565,69.67,70.21,12057648.0
+2017-10-23,71.02,71.33,69.55,69.8,12004583.0,0.0,1.0,71.02,71.33,69.55,69.8,12004583.0
+2017-10-20,71.33,71.73,69.69,70.97,33976887.0,0.0,1.0,71.33,71.73,69.69,70.97,33976887.0
+2017-10-19,67.3,67.45,66.16,67.25,11645310.0,0.0,1.0,67.3,67.45,66.16,67.25,11645310.0
+2017-10-18,67.4,67.5,67.0,67.26,7866118.0,0.0,1.0,67.4,67.5,67.0,67.26,7866118.0
+2017-10-17,67.65,67.67,66.35,66.67,10630805.0,0.0,1.0,67.65,67.67,66.35,66.67,10630805.0
+2017-10-16,69.04,69.2,67.28,67.31,9449837.0,0.0,1.0,69.04,69.2,67.28,67.31,9449837.0
+2017-10-13,69.49,69.61,68.0,68.66,8596855.0,0.0,1.0,69.49,69.61,68.0,68.66,8596855.0
+2017-10-12,68.02,68.98,67.8048,68.86,8607233.0,0.0,1.0,68.02,68.98,67.8048,68.86,8607233.0
+2017-10-11,67.25,68.42,66.98,67.78,11918941.0,0.0,1.0,67.25,68.42,66.98,67.78,11918941.0
+2017-10-10,66.6,66.67,65.79,66.04,5795772.0,0.0,1.0,66.6,66.67,65.79,66.04,5795772.0
+2017-10-09,66.2,66.55,65.9,66.23,5511409.0,0.0,1.0,66.2,66.55,65.9,66.23,5511409.0
+2017-10-06,66.0,66.41,65.79,66.05,6102894.0,0.0,1.0,66.0,66.41,65.79,66.05,6102894.0
+2017-10-05,64.38,66.0,64.22,65.82,6918222.0,0.0,1.0,64.38,66.0,64.22,65.82,6918222.0
+2017-10-04,64.3,64.3,63.69,64.01,4399565.0,0.0,1.0,64.3,64.3,63.69,64.01,4399565.0
+2017-10-03,64.51,64.51,63.7607,64.22,5614020.0,0.0,1.0,64.51,64.51,63.7607,64.22,5614020.0
+2017-10-02,64.5,65.12,64.1,64.18,5141673.0,0.0,1.0,64.5,65.12,64.1,64.18,5141673.0
+2017-09-29,63.86,64.17,63.5,64.03,6706995.0,0.0,1.0,63.86,64.17,63.5,64.03,6706995.0
+2017-09-28,63.62,64.055,63.11,63.93,3982117.0,0.0,1.0,63.62,64.055,63.11,63.93,3982117.0
+2017-09-27,63.41,63.75,63.1601,63.33,6807674.0,0.0,1.0,63.41,63.75,63.1601,63.33,6807674.0
+2017-09-26,63.71,63.7623,62.84,62.94,8084916.0,0.0,1.0,63.71,63.7623,62.84,62.94,8084916.0
+2017-09-25,65.0,65.0,62.365,63.5,13088161.0,0.0,1.0,65.0,65.0,62.365,63.5,13088161.0
+2017-09-22,64.33,65.24,64.11,65.08,6539011.0,0.0,1.0,64.33,65.24,64.11,65.08,6539011.0
+2017-09-21,64.67,64.95,63.905,64.63,6539750.0,0.0,1.0,64.67,64.95,63.905,64.63,6539750.0
+2017-09-20,63.99,64.87,63.83,64.74,11704012.0,0.0,1.0,63.99,64.87,63.83,64.74,11704012.0
+2017-09-19,63.01,63.925,62.96,63.83,7646245.0,0.0,1.0,63.01,63.925,62.96,63.83,7646245.0
+2017-09-18,62.62,63.5299,62.52,62.92,7561354.0,0.0,1.0,62.62,63.5299,62.52,62.92,7561354.0
+2017-09-15,62.27,62.8,61.96,62.5,9561717.0,0.0,1.0,62.27,62.8,61.96,62.5,9561717.0
+2017-09-14,62.04,62.37,61.71,62.24,5657030.0,0.0,1.0,62.04,62.37,61.71,62.24,5657030.0
+2017-09-13,62.47,62.75,61.58,62.04,6113877.0,0.0,1.0,62.47,62.75,61.58,62.04,6113877.0
+2017-09-12,62.95,63.12,62.15,62.56,6199885.0,0.0,1.0,62.95,63.12,62.15,62.56,6199885.0
+2017-09-11,61.73,63.26,61.62,62.64,8162604.0,0.0,1.0,61.73,63.26,61.62,62.64,8162604.0
+2017-09-08,61.94,62.0,61.1,61.13,4876488.0,0.0,1.0,61.94,62.0,61.1,61.13,4876488.0
+2017-09-07,61.33,62.13,61.28,62.0,4962951.0,0.0,1.0,61.33,62.13,61.28,62.0,4962951.0
+2017-09-06,61.74,61.99,60.9,61.24,5217668.0,0.0,1.0,61.74,61.99,60.9,61.24,5217668.0
+2017-09-05,61.26,61.75,60.58,61.27,5696603.0,0.0,1.0,61.26,61.75,60.58,61.27,5696603.0
+2017-09-01,61.98,62.23,61.3831,61.46,3389772.0,0.0,1.0,61.98,62.23,61.3831,61.46,3389772.0
+2017-08-31,62.0,62.029,61.17,61.68,6088973.0,0.0,1.0,62.0,62.029,61.17,61.68,6088973.0
+2017-08-30,61.05,61.86,60.89,61.77,5613393.0,0.0,1.0,61.05,61.86,60.89,61.77,5613393.0
+2017-08-29,59.82,61.16,59.63,61.01,4330268.0,0.0,1.0,59.82,61.16,59.63,61.01,4330268.0
+2017-08-28,60.31,60.53,59.81,60.53,4616049.0,0.0,1.0,60.31,60.53,59.81,60.53,4616049.0
+2017-08-25,60.33,60.58,59.61,59.97,4006421.0,0.0,1.0,60.33,60.58,59.61,59.97,4006421.0
+2017-08-24,60.22,60.43,59.11,60.0,3787878.0,0.0,1.0,60.22,60.43,59.11,60.0,3787878.0
+2017-08-23,60.3,60.51,59.82,60.04,4511679.0,0.0,1.0,60.3,60.51,59.82,60.04,4511679.0
+2017-08-22,59.72,61.0,59.44,60.84,5782471.0,0.0,1.0,59.72,61.0,59.44,60.84,5782471.0
+2017-08-21,59.33,59.65,58.755,59.4,4206531.0,0.0,1.0,59.33,59.65,58.755,59.4,4206531.0
+2017-08-18,59.36,59.82,58.94,59.44,4594653.0,0.0,1.0,59.36,59.82,58.94,59.44,4594653.0
+2017-08-17,60.15,60.28,59.29,59.29,6537123.0,0.0,1.0,60.15,60.28,59.29,59.29,6537123.0
+2017-08-16,59.95,60.7,59.6,60.29,5679048.0,0.0,1.0,59.95,60.7,59.6,60.29,5679048.0
+2017-08-15,59.3,59.98,59.23,59.69,6419599.0,0.0,1.0,59.3,59.98,59.23,59.69,6419599.0
+2017-08-14,58.61,59.2763,58.271,59.06,7127903.0,0.0,1.0,58.61,59.2763,58.271,59.06,7127903.0
+2017-08-11,57.85,58.25,57.58,58.04,6891359.0,0.0,1.0,57.85,58.25,57.58,58.04,6891359.0
+2017-08-10,59.24,59.37,57.81,58.02,9341375.0,0.0,1.0,59.24,59.37,57.81,58.02,9341375.0
+2017-08-09,58.97,59.73,58.59,59.67,5991127.0,0.0,1.0,58.97,59.73,58.59,59.67,5991127.0
+2017-08-08,59.61,59.88,59.25,59.48,5960460.0,0.0,1.0,59.61,59.88,59.25,59.48,5960460.0
+2017-08-07,59.18,59.64,58.84,59.62,5875028.0,0.0,1.0,59.18,59.64,58.84,59.62,5875028.0
+2017-08-04,58.62,58.93,58.32,58.86,6118655.0,0.0,1.0,58.62,58.93,58.32,58.86,6118655.0
+2017-08-03,59.16,59.28,58.36,58.42,6104372.0,0.0,1.0,59.16,59.28,58.36,58.42,6104372.0
+2017-08-02,59.67,59.71,58.44,59.12,6486312.0,0.0,1.0,59.67,59.71,58.44,59.12,6486312.0
+2017-08-01,59.0,59.39,58.79,59.34,8950112.0,0.0,1.0,59.0,59.39,58.79,59.34,8950112.0
+2017-07-31,59.37,59.64,58.52,58.55,7307044.0,0.0,1.0,59.37,59.64,58.52,58.55,7307044.0
+2017-07-28,59.8,60.71,59.04,59.2,10684806.0,0.0,1.0,59.8,60.71,59.04,59.2,10684806.0
+2017-07-27,61.0,61.3,57.6921,60.15,22678000.0,0.0,1.0,61.0,61.3,57.6921,60.15,22678000.0
+2017-07-26,58.48,58.94,57.9,58.79,12794748.0,0.0,1.0,58.48,58.94,57.9,58.79,12794748.0
+2017-07-25,58.73,58.83,58.19,58.26,7859354.0,0.0,1.0,58.73,58.83,58.19,58.26,7859354.0
+2017-07-24,58.9,59.07,58.34,58.58,6373567.0,0.0,1.0,58.9,59.07,58.34,58.58,6373567.0
+2017-07-21,59.0,59.33,58.59,58.67,7486133.0,0.0,1.0,59.0,59.33,58.59,58.67,7486133.0
+2017-07-20,58.75,59.38,58.43,59.09,7990391.0,0.0,1.0,58.75,59.38,58.43,59.09,7990391.0
+2017-07-19,58.31,58.62,57.55,58.35,9624663.0,0.0,1.0,58.31,58.62,57.55,58.35,9624663.0
+2017-07-18,57.5,58.96,57.31,58.96,9436755.0,0.0,1.0,57.5,58.96,57.31,58.96,9436755.0
+2017-07-17,57.53,57.6,57.02,57.58,5604480.0,0.0,1.0,57.53,57.6,57.02,57.58,5604480.0
+2017-07-14,58.14,58.63,56.915,57.16,11651935.0,0.0,1.0,58.14,58.63,56.915,57.16,11651935.0
+2017-07-13,57.3,57.91,56.8,57.9,14687917.0,0.0,1.0,57.3,57.91,56.8,57.9,14687917.0
+2017-07-12,56.6,57.445,55.55,56.55,17345098.0,0.0,1.0,56.6,57.445,55.55,56.55,17345098.0
+2017-07-11,54.92,55.2,54.33,54.76,8865099.0,0.0,1.0,54.92,55.2,54.33,54.76,8865099.0
+2017-07-10,54.91,55.42,54.7,54.96,9916785.0,0.0,1.0,54.91,55.42,54.7,54.96,9916785.0
+2017-07-07,53.7,54.48,53.52,53.97,4805962.0,0.0,1.0,53.7,54.48,53.52,53.97,4805962.0
+2017-07-06,54.22,54.3506,53.15,53.47,7289275.0,0.0,1.0,54.22,54.3506,53.15,53.47,7289275.0
+2017-07-05,53.0,54.75,52.94,54.61,9638570.0,0.0,1.0,53.0,54.75,52.94,54.61,9638570.0
+2017-07-03,54.14,54.33,52.83,52.87,4831590.0,0.0,1.0,54.14,54.33,52.83,52.87,4831590.0
+2017-06-30,53.6,54.25,53.29,53.67,7611077.0,0.0,1.0,53.6,54.25,53.29,53.67,7611077.0
+2017-06-29,53.81,54.1,52.52,53.42,11162726.0,0.0,1.0,53.81,54.1,52.52,53.42,11162726.0
+2017-06-28,52.75,54.44,52.65,54.39,7894816.0,0.0,1.0,52.75,54.44,52.65,54.39,7894816.0
+2017-06-27,53.6,53.79,52.64,52.73,7680978.0,0.0,1.0,53.6,53.79,52.64,52.73,7680978.0
+2017-06-26,54.44,55.1,53.65,53.74,4728731.0,0.0,1.0,54.44,55.1,53.65,53.74,4728731.0
+2017-06-23,53.82,54.53,53.69,54.34,5954697.0,0.0,1.0,53.82,54.53,53.69,54.34,5954697.0
+2017-06-22,53.71,53.951,52.86,53.87,9631525.0,0.0,1.0,53.71,53.951,52.86,53.87,9631525.0
+2017-06-21,52.99,53.58,52.61,53.54,7992648.0,0.0,1.0,52.99,53.58,52.61,53.54,7992648.0
+2017-06-20,52.84,53.23,52.43,52.52,4522851.0,0.0,1.0,52.84,53.23,52.43,52.52,4522851.0
+2017-06-19,52.28,53.0,52.1101,52.93,5276661.0,0.0,1.0,52.28,53.0,52.1101,52.93,5276661.0
+2017-06-16,52.04,52.16,51.58,51.84,10792581.0,0.0,1.0,52.04,52.16,51.58,51.84,10792581.0
+2017-06-15,51.44,52.38,50.83,52.29,9945649.0,0.0,1.0,51.44,52.38,50.83,52.29,9945649.0
+2017-06-14,52.0,52.505,51.535,51.9,7114891.0,0.0,1.0,52.0,52.505,51.535,51.9,7114891.0
+2017-06-13,52.29,52.485,51.7,52.04,10119801.0,0.0,1.0,52.29,52.485,51.7,52.04,10119801.0
+2017-06-12,52.81,52.9,51.43,52.16,15724406.0,0.0,1.0,52.81,52.9,51.43,52.16,15724406.0
+2017-06-09,54.65,55.14,52.85,53.4,10524856.0,0.0,1.0,54.65,55.14,52.85,53.4,10524856.0
+2017-06-08,54.03,54.43,53.45,54.39,6251592.0,0.0,1.0,54.03,54.43,53.45,54.39,6251592.0
+2017-06-07,53.3,53.94,53.26,53.85,6282623.0,0.0,1.0,53.3,53.94,53.26,53.85,6282623.0
+2017-06-06,53.75,53.8,53.16,53.4,6212080.0,0.0,1.0,53.75,53.8,53.16,53.4,6212080.0
+2017-06-05,53.77,54.07,53.59,53.8,9119908.0,0.0,1.0,53.77,54.07,53.59,53.8,9119908.0
+2017-06-02,53.44,53.64,53.08,53.52,9019731.0,0.0,1.0,53.44,53.64,53.08,53.52,9019731.0
+2017-06-01,52.48,53.39,52.475,53.16,13878328.0,0.0,1.0,52.48,53.39,52.475,53.16,13878328.0
diff --git a/examples/quick/demos/stocqt/content/data/QCOM.csv b/examples/quick/demos/stocqt/content/data/QCOM.csv
new file mode 100644
index 0000000000..0067fe307b
--- /dev/null
+++ b/examples/quick/demos/stocqt/content/data/QCOM.csv
@@ -0,0 +1,147 @@
+Date,Open,High,Low,Close,Volume,Ex-Dividend,Split Ratio,Adj. Open,Adj. High,Adj. Low,Adj. Close,Adj. Volume
+2017-12-29,64.36,64.65,64.0,64.02,4553732.0,0.0,1.0,64.36,64.65,64.0,64.02,4553732.0
+2017-12-28,64.69,64.73,64.35,64.38,2371094.0,0.0,1.0,64.69,64.73,64.35,64.38,2371094.0
+2017-12-27,64.32,64.64,64.18,64.54,4821727.0,0.0,1.0,64.32,64.64,64.18,64.54,4821727.0
+2017-12-26,64.49,64.94,64.2,64.3,4185772.0,0.0,1.0,64.49,64.94,64.2,64.3,4185772.0
+2017-12-22,64.31,64.98,64.3,64.73,4386678.0,0.0,1.0,64.31,64.98,64.3,64.73,4386678.0
+2017-12-21,64.75,64.9604,64.34,64.39,5349137.0,0.0,1.0,64.75,64.9604,64.34,64.39,5349137.0
+2017-12-20,64.56,65.17,64.33,64.6,6919901.0,0.0,1.0,64.56,65.17,64.33,64.6,6919901.0
+2017-12-19,65.11,65.48,64.43,64.5,6906151.0,0.0,1.0,65.11,65.48,64.43,64.5,6906151.0
+2017-12-18,64.93,65.46,64.8,65.38,7092422.0,0.0,1.0,64.93,65.46,64.8,65.38,7092422.0
+2017-12-15,65.33,65.42,64.5,64.76,14158271.0,0.0,1.0,65.33,65.42,64.5,64.76,14158271.0
+2017-12-14,64.86,65.17,64.545,64.7,7012732.0,0.0,1.0,64.86,65.17,64.545,64.7,7012732.0
+2017-12-13,64.98,65.425,64.83,64.9,6431073.0,0.0,1.0,64.98,65.425,64.83,64.9,6431073.0
+2017-12-12,64.88,65.11,64.55,64.86,5559918.0,0.0,1.0,64.88,65.11,64.55,64.86,5559918.0
+2017-12-11,64.06,65.2631,64.0,65.18,11846177.0,0.0,1.0,64.06,65.2631,64.0,65.18,11846177.0
+2017-12-08,65.6,65.6,63.88,64.24,9170240.0,0.0,1.0,65.6,65.6,63.88,64.24,9170240.0
+2017-12-07,65.21,65.55,64.77,65.23,6068240.0,0.0,1.0,65.21,65.55,64.77,65.23,6068240.0
+2017-12-06,64.64,65.68,64.36,64.98,6907606.0,0.0,1.0,64.64,65.68,64.36,64.98,6907606.0
+2017-12-05,64.85,65.03,64.4,64.69,9492637.0,0.0,1.0,64.85,65.03,64.4,64.69,9492637.0
+2017-12-04,65.6,65.7,63.8,64.56,17057274.0,0.0,1.0,65.6,65.7,63.8,64.56,17057274.0
+2017-12-01,65.2,66.12,64.6,65.49,15286995.0,0.0,1.0,65.2,66.12,64.6,65.49,15286995.0
+2017-11-30,66.51,67.1,65.72,66.34,14675004.0,0.0,1.0,66.51,67.1,65.72,66.34,14675004.0
+2017-11-29,68.1,68.2,66.03,66.52,16841361.0,0.0,1.0,68.1,68.2,66.03,66.52,16841361.0
+2017-11-28,67.59,68.41,67.22,68.38,12641308.0,0.57,1.0,67.59,68.41,67.22,68.38,12641308.0
+2017-11-27,68.6,68.92,68.04,68.14,20112979.0,0.0,1.0,68.032893401015,68.350248005801,67.47752284264,67.576696156635,20112979.0
+2017-11-24,68.51,69.28,68.45,68.91,9233010.0,0.0,1.0,67.943637418419,68.707271936186,67.884133430022,68.340330674402,9233010.0
+2017-11-22,66.37,68.26,66.24,68.13,15165652.0,0.0,1.0,65.821328498912,67.69570413343,65.692403190718,67.566778825236,15165652.0
+2017-11-21,65.35,66.93,65.27,66.67,11062010.0,0.0,1.0,64.809760696157,66.376699057288,64.73042204496,66.118848440899,11062010.0
+2017-11-20,66.18,66.85,65.95,66.47,9677801.0,0.0,1.0,65.632899202321,66.297360406091,65.404800580131,65.920501812908,9677801.0
+2017-11-17,66.37,66.95,66.0,66.72,12134512.0,0.0,1.0,65.821328498912,66.396533720087,65.454387237128,66.168435097897,12134512.0
+2017-11-16,65.77,66.54,65.43,66.11,12142331.0,0.0,1.0,65.226288614938,65.989923132705,64.889099347353,65.563477882524,12142331.0
+2017-11-15,65.55,66.4838,65.24,65.61,10531408.0,0.0,1.0,65.008107324148,65.934187730239,64.700670050761,65.067611312545,10531408.0
+2017-11-14,66.16,66.8,65.55,66.0,13970519.0,0.0,1.0,65.613064539521,66.247773749094,65.008107324148,65.454387237128,13970519.0
+2017-11-13,64.96,66.82,64.75,66.49,24327595.0,0.0,1.0,64.422984771574,66.267608411893,64.214720812183,65.940336475707,24327595.0
+2017-11-10,64.36,65.1,63.92,64.57,9597929.0,0.0,1.0,63.8279448876,64.561827411168,63.391582306019,64.036208846991,9597929.0
+2017-11-09,64.91,65.33,63.93,64.6,15600914.0,0.0,1.0,64.373398114576,64.789926033358,63.401499637418,64.065960841189,15600914.0
+2017-11-07,62.52,64.16,62.45,64.1,23249338.0,0.0,1.0,62.00315591008,63.629598259608,61.933734590283,63.570094271211,23249338.0
+2017-11-06,64.54,65.33,62.15,62.52,58620899.0,0.0,1.0,64.006456852792,64.789926033358,61.636214648296,62.00315591008,58620899.0
+2017-11-03,54.76,64.99,54.21,61.81,78515925.0,0.0,1.0,54.307306744017,64.452736765772,53.761853517041,61.299025380711,78515925.0
+2017-11-02,53.6,55.68,53.6,54.84,17115009.0,0.0,1.0,53.156896301668,55.219701232777,53.156896301668,54.386645395214,17115009.0
+2017-11-01,51.47,53.49,50.51,53.46,14923803.0,0.0,1.0,51.044504713561,53.047805656273,50.092440899202,53.018053662074,14923803.0
+2017-10-31,52.26,52.49,50.02,51.01,28432806.0,0.0,1.0,51.827973894126,52.056072516316,49.606491660624,50.588307469181,28432806.0
+2017-10-30,54.16,54.77,54.08,54.66,6986348.0,0.0,1.0,53.712266860044,54.317224075417,53.632928208847,54.208133430022,6986348.0
+2017-10-27,53.7,54.7,53.36,54.57,8637328.0,0.0,1.0,53.256069615664,54.24780275562,52.918880348078,54.118877447426,8637328.0
+2017-10-26,54.1,54.39,53.665,53.8,5227877.0,0.0,1.0,53.652762871646,53.940365482234,53.221358955765,53.355242929659,5227877.0
+2017-10-25,53.98,54.43,53.475,53.84,7352176.0,0.0,1.0,53.533754894851,53.980034807832,53.032929659173,53.394912255257,7352176.0
+2017-10-24,53.44,54.44,53.4,54.25,10450810.0,0.0,1.0,52.998218999275,53.989952139231,52.958549673677,53.80152284264,10450810.0
+2017-10-23,52.3,53.78,52.13,53.39,9698032.0,0.0,1.0,51.867643219724,53.33540826686,51.699048585932,52.948632342277,9698032.0
+2017-10-20,52.51,52.59,51.94,52.02,8405771.0,0.0,1.0,52.075907179115,52.155245830312,51.51061928934,51.589957940537,8405771.0
+2017-10-19,52.03,52.4,52.01,52.29,6657536.0,0.0,1.0,51.599875271936,51.96681653372,51.580040609137,51.857725888325,6657536.0
+2017-10-18,52.54,52.67,52.02,52.21,5928735.0,0.0,1.0,52.105659173314,52.234584481508,51.589957940537,51.778387237128,5928735.0
+2017-10-17,52.32,52.44,51.8501,52.41,7456659.0,0.0,1.0,51.887477882524,52.006485859318,51.421462480058,51.97673386512,7456659.0
+2017-10-16,52.98,53.0,52.3101,52.38,5749880.0,0.0,1.0,52.542021754895,52.561856417694,51.877659724438,51.946981870921,5749880.0
+2017-10-13,53.38,53.38,52.74,52.82,6293816.0,0.0,1.0,52.938715010877,52.938715010877,52.304005801305,52.383344452502,6293816.0
+2017-10-12,53.88,54.175,52.96,53.0,7000530.0,0.0,1.0,53.434581580856,53.727142857143,52.522187092096,52.561856417694,7000530.0
+2017-10-11,53.79,54.38,53.66,54.12,8679167.0,0.0,1.0,53.34532559826,53.930448150834,53.216400290065,53.672597534445,8679167.0
+2017-10-10,52.95,53.9,52.9,53.87,8701455.0,0.0,1.0,52.512269760696,53.454416243655,52.462683103698,53.424664249456,8701455.0
+2017-10-09,52.68,52.9799,52.38,52.88,5803730.0,0.0,1.0,52.244501812908,52.541922581581,51.946981870921,52.442848440899,5803730.0
+2017-10-06,52.16,52.63,52.16,52.49,4780961.0,0.0,1.0,51.728800580131,52.19491515591,51.728800580131,52.056072516316,4780961.0
+2017-10-05,52.17,52.43,51.96,52.35,5144244.0,0.0,1.0,51.73871791153,51.996568527919,51.530453952139,51.917229876722,5144244.0
+2017-10-04,51.93,52.12,51.67,51.96,4521452.0,0.0,1.0,51.500701957941,51.689131254532,51.242851341552,51.530453952139,4521452.0
+2017-10-03,51.99,52.22,51.65,52.02,4176210.0,0.0,1.0,51.560205946338,51.788304568528,51.223016678753,51.589957940537,4176210.0
+2017-10-02,52.09,52.16,51.7,51.88,4363679.0,0.0,1.0,51.659379260334,51.728800580131,51.272603335751,51.451115300943,4363679.0
+2017-09-29,51.91,52.0447,51.62,51.84,5159612.0,0.0,1.0,51.480867295141,51.614453749094,51.193264684554,51.411445975344,5159612.0
+2017-09-28,51.38,52.04,51.31,51.75,5671994.0,0.0,1.0,50.955248730964,51.609792603336,50.885827411168,51.322189992748,5671994.0
+2017-09-27,51.43,51.61,51.1526,51.55,8122353.0,0.0,1.0,51.004835387962,51.183347353154,50.729728614938,51.123843364757,8122353.0
+2017-09-26,51.75,51.87,50.85,51.13,9148913.0,0.0,1.0,51.322189992748,51.441197969543,50.429630166788,50.707315445975,9148913.0
+2017-09-25,51.9,52.285,51.61,51.63,7931316.0,0.0,1.0,51.470949963742,51.852767222625,51.183347353154,51.203182015954,7931316.0
+2017-09-22,51.82,52.23,51.78,52.09,4077699.0,0.0,1.0,51.391611312545,51.798221899927,51.351941986947,51.659379260334,4077699.0
+2017-09-21,51.86,52.2,51.71,52.03,5192113.0,0.0,1.0,51.431280638144,51.768469905729,51.28252066715,51.599875271936,5192113.0
+2017-09-20,52.43,52.52,51.48,51.98,8273935.0,0.0,1.0,51.996568527919,52.085824510515,51.05442204496,51.550288614938,8273935.0
+2017-09-19,52.4,52.5,52.06,52.3,4897549.0,0.0,1.0,51.96681653372,52.065989847716,51.629627266135,51.867643219724,4897549.0
+2017-09-18,52.24,52.37,51.955,52.25,5951635.0,0.0,1.0,51.808139231327,51.937064539521,51.525495286439,51.818056562727,5951635.0
+2017-09-15,51.95,52.29,51.44,52.19,12717688.0,0.0,1.0,51.52053662074,51.857725888325,51.014752719362,51.758552574329,12717688.0
+2017-09-14,50.97,51.59,50.67,51.48,7677860.0,0.0,1.0,50.548638143582,51.163512690355,50.251118201595,51.05442204496,7677860.0
+2017-09-13,50.8,51.1054,50.72,51.01,6147412.0,0.0,1.0,50.38004350979,50.682918810732,50.300704858593,50.588307469181,6147412.0
+2017-09-12,50.6,51.07,50.52,50.9,4444021.0,0.0,1.0,50.181696881798,50.647811457578,50.102358230602,50.479216823785,4444021.0
+2017-09-11,49.94,50.67,49.91,50.57,7137370.0,0.0,1.0,49.527153009427,50.251118201595,49.497401015228,50.1519448876,7137370.0
+2017-09-08,50.35,50.45,48.92,49.64,12445202.0,0.0,1.0,49.933763596809,50.032936910805,48.515585206672,49.22963306744,12445202.0
+2017-09-07,50.56,50.69,50.25,50.38,8214389.0,0.0,1.0,50.1420275562,50.270952864394,49.834590282814,49.963515591008,8214389.0
+2017-09-06,50.19,50.77,49.83,50.45,16009190.0,0.0,1.0,49.775086294416,50.350291515591,49.418062364032,50.032936910805,16009190.0
+2017-09-05,51.86,51.9,49.83,50.03,17850640.0,0.0,1.0,51.431280638144,51.470949963742,49.418062364032,49.616408992023,17850640.0
+2017-09-01,52.53,52.77,51.925,52.05,5250026.0,0.0,1.0,52.095741841914,52.333757795504,51.495743292241,51.619709934735,5250026.0
+2017-08-31,52.26,52.59,52.12,52.27,7907278.0,0.0,1.0,51.827973894126,52.155245830312,51.689131254532,51.837891225526,7907278.0
+2017-08-30,51.75,52.286,51.56,52.12,4806103.0,0.0,1.0,51.322189992748,51.853758955765,51.133760696157,51.689131254532,4806103.0
+2017-08-29,51.31,51.86,51.28,51.81,4896218.0,0.0,1.0,50.885827411168,51.431280638144,50.856075416969,51.381693981146,4896218.0
+2017-08-28,51.77,51.81,51.46,51.81,4441742.0,0.57,1.0,51.342024655548,51.381693981146,51.034587382161,51.381693981146,4441742.0
+2017-08-25,52.78,52.8545,52.02,52.03,8502179.0,0.0,1.0,51.774070414755,51.847150525515,51.028555190897,51.038364601738,8502179.0
+2017-08-24,52.37,52.71,52.26,52.49,5972821.0,0.0,1.0,51.371884570306,51.705404538873,51.263981051063,51.489597500388,5972821.0
+2017-08-23,52.3,52.405,51.78,52.23,5046782.0,0.0,1.0,51.303218694424,51.406217508246,50.793129330732,51.234552818542,5046782.0
+2017-08-22,52.21,52.62,52.21,52.35,4350136.0,0.0,1.0,51.214933996862,51.617119841311,51.214933996862,51.352265748625,4350136.0
+2017-08-21,52.0,52.08,51.5,51.98,5185851.0,0.0,1.0,51.008936369217,51.087411655939,50.518465827205,50.989317547536,5185851.0
+2017-08-18,52.26,52.415,51.9,51.92,6642109.0,0.0,1.0,51.263981051063,51.416026919087,50.910842260815,50.930461082495,6642109.0
+2017-08-17,53.19,53.41,52.27,52.27,6087867.0,0.0,1.0,52.176256259205,52.39206329769,51.273790461903,51.273790461903,6087867.0
+2017-08-16,54.06,54.1,53.255,53.31,7034292.0,0.0,1.0,53.029675002305,53.068912645666,52.240017429666,52.293969189288,7034292.0
+2017-08-15,53.66,54.08,53.35,53.87,7562385.0,0.0,1.0,52.637298568696,53.049293823986,52.333206832648,52.843296196341,7562385.0
+2017-08-14,53.04,53.64,52.91,53.55,7558235.0,0.0,1.0,52.029115096601,52.617679747015,51.901592755678,52.529395049453,7558235.0
+2017-08-11,52.39,53.13,52.29,52.72,5835863.0,0.0,1.0,51.391503391986,52.117399794163,51.293409283584,51.715213949714,5835863.0
+2017-08-10,52.54,52.75,52.11,52.34,9578948.0,0.0,1.0,51.53864455459,51.744642182234,51.116839888459,51.342456337785,9578948.0
+2017-08-09,52.05,52.8,52.0,52.77,7039352.0,0.0,1.0,51.057983423418,51.793689236436,51.008936369217,51.764261003915,7039352.0
+2017-08-08,52.55,53.33,52.21,52.29,8779415.0,0.0,1.0,51.54845396543,52.313588010968,51.214933996862,51.293409283584,8779415.0
+2017-08-04,53.0,53.0,52.51,52.62,8645879.0,0.0,1.0,51.98987745324,51.98987745324,51.509216322069,51.617119841311,8645879.0
+2017-08-03,53.16,53.3399,52.75,52.95,8481098.0,0.0,1.0,52.146828026684,52.3232993277,51.744642182234,51.940830399039,8481098.0
+2017-08-02,53.295,53.3885,52.78,53.17,19324507.0,0.0,1.0,52.279255073027,52.370973064383,51.774070414755,52.156637437524,19324507.0
+2017-08-01,53.3,53.43,52.91,53.41,7480549.0,0.0,1.0,52.284159778447,52.41168211937,51.901592755678,52.39206329769,7480549.0
+2017-07-31,53.1,53.295,52.75,53.19,10641489.0,0.0,1.0,52.087971561643,52.279255073027,51.744642182234,52.176256259205,10641489.0
+2017-07-28,52.27,52.9865,52.27,52.88,6534345.0,0.0,1.0,51.273790461903,51.976634748606,51.273790461903,51.872164523157,6534345.0
+2017-07-27,53.08,53.37,52.23,52.49,13964311.0,0.0,1.0,52.068352739962,52.352825654329,51.234552818542,51.489597500388,13964311.0
+2017-07-26,53.29,53.35,52.74,53.14,7492633.0,0.0,1.0,52.274350367607,52.333206832648,51.734832771394,52.127209205004,7492633.0
+2017-07-25,53.2,53.65,53.07,53.27,7060158.0,0.0,1.0,52.186065670045,52.627489157855,52.058543329122,52.254731545927,7060158.0
+2017-07-24,53.75,53.88,53.09,53.22,8739769.0,0.0,1.0,52.725583266258,52.853105607181,52.078162150802,52.205684491725,8739769.0
+2017-07-21,53.66,54.0,53.37,53.84,11963407.0,0.0,1.0,52.637298568696,52.970818537264,52.352825654329,52.81386796382,11963407.0
+2017-07-20,55.11,55.43,53.46,53.97,35647961.0,0.0,1.0,54.05966314053,54.373564287417,52.441110351891,52.941390304743,35647961.0
+2017-07-19,56.46,56.9399,56.01,56.78,7437353.0,0.0,1.0,55.383933603961,55.854687230184,54.942510116151,55.697834750849,7437353.0
+2017-07-18,56.34,56.38,56.0,56.29,7329551.0,0.0,1.0,55.266220673878,55.305458317239,54.93270070531,55.217173619677,7329551.0
+2017-07-17,56.73,56.92,56.39,56.45,5067322.0,0.0,1.0,55.648787696648,55.835166502612,55.31526772808,55.374124193121,5067322.0
+2017-07-14,56.5,56.93,56.15,56.81,4365609.0,0.0,1.0,55.423171247322,55.844975913452,55.079841867914,55.727262983369,4365609.0
+2017-07-13,56.38,56.52,56.17,56.23,5884064.0,0.0,1.0,55.305458317239,55.442790069003,55.099460689594,55.158317154636,5884064.0
+2017-07-12,55.79,56.31,55.72,56.2,6082481.0,0.0,1.0,54.726703077666,55.236792441358,54.658037201784,55.128888922115,6082481.0
+2017-07-11,55.63,55.63,55.02,55.33,6009448.0,0.0,1.0,54.569752504222,54.569752504222,53.971378442968,54.275470179015,6009448.0
+2017-07-10,55.37,55.885,55.19,55.64,4973557.0,0.0,1.0,54.314707822376,54.819892480648,54.138138427252,54.579561915062,4973557.0
+2017-07-07,55.04,55.73,54.87,55.35,5156330.0,0.0,1.0,53.990997264648,54.667846612624,53.824237280364,54.295089000695,5156330.0
+2017-07-06,55.02,55.23,54.735,54.79,5557013.0,0.0,1.0,53.971378442968,54.177376070612,53.691810234021,53.745761993642,5557013.0
+2017-07-05,55.01,55.56,54.78,55.45,6624023.0,0.0,1.0,53.961569032127,54.50108662834,53.735952582802,54.393183109098,6624023.0
+2017-07-03,55.53,56.02,54.92,54.95,4379566.0,0.0,1.0,54.471658395819,54.952319526991,53.873284334565,53.902712567086,4379566.0
+2017-06-30,55.6,55.63,55.03,55.22,8596198.0,0.0,1.0,54.540324271701,54.569752504222,53.981187853808,54.167566659772,8596198.0
+2017-06-29,55.93,55.93,54.55,55.08,8333137.0,0.0,1.0,54.864034829429,54.864034829429,53.510336133477,54.030234908009,8333137.0
+2017-06-28,55.4,56.32,55.18,56.16,7231216.0,0.0,1.0,54.344136054896,55.246601852198,54.128329016411,55.089651278754,7231216.0
+2017-06-27,56.29,56.33,55.41,55.43,6734074.0,0.0,1.0,55.217173619677,55.256411263038,54.353945465737,54.373564287417,6734074.0
+2017-06-26,57.09,57.6892,56.21,56.56,7255489.0,0.0,1.0,56.001926486896,56.589706384443,55.138698332955,55.482027712364,7255489.0
+2017-06-23,56.64,57.4365,56.57,56.91,8660612.0,0.0,1.0,55.560502999085,56.34182257251,55.491837123204,55.825357091772,8660612.0
+2017-06-22,56.24,56.745,56.06,56.47,5512097.0,0.0,1.0,55.168126565476,55.663501812908,54.991557170352,55.393743014801,5512097.0
+2017-06-21,56.79,56.84,56.12,56.33,8189893.0,0.0,1.0,55.707644161689,55.75669121589,55.050413635393,55.256411263038,8189893.0
+2017-06-20,57.46,57.61,56.51,56.79,8087133.0,0.0,1.0,56.364874687985,56.512015850588,55.432980658162,55.707644161689,8087133.0
+2017-06-19,56.96,57.66,56.91,57.61,6909034.0,0.0,1.0,55.874404145973,56.561062904789,55.825357091772,56.512015850588,6909034.0
+2017-06-16,56.98,57.01,56.35,56.82,13536039.0,0.0,1.0,55.894022967653,55.923451200174,55.276030084719,55.73707239421,13536039.0
+2017-06-15,56.42,57.17,56.4,56.93,5371464.0,0.0,1.0,55.3446959606,56.080401773618,55.32507713892,55.844975913452,5371464.0
+2017-06-14,57.7,57.97,56.67,57.01,6702810.0,0.0,1.0,56.60030054815,56.865154640837,55.589931231606,55.923451200174,6702810.0
+2017-06-13,57.95,58.065,57.5,57.54,6971106.0,0.0,1.0,56.845535819156,56.958344043819,56.404112331346,56.443349974707,6971106.0
+2017-06-12,56.52,57.675,56.48,57.49,9871291.0,0.0,1.0,55.442790069003,56.57577702105,55.403552425642,56.394302920505,9871291.0
+2017-06-09,58.37,58.49,56.74,57.05,13572264.0,0.0,1.0,57.257531074446,57.375244004529,55.658597107488,55.962688843535,13572264.0
+2017-06-08,57.77,58.15,57.61,58.12,10134415.0,0.0,1.0,56.668966424032,57.041724035961,56.512015850588,57.01229580344,10134415.0
+2017-06-07,58.3,58.49,57.13,57.53,9967746.0,0.0,1.0,57.188865198564,57.375244004529,56.041164130257,56.433540563866,9967746.0
+2017-06-06,58.6,58.91,58.18,58.2,7808482.0,0.0,1.0,57.483147523771,57.787239259819,57.071152268481,57.090771090162,7808482.0
+2017-06-05,58.5,59.05,58.48,58.85,7655063.0,0.0,1.0,57.385053415369,57.924571011582,57.365434593689,57.728382794777,7655063.0
+2017-06-02,58.89,58.96,58.35,58.58,9461824.0,0.0,1.0,57.767620438138,57.83628631402,57.237912252765,57.463528702091,9461824.0
+2017-06-01,57.45,58.65,57.35,58.62,11116224.0,0.0,1.0,56.355065277144,57.532194577972,56.256971168742,57.502766345452,11116224.0
diff --git a/examples/quick/demos/stocqt/content/data/TSLA.csv b/examples/quick/demos/stocqt/content/data/TSLA.csv
new file mode 100644
index 0000000000..c1343441d8
--- /dev/null
+++ b/examples/quick/demos/stocqt/content/data/TSLA.csv
@@ -0,0 +1,148 @@
+Date,Open,High,Low,Close,Volume,Ex-Dividend,Split Ratio,Adj. Open,Adj. High,Adj. Low,Adj. Close,Adj. Volume
+2017-12-29,316.18,316.41,310.0,311.35,3727621.0,0.0,1.0,316.18,316.41,310.0,311.35,3727621.0
+2017-12-28,311.75,315.82,309.54,315.36,4294689.0,0.0,1.0,311.75,315.82,309.54,315.36,4294689.0
+2017-12-27,316.0,317.68,310.75,311.64,4645441.0,0.0,1.0,316.0,317.68,310.75,311.64,4645441.0
+2017-12-26,323.83,323.94,316.58,317.29,4321909.0,0.0,1.0,323.83,323.94,316.58,317.29,4321909.0
+2017-12-22,329.51,330.9214,324.82,325.2,4186131.0,0.0,1.0,329.51,330.9214,324.82,325.2,4186131.0
+2017-12-21,329.59,333.74,327.21,331.66,4344701.0,0.0,1.0,329.59,333.74,327.21,331.66,4344701.0
+2017-12-20,332.69,333.1,325.04,328.98,5937684.0,0.0,1.0,332.69,333.1,325.04,328.98,5937684.0
+2017-12-19,340.26,341.4925,330.3,331.1,6792009.0,0.0,1.0,340.26,341.4925,330.3,331.1,6792009.0
+2017-12-18,344.9,346.73,337.58,338.87,5441450.0,0.0,1.0,344.9,346.73,337.58,338.87,5441450.0
+2017-12-15,342.04,343.9,335.76,343.45,6832071.0,0.0,1.0,342.04,343.9,335.76,343.45,6832071.0
+2017-12-14,341.01,347.44,336.9,337.89,5744750.0,0.0,1.0,341.01,347.44,336.9,337.89,5744750.0
+2017-12-13,340.93,344.22,336.5,339.03,6189204.0,0.0,1.0,340.93,344.22,336.5,339.03,6189204.0
+2017-12-12,330.45,341.44,330.03,341.03,8648534.0,0.0,1.0,330.45,341.44,330.03,341.03,8648534.0
+2017-12-11,314.63,329.01,313.75,328.91,7867288.0,0.0,1.0,314.63,329.01,313.75,328.91,7867288.0
+2017-12-08,314.6,316.98,311.26,315.13,3442898.0,0.0,1.0,314.6,316.98,311.26,315.13,3442898.0
+2017-12-07,312.0,318.6341,311.05,311.24,4705140.0,0.0,1.0,312.0,318.6341,311.05,311.24,4705140.0
+2017-12-06,300.1,313.39,300.0,313.26,7160938.0,0.0,1.0,300.1,313.39,300.0,313.26,7160938.0
+2017-12-05,302.0,308.0,301.0,303.7,4628462.0,0.0,1.0,302.0,308.0,301.0,303.7,4628462.0
+2017-12-04,306.5,308.265,300.61,305.2,5811205.0,0.0,1.0,306.5,308.265,300.61,305.2,5811205.0
+2017-12-01,305.44,310.32,305.05,306.53,4256030.0,0.0,1.0,305.44,310.32,305.05,306.53,4256030.0
+2017-11-30,308.56,310.7,304.54,308.85,4288221.0,0.0,1.0,308.56,310.7,304.54,308.85,4288221.0
+2017-11-29,317.3,318.0,301.23,307.54,8732941.0,0.0,1.0,317.3,318.0,301.23,307.54,8732941.0
+2017-11-28,316.36,320.0,313.92,317.55,4916555.0,0.0,1.0,316.36,320.0,313.92,317.55,4916555.0
+2017-11-27,313.25,317.34,309.51,316.81,4524921.0,0.0,1.0,313.25,317.34,309.51,316.81,4524921.0
+2017-11-24,313.79,316.41,311.0,315.55,3242220.0,0.0,1.0,313.79,316.41,311.0,315.55,3242220.0
+2017-11-22,316.77,317.42,311.84,312.6,4890091.0,0.0,1.0,316.77,317.42,311.84,312.6,4890091.0
+2017-11-21,310.86,318.23,308.71,317.81,7230570.0,0.0,1.0,310.86,318.23,308.71,317.81,7230570.0
+2017-11-20,313.79,315.5,304.75,308.74,8220759.0,0.0,1.0,313.79,315.5,304.75,308.74,8220759.0
+2017-11-17,325.67,326.67,313.15,315.05,13682753.0,0.0,1.0,325.67,326.67,313.15,315.05,13682753.0
+2017-11-16,313.99,318.14,311.3,312.5,5757709.0,0.0,1.0,313.99,318.14,311.3,312.5,5757709.0
+2017-11-15,306.01,312.49,301.5,311.3,5909055.0,0.0,1.0,306.01,312.49,301.5,311.3,5909055.0
+2017-11-14,315.0,316.35,306.9,308.7,5641615.0,0.0,1.0,315.0,316.35,306.9,308.7,5641615.0
+2017-11-13,300.13,316.8,299.11,315.4,7536669.0,0.0,1.0,300.13,316.8,299.11,315.4,7536669.0
+2017-11-10,302.5,308.36,301.85,302.99,4600097.0,0.0,1.0,302.5,308.36,301.85,302.99,4600097.0
+2017-11-09,302.5,304.46,296.3,302.99,5419497.0,0.0,1.0,302.5,304.46,296.3,302.99,5419497.0
+2017-11-07,301.02,306.5,300.03,306.05,5209573.0,0.0,1.0,301.02,306.5,300.03,306.05,5209573.0
+2017-11-06,307.0,307.5,299.01,302.78,6463227.0,0.0,1.0,307.0,307.5,299.01,302.78,6463227.0
+2017-11-03,299.5,306.25,295.13,306.09,8835157.0,0.0,1.0,299.5,306.25,295.13,306.09,8835157.0
+2017-11-02,300.13,308.69,292.63,299.26,19731322.0,0.0,1.0,300.13,308.69,292.63,299.26,19731322.0
+2017-11-01,332.25,332.6089,320.26,321.08,7028856.0,0.0,1.0,332.25,332.6089,320.26,321.08,7028856.0
+2017-10-31,320.23,331.95,320.18,331.53,5532647.0,0.0,1.0,320.23,331.95,320.18,331.53,5532647.0
+2017-10-30,319.18,323.78,317.25,320.08,4236029.0,0.0,1.0,319.18,323.78,317.25,320.08,4236029.0
+2017-10-27,319.75,324.59,316.66,320.87,6942493.0,0.0,1.0,319.75,324.59,316.66,320.87,6942493.0
+2017-10-26,327.78,330.23,323.2,326.17,4980316.0,0.0,1.0,327.78,330.23,323.2,326.17,4980316.0
+2017-10-25,336.7,337.5,323.56,325.84,8547764.0,0.0,1.0,336.7,337.5,323.56,325.84,8547764.0
+2017-10-24,338.8,342.8,336.16,337.34,4463807.0,0.0,1.0,338.8,342.8,336.16,337.34,4463807.0
+2017-10-23,349.88,349.95,336.25,337.02,5715817.0,0.0,1.0,349.88,349.95,336.25,337.02,5715817.0
+2017-10-20,352.69,354.55,344.34,345.1,4888221.0,0.0,1.0,352.69,354.55,344.34,345.1,4888221.0
+2017-10-19,355.56,357.1465,348.2,351.81,5032884.0,0.0,1.0,355.56,357.1465,348.2,351.81,5032884.0
+2017-10-18,355.97,363.0,354.13,359.65,4898808.0,0.0,1.0,355.97,363.0,354.13,359.65,4898808.0
+2017-10-17,350.91,356.22,350.07,355.75,3280670.0,0.0,1.0,350.91,356.22,350.07,355.75,3280670.0
+2017-10-16,353.76,354.48,347.16,350.6,5353262.0,0.0,1.0,353.76,354.48,347.16,350.6,5353262.0
+2017-10-13,356.98,358.49,353.68,355.57,3528413.0,0.0,1.0,356.98,358.49,353.68,355.57,3528413.0
+2017-10-12,352.95,359.78,352.64,355.68,4047318.0,0.0,1.0,352.95,359.78,352.64,355.68,4047318.0
+2017-10-11,353.89,357.6,351.15,354.6,4476769.0,0.0,1.0,353.89,357.6,351.15,354.6,4476769.0
+2017-10-10,346.8,355.63,345.5305,355.59,6914972.0,0.0,1.0,346.8,355.63,345.5305,355.59,6914972.0
+2017-10-09,349.65,351.75,342.67,342.94,7406324.0,0.0,1.0,349.65,351.75,342.67,342.94,7406324.0
+2017-10-06,353.1,360.0992,352.25,356.88,4171789.0,0.0,1.0,353.1,360.0992,352.25,356.88,4171789.0
+2017-10-05,356.0,357.435,351.35,355.33,4102286.0,0.0,1.0,356.0,357.435,351.35,355.33,4102286.0
+2017-10-04,351.25,358.62,349.6,355.01,8120353.0,0.0,1.0,351.25,358.62,349.6,355.01,8120353.0
+2017-10-03,335.9,348.55,331.28,348.14,9981885.0,0.0,1.0,335.9,348.55,331.28,348.14,9981885.0
+2017-10-02,342.52,343.7,335.51,341.53,4901453.0,0.0,1.0,342.52,343.7,335.51,341.53,4901453.0
+2017-09-29,341.86,344.68,338.601,341.1,5062297.0,0.0,1.0,341.86,344.68,338.601,341.1,5062297.0
+2017-09-28,339.88,342.75,335.4,339.6,5279310.0,0.0,1.0,339.88,342.75,335.4,339.6,5279310.0
+2017-09-27,349.9,351.489,340.5,340.97,6010631.0,0.0,1.0,349.9,351.489,340.5,340.97,6010631.0
+2017-09-26,350.93,351.24,340.9,345.25,7126550.0,0.0,1.0,350.93,351.24,340.9,345.25,7126550.0
+2017-09-25,353.15,357.469,342.88,344.99,7542161.0,0.0,1.0,353.15,357.469,342.88,344.99,7542161.0
+2017-09-22,366.49,369.8999,350.88,351.09,8105653.0,0.0,1.0,366.49,369.8999,350.88,351.09,8105653.0
+2017-09-21,374.9,376.83,364.51,366.48,4605428.0,0.0,1.0,374.9,376.83,364.51,366.48,4605428.0
+2017-09-20,373.0,378.249,371.07,373.91,4892872.0,0.0,1.0,373.0,378.249,371.07,373.91,4892872.0
+2017-09-19,380.0,382.39,373.57,375.1,6256035.0,0.0,1.0,380.0,382.39,373.57,375.1,6256035.0
+2017-09-18,380.25,389.61,377.68,385.0,7149295.0,0.0,1.0,380.25,389.61,377.68,385.0,7149295.0
+2017-09-15,374.51,380.0,372.7,379.81,5338678.0,0.0,1.0,374.51,380.0,372.7,379.81,5338678.0
+2017-09-14,364.33,377.96,362.63,377.64,7141663.0,0.0,1.0,364.33,377.96,362.63,377.64,7141663.0
+2017-09-13,363.82,368.07,359.59,366.23,4161382.0,0.0,1.0,363.82,368.07,359.59,366.23,4161382.0
+2017-09-12,364.49,368.76,360.4,362.75,5929289.0,0.0,1.0,364.49,368.76,360.4,362.75,5929289.0
+2017-09-11,351.35,363.71,350.0,363.69,7610309.0,0.0,1.0,351.35,363.71,350.0,363.69,7610309.0
+2017-09-08,348.99,349.78,342.3,343.4,3248803.0,0.0,1.0,348.99,349.78,342.3,343.4,3248803.0
+2017-09-07,345.98,352.48,343.45,350.61,4219997.0,0.0,1.0,345.98,352.48,343.45,350.61,4219997.0
+2017-09-06,349.5,350.979,341.56,344.53,4058983.0,0.0,1.0,349.5,350.979,341.56,344.53,4058983.0
+2017-09-05,353.8,355.49,345.89,349.59,3813862.0,0.0,1.0,353.8,355.49,345.89,349.59,3813862.0
+2017-09-01,356.12,357.59,353.6902,355.4,3028578.0,0.0,1.0,356.12,357.59,353.6902,355.4,3028578.0
+2017-08-31,353.55,358.44,352.82,355.9,4019065.0,0.0,1.0,353.55,358.44,352.82,355.9,4019065.0
+2017-08-30,349.67,353.47,347.0,353.18,3390055.0,0.0,1.0,349.67,353.47,347.0,353.18,3390055.0
+2017-08-29,339.48,349.05,338.75,347.36,4032825.0,0.0,1.0,339.48,349.05,338.75,347.36,4032825.0
+2017-08-28,347.28,347.35,339.72,345.66,3718108.0,0.0,1.0,347.28,347.35,339.72,345.66,3718108.0
+2017-08-25,354.24,355.69,347.3,348.05,3461744.0,0.0,1.0,354.24,355.69,347.3,348.05,3461744.0
+2017-08-24,352.52,356.66,349.74,352.93,4540652.0,0.0,1.0,352.52,356.66,349.74,352.93,4540652.0
+2017-08-23,338.99,353.49,338.3041,352.77,4914201.0,0.0,1.0,338.99,353.49,338.3041,352.77,4914201.0
+2017-08-22,341.13,342.24,337.3725,341.35,4288367.0,0.0,1.0,341.13,342.24,337.3725,341.35,4288367.0
+2017-08-21,345.82,345.82,331.85,337.86,6458812.0,0.0,1.0,345.82,345.82,331.85,337.86,6458812.0
+2017-08-18,352.91,354.0,345.8,347.46,5335793.0,0.0,1.0,352.91,354.0,345.8,347.46,5335793.0
+2017-08-17,361.21,363.3,351.59,351.92,4969222.0,0.0,1.0,361.21,363.3,351.59,351.92,4969222.0
+2017-08-16,363.0,366.5,362.52,362.91,3328576.0,0.0,1.0,363.0,366.5,362.52,362.91,3328576.0
+2017-08-15,365.2,365.49,359.37,362.33,3048074.0,0.0,1.0,365.2,365.49,359.37,362.33,3048074.0
+2017-08-14,364.63,367.66,362.6,363.8,4461215.0,0.0,1.0,364.63,367.66,362.6,363.8,4461215.0
+2017-08-11,356.97,361.26,353.62,357.715,4318835.0,0.0,1.0,356.97,361.26,353.62,357.715,4318835.0
+2017-08-10,361.6,366.6504,354.66,355.13,7035192.0,0.0,1.0,361.6,366.6504,354.66,355.13,7035192.0
+2017-08-09,361.0,370.0,358.95,363.525,6847245.0,0.0,1.0,361.0,370.0,358.95,363.525,6847245.0
+2017-08-08,357.53,368.58,357.4,365.22,7363033.0,0.0,1.0,357.53,368.58,357.4,365.22,7363033.0
+2017-08-07,357.35,359.48,352.75,355.17,6265570.0,0.0,1.0,357.35,359.48,352.75,355.17,6265570.0
+2017-08-04,347.0,357.27,343.3,356.91,9151520.0,0.0,1.0,347.0,357.27,343.3,356.91,9151520.0
+2017-08-03,345.33,350.0,343.15,347.09,13448583.0,0.0,1.0,345.33,350.0,343.15,347.09,13448583.0
+2017-08-02,318.94,327.12,311.22,325.89,9911432.0,0.0,1.0,318.94,327.12,311.22,325.89,9911432.0
+2017-08-01,323.0,324.45,316.13,319.57,8247544.0,0.0,1.0,323.0,324.45,316.13,319.57,8247544.0
+2017-07-31,335.5,341.49,321.04,323.47,8499335.0,0.0,1.0,335.5,341.49,321.04,323.47,8499335.0
+2017-07-28,336.89,339.6,332.51,335.07,4841257.0,0.0,1.0,336.89,339.6,332.51,335.07,4841257.0
+2017-07-27,346.0,347.5,326.29,334.46,8259202.0,0.0,1.0,346.0,347.5,326.29,334.46,8259202.0
+2017-07-26,340.36,345.5,338.12,343.85,4750198.0,0.0,1.0,340.36,345.5,338.12,343.85,4750198.0
+2017-07-25,345.0,345.6,334.15,339.6,6958889.0,0.0,1.0,345.0,345.6,334.15,339.6,6958889.0
+2017-07-24,330.24,343.399,330.01,342.52,8552012.0,0.0,1.0,330.24,343.399,330.01,342.52,8552012.0
+2017-07-21,329.46,331.2575,325.8,328.4,4826383.0,0.0,1.0,329.46,331.2575,325.8,328.4,4826383.0
+2017-07-20,326.9,330.22,324.2,329.92,5098707.0,0.0,1.0,326.9,330.22,324.2,329.92,5098707.0
+2017-07-19,328.23,331.65,323.2193,325.26,6300735.0,0.0,1.0,328.23,331.65,323.2193,325.26,6300735.0
+2017-07-18,317.5,329.13,315.66,328.24,6326961.0,0.0,1.0,317.5,329.13,315.66,328.24,6326961.0
+2017-07-17,325.54,327.1,313.45,319.57,9784200.0,0.0,1.0,325.54,327.1,313.45,319.57,9784200.0
+2017-07-14,323.19,328.42,321.22,327.78,5590393.0,0.0,1.0,323.19,328.42,321.22,327.78,5590393.0
+2017-07-13,330.11,331.6,319.97,323.41,8540442.0,0.0,1.0,330.11,331.6,319.97,323.41,8540442.0
+2017-07-12,330.4,333.1,324.5,329.52,10297839.0,0.0,1.0,330.4,333.1,324.5,329.52,10297839.0
+2017-07-11,316.0,327.28,314.3,327.22,11400054.0,0.0,1.0,316.0,327.28,314.3,327.22,11400054.0
+2017-07-10,312.9,317.94,303.13,316.05,13702080.0,0.0,1.0,312.9,317.94,303.13,316.05,13702080.0
+2017-07-07,313.5,317.0,307.38,313.22,14053750.0,0.0,1.0,313.5,317.0,307.38,313.22,14053750.0
+2017-07-06,317.26,320.7899,306.3,308.89,19189195.0,0.0,1.0,317.26,320.7899,306.3,308.89,19189195.0
+2017-07-05,347.2,347.24,326.33,327.09,16883496.0,0.0,1.0,347.2,347.24,326.33,327.09,16883496.0
+2017-07-03,370.24,371.35,351.5,352.62,6297330.0,0.0,1.0,370.24,371.35,351.5,352.62,6297330.0
+2017-06-30,363.71,366.7674,359.6187,361.61,5759458.0,0.0,1.0,363.71,366.7674,359.6187,361.61,5759458.0
+2017-06-29,370.61,371.0,354.1,360.75,8180408.0,0.0,1.0,370.61,371.0,354.1,360.75,8180408.0
+2017-06-28,366.68,371.74,362.52,371.24,6245040.0,0.0,1.0,366.68,371.74,362.52,371.24,6245040.0
+2017-06-27,376.4,376.4,362.02,362.37,6884529.0,0.0,1.0,376.4,376.4,362.02,362.37,6884529.0
+2017-06-26,386.69,386.95,373.1,377.49,6575285.0,0.0,1.0,386.69,386.95,373.1,377.49,6575285.0
+2017-06-23,382.45,386.99,379.345,383.45,6176578.0,0.0,1.0,382.45,386.99,379.345,383.45,6176578.0
+2017-06-22,377.99,385.0,373.57,382.61,7485677.0,0.0,1.0,377.99,385.0,373.57,382.61,7485677.0
+2017-06-21,374.35,376.99,368.02,376.4,4900356.0,0.0,1.0,374.35,376.99,368.02,376.4,4900356.0
+2017-06-20,376.67,378.88,369.73,372.24,7396357.0,0.0,1.0,376.67,378.88,369.73,372.24,7396357.0
+2017-06-19,375.0,376.7,367.8,369.8,6392331.0,0.0,1.0,375.0,376.7,367.8,369.8,6392331.0
+2017-06-16,377.975,378.01,370.1,371.4,6259666.0,0.0,1.0,377.975,378.01,370.1,371.4,6259666.0
+2017-06-15,372.5,375.46,366.49,375.34,10371559.0,0.0,1.0,372.5,375.46,366.49,375.34,10371559.0
+2017-06-14,381.085,384.25,376.31,380.66,12731997.0,0.0,1.0,381.085,384.25,376.31,380.66,12731997.0
+2017-06-13,367.62,376.0,366.61,375.95,11693404.0,0.0,1.0,367.62,376.0,366.61,375.95,11693404.0
+2017-06-12,357.99,364.5,350.62,359.01,10476833.0,0.0,1.0,357.99,364.5,350.62,359.01,10476833.0
+2017-06-09,374.42,376.87,354.8,357.32,17160231.0,0.0,1.0,374.42,376.87,354.8,357.32,17160231.0
+2017-06-08,363.75,371.9,360.22,370.0,8975028.0,0.0,1.0,363.75,371.9,360.22,370.0,8975028.0
+2017-06-07,356.34,360.5,355.14,359.65,9287888.0,0.0,1.0,356.34,360.5,355.14,359.65,9287888.0
+2017-06-06,344.7,359.4929,339.97,352.85,10951473.0,0.0,1.0,344.7,359.4929,339.97,352.85,10951473.0
+2017-06-05,338.5,348.44,334.21,347.32,6737855.0,0.0,1.0,338.5,348.44,334.21,347.32,6737855.0
+2017-06-02,339.77,342.88,335.93,339.85,5570256.0,0.0,1.0,339.77,342.88,335.93,339.85,5570256.0
+2017-06-01,344.0,344.88,337.29,340.37,7580447.0,0.0,1.0,344.0,344.88,337.29,340.37,7580447.0
diff --git a/examples/quick/demos/stocqt/content/data/TXN.csv b/examples/quick/demos/stocqt/content/data/TXN.csv
new file mode 100644
index 0000000000..d42c304e8f
--- /dev/null
+++ b/examples/quick/demos/stocqt/content/data/TXN.csv
@@ -0,0 +1,148 @@
+Date,Open,High,Low,Close,Volume,Ex-Dividend,Split Ratio,Adj. Open,Adj. High,Adj. Low,Adj. Close,Adj. Volume
+2017-12-29,104.58,105.08,104.42,104.44,2767863.0,0.0,1.0,104.58,105.08,104.42,104.44,2767863.0
+2017-12-28,104.92,104.92,104.2194,104.82,1632350.0,0.0,1.0,104.92,104.92,104.2194,104.82,1632350.0
+2017-12-27,104.42,104.9,103.98,104.53,1699287.0,0.0,1.0,104.42,104.9,103.98,104.53,1699287.0
+2017-12-26,103.58,104.19,103.06,104.15,1468127.0,0.0,1.0,103.58,104.19,103.06,104.15,1468127.0
+2017-12-22,104.0,104.34,103.64,104.13,3022033.0,0.0,1.0,104.0,104.34,103.64,104.13,3022033.0
+2017-12-21,105.16,105.33,104.0055,104.07,4505720.0,0.0,1.0,105.16,105.33,104.0055,104.07,4505720.0
+2017-12-20,104.9,105.15,103.48,104.8,5433234.0,0.0,1.0,104.9,105.15,103.48,104.8,5433234.0
+2017-12-19,103.19,104.3,103.08,104.1,5133128.0,0.0,1.0,103.19,104.3,103.08,104.1,5133128.0
+2017-12-18,102.1,103.37,101.65,103.27,5494703.0,0.0,1.0,102.1,103.37,101.65,103.27,5494703.0
+2017-12-15,101.28,101.6,100.07,101.22,7773336.0,0.0,1.0,101.28,101.6,100.07,101.22,7773336.0
+2017-12-14,98.96,100.537,98.78,100.25,6802423.0,0.0,1.0,98.96,100.537,98.78,100.25,6802423.0
+2017-12-13,98.97,99.18,98.21,98.86,5151351.0,0.0,1.0,98.97,99.18,98.21,98.86,5151351.0
+2017-12-12,98.7,99.19,98.23,98.43,5766972.0,0.0,1.0,98.7,99.19,98.23,98.43,5766972.0
+2017-12-11,98.07,98.88,97.77,98.83,5137163.0,0.0,1.0,98.07,98.88,97.77,98.83,5137163.0
+2017-12-08,98.92,99.31,97.78,98.02,5282589.0,0.0,1.0,98.92,99.31,97.78,98.02,5282589.0
+2017-12-07,97.32,98.14,96.94,97.78,4195838.0,0.0,1.0,97.32,98.14,96.94,97.78,4195838.0
+2017-12-06,96.25,97.45,95.87,97.02,4438627.0,0.0,1.0,96.25,97.45,95.87,97.02,4438627.0
+2017-12-05,95.98,98.72,95.36,96.9,4759253.0,0.0,1.0,95.98,98.72,95.36,96.9,4759253.0
+2017-12-04,97.54,97.88,95.27,95.97,4891987.0,0.0,1.0,97.54,97.88,95.27,95.97,4891987.0
+2017-12-01,96.54,97.41,94.72,97.18,4925917.0,0.0,1.0,96.54,97.41,94.72,97.18,4925917.0
+2017-11-30,97.38,98.47,96.7,97.29,7195996.0,0.0,1.0,97.38,98.47,96.7,97.29,7195996.0
+2017-11-29,99.73,99.79,96.45,96.88,5408821.0,0.0,1.0,99.73,99.79,96.45,96.88,5408821.0
+2017-11-28,99.09,99.73,98.62,99.48,3010642.0,0.0,1.0,99.09,99.73,98.62,99.48,3010642.0
+2017-11-27,98.95,99.25,98.61,98.63,2900573.0,0.0,1.0,98.95,99.25,98.61,98.63,2900573.0
+2017-11-24,98.2,99.33,98.19,99.3,1288450.0,0.0,1.0,98.2,99.33,98.19,99.3,1288450.0
+2017-11-22,99.15,99.35,98.07,98.08,2109870.0,0.0,1.0,99.15,99.35,98.07,98.08,2109870.0
+2017-11-21,98.75,99.65,98.65,99.19,3668182.0,0.0,1.0,98.75,99.65,98.65,99.19,3668182.0
+2017-11-20,97.81,98.92,97.8,98.28,2912436.0,0.0,1.0,97.81,98.92,97.8,98.28,2912436.0
+2017-11-17,98.56,98.56,97.61,97.74,3694813.0,0.0,1.0,98.56,98.56,97.61,97.74,3694813.0
+2017-11-16,97.07,98.63,97.05,98.32,3531463.0,0.0,1.0,97.07,98.63,97.05,98.32,3531463.0
+2017-11-15,96.62,98.03,96.28,96.77,3332930.0,0.0,1.0,96.62,98.03,96.28,96.77,3332930.0
+2017-11-14,96.7,97.23,96.35,96.96,2727637.0,0.0,1.0,96.7,97.23,96.35,96.96,2727637.0
+2017-11-13,96.4,97.29,96.35,97.03,2158456.0,0.0,1.0,96.4,97.29,96.35,97.03,2158456.0
+2017-11-10,96.67,97.05,96.4,96.94,3093870.0,0.0,1.0,96.67,97.05,96.4,96.94,3093870.0
+2017-11-09,97.6,98.03,95.63,97.05,4180900.0,0.0,1.0,97.6,98.03,95.63,97.05,4180900.0
+2017-11-07,98.55,99.05,98.28,98.4,3883582.0,0.0,1.0,98.55,99.05,98.28,98.4,3883582.0
+2017-11-06,97.82,98.67,97.67,98.54,4261980.0,0.0,1.0,97.82,98.67,97.67,98.54,4261980.0
+2017-11-03,97.0,98.0,96.34,97.98,3329584.0,0.0,1.0,97.0,98.0,96.34,97.98,3329584.0
+2017-11-02,96.25,96.88,95.6,96.79,3274438.0,0.0,1.0,96.25,96.88,95.6,96.79,3274438.0
+2017-11-01,96.97,97.25,95.77,96.35,3826516.0,0.0,1.0,96.97,97.25,95.77,96.35,3826516.0
+2017-10-31,96.28,97.04,96.18,96.69,3747495.0,0.0,1.0,96.28,97.04,96.18,96.69,3747495.0
+2017-10-30,96.68,97.13,95.92,96.06,4914536.0,0.62,1.0,96.68,97.13,95.92,96.06,4914536.0
+2017-10-27,95.94,97.56,95.71,97.5,5534015.0,0.0,1.0,95.324745552338,96.934356640463,95.096220521307,96.874741414977,5534015.0
+2017-10-26,96.44,96.9399,95.84,96.17,5481993.0,0.0,1.0,95.821539098055,96.318233285064,95.225386843194,95.553270583368,5481993.0
+2017-10-25,95.0,96.7,94.16,95.82,6805958.0,0.0,1.0,94.390773686388,96.079871741829,93.556160529582,95.205515101365,6805958.0
+2017-10-24,96.3,96.62,95.46,96.44,7521218.0,0.0,1.0,95.682436905254,96.000384774514,94.847823748448,95.821539098055,7521218.0
+2017-10-23,96.0,96.7399,95.44,96.21,7248578.0,0.0,1.0,95.384360777824,96.119515866777,94.82795200662,95.593014067025,7248578.0
+2017-10-20,94.05,95.4,94.0,95.18,4775490.0,0.0,1.0,93.446865949524,94.788208522962,93.397186594952,94.569619362847,4775490.0
+2017-10-19,92.97,93.64,92.57,93.45,3890390.0,0.0,1.0,92.373791890774,93.039495242036,91.976357054199,92.850713694663,3890390.0
+2017-10-18,94.26,94.29,93.2,93.43,3528482.0,0.0,1.0,93.655519238726,93.685326851469,92.602316921804,92.830841952834,3528482.0
+2017-10-17,94.17,94.31,93.54,94.27,3136049.0,0.0,1.0,93.566096400496,93.705198593297,92.940136532892,93.66545510964,3136049.0
+2017-10-16,94.21,94.41,93.67,94.23,3109004.0,0.0,1.0,93.605839884154,93.804557302441,93.069302854779,93.625711625983,3109004.0
+2017-10-13,93.09,93.73,92.8,93.59,2666130.0,0.0,1.0,92.493022341746,93.128918080265,92.20488208523,92.989815887464,2666130.0
+2017-10-12,92.88,93.31,92.59,92.62,3415763.0,0.0,1.0,92.284369052544,92.711611501862,91.996228796028,92.026036408771,3415763.0
+2017-10-11,91.99,92.92,91.72,92.87,2996950.0,0.0,1.0,91.400076541167,92.324112536202,91.131808026479,92.27443318163,2996950.0
+2017-10-10,91.97,92.41,91.465,92.38,2805769.0,0.0,1.0,91.380204799338,91.81738311957,90.878443318163,91.787575506827,2805769.0
+2017-10-09,91.61,91.86,91.31,91.57,1636340.0,0.0,1.0,91.022513446421,91.27091021928,90.72443731899,90.982769962764,1636340.0
+2017-10-06,90.74,91.54,90.74,91.35,2300990.0,0.0,1.0,90.158092676872,90.952962350021,90.158092676872,90.764180802648,2300990.0
+2017-10-05,90.55,91.3,90.11,91.14,3105380.0,0.0,1.0,89.969311129499,90.714501448076,89.532132809268,90.555527513446,3105380.0
+2017-10-04,89.9,90.56,89.58,90.49,3781466.0,0.0,1.0,89.323479520066,89.979247000414,89.005531650807,89.909695904013,3781466.0
+2017-10-03,89.65,90.24,89.5,89.94,2330174.0,0.0,1.0,89.075082747207,89.661299131154,88.926044683492,89.363223003724,2330174.0
+2017-10-02,89.88,90.24,89.31,89.65,3134142.0,0.0,1.0,89.303607778237,89.661299131154,88.737263136119,89.075082747207,3134142.0
+2017-09-29,89.77,89.89,89.09,89.64,3144262.0,0.0,1.0,89.19431319818,89.313543649152,88.518673976003,89.065146876293,3144262.0
+2017-09-28,88.44,89.66,88.35,89.65,5054134.0,0.0,1.0,87.87284236657,89.085018618122,87.783419528341,89.075082747207,5054134.0
+2017-09-27,88.48,89.15,87.85,88.81,3611592.0,0.0,1.0,87.912585850228,88.578289201489,87.286625982623,88.240469590401,3611592.0
+2017-09-26,87.99,88.29,87.45,87.7,2961476.0,0.0,1.0,87.425728175424,87.723804302855,86.889191146049,87.137587918908,2961476.0
+2017-09-25,87.65,88.08,86.9188,87.5,5475113.0,0.0,1.0,87.087908564336,87.515151013653,86.361397683078,86.938870500621,5475113.0
+2017-09-22,86.59,88.45,86.5,88.27,6374309.0,0.0,1.0,86.034706247414,87.882778237484,85.945283409185,87.703932561026,6374309.0
+2017-09-21,86.02,86.59,85.67,86.05,3979462.0,0.0,1.0,85.468361605296,86.034706247414,85.120606123293,85.498169218039,3979462.0
+2017-09-20,87.0,87.0,84.48,85.83,4829104.0,0.0,1.0,86.442076954903,86.442076954903,83.938237484485,85.279580057923,4829104.0
+2017-09-19,86.37,87.24,85.64,86.81,3924755.0,0.0,1.0,85.816117087298,86.680537856847,85.09079851055,86.25329540753,3924755.0
+2017-09-18,85.0,86.47,84.89,86.14,5296505.0,0.0,1.0,84.454902772031,85.915475796442,84.345608191974,85.587592056268,5296505.0
+2017-09-15,83.14,85.03,82.87,84.84,9419782.0,0.0,1.0,82.606830781961,84.484710384775,82.338562267273,84.295928837402,9419782.0
+2017-09-14,82.4,83.67,82.4,83.29,3482781.0,0.0,1.0,81.871576334299,83.133431940422,81.871576334299,82.755868845676,3482781.0
+2017-09-13,82.84,82.94,82.28,82.7,2531515.0,0.0,1.0,82.30875465453,82.408113363674,81.752345883326,82.169652461729,2531515.0
+2017-09-12,82.34,82.95,82.155,82.89,4559914.0,0.0,1.0,81.811961108813,82.418049234588,81.628147496897,82.358434009102,4559914.0
+2017-09-11,81.9,82.73,81.81,82.22,3810169.0,0.0,1.0,81.374782788581,82.199460074472,81.285359950352,81.69273065784,3810169.0
+2017-09-08,81.98,82.035,81.25,81.38,2423569.0,0.0,1.0,81.454269755896,81.508917045925,80.728951179148,80.858117501034,2423569.0
+2017-09-07,82.45,83.99,81.79,82.0,3568251.0,0.0,1.0,81.921255688871,83.451379809681,81.265488208523,81.474141497724,3568251.0
+2017-09-06,82.24,82.37,81.59,82.07,3627993.0,0.0,1.0,81.712602399669,81.841768721556,81.066770790236,81.543692594125,3627993.0
+2017-09-05,82.32,82.49,81.27,81.85,3665925.0,0.0,1.0,81.792089366984,81.960999172528,80.748822920976,81.325103434009,3665925.0
+2017-09-01,82.74,83.1137,82.38,82.54,2644706.0,0.0,1.0,82.209395945387,82.580699441456,81.85170459247,82.0106785271,2644706.0
+2017-08-31,82.44,82.95,82.13,82.82,4301382.0,0.0,1.0,81.911319817956,82.418049234588,81.603307819611,82.288882912702,4301382.0
+2017-08-30,81.21,82.41,81.1,82.31,4353457.0,0.0,1.0,80.68920769549,81.881512205213,80.579913115432,81.78215349607,4353457.0
+2017-08-29,80.08,81.25,80.03,81.03,3677615.0,0.0,1.0,79.566454282168,80.728951179148,79.516774927596,80.510362019032,3677615.0
+2017-08-28,81.44,81.66,80.58,80.76,3042730.0,0.0,1.0,80.91773272652,81.136321886636,80.063247827886,80.242093504344,3042730.0
+2017-08-25,81.58,81.9,80.94,80.98,2560280.0,0.0,1.0,81.056834919321,81.374782788581,80.420939180803,80.46068266446,2560280.0
+2017-08-24,81.16,81.495,80.82,81.25,3312832.0,0.0,1.0,80.639528340918,80.972380016549,80.30170872983,80.728951179148,3312832.0
+2017-08-23,80.24,81.12,80.07,80.89,4039288.0,0.0,1.0,79.725428216798,80.599784857261,79.556518411254,80.371259826231,4039288.0
+2017-08-22,80.34,81.13,80.06,80.75,4302975.0,0.0,1.0,79.824786925941,80.609720728175,79.546582540339,80.23215763343,4302975.0
+2017-08-21,80.14,80.24,79.6,79.89,3167966.0,0.0,1.0,79.626069507654,79.725428216798,79.089532478279,79.377672734795,3167966.0
+2017-08-18,80.09,80.69,79.94,79.97,3605319.0,0.0,1.0,79.576390153082,80.172542407944,79.427352089367,79.45715970211,3605319.0
+2017-08-17,81.95,82.16,80.09,80.15,4036391.0,0.0,1.0,81.424462143153,81.633115432354,79.576390153082,79.636005378568,4036391.0
+2017-08-16,82.42,82.66,81.95,82.46,3171387.0,0.0,1.0,81.891448076127,82.129908978072,81.424462143153,81.931191559785,3171387.0
+2017-08-15,82.07,82.31,81.69,81.95,3597596.0,0.0,1.0,81.543692594125,81.78215349607,81.166129499379,81.424462143153,3597596.0
+2017-08-14,81.48,82.21,81.2031,82.05,3449064.0,0.0,1.0,80.957476210178,81.682794786926,80.682351944559,81.523820852296,3449064.0
+2017-08-11,80.58,81.34,80.43,80.89,3348656.0,0.0,1.0,80.063247827886,80.818374017377,79.91420976417,80.371259826231,3348656.0
+2017-08-10,81.8,82.0,80.28,80.36,4260051.0,0.0,1.0,81.275424079437,81.474141497724,79.765171700455,79.84465866777,4260051.0
+2017-08-09,81.97,82.31,81.38,82.28,4083335.0,0.0,1.0,81.444333884981,81.78215349607,80.858117501034,81.752345883326,4083335.0
+2017-08-08,81.99,83.69,81.89,82.45,6995231.0,0.0,1.0,81.46420562681,83.153303682251,81.364846917667,81.921255688871,6995231.0
+2017-08-07,81.44,82.2,81.44,82.17,2808616.0,0.0,1.0,80.91773272652,81.672858916012,80.91773272652,81.643051303269,2808616.0
+2017-08-04,81.63,81.96,81.25,81.43,2293905.0,0.0,1.0,81.106514273893,81.434398014067,80.728951179148,80.907796855606,2293905.0
+2017-08-03,81.3,81.73,80.965,81.36,2704547.0,0.0,1.0,80.778630533719,81.205872983037,80.445778858089,80.838245759206,2704547.0
+2017-08-02,82.01,82.01,80.64,81.31,3121636.0,0.0,1.0,81.484077368639,81.484077368639,80.122863053372,80.788566404634,3121636.0
+2017-08-01,81.6,81.84,81.02,81.71,3243303.0,0.0,1.0,81.07670666115,81.315167563095,80.500426148117,81.186001241208,3243303.0
+2017-07-31,80.83,81.66,80.78,81.38,5780471.0,0.0,1.0,80.311644600745,81.136321886636,80.261965246173,80.858117501034,5780471.0
+2017-07-28,80.42,81.04,80.05,80.71,5188380.0,0.0,1.0,79.904273893256,80.520297889946,79.536646669425,80.192414149772,5188380.0
+2017-07-27,82.125,82.53,80.09,80.97,6842762.0,0.5,1.0,81.598339884154,82.000742656185,79.576390153082,80.450746793546,6842762.0
+2017-07-26,83.0,84.24,81.96,82.55,6633813.0,0.0,1.0,81.9616053009,83.186091934311,80.934616511587,81.517235151678,6633813.0
+2017-07-25,81.05,81.93,80.58,81.39,6302456.0,0.0,1.0,80.036001320939,80.904991834972,79.571881387307,80.371747655906,6302456.0
+2017-07-24,81.86,81.8673,80.6,80.92,4333751.0,0.0,1.0,80.835867589538,80.843076260847,79.591631171717,79.907627722275,4333751.0
+2017-07-21,81.46,82.0,81.0,81.7,4396691.0,0.0,1.0,80.440871901341,80.974116080407,79.986626859914,80.677869314259,4396691.0
+2017-07-20,82.2,82.81,81.8621,82.69,3719865.0,0.0,1.0,81.171613924505,81.773982349006,80.837941316901,81.655483642547,3719865.0
+2017-07-19,82.49,82.7,81.86,82.16,3065398.0,0.0,1.0,81.457985798448,81.665358534752,80.835867589538,81.132114355686,3065398.0
+2017-07-18,81.5,82.205,81.15,82.16,2713549.0,0.0,1.0,80.480371470161,81.176551370608,80.134750242988,81.132114355686,2713549.0
+2017-07-17,81.82,82.0,81.48,81.66,2955424.0,0.0,1.0,80.796368020718,80.974116080407,80.460621685751,80.638369745439,2955424.0
+2017-07-14,80.95,82.11,80.8481,82.0,3597113.0,0.0,1.0,79.937252398889,81.082739894661,79.836627247321,80.974116080407,3597113.0
+2017-07-13,80.41,80.98,80.265,80.54,3323859.0,0.0,1.0,79.404008219823,79.966877075504,79.260822282852,79.532381818487,3323859.0
+2017-07-12,79.46,80.54,79.46,80.52,3839369.0,0.0,1.0,78.465893460355,79.532381818487,78.465893460355,79.512632034078,3839369.0
+2017-07-11,78.78,79.145,78.28,79.04,2673057.0,0.0,1.0,77.79440079042,78.1548343559,77.300656180174,78.051147987748,2673057.0
+2017-07-10,78.43,79.09,77.925,78.78,3266394.0,0.0,1.0,77.448779563248,78.100522448773,76.950097506899,77.79440079042,3266394.0
+2017-07-07,77.31,78.66,77.31,78.48,5215579.0,0.0,1.0,76.342791636296,77.675902083961,76.342791636296,77.498154024272,5215579.0
+2017-07-06,76.19,77.69,76.19,76.86,4998196.0,0.0,1.0,75.236803709344,76.718037540083,75.236803709344,75.898421487074,4998196.0
+2017-07-05,76.63,77.51,76.24,76.91,6552479.0,0.0,1.0,75.671298966361,76.540289480394,75.286178170369,75.947795948099,6552479.0
+2017-07-03,77.45,77.635,76.4,76.41,3493669.0,0.0,1.0,76.481040127165,76.663725632956,75.444176445647,75.454051337852,3493669.0
+2017-06-30,77.69,77.69,76.61,76.93,4618555.0,0.0,1.0,76.718037540083,76.718037540083,75.651549181951,75.967545732509,4618555.0
+2017-06-29,77.5,77.93,75.9199,76.9,6526856.0,0.0,1.0,76.530414588189,76.955034953001,74.970082870889,75.937921055894,6526856.0
+2017-06-28,77.61,78.21,76.95,78.06,6338112.0,0.0,1.0,76.639038402444,77.231531934739,75.987295516918,77.083408551665,6338112.0
+2017-06-27,78.0,78.27,76.94,76.95,5697074.0,0.0,1.0,77.024159198436,77.290781287969,75.977420624713,75.987295516918,5697074.0
+2017-06-26,80.04,80.09,78.24,78.31,4881033.0,0.0,1.0,79.038637208241,79.088011669266,77.261156611354,77.330280856789,4881033.0
+2017-06-23,79.06,80.02,78.64,79.58,3608764.0,0.0,1.0,78.070897772158,79.018887423831,77.656152299551,78.584392166814,3608764.0
+2017-06-22,79.95,80.05,78.95,79.05,3306610.0,0.0,1.0,78.949763178397,79.048512100446,77.962273957904,78.061022879953,3306610.0
+2017-06-21,79.7,79.92,79.23,79.67,4256147.0,0.0,1.0,78.702890873274,78.920138501782,78.238770939642,78.673266196659,4256147.0
+2017-06-20,81.16,81.23,79.54,79.57,3789428.0,0.0,1.0,80.144625135193,80.213749380627,78.544892597995,78.574517274609,3789428.0
+2017-06-19,80.37,81.45,80.28,81.42,3479332.0,0.0,1.0,79.364508651004,80.430997009136,79.275634621159,80.401372332521,3479332.0
+2017-06-16,79.85,80.23,79.02,79.7,5945383.0,0.0,1.0,78.851014256347,79.226260160135,78.031398203338,78.702890873274,5945383.0
+2017-06-15,79.35,80.4,79.22,80.08,3024056.0,0.0,1.0,78.357269646101,79.394133327618,78.228896047437,79.078136777061,3024056.0
+2017-06-14,81.26,81.49,79.44,80.16,3919507.0,0.0,1.0,80.243374057242,80.470496577956,78.446143675945,79.1571359147,3919507.0
+2017-06-13,81.41,81.8,80.6,80.98,4274125.0,0.0,1.0,80.391497440316,80.776618236308,79.591631171717,79.966877075504,4274125.0
+2017-06-12,79.82,81.32,79.6678,81.05,6724786.0,0.0,1.0,78.821389579733,80.302623410472,78.671093720374,80.036001320939,6724786.0
+2017-06-09,84.23,84.65,79.94,80.9,6785300.0,0.0,1.0,83.176217042106,83.590962514713,78.939888286192,79.887877937865,6785300.0
+2017-06-08,83.2,84.36,82.62,84.34,4332428.0,0.0,1.0,82.159103144998,83.30459064077,81.586359397112,83.28484085636,4332428.0
+2017-06-07,82.8,83.43,82.29,82.89,3705908.0,0.0,1.0,81.764107456801,82.386225665712,81.26048795435,81.852981486645,3705908.0
+2017-06-06,81.65,82.875,81.51,82.22,3222387.0,0.0,1.0,80.628494853234,81.838169148338,80.490246362365,81.191363708915,3222387.0
+2017-06-05,81.66,82.38,81.66,81.885,2467546.0,0.0,1.0,80.638369745439,81.349361984194,80.638369745439,80.86055482005,2467546.0
+2017-06-02,81.96,81.97,80.86,81.63,4714171.0,0.0,1.0,80.934616511587,80.944491403792,79.848378369045,80.608745068825,4714171.0
+2017-06-01,82.61,82.8642,81.215,81.49,4292961.0,0.0,1.0,81.576484504907,81.827504264757,80.19893704232,80.470496577956,4292961.0
diff --git a/examples/quick/demos/stocqt/doc/images/qtquick-demo-stocqt.png b/examples/quick/demos/stocqt/doc/images/qtquick-demo-stocqt.png
index dc09a84dc3..38e279d60d 100644
--- a/examples/quick/demos/stocqt/doc/images/qtquick-demo-stocqt.png
+++ b/examples/quick/demos/stocqt/doc/images/qtquick-demo-stocqt.png
Binary files differ
diff --git a/examples/quick/demos/stocqt/doc/src/stocqt.qdoc b/examples/quick/demos/stocqt/doc/src/stocqt.qdoc
index c2fa4062cb..e324cf63b5 100644
--- a/examples/quick/demos/stocqt/doc/src/stocqt.qdoc
+++ b/examples/quick/demos/stocqt/doc/src/stocqt.qdoc
@@ -30,19 +30,18 @@
\ingroup qtquickdemos
\example demos/stocqt
\brief A configurable stock chart for the NASDAQ-100.
- \image qtquick-demo-stocqt.png
+ \borderedimage qtquick-demo-stocqt.png
The \e{StocQt} application presents a trend chart for the first stock in
- the list of NASDAQ-100 stocks maintained by it. It allows the user to
- choose another stock from the list, and fetches the required data for
- the selected stock by sending an \c XMLHttpRequest to
- http://finance.yahoo.com.
+ the list of NASDAQ-100 stocks. It allows the user to choose another stock
+ from the list, and fetches the required data from the offline dataset
+ using \c XMLHttpRequest.
The application uses several custom types such as Button, CheckBox,
StockChart, StockInfo, StockView, and so on. These types are used to
present the stock data in a readable form and also let the user customize
- the trend chart. For example, the user can choose to view the yearly,
- monthly, or daily trends in the stock price.
+ the trend chart. For example, the user can choose to view the weekly,
+ monthly, quarterly, or half yearly trends in the stock price.
The application uses the ObjectModel type to access the two visual data
models that it depends on.
diff --git a/examples/quick/demos/stocqt/stocqt.qrc b/examples/quick/demos/stocqt/stocqt.qrc
index ab7772a62a..a1c3b25494 100644
--- a/examples/quick/demos/stocqt/stocqt.qrc
+++ b/examples/quick/demos/stocqt/stocqt.qrc
@@ -18,5 +18,25 @@
<file>content/+windows/Settings.qml</file>
<file>content/StockListDelegate.qml</file>
<file>content/Banner.qml</file>
+ <file>content/data/AAPL.csv</file>
+ <file>content/data/ADSK.csv</file>
+ <file>content/data/AMZN.csv</file>
+ <file>content/data/AMD.csv</file>
+ <file>content/data/CSCO.csv</file>
+ <file>content/data/FB.csv</file>
+ <file>content/data/GOOG.csv</file>
+ <file>content/data/GOOGL.csv</file>
+ <file>content/data/MSFT.csv</file>
+ <file>content/data/NCLH.csv</file>
+ <file>content/data/NFLX.csv</file>
+ <file>content/data/TXN.csv</file>
+ <file>content/data/EA.csv</file>
+ <file>content/data/EBAY.csv</file>
+ <file>content/data/PYPL.csv</file>
+ <file>content/data/INTC.csv</file>
+ <file>content/data/NTAP.csv</file>
+ <file>content/data/QCOM.csv</file>
+ <file>content/data/NVDA.csv</file>
+ <file>content/data/TSLA.csv</file>
</qresource>
</RCC>
diff --git a/examples/quick/imageelements/animatedimage.qml b/examples/quick/imageelements/animatedimage.qml
new file mode 100644
index 0000000000..0a119d0aba
--- /dev/null
+++ b/examples/quick/imageelements/animatedimage.qml
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.11
+import Qt.labs.handlers 1.0
+import "../shared" as Examples
+
+Column {
+ width: 320
+ height: 480
+ spacing: 6
+ y: 12
+
+//! [image]
+ AnimatedImage {
+ id: animation
+ source: "content/Uniflow_steam_engine.gif"
+ anchors.horizontalCenter: parent.horizontalCenter
+ speed: speedSlider.value
+ TapHandler {
+ onTapped: animation.playing = !animation.playing
+ }
+ }
+//! [image]
+
+ Rectangle {
+ id: timeline
+ color: "steelblue"
+ width: animation.width
+ height: 1
+ x: animation.x
+ y: animation.height + 12
+ visible: animation.playing
+
+ Rectangle {
+ property int frames: animation.frameCount
+ width: 4; height: 8
+ x: (animation.width - width) * animation.currentFrame / frames
+ y: -4
+ color: "red"
+ }
+ }
+
+ Examples.Slider {
+ id: speedSlider
+ name: "Speed"
+ min: 0
+ max: 5
+ init: 1
+ width: 240
+ x: animation.x
+ Text {
+ font.pointSize: 12
+ text: Math.round(animation.speed * 100) + "%"
+ x: animation.width - width
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.margins: 6
+ }
+ }
+
+ Examples.Button {
+ text: "Reset"
+ enabled: speedSlider.value !== 1
+ anchors.horizontalCenter: parent.horizontalCenter
+ onClicked: {
+ speedSlider.setValue(1)
+ animation.playing = true
+ }
+ }
+}
diff --git a/examples/quick/imageelements/content/Uniflow_steam_engine.gif b/examples/quick/imageelements/content/Uniflow_steam_engine.gif
new file mode 100644
index 0000000000..8754de4af9
--- /dev/null
+++ b/examples/quick/imageelements/content/Uniflow_steam_engine.gif
Binary files differ
diff --git a/examples/quick/imageelements/imageelements.qml b/examples/quick/imageelements/imageelements.qml
index e0eb503ecf..dfb4d24ea6 100644
--- a/examples/quick/imageelements/imageelements.qml
+++ b/examples/quick/imageelements/imageelements.qml
@@ -61,6 +61,7 @@ Item {
addExample("BorderImage", "An image with scaled borders", Qt.resolvedUrl("borderimage.qml"));
addExample("Image", "A showcase of the options available to Image", Qt.resolvedUrl("image.qml"));
addExample("Shadows", "Rectangles with a drop-shadow effect", Qt.resolvedUrl("shadows.qml"));
+ addExample("AnimatedImage", "An image which plays animated formats", Qt.resolvedUrl("animatedimage.qml"));
addExample("AnimatedSprite", "A simple sprite-based animation", Qt.resolvedUrl("animatedsprite.qml"));
addExample("SpriteSequence", "A sprite-based animation with complex transitions", Qt.resolvedUrl("spritesequence.qml"));
}
diff --git a/examples/quick/imageelements/imageelements.qrc b/examples/quick/imageelements/imageelements.qrc
index ef8a9e52cb..2488fb083b 100644
--- a/examples/quick/imageelements/imageelements.qrc
+++ b/examples/quick/imageelements/imageelements.qrc
@@ -13,7 +13,9 @@
<file>content/shadow.png</file>
<file>content/ShadowRectangle.qml</file>
<file>content/speaker.png</file>
+ <file>content/Uniflow_steam_engine.gif</file>
<file>imageelements.qml</file>
+ <file>animatedimage.qml</file>
<file>animatedsprite.qml</file>
<file>borderimage.qml</file>
<file>image.qml</file>
diff --git a/examples/quick/quick.pro b/examples/quick/quick.pro
index 7da255e903..ef51d98d44 100644
--- a/examples/quick/quick.pro
+++ b/examples/quick/quick.pro
@@ -24,6 +24,7 @@ SUBDIRS = quick-accessibility \
imageresponseprovider \
window \
particles \
+ shapes \
demos
#OpenGL Support Required
diff --git a/examples/quick/quickwidgets/qquickviewcomparison/fbitem.h b/examples/quick/quickwidgets/qquickviewcomparison/fbitem.h
index f437e5771c..3a4c5a13c2 100644
--- a/examples/quick/quickwidgets/qquickviewcomparison/fbitem.h
+++ b/examples/quick/quickwidgets/qquickviewcomparison/fbitem.h
@@ -64,9 +64,9 @@ class FbItemRenderer : public QQuickFramebufferObject::Renderer
{
public:
FbItemRenderer(bool multisample);
- void synchronize(QQuickFramebufferObject *item) Q_DECL_OVERRIDE;
- void render() Q_DECL_OVERRIDE;
- QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) Q_DECL_OVERRIDE;
+ void synchronize(QQuickFramebufferObject *item) override;
+ void render() override;
+ QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) override;
private:
void ensureInit();
@@ -115,7 +115,7 @@ class FbItem : public QQuickFramebufferObject
public:
explicit FbItem(QQuickItem *parent = 0);
- QQuickFramebufferObject::Renderer *createRenderer() const Q_DECL_OVERRIDE;
+ QQuickFramebufferObject::Renderer *createRenderer() const override;
QVector3D eye() const { return m_eye; }
void setEye(const QVector3D &v);
diff --git a/examples/quick/quickwidgets/qquickviewcomparison/main.cpp b/examples/quick/quickwidgets/qquickviewcomparison/main.cpp
index a80d151401..73db97eddb 100644
--- a/examples/quick/quickwidgets/qquickviewcomparison/main.cpp
+++ b/examples/quick/quickwidgets/qquickviewcomparison/main.cpp
@@ -49,6 +49,8 @@
****************************************************************************/
#include <QApplication>
+#include <QCommandLineParser>
+#include <QCommandLineOption>
#include "mainwindow.h"
@@ -58,8 +60,22 @@ int main(int argc, char **argv)
QApplication app(argc, argv);
- bool transparency = QCoreApplication::arguments().contains(QStringLiteral("--transparent"));
- MainWindow widgetWindow(transparency);
+ QCoreApplication::setApplicationName("Qt QQuickView/QQuickWidget Comparison Example");
+ QCoreApplication::setOrganizationName("QtProject");
+ QCoreApplication::setApplicationVersion(QT_VERSION_STR);
+ QCommandLineParser parser;
+ parser.setApplicationDescription(QCoreApplication::applicationName());
+ parser.addHelpOption();
+ parser.addVersionOption();
+ QCommandLineOption noRenderAlphaOption("no-render-alpha", "Do not render Alpha");
+ parser.addOption(noRenderAlphaOption);
+ QCommandLineOption transparentOption("transparent", "Transparent window");
+ parser.addOption(transparentOption);
+
+ parser.process(app);
+
+ const bool transparency = parser.isSet(transparentOption);
+ MainWindow widgetWindow(transparency, parser.isSet(noRenderAlphaOption));
if (transparency) {
widgetWindow.setAttribute(Qt::WA_TranslucentBackground);
widgetWindow.setAttribute(Qt::WA_NoSystemBackground, false);
diff --git a/examples/quick/quickwidgets/qquickviewcomparison/mainwindow.cpp b/examples/quick/quickwidgets/qquickviewcomparison/mainwindow.cpp
index e2892640f7..524af1e915 100644
--- a/examples/quick/quickwidgets/qquickviewcomparison/mainwindow.cpp
+++ b/examples/quick/quickwidgets/qquickviewcomparison/mainwindow.cpp
@@ -50,7 +50,6 @@
#include "mainwindow.h"
#include "fbitem.h"
-#include <QCoreApplication>
#include <QVBoxLayout>
#include <QGroupBox>
#include <QRadioButton>
@@ -58,10 +57,11 @@
#include <QLabel>
#include <QQuickItem>
-MainWindow::MainWindow(bool transparency)
+MainWindow::MainWindow(bool transparency, bool noRenderAlpha)
: m_currentView(0),
m_currentRootObject(0),
- m_transparent(transparency)
+ m_transparent(transparency),
+ m_noRenderAlpha(noRenderAlpha)
{
QVBoxLayout *layout = new QVBoxLayout;
@@ -188,7 +188,7 @@ void MainWindow::updateView()
if (m_currentRootObject) {
m_currentRootObject->setProperty("currentText", text);
m_currentRootObject->setProperty("multisample", m_checkboxMultiSample->isChecked());
- if (!QCoreApplication::arguments().contains(QStringLiteral("--no_render_alpha")))
+ if (!m_noRenderAlpha)
m_currentRootObject->setProperty("translucency", m_transparent);
}
diff --git a/examples/quick/quickwidgets/qquickviewcomparison/mainwindow.h b/examples/quick/quickwidgets/qquickviewcomparison/mainwindow.h
index 4358e6769f..d182b70960 100644
--- a/examples/quick/quickwidgets/qquickviewcomparison/mainwindow.h
+++ b/examples/quick/quickwidgets/qquickviewcomparison/mainwindow.h
@@ -63,7 +63,7 @@ QT_FORWARD_DECLARE_CLASS(QLayout)
class MainWindow : public QWidget
{
public:
- MainWindow(bool transparency);
+ explicit MainWindow(bool transparency, bool noRenderAlpha);
protected:
void resizeEvent(QResizeEvent*);
@@ -96,6 +96,7 @@ private:
QSurfaceFormat m_format;
bool m_transparent;
+ bool m_noRenderAlpha;
};
#endif
diff --git a/examples/quick/quickwidgets/quickwidget/main.cpp b/examples/quick/quickwidgets/quickwidget/main.cpp
index 382744ca93..c54586c5de 100644
--- a/examples/quick/quickwidgets/quickwidget/main.cpp
+++ b/examples/quick/quickwidgets/quickwidget/main.cpp
@@ -54,6 +54,9 @@
#include <QtWidgets>
#include "fbitem.h"
+static bool optMultipleSample = false;
+static bool optCoreProfile = false;
+
class MainWindow : public QMainWindow {
Q_OBJECT
public:
@@ -75,11 +78,11 @@ MainWindow::MainWindow()
: m_quickWidget(new QQuickWidget)
{
QSurfaceFormat format;
- if (QCoreApplication::arguments().contains(QStringLiteral("--coreprofile"))) {
+ if (optCoreProfile) {
format.setVersion(4, 4);
format.setProfile(QSurfaceFormat::CoreProfile);
}
- if (QCoreApplication::arguments().contains(QStringLiteral("--multisample")))
+ if (optMultipleSample)
format.setSamples(4);
m_quickWidget->setFormat(format);
@@ -194,6 +197,23 @@ int main(int argc, char **argv)
{
QApplication app(argc, argv);
+ QCoreApplication::setApplicationName("Qt QQuickWidget Example");
+ QCoreApplication::setOrganizationName("QtProject");
+ QCoreApplication::setApplicationVersion(QT_VERSION_STR);
+ QCommandLineParser parser;
+ parser.setApplicationDescription(QCoreApplication::applicationName());
+ parser.addHelpOption();
+ parser.addVersionOption();
+ QCommandLineOption multipleSampleOption("multisample", "Multisampling");
+ parser.addOption(multipleSampleOption);
+ QCommandLineOption coreProfileOption("coreprofile", "Use core profile");
+ parser.addOption(coreProfileOption);
+
+ parser.process(app);
+
+ optMultipleSample = parser.isSet(multipleSampleOption);
+ optCoreProfile = parser.isSet(coreProfileOption);
+
qmlRegisterType<FbItem>("QuickWidgetExample", 1, 0, "FbItem");
MainWindow mainWindow;
diff --git a/examples/quick/rendercontrol/main.cpp b/examples/quick/rendercontrol/main.cpp
index c9c7eeb525..71903045cc 100644
--- a/examples/quick/rendercontrol/main.cpp
+++ b/examples/quick/rendercontrol/main.cpp
@@ -49,6 +49,8 @@
****************************************************************************/
#include <QGuiApplication>
+#include <QCommandLineParser>
+#include <QCommandLineOption>
#include "window_singlethreaded.h"
#include "window_multithreaded.h"
@@ -56,8 +58,20 @@ int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);
+ QCoreApplication::setApplicationName("Qt Render Control Example");
+ QCoreApplication::setOrganizationName("QtProject");
+ QCoreApplication::setApplicationVersion(QT_VERSION_STR);
+ QCommandLineParser parser;
+ parser.setApplicationDescription(QCoreApplication::applicationName());
+ parser.addHelpOption();
+ parser.addVersionOption();
+ QCommandLineOption threadedOption("threaded", "Threaded Rendering");
+ parser.addOption(threadedOption);
+
+ parser.process(app);
+
QScopedPointer<QWindow> window;
- if (QCoreApplication::arguments().contains(QLatin1String("--threaded"))) {
+ if (parser.isSet(threadedOption)) {
qWarning("Using separate Qt Quick render thread");
window.reset(new WindowMultiThreaded);
} else {
diff --git a/examples/quick/rendercontrol/window_multithreaded.cpp b/examples/quick/rendercontrol/window_multithreaded.cpp
index 7e9db36776..ac82847dbf 100644
--- a/examples/quick/rendercontrol/window_multithreaded.cpp
+++ b/examples/quick/rendercontrol/window_multithreaded.cpp
@@ -227,14 +227,14 @@ class RenderControl : public QQuickRenderControl
{
public:
RenderControl(QWindow *w) : m_window(w) { }
- QWindow *renderWindow(QPoint *offset) Q_DECL_OVERRIDE;
+ QWindow *renderWindow(QPoint *offset) override;
private:
QWindow *m_window;
};
WindowMultiThreaded::WindowMultiThreaded()
- : m_qmlComponent(Q_NULLPTR),
+ : m_qmlComponent(nullptr),
m_rootItem(0),
m_quickInitialized(false),
m_psrRequested(false)
diff --git a/examples/quick/rendercontrol/window_multithreaded.h b/examples/quick/rendercontrol/window_multithreaded.h
index 71ce136500..ded80a0064 100644
--- a/examples/quick/rendercontrol/window_multithreaded.h
+++ b/examples/quick/rendercontrol/window_multithreaded.h
@@ -92,7 +92,7 @@ public:
void aboutToQuit();
private:
- bool event(QEvent *e) Q_DECL_OVERRIDE;
+ bool event(QEvent *e) override;
void init();
void cleanup();
void ensureFbo();
@@ -120,11 +120,11 @@ public:
~WindowMultiThreaded();
protected:
- void exposeEvent(QExposeEvent *e) Q_DECL_OVERRIDE;
- void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE;
- void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE;
- void mouseReleaseEvent(QMouseEvent *e) Q_DECL_OVERRIDE;
- bool event(QEvent *e) Q_DECL_OVERRIDE;
+ void exposeEvent(QExposeEvent *e) override;
+ void resizeEvent(QResizeEvent *e) override;
+ void mousePressEvent(QMouseEvent *e) override;
+ void mouseReleaseEvent(QMouseEvent *e) override;
+ bool event(QEvent *e) override;
private slots:
void run();
diff --git a/examples/quick/rendercontrol/window_singlethreaded.cpp b/examples/quick/rendercontrol/window_singlethreaded.cpp
index 1dee8b9f74..d0bf0adad4 100644
--- a/examples/quick/rendercontrol/window_singlethreaded.cpp
+++ b/examples/quick/rendercontrol/window_singlethreaded.cpp
@@ -70,7 +70,7 @@ class RenderControl : public QQuickRenderControl
{
public:
RenderControl(QWindow *w) : m_window(w) { }
- QWindow *renderWindow(QPoint *offset) Q_DECL_OVERRIDE;
+ QWindow *renderWindow(QPoint *offset) override;
private:
QWindow *m_window;
@@ -92,6 +92,10 @@ WindowSingleThreaded::WindowSingleThreaded()
{
setSurfaceType(QSurface::OpenGLSurface);
+ // The rendercontrol does not necessarily need an FBO. Demonstrate this
+ // when requested.
+ m_onscreen = QCoreApplication::arguments().contains(QStringLiteral("--onscreen"));
+
QSurfaceFormat format;
// Qt Quick may need a depth and stencil buffer. Always make sure these are available.
format.setDepthBufferSize(16);
@@ -174,8 +178,14 @@ void WindowSingleThreaded::createFbo()
// The scene graph has been initialized. It is now time to create an FBO and associate
// it with the QQuickWindow.
m_dpr = devicePixelRatio();
- m_fbo = new QOpenGLFramebufferObject(size() * m_dpr, QOpenGLFramebufferObject::CombinedDepthStencil);
- m_quickWindow->setRenderTarget(m_fbo);
+ if (!m_onscreen) {
+ m_fbo = new QOpenGLFramebufferObject(size() * m_dpr, QOpenGLFramebufferObject::CombinedDepthStencil);
+ m_quickWindow->setRenderTarget(m_fbo);
+ } else {
+ // Special case: No FBO. Render directly to the window's default framebuffer.
+ m_onscreenSize = size() * m_dpr;
+ m_quickWindow->setRenderTarget(0, m_onscreenSize);
+ }
}
void WindowSingleThreaded::destroyFbo()
@@ -186,7 +196,10 @@ void WindowSingleThreaded::destroyFbo()
void WindowSingleThreaded::render()
{
- if (!m_context->makeCurrent(m_offscreenSurface))
+ QSurface *surface = m_offscreenSurface;
+ if (m_onscreen)
+ surface = this;
+ if (!m_context->makeCurrent(surface))
return;
// Polish, synchronize and render the next frame (into our fbo). In this example
@@ -205,7 +218,10 @@ void WindowSingleThreaded::render()
m_quickReady = true;
// Get something onto the screen.
- m_cubeRenderer->render(this, m_context, m_quickReady ? m_fbo->texture() : 0);
+ if (!m_onscreen)
+ m_cubeRenderer->render(this, m_context, m_quickReady ? m_fbo->texture() : 0);
+ else
+ m_context->swapBuffers(this);
}
void WindowSingleThreaded::requestUpdate()
@@ -247,7 +263,10 @@ void WindowSingleThreaded::run()
updateSizes();
// Initialize the render control and our OpenGL resources.
- m_context->makeCurrent(m_offscreenSurface);
+ QSurface *surface = m_offscreenSurface;
+ if (m_onscreen)
+ surface = this;
+ m_context->makeCurrent(surface);
m_renderControl->initialize(m_context);
m_quickInitialized = true;
}
@@ -276,7 +295,8 @@ void WindowSingleThreaded::exposeEvent(QExposeEvent *)
{
if (isExposed()) {
if (!m_quickInitialized) {
- m_cubeRenderer->render(this, m_context, m_quickReady ? m_fbo->texture() : 0);
+ if (!m_onscreen)
+ m_cubeRenderer->render(this, m_context, m_quickReady ? m_fbo->texture() : 0);
startQuick(QStringLiteral("qrc:/rendercontrol/demo.qml"));
}
}
@@ -284,7 +304,10 @@ void WindowSingleThreaded::exposeEvent(QExposeEvent *)
void WindowSingleThreaded::resizeFbo()
{
- if (m_rootItem && m_context->makeCurrent(m_offscreenSurface)) {
+ QSurface *surface = m_offscreenSurface;
+ if (m_onscreen)
+ surface = this;
+ if (m_rootItem && m_context->makeCurrent(surface)) {
delete m_fbo;
createFbo();
m_context->doneCurrent();
@@ -297,8 +320,13 @@ void WindowSingleThreaded::resizeEvent(QResizeEvent *)
{
// If this is a resize after the scene is up and running, recreate the fbo and the
// Quick item and scene.
- if (m_fbo && m_fbo->size() != size() * devicePixelRatio())
- resizeFbo();
+ if (!m_onscreen) {
+ if (m_fbo && m_fbo->size() != size() * devicePixelRatio())
+ resizeFbo();
+ } else {
+ if (m_onscreenSize != size() * devicePixelRatio())
+ resizeFbo();
+ }
}
void WindowSingleThreaded::handleScreenChange()
diff --git a/examples/quick/rendercontrol/window_singlethreaded.h b/examples/quick/rendercontrol/window_singlethreaded.h
index dadd9daf7e..44b79d9f51 100644
--- a/examples/quick/rendercontrol/window_singlethreaded.h
+++ b/examples/quick/rendercontrol/window_singlethreaded.h
@@ -75,10 +75,10 @@ public:
~WindowSingleThreaded();
protected:
- void exposeEvent(QExposeEvent *e) Q_DECL_OVERRIDE;
- void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE;
- void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE;
- void mouseReleaseEvent(QMouseEvent *e) Q_DECL_OVERRIDE;
+ void exposeEvent(QExposeEvent *e) override;
+ void resizeEvent(QResizeEvent *e) override;
+ void mousePressEvent(QMouseEvent *e) override;
+ void mouseReleaseEvent(QMouseEvent *e) override;
private slots:
void run();
@@ -107,6 +107,8 @@ private:
QTimer m_updateTimer;
CubeRenderer *m_cubeRenderer;
qreal m_dpr;
+ bool m_onscreen;
+ QSize m_onscreenSize;
};
#endif
diff --git a/examples/quick/scenegraph/customgeometry/beziercurve.cpp b/examples/quick/scenegraph/customgeometry/beziercurve.cpp
index ca3c6f524b..750ff6aa3b 100644
--- a/examples/quick/scenegraph/customgeometry/beziercurve.cpp
+++ b/examples/quick/scenegraph/customgeometry/beziercurve.cpp
@@ -152,7 +152,7 @@ QSGNode *BezierCurve::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
//! [7]
//! [8]
- QRectF bounds = boundingRect();
+ QSizeF itemSize = size();
QSGGeometry::Point2D *vertices = geometry->vertexDataAsPoint2D();
for (int i = 0; i < m_segmentCount; ++i) {
qreal t = i / qreal(m_segmentCount - 1);
@@ -163,8 +163,8 @@ QSGNode *BezierCurve::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+ 3 * invt * t * t * m_p3
+ t * t * t * m_p4;
- float x = bounds.x() + pos.x() * bounds.width();
- float y = bounds.y() + pos.y() * bounds.height();
+ float x = pos.x() * itemSize.width();
+ float y = pos.y() * itemSize.height();
vertices[i].set(x, y);
}
diff --git a/examples/quick/scenegraph/graph/noisynode.cpp b/examples/quick/scenegraph/graph/noisynode.cpp
index 762a47ec1f..6e79bb247f 100644
--- a/examples/quick/scenegraph/graph/noisynode.cpp
+++ b/examples/quick/scenegraph/graph/noisynode.cpp
@@ -50,6 +50,7 @@
#include "noisynode.h"
+#include <QtCore/QRandomGenerator>
#include <QtQuick/QSGSimpleMaterialShader>
#include <QtQuick/QSGTexture>
#include <QtQuick/QQuickWindow>
@@ -113,7 +114,7 @@ NoisyNode::NoisyNode(QQuickWindow *window)
QImage image(NOISE_SIZE, NOISE_SIZE, QImage::Format_RGB32);
uint *data = (uint *) image.bits();
for (int i=0; i<NOISE_SIZE * NOISE_SIZE; ++i) {
- uint g = rand() & 0xff;
+ uint g = QRandomGenerator::global()->bounded(0xff);
data[i] = 0xff000000 | (g << 16) | (g << 8) | g;
}
diff --git a/examples/quick/scenegraph/graph/shaders/line.fsh b/examples/quick/scenegraph/graph/shaders/line.fsh
index 378cc1084f..77e05a2d15 100644
--- a/examples/quick/scenegraph/graph/shaders/line.fsh
+++ b/examples/quick/scenegraph/graph/shaders/line.fsh
@@ -54,7 +54,7 @@ uniform lowp float spread;
varying lowp float vT;
-#define PI 3.14159265359
+#define PI 3.14159265358979323846
void main(void)
{
diff --git a/examples/quick/scenegraph/graph/shaders/noisy.fsh b/examples/quick/scenegraph/graph/shaders/noisy.fsh
index 2796f24bd8..14ea675360 100644
--- a/examples/quick/scenegraph/graph/shaders/noisy.fsh
+++ b/examples/quick/scenegraph/graph/shaders/noisy.fsh
@@ -55,7 +55,7 @@ uniform lowp vec4 color;
varying highp vec2 vTexCoord;
varying lowp vec2 vShadeCoord;
-#define PI 3.14159265359
+#define PI 3.14159265358979323846
void main()
{
diff --git a/examples/quick/scenegraph/rendernode/main.cpp b/examples/quick/scenegraph/rendernode/main.cpp
index d6c1b000c3..21419abfc9 100644
--- a/examples/quick/scenegraph/rendernode/main.cpp
+++ b/examples/quick/scenegraph/rendernode/main.cpp
@@ -48,6 +48,8 @@
**
****************************************************************************/
+#include <QCommandLineParser>
+#include <QCommandLineOption>
#include <QGuiApplication>
#include <QQuickView>
#include "customrenderitem.h"
@@ -60,7 +62,19 @@ int main(int argc, char **argv)
QQuickView view;
- if (QCoreApplication::arguments().contains(QStringLiteral("--multisample"))) {
+ QCoreApplication::setApplicationName("Qt Scene Graph Render Node Example");
+ QCoreApplication::setOrganizationName("QtProject");
+ QCoreApplication::setApplicationVersion(QT_VERSION_STR);
+ QCommandLineParser parser;
+ parser.setApplicationDescription(QCoreApplication::applicationName());
+ parser.addHelpOption();
+ parser.addVersionOption();
+ QCommandLineOption multipleSampleOption("multisample", "Multisampling");
+ parser.addOption(multipleSampleOption);
+
+ parser.process(app);
+
+ if (parser.isSet(multipleSampleOption)) {
QSurfaceFormat fmt;
fmt.setSamples(4);
view.setFormat(fmt);
diff --git a/examples/quick/scenegraph/rendernode/softwarerenderer.cpp b/examples/quick/scenegraph/rendernode/softwarerenderer.cpp
index f1c496e23a..b6f7ffa577 100644
--- a/examples/quick/scenegraph/rendernode/softwarerenderer.cpp
+++ b/examples/quick/scenegraph/rendernode/softwarerenderer.cpp
@@ -74,11 +74,12 @@ void SoftwareRenderNode::render(const RenderState *renderState)
QPainter *p = static_cast<QPainter *>(rif->getResource(m_item->window(), QSGRendererInterface::PainterResource));
Q_ASSERT(p);
- p->setTransform(matrix()->toTransform());
- p->setOpacity(inheritedOpacity());
const QRegion *clipRegion = renderState->clipRegion();
if (clipRegion && !clipRegion->isEmpty())
- p->setClipRegion(*clipRegion, Qt::IntersectClip);
+ p->setClipRegion(*clipRegion, Qt::ReplaceClip); // must be done before setTransform
+
+ p->setTransform(matrix()->toTransform());
+ p->setOpacity(inheritedOpacity());
const QPointF p0(m_item->width() - 1, m_item->height() - 1);
const QPointF p1(0, 0);
diff --git a/examples/quick/scenegraph/sgengine/window.cpp b/examples/quick/scenegraph/sgengine/window.cpp
index 96b730ebfc..6f22510a81 100644
--- a/examples/quick/scenegraph/sgengine/window.cpp
+++ b/examples/quick/scenegraph/sgengine/window.cpp
@@ -58,6 +58,7 @@
#include <QScreen>
#include <QVariantAnimation>
#include <QOpenGLFunctions>
+#include <QRandomGenerator>
class Item {
public:
@@ -71,9 +72,9 @@ public:
transformNode->appendChildNode(textureNode);
parentNode->appendChildNode(transformNode);
- int duration = qrand() / float(RAND_MAX) * 400 + 800;
- rotAnimation.setStartValue(qrand() / float(RAND_MAX) * 720 - 180);
- rotAnimation.setEndValue(qrand() / float(RAND_MAX) * 720 - 180);
+ int duration = QRandomGenerator::global()->generateDouble() * 400 + 800;
+ rotAnimation.setStartValue(QRandomGenerator::global()->generateDouble() * 720 - 180);
+ rotAnimation.setEndValue(QRandomGenerator::global()->generateDouble() * 720 - 180);
rotAnimation.setDuration(duration);
rotAnimation.start();
@@ -181,8 +182,8 @@ void Window::addItems()
QSGTexture *textures[] = { m_smileTexture.data(), m_qtTexture.data() };
for (int i = 0; i < 50; ++i) {
QSGTexture *tex = textures[i%2];
- QPointF fromPos(-tex->textureSize().width(), qrand() / float(RAND_MAX) * (height() - tex->textureSize().height()));
- QPointF toPos(width(), qrand() / float(RAND_MAX) * height() * 1.5 - height() * 0.25);
+ QPointF fromPos(-tex->textureSize().width(), QRandomGenerator::global()->generateDouble() * (height() - tex->textureSize().height()));
+ QPointF toPos(width(), QRandomGenerator::global()->generateDouble() * height() * 1.5 - height() * 0.25);
m_items.append(QSharedPointer<Item>::create(m_sgRootNode.data(), tex, fromPos, toPos));
}
update();
diff --git a/examples/quick/scenegraph/shared/logorenderer.cpp b/examples/quick/scenegraph/shared/logorenderer.cpp
index 8dea8d9d0c..0c34fb4402 100644
--- a/examples/quick/scenegraph/shared/logorenderer.cpp
+++ b/examples/quick/scenegraph/shared/logorenderer.cpp
@@ -51,7 +51,7 @@
#include "logorenderer.h"
#include <QPainter>
#include <QPaintEngine>
-#include <math.h>
+#include <qmath.h>
LogoRenderer::LogoRenderer()
{
@@ -176,7 +176,7 @@ void LogoRenderer::createGeometry()
extrude(x4, y4, y4, x4);
extrude(y4, x4, y3, x3);
- const qreal Pi = 3.14159f;
+ const qreal Pi = M_PI;
const int NumSectors = 100;
for (int i = 0; i < NumSectors; ++i) {
diff --git a/examples/quick/scenegraph/textureinsgnode/main.qml b/examples/quick/scenegraph/textureinsgnode/main.qml
index c8509707ae..92fa99e847 100644
--- a/examples/quick/scenegraph/textureinsgnode/main.qml
+++ b/examples/quick/scenegraph/textureinsgnode/main.qml
@@ -74,7 +74,7 @@ Item {
uniform highp vec2 pixelSize;
varying highp vec2 qt_TexCoord0;
void main() {
- highp vec2 tc = sign(sin(3.14152 * qt_TexCoord0 * pixelSize));
+ highp vec2 tc = sign(sin(3.14159265358979323846 * qt_TexCoord0 * pixelSize));
if (tc.x != tc.y)
gl_FragColor = color1;
else
diff --git a/examples/quick/scenegraph/textureinthread/main.qml b/examples/quick/scenegraph/textureinthread/main.qml
index f20d318807..eefee92f15 100644
--- a/examples/quick/scenegraph/textureinthread/main.qml
+++ b/examples/quick/scenegraph/textureinthread/main.qml
@@ -74,7 +74,7 @@ Item {
uniform highp vec2 pixelSize;
varying highp vec2 qt_TexCoord0;
void main() {
- highp vec2 tc = sign(sin(3.14152 * qt_TexCoord0 * pixelSize));
+ highp vec2 tc = sign(sin(3.14159265358979323846 * qt_TexCoord0 * pixelSize));
if (tc.x != tc.y)
gl_FragColor = color1;
else
diff --git a/examples/quick/scenegraph/twotextureproviders/main.qml b/examples/quick/scenegraph/twotextureproviders/main.qml
index 641034104c..296df766a1 100644
--- a/examples/quick/scenegraph/twotextureproviders/main.qml
+++ b/examples/quick/scenegraph/twotextureproviders/main.qml
@@ -71,7 +71,7 @@ Item {
uniform highp vec2 pixelSize;
varying highp vec2 qt_TexCoord0;
void main() {
- highp vec2 tc = sign(sin(3.14152 * qt_TexCoord0 * pixelSize));
+ highp vec2 tc = sign(sin(3.14159265358979323846 * qt_TexCoord0 * pixelSize));
if (tc.x != tc.y)
gl_FragColor = color1;
else
diff --git a/examples/quick/shapes/content/clippedtigers.qml b/examples/quick/shapes/content/clippedtigers.qml
new file mode 100644
index 0000000000..c55efdc403
--- /dev/null
+++ b/examples/quick/shapes/content/clippedtigers.qml
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+import QtQuick.Shapes 1.0
+
+Rectangle {
+ id: root
+ width: 1024
+ height: 768
+
+ property color col: "lightsteelblue"
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: Qt.tint(root.col, "#20FFFFFF") }
+ GradientStop { position: 0.1; color: Qt.tint(root.col, "#20AAAAAA") }
+ GradientStop { position: 0.9; color: Qt.tint(root.col, "#20666666") }
+ GradientStop { position: 1.0; color: Qt.tint(root.col, "#20000000") }
+ }
+
+ Rectangle {
+ id: scissorRect
+ width: 200
+ height: 200
+ x: 150
+ property real centerY: parent.height / 2 - height / 2
+ property real dy: 0
+ y: centerY + dy
+ clip: true
+
+ Loader {
+ id: loader1
+ width: parent.width
+ height: parent.height
+ y: 25 - scissorRect.dy
+ source: "tiger.qml"
+ asynchronous: true
+ visible: status === Loader.Ready
+ }
+
+ SequentialAnimation on dy {
+ loops: Animation.Infinite
+ running: loader1.status === Loader.Ready && loader1.item.status === Shape.Ready
+ NumberAnimation {
+ from: 0
+ to: -scissorRect.centerY
+ duration: 2000
+ }
+ NumberAnimation {
+ from: -scissorRect.centerY
+ to: scissorRect.centerY
+ duration: 4000
+ }
+ NumberAnimation {
+ from: scissorRect.centerY
+ to: 0
+ duration: 2000
+ }
+ }
+ }
+
+ // With a more complex transformation (like rotation), stenciling is used
+ // instead of scissoring, this is more expensive. It may also trigger a
+ // slower code path for Shapes, depending on the path rendering backend
+ // in use, and may affect rendering quality as well.
+ Rectangle {
+ id: stencilRect
+ width: 300
+ height: 200
+ anchors.right: parent.right
+ anchors.rightMargin: 100
+ anchors.verticalCenter: parent.verticalCenter
+ clip: true // NB! still clips to bounding rect (not shape)
+
+ Loader {
+ id: loader2
+ width: parent.width
+ height: parent.height
+ source: "tiger.qml"
+ asynchronous: true
+ visible: status === Loader.Ready
+ }
+
+ NumberAnimation on rotation {
+ from: 0
+ to: 360
+ duration: 5000
+ loops: Animation.Infinite
+ }
+ }
+}
diff --git a/examples/quick/shapes/content/interactive.qml b/examples/quick/shapes/content/interactive.qml
new file mode 100644
index 0000000000..55a1d16299
--- /dev/null
+++ b/examples/quick/shapes/content/interactive.qml
@@ -0,0 +1,285 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+import QtQuick.Shapes 1.0
+
+Rectangle {
+ id: root
+ width: 1024
+ height: 768
+
+ property color col: "lightsteelblue"
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: Qt.tint(root.col, "#20FFFFFF") }
+ GradientStop { position: 0.1; color: Qt.tint(root.col, "#20AAAAAA") }
+ GradientStop { position: 0.9; color: Qt.tint(root.col, "#20666666") }
+ GradientStop { position: 1.0; color: Qt.tint(root.col, "#20000000") }
+ }
+
+ property int mode: 0
+ property bool showResizers: true
+ property bool fill: false
+
+ Row {
+ x: 20
+ y: 10
+ spacing: 20
+ Rectangle {
+ border.color: "black"
+ color: root.mode === 0 ? "red" : "transparent"
+ width: 100
+ height: 40
+ Text {
+ anchors.centerIn: parent
+ text: "Line"
+ }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: root.mode = 0
+ }
+ }
+ Rectangle {
+ border.color: "black"
+ color: root.mode === 1 ? "red" : "transparent"
+ width: 100
+ height: 40
+ Text {
+ anchors.centerIn: parent
+ text: "Cubic"
+ }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: root.mode = 1
+ }
+ }
+ Rectangle {
+ border.color: "black"
+ color: root.mode === 2 ? "red" : "transparent"
+ width: 100
+ height: 40
+ Text {
+ anchors.centerIn: parent
+ text: "Quadratic"
+ }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: root.mode = 2
+ }
+ }
+
+ Slider {
+ id: widthSlider
+ name: "Width"
+ min: 1
+ max: 60
+ init: 4
+ }
+
+ Rectangle {
+ border.color: "black"
+ color: root.showResizers ? "yellow" : "transparent"
+ width: 50
+ height: 40
+ Text {
+ anchors.centerIn: parent
+ text: "Manip"
+ }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ root.showResizers = !root.showResizers;
+ for (var i = 0; i < canvas.resizers.length; ++i)
+ canvas.resizers[i].visible = root.showResizers;
+ }
+ }
+ }
+
+ Rectangle {
+ border.color: "black"
+ color: root.fill ? "yellow" : "transparent"
+ width: 50
+ height: 40
+ Text {
+ anchors.centerIn: parent
+ text: "Fill"
+ }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: root.fill = !root.fill
+ }
+ }
+ }
+
+ Rectangle {
+ id: canvas
+ width: root.width - 40
+ height: root.height - 120
+ x: 20
+ y: 100
+
+ property variant activePath: null
+
+ property variant resizers: []
+ property variant funcs
+
+ function genResizer(obj, x, y, xprop, yprop, color) {
+ var ma = Qt.createQmlObject('import QtQuick 2.9; import QtQuick.Shapes 1.0; Rectangle { id: rr; property variant obj; color: "' + color + '"; width: 20; height: 20;'+
+ 'MouseArea { anchors.fill: parent; hoverEnabled: true;' +
+ 'onEntered: color = "yellow"; onExited: color = "' + color + '";' +
+ 'property bool a: false; onPressed: a = true; onReleased: a = false; ' +
+ 'onPositionChanged: if (a) { var pt = mapToItem(rr.parent, mouse.x, mouse.y);' +
+ 'obj.' + xprop + ' = pt.x; obj.' + yprop + ' = pt.y; rr.x = pt.x - 10; rr.y = pt.y - 10; } } }',
+ canvas, "resizer_item");
+ ma.visible = root.showResizers;
+ ma.obj = obj;
+ ma.x = x - 10;
+ ma.y = y - 10;
+ resizers.push(ma);
+ return ma;
+ }
+
+ Component.onCompleted: {
+ funcs = [
+ { "start": function(x, y) {
+ var p = Qt.createQmlObject('import QtQuick 2.9; import QtQuick.Shapes 1.0; ShapePath {' +
+ 'strokeColor: "black"; fillColor: "transparent";'+
+ 'strokeWidth: ' + widthSlider.value + ';' +
+ 'startX: ' + x + '; startY: ' + y + ';' +
+ 'PathLine { x: ' + x + ' + 1; y: ' + y + ' + 1 } }',
+ root, "dynamic_visual_path");
+ shape.data.push(p);
+ activePath = p;
+ }, "move": function(x, y) {
+ if (!activePath)
+ return;
+ var pathObj = activePath.pathElements[0];
+ pathObj.x = x;
+ pathObj.y = y;
+ }, "end": function() {
+ canvas.genResizer(activePath, activePath.startX, activePath.startY, "startX", "startY", "red");
+ var pathObj = activePath.pathElements[0];
+ canvas.genResizer(pathObj, pathObj.x, pathObj.y, "x", "y", "red");
+ activePath = null;
+ }
+ },
+ { "start": function(x, y) {
+ var p = Qt.createQmlObject('import QtQuick 2.9; import QtQuick.Shapes 1.0; ShapePath {' +
+ 'strokeColor: "black"; fillColor: "' + (root.fill ? 'green' : 'transparent') + '";'+
+ 'strokeWidth: ' + widthSlider.value + ';' +
+ 'startX: ' + x + '; startY: ' + y + ';' +
+ 'PathCubic { x: ' + x + ' + 1; y: ' + y + ' + 1;' +
+ 'control1X: ' + x + ' + 50; control1Y: ' + y + ' + 50; control2X: ' + x + ' + 150; control2Y: ' + y + ' + 50; } }',
+ root, "dynamic_visual_path");
+ shape.data.push(p);
+ activePath = p;
+ }, "move": function(x, y) {
+ if (!activePath)
+ return;
+ var pathObj = activePath.pathElements[0];
+ pathObj.x = x;
+ pathObj.y = y;
+ }, "end": function() {
+ canvas.genResizer(activePath, activePath.startX, activePath.startY, "startX", "startY", "red");
+ var pathObj = activePath.pathElements[0];
+ canvas.genResizer(pathObj, pathObj.x, pathObj.y, "x", "y", "red");
+ canvas.genResizer(pathObj, pathObj.control1X, pathObj.control1Y, "control1X", "control1Y", "blue");
+ canvas.genResizer(pathObj, pathObj.control2X, pathObj.control2Y, "control2X", "control2Y", "lightBlue");
+ activePath = null;
+ }
+ },
+ { "start": function(x, y) {
+ var p = Qt.createQmlObject('import QtQuick 2.9; import QtQuick.Shapes 1.0; ShapePath {' +
+ 'strokeColor: "black"; fillColor: "' + (root.fill ? 'green' : 'transparent') + '";'+
+ 'strokeWidth: ' + widthSlider.value + ';' +
+ 'startX: ' + x + '; startY: ' + y + ';' +
+ 'PathQuad { x: ' + x + ' + 1; y: ' + y + ' + 1;' +
+ 'controlX: ' + x + ' + 50; controlY: ' + y + ' + 50 } }',
+ root, "dynamic_visual_path");
+ shape.data.push(p);
+ activePath = p;
+ }, "move": function(x, y) {
+ if (!activePath)
+ return;
+ var pathObj = activePath.pathElements[0];
+ pathObj.x = x;
+ pathObj.y = y;
+ }, "end": function() {
+ canvas.genResizer(activePath, activePath.startX, activePath.startY, "startX", "startY", "red");
+ var pathObj = activePath.pathElements[0];
+ canvas.genResizer(pathObj, pathObj.x, pathObj.y, "x", "y", "red");
+ canvas.genResizer(pathObj, pathObj.controlX, pathObj.controlY, "controlX", "controlY", "blue");
+ activePath = null;
+ }
+ }
+ ];
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onPressed: {
+ canvas.funcs[root.mode].start(mouse.x, mouse.y);
+ }
+ onPositionChanged: {
+ canvas.funcs[root.mode].move(mouse.x, mouse.y);
+ }
+ onReleased: {
+ canvas.funcs[root.mode].end();
+ }
+ }
+
+ Shape {
+ id: shape
+ anchors.fill: parent
+
+ data: []
+ }
+ }
+}
diff --git a/examples/quick/shapes/content/item10.qml b/examples/quick/shapes/content/item10.qml
new file mode 100644
index 0000000000..e91342c2fe
--- /dev/null
+++ b/examples/quick/shapes/content/item10.qml
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+import QtQuick.Shapes 1.0
+
+Rectangle {
+ color: "lightGray"
+
+ Item {
+ width: 200
+ height: 200
+ anchors.centerIn: parent
+
+ Shape {
+ id: shape
+ anchors.fill: parent
+
+ ShapePath {
+ strokeWidth: 4
+ strokeColor: "black"
+ fillGradient: ConicalGradient {
+ id: conGrad
+ centerX: 100; centerY: 75
+ NumberAnimation on angle { from: 0; to: 360; duration: 10000; loops: Animation.Infinite }
+ GradientStop { position: 0; color: "#00000000" }
+ GradientStop { position: 0.10; color: "#ffe0cc73" }
+ GradientStop { position: 0.17; color: "#ffc6a006" }
+ GradientStop { position: 0.46; color: "#ff600659" }
+ GradientStop { position: 0.72; color: "#ff0680ac" }
+ GradientStop { position: 0.92; color: "#ffb9d9e6" }
+ GradientStop { position: 1.00; color: "#00000000" }
+ }
+
+ startX: 50; startY: 100
+ PathCubic {
+ x: 150; y: 100
+ control1X: cp1.x; control1Y: cp1.y
+ control2X: cp2.x; control2Y: cp2.y
+ }
+ }
+ }
+
+ Rectangle {
+ id: cp1
+ color: "red"
+ width: 10; height: 10
+ SequentialAnimation {
+ loops: Animation.Infinite
+ running: true
+ NumberAnimation {
+ target: cp1
+ property: "x"
+ from: 0
+ to: shape.width - cp1.width
+ duration: 5000
+ }
+ NumberAnimation {
+ target: cp1
+ property: "x"
+ from: shape.width - cp1.width
+ to: 0
+ duration: 5000
+ }
+ NumberAnimation {
+ target: cp1
+ property: "y"
+ from: 0
+ to: shape.height - cp1.height
+ duration: 5000
+ }
+ NumberAnimation {
+ target: cp1
+ property: "y"
+ from: shape.height - cp1.height
+ to: 0
+ duration: 5000
+ }
+ }
+ }
+
+ Rectangle {
+ id: cp2
+ color: "blue"
+ width: 10; height: 10
+ x: shape.width - width
+ SequentialAnimation {
+ loops: Animation.Infinite
+ running: true
+ NumberAnimation {
+ target: cp2
+ property: "y"
+ from: 0
+ to: shape.height - cp2.height
+ duration: 5000
+ }
+ NumberAnimation {
+ target: cp2
+ property: "y"
+ from: shape.height - cp2.height
+ to: 0
+ duration: 5000
+ }
+ NumberAnimation {
+ target: cp2
+ property: "x"
+ from: shape.width - cp2.width
+ to: 0
+ duration: 5000
+ }
+ NumberAnimation {
+ target: cp2
+ property: "x"
+ from: 0
+ to: shape.width - cp2.width
+ duration: 5000
+ }
+ }
+ }
+ }
+
+ Text {
+ anchors.right: parent.right
+ anchors.top: parent.top
+ text: "Conical gradient angle: " + Math.round(conGrad.angle)
+ }
+}
diff --git a/examples/quick/shapes/content/item11.qml b/examples/quick/shapes/content/item11.qml
new file mode 100644
index 0000000000..bdd08339e3
--- /dev/null
+++ b/examples/quick/shapes/content/item11.qml
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.11
+import QtQuick.Shapes 1.0
+
+Rectangle {
+ color: "lightGray"
+ Shape {
+ id: shape
+ width: 220
+ height: 200
+ anchors.centerIn: parent
+
+ ShapePath {
+ fillGradient: LinearGradient {
+ y2: shape.height
+ GradientStop { position: 0; color: "yellow" }
+ GradientStop { position: 1; color: "green" }
+ }
+
+ startX: 10; startY: 100
+ PathArc {
+ relativeX: 50; y: 100
+ radiusX: 25; radiusY: 25
+ }
+ PathArc {
+ relativeX: 50; y: 100
+ radiusX: 25; radiusY: 35
+ }
+ PathArc {
+ relativeX: 50; y: 100
+ radiusX: 25; radiusY: 60
+ }
+ PathArc {
+ relativeX: 50; y: 100
+ radiusX: 50; radiusY: 120
+ }
+ }
+ }
+
+ Shape {
+ width: 120
+ height: 130
+ anchors.bottom: parent.bottom
+ anchors.right: parent.right
+
+ scale: 0.5
+
+ ShapePath {
+ fillColor: "transparent"
+ strokeColor: "darkBlue"
+ strokeWidth: 20
+ capStyle: ShapePath.RoundCap
+
+ PathAngleArc {
+ centerX: 65; centerY: 95
+ radiusX: 45; radiusY: 45
+ startAngle: -180
+ SequentialAnimation on sweepAngle {
+ loops: Animation.Infinite
+ NumberAnimation { to: 360; duration: 2000 }
+ NumberAnimation { to: 0; duration: 2000 }
+ }
+ }
+ }
+ }
+}
diff --git a/examples/quick/shapes/content/item12.qml b/examples/quick/shapes/content/item12.qml
new file mode 100644
index 0000000000..8bdd1bfe50
--- /dev/null
+++ b/examples/quick/shapes/content/item12.qml
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+import QtQuick.Shapes 1.0
+
+Rectangle {
+ color: "lightGray"
+ Rectangle {
+ border.color: "black"
+ width: 200
+ height: 200
+ anchors.centerIn: parent
+
+ Shape {
+ anchors.fill: parent
+
+ ShapePath {
+ strokeColor: "transparent"
+
+ fillGradient: LinearGradient {
+ id: grad
+ y1: 50; y2: 150
+ GradientStop { position: 0; color: "black" }
+ GradientStop { position: 1; color: "red" }
+ }
+
+ startX: 10; startY: 10
+ PathLine { relativeX: 180; relativeY: 0 }
+ PathLine { relativeX: 0; relativeY: 180 }
+ PathLine { relativeX: -180; relativeY: 0 }
+ PathLine { relativeX: 0; relativeY: -180 }
+ }
+ }
+
+ Timer {
+ id: spreadTimer
+ interval: 3000
+ running: true
+ repeat: true
+ property variant spreads: [ ShapeGradient.PadSpread, ShapeGradient.RepeatSpread, ShapeGradient.ReflectSpread ]
+ property variant spreadTexts: [ "PadSpread", "RepeatSpread", "ReflectSpread" ]
+ property int spreadIdx: 0
+ onTriggered: { spreadIdx = (spreadIdx + 1) % spreads.length; grad.spread = spreads[spreadIdx] }
+ }
+
+
+ Shape {
+ anchors.fill: parent
+ ShapePath {
+ strokeColor: "gray"
+ strokeWidth: 2
+ fillColor: "transparent"
+ PathMove { x: 0; y: 50 }
+ PathLine { relativeX: 200; relativeY: 0 }
+ PathMove { x: 0; y: 150 }
+ PathLine { relativeX: 200; relativeY: 0 }
+ }
+ }
+ }
+
+ Text {
+ anchors.right: parent.right
+ text: spreadTimer.spreadTexts[spreadTimer.spreadIdx]
+ }
+}
diff --git a/examples/quick/shapes/content/item13.qml b/examples/quick/shapes/content/item13.qml
new file mode 100644
index 0000000000..93160af7d8
--- /dev/null
+++ b/examples/quick/shapes/content/item13.qml
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+import QtQuick.Shapes 1.0
+
+Rectangle {
+ color: "lightGray"
+
+ Rectangle {
+ width: 100
+ height: 100
+ anchors.centerIn: parent
+ border.color: "gray"
+
+ Repeater {
+ model: 2
+ Shape {
+ anchors.fill: parent
+
+ ShapePath {
+ fillColor: "transparent"
+ strokeColor: model.index === 0 ? "red" : "blue"
+ strokeStyle: ShapePath.DashLine
+ strokeWidth: 4
+
+ startX: 4; startY: 4
+ PathArc {
+ id: arc
+ x: 96; y: 96
+ radiusX: 100; radiusY: 100
+ direction: model.index === 0 ? PathArc.Clockwise : PathArc.Counterclockwise
+ }
+ }
+ }
+ }
+ }
+
+ Column {
+ anchors.right: parent.right
+ Text {
+ text: "Clockwise (sweep 1)"
+ color: "red"
+ }
+ Text {
+ text: "Counter clockwise (sweep 0)"
+ color: "blue"
+ }
+ }
+}
diff --git a/examples/quick/shapes/content/item14.qml b/examples/quick/shapes/content/item14.qml
new file mode 100644
index 0000000000..fd5b7d1048
--- /dev/null
+++ b/examples/quick/shapes/content/item14.qml
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+import QtQuick.Shapes 1.0
+
+Rectangle {
+ color: "lightGray"
+
+ Repeater {
+ model: 2
+ Shape {
+ width: 200
+ height: 200
+ anchors.centerIn: parent
+
+ ShapePath {
+ fillColor: "transparent"
+ strokeColor: model.index === 0 ? "red" : "blue"
+ strokeStyle: ShapePath.DashLine
+ strokeWidth: 4
+
+ startX: 50; startY: 100
+ PathArc {
+ x: 100; y: 150
+ radiusX: 50; radiusY: 50
+ useLargeArc: model.index === 1
+ }
+ }
+ }
+ }
+
+ Column {
+ anchors.right: parent.right
+ Text {
+ text: "Small"
+ color: "red"
+ }
+ Text {
+ text: "Large"
+ color: "blue"
+ }
+ }
+}
diff --git a/examples/quick/shapes/content/item15.qml b/examples/quick/shapes/content/item15.qml
new file mode 100644
index 0000000000..eb23b8b3c5
--- /dev/null
+++ b/examples/quick/shapes/content/item15.qml
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+import QtQuick.Shapes 1.0
+
+Rectangle {
+ color: "lightGray"
+
+ Repeater {
+ model: 2
+ Shape {
+ width: 200
+ height: 200
+ anchors.centerIn: parent
+
+ ShapePath {
+ fillColor: "transparent"
+ strokeColor: model.index === 0 ? "red" : "blue"
+ strokeStyle: ShapePath.DashLine
+ strokeWidth: 4
+
+ startX: 50; startY: 100
+ PathArc {
+ x: 150; y: 100
+ radiusX: 50; radiusY: 20
+ xAxisRotation: model.index === 0 ? 0 : 45
+ }
+ }
+ }
+ }
+
+ Repeater {
+ model: 2
+ Shape {
+ width: 200
+ height: 200
+ anchors.centerIn: parent
+
+ ShapePath {
+ fillColor: "transparent"
+ strokeColor: model.index === 0 ? "red" : "blue"
+
+ startX: 50; startY: 100
+ PathArc {
+ x: 150; y: 100
+ radiusX: 50; radiusY: 20
+ xAxisRotation: model.index === 0 ? 0 : 45
+ direction: PathArc.Counterclockwise
+ }
+ }
+ }
+ }
+
+ Column {
+ anchors.right: parent.right
+ Text {
+ text: "0 degrees"
+ color: "red"
+ }
+ Text {
+ text: "45 degrees"
+ color: "blue"
+ }
+ }
+}
diff --git a/examples/quick/shapes/content/item17.qml b/examples/quick/shapes/content/item17.qml
new file mode 100644
index 0000000000..6ee03ddd04
--- /dev/null
+++ b/examples/quick/shapes/content/item17.qml
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+import QtQuick.Shapes 1.0
+
+Rectangle {
+ color: "lightGray"
+
+ Item {
+ anchors.fill: parent
+
+ Text {
+ anchors.centerIn: parent
+ text: "Loading"
+ // Phase #1: Loader loads tiger.qml. After this we have our item.
+ // Phase #2: With some backends (generic) the item will start async processing. Wait for this too.
+ visible: shapeLoader.status != Loader.Ready || shapeLoader.item.status === Shape.Processing
+ }
+
+ Loader {
+ id: shapeLoader
+ anchors.fill: parent
+ source: "tiger.qml"
+ asynchronous: true
+ visible: status == Loader.Ready
+ scale: 0.4
+ }
+ }
+}
diff --git a/examples/quick/shapes/content/item2.qml b/examples/quick/shapes/content/item2.qml
new file mode 100644
index 0000000000..a033ba88c7
--- /dev/null
+++ b/examples/quick/shapes/content/item2.qml
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+import QtQuick.Shapes 1.0
+
+Rectangle {
+ color: "lightGray"
+
+ Shape {
+ id: circ1
+ anchors.fill: parent
+
+ ShapePath {
+ id: p1
+ fillColor: "transparent" // stroke only
+ strokeWidth: 4
+
+ SequentialAnimation on strokeColor {
+ loops: Animation.Infinite
+ ColorAnimation {
+ from: "black"
+ to: "yellow"
+ duration: 5000
+ }
+ ColorAnimation {
+ from: "yellow"
+ to: "green"
+ duration: 5000
+ }
+ ColorAnimation {
+ from: "green"
+ to: "black"
+ duration: 5000
+ }
+ }
+
+ property real r: 60
+ startX: circ1.width / 2 - r
+ startY: circ1.height / 2 - r
+ PathArc {
+ x: circ1.width / 2 + p1.r
+ y: circ1.height / 2 + p1.r
+ radiusX: p1.r; radiusY: p1.r
+ useLargeArc: true
+ }
+ PathArc {
+ x: circ1.width / 2 - p1.r
+ y: circ1.height / 2 - p1.r
+ radiusX: p1.r; radiusY: p1.r
+ useLargeArc: true
+ }
+ }
+ }
+
+ Shape {
+ id: circ2
+ anchors.fill: parent
+
+ SequentialAnimation on opacity {
+ loops: Animation.Infinite
+ NumberAnimation { from: 1.0; to: 0.0; duration: 5000 }
+ NumberAnimation { from: 0.0; to: 1.0; duration: 5000 }
+ }
+
+ ShapePath {
+ id: p2
+ strokeWidth: -1 // or strokeColor: "transparent"
+
+ SequentialAnimation on fillColor {
+ loops: Animation.Infinite
+ ColorAnimation {
+ from: "gray"
+ to: "purple"
+ duration: 3000
+ }
+ ColorAnimation {
+ from: "purple"
+ to: "red"
+ duration: 3000
+ }
+ ColorAnimation {
+ from: "red"
+ to: "gray"
+ duration: 3000
+ }
+ }
+
+ property real r: 40
+ startX: circ2.width / 2 - r
+ startY: circ2.height / 2 - r
+ PathArc {
+ x: circ2.width / 2 + p2.r
+ y: circ2.height / 2 + p2.r
+ radiusX: p2.r; radiusY: p2.r
+ useLargeArc: true
+ }
+ PathArc {
+ x: circ2.width / 2 - p2.r
+ y: circ2.height / 2 - p2.r
+ radiusX: p2.r; radiusY: p2.r
+ useLargeArc: true
+ }
+ }
+ }
+}
diff --git a/examples/quick/shapes/content/item3.qml b/examples/quick/shapes/content/item3.qml
new file mode 100644
index 0000000000..4274f260f3
--- /dev/null
+++ b/examples/quick/shapes/content/item3.qml
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+import QtQuick.Shapes 1.0
+
+Rectangle {
+ color: "lightGray"
+ Shape {
+ width: 200
+ height: 150
+ anchors.centerIn: parent
+ ShapePath {
+ strokeWidth: 4
+ strokeColor: "red"
+ fillGradient: RadialGradient {
+ centerX: 100; centerY: 100; centerRadius: 100
+ SequentialAnimation on focalRadius {
+ loops: Animation.Infinite
+ NumberAnimation { from: 1; to: 20; duration: 2000 }
+ NumberAnimation { from: 20; to: 1; duration: 2000 }
+ }
+ SequentialAnimation on focalX {
+ loops: Animation.Infinite
+ NumberAnimation { from: 50; to: 150; duration: 3000 }
+ NumberAnimation { from: 150; to: 50; duration: 3000 }
+ }
+ SequentialAnimation on focalY {
+ loops: Animation.Infinite
+ NumberAnimation { from: 50; to: 150; duration: 1000 }
+ NumberAnimation { from: 150; to: 50; duration: 1000 }
+ }
+ GradientStop { position: 0; color: "#ffffff" }
+ GradientStop { position: 0.11; color: "#f9ffa0" }
+ GradientStop { position: 0.13; color: "#f9ff99" }
+ GradientStop { position: 0.14; color: "#f3ff86" }
+ GradientStop { position: 0.49; color: "#93b353" }
+ GradientStop { position: 0.87; color: "#264619" }
+ GradientStop { position: 0.96; color: "#0c1306" }
+ GradientStop { position: 1; color: "#000000" }
+ }
+ fillColor: "blue" // ignored with the gradient set
+ strokeStyle: ShapePath.DashLine
+ dashPattern: [ 1, 4 ]
+ startX: 20; startY: 20
+ PathLine { x: 180; y: 130 }
+ PathLine { x: 20; y: 130 }
+ PathLine { x: 20; y: 20 }
+ }
+ }
+}
diff --git a/examples/quick/shapes/content/item4.qml b/examples/quick/shapes/content/item4.qml
new file mode 100644
index 0000000000..2b20c0a263
--- /dev/null
+++ b/examples/quick/shapes/content/item4.qml
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+import QtQuick.Shapes 1.0
+
+Rectangle {
+ color: "lightGray"
+ Shape {
+ id: shape
+ anchors.fill: parent
+
+ ShapePath {
+ id: p
+ strokeWidth: 5
+ strokeColor: "blue"
+ strokeStyle: ShapePath.DashLine
+ dashPattern: [ 1, 4, 4, 4 ]
+ fillColor: "lightBlue"
+
+ property real xr: 70
+ property real yr: 30
+ startX: shape.width / 2 - xr
+ startY: shape.height / 2 - yr
+ PathArc {
+ x: shape.width / 2 + p.xr
+ y: shape.height / 2 + p.yr
+ radiusX: p.xr; radiusY: p.yr
+ useLargeArc: true
+ }
+ PathArc {
+ x: shape.width / 2 - p.xr
+ y: shape.height / 2 - p.yr
+ radiusX: p.xr; radiusY: p.yr
+ useLargeArc: true
+ }
+ }
+ }
+}
diff --git a/examples/quick/shapes/content/item5.qml b/examples/quick/shapes/content/item5.qml
new file mode 100644
index 0000000000..5fd25093ae
--- /dev/null
+++ b/examples/quick/shapes/content/item5.qml
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+import QtQuick.Shapes 1.0
+
+Rectangle {
+ color: "lightGray"
+ Shape {
+ width: 200
+ height: 150
+ anchors.centerIn: parent
+ ShapePath {
+ strokeWidth: 4
+ strokeColor: "red"
+ fillGradient: LinearGradient {
+ x1: 20; y1: 20
+ x2: 180; y2: 130
+ GradientStop { position: 0; color: "blue" }
+ GradientStop { position: 0.2; color: "green" }
+ GradientStop { position: 0.4; color: "red" }
+ GradientStop { position: 0.6; color: "yellow" }
+ GradientStop { position: 1; color: "cyan" }
+ }
+ fillColor: "blue" // ignored with the gradient set
+ strokeStyle: ShapePath.DashLine
+ dashPattern: [ 1, 4 ]
+ startX: 20; startY: 20
+ PathLine { x: 180; y: 130 }
+ PathLine { x: 20; y: 130 }
+ PathLine { x: 20; y: 20 }
+ }
+ transform: Rotation { origin.x: 100; origin.y: 50; axis { x: 0; y: 1; z: 0 }
+ SequentialAnimation on angle {
+ NumberAnimation { from: 0; to: 75; duration: 2000 }
+ NumberAnimation { from: 75; to: -75; duration: 4000 }
+ NumberAnimation { from: -75; to: 0; duration: 2000 }
+ loops: Animation.Infinite
+ }
+ }
+ }
+}
diff --git a/examples/quick/shapes/content/item6.qml b/examples/quick/shapes/content/item6.qml
new file mode 100644
index 0000000000..f0791c30d2
--- /dev/null
+++ b/examples/quick/shapes/content/item6.qml
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+import QtQuick.Shapes 1.0
+
+Rectangle {
+ color: "lightGray"
+ Shape {
+ width: 100
+ height: 100
+ anchors.centerIn: parent
+ ShapePath {
+ id: star
+ strokeColor: "blue"
+ fillColor: "magenta"
+ strokeWidth: 2
+ PathMove { x: 90; y: 50 }
+ PathLine { x: 50 + 40 * Math.cos(0.8 * 1 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 1 * Math.PI) }
+ PathLine { x: 50 + 40 * Math.cos(0.8 * 2 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 2 * Math.PI) }
+ PathLine { x: 50 + 40 * Math.cos(0.8 * 3 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 3 * Math.PI) }
+ PathLine { x: 50 + 40 * Math.cos(0.8 * 4 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 4 * Math.PI) }
+ PathLine { x: 90; y: 50 }
+ }
+ NumberAnimation on rotation {
+ from: 0
+ to: 360
+ duration: 5000
+ loops: Animation.Infinite
+ }
+ }
+ Timer {
+ interval: 2000
+ onTriggered: star.fillRule = (star.fillRule === ShapePath.OddEvenFill ? ShapePath.WindingFill : ShapePath.OddEvenFill)
+ repeat: true
+ running: true
+ }
+ Text {
+ anchors.right: parent.right
+ text: star.fillRule === ShapePath.OddEvenFill ? "OddEvenFill" : "WindingFill"
+ }
+}
diff --git a/examples/quick/shapes/content/item7.qml b/examples/quick/shapes/content/item7.qml
new file mode 100644
index 0000000000..ff5c5702da
--- /dev/null
+++ b/examples/quick/shapes/content/item7.qml
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+import QtQuick.Shapes 1.0
+
+Rectangle {
+ color: "lightGray"
+
+ Shape {
+ width: 120
+ height: 120
+ anchors.centerIn: parent
+
+ ShapePath {
+ id: joinTest
+
+ strokeColor: "black"
+ strokeWidth: 16
+ fillColor: "transparent"
+ capStyle: ShapePath.RoundCap
+
+ property int joinStyleIdx: 0
+ property variant styles: [ ShapePath.BevelJoin, ShapePath.MiterJoin, ShapePath.RoundJoin ]
+ property variant styleTexts: [ "BevelJoin", "MiterJoin", "RoundJoin" ]
+
+ joinStyle: styles[joinStyleIdx]
+
+ startX: 30
+ startY: 30
+ PathLine { x: 100; y: 100 }
+ PathLine { x: 30; y: 100 }
+ }
+ }
+
+ Timer {
+ interval: 1000
+ repeat: true
+ running: true
+ onTriggered: joinTest.joinStyleIdx = (joinTest.joinStyleIdx + 1) % joinTest.styles.length
+ }
+
+ Text {
+ id: txt
+ anchors.right: parent.right
+ text: joinTest.styleTexts[joinTest.joinStyleIdx]
+ }
+}
diff --git a/examples/quick/shapes/content/item8.qml b/examples/quick/shapes/content/item8.qml
new file mode 100644
index 0000000000..07f633fa56
--- /dev/null
+++ b/examples/quick/shapes/content/item8.qml
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+import QtQuick.Shapes 1.0
+
+Rectangle {
+ color: "lightGray"
+
+ Shape {
+ anchors.centerIn: parent
+ width: 200
+ height: 100
+
+ ShapePath {
+ id: capTest
+ strokeColor: "green"
+ strokeWidth: 20
+ fillColor: "transparent"
+
+ property int capStyleIdx: 0
+ property variant styles: [ ShapePath.FlatCap, ShapePath.SquareCap, ShapePath.RoundCap ]
+ property variant styleTexts: [ "FlatCap", "SquareCap", "RoundCap" ]
+
+ capStyle: styles[capStyleIdx]
+
+ startX: 40; startY: 30
+ PathQuad { x: 50; y: 80; controlX: 0; controlY: 80 }
+ PathLine { x: 150; y: 80 }
+ PathQuad { x: 160; y: 30; controlX: 200; controlY: 80 }
+ }
+ }
+
+ Timer {
+ interval: 1000
+ repeat: true
+ running: true
+ onTriggered: capTest.capStyleIdx = (capTest.capStyleIdx + 1) % capTest.styles.length
+ }
+
+ Text {
+ id: txt
+ anchors.right: parent.right
+ text: capTest.styleTexts[capTest.capStyleIdx]
+ }
+}
diff --git a/examples/quick/shapes/content/item9.qml b/examples/quick/shapes/content/item9.qml
new file mode 100644
index 0000000000..4e5b4022b6
--- /dev/null
+++ b/examples/quick/shapes/content/item9.qml
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+import QtQuick.Shapes 1.0
+
+Rectangle {
+ color: "lightGray"
+
+ Item {
+ width: 200
+ height: 100
+ anchors.centerIn: parent
+
+ Shape {
+ id: shape
+ anchors.fill: parent
+
+ ShapePath {
+ strokeWidth: 4
+ strokeColor: "black"
+ fillColor: "transparent"
+
+ startX: 50
+ startY: 50
+ PathQuad {
+ x: 150; y: 50
+ controlX: cp.x; controlY: cp.y
+ }
+ }
+ }
+
+ Rectangle {
+ id: cp
+ color: "red"
+ width: 10
+ height: 10
+ SequentialAnimation on x {
+ loops: Animation.Infinite
+ NumberAnimation {
+ from: 0
+ to: shape.width - cp.width
+ duration: 5000
+ }
+ NumberAnimation {
+ from: shape.width - cp.width
+ to: 0
+ duration: 5000
+ }
+ }
+ }
+ }
+}
diff --git a/examples/quick/shapes/content/main.qml b/examples/quick/shapes/content/main.qml
new file mode 100644
index 0000000000..8efa47d30b
--- /dev/null
+++ b/examples/quick/shapes/content/main.qml
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Item {
+ width: 1280
+ height: 720
+ LauncherList {
+ anchors.fill: parent
+ Component.onCompleted: {
+ addExample("Shape Gallery", "Simple path rendering examples", Qt.resolvedUrl("shapegallery.qml"))
+ addExample("Interactive Shape", "Dynamic, interactive path rendering examples", Qt.resolvedUrl("interactive.qml"))
+ addExample("Super- and multisampling", "Improving quality", Qt.resolvedUrl("sampling.qml"))
+ addExample("Clip My Tiger!", "Clip examples, a.k.a. What Not To Do", Qt.resolvedUrl("clippedtigers.qml"))
+ }
+ }
+}
diff --git a/examples/quick/shapes/content/sampling.qml b/examples/quick/shapes/content/sampling.qml
new file mode 100644
index 0000000000..6b651f8a1d
--- /dev/null
+++ b/examples/quick/shapes/content/sampling.qml
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+import QtQuick.Shapes 1.0
+
+Rectangle {
+ id: root
+ width: 1024
+ height: 768
+
+ property color col: "lightsteelblue"
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: Qt.tint(root.col, "#20FFFFFF") }
+ GradientStop { position: 0.1; color: Qt.tint(root.col, "#20AAAAAA") }
+ GradientStop { position: 0.9; color: Qt.tint(root.col, "#20666666") }
+ GradientStop { position: 1.0; color: Qt.tint(root.col, "#20000000") }
+ }
+
+ Row {
+ anchors.fill: parent
+ anchors.margins: 20
+ spacing: 40
+
+ Column {
+ spacing: 40
+
+ Text {
+ text: "Original"
+ }
+
+ // A simple Shape without anything special.
+ Rectangle {
+ color: "lightGray"
+ width: 400
+ height: 200
+
+ Shape {
+ x: 30
+ y: 20
+ width: 50
+ height: 50
+ scale: 2
+
+ ShapePath {
+ strokeColor: "green"
+ NumberAnimation on strokeWidth { from: 1; to: 20; duration: 5000 }
+ fillColor: "transparent"
+ capStyle: ShapePath.RoundCap
+
+ startX: 40; startY: 30
+ PathQuad { x: 50; y: 80; controlX: 0; controlY: 80 }
+ PathLine { x: 150; y: 80 }
+ PathQuad { x: 160; y: 30; controlX: 200; controlY: 80 }
+ }
+ }
+ }
+
+ Text {
+ text: "Supersampling (2x)"
+ }
+
+ // Now let's use 2x supersampling via layers. This way the entire subtree
+ // is rendered into an FBO twice the size and then drawn with linear
+ // filtering. This allows having some level of AA even when there is no
+ // support for multisample framebuffers.
+ Rectangle {
+ id: supersampledItem
+ color: "lightGray"
+ width: 400
+ height: 200
+
+ layer.enabled: true
+ layer.smooth: true
+ layer.textureSize: Qt.size(supersampledItem.width * 2, supersampledItem.height * 2)
+
+ Shape {
+ x: 30
+ y: 20
+ width: 50
+ height: 50
+ scale: 2
+
+ ShapePath {
+ strokeColor: "green"
+ NumberAnimation on strokeWidth { from: 1; to: 20; duration: 5000 }
+ fillColor: "transparent"
+ capStyle: ShapePath.RoundCap
+
+ startX: 40; startY: 30
+ PathQuad { x: 50; y: 80; controlX: 0; controlY: 80 }
+ PathLine { x: 150; y: 80 }
+ PathQuad { x: 160; y: 30; controlX: 200; controlY: 80 }
+ }
+ }
+ }
+ }
+
+ Column {
+ spacing: 40
+
+ Text {
+ text: "Multisampling (4x)"
+ }
+
+ // Now let's use 4x MSAA, again via layers. This needs support for
+ // multisample renderbuffers and framebuffer blits.
+ Rectangle {
+ color: "lightGray"
+ width: 400
+ height: 200
+
+ layer.enabled: true
+ layer.smooth: true
+ layer.samples: 4
+
+ Shape {
+ x: 30
+ y: 20
+ width: 50
+ height: 50
+ scale: 2
+
+ ShapePath {
+ strokeColor: "green"
+ NumberAnimation on strokeWidth { from: 1; to: 20; duration: 5000 }
+ fillColor: "transparent"
+ capStyle: ShapePath.RoundCap
+
+ startX: 40; startY: 30
+ PathQuad { x: 50; y: 80; controlX: 0; controlY: 80 }
+ PathLine { x: 150; y: 80 }
+ PathQuad { x: 160; y: 30; controlX: 200; controlY: 80 }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/examples/quick/shapes/content/shapegallery.qml b/examples/quick/shapes/content/shapegallery.qml
new file mode 100644
index 0000000000..86445e25c2
--- /dev/null
+++ b/examples/quick/shapes/content/shapegallery.qml
@@ -0,0 +1,196 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+import QtQuick.Shapes 1.0
+
+Rectangle {
+ id: root
+ width: 1024
+ height: 768
+
+ property color col: "lightsteelblue"
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: Qt.tint(root.col, "#20FFFFFF") }
+ GradientStop { position: 0.1; color: Qt.tint(root.col, "#20AAAAAA") }
+ GradientStop { position: 0.9; color: Qt.tint(root.col, "#20666666") }
+ GradientStop { position: 1.0; color: Qt.tint(root.col, "#20000000") }
+ }
+
+ ListModel {
+ id: pathGalleryModel
+ ListElement {
+ name: "Stroke and fill"
+ shapeUrl: "tapableTriangle.qml"
+ }
+ ListElement {
+ name: "Stroke or fill only"
+ shapeUrl: "item2.qml"
+ }
+ ListElement {
+ name: "Dash pattern"
+ shapeUrl: "item4.qml"
+ }
+ ListElement {
+ name: "Linear gradient"
+ shapeUrl: "item5.qml"
+ }
+ ListElement {
+ name: "Radial gradient"
+ shapeUrl: "item3.qml"
+ }
+ ListElement {
+ name: "Fill rules"
+ shapeUrl: "item6.qml"
+ }
+ ListElement {
+ name: "Join styles"
+ shapeUrl: "item7.qml"
+ }
+ ListElement {
+ name: "Cap styles"
+ shapeUrl: "item8.qml"
+ }
+ ListElement {
+ name: "Quadratic curve"
+ shapeUrl: "item9.qml"
+ }
+ ListElement {
+ name: "Cubic curve"
+ shapeUrl: "item10.qml"
+ }
+ ListElement {
+ name: "Elliptical arc"
+ shapeUrl: "item11.qml"
+ }
+ ListElement {
+ name: "Gradient spread modes"
+ shapeUrl: "item12.qml"
+ }
+ ListElement {
+ name: "Arc direction"
+ shapeUrl: "item13.qml"
+ }
+ ListElement {
+ name: "Large/small arc"
+ shapeUrl: "item14.qml"
+ }
+ ListElement {
+ name: "Arc rotation"
+ shapeUrl: "item15.qml"
+ }
+ ListElement {
+ name: "Tiger"
+ shapeUrl: "item17.qml"
+ }
+ }
+
+ property int gridSpacing: 10
+
+ Component {
+ id: pathGalleryDelegate
+ Rectangle {
+ border.color: "purple"
+ width: grid.cellWidth - root.gridSpacing
+ height: grid.cellHeight - root.gridSpacing
+ Column {
+ anchors.fill: parent
+ anchors.margins: 4
+ Item {
+ width: parent.width
+ height: parent.height - delegText.height
+ Loader {
+ source: Qt.resolvedUrl(shapeUrl)
+ anchors.fill: parent
+ }
+ }
+ Text {
+ id: delegText
+ text: model.name
+ font.pointSize: 16
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ anchors.fill: parent
+ anchors.margins: 10
+ color: "lightBlue"
+ clip: true
+
+ GridView {
+ id: grid
+ anchors.fill: parent
+ anchors.margins: root.gridSpacing
+ cellWidth: 300
+ cellHeight: 300
+ delegate: pathGalleryDelegate
+ model: pathGalleryModel
+ }
+ }
+
+ Text {
+ anchors.right: parent.right
+ Shape { id: dummyShape; ShapePath { } } // used only to get the renderer type
+ color: "darkBlue"
+ font.pointSize: 12
+ property variant rendererStrings: [ "Unknown", "Generic (QtGui triangulator)", "GL_NV_path_rendering", "Software (QPainter)" ]
+ text: "Active Shape backend: " + rendererStrings[dummyShape.rendererType]
+ SequentialAnimation on opacity {
+ NumberAnimation { from: 1; to: 0; duration: 5000 }
+ PauseAnimation { duration: 5000 }
+ NumberAnimation { from: 0; to: 1; duration: 1000 }
+ PauseAnimation { duration: 5000 }
+ loops: Animation.Infinite
+ }
+ }
+}
diff --git a/examples/quick/shapes/content/tapableTriangle.qml b/examples/quick/shapes/content/tapableTriangle.qml
new file mode 100644
index 0000000000..274552f525
--- /dev/null
+++ b/examples/quick/shapes/content/tapableTriangle.qml
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.11
+import QtQuick.Shapes 1.11
+import Qt.labs.handlers 1.0
+
+Rectangle {
+ width: 120
+ height: 120
+ color: th.pressed ? "steelBlue" : "lightGray"
+ containsMask: ctr
+
+ TapHandler { id: th }
+
+ Shape {
+ id: ctr
+ anchors.fill: parent
+ containsMode: Shape.FillContains
+
+ ShapePath {
+ strokeColor: "red"
+ fillColor: "blue"
+
+ SequentialAnimation on strokeWidth {
+ loops: Animation.Infinite
+ NumberAnimation { from: 1; to: 30; duration: 5000 }
+ NumberAnimation { from: 30; to: 1; duration: 5000 }
+ PauseAnimation { duration: 2000 }
+ }
+
+ startX: 30; startY: 30
+ PathLine { x: ctr.width - 30; y: ctr.height - 30 }
+ PathLine { x: 30; y: ctr.height - 30 }
+ PathLine { x: 30; y: 30 }
+ }
+
+ // Besides ShapePath, Shape supports visual and non-visual objects too, allowing
+ // free mixing without going through extra hoops:
+ Rectangle {
+ id: testRect
+ color: "green"
+ opacity: 0.3
+ width: 20
+ height: 20
+ anchors.right: parent.right
+ }
+ Timer {
+ interval: 100
+ repeat: true
+ onTriggered: testRect.width = testRect.width > 1 ? testRect.width - 1 : 20
+ running: true
+ }
+ }
+}
diff --git a/examples/quick/shapes/content/tiger.qml b/examples/quick/shapes/content/tiger.qml
new file mode 100644
index 0000000000..7fa6ca2706
--- /dev/null
+++ b/examples/quick/shapes/content/tiger.qml
@@ -0,0 +1,3715 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.11
+import QtQuick.Shapes 1.11
+import Qt.labs.handlers 1.0
+
+Shape {
+ asynchronous: true
+ width: 494; height: 510
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.172
+ PathMove { x: -122.304; y: 84.285 }
+ PathCubic { control1X: -122.304; control1Y: 84.285; control2X: -122.203; control2Y: 86.179; x: -123.027; y: 86.16 }
+ PathCubic { control1X: -123.851; control1Y: 86.141; control2X: -140.305; control2Y: 38.066; x: -160.833; y: 40.309 }
+ PathCubic { control1X: -160.833; control1Y: 40.309; control2X: -143.05; control2Y: 32.956; x: -122.304; y: 84.285 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.172
+ PathMove { x: -118.774; y: 81.262 }
+ PathCubic { control1X: -118.774; control1Y: 81.262; control2X: -119.323; control2Y: 83.078; x: -120.092; y: 82.779 }
+ PathCubic { control1X: -120.86; control1Y: 82.481; control2X: -119.977; control2Y: 31.675; x: -140.043; y: 26.801 }
+ PathCubic { control1X: -140.043; control1Y: 26.801; control2X: -120.82; control2Y: 25.937; x: -118.774; y: 81.262 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.172
+ PathMove { x: -91.284; y: 123.59 }
+ PathCubic { control1X: -91.284; control1Y: 123.59; control2X: -89.648; control2Y: 124.55; x: -90.118; y: 125.227 }
+ PathCubic { control1X: -90.589; control1Y: 125.904; control2X: -139.763; control2Y: 113.102; x: -149.218; y: 131.459 }
+ PathCubic { control1X: -149.218; control1Y: 131.459; control2X: -145.539; control2Y: 112.572; x: -91.284; y: 123.59 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.172
+ PathMove { x: -94.093; y: 133.801 }
+ PathCubic { control1X: -94.093; control1Y: 133.801; control2X: -92.237; control2Y: 134.197; x: -92.471; y: 134.988 }
+ PathCubic { control1X: -92.704; control1Y: 135.779; control2X: -143.407; control2Y: 139.121; x: -146.597; y: 159.522 }
+ PathCubic { control1X: -146.597; control1Y: 159.522; control2X: -149.055; control2Y: 140.437; x: -94.093; y: 133.801 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.172
+ PathMove { x: -98.304; y: 128.276 }
+ PathCubic { control1X: -98.304; control1Y: 128.276; control2X: -96.526; control2Y: 128.939; x: -96.872; y: 129.687 }
+ PathCubic { control1X: -97.218; control1Y: 130.435; control2X: -147.866; control2Y: 126.346; x: -153.998; y: 146.064 }
+ PathCubic { control1X: -153.998; control1Y: 146.064; control2X: -153.646; control2Y: 126.825; x: -98.304; y: 128.276 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.172
+ PathMove { x: -109.009; y: 110.072 }
+ PathCubic { control1X: -109.009; control1Y: 110.072; control2X: -107.701; control2Y: 111.446; x: -108.34; y: 111.967 }
+ PathCubic { control1X: -108.979; control1Y: 112.488; control2X: -152.722; control2Y: 86.634; x: -166.869; y: 101.676 }
+ PathCubic { control1X: -166.869; control1Y: 101.676; control2X: -158.128; control2Y: 84.533; x: -109.009; y: 110.072 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.172
+ PathMove { x: -116.554; y: 114.263 }
+ PathCubic { control1X: -116.554; control1Y: 114.263; control2X: -115.098; control2Y: 115.48; x: -115.674; y: 116.071 }
+ PathCubic { control1X: -116.25; control1Y: 116.661; control2X: -162.638; control2Y: 95.922; x: -174.992; y: 112.469 }
+ PathCubic { control1X: -174.992; control1Y: 112.469; control2X: -168.247; control2Y: 94.447; x: -116.554; y: 114.263 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.172
+ PathMove { x: -119.154; y: 118.335 }
+ PathCubic { control1X: -119.154; control1Y: 118.335; control2X: -117.546; control2Y: 119.343; x: -118.036; y: 120.006 }
+ PathCubic { control1X: -118.526; control1Y: 120.669; control2X: -167.308; control2Y: 106.446; x: -177.291; y: 124.522 }
+ PathCubic { control1X: -177.291; control1Y: 124.522; control2X: -173.066; control2Y: 105.749; x: -119.154; y: 118.335 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.172
+ PathMove { x: -108.42; y: 118.949 }
+ PathCubic { control1X: -108.42; control1Y: 118.949; control2X: -107.298; control2Y: 120.48; x: -107.999; y: 120.915 }
+ PathCubic { control1X: -108.7; control1Y: 121.35; control2X: -148.769; control2Y: 90.102; x: -164.727; y: 103.207 }
+ PathCubic { control1X: -164.727; control1Y: 103.207; control2X: -153.862; control2Y: 87.326; x: -108.42; y: 118.949 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.172
+ PathMove { x: -128.2; y: 90 }
+ PathCubic { control1X: -128.2; control1Y: 90; control2X: -127.6; control2Y: 91.8; x: -128.4; y: 92 }
+ PathCubic { control1X: -129.2; control1Y: 92.2; control2X: -157.8; control2Y: 50.2; x: -177.001; y: 57.8 }
+ PathCubic { control1X: -177.001; control1Y: 57.8; control2X: -161.8; control2Y: 46; x: -128.2; y: 90 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.172
+ PathMove { x: -127.505; y: 96.979 }
+ PathCubic { control1X: -127.505; control1Y: 96.979; control2X: -126.53; control2Y: 98.608; x: -127.269; y: 98.975 }
+ PathCubic { control1X: -128.007; control1Y: 99.343; control2X: -164.992; control2Y: 64.499; x: -182.101; y: 76.061 }
+ PathCubic { control1X: -182.101; control1Y: 76.061; control2X: -169.804; control2Y: 61.261; x: -127.505; y: 96.979 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.172
+ PathMove { x: -127.62; y: 101.349 }
+ PathCubic { control1X: -127.62; control1Y: 101.349; control2X: -126.498; control2Y: 102.88; x: -127.199; y: 103.315 }
+ PathCubic { control1X: -127.9; control1Y: 103.749; control2X: -167.969; control2Y: 72.502; x: -183.927; y: 85.607 }
+ PathCubic { control1X: -183.927; control1Y: 85.607; control2X: -173.062; control2Y: 69.726; x: -127.62; y: 101.349 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 1
+ PathMove { x: -129.83; y: 103.065 }
+ PathCubic { control1X: -129.327; control1Y: 109.113; control2X: -128.339; control2Y: 115.682; x: -126.6; y: 118.801 }
+ PathCubic { control1X: -126.6; control1Y: 118.801; control2X: -130.2; control2Y: 131.201; x: -121.4; y: 144.401 }
+ PathCubic { control1X: -121.4; control1Y: 144.401; control2X: -121.8; control2Y: 151.601; x: -120.2; y: 154.801 }
+ PathCubic { control1X: -120.2; control1Y: 154.801; control2X: -116.2; control2Y: 163.201; x: -111.4; y: 164.001 }
+ PathCubic { control1X: -107.516; control1Y: 164.648; control2X: -98.793; control2Y: 167.717; x: -88.932; y: 169.121 }
+ PathCubic { control1X: -88.932; control1Y: 169.121; control2X: -71.8; control2Y: 183.201; x: -75; y: 196.001 }
+ PathCubic { control1X: -75; control1Y: 196.001; control2X: -75.4; control2Y: 212.401; x: -79; y: 214.001 }
+ PathCubic { control1X: -79; control1Y: 214.001; control2X: -67.4; control2Y: 202.801; x: -77; y: 219.601 }
+ PathLine { x: -81.4; y: 238.401 }
+ PathCubic { control1X: -81.4; control1Y: 238.401; control2X: -55.8; control2Y: 216.801; x: -71.4; y: 235.201 }
+ PathLine { x: -81.4; y: 261.201 }
+ PathCubic { control1X: -81.4; control1Y: 261.201; control2X: -61.8; control2Y: 242.801; x: -69; y: 251.201 }
+ PathLine { x: -72.2; y: 260.001 }
+ PathCubic { control1X: -72.2; control1Y: 260.001; control2X: -29; control2Y: 232.801; x: -59.8; y: 262.401 }
+ PathCubic { control1X: -59.8; control1Y: 262.401; control2X: -51.8; control2Y: 258.801; x: -47.4; y: 261.601 }
+ PathCubic { control1X: -47.4; control1Y: 261.601; control2X: -40.6; control2Y: 260.401; x: -41.4; y: 262.001 }
+ PathCubic { control1X: -41.4; control1Y: 262.001; control2X: -62.2; control2Y: 272.401; x: -65.8; y: 290.801 }
+ PathCubic { control1X: -65.8; control1Y: 290.801; control2X: -57.4; control2Y: 280.801; x: -60.6; y: 291.601 }
+ PathLine { x: -60.2; y: 303.201 }
+ PathCubic { control1X: -60.2; control1Y: 303.201; control2X: -56.2; control2Y: 281.601; x: -56.6; y: 319.201 }
+ PathCubic { control1X: -56.6; control1Y: 319.201; control2X: -37.4; control2Y: 301.201; x: -49; y: 322.001 }
+ PathLine { x: -49; y: 338.801 }
+ PathCubic { control1X: -49; control1Y: 338.801; control2X: -33.8; control2Y: 322.401; x: -40.2; y: 335.201 }
+ PathCubic { control1X: -40.2; control1Y: 335.201; control2X: -30.2; control2Y: 326.401; x: -34.2; y: 341.601 }
+ PathCubic { control1X: -34.2; control1Y: 341.601; control2X: -35; control2Y: 352.001; x: -30.6; y: 340.801 }
+ PathCubic { control1X: -30.6; control1Y: 340.801; control2X: -14.6; control2Y: 310.201; x: -20.6; y: 336.401 }
+ PathCubic { control1X: -20.6; control1Y: 336.401; control2X: -21.4; control2Y: 355.601; x: -16.6; y: 340.801 }
+ PathCubic { control1X: -16.6; control1Y: 340.801; control2X: -16.2; control2Y: 351.201; x: -7; y: 358.401 }
+ PathCubic { control1X: -7; control1Y: 358.401; control2X: -8.2; control2Y: 307.601; x: 4.6; y: 343.601 }
+ PathLine { x: 8.6; y: 360.001 }
+ PathCubic { control1X: 8.6; control1Y: 360.001; control2X: 11.4; control2Y: 350.801; x: 11; y: 345.601 }
+ PathCubic { control1X: 11; control1Y: 345.601; control2X: 25.8; control2Y: 329.201; x: 19; y: 353.601 }
+ PathCubic { control1X: 19; control1Y: 353.601; control2X: 34.2; control2Y: 330.801; x: 31; y: 344.001 }
+ PathCubic { control1X: 31; control1Y: 344.001; control2X: 23.4; control2Y: 360.001; x: 25; y: 364.801 }
+ PathCubic { control1X: 25; control1Y: 364.801; control2X: 41.8; control2Y: 330.001; x: 43; y: 328.401 }
+ PathCubic { control1X: 43; control1Y: 328.401; control2X: 41; control2Y: 370.802; x: 51.8; y: 334.801 }
+ PathCubic { control1X: 51.8; control1Y: 334.801; control2X: 57.4; control2Y: 346.801; x: 54.6; y: 351.201 }
+ PathCubic { control1X: 54.6; control1Y: 351.201; control2X: 62.6; control2Y: 343.201; x: 61.8; y: 340.001 }
+ PathCubic { control1X: 61.8; control1Y: 340.001; control2X: 66.4; control2Y: 331.801; x: 69.2; y: 345.401 }
+ PathCubic { control1X: 69.2; control1Y: 345.401; control2X: 71; control2Y: 354.801; x: 72.6; y: 351.601 }
+ PathCubic { control1X: 72.6; control1Y: 351.601; control2X: 76.6; control2Y: 375.602; x: 77.8; y: 352.801 }
+ PathCubic { control1X: 77.8; control1Y: 352.801; control2X: 79.4; control2Y: 339.201; x: 72.2; y: 327.601 }
+ PathCubic { control1X: 72.2; control1Y: 327.601; control2X: 73; control2Y: 324.401; x: 70.2; y: 320.401 }
+ PathCubic { control1X: 70.2; control1Y: 320.401; control2X: 83.8; control2Y: 342.001; x: 76.6; y: 313.201 }
+ PathCubic { control1X: 76.6; control1Y: 313.201; control2X: 87.801; control2Y: 321.201; x: 89.001; y: 321.201 }
+ PathCubic { control1X: 89.001; control1Y: 321.201; control2X: 75.4; control2Y: 298.001; x: 84.2; y: 302.801 }
+ PathCubic { control1X: 84.2; control1Y: 302.801; control2X: 79; control2Y: 292.401; x: 97.001; y: 304.401 }
+ PathCubic { control1X: 97.001; control1Y: 304.401; control2X: 81; control2Y: 288.401; x: 98.601; y: 298.001 }
+ PathCubic { control1X: 98.601; control1Y: 298.001; control2X: 106.601; control2Y: 304.401; x: 99.001; y: 294.401 }
+ PathCubic { control1X: 99.001; control1Y: 294.401; control2X: 84.6; control2Y: 278.401; x: 106.601; y: 296.401 }
+ PathCubic { control1X: 106.601; control1Y: 296.401; control2X: 118.201; control2Y: 312.801; x: 119.001; y: 315.601 }
+ PathCubic { control1X: 119.001; control1Y: 315.601; control2X: 109.001; control2Y: 286.401; x: 104.601; y: 283.601 }
+ PathCubic { control1X: 104.601; control1Y: 283.601; control2X: 113.001; control2Y: 247.201; x: 154.201; y: 262.801 }
+ PathCubic { control1X: 154.201; control1Y: 262.801; control2X: 161.001; control2Y: 280.001; x: 165.401; y: 261.601 }
+ PathCubic { control1X: 165.401; control1Y: 261.601; control2X: 178.201; control2Y: 255.201; x: 189.401; y: 282.801 }
+ PathCubic { control1X: 189.401; control1Y: 282.801; control2X: 193.401; control2Y: 269.201; x: 192.601; y: 266.401 }
+ PathCubic { control1X: 192.601; control1Y: 266.401; control2X: 199.401; control2Y: 267.601; x: 198.601; y: 266.401 }
+ PathCubic { control1X: 198.601; control1Y: 266.401; control2X: 211.801; control2Y: 270.801; x: 213.001; y: 270.001 }
+ PathCubic { control1X: 213.001; control1Y: 270.001; control2X: 219.801; control2Y: 276.801; x: 220.201; y: 273.201 }
+ PathCubic { control1X: 220.201; control1Y: 273.201; control2X: 229.401; control2Y: 276.001; x: 227.401; y: 272.401 }
+ PathCubic { control1X: 227.401; control1Y: 272.401; control2X: 236.201; control2Y: 288.001; x: 236.601; y: 291.601 }
+ PathLine { x: 239.001; y: 277.601 }
+ PathLine { x: 241.001; y: 280.401 }
+ PathCubic { control1X: 241.001; control1Y: 280.401; control2X: 242.601; control2Y: 272.801; x: 241.801; y: 271.601 }
+ PathCubic { control1X: 241.001; control1Y: 270.401; control2X: 261.801; control2Y: 278.401; x: 266.601; y: 299.201 }
+ PathLine { x: 268.601; y: 307.601 }
+ PathCubic { control1X: 268.601; control1Y: 307.601; control2X: 274.601; control2Y: 292.801; x: 273.001; y: 288.801 }
+ PathCubic { control1X: 273.001; control1Y: 288.801; control2X: 278.201; control2Y: 289.601; x: 278.601; y: 294.001 }
+ PathCubic { control1X: 278.601; control1Y: 294.001; control2X: 282.601; control2Y: 270.801; x: 277.801; y: 264.801 }
+ PathCubic { control1X: 277.801; control1Y: 264.801; control2X: 282.201; control2Y: 264.001; x: 283.401; y: 267.601 }
+ PathLine { x: 283.401; y: 260.401 }
+ PathCubic { control1X: 283.401; control1Y: 260.401; control2X: 290.601; control2Y: 261.201; x: 290.601; y: 258.801 }
+ PathCubic { control1X: 290.601; control1Y: 258.801; control2X: 295.001; control2Y: 254.801; x: 297.001; y: 259.601 }
+ PathCubic { control1X: 297.001; control1Y: 259.601; control2X: 284.601; control2Y: 224.401; x: 303.001; y: 243.601 }
+ PathCubic { control1X: 303.001; control1Y: 243.601; control2X: 310.201; control2Y: 254.401; x: 306.601; y: 235.601 }
+ PathCubic { control1X: 303.001; control1Y: 216.801; control2X: 299.001; control2Y: 215.201; x: 303.801; y: 214.801 }
+ PathCubic { control1X: 303.801; control1Y: 214.801; control2X: 304.601; control2Y: 211.201; x: 302.601; y: 209.601 }
+ PathCubic { control1X: 300.601; control1Y: 208.001; control2X: 303.801; control2Y: 209.601; x: 303.801; y: 209.601 }
+ PathCubic { control1X: 303.801; control1Y: 209.601; control2X: 308.601; control2Y: 213.601; x: 303.401; y: 191.601 }
+ PathCubic { control1X: 303.401; control1Y: 191.601; control2X: 309.801; control2Y: 193.201; x: 297.801; y: 164.001 }
+ PathCubic { control1X: 297.801; control1Y: 164.001; control2X: 300.601; control2Y: 161.601; x: 296.601; y: 153.201 }
+ PathCubic { control1X: 296.601; control1Y: 153.201; control2X: 304.601; control2Y: 157.601; x: 307.401; y: 156.001 }
+ PathCubic { control1X: 307.401; control1Y: 156.001; control2X: 307.001; control2Y: 154.401; x: 303.801; y: 150.401 }
+ PathCubic { control1X: 303.801; control1Y: 150.401; control2X: 282.201; control2Y: 95.6; x: 302.601; y: 117.601 }
+ PathCubic { control1X: 302.601; control1Y: 117.601; control2X: 314.451; control2Y: 131.151; x: 308.051; y: 108.351 }
+ PathCubic { control1X: 308.051; control1Y: 108.351; control2X: 298.94; control2Y: 84.341; x: 299.717; y: 80.045 }
+ PathLine { x: -129.83; y: 103.065 }
+ }
+
+ ShapePath {
+ fillColor: "#cc7226"
+ strokeColor: "#000000"
+ strokeWidth: 1
+ PathMove { x: 299.717; y: 80.245 }
+ PathCubic { control1X: 300.345; control1Y: 80.426; control2X: 302.551; control2Y: 81.55; x: 303.801; y: 83.2 }
+ PathCubic { control1X: 303.801; control1Y: 83.2; control2X: 310.601; control2Y: 94; x: 305.401; y: 75.6 }
+ PathCubic { control1X: 305.401; control1Y: 75.6; control2X: 296.201; control2Y: 46.8; x: 305.001; y: 58 }
+ PathCubic { control1X: 305.001; control1Y: 58; control2X: 311.001; control2Y: 65.2; x: 307.801; y: 51.6 }
+ PathCubic { control1X: 303.936; control1Y: 35.173; control2X: 301.401; control2Y: 28.8; x: 301.401; y: 28.8 }
+ PathCubic { control1X: 301.401; control1Y: 28.8; control2X: 313.001; control2Y: 33.6; x: 286.201; y: -6 }
+ PathLine { x: 295.001; y: -2.4 }
+ PathCubic { control1X: 295.001; control1Y: -2.4; control2X: 275.401; control2Y: -42; x: 253.801; y: -47.2 }
+ PathLine { x: 245.801; y: -53.2 }
+ PathCubic { control1X: 245.801; control1Y: -53.2; control2X: 284.201; control2Y: -91.2; x: 271.401; y: -128 }
+ PathCubic { control1X: 271.401; control1Y: -128; control2X: 264.601; control2Y: -133.2; x: 255.001; y: -124 }
+ PathCubic { control1X: 255.001; control1Y: -124; control2X: 248.601; control2Y: -119.2; x: 242.601; y: -120.8 }
+ PathCubic { control1X: 242.601; control1Y: -120.8; control2X: 211.801; control2Y: -119.6; x: 209.801; y: -119.6 }
+ PathCubic { control1X: 207.801; control1Y: -119.6; control2X: 173.001; control2Y: -156.8; x: 107.401; y: -139.2 }
+ PathCubic { control1X: 107.401; control1Y: -139.2; control2X: 102.201; control2Y: -137.2; x: 97.801; y: -138.4 }
+ PathCubic { control1X: 97.801; control1Y: -138.4; control2X: 79.4; control2Y: -154.4; x: 30.6; y: -131.6 }
+ PathCubic { control1X: 30.6; control1Y: -131.6; control2X: 20.6; control2Y: -129.6; x: 19; y: -129.6 }
+ PathCubic { control1X: 17.4; control1Y: -129.6; control2X: 14.6; control2Y: -129.6; x: 6.6; y: -123.2 }
+ PathCubic { control1X: -1.4; control1Y: -116.8; control2X: -1.8; control2Y: -116; x: -3.8; y: -114.4 }
+ PathCubic { control1X: -3.8; control1Y: -114.4; control2X: -20.2; control2Y: -103.2; x: -25; y: -102.4 }
+ PathCubic { control1X: -25; control1Y: -102.4; control2X: -36.6; control2Y: -96; x: -41; y: -86 }
+ PathLine { x: -44.6; y: -84.8 }
+ PathCubic { control1X: -44.6; control1Y: -84.8; control2X: -46.2; control2Y: -77.6; x: -46.6; y: -76.4 }
+ PathCubic { control1X: -46.6; control1Y: -76.4; control2X: -51.4; control2Y: -72.8; x: -52.2; y: -67.2 }
+ PathCubic { control1X: -52.2; control1Y: -67.2; control2X: -61; control2Y: -61.2; x: -60.6; y: -56.8 }
+ PathCubic { control1X: -60.6; control1Y: -56.8; control2X: -62.2; control2Y: -51.6; x: -63; y: -46.8 }
+ PathCubic { control1X: -63; control1Y: -46.8; control2X: -70.2; control2Y: -42; x: -69.4; y: -39.2 }
+ PathCubic { control1X: -69.4; control1Y: -39.2; control2X: -77; control2Y: -25.2; x: -75.8; y: -18.4 }
+ PathCubic { control1X: -75.8; control1Y: -18.4; control2X: -82.2; control2Y: -18.8; x: -85; y: -16.4 }
+ PathCubic { control1X: -85; control1Y: -16.4; control2X: -85.8; control2Y: -11.6; x: -87.4; y: -11.2 }
+ PathCubic { control1X: -87.4; control1Y: -11.2; control2X: -90.2; control2Y: -10; x: -87.8; y: -6 }
+ PathCubic { control1X: -87.8; control1Y: -6; control2X: -89.4; control2Y: -3.2; x: -89.8; y: -1.6 }
+ PathCubic { control1X: -89.8; control1Y: -1.6; control2X: -89; control2Y: 1.2; x: -93.4; y: 6.8 }
+ PathCubic { control1X: -93.4; control1Y: 6.8; control2X: -99.8; control2Y: 25.6; x: -97.8; y: 30.8 }
+ PathCubic { control1X: -97.8; control1Y: 30.8; control2X: -97.4; control2Y: 35.6; x: -100.2; y: 37.2 }
+ PathCubic { control1X: -100.2; control1Y: 37.2; control2X: -103.8; control2Y: 36.8; x: -95.4; y: 48.8 }
+ PathCubic { control1X: -95.4; control1Y: 48.8; control2X: -94.6; control2Y: 50; x: -97.8; y: 52.4 }
+ PathCubic { control1X: -97.8; control1Y: 52.4; control2X: -115; control2Y: 56; x: -117.4; y: 72.4 }
+ PathCubic { control1X: -117.4; control1Y: 72.4; control2X: -131; control2Y: 87.2; x: -131; y: 92.4 }
+ PathCubic { control1X: -131; control1Y: 94.705; control2X: -130.729; control2Y: 97.852; x: -130.03; y: 102.465 }
+ PathCubic { control1X: -130.03; control1Y: 102.465; control2X: -130.6; control2Y: 110.801; x: -103; y: 111.601 }
+ PathCubic { control1X: -75.4; control1Y: 112.401; control2X: 299.717; control2Y: 80.245; x: 299.717; y: 80.245 }
+ }
+
+ ShapePath {
+ fillColor: "#cc7226"
+ strokeWidth: -1
+ PathMove { x: -115.6; y: 102.6 }
+ PathCubic { control1X: -140.6; control1Y: 63.2; control2X: -126.2; control2Y: 119.601; x: -126.2; y: 119.601 }
+ PathCubic { control1X: -117.4; control1Y: 154.001; control2X: 12.2; control2Y: 116.401; x: 12.2; y: 116.401 }
+ PathCubic { control1X: 12.2; control1Y: 116.401; control2X: 181.001; control2Y: 86; x: 192.201; y: 82 }
+ PathCubic { control1X: 203.401; control1Y: 78; control2X: 298.601; control2Y: 84.4; x: 298.601; y: 84.4 }
+ PathLine { x: 293.001; y: 67.6 }
+ PathCubic { control1X: 228.201; control1Y: 21.2; control2X: 209.001; control2Y: 44.4; x: 195.401; y: 40.4 }
+ PathCubic { control1X: 181.801; control1Y: 36.4; control2X: 184.201; control2Y: 46; x: 181.001; y: 46.8 }
+ PathCubic { control1X: 177.801; control1Y: 47.6; control2X: 138.601; control2Y: 22.8; x: 132.201; y: 23.6 }
+ PathCubic { control1X: 125.801; control1Y: 24.4; control2X: 100.459; control2Y: 0.649; x: 115.401; y: 32.4 }
+ PathCubic { control1X: 131.401; control1Y: 66.4; control2X: 57; control2Y: 71.6; x: 40.2; y: 60.4 }
+ PathCubic { control1X: 23.4; control1Y: 49.2; control2X: 47.4; control2Y: 78.8; x: 47.4; y: 78.8 }
+ PathCubic { control1X: 65.8; control1Y: 98.8; control2X: 31.4; control2Y: 82; x: 31.4; y: 82 }
+ PathCubic { control1X: -3; control1Y: 69.2; control2X: -27; control2Y: 94.8; x: -30.2; y: 95.6 }
+ PathCubic { control1X: -33.4; control1Y: 96.4; control2X: -38.2; control2Y: 99.6; x: -39; y: 93.2 }
+ PathCubic { control1X: -39.8; control1Y: 86.8; control2X: -47.31; control2Y: 70.099; x: -79; y: 96.4 }
+ PathCubic { control1X: -99; control1Y: 113.001; control2X: -112.8; control2Y: 91; x: -112.8; y: 91 }
+ PathLine { x: -115.6; y: 102.6 }
+ }
+
+ ShapePath {
+ fillColor: "#e87f3a"
+ strokeWidth: -1
+ PathMove { x: 133.51; y: 25.346 }
+ PathCubic { control1X: 127.11; control1Y: 26.146; control2X: 101.743; control2Y: 2.407; x: 116.71; y: 34.146 }
+ PathCubic { control1X: 133.31; control1Y: 69.346; control2X: 58.31; control2Y: 73.346; x: 41.51; y: 62.146 }
+ PathCubic { control1X: 24.709; control1Y: 50.946; control2X: 48.71; control2Y: 80.546; x: 48.71; y: 80.546 }
+ PathCubic { control1X: 67.11; control1Y: 100.546; control2X: 32.709; control2Y: 83.746; x: 32.709; y: 83.746 }
+ PathCubic { control1X: -1.691; control1Y: 70.946; control2X: -25.691; control2Y: 96.546; x: -28.891; y: 97.346 }
+ PathCubic { control1X: -32.091; control1Y: 98.146; control2X: -36.891; control2Y: 101.346; x: -37.691; y: 94.946 }
+ PathCubic { control1X: -38.491; control1Y: 88.546; control2X: -45.87; control2Y: 72.012; x: -77.691; y: 98.146 }
+ PathCubic { control1X: -98.927; control1Y: 115.492; control2X: -112.418; control2Y: 94.037; x: -112.418; y: 94.037 }
+ PathLine { x: -115.618; y: 104.146 }
+ PathCubic { control1X: -140.618; control1Y: 64.346; control2X: -125.546; control2Y: 122.655; x: -125.546; y: 122.655 }
+ PathCubic { control1X: -116.745; control1Y: 157.056; control2X: 13.509; control2Y: 118.146; x: 13.509; y: 118.146 }
+ PathCubic { control1X: 13.509; control1Y: 118.146; control2X: 182.31; control2Y: 87.746; x: 193.51; y: 83.746 }
+ PathCubic { control1X: 204.71; control1Y: 79.746; control2X: 299.038; control2Y: 86.073; x: 299.038; y: 86.073 }
+ PathLine { x: 293.51; y: 68.764 }
+ PathCubic { control1X: 228.71; control1Y: 22.364; control2X: 210.31; control2Y: 46.146; x: 196.71; y: 42.146 }
+ PathCubic { control1X: 183.11; control1Y: 38.146; control2X: 185.51; control2Y: 47.746; x: 182.31; y: 48.546 }
+ PathCubic { control1X: 179.11; control1Y: 49.346; control2X: 139.91; control2Y: 24.546; x: 133.51; y: 25.346 }
+ }
+
+ ShapePath {
+ fillColor: "#ea8c4d"
+ strokeWidth: -1
+ PathMove { x: 134.819; y: 27.091 }
+ PathCubic { control1X: 128.419; control1Y: 27.891; control2X: 103.685; control2Y: 3.862; x: 118.019; y: 35.891 }
+ PathCubic { control1X: 134.219; control1Y: 72.092; control2X: 59.619; control2Y: 75.092; x: 42.819; y: 63.892 }
+ PathCubic { control1X: 26.019; control1Y: 52.692; control2X: 50.019; control2Y: 82.292; x: 50.019; y: 82.292 }
+ PathCubic { control1X: 68.419; control1Y: 102.292; control2X: 34.019; control2Y: 85.492; x: 34.019; y: 85.492 }
+ PathCubic { control1X: -0.381; control1Y: 72.692; control2X: -24.382; control2Y: 98.292; x: -27.582; y: 99.092 }
+ PathCubic { control1X: -30.782; control1Y: 99.892; control2X: -35.582; control2Y: 103.092; x: -36.382; y: 96.692 }
+ PathCubic { control1X: -37.182; control1Y: 90.292; control2X: -44.43; control2Y: 73.925; x: -76.382; y: 99.892 }
+ PathCubic { control1X: -98.855; control1Y: 117.983; control2X: -112.036; control2Y: 97.074; x: -112.036; y: 97.074 }
+ PathLine { x: -115.636; y: 105.692 }
+ PathCubic { control1X: -139.436; control1Y: 66.692; control2X: -124.891; control2Y: 125.71; x: -124.891; y: 125.71 }
+ PathCubic { control1X: -116.091; control1Y: 160.11; control2X: 14.819; control2Y: 119.892; x: 14.819; y: 119.892 }
+ PathCubic { control1X: 14.819; control1Y: 119.892; control2X: 183.619; control2Y: 89.492; x: 194.819; y: 85.492 }
+ PathCubic { control1X: 206.019; control1Y: 81.492; control2X: 299.474; control2Y: 87.746; x: 299.474; y: 87.746 }
+ PathLine { x: 294.02; y: 69.928 }
+ PathCubic { control1X: 229.219; control1Y: 23.528; control2X: 211.619; control2Y: 47.891; x: 198.019; y: 43.891 }
+ PathCubic { control1X: 184.419; control1Y: 39.891; control2X: 186.819; control2Y: 49.491; x: 183.619; y: 50.292 }
+ PathCubic { control1X: 180.419; control1Y: 51.092; control2X: 141.219; control2Y: 26.291; x: 134.819; y: 27.091 }
+ }
+
+ ShapePath {
+ fillColor: "#ec9961"
+ strokeWidth: -1
+ PathMove { x: 136.128; y: 28.837 }
+ PathCubic { control1X: 129.728; control1Y: 29.637; control2X: 104.999; control2Y: 5.605; x: 119.328; y: 37.637 }
+ PathCubic { control1X: 136.128; control1Y: 75.193; control2X: 60.394; control2Y: 76.482; x: 44.128; y: 65.637 }
+ PathCubic { control1X: 27.328; control1Y: 54.437; control2X: 51.328; control2Y: 84.037; x: 51.328; y: 84.037 }
+ PathCubic { control1X: 69.728; control1Y: 104.037; control2X: 35.328; control2Y: 87.237; x: 35.328; y: 87.237 }
+ PathCubic { control1X: 0.928; control1Y: 74.437; control2X: -23.072; control2Y: 100.037; x: -26.272; y: 100.837 }
+ PathCubic { control1X: -29.472; control1Y: 101.637; control2X: -34.272; control2Y: 104.837; x: -35.072; y: 98.437 }
+ PathCubic { control1X: -35.872; control1Y: 92.037; control2X: -42.989; control2Y: 75.839; x: -75.073; y: 101.637 }
+ PathCubic { control1X: -98.782; control1Y: 120.474; control2X: -111.655; control2Y: 100.11; x: -111.655; y: 100.11 }
+ PathLine { x: -115.655; y: 107.237 }
+ PathCubic { control1X: -137.455; control1Y: 70.437; control2X: -124.236; control2Y: 128.765; x: -124.236; y: 128.765 }
+ PathCubic { control1X: -115.436; control1Y: 163.165; control2X: 16.128; control2Y: 121.637; x: 16.128; y: 121.637 }
+ PathCubic { control1X: 16.128; control1Y: 121.637; control2X: 184.928; control2Y: 91.237; x: 196.129; y: 87.237 }
+ PathCubic { control1X: 207.329; control1Y: 83.237; control2X: 299.911; control2Y: 89.419; x: 299.911; y: 89.419 }
+ PathLine { x: 294.529; y: 71.092 }
+ PathCubic { control1X: 229.729; control1Y: 24.691; control2X: 212.929; control2Y: 49.637; x: 199.329; y: 45.637 }
+ PathCubic { control1X: 185.728; control1Y: 41.637; control2X: 188.128; control2Y: 51.237; x: 184.928; y: 52.037 }
+ PathCubic { control1X: 181.728; control1Y: 52.837; control2X: 142.528; control2Y: 28.037; x: 136.128; y: 28.837 }
+ }
+
+ ShapePath {
+ fillColor: "#eea575"
+ strokeWidth: -1
+ PathMove { x: 137.438; y: 30.583 }
+ PathCubic { control1X: 131.037; control1Y: 31.383; control2X: 106.814; control2Y: 7.129; x: 120.637; y: 39.383 }
+ PathCubic { control1X: 137.438; control1Y: 78.583; control2X: 62.237; control2Y: 78.583; x: 45.437; y: 67.383 }
+ PathCubic { control1X: 28.637; control1Y: 56.183; control2X: 52.637; control2Y: 85.783; x: 52.637; y: 85.783 }
+ PathCubic { control1X: 71.037; control1Y: 105.783; control2X: 36.637; control2Y: 88.983; x: 36.637; y: 88.983 }
+ PathCubic { control1X: 2.237; control1Y: 76.183; control2X: -21.763; control2Y: 101.783; x: -24.963; y: 102.583 }
+ PathCubic { control1X: -28.163; control1Y: 103.383; control2X: -32.963; control2Y: 106.583; x: -33.763; y: 100.183 }
+ PathCubic { control1X: -34.563; control1Y: 93.783; control2X: -41.548; control2Y: 77.752; x: -73.763; y: 103.383 }
+ PathCubic { control1X: -98.709; control1Y: 122.965; control2X: -111.273; control2Y: 103.146; x: -111.273; y: 103.146 }
+ PathLine { x: -115.673; y: 108.783 }
+ PathCubic { control1X: -135.473; control1Y: 73.982; control2X: -123.582; control2Y: 131.819; x: -123.582; y: 131.819 }
+ PathCubic { control1X: -114.782; control1Y: 166.22; control2X: 17.437; control2Y: 123.383; x: 17.437; y: 123.383 }
+ PathCubic { control1X: 17.437; control1Y: 123.383; control2X: 186.238; control2Y: 92.983; x: 197.438; y: 88.983 }
+ PathCubic { control1X: 208.638; control1Y: 84.983; control2X: 300.347; control2Y: 91.092; x: 300.347; y: 91.092 }
+ PathLine { x: 295.038; y: 72.255 }
+ PathCubic { control1X: 230.238; control1Y: 25.855; control2X: 214.238; control2Y: 51.383; x: 200.638; y: 47.383 }
+ PathCubic { control1X: 187.038; control1Y: 43.383; control2X: 189.438; control2Y: 52.983; x: 186.238; y: 53.783 }
+ PathCubic { control1X: 183.038; control1Y: 54.583; control2X: 143.838; control2Y: 29.783; x: 137.438; y: 30.583 }
+ }
+
+ ShapePath {
+ fillColor: "#f1b288"
+ strokeWidth: -1
+ PathMove { x: 138.747; y: 32.328 }
+ PathCubic { control1X: 132.347; control1Y: 33.128; control2X: 106.383; control2Y: 9.677; x: 121.947; y: 41.128 }
+ PathCubic { control1X: 141.147; control1Y: 79.928; control2X: 63.546; control2Y: 80.328; x: 46.746; y: 69.128 }
+ PathCubic { control1X: 29.946; control1Y: 57.928; control2X: 53.946; control2Y: 87.528; x: 53.946; y: 87.528 }
+ PathCubic { control1X: 72.346; control1Y: 107.528; control2X: 37.946; control2Y: 90.728; x: 37.946; y: 90.728 }
+ PathCubic { control1X: 3.546; control1Y: 77.928; control2X: -20.454; control2Y: 103.528; x: -23.654; y: 104.328 }
+ PathCubic { control1X: -26.854; control1Y: 105.128; control2X: -31.654; control2Y: 108.328; x: -32.454; y: 101.928 }
+ PathCubic { control1X: -33.254; control1Y: 95.528; control2X: -40.108; control2Y: 79.665; x: -72.454; y: 105.128 }
+ PathCubic { control1X: -98.636; control1Y: 125.456; control2X: -110.891; control2Y: 106.183; x: -110.891; y: 106.183 }
+ PathLine { x: -115.691; y: 110.328 }
+ PathCubic { control1X: -133.691; control1Y: 77.128; control2X: -122.927; control2Y: 134.874; x: -122.927; y: 134.874 }
+ PathCubic { control1X: -114.127; control1Y: 169.274; control2X: 18.746; control2Y: 125.128; x: 18.746; y: 125.128 }
+ PathCubic { control1X: 18.746; control1Y: 125.128; control2X: 187.547; control2Y: 94.728; x: 198.747; y: 90.728 }
+ PathCubic { control1X: 209.947; control1Y: 86.728; control2X: 300.783; control2Y: 92.764; x: 300.783; y: 92.764 }
+ PathLine { x: 295.547; y: 73.419 }
+ PathCubic { control1X: 230.747; control1Y: 27.019; control2X: 215.547; control2Y: 53.128; x: 201.947; y: 49.128 }
+ PathCubic { control1X: 188.347; control1Y: 45.128; control2X: 190.747; control2Y: 54.728; x: 187.547; y: 55.528 }
+ PathCubic { control1X: 184.347; control1Y: 56.328; control2X: 145.147; control2Y: 31.528; x: 138.747; y: 32.328 }
+ }
+
+ ShapePath {
+ fillColor: "#f3bf9c"
+ strokeWidth: -1
+ PathMove { x: 140.056; y: 34.073 }
+ PathCubic { control1X: 133.655; control1Y: 34.873; control2X: 107.313; control2Y: 11.613; x: 123.255; y: 42.873 }
+ PathCubic { control1X: 143.656; control1Y: 82.874; control2X: 64.855; control2Y: 82.074; x: 48.055; y: 70.874 }
+ PathCubic { control1X: 31.255; control1Y: 59.674; control2X: 55.255; control2Y: 89.274; x: 55.255; y: 89.274 }
+ PathCubic { control1X: 73.655; control1Y: 109.274; control2X: 39.255; control2Y: 92.474; x: 39.255; y: 92.474 }
+ PathCubic { control1X: 4.855; control1Y: 79.674; control2X: -19.145; control2Y: 105.274; x: -22.345; y: 106.074 }
+ PathCubic { control1X: -25.545; control1Y: 106.874; control2X: -30.345; control2Y: 110.074; x: -31.145; y: 103.674 }
+ PathCubic { control1X: -31.945; control1Y: 97.274; control2X: -38.668; control2Y: 81.578; x: -71.145; y: 106.874 }
+ PathCubic { control1X: -98.564; control1Y: 127.947; control2X: -110.509; control2Y: 109.219; x: -110.509; y: 109.219 }
+ PathLine { x: -115.709; y: 111.874 }
+ PathCubic { control1X: -131.709; control1Y: 81.674; control2X: -122.273; control2Y: 137.929; x: -122.273; y: 137.929 }
+ PathCubic { control1X: -113.473; control1Y: 172.329; control2X: 20.055; control2Y: 126.874; x: 20.055; y: 126.874 }
+ PathCubic { control1X: 20.055; control1Y: 126.874; control2X: 188.856; control2Y: 96.474; x: 200.056; y: 92.474 }
+ PathCubic { control1X: 211.256; control1Y: 88.474; control2X: 301.22; control2Y: 94.437; x: 301.22; y: 94.437 }
+ PathLine { x: 296.056; y: 74.583 }
+ PathCubic { control1X: 231.256; control1Y: 28.183; control2X: 216.856; control2Y: 54.874; x: 203.256; y: 50.874 }
+ PathCubic { control1X: 189.656; control1Y: 46.873; control2X: 192.056; control2Y: 56.474; x: 188.856; y: 57.274 }
+ PathCubic { control1X: 185.656; control1Y: 58.074; control2X: 146.456; control2Y: 33.273; x: 140.056; y: 34.073 }
+ }
+
+ ShapePath {
+ fillColor: "#f5ccb0"
+ strokeWidth: -1
+ PathMove { x: 141.365; y: 35.819 }
+ PathCubic { control1X: 134.965; control1Y: 36.619; control2X: 107.523; control2Y: 13.944; x: 124.565; y: 44.619 }
+ PathCubic { control1X: 146.565; control1Y: 84.219; control2X: 66.164; control2Y: 83.819; x: 49.364; y: 72.619 }
+ PathCubic { control1X: 32.564; control1Y: 61.419; control2X: 56.564; control2Y: 91.019; x: 56.564; y: 91.019 }
+ PathCubic { control1X: 74.964; control1Y: 111.019; control2X: 40.564; control2Y: 94.219; x: 40.564; y: 94.219 }
+ PathCubic { control1X: 6.164; control1Y: 81.419; control2X: -17.836; control2Y: 107.019; x: -21.036; y: 107.819 }
+ PathCubic { control1X: -24.236; control1Y: 108.619; control2X: -29.036; control2Y: 111.819; x: -29.836; y: 105.419 }
+ PathCubic { control1X: -30.636; control1Y: 99.019; control2X: -37.227; control2Y: 83.492; x: -69.836; y: 108.619 }
+ PathCubic { control1X: -98.491; control1Y: 130.438; control2X: -110.127; control2Y: 112.256; x: -110.127; y: 112.256 }
+ PathLine { x: -115.727; y: 113.419 }
+ PathCubic { control1X: -130.128; control1Y: 85.019; control2X: -121.618; control2Y: 140.983; x: -121.618; y: 140.983 }
+ PathCubic { control1X: -112.818; control1Y: 175.384; control2X: 21.364; control2Y: 128.619; x: 21.364; y: 128.619 }
+ PathCubic { control1X: 21.364; control1Y: 128.619; control2X: 190.165; control2Y: 98.219; x: 201.365; y: 94.219 }
+ PathCubic { control1X: 212.565; control1Y: 90.219; control2X: 301.656; control2Y: 96.11; x: 301.656; y: 96.11 }
+ PathLine { x: 296.565; y: 75.746 }
+ PathCubic { control1X: 231.765; control1Y: 29.346; control2X: 218.165; control2Y: 56.619; x: 204.565; y: 52.619 }
+ PathCubic { control1X: 190.965; control1Y: 48.619; control2X: 193.365; control2Y: 58.219; x: 190.165; y: 59.019 }
+ PathCubic { control1X: 186.965; control1Y: 59.819; control2X: 147.765; control2Y: 35.019; x: 141.365; y: 35.819 }
+ }
+
+ ShapePath {
+ fillColor: "#f8d8c4"
+ strokeWidth: -1
+ PathMove { x: 142.674; y: 37.565 }
+ PathCubic { control1X: 136.274; control1Y: 38.365; control2X: 108.832; control2Y: 15.689; x: 125.874; y: 46.365 }
+ PathCubic { control1X: 147.874; control1Y: 85.965; control2X: 67.474; control2Y: 85.565; x: 50.674; y: 74.365 }
+ PathCubic { control1X: 33.874; control1Y: 63.165; control2X: 57.874; control2Y: 92.765; x: 57.874; y: 92.765 }
+ PathCubic { control1X: 76.274; control1Y: 112.765; control2X: 41.874; control2Y: 95.965; x: 41.874; y: 95.965 }
+ PathCubic { control1X: 7.473; control1Y: 83.165; control2X: -16.527; control2Y: 108.765; x: -19.727; y: 109.565 }
+ PathCubic { control1X: -22.927; control1Y: 110.365; control2X: -27.727; control2Y: 113.565; x: -28.527; y: 107.165 }
+ PathCubic { control1X: -29.327; control1Y: 100.765; control2X: -35.786; control2Y: 85.405; x: -68.527; y: 110.365 }
+ PathCubic { control1X: -98.418; control1Y: 132.929; control2X: -109.745; control2Y: 115.293; x: -109.745; y: 115.293 }
+ PathLine { x: -115.745; y: 114.965 }
+ PathCubic { control1X: -129.346; control1Y: 88.564; control2X: -120.963; control2Y: 144.038; x: -120.963; y: 144.038 }
+ PathCubic { control1X: -112.163; control1Y: 178.438; control2X: 22.673; control2Y: 130.365; x: 22.673; y: 130.365 }
+ PathCubic { control1X: 22.673; control1Y: 130.365; control2X: 191.474; control2Y: 99.965; x: 202.674; y: 95.965 }
+ PathCubic { control1X: 213.874; control1Y: 91.965; control2X: 302.093; control2Y: 97.783; x: 302.093; y: 97.783 }
+ PathLine { x: 297.075; y: 76.91 }
+ PathCubic { control1X: 232.274; control1Y: 30.51; control2X: 219.474; control2Y: 58.365; x: 205.874; y: 54.365 }
+ PathCubic { control1X: 192.274; control1Y: 50.365; control2X: 194.674; control2Y: 59.965; x: 191.474; y: 60.765 }
+ PathCubic { control1X: 188.274; control1Y: 61.565; control2X: 149.074; control2Y: 36.765; x: 142.674; y: 37.565 }
+ }
+
+ ShapePath {
+ fillColor: "#fae5d7"
+ strokeWidth: -1
+ PathMove { x: 143.983; y: 39.31 }
+ PathCubic { control1X: 137.583; control1Y: 40.11; control2X: 110.529; control2Y: 17.223; x: 127.183; y: 48.11 }
+ PathCubic { control1X: 149.183; control1Y: 88.91; control2X: 68.783; control2Y: 87.31; x: 51.983; y: 76.11 }
+ PathCubic { control1X: 35.183; control1Y: 64.91; control2X: 59.183; control2Y: 94.51; x: 59.183; y: 94.51 }
+ PathCubic { control1X: 77.583; control1Y: 114.51; control2X: 43.183; control2Y: 97.71; x: 43.183; y: 97.71 }
+ PathCubic { control1X: 8.783; control1Y: 84.91; control2X: -15.217; control2Y: 110.51; x: -18.417; y: 111.31 }
+ PathCubic { control1X: -21.618; control1Y: 112.11; control2X: -26.418; control2Y: 115.31; x: -27.218; y: 108.91 }
+ PathCubic { control1X: -28.018; control1Y: 102.51; control2X: -34.346; control2Y: 87.318; x: -67.218; y: 112.11 }
+ PathCubic { control1X: -98.345; control1Y: 135.42; control2X: -109.363; control2Y: 118.329; x: -109.363; y: 118.329 }
+ PathLine { x: -115.764; y: 116.51 }
+ PathCubic { control1X: -128.764; control1Y: 92.51; control2X: -120.309; control2Y: 147.093; x: -120.309; y: 147.093 }
+ PathCubic { control1X: -111.509; control1Y: 181.493; control2X: 23.983; control2Y: 132.11; x: 23.983; y: 132.11 }
+ PathCubic { control1X: 23.983; control1Y: 132.11; control2X: 192.783; control2Y: 101.71; x: 203.983; y: 97.71 }
+ PathCubic { control1X: 215.183; control1Y: 93.71; control2X: 302.529; control2Y: 99.456; x: 302.529; y: 99.456 }
+ PathLine { x: 297.583; y: 78.074 }
+ PathCubic { control1X: 232.783; control1Y: 31.673; control2X: 220.783; control2Y: 60.11; x: 207.183; y: 56.11 }
+ PathCubic { control1X: 193.583; control1Y: 52.11; control2X: 195.983; control2Y: 61.71; x: 192.783; y: 62.51 }
+ PathCubic { control1X: 189.583; control1Y: 63.31; control2X: 150.383; control2Y: 38.51; x: 143.983; y: 39.31 }
+ }
+
+ ShapePath {
+ fillColor: "#fcf2eb"
+ strokeWidth: -1
+ PathMove { x: 145.292; y: 41.055 }
+ PathCubic { control1X: 138.892; control1Y: 41.855; control2X: 112.917; control2Y: 18.411; x: 128.492; y: 49.855 }
+ PathCubic { control1X: 149.692; control1Y: 92.656; control2X: 70.092; control2Y: 89.056; x: 53.292; y: 77.856 }
+ PathCubic { control1X: 36.492; control1Y: 66.656; control2X: 60.492; control2Y: 96.256; x: 60.492; y: 96.256 }
+ PathCubic { control1X: 78.892; control1Y: 116.256; control2X: 44.492; control2Y: 99.456; x: 44.492; y: 99.456 }
+ PathCubic { control1X: 10.092; control1Y: 86.656; control2X: -13.908; control2Y: 112.256; x: -17.108; y: 113.056 }
+ PathCubic { control1X: -20.308; control1Y: 113.856; control2X: -25.108; control2Y: 117.056; x: -25.908; y: 110.656 }
+ PathCubic { control1X: -26.708; control1Y: 104.256; control2X: -32.905; control2Y: 89.232; x: -65.908; y: 113.856 }
+ PathCubic { control1X: -98.273; control1Y: 137.911; control2X: -108.982; control2Y: 121.365; x: -108.982; y: 121.365 }
+ PathLine { x: -115.782; y: 118.056 }
+ PathCubic { control1X: -128.582; control1Y: 94.856; control2X: -119.654; control2Y: 150.147; x: -119.654; y: 150.147 }
+ PathCubic { control1X: -110.854; control1Y: 184.547; control2X: 25.292; control2Y: 133.856; x: 25.292; y: 133.856 }
+ PathCubic { control1X: 25.292; control1Y: 133.856; control2X: 194.093; control2Y: 103.456; x: 205.293; y: 99.456 }
+ PathCubic { control1X: 216.493; control1Y: 95.456; control2X: 302.965; control2Y: 101.128; x: 302.965; y: 101.128 }
+ PathLine { x: 298.093; y: 79.237 }
+ PathCubic { control1X: 233.292; control1Y: 32.837; control2X: 222.093; control2Y: 61.856; x: 208.493; y: 57.856 }
+ PathCubic { control1X: 194.893; control1Y: 53.855; control2X: 197.293; control2Y: 63.456; x: 194.093; y: 64.256 }
+ PathCubic { control1X: 190.892; control1Y: 65.056; control2X: 151.692; control2Y: 40.255; x: 145.292; y: 41.055 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeWidth: -1
+ PathMove { x: -115.8; y: 119.601 }
+ PathCubic { control1X: -128.6; control1Y: 97.6; control2X: -119; control2Y: 153.201; x: -119; y: 153.201 }
+ PathCubic { control1X: -110.2; control1Y: 187.601; control2X: 26.6; control2Y: 135.601; x: 26.6; y: 135.601 }
+ PathCubic { control1X: 26.6; control1Y: 135.601; control2X: 195.401; control2Y: 105.2; x: 206.601; y: 101.2 }
+ PathCubic { control1X: 217.801; control1Y: 97.2; control2X: 303.401; control2Y: 102.8; x: 303.401; y: 102.8 }
+ PathLine { x: 298.601; y: 80.4 }
+ PathCubic { control1X: 233.801; control1Y: 34; control2X: 223.401; control2Y: 63.6; x: 209.801; y: 59.6 }
+ PathCubic { control1X: 196.201; control1Y: 55.6; control2X: 198.601; control2Y: 65.2; x: 195.401; y: 66 }
+ PathCubic { control1X: 192.201; control1Y: 66.8; control2X: 153.001; control2Y: 42; x: 146.601; y: 42.8 }
+ PathCubic { control1X: 140.201; control1Y: 43.6; control2X: 114.981; control2Y: 19.793; x: 129.801; y: 51.6 }
+ PathCubic { control1X: 152.028; control1Y: 99.307; control2X: 69.041; control2Y: 89.227; x: 54.6; y: 79.6 }
+ PathCubic { control1X: 37.8; control1Y: 68.4; control2X: 61.8; control2Y: 98; x: 61.8; y: 98 }
+ PathCubic { control1X: 80.2; control1Y: 118.001; control2X: 45.8; control2Y: 101.2; x: 45.8; y: 101.2 }
+ PathCubic { control1X: 11.4; control1Y: 88.4; control2X: -12.6; control2Y: 114.001; x: -15.8; y: 114.801 }
+ PathCubic { control1X: -19; control1Y: 115.601; control2X: -23.8; control2Y: 118.801; x: -24.6; y: 112.401 }
+ PathCubic { control1X: -25.4; control1Y: 106; control2X: -31.465; control2Y: 91.144; x: -64.6; y: 115.601 }
+ PathCubic { control1X: -98.2; control1Y: 140.401; control2X: -108.6; control2Y: 124.401; x: -108.6; y: 124.401 }
+ PathLine { x: -115.8; y: 119.601 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -74.2; y: 149.601 }
+ PathCubic { control1X: -74.2; control1Y: 149.601; control2X: -81.4; control2Y: 161.201; x: -60.6; y: 174.401 }
+ PathCubic { control1X: -60.6; control1Y: 174.401; control2X: -59.2; control2Y: 175.801; x: -77.2; y: 171.601 }
+ PathCubic { control1X: -77.2; control1Y: 171.601; control2X: -83.4; control2Y: 169.601; x: -85; y: 159.201 }
+ PathCubic { control1X: -85; control1Y: 159.201; control2X: -89.8; control2Y: 154.801; x: -94.6; y: 149.201 }
+ PathCubic { control1X: -99.4; control1Y: 143.601; control2X: -74.2; control2Y: 149.601; x: -74.2; y: 149.601 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: 65.8; y: 102 }
+ PathCubic { control1X: 65.8; control1Y: 102; control2X: 83.498; control2Y: 128.821; x: 82.9; y: 133.601 }
+ PathCubic { control1X: 81.6; control1Y: 144.001; control2X: 81.4; control2Y: 153.601; x: 84.6; y: 157.601 }
+ PathCubic { control1X: 87.801; control1Y: 161.601; control2X: 96.601; control2Y: 194.801; x: 96.601; y: 194.801 }
+ PathCubic { control1X: 96.601; control1Y: 194.801; control2X: 96.201; control2Y: 196.001; x: 108.601; y: 158.001 }
+ PathCubic { control1X: 108.601; control1Y: 158.001; control2X: 120.201; control2Y: 142.001; x: 100.201; y: 123.601 }
+ PathCubic { control1X: 100.201; control1Y: 123.601; control2X: 65; control2Y: 94.8; x: 65.8; y: 102 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -54.2; y: 176.401 }
+ PathCubic { control1X: -54.2; control1Y: 176.401; control2X: -43; control2Y: 183.601; x: -57.4; y: 214.801 }
+ PathLine { x: -51; y: 212.401 }
+ PathCubic { control1X: -51; control1Y: 212.401; control2X: -51.8; control2Y: 223.601; x: -55; y: 226.001 }
+ PathLine { x: -47.8; y: 222.801 }
+ PathCubic { control1X: -47.8; control1Y: 222.801; control2X: -43; control2Y: 230.801; x: -47; y: 235.601 }
+ PathCubic { control1X: -47; control1Y: 235.601; control2X: -30.2; control2Y: 243.601; x: -31; y: 250.001 }
+ PathCubic { control1X: -31; control1Y: 250.001; control2X: -24.6; control2Y: 242.001; x: -28.6; y: 235.601 }
+ PathCubic { control1X: -32.6; control1Y: 229.201; control2X: -39.8; control2Y: 233.201; x: -39; y: 214.801 }
+ PathLine { x: -47.8; y: 218.001 }
+ PathCubic { control1X: -47.8; control1Y: 218.001; control2X: -42.2; control2Y: 209.201; x: -42.2; y: 202.801 }
+ PathLine { x: -50.2; y: 205.201 }
+ PathCubic { control1X: -50.2; control1Y: 205.201; control2X: -34.731; control2Y: 178.623; x: -45.4; y: 177.201 }
+ PathCubic { control1X: -51.4; control1Y: 176.401; control2X: -54.2; control2Y: 176.401; x: -54.2; y: 176.401 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: -21.8; y: 193.201 }
+ PathCubic { control1X: -21.8; control1Y: 193.201; control2X: -19; control2Y: 188.801; x: -21.8; y: 189.601 }
+ PathCubic { control1X: -24.6; control1Y: 190.401; control2X: -55.8; control2Y: 205.201; x: -61.8; y: 214.801 }
+ PathCubic { control1X: -61.8; control1Y: 214.801; control2X: -27.4; control2Y: 190.401; x: -21.8; y: 193.201 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: -11.4; y: 201.201 }
+ PathCubic { control1X: -11.4; control1Y: 201.201; control2X: -8.6; control2Y: 196.801; x: -11.4; y: 197.601 }
+ PathCubic { control1X: -14.2; control1Y: 198.401; control2X: -45.4; control2Y: 213.201; x: -51.4; y: 222.801 }
+ PathCubic { control1X: -51.4; control1Y: 222.801; control2X: -17; control2Y: 198.401; x: -11.4; y: 201.201 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: 1.8; y: 186.001 }
+ PathCubic { control1X: 1.8; control1Y: 186.001; control2X: 4.6; control2Y: 181.601; x: 1.8; y: 182.401 }
+ PathCubic { control1X: -1; control1Y: 183.201; control2X: -32.2; control2Y: 198.001; x: -38.2; y: 207.601 }
+ PathCubic { control1X: -38.2; control1Y: 207.601; control2X: -3.8; control2Y: 183.201; x: 1.8; y: 186.001 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: -21.4; y: 229.601 }
+ PathCubic { control1X: -21.4; control1Y: 229.601; control2X: -21.4; control2Y: 223.601; x: -24.2; y: 224.401 }
+ PathCubic { control1X: -27; control1Y: 225.201; control2X: -63; control2Y: 242.801; x: -69; y: 252.401 }
+ PathCubic { control1X: -69; control1Y: 252.401; control2X: -27; control2Y: 226.801; x: -21.4; y: 229.601 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: -20.2; y: 218.801 }
+ PathCubic { control1X: -20.2; control1Y: 218.801; control2X: -19; control2Y: 214.001; x: -21.8; y: 214.801 }
+ PathCubic { control1X: -23.8; control1Y: 214.801; control2X: -50.2; control2Y: 226.401; x: -56.2; y: 236.001 }
+ PathCubic { control1X: -56.2; control1Y: 236.001; control2X: -26.6; control2Y: 214.401; x: -20.2; y: 218.801 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: -34.6; y: 266.401 }
+ PathLine { x: -44.6; y: 274.001 }
+ PathCubic { control1X: -44.6; control1Y: 274.001; control2X: -34.2; control2Y: 266.401; x: -30.6; y: 267.601 }
+ PathCubic { control1X: -30.6; control1Y: 267.601; control2X: -37.4; control2Y: 278.801; x: -38.2; y: 284.001 }
+ PathCubic { control1X: -38.2; control1Y: 284.001; control2X: -27.8; control2Y: 271.201; x: -22.2; y: 271.601 }
+ PathCubic { control1X: -22.2; control1Y: 271.601; control2X: -14.6; control2Y: 272.001; x: -14.6; y: 282.801 }
+ PathCubic { control1X: -14.6; control1Y: 282.801; control2X: -9; control2Y: 272.401; x: -5.8; y: 272.801 }
+ PathCubic { control1X: -5.8; control1Y: 272.801; control2X: -4.6; control2Y: 279.201; x: -5.8; y: 286.001 }
+ PathCubic { control1X: -5.8; control1Y: 286.001; control2X: -1.8; control2Y: 278.401; x: 2.2; y: 280.001 }
+ PathCubic { control1X: 2.2; control1Y: 280.001; control2X: 8.6; control2Y: 278.001; x: 7.8; y: 289.601 }
+ PathCubic { control1X: 7.8; control1Y: 289.601; control2X: 7.8; control2Y: 300.001; x: 7; y: 302.801 }
+ PathCubic { control1X: 7; control1Y: 302.801; control2X: 12.6; control2Y: 276.401; x: 15; y: 276.001 }
+ PathCubic { control1X: 15; control1Y: 276.001; control2X: 23; control2Y: 274.801; x: 27.8; y: 283.601 }
+ PathCubic { control1X: 27.8; control1Y: 283.601; control2X: 23.8; control2Y: 276.001; x: 28.6; y: 278.001 }
+ PathCubic { control1X: 28.6; control1Y: 278.001; control2X: 39.4; control2Y: 279.601; x: 42.6; y: 286.401 }
+ PathCubic { control1X: 42.6; control1Y: 286.401; control2X: 35.8; control2Y: 274.401; x: 41.4; y: 277.601 }
+ PathCubic { control1X: 41.4; control1Y: 277.601; control2X: 48.2; control2Y: 277.601; x: 49.4; y: 284.001 }
+ PathCubic { control1X: 49.4; control1Y: 284.001; control2X: 57.8; control2Y: 305.201; x: 59.8; y: 306.801 }
+ PathCubic { control1X: 59.8; control1Y: 306.801; control2X: 52.2; control2Y: 285.201; x: 53.8; y: 285.201 }
+ PathCubic { control1X: 53.8; control1Y: 285.201; control2X: 51.8; control2Y: 273.201; x: 57; y: 288.001 }
+ PathCubic { control1X: 57; control1Y: 288.001; control2X: 53.8; control2Y: 274.001; x: 59.4; y: 274.801 }
+ PathCubic { control1X: 65; control1Y: 275.601; control2X: 69.4; control2Y: 285.601; x: 77.8; y: 283.201 }
+ PathCubic { control1X: 77.8; control1Y: 283.201; control2X: 87.401; control2Y: 288.801; x: 89.401; y: 219.601 }
+ PathLine { x: -34.6; y: 266.401 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -29.8; y: 173.601 }
+ PathCubic { control1X: -29.8; control1Y: 173.601; control2X: -15; control2Y: 167.601; x: 25; y: 173.601 }
+ PathCubic { control1X: 25; control1Y: 173.601; control2X: 32.2; control2Y: 174.001; x: 39; y: 165.201 }
+ PathCubic { control1X: 45.8; control1Y: 156.401; control2X: 72.6; control2Y: 149.201; x: 79; y: 151.201 }
+ PathLine { x: 88.601; y: 157.601 }
+ PathLine { x: 89.401; y: 158.801 }
+ PathCubic { control1X: 89.401; control1Y: 158.801; control2X: 101.801; control2Y: 169.201; x: 102.201; y: 176.801 }
+ PathCubic { control1X: 102.601; control1Y: 184.401; control2X: 87.801; control2Y: 232.401; x: 78.2; y: 248.401 }
+ PathCubic { control1X: 68.6; control1Y: 264.401; control2X: 59; control2Y: 276.801; x: 39.8; y: 274.401 }
+ PathCubic { control1X: 39.8; control1Y: 274.401; control2X: 19; control2Y: 270.401; x: -6.6; y: 274.401 }
+ PathCubic { control1X: -6.6; control1Y: 274.401; control2X: -35.8; control2Y: 272.801; x: -38.6; y: 264.801 }
+ PathCubic { control1X: -41.4; control1Y: 256.801; control2X: -27.4; control2Y: 241.601; x: -27.4; y: 241.601 }
+ PathCubic { control1X: -27.4; control1Y: 241.601; control2X: -23; control2Y: 233.201; x: -24.2; y: 218.801 }
+ PathCubic { control1X: -25.4; control1Y: 204.401; control2X: -25; control2Y: 176.401; x: -29.8; y: 173.601 }
+ }
+
+ ShapePath {
+ fillColor: "#e5668c"
+ strokeWidth: -1
+ PathMove { x: -7.8; y: 175.601 }
+ PathCubic { control1X: 0.6; control1Y: 194.001; control2X: -29; control2Y: 259.201; x: -29; y: 259.201 }
+ PathCubic { control1X: -31; control1Y: 260.801; control2X: -16.34; control2Y: 266.846; x: -6.2; y: 264.401 }
+ PathCubic { control1X: 4.746; control1Y: 261.763; control2X: 45; control2Y: 266.001; x: 45; y: 266.001 }
+ PathCubic { control1X: 68.6; control1Y: 250.401; control2X: 81.4; control2Y: 206.001; x: 81.4; y: 206.001 }
+ PathCubic { control1X: 81.4; control1Y: 206.001; control2X: 91.801; control2Y: 182.001; x: 74.2; y: 178.801 }
+ PathCubic { control1X: 56.6; control1Y: 175.601; control2X: -7.8; control2Y: 175.601; x: -7.8; y: 175.601 }
+ }
+
+ ShapePath {
+ fillColor: "#b23259"
+ strokeWidth: -1
+ PathMove { x: -9.831; y: 206.497 }
+ PathCubic { control1X: -6.505; control1Y: 193.707; control2X: -4.921; control2Y: 181.906; x: -7.8; y: 175.601 }
+ PathCubic { control1X: -7.8; control1Y: 175.601; control2X: 54.6; control2Y: 182.001; x: 65.8; y: 161.201 }
+ PathCubic { control1X: 70.041; control1Y: 153.326; control2X: 84.801; control2Y: 184.001; x: 84.4; y: 193.601 }
+ PathCubic { control1X: 84.4; control1Y: 193.601; control2X: 21.4; control2Y: 208.001; x: 6.6; y: 196.801 }
+ PathLine { x: -9.831; y: 206.497 }
+ }
+
+ ShapePath {
+ fillColor: "#a5264c"
+ strokeWidth: -1
+ PathMove { x: -5.4; y: 222.801 }
+ PathCubic { control1X: -5.4; control1Y: 222.801; control2X: -3.4; control2Y: 230.001; x: -5.8; y: 234.001 }
+ PathCubic { control1X: -5.8; control1Y: 234.001; control2X: -7.4; control2Y: 234.801; x: -8.6; y: 235.201 }
+ PathCubic { control1X: -8.6; control1Y: 235.201; control2X: -7.4; control2Y: 238.801; x: -1.4; y: 240.401 }
+ PathCubic { control1X: -1.4; control1Y: 240.401; control2X: 0.6; control2Y: 244.801; x: 3; y: 245.201 }
+ PathCubic { control1X: 5.4; control1Y: 245.601; control2X: 10.2; control2Y: 251.201; x: 14.2; y: 250.001 }
+ PathCubic { control1X: 18.2; control1Y: 248.801; control2X: 29.4; control2Y: 244.801; x: 29.4; y: 244.801 }
+ PathCubic { control1X: 29.4; control1Y: 244.801; control2X: 35; control2Y: 241.601; x: 43.8; y: 245.201 }
+ PathCubic { control1X: 43.8; control1Y: 245.201; control2X: 46.175; control2Y: 244.399; x: 46.6; y: 240.401 }
+ PathCubic { control1X: 47.1; control1Y: 235.701; control2X: 50.2; control2Y: 232.001; x: 52.2; y: 230.001 }
+ PathCubic { control1X: 54.2; control1Y: 228.001; control2X: 63.8; control2Y: 215.201; x: 62.6; y: 214.801 }
+ PathCubic { control1X: 61.4; control1Y: 214.401; control2X: -5.4; control2Y: 222.801; x: -5.4; y: 222.801 }
+ }
+
+ ShapePath {
+ fillColor: "#ff727f"
+ strokeColor: "#000000"
+ strokeWidth: 1
+ PathMove { x: -9.8; y: 174.401 }
+ PathCubic { control1X: -9.8; control1Y: 174.401; control2X: -12.6; control2Y: 196.801; x: -9.4; y: 205.201 }
+ PathCubic { control1X: -6.2; control1Y: 213.601; control2X: -7; control2Y: 215.601; x: -7.8; y: 219.601 }
+ PathCubic { control1X: -8.6; control1Y: 223.601; control2X: -4.2; control2Y: 233.601; x: 1.4; y: 239.601 }
+ PathLine { x: 13.4; y: 241.201 }
+ PathCubic { control1X: 13.4; control1Y: 241.201; control2X: 28.6; control2Y: 237.601; x: 37.8; y: 240.401 }
+ PathCubic { control1X: 37.8; control1Y: 240.401; control2X: 46.794; control2Y: 241.744; x: 50.2; y: 226.801 }
+ PathCubic { control1X: 50.2; control1Y: 226.801; control2X: 55; control2Y: 220.401; x: 62.2; y: 217.601 }
+ PathCubic { control1X: 69.4; control1Y: 214.801; control2X: 76.6; control2Y: 173.201; x: 72.6; y: 165.201 }
+ PathCubic { control1X: 68.6; control1Y: 157.201; control2X: 54.2; control2Y: 152.801; x: 38.2; y: 168.401 }
+ PathCubic { control1X: 22.2; control1Y: 184.001; control2X: 20.2; control2Y: 167.201; x: -9.8; y: 174.401 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffcc"
+ strokeColor: "#000000"
+ strokeWidth: 0.5
+ PathMove { x: -8.2; y: 249.201 }
+ PathCubic { control1X: -8.2; control1Y: 249.201; control2X: -9; control2Y: 247.201; x: -13.4; y: 246.801 }
+ PathCubic { control1X: -13.4; control1Y: 246.801; control2X: -35.8; control2Y: 243.201; x: -44.2; y: 230.801 }
+ PathCubic { control1X: -44.2; control1Y: 230.801; control2X: -51; control2Y: 225.201; x: -46.6; y: 236.801 }
+ PathCubic { control1X: -46.6; control1Y: 236.801; control2X: -36.2; control2Y: 257.201; x: -29.4; y: 260.001 }
+ PathCubic { control1X: -29.4; control1Y: 260.001; control2X: -13; control2Y: 264.001; x: -8.2; y: 249.201 }
+ }
+
+ ShapePath {
+ fillColor: "#cc3f4c"
+ strokeWidth: -1
+ PathMove { x: 71.742; y: 185.229 }
+ PathCubic { control1X: 72.401; control1Y: 177.323; control2X: 74.354; control2Y: 168.709; x: 72.6; y: 165.201 }
+ PathCubic { control1X: 66.154; control1Y: 152.307; control2X: 49.181; control2Y: 157.695; x: 38.2; y: 168.401 }
+ PathCubic { control1X: 22.2; control1Y: 184.001; control2X: 20.2; control2Y: 167.201; x: -9.8; y: 174.401 }
+ PathCubic { control1X: -9.8; control1Y: 174.401; control2X: -11.545; control2Y: 188.364; x: -10.705; y: 198.376 }
+ PathCubic { control1X: -10.705; control1Y: 198.376; control2X: 26.6; control2Y: 186.801; x: 27.4; y: 192.401 }
+ PathCubic { control1X: 27.4; control1Y: 192.401; control2X: 29; control2Y: 189.201; x: 38.2; y: 189.201 }
+ PathCubic { control1X: 47.4; control1Y: 189.201; control2X: 70.142; control2Y: 188.029; x: 71.742; y: 185.229 }
+ }
+
+ ShapePath {
+ fillColor: "transparent"
+ strokeColor: "#a51926"
+ strokeWidth: 2
+ PathMove { x: 28.6; y: 175.201 }
+ PathCubic { control1X: 28.6; control1Y: 175.201; control2X: 33.4; control2Y: 180.001; x: 29.8; y: 189.601 }
+ PathCubic { control1X: 29.8; control1Y: 189.601; control2X: 15.4; control2Y: 205.601; x: 17.4; y: 219.601 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffcc"
+ strokeColor: "#000000"
+ strokeWidth: 0.5
+ PathMove { x: -19.4; y: 260.001 }
+ PathCubic { control1X: -19.4; control1Y: 260.001; control2X: -23.8; control2Y: 247.201; x: -15; y: 254.001 }
+ PathCubic { control1X: -15; control1Y: 254.001; control2X: -10.2; control2Y: 256.001; x: -11.4; y: 257.601 }
+ PathCubic { control1X: -12.6; control1Y: 259.201; control2X: -18.2; control2Y: 263.201; x: -19.4; y: 260.001 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffcc"
+ strokeColor: "#000000"
+ strokeWidth: 0.5
+ PathMove { x: -14.36; y: 261.201 }
+ PathCubic { control1X: -14.36; control1Y: 261.201; control2X: -17.88; control2Y: 250.961; x: -10.84; y: 256.401 }
+ PathCubic { control1X: -10.84; control1Y: 256.401; control2X: -6.419; control2Y: 258.849; x: -7.96; y: 259.281 }
+ PathCubic { control1X: -12.52; control1Y: 260.561; control2X: -7.96; control2Y: 263.121; x: -14.36; y: 261.201 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffcc"
+ strokeColor: "#000000"
+ strokeWidth: 0.5
+ PathMove { x: -9.56; y: 261.201 }
+ PathCubic { control1X: -9.56; control1Y: 261.201; control2X: -13.08; control2Y: 250.961; x: -6.04; y: 256.401 }
+ PathCubic { control1X: -6.04; control1Y: 256.401; control2X: -1.665; control2Y: 258.711; x: -3.16; y: 259.281 }
+ PathCubic { control1X: -6.52; control1Y: 260.561; control2X: -3.16; control2Y: 263.121; x: -9.56; y: 261.201 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffcc"
+ strokeColor: "#000000"
+ strokeWidth: 0.5
+ PathMove { x: -2.96; y: 261.401 }
+ PathCubic { control1X: -2.96; control1Y: 261.401; control2X: -6.48; control2Y: 251.161; x: 0.56; y: 256.601 }
+ PathCubic { control1X: 0.56; control1Y: 256.601; control2X: 4.943; control2Y: 258.933; x: 3.441; y: 259.481 }
+ PathCubic { control1X: 0.48; control1Y: 260.561; control2X: 3.441; control2Y: 263.321; x: -2.96; y: 261.401 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffcc"
+ strokeColor: "#000000"
+ strokeWidth: 0.5
+ PathMove { x: 3.52; y: 261.321 }
+ PathCubic { control1X: 3.52; control1Y: 261.321; control2X: 0; control2Y: 251.081; x: 7.041; y: 256.521 }
+ PathCubic { control1X: 7.041; control1Y: 256.521; control2X: 10.881; control2Y: 258.121; x: 9.921; y: 259.401 }
+ PathCubic { control1X: 8.961; control1Y: 260.681; control2X: 9.921; control2Y: 263.241; x: 3.52; y: 261.321 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffcc"
+ strokeColor: "#000000"
+ strokeWidth: 0.5
+ PathMove { x: 10.2; y: 262.001 }
+ PathCubic { control1X: 10.2; control1Y: 262.001; control2X: 5.4; control2Y: 249.601; x: 14.6; y: 256.001 }
+ PathCubic { control1X: 14.6; control1Y: 256.001; control2X: 19.4; control2Y: 258.001; x: 18.2; y: 259.601 }
+ PathCubic { control1X: 17; control1Y: 261.201; control2X: 18.2; control2Y: 264.401; x: 10.2; y: 262.001 }
+ }
+
+ ShapePath {
+ fillColor: "transparent"
+ strokeColor: "#a5264c"
+ strokeWidth: 2
+ PathMove { x: -18.2; y: 244.801 }
+ PathCubic { control1X: -18.2; control1Y: 244.801; control2X: -5; control2Y: 242.001; x: 1; y: 245.201 }
+ PathCubic { control1X: 1; control1Y: 245.201; control2X: 7; control2Y: 246.401; x: 8.2; y: 246.001 }
+ PathCubic { control1X: 9.4; control1Y: 245.601; control2X: 12.6; control2Y: 245.201; x: 12.6; y: 245.201 }
+ }
+
+ ShapePath {
+ fillColor: "transparent"
+ strokeColor: "#a5264c"
+ strokeWidth: 2
+ PathMove { x: 15.8; y: 253.601 }
+ PathCubic { control1X: 15.8; control1Y: 253.601; control2X: 27.8; control2Y: 240.001; x: 39.8; y: 244.401 }
+ PathCubic { control1X: 46.816; control1Y: 246.974; control2X: 45.8; control2Y: 243.601; x: 46.6; y: 240.801 }
+ PathCubic { control1X: 47.4; control1Y: 238.001; control2X: 47.6; control2Y: 233.801; x: 52.6; y: 230.801 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffcc"
+ strokeColor: "#000000"
+ strokeWidth: 0.5
+ PathMove { x: 33; y: 237.601 }
+ PathCubic { control1X: 33; control1Y: 237.601; control2X: 29; control2Y: 226.801; x: 26.2; y: 239.601 }
+ PathCubic { control1X: 23.4; control1Y: 252.401; control2X: 20.2; control2Y: 256.001; x: 18.6; y: 258.801 }
+ PathCubic { control1X: 18.6; control1Y: 258.801; control2X: 18.6; control2Y: 264.001; x: 27; y: 263.601 }
+ PathCubic { control1X: 27; control1Y: 263.601; control2X: 37.8; control2Y: 263.201; x: 38.2; y: 260.401 }
+ PathCubic { control1X: 38.6; control1Y: 257.601; control2X: 37; control2Y: 246.001; x: 33; y: 237.601 }
+ }
+
+ ShapePath {
+ fillColor: "transparent"
+ strokeColor: "#a5264c"
+ strokeWidth: 2
+ PathMove { x: 47; y: 244.801 }
+ PathCubic { control1X: 47; control1Y: 244.801; control2X: 50.6; control2Y: 242.401; x: 53; y: 243.601 }
+ }
+
+ ShapePath {
+ fillColor: "transparent"
+ strokeColor: "#a5264c"
+ strokeWidth: 2
+ PathMove { x: 53.5; y: 228.401 }
+ PathCubic { control1X: 53.5; control1Y: 228.401; control2X: 56.4; control2Y: 223.501; x: 61.2; y: 222.701 }
+ }
+
+ ShapePath {
+ fillColor: "#b2b2b2"
+ strokeWidth: -1
+ PathMove { x: -25.8; y: 265.201 }
+ PathCubic { control1X: -25.8; control1Y: 265.201; control2X: -7.8; control2Y: 268.401; x: -3.4; y: 266.801 }
+ PathCubic { control1X: -3.4; control1Y: 266.801; control2X: 5.4; control2Y: 266.801; x: -3; y: 268.801 }
+ PathCubic { control1X: -3; control1Y: 268.801; control2X: -15.8; control2Y: 268.801; x: -23.8; y: 267.601 }
+ PathCubic { control1X: -23.8; control1Y: 267.601; control2X: -35.4; control2Y: 262.001; x: -25.8; y: 265.201 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffcc"
+ strokeColor: "#000000"
+ strokeWidth: 0.5
+ PathMove { x: -11.8; y: 172.001 }
+ PathCubic { control1X: -11.8; control1Y: 172.001; control2X: 5.8; control2Y: 172.001; x: 7.8; y: 172.801 }
+ PathCubic { control1X: 7.8; control1Y: 172.801; control2X: 15; control2Y: 203.601; x: 11.4; y: 211.201 }
+ PathCubic { control1X: 11.4; control1Y: 211.201; control2X: 10.2; control2Y: 214.001; x: 7.4; y: 208.401 }
+ PathCubic { control1X: 7.4; control1Y: 208.401; control2X: -11; control2Y: 175.601; x: -14.2; y: 173.601 }
+ PathCubic { control1X: -17.4; control1Y: 171.601; control2X: -13; control2Y: 172.001; x: -11.8; y: 172.001 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffcc"
+ strokeColor: "#000000"
+ strokeWidth: 0.5
+ PathMove { x: -88.9; y: 169.301 }
+ PathCubic { control1X: -88.9; control1Y: 169.301; control2X: -80; control2Y: 171.001; x: -67.4; y: 173.601 }
+ PathCubic { control1X: -67.4; control1Y: 173.601; control2X: -62.6; control2Y: 196.001; x: -59.4; y: 200.801 }
+ PathCubic { control1X: -56.2; control1Y: 205.601; control2X: -59.8; control2Y: 205.601; x: -63.4; y: 202.801 }
+ PathCubic { control1X: -67; control1Y: 200.001; control2X: -81.8; control2Y: 186.001; x: -83.8; y: 181.601 }
+ PathCubic { control1X: -85.8; control1Y: 177.201; control2X: -88.9; control2Y: 169.301; x: -88.9; y: 169.301 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffcc"
+ strokeColor: "#000000"
+ strokeWidth: 0.5
+ PathMove { x: -67.039; y: 173.818 }
+ PathCubic { control1X: -67.039; control1Y: 173.818; control2X: -61.239; control2Y: 175.366; x: -60.23; y: 177.581 }
+ PathCubic { control1X: -59.222; control1Y: 179.795; control2X: -61.432; control2Y: 183.092; x: -61.432; y: 183.092 }
+ PathCubic { control1X: -61.432; control1Y: 183.092; control2X: -62.432; control2Y: 186.397; x: -63.634; y: 184.235 }
+ PathCubic { control1X: -64.836; control1Y: 182.072; control2X: -67.708; control2Y: 174.412; x: -67.039; y: 173.818 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -67; y: 173.601 }
+ PathCubic { control1X: -67; control1Y: 173.601; control2X: -63.4; control2Y: 178.801; x: -59.8; y: 178.801 }
+ PathCubic { control1X: -56.2; control1Y: 178.801; control2X: -55.818; control2Y: 178.388; x: -53; y: 179.001 }
+ PathCubic { control1X: -48.4; control1Y: 180.001; control2X: -48.8; control2Y: 178.001; x: -42.2; y: 179.201 }
+ PathCubic { control1X: -39.56; control1Y: 179.681; control2X: -37; control2Y: 178.801; x: -34.2; y: 180.001 }
+ PathCubic { control1X: -31.4; control1Y: 181.201; control2X: -28.2; control2Y: 180.401; x: -27; y: 178.401 }
+ PathCubic { control1X: -25.8; control1Y: 176.401; control2X: -21; control2Y: 172.201; x: -21; y: 172.201 }
+ PathCubic { control1X: -21; control1Y: 172.201; control2X: -33.8; control2Y: 174.001; x: -36.6; y: 174.801 }
+ PathCubic { control1X: -36.6; control1Y: 174.801; control2X: -59; control2Y: 176.001; x: -67; y: 173.601 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffcc"
+ strokeColor: "#000000"
+ strokeWidth: 0.5
+ PathMove { x: -22.4; y: 173.801 }
+ PathCubic { control1X: -22.4; control1Y: 173.801; control2X: -28.85; control2Y: 177.301; x: -29.25; y: 179.701 }
+ PathCubic { control1X: -29.65; control1Y: 182.101; control2X: -24; control2Y: 185.801; x: -24; y: 185.801 }
+ PathCubic { control1X: -24; control1Y: 185.801; control2X: -21.25; control2Y: 190.401; x: -20.65; y: 188.001 }
+ PathCubic { control1X: -20.05; control1Y: 185.601; control2X: -21.6; control2Y: 174.201; x: -22.4; y: 173.801 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffcc"
+ strokeColor: "#000000"
+ strokeWidth: 0.5
+ PathMove { x: -59.885; y: 179.265 }
+ PathCubic { control1X: -59.885; control1Y: 179.265; control2X: -52.878; control2Y: 190.453; x: -52.661; y: 179.242 }
+ PathCubic { control1X: -52.661; control1Y: 179.242; control2X: -52.104; control2Y: 177.984; x: -53.864; y: 177.962 }
+ PathCubic { control1X: -59.939; control1Y: 177.886; control2X: -58.418; control2Y: 173.784; x: -59.885; y: 179.265 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffcc"
+ strokeColor: "#000000"
+ strokeWidth: 0.5
+ PathMove { x: -52.707; y: 179.514 }
+ PathCubic { control1X: -52.707; control1Y: 179.514; control2X: -44.786; control2Y: 190.701; x: -45.422; y: 179.421 }
+ PathCubic { control1X: -45.422; control1Y: 179.421; control2X: -45.415; control2Y: 179.089; x: -47.168; y: 178.936 }
+ PathCubic { control1X: -51.915; control1Y: 178.522; control2X: -51.57; control2Y: 174.004; x: -52.707; y: 179.514 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffcc"
+ strokeColor: "#000000"
+ strokeWidth: 0.5
+ PathMove { x: -45.494; y: 179.522 }
+ PathCubic { control1X: -45.494; control1Y: 179.522; control2X: -37.534; control2Y: 190.15; x: -38.203; y: 180.484 }
+ PathCubic { control1X: -38.203; control1Y: 180.484; control2X: -38.084; control2Y: 179.251; x: -39.738; y: 178.95 }
+ PathCubic { control1X: -43.63; control1Y: 178.244; control2X: -43.841; control2Y: 174.995; x: -45.494; y: 179.522 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffcc"
+ strokeColor: "#000000"
+ strokeWidth: 0.5
+ PathMove { x: -38.618; y: 179.602 }
+ PathCubic { control1X: -38.618; control1Y: 179.602; control2X: -30.718; control2Y: 191.163; x: -30.37; y: 181.382 }
+ PathCubic { control1X: -30.37; control1Y: 181.382; control2X: -28.726; control2Y: 180.004; x: -30.472; y: 179.782 }
+ PathCubic { control1X: -36.29; control1Y: 179.042; control2X: -35.492; control2Y: 174.588; x: -38.618; y: 179.602 }
+ }
+
+ ShapePath {
+ fillColor: "#e5e5b2"
+ strokeWidth: -1
+ PathMove { x: -74.792; y: 183.132 }
+ PathLine { x: -82.45; y: 181.601 }
+ PathCubic { control1X: -85.05; control1Y: 176.601; control2X: -87.15; control2Y: 170.451; x: -87.15; y: 170.451 }
+ PathCubic { control1X: -87.15; control1Y: 170.451; control2X: -80.8; control2Y: 171.451; x: -68.3; y: 174.251 }
+ PathCubic { control1X: -68.3; control1Y: 174.251; control2X: -67.424; control2Y: 177.569; x: -65.952; y: 183.364 }
+ PathLine { x: -74.792; y: 183.132 }
+ }
+
+ ShapePath {
+ fillColor: "#e5e5b2"
+ strokeWidth: -1
+ PathMove { x: -9.724; y: 178.47 }
+ PathCubic { control1X: -11.39; control1Y: 175.964; control2X: -12.707; control2Y: 174.206; x: -13.357; y: 173.8 }
+ PathCubic { control1X: -16.37; control1Y: 171.917; control2X: -12.227; control2Y: 172.294; x: -11.098; y: 172.294 }
+ PathCubic { control1X: -11.098; control1Y: 172.294; control2X: 5.473; control2Y: 172.294; x: 7.356; y: 173.047 }
+ PathCubic { control1X: 7.356; control1Y: 173.047; control2X: 7.88; control2Y: 175.289; x: 8.564; y: 178.68 }
+ PathCubic { control1X: 8.564; control1Y: 178.68; control2X: -1.524; control2Y: 176.67; x: -9.724; y: 178.47 }
+ }
+
+ ShapePath {
+ fillColor: "#cc7226"
+ strokeWidth: -1
+ PathMove { x: 43.88; y: 40.321 }
+ PathCubic { control1X: 71.601; control1Y: 44.281; control2X: 97.121; control2Y: 8.641; x: 98.881; y: -1.04 }
+ PathCubic { control1X: 100.641; control1Y: -10.72; control2X: 90.521; control2Y: -22.6; x: 90.521; y: -22.6 }
+ PathCubic { control1X: 91.841; control1Y: -25.68; control2X: 87.001; control2Y: -39.76; x: 81.721; y: -49 }
+ PathCubic { control1X: 76.441; control1Y: -58.24; control2X: 60.54; control2Y: -57.266; x: 43; y: -58.24 }
+ PathCubic { control1X: 27.16; control1Y: -59.12; control2X: 8.68; control2Y: -35.8; x: 7.36; y: -34.04 }
+ PathCubic { control1X: 6.04; control1Y: -32.28; control2X: 12.2; control2Y: 6.001; x: 13.52; y: 11.721 }
+ PathCubic { control1X: 14.84; control1Y: 17.441; control2X: 12.2; control2Y: 43.841; x: 12.2; y: 43.841 }
+ PathCubic { control1X: 46.44; control1Y: 34.741; control2X: 16.16; control2Y: 36.361; x: 43.88; y: 40.321 }
+ }
+
+ ShapePath {
+ fillColor: "#ea8e51"
+ strokeWidth: -1
+ PathMove { x: 8.088; y: -33.392 }
+ PathCubic { control1X: 6.792; control1Y: -31.664; control2X: 12.84; control2Y: 5.921; x: 14.136; y: 11.537 }
+ PathCubic { control1X: 15.432; control1Y: 17.153; control2X: 12.84; control2Y: 43.073; x: 12.84; y: 43.073 }
+ PathCubic { control1X: 45.512; control1Y: 34.193; control2X: 16.728; control2Y: 35.729; x: 43.944; y: 39.617 }
+ PathCubic { control1X: 71.161; control1Y: 43.505; control2X: 96.217; control2Y: 8.513; x: 97.945; y: -0.992 }
+ PathCubic { control1X: 99.673; control1Y: -10.496; control2X: 89.737; control2Y: -22.16; x: 89.737; y: -22.16 }
+ PathCubic { control1X: 91.033; control1Y: -25.184; control2X: 86.281; control2Y: -39.008; x: 81.097; y: -48.08 }
+ PathCubic { control1X: 75.913; control1Y: -57.152; control2X: 60.302; control2Y: -56.195; x: 43.08; y: -57.152 }
+ PathCubic { control1X: 27.528; control1Y: -58.016; control2X: 9.384; control2Y: -35.12; x: 8.088; y: -33.392 }
+ }
+
+ ShapePath {
+ fillColor: "#efaa7c"
+ strokeWidth: -1
+ PathMove { x: 8.816; y: -32.744 }
+ PathCubic { control1X: 7.544; control1Y: -31.048; control2X: 13.48; control2Y: 5.841; x: 14.752; y: 11.353 }
+ PathCubic { control1X: 16.024; control1Y: 16.865; control2X: 13.48; control2Y: 42.305; x: 13.48; y: 42.305 }
+ PathCubic { control1X: 44.884; control1Y: 33.145; control2X: 17.296; control2Y: 35.097; x: 44.008; y: 38.913 }
+ PathCubic { control1X: 70.721; control1Y: 42.729; control2X: 95.313; control2Y: 8.385; x: 97.009; y: -0.944 }
+ PathCubic { control1X: 98.705; control1Y: -10.272; control2X: 88.953; control2Y: -21.72; x: 88.953; y: -21.72 }
+ PathCubic { control1X: 90.225; control1Y: -24.688; control2X: 85.561; control2Y: -38.256; x: 80.473; y: -47.16 }
+ PathCubic { control1X: 75.385; control1Y: -56.064; control2X: 60.063; control2Y: -55.125; x: 43.16; y: -56.064 }
+ PathCubic { control1X: 27.896; control1Y: -56.912; control2X: 10.088; control2Y: -34.44; x: 8.816; y: -32.744 }
+ }
+
+ ShapePath {
+ fillColor: "#f4c6a8"
+ strokeWidth: -1
+ PathMove { x: 9.544; y: -32.096 }
+ PathCubic { control1X: 8.296; control1Y: -30.432; control2X: 14.12; control2Y: 5.761; x: 15.368; y: 11.169 }
+ PathCubic { control1X: 16.616; control1Y: 16.577; control2X: 14.12; control2Y: 41.537; x: 14.12; y: 41.537 }
+ PathCubic { control1X: 43.556; control1Y: 32.497; control2X: 17.864; control2Y: 34.465; x: 44.072; y: 38.209 }
+ PathCubic { control1X: 70.281; control1Y: 41.953; control2X: 94.409; control2Y: 8.257; x: 96.073; y: -0.895 }
+ PathCubic { control1X: 97.737; control1Y: -10.048; control2X: 88.169; control2Y: -21.28; x: 88.169; y: -21.28 }
+ PathCubic { control1X: 89.417; control1Y: -24.192; control2X: 84.841; control2Y: -37.504; x: 79.849; y: -46.24 }
+ PathCubic { control1X: 74.857; control1Y: -54.976; control2X: 59.824; control2Y: -54.055; x: 43.24; y: -54.976 }
+ PathCubic { control1X: 28.264; control1Y: -55.808; control2X: 10.792; control2Y: -33.76; x: 9.544; y: -32.096 }
+ }
+
+ ShapePath {
+ fillColor: "#f9e2d3"
+ strokeWidth: -1
+ PathMove { x: 10.272; y: -31.448 }
+ PathCubic { control1X: 9.048; control1Y: -29.816; control2X: 14.76; control2Y: 5.681; x: 15.984; y: 10.985 }
+ PathCubic { control1X: 17.208; control1Y: 16.289; control2X: 14.76; control2Y: 40.769; x: 14.76; y: 40.769 }
+ PathCubic { control1X: 42.628; control1Y: 31.849; control2X: 18.432; control2Y: 33.833; x: 44.136; y: 37.505 }
+ PathCubic { control1X: 69.841; control1Y: 41.177; control2X: 93.505; control2Y: 8.129; x: 95.137; y: -0.848 }
+ PathCubic { control1X: 96.769; control1Y: -9.824; control2X: 87.385; control2Y: -20.84; x: 87.385; y: -20.84 }
+ PathCubic { control1X: 88.609; control1Y: -23.696; control2X: 84.121; control2Y: -36.752; x: 79.225; y: -45.32 }
+ PathCubic { control1X: 74.329; control1Y: -53.888; control2X: 59.585; control2Y: -52.985; x: 43.32; y: -53.888 }
+ PathCubic { control1X: 28.632; control1Y: -54.704; control2X: 11.496; control2Y: -33.08; x: 10.272; y: -31.448 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeWidth: -1
+ PathMove { x: 44.2; y: 36.8 }
+ PathCubic { control1X: 69.4; control1Y: 40.4; control2X: 92.601; control2Y: 8; x: 94.201; y: -0.8 }
+ PathCubic { control1X: 95.801; control1Y: -9.6; control2X: 86.601; control2Y: -20.4; x: 86.601; y: -20.4 }
+ PathCubic { control1X: 87.801; control1Y: -23.2; control2X: 83.4; control2Y: -36; x: 78.6; y: -44.4 }
+ PathCubic { control1X: 73.8; control1Y: -52.8; control2X: 59.346; control2Y: -51.914; x: 43.4; y: -52.8 }
+ PathCubic { control1X: 29; control1Y: -53.6; control2X: 12.2; control2Y: -32.4; x: 11; y: -30.8 }
+ PathCubic { control1X: 9.8; control1Y: -29.2; control2X: 15.4; control2Y: 5.6; x: 16.6; y: 10.8 }
+ PathCubic { control1X: 17.8; control1Y: 16; control2X: 15.4; control2Y: 40; x: 15.4; y: 40 }
+ PathCubic { control1X: 40.9; control1Y: 31.4; control2X: 19; control2Y: 33.2; x: 44.2; y: 36.8 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: 90.601; y: 2.8 }
+ PathCubic { control1X: 90.601; control1Y: 2.8; control2X: 62.8; control2Y: 10.4; x: 51.2; y: 8.8 }
+ PathCubic { control1X: 51.2; control1Y: 8.8; control2X: 35.4; control2Y: 2.2; x: 26.6; y: 24 }
+ PathCubic { control1X: 26.6; control1Y: 24; control2X: 23; control2Y: 31.2; x: 21; y: 33.2 }
+ PathCubic { control1X: 19; control1Y: 35.2; control2X: 90.601; control2Y: 2.8; x: 90.601; y: 2.8 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 94.401; y: 0.6 }
+ PathCubic { control1X: 94.401; control1Y: 0.6; control2X: 65.4; control2Y: 12.8; x: 55.4; y: 12.4 }
+ PathCubic { control1X: 55.4; control1Y: 12.4; control2X: 39; control2Y: 7.8; x: 30.6; y: 22.4 }
+ PathCubic { control1X: 30.6; control1Y: 22.4; control2X: 22.2; control2Y: 31.6; x: 19; y: 33.2 }
+ PathCubic { control1X: 19; control1Y: 33.2; control2X: 18.6; control2Y: 34.8; x: 25; y: 30.8 }
+ PathLine { x: 35.4; y: 36 }
+ PathCubic { control1X: 35.4; control1Y: 36; control2X: 50.2; control2Y: 45.6; x: 59.8; y: 29.6 }
+ PathCubic { control1X: 59.8; control1Y: 29.6; control2X: 63.8; control2Y: 18.4; x: 63.8; y: 16.4 }
+ PathCubic { control1X: 63.8; control1Y: 14.4; control2X: 85; control2Y: 8.8; x: 86.601; y: 8.4 }
+ PathCubic { control1X: 88.201; control1Y: 8; control2X: 94.801; control2Y: 3.8; x: 94.401; y: 0.6 }
+ }
+
+ ShapePath {
+ fillColor: "#99cc32"
+ strokeWidth: -1
+ PathMove { x: 47; y: 36.514 }
+ PathCubic { control1X: 40.128; control1Y: 36.514; control2X: 31.755; control2Y: 32.649; x: 31.755; y: 26.4 }
+ PathCubic { control1X: 31.755; control1Y: 20.152; control2X: 40.128; control2Y: 13.887; x: 47; y: 13.887 }
+ PathCubic { control1X: 53.874; control1Y: 13.887; control2X: 59.446; control2Y: 18.952; x: 59.446; y: 25.2 }
+ PathCubic { control1X: 59.446; control1Y: 31.449; control2X: 53.874; control2Y: 36.514; x: 47; y: 36.514 }
+ }
+
+ ShapePath {
+ fillColor: "#659900"
+ strokeWidth: -1
+ PathMove { x: 43.377; y: 19.83 }
+ PathCubic { control1X: 38.531; control1Y: 20.552; control2X: 33.442; control2Y: 22.055; x: 33.514; y: 21.839 }
+ PathCubic { control1X: 35.054; control1Y: 17.22; control2X: 41.415; control2Y: 13.887; x: 47; y: 13.887 }
+ PathCubic { control1X: 51.296; control1Y: 13.887; control2X: 55.084; control2Y: 15.865; x: 57.32; y: 18.875 }
+ PathCubic { control1X: 57.32; control1Y: 18.875; control2X: 52.004; control2Y: 18.545; x: 43.377; y: 19.83 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeWidth: -1
+ PathMove { x: 55.4; y: 19.6 }
+ PathCubic { control1X: 55.4; control1Y: 19.6; control2X: 51; control2Y: 16.4; x: 51; y: 18.6 }
+ PathCubic { control1X: 51; control1Y: 18.6; control2X: 54.6; control2Y: 23; x: 55.4; y: 19.6 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 45.4; y: 27.726 }
+ PathCubic { control1X: 42.901; control1Y: 27.726; control2X: 40.875; control2Y: 25.7; x: 40.875; y: 23.2 }
+ PathCubic { control1X: 40.875; control1Y: 20.701; control2X: 42.901; control2Y: 18.675; x: 45.4; y: 18.675 }
+ PathCubic { control1X: 47.9; control1Y: 18.675; control2X: 49.926; control2Y: 20.701; x: 49.926; y: 23.2 }
+ PathCubic { control1X: 49.926; control1Y: 25.7; control2X: 47.9; control2Y: 27.726; x: 45.4; y: 27.726 }
+ }
+
+ ShapePath {
+ fillColor: "#cc7226"
+ strokeWidth: -1
+ PathMove { x: -58.6; y: 14.4 }
+ PathCubic { control1X: -58.6; control1Y: 14.4; control2X: -61.8; control2Y: -6.8; x: -59.4; y: -11.2 }
+ PathCubic { control1X: -59.4; control1Y: -11.2; control2X: -48.6; control2Y: -21.2; x: -49; y: -24.8 }
+ PathCubic { control1X: -49; control1Y: -24.8; control2X: -49.4; control2Y: -42.8; x: -50.6; y: -43.6 }
+ PathCubic { control1X: -51.8; control1Y: -44.4; control2X: -59.4; control2Y: -50.4; x: -65.4; y: -44 }
+ PathCubic { control1X: -65.4; control1Y: -44; control2X: -75.8; control2Y: -26; x: -75; y: -19.6 }
+ PathLine { x: -75; y: -17.6 }
+ PathCubic { control1X: -75; control1Y: -17.6; control2X: -82.6; control2Y: -18; x: -84.2; y: -16 }
+ PathCubic { control1X: -84.2; control1Y: -16; control2X: -85.4; control2Y: -10.8; x: -86.6; y: -10.4 }
+ PathCubic { control1X: -86.6; control1Y: -10.4; control2X: -89.4; control2Y: -8; x: -87.4; y: -5.2 }
+ PathCubic { control1X: -87.4; control1Y: -5.2; control2X: -89.4; control2Y: -2.8; x: -89; y: 1.2 }
+ PathLine { x: -81.4; y: 5.2 }
+ PathCubic { control1X: -81.4; control1Y: 5.2; control2X: -79.4; control2Y: 19.6; x: -68.6; y: 24.8 }
+ PathCubic { control1X: -63.764; control1Y: 27.129; control2X: -60.6; control2Y: 20.4; x: -58.6; y: 14.4 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeWidth: -1
+ PathMove { x: -59.6; y: 12.56 }
+ PathCubic { control1X: -59.6; control1Y: 12.56; control2X: -62.48; control2Y: -6.52; x: -60.32; y: -10.48 }
+ PathCubic { control1X: -60.32; control1Y: -10.48; control2X: -50.6; control2Y: -19.48; x: -50.96; y: -22.72 }
+ PathCubic { control1X: -50.96; control1Y: -22.72; control2X: -51.32; control2Y: -38.92; x: -52.4; y: -39.64 }
+ PathCubic { control1X: -53.48; control1Y: -40.36; control2X: -60.32; control2Y: -45.76; x: -65.72; y: -40 }
+ PathCubic { control1X: -65.72; control1Y: -40; control2X: -75.08; control2Y: -23.8; x: -74.36; y: -18.04 }
+ PathLine { x: -74.36; y: -16.24 }
+ PathCubic { control1X: -74.36; control1Y: -16.24; control2X: -81.2; control2Y: -16.6; x: -82.64; y: -14.8 }
+ PathCubic { control1X: -82.64; control1Y: -14.8; control2X: -83.72; control2Y: -10.12; x: -84.8; y: -9.76 }
+ PathCubic { control1X: -84.8; control1Y: -9.76; control2X: -87.32; control2Y: -7.6; x: -85.52; y: -5.08 }
+ PathCubic { control1X: -85.52; control1Y: -5.08; control2X: -87.32; control2Y: -2.92; x: -86.96; y: 0.68 }
+ PathLine { x: -80.12; y: 4.28 }
+ PathCubic { control1X: -80.12; control1Y: 4.28; control2X: -78.32; control2Y: 17.24; x: -68.6; y: 21.92 }
+ PathCubic { control1X: -64.248; control1Y: 24.015; control2X: -61.4; control2Y: 17.96; x: -59.6; y: 12.56 }
+ }
+
+ ShapePath {
+ fillColor: "#eb955c"
+ strokeWidth: -1
+ PathMove { x: -51.05; y: -42.61 }
+ PathCubic { control1X: -52.14; control1Y: -43.47; control2X: -59.63; control2Y: -49.24; x: -65.48; y: -43 }
+ PathCubic { control1X: -65.48; control1Y: -43; control2X: -75.62; control2Y: -25.45; x: -74.84; y: -19.21 }
+ PathLine { x: -74.84; y: -17.26 }
+ PathCubic { control1X: -74.84; control1Y: -17.26; control2X: -82.25; control2Y: -17.65; x: -83.81; y: -15.7 }
+ PathCubic { control1X: -83.81; control1Y: -15.7; control2X: -84.98; control2Y: -10.63; x: -86.15; y: -10.24 }
+ PathCubic { control1X: -86.15; control1Y: -10.24; control2X: -88.88; control2Y: -7.9; x: -86.93; y: -5.17 }
+ PathCubic { control1X: -86.93; control1Y: -5.17; control2X: -88.88; control2Y: -2.83; x: -88.49; y: 1.07 }
+ PathLine { x: -81.08; y: 4.97 }
+ PathCubic { control1X: -81.08; control1Y: 4.97; control2X: -79.13; control2Y: 19.01; x: -68.6; y: 24.08 }
+ PathCubic { control1X: -63.886; control1Y: 26.35; control2X: -60.8; control2Y: 19.79; x: -58.85; y: 13.94 }
+ PathCubic { control1X: -58.85; control1Y: 13.94; control2X: -61.97; control2Y: -6.73; x: -59.63; y: -11.02 }
+ PathCubic { control1X: -59.63; control1Y: -11.02; control2X: -49.1; control2Y: -20.77; x: -49.49; y: -24.28 }
+ PathCubic { control1X: -49.49; control1Y: -24.28; control2X: -49.88; control2Y: -41.83; x: -51.05; y: -42.61 }
+ }
+
+ ShapePath {
+ fillColor: "#f2b892"
+ strokeWidth: -1
+ PathMove { x: -51.5; y: -41.62 }
+ PathCubic { control1X: -52.48; control1Y: -42.54; control2X: -59.86; control2Y: -48.08; x: -65.56; y: -42 }
+ PathCubic { control1X: -65.56; control1Y: -42; control2X: -75.44; control2Y: -24.9; x: -74.68; y: -18.82 }
+ PathLine { x: -74.68; y: -16.92 }
+ PathCubic { control1X: -74.68; control1Y: -16.92; control2X: -81.9; control2Y: -17.3; x: -83.42; y: -15.4 }
+ PathCubic { control1X: -83.42; control1Y: -15.4; control2X: -84.56; control2Y: -10.46; x: -85.7; y: -10.08 }
+ PathCubic { control1X: -85.7; control1Y: -10.08; control2X: -88.36; control2Y: -7.8; x: -86.46; y: -5.14 }
+ PathCubic { control1X: -86.46; control1Y: -5.14; control2X: -88.36; control2Y: -2.86; x: -87.98; y: 0.94 }
+ PathLine { x: -80.76; y: 4.74 }
+ PathCubic { control1X: -80.76; control1Y: 4.74; control2X: -78.86; control2Y: 18.42; x: -68.6; y: 23.36 }
+ PathCubic { control1X: -64.006; control1Y: 25.572; control2X: -61; control2Y: 19.18; x: -59.1; y: 13.48 }
+ PathCubic { control1X: -59.1; control1Y: 13.48; control2X: -62.14; control2Y: -6.66; x: -59.86; y: -10.84 }
+ PathCubic { control1X: -59.86; control1Y: -10.84; control2X: -49.6; control2Y: -20.34; x: -49.98; y: -23.76 }
+ PathCubic { control1X: -49.98; control1Y: -23.76; control2X: -50.36; control2Y: -40.86; x: -51.5; y: -41.62 }
+ }
+
+ ShapePath {
+ fillColor: "#f8dcc8"
+ strokeWidth: -1
+ PathMove { x: -51.95; y: -40.63 }
+ PathCubic { control1X: -52.82; control1Y: -41.61; control2X: -60.09; control2Y: -46.92; x: -65.64; y: -41 }
+ PathCubic { control1X: -65.64; control1Y: -41; control2X: -75.26; control2Y: -24.35; x: -74.52; y: -18.43 }
+ PathLine { x: -74.52; y: -16.58 }
+ PathCubic { control1X: -74.52; control1Y: -16.58; control2X: -81.55; control2Y: -16.95; x: -83.03; y: -15.1 }
+ PathCubic { control1X: -83.03; control1Y: -15.1; control2X: -84.14; control2Y: -10.29; x: -85.25; y: -9.92 }
+ PathCubic { control1X: -85.25; control1Y: -9.92; control2X: -87.84; control2Y: -7.7; x: -85.99; y: -5.11 }
+ PathCubic { control1X: -85.99; control1Y: -5.11; control2X: -87.84; control2Y: -2.89; x: -87.47; y: 0.81 }
+ PathLine { x: -80.44; y: 4.51 }
+ PathCubic { control1X: -80.44; control1Y: 4.51; control2X: -78.59; control2Y: 17.83; x: -68.6; y: 22.64 }
+ PathCubic { control1X: -64.127; control1Y: 24.794; control2X: -61.2; control2Y: 18.57; x: -59.35; y: 13.02 }
+ PathCubic { control1X: -59.35; control1Y: 13.02; control2X: -62.31; control2Y: -6.59; x: -60.09; y: -10.66 }
+ PathCubic { control1X: -60.09; control1Y: -10.66; control2X: -50.1; control2Y: -19.91; x: -50.47; y: -23.24 }
+ PathCubic { control1X: -50.47; control1Y: -23.24; control2X: -50.84; control2Y: -39.89; x: -51.95; y: -40.63 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeWidth: -1
+ PathMove { x: -59.6; y: 12.46 }
+ PathCubic { control1X: -59.6; control1Y: 12.46; control2X: -62.48; control2Y: -6.52; x: -60.32; y: -10.48 }
+ PathCubic { control1X: -60.32; control1Y: -10.48; control2X: -50.6; control2Y: -19.48; x: -50.96; y: -22.72 }
+ PathCubic { control1X: -50.96; control1Y: -22.72; control2X: -51.32; control2Y: -38.92; x: -52.4; y: -39.64 }
+ PathCubic { control1X: -53.16; control1Y: -40.68; control2X: -60.32; control2Y: -45.76; x: -65.72; y: -40 }
+ PathCubic { control1X: -65.72; control1Y: -40; control2X: -75.08; control2Y: -23.8; x: -74.36; y: -18.04 }
+ PathLine { x: -74.36; y: -16.24 }
+ PathCubic { control1X: -74.36; control1Y: -16.24; control2X: -81.2; control2Y: -16.6; x: -82.64; y: -14.8 }
+ PathCubic { control1X: -82.64; control1Y: -14.8; control2X: -83.72; control2Y: -10.12; x: -84.8; y: -9.76 }
+ PathCubic { control1X: -84.8; control1Y: -9.76; control2X: -87.32; control2Y: -7.6; x: -85.52; y: -5.08 }
+ PathCubic { control1X: -85.52; control1Y: -5.08; control2X: -87.32; control2Y: -2.92; x: -86.96; y: 0.68 }
+ PathLine { x: -80.12; y: 4.28 }
+ PathCubic { control1X: -80.12; control1Y: 4.28; control2X: -78.32; control2Y: 17.24; x: -68.6; y: 21.92 }
+ PathCubic { control1X: -64.248; control1Y: 24.015; control2X: -61.4; control2Y: 17.86; x: -59.6; y: 12.46 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: -62.7; y: 6.2 }
+ PathCubic { control1X: -62.7; control1Y: 6.2; control2X: -84.3; control2Y: -4; x: -85.2; y: -4.8 }
+ PathCubic { control1X: -85.2; control1Y: -4.8; control2X: -76.1; control2Y: 3.4; x: -75.3; y: 3.4 }
+ PathCubic { control1X: -74.5; control1Y: 3.4; control2X: -62.7; control2Y: 6.2; x: -62.7; y: 6.2 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -79.8; y: 0 }
+ PathCubic { control1X: -79.8; control1Y: 0; control2X: -61.4; control2Y: 3.6; x: -61.4; y: 8 }
+ PathCubic { control1X: -61.4; control1Y: 10.912; control2X: -61.643; control2Y: 24.331; x: -67; y: 22.8 }
+ PathCubic { control1X: -75.4; control1Y: 20.4; control2X: -71.8; control2Y: 6; x: -79.8; y: 0 }
+ }
+
+ ShapePath {
+ fillColor: "#99cc32"
+ strokeWidth: -1
+ PathMove { x: -71.4; y: 3.8 }
+ PathCubic { control1X: -71.4; control1Y: 3.8; control2X: -62.422; control2Y: 5.274; x: -61.4; y: 8 }
+ PathCubic { control1X: -60.8; control1Y: 9.6; control2X: -60.137; control2Y: 17.908; x: -65.6; y: 19 }
+ PathCubic { control1X: -70.152; control1Y: 19.911; control2X: -72.382; control2Y: 9.69; x: -71.4; y: 3.8 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 14.595; y: 46.349 }
+ PathCubic { control1X: 14.098; control1Y: 44.607; control2X: 15.409; control2Y: 44.738; x: 17.2; y: 44.2 }
+ PathCubic { control1X: 19.2; control1Y: 43.6; control2X: 31.4; control2Y: 39.8; x: 32.2; y: 37.2 }
+ PathCubic { control1X: 33; control1Y: 34.6; control2X: 46.2; control2Y: 39; x: 46.2; y: 39 }
+ PathCubic { control1X: 48; control1Y: 39.8; control2X: 52.4; control2Y: 42.4; x: 52.4; y: 42.4 }
+ PathCubic { control1X: 57.2; control1Y: 43.6; control2X: 63.8; control2Y: 44; x: 63.8; y: 44 }
+ PathCubic { control1X: 66.2; control1Y: 45; control2X: 69.6; control2Y: 47.8; x: 69.6; y: 47.8 }
+ PathCubic { control1X: 84.2; control1Y: 58; control2X: 96.601; control2Y: 50.8; x: 96.601; y: 50.8 }
+ PathCubic { control1X: 116.601; control1Y: 44.2; control2X: 110.601; control2Y: 27; x: 110.601; y: 27 }
+ PathCubic { control1X: 107.601; control1Y: 18; control2X: 110.801; control2Y: 14.6; x: 110.801; y: 14.6 }
+ PathCubic { control1X: 111.001; control1Y: 10.8; control2X: 118.201; control2Y: 17.2; x: 118.201; y: 17.2 }
+ PathCubic { control1X: 120.801; control1Y: 21.4; control2X: 121.601; control2Y: 26.4; x: 121.601; y: 26.4 }
+ PathCubic { control1X: 129.601; control1Y: 37.6; control2X: 126.201; control2Y: 19.8; x: 126.201; y: 19.8 }
+ PathCubic { control1X: 126.401; control1Y: 18.8; control2X: 123.601; control2Y: 15.2; x: 123.601; y: 14 }
+ PathCubic { control1X: 123.601; control1Y: 12.8; control2X: 121.801; control2Y: 9.4; x: 121.801; y: 9.4 }
+ PathCubic { control1X: 118.801; control1Y: 6; control2X: 121.201; control2Y: -1; x: 121.201; y: -1 }
+ PathCubic { control1X: 123.001; control1Y: -14.8; control2X: 120.801; control2Y: -13; x: 120.801; y: -13 }
+ PathCubic { control1X: 119.601; control1Y: -14.8; control2X: 110.401; control2Y: -4.8; x: 110.401; y: -4.8 }
+ PathCubic { control1X: 108.201; control1Y: -1.4; control2X: 102.201; control2Y: 0.2; x: 102.201; y: 0.2 }
+ PathCubic { control1X: 99.401; control1Y: 2; control2X: 96.001; control2Y: 0.6; x: 96.001; y: 0.6 }
+ PathCubic { control1X: 93.401; control1Y: 0.2; control2X: 87.801; control2Y: 7.2; x: 87.801; y: 7.2 }
+ PathCubic { control1X: 90.601; control1Y: 7; control2X: 93.001; control2Y: 11.4; x: 95.401; y: 11.6 }
+ PathCubic { control1X: 97.801; control1Y: 11.8; control2X: 99.601; control2Y: 9.2; x: 101.201; y: 8.6 }
+ PathCubic { control1X: 102.801; control1Y: 8; control2X: 105.601; control2Y: 13.8; x: 105.601; y: 13.8 }
+ PathCubic { control1X: 106.001; control1Y: 16.4; control2X: 100.401; control2Y: 21.2; x: 100.401; y: 21.2 }
+ PathCubic { control1X: 100.001; control1Y: 25.8; control2X: 98.401; control2Y: 24.2; x: 98.401; y: 24.2 }
+ PathCubic { control1X: 95.401; control1Y: 23.6; control2X: 94.201; control2Y: 27.4; x: 93.201; y: 32 }
+ PathCubic { control1X: 92.201; control1Y: 36.6; control2X: 88.001; control2Y: 37; x: 88.001; y: 37 }
+ PathCubic { control1X: 86.401; control1Y: 44.4; control2X: 85.2; control2Y: 41.4; x: 85.2; y: 41.4 }
+ PathCubic { control1X: 85; control1Y: 35.8; control2X: 79; control2Y: 41.6; x: 79; y: 41.6 }
+ PathCubic { control1X: 77.8; control1Y: 43.6; control2X: 73.2; control2Y: 41.4; x: 73.2; y: 41.4 }
+ PathCubic { control1X: 66.4; control1Y: 39.4; control2X: 68.8; control2Y: 37.4; x: 68.8; y: 37.4 }
+ PathCubic { control1X: 70.6; control1Y: 35.2; control2X: 81.8; control2Y: 37.4; x: 81.8; y: 37.4 }
+ PathCubic { control1X: 84; control1Y: 35.8; control2X: 76; control2Y: 31.8; x: 76; y: 31.8 }
+ PathCubic { control1X: 75.4; control1Y: 30; control2X: 76.4; control2Y: 25.6; x: 76.4; y: 25.6 }
+ PathCubic { control1X: 77.6; control1Y: 22.4; control2X: 84.4; control2Y: 16.8; x: 84.4; y: 16.8 }
+ PathCubic { control1X: 93.801; control1Y: 15.6; control2X: 91.001; control2Y: 14; x: 91.001; y: 14 }
+ PathCubic { control1X: 84.801; control1Y: 8.8; control2X: 79; control2Y: 16.4; x: 79; y: 16.4 }
+ PathCubic { control1X: 76.8; control1Y: 22.6; control2X: 59.4; control2Y: 37.6; x: 59.4; y: 37.6 }
+ PathCubic { control1X: 54.6; control1Y: 41; control2X: 57.2; control2Y: 34.2; x: 53.2; y: 37.6 }
+ PathCubic { control1X: 49.2; control1Y: 41; control2X: 28.6; control2Y: 32; x: 28.6; y: 32 }
+ PathCubic { control1X: 17.038; control1Y: 30.807; control2X: 14.306; control2Y: 46.549; x: 10.777; y: 43.429 }
+ PathCubic { control1X: 10.777; control1Y: 43.429; control2X: 16.195; control2Y: 51.949; x: 14.595; y: 46.349 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 209.401; y: -120 }
+ PathCubic { control1X: 209.401; control1Y: -120; control2X: 183.801; control2Y: -112; x: 181.001; y: -93.2 }
+ PathCubic { control1X: 181.001; control1Y: -93.2; control2X: 178.601; control2Y: -70.4; x: 199.001; y: -52.8 }
+ PathCubic { control1X: 199.001; control1Y: -52.8; control2X: 199.401; control2Y: -46.4; x: 201.401; y: -43.2 }
+ PathCubic { control1X: 201.401; control1Y: -43.2; control2X: 199.801; control2Y: -38.4; x: 218.601; y: -46 }
+ PathLine { x: 245.801; y: -54.4 }
+ PathCubic { control1X: 245.801; control1Y: -54.4; control2X: 252.201; control2Y: -56.8; x: 257.401; y: -65.6 }
+ PathCubic { control1X: 262.601; control1Y: -74.4; control2X: 277.801; control2Y: -93.2; x: 274.201; y: -118.4 }
+ PathCubic { control1X: 274.201; control1Y: -118.4; control2X: 275.401; control2Y: -129.6; x: 269.401; y: -130 }
+ PathCubic { control1X: 269.401; control1Y: -130; control2X: 261.001; control2Y: -131.6; x: 253.801; y: -124 }
+ PathCubic { control1X: 253.801; control1Y: -124; control2X: 247.001; control2Y: -120.8; x: 244.601; y: -121.2 }
+ PathLine { x: 209.401; y: -120 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 264.022; y: -120.99 }
+ PathCubic { control1X: 264.022; control1Y: -120.99; control2X: 266.122; control2Y: -129.92; x: 261.282; y: -125.08 }
+ PathCubic { control1X: 261.282; control1Y: -125.08; control2X: 254.242; control2Y: -119.36; x: 246.761; y: -119.36 }
+ PathCubic { control1X: 246.761; control1Y: -119.36; control2X: 232.241; control2Y: -117.16; x: 227.841; y: -103.96 }
+ PathCubic { control1X: 227.841; control1Y: -103.96; control2X: 223.881; control2Y: -77.12; x: 231.801; y: -71.4 }
+ PathCubic { control1X: 231.801; control1Y: -71.4; control2X: 236.641; control2Y: -63.92; x: 243.681; y: -70.52 }
+ PathCubic { control1X: 250.722; control1Y: -77.12; control2X: 266.222; control2Y: -107.35; x: 264.022; y: -120.99 }
+ }
+
+ ShapePath {
+ fillColor: "#323232"
+ strokeWidth: -1
+ PathMove { x: 263.648; y: -120.632 }
+ PathCubic { control1X: 263.648; control1Y: -120.632; control2X: 265.738; control2Y: -129.376; x: 260.986; y: -124.624 }
+ PathCubic { control1X: 260.986; control1Y: -124.624; control2X: 254.074; control2Y: -119.008; x: 246.729; y: -119.008 }
+ PathCubic { control1X: 246.729; control1Y: -119.008; control2X: 232.473; control2Y: -116.848; x: 228.153; y: -103.888 }
+ PathCubic { control1X: 228.153; control1Y: -103.888; control2X: 224.265; control2Y: -77.536; x: 232.041; y: -71.92 }
+ PathCubic { control1X: 232.041; control1Y: -71.92; control2X: 236.793; control2Y: -64.576; x: 243.705; y: -71.056 }
+ PathCubic { control1X: 250.618; control1Y: -77.536; control2X: 265.808; control2Y: -107.24; x: 263.648; y: -120.632 }
+ }
+
+ ShapePath {
+ fillColor: "#666666"
+ strokeWidth: -1
+ PathMove { x: 263.274; y: -120.274 }
+ PathCubic { control1X: 263.274; control1Y: -120.274; control2X: 265.354; control2Y: -128.832; x: 260.69; y: -124.168 }
+ PathCubic { control1X: 260.69; control1Y: -124.168; control2X: 253.906; control2Y: -118.656; x: 246.697; y: -118.656 }
+ PathCubic { control1X: 246.697; control1Y: -118.656; control2X: 232.705; control2Y: -116.536; x: 228.465; y: -103.816 }
+ PathCubic { control1X: 228.465; control1Y: -103.816; control2X: 224.649; control2Y: -77.952; x: 232.281; y: -72.44 }
+ PathCubic { control1X: 232.281; control1Y: -72.44; control2X: 236.945; control2Y: -65.232; x: 243.729; y: -71.592 }
+ PathCubic { control1X: 250.514; control1Y: -77.952; control2X: 265.394; control2Y: -107.13; x: 263.274; y: -120.274 }
+ }
+
+ ShapePath {
+ fillColor: "#999999"
+ strokeWidth: -1
+ PathMove { x: 262.9; y: -119.916 }
+ PathCubic { control1X: 262.9; control1Y: -119.916; control2X: 264.97; control2Y: -128.288; x: 260.394; y: -123.712 }
+ PathCubic { control1X: 260.394; control1Y: -123.712; control2X: 253.738; control2Y: -118.304; x: 246.665; y: -118.304 }
+ PathCubic { control1X: 246.665; control1Y: -118.304; control2X: 232.937; control2Y: -116.224; x: 228.777; y: -103.744 }
+ PathCubic { control1X: 228.777; control1Y: -103.744; control2X: 225.033; control2Y: -78.368; x: 232.521; y: -72.96 }
+ PathCubic { control1X: 232.521; control1Y: -72.96; control2X: 237.097; control2Y: -65.888; x: 243.753; y: -72.128 }
+ PathCubic { control1X: 250.41; control1Y: -78.368; control2X: 264.98; control2Y: -107.02; x: 262.9; y: -119.916 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: 262.526; y: -119.558 }
+ PathCubic { control1X: 262.526; control1Y: -119.558; control2X: 264.586; control2Y: -127.744; x: 260.098; y: -123.256 }
+ PathCubic { control1X: 260.098; control1Y: -123.256; control2X: 253.569; control2Y: -117.952; x: 246.633; y: -117.952 }
+ PathCubic { control1X: 246.633; control1Y: -117.952; control2X: 233.169; control2Y: -115.912; x: 229.089; y: -103.672 }
+ PathCubic { control1X: 229.089; control1Y: -103.672; control2X: 225.417; control2Y: -78.784; x: 232.761; y: -73.48 }
+ PathCubic { control1X: 232.761; control1Y: -73.48; control2X: 237.249; control2Y: -66.544; x: 243.777; y: -72.664 }
+ PathCubic { control1X: 250.305; control1Y: -78.784; control2X: 264.566; control2Y: -106.91; x: 262.526; y: -119.558 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeWidth: -1
+ PathMove { x: 262.151; y: -119.2 }
+ PathCubic { control1X: 262.151; control1Y: -119.2; control2X: 264.201; control2Y: -127.2; x: 259.801; y: -122.8 }
+ PathCubic { control1X: 259.801; control1Y: -122.8; control2X: 253.401; control2Y: -117.6; x: 246.601; y: -117.6 }
+ PathCubic { control1X: 246.601; control1Y: -117.6; control2X: 233.401; control2Y: -115.6; x: 229.401; y: -103.6 }
+ PathCubic { control1X: 229.401; control1Y: -103.6; control2X: 225.801; control2Y: -79.2; x: 233.001; y: -74 }
+ PathCubic { control1X: 233.001; control1Y: -74; control2X: 237.401; control2Y: -67.2; x: 243.801; y: -73.2 }
+ PathCubic { control1X: 250.201; control1Y: -79.2; control2X: 264.151; control2Y: -106.8; x: 262.151; y: -119.2 }
+ }
+
+ ShapePath {
+ fillColor: "#992600"
+ strokeWidth: -1
+ PathMove { x: 50.6; y: 84 }
+ PathCubic { control1X: 50.6; control1Y: 84; control2X: 30.2; control2Y: 64.8; x: 22.2; y: 64 }
+ PathCubic { control1X: 22.2; control1Y: 64; control2X: -12.2; control2Y: 60; x: -27; y: 78 }
+ PathCubic { control1X: -27; control1Y: 78; control2X: -9.4; control2Y: 57.6; x: 18.2; y: 63.2 }
+ PathCubic { control1X: 18.2; control1Y: 63.2; control2X: -3.4; control2Y: 58.8; x: -15.8; y: 62 }
+ PathCubic { control1X: -15.8; control1Y: 62; control2X: -32.6; control2Y: 62; x: -42.2; y: 76 }
+ PathLine { x: -45; y: 80.8 }
+ PathCubic { control1X: -45; control1Y: 80.8; control2X: -41; control2Y: 66; x: -22.6; y: 60 }
+ PathCubic { control1X: -22.6; control1Y: 60; control2X: 0.2; control2Y: 55.2; x: 11; y: 60 }
+ PathCubic { control1X: 11; control1Y: 60; control2X: -10.6; control2Y: 53.2; x: -20.6; y: 55.2 }
+ PathCubic { control1X: -20.6; control1Y: 55.2; control2X: -51; control2Y: 52.8; x: -63.8; y: 79.2 }
+ PathCubic { control1X: -63.8; control1Y: 79.2; control2X: -59.8; control2Y: 64.8; x: -45; y: 57.6 }
+ PathCubic { control1X: -45; control1Y: 57.6; control2X: -31.4; control2Y: 48.8; x: -11; y: 51.6 }
+ PathCubic { control1X: -11; control1Y: 51.6; control2X: 3.4; control2Y: 54.8; x: 8.6; y: 57.2 }
+ PathCubic { control1X: 13.8; control1Y: 59.6; control2X: 12.6; control2Y: 56.8; x: 4.2; y: 52 }
+ PathCubic { control1X: 4.2; control1Y: 52; control2X: -1.4; control2Y: 42; x: -15.4; y: 42.4 }
+ PathCubic { control1X: -15.4; control1Y: 42.4; control2X: -58.2; control2Y: 46; x: -68.6; y: 58 }
+ PathCubic { control1X: -68.6; control1Y: 58; control2X: -55; control2Y: 46.8; x: -44.6; y: 44 }
+ PathCubic { control1X: -44.6; control1Y: 44; control2X: -22.2; control2Y: 36; x: -13.8; y: 36.8 }
+ PathCubic { control1X: -13.8; control1Y: 36.8; control2X: 11; control2Y: 37.8; x: 18.6; y: 33.8 }
+ PathCubic { control1X: 18.6; control1Y: 33.8; control2X: 7.4; control2Y: 38.8; x: 10.6; y: 42 }
+ PathCubic { control1X: 13.8; control1Y: 45.2; control2X: 20.6; control2Y: 52.8; x: 20.6; y: 54 }
+ PathCubic { control1X: 20.6; control1Y: 55.2; control2X: 44.8; control2Y: 77.3; x: 48.4; y: 81.7 }
+ PathLine { x: 50.6; y: 84 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: 189; y: 278 }
+ PathCubic { control1X: 189; control1Y: 278; control2X: 173.5; control2Y: 241.5; x: 161; y: 232 }
+ PathCubic { control1X: 161; control1Y: 232; control2X: 187; control2Y: 248; x: 190.5; y: 266 }
+ PathCubic { control1X: 190.5; control1Y: 266; control2X: 190.5; control2Y: 276; x: 189; y: 278 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: 236; y: 285.5 }
+ PathCubic { control1X: 236; control1Y: 285.5; control2X: 209.5; control2Y: 230.5; x: 191; y: 206.5 }
+ PathCubic { control1X: 191; control1Y: 206.5; control2X: 234.5; control2Y: 244; x: 239.5; y: 270.5 }
+ PathLine { x: 240; y: 276 }
+ PathLine { x: 237; y: 273.5 }
+ PathCubic { control1X: 237; control1Y: 273.5; control2X: 236.5; control2Y: 282.5; x: 236; y: 285.5 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: 292.5; y: 237 }
+ PathCubic { control1X: 292.5; control1Y: 237; control2X: 230; control2Y: 177.5; x: 228.5; y: 175 }
+ PathCubic { control1X: 228.5; control1Y: 175; control2X: 289; control2Y: 241; x: 292; y: 248.5 }
+ PathCubic { control1X: 292; control1Y: 248.5; control2X: 290; control2Y: 239.5; x: 292.5; y: 237 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: 104; y: 280.5 }
+ PathCubic { control1X: 104; control1Y: 280.5; control2X: 123.5; control2Y: 228.5; x: 142.5; y: 251 }
+ PathCubic { control1X: 142.5; control1Y: 251; control2X: 157.5; control2Y: 261; x: 157; y: 264 }
+ PathCubic { control1X: 157; control1Y: 264; control2X: 153; control2Y: 257.5; x: 135; y: 258 }
+ PathCubic { control1X: 135; control1Y: 258; control2X: 116; control2Y: 255; x: 104; y: 280.5 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: 294.5; y: 153 }
+ PathCubic { control1X: 294.5; control1Y: 153; control2X: 249.5; control2Y: 124.5; x: 242; y: 123 }
+ PathCubic { control1X: 230.193; control1Y: 120.639; control2X: 291.5; control2Y: 152; x: 296.5; y: 162.5 }
+ PathCubic { control1X: 296.5; control1Y: 162.5; control2X: 298.5; control2Y: 160; x: 294.5; y: 153 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 143.801; y: 259.601 }
+ PathCubic { control1X: 143.801; control1Y: 259.601; control2X: 164.201; control2Y: 257.601; x: 171.001; y: 250.801 }
+ PathLine { x: 175.401; y: 254.401 }
+ PathLine { x: 193.001; y: 216.001 }
+ PathLine { x: 196.601; y: 221.201 }
+ PathCubic { control1X: 196.601; control1Y: 221.201; control2X: 211.001; control2Y: 206.401; x: 210.201; y: 198.401 }
+ PathCubic { control1X: 209.401; control1Y: 190.401; control2X: 223.001; control2Y: 204.401; x: 223.001; y: 204.401 }
+ PathCubic { control1X: 223.001; control1Y: 204.401; control2X: 222.201; control2Y: 192.801; x: 229.401; y: 199.601 }
+ PathCubic { control1X: 229.401; control1Y: 199.601; control2X: 227.001; control2Y: 184.001; x: 235.401; y: 192.001 }
+ PathCubic { control1X: 235.401; control1Y: 192.001; control2X: 224.864; control2Y: 161.844; x: 247.401; y: 187.601 }
+ PathCubic { control1X: 253.001; control1Y: 194.001; control2X: 248.601; control2Y: 187.201; x: 248.601; y: 187.201 }
+ PathCubic { control1X: 248.601; control1Y: 187.201; control2X: 222.601; control2Y: 139.201; x: 244.201; y: 153.601 }
+ PathCubic { control1X: 244.201; control1Y: 153.601; control2X: 246.201; control2Y: 130.801; x: 245.001; y: 126.401 }
+ PathCubic { control1X: 243.801; control1Y: 122.001; control2X: 241.801; control2Y: 99.6; x: 237.001; y: 94.4 }
+ PathCubic { control1X: 232.201; control1Y: 89.2; control2X: 237.401; control2Y: 87.6; x: 243.001; y: 92.8 }
+ PathCubic { control1X: 243.001; control1Y: 92.8; control2X: 231.801; control2Y: 68.8; x: 245.001; y: 80.8 }
+ PathCubic { control1X: 245.001; control1Y: 80.8; control2X: 241.401; control2Y: 65.6; x: 237.001; y: 62.8 }
+ PathCubic { control1X: 237.001; control1Y: 62.8; control2X: 231.401; control2Y: 45.6; x: 246.601; y: 56.4 }
+ PathCubic { control1X: 246.601; control1Y: 56.4; control2X: 242.201; control2Y: 44; x: 239.001; y: 40.8 }
+ PathCubic { control1X: 239.001; control1Y: 40.8; control2X: 227.401; control2Y: 13.2; x: 234.601; y: 18 }
+ PathLine { x: 239.001; y: 21.6 }
+ PathCubic { control1X: 239.001; control1Y: 21.6; control2X: 232.201; control2Y: 7.6; x: 238.601; y: 12 }
+ PathCubic { control1X: 245.001; control1Y: 16.4; control2X: 245.001; control2Y: 16; x: 245.001; y: 16 }
+ PathCubic { control1X: 245.001; control1Y: 16; control2X: 223.801; control2Y: -17.2; x: 244.201; y: 0.4 }
+ PathCubic { control1X: 244.201; control1Y: 0.4; control2X: 236.042; control2Y: -13.518; x: 232.601; y: -20.4 }
+ PathCubic { control1X: 232.601; control1Y: -20.4; control2X: 213.801; control2Y: -40.8; x: 228.201; y: -34.4 }
+ PathLine { x: 233.001; y: -32.8 }
+ PathCubic { control1X: 233.001; control1Y: -32.8; control2X: 224.201; control2Y: -42.8; x: 216.201; y: -44.4 }
+ PathCubic { control1X: 208.201; control1Y: -46; control2X: 218.601; control2Y: -52.4; x: 225.001; y: -50.4 }
+ PathCubic { control1X: 231.401; control1Y: -48.4; control2X: 247.001; control2Y: -40.8; x: 247.001; y: -40.8 }
+ PathCubic { control1X: 247.001; control1Y: -40.8; control2X: 259.801; control2Y: -22; x: 263.801; y: -21.6 }
+ PathCubic { control1X: 263.801; control1Y: -21.6; control2X: 243.801; control2Y: -29.2; x: 249.801; y: -21.2 }
+ PathCubic { control1X: 249.801; control1Y: -21.2; control2X: 264.201; control2Y: -7.2; x: 257.001; y: -7.6 }
+ PathCubic { control1X: 257.001; control1Y: -7.6; control2X: 251.001; control2Y: -0.4; x: 255.801; y: 8.4 }
+ PathCubic { control1X: 255.801; control1Y: 8.4; control2X: 237.342; control2Y: -9.991; x: 252.201; y: 15.6 }
+ PathLine { x: 259.001; y: 32 }
+ PathCubic { control1X: 259.001; control1Y: 32; control2X: 234.601; control2Y: 7.2; x: 245.801; y: 29.2 }
+ PathCubic { control1X: 245.801; control1Y: 29.2; control2X: 263.001; control2Y: 52.8; x: 265.001; y: 53.2 }
+ PathCubic { control1X: 267.001; control1Y: 53.6; control2X: 271.401; control2Y: 62.4; x: 271.401; y: 62.4 }
+ PathLine { x: 267.001; y: 60.4 }
+ PathLine { x: 272.201; y: 69.2 }
+ PathCubic { control1X: 272.201; control1Y: 69.2; control2X: 261.001; control2Y: 57.2; x: 267.001; y: 70.4 }
+ PathLine { x: 272.601; y: 84.8 }
+ PathCubic { control1X: 272.601; control1Y: 84.8; control2X: 252.201; control2Y: 62.8; x: 265.801; y: 92.4 }
+ PathCubic { control1X: 265.801; control1Y: 92.4; control2X: 249.401; control2Y: 87.2; x: 258.201; y: 104.4 }
+ PathCubic { control1X: 258.201; control1Y: 104.4; control2X: 256.601; control2Y: 120.401; x: 257.001; y: 125.601 }
+ PathCubic { control1X: 257.401; control1Y: 130.801; control2X: 258.601; control2Y: 159.201; x: 254.201; y: 167.201 }
+ PathCubic { control1X: 249.801; control1Y: 175.201; control2X: 260.201; control2Y: 194.401; x: 262.201; y: 198.401 }
+ PathCubic { control1X: 264.201; control1Y: 202.401; control2X: 267.801; control2Y: 213.201; x: 259.001; y: 204.001 }
+ PathCubic { control1X: 250.201; control1Y: 194.801; control2X: 254.601; control2Y: 200.401; x: 256.601; y: 209.201 }
+ PathCubic { control1X: 258.601; control1Y: 218.001; control2X: 264.601; control2Y: 233.601; x: 263.801; y: 239.201 }
+ PathCubic { control1X: 263.801; control1Y: 239.201; control2X: 262.601; control2Y: 240.401; x: 259.401; y: 236.801 }
+ PathCubic { control1X: 259.401; control1Y: 236.801; control2X: 244.601; control2Y: 214.001; x: 246.201; y: 228.401 }
+ PathCubic { control1X: 246.201; control1Y: 228.401; control2X: 245.001; control2Y: 236.401; x: 241.801; y: 245.201 }
+ PathCubic { control1X: 241.801; control1Y: 245.201; control2X: 238.601; control2Y: 256.001; x: 238.601; y: 247.201 }
+ PathCubic { control1X: 238.601; control1Y: 247.201; control2X: 235.401; control2Y: 230.401; x: 232.601; y: 238.001 }
+ PathCubic { control1X: 229.801; control1Y: 245.601; control2X: 226.201; control2Y: 251.601; x: 223.401; y: 254.001 }
+ PathCubic { control1X: 220.601; control1Y: 256.401; control2X: 215.401; control2Y: 233.601; x: 214.201; y: 244.001 }
+ PathCubic { control1X: 214.201; control1Y: 244.001; control2X: 202.201; control2Y: 231.601; x: 197.401; y: 248.001 }
+ PathLine { x: 185.801; y: 264.401 }
+ PathCubic { control1X: 185.801; control1Y: 264.401; control2X: 185.401; control2Y: 252.001; x: 184.201; y: 258.001 }
+ PathCubic { control1X: 184.201; control1Y: 258.001; control2X: 154.201; control2Y: 264.001; x: 143.801; y: 259.601 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 109.401; y: -97.2 }
+ PathCubic { control1X: 109.401; control1Y: -97.2; control2X: 97.801; control2Y: -105.2; x: 93.801; y: -104.8 }
+ PathCubic { control1X: 89.801; control1Y: -104.4; control2X: 121.401; control2Y: -113.6; x: 162.601; y: -86 }
+ PathCubic { control1X: 162.601; control1Y: -86; control2X: 167.401; control2Y: -83.2; x: 171.001; y: -83.6 }
+ PathCubic { control1X: 171.001; control1Y: -83.6; control2X: 174.201; control2Y: -81.2; x: 171.401; y: -77.6 }
+ PathCubic { control1X: 171.401; control1Y: -77.6; control2X: 162.601; control2Y: -68; x: 173.801; y: -56.8 }
+ PathCubic { control1X: 173.801; control1Y: -56.8; control2X: 192.201; control2Y: -50; x: 186.601; y: -58.8 }
+ PathCubic { control1X: 186.601; control1Y: -58.8; control2X: 197.401; control2Y: -54.8; x: 199.801; y: -50.8 }
+ PathCubic { control1X: 202.201; control1Y: -46.8; control2X: 201.001; control2Y: -50.8; x: 201.001; y: -50.8 }
+ PathCubic { control1X: 201.001; control1Y: -50.8; control2X: 194.601; control2Y: -58; x: 188.601; y: -63.2 }
+ PathCubic { control1X: 188.601; control1Y: -63.2; control2X: 183.401; control2Y: -65.2; x: 180.601; y: -73.6 }
+ PathCubic { control1X: 177.801; control1Y: -82; control2X: 175.401; control2Y: -92; x: 179.801; y: -95.2 }
+ PathCubic { control1X: 179.801; control1Y: -95.2; control2X: 175.801; control2Y: -90.8; x: 176.601; y: -94.8 }
+ PathCubic { control1X: 177.401; control1Y: -98.8; control2X: 181.001; control2Y: -102.4; x: 182.601; y: -102.8 }
+ PathCubic { control1X: 184.201; control1Y: -103.2; control2X: 200.601; control2Y: -119; x: 207.401; y: -119.4 }
+ PathCubic { control1X: 207.401; control1Y: -119.4; control2X: 198.201; control2Y: -118; x: 195.201; y: -119 }
+ PathCubic { control1X: 192.201; control1Y: -120; control2X: 165.601; control2Y: -131.4; x: 159.601; y: -132.6 }
+ PathCubic { control1X: 159.601; control1Y: -132.6; control2X: 142.801; control2Y: -139.2; x: 154.801; y: -137.2 }
+ PathCubic { control1X: 154.801; control1Y: -137.2; control2X: 190.601; control2Y: -133.4; x: 208.801; y: -120.2 }
+ PathCubic { control1X: 208.801; control1Y: -120.2; control2X: 201.601; control2Y: -128.6; x: 183.201; y: -135.6 }
+ PathCubic { control1X: 183.201; control1Y: -135.6; control2X: 161.001; control2Y: -148.2; x: 125.801; y: -143.2 }
+ PathCubic { control1X: 125.801; control1Y: -143.2; control2X: 108.001; control2Y: -140; x: 100.201; y: -138.2 }
+ PathCubic { control1X: 100.201; control1Y: -138.2; control2X: 97.601; control2Y: -138.8; x: 97.001; y: -139.2 }
+ PathCubic { control1X: 96.401; control1Y: -139.6; control2X: 84.6; control2Y: -148.6; x: 57; y: -141.6 }
+ PathCubic { control1X: 57; control1Y: -141.6; control2X: 40; control2Y: -137; x: 31.4; y: -132.2 }
+ PathCubic { control1X: 31.4; control1Y: -132.2; control2X: 16.2; control2Y: -131; x: 12.6; y: -127.8 }
+ PathCubic { control1X: 12.6; control1Y: -127.8; control2X: -6; control2Y: -113.2; x: -8; y: -112.4 }
+ PathCubic { control1X: -10; control1Y: -111.6; control2X: -21.4; control2Y: -104; x: -22.2; y: -103.6 }
+ PathCubic { control1X: -22.2; control1Y: -103.6; control2X: 2.4; control2Y: -110.2; x: 4.8; y: -112.6 }
+ PathCubic { control1X: 7.2; control1Y: -115; control2X: 24.6; control2Y: -117.6; x: 27; y: -116.2 }
+ PathCubic { control1X: 29.4; control1Y: -114.8; control2X: 37.8; control2Y: -115.4; x: 28.2; y: -114.8 }
+ PathCubic { control1X: 28.2; control1Y: -114.8; control2X: 103.801; control2Y: -100; x: 104.601; y: -98 }
+ PathCubic { control1X: 105.401; control1Y: -96; control2X: 109.401; control2Y: -97.2; x: 109.401; y: -97.2 }
+ }
+
+ ShapePath {
+ fillColor: "#cc7226"
+ strokeWidth: -1
+ PathMove { x: 180.801; y: -106.4 }
+ PathCubic { control1X: 180.801; control1Y: -106.4; control2X: 170.601; control2Y: -113.8; x: 168.601; y: -113.8 }
+ PathCubic { control1X: 166.601; control1Y: -113.8; control2X: 154.201; control2Y: -124; x: 150.001; y: -123.6 }
+ PathCubic { control1X: 145.801; control1Y: -123.2; control2X: 133.601; control2Y: -133.2; x: 106.201; y: -125 }
+ PathCubic { control1X: 106.201; control1Y: -125; control2X: 105.601; control2Y: -127; x: 109.201; y: -127.8 }
+ PathCubic { control1X: 109.201; control1Y: -127.8; control2X: 115.601; control2Y: -130; x: 116.001; y: -130.6 }
+ PathCubic { control1X: 116.001; control1Y: -130.6; control2X: 136.201; control2Y: -134.8; x: 143.401; y: -131.2 }
+ PathCubic { control1X: 143.401; control1Y: -131.2; control2X: 152.601; control2Y: -128.6; x: 158.801; y: -122.4 }
+ PathCubic { control1X: 158.801; control1Y: -122.4; control2X: 170.001; control2Y: -119.2; x: 173.201; y: -120.2 }
+ PathCubic { control1X: 173.201; control1Y: -120.2; control2X: 182.001; control2Y: -118; x: 182.401; y: -116.2 }
+ PathCubic { control1X: 182.401; control1Y: -116.2; control2X: 188.201; control2Y: -113.2; x: 186.401; y: -110.6 }
+ PathCubic { control1X: 186.401; control1Y: -110.6; control2X: 186.801; control2Y: -109; x: 180.801; y: -106.4 }
+ }
+
+ ShapePath {
+ fillColor: "#cc7226"
+ strokeWidth: -1
+ PathMove { x: 168.33; y: -108.509 }
+ PathCubic { control1X: 169.137; control1Y: -107.877; control2X: 170.156; control2Y: -107.779; x: 170.761; y: -106.97 }
+ PathCubic { control1X: 170.995; control1Y: -106.656; control2X: 170.706; control2Y: -106.33; x: 170.391; y: -106.233 }
+ PathCubic { control1X: 169.348; control1Y: -105.916; control2X: 168.292; control2Y: -106.486; x: 167.15; y: -105.898 }
+ PathCubic { control1X: 166.748; control1Y: -105.691; control2X: 166.106; control2Y: -105.873; x: 165.553; y: -106.022 }
+ PathCubic { control1X: 163.921; control1Y: -106.463; control2X: 162.092; control2Y: -106.488; x: 160.401; y: -105.8 }
+ PathCubic { control1X: 158.416; control1Y: -106.929; control2X: 156.056; control2Y: -106.345; x: 153.975; y: -107.346 }
+ PathCubic { control1X: 153.917; control1Y: -107.373; control2X: 153.695; control2Y: -107.027; x: 153.621; y: -107.054 }
+ PathCubic { control1X: 150.575; control1Y: -108.199; control2X: 146.832; control2Y: -107.916; x: 144.401; y: -110.2 }
+ PathCubic { control1X: 141.973; control1Y: -110.612; control2X: 139.616; control2Y: -111.074; x: 137.188; y: -111.754 }
+ PathCubic { control1X: 135.37; control1Y: -112.263; control2X: 133.961; control2Y: -113.252; x: 132.341; y: -114.084 }
+ PathCubic { control1X: 130.964; control1Y: -114.792; control2X: 129.507; control2Y: -115.314; x: 127.973; y: -115.686 }
+ PathCubic { control1X: 126.11; control1Y: -116.138; control2X: 124.279; control2Y: -116.026; x: 122.386; y: -116.546 }
+ PathCubic { control1X: 122.293; control1Y: -116.571; control2X: 122.101; control2Y: -116.227; x: 122.019; y: -116.254 }
+ PathCubic { control1X: 121.695; control1Y: -116.362; control2X: 121.405; control2Y: -116.945; x: 121.234; y: -116.892 }
+ PathCubic { control1X: 119.553; control1Y: -116.37; control2X: 118.065; control2Y: -117.342; x: 116.401; y: -117 }
+ PathCubic { control1X: 115.223; control1Y: -118.224; control2X: 113.495; control2Y: -117.979; x: 111.949; y: -118.421 }
+ PathCubic { control1X: 108.985; control1Y: -119.269; control2X: 105.831; control2Y: -117.999; x: 102.801; y: -119 }
+ PathCubic { control1X: 106.914; control1Y: -120.842; control2X: 111.601; control2Y: -119.61; x: 115.663; y: -121.679 }
+ PathCubic { control1X: 117.991; control1Y: -122.865; control2X: 120.653; control2Y: -121.763; x: 123.223; y: -122.523 }
+ PathCubic { control1X: 123.71; control1Y: -122.667; control2X: 124.401; control2Y: -122.869; x: 124.801; y: -122.2 }
+ PathCubic { control1X: 124.935; control1Y: -122.335; control2X: 125.117; control2Y: -122.574; x: 125.175; y: -122.546 }
+ PathCubic { control1X: 127.625; control1Y: -121.389; control2X: 129.94; control2Y: -120.115; x: 132.422; y: -119.049 }
+ PathCubic { control1X: 132.763; control1Y: -118.903; control2X: 133.295; control2Y: -119.135; x: 133.547; y: -118.933 }
+ PathCubic { control1X: 135.067; control1Y: -117.717; control2X: 137.01; control2Y: -117.82; x: 138.401; y: -116.6 }
+ PathCubic { control1X: 140.099; control1Y: -117.102; control2X: 141.892; control2Y: -116.722; x: 143.621; y: -117.346 }
+ PathCubic { control1X: 143.698; control1Y: -117.373; control2X: 143.932; control2Y: -117.032; x: 143.965; y: -117.054 }
+ PathCubic { control1X: 145.095; control1Y: -117.802; control2X: 146.25; control2Y: -117.531; x: 147.142; y: -117.227 }
+ PathCubic { control1X: 147.48; control1Y: -117.112; control2X: 148.143; control2Y: -116.865; x: 148.448; y: -116.791 }
+ PathCubic { control1X: 149.574; control1Y: -116.515; control2X: 150.43; control2Y: -116.035; x: 151.609; y: -115.852 }
+ PathCubic { control1X: 151.723; control1Y: -115.834; control2X: 151.908; control2Y: -116.174; x: 151.98; y: -116.146 }
+ PathCubic { control1X: 153.103; control1Y: -115.708; control2X: 154.145; control2Y: -115.764; x: 154.801; y: -114.6 }
+ PathCubic { control1X: 154.936; control1Y: -114.735; control2X: 155.101; control2Y: -114.973; x: 155.183; y: -114.946 }
+ PathCubic { control1X: 156.21; control1Y: -114.608; control2X: 156.859; control2Y: -113.853; x: 157.96; y: -113.612 }
+ PathCubic { control1X: 158.445; control1Y: -113.506; control2X: 159.057; control2Y: -112.88; x: 159.633; y: -112.704 }
+ PathCubic { control1X: 162.025; control1Y: -111.973; control2X: 163.868; control2Y: -110.444; x: 166.062; y: -109.549 }
+ PathCubic { control1X: 166.821; control1Y: -109.239; control2X: 167.697; control2Y: -109.005; x: 168.33; y: -108.509 }
+ }
+
+ ShapePath {
+ fillColor: "#cc7226"
+ strokeWidth: -1
+ PathMove { x: 91.696; y: -122.739 }
+ PathCubic { control1X: 89.178; control1Y: -124.464; control2X: 86.81; control2Y: -125.57; x: 84.368; y: -127.356 }
+ PathCubic { control1X: 84.187; control1Y: -127.489; control2X: 83.827; control2Y: -127.319; x: 83.625; y: -127.441 }
+ PathCubic { control1X: 82.618; control1Y: -128.05; control2X: 81.73; control2Y: -128.631; x: 80.748; y: -129.327 }
+ PathCubic { control1X: 80.209; control1Y: -129.709; control2X: 79.388; control2Y: -129.698; x: 78.88; y: -129.956 }
+ PathCubic { control1X: 76.336; control1Y: -131.248; control2X: 73.707; control2Y: -131.806; x: 71.2; y: -133 }
+ PathCubic { control1X: 71.882; control1Y: -133.638; control2X: 73.004; control2Y: -133.394; x: 73.6; y: -134.2 }
+ PathCubic { control1X: 73.795; control1Y: -133.92; control2X: 74.033; control2Y: -133.636; x: 74.386; y: -133.827 }
+ PathCubic { control1X: 76.064; control1Y: -134.731; control2X: 77.914; control2Y: -134.884; x: 79.59; y: -134.794 }
+ PathCubic { control1X: 81.294; control1Y: -134.702; control2X: 83.014; control2Y: -134.397; x: 84.789; y: -134.125 }
+ PathCubic { control1X: 85.096; control1Y: -134.078; control2X: 85.295; control2Y: -133.555; x: 85.618; y: -133.458 }
+ PathCubic { control1X: 87.846; control1Y: -132.795; control2X: 90.235; control2Y: -133.32; x: 92.354; y: -132.482 }
+ PathCubic { control1X: 93.945; control1Y: -131.853; control2X: 95.515; control2Y: -131.03; x: 96.754; y: -129.755 }
+ PathCubic { control1X: 97.006; control1Y: -129.495; control2X: 96.681; control2Y: -129.194; x: 96.401; y: -129 }
+ PathCubic { control1X: 96.789; control1Y: -129.109; control2X: 97.062; control2Y: -128.903; x: 97.173; y: -128.59 }
+ PathCubic { control1X: 97.257; control1Y: -128.351; control2X: 97.257; control2Y: -128.049; x: 97.173; y: -127.81 }
+ PathCubic { control1X: 97.061; control1Y: -127.498; control2X: 96.782; control2Y: -127.397; x: 96.408; y: -127.346 }
+ PathCubic { control1X: 95.001; control1Y: -127.156; control2X: 96.773; control2Y: -128.536; x: 96.073; y: -128.088 }
+ PathCubic { control1X: 94.8; control1Y: -127.274; control2X: 95.546; control2Y: -125.868; x: 94.801; y: -124.6 }
+ PathCubic { control1X: 94.521; control1Y: -124.794; control2X: 94.291; control2Y: -125.012; x: 94.401; y: -125.4 }
+ PathCubic { control1X: 94.635; control1Y: -124.878; control2X: 94.033; control2Y: -124.588; x: 93.865; y: -124.272 }
+ PathCubic { control1X: 93.48; control1Y: -123.547; control2X: 92.581; control2Y: -122.132; x: 91.696; y: -122.739 }
+ }
+
+ ShapePath {
+ fillColor: "#cc7226"
+ strokeWidth: -1
+ PathMove { x: 59.198; y: -115.391 }
+ PathCubic { control1X: 56.044; control1Y: -116.185; control2X: 52.994; control2Y: -116.07; x: 49.978; y: -117.346 }
+ PathCubic { control1X: 49.911; control1Y: -117.374; control2X: 49.688; control2Y: -117.027; x: 49.624; y: -117.054 }
+ PathCubic { control1X: 48.258; control1Y: -117.648; control2X: 47.34; control2Y: -118.614; x: 46.264; y: -119.66 }
+ PathCubic { control1X: 45.351; control1Y: -120.548; control2X: 43.693; control2Y: -120.161; x: 42.419; y: -120.648 }
+ PathCubic { control1X: 42.095; control1Y: -120.772; control2X: 41.892; control2Y: -121.284; x: 41.591; y: -121.323 }
+ PathCubic { control1X: 40.372; control1Y: -121.48; control2X: 39.445; control2Y: -122.429; x: 38.4; y: -123 }
+ PathCubic { control1X: 40.736; control1Y: -123.795; control2X: 43.147; control2Y: -123.764; x: 45.609; y: -124.148 }
+ PathCubic { control1X: 45.722; control1Y: -124.166; control2X: 45.867; control2Y: -123.845; x: 46; y: -123.845 }
+ PathCubic { control1X: 46.136; control1Y: -123.845; control2X: 46.266; control2Y: -124.066; x: 46.4; y: -124.2 }
+ PathCubic { control1X: 46.595; control1Y: -123.92; control2X: 46.897; control2Y: -123.594; x: 47.154; y: -123.848 }
+ PathCubic { control1X: 47.702; control1Y: -124.388; control2X: 48.258; control2Y: -124.198; x: 48.798; y: -124.158 }
+ PathCubic { control1X: 48.942; control1Y: -124.148; control2X: 49.067; control2Y: -123.845; x: 49.2; y: -123.845 }
+ PathCubic { control1X: 49.336; control1Y: -123.845; control2X: 49.467; control2Y: -124.156; x: 49.6; y: -124.156 }
+ PathCubic { control1X: 49.736; control1Y: -124.155; control2X: 49.867; control2Y: -123.845; x: 50; y: -123.845 }
+ PathCubic { control1X: 50.136; control1Y: -123.845; control2X: 50.266; control2Y: -124.066; x: 50.4; y: -124.2 }
+ PathCubic { control1X: 51.092; control1Y: -123.418; control2X: 51.977; control2Y: -123.972; x: 52.799; y: -123.793 }
+ PathCubic { control1X: 53.837; control1Y: -123.566; control2X: 54.104; control2Y: -122.418; x: 55.178; y: -122.12 }
+ PathCubic { control1X: 59.893; control1Y: -120.816; control2X: 64.03; control2Y: -118.671; x: 68.393; y: -116.584 }
+ PathCubic { control1X: 68.7; control1Y: -116.437; control2X: 68.91; control2Y: -116.189; x: 68.8; y: -115.8 }
+ PathCubic { control1X: 69.067; control1Y: -115.8; control2X: 69.38; control2Y: -115.888; x: 69.57; y: -115.756 }
+ PathCubic { control1X: 70.628; control1Y: -115.024; control2X: 71.669; control2Y: -114.476; x: 72.366; y: -113.378 }
+ PathCubic { control1X: 72.582; control1Y: -113.039; control2X: 72.253; control2Y: -112.632; x: 72.02; y: -112.684 }
+ PathCubic { control1X: 67.591; control1Y: -113.679; control2X: 63.585; control2Y: -114.287; x: 59.198; y: -115.391 }
+ }
+
+ ShapePath {
+ fillColor: "#cc7226"
+ strokeWidth: -1
+ PathMove { x: 45.338; y: -71.179 }
+ PathCubic { control1X: 43.746; control1Y: -72.398; control2X: 43.162; control2Y: -74.429; x: 42.034; y: -76.221 }
+ PathCubic { control1X: 41.82; control1Y: -76.561; control2X: 42.094; control2Y: -76.875; x: 42.411; y: -76.964 }
+ PathCubic { control1X: 42.971; control1Y: -77.123; control2X: 43.514; control2Y: -76.645; x: 43.923; y: -76.443 }
+ PathCubic { control1X: 45.668; control1Y: -75.581; control2X: 47.203; control2Y: -74.339; x: 49.2; y: -74.2 }
+ PathCubic { control1X: 51.19; control1Y: -71.966; control2X: 55.45; control2Y: -71.581; x: 55.457; y: -68.2 }
+ PathCubic { control1X: 55.458; control1Y: -67.341; control2X: 54.03; control2Y: -68.259; x: 53.6; y: -67.4 }
+ PathCubic { control1X: 51.149; control1Y: -68.403; control2X: 48.76; control2Y: -68.3; x: 46.38; y: -69.767 }
+ PathCubic { control1X: 45.763; control1Y: -70.148; control2X: 46.093; control2Y: -70.601; x: 45.338; y: -71.179 }
+ }
+
+ ShapePath {
+ fillColor: "#cc7226"
+ strokeWidth: -1
+ PathMove { x: 17.8; y: -123.756 }
+ PathCubic { control1X: 17.935; control1Y: -123.755; control2X: 24.966; control2Y: -123.522; x: 24.949; y: -123.408 }
+ PathCubic { control1X: 24.904; control1Y: -123.099; control2X: 17.174; control2Y: -122.05; x: 16.81; y: -122.22 }
+ PathCubic { control1X: 16.646; control1Y: -122.296; control2X: 9.134; control2Y: -119.866; x: 9; y: -120 }
+ PathCubic { control1X: 9.268; control1Y: -120.135; control2X: 17.534; control2Y: -123.756; x: 17.8; y: -123.756 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 33.2; y: -114 }
+ PathCubic { control1X: 33.2; control1Y: -114; control2X: 18.4; control2Y: -112.2; x: 14; y: -111 }
+ PathCubic { control1X: 9.6; control1Y: -109.8; control2X: -9; control2Y: -102.2; x: -12; y: -100.2 }
+ PathCubic { control1X: -12; control1Y: -100.2; control2X: -25.4; control2Y: -94.8; x: -42.4; y: -74.8 }
+ PathCubic { control1X: -42.4; control1Y: -74.8; control2X: -34.8; control2Y: -78.2; x: -32.6; y: -81 }
+ PathCubic { control1X: -32.6; control1Y: -81; control2X: -19; control2Y: -93.6; x: -19.2; y: -91 }
+ PathCubic { control1X: -19.2; control1Y: -91; control2X: -7; control2Y: -99.6; x: -7.6; y: -97.4 }
+ PathCubic { control1X: -7.6; control1Y: -97.4; control2X: 16.8; control2Y: -108.6; x: 14.8; y: -105.4 }
+ PathCubic { control1X: 14.8; control1Y: -105.4; control2X: 36.4; control2Y: -110; x: 35.4; y: -108 }
+ PathCubic { control1X: 35.4; control1Y: -108; control2X: 54.2; control2Y: -103.6; x: 51.4; y: -103.4 }
+ PathCubic { control1X: 51.4; control1Y: -103.4; control2X: 45.6; control2Y: -102.2; x: 52; y: -98.6 }
+ PathCubic { control1X: 52; control1Y: -98.6; control2X: 48.6; control2Y: -94.2; x: 43.2; y: -98.2 }
+ PathCubic { control1X: 37.8; control1Y: -102.2; control2X: 40.8; control2Y: -100; x: 35.8; y: -99 }
+ PathCubic { control1X: 35.8; control1Y: -99; control2X: 33.2; control2Y: -98.2; x: 28.6; y: -102.2 }
+ PathCubic { control1X: 28.6; control1Y: -102.2; control2X: 23; control2Y: -106.8; x: 14.2; y: -103.2 }
+ PathCubic { control1X: 14.2; control1Y: -103.2; control2X: -16.4; control2Y: -90.6; x: -18.4; y: -90 }
+ PathCubic { control1X: -18.4; control1Y: -90; control2X: -22; control2Y: -87.2; x: -24.4; y: -83.6 }
+ PathCubic { control1X: -24.4; control1Y: -83.6; control2X: -30.2; control2Y: -79.2; x: -33.2; y: -77.8 }
+ PathCubic { control1X: -33.2; control1Y: -77.8; control2X: -46; control2Y: -66.2; x: -47.2; y: -64.8 }
+ PathCubic { control1X: -47.2; control1Y: -64.8; control2X: -50.6; control2Y: -59.6; x: -51.4; y: -59.2 }
+ PathCubic { control1X: -51.4; control1Y: -59.2; control2X: -45; control2Y: -63; x: -43; y: -65 }
+ PathCubic { control1X: -43; control1Y: -65; control2X: -29; control2Y: -75; x: -23.6; y: -75.8 }
+ PathCubic { control1X: -23.6; control1Y: -75.8; control2X: -19.2; control2Y: -78.8; x: -18.4; y: -80.2 }
+ PathCubic { control1X: -18.4; control1Y: -80.2; control2X: -4; control2Y: -89.4; x: 0.2; y: -89.4 }
+ PathCubic { control1X: 0.2; control1Y: -89.4; control2X: 9.4; control2Y: -84.2; x: 11.8; y: -91.2 }
+ PathCubic { control1X: 11.8; control1Y: -91.2; control2X: 17.6; control2Y: -93; x: 23.2; y: -91.8 }
+ PathCubic { control1X: 23.2; control1Y: -91.8; control2X: 26.4; control2Y: -94.4; x: 25.6; y: -96.6 }
+ PathCubic { control1X: 25.6; control1Y: -96.6; control2X: 27.2; control2Y: -98.4; x: 28.2; y: -94.6 }
+ PathCubic { control1X: 28.2; control1Y: -94.6; control2X: 31.6; control2Y: -91; x: 36.4; y: -93 }
+ PathCubic { control1X: 36.4; control1Y: -93; control2X: 40.4; control2Y: -93.2; x: 38.4; y: -90.8 }
+ PathCubic { control1X: 38.4; control1Y: -90.8; control2X: 34; control2Y: -87; x: 22.2; y: -86.8 }
+ PathCubic { control1X: 22.2; control1Y: -86.8; control2X: 9.8; control2Y: -86.2; x: -6.6; y: -78.6 }
+ PathCubic { control1X: -6.6; control1Y: -78.6; control2X: -36.4; control2Y: -68.2; x: -45.6; y: -57.8 }
+ PathCubic { control1X: -45.6; control1Y: -57.8; control2X: -52; control2Y: -49; x: -57.4; y: -47.8 }
+ PathCubic { control1X: -57.4; control1Y: -47.8; control2X: -63.2; control2Y: -47; x: -69.2; y: -39.6 }
+ PathCubic { control1X: -69.2; control1Y: -39.6; control2X: -59.4; control2Y: -45.4; x: -50.4; y: -45.4 }
+ PathCubic { control1X: -50.4; control1Y: -45.4; control2X: -46.4; control2Y: -47.8; x: -50.2; y: -44.2 }
+ PathCubic { control1X: -50.2; control1Y: -44.2; control2X: -53.8; control2Y: -36.6; x: -52.2; y: -31.2 }
+ PathCubic { control1X: -52.2; control1Y: -31.2; control2X: -52.8; control2Y: -26; x: -53.6; y: -24.4 }
+ PathCubic { control1X: -53.6; control1Y: -24.4; control2X: -61.4; control2Y: -11.6; x: -61.4; y: -9.2 }
+ PathCubic { control1X: -61.4; control1Y: -6.8; control2X: -60.2; control2Y: 3; x: -59.8; y: 3.6 }
+ PathCubic { control1X: -59.4; control1Y: 4.2; control2X: -60.8; control2Y: 2; x: -57; y: 4.4 }
+ PathCubic { control1X: -53.2; control1Y: 6.8; control2X: -50.4; control2Y: 8.4; x: -49.6; y: 11.2 }
+ PathCubic { control1X: -48.8; control1Y: 14; control2X: -51.6; control2Y: 5.8; x: -51.8; y: 4 }
+ PathCubic { control1X: -52; control1Y: 2.2; control2X: -56.2; control2Y: -5; x: -55.4; y: -7.4 }
+ PathCubic { control1X: -55.4; control1Y: -7.4; control2X: -54.4; control2Y: -6.4; x: -53.6; y: -5 }
+ PathCubic { control1X: -53.6; control1Y: -5; control2X: -54.2; control2Y: -5.6; x: -53.6; y: -9.2 }
+ PathCubic { control1X: -53.6; control1Y: -9.2; control2X: -52.8; control2Y: -14.4; x: -51.4; y: -17.6 }
+ PathCubic { control1X: -50; control1Y: -20.8; control2X: -48; control2Y: -24.6; x: -47.6; y: -25.4 }
+ PathCubic { control1X: -47.2; control1Y: -26.2; control2X: -47.2; control2Y: -32; x: -45.8; y: -29.4 }
+ PathLine { x: -42.4; y: -26.8 }
+ PathCubic { control1X: -42.4; control1Y: -26.8; control2X: -45.2; control2Y: -29.4; x: -43; y: -31.6 }
+ PathCubic { control1X: -43; control1Y: -31.6; control2X: -44; control2Y: -37.2; x: -42.2; y: -39.8 }
+ PathCubic { control1X: -42.2; control1Y: -39.8; control2X: -35.2; control2Y: -48.2; x: -33.6; y: -49.2 }
+ PathCubic { control1X: -32; control1Y: -50.2; control2X: -33.4; control2Y: -49.8; x: -33.4; y: -49.8 }
+ PathCubic { control1X: -33.4; control1Y: -49.8; control2X: -27.4; control2Y: -54; x: -33.2; y: -52.4 }
+ PathCubic { control1X: -33.2; control1Y: -52.4; control2X: -37.2; control2Y: -50.8; x: -40.2; y: -50.8 }
+ PathCubic { control1X: -40.2; control1Y: -50.8; control2X: -47.8; control2Y: -48.8; x: -43.8; y: -53 }
+ PathCubic { control1X: -39.8; control1Y: -57.2; control2X: -29.8; control2Y: -62.6; x: -26; y: -62.4 }
+ PathLine { x: -25.2; y: -60.8 }
+ PathLine { x: -14; y: -63.2 }
+ PathLine { x: -15.2; y: -62.4 }
+ PathCubic { control1X: -15.2; control1Y: -62.4; control2X: -15.4; control2Y: -62.6; x: -11.2; y: -63 }
+ PathCubic { control1X: -7; control1Y: -63.4; control2X: -1.2; control2Y: -62; x: 0.2; y: -63.8 }
+ PathCubic { control1X: 1.6; control1Y: -65.6; control2X: 5; control2Y: -66.6; x: 4.6; y: -65.2 }
+ PathCubic { control1X: 4.2; control1Y: -63.8; control2X: 4; control2Y: -61.8; x: 4; y: -61.8 }
+ PathCubic { control1X: 4; control1Y: -61.8; control2X: 9; control2Y: -67.6; x: 8.4; y: -65.4 }
+ PathCubic { control1X: 7.8; control1Y: -63.2; control2X: -0.4; control2Y: -58; x: -1.8; y: -51.8 }
+ PathLine { x: 8.6; y: -60 }
+ PathLine { x: 12.2; y: -63 }
+ PathCubic { control1X: 12.2; control1Y: -63; control2X: 15.8; control2Y: -60.8; x: 16; y: -62.4 }
+ PathCubic { control1X: 16.2; control1Y: -64; control2X: 20.8; control2Y: -69.8; x: 22; y: -69.6 }
+ PathCubic { control1X: 23.2; control1Y: -69.4; control2X: 25.2; control2Y: -72.2; x: 25; y: -69.6 }
+ PathCubic { control1X: 24.8; control1Y: -67; control2X: 32.4; control2Y: -61.6; x: 32.4; y: -61.6 }
+ PathCubic { control1X: 32.4; control1Y: -61.6; control2X: 35.6; control2Y: -63.4; x: 37; y: -62 }
+ PathCubic { control1X: 38.4; control1Y: -60.6; control2X: 42.6; control2Y: -81.8; x: 42.6; y: -81.8 }
+ PathLine { x: 67.6; y: -92.4 }
+ PathLine { x: 111.201; y: -95.8 }
+ PathLine { x: 94.201; y: -102.6 }
+ PathLine { x: 33.2; y: -114 }
+ }
+
+ ShapePath {
+ fillColor: "transparent"
+ strokeColor: "#4c0000"
+ strokeWidth: 2
+ PathMove { x: 51.4; y: 85 }
+ PathCubic { control1X: 51.4; control1Y: 85; control2X: 36.4; control2Y: 68.2; x: 28; y: 65.6 }
+ PathCubic { control1X: 28; control1Y: 65.6; control2X: 14.6; control2Y: 58.8; x: -10; y: 66.6 }
+ }
+
+ ShapePath {
+ fillColor: "transparent"
+ strokeColor: "#4c0000"
+ strokeWidth: 2
+ PathMove { x: 24.8; y: 64.2 }
+ PathCubic { control1X: 24.8; control1Y: 64.2; control2X: -0.4; control2Y: 56.2; x: -15.8; y: 60.4 }
+ PathCubic { control1X: -15.8; control1Y: 60.4; control2X: -34.2; control2Y: 62.4; x: -42.6; y: 76.2 }
+ }
+
+ ShapePath {
+ fillColor: "transparent"
+ strokeColor: "#4c0000"
+ strokeWidth: 2
+ PathMove { x: 21.2; y: 63 }
+ PathCubic { control1X: 21.2; control1Y: 63; control2X: 4.2; control2Y: 55.8; x: -10.6; y: 53.6 }
+ PathCubic { control1X: -10.6; control1Y: 53.6; control2X: -27.2; control2Y: 51; x: -43.8; y: 58.2 }
+ PathCubic { control1X: -43.8; control1Y: 58.2; control2X: -56; control2Y: 64.2; x: -61.4; y: 74.4 }
+ }
+
+ ShapePath {
+ fillColor: "transparent"
+ strokeColor: "#4c0000"
+ strokeWidth: 2
+ PathMove { x: 22.2; y: 63.4 }
+ PathCubic { control1X: 22.2; control1Y: 63.4; control2X: 6.8; control2Y: 52.4; x: 5.8; y: 51 }
+ PathCubic { control1X: 5.8; control1Y: 51; control2X: -1.2; control2Y: 40; x: -14.2; y: 39.6 }
+ PathCubic { control1X: -14.2; control1Y: 39.6; control2X: -35.6; control2Y: 40.4; x: -52.8; y: 48.4 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 20.895; y: 54.407 }
+ PathCubic { control1X: 22.437; control1Y: 55.87; control2X: 49.4; control2Y: 84.8; x: 49.4; y: 84.8 }
+ PathCubic { control1X: 84.6; control1Y: 121.401; control2X: 56.6; control2Y: 87.2; x: 56.6; y: 87.2 }
+ PathCubic { control1X: 49; control1Y: 82.4; control2X: 39.8; control2Y: 63.6; x: 39.8; y: 63.6 }
+ PathCubic { control1X: 38.6; control1Y: 60.8; control2X: 53.8; control2Y: 70.8; x: 53.8; y: 70.8 }
+ PathCubic { control1X: 57.8; control1Y: 71.6; control2X: 71.4; control2Y: 90.8; x: 71.4; y: 90.8 }
+ PathCubic { control1X: 64.6; control1Y: 88.4; control2X: 69.4; control2Y: 95.6; x: 69.4; y: 95.6 }
+ PathCubic { control1X: 72.2; control1Y: 97.6; control2X: 92.601; control2Y: 113.201; x: 92.601; y: 113.201 }
+ PathCubic { control1X: 96.201; control1Y: 117.201; control2X: 100.201; control2Y: 118.801; x: 100.201; y: 118.801 }
+ PathCubic { control1X: 114.201; control1Y: 113.601; control2X: 107.801; control2Y: 126.801; x: 107.801; y: 126.801 }
+ PathCubic { control1X: 110.201; control1Y: 133.601; control2X: 115.801; control2Y: 122.001; x: 115.801; y: 122.001 }
+ PathCubic { control1X: 127.001; control1Y: 105.2; control2X: 110.601; control2Y: 107.601; x: 110.601; y: 107.601 }
+ PathCubic { control1X: 80.6; control1Y: 110.401; control2X: 73.8; control2Y: 94.4; x: 73.8; y: 94.4 }
+ PathCubic { control1X: 71.4; control1Y: 92; control2X: 80.2; control2Y: 94.4; x: 80.2; y: 94.4 }
+ PathCubic { control1X: 88.601; control1Y: 96.4; control2X: 73; control2Y: 82; x: 73; y: 82 }
+ PathCubic { control1X: 75.4; control1Y: 82; control2X: 84.6; control2Y: 88.8; x: 84.6; y: 88.8 }
+ PathCubic { control1X: 95.001; control1Y: 98; control2X: 97.001; control2Y: 96; x: 97.001; y: 96 }
+ PathCubic { control1X: 115.001; control1Y: 87.2; control2X: 125.401; control2Y: 94.8; x: 125.401; y: 94.8 }
+ PathCubic { control1X: 127.401; control1Y: 96.4; control2X: 121.801; control2Y: 103.2; x: 123.401; y: 108.401 }
+ PathCubic { control1X: 125.001; control1Y: 113.601; control2X: 129.801; control2Y: 126.001; x: 129.801; y: 126.001 }
+ PathCubic { control1X: 127.401; control1Y: 127.601; control2X: 127.801; control2Y: 138.401; x: 127.801; y: 138.401 }
+ PathCubic { control1X: 144.601; control1Y: 161.601; control2X: 135.001; control2Y: 159.601; x: 135.001; y: 159.601 }
+ PathCubic { control1X: 119.401; control1Y: 159.201; control2X: 134.201; control2Y: 166.801; x: 134.201; y: 166.801 }
+ PathCubic { control1X: 137.401; control1Y: 168.801; control2X: 146.201; control2Y: 176.001; x: 146.201; y: 176.001 }
+ PathCubic { control1X: 143.401; control1Y: 174.801; control2X: 141.801; control2Y: 180.001; x: 141.801; y: 180.001 }
+ PathCubic { control1X: 146.601; control1Y: 184.001; control2X: 143.801; control2Y: 188.801; x: 143.801; y: 188.801 }
+ PathCubic { control1X: 137.801; control1Y: 190.001; control2X: 136.601; control2Y: 194.001; x: 136.601; y: 194.001 }
+ PathCubic { control1X: 143.401; control1Y: 202.001; control2X: 133.401; control2Y: 202.401; x: 133.401; y: 202.401 }
+ PathCubic { control1X: 137.001; control1Y: 206.801; control2X: 132.201; control2Y: 218.801; x: 132.201; y: 218.801 }
+ PathCubic { control1X: 127.401; control1Y: 218.801; control2X: 121.001; control2Y: 224.401; x: 121.001; y: 224.401 }
+ PathCubic { control1X: 123.401; control1Y: 229.201; control2X: 113.001; control2Y: 234.801; x: 113.001; y: 234.801 }
+ PathCubic { control1X: 104.601; control1Y: 236.401; control2X: 107.401; control2Y: 243.201; x: 107.401; y: 243.201 }
+ PathCubic { control1X: 99.401; control1Y: 249.201; control2X: 97.001; control2Y: 265.201; x: 97.001; y: 265.201 }
+ PathCubic { control1X: 96.201; control1Y: 275.601; control2X: 93.801; control2Y: 278.801; x: 99.001; y: 276.801 }
+ PathCubic { control1X: 104.201; control1Y: 274.801; control2X: 103.401; control2Y: 262.401; x: 103.401; y: 262.401 }
+ PathCubic { control1X: 98.601; control1Y: 246.801; control2X: 141.401; control2Y: 230.801; x: 141.401; y: 230.801 }
+ PathCubic { control1X: 145.401; control1Y: 229.201; control2X: 146.201; control2Y: 224.001; x: 146.201; y: 224.001 }
+ PathCubic { control1X: 148.201; control1Y: 224.401; control2X: 157.001; control2Y: 232.001; x: 157.001; y: 232.001 }
+ PathCubic { control1X: 164.601; control1Y: 243.201; control2X: 165.001; control2Y: 234.001; x: 165.001; y: 234.001 }
+ PathCubic { control1X: 166.201; control1Y: 230.401; control2X: 164.601; control2Y: 224.401; x: 164.601; y: 224.401 }
+ PathCubic { control1X: 170.601; control1Y: 202.801; control2X: 156.601; control2Y: 196.401; x: 156.601; y: 196.401 }
+ PathCubic { control1X: 146.601; control1Y: 162.801; control2X: 160.601; control2Y: 171.201; x: 160.601; y: 171.201 }
+ PathCubic { control1X: 163.401; control1Y: 176.801; control2X: 174.201; control2Y: 182.001; x: 174.201; y: 182.001 }
+ PathLine { x: 177.801; y: 179.601 }
+ PathCubic { control1X: 176.201; control1Y: 174.801; control2X: 184.601; control2Y: 168.801; x: 184.601; y: 168.801 }
+ PathCubic { control1X: 187.401; control1Y: 175.201; control2X: 193.401; control2Y: 167.201; x: 193.401; y: 167.201 }
+ PathCubic { control1X: 197.001; control1Y: 142.801; control2X: 209.401; control2Y: 157.201; x: 209.401; y: 157.201 }
+ PathCubic { control1X: 213.401; control1Y: 158.401; control2X: 214.601; control2Y: 151.601; x: 214.601; y: 151.601 }
+ PathCubic { control1X: 218.201; control1Y: 141.201; control2X: 214.601; control2Y: 127.601; x: 214.601; y: 127.601 }
+ PathCubic { control1X: 218.201; control1Y: 127.201; control2X: 227.801; control2Y: 133.201; x: 227.801; y: 133.201 }
+ PathCubic { control1X: 230.601; control1Y: 129.601; control2X: 221.401; control2Y: 112.801; x: 225.401; y: 115.201 }
+ PathCubic { control1X: 229.401; control1Y: 117.601; control2X: 233.801; control2Y: 119.201; x: 233.801; y: 119.201 }
+ PathCubic { control1X: 234.601; control1Y: 117.201; control2X: 224.601; control2Y: 104.801; x: 224.601; y: 104.801 }
+ PathCubic { control1X: 220.201; control1Y: 102; control2X: 215.001; control2Y: 81.6; x: 215.001; y: 81.6 }
+ PathCubic { control1X: 222.201; control1Y: 85.2; control2X: 212.201; control2Y: 70; x: 212.201; y: 70 }
+ PathCubic { control1X: 212.201; control1Y: 66.8; control2X: 218.201; control2Y: 55.6; x: 218.201; y: 55.6 }
+ PathCubic { control1X: 217.401; control1Y: 48.8; control2X: 218.201; control2Y: 49.2; x: 218.201; y: 49.2 }
+ PathCubic { control1X: 221.001; control1Y: 50.4; control2X: 229.001; control2Y: 52; x: 222.201; y: 45.6 }
+ PathCubic { control1X: 215.401; control1Y: 39.2; control2X: 223.001; control2Y: 34.4; x: 223.001; y: 34.4 }
+ PathCubic { control1X: 227.401; control1Y: 31.6; control2X: 213.801; control2Y: 32; x: 213.801; y: 32 }
+ PathCubic { control1X: 208.601; control1Y: 27.6; control2X: 209.001; control2Y: 23.6; x: 209.001; y: 23.6 }
+ PathCubic { control1X: 217.001; control1Y: 25.6; control2X: 202.601; control2Y: 11.2; x: 200.201; y: 7.6 }
+ PathCubic { control1X: 197.801; control1Y: 4; control2X: 207.401; control2Y: -1.2; x: 207.401; y: -1.2 }
+ PathCubic { control1X: 220.601; control1Y: -4.8; control2X: 209.001; control2Y: -8; x: 209.001; y: -8 }
+ PathCubic { control1X: 189.401; control1Y: -7.6; control2X: 200.201; control2Y: -18.4; x: 200.201; y: -18.4 }
+ PathCubic { control1X: 206.201; control1Y: -18; control2X: 204.601; control2Y: -20.4; x: 204.601; y: -20.4 }
+ PathCubic { control1X: 199.401; control1Y: -21.6; control2X: 189.801; control2Y: -28; x: 189.801; y: -28 }
+ PathCubic { control1X: 185.801; control1Y: -31.6; control2X: 189.401; control2Y: -30.8; x: 189.401; y: -30.8 }
+ PathCubic { control1X: 206.201; control1Y: -29.6; control2X: 177.401; control2Y: -40.8; x: 177.401; y: -40.8 }
+ PathCubic { control1X: 185.401; control1Y: -40.8; control2X: 167.401; control2Y: -51.2; x: 167.401; y: -51.2 }
+ PathCubic { control1X: 165.401; control1Y: -52.8; control2X: 162.201; control2Y: -60.4; x: 162.201; y: -60.4 }
+ PathCubic { control1X: 156.201; control1Y: -65.6; control2X: 151.401; control2Y: -72.4; x: 151.401; y: -72.4 }
+ PathCubic { control1X: 151.001; control1Y: -76.8; control2X: 146.201; control2Y: -81.6; x: 146.201; y: -81.6 }
+ PathCubic { control1X: 134.601; control1Y: -95.2; control2X: 129.001; control2Y: -94.8; x: 129.001; y: -94.8 }
+ PathCubic { control1X: 114.201; control1Y: -98.4; control2X: 109.001; control2Y: -97.6; x: 109.001; y: -97.6 }
+ PathLine { x: 56.2; y: -93.2 }
+ PathCubic { control1X: 29.8; control1Y: -80.4; control2X: 37.6; control2Y: -59.4; x: 37.6; y: -59.4 }
+ PathCubic { control1X: 44; control1Y: -51; control2X: 53.2; control2Y: -54.8; x: 53.2; y: -54.8 }
+ PathCubic { control1X: 57.8; control1Y: -61; control2X: 69.4; control2Y: -58.8; x: 69.4; y: -58.8 }
+ PathCubic { control1X: 89.801; control1Y: -55.6; control2X: 87.201; control2Y: -59.2; x: 87.201; y: -59.2 }
+ PathCubic { control1X: 84.801; control1Y: -63.8; control2X: 68.6; control2Y: -70; x: 68.4; y: -70.6 }
+ PathCubic { control1X: 68.2; control1Y: -71.2; control2X: 59.4; control2Y: -74.6; x: 59.4; y: -74.6 }
+ PathCubic { control1X: 56.4; control1Y: -75.8; control2X: 52; control2Y: -85; x: 52; y: -85 }
+ PathCubic { control1X: 48.8; control1Y: -88.4; control2X: 64.6; control2Y: -82.6; x: 64.6; y: -82.6 }
+ PathCubic { control1X: 63.4; control1Y: -81.6; control2X: 70.8; control2Y: -77.6; x: 70.8; y: -77.6 }
+ PathCubic { control1X: 88.201; control1Y: -78.6; control2X: 98.801; control2Y: -67.8; x: 98.801; y: -67.8 }
+ PathCubic { control1X: 109.601; control1Y: -51.2; control2X: 109.801; control2Y: -59.4; x: 109.801; y: -59.4 }
+ PathCubic { control1X: 112.601; control1Y: -68.8; control2X: 100.801; control2Y: -90; x: 100.801; y: -90 }
+ PathCubic { control1X: 101.201; control1Y: -92; control2X: 109.401; control2Y: -85.4; x: 109.401; y: -85.4 }
+ PathCubic { control1X: 110.801; control1Y: -87.4; control2X: 111.601; control2Y: -81.6; x: 111.601; y: -81.6 }
+ PathCubic { control1X: 111.801; control1Y: -79.2; control2X: 115.601; control2Y: -71.2; x: 115.601; y: -71.2 }
+ PathCubic { control1X: 118.401; control1Y: -58.2; control2X: 122.001; control2Y: -65.6; x: 122.001; y: -65.6 }
+ PathLine { x: 126.601; y: -56.2 }
+ PathCubic { control1X: 128.001; control1Y: -53.6; control2X: 122.001; control2Y: -46; x: 122.001; y: -46 }
+ PathCubic { control1X: 121.801; control1Y: -43.2; control2X: 122.601; control2Y: -43.4; x: 117.001; y: -35.8 }
+ PathCubic { control1X: 111.401; control1Y: -28.2; control2X: 114.801; control2Y: -23.8; x: 114.801; y: -23.8 }
+ PathCubic { control1X: 113.401; control1Y: -17.2; control2X: 122.201; control2Y: -17.6; x: 122.201; y: -17.6 }
+ PathCubic { control1X: 124.801; control1Y: -15.4; control2X: 128.201; control2Y: -15.4; x: 128.201; y: -15.4 }
+ PathCubic { control1X: 130.001; control1Y: -13.4; control2X: 132.401; control2Y: -14; x: 132.401; y: -14 }
+ PathCubic { control1X: 134.001; control1Y: -17.8; control2X: 140.201; control2Y: -15.8; x: 140.201; y: -15.8 }
+ PathCubic { control1X: 141.601; control1Y: -18.2; control2X: 149.801; control2Y: -18.6; x: 149.801; y: -18.6 }
+ PathCubic { control1X: 150.801; control1Y: -21.2; control2X: 151.201; control2Y: -22.8; x: 154.601; y: -23.4 }
+ PathCubic { control1X: 158.001; control1Y: -24; control2X: 133.401; control2Y: -67; x: 133.401; y: -67 }
+ PathCubic { control1X: 139.801; control1Y: -67.8; control2X: 131.601; control2Y: -80.2; x: 131.601; y: -80.2 }
+ PathCubic { control1X: 129.401; control1Y: -86.8; control2X: 140.801; control2Y: -72.2; x: 143.001; y: -70.8 }
+ PathCubic { control1X: 145.201; control1Y: -69.4; control2X: 146.201; control2Y: -67.2; x: 144.601; y: -67.4 }
+ PathCubic { control1X: 143.001; control1Y: -67.6; control2X: 141.201; control2Y: -65.4; x: 142.601; y: -65.2 }
+ PathCubic { control1X: 144.001; control1Y: -65; control2X: 157.001; control2Y: -50; x: 160.401; y: -39.8 }
+ PathCubic { control1X: 163.801; control1Y: -29.6; control2X: 169.801; control2Y: -25.6; x: 176.001; y: -19.6 }
+ PathCubic { control1X: 182.201; control1Y: -13.6; control2X: 181.401; control2Y: 10.6; x: 181.401; y: 10.6 }
+ PathCubic { control1X: 181.001; control1Y: 19.4; control2X: 187.001; control2Y: 30; x: 187.001; y: 30 }
+ PathCubic { control1X: 189.001; control1Y: 33.8; control2X: 184.801; control2Y: 52; x: 184.801; y: 52 }
+ PathCubic { control1X: 182.801; control1Y: 54.2; control2X: 184.201; control2Y: 55; x: 184.201; y: 55 }
+ PathCubic { control1X: 185.201; control1Y: 56.2; control2X: 192.001; control2Y: 69.4; x: 192.001; y: 69.4 }
+ PathCubic { control1X: 190.201; control1Y: 69.2; control2X: 193.801; control2Y: 72.8; x: 193.801; y: 72.8 }
+ PathCubic { control1X: 199.001; control1Y: 78.8; control2X: 192.601; control2Y: 75.8; x: 192.601; y: 75.8 }
+ PathCubic { control1X: 186.601; control1Y: 74.2; control2X: 193.601; control2Y: 84; x: 193.601; y: 84 }
+ PathCubic { control1X: 194.801; control1Y: 85.8; control2X: 185.801; control2Y: 81.2; x: 185.801; y: 81.2 }
+ PathCubic { control1X: 176.601; control1Y: 80.6; control2X: 188.201; control2Y: 87.8; x: 188.201; y: 87.8 }
+ PathCubic { control1X: 196.801; control1Y: 95; control2X: 185.401; control2Y: 90.6; x: 185.401; y: 90.6 }
+ PathCubic { control1X: 180.801; control1Y: 88.8; control2X: 184.001; control2Y: 95.6; x: 184.001; y: 95.6 }
+ PathCubic { control1X: 187.201; control1Y: 97.2; control2X: 204.401; control2Y: 104.2; x: 204.401; y: 104.2 }
+ PathCubic { control1X: 204.801; control1Y: 108.001; control2X: 201.801; control2Y: 113.001; x: 201.801; y: 113.001 }
+ PathCubic { control1X: 202.201; control1Y: 117.001; control2X: 200.001; control2Y: 120.401; x: 200.001; y: 120.401 }
+ PathCubic { control1X: 198.801; control1Y: 128.601; control2X: 198.201; control2Y: 129.401; x: 198.201; y: 129.401 }
+ PathCubic { control1X: 194.001; control1Y: 129.601; control2X: 186.601; control2Y: 143.401; x: 186.601; y: 143.401 }
+ PathCubic { control1X: 184.801; control1Y: 146.001; control2X: 174.601; control2Y: 158.001; x: 174.601; y: 158.001 }
+ PathCubic { control1X: 172.601; control1Y: 165.001; control2X: 154.601; control2Y: 157.801; x: 154.601; y: 157.801 }
+ PathCubic { control1X: 148.001; control1Y: 161.201; control2X: 150.001; control2Y: 157.801; x: 150.001; y: 157.801 }
+ PathCubic { control1X: 149.601; control1Y: 155.601; control2X: 154.401; control2Y: 149.601; x: 154.401; y: 149.601 }
+ PathCubic { control1X: 161.401; control1Y: 147.001; control2X: 158.801; control2Y: 136.201; x: 158.801; y: 136.201 }
+ PathCubic { control1X: 162.801; control1Y: 134.801; control2X: 151.601; control2Y: 132.001; x: 151.801; y: 130.801 }
+ PathCubic { control1X: 152.001; control1Y: 129.601; control2X: 157.801; control2Y: 128.201; x: 157.801; y: 128.201 }
+ PathCubic { control1X: 165.801; control1Y: 126.201; control2X: 161.401; control2Y: 123.801; x: 161.401; y: 123.801 }
+ PathCubic { control1X: 160.801; control1Y: 119.801; control2X: 163.801; control2Y: 114.201; x: 163.801; y: 114.201 }
+ PathCubic { control1X: 175.401; control1Y: 113.401; control2X: 163.801; control2Y: 97.2; x: 163.801; y: 97.2 }
+ PathCubic { control1X: 153.001; control1Y: 89.6; control2X: 152.001; control2Y: 83.8; x: 152.001; y: 83.8 }
+ PathCubic { control1X: 164.601; control1Y: 75.6; control2X: 156.401; control2Y: 63.2; x: 156.601; y: 59.6 }
+ PathCubic { control1X: 156.801; control1Y: 56; control2X: 158.001; control2Y: 34.4; x: 158.001; y: 34.4 }
+ PathCubic { control1X: 156.001; control1Y: 28.2; control2X: 153.001; control2Y: 14.6; x: 153.001; y: 14.6 }
+ PathCubic { control1X: 155.201; control1Y: 9.4; control2X: 162.601; control2Y: -3.2; x: 162.601; y: -3.2 }
+ PathCubic { control1X: 165.401; control1Y: -7.4; control2X: 174.201; control2Y: -12.2; x: 172.001; y: -15.2 }
+ PathCubic { control1X: 169.801; control1Y: -18.2; control2X: 162.001; control2Y: -16.4; x: 162.001; y: -16.4 }
+ PathCubic { control1X: 154.201; control1Y: -17.8; control2X: 154.801; control2Y: -12.6; x: 154.801; y: -12.6 }
+ PathCubic { control1X: 153.201; control1Y: -11.6; control2X: 152.401; control2Y: -6.6; x: 152.401; y: -6.6 }
+ PathCubic { control1X: 151.68; control1Y: 1.333; control2X: 142.801; control2Y: 7.6; x: 142.801; y: 7.6 }
+ PathCubic { control1X: 131.601; control1Y: 13.8; control2X: 140.801; control2Y: 17.8; x: 140.801; y: 17.8 }
+ PathCubic { control1X: 146.801; control1Y: 24.4; control2X: 137.001; control2Y: 24.6; x: 137.001; y: 24.6 }
+ PathCubic { control1X: 126.001; control1Y: 22.8; control2X: 134.201; control2Y: 33; x: 134.201; y: 33 }
+ PathCubic { control1X: 145.001; control1Y: 45.8; control2X: 142.001; control2Y: 48.6; x: 142.001; y: 48.6 }
+ PathCubic { control1X: 131.801; control1Y: 49.6; control2X: 144.401; control2Y: 58.8; x: 144.401; y: 58.8 }
+ PathCubic { control1X: 144.401; control1Y: 58.8; control2X: 143.601; control2Y: 56.8; x: 143.801; y: 58.6 }
+ PathCubic { control1X: 144.001; control1Y: 60.4; control2X: 147.001; control2Y: 64.6; x: 147.801; y: 66.6 }
+ PathCubic { control1X: 148.601; control1Y: 68.6; control2X: 144.601; control2Y: 68.8; x: 144.601; y: 68.8 }
+ PathCubic { control1X: 145.201; control1Y: 78.4; control2X: 129.801; control2Y: 74.2; x: 129.801; y: 74.2 }
+ PathCubic { control1X: 129.801; control1Y: 74.2; control2X: 129.801; control2Y: 74.2; x: 128.201; y: 74.4 }
+ PathCubic { control1X: 126.601; control1Y: 74.6; control2X: 115.401; control2Y: 73.8; x: 109.601; y: 71.6 }
+ PathCubic { control1X: 103.801; control1Y: 69.4; control2X: 97.001; control2Y: 69.4; x: 97.001; y: 69.4 }
+ PathCubic { control1X: 97.001; control1Y: 69.4; control2X: 93.001; control2Y: 71.2; x: 85.4; y: 71 }
+ PathCubic { control1X: 77.8; control1Y: 70.8; control2X: 69.8; control2Y: 73.6; x: 69.8; y: 73.6 }
+ PathCubic { control1X: 65.4; control1Y: 73.2; control2X: 74; control2Y: 68.8; x: 74.2; y: 69 }
+ PathCubic { control1X: 74.4; control1Y: 69.2; control2X: 80; control2Y: 63.6; x: 72; y: 64.2 }
+ PathCubic { control1X: 50.203; control1Y: 65.835; control2X: 39.4; control2Y: 55.6; x: 39.4; y: 55.6 }
+ PathCubic { control1X: 37.4; control1Y: 54.2; control2X: 34.8; control2Y: 51.4; x: 34.8; y: 51.4 }
+ PathCubic { control1X: 24.8; control1Y: 49.4; control2X: 36.2; control2Y: 63.8; x: 36.2; y: 63.8 }
+ PathCubic { control1X: 37.4; control1Y: 65.2; control2X: 36; control2Y: 66.2; x: 36; y: 66.2 }
+ PathCubic { control1X: 35.2; control1Y: 64.6; control2X: 27.4; control2Y: 59.2; x: 27.4; y: 59.2 }
+ PathCubic { control1X: 24.589; control1Y: 58.227; control2X: 23.226; control2Y: 56.893; x: 20.895; y: 54.407 }
+ }
+
+ ShapePath {
+ fillColor: "#4c0000"
+ strokeWidth: -1
+ PathMove { x: -3; y: 42.8 }
+ PathCubic { control1X: -3; control1Y: 42.8; control2X: 8.6; control2Y: 48.4; x: 11.2; y: 51.2 }
+ PathCubic { control1X: 13.8; control1Y: 54; control2X: 27.8; control2Y: 65.4; x: 27.8; y: 65.4 }
+ PathCubic { control1X: 27.8; control1Y: 65.4; control2X: 22.4; control2Y: 63.4; x: 19.8; y: 61.6 }
+ PathCubic { control1X: 17.2; control1Y: 59.8; control2X: 6.4; control2Y: 51.6; x: 6.4; y: 51.6 }
+ PathCubic { control1X: 6.4; control1Y: 51.6; control2X: 2.6; control2Y: 45.6; x: -3; y: 42.8 }
+ }
+
+ ShapePath {
+ fillColor: "#99cc32"
+ strokeWidth: -1
+ PathMove { x: -61.009; y: 11.603 }
+ PathCubic { control1X: -60.672; control1Y: 11.455; control2X: -61.196; control2Y: 8.743; x: -61.4; y: 8.2 }
+ PathCubic { control1X: -62.422; control1Y: 5.474; control2X: -71.4; control2Y: 4; x: -71.4; y: 4 }
+ PathCubic { control1X: -71.627; control1Y: 5.365; control2X: -71.682; control2Y: 6.961; x: -71.576; y: 8.599 }
+ PathCubic { control1X: -71.576; control1Y: 8.599; control2X: -66.708; control2Y: 14.118; x: -61.009; y: 11.603 }
+ }
+
+ ShapePath {
+ fillColor: "#659900"
+ strokeWidth: -1
+ PathMove { x: -61.009; y: 11.403 }
+ PathCubic { control1X: -61.458; control1Y: 11.561; control2X: -61.024; control2Y: 8.669; x: -61.2; y: 8.2 }
+ PathCubic { control1X: -62.222; control1Y: 5.474; control2X: -71.4; control2Y: 3.9; x: -71.4; y: 3.9 }
+ PathCubic { control1X: -71.627; control1Y: 5.265; control2X: -71.682; control2Y: 6.861; x: -71.576; y: 8.499 }
+ PathCubic { control1X: -71.576; control1Y: 8.499; control2X: -67.308; control2Y: 13.618; x: -61.009; y: 11.403 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -65.4; y: 11.546 }
+ PathCubic { control1X: -66.025; control1Y: 11.546; control2X: -66.531; control2Y: 10.406; x: -66.531; y: 9 }
+ PathCubic { control1X: -66.531; control1Y: 7.595; control2X: -66.025; control2Y: 6.455; x: -65.4; y: 6.455 }
+ PathCubic { control1X: -64.775; control1Y: 6.455; control2X: -64.268; control2Y: 7.595; x: -64.268; y: 9 }
+ PathCubic { control1X: -64.268; control1Y: 10.406; control2X: -64.775; control2Y: 11.546; x: -65.4; y: 11.546 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -65.4; y: 9 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -111; y: 109.601 }
+ PathCubic { control1X: -111; control1Y: 109.601; control2X: -116.6; control2Y: 119.601; x: -91.8; y: 113.601 }
+ PathCubic { control1X: -91.8; control1Y: 113.601; control2X: -77.8; control2Y: 112.401; x: -75.4; y: 110.001 }
+ PathCubic { control1X: -74.2; control1Y: 110.801; control2X: -65.834; control2Y: 113.734; x: -63; y: 114.401 }
+ PathCubic { control1X: -56.2; control1Y: 116.001; control2X: -47.8; control2Y: 106; x: -47.8; y: 106 }
+ PathCubic { control1X: -47.8; control1Y: 106; control2X: -43.2; control2Y: 95.5; x: -40.4; y: 95.5 }
+ PathCubic { control1X: -37.6; control1Y: 95.5; control2X: -40.8; control2Y: 97.1; x: -40.8; y: 97.1 }
+ PathCubic { control1X: -40.8; control1Y: 97.1; control2X: -47.4; control2Y: 107.201; x: -47; y: 108.801 }
+ PathCubic { control1X: -47; control1Y: 108.801; control2X: -52.2; control2Y: 128.801; x: -68.2; y: 129.601 }
+ PathCubic { control1X: -68.2; control1Y: 129.601; control2X: -84.35; control2Y: 130.551; x: -83; y: 136.401 }
+ PathCubic { control1X: -83; control1Y: 136.401; control2X: -74.2; control2Y: 134.001; x: -71.8; y: 136.401 }
+ PathCubic { control1X: -71.8; control1Y: 136.401; control2X: -61; control2Y: 136.001; x: -69; y: 142.401 }
+ PathLine { x: -75.8; y: 154.001 }
+ PathCubic { control1X: -75.8; control1Y: 154.001; control2X: -75.66; control2Y: 157.919; x: -85.8; y: 154.401 }
+ PathCubic { control1X: -95.6; control1Y: 151.001; control2X: -105.9; control2Y: 138.101; x: -105.9; y: 138.101 }
+ PathCubic { control1X: -105.9; control1Y: 138.101; control2X: -121.85; control2Y: 123.551; x: -111; y: 109.601 }
+ }
+
+ ShapePath {
+ fillColor: "#e59999"
+ strokeWidth: -1
+ PathMove { x: -112.2; y: 113.601 }
+ PathCubic { control1X: -112.2; control1Y: 113.601; control2X: -114.2; control2Y: 123.201; x: -77.4; y: 112.801 }
+ PathCubic { control1X: -77.4; control1Y: 112.801; control2X: -73; control2Y: 112.801; x: -70.6; y: 113.601 }
+ PathCubic { control1X: -68.2; control1Y: 114.401; control2X: -56.2; control2Y: 117.201; x: -54.2; y: 116.001 }
+ PathCubic { control1X: -54.2; control1Y: 116.001; control2X: -61.4; control2Y: 129.601; x: -73; y: 128.001 }
+ PathCubic { control1X: -73; control1Y: 128.001; control2X: -86.2; control2Y: 129.601; x: -85.8; y: 134.401 }
+ PathCubic { control1X: -85.8; control1Y: 134.401; control2X: -81.8; control2Y: 141.601; x: -77; y: 144.001 }
+ PathCubic { control1X: -77; control1Y: 144.001; control2X: -74.2; control2Y: 146.401; x: -74.6; y: 149.601 }
+ PathCubic { control1X: -75; control1Y: 152.801; control2X: -77.8; control2Y: 154.401; x: -79.8; y: 155.201 }
+ PathCubic { control1X: -81.8; control1Y: 156.001; control2X: -85; control2Y: 152.801; x: -86.6; y: 152.801 }
+ PathCubic { control1X: -88.2; control1Y: 152.801; control2X: -96.6; control2Y: 146.401; x: -101; y: 141.601 }
+ PathCubic { control1X: -105.4; control1Y: 136.801; control2X: -113.8; control2Y: 124.801; x: -113.4; y: 122.001 }
+ PathCubic { control1X: -113; control1Y: 119.201; control2X: -112.2; control2Y: 113.601; x: -112.2; y: 113.601 }
+ }
+
+ ShapePath {
+ fillColor: "#b26565"
+ strokeWidth: -1
+ PathMove { x: -109; y: 131.051 }
+ PathCubic { control1X: -106.4; control1Y: 135.001; control2X: -103.2; control2Y: 139.201; x: -101; y: 141.601 }
+ PathCubic { control1X: -96.6; control1Y: 146.401; control2X: -88.2; control2Y: 152.801; x: -86.6; y: 152.801 }
+ PathCubic { control1X: -85; control1Y: 152.801; control2X: -81.8; control2Y: 156.001; x: -79.8; y: 155.201 }
+ PathCubic { control1X: -77.8; control1Y: 154.401; control2X: -75; control2Y: 152.801; x: -74.6; y: 149.601 }
+ PathCubic { control1X: -74.2; control1Y: 146.401; control2X: -77; control2Y: 144.001; x: -77; y: 144.001 }
+ PathCubic { control1X: -80.066; control1Y: 142.468; control2X: -82.806; control2Y: 138.976; x: -84.385; y: 136.653 }
+ PathCubic { control1X: -84.385; control1Y: 136.653; control2X: -84.2; control2Y: 139.201; x: -89.4; y: 138.401 }
+ PathCubic { control1X: -94.6; control1Y: 137.601; control2X: -99.8; control2Y: 134.801; x: -101.4; y: 131.601 }
+ PathCubic { control1X: -103; control1Y: 128.401; control2X: -105.4; control2Y: 126.001; x: -103.8; y: 129.601 }
+ PathCubic { control1X: -102.2; control1Y: 133.201; control2X: -99.8; control2Y: 136.801; x: -98.2; y: 137.201 }
+ PathCubic { control1X: -96.6; control1Y: 137.601; control2X: -97; control2Y: 138.801; x: -99.4; y: 138.401 }
+ PathCubic { control1X: -101.8; control1Y: 138.001; control2X: -104.6; control2Y: 137.601; x: -109; y: 132.401 }
+ }
+
+ ShapePath {
+ fillColor: "#992600"
+ strokeWidth: -1
+ PathMove { x: -111.6; y: 110.001 }
+ PathCubic { control1X: -111.6; control1Y: 110.001; control2X: -109.8; control2Y: 96.4; x: -108.6; y: 92.4 }
+ PathCubic { control1X: -108.6; control1Y: 92.4; control2X: -109.4; control2Y: 85.6; x: -107; y: 81.4 }
+ PathCubic { control1X: -104.6; control1Y: 77.2; control2X: -102.6; control2Y: 71; x: -99.6; y: 65.6 }
+ PathCubic { control1X: -96.6; control1Y: 60.2; control2X: -96.4; control2Y: 56.2; x: -92.4; y: 54.6 }
+ PathCubic { control1X: -88.4; control1Y: 53; control2X: -82.4; control2Y: 44.4; x: -79.6; y: 43.4 }
+ PathCubic { control1X: -76.8; control1Y: 42.4; control2X: -77; control2Y: 43.2; x: -77; y: 43.2 }
+ PathCubic { control1X: -77; control1Y: 43.2; control2X: -70.2; control2Y: 28.4; x: -56.6; y: 32.4 }
+ PathCubic { control1X: -56.6; control1Y: 32.4; control2X: -72.8; control2Y: 29.6; x: -57; y: 20.2 }
+ PathCubic { control1X: -57; control1Y: 20.2; control2X: -61.8; control2Y: 21.3; x: -58.5; y: 14.3 }
+ PathCubic { control1X: -56.299; control1Y: 9.632; control2X: -56.8; control2Y: 16.4; x: -67.8; y: 28.2 }
+ PathCubic { control1X: -67.8; control1Y: 28.2; control2X: -72.8; control2Y: 36.8; x: -78; y: 39.8 }
+ PathCubic { control1X: -83.2; control1Y: 42.8; control2X: -95.2; control2Y: 49.8; x: -96.4; y: 53.6 }
+ PathCubic { control1X: -97.6; control1Y: 57.4; control2X: -100.8; control2Y: 63.2; x: -102.8; y: 64.8 }
+ PathCubic { control1X: -104.8; control1Y: 66.4; control2X: -107.6; control2Y: 70.6; x: -108; y: 74 }
+ PathCubic { control1X: -108; control1Y: 74; control2X: -109.2; control2Y: 78; x: -110.6; y: 79.2 }
+ PathCubic { control1X: -112; control1Y: 80.4; control2X: -112.2; control2Y: 83.6; x: -112.2; y: 85.6 }
+ PathCubic { control1X: -112.2; control1Y: 87.6; control2X: -114.2; control2Y: 90.4; x: -114; y: 92.8 }
+ PathCubic { control1X: -114; control1Y: 92.8; control2X: -113.2; control2Y: 111.801; x: -113.6; y: 113.801 }
+ PathLine { x: -111.6; y: 110.001 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeWidth: -1
+ PathMove { x: -120.2; y: 114.601 }
+ PathCubic { control1X: -120.2; control1Y: 114.601; control2X: -122.2; control2Y: 113.201; x: -126.6; y: 119.201 }
+ PathCubic { control1X: -126.6; control1Y: 119.201; control2X: -119.3; control2Y: 152.201; x: -119.3; y: 153.601 }
+ PathCubic { control1X: -119.3; control1Y: 153.601; control2X: -118.2; control2Y: 151.501; x: -119.5; y: 144.301 }
+ PathCubic { control1X: -120.8; control1Y: 137.101; control2X: -121.7; control2Y: 124.401; x: -121.7; y: 124.401 }
+ PathLine { x: -120.2; y: 114.601 }
+ }
+
+ ShapePath {
+ fillColor: "#992600"
+ strokeWidth: -1
+ PathMove { x: -98.6; y: 54 }
+ PathCubic { control1X: -98.6; control1Y: 54; control2X: -116.2; control2Y: 57.2; x: -115.8; y: 86.4 }
+ PathLine { x: -116.6; y: 111.201 }
+ PathCubic { control1X: -116.6; control1Y: 111.201; control2X: -117.8; control2Y: 85.6; x: -119; y: 84 }
+ PathCubic { control1X: -120.2; control1Y: 82.4; control2X: -116.2; control2Y: 71.2; x: -119.4; y: 77.2 }
+ PathCubic { control1X: -119.4; control1Y: 77.2; control2X: -133.4; control2Y: 91.2; x: -125.4; y: 112.401 }
+ PathCubic { control1X: -125.4; control1Y: 112.401; control2X: -123.9; control2Y: 115.701; x: -126.9; y: 111.101 }
+ PathCubic { control1X: -126.9; control1Y: 111.101; control2X: -131.5; control2Y: 98.5; x: -130.4; y: 92.1 }
+ PathCubic { control1X: -130.4; control1Y: 92.1; control2X: -130.2; control2Y: 89.9; x: -128.3; y: 87.1 }
+ PathCubic { control1X: -128.3; control1Y: 87.1; control2X: -119.7; control2Y: 75.4; x: -117; y: 73.1 }
+ PathCubic { control1X: -117; control1Y: 73.1; control2X: -115.2; control2Y: 58.7; x: -99.8; y: 53.5 }
+ PathCubic { control1X: -99.8; control1Y: 53.5; control2X: -94.1; control2Y: 51.2; x: -98.6; y: 54 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 40.8; y: -12.2 }
+ PathCubic { control1X: 41.46; control1Y: -12.554; control2X: 41.451; control2Y: -13.524; x: 42.031; y: -13.697 }
+ PathCubic { control1X: 43.18; control1Y: -14.041; control2X: 43.344; control2Y: -15.108; x: 43.862; y: -15.892 }
+ PathCubic { control1X: 44.735; control1Y: -17.211; control2X: 44.928; control2Y: -18.744; x: 45.51; y: -20.235 }
+ PathCubic { control1X: 45.782; control1Y: -20.935; control2X: 45.809; control2Y: -21.89; x: 45.496; y: -22.55 }
+ PathCubic { control1X: 44.322; control1Y: -25.031; control2X: 43.62; control2Y: -27.48; x: 42.178; y: -29.906 }
+ PathCubic { control1X: 41.91; control1Y: -30.356; control2X: 41.648; control2Y: -31.15; x: 41.447; y: -31.748 }
+ PathCubic { control1X: 40.984; control1Y: -33.132; control2X: 39.727; control2Y: -34.123; x: 38.867; y: -35.443 }
+ PathCubic { control1X: 38.579; control1Y: -35.884; control2X: 39.104; control2Y: -36.809; x: 38.388; y: -36.893 }
+ PathCubic { control1X: 37.491; control1Y: -36.998; control2X: 36.042; control2Y: -37.578; x: 35.809; y: -36.552 }
+ PathCubic { control1X: 35.221; control1Y: -33.965; control2X: 36.232; control2Y: -31.442; x: 37.2; y: -29 }
+ PathCubic { control1X: 36.418; control1Y: -28.308; control2X: 36.752; control2Y: -27.387; x: 36.904; y: -26.62 }
+ PathCubic { control1X: 37.614; control1Y: -23.014; control2X: 36.416; control2Y: -19.662; x: 35.655; y: -16.188 }
+ PathCubic { control1X: 35.632; control1Y: -16.084; control2X: 35.974; control2Y: -15.886; x: 35.946; y: -15.824 }
+ PathCubic { control1X: 34.724; control1Y: -13.138; control2X: 33.272; control2Y: -10.693; x: 31.453; y: -8.312 }
+ PathCubic { control1X: 30.695; control1Y: -7.32; control2X: 29.823; control2Y: -6.404; x: 29.326; y: -5.341 }
+ PathCubic { control1X: 28.958; control1Y: -4.554; control2X: 28.55; control2Y: -3.588; x: 28.8; y: -2.6 }
+ PathCubic { control1X: 25.365; control1Y: 0.18; control2X: 23.115; control2Y: 4.025; x: 20.504; y: 7.871 }
+ PathCubic { control1X: 20.042; control1Y: 8.551; control2X: 20.333; control2Y: 9.76; x: 20.884; y: 10.029 }
+ PathCubic { control1X: 21.697; control1Y: 10.427; control2X: 22.653; control2Y: 9.403; x: 23.123; y: 8.557 }
+ PathCubic { control1X: 23.512; control1Y: 7.859; control2X: 23.865; control2Y: 7.209; x: 24.356; y: 6.566 }
+ PathCubic { control1X: 24.489; control1Y: 6.391; control2X: 24.31; control2Y: 5.972; x: 24.445; y: 5.851 }
+ PathCubic { control1X: 27.078; control1Y: 3.504; control2X: 28.747; control2Y: 0.568; x: 31.2; y: -1.8 }
+ PathCubic { control1X: 33.15; control1Y: -2.129; control2X: 34.687; control2Y: -3.127; x: 36.435; y: -4.14 }
+ PathCubic { control1X: 36.743; control1Y: -4.319; control2X: 37.267; control2Y: -4.07; x: 37.557; y: -4.265 }
+ PathCubic { control1X: 39.31; control1Y: -5.442; control2X: 39.308; control2Y: -7.478; x: 39.414; y: -9.388 }
+ PathCubic { control1X: 39.464; control1Y: -10.272; control2X: 39.66; control2Y: -11.589; x: 40.8; y: -12.2 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 31.959; y: -16.666 }
+ PathCubic { control1X: 32.083; control1Y: -16.743; control2X: 31.928; control2Y: -17.166; x: 32.037; y: -17.382 }
+ PathCubic { control1X: 32.199; control1Y: -17.706; control2X: 32.602; control2Y: -17.894; x: 32.764; y: -18.218 }
+ PathCubic { control1X: 32.873; control1Y: -18.434; control2X: 32.71; control2Y: -18.814; x: 32.846; y: -18.956 }
+ PathCubic { control1X: 35.179; control1Y: -21.403; control2X: 35.436; control2Y: -24.427; x: 34.4; y: -27.4 }
+ PathCubic { control1X: 35.424; control1Y: -28.02; control2X: 35.485; control2Y: -29.282; x: 35.06; y: -30.129 }
+ PathCubic { control1X: 34.207; control1Y: -31.829; control2X: 34.014; control2Y: -33.755; x: 33.039; y: -35.298 }
+ PathCubic { control1X: 32.237; control1Y: -36.567; control2X: 30.659; control2Y: -37.811; x: 29.288; y: -36.508 }
+ PathCubic { control1X: 28.867; control1Y: -36.108; control2X: 28.546; control2Y: -35.321; x: 28.824; y: -34.609 }
+ PathCubic { control1X: 28.888; control1Y: -34.446; control2X: 29.173; control2Y: -34.3; x: 29.146; y: -34.218 }
+ PathCubic { control1X: 29.039; control1Y: -33.894; control2X: 28.493; control2Y: -33.67; x: 28.487; y: -33.398 }
+ PathCubic { control1X: 28.457; control1Y: -31.902; control2X: 27.503; control2Y: -30.391; x: 28.133; y: -29.062 }
+ PathCubic { control1X: 28.905; control1Y: -27.433; control2X: 29.724; control2Y: -25.576; x: 30.4; y: -23.8 }
+ PathCubic { control1X: 29.166; control1Y: -21.684; control2X: 30.199; control2Y: -19.235; x: 28.446; y: -17.358 }
+ PathCubic { control1X: 28.31; control1Y: -17.212; control2X: 28.319; control2Y: -16.826; x: 28.441; y: -16.624 }
+ PathCubic { control1X: 28.733; control1Y: -16.138; control2X: 29.139; control2Y: -15.732; x: 29.625; y: -15.44 }
+ PathCubic { control1X: 29.827; control1Y: -15.319; control2X: 30.175; control2Y: -15.317; x: 30.375; y: -15.441 }
+ PathCubic { control1X: 30.953; control1Y: -15.803; control2X: 31.351; control2Y: -16.29; x: 31.959; y: -16.666 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 94.771; y: -26.977 }
+ PathCubic { control1X: 96.16; control1Y: -25.185; control2X: 96.45; control2Y: -22.39; x: 94.401; y: -21 }
+ PathCubic { control1X: 94.951; control1Y: -17.691; control2X: 98.302; control2Y: -19.67; x: 100.401; y: -20.2 }
+ PathCubic { control1X: 100.292; control1Y: -20.588; control2X: 100.519; control2Y: -20.932; x: 100.802; y: -20.937 }
+ PathCubic { control1X: 101.859; control1Y: -20.952; control2X: 102.539; control2Y: -21.984; x: 103.601; y: -21.8 }
+ PathCubic { control1X: 104.035; control1Y: -23.357; control2X: 105.673; control2Y: -24.059; x: 106.317; y: -25.439 }
+ PathCubic { control1X: 108.043; control1Y: -29.134; control2X: 107.452; control2Y: -33.407; x: 104.868; y: -36.653 }
+ PathCubic { control1X: 104.666; control1Y: -36.907; control2X: 104.883; control2Y: -37.424; x: 104.759; y: -37.786 }
+ PathCubic { control1X: 104.003; control1Y: -39.997; control2X: 101.935; control2Y: -40.312; x: 100.001; y: -41 }
+ PathCubic { control1X: 98.824; control1Y: -44.875; control2X: 98.163; control2Y: -48.906; x: 96.401; y: -52.6 }
+ PathCubic { control1X: 94.787; control1Y: -52.85; control2X: 94.089; control2Y: -54.589; x: 92.752; y: -55.309 }
+ PathCubic { control1X: 91.419; control1Y: -56.028; control2X: 90.851; control2Y: -54.449; x: 90.892; y: -53.403 }
+ PathCubic { control1X: 90.899; control1Y: -53.198; control2X: 91.351; control2Y: -52.974; x: 91.181; y: -52.609 }
+ PathCubic { control1X: 91.105; control1Y: -52.445; control2X: 90.845; control2Y: -52.334; x: 90.845; y: -52.2 }
+ PathCubic { control1X: 90.846; control1Y: -52.065; control2X: 91.067; control2Y: -51.934; x: 91.201; y: -51.8 }
+ PathCubic { control1X: 90.283; control1Y: -50.98; control2X: 88.86; control2Y: -50.503; x: 88.565; y: -49.358 }
+ PathCubic { control1X: 87.611; control1Y: -45.648; control2X: 90.184; control2Y: -42.523; x: 91.852; y: -39.322 }
+ PathCubic { control1X: 92.443; control1Y: -38.187; control2X: 91.707; control2Y: -36.916; x: 90.947; y: -35.708 }
+ PathCubic { control1X: 90.509; control1Y: -35.013; control2X: 90.617; control2Y: -33.886; x: 90.893; y: -33.03 }
+ PathCubic { control1X: 91.645; control1Y: -30.699; control2X: 93.236; control2Y: -28.96; x: 94.771; y: -26.977 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 57.611; y: -8.591 }
+ PathCubic { control1X: 56.124; control1Y: -6.74; control2X: 52.712; control2Y: -4.171; x: 55.629; y: -2.243 }
+ PathCubic { control1X: 55.823; control1Y: -2.114; control2X: 56.193; control2Y: -2.11; x: 56.366; y: -2.244 }
+ PathCubic { control1X: 58.387; control1Y: -3.809; control2X: 60.39; control2Y: -4.712; x: 62.826; y: -5.294 }
+ PathCubic { control1X: 62.95; control1Y: -5.323; control2X: 63.224; control2Y: -4.856; x: 63.593; y: -5.017 }
+ PathCubic { control1X: 65.206; control1Y: -5.72; control2X: 67.216; control2Y: -5.662; x: 68.4; y: -7 }
+ PathCubic { control1X: 72.167; control1Y: -6.776; control2X: 75.732; control2Y: -7.892; x: 79.123; y: -9.2 }
+ PathCubic { control1X: 80.284; control1Y: -9.648; control2X: 81.554; control2Y: -10.207; x: 82.755; y: -10.709 }
+ PathCubic { control1X: 84.131; control1Y: -11.285; control2X: 85.335; control2Y: -12.213; x: 86.447; y: -13.354 }
+ PathCubic { control1X: 86.58; control1Y: -13.49; control2X: 86.934; control2Y: -13.4; x: 87.201; y: -13.4 }
+ PathCubic { control1X: 87.161; control1Y: -14.263; control2X: 88.123; control2Y: -14.39; x: 88.37; y: -15.012 }
+ PathCubic { control1X: 88.462; control1Y: -15.244; control2X: 88.312; control2Y: -15.64; x: 88.445; y: -15.742 }
+ PathCubic { control1X: 90.583; control1Y: -17.372; control2X: 91.503; control2Y: -19.39; x: 90.334; y: -21.767 }
+ PathCubic { control1X: 90.049; control1Y: -22.345; control2X: 89.8; control2Y: -22.963; x: 89.234; y: -23.439 }
+ PathCubic { control1X: 88.149; control1Y: -24.35; control2X: 87.047; control2Y: -23.496; x: 86; y: -23.8 }
+ PathCubic { control1X: 85.841; control1Y: -23.172; control2X: 85.112; control2Y: -23.344; x: 84.726; y: -23.146 }
+ PathCubic { control1X: 83.867; control1Y: -22.707; control2X: 82.534; control2Y: -23.292; x: 81.675; y: -22.854 }
+ PathCubic { control1X: 80.313; control1Y: -22.159; control2X: 79.072; control2Y: -21.99; x: 77.65; y: -21.613 }
+ PathCubic { control1X: 77.338; control1Y: -21.531; control2X: 76.56; control2Y: -21.627; x: 76.4; y: -21 }
+ PathCubic { control1X: 76.266; control1Y: -21.134; control2X: 76.118; control2Y: -21.368; x: 76.012; y: -21.346 }
+ PathCubic { control1X: 74.104; control1Y: -20.95; control2X: 72.844; control2Y: -20.736; x: 71.543; y: -19.044 }
+ PathCubic { control1X: 71.44; control1Y: -18.911; control2X: 70.998; control2Y: -19.09; x: 70.839; y: -18.955 }
+ PathCubic { control1X: 69.882; control1Y: -18.147; control2X: 69.477; control2Y: -16.913; x: 68.376; y: -16.241 }
+ PathCubic { control1X: 68.175; control1Y: -16.118; control2X: 67.823; control2Y: -16.286; x: 67.629; y: -16.157 }
+ PathCubic { control1X: 66.983; control1Y: -15.726; control2X: 66.616; control2Y: -15.085; x: 65.974; y: -14.638 }
+ PathCubic { control1X: 65.645; control1Y: -14.409; control2X: 65.245; control2Y: -14.734; x: 65.277; y: -14.99 }
+ PathCubic { control1X: 65.522; control1Y: -16.937; control2X: 66.175; control2Y: -18.724; x: 65.6; y: -20.6 }
+ PathCubic { control1X: 67.677; control1Y: -23.12; control2X: 70.194; control2Y: -25.069; x: 72; y: -27.8 }
+ PathCubic { control1X: 72.015; control1Y: -29.966; control2X: 72.707; control2Y: -32.112; x: 72.594; y: -34.189 }
+ PathCubic { control1X: 72.584; control1Y: -34.382; control2X: 72.296; control2Y: -35.115; x: 72.17; y: -35.462 }
+ PathCubic { control1X: 71.858; control1Y: -36.316; control2X: 72.764; control2Y: -37.382; x: 71.92; y: -38.106 }
+ PathCubic { control1X: 70.516; control1Y: -39.309; control2X: 69.224; control2Y: -38.433; x: 68.4; y: -37 }
+ PathCubic { control1X: 66.562; control1Y: -36.61; control2X: 64.496; control2Y: -35.917; x: 62.918; y: -37.151 }
+ PathCubic { control1X: 61.911; control1Y: -37.938; control2X: 61.333; control2Y: -38.844; x: 60.534; y: -39.9 }
+ PathCubic { control1X: 59.549; control1Y: -41.202; control2X: 59.884; control2Y: -42.638; x: 59.954; y: -44.202 }
+ PathCubic { control1X: 59.96; control1Y: -44.33; control2X: 59.645; control2Y: -44.466; x: 59.645; y: -44.6 }
+ PathCubic { control1X: 59.646; control1Y: -44.735; control2X: 59.866; control2Y: -44.866; x: 60; y: -45 }
+ PathCubic { control1X: 59.294; control1Y: -45.626; control2X: 59.019; control2Y: -46.684; x: 58; y: -47 }
+ PathCubic { control1X: 58.305; control1Y: -48.092; control2X: 57.629; control2Y: -48.976; x: 56.758; y: -49.278 }
+ PathCubic { control1X: 54.763; control1Y: -49.969; control2X: 53.086; control2Y: -48.057; x: 51.194; y: -47.984 }
+ PathCubic { control1X: 50.68; control1Y: -47.965; control2X: 50.213; control2Y: -49.003; x: 49.564; y: -49.328 }
+ PathCubic { control1X: 49.132; control1Y: -49.544; control2X: 48.428; control2Y: -49.577; x: 48.066; y: -49.311 }
+ PathCubic { control1X: 47.378; control1Y: -48.807; control2X: 46.789; control2Y: -48.693; x: 46.031; y: -48.488 }
+ PathCubic { control1X: 44.414; control1Y: -48.052; control2X: 43.136; control2Y: -46.958; x: 41.656; y: -46.103 }
+ PathCubic { control1X: 40.171; control1Y: -45.246; control2X: 39.216; control2Y: -43.809; x: 38.136; y: -42.489 }
+ PathCubic { control1X: 37.195; control1Y: -41.337; control2X: 37.059; control2Y: -38.923; x: 38.479; y: -38.423 }
+ PathCubic { control1X: 40.322; control1Y: -37.773; control2X: 41.626; control2Y: -40.476; x: 43.592; y: -40.15 }
+ PathCubic { control1X: 43.904; control1Y: -40.099; control2X: 44.11; control2Y: -39.788; x: 44; y: -39.4 }
+ PathCubic { control1X: 44.389; control1Y: -39.291; control2X: 44.607; control2Y: -39.52; x: 44.8; y: -39.8 }
+ PathCubic { control1X: 45.658; control1Y: -38.781; control2X: 46.822; control2Y: -38.444; x: 47.76; y: -37.571 }
+ PathCubic { control1X: 48.73; control1Y: -36.667; control2X: 50.476; control2Y: -37.085; x: 51.491; y: -36.088 }
+ PathCubic { control1X: 53.02; control1Y: -34.586; control2X: 52.461; control2Y: -31.905; x: 54.4; y: -30.6 }
+ PathCubic { control1X: 53.814; control1Y: -29.287; control2X: 53.207; control2Y: -28.01; x: 52.872; y: -26.583 }
+ PathCubic { control1X: 52.59; control1Y: -25.377; control2X: 53.584; control2Y: -24.18; x: 54.795; y: -24.271 }
+ PathCubic { control1X: 56.053; control1Y: -24.365; control2X: 56.315; control2Y: -25.124; x: 56.8; y: -26.2 }
+ PathCubic { control1X: 57.067; control1Y: -25.933; control2X: 57.536; control2Y: -25.636; x: 57.495; y: -25.42 }
+ PathCubic { control1X: 57.038; control1Y: -23.033; control2X: 56.011; control2Y: -21.04; x: 55.553; y: -18.609 }
+ PathCubic { control1X: 55.494; control1Y: -18.292; control2X: 55.189; control2Y: -18.09; x: 54.8; y: -18.2 }
+ PathCubic { control1X: 54.332; control1Y: -14.051; control2X: 50.28; control2Y: -11.657; x: 47.735; y: -8.492 }
+ PathCubic { control1X: 47.332; control1Y: -7.99; control2X: 47.328; control2Y: -6.741; x: 47.737; y: -6.338 }
+ PathCubic { control1X: 49.14; control1Y: -4.951; control2X: 51.1; control2Y: -6.497; x: 52.8; y: -7 }
+ PathCubic { control1X: 53.013; control1Y: -8.206; control2X: 53.872; control2Y: -9.148; x: 55.204; y: -9.092 }
+ PathCubic { control1X: 55.46; control1Y: -9.082; control2X: 55.695; control2Y: -9.624; x: 56.019; y: -9.754 }
+ PathCubic { control1X: 56.367; control1Y: -9.892; control2X: 56.869; control2Y: -9.668; x: 57.155; y: -9.866 }
+ PathCubic { control1X: 58.884; control1Y: -11.061; control2X: 60.292; control2Y: -12.167; x: 62.03; y: -13.356 }
+ PathCubic { control1X: 62.222; control1Y: -13.487; control2X: 62.566; control2Y: -13.328; x: 62.782; y: -13.436 }
+ PathCubic { control1X: 63.107; control1Y: -13.598; control2X: 63.294; control2Y: -13.985; x: 63.617; y: -14.17 }
+ PathCubic { control1X: 63.965; control1Y: -14.37; control2X: 64.207; control2Y: -14.08; x: 64.4; y: -13.8 }
+ PathCubic { control1X: 63.754; control1Y: -13.451; control2X: 63.75; control2Y: -12.494; x: 63.168; y: -12.292 }
+ PathCubic { control1X: 62.393; control1Y: -12.024; control2X: 61.832; control2Y: -11.511; x: 61.158; y: -11.064 }
+ PathCubic { control1X: 60.866; control1Y: -10.871; control2X: 60.207; control2Y: -11.119; x: 60.103; y: -10.94 }
+ PathCubic { control1X: 59.505; control1Y: -9.912; control2X: 58.321; control2Y: -9.474; x: 57.611; y: -8.591 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 2.2; y: -58 }
+ PathCubic { control1X: 2.2; control1Y: -58; control2X: -7.038; control2Y: -60.872; x: -18.2; y: -35.2 }
+ PathCubic { control1X: -18.2; control1Y: -35.2; control2X: -20.6; control2Y: -30; x: -23; y: -28 }
+ PathCubic { control1X: -25.4; control1Y: -26; control2X: -36.6; control2Y: -22.4; x: -38.6; y: -18.4 }
+ PathLine { x: -49; y: -2.4 }
+ PathCubic { control1X: -49; control1Y: -2.4; control2X: -34.2; control2Y: -18.4; x: -31; y: -20.8 }
+ PathCubic { control1X: -31; control1Y: -20.8; control2X: -23; control2Y: -29.2; x: -26.2; y: -22.4 }
+ PathCubic { control1X: -26.2; control1Y: -22.4; control2X: -40.2; control2Y: -11.6; x: -39; y: -2.4 }
+ PathCubic { control1X: -39; control1Y: -2.4; control2X: -44.6; control2Y: 12; x: -45.4; y: 14 }
+ PathCubic { control1X: -45.4; control1Y: 14; control2X: -29.4; control2Y: -18; x: -27; y: -19.2 }
+ PathCubic { control1X: -24.6; control1Y: -20.4; control2X: -23.4; control2Y: -20.4; x: -24.6; y: -16.8 }
+ PathCubic { control1X: -25.8; control1Y: -13.2; control2X: -26.2; control2Y: 3.2; x: -29; y: 5.2 }
+ PathCubic { control1X: -29; control1Y: 5.2; control2X: -21; control2Y: -15.2; x: -21.8; y: -18.4 }
+ PathCubic { control1X: -21.8; control1Y: -18.4; control2X: -18.6; control2Y: -22; x: -16.2; y: -16.8 }
+ PathLine { x: -17.4; y: -0.8 }
+ PathLine { x: -13; y: 11.2 }
+ PathCubic { control1X: -13; control1Y: 11.2; control2X: -15.4; control2Y: 0; x: -13.8; y: -15.6 }
+ PathCubic { control1X: -13.8; control1Y: -15.6; control2X: -15.8; control2Y: -26; x: -11.8; y: -20.4 }
+ PathCubic { control1X: -7.8; control1Y: -14.8; control2X: 1.8; control2Y: -8.8; x: 1.8; y: -4 }
+ PathCubic { control1X: 1.8; control1Y: -4; control2X: -3.4; control2Y: -21.6; x: -12.6; y: -26.4 }
+ PathLine { x: -16.6; y: -20.4 }
+ PathLine { x: -17.8; y: -22.4 }
+ PathCubic { control1X: -17.8; control1Y: -22.4; control2X: -21.4; control2Y: -23.2; x: -17; y: -30 }
+ PathCubic { control1X: -12.6; control1Y: -36.8; control2X: -13; control2Y: -37.6; x: -13; y: -37.6 }
+ PathCubic { control1X: -13; control1Y: -37.6; control2X: -6.6; control2Y: -30.4; x: -5; y: -30.4 }
+ PathCubic { control1X: -5; control1Y: -30.4; control2X: 8.2; control2Y: -38; x: 9.4; y: -13.6 }
+ PathCubic { control1X: 9.4; control1Y: -13.6; control2X: 16.2; control2Y: -28; x: 7; y: -34.8 }
+ PathCubic { control1X: 7; control1Y: -34.8; control2X: -7.8; control2Y: -36.8; x: -6.6; y: -42 }
+ PathLine { x: 0.6; y: -54.4 }
+ PathCubic { control1X: 4.2; control1Y: -59.6; control2X: 2.6; control2Y: -56.8; x: 2.6; y: -56.8 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -17.8; y: -41.6 }
+ PathCubic { control1X: -17.8; control1Y: -41.6; control2X: -30.6; control2Y: -41.6; x: -33.8; y: -36.4 }
+ PathLine { x: -41; y: -26.8 }
+ PathCubic { control1X: -41; control1Y: -26.8; control2X: -23.8; control2Y: -36.8; x: -19.8; y: -38 }
+ PathCubic { control1X: -15.8; control1Y: -39.2; control2X: -17.8; control2Y: -41.6; x: -17.8; y: -41.6 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -57.8; y: -35.2 }
+ PathCubic { control1X: -57.8; control1Y: -35.2; control2X: -59.8; control2Y: -34; x: -60.2; y: -31.2 }
+ PathCubic { control1X: -60.6; control1Y: -28.4; control2X: -63; control2Y: -28; x: -62.2; y: -25.2 }
+ PathCubic { control1X: -61.4; control1Y: -22.4; control2X: -59.4; control2Y: -20; x: -59.4; y: -24 }
+ PathCubic { control1X: -59.4; control1Y: -28; control2X: -57.8; control2Y: -30; x: -57; y: -31.2 }
+ PathCubic { control1X: -56.2; control1Y: -32.4; control2X: -54.6; control2Y: -36.8; x: -57.8; y: -35.2 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -66.6; y: 26 }
+ PathCubic { control1X: -66.6; control1Y: 26; control2X: -75; control2Y: 22; x: -78.2; y: 18.4 }
+ PathCubic { control1X: -81.4; control1Y: 14.8; control2X: -80.948; control2Y: 19.966; x: -85.8; y: 19.6 }
+ PathCubic { control1X: -91.647; control1Y: 19.159; control2X: -90.6; control2Y: 3.2; x: -90.6; y: 3.2 }
+ PathLine { x: -94.6; y: 10.8 }
+ PathCubic { control1X: -94.6; control1Y: 10.8; control2X: -95.8; control2Y: 25.2; x: -87.8; y: 22.8 }
+ PathCubic { control1X: -83.893; control1Y: 21.628; control2X: -82.6; control2Y: 23.2; x: -84.2; y: 24 }
+ PathCubic { control1X: -85.8; control1Y: 24.8; control2X: -78.6; control2Y: 25.2; x: -81.4; y: 26.8 }
+ PathCubic { control1X: -84.2; control1Y: 28.4; control2X: -69.8; control2Y: 23.2; x: -72.2; y: 33.6 }
+ PathLine { x: -66.6; y: 26 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -79.2; y: 40.4 }
+ PathCubic { control1X: -79.2; control1Y: 40.4; control2X: -94.6; control2Y: 44.8; x: -98.2; y: 35.2 }
+ PathCubic { control1X: -98.2; control1Y: 35.2; control2X: -103; control2Y: 37.6; x: -100.8; y: 40.6 }
+ PathCubic { control1X: -98.6; control1Y: 43.6; control2X: -97.4; control2Y: 44; x: -97.4; y: 44 }
+ PathCubic { control1X: -97.4; control1Y: 44; control2X: -92; control2Y: 45.2; x: -92.6; y: 46 }
+ PathCubic { control1X: -93.2; control1Y: 46.8; control2X: -95.6; control2Y: 50.2; x: -95.6; y: 50.2 }
+ PathCubic { control1X: -95.6; control1Y: 50.2; control2X: -85.4; control2Y: 44.2; x: -79.2; y: 40.4 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeWidth: -1
+ PathMove { x: 149.201; y: 118.601 }
+ PathCubic { control1X: 148.774; control1Y: 120.735; control2X: 147.103; control2Y: 121.536; x: 145.201; y: 122.201 }
+ PathCubic { control1X: 143.284; control1Y: 121.243; control2X: 140.686; control2Y: 118.137; x: 138.801; y: 120.201 }
+ PathCubic { control1X: 138.327; control1Y: 119.721; control2X: 137.548; control2Y: 119.661; x: 137.204; y: 118.999 }
+ PathCubic { control1X: 136.739; control1Y: 118.101; control2X: 137.011; control2Y: 117.055; x: 136.669; y: 116.257 }
+ PathCubic { control1X: 136.124; control1Y: 114.985; control2X: 135.415; control2Y: 113.619; x: 135.601; y: 112.201 }
+ PathCubic { control1X: 137.407; control1Y: 111.489; control2X: 138.002; control2Y: 109.583; x: 137.528; y: 107.82 }
+ PathCubic { control1X: 137.459; control1Y: 107.563; control2X: 137.03; control2Y: 107.366; x: 137.23; y: 107.017 }
+ PathCubic { control1X: 137.416; control1Y: 106.694; control2X: 137.734; control2Y: 106.467; x: 138.001; y: 106.2 }
+ PathCubic { control1X: 137.866; control1Y: 106.335; control2X: 137.721; control2Y: 106.568; x: 137.61; y: 106.548 }
+ PathCubic { control1X: 137; control1Y: 106.442; control2X: 137.124; control2Y: 105.805; x: 137.254; y: 105.418 }
+ PathCubic { control1X: 137.839; control1Y: 103.672; control2X: 139.853; control2Y: 103.408; x: 141.201; y: 104.6 }
+ PathCubic { control1X: 141.457; control1Y: 104.035; control2X: 141.966; control2Y: 104.229; x: 142.401; y: 104.2 }
+ PathCubic { control1X: 142.351; control1Y: 103.621; control2X: 142.759; control2Y: 103.094; x: 142.957; y: 102.674 }
+ PathCubic { control1X: 143.475; control1Y: 101.576; control2X: 145.104; control2Y: 102.682; x: 145.901; y: 102.07 }
+ PathCubic { control1X: 146.977; control1Y: 101.245; control2X: 148.04; control2Y: 100.546; x: 149.118; y: 101.149 }
+ PathCubic { control1X: 150.927; control1Y: 102.162; control2X: 152.636; control2Y: 103.374; x: 153.835; y: 105.115 }
+ PathCubic { control1X: 154.41; control1Y: 105.949; control2X: 154.65; control2Y: 107.23; x: 154.592; y: 108.188 }
+ PathCubic { control1X: 154.554; control1Y: 108.835; control2X: 153.173; control2Y: 108.483; x: 152.83; y: 109.412 }
+ PathCubic { control1X: 152.185; control1Y: 111.16; control2X: 154.016; control2Y: 111.679; x: 154.772; y: 113.017 }
+ PathCubic { control1X: 154.97; control1Y: 113.366; control2X: 154.706; control2Y: 113.67; x: 154.391; y: 113.768 }
+ PathCubic { control1X: 153.98; control1Y: 113.896; control2X: 153.196; control2Y: 113.707; x: 153.334; y: 114.16 }
+ PathCubic { control1X: 154.306; control1Y: 117.353; control2X: 151.55; control2Y: 118.031; x: 149.201; y: 118.601 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeWidth: -1
+ PathMove { x: 139.6; y: 138.201 }
+ PathCubic { control1X: 139.593; control1Y: 136.463; control2X: 137.992; control2Y: 134.707; x: 139.201; y: 133.001 }
+ PathCubic { control1X: 139.336; control1Y: 133.135; control2X: 139.467; control2Y: 133.356; x: 139.601; y: 133.356 }
+ PathCubic { control1X: 139.736; control1Y: 133.356; control2X: 139.867; control2Y: 133.135; x: 140.001; y: 133.001 }
+ PathCubic { control1X: 141.496; control1Y: 135.217; control2X: 145.148; control2Y: 136.145; x: 145.006; y: 138.991 }
+ PathCubic { control1X: 144.984; control1Y: 139.438; control2X: 143.897; control2Y: 140.356; x: 144.801; y: 141.001 }
+ PathCubic { control1X: 142.988; control1Y: 142.349; control2X: 142.933; control2Y: 144.719; x: 142.001; y: 146.601 }
+ PathCubic { control1X: 140.763; control1Y: 146.315; control2X: 139.551; control2Y: 145.952; x: 138.401; y: 145.401 }
+ PathCubic { control1X: 138.753; control1Y: 143.915; control2X: 138.636; control2Y: 142.231; x: 139.456; y: 140.911 }
+ PathCubic { control1X: 139.89; control1Y: 140.213; control2X: 139.603; control2Y: 139.134; x: 139.6; y: 138.201 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: -26.6; y: 129.201 }
+ PathCubic { control1X: -26.6; control1Y: 129.201; control2X: -43.458; control2Y: 139.337; x: -29.4; y: 124.001 }
+ PathCubic { control1X: -20.6; control1Y: 114.401; control2X: -10.6; control2Y: 108.801; x: -10.6; y: 108.801 }
+ PathCubic { control1X: -10.6; control1Y: 108.801; control2X: -0.2; control2Y: 104.4; x: 3.4; y: 103.2 }
+ PathCubic { control1X: 7; control1Y: 102; control2X: 22.2; control2Y: 96.8; x: 25.4; y: 96.4 }
+ PathCubic { control1X: 28.6; control1Y: 96; control2X: 38.2; control2Y: 92; x: 45; y: 96 }
+ PathCubic { control1X: 51.8; control1Y: 100; control2X: 59.8; control2Y: 104.4; x: 59.8; y: 104.4 }
+ PathCubic { control1X: 59.8; control1Y: 104.4; control2X: 43.4; control2Y: 96; x: 39.8; y: 98.4 }
+ PathCubic { control1X: 36.2; control1Y: 100.8; control2X: 29; control2Y: 100.4; x: 23; y: 103.6 }
+ PathCubic { control1X: 23; control1Y: 103.6; control2X: 8.2; control2Y: 108.001; x: 5; y: 110.001 }
+ PathCubic { control1X: 1.8; control1Y: 112.001; control2X: -8.6; control2Y: 123.601; x: -10.2; y: 122.801 }
+ PathCubic { control1X: -11.8; control1Y: 122.001; control2X: -9.8; control2Y: 121.601; x: -8.6; y: 118.801 }
+ PathCubic { control1X: -7.4; control1Y: 116.001; control2X: -9.4; control2Y: 114.401; x: -17.4; y: 120.801 }
+ PathCubic { control1X: -25.4; control1Y: 127.201; control2X: -26.6; control2Y: 129.201; x: -26.6; y: 129.201 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -19.195; y: 123.234 }
+ PathCubic { control1X: -19.195; control1Y: 123.234; control2X: -17.785; control2Y: 110.194; x: -9.307; y: 111.859 }
+ PathCubic { control1X: -9.307; control1Y: 111.859; control2X: -1.081; control2Y: 107.689; x: 1.641; y: 105.721 }
+ PathCubic { control1X: 1.641; control1Y: 105.721; control2X: 9.78; control2Y: 104.019; x: 11.09; y: 103.402 }
+ PathCubic { control1X: 29.569; control1Y: 94.702; control2X: 44.288; control2Y: 99.221; x: 44.835; y: 98.101 }
+ PathCubic { control1X: 45.381; control1Y: 96.982; control2X: 65.006; control2Y: 104.099; x: 68.615; y: 108.185 }
+ PathCubic { control1X: 69.006; control1Y: 108.628; control2X: 58.384; control2Y: 102.588; x: 48.686; y: 100.697 }
+ PathCubic { control1X: 40.413; control1Y: 99.083; control2X: 18.811; control2Y: 100.944; x: 7.905; y: 106.48 }
+ PathCubic { control1X: 4.932; control1Y: 107.989; control2X: -4.013; control2Y: 113.773; x: -6.544; y: 113.662 }
+ PathCubic { control1X: -9.075; control1Y: 113.55; control2X: -19.195; control2Y: 123.234; x: -19.195; y: 123.234 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: -23; y: 148.801 }
+ PathCubic { control1X: -23; control1Y: 148.801; control2X: -38.2; control2Y: 146.401; x: -21.4; y: 144.801 }
+ PathCubic { control1X: -21.4; control1Y: 144.801; control2X: -3.4; control2Y: 142.801; x: 0.6; y: 137.601 }
+ PathCubic { control1X: 0.6; control1Y: 137.601; control2X: 14.2; control2Y: 128.401; x: 17; y: 128.001 }
+ PathCubic { control1X: 19.8; control1Y: 127.601; control2X: 49.8; control2Y: 120.401; x: 50.2; y: 118.001 }
+ PathCubic { control1X: 50.6; control1Y: 115.601; control2X: 56.2; control2Y: 115.601; x: 57.8; y: 116.401 }
+ PathCubic { control1X: 59.4; control1Y: 117.201; control2X: 58.6; control2Y: 118.401; x: 55.8; y: 119.201 }
+ PathCubic { control1X: 53; control1Y: 120.001; control2X: 21.8; control2Y: 136.401; x: 15.4; y: 137.601 }
+ PathCubic { control1X: 9; control1Y: 138.801; control2X: -2.6; control2Y: 146.401; x: -7.4; y: 147.601 }
+ PathCubic { control1X: -12.2; control1Y: 148.801; control2X: -23; control2Y: 148.801; x: -23; y: 148.801 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -3.48; y: 141.403 }
+ PathCubic { control1X: -3.48; control1Y: 141.403; control2X: -12.062; control2Y: 140.574; x: -3.461; y: 139.755 }
+ PathCubic { control1X: -3.461; control1Y: 139.755; control2X: 5.355; control2Y: 136.331; x: 7.403; y: 133.668 }
+ PathCubic { control1X: 7.403; control1Y: 133.668; control2X: 14.367; control2Y: 128.957; x: 15.8; y: 128.753 }
+ PathCubic { control1X: 17.234; control1Y: 128.548; control2X: 31.194; control2Y: 124.861; x: 31.399; y: 123.633 }
+ PathCubic { control1X: 31.604; control1Y: 122.404; control2X: 65.67; control2Y: 109.823; x: 70.09; y: 113.013 }
+ PathCubic { control1X: 73.001; control1Y: 115.114; control2X: 63.1; control2Y: 113.437; x: 53.466; y: 117.847 }
+ PathCubic { control1X: 52.111; control1Y: 118.467; control2X: 18.258; control2Y: 133.054; x: 14.981; y: 133.668 }
+ PathCubic { control1X: 11.704; control1Y: 134.283; control2X: 5.765; control2Y: 138.174; x: 3.307; y: 138.788 }
+ PathCubic { control1X: 0.85; control1Y: 139.403; control2X: -3.48; control2Y: 141.403; x: -3.48; y: 141.403 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -11.4; y: 143.601 }
+ PathCubic { control1X: -11.4; control1Y: 143.601; control2X: -6.2; control2Y: 143.201; x: -7.4; y: 144.801 }
+ PathCubic { control1X: -8.6; control1Y: 146.401; control2X: -11; control2Y: 145.601; x: -11; y: 145.601 }
+ PathLine { x: -11.4; y: 143.601 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -18.6; y: 145.201 }
+ PathCubic { control1X: -18.6; control1Y: 145.201; control2X: -13.4; control2Y: 144.801; x: -14.6; y: 146.401 }
+ PathCubic { control1X: -15.8; control1Y: 148.001; control2X: -18.2; control2Y: 147.201; x: -18.2; y: 147.201 }
+ PathLine { x: -18.6; y: 145.201 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -29; y: 146.801 }
+ PathCubic { control1X: -29; control1Y: 146.801; control2X: -23.8; control2Y: 146.401; x: -25; y: 148.001 }
+ PathCubic { control1X: -26.2; control1Y: 149.601; control2X: -28.6; control2Y: 148.801; x: -28.6; y: 148.801 }
+ PathLine { x: -29; y: 146.801 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -36.6; y: 147.601 }
+ PathCubic { control1X: -36.6; control1Y: 147.601; control2X: -31.4; control2Y: 147.201; x: -32.6; y: 148.801 }
+ PathCubic { control1X: -33.8; control1Y: 150.401; control2X: -36.2; control2Y: 149.601; x: -36.2; y: 149.601 }
+ PathLine { x: -36.6; y: 147.601 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 1.8; y: 108.001 }
+ PathCubic { control1X: 1.8; control1Y: 108.001; control2X: 6.2; control2Y: 108.001; x: 5; y: 109.601 }
+ PathCubic { control1X: 3.8; control1Y: 111.201; control2X: 0.6; control2Y: 110.801; x: 0.6; y: 110.801 }
+ PathLine { x: 1.8; y: 108.001 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -8.2; y: 113.601 }
+ PathCubic { control1X: -8.2; control1Y: 113.601; control2X: -1.694; control2Y: 111.46; x: -4.2; y: 114.801 }
+ PathCubic { control1X: -5.4; control1Y: 116.401; control2X: -7.8; control2Y: 115.601; x: -7.8; y: 115.601 }
+ PathLine { x: -8.2; y: 113.601 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -19.4; y: 118.401 }
+ PathCubic { control1X: -19.4; control1Y: 118.401; control2X: -14.2; control2Y: 118.001; x: -15.4; y: 119.601 }
+ PathCubic { control1X: -16.6; control1Y: 121.201; control2X: -19; control2Y: 120.401; x: -19; y: 120.401 }
+ PathLine { x: -19.4; y: 118.401 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -27; y: 124.401 }
+ PathCubic { control1X: -27; control1Y: 124.401; control2X: -21.8; control2Y: 124.001; x: -23; y: 125.601 }
+ PathCubic { control1X: -24.2; control1Y: 127.201; control2X: -26.6; control2Y: 126.401; x: -26.6; y: 126.401 }
+ PathLine { x: -27; y: 124.401 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -33.8; y: 129.201 }
+ PathCubic { control1X: -33.8; control1Y: 129.201; control2X: -28.6; control2Y: 128.801; x: -29.8; y: 130.401 }
+ PathCubic { control1X: -31; control1Y: 132.001; control2X: -33.4; control2Y: 131.201; x: -33.4; y: 131.201 }
+ PathLine { x: -33.8; y: 129.201 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 5.282; y: 135.598 }
+ PathCubic { control1X: 5.282; control1Y: 135.598; control2X: 12.203; control2Y: 135.066; x: 10.606; y: 137.195 }
+ PathCubic { control1X: 9.009; control1Y: 139.325; control2X: 5.814; control2Y: 138.26; x: 5.814; y: 138.26 }
+ PathLine { x: 5.282; y: 135.598 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 15.682; y: 130.798 }
+ PathCubic { control1X: 15.682; control1Y: 130.798; control2X: 22.603; control2Y: 130.266; x: 21.006; y: 132.395 }
+ PathCubic { control1X: 19.409; control1Y: 134.525; control2X: 16.214; control2Y: 133.46; x: 16.214; y: 133.46 }
+ PathLine { x: 15.682; y: 130.798 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 26.482; y: 126.398 }
+ PathCubic { control1X: 26.482; control1Y: 126.398; control2X: 33.403; control2Y: 125.866; x: 31.806; y: 127.995 }
+ PathCubic { control1X: 30.209; control1Y: 130.125; control2X: 27.014; control2Y: 129.06; x: 27.014; y: 129.06 }
+ PathLine { x: 26.482; y: 126.398 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 36.882; y: 121.598 }
+ PathCubic { control1X: 36.882; control1Y: 121.598; control2X: 43.803; control2Y: 121.066; x: 42.206; y: 123.195 }
+ PathCubic { control1X: 40.609; control1Y: 125.325; control2X: 37.414; control2Y: 124.26; x: 37.414; y: 124.26 }
+ PathLine { x: 36.882; y: 121.598 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 9.282; y: 103.598 }
+ PathCubic { control1X: 9.282; control1Y: 103.598; control2X: 16.203; control2Y: 103.066; x: 14.606; y: 105.195 }
+ PathCubic { control1X: 13.009; control1Y: 107.325; control2X: 9.014; control2Y: 107.06; x: 9.014; y: 107.06 }
+ PathLine { x: 9.282; y: 103.598 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 19.282; y: 100.398 }
+ PathCubic { control1X: 19.282; control1Y: 100.398; control2X: 26.203; control2Y: 99.866; x: 24.606; y: 101.995 }
+ PathCubic { control1X: 23.009; control1Y: 104.125; control2X: 18.614; control2Y: 103.86; x: 18.614; y: 103.86 }
+ PathLine { x: 19.282; y: 100.398 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -3.4; y: 140.401 }
+ PathCubic { control1X: -3.4; control1Y: 140.401; control2X: 1.8; control2Y: 140.001; x: 0.6; y: 141.601 }
+ PathCubic { control1X: -0.6; control1Y: 143.201; control2X: -3; control2Y: 142.401; x: -3; y: 142.401 }
+ PathLine { x: -3.4; y: 140.401 }
+ }
+
+ ShapePath {
+ fillColor: "#992600"
+ strokeWidth: -1
+ PathMove { x: -76.6; y: 41.2 }
+ PathCubic { control1X: -76.6; control1Y: 41.2; control2X: -81; control2Y: 50; x: -81.4; y: 53.2 }
+ PathCubic { control1X: -81.4; control1Y: 53.2; control2X: -80.6; control2Y: 44.4; x: -79.4; y: 42.4 }
+ PathCubic { control1X: -78.2; control1Y: 40.4; control2X: -76.6; control2Y: 41.2; x: -76.6; y: 41.2 }
+ }
+
+ ShapePath {
+ fillColor: "#992600"
+ strokeWidth: -1
+ PathMove { x: -95; y: 55.2 }
+ PathCubic { control1X: -95; control1Y: 55.2; control2X: -98.2; control2Y: 69.6; x: -97.8; y: 72.4 }
+ PathCubic { control1X: -97.8; control1Y: 72.4; control2X: -99; control2Y: 60.8; x: -98.6; y: 59.6 }
+ PathCubic { control1X: -98.2; control1Y: 58.4; control2X: -95; control2Y: 55.2; x: -95; y: 55.2 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: -74.2; y: -19.4 }
+ PathLine { x: -74.4; y: -16.2 }
+ PathLine { x: -76.6; y: -16 }
+ PathCubic { control1X: -76.6; control1Y: -16; control2X: -62.4; control2Y: -3.4; x: -61.8; y: 4.2 }
+ PathCubic { control1X: -61.8; control1Y: 4.2; control2X: -61; control2Y: -4; x: -74.2; y: -19.4 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -70.216; y: -18.135 }
+ PathCubic { control1X: -70.647; control1Y: -18.551; control2X: -70.428; control2Y: -19.296; x: -70.836; y: -19.556 }
+ PathCubic { control1X: -71.645; control1Y: -20.072; control2X: -69.538; control2Y: -20.129; x: -69.766; y: -20.845 }
+ PathCubic { control1X: -70.149; control1Y: -22.051; control2X: -69.962; control2Y: -22.072; x: -70.084; y: -23.348 }
+ PathCubic { control1X: -70.141; control1Y: -23.946; control2X: -69.553; control2Y: -25.486; x: -69.168; y: -25.926 }
+ PathCubic { control1X: -67.722; control1Y: -27.578; control2X: -69.046; control2Y: -30.51; x: -67.406; y: -32.061 }
+ PathCubic { control1X: -67.102; control1Y: -32.35; control2X: -66.726; control2Y: -32.902; x: -66.441; y: -33.32 }
+ PathCubic { control1X: -65.782; control1Y: -34.283; control2X: -64.598; control2Y: -34.771; x: -63.648; y: -35.599 }
+ PathCubic { control1X: -63.33; control1Y: -35.875; control2X: -63.531; control2Y: -36.702; x: -62.962; y: -36.61 }
+ PathCubic { control1X: -62.248; control1Y: -36.495; control2X: -61.007; control2Y: -36.625; x: -61.052; y: -35.784 }
+ PathCubic { control1X: -61.165; control1Y: -33.664; control2X: -62.494; control2Y: -31.944; x: -63.774; y: -30.276 }
+ PathCubic { control1X: -63.323; control1Y: -29.572; control2X: -63.781; control2Y: -28.937; x: -64.065; y: -28.38 }
+ PathCubic { control1X: -65.4; control1Y: -25.76; control2X: -65.211; control2Y: -22.919; x: -65.385; y: -20.079 }
+ PathCubic { control1X: -65.39; control1Y: -19.994; control2X: -65.697; control2Y: -19.916; x: -65.689; y: -19.863 }
+ PathCubic { control1X: -65.336; control1Y: -17.528; control2X: -64.752; control2Y: -15.329; x: -63.873; y: -13.1 }
+ PathCubic { control1X: -63.507; control1Y: -12.17; control2X: -63.036; control2Y: -11.275; x: -62.886; y: -10.348 }
+ PathCubic { control1X: -62.775; control1Y: -9.662; control2X: -62.672; control2Y: -8.829; x: -63.08; y: -8.124 }
+ PathCubic { control1X: -61.045; control1Y: -5.234; control2X: -62.354; control2Y: -2.583; x: -61.185; y: 0.948 }
+ PathCubic { control1X: -60.978; control1Y: 1.573; control2X: -59.286; control2Y: 3.487; x: -59.749; y: 3.326 }
+ PathCubic { control1X: -62.262; control1Y: 2.455; control2X: -62.374; control2Y: 2.057; x: -62.551; y: 1.304 }
+ PathCubic { control1X: -62.697; control1Y: 0.681; control2X: -63.027; control2Y: -0.696; x: -63.264; y: -1.298 }
+ PathCubic { control1X: -63.328; control1Y: -1.462; control2X: -63.499; control2Y: -3.346; x: -63.577; y: -3.468 }
+ PathCubic { control1X: -65.09; control1Y: -5.85; control2X: -63.732; control2Y: -5.674; x: -65.102; y: -8.032 }
+ PathCubic { control1X: -66.53; control1Y: -8.712; control2X: -67.496; control2Y: -9.816; x: -68.619; y: -10.978 }
+ PathCubic { control1X: -68.817; control1Y: -11.182; control2X: -67.674; control2Y: -11.906; x: -67.855; y: -12.119 }
+ PathCubic { control1X: -68.947; control1Y: -13.408; control2X: -70.1; control2Y: -14.175; x: -69.764; y: -15.668 }
+ PathCubic { control1X: -69.609; control1Y: -16.358; control2X: -69.472; control2Y: -17.415; x: -70.216; y: -18.135 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -73.8; y: -16.4 }
+ PathCubic { control1X: -73.8; control1Y: -16.4; control2X: -73.4; control2Y: -9.6; x: -71; y: -8 }
+ PathCubic { control1X: -68.6; control1Y: -6.4; control2X: -69.8; control2Y: -7.2; x: -73; y: -8.4 }
+ PathCubic { control1X: -76.2; control1Y: -9.6; control2X: -75; control2Y: -10.4; x: -75; y: -10.4 }
+ PathCubic { control1X: -75; control1Y: -10.4; control2X: -77.8; control2Y: -10; x: -75.4; y: -8 }
+ PathCubic { control1X: -73; control1Y: -6; control2X: -69.4; control2Y: -3.6; x: -71; y: -3.6 }
+ PathCubic { control1X: -72.6; control1Y: -3.6; control2X: -80.2; control2Y: -7.6; x: -80.2; y: -10.4 }
+ PathCubic { control1X: -80.2; control1Y: -13.2; control2X: -81.2; control2Y: -17.3; x: -81.2; y: -17.3 }
+ PathCubic { control1X: -81.2; control1Y: -17.3; control2X: -80.1; control2Y: -18.1; x: -75.3; y: -18 }
+ PathCubic { control1X: -75.3; control1Y: -18; control2X: -73.9; control2Y: -17.3; x: -73.8; y: -16.4 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: -74.6; y: 2.2 }
+ PathCubic { control1X: -74.6; control1Y: 2.2; control2X: -83.12; control2Y: -0.591; x: -101.6; y: 2.8 }
+ PathCubic { control1X: -101.6; control1Y: 2.8; control2X: -92.569; control2Y: 0.722; x: -73.8; y: 3 }
+ PathCubic { control1X: -63.5; control1Y: 4.25; control2X: -74.6; control2Y: 2.2; x: -74.6; y: 2.2 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: -72.502; y: 2.129 }
+ PathCubic { control1X: -72.502; control1Y: 2.129; control2X: -80.748; control2Y: -1.389; x: -99.453; y: 0.392 }
+ PathCubic { control1X: -99.453; control1Y: 0.392; control2X: -90.275; control2Y: -0.897; x: -71.774; y: 2.995 }
+ PathCubic { control1X: -61.62; control1Y: 5.131; control2X: -72.502; control2Y: 2.129; x: -72.502; y: 2.129 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: -70.714; y: 2.222 }
+ PathCubic { control1X: -70.714; control1Y: 2.222; control2X: -78.676; control2Y: -1.899; x: -97.461; y: -1.514 }
+ PathCubic { control1X: -97.461; control1Y: -1.514; control2X: -88.213; control2Y: -2.118; x: -70.052; y: 3.14 }
+ PathCubic { control1X: -60.086; control1Y: 6.025; control2X: -70.714; control2Y: 2.222; x: -70.714; y: 2.222 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: -69.444; y: 2.445 }
+ PathCubic { control1X: -69.444; control1Y: 2.445; control2X: -76.268; control2Y: -1.862; x: -93.142; y: -2.96 }
+ PathCubic { control1X: -93.142; control1Y: -2.96; control2X: -84.803; control2Y: -2.79; x: -68.922; y: 3.319 }
+ PathCubic { control1X: -60.206; control1Y: 6.672; control2X: -69.444; control2Y: 2.445; x: -69.444; y: 2.445 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: 45.84; y: 12.961 }
+ PathCubic { control1X: 45.84; control1Y: 12.961; control2X: 44.91; control2Y: 13.605; x: 45.124; y: 12.424 }
+ PathCubic { control1X: 45.339; control1Y: 11.243; control2X: 73.547; control2Y: -1.927; x: 77.161; y: -1.677 }
+ PathCubic { control1X: 77.161; control1Y: -1.677; control2X: 46.913; control2Y: 11.529; x: 45.84; y: 12.961 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: 42.446; y: 13.6 }
+ PathCubic { control1X: 42.446; control1Y: 13.6; control2X: 41.57; control2Y: 14.315; x: 41.691; y: 13.121 }
+ PathCubic { control1X: 41.812; control1Y: 11.927; control2X: 68.899; control2Y: -3.418; x: 72.521; y: -3.452 }
+ PathCubic { control1X: 72.521; control1Y: -3.452; control2X: 43.404; control2Y: 12.089; x: 42.446; y: 13.6 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: 39.16; y: 14.975 }
+ PathCubic { control1X: 39.16; control1Y: 14.975; control2X: 38.332; control2Y: 15.747; x: 38.374; y: 14.547 }
+ PathCubic { control1X: 38.416; control1Y: 13.348; control2X: 58.233; control2Y: -2.149; x: 68.045; y: -4.023 }
+ PathCubic { control1X: 68.045; control1Y: -4.023; control2X: 50.015; control2Y: 4.104; x: 39.16; y: 14.975 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: 36.284; y: 16.838 }
+ PathCubic { control1X: 36.284; control1Y: 16.838; control2X: 35.539; control2Y: 17.532; x: 35.577; y: 16.453 }
+ PathCubic { control1X: 35.615; control1Y: 15.373; control2X: 53.449; control2Y: 1.426; x: 62.28; y: -0.26 }
+ PathCubic { control1X: 62.28; control1Y: -0.26; control2X: 46.054; control2Y: 7.054; x: 36.284; y: 16.838 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: 4.6; y: 164.801 }
+ PathCubic { control1X: 4.6; control1Y: 164.801; control2X: -10.6; control2Y: 162.401; x: 6.2; y: 160.801 }
+ PathCubic { control1X: 6.2; control1Y: 160.801; control2X: 24.2; control2Y: 158.801; x: 28.2; y: 153.601 }
+ PathCubic { control1X: 28.2; control1Y: 153.601; control2X: 41.8; control2Y: 144.401; x: 44.6; y: 144.001 }
+ PathCubic { control1X: 47.4; control1Y: 143.601; control2X: 63.8; control2Y: 140.001; x: 64.2; y: 137.601 }
+ PathCubic { control1X: 64.6; control1Y: 135.201; control2X: 70.6; control2Y: 132.801; x: 72.2; y: 133.601 }
+ PathCubic { control1X: 73.8; control1Y: 134.401; control2X: 73.8; control2Y: 143.601; x: 71; y: 144.401 }
+ PathCubic { control1X: 68.2; control1Y: 145.201; control2X: 49.4; control2Y: 152.401; x: 43; y: 153.601 }
+ PathCubic { control1X: 36.6; control1Y: 154.801; control2X: 25; control2Y: 162.401; x: 20.2; y: 163.601 }
+ PathCubic { control1X: 15.4; control1Y: 164.801; control2X: 4.6; control2Y: 164.801; x: 4.6; y: 164.801 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 77.6; y: 127.401 }
+ PathCubic { control1X: 77.6; control1Y: 127.401; control2X: 74.6; control2Y: 129.001; x: 73.4; y: 131.601 }
+ PathCubic { control1X: 73.4; control1Y: 131.601; control2X: 67; control2Y: 142.201; x: 52.8; y: 145.401 }
+ PathCubic { control1X: 52.8; control1Y: 145.401; control2X: 29.8; control2Y: 154.401; x: 22; y: 156.401 }
+ PathCubic { control1X: 22; control1Y: 156.401; control2X: 8.6; control2Y: 161.401; x: 1.2; y: 160.601 }
+ PathCubic { control1X: 1.2; control1Y: 160.601; control2X: -5.8; control2Y: 160.801; x: 0.4; y: 162.401 }
+ PathCubic { control1X: 0.4; control1Y: 162.401; control2X: 20.6; control2Y: 160.401; x: 24; y: 158.601 }
+ PathCubic { control1X: 24; control1Y: 158.601; control2X: 39.6; control2Y: 153.401; x: 42.6; y: 150.801 }
+ PathCubic { control1X: 45.6; control1Y: 148.201; control2X: 63.8; control2Y: 143.201; x: 66; y: 141.201 }
+ PathCubic { control1X: 68.2; control1Y: 139.201; control2X: 78; control2Y: 130.801; x: 77.6; y: 127.401 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 18.882; y: 158.911 }
+ PathCubic { control1X: 18.882; control1Y: 158.911; control2X: 24.111; control2Y: 158.685; x: 22.958; y: 160.234 }
+ PathCubic { control1X: 21.805; control1Y: 161.784; control2X: 19.357; control2Y: 160.91; x: 19.357; y: 160.91 }
+ PathLine { x: 18.882; y: 158.911 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 11.68; y: 160.263 }
+ PathCubic { control1X: 11.68; control1Y: 160.263; control2X: 16.908; control2Y: 160.037; x: 15.756; y: 161.586 }
+ PathCubic { control1X: 14.603; control1Y: 163.136; control2X: 12.155; control2Y: 162.263; x: 12.155; y: 162.263 }
+ PathLine { x: 11.68; y: 160.263 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 1.251; y: 161.511 }
+ PathCubic { control1X: 1.251; control1Y: 161.511; control2X: 6.48; control2Y: 161.284; x: 5.327; y: 162.834 }
+ PathCubic { control1X: 4.174; control1Y: 164.383; control2X: 1.726; control2Y: 163.51; x: 1.726; y: 163.51 }
+ PathLine { x: 1.251; y: 161.511 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -6.383; y: 162.055 }
+ PathCubic { control1X: -6.383; control1Y: 162.055; control2X: -1.154; control2Y: 161.829; x: -2.307; y: 163.378 }
+ PathCubic { control1X: -3.46; control1Y: 164.928; control2X: -5.908; control2Y: 164.054; x: -5.908; y: 164.054 }
+ PathLine { x: -6.383; y: 162.055 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 35.415; y: 151.513 }
+ PathCubic { control1X: 35.415; control1Y: 151.513; control2X: 42.375; control2Y: 151.212; x: 40.84; y: 153.274 }
+ PathCubic { control1X: 39.306; control1Y: 155.336; control2X: 36.047; control2Y: 154.174; x: 36.047; y: 154.174 }
+ PathLine { x: 35.415; y: 151.513 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 45.73; y: 147.088 }
+ PathCubic { control1X: 45.73; control1Y: 147.088; control2X: 51.689; control2Y: 143.787; x: 51.155; y: 148.849 }
+ PathCubic { control1X: 50.885; control1Y: 151.405; control2X: 46.362; control2Y: 149.749; x: 46.362; y: 149.749 }
+ PathLine { x: 45.73; y: 147.088 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 54.862; y: 144.274 }
+ PathCubic { control1X: 54.862; control1Y: 144.274; control2X: 62.021; control2Y: 140.573; x: 60.287; y: 146.035 }
+ PathCubic { control1X: 59.509; control1Y: 148.485; control2X: 55.493; control2Y: 146.935; x: 55.493; y: 146.935 }
+ PathLine { x: 54.862; y: 144.274 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 64.376; y: 139.449 }
+ PathCubic { control1X: 64.376; control1Y: 139.449; control2X: 68.735; control2Y: 134.548; x: 69.801; y: 141.21 }
+ PathCubic { control1X: 70.207; control1Y: 143.748; control2X: 65.008; control2Y: 142.11; x: 65.008; y: 142.11 }
+ PathLine { x: 64.376; y: 139.449 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 26.834; y: 155.997 }
+ PathCubic { control1X: 26.834; control1Y: 155.997; control2X: 32.062; control2Y: 155.77; x: 30.91; y: 157.32 }
+ PathCubic { control1X: 29.757; control1Y: 158.869; control2X: 27.308; control2Y: 157.996; x: 27.308; y: 157.996 }
+ PathLine { x: 26.834; y: 155.997 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: 62.434; y: 34.603 }
+ PathCubic { control1X: 62.434; control1Y: 34.603; control2X: 61.708; control2Y: 35.268; x: 61.707; y: 34.197 }
+ PathCubic { control1X: 61.707; control1Y: 33.127; control2X: 79.191; control2Y: 19.863; x: 88.034; y: 18.479 }
+ PathCubic { control1X: 88.034; control1Y: 18.479; control2X: 71.935; control2Y: 25.208; x: 62.434; y: 34.603 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: 65.4; y: 98.4 }
+ PathCubic { control1X: 65.4; control1Y: 98.4; control2X: 87.401; control2Y: 120.801; x: 96.601; y: 124.401 }
+ PathCubic { control1X: 96.601; control1Y: 124.401; control2X: 105.801; control2Y: 135.601; x: 101.801; y: 161.601 }
+ PathCubic { control1X: 101.801; control1Y: 161.601; control2X: 98.601; control2Y: 169.201; x: 95.401; y: 148.401 }
+ PathCubic { control1X: 95.401; control1Y: 148.401; control2X: 98.601; control2Y: 123.201; x: 87.401; y: 139.201 }
+ PathCubic { control1X: 87.401; control1Y: 139.201; control2X: 79; control2Y: 129.301; x: 85.4; y: 129.601 }
+ PathCubic { control1X: 85.4; control1Y: 129.601; control2X: 88.601; control2Y: 131.601; x: 89.001; y: 130.001 }
+ PathCubic { control1X: 89.401; control1Y: 128.401; control2X: 81.4; control2Y: 114.801; x: 64.2; y: 100.4 }
+ PathCubic { control1X: 47; control1Y: 86; control2X: 65.4; control2Y: 98.4; x: 65.4; y: 98.4 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: 7; y: 137.201 }
+ PathCubic { control1X: 7; control1Y: 137.201; control2X: 6.8; control2Y: 135.401; x: 8.6; y: 136.201 }
+ PathCubic { control1X: 10.4; control1Y: 137.001; control2X: 104.601; control2Y: 143.201; x: 136.201; y: 167.201 }
+ PathCubic { control1X: 136.201; control1Y: 167.201; control2X: 91.001; control2Y: 144.001; x: 7; y: 137.201 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: 17.4; y: 132.801 }
+ PathCubic { control1X: 17.4; control1Y: 132.801; control2X: 17.2; control2Y: 131.001; x: 19; y: 131.801 }
+ PathCubic { control1X: 20.8; control1Y: 132.601; control2X: 157.401; control2Y: 131.601; x: 181.001; y: 164.001 }
+ PathCubic { control1X: 181.001; control1Y: 164.001; control2X: 159.001; control2Y: 138.801; x: 17.4; y: 132.801 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: 29; y: 128.801 }
+ PathCubic { control1X: 29; control1Y: 128.801; control2X: 28.8; control2Y: 127.001; x: 30.6; y: 127.801 }
+ PathCubic { control1X: 32.4; control1Y: 128.601; control2X: 205.801; control2Y: 115.601; x: 229.401; y: 148.001 }
+ PathCubic { control1X: 229.401; control1Y: 148.001; control2X: 219.801; control2Y: 122.401; x: 29; y: 128.801 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: 39; y: 124.001 }
+ PathCubic { control1X: 39; control1Y: 124.001; control2X: 38.8; control2Y: 122.201; x: 40.6; y: 123.001 }
+ PathCubic { control1X: 42.4; control1Y: 123.801; control2X: 164.601; control2Y: 85.2; x: 188.201; y: 117.601 }
+ PathCubic { control1X: 188.201; control1Y: 117.601; control2X: 174.801; control2Y: 93; x: 39; y: 124.001 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: -19; y: 146.801 }
+ PathCubic { control1X: -19; control1Y: 146.801; control2X: -19.2; control2Y: 145.001; x: -17.4; y: 145.801 }
+ PathCubic { control1X: -15.6; control1Y: 146.601; control2X: 2.2; control2Y: 148.801; x: 4.2; y: 187.601 }
+ PathCubic { control1X: 4.2; control1Y: 187.601; control2X: -3; control2Y: 145.601; x: -19; y: 146.801 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: -27.8; y: 148.401 }
+ PathCubic { control1X: -27.8; control1Y: 148.401; control2X: -28; control2Y: 146.601; x: -26.2; y: 147.401 }
+ PathCubic { control1X: -24.4; control1Y: 148.201; control2X: -10.2; control2Y: 143.601; x: -13; y: 182.401 }
+ PathCubic { control1X: -13; control1Y: 182.401; control2X: -11.8; control2Y: 147.201; x: -27.8; y: 148.401 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: -35.8; y: 148.801 }
+ PathCubic { control1X: -35.8; control1Y: 148.801; control2X: -36; control2Y: 147.001; x: -34.2; y: 147.801 }
+ PathCubic { control1X: -32.4; control1Y: 148.601; control2X: -17; control2Y: 149.201; x: -29.4; y: 171.601 }
+ PathCubic { control1X: -29.4; control1Y: 171.601; control2X: -19.8; control2Y: 147.601; x: -35.8; y: 148.801 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: 11.526; y: 104.465 }
+ PathCubic { control1X: 11.526; control1Y: 104.465; control2X: 11.082; control2Y: 106.464; x: 12.631; y: 105.247 }
+ PathCubic { control1X: 28.699; control1Y: 92.622; control2X: 61.141; control2Y: 33.72; x: 116.826; y: 28.086 }
+ PathCubic { control1X: 116.826; control1Y: 28.086; control2X: 78.518; control2Y: 15.976; x: 11.526; y: 104.465 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: 22.726; y: 102.665 }
+ PathCubic { control1X: 22.726; control1Y: 102.665; control2X: 21.363; control2Y: 101.472; x: 23.231; y: 100.847 }
+ PathCubic { control1X: 25.099; control1Y: 100.222; control2X: 137.541; control2Y: 27.72; x: 176.826; y: 35.686 }
+ PathCubic { control1X: 176.826; control1Y: 35.686; control2X: 149.719; control2Y: 28.176; x: 22.726; y: 102.665 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: 1.885; y: 108.767 }
+ PathCubic { control1X: 1.885; control1Y: 108.767; control2X: 1.376; control2Y: 110.366; x: 3.087; y: 109.39 }
+ PathCubic { control1X: 12.062; control1Y: 104.27; control2X: 15.677; control2Y: 47.059; x: 59.254; y: 45.804 }
+ PathCubic { control1X: 59.254; control1Y: 45.804; control2X: 26.843; control2Y: 31.09; x: 1.885; y: 108.767 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: -18.038; y: 119.793 }
+ PathCubic { control1X: -18.038; control1Y: 119.793; control2X: -19.115; control2Y: 121.079; x: -17.162; y: 120.825 }
+ PathCubic { control1X: -6.916; control1Y: 119.493; control2X: 14.489; control2Y: 78.222; x: 58.928; y: 83.301 }
+ PathCubic { control1X: 58.928; control1Y: 83.301; control2X: 26.962; control2Y: 68.955; x: -18.038; y: 119.793 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: -6.8; y: 113.667 }
+ PathCubic { control1X: -6.8; control1Y: 113.667; control2X: -7.611; control2Y: 115.136; x: -5.742; y: 114.511 }
+ PathCubic { control1X: 4.057; control1Y: 111.237; control2X: 17.141; control2Y: 66.625; x: 61.729; y: 63.078 }
+ PathCubic { control1X: 61.729; control1Y: 63.078; control2X: 27.603; control2Y: 55.135; x: -6.8; y: 113.667 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: -25.078; y: 124.912 }
+ PathCubic { control1X: -25.078; control1Y: 124.912; control2X: -25.951; control2Y: 125.954; x: -24.369; y: 125.748 }
+ PathCubic { control1X: -16.07; control1Y: 124.669; control2X: 1.268; control2Y: 91.24; x: 37.264; y: 95.354 }
+ PathCubic { control1X: 37.264; control1Y: 95.354; control2X: 11.371; control2Y: 83.734; x: -25.078; y: 124.912 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: -32.677; y: 130.821 }
+ PathCubic { control1X: -32.677; control1Y: 130.821; control2X: -33.682; control2Y: 131.866; x: -32.091; y: 131.748 }
+ PathCubic { control1X: -27.923; control1Y: 131.439; control2X: 2.715; control2Y: 98.36; x: 21.183; y: 113.862 }
+ PathCubic { control1X: 21.183; control1Y: 113.862; control2X: 9.168; control2Y: 95.139; x: -32.677; y: 130.821 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: 36.855; y: 98.898 }
+ PathCubic { control1X: 36.855; control1Y: 98.898; control2X: 35.654; control2Y: 97.543; x: 37.586; y: 97.158 }
+ PathCubic { control1X: 39.518; control1Y: 96.774; control2X: 160.221; control2Y: 39.061; x: 198.184; y: 51.927 }
+ PathCubic { control1X: 198.184; control1Y: 51.927; control2X: 172.243; control2Y: 41.053; x: 36.855; y: 98.898 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: 3.4; y: 163.201 }
+ PathCubic { control1X: 3.4; control1Y: 163.201; control2X: 3.2; control2Y: 161.401; x: 5; y: 162.201 }
+ PathCubic { control1X: 6.8; control1Y: 163.001; control2X: 22.2; control2Y: 163.601; x: 9.8; y: 186.001 }
+ PathCubic { control1X: 9.8; control1Y: 186.001; control2X: 19.4; control2Y: 162.001; x: 3.4; y: 163.201 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: 13.8; y: 161.601 }
+ PathCubic { control1X: 13.8; control1Y: 161.601; control2X: 13.6; control2Y: 159.801; x: 15.4; y: 160.601 }
+ PathCubic { control1X: 17.2; control1Y: 161.401; control2X: 35; control2Y: 163.601; x: 37; y: 202.401 }
+ PathCubic { control1X: 37; control1Y: 202.401; control2X: 29.8; control2Y: 160.401; x: 13.8; y: 161.601 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: 20.6; y: 160.001 }
+ PathCubic { control1X: 20.6; control1Y: 160.001; control2X: 20.4; control2Y: 158.201; x: 22.2; y: 159.001 }
+ PathCubic { control1X: 24; control1Y: 159.801; control2X: 48.6; control2Y: 163.201; x: 72.2; y: 195.601 }
+ PathCubic { control1X: 72.2; control1Y: 195.601; control2X: 36.6; control2Y: 158.801; x: 20.6; y: 160.001 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: 28.225; y: 157.972 }
+ PathCubic { control1X: 28.225; control1Y: 157.972; control2X: 27.788; control2Y: 156.214; x: 29.678; y: 156.768 }
+ PathCubic { control1X: 31.568; control1Y: 157.322; control2X: 52.002; control2Y: 155.423; x: 90.099; y: 189.599 }
+ PathCubic { control1X: 90.099; control1Y: 189.599; control2X: 43.924; control2Y: 154.656; x: 28.225; y: 157.972 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: 38.625; y: 153.572 }
+ PathCubic { control1X: 38.625; control1Y: 153.572; control2X: 38.188; control2Y: 151.814; x: 40.078; y: 152.368 }
+ PathCubic { control1X: 41.968; control1Y: 152.922; control2X: 76.802; control2Y: 157.423; x: 128.499; y: 192.399 }
+ PathCubic { control1X: 128.499; control1Y: 192.399; control2X: 54.324; control2Y: 150.256; x: 38.625; y: 153.572 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: -1.8; y: 142.001 }
+ PathCubic { control1X: -1.8; control1Y: 142.001; control2X: -2; control2Y: 140.201; x: -0.2; y: 141.001 }
+ PathCubic { control1X: 1.6; control1Y: 141.801; control2X: 55; control2Y: 144.401; x: 85.4; y: 171.201 }
+ PathCubic { control1X: 85.4; control1Y: 171.201; control2X: 50.499; control2Y: 146.426; x: -1.8; y: 142.001 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: -11.8; y: 146.001 }
+ PathCubic { control1X: -11.8; control1Y: 146.001; control2X: -12; control2Y: 144.201; x: -10.2; y: 145.001 }
+ PathCubic { control1X: -8.4; control1Y: 145.801; control2X: 16.2; control2Y: 149.201; x: 39.8; y: 181.601 }
+ PathCubic { control1X: 39.8; control1Y: 181.601; control2X: 4.2; control2Y: 144.801; x: -11.8; y: 146.001 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: 49.503; y: 148.962 }
+ PathCubic { control1X: 49.503; control1Y: 148.962; control2X: 48.938; control2Y: 147.241; x: 50.864; y: 147.655 }
+ PathCubic { control1X: 52.79; control1Y: 148.068; control2X: 87.86; control2Y: 150.004; x: 141.981; y: 181.098 }
+ PathCubic { control1X: 141.981; control1Y: 181.098; control2X: 64.317; control2Y: 146.704; x: 49.503; y: 148.962 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: 57.903; y: 146.562 }
+ PathCubic { control1X: 57.903; control1Y: 146.562; control2X: 57.338; control2Y: 144.841; x: 59.264; y: 145.255 }
+ PathCubic { control1X: 61.19; control1Y: 145.668; control2X: 96.26; control2Y: 147.604; x: 150.381; y: 178.698 }
+ PathCubic { control1X: 150.381; control1Y: 178.698; control2X: 73.317; control2Y: 143.904; x: 57.903; y: 146.562 }
+ }
+
+ ShapePath {
+ fillColor: "#ffffff"
+ strokeColor: "#000000"
+ strokeWidth: 0.1
+ PathMove { x: 67.503; y: 141.562 }
+ PathCubic { control1X: 67.503; control1Y: 141.562; control2X: 66.938; control2Y: 139.841; x: 68.864; y: 140.255 }
+ PathCubic { control1X: 70.79; control1Y: 140.668; control2X: 113.86; control2Y: 145.004; x: 203.582; y: 179.298 }
+ PathCubic { control1X: 203.582; control1Y: 179.298; control2X: 82.917; control2Y: 138.904; x: 67.503; y: 141.562 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -43.8; y: 148.401 }
+ PathCubic { control1X: -43.8; control1Y: 148.401; control2X: -38.6; control2Y: 148.001; x: -39.8; y: 149.601 }
+ PathCubic { control1X: -41; control1Y: 151.201; control2X: -43.4; control2Y: 150.401; x: -43.4; y: 150.401 }
+ PathLine { x: -43.8; y: 148.401 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -13; y: 162.401 }
+ PathCubic { control1X: -13; control1Y: 162.401; control2X: -7.8; control2Y: 162.001; x: -9; y: 163.601 }
+ PathCubic { control1X: -10.2; control1Y: 165.201; control2X: -12.6; control2Y: 164.401; x: -12.6; y: 164.401 }
+ PathLine { x: -13; y: 162.401 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -21.8; y: 162.001 }
+ PathCubic { control1X: -21.8; control1Y: 162.001; control2X: -16.6; control2Y: 161.601; x: -17.8; y: 163.201 }
+ PathCubic { control1X: -19; control1Y: 164.801; control2X: -21.4; control2Y: 164.001; x: -21.4; y: 164.001 }
+ PathLine { x: -21.8; y: 162.001 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -117.169; y: 150.182 }
+ PathCubic { control1X: -117.169; control1Y: 150.182; control2X: -112.124; control2Y: 151.505; x: -113.782; y: 152.624 }
+ PathCubic { control1X: -115.439; control1Y: 153.744; control2X: -117.446; control2Y: 152.202; x: -117.446; y: 152.202 }
+ PathLine { x: -117.169; y: 150.182 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -115.169; y: 140.582 }
+ PathCubic { control1X: -115.169; control1Y: 140.582; control2X: -110.124; control2Y: 141.905; x: -111.782; y: 143.024 }
+ PathCubic { control1X: -113.439; control1Y: 144.144; control2X: -115.446; control2Y: 142.602; x: -115.446; y: 142.602 }
+ PathLine { x: -115.169; y: 140.582 }
+ }
+
+ ShapePath {
+ fillColor: "#000000"
+ strokeWidth: -1
+ PathMove { x: -122.369; y: 136.182 }
+ PathCubic { control1X: -122.369; control1Y: 136.182; control2X: -117.324; control2Y: 137.505; x: -118.982; y: 138.624 }
+ PathCubic { control1X: -120.639; control1Y: 139.744; control2X: -122.646; control2Y: 138.202; x: -122.646; y: 138.202 }
+ PathLine { x: -122.369; y: 136.182 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: -42.6; y: 211.201 }
+ PathCubic { control1X: -42.6; control1Y: 211.201; control2X: -44.2; control2Y: 211.201; x: -48.2; y: 213.201 }
+ PathCubic { control1X: -50.2; control1Y: 213.201; control2X: -61.4; control2Y: 216.801; x: -67; y: 226.801 }
+ PathCubic { control1X: -67; control1Y: 226.801; control2X: -54.6; control2Y: 217.201; x: -42.6; y: 211.201 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: 45.116; y: 303.847 }
+ PathCubic { control1X: 45.257; control1Y: 304.105; control2X: 45.312; control2Y: 304.525; x: 45.604; y: 304.542 }
+ PathCubic { control1X: 46.262; control1Y: 304.582; control2X: 47.495; control2Y: 304.883; x: 47.37; y: 304.247 }
+ PathCubic { control1X: 46.522; control1Y: 299.941; control2X: 45.648; control2Y: 295.004; x: 41.515; y: 293.197 }
+ PathCubic { control1X: 40.876; control1Y: 292.918; control2X: 39.434; control2Y: 293.331; x: 39.36; y: 294.215 }
+ PathCubic { control1X: 39.233; control1Y: 295.739; control2X: 39.116; control2Y: 297.088; x: 39.425; y: 298.554 }
+ PathCubic { control1X: 39.725; control1Y: 299.975; control2X: 41.883; control2Y: 299.985; x: 42.8; y: 298.601 }
+ PathCubic { control1X: 43.736; control1Y: 300.273; control2X: 44.168; control2Y: 302.116; x: 45.116; y: 303.847 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: 34.038; y: 308.581 }
+ PathCubic { control1X: 34.786; control1Y: 309.994; control2X: 34.659; control2Y: 311.853; x: 36.074; y: 312.416 }
+ PathCubic { control1X: 36.814; control1Y: 312.71; control2X: 38.664; control2Y: 311.735; x: 38.246; y: 310.661 }
+ PathCubic { control1X: 37.444; control1Y: 308.6; control2X: 37.056; control2Y: 306.361; x: 35.667; y: 304.55 }
+ PathCubic { control1X: 35.467; control1Y: 304.288; control2X: 35.707; control2Y: 303.755; x: 35.547; y: 303.427 }
+ PathCubic { control1X: 34.953; control1Y: 302.207; control2X: 33.808; control2Y: 301.472; x: 32.4; y: 301.801 }
+ PathCubic { control1X: 31.285; control1Y: 304.004; control2X: 32.433; control2Y: 306.133; x: 33.955; y: 307.842 }
+ PathCubic { control1X: 34.091; control1Y: 307.994; control2X: 33.925; control2Y: 308.37; x: 34.038; y: 308.581 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: -5.564; y: 303.391 }
+ PathCubic { control1X: -5.672; control1Y: 303.014; control2X: -5.71; control2Y: 302.551; x: -5.545; y: 302.23 }
+ PathCubic { control1X: -5.014; control1Y: 301.197; control2X: -4.221; control2Y: 300.075; x: -4.558; y: 299.053 }
+ PathCubic { control1X: -4.906; control1Y: 297.997; control2X: -6.022; control2Y: 298.179; x: -6.672; y: 298.748 }
+ PathCubic { control1X: -7.807; control1Y: 299.742; control2X: -7.856; control2Y: 301.568; x: -8.547; y: 302.927 }
+ PathCubic { control1X: -8.743; control1Y: 303.313; control2X: -8.692; control2Y: 303.886; x: -9.133; y: 304.277 }
+ PathCubic { control1X: -9.607; control1Y: 304.698; control2X: -10.047; control2Y: 306.222; x: -9.951; y: 306.793 }
+ PathCubic { control1X: -9.898; control1Y: 307.106; control2X: -10.081; control2Y: 317.014; x: -9.859; y: 316.751 }
+ PathCubic { control1X: -9.24; control1Y: 316.018; control2X: -6.19; control2Y: 306.284; x: -6.121; y: 305.392 }
+ PathCubic { control1X: -6.064; control1Y: 304.661; control2X: -5.332; control2Y: 304.196; x: -5.564; y: 303.391 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: -31.202; y: 296.599 }
+ PathCubic { control1X: -28.568; control1Y: 294.1; control2X: -25.778; control2Y: 291.139; x: -26.22; y: 287.427 }
+ PathCubic { control1X: -26.336; control1Y: 286.451; control2X: -28.111; control2Y: 286.978; x: -28.298; y: 287.824 }
+ PathCubic { control1X: -29.1; control1Y: 291.449; control2X: -31.139; control2Y: 294.11; x: -33.707; y: 296.502 }
+ PathCubic { control1X: -35.903; control1Y: 298.549; control2X: -37.765; control2Y: 304.893; x: -38; y: 305.401 }
+ PathCubic { control1X: -34.303; control1Y: 300.145; control2X: -32.046; control2Y: 297.399; x: -31.202; y: 296.599 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: -44.776; y: 290.635 }
+ PathCubic { control1X: -44.253; control1Y: 290.265; control2X: -44.555; control2Y: 289.774; x: -44.338; y: 289.442 }
+ PathCubic { control1X: -43.385; control1Y: 287.984; control2X: -42.084; control2Y: 286.738; x: -42.066; y: 285 }
+ PathCubic { control1X: -42.063; control1Y: 284.723; control2X: -42.441; control2Y: 284.414; x: -42.776; y: 284.638 }
+ PathCubic { control1X: -43.053; control1Y: 284.822; control2X: -43.395; control2Y: 284.952; x: -43.503; y: 285.082 }
+ PathCubic { control1X: -45.533; control1Y: 287.531; control2X: -46.933; control2Y: 290.202; x: -48.376; y: 293.014 }
+ PathCubic { control1X: -48.559; control1Y: 293.371; control2X: -49.703; control2Y: 297.862; x: -49.39; y: 297.973 }
+ PathCubic { control1X: -49.151; control1Y: 298.058; control2X: -47.431; control2Y: 293.877; x: -47.221; y: 293.763 }
+ PathCubic { control1X: -45.958; control1Y: 293.077; control2X: -45.946; control2Y: 291.462; x: -44.776; y: 290.635 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: -28.043; y: 310.179 }
+ PathCubic { control1X: -27.599; control1Y: 309.31; control2X: -26.023; control2Y: 308.108; x: -26.136; y: 307.219 }
+ PathCubic { control1X: -26.254; control1Y: 306.291; control2X: -25.786; control2Y: 304.848; x: -26.698; y: 305.536 }
+ PathCubic { control1X: -27.955; control1Y: 306.484; control2X: -31.404; control2Y: 307.833; x: -31.674; y: 313.641 }
+ PathCubic { control1X: -31.7; control1Y: 314.212; control2X: -28.726; control2Y: 311.519; x: -28.043; y: 310.179 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: -13.6; y: 293.001 }
+ PathCubic { control1X: -13.2; control1Y: 292.333; control2X: -12.492; control2Y: 292.806; x: -12.033; y: 292.543 }
+ PathCubic { control1X: -11.385; control1Y: 292.171; control2X: -10.774; control2Y: 291.613; x: -10.482; y: 290.964 }
+ PathCubic { control1X: -9.512; control1Y: 288.815; control2X: -7.743; control2Y: 286.995; x: -7.6; y: 284.601 }
+ PathCubic { control1X: -9.091; control1Y: 283.196; control2X: -9.77; control2Y: 285.236; x: -10.4; y: 286.201 }
+ PathCubic { control1X: -11.723; control1Y: 284.554; control2X: -12.722; control2Y: 286.428; x: -14.022; y: 286.947 }
+ PathCubic { control1X: -14.092; control1Y: 286.975; control2X: -14.305; control2Y: 286.628; x: -14.38; y: 286.655 }
+ PathCubic { control1X: -15.557; control1Y: 287.095; control2X: -16.237; control2Y: 288.176; x: -17.235; y: 288.957 }
+ PathCubic { control1X: -17.406; control1Y: 289.091; control2X: -17.811; control2Y: 288.911; x: -17.958; y: 289.047 }
+ PathCubic { control1X: -18.61; control1Y: 289.65; control2X: -19.583; control2Y: 289.975; x: -19.863; y: 290.657 }
+ PathCubic { control1X: -20.973; control1Y: 293.364; control2X: -24.113; control2Y: 295.459; x: -26; y: 303.001 }
+ PathCubic { control1X: -25.619; control1Y: 303.91; control2X: -21.488; control2Y: 296.359; x: -21.001; y: 295.661 }
+ PathCubic { control1X: -20.165; control1Y: 294.465; control2X: -20.047; control2Y: 297.322; x: -18.771; y: 296.656 }
+ PathCubic { control1X: -18.72; control1Y: 296.629; control2X: -18.534; control2Y: 296.867; x: -18.4; y: 297.001 }
+ PathCubic { control1X: -18.206; control1Y: 296.721; control2X: -17.988; control2Y: 296.492; x: -17.6; y: 296.601 }
+ PathCubic { control1X: -17.6; control1Y: 296.201; control2X: -17.734; control2Y: 295.645; x: -17.533; y: 295.486 }
+ PathCubic { control1X: -16.296; control1Y: 294.509; control2X: -16.38; control2Y: 293.441; x: -15.6; y: 292.201 }
+ PathCubic { control1X: -15.142; control1Y: 292.99; control2X: -14.081; control2Y: 292.271; x: -13.6; y: 293.001 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: 46.2; y: 347.401 }
+ PathCubic { control1X: 46.2; control1Y: 347.401; control2X: 53.6; control2Y: 327.001; x: 49.2; y: 315.801 }
+ PathCubic { control1X: 49.2; control1Y: 315.801; control2X: 60.6; control2Y: 337.401; x: 56; y: 348.601 }
+ PathCubic { control1X: 56; control1Y: 348.601; control2X: 55.6; control2Y: 338.201; x: 51.6; y: 333.201 }
+ PathCubic { control1X: 51.6; control1Y: 333.201; control2X: 47.6; control2Y: 346.001; x: 46.2; y: 347.401 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: 31.4; y: 344.801 }
+ PathCubic { control1X: 31.4; control1Y: 344.801; control2X: 36.8; control2Y: 336.001; x: 28.8; y: 317.601 }
+ PathCubic { control1X: 28.8; control1Y: 317.601; control2X: 28; control2Y: 338.001; x: 21.2; y: 349.001 }
+ PathCubic { control1X: 21.2; control1Y: 349.001; control2X: 35.4; control2Y: 328.801; x: 31.4; y: 344.801 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: 21.4; y: 342.801 }
+ PathCubic { control1X: 21.4; control1Y: 342.801; control2X: 21.2; control2Y: 322.801; x: 21.6; y: 319.801 }
+ PathCubic { control1X: 21.6; control1Y: 319.801; control2X: 17.8; control2Y: 336.401; x: 7.6; y: 346.001 }
+ PathCubic { control1X: 7.6; control1Y: 346.001; control2X: 22; control2Y: 334.001; x: 21.4; y: 342.801 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: 11.8; y: 310.801 }
+ PathCubic { control1X: 11.8; control1Y: 310.801; control2X: 17.8; control2Y: 324.401; x: 7.8; y: 342.801 }
+ PathCubic { control1X: 7.8; control1Y: 342.801; control2X: 14.2; control2Y: 330.601; x: 9.4; y: 323.601 }
+ PathCubic { control1X: 9.4; control1Y: 323.601; control2X: 12; control2Y: 320.201; x: 11.8; y: 310.801 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: -7.4; y: 342.401 }
+ PathCubic { control1X: -7.4; control1Y: 342.401; control2X: -8.4; control2Y: 326.801; x: -6.6; y: 324.601 }
+ PathCubic { control1X: -6.6; control1Y: 324.601; control2X: -6.4; control2Y: 318.201; x: -6.8; y: 317.201 }
+ PathCubic { control1X: -6.8; control1Y: 317.201; control2X: -2.8; control2Y: 311.001; x: -2.6; y: 318.401 }
+ PathCubic { control1X: -2.6; control1Y: 318.401; control2X: -1.2; control2Y: 326.201; x: 1.6; y: 330.801 }
+ PathCubic { control1X: 1.6; control1Y: 330.801; control2X: 5.2; control2Y: 336.201; x: 5; y: 342.601 }
+ PathCubic { control1X: 5; control1Y: 342.601; control2X: -5; control2Y: 312.401; x: -7.4; y: 342.401 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: -11; y: 314.801 }
+ PathCubic { control1X: -11; control1Y: 314.801; control2X: -17.6; control2Y: 325.601; x: -19.4; y: 344.601 }
+ PathCubic { control1X: -19.4; control1Y: 344.601; control2X: -20.8; control2Y: 338.401; x: -17; y: 324.001 }
+ PathCubic { control1X: -17; control1Y: 324.001; control2X: -12.8; control2Y: 308.601; x: -11; y: 314.801 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: -32.8; y: 334.601 }
+ PathCubic { control1X: -32.8; control1Y: 334.601; control2X: -27.8; control2Y: 329.201; x: -26.4; y: 324.201 }
+ PathCubic { control1X: -26.4; control1Y: 324.201; control2X: -22.8; control2Y: 308.401; x: -29.2; y: 317.001 }
+ PathCubic { control1X: -29.2; control1Y: 317.001; control2X: -29; control2Y: 325.001; x: -37.2; y: 332.401 }
+ PathCubic { control1X: -37.2; control1Y: 332.401; control2X: -32.4; control2Y: 330.001; x: -32.8; y: 334.601 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: -38.6; y: 329.601 }
+ PathCubic { control1X: -38.6; control1Y: 329.601; control2X: -35.2; control2Y: 312.201; x: -34.4; y: 311.401 }
+ PathCubic { control1X: -34.4; control1Y: 311.401; control2X: -32.6; control2Y: 308.001; x: -35.4; y: 311.201 }
+ PathCubic { control1X: -35.4; control1Y: 311.201; control2X: -44.2; control2Y: 330.401; x: -48.2; y: 337.001 }
+ PathCubic { control1X: -48.2; control1Y: 337.001; control2X: -40.2; control2Y: 327.801; x: -38.6; y: 329.601 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: -44.4; y: 313.001 }
+ PathCubic { control1X: -44.4; control1Y: 313.001; control2X: -32.8; control2Y: 290.601; x: -54.6; y: 316.401 }
+ PathCubic { control1X: -54.6; control1Y: 316.401; control2X: -43.6; control2Y: 306.601; x: -44.4; y: 313.001 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: -59.8; y: 298.401 }
+ PathCubic { control1X: -59.8; control1Y: 298.401; control2X: -55; control2Y: 279.601; x: -52.4; y: 279.801 }
+ PathCubic { control1X: -52.4; control1Y: 279.801; control2X: -44.2; control2Y: 270.801; x: -50.8; y: 281.401 }
+ PathCubic { control1X: -50.8; control1Y: 281.401; control2X: -56.8; control2Y: 291.001; x: -56.2; y: 300.801 }
+ PathCubic { control1X: -56.2; control1Y: 300.801; control2X: -56.8; control2Y: 291.201; x: -59.8; y: 298.401 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: 270.5; y: 287 }
+ PathCubic { control1X: 270.5; control1Y: 287; control2X: 258.5; control2Y: 277; x: 256; y: 273.5 }
+ PathCubic { control1X: 256; control1Y: 273.5; control2X: 269.5; control2Y: 292; x: 269.5; y: 299 }
+ PathCubic { control1X: 269.5; control1Y: 299; control2X: 272; control2Y: 291.5; x: 270.5; y: 287 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: 276; y: 265 }
+ PathCubic { control1X: 276; control1Y: 265; control2X: 255; control2Y: 250; x: 251.5; y: 242.5 }
+ PathCubic { control1X: 251.5; control1Y: 242.5; control2X: 278; control2Y: 272; x: 278; y: 276.5 }
+ PathCubic { control1X: 278; control1Y: 276.5; control2X: 278.5; control2Y: 267.5; x: 276; y: 265 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: 293; y: 111 }
+ PathCubic { control1X: 293; control1Y: 111; control2X: 281; control2Y: 103; x: 279.5; y: 105 }
+ PathCubic { control1X: 279.5; control1Y: 105; control2X: 290; control2Y: 111.5; x: 292.5; y: 120 }
+ PathCubic { control1X: 292.5; control1Y: 120; control2X: 291; control2Y: 111; x: 293; y: 111 }
+ }
+
+ ShapePath {
+ fillColor: "#cccccc"
+ strokeWidth: -1
+ PathMove { x: 301.5; y: 191.5 }
+ PathLine { x: 284; y: 179.5 }
+ PathCubic { control1X: 284; control1Y: 179.5; control2X: 303; control2Y: 196.5; x: 303.5; y: 200.5 }
+ PathLine { x: 301.5; y: 191.5 }
+ }
+
+ ShapePath {
+ fillColor: "transparent"
+ strokeColor: "#000000"
+ strokeWidth: 1
+ PathMove { x: -89.25; y: 169 }
+ PathLine { x: -67.25; y: 173.75 }
+ }
+
+ ShapePath {
+ fillColor: "transparent"
+ strokeColor: "#000000"
+ strokeWidth: 1
+ PathMove { x: -39; y: 331 }
+ PathCubic { control1X: -39; control1Y: 331; control2X: -39.5; control2Y: 327.5; x: -48.5; y: 338 }
+ }
+
+ ShapePath {
+ fillColor: "transparent"
+ strokeColor: "#000000"
+ strokeWidth: 1
+ PathMove { x: -33.5; y: 336 }
+ PathCubic { control1X: -33.5; control1Y: 336; control2X: -31.5; control2Y: 329.5; x: -38; y: 334 }
+ }
+
+ ShapePath {
+ fillColor: "transparent"
+ strokeColor: "#000000"
+ strokeWidth: 1
+ PathMove { x: 20.5; y: 344.5 }
+ PathCubic { control1X: 20.5; control1Y: 344.5; control2X: 22; control2Y: 333.5; x: 10.5; y: 346.5 }
+ }
+
+ Shape {
+ x: -184; y: -144; width: parent.width; height: parent.height
+ opacity: tapHandler.pressed ? 1 : 0
+ containsMode: Shape.FillContains
+
+ TapHandler { id: tapHandler }
+
+ ShapePath {
+ strokeColor: "red"
+ strokeWidth: 4
+ fillColor: "transparent"
+ PathSvg { path: "m 325.03711,0.5
+ c -26.61408,6.4494547 -49.95197,2.1018066 -76.21132,1.0771669
+ -22.26577,7.6817151 -47.96405,9.3627181 -65.67832,25.8497861
+ -15.74718,12.80008 -41.1564,19.605644 -45.74903,40.600391
+ -12.46933,17.76181 -25.36105,35.720146 -29.20117,57.999996
+ -18.709864,3.10961 -16.347355,30.83801 -22.385143,46.675
+ -6.848711,11.2677 11.07278,24.69174 -8.514666,27.97383
+ -10.266901,5.61543 -12.859313,28.96588 -13.732346,5.78143
+ 0.940083,-11.53398 -13.486195,-38.30626 -16.81701,-34.20231
+ 14.608079,7.8234 21.299281,50.52979 11.380052,48.14418
+ -3.406456,-15.12428 -26.181106,-38.29457 -31.849471,-35.62945
+ 16.851912,6.41472 35.569884,31.75215 28.172486,47.93115
+ -7.906485,-15.42757 -37.758959,-35.53783 -44.275447,-31.28685
+ 18.975831,1.7428 37.986009,20.68109 42.87115,37.14427 C
+ 42.279655,225.774 9.879724,213.57795 4.7080253,219.04989
+ 20.780803,212.57418 55.055919,239.88547 49.602579,241.25683
+ 38.186641,230.40078 6.6930104,222.77983 2.5752529,228.41774 c
+ 13.6045481,-8.33065 49.4437901,14.89041 43.5525671,14.2358
+ -9.759981,-7.96123 -43.5842921,7.36937 -17.554974,-1.20248
+ 9.464499,-3.73452 40.555672,12.80659 16.398749,5.14121
+ -9.1987,-7.28225 -39.0013156,3.37352 -14.121965,-2.12828
+ 13.244874,-0.0206 35.758428,14.62706 10.562447,6.42228
+ -10.780465,-8.4873 -47.8282254,11.10651 -21.027329,-0.003
+ 11.640859,-4.82877 52.615601,10.74471 24.234828,8.2659
+ -10.695834,-7.03902 -42.9384162,8.93905 -34.227854,5.58373
+ 9.077539,-8.56443 49.068801,-5.28097 43.06838,0.45546
+ -10.900893,-0.7118 -27.449619,17.27258 -10.00187,3.46526
+ 15.705191,-9.18198 18.344231,9.31645 1.10807,8.73907
+ -9.908444,1.77856 -21.108189,20.66671 -7.974821,4.92019
+ 15.750746,-14.10374 34.01348,2.07267 9.796961,8.69337
+ -8.17128,5.49929 -12.642664,19.13654 -3.994573,4.19708
+ 9.044753,-8.7077 23.850399,-13.64552 21.404959,4.02329
+ 12.509737,17.12562 51.158782,11.0442 45.106112,43.34009
+ -0.65006,10.05318 -3.79228,13.95389 1.62128,14.30064
+ -4.30913,8.82737 -14.652714,37.9591 2.92144,17.46024
+ 7.37972,-3.68333 -7.62399,16.24161 -7.98007,23.83761
+ -9.336865,18.77418 19.74873,-18.55943 6.62229,5.46195
+ 5.46464,-3.7389 36.23886,-19.41901 14.78167,0.58987
+ -8.59505,4.55644 29.29441,-2.99423 8.95489,6.47134 -9.22562,5.54437
+ -24.09765,26.79976 -11.73274,22.20385 -0.81685,5.4936
+ -1.58629,21.47626 2.34158,9.14886 1.61237,14.67029
+ -2.38384,25.22225 12.26908,15.1741 -4.40761,8.01039
+ -8.23679,36.91214 5.12235,17.92578 1.53454,2.99551 9.37569,3.1726
+ 7.15304,14.93579 3.51234,-11.31873 18.4607,-29.83809
+ 12.36869,-6.48005 -0.22629,16.26174 5.44303,-7.24791
+ 6.56926,10.49819 12.45412,28.9931 3.40908,-41.89883
+ 17.52051,-9.19238 3.23093,11.1924 6.53006,29.46941 7.55984,5.1249
+ 15.37236,-19.52583 4.09776,20.07416 12.64063,1.48215
+ 18.11247,-24.55068 -8.92586,38.39355 6.73828,6.62225
+ 4.55353,-6.91007 15.35028,-38.88977 12.55806,-13.78666
+ 1.05309,27.02664 11.54743,-24.40259 12.40657,6.86306
+ -1.72561,13.28253 11.85393,-24.15909 13.85568,-1.38002
+ 3.12455,8.33539 8.76536,26.46432 8.73882,5.09231 3.57025,-10.37352
+ -16.025,-37.75672 0.20707,-22.5788 -1.2458,-14.17213
+ -2.38918,-16.90145 10.85489,-6.71468 -16.57629,-17.22152
+ 0.19706,-26.08949 5.7751,-19.14889 -14.91681,-16.1674
+ 19.74174,7.19334 2.31875,-9.86869 -4.32508,-15.23278
+ 27.25228,29.12341 20.27514,18.81172 -11.97527,-18.92603
+ -17.96305,-45.80333 11.70099,-51.52566 17.19069,-9.57351
+ 31.17452,21.93154 38.50541,1.56304 16.26048,-4.6633
+ 22.3749,38.26516 24.86349,9.11316 5.94153,-9.9731 30.14313,6.97379
+ 36.34294,4.75012 7.07435,18.27732 8.06778,14.78971 11.04264,3.86016
+ 2.73754,-15.85945 28.7269,10.06391 28.09146,25.96561 3.00672,2.4754
+ 6.55025,-22.10264 11.23552,-14.43872 2.84155,-11.4823
+ -3.28976,-27.88574 4.24895,-25.5189 -0.61494,-11.53957
+ 22.83611,0.11011 10.64648,-15.28756 -6.5587,-21.38598
+ 9.32959,-3.0159 13.5107,-4.69375 -1.38592,-16.74533
+ -8.66673,-31.83316 -1.90087,-41.0875 2.39623,-15.14303
+ -12.50533,-44.45478 -4.70573,-48.49375 15.08472,3.42779
+ -20.39159,-42.17451 -1.69776,-40.85728 24.07272,21.63552
+ -3.65989,-30.10299 2.27233,-33.17152 16.90643,17.53071
+ -12.7383,-38.42821 6.79531,-21.57013 -4.50946,-21.08135
+ -2.53357,-37.43561 -15.5535,-55.59527 -11.0035,-12.40086
+ -1.87775,-7.12745 1.34831,-8.11755 C 468.27562,118.9774
+ 451.40746,102.656 430.98897,92.119168 439.06192,78.203836
+ 455.88012,60.123881 457.38638,40.337815 463.2373,23.183067
+ 450.82861,4.7342783 435.04883,22.626367 409.5188,28.206712
+ 386.3569,24.131269 365.63904,8.0954152 352.788,2.8857182
+ 338.88892,0.40735091 325.03711,0.5 Z m -219.0625,357.04297
+ -0.97656,0.88476 z"
+ }
+ }
+ }
+}
+
diff --git a/examples/quick/shapes/doc/images/qml-shapes-example.png b/examples/quick/shapes/doc/images/qml-shapes-example.png
new file mode 100644
index 0000000000..055fc244ea
--- /dev/null
+++ b/examples/quick/shapes/doc/images/qml-shapes-example.png
Binary files differ
diff --git a/examples/quick/shapes/doc/src/shapes.qdoc b/examples/quick/shapes/doc/src/shapes.qdoc
new file mode 100644
index 0000000000..46c1f930d3
--- /dev/null
+++ b/examples/quick/shapes/doc/src/shapes.qdoc
@@ -0,0 +1,39 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** 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. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+/*!
+ \title Qt Quick Examples - Shapes
+ \example shapes
+ \image qml-shapes-example.png
+ \brief A Qt Quick example demonstrating the use of shape items.
+ \ingroup qtquickexamples
+
+ This example demonstrates the usage of the \l Shape type in Qt Quick. Shapes
+ allow efficiently rendering stroked and filled lines, curves, and arcs in Qt
+ Quick scenes.
+
+ \include examples-run.qdocinc
+*/
diff --git a/examples/quick/shapes/main.cpp b/examples/quick/shapes/main.cpp
new file mode 100644
index 0000000000..60f6c98f42
--- /dev/null
+++ b/examples/quick/shapes/main.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "../shared/shared.h"
+DECLARATIVE_EXAMPLE_MAIN(shapes/main)
diff --git a/examples/quick/shapes/shapes.pro b/examples/quick/shapes/shapes.pro
new file mode 100644
index 0000000000..ff6fa422fb
--- /dev/null
+++ b/examples/quick/shapes/shapes.pro
@@ -0,0 +1,30 @@
+TEMPLATE = app
+
+QT += quick qml
+SOURCES += main.cpp
+RESOURCES += shapes.qrc
+OTHER_FILES += content/main.qml \
+ content/shapegallery.qml \
+ content/interactive.qml \
+ content/sampling.qml \
+ content/clippedtigers.qml \
+ content/tiger.qml \
+ content/tapableTriangle.qml \
+ content/item2.qml \
+ content/item3.qml \
+ content/item4.qml \
+ content/item5.qml \
+ content/item6.qml \
+ content/item7.qml \
+ content/item8.qml \
+ content/item9.qml \
+ content/item10.qml \
+ content/item11.qml \
+ content/item12.qml \
+ content/item13.qml \
+ content/item14.qml \
+ content/item15.qml \
+ content/item17.qml
+
+target.path = $$[QT_INSTALL_EXAMPLES]/quick/shapes
+INSTALLS += target
diff --git a/examples/quick/shapes/shapes.qrc b/examples/quick/shapes/shapes.qrc
new file mode 100644
index 0000000000..e03c0e8a0a
--- /dev/null
+++ b/examples/quick/shapes/shapes.qrc
@@ -0,0 +1,32 @@
+<RCC>
+ <qresource prefix="/shapes">
+ <file alias="LauncherList.qml">../shared/LauncherList.qml</file>
+ <file alias="SimpleLauncherDelegate.qml">../shared/SimpleLauncherDelegate.qml</file>
+ <file alias="images/next.png">../shared/images/next.png</file>
+ <file alias="images/back.png">../shared/images/back.png</file>
+ <file alias="images/slider_handle.png">../shared/images/slider_handle.png</file>
+ <file alias="Slider.qml">../shared/Slider.qml</file>
+ <file alias="main.qml">content/main.qml</file>
+ <file alias="shapegallery.qml">content/shapegallery.qml</file>
+ <file alias="interactive.qml">content/interactive.qml</file>
+ <file alias="sampling.qml">content/sampling.qml</file>
+ <file alias="clippedtigers.qml">content/clippedtigers.qml</file>
+ <file alias="tiger.qml">content/tiger.qml</file>
+ <file alias="tapableTriangle.qml">content/tapableTriangle.qml</file>
+ <file alias="item2.qml">content/item2.qml</file>
+ <file alias="item3.qml">content/item3.qml</file>
+ <file alias="item4.qml">content/item4.qml</file>
+ <file alias="item5.qml">content/item5.qml</file>
+ <file alias="item6.qml">content/item6.qml</file>
+ <file alias="item7.qml">content/item7.qml</file>
+ <file alias="item8.qml">content/item8.qml</file>
+ <file alias="item9.qml">content/item9.qml</file>
+ <file alias="item10.qml">content/item10.qml</file>
+ <file alias="item11.qml">content/item11.qml</file>
+ <file alias="item12.qml">content/item12.qml</file>
+ <file alias="item13.qml">content/item13.qml</file>
+ <file alias="item14.qml">content/item14.qml</file>
+ <file alias="item15.qml">content/item15.qml</file>
+ <file alias="item17.qml">content/item17.qml</file>
+ </qresource>
+</RCC>
diff --git a/examples/quick/shared/LauncherList.qml b/examples/quick/shared/LauncherList.qml
index 65dec0f29f..e532b53e7f 100644
--- a/examples/quick/shared/LauncherList.qml
+++ b/examples/quick/shared/LauncherList.qml
@@ -57,10 +57,12 @@ Rectangle {
//function used to add to model A) to enforce scheme B) to allow Qt.resolveUrl in url assignments
color: "#eee"
- function addExample(name, desc, url)
- {
+ function addExample(name, desc, url) {
myModel.append({"name":name, "description":desc, "url":url})
}
+ function showExample(url) {
+ pageComponent.createObject(pageContainer, { exampleUrl: url }).show()
+ }
// The container rectangle here is used to give a nice "feel" when
// transitioning into an example.
@@ -72,10 +74,7 @@ Rectangle {
id: launcherList
clip: true
delegate: SimpleLauncherDelegate{
- onClicked: {
- var page = pageComponent.createObject(pageContainer, { exampleUrl: url })
- page.show()
- }
+ onClicked: showExample(url)
}
model: ListModel {id:myModel}
anchors.fill: parent
diff --git a/examples/quick/shared/shared.h b/examples/quick/shared/shared.h
index 317d8c70cb..18e7ff056b 100644
--- a/examples/quick/shared/shared.h
+++ b/examples/quick/shared/shared.h
@@ -66,6 +66,11 @@
f.setVersion(4, 4);\
view.setFormat(f);\
}\
+ if (qgetenv("QT_QUICK_MULTISAMPLE").toInt()) {\
+ QSurfaceFormat f = view.format();\
+ f.setSamples(4);\
+ view.setFormat(f);\
+ }\
view.connect(view.engine(), &QQmlEngine::quit, &app, &QCoreApplication::quit);\
new QQmlFileSelector(view.engine(), &view);\
view.setSource(QUrl("qrc:///" #NAME ".qml")); \
diff --git a/examples/quick/textureprovider/main.cpp b/examples/quick/textureprovider/main.cpp
index 1d5889cb5a..658620bc82 100644
--- a/examples/quick/textureprovider/main.cpp
+++ b/examples/quick/textureprovider/main.cpp
@@ -58,6 +58,10 @@ int main(int argc, char* argv[])
QGuiApplication app(argc,argv);
QQuickView view;
+ /*
+ NOTE: ETC compressed textures in PKM files are supported out-of-the-box since Qt 5.10.
+ However, we retain this example to show how custom texture providers can be integrated.
+ */
EtcProvider *provider = new EtcProvider();
provider->setBaseUrl(QUrl("qrc:///textureprovider/"));
view.engine()->addImageProvider("etc", provider);
diff --git a/examples/quick/window/CurrentScreen.qml b/examples/quick/window/CurrentScreen.qml
index 931b381d25..2703582399 100644
--- a/examples/quick/window/CurrentScreen.qml
+++ b/examples/quick/window/CurrentScreen.qml
@@ -49,7 +49,7 @@
****************************************************************************/
import QtQuick 2.3
-import QtQuick.Window 2.1
+import QtQuick.Window 2.10
import "../shared" as Shared
Item {
@@ -87,6 +87,15 @@ Item {
}
Item { width: 1; height: 1 } // spacer
+ Shared.Label { text: "manufacturer" }
+ Shared.Label { text: Screen.manufacturer ? Screen.manufacturer : "unknown" }
+
+ Shared.Label { text: "model" }
+ Shared.Label { text: Screen.model ? Screen.model : "unknown" }
+
+ Shared.Label { text: "serial number" }
+ Shared.Label { text: Screen.serialNumber ? Screen.serialNumber : "unknown" }
+
Shared.Label { text: "dimensions" }
Shared.Label { text: Screen.width + "x" + Screen.height }
diff --git a/src/3rdparty/masm/assembler/MacroAssembler.h b/src/3rdparty/masm/assembler/MacroAssembler.h
index 6e77a9ffb7..20ddcadae1 100644
--- a/src/3rdparty/masm/assembler/MacroAssembler.h
+++ b/src/3rdparty/masm/assembler/MacroAssembler.h
@@ -810,7 +810,7 @@ public:
Jump branchPtr(RelationalCondition cond, RegisterID left, TrustedImmPtr right)
{
- return branch64(cond, left, TrustedImm64(right));
+ return this->branch64(cond, left, TrustedImm64(right));
}
Jump branchPtr(RelationalCondition cond, RegisterID left, Address right)
diff --git a/src/3rdparty/masm/assembler/MacroAssemblerARM64.h b/src/3rdparty/masm/assembler/MacroAssemblerARM64.h
index d5f4acb3ca..1f94eb9032 100644
--- a/src/3rdparty/masm/assembler/MacroAssemblerARM64.h
+++ b/src/3rdparty/masm/assembler/MacroAssemblerARM64.h
@@ -718,15 +718,20 @@ public:
void or64(TrustedImm64 imm, RegisterID dest)
{
+ or64(imm, dest, dest);
+ }
+
+ void or64(TrustedImm64 imm, RegisterID src, RegisterID dest)
+ {
LogicalImmediate logicalImm = LogicalImmediate::create64(static_cast<intptr_t>(static_cast<int64_t>(imm.m_value)));
if (logicalImm.isValid()) {
- m_assembler.orr<64>(dest, dest, logicalImm);
+ m_assembler.orr<64>(dest, src, logicalImm);
return;
}
move(imm, getCachedDataTempRegisterIDAndInvalidate());
- m_assembler.orr<64>(dest, dest, dataTempRegister);
+ m_assembler.orr<64>(dest, src, dataTempRegister);
}
void rotateRight64(TrustedImm32 imm, RegisterID srcDst)
diff --git a/src/3rdparty/masm/assembler/MacroAssemblerARMv7.h b/src/3rdparty/masm/assembler/MacroAssemblerARMv7.h
index fe8170d098..d91122d4a1 100644
--- a/src/3rdparty/masm/assembler/MacroAssemblerARMv7.h
+++ b/src/3rdparty/masm/assembler/MacroAssemblerARMv7.h
@@ -815,6 +815,17 @@ public:
store8(src, setupArmAddress(address));
}
+ void store8(RegisterID src, Address address)
+ {
+ store8(src, setupArmAddress(address));
+ }
+
+ void store8(TrustedImm32 imm, Address address)
+ {
+ move(imm, dataTempRegister);
+ store8(dataTempRegister, address);
+ }
+
#if !defined(V4_BOOTSTRAP)
void store8(RegisterID src, void* address)
{
diff --git a/src/3rdparty/masm/assembler/MacroAssemblerX86_64.h b/src/3rdparty/masm/assembler/MacroAssemblerX86_64.h
index 8ee134c2fa..002caaae78 100644
--- a/src/3rdparty/masm/assembler/MacroAssemblerX86_64.h
+++ b/src/3rdparty/masm/assembler/MacroAssemblerX86_64.h
@@ -292,6 +292,12 @@ public:
or64(imm, dest);
}
+ void or64(TrustedImm64 imm, RegisterID src, RegisterID dest)
+ {
+ move(src, dest);
+ or64(imm, dest);
+ }
+
void rotateRight64(TrustedImm32 imm, RegisterID srcDst)
{
m_assembler.rorq_i8r(imm.m_value, srcDst);
@@ -328,14 +334,68 @@ public:
m_assembler.xorq_ir(imm.m_value, srcDest);
}
+ void lshift64(TrustedImm32 imm, RegisterID dest)
+ {
+ m_assembler.shlq_i8r(imm.m_value, dest);
+ }
+
+ void lshift64(RegisterID src, RegisterID dest)
+ {
+ if (src == X86Registers::ecx)
+ m_assembler.shlq_CLr(dest);
+ else {
+ ASSERT(src != dest);
+
+ // Can only shift by ecx, so we do some swapping if we see anything else.
+ swap(src, X86Registers::ecx);
+ m_assembler.shlq_CLr(dest == X86Registers::ecx ? src : dest);
+ swap(src, X86Registers::ecx);
+ }
+ }
+
+ void rshift64(TrustedImm32 imm, RegisterID dest)
+ {
+ m_assembler.sarq_i8r(imm.m_value, dest);
+ }
+
+ void rshift64(RegisterID src, RegisterID dest)
+ {
+ if (src == X86Registers::ecx)
+ m_assembler.sarq_CLr(dest);
+ else {
+ ASSERT(src != dest);
+
+ // Can only shift by ecx, so we do some swapping if we see anything else.
+ swap(src, X86Registers::ecx);
+ m_assembler.sarq_CLr(dest == X86Registers::ecx ? src : dest);
+ swap(src, X86Registers::ecx);
+ }
+ }
+
+ void urshift64(RegisterID src, TrustedImm32 imm, RegisterID dest)
+ {
+ if (src != dest)
+ move(src, dest);
+ urshift64(imm, dest);
+ }
+
void urshift64(TrustedImm32 imm, RegisterID dest)
{
m_assembler.shrq_i8r(imm.m_value, dest);
}
- void lshift64(TrustedImm32 imm, RegisterID dest)
+ void urshift64(RegisterID src, RegisterID dest)
{
- m_assembler.shlq_i8r(imm.m_value, dest);
+ if (src == X86Registers::ecx)
+ m_assembler.shrq_CLr(dest);
+ else {
+ ASSERT(src != dest);
+
+ // Can only shift by ecx, so we do some swapping if we see anything else.
+ swap(src, X86Registers::ecx);
+ m_assembler.shrq_CLr(dest == X86Registers::ecx ? src : dest);
+ swap(src, X86Registers::ecx);
+ }
}
void load64(ImplicitAddress address, RegisterID dest)
diff --git a/src/3rdparty/masm/assembler/X86Assembler.h b/src/3rdparty/masm/assembler/X86Assembler.h
index 46f2cd714a..b71cf290f8 100644
--- a/src/3rdparty/masm/assembler/X86Assembler.h
+++ b/src/3rdparty/masm/assembler/X86Assembler.h
@@ -725,6 +725,21 @@ public:
}
}
+ void sarq_CLr(RegisterID dst)
+ {
+ m_formatter.oneByteOp64(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst);
+ }
+
+ void sarq_i8r(int imm, RegisterID dst)
+ {
+ if (imm == 1)
+ m_formatter.oneByteOp64(OP_GROUP2_Ev1, GROUP2_OP_SAR, dst);
+ else {
+ m_formatter.oneByteOp64(OP_GROUP2_EvIb, GROUP2_OP_SAR, dst);
+ m_formatter.immediate8(imm);
+ }
+ }
+
void shrq_i8r(int imm, RegisterID dst)
{
// ### doesn't work when removing the "0 &&"
@@ -736,6 +751,11 @@ public:
}
}
+ void shrq_CLr(RegisterID dst)
+ {
+ m_formatter.oneByteOp64(OP_GROUP2_EvCL, GROUP2_OP_SHR, dst);
+ }
+
void shlq_i8r(int imm, RegisterID dst)
{
// ### doesn't work when removing the "0 &&"
@@ -747,7 +767,10 @@ public:
}
}
-
+ void shlq_CLr(RegisterID dst)
+ {
+ m_formatter.oneByteOp64(OP_GROUP2_EvCL, GROUP2_OP_SHL, dst);
+ }
#endif
void sarl_i8r(int imm, RegisterID dst)
@@ -795,23 +818,6 @@ public:
m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SHL, dst);
}
-#if CPU(X86_64)
- void sarq_CLr(RegisterID dst)
- {
- m_formatter.oneByteOp64(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst);
- }
-
- void sarq_i8r(int imm, RegisterID dst)
- {
- if (imm == 1)
- m_formatter.oneByteOp64(OP_GROUP2_Ev1, GROUP2_OP_SAR, dst);
- else {
- m_formatter.oneByteOp64(OP_GROUP2_EvIb, GROUP2_OP_SAR, dst);
- m_formatter.immediate8(imm);
- }
- }
-#endif
-
void imull_rr(RegisterID src, RegisterID dst)
{
m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, src);
diff --git a/src/3rdparty/masm/masm-defs.pri b/src/3rdparty/masm/masm-defs.pri
index c0c5f3d114..34d6a67451 100644
--- a/src/3rdparty/masm/masm-defs.pri
+++ b/src/3rdparty/masm/masm-defs.pri
@@ -3,6 +3,7 @@ DEFINES += ENABLE_ASSEMBLER_WX_EXCLUSIVE=1
# Avoid symbol clashes with QtScript during static linking
DEFINES += WTFReportAssertionFailure=qmlWTFReportAssertionFailure
+DEFINES += WTFReportAssertionFailureWithMessage=qmlWTFReportAssertionFailureWithMessage
DEFINES += WTFReportBacktrace=qmlWTFReportBacktrace
DEFINES += WTFInvokeCrashHook=qmlWTFInvokeCrashHook
diff --git a/src/3rdparty/masm/stubs/WTFStubs.cpp b/src/3rdparty/masm/stubs/WTFStubs.cpp
index 610b632baf..ea7e2d78e0 100644
--- a/src/3rdparty/masm/stubs/WTFStubs.cpp
+++ b/src/3rdparty/masm/stubs/WTFStubs.cpp
@@ -112,6 +112,11 @@ void dataLogFString(const char* str)
}
extern "C" {
+// When adding a new stub here do not forget to add
+// DEFINES += StubFunctionName=qmlStubFunctionName
+// for example:
+// DEFINES += WTFReportAssertionFailureWithMessage=qmlWTFReportAssertionFailureWithMessage
+// to prevent "duplicate symbol" error during static library linking. See bugs QTBUG-35041 and QTBUG-63050
void WTFReportAssertionFailure(const char* file, int line, const char* function, const char*assertion)
{
diff --git a/src/3rdparty/masm/yarr/YarrPattern.cpp b/src/3rdparty/masm/yarr/YarrPattern.cpp
index ae527f065f..c7e5b6b09b 100644
--- a/src/3rdparty/masm/yarr/YarrPattern.cpp
+++ b/src/3rdparty/masm/yarr/YarrPattern.cpp
@@ -233,7 +233,7 @@ private:
ranges.insert(i, CharacterRange(lo, hi));
return;
}
- // Okay, since we didn't hit the last case, the end of the new range is definitely at or after the begining
+ // Okay, since we didn't hit the last case, the end of the new range is definitely at or after the beginning
// If the new range start at or before the end of the last range, then the overlap (if it starts one after the
// end of the last range they concatenate, which is just as good.
if (lo <= (ranges[i].end + 1)) {
diff --git a/src/imports/builtins/builtins.qmltypes b/src/imports/builtins/builtins.qmltypes
index c2f8f5b521..5fb68d15d9 100644
--- a/src/imports/builtins/builtins.qmltypes
+++ b/src/imports/builtins/builtins.qmltypes
@@ -461,7 +461,10 @@ Module {
"AA_CompressHighFrequencyEvents": 25,
"AA_DontCheckOpenGLContextThreadAffinity": 26,
"AA_DisableShaderDiskCache": 27,
- "AA_AttributeCount": 28
+ "AA_DontShowShortcutsInContextMenus": 28,
+ "AA_CompressTabletEvents": 29,
+ "AA_DisableWindowContextHelpButton": 30,
+ "AA_AttributeCount": 31
}
}
Enum {
diff --git a/src/imports/folderlistmodel/fileinfothread.cpp b/src/imports/folderlistmodel/fileinfothread.cpp
index d3e256bb7e..4ef8d02810 100644
--- a/src/imports/folderlistmodel/fileinfothread.cpp
+++ b/src/imports/folderlistmodel/fileinfothread.cpp
@@ -222,8 +222,10 @@ void FileInfoThread::run()
if (abort) {
return;
}
- if (currentPath.isEmpty() || !needUpdate)
+ if (currentPath.isEmpty() || !needUpdate) {
+ emit statusChanged(currentPath.isEmpty() ? QQuickFolderListModel::Null : QQuickFolderListModel::Ready);
condition.wait(&mutex);
+ }
if (abort) {
return;
@@ -231,6 +233,7 @@ void FileInfoThread::run()
if (!currentPath.isEmpty()) {
updateFiles = true;
+ emit statusChanged(QQuickFolderListModel::Loading);
}
if (updateFiles)
getFileInfos(currentPath);
diff --git a/src/imports/folderlistmodel/fileinfothread_p.h b/src/imports/folderlistmodel/fileinfothread_p.h
index b505ece750..67d2a1f5f7 100644
--- a/src/imports/folderlistmodel/fileinfothread_p.h
+++ b/src/imports/folderlistmodel/fileinfothread_p.h
@@ -59,6 +59,7 @@
#include <QDir>
#include "fileproperty_p.h"
+#include "qquickfolderlistmodel.h"
class FileInfoThread : public QThread
{
@@ -68,6 +69,7 @@ Q_SIGNALS:
void directoryChanged(const QString &directory, const QList<FileProperty> &list) const;
void directoryUpdated(const QString &directory, const QList<FileProperty> &list, int fromIndex, int toIndex) const;
void sortFinished(const QList<FileProperty> &list) const;
+ void statusChanged(QQuickFolderListModel::Status status) const;
public:
FileInfoThread(QObject *parent = 0);
diff --git a/src/imports/folderlistmodel/plugin.cpp b/src/imports/folderlistmodel/plugin.cpp
index ef719109bd..e90c8724e0 100644
--- a/src/imports/folderlistmodel/plugin.cpp
+++ b/src/imports/folderlistmodel/plugin.cpp
@@ -59,13 +59,19 @@ class QmlFolderListModelPlugin : public QQmlExtensionPlugin
public:
QmlFolderListModelPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); }
- void registerTypes(const char *uri) Q_DECL_OVERRIDE
+ void registerTypes(const char *uri) override
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.folderlistmodel"));
qmlRegisterType<QQuickFolderListModel>(uri,1,0,"FolderListModel");
qmlRegisterType<QQuickFolderListModel>(uri,2,0,"FolderListModel");
qmlRegisterType<QQuickFolderListModel,1>(uri,2,1,"FolderListModel");
qmlRegisterType<QQuickFolderListModel,2>(uri,2,2,"FolderListModel");
+
+ // Auto-increment the import to stay in sync with ALL future QtQuick minor versions from 5.11 onward
+ qmlRegisterModule(uri, 2, QT_VERSION_MINOR);
+
+ // revision in Qt 5.11: added status property
+ qmlRegisterType<QQuickFolderListModel,11>(uri, 2, 11, "FolderListModel");
}
};
//![class decl]
diff --git a/src/imports/folderlistmodel/plugins.qmltypes b/src/imports/folderlistmodel/plugins.qmltypes
index e77b633932..a336b55022 100644
--- a/src/imports/folderlistmodel/plugins.qmltypes
+++ b/src/imports/folderlistmodel/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable Qt.labs.folderlistmodel 2.2'
+// 'qmlplugindump -nonrelocatable Qt.labs.folderlistmodel 2.11'
Module {
dependencies: ["QtQuick 2.8"]
@@ -15,9 +15,10 @@ Module {
"Qt.labs.folderlistmodel/FolderListModel 1.0",
"Qt.labs.folderlistmodel/FolderListModel 2.0",
"Qt.labs.folderlistmodel/FolderListModel 2.1",
+ "Qt.labs.folderlistmodel/FolderListModel 2.11",
"Qt.labs.folderlistmodel/FolderListModel 2.2"
]
- exportMetaObjectRevisions: [0, 0, 1, 2]
+ exportMetaObjectRevisions: [0, 0, 1, 11, 2]
Enum {
name: "SortField"
values: {
@@ -28,6 +29,14 @@ Module {
"Type": 4
}
}
+ Enum {
+ name: "Status"
+ values: {
+ "Null": 0,
+ "Ready": 1,
+ "Loading": 2
+ }
+ }
Property { name: "folder"; type: "QUrl" }
Property { name: "rootFolder"; type: "QUrl" }
Property { name: "parentFolder"; type: "QUrl"; isReadonly: true }
@@ -42,8 +51,10 @@ Module {
Property { name: "showOnlyReadable"; type: "bool" }
Property { name: "caseSensitive"; revision: 2; type: "bool" }
Property { name: "count"; type: "int"; isReadonly: true }
+ Property { name: "status"; revision: 11; type: "Status"; isReadonly: true }
Signal { name: "rowCountChanged" }
Signal { name: "countChanged"; revision: 1 }
+ Signal { name: "statusChanged"; revision: 11 }
Method {
name: "isFolder"
type: "bool"
diff --git a/src/imports/folderlistmodel/qquickfolderlistmodel.cpp b/src/imports/folderlistmodel/qquickfolderlistmodel.cpp
index fdcce9c685..b3c1de6cc9 100644
--- a/src/imports/folderlistmodel/qquickfolderlistmodel.cpp
+++ b/src/imports/folderlistmodel/qquickfolderlistmodel.cpp
@@ -55,7 +55,7 @@ public:
: q_ptr(q),
sortField(QQuickFolderListModel::Name), sortReversed(false), showFiles(true),
showDirs(true), showDirsFirst(false), showDotAndDotDot(false), showOnlyReadable(false),
- showHidden(false), caseSensitive(true)
+ showHidden(false), caseSensitive(true), status(QQuickFolderListModel::Null)
{
nameFilters << QLatin1String("*");
}
@@ -77,6 +77,7 @@ public:
bool showOnlyReadable;
bool showHidden;
bool caseSensitive;
+ QQuickFolderListModel::Status status;
~QQuickFolderListModelPrivate() {}
void init();
@@ -86,6 +87,7 @@ public:
void _q_directoryChanged(const QString &directory, const QList<FileProperty> &list);
void _q_directoryUpdated(const QString &directory, const QList<FileProperty> &list, int fromIndex, int toIndex);
void _q_sortFinished(const QList<FileProperty> &list);
+ void _q_statusChanged(QQuickFolderListModel::Status s);
static QString resolvePath(const QUrl &path);
};
@@ -95,12 +97,15 @@ void QQuickFolderListModelPrivate::init()
{
Q_Q(QQuickFolderListModel);
qRegisterMetaType<QList<FileProperty> >("QList<FileProperty>");
+ qRegisterMetaType<QQuickFolderListModel::Status>("QQuickFolderListModel::Status");
q->connect(&fileInfoThread, SIGNAL(directoryChanged(QString,QList<FileProperty>)),
q, SLOT(_q_directoryChanged(QString,QList<FileProperty>)));
q->connect(&fileInfoThread, SIGNAL(directoryUpdated(QString,QList<FileProperty>,int,int)),
q, SLOT(_q_directoryUpdated(QString,QList<FileProperty>,int,int)));
q->connect(&fileInfoThread, SIGNAL(sortFinished(QList<FileProperty>)),
q, SLOT(_q_sortFinished(QList<FileProperty>)));
+ q->connect(&fileInfoThread, SIGNAL(statusChanged(QQuickFolderListModel::Status)),
+ q, SLOT(_q_statusChanged(QQuickFolderListModel::Status)));
q->connect(q, SIGNAL(rowCountChanged()), q, SIGNAL(countChanged()));
}
@@ -198,6 +203,16 @@ void QQuickFolderListModelPrivate::_q_sortFinished(const QList<FileProperty> &li
q->endInsertRows();
}
+void QQuickFolderListModelPrivate::_q_statusChanged(QQuickFolderListModel::Status s)
+{
+ Q_Q(QQuickFolderListModel);
+
+ if (status != s) {
+ status = s;
+ emit q->statusChanged();
+ }
+}
+
QString QQuickFolderListModelPrivate::resolvePath(const QUrl &path)
{
QString localPath = QQmlFile::urlToLocalFileOrQrc(path);
@@ -209,7 +224,7 @@ QString QQuickFolderListModelPrivate::resolvePath(const QUrl &path)
}
/*!
- \qmlmodule Qt.labs.folderlistmodel 2.1
+ \qmlmodule Qt.labs.folderlistmodel 2.11
\title Qt Labs FolderListModel QML Types
\ingroup qmlmodules
\brief The FolderListModel provides a model of the contents of a file system folder.
@@ -217,7 +232,7 @@ QString QQuickFolderListModelPrivate::resolvePath(const QUrl &path)
To use this module, import the module with the following line:
\code
- import Qt.labs.folderlistmodel 2.1
+ import Qt.labs.folderlistmodel 2.11
\endcode
*/
@@ -236,7 +251,7 @@ QString QQuickFolderListModelPrivate::resolvePath(const QUrl &path)
\e{Elements in the Qt.labs module are not guaranteed to remain compatible
in future versions.}
- \b{import Qt.labs.folderlistmodel 2.1}
+ \b{import Qt.labs.folderlistmodel 2.11}
The \l folder property specifies the folder to access. Information about the
files and directories in the folder is supplied via the model's interface.
@@ -282,7 +297,7 @@ QString QQuickFolderListModelPrivate::resolvePath(const QUrl &path)
\qml
import QtQuick 2.0
- import Qt.labs.folderlistmodel 2.1
+ import Qt.labs.folderlistmodel 2.11
ListView {
width: 200; height: 400
@@ -437,6 +452,10 @@ void QQuickFolderListModel::setFolder(const QUrl &folder)
d->data.clear();
endResetModel();
emit rowCountChanged();
+ if (d->status != QQuickFolderListModel::Null) {
+ d->status = QQuickFolderListModel::Null;
+ emit statusChanged();
+ }
return;
}
@@ -795,6 +814,46 @@ void QQuickFolderListModel::setCaseSensitive(bool on)
}
/*!
+ \qmlproperty enumeration FolderListModel::status
+ \since 5.11
+
+ This property holds the status of folder reading. It can be one of:
+ \list
+ \li FolderListModel.Null - no \a folder has been set
+ \li FolderListModel.Ready - the folder has been loaded
+ \li FolderListModel.Loading - the folder is currently being loaded
+ \endlist
+
+ Use this status to provide an update or respond to the status change in some way.
+ For example, you could:
+
+ \list
+ \li Trigger a state change:
+ \qml
+ State { name: 'loaded'; when: folderModel.status == FolderListModel.Ready }
+ \endqml
+
+ \li Implement an \c onStatusChanged signal handler:
+ \qml
+ FolderListModel {
+ id: folderModel
+ onStatusChanged: if (folderModel.status == FolderListModel.Ready) console.log('Loaded')
+ }
+ \endqml
+
+ \li Bind to the status value:
+ \qml
+ Text { text: folderModel.status == FolderListModel.Ready ? 'Loaded' : 'Not loaded' }
+ \endqml
+ \endlist
+*/
+QQuickFolderListModel::Status QQuickFolderListModel::status() const
+{
+ Q_D(const QQuickFolderListModel);
+ return d->status;
+}
+
+/*!
\qmlmethod var FolderListModel::get(int index, string property)
Get the folder property for the given index. The following properties
diff --git a/src/imports/folderlistmodel/qquickfolderlistmodel.h b/src/imports/folderlistmodel/qquickfolderlistmodel.h
index dee73dff3e..a449f0dd0f 100644
--- a/src/imports/folderlistmodel/qquickfolderlistmodel.h
+++ b/src/imports/folderlistmodel/qquickfolderlistmodel.h
@@ -75,6 +75,7 @@ class QQuickFolderListModel : public QAbstractListModel, public QQmlParserStatus
Q_PROPERTY(bool showOnlyReadable READ showOnlyReadable WRITE setShowOnlyReadable)
Q_PROPERTY(bool caseSensitive READ caseSensitive WRITE setCaseSensitive REVISION 2)
Q_PROPERTY(int count READ count NOTIFY countChanged)
+ Q_PROPERTY(Status status READ status NOTIFY statusChanged REVISION 11)
//![class props]
//![abslistmodel]
@@ -137,6 +138,10 @@ public:
void setShowOnlyReadable(bool on);
bool caseSensitive() const;
void setCaseSensitive(bool on);
+
+ enum Status { Null, Ready, Loading };
+ Q_ENUM(Status)
+ Status status() const;
//![prop funcs]
Q_INVOKABLE bool isFolder(int index) const;
@@ -155,6 +160,7 @@ Q_SIGNALS:
void folderChanged();
void rowCountChanged() const;
Q_REVISION(1) void countChanged() const;
+ Q_REVISION(11) void statusChanged();
//![notifier]
//![class end]
@@ -168,6 +174,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_directoryChanged(const QString &directory, const QList<FileProperty> &list))
Q_PRIVATE_SLOT(d_func(), void _q_directoryUpdated(const QString &directory, const QList<FileProperty> &list, int fromIndex, int toIndex))
Q_PRIVATE_SLOT(d_func(), void _q_sortFinished(const QList<FileProperty> &list))
+ Q_PRIVATE_SLOT(d_func(), void _q_statusChanged(QQuickFolderListModel::Status s))
};
//![class end]
diff --git a/src/imports/handlers/handlers.pro b/src/imports/handlers/handlers.pro
new file mode 100644
index 0000000000..0e32644773
--- /dev/null
+++ b/src/imports/handlers/handlers.pro
@@ -0,0 +1,11 @@
+CXX_MODULE = qml
+TARGET = handlersplugin
+TARGETPATH = Qt/labs/handlers
+IMPORT_VERSION = 1.0
+
+SOURCES += \
+ plugin.cpp
+
+QT += quick-private qml-private
+
+load(qml_plugin)
diff --git a/src/imports/handlers/plugin.cpp b/src/imports/handlers/plugin.cpp
new file mode 100644
index 0000000000..d26ef2b2d4
--- /dev/null
+++ b/src/imports/handlers/plugin.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtQml/qqmlextensionplugin.h>
+
+#include <private/qquickhandlersmodule_p.h>
+
+static void initResources()
+{
+#ifdef QT_STATIC
+ Q_INIT_RESOURCE(qmake_Qt_labs_handlers);
+#endif
+}
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmlmodule Qt.labs.handlers 1.0
+ \title Qt Quick Pointer Handlers
+ \ingroup qmlmodules
+ \brief Provides QML types for handling pointer events.
+
+ This QML module contains types for handling pointer events, which are an abstraction
+ of mouse, touch and tablet events.
+
+ To use the types in this module, import the module with the following line:
+
+ \code
+ import Qt.labs.handlers 1.0
+ \endcode
+*/
+
+
+//![class decl]
+class QtQuickHandlersPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
+public:
+ QtQuickHandlersPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); }
+ void registerTypes(const char *uri) override
+ {
+ Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.handlers"));
+ Q_UNUSED(uri);
+ QQuickHandlersModule::defineModule();
+ }
+};
+//![class decl]
+
+QT_END_NAMESPACE
+
+#include "plugin.moc"
diff --git a/src/imports/handlers/plugins.qmltypes b/src/imports/handlers/plugins.qmltypes
new file mode 100644
index 0000000000..f51e1e4bf3
--- /dev/null
+++ b/src/imports/handlers/plugins.qmltypes
@@ -0,0 +1,308 @@
+import QtQuick.tooling 1.2
+
+// This file describes the plugin-supplied types contained in the library.
+// It is used for QML tooling purposes only.
+//
+// This file was auto-generated by:
+// 'qmlplugindump -nonrelocatable Qt.labs.handlers 1.0'
+
+Module {
+ dependencies: ["QtQuick 2.8"]
+ Component {
+ name: "QQuickDragAxis"
+ prototype: "QObject"
+ exports: ["Qt.labs.handlers/DragAxis 1.0"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ Property { name: "minimum"; type: "double" }
+ Property { name: "maximum"; type: "double" }
+ Property { name: "enabled"; type: "bool" }
+ }
+ Component {
+ name: "QQuickDragHandler"
+ prototype: "QQuickSinglePointHandler"
+ exports: ["Qt.labs.handlers/DragHandler 1.0"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "xAxis"; type: "QQuickDragAxis"; isReadonly: true; isPointer: true }
+ Property { name: "yAxis"; type: "QQuickDragAxis"; isReadonly: true; isPointer: true }
+ Property { name: "translation"; type: "QVector2D"; isReadonly: true }
+ Method { name: "enforceConstraints" }
+ }
+ Component {
+ name: "QQuickEventPoint"
+ prototype: "QObject"
+ exports: ["Qt.labs.handlers/EventPoint 1.0"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ Enum {
+ name: "States"
+ values: {
+ "Pressed": 1,
+ "Updated": 2,
+ "Stationary": 4,
+ "Released": 8
+ }
+ }
+ Enum {
+ name: "GrabState"
+ values: {
+ "GrabPassive": 1,
+ "UngrabPassive": 2,
+ "CancelGrabPassive": 3,
+ "OverrideGrabPassive": 4,
+ "GrabExclusive": 16,
+ "UngrabExclusive": 32,
+ "CancelGrabExclusive": 48
+ }
+ }
+ Property { name: "event"; type: "QQuickPointerEvent"; isReadonly: true; isPointer: true }
+ Property { name: "position"; type: "QPointF"; isReadonly: true }
+ Property { name: "scenePosition"; type: "QPointF"; isReadonly: true }
+ Property { name: "scenePressPosition"; type: "QPointF"; isReadonly: true }
+ Property { name: "sceneGrabPosition"; type: "QPointF"; isReadonly: true }
+ Property { name: "state"; type: "State"; isReadonly: true }
+ Property { name: "pointId"; type: "int"; isReadonly: true }
+ Property { name: "timeHeld"; type: "double"; isReadonly: true }
+ Property { name: "velocity"; type: "QVector2D"; isReadonly: true }
+ Property { name: "accepted"; type: "bool" }
+ Property { name: "exclusiveGrabber"; type: "QObject"; isPointer: true }
+ }
+ Component {
+ name: "QQuickEventTouchPoint"
+ prototype: "QQuickEventPoint"
+ exports: ["Qt.labs.handlers/EventTouchPoint 1.0"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ Property { name: "rotation"; type: "double"; isReadonly: true }
+ Property { name: "pressure"; type: "double"; isReadonly: true }
+ Property { name: "ellipseDiameters"; type: "QSizeF"; isReadonly: true }
+ Property { name: "uniqueId"; type: "QPointingDeviceUniqueId"; isReadonly: true }
+ }
+ Component {
+ name: "QQuickMultiPointHandler"
+ prototype: "QQuickPointerDeviceHandler"
+ Property { name: "minimumPointCount"; type: "int" }
+ Property { name: "maximumPointCount"; type: "int" }
+ Property { name: "pointDistanceThreshold"; type: "double" }
+ }
+ Component {
+ name: "QQuickPinchHandler"
+ prototype: "QQuickMultiPointHandler"
+ exports: ["Qt.labs.handlers/PinchHandler 1.0"]
+ exportMetaObjectRevisions: [0]
+ Enum {
+ name: "PinchOrigin"
+ values: {
+ "FirstPoint": 0,
+ "PinchCenter": 1,
+ "TargetCenter": 2
+ }
+ }
+ Property { name: "minimumScale"; type: "double" }
+ Property { name: "maximumScale"; type: "double" }
+ Property { name: "minimumRotation"; type: "double" }
+ Property { name: "maximumRotation"; type: "double" }
+ Property { name: "pinchOrigin"; type: "PinchOrigin" }
+ Property { name: "centroid"; type: "QPointF"; isReadonly: true }
+ Property { name: "centroidVelocity"; type: "QVector2D"; isReadonly: true }
+ Property { name: "scale"; type: "double"; isReadonly: true }
+ Property { name: "rotation"; type: "double"; isReadonly: true }
+ Property { name: "translation"; type: "QVector2D"; isReadonly: true }
+ Property { name: "minimumX"; type: "double" }
+ Property { name: "maximumX"; type: "double" }
+ Property { name: "minimumY"; type: "double" }
+ Property { name: "maximumY"; type: "double" }
+ Signal { name: "updated" }
+ }
+ Component {
+ name: "QQuickPointHandler"
+ prototype: "QQuickSinglePointHandler"
+ exports: ["Qt.labs.handlers/PointHandler 1.0"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "translation"; type: "QVector2D"; isReadonly: true }
+ }
+ Component {
+ name: "QQuickPointerDevice"
+ prototype: "QObject"
+ exports: ["Qt.labs.handlers/PointerDevice 1.0"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ Enum {
+ name: "DeviceType"
+ values: {
+ "UnknownDevice": 0,
+ "Mouse": 1,
+ "TouchScreen": 2,
+ "TouchPad": 4,
+ "Puck": 8,
+ "Stylus": 16,
+ "Airbrush": 32,
+ "AllDevices": 63
+ }
+ }
+ Enum {
+ name: "DeviceTypes"
+ values: {
+ "UnknownDevice": 0,
+ "Mouse": 1,
+ "TouchScreen": 2,
+ "TouchPad": 4,
+ "Puck": 8,
+ "Stylus": 16,
+ "Airbrush": 32,
+ "AllDevices": 63
+ }
+ }
+ Enum {
+ name: "PointerType"
+ values: {
+ "GenericPointer": 1,
+ "Finger": 2,
+ "Pen": 4,
+ "Eraser": 8,
+ "Cursor": 16,
+ "AllPointerTypes": 31
+ }
+ }
+ Enum {
+ name: "PointerTypes"
+ values: {
+ "GenericPointer": 1,
+ "Finger": 2,
+ "Pen": 4,
+ "Eraser": 8,
+ "Cursor": 16,
+ "AllPointerTypes": 31
+ }
+ }
+ Enum {
+ name: "CapabilityFlag"
+ values: {
+ "Position": 1,
+ "Area": 2,
+ "Pressure": 4,
+ "Velocity": 8,
+ "Scroll": 256,
+ "Hover": 512,
+ "Rotation": 1024,
+ "XTilt": 2048,
+ "YTilt": 4096
+ }
+ }
+ Enum {
+ name: "Capabilities"
+ values: {
+ "Position": 1,
+ "Area": 2,
+ "Pressure": 4,
+ "Velocity": 8,
+ "Scroll": 256,
+ "Hover": 512,
+ "Rotation": 1024,
+ "XTilt": 2048,
+ "YTilt": 4096
+ }
+ }
+ Property { name: "type"; type: "DeviceType"; isReadonly: true }
+ Property { name: "pointerType"; type: "PointerType"; isReadonly: true }
+ Property { name: "capabilities"; type: "Capabilities"; isReadonly: true }
+ Property { name: "maximumTouchPoints"; type: "int"; isReadonly: true }
+ Property { name: "buttonCount"; type: "int"; isReadonly: true }
+ Property { name: "name"; type: "string"; isReadonly: true }
+ Property { name: "uniqueId"; type: "QPointingDeviceUniqueId"; isReadonly: true }
+ }
+ Component {
+ name: "QQuickPointerDeviceHandler"
+ prototype: "QQuickPointerHandler"
+ Property { name: "acceptedDevices"; type: "QQuickPointerDevice::DeviceTypes" }
+ Property { name: "acceptedPointerTypes"; type: "QQuickPointerDevice::PointerTypes" }
+ Property { name: "acceptedModifiers"; type: "Qt::KeyboardModifiers" }
+ Method {
+ name: "setAcceptedDevices"
+ Parameter { name: "acceptedDevices"; type: "QQuickPointerDevice::DeviceTypes" }
+ }
+ Method {
+ name: "setAcceptedPointerTypes"
+ Parameter { name: "acceptedPointerTypes"; type: "QQuickPointerDevice::PointerTypes" }
+ }
+ Method {
+ name: "setAcceptedModifiers"
+ Parameter { name: "acceptedModifiers"; type: "Qt::KeyboardModifiers" }
+ }
+ }
+ Component {
+ name: "QQuickPointerEvent"
+ prototype: "QObject"
+ exports: ["Qt.labs.handlers/PointerEvent 1.0"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ Property { name: "device"; type: "const QQuickPointerDevice"; isReadonly: true; isPointer: true }
+ Property { name: "modifiers"; type: "Qt::KeyboardModifiers"; isReadonly: true }
+ Property { name: "button"; type: "Qt::MouseButtons"; isReadonly: true }
+ Property { name: "buttons"; type: "Qt::MouseButtons"; isReadonly: true }
+ }
+ Component {
+ name: "QQuickPointerHandler"
+ prototype: "QObject"
+ exports: ["Qt.labs.handlers/PointerHandler 1.0"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ Enum {
+ name: "GrabPermissions"
+ values: {
+ "TakeOverForbidden": 0,
+ "CanTakeOverFromHandlersOfSameType": 1,
+ "CanTakeOverFromHandlersOfDifferentType": 2,
+ "CanTakeOverFromItems": 4,
+ "CanTakeOverFromAnything": 15,
+ "ApprovesTakeOverByHandlersOfSameType": 16,
+ "ApprovesTakeOverByHandlersOfDifferentType": 32,
+ "ApprovesTakeOverByItems": 64,
+ "ApprovesCancellation": 128,
+ "ApprovesTakeOverByAnything": 240
+ }
+ }
+ Property { name: "enabled"; type: "bool" }
+ Property { name: "active"; type: "bool"; isReadonly: true }
+ Property { name: "target"; type: "QQuickItem"; isPointer: true }
+ Property { name: "parent"; type: "QQuickItem"; isReadonly: true; isPointer: true }
+ Property { name: "grabPermissions"; type: "GrabPermissions" }
+ Signal {
+ name: "grabChanged"
+ Parameter { name: "point"; type: "QQuickEventPoint"; isPointer: true }
+ }
+ Signal { name: "grabPermissionChanged" }
+ Signal {
+ name: "canceled"
+ Parameter { name: "point"; type: "QQuickEventPoint"; isPointer: true }
+ }
+ }
+ Component {
+ name: "QQuickSinglePointHandler"
+ prototype: "QQuickPointerDeviceHandler"
+ Property { name: "acceptedButtons"; type: "Qt::MouseButtons" }
+ Property { name: "point"; type: "QQuickHandlerPoint"; isReadonly: true }
+ Signal { name: "singlePointGrabChanged" }
+ }
+ Component {
+ name: "QQuickTapHandler"
+ prototype: "QQuickSinglePointHandler"
+ exports: ["Qt.labs.handlers/TapHandler 1.0"]
+ exportMetaObjectRevisions: [0]
+ Enum {
+ name: "GesturePolicy"
+ values: {
+ "DragThreshold": 0,
+ "WithinBounds": 1,
+ "ReleaseWithinBounds": 2
+ }
+ }
+ Property { name: "pressed"; type: "bool"; isReadonly: true }
+ Property { name: "tapCount"; type: "int"; isReadonly: true }
+ Property { name: "timeHeld"; type: "double"; isReadonly: true }
+ Property { name: "longPressThreshold"; type: "double" }
+ Property { name: "gesturePolicy"; type: "GesturePolicy" }
+ Signal { name: "tapped" }
+ Signal { name: "longPressed" }
+ }
+}
diff --git a/src/imports/handlers/qmldir b/src/imports/handlers/qmldir
new file mode 100644
index 0000000000..4896348c2e
--- /dev/null
+++ b/src/imports/handlers/qmldir
@@ -0,0 +1,5 @@
+module Qt.labs.handlers
+plugin handlersplugin
+classname QtQuickHandlersPlugin
+typeinfo plugins.qmltypes
+
diff --git a/src/imports/imports.pro b/src/imports/imports.pro
index c03224958c..5d7e434884 100644
--- a/src/imports/imports.pro
+++ b/src/imports/imports.pro
@@ -14,6 +14,7 @@ qtConfig(statemachine): SUBDIRS += statemachine
qtHaveModule(quick) {
SUBDIRS += \
+ handlers \
layouts \
qtquick2 \
window \
@@ -22,6 +23,8 @@ qtHaveModule(quick) {
qtConfig(systemsemaphore): SUBDIRS += sharedimage
qtConfig(quick-particles): \
SUBDIRS += particles
+
+ SUBDIRS += shapes
}
qtHaveModule(xmlpatterns) : SUBDIRS += xmllistmodel
diff --git a/src/imports/layouts/plugin.cpp b/src/imports/layouts/plugin.cpp
index da5f264ab5..fc3938c5d8 100644
--- a/src/imports/layouts/plugin.cpp
+++ b/src/imports/layouts/plugin.cpp
@@ -61,7 +61,7 @@ public:
{
initResources();
}
- void registerTypes(const char *uri) Q_DECL_OVERRIDE
+ void registerTypes(const char *uri) override
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.Layouts"));
Q_UNUSED(uri);
diff --git a/src/imports/layouts/qquicklayout.cpp b/src/imports/layouts/qquicklayout.cpp
index df64b593d9..7d51ec3ca9 100644
--- a/src/imports/layouts/qquicklayout.cpp
+++ b/src/imports/layouts/qquicklayout.cpp
@@ -95,6 +95,8 @@ QQuickLayoutAttached::QQuickLayoutAttached(QObject *parent)
m_maximumWidth(std::numeric_limits<qreal>::infinity()),
m_maximumHeight(std::numeric_limits<qreal>::infinity()),
m_defaultMargins(0),
+ m_fallbackWidth(-1),
+ m_fallbackHeight(-1),
m_row(-1),
m_column(-1),
m_rowSpan(1),
@@ -767,6 +769,12 @@ bool QQuickLayout::shouldIgnoreItem(QQuickItem *child, QQuickLayoutAttached *&in
return ignoreItem;
}
+void QQuickLayout::checkAnchors(QQuickItem *item) const
+{
+ if (QQuickItemPrivate::get(item)->_anchors)
+ qmlWarning(item) << "Detected anchors on an item that is part of a layout. This is undefined behavior.";
+}
+
void QQuickLayout::itemChange(ItemChange change, const ItemChangeData &value)
{
if (change == ItemChildAddedChange) {
@@ -1049,39 +1057,32 @@ void QQuickLayout::effectiveSizeHints_helper(QQuickItem *item, QSizeF *cachedSiz
prefHeight = qCeil(item->implicitHeight());
// If that fails, make an ultimate fallback to width/height
-
- if (!info && (prefWidth < 0 || prefHeight < 0))
- info = attachedLayoutObject(item);
-
- if (useFallbackToWidthOrHeight && info) {
- /* This block is a bit hacky, but if we want to support using width/height
- as preferred size hints in layouts, (which we think most people expect),
- we only want to use the initial width.
- This is because the width will change due to layout rearrangement, and the preferred
- width should return the same value, regardless of the current width.
- We therefore store the width in the implicitWidth attached property.
- Since the layout listens to changes of implicitWidth, (it will
- basically cause an invalidation of the layout), we have to disable that
- notification while we set the implicit width (and height).
-
- Only use this fallback the first time the size hint is queried. Otherwise, we might
- end up picking a width that is different than what was specified in the QML.
+ if (useFallbackToWidthOrHeight && !prefS.isValid()) {
+ /* If we want to support using width/height as preferred size hints in
+ layouts, (which we think most people expect), we only want to use the
+ initial width.
+ This is because the width will change due to layout rearrangement,
+ and the preferred width should return the same value, regardless of
+ the current width.
+ We therefore store this initial width in the attached layout object
+ and reuse it if needed rather than querying the width another time.
+ That means we need to ensure that an Layout attached object is available
+ by creating one if necessary.
*/
- if (prefWidth < 0 || prefHeight < 0) {
- item->blockSignals(true);
- if (prefWidth < 0) {
- prefWidth = item->width();
- item->setImplicitWidth(prefWidth);
- }
- if (prefHeight < 0) {
- prefHeight = item->height();
- item->setImplicitHeight(prefHeight);
- }
- item->blockSignals(false);
- }
- }
+ if (!info)
+ info = attachedLayoutObject(item);
+ auto updatePreferredSizes = [](qreal &cachedSize, qreal &attachedSize, qreal size) {
+ if (cachedSize < 0) {
+ if (attachedSize < 0)
+ attachedSize = size;
+ cachedSize = attachedSize;
+ }
+ };
+ updatePreferredSizes(prefWidth, info->m_fallbackWidth, item->width());
+ updatePreferredSizes(prefHeight, info->m_fallbackHeight, item->height());
+ }
// Normalize again after the implicit hints have been gathered
expandSize(prefS, minS);
diff --git a/src/imports/layouts/qquicklayout_p.h b/src/imports/layouts/qquicklayout_p.h
index 113498eb2b..b31bffa290 100644
--- a/src/imports/layouts/qquicklayout_p.h
+++ b/src/imports/layouts/qquicklayout_p.h
@@ -75,7 +75,7 @@ public:
static QQuickLayoutAttached *qmlAttachedProperties(QObject *object);
- void componentComplete() Q_DECL_OVERRIDE;
+ void componentComplete() override;
virtual QSizeF sizeHint(Qt::SizeHint whichSizeHint) const = 0;
virtual void setAlignment(QQuickItem *item, Qt::Alignment align) = 0;
virtual void invalidate(QQuickItem * childItem = 0);
@@ -91,22 +91,23 @@ public:
static void effectiveSizeHints_helper(QQuickItem *item, QSizeF *cachedSizeHints, QQuickLayoutAttached **info, bool useFallbackToWidthOrHeight);
static QLayoutPolicy::Policy effectiveSizePolicy_helper(QQuickItem *item, Qt::Orientation orientation, QQuickLayoutAttached *info);
bool shouldIgnoreItem(QQuickItem *child, QQuickLayoutAttached *&info, QSizeF *sizeHints) const;
+ void checkAnchors(QQuickItem *item) const;
- void itemChange(ItemChange change, const ItemChangeData &value) Q_DECL_OVERRIDE;
- void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
+ void itemChange(ItemChange change, const ItemChangeData &value) override;
+ void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
bool isReady() const;
void deactivateRecur();
/* QQuickItemChangeListener */
- void itemSiblingOrderChanged(QQuickItem *item) Q_DECL_OVERRIDE;
- void itemImplicitWidthChanged(QQuickItem *item) Q_DECL_OVERRIDE;
- void itemImplicitHeightChanged(QQuickItem *item) Q_DECL_OVERRIDE;
- void itemDestroyed(QQuickItem *item) Q_DECL_OVERRIDE;
- void itemVisibilityChanged(QQuickItem *item) Q_DECL_OVERRIDE;
+ void itemSiblingOrderChanged(QQuickItem *item) override;
+ void itemImplicitWidthChanged(QQuickItem *item) override;
+ void itemImplicitHeightChanged(QQuickItem *item) override;
+ void itemDestroyed(QQuickItem *item) override;
+ void itemVisibilityChanged(QQuickItem *item) override;
protected:
- void updatePolish() Q_DECL_OVERRIDE;
+ void updatePolish() override;
enum Orientation {
Vertical = 0,
@@ -294,6 +295,9 @@ private:
qreal m_defaultMargins;
QMarginsF m_margins;
+ qreal m_fallbackWidth;
+ qreal m_fallbackHeight;
+
// GridLayout specific properties
int m_row;
int m_column;
diff --git a/src/imports/layouts/qquicklayoutstyleinfo_p.h b/src/imports/layouts/qquicklayoutstyleinfo_p.h
index ce86c2a37d..79f4ce2962 100644
--- a/src/imports/layouts/qquicklayoutstyleinfo_p.h
+++ b/src/imports/layouts/qquicklayoutstyleinfo_p.h
@@ -49,9 +49,9 @@ class QQuickLayoutStyleInfo : public QAbstractLayoutStyleInfo
public:
QQuickLayoutStyleInfo();
- qreal spacing(Qt::Orientation orientation) const Q_DECL_OVERRIDE;
- qreal windowMargin(Qt::Orientation orientation) const Q_DECL_OVERRIDE;
- bool hasChangedCore() const Q_DECL_OVERRIDE;
+ qreal spacing(Qt::Orientation orientation) const override;
+ qreal windowMargin(Qt::Orientation orientation) const override;
+ bool hasChangedCore() const override;
};
diff --git a/src/imports/layouts/qquicklinearlayout.cpp b/src/imports/layouts/qquicklinearlayout.cpp
index 4410723f3d..db983e06ba 100644
--- a/src/imports/layouts/qquicklinearlayout.cpp
+++ b/src/imports/layouts/qquicklinearlayout.cpp
@@ -652,6 +652,7 @@ void QQuickGridLayout::insertLayoutItems()
QSizeF sizeHints[Qt::NSizeHints];
const auto items = childItems();
for (QQuickItem *child : items) {
+ checkAnchors(child);
QQuickLayoutAttached *info = 0;
// Will skip all items with effective maximum width/height == 0
@@ -826,6 +827,7 @@ void QQuickLinearLayout::insertLayoutItems()
const auto items = childItems();
for (QQuickItem *child : items) {
Q_ASSERT(child);
+ checkAnchors(child);
QQuickLayoutAttached *info = 0;
// Will skip all items with effective maximum width/height == 0
diff --git a/src/imports/layouts/qquicklinearlayout_p.h b/src/imports/layouts/qquicklinearlayout_p.h
index f796c8a855..6706ebf9fa 100644
--- a/src/imports/layouts/qquicklinearlayout_p.h
+++ b/src/imports/layouts/qquicklinearlayout_p.h
@@ -67,26 +67,26 @@ public:
QQuickItem *parent = 0);
~QQuickGridLayoutBase();
- void componentComplete() Q_DECL_OVERRIDE;
- void invalidate(QQuickItem *childItem = 0) Q_DECL_OVERRIDE;
+ void componentComplete() override;
+ void invalidate(QQuickItem *childItem = 0) override;
Qt::Orientation orientation() const;
void setOrientation(Qt::Orientation orientation);
- QSizeF sizeHint(Qt::SizeHint whichSizeHint) const Q_DECL_OVERRIDE;
+ QSizeF sizeHint(Qt::SizeHint whichSizeHint) const override;
Qt::LayoutDirection layoutDirection() const;
void setLayoutDirection(Qt::LayoutDirection dir);
Qt::LayoutDirection effectiveLayoutDirection() const;
- void setAlignment(QQuickItem *item, Qt::Alignment align) Q_DECL_OVERRIDE;
+ void setAlignment(QQuickItem *item, Qt::Alignment align) override;
/* QQuickItemChangeListener */
- void itemDestroyed(QQuickItem *item) Q_DECL_OVERRIDE;
- void itemVisibilityChanged(QQuickItem *item) Q_DECL_OVERRIDE;
+ void itemDestroyed(QQuickItem *item) override;
+ void itemVisibilityChanged(QQuickItem *item) override;
protected:
- void updateLayoutItems() Q_DECL_OVERRIDE;
- QQuickItem *itemAt(int index) const Q_DECL_OVERRIDE;
- int itemCount() const Q_DECL_OVERRIDE;
+ void updateLayoutItems() override;
+ QQuickItem *itemAt(int index) const override;
+ int itemCount() const override;
- void rearrange(const QSizeF &size) Q_DECL_OVERRIDE;
+ void rearrange(const QSizeF &size) override;
virtual void insertLayoutItems() {}
signals:
@@ -109,7 +109,7 @@ public:
, m_layoutDirection(Qt::LeftToRight)
{}
- void mirrorChange() Q_DECL_OVERRIDE
+ void mirrorChange() override
{
Q_Q(QQuickGridLayoutBase);
q->invalidate();
diff --git a/src/imports/layouts/qquickstacklayout.cpp b/src/imports/layouts/qquickstacklayout.cpp
index 9a7ec71473..cf70856e14 100644
--- a/src/imports/layouts/qquickstacklayout.cpp
+++ b/src/imports/layouts/qquickstacklayout.cpp
@@ -288,8 +288,11 @@ void QQuickStackLayout::updateLayoutItems()
d->count = count;
emit countChanged();
}
- for (int i = 0; i < count; ++i)
- itemAt(i)->setVisible(d->currentIndex == i);
+ for (int i = 0; i < count; ++i) {
+ QQuickItem *child = itemAt(i);
+ checkAnchors(child);
+ child->setVisible(d->currentIndex == i);
+ }
invalidate();
}
diff --git a/src/imports/layouts/qquickstacklayout_p.h b/src/imports/layouts/qquickstacklayout_p.h
index 7b6400c3a3..8ba41720aa 100644
--- a/src/imports/layouts/qquickstacklayout_p.h
+++ b/src/imports/layouts/qquickstacklayout_p.h
@@ -56,16 +56,16 @@ public:
int currentIndex() const;
void setCurrentIndex(int index);
- void componentComplete() Q_DECL_OVERRIDE;
- QSizeF sizeHint(Qt::SizeHint whichSizeHint) const Q_DECL_OVERRIDE;
- void setAlignment(QQuickItem *item, Qt::Alignment align) Q_DECL_OVERRIDE;
- void invalidate(QQuickItem *childItem = 0) Q_DECL_OVERRIDE;
- void updateLayoutItems() Q_DECL_OVERRIDE;
- void rearrange(const QSizeF &) Q_DECL_OVERRIDE;
+ void componentComplete() override;
+ QSizeF sizeHint(Qt::SizeHint whichSizeHint) const override;
+ void setAlignment(QQuickItem *item, Qt::Alignment align) override;
+ void invalidate(QQuickItem *childItem = 0) override;
+ void updateLayoutItems() override;
+ void rearrange(const QSizeF &) override;
// iterator
- Q_INVOKABLE QQuickItem *itemAt(int index) const Q_DECL_OVERRIDE;
- int itemCount() const Q_DECL_OVERRIDE;
+ Q_INVOKABLE QQuickItem *itemAt(int index) const override;
+ int itemCount() const override;
int indexOf(QQuickItem *item) const;
diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp
index 02cf125e48..9a67b9a19b 100644
--- a/src/imports/localstorage/plugin.cpp
+++ b/src/imports/localstorage/plugin.cpp
@@ -58,6 +58,7 @@
#include <private/qv4functionobject_p.h>
#include <private/qv4objectproto_p.h>
#include <private/qv4scopedvalue_p.h>
+#include <private/qv4jscall_p.h>
#include <private/qv4objectiterator_p.h>
static void initResources()
@@ -164,18 +165,20 @@ DEFINE_OBJECT_VTABLE(QV4::QQmlSqlDatabaseWrapper);
-static void qmlsqldatabase_version(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+static ReturnedValue qmlsqldatabase_version(const FunctionObject *b, const Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, callData->thisObject.as<QQmlSqlDatabaseWrapper>());
+ Scope scope(b);
+ QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, thisObject->as<QQmlSqlDatabaseWrapper>());
if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Database)
V4THROW_REFERENCE("Not a SQLDatabase object");
RETURN_RESULT(Encode(scope.engine->newString(*r->d()->version)));
}
-static void qmlsqldatabase_rows_length(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+static ReturnedValue qmlsqldatabase_rows_length(const FunctionObject *b, const Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, callData->thisObject.as<QQmlSqlDatabaseWrapper>());
+ Scope scope(b);
+ QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, thisObject->as<QQmlSqlDatabaseWrapper>());
if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Rows)
V4THROW_REFERENCE("Not a SQLDatabase::Rows object");
@@ -191,23 +194,25 @@ static void qmlsqldatabase_rows_length(const QV4::BuiltinFunction *, QV4::Scope
RETURN_RESULT(Encode(s));
}
-static void qmlsqldatabase_rows_forwardOnly(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+static ReturnedValue qmlsqldatabase_rows_forwardOnly(const FunctionObject *b, const Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, callData->thisObject.as<QQmlSqlDatabaseWrapper>());
+ Scope scope(b);
+ QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, thisObject->as<QQmlSqlDatabaseWrapper>());
if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Rows)
V4THROW_REFERENCE("Not a SQLDatabase::Rows object");
RETURN_RESULT(Encode(r->d()->sqlQuery->isForwardOnly()));
}
-static void qmlsqldatabase_rows_setForwardOnly(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+static ReturnedValue qmlsqldatabase_rows_setForwardOnly(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, callData->thisObject.as<QQmlSqlDatabaseWrapper>());
+ Scope scope(b);
+ QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, thisObject->as<QQmlSqlDatabaseWrapper>());
if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Rows)
V4THROW_REFERENCE("Not a SQLDatabase::Rows object");
- if (callData->argc < 1)
+ if (argc < 1)
RETURN_RESULT(scope.engine->throwTypeError());
- r->d()->sqlQuery->setForwardOnly(callData->args[0].toBoolean());
+ r->d()->sqlQuery->setForwardOnly(argv[0].toBoolean());
RETURN_UNDEFINED();
}
@@ -249,13 +254,14 @@ ReturnedValue QQmlSqlDatabaseWrapper::getIndexed(const Managed *m, uint index, b
return qmlsqldatabase_rows_index(r, r->engine(), index, hasProperty);
}
-static void qmlsqldatabase_rows_item(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+static ReturnedValue qmlsqldatabase_rows_item(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, callData->thisObject.as<QQmlSqlDatabaseWrapper>());
+ Scope scope(b);
+ QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, thisObject->as<QQmlSqlDatabaseWrapper>());
if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Rows)
V4THROW_REFERENCE("Not a SQLDatabase::Rows object");
- RETURN_RESULT(qmlsqldatabase_rows_index(r, scope.engine, callData->argc ? callData->args[0].toUInt32() : 0));
+ RETURN_RESULT(qmlsqldatabase_rows_index(r, scope.engine, argc ? argv[0].toUInt32() : 0));
}
static QVariant toSqlVariant(QV4::ExecutionEngine *engine, const QV4::ScopedValue &value)
@@ -267,9 +273,10 @@ static QVariant toSqlVariant(QV4::ExecutionEngine *engine, const QV4::ScopedValu
return engine->toVariant(value, /*typehint*/-1);
}
-static void qmlsqldatabase_executeSql(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+static ReturnedValue qmlsqldatabase_executeSql(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, callData->thisObject.as<QQmlSqlDatabaseWrapper>());
+ Scope scope(b);
+ QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, thisObject->as<QQmlSqlDatabaseWrapper>());
if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Query)
V4THROW_REFERENCE("Not a SQLDatabase::Query object");
@@ -278,7 +285,7 @@ static void qmlsqldatabase_executeSql(const QV4::BuiltinFunction *, QV4::Scope &
QSqlDatabase db = *r->d()->database;
- QString sql = callData->argc ? callData->args[0].toQString() : QString();
+ QString sql = argc ? argv[0].toQString() : QString();
if (r->d()->readonly && !sql.startsWith(QLatin1String("SELECT"),Qt::CaseInsensitive)) {
V4THROW_SQL(SQLEXCEPTION_SYNTAX_ERR, QQmlEngine::tr("Read-only Transaction"));
@@ -290,8 +297,8 @@ static void qmlsqldatabase_executeSql(const QV4::BuiltinFunction *, QV4::Scope &
ScopedValue result(scope, Primitive::undefinedValue());
if (query.prepare(sql)) {
- if (callData->argc > 1) {
- ScopedValue values(scope, callData->args[1]);
+ if (argc > 1) {
+ ScopedValue values(scope, argv[1]);
if (values->as<ArrayObject>()) {
ScopedArrayObject array(scope, values);
quint32 size = array->getLength();
@@ -377,19 +384,20 @@ struct TransactionRollback {
};
-static void qmlsqldatabase_changeVersion(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+static ReturnedValue qmlsqldatabase_changeVersion(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- if (callData->argc < 2)
+ Scope scope(b);
+ if (argc < 2)
RETURN_UNDEFINED();
- Scoped<QQmlSqlDatabaseWrapper> r(scope, callData->thisObject);
+ Scoped<QQmlSqlDatabaseWrapper> r(scope, *thisObject);
if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Database)
V4THROW_REFERENCE("Not a SQLDatabase object");
QSqlDatabase db = *r->d()->database;
- QString from_version = callData->args[0].toQString();
- QString to_version = callData->args[1].toQString();
- ScopedFunctionObject callback(scope, callData->argc > 2 ? callData->args[2] : Primitive::undefinedValue());
+ QString from_version = argv[0].toQString();
+ QString to_version = argv[1].toQString();
+ ScopedFunctionObject callback(scope, argc > 2 ? argv[2] : Primitive::undefinedValue());
if (from_version != *r->d()->version)
V4THROW_SQL(SQLEXCEPTION_VERSION_ERR, QQmlEngine::tr("Version mismatch: expected %1, found %2").arg(from_version).arg(*r->d()->version));
@@ -406,12 +414,12 @@ static void qmlsqldatabase_changeVersion(const QV4::BuiltinFunction *, QV4::Scop
ok = false;
db.transaction();
- ScopedCallData callData(scope, 1);
- callData->thisObject = scope.engine->globalObject;
- callData->args[0] = w;
+ JSCallData jsCall(scope, 1);
+ *jsCall->thisObject = scope.engine->globalObject;
+ jsCall->args[0] = w;
TransactionRollback rollbackOnException(&db, &w->d()->inTransaction);
- callback->call(scope, callData);
+ callback->call(jsCall);
rollbackOnException.clear();
if (!db.commit()) {
db.rollback();
@@ -433,13 +441,14 @@ static void qmlsqldatabase_changeVersion(const QV4::BuiltinFunction *, QV4::Scop
RETURN_UNDEFINED();
}
-static void qmlsqldatabase_transaction_shared(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData, bool readOnly)
+static ReturnedValue qmlsqldatabase_transaction_shared(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc, bool readOnly)
{
- QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, callData->thisObject.as<QQmlSqlDatabaseWrapper>());
+ Scope scope(b);
+ QV4::Scoped<QQmlSqlDatabaseWrapper> r(scope, thisObject->as<QQmlSqlDatabaseWrapper>());
if (!r || r->d()->type != Heap::QQmlSqlDatabaseWrapper::Database)
V4THROW_REFERENCE("Not a SQLDatabase object");
- const FunctionObject *callback = callData->argc ? callData->args[0].as<FunctionObject>() : 0;
+ const FunctionObject *callback = argc ? argv[0].as<FunctionObject>() : 0;
if (!callback)
V4THROW_SQL(SQLEXCEPTION_UNKNOWN_ERR, QQmlEngine::tr("transaction: missing callback"));
@@ -455,11 +464,11 @@ static void qmlsqldatabase_transaction_shared(const QV4::BuiltinFunction *, QV4:
db.transaction();
if (callback) {
- ScopedCallData callData(scope, 1);
- callData->thisObject = scope.engine->globalObject;
- callData->args[0] = w;
+ JSCallData jsCall(scope, 1);
+ *jsCall->thisObject = scope.engine->globalObject;
+ jsCall->args[0] = w;
TransactionRollback rollbackOnException(&db, &w->d()->inTransaction);
- callback->call(scope, callData);
+ callback->call(jsCall);
rollbackOnException.clear();
if (!db.commit())
@@ -469,14 +478,14 @@ static void qmlsqldatabase_transaction_shared(const QV4::BuiltinFunction *, QV4:
RETURN_UNDEFINED();
}
-static void qmlsqldatabase_transaction(const QV4::BuiltinFunction *f, QV4::Scope &scope, QV4::CallData *callData)
+static ReturnedValue qmlsqldatabase_transaction(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
{
- qmlsqldatabase_transaction_shared(f, scope, callData, false);
+ return qmlsqldatabase_transaction_shared(f, thisObject, argv, argc, false);
}
-static void qmlsqldatabase_read_transaction(const QV4::BuiltinFunction *f, QV4::Scope &scope, QV4::CallData *callData)
+static ReturnedValue qmlsqldatabase_read_transaction(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
{
- qmlsqldatabase_transaction_shared(f, scope, callData, true);
+ return qmlsqldatabase_transaction_shared(f, thisObject, argv, argc, true);
}
QQmlSqlDatabaseData::QQmlSqlDatabaseData(ExecutionEngine *v4)
@@ -754,10 +763,10 @@ void QQuickLocalStorage::openDatabaseSync(QQmlV4Function *args)
*db->d()->version = version;
if (created && dbcreationCallback) {
- ScopedCallData callData(scope, 1);
- callData->thisObject = scope.engine->globalObject;
- callData->args[0] = db;
- dbcreationCallback->call(scope, callData);
+ JSCallData jsCall(scope, 1);
+ *jsCall->thisObject = scope.engine->globalObject;
+ jsCall->args[0] = db;
+ dbcreationCallback->call(jsCall);
}
args->setReturnValue(db.asReturnedValue());
@@ -785,7 +794,7 @@ public:
{
initResources();
}
- void registerTypes(const char *uri) Q_DECL_OVERRIDE
+ void registerTypes(const char *uri) override
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.LocalStorage"));
qmlRegisterSingletonType<QQuickLocalStorage>(uri, 2, 0, "LocalStorage", module_api_factory);
diff --git a/src/imports/models/plugin.cpp b/src/imports/models/plugin.cpp
index dbb62cd25d..5933128713 100644
--- a/src/imports/models/plugin.cpp
+++ b/src/imports/models/plugin.cpp
@@ -78,7 +78,7 @@ class QtQmlModelsPlugin : public QQmlExtensionPlugin
Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
public:
QtQmlModelsPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); }
- void registerTypes(const char *uri) Q_DECL_OVERRIDE
+ void registerTypes(const char *uri) override
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQml.Models"));
Q_UNUSED(uri);
diff --git a/src/imports/particles/plugin.cpp b/src/imports/particles/plugin.cpp
index 28ce0f7796..f7a3472403 100644
--- a/src/imports/particles/plugin.cpp
+++ b/src/imports/particles/plugin.cpp
@@ -57,7 +57,7 @@ class QtQuick2ParticlesPlugin : public QQmlExtensionPlugin
Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
public:
QtQuick2ParticlesPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); }
- void registerTypes(const char *uri) Q_DECL_OVERRIDE
+ void registerTypes(const char *uri) override
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.Particles"));
Q_UNUSED(uri);
diff --git a/src/imports/qtquick2/plugin.cpp b/src/imports/qtquick2/plugin.cpp
index d16467a5bb..a5b2c8c67e 100644
--- a/src/imports/qtquick2/plugin.cpp
+++ b/src/imports/qtquick2/plugin.cpp
@@ -57,7 +57,7 @@ class QtQuick2Plugin : public QQmlExtensionPlugin
Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
public:
QtQuick2Plugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); }
- void registerTypes(const char *uri) Q_DECL_OVERRIDE
+ void registerTypes(const char *uri) override
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick"));
Q_UNUSED(uri);
diff --git a/src/imports/qtquick2/plugins.qmltypes b/src/imports/qtquick2/plugins.qmltypes
index 834b4bfac2..0fce98a212 100644
--- a/src/imports/qtquick2/plugins.qmltypes
+++ b/src/imports/qtquick2/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable -noforceqtquick QtQuick 2.9'
+// 'qmlplugindump -nonrelocatable -noforceqtquick QtQuick 2.10'
Module {
dependencies: []
@@ -1517,8 +1517,12 @@ Module {
name: "QQuickFlickable"
defaultProperty: "flickableData"
prototype: "QQuickItem"
- exports: ["QtQuick/Flickable 2.0", "QtQuick/Flickable 2.9"]
- exportMetaObjectRevisions: [0, 9]
+ exports: [
+ "QtQuick/Flickable 2.0",
+ "QtQuick/Flickable 2.10",
+ "QtQuick/Flickable 2.9"
+ ]
+ exportMetaObjectRevisions: [0, 10, 9]
Enum {
name: "BoundsBehavior"
values: {
@@ -1529,6 +1533,12 @@ Module {
}
}
Enum {
+ name: "BoundsMovement"
+ values: {
+ "FollowBoundsBehavior": 1
+ }
+ }
+ Enum {
name: "FlickableDirection"
values: {
"AutoFlickDirection": 0,
@@ -1552,6 +1562,7 @@ Module {
Property { name: "horizontalVelocity"; type: "double"; isReadonly: true }
Property { name: "verticalVelocity"; type: "double"; isReadonly: true }
Property { name: "boundsBehavior"; type: "BoundsBehavior" }
+ Property { name: "boundsMovement"; revision: 10; type: "BoundsMovement" }
Property { name: "rebound"; type: "QQuickTransition"; isPointer: true }
Property { name: "maximumFlickVelocity"; type: "double" }
Property { name: "flickDeceleration"; type: "double" }
@@ -1583,6 +1594,7 @@ Module {
Property { name: "flickableData"; type: "QObject"; isList: true; isReadonly: true }
Property { name: "flickableChildren"; type: "QQuickItem"; isList: true; isReadonly: true }
Signal { name: "isAtBoundaryChanged" }
+ Signal { name: "boundsMovementChanged"; revision: 10 }
Signal { name: "movementStarted" }
Signal { name: "movementEnded" }
Signal { name: "flickStarted" }
@@ -1795,6 +1807,8 @@ Module {
Property { name: "letterSpacing"; type: "double" }
Property { name: "wordSpacing"; type: "double" }
Property { name: "hintingPreference"; type: "HintingPreference" }
+ Property { name: "kerning"; type: "bool" }
+ Property { name: "preferShaping"; type: "bool" }
Method { name: "toString"; type: "string" }
}
Component {
@@ -2088,8 +2102,6 @@ Module {
prototype: "QQuickItem"
Property { name: "implicitWidth"; type: "double"; isReadonly: true }
Property { name: "implicitHeight"; type: "double"; isReadonly: true }
- Signal { name: "implicitWidthChanged2"; revision: 1 }
- Signal { name: "implicitHeightChanged2"; revision: 1 }
}
Component {
name: "QQuickIntValidator"
@@ -2300,6 +2312,7 @@ Module {
Property { name: "samplerName"; type: "QByteArray" }
Property { name: "effect"; type: "QQmlComponent"; isPointer: true }
Property { name: "textureMirroring"; type: "QQuickShaderEffectSource::TextureMirroring" }
+ Property { name: "samples"; type: "int" }
Signal {
name: "enabledChanged"
Parameter { name: "enabled"; type: "bool" }
@@ -2340,6 +2353,10 @@ Module {
name: "textureMirroringChanged"
Parameter { name: "mirroring"; type: "QQuickShaderEffectSource::TextureMirroring" }
}
+ Signal {
+ name: "samplesChanged"
+ Parameter { name: "count"; type: "int" }
+ }
}
Component {
name: "QQuickItemView"
@@ -3065,8 +3082,8 @@ Module {
Component {
name: "QQuickPathArc"
prototype: "QQuickCurve"
- exports: ["QtQuick/PathArc 2.0"]
- exportMetaObjectRevisions: [0]
+ exports: ["QtQuick/PathArc 2.0", "QtQuick/PathArc 2.9"]
+ exportMetaObjectRevisions: [0, 2]
Enum {
name: "ArcDirection"
values: {
@@ -3078,6 +3095,8 @@ Module {
Property { name: "radiusY"; type: "double" }
Property { name: "useLargeArc"; type: "bool" }
Property { name: "direction"; type: "ArcDirection" }
+ Property { name: "xAxisRotation"; revision: 2; type: "double" }
+ Signal { name: "xAxisRotationChanged"; revision: 2 }
}
Component {
name: "QQuickPathAttribute"
@@ -3130,6 +3149,12 @@ Module {
exportMetaObjectRevisions: [0]
}
Component {
+ name: "QQuickPathMove"
+ prototype: "QQuickCurve"
+ exports: ["QtQuick/PathMove 2.9"]
+ exportMetaObjectRevisions: [0]
+ }
+ Component {
name: "QQuickPathPercent"
prototype: "QQuickPathElement"
exports: ["QtQuick/PathPercent 2.0"]
@@ -3594,9 +3619,10 @@ Module {
prototype: "QQuickItem"
exports: [
"QtQuick/ShaderEffectSource 2.0",
- "QtQuick/ShaderEffectSource 2.6"
+ "QtQuick/ShaderEffectSource 2.6",
+ "QtQuick/ShaderEffectSource 2.9"
]
- exportMetaObjectRevisions: [0, 1]
+ exportMetaObjectRevisions: [0, 1, 2]
Enum {
name: "WrapMode"
values: {
@@ -3632,6 +3658,7 @@ Module {
Property { name: "mipmap"; type: "bool" }
Property { name: "recursive"; type: "bool" }
Property { name: "textureMirroring"; revision: 1; type: "TextureMirroring" }
+ Property { name: "samples"; revision: 2; type: "int" }
Signal { name: "scheduledUpdateCompleted" }
Method { name: "scheduleUpdate" }
}
@@ -3968,12 +3995,13 @@ Module {
prototype: "QQuickImplicitSizeItem"
exports: [
"QtQuick/Text 2.0",
+ "QtQuick/Text 2.10",
"QtQuick/Text 2.2",
"QtQuick/Text 2.3",
"QtQuick/Text 2.6",
"QtQuick/Text 2.9"
]
- exportMetaObjectRevisions: [0, 2, 3, 6, 9]
+ exportMetaObjectRevisions: [0, 10, 2, 3, 6, 9]
Enum {
name: "HAlignment"
values: {
@@ -4084,6 +4112,7 @@ Module {
Property { name: "rightPadding"; revision: 6; type: "double" }
Property { name: "bottomPadding"; revision: 6; type: "double" }
Property { name: "fontInfo"; revision: 9; type: "QJSValue"; isReadonly: true }
+ Property { name: "advance"; revision: 10; type: "QSizeF"; isReadonly: true }
Signal {
name: "textChanged"
Parameter { name: "text"; type: "string" }
@@ -4158,12 +4187,13 @@ Module {
exports: [
"QtQuick/TextEdit 2.0",
"QtQuick/TextEdit 2.1",
+ "QtQuick/TextEdit 2.10",
"QtQuick/TextEdit 2.2",
"QtQuick/TextEdit 2.3",
"QtQuick/TextEdit 2.6",
"QtQuick/TextEdit 2.7"
]
- exportMetaObjectRevisions: [0, 1, 2, 3, 6, 7]
+ exportMetaObjectRevisions: [0, 1, 10, 2, 3, 6, 7]
Enum {
name: "HAlignment"
values: {
@@ -4265,6 +4295,7 @@ Module {
Property { name: "rightPadding"; revision: 6; type: "double" }
Property { name: "bottomPadding"; revision: 6; type: "double" }
Property { name: "preeditText"; revision: 7; type: "string"; isReadonly: true }
+ Property { name: "tabStopDistance"; revision: 10; type: "double" }
Signal { name: "preeditTextChanged"; revision: 7 }
Signal { name: "contentSizeChanged" }
Signal {
@@ -4347,6 +4378,11 @@ Module {
Signal { name: "leftPaddingChanged"; revision: 6 }
Signal { name: "rightPaddingChanged"; revision: 6 }
Signal { name: "bottomPaddingChanged"; revision: 6 }
+ Signal {
+ name: "tabStopDistanceChanged"
+ revision: 10
+ Parameter { name: "distance"; type: "double" }
+ }
Method { name: "selectAll" }
Method { name: "selectWord" }
Method {
diff --git a/src/imports/settings/plugin.cpp b/src/imports/settings/plugin.cpp
index c422296446..70d24c12cd 100644
--- a/src/imports/settings/plugin.cpp
+++ b/src/imports/settings/plugin.cpp
@@ -58,7 +58,7 @@ class QmlSettingsPlugin : public QQmlExtensionPlugin
public:
QmlSettingsPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); }
- void registerTypes(const char *uri) Q_DECL_OVERRIDE
+ void registerTypes(const char *uri) override
{
Q_ASSERT(QByteArray(uri) == QByteArray("Qt.labs.settings"));
qmlRegisterType<QQmlSettings>(uri, 1, 0, "Settings");
diff --git a/src/imports/settings/qqmlsettings.cpp b/src/imports/settings/qqmlsettings.cpp
index ae12d54f5a..f6040e7a64 100644
--- a/src/imports/settings/qqmlsettings.cpp
+++ b/src/imports/settings/qqmlsettings.cpp
@@ -39,6 +39,7 @@
#include "qqmlsettings_p.h"
#include <qcoreevent.h>
+#include <qloggingcategory.h>
#include <qsettings.h>
#include <qpointer.h>
#include <qjsvalue.h>
@@ -231,7 +232,7 @@ QT_BEGIN_NAMESPACE
\sa QSettings
*/
-// #define SETTINGS_DEBUG
+Q_LOGGING_CATEGORY(lcSettings, "qt.labs.settings")
static const int settingsWriteDelay = 500;
@@ -282,9 +283,7 @@ QSettings *QQmlSettingsPrivate::instance() const
void QQmlSettingsPrivate::init()
{
if (!initialized) {
-#ifdef SETTINGS_DEBUG
- qDebug() << "QQmlSettings: stored at" << instance()->fileName();
-#endif
+ qCDebug(lcSettings) << "QQmlSettings: stored at" << instance()->fileName();
load();
initialized = true;
}
@@ -312,9 +311,7 @@ void QQmlSettingsPrivate::load()
if (!currentValue.isNull() && (!previousValue.isValid()
|| (currentValue.canConvert(previousValue.type()) && previousValue != currentValue))) {
property.write(q, currentValue);
-#ifdef SETTINGS_DEBUG
- qDebug() << "QQmlSettings: load" << property.name() << "setting:" << currentValue << "default:" << previousValue;
-#endif
+ qCDebug(lcSettings) << "QQmlSettings: load" << property.name() << "setting:" << currentValue << "default:" << previousValue;
}
// ensure that a non-existent setting gets written
@@ -335,9 +332,7 @@ void QQmlSettingsPrivate::store()
QHash<const char *, QVariant>::const_iterator it = changedProperties.constBegin();
while (it != changedProperties.constEnd()) {
instance()->setValue(it.key(), it.value());
-#ifdef SETTINGS_DEBUG
- qDebug() << "QQmlSettings: store" << it.key() << ":" << it.value();
-#endif
+ qCDebug(lcSettings) << "QQmlSettings: store" << it.key() << ":" << it.value();
++it;
}
changedProperties.clear();
@@ -353,9 +348,7 @@ void QQmlSettingsPrivate::_q_propertyChanged()
const QMetaProperty &property = mo->property(i);
const QVariant value = readProperty(property);
changedProperties.insert(property.name(), value);
-#ifdef SETTINGS_DEBUG
- qDebug() << "QQmlSettings: cache" << property.name() << ":" << value;
-#endif
+ qCDebug(lcSettings) << "QQmlSettings: cache" << property.name() << ":" << value;
}
if (timerId != 0)
q->killTimer(timerId);
diff --git a/src/imports/shapes/plugin.cpp b/src/imports/shapes/plugin.cpp
new file mode 100644
index 0000000000..74731aa35f
--- /dev/null
+++ b/src/imports/shapes/plugin.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtQml/qqmlextensionplugin.h>
+#include <QtQml/qqml.h>
+
+#include "qquickshape_p.h"
+
+static void initResources()
+{
+#ifdef QT_STATIC
+ Q_INIT_RESOURCE(qmake_QtQuick_Shapes);
+#endif
+ Q_INIT_RESOURCE(qtquickshapesplugin);
+}
+
+QT_BEGIN_NAMESPACE
+
+class QmlShapesPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
+
+public:
+ QmlShapesPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); }
+ void registerTypes(const char *uri) override
+ {
+ Q_ASSERT(QByteArray(uri) == QByteArray("QtQuick.Shapes"));
+ qmlRegisterType<QQuickShape>(uri, 1, 0, "Shape");
+ qmlRegisterType<QQuickShapePath>(uri, 1, 0, "ShapePath");
+ qmlRegisterUncreatableType<QQuickShapeGradient>(uri, 1, 0, "ShapeGradient", QQuickShapeGradient::tr("ShapeGradient is an abstract base class"));
+ qmlRegisterType<QQuickShapeLinearGradient>(uri, 1, 0, "LinearGradient");
+ qmlRegisterType<QQuickShapeRadialGradient>(uri, 1, 0, "RadialGradient");
+ qmlRegisterType<QQuickShapeConicalGradient>(uri, 1, 0, "ConicalGradient");
+
+ // Auto-increment the import to stay in sync with ALL future QtQuick minor versions
+ qmlRegisterModule(uri, 1, QT_VERSION_MINOR);
+
+ // revision in Qt 5.11: added containsMode property
+ qmlRegisterType<QQuickShape, 11>(uri, 1, 11, "Shape");
+ }
+};
+
+QT_END_NAMESPACE
+
+#include "plugin.moc"
diff --git a/src/imports/shapes/plugins.qmltypes b/src/imports/shapes/plugins.qmltypes
new file mode 100644
index 0000000000..a140644d6d
--- /dev/null
+++ b/src/imports/shapes/plugins.qmltypes
@@ -0,0 +1,150 @@
+import QtQuick.tooling 1.2
+
+// This file describes the plugin-supplied types contained in the library.
+// It is used for QML tooling purposes only.
+//
+// This file was auto-generated by:
+// 'qmlplugindump -nonrelocatable QtQuick.Shapes 1.11'
+
+Module {
+ dependencies: ["QtQuick 2.8"]
+ Component {
+ name: "QQuickShape"
+ defaultProperty: "data"
+ prototype: "QQuickItem"
+ exports: ["QtQuick.Shapes/Shape 1.0", "QtQuick.Shapes/Shape 1.11"]
+ exportMetaObjectRevisions: [0, 11]
+ Enum {
+ name: "RendererType"
+ values: {
+ "UnknownRenderer": 0,
+ "GeometryRenderer": 1,
+ "NvprRenderer": 2,
+ "SoftwareRenderer": 3
+ }
+ }
+ Enum {
+ name: "Status"
+ values: {
+ "Null": 0,
+ "Ready": 1,
+ "Processing": 2
+ }
+ }
+ Enum {
+ name: "ContainsMode"
+ values: {
+ "BoundingRectContains": 0,
+ "FillContains": 1
+ }
+ }
+ Property { name: "rendererType"; type: "RendererType"; isReadonly: true }
+ Property { name: "asynchronous"; type: "bool" }
+ Property { name: "vendorExtensionsEnabled"; type: "bool" }
+ Property { name: "status"; type: "Status"; isReadonly: true }
+ Property { name: "containsMode"; revision: 11; type: "ContainsMode" }
+ Property { name: "data"; type: "QObject"; isList: true; isReadonly: true }
+ Signal { name: "rendererChanged" }
+ Signal { name: "containsModeChanged"; revision: 11 }
+ }
+ Component {
+ name: "QQuickShapeConicalGradient"
+ defaultProperty: "stops"
+ prototype: "QQuickShapeGradient"
+ exports: ["QtQuick.Shapes/ConicalGradient 1.0"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "centerX"; type: "double" }
+ Property { name: "centerY"; type: "double" }
+ Property { name: "angle"; type: "double" }
+ }
+ Component {
+ name: "QQuickShapeGradient"
+ defaultProperty: "stops"
+ prototype: "QQuickGradient"
+ exports: ["QtQuick.Shapes/ShapeGradient 1.0"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ Enum {
+ name: "SpreadMode"
+ values: {
+ "PadSpread": 0,
+ "RepeatSpread": 1,
+ "ReflectSpread": 2
+ }
+ }
+ Property { name: "spread"; type: "SpreadMode" }
+ }
+ Component {
+ name: "QQuickShapeLinearGradient"
+ defaultProperty: "stops"
+ prototype: "QQuickShapeGradient"
+ exports: ["QtQuick.Shapes/LinearGradient 1.0"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "x1"; type: "double" }
+ Property { name: "y1"; type: "double" }
+ Property { name: "x2"; type: "double" }
+ Property { name: "y2"; type: "double" }
+ }
+ Component {
+ name: "QQuickShapePath"
+ defaultProperty: "pathElements"
+ prototype: "QQuickPath"
+ exports: ["QtQuick.Shapes/ShapePath 1.0"]
+ exportMetaObjectRevisions: [0]
+ Enum {
+ name: "FillRule"
+ values: {
+ "OddEvenFill": 0,
+ "WindingFill": 1
+ }
+ }
+ Enum {
+ name: "JoinStyle"
+ values: {
+ "MiterJoin": 0,
+ "BevelJoin": 64,
+ "RoundJoin": 128
+ }
+ }
+ Enum {
+ name: "CapStyle"
+ values: {
+ "FlatCap": 0,
+ "SquareCap": 16,
+ "RoundCap": 32
+ }
+ }
+ Enum {
+ name: "StrokeStyle"
+ values: {
+ "SolidLine": 1,
+ "DashLine": 2
+ }
+ }
+ Property { name: "strokeColor"; type: "QColor" }
+ Property { name: "strokeWidth"; type: "double" }
+ Property { name: "fillColor"; type: "QColor" }
+ Property { name: "fillRule"; type: "FillRule" }
+ Property { name: "joinStyle"; type: "JoinStyle" }
+ Property { name: "miterLimit"; type: "int" }
+ Property { name: "capStyle"; type: "CapStyle" }
+ Property { name: "strokeStyle"; type: "StrokeStyle" }
+ Property { name: "dashOffset"; type: "double" }
+ Property { name: "dashPattern"; type: "QVector<qreal>" }
+ Property { name: "fillGradient"; type: "QQuickShapeGradient"; isPointer: true }
+ Signal { name: "shapePathChanged" }
+ }
+ Component {
+ name: "QQuickShapeRadialGradient"
+ defaultProperty: "stops"
+ prototype: "QQuickShapeGradient"
+ exports: ["QtQuick.Shapes/RadialGradient 1.0"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "centerX"; type: "double" }
+ Property { name: "centerY"; type: "double" }
+ Property { name: "centerRadius"; type: "double" }
+ Property { name: "focalX"; type: "double" }
+ Property { name: "focalY"; type: "double" }
+ Property { name: "focalRadius"; type: "double" }
+ }
+}
diff --git a/src/imports/shapes/qmldir b/src/imports/shapes/qmldir
new file mode 100644
index 0000000000..306ad1ecd7
--- /dev/null
+++ b/src/imports/shapes/qmldir
@@ -0,0 +1,4 @@
+module QtQuick.Shapes
+plugin qmlshapesplugin
+classname QmlShapesPlugin
+typeinfo plugins.qmltypes
diff --git a/src/imports/shapes/qquicknvprfunctions.cpp b/src/imports/shapes/qquicknvprfunctions.cpp
new file mode 100644
index 0000000000..409a59be7f
--- /dev/null
+++ b/src/imports/shapes/qquicknvprfunctions.cpp
@@ -0,0 +1,281 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquicknvprfunctions_p.h"
+
+#if QT_CONFIG(opengl)
+
+#include <QOpenGLContext>
+#include <QOffscreenSurface>
+#include <QOpenGLExtraFunctions>
+#include "qquicknvprfunctions_p_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QQuickNvprFunctions
+
+ \brief Function resolvers and other helpers for GL_NV_path_rendering
+ for both desktop (GL 4.3+) and mobile/embedded (GLES 3.1+) in a manner
+ that does not distract builds that do not have NVPR support either at
+ compile or run time.
+
+ \internal
+ */
+
+QQuickNvprFunctions::QQuickNvprFunctions()
+ : d(new QQuickNvprFunctionsPrivate(this))
+{
+}
+
+QQuickNvprFunctions::~QQuickNvprFunctions()
+{
+ delete d;
+}
+
+/*!
+ \return a recommended QSurfaceFormat suitable for GL_NV_path_rendering on top
+ of OpenGL 4.3 or OpenGL ES 3.1.
+ */
+QSurfaceFormat QQuickNvprFunctions::format()
+{
+ QSurfaceFormat fmt;
+ fmt.setDepthBufferSize(24);
+ fmt.setStencilBufferSize(8);
+ if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) {
+ fmt.setVersion(4, 3);
+ fmt.setProfile(QSurfaceFormat::CompatibilityProfile);
+ } else if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) {
+ fmt.setVersion(3, 1);
+ }
+ return fmt;
+}
+
+#define PROC(type, name) reinterpret_cast<type>(ctx->getProcAddress(#name))
+
+/*!
+ \return true if GL_NV_path_rendering is supported with the current OpenGL
+ context.
+
+ When there is no current context, a temporary dummy one will be created and
+ made current.
+ */
+bool QQuickNvprFunctions::isSupported()
+{
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ QScopedPointer<QOpenGLContext> tempContext;
+ QScopedPointer<QOffscreenSurface> tempSurface;
+ if (!ctx) {
+ tempContext.reset(new QOpenGLContext);
+ if (!tempContext->create())
+ return false;
+ ctx = tempContext.data();
+ tempSurface.reset(new QOffscreenSurface);
+ tempSurface->setFormat(ctx->format());
+ tempSurface->create();
+ if (!ctx->makeCurrent(tempSurface.data()))
+ return false;
+ }
+
+ if (!ctx->hasExtension(QByteArrayLiteral("GL_NV_path_rendering")))
+ return false;
+
+ // Check that GL_NV_Path_rendering extension is at least API revision 1.3
+ if (!PROC(PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC, glProgramPathFragmentInputGenNV))
+ return false;
+
+ // Do not check for DSA as the string may not be exposed on ES
+ // drivers, yet the functions we need are resolvable.
+#if 0
+ if (!ctx->hasExtension(QByteArrayLiteral("GL_EXT_direct_state_access"))) {
+ qWarning("QtQuickPath/NVPR: GL_EXT_direct_state_access not supported");
+ return false;
+ }
+#endif
+
+ return true;
+}
+
+/*!
+ Initializes using the current OpenGL context.
+
+ \return true when GL_NV_path_rendering is supported and initialization was
+ successful.
+ */
+bool QQuickNvprFunctions::create()
+{
+ return isSupported() && d->resolve();
+}
+
+/*!
+ Creates a program pipeline consisting of a separable fragment shader program.
+
+ This is essential for using NVPR with OpenGL ES 3.1+ since normal,
+ GLES2-style programs would not work without a vertex shader.
+
+ \note \a fragmentShaderSource should be a \c{version 310 es} shader since
+ this works both on desktop and embedded NVIDIA drivers, thus avoiding the
+ need to fight GLSL and GLSL ES differences.
+
+ The pipeline object is stored into \a pipeline, the fragment shader program
+ into \a program.
+
+ Use QOpenGLExtraFunctions to set uniforms, bind the pipeline, etc.
+
+ \return \c false on failure in which case the error log is printed on the
+ debug output. \c true on success.
+ */
+bool QQuickNvprFunctions::createFragmentOnlyPipeline(const char *fragmentShaderSource, GLuint *pipeline, GLuint *program)
+{
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ if (!ctx)
+ return false;
+
+ QOpenGLExtraFunctions *f = ctx->extraFunctions();
+ *program = f->glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &fragmentShaderSource);
+ GLint status = 0;
+ f->glGetProgramiv(*program, GL_LINK_STATUS, &status);
+ if (!status) {
+ GLint len = 0;
+ f->glGetProgramiv(*program, GL_INFO_LOG_LENGTH, &len);
+ if (len) {
+ QByteArray s;
+ s.resize(len);
+ f->glGetProgramInfoLog(*program, s.count(), nullptr, s.data());
+ qWarning("Failed to create separable shader program:\n%s", s.constData());
+ }
+ return false;
+ }
+
+ f->glGenProgramPipelines(1, pipeline);
+ f->glUseProgramStages(*pipeline, GL_FRAGMENT_SHADER_BIT, *program);
+ f->glActiveShaderProgram(*pipeline, *program);
+
+ f->glValidateProgramPipeline(*pipeline);
+ status = 0;
+ f->glGetProgramPipelineiv(*pipeline, GL_VALIDATE_STATUS, &status);
+ if (!status) {
+ GLint len = 0;
+ f->glGetProgramPipelineiv(*pipeline, GL_INFO_LOG_LENGTH, &len);
+ if (len) {
+ QByteArray s;
+ s.resize(len);
+ f->glGetProgramPipelineInfoLog(*pipeline, s.count(), nullptr, s.data());
+ qWarning("Program pipeline validation failed:\n%s", s.constData());
+ }
+ return false;
+ }
+
+ return true;
+}
+
+bool QQuickNvprFunctionsPrivate::resolve()
+{
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+
+ q->genPaths = PROC(PFNGLGENPATHSNVPROC, glGenPathsNV);
+ q->deletePaths = PROC(PFNGLDELETEPATHSNVPROC, glDeletePathsNV);
+ q->isPath = PROC(PFNGLISPATHNVPROC, glIsPathNV);
+ q->pathCommands = PROC(PFNGLPATHCOMMANDSNVPROC, glPathCommandsNV);
+ q->pathCoords = PROC(PFNGLPATHCOORDSNVPROC, glPathCoordsNV);
+ q->pathSubCommands = PROC(PFNGLPATHSUBCOMMANDSNVPROC, glPathSubCommandsNV);
+ q->pathSubCoords = PROC(PFNGLPATHSUBCOORDSNVPROC, glPathSubCoordsNV);
+ q->pathString = PROC(PFNGLPATHSTRINGNVPROC, glPathStringNV);
+ q->pathGlyphs = PROC(PFNGLPATHGLYPHSNVPROC, glPathGlyphsNV);
+ q->pathGlyphRange = PROC(PFNGLPATHGLYPHRANGENVPROC, glPathGlyphRangeNV);
+ q->weightPaths = PROC(PFNGLWEIGHTPATHSNVPROC, glWeightPathsNV);
+ q->copyPath = PROC(PFNGLCOPYPATHNVPROC, glCopyPathNV);
+ q->interpolatePaths = PROC(PFNGLINTERPOLATEPATHSNVPROC, glInterpolatePathsNV);
+ q->transformPath = PROC(PFNGLTRANSFORMPATHNVPROC, glTransformPathNV);
+ q->pathParameteriv = PROC(PFNGLPATHPARAMETERIVNVPROC, glPathParameterivNV);
+ q->pathParameteri = PROC(PFNGLPATHPARAMETERINVPROC, glPathParameteriNV);
+ q->pathParameterfv = PROC(PFNGLPATHPARAMETERFVNVPROC, glPathParameterfvNV);
+ q->pathParameterf = PROC(PFNGLPATHPARAMETERFNVPROC, glPathParameterfNV);
+ q->pathDashArray = PROC(PFNGLPATHDASHARRAYNVPROC, glPathDashArrayNV);
+ q->pathStencilFunc = PROC(PFNGLPATHSTENCILFUNCNVPROC, glPathStencilFuncNV);
+ q->pathStencilDepthOffset = PROC(PFNGLPATHSTENCILDEPTHOFFSETNVPROC, glPathStencilDepthOffsetNV);
+ q->stencilFillPath = PROC(PFNGLSTENCILFILLPATHNVPROC, glStencilFillPathNV);
+ q->stencilStrokePath = PROC(PFNGLSTENCILSTROKEPATHNVPROC, glStencilStrokePathNV);
+ q->stencilFillPathInstanced = PROC(PFNGLSTENCILFILLPATHINSTANCEDNVPROC, glStencilFillPathInstancedNV);
+ q->stencilStrokePathInstanced = PROC(PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC, glStencilStrokePathInstancedNV);
+ q->pathCoverDepthFunc = PROC(PFNGLPATHCOVERDEPTHFUNCNVPROC, glPathCoverDepthFuncNV);
+ q->coverFillPath = PROC(PFNGLCOVERFILLPATHNVPROC, glCoverFillPathNV);
+ q->coverStrokePath = PROC(PFNGLCOVERSTROKEPATHNVPROC, glCoverStrokePathNV);
+ q->coverFillPathInstanced = PROC(PFNGLCOVERFILLPATHINSTANCEDNVPROC, glCoverFillPathInstancedNV);
+ q->coverStrokePathInstanced = PROC(PFNGLCOVERSTROKEPATHINSTANCEDNVPROC, glCoverStrokePathInstancedNV);
+ q->getPathParameteriv = PROC(PFNGLGETPATHPARAMETERIVNVPROC, glGetPathParameterivNV);
+ q->getPathParameterfv = PROC(PFNGLGETPATHPARAMETERFVNVPROC, glGetPathParameterfvNV);
+ q->getPathCommands = PROC(PFNGLGETPATHCOMMANDSNVPROC, glGetPathCommandsNV);
+ q->getPathCoords = PROC(PFNGLGETPATHCOORDSNVPROC, glGetPathCoordsNV);
+ q->getPathDashArray = PROC(PFNGLGETPATHDASHARRAYNVPROC, glGetPathDashArrayNV);
+ q->getPathMetrics = PROC(PFNGLGETPATHMETRICSNVPROC, glGetPathMetricsNV);
+ q->getPathMetricRange = PROC(PFNGLGETPATHMETRICRANGENVPROC, glGetPathMetricRangeNV);
+ q->getPathSpacing = PROC(PFNGLGETPATHSPACINGNVPROC, glGetPathSpacingNV);
+ q->isPointInFillPath = PROC(PFNGLISPOINTINFILLPATHNVPROC, glIsPointInFillPathNV);
+ q->isPointInStrokePath = PROC(PFNGLISPOINTINSTROKEPATHNVPROC, glIsPointInStrokePathNV);
+ q->getPathLength = PROC(PFNGLGETPATHLENGTHNVPROC, glGetPathLengthNV);
+ q->getPointAlongPath = PROC(PFNGLPOINTALONGPATHNVPROC, glPointAlongPathNV);
+ q->matrixLoad3x2f = PROC(PFNGLMATRIXLOAD3X2FNVPROC, glMatrixLoad3x2fNV);
+ q->matrixLoad3x3f = PROC(PFNGLMATRIXLOAD3X3FNVPROC, glMatrixLoad3x3fNV);
+ q->matrixLoadTranspose3x3f = PROC(PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC, glMatrixLoadTranspose3x3fNV);
+ q->matrixMult3x2f = PROC(PFNGLMATRIXMULT3X2FNVPROC, glMatrixMult3x2fNV);
+ q->matrixMult3x3f = PROC(PFNGLMATRIXMULT3X3FNVPROC, glMatrixMult3x3fNV);
+ q->matrixMultTranspose3x3f = PROC(PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC, glMatrixMultTranspose3x3fNV);
+ q->stencilThenCoverFillPath = PROC(PFNGLSTENCILTHENCOVERFILLPATHNVPROC, glStencilThenCoverFillPathNV);
+ q->stencilThenCoverStrokePath = PROC(PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC, glStencilThenCoverStrokePathNV);
+ q->stencilThenCoverFillPathInstanced = PROC(PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC, glStencilThenCoverFillPathInstancedNV);
+ q->stencilThenCoverStrokePathInstanced = PROC(PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC, glStencilThenCoverStrokePathInstancedNV);
+ q->pathGlyphIndexRange = PROC(PFNGLPATHGLYPHINDEXRANGENVPROC, glPathGlyphIndexRangeNV);
+ q->pathGlyphIndexArray = PROC(PFNGLPATHGLYPHINDEXARRAYNVPROC, glPathGlyphIndexArrayNV);
+ q->pathMemoryGlyphIndexArray = PROC(PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC, glPathMemoryGlyphIndexArrayNV);
+ q->programPathFragmentInputGen = PROC(PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC, glProgramPathFragmentInputGenNV);
+ q->getProgramResourcefv = PROC(PFNGLGETPROGRAMRESOURCEFVNVPROC, glGetProgramResourcefvNV);
+
+ q->matrixLoadf = PROC(PFNGLMATRIXLOADFEXTPROC, glMatrixLoadfEXT);
+ q->matrixLoadIdentity = PROC(PFNGLMATRIXLOADIDENTITYEXTPROC, glMatrixLoadIdentityEXT);
+
+ return q->genPaths != nullptr // base path rendering ext
+ && q->programPathFragmentInputGen != nullptr // updated path rendering ext
+ && q->matrixLoadf != nullptr // direct state access ext
+ && q->matrixLoadIdentity != nullptr;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(opengl)
diff --git a/src/imports/shapes/qquicknvprfunctions_p.h b/src/imports/shapes/qquicknvprfunctions_p.h
new file mode 100644
index 0000000000..342e92cbc3
--- /dev/null
+++ b/src/imports/shapes/qquicknvprfunctions_p.h
@@ -0,0 +1,400 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKNVPRFUNCTIONS_P_H
+#define QQUICKNVPRFUNCTIONS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of a number of Qt sources files. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <qopengl.h>
+#include <QtGui/qsurfaceformat.h>
+
+#if QT_CONFIG(opengl)
+
+QT_BEGIN_NAMESPACE
+
+// note: fixed pipeline specific functions are removed - modern ES ext
+// headers have all this, but not the fixed stuff
+
+#ifndef GL_NV_path_rendering
+#define GL_PATH_FORMAT_SVG_NV 0x9070
+#define GL_PATH_FORMAT_PS_NV 0x9071
+#define GL_STANDARD_FONT_NAME_NV 0x9072
+#define GL_SYSTEM_FONT_NAME_NV 0x9073
+#define GL_FILE_NAME_NV 0x9074
+#define GL_PATH_STROKE_WIDTH_NV 0x9075
+#define GL_PATH_END_CAPS_NV 0x9076
+#define GL_PATH_INITIAL_END_CAP_NV 0x9077
+#define GL_PATH_TERMINAL_END_CAP_NV 0x9078
+#define GL_PATH_JOIN_STYLE_NV 0x9079
+#define GL_PATH_MITER_LIMIT_NV 0x907A
+#define GL_PATH_DASH_CAPS_NV 0x907B
+#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C
+#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D
+#define GL_PATH_DASH_OFFSET_NV 0x907E
+#define GL_PATH_CLIENT_LENGTH_NV 0x907F
+#define GL_PATH_FILL_MODE_NV 0x9080
+#define GL_PATH_FILL_MASK_NV 0x9081
+#define GL_PATH_FILL_COVER_MODE_NV 0x9082
+#define GL_PATH_STROKE_COVER_MODE_NV 0x9083
+#define GL_PATH_STROKE_MASK_NV 0x9084
+#define GL_COUNT_UP_NV 0x9088
+#define GL_COUNT_DOWN_NV 0x9089
+#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A
+#define GL_CONVEX_HULL_NV 0x908B
+#define GL_BOUNDING_BOX_NV 0x908D
+#define GL_TRANSLATE_X_NV 0x908E
+#define GL_TRANSLATE_Y_NV 0x908F
+#define GL_TRANSLATE_2D_NV 0x9090
+#define GL_TRANSLATE_3D_NV 0x9091
+#define GL_AFFINE_2D_NV 0x9092
+#define GL_AFFINE_3D_NV 0x9094
+#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096
+#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098
+#define GL_UTF8_NV 0x909A
+#define GL_UTF16_NV 0x909B
+#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C
+#define GL_PATH_COMMAND_COUNT_NV 0x909D
+#define GL_PATH_COORD_COUNT_NV 0x909E
+#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F
+#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0
+#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1
+#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2
+#define GL_SQUARE_NV 0x90A3
+#define GL_ROUND_NV 0x90A4
+#define GL_TRIANGULAR_NV 0x90A5
+#define GL_BEVEL_NV 0x90A6
+#define GL_MITER_REVERT_NV 0x90A7
+#define GL_MITER_TRUNCATE_NV 0x90A8
+#define GL_SKIP_MISSING_GLYPH_NV 0x90A9
+#define GL_USE_MISSING_GLYPH_NV 0x90AA
+#define GL_PATH_ERROR_POSITION_NV 0x90AB
+#define GL_PATH_FOG_GEN_MODE_NV 0x90AC
+#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD
+#define GL_ADJACENT_PAIRS_NV 0x90AE
+#define GL_FIRST_TO_REST_NV 0x90AF
+#define GL_PATH_GEN_MODE_NV 0x90B0
+#define GL_PATH_GEN_COEFF_NV 0x90B1
+#define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2
+#define GL_PATH_GEN_COMPONENTS_NV 0x90B3
+#define GL_PATH_STENCIL_FUNC_NV 0x90B7
+#define GL_PATH_STENCIL_REF_NV 0x90B8
+#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9
+#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD
+#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE
+#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF
+#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4
+#define GL_MOVE_TO_RESETS_NV 0x90B5
+#define GL_MOVE_TO_CONTINUES_NV 0x90B6
+#define GL_CLOSE_PATH_NV 0x00
+#define GL_MOVE_TO_NV 0x02
+#define GL_RELATIVE_MOVE_TO_NV 0x03
+#define GL_LINE_TO_NV 0x04
+#define GL_RELATIVE_LINE_TO_NV 0x05
+#define GL_HORIZONTAL_LINE_TO_NV 0x06
+#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07
+#define GL_VERTICAL_LINE_TO_NV 0x08
+#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09
+#define GL_QUADRATIC_CURVE_TO_NV 0x0A
+#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B
+#define GL_CUBIC_CURVE_TO_NV 0x0C
+#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D
+#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E
+#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F
+#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10
+#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11
+#define GL_SMALL_CCW_ARC_TO_NV 0x12
+#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13
+#define GL_SMALL_CW_ARC_TO_NV 0x14
+#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15
+#define GL_LARGE_CCW_ARC_TO_NV 0x16
+#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17
+#define GL_LARGE_CW_ARC_TO_NV 0x18
+#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19
+#define GL_RESTART_PATH_NV 0xF0
+#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2
+#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4
+#define GL_RECT_NV 0xF6
+#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8
+#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA
+#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC
+#define GL_ARC_TO_NV 0xFE
+#define GL_RELATIVE_ARC_TO_NV 0xFF
+#define GL_BOLD_BIT_NV 0x01
+#define GL_ITALIC_BIT_NV 0x02
+#define GL_GLYPH_WIDTH_BIT_NV 0x01
+#define GL_GLYPH_HEIGHT_BIT_NV 0x02
+#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04
+#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08
+#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10
+#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20
+#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40
+#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80
+#define GL_GLYPH_HAS_KERNING_BIT_NV 0x100
+#define GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000
+#define GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000
+#define GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000
+#define GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000
+#define GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000
+#define GL_FONT_ASCENDER_BIT_NV 0x00200000
+#define GL_FONT_DESCENDER_BIT_NV 0x00400000
+#define GL_FONT_HEIGHT_BIT_NV 0x00800000
+#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000
+#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000
+#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000
+#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000
+#define GL_FONT_HAS_KERNING_BIT_NV 0x10000000
+#define GL_PRIMARY_COLOR_NV 0x852C
+#define GL_SECONDARY_COLOR_NV 0x852D
+#define GL_ROUNDED_RECT_NV 0xE8
+#define GL_RELATIVE_ROUNDED_RECT_NV 0xE9
+#define GL_ROUNDED_RECT2_NV 0xEA
+#define GL_RELATIVE_ROUNDED_RECT2_NV 0xEB
+#define GL_ROUNDED_RECT4_NV 0xEC
+#define GL_RELATIVE_ROUNDED_RECT4_NV 0xED
+#define GL_ROUNDED_RECT8_NV 0xEE
+#define GL_RELATIVE_ROUNDED_RECT8_NV 0xEF
+#define GL_RELATIVE_RECT_NV 0xF7
+#define GL_FONT_GLYPHS_AVAILABLE_NV 0x9368
+#define GL_FONT_TARGET_UNAVAILABLE_NV 0x9369
+#define GL_FONT_UNAVAILABLE_NV 0x936A
+#define GL_FONT_UNINTELLIGIBLE_NV 0x936B
+#define GL_CONIC_CURVE_TO_NV 0x1A
+#define GL_RELATIVE_CONIC_CURVE_TO_NV 0x1B
+#define GL_FONT_NUM_GLYPH_INDICES_BIT_NV 0x20000000
+#define GL_STANDARD_FONT_FORMAT_NV 0x936C
+#define GL_2_BYTES_NV 0x1407
+#define GL_3_BYTES_NV 0x1408
+#define GL_4_BYTES_NV 0x1409
+#define GL_EYE_LINEAR_NV 0x2400
+#define GL_OBJECT_LINEAR_NV 0x2401
+#define GL_CONSTANT_NV 0x8576
+#define GL_PATH_PROJECTION_NV 0x1701
+#define GL_PATH_MODELVIEW_NV 0x1700
+#define GL_PATH_MODELVIEW_STACK_DEPTH_NV 0x0BA3
+#define GL_PATH_MODELVIEW_MATRIX_NV 0x0BA6
+#define GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV 0x0D36
+#define GL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV 0x84E3
+#define GL_PATH_PROJECTION_STACK_DEPTH_NV 0x0BA4
+#define GL_PATH_PROJECTION_MATRIX_NV 0x0BA7
+#define GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV 0x0D38
+#define GL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV 0x84E4
+#define GL_FRAGMENT_INPUT_NV 0x936D
+
+typedef GLuint (QOPENGLF_APIENTRYP PFNGLGENPATHSNVPROC) (GLsizei range);
+typedef void (QOPENGLF_APIENTRYP PFNGLDELETEPATHSNVPROC) (GLuint path, GLsizei range);
+typedef GLboolean (QOPENGLF_APIENTRYP PFNGLISPATHNVPROC) (GLuint path);
+typedef void (QOPENGLF_APIENTRYP PFNGLPATHCOMMANDSNVPROC) (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords);
+typedef void (QOPENGLF_APIENTRYP PFNGLPATHCOORDSNVPROC) (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords);
+typedef void (QOPENGLF_APIENTRYP PFNGLPATHSUBCOMMANDSNVPROC) (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords);
+typedef void (QOPENGLF_APIENTRYP PFNGLPATHSUBCOORDSNVPROC) (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords);
+typedef void (QOPENGLF_APIENTRYP PFNGLPATHSTRINGNVPROC) (GLuint path, GLenum format, GLsizei length, const void *pathString);
+typedef void (QOPENGLF_APIENTRYP PFNGLPATHGLYPHSNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+typedef void (QOPENGLF_APIENTRYP PFNGLPATHGLYPHRANGENVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+typedef void (QOPENGLF_APIENTRYP PFNGLWEIGHTPATHSNVPROC) (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights);
+typedef void (QOPENGLF_APIENTRYP PFNGLCOPYPATHNVPROC) (GLuint resultPath, GLuint srcPath);
+typedef void (QOPENGLF_APIENTRYP PFNGLINTERPOLATEPATHSNVPROC) (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight);
+typedef void (QOPENGLF_APIENTRYP PFNGLTRANSFORMPATHNVPROC) (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues);
+typedef void (QOPENGLF_APIENTRYP PFNGLPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, const GLint *value);
+typedef void (QOPENGLF_APIENTRYP PFNGLPATHPARAMETERINVPROC) (GLuint path, GLenum pname, GLint value);
+typedef void (QOPENGLF_APIENTRYP PFNGLPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, const GLfloat *value);
+typedef void (QOPENGLF_APIENTRYP PFNGLPATHPARAMETERFNVPROC) (GLuint path, GLenum pname, GLfloat value);
+typedef void (QOPENGLF_APIENTRYP PFNGLPATHDASHARRAYNVPROC) (GLuint path, GLsizei dashCount, const GLfloat *dashArray);
+typedef void (QOPENGLF_APIENTRYP PFNGLPATHSTENCILFUNCNVPROC) (GLenum func, GLint ref, GLuint mask);
+typedef void (QOPENGLF_APIENTRYP PFNGLPATHSTENCILDEPTHOFFSETNVPROC) (GLfloat factor, GLfloat units);
+typedef void (QOPENGLF_APIENTRYP PFNGLSTENCILFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask);
+typedef void (QOPENGLF_APIENTRYP PFNGLSTENCILSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask);
+typedef void (QOPENGLF_APIENTRYP PFNGLSTENCILFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues);
+typedef void (QOPENGLF_APIENTRYP PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues);
+typedef void (QOPENGLF_APIENTRYP PFNGLPATHCOVERDEPTHFUNCNVPROC) (GLenum func);
+typedef void (QOPENGLF_APIENTRYP PFNGLCOVERFILLPATHNVPROC) (GLuint path, GLenum coverMode);
+typedef void (QOPENGLF_APIENTRYP PFNGLCOVERSTROKEPATHNVPROC) (GLuint path, GLenum coverMode);
+typedef void (QOPENGLF_APIENTRYP PFNGLCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+typedef void (QOPENGLF_APIENTRYP PFNGLCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+typedef void (QOPENGLF_APIENTRYP PFNGLGETPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, GLint *value);
+typedef void (QOPENGLF_APIENTRYP PFNGLGETPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, GLfloat *value);
+typedef void (QOPENGLF_APIENTRYP PFNGLGETPATHCOMMANDSNVPROC) (GLuint path, GLubyte *commands);
+typedef void (QOPENGLF_APIENTRYP PFNGLGETPATHCOORDSNVPROC) (GLuint path, GLfloat *coords);
+typedef void (QOPENGLF_APIENTRYP PFNGLGETPATHDASHARRAYNVPROC) (GLuint path, GLfloat *dashArray);
+typedef void (QOPENGLF_APIENTRYP PFNGLGETPATHMETRICSNVPROC) (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics);
+typedef void (QOPENGLF_APIENTRYP PFNGLGETPATHMETRICRANGENVPROC) (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics);
+typedef void (QOPENGLF_APIENTRYP PFNGLGETPATHSPACINGNVPROC) (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing);
+typedef GLboolean (QOPENGLF_APIENTRYP PFNGLISPOINTINFILLPATHNVPROC) (GLuint path, GLuint mask, GLfloat x, GLfloat y);
+typedef GLboolean (QOPENGLF_APIENTRYP PFNGLISPOINTINSTROKEPATHNVPROC) (GLuint path, GLfloat x, GLfloat y);
+typedef GLfloat (QOPENGLF_APIENTRYP PFNGLGETPATHLENGTHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments);
+typedef GLboolean (QOPENGLF_APIENTRYP PFNGLPOINTALONGPATHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY);
+typedef void (QOPENGLF_APIENTRYP PFNGLMATRIXLOAD3X2FNVPROC) (GLenum matrixMode, const GLfloat *m);
+typedef void (QOPENGLF_APIENTRYP PFNGLMATRIXLOAD3X3FNVPROC) (GLenum matrixMode, const GLfloat *m);
+typedef void (QOPENGLF_APIENTRYP PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat *m);
+typedef void (QOPENGLF_APIENTRYP PFNGLMATRIXMULT3X2FNVPROC) (GLenum matrixMode, const GLfloat *m);
+typedef void (QOPENGLF_APIENTRYP PFNGLMATRIXMULT3X3FNVPROC) (GLenum matrixMode, const GLfloat *m);
+typedef void (QOPENGLF_APIENTRYP PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat *m);
+typedef void (QOPENGLF_APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode);
+typedef void (QOPENGLF_APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask, GLenum coverMode);
+typedef void (QOPENGLF_APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+typedef void (QOPENGLF_APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues);
+typedef GLenum (QOPENGLF_APIENTRYP PFNGLPATHGLYPHINDEXRANGENVPROC) (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint baseAndCount[2]);
+typedef GLenum (QOPENGLF_APIENTRYP PFNGLPATHGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+typedef GLenum (QOPENGLF_APIENTRYP PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
+typedef void (QOPENGLF_APIENTRYP PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC) (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs);
+typedef void (QOPENGLF_APIENTRYP PFNGLGETPROGRAMRESOURCEFVNVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLfloat *params);
+#endif
+
+#ifndef GL_FLAT
+#define GL_FLAT 0x1D00
+#endif
+
+#ifndef GL_INVERT
+#define GL_INVERT 0x150A
+#endif
+
+// this one originates from fixed pipeline so may not be in GLES ext headers, but we need it still
+#ifndef GL_OBJECT_LINEAR_NV
+#define GL_OBJECT_LINEAR_NV 0x2401
+#endif
+
+#ifndef GL_EXT_direct_state_access
+typedef void (QOPENGLF_APIENTRYP PFNGLMATRIXLOADFEXTPROC) (GLenum mode, const GLfloat *m);
+typedef void (QOPENGLF_APIENTRYP PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum mode);
+#endif
+
+// When building on a system with GLES 2.0 or 3.0, we may still compile the NVPR
+// code path even though it's never used. Keep it compiling by defining the
+// necessary ES 3.1 separable program constants.
+#ifndef GL_FRAGMENT_SHADER_BIT
+#define GL_FRAGMENT_SHADER_BIT 0x00000002
+#endif
+#ifndef GL_UNIFORM
+#define GL_UNIFORM 0x92E1
+#endif
+
+class QQuickNvprFunctionsPrivate;
+
+class QQuickNvprFunctions
+{
+public:
+ QQuickNvprFunctions();
+ ~QQuickNvprFunctions();
+
+ static QSurfaceFormat format();
+ static bool isSupported();
+
+ bool create();
+
+ bool createFragmentOnlyPipeline(const char *fragmentShaderSource, GLuint *pipeline, GLuint *program);
+
+ PFNGLGENPATHSNVPROC genPaths = nullptr;
+ PFNGLDELETEPATHSNVPROC deletePaths = nullptr;
+ PFNGLISPATHNVPROC isPath = nullptr;
+ PFNGLPATHCOMMANDSNVPROC pathCommands = nullptr;
+ PFNGLPATHCOORDSNVPROC pathCoords = nullptr;
+ PFNGLPATHSUBCOMMANDSNVPROC pathSubCommands = nullptr;
+ PFNGLPATHSUBCOORDSNVPROC pathSubCoords = nullptr;
+ PFNGLPATHSTRINGNVPROC pathString = nullptr;
+ PFNGLPATHGLYPHSNVPROC pathGlyphs = nullptr;
+ PFNGLPATHGLYPHRANGENVPROC pathGlyphRange = nullptr;
+ PFNGLWEIGHTPATHSNVPROC weightPaths = nullptr;
+ PFNGLCOPYPATHNVPROC copyPath = nullptr;
+ PFNGLINTERPOLATEPATHSNVPROC interpolatePaths = nullptr;
+ PFNGLTRANSFORMPATHNVPROC transformPath = nullptr;
+ PFNGLPATHPARAMETERIVNVPROC pathParameteriv = nullptr;
+ PFNGLPATHPARAMETERINVPROC pathParameteri = nullptr;
+ PFNGLPATHPARAMETERFVNVPROC pathParameterfv = nullptr;
+ PFNGLPATHPARAMETERFNVPROC pathParameterf = nullptr;
+ PFNGLPATHDASHARRAYNVPROC pathDashArray = nullptr;
+ PFNGLPATHSTENCILFUNCNVPROC pathStencilFunc = nullptr;
+ PFNGLPATHSTENCILDEPTHOFFSETNVPROC pathStencilDepthOffset = nullptr;
+ PFNGLSTENCILFILLPATHNVPROC stencilFillPath = nullptr;
+ PFNGLSTENCILSTROKEPATHNVPROC stencilStrokePath = nullptr;
+ PFNGLSTENCILFILLPATHINSTANCEDNVPROC stencilFillPathInstanced = nullptr;
+ PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC stencilStrokePathInstanced = nullptr;
+ PFNGLPATHCOVERDEPTHFUNCNVPROC pathCoverDepthFunc = nullptr;
+ PFNGLCOVERFILLPATHNVPROC coverFillPath = nullptr;
+ PFNGLCOVERSTROKEPATHNVPROC coverStrokePath = nullptr;
+ PFNGLCOVERFILLPATHINSTANCEDNVPROC coverFillPathInstanced = nullptr;
+ PFNGLCOVERSTROKEPATHINSTANCEDNVPROC coverStrokePathInstanced = nullptr;
+ PFNGLGETPATHPARAMETERIVNVPROC getPathParameteriv = nullptr;
+ PFNGLGETPATHPARAMETERFVNVPROC getPathParameterfv = nullptr;
+ PFNGLGETPATHCOMMANDSNVPROC getPathCommands = nullptr;
+ PFNGLGETPATHCOORDSNVPROC getPathCoords = nullptr;
+ PFNGLGETPATHDASHARRAYNVPROC getPathDashArray = nullptr;
+ PFNGLGETPATHMETRICSNVPROC getPathMetrics = nullptr;
+ PFNGLGETPATHMETRICRANGENVPROC getPathMetricRange = nullptr;
+ PFNGLGETPATHSPACINGNVPROC getPathSpacing = nullptr;
+ PFNGLISPOINTINFILLPATHNVPROC isPointInFillPath = nullptr;
+ PFNGLISPOINTINSTROKEPATHNVPROC isPointInStrokePath = nullptr;
+ PFNGLGETPATHLENGTHNVPROC getPathLength = nullptr;
+ PFNGLPOINTALONGPATHNVPROC getPointAlongPath = nullptr;
+ PFNGLMATRIXLOAD3X2FNVPROC matrixLoad3x2f = nullptr;
+ PFNGLMATRIXLOAD3X3FNVPROC matrixLoad3x3f = nullptr;
+ PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC matrixLoadTranspose3x3f = nullptr;
+ PFNGLMATRIXMULT3X2FNVPROC matrixMult3x2f = nullptr;
+ PFNGLMATRIXMULT3X3FNVPROC matrixMult3x3f = nullptr;
+ PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC matrixMultTranspose3x3f = nullptr;
+ PFNGLSTENCILTHENCOVERFILLPATHNVPROC stencilThenCoverFillPath = nullptr;
+ PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC stencilThenCoverStrokePath = nullptr;
+ PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC stencilThenCoverFillPathInstanced = nullptr;
+ PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC stencilThenCoverStrokePathInstanced = nullptr;
+ PFNGLPATHGLYPHINDEXRANGENVPROC pathGlyphIndexRange = nullptr;
+ PFNGLPATHGLYPHINDEXARRAYNVPROC pathGlyphIndexArray = nullptr;
+ PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC pathMemoryGlyphIndexArray = nullptr;
+ PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC programPathFragmentInputGen = nullptr;
+ PFNGLGETPROGRAMRESOURCEFVNVPROC getProgramResourcefv = nullptr;
+
+ PFNGLMATRIXLOADFEXTPROC matrixLoadf = nullptr;
+ PFNGLMATRIXLOADIDENTITYEXTPROC matrixLoadIdentity = nullptr;
+
+private:
+ QQuickNvprFunctionsPrivate *d;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(opengl)
+
+#endif // QQUICKNVPRFUNCTIONS_P_H
diff --git a/src/imports/shapes/qquicknvprfunctions_p_p.h b/src/imports/shapes/qquicknvprfunctions_p_p.h
new file mode 100644
index 0000000000..6df20566af
--- /dev/null
+++ b/src/imports/shapes/qquicknvprfunctions_p_p.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKNVPRFUNCTIONS_P_P_H
+#define QQUICKNVPRFUNCTIONS_P_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of a number of Qt sources files. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qquicknvprfunctions_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQuickNvprFunctionsPrivate
+{
+public:
+ QQuickNvprFunctionsPrivate(QQuickNvprFunctions *q_ptr) : q(q_ptr) { }
+
+ bool resolve();
+
+ QQuickNvprFunctions *q;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKNVPRFUNCTIONS_P_P_H
diff --git a/src/imports/shapes/qquickshape.cpp b/src/imports/shapes/qquickshape.cpp
new file mode 100644
index 0000000000..f0fdebe162
--- /dev/null
+++ b/src/imports/shapes/qquickshape.cpp
@@ -0,0 +1,1607 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickshape_p.h"
+#include "qquickshape_p_p.h"
+#include "qquickshapegenericrenderer_p.h"
+#include "qquickshapenvprrenderer_p.h"
+#include "qquickshapesoftwarerenderer_p.h"
+#include <private/qsgtexture_p.h>
+#include <private/qquicksvgparser_p.h>
+#include <QtGui/private/qdrawhelper_p.h>
+#include <QOpenGLFunctions>
+#include <QLoggingCategory>
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(QQSHAPE_LOG_TIME_DIRTY_SYNC, "qt.shape.time.sync")
+
+/*!
+ \qmlmodule QtQuick.Shapes 1.11
+ \title Qt Quick Shapes QML Types
+ \ingroup qmlmodules
+ \brief Provides QML types for drawing stroked and filled shapes.
+
+ To use the types in this module, import the module with the following line:
+
+ \badcode
+ import QtQuick.Shapes 1.11
+ \endcode
+*/
+
+QQuickShapeStrokeFillParams::QQuickShapeStrokeFillParams()
+ : strokeColor(Qt::white),
+ strokeWidth(1),
+ fillColor(Qt::white),
+ fillRule(QQuickShapePath::OddEvenFill),
+ joinStyle(QQuickShapePath::BevelJoin),
+ miterLimit(2),
+ capStyle(QQuickShapePath::SquareCap),
+ strokeStyle(QQuickShapePath::SolidLine),
+ dashOffset(0),
+ fillGradient(nullptr)
+{
+ dashPattern << 4 << 2; // 4 * strokeWidth dash followed by 2 * strokeWidth space
+}
+
+/*!
+ \qmltype ShapePath
+ \instantiates QQuickShapePath
+ \inqmlmodule QtQuick.Shapes
+ \ingroup qtquick-paths
+ \ingroup qtquick-views
+ \inherits Path
+ \brief Describes a Path and associated properties for stroking and filling.
+ \since 5.10
+
+ A \l Shape contains one or more ShapePath elements. At least one ShapePath is
+ necessary in order to have a Shape output anything visible. A ShapePath
+ itself is a \l Path with additional properties describing the stroking and
+ filling parameters, such as the stroke width and color, the fill color or
+ gradient, join and cap styles, and so on. As with ordinary \l Path objects,
+ ShapePath also contains a list of path elements like \l PathMove, \l PathLine,
+ \l PathCubic, \l PathQuad, \l PathArc, together with a starting position.
+
+ Any property changes in these data sets will be bubble up and change the
+ output of the Shape. This means that it is simple and easy to change, or
+ even animate, the starting and ending position, control points, or any
+ stroke or fill parameters using the usual QML bindings and animation types
+ like NumberAnimation.
+
+ In the following example the line join style changes automatically based on
+ the value of joinStyleIndex:
+
+ \qml
+ ShapePath {
+ strokeColor: "black"
+ strokeWidth: 16
+ fillColor: "transparent"
+ capStyle: ShapePath.RoundCap
+
+ property int joinStyleIndex: 0
+
+ property variant styles: [
+ ShapePath.BevelJoin,
+ ShapePath.MiterJoin,
+ ShapePath.RoundJoin
+ ]
+
+ joinStyle: styles[joinStyleIndex]
+
+ startX: 30
+ startY: 30
+ PathLine { x: 100; y: 100 }
+ PathLine { x: 30; y: 100 }
+ }
+ \endqml
+
+ Once associated with a Shape, here is the output with a joinStyleIndex
+ of 2 (ShapePath.RoundJoin):
+
+ \image visualpath-code-example.png
+
+ \sa {Qt Quick Examples - Shapes}, Shape
+ */
+
+QQuickShapePathPrivate::QQuickShapePathPrivate()
+ : dirty(DirtyAll)
+{
+ // Set this QQuickPath to be a ShapePath
+ isShapePath = true;
+}
+
+QQuickShapePath::QQuickShapePath(QObject *parent)
+ : QQuickPath(*(new QQuickShapePathPrivate), parent)
+{
+ // The inherited changed() and the shapePathChanged() signals remain
+ // distinct, and this is intentional. Combining the two is not possible due
+ // to the difference in semantics and the need to act (see dirty flag
+ // below) differently on QQuickPath-related changes.
+
+ connect(this, &QQuickPath::changed, [this]() {
+ Q_D(QQuickShapePath);
+ d->dirty |= QQuickShapePathPrivate::DirtyPath;
+ emit shapePathChanged();
+ });
+}
+
+QQuickShapePath::~QQuickShapePath()
+{
+}
+
+/*!
+ \qmlproperty color QtQuick.Shapes::ShapePath::strokeColor
+
+ This property holds the stroking color.
+
+ When set to \c transparent, no stroking occurs.
+
+ The default value is \c white.
+ */
+
+QColor QQuickShapePath::strokeColor() const
+{
+ Q_D(const QQuickShapePath);
+ return d->sfp.strokeColor;
+}
+
+void QQuickShapePath::setStrokeColor(const QColor &color)
+{
+ Q_D(QQuickShapePath);
+ if (d->sfp.strokeColor != color) {
+ d->sfp.strokeColor = color;
+ d->dirty |= QQuickShapePathPrivate::DirtyStrokeColor;
+ emit strokeColorChanged();
+ emit shapePathChanged();
+ }
+}
+
+/*!
+ \qmlproperty color QtQuick.Shapes::ShapePath::strokeWidth
+
+ This property holds the stroke width.
+
+ When set to a negative value, no stroking occurs.
+
+ The default value is 1.
+ */
+
+qreal QQuickShapePath::strokeWidth() const
+{
+ Q_D(const QQuickShapePath);
+ return d->sfp.strokeWidth;
+}
+
+void QQuickShapePath::setStrokeWidth(qreal w)
+{
+ Q_D(QQuickShapePath);
+ if (d->sfp.strokeWidth != w) {
+ d->sfp.strokeWidth = w;
+ d->dirty |= QQuickShapePathPrivate::DirtyStrokeWidth;
+ emit strokeWidthChanged();
+ emit shapePathChanged();
+ }
+}
+
+/*!
+ \qmlproperty color QtQuick.Shapes::ShapePath::fillColor
+
+ This property holds the fill color.
+
+ When set to \c transparent, no filling occurs.
+
+ The default value is \c white.
+ */
+
+QColor QQuickShapePath::fillColor() const
+{
+ Q_D(const QQuickShapePath);
+ return d->sfp.fillColor;
+}
+
+void QQuickShapePath::setFillColor(const QColor &color)
+{
+ Q_D(QQuickShapePath);
+ if (d->sfp.fillColor != color) {
+ d->sfp.fillColor = color;
+ d->dirty |= QQuickShapePathPrivate::DirtyFillColor;
+ emit fillColorChanged();
+ emit shapePathChanged();
+ }
+}
+
+/*!
+ \qmlproperty enumeration QtQuick.Shapes::ShapePath::fillRule
+
+ This property holds the fill rule. The default value is
+ \c ShapePath.OddEvenFill. For an explanation on fill rules, see
+ QPainterPath::setFillRule().
+
+ \value ShapePath.OddEvenFill
+ Odd-even fill rule.
+
+ \value ShapePath.WindingFill
+ Non-zero winding fill rule.
+ */
+
+QQuickShapePath::FillRule QQuickShapePath::fillRule() const
+{
+ Q_D(const QQuickShapePath);
+ return d->sfp.fillRule;
+}
+
+void QQuickShapePath::setFillRule(FillRule fillRule)
+{
+ Q_D(QQuickShapePath);
+ if (d->sfp.fillRule != fillRule) {
+ d->sfp.fillRule = fillRule;
+ d->dirty |= QQuickShapePathPrivate::DirtyFillRule;
+ emit fillRuleChanged();
+ emit shapePathChanged();
+ }
+}
+
+/*!
+ \qmlproperty enumeration QtQuick.Shapes::ShapePath::joinStyle
+
+ This property defines how joins between two connected lines are drawn. The
+ default value is \c ShapePath.BevelJoin.
+
+ \value ShapePath.MiterJoin
+ The outer edges of the lines are extended to meet at an angle, and
+ this area is filled.
+
+ \value ShapePath.BevelJoin
+ The triangular notch between the two lines is filled.
+
+ \value ShapePath.RoundJoin
+ A circular arc between the two lines is filled.
+ */
+
+QQuickShapePath::JoinStyle QQuickShapePath::joinStyle() const
+{
+ Q_D(const QQuickShapePath);
+ return d->sfp.joinStyle;
+}
+
+void QQuickShapePath::setJoinStyle(JoinStyle style)
+{
+ Q_D(QQuickShapePath);
+ if (d->sfp.joinStyle != style) {
+ d->sfp.joinStyle = style;
+ d->dirty |= QQuickShapePathPrivate::DirtyStyle;
+ emit joinStyleChanged();
+ emit shapePathChanged();
+ }
+}
+
+/*!
+ \qmlproperty int QtQuick.Shapes::ShapePath::miterLimit
+
+ When joinStyle is set to \c ShapePath.MiterJoin, this property
+ specifies how far the miter join can extend from the join point.
+
+ The default value is 2.
+ */
+
+int QQuickShapePath::miterLimit() const
+{
+ Q_D(const QQuickShapePath);
+ return d->sfp.miterLimit;
+}
+
+void QQuickShapePath::setMiterLimit(int limit)
+{
+ Q_D(QQuickShapePath);
+ if (d->sfp.miterLimit != limit) {
+ d->sfp.miterLimit = limit;
+ d->dirty |= QQuickShapePathPrivate::DirtyStyle;
+ emit miterLimitChanged();
+ emit shapePathChanged();
+ }
+}
+
+/*!
+ \qmlproperty enumeration QtQuick.Shapes::ShapePath::capStyle
+
+ This property defines how the end points of lines are drawn. The
+ default value is \c ShapePath.SquareCap.
+
+ \value ShapePath.FlatCap
+ A square line end that does not cover the end point of the line.
+
+ \value ShapePath.SquareCap
+ A square line end that covers the end point and extends beyond it
+ by half the line width.
+
+ \value ShapePath.RoundCap
+ A rounded line end.
+ */
+
+QQuickShapePath::CapStyle QQuickShapePath::capStyle() const
+{
+ Q_D(const QQuickShapePath);
+ return d->sfp.capStyle;
+}
+
+void QQuickShapePath::setCapStyle(CapStyle style)
+{
+ Q_D(QQuickShapePath);
+ if (d->sfp.capStyle != style) {
+ d->sfp.capStyle = style;
+ d->dirty |= QQuickShapePathPrivate::DirtyStyle;
+ emit capStyleChanged();
+ emit shapePathChanged();
+ }
+}
+
+/*!
+ \qmlproperty enumeration QtQuick.Shapes::ShapePath::strokeStyle
+
+ This property defines the style of stroking. The default value is
+ ShapePath.SolidLine.
+
+ \list
+ \li ShapePath.SolidLine - A plain line.
+ \li ShapePath.DashLine - Dashes separated by a few pixels.
+ \endlist
+ */
+
+QQuickShapePath::StrokeStyle QQuickShapePath::strokeStyle() const
+{
+ Q_D(const QQuickShapePath);
+ return d->sfp.strokeStyle;
+}
+
+void QQuickShapePath::setStrokeStyle(StrokeStyle style)
+{
+ Q_D(QQuickShapePath);
+ if (d->sfp.strokeStyle != style) {
+ d->sfp.strokeStyle = style;
+ d->dirty |= QQuickShapePathPrivate::DirtyDash;
+ emit strokeStyleChanged();
+ emit shapePathChanged();
+ }
+}
+
+/*!
+ \qmlproperty real QtQuick.Shapes::ShapePath::dashOffset
+
+ This property defines the starting point on the dash pattern, measured in
+ units used to specify the dash pattern.
+
+ The default value is 0.
+
+ \sa QPen::setDashOffset()
+ */
+
+qreal QQuickShapePath::dashOffset() const
+{
+ Q_D(const QQuickShapePath);
+ return d->sfp.dashOffset;
+}
+
+void QQuickShapePath::setDashOffset(qreal offset)
+{
+ Q_D(QQuickShapePath);
+ if (d->sfp.dashOffset != offset) {
+ d->sfp.dashOffset = offset;
+ d->dirty |= QQuickShapePathPrivate::DirtyDash;
+ emit dashOffsetChanged();
+ emit shapePathChanged();
+ }
+}
+
+/*!
+ \qmlproperty list<real> QtQuick.Shapes::ShapePath::dashPattern
+
+ This property defines the dash pattern when ShapePath.strokeStyle is set
+ to ShapePath.DashLine. The pattern must be specified as an even number of
+ positive entries where the entries 1, 3, 5... are the dashes and 2, 4,
+ 6... are the spaces. The pattern is specified in units of the pen's width.
+
+ The default value is (4, 2), meaning a dash of 4 * ShapePath.strokeWidth
+ pixels followed by a space of 2 * ShapePath.strokeWidth pixels.
+
+ \sa QPen::setDashPattern()
+ */
+
+QVector<qreal> QQuickShapePath::dashPattern() const
+{
+ Q_D(const QQuickShapePath);
+ return d->sfp.dashPattern;
+}
+
+void QQuickShapePath::setDashPattern(const QVector<qreal> &array)
+{
+ Q_D(QQuickShapePath);
+ if (d->sfp.dashPattern != array) {
+ d->sfp.dashPattern = array;
+ d->dirty |= QQuickShapePathPrivate::DirtyDash;
+ emit dashPatternChanged();
+ emit shapePathChanged();
+ }
+}
+
+/*!
+ \qmlproperty ShapeGradient QtQuick.Shapes::ShapePath::fillGradient
+
+ This property defines the fill gradient. By default no gradient is enabled
+ and the value is \c null. In this case the fill uses a solid color based
+ on the value of ShapePath.fillColor.
+
+ When set, ShapePath.fillColor is ignored and filling is done using one of
+ the ShapeGradient subtypes.
+
+ \note The Gradient type cannot be used here. Rather, prefer using one of
+ the advanced subtypes, like LinearGradient.
+ */
+
+QQuickShapeGradient *QQuickShapePath::fillGradient() const
+{
+ Q_D(const QQuickShapePath);
+ return d->sfp.fillGradient;
+}
+
+void QQuickShapePath::setFillGradient(QQuickShapeGradient *gradient)
+{
+ Q_D(QQuickShapePath);
+ if (d->sfp.fillGradient != gradient) {
+ if (d->sfp.fillGradient)
+ qmlobject_disconnect(d->sfp.fillGradient, QQuickShapeGradient, SIGNAL(updated()),
+ this, QQuickShapePath, SLOT(_q_fillGradientChanged()));
+ d->sfp.fillGradient = gradient;
+ if (d->sfp.fillGradient)
+ qmlobject_connect(d->sfp.fillGradient, QQuickShapeGradient, SIGNAL(updated()),
+ this, QQuickShapePath, SLOT(_q_fillGradientChanged()));
+ d->dirty |= QQuickShapePathPrivate::DirtyFillGradient;
+ emit shapePathChanged();
+ }
+}
+
+void QQuickShapePathPrivate::_q_fillGradientChanged()
+{
+ Q_Q(QQuickShapePath);
+ dirty |= DirtyFillGradient;
+ emit q->shapePathChanged();
+}
+
+void QQuickShapePath::resetFillGradient()
+{
+ setFillGradient(nullptr);
+}
+
+/*!
+ \qmltype Shape
+ \instantiates QQuickShape
+ \inqmlmodule QtQuick.Shapes
+ \ingroup qtquick-paths
+ \ingroup qtquick-views
+ \inherits Item
+ \brief Renders a path.
+ \since 5.10
+
+ Renders a path either by generating geometry via QPainterPath and manual
+ triangulation or by using a GPU vendor extension like
+ \c{GL_NV_path_rendering}.
+
+ This approach is different from rendering shapes via QQuickPaintedItem or
+ the 2D Canvas because the path never gets rasterized in software.
+ Therefore Shape is suitable for creating shapes spreading over larger
+ areas of the screen, avoiding the performance penalty for texture uploads
+ or framebuffer blits. In addition, the declarative API allows manipulating,
+ binding to, and even animating the path element properties like starting
+ and ending position, the control points, and so on.
+
+ The types for specifying path elements are shared between \l PathView and
+ Shape. However, not all Shape implementations support all path
+ element types, while some may not make sense for PathView. Shape's
+ currently supported subset is: PathMove, PathLine, PathQuad, PathCubic,
+ PathArc, and PathSvg.
+
+ See \l Path for a detailed overview of the supported path elements.
+
+ \qml
+ Shape {
+ width: 200
+ height: 150
+ anchors.centerIn: parent
+ ShapePath {
+ strokeWidth: 4
+ strokeColor: "red"
+ fillGradient: LinearGradient {
+ x1: 20; y1: 20
+ x2: 180; y2: 130
+ GradientStop { position: 0; color: "blue" }
+ GradientStop { position: 0.2; color: "green" }
+ GradientStop { position: 0.4; color: "red" }
+ GradientStop { position: 0.6; color: "yellow" }
+ GradientStop { position: 1; color: "cyan" }
+ }
+ strokeStyle: ShapePath.DashLine
+ dashPattern: [ 1, 4 ]
+ startX: 20; startY: 20
+ PathLine { x: 180; y: 130 }
+ PathLine { x: 20; y: 130 }
+ PathLine { x: 20; y: 20 }
+ }
+ }
+ \endqml
+
+ \image pathitem-code-example.png
+
+ Like \l Item, Shape also allows any visual or non-visual objects to be
+ declared as children. ShapePath objects are handled specially. This is
+ useful since it allows adding visual items, like \l Rectangle or \l Image,
+ and non-visual objects, like \l Timer directly as children of Shape.
+
+ The following list summarizes the available Shape rendering approaches:
+
+ \list
+
+ \li When running with the default, OpenGL backend of Qt Quick, both the
+ generic, triangulation-based and the NVIDIA-specific
+ \c{GL_NV_path_rendering} methods are available. The choice is made at
+ runtime, depending on the graphics driver's capabilities. When this is not
+ desired, applications can force using the generic method by setting the
+ Shape.vendorExtensionsEnabled property to \c false.
+
+ \li The \c software backend is fully supported. The path is rendered via
+ QPainter::strokePath() and QPainter::fillPath() in this case.
+
+ \li The Direct 3D 12 backend is not currently supported.
+
+ \li The OpenVG backend is not currently supported.
+
+ \endlist
+
+ When using Shape, it is important to be aware of potential performance
+ implications:
+
+ \list
+
+ \li When the application is running with the generic, triangulation-based
+ Shape implementation, the geometry generation happens entirely on the
+ CPU. This is potentially expensive. Changing the set of path elements,
+ changing the properties of these elements, or changing certain properties
+ of the Shape itself all lead to retriangulation of the affected paths on
+ every change. Therefore, applying animation to such properties can affect
+ performance on less powerful systems.
+
+ \li However, the data-driven, declarative nature of the Shape API often
+ means better cacheability for the underlying CPU and GPU resources. A
+ property change in one ShapePath will only lead to reprocessing the
+ affected ShapePath, leaving other parts of the Shape unchanged. Therefore,
+ a frequently changing property can still result in a lower overall system
+ load than with imperative painting approaches (for example, QPainter).
+
+ \li If animating properties other than stroke and fill colors is a must,
+ it is recommended to target systems providing \c{GL_NV_path_rendering}
+ where the cost of property changes is smaller.
+
+ \li At the same time, attention must be paid to the number of Shape
+ elements in the scene, in particular when using this special accelerated
+ approach for \c{GL_NV_path_rendering}. The way such a Shape item is
+ represented in the scene graph is different from an ordinary
+ geometry-based item, and incurs a certain cost when it comes to OpenGL
+ state changes.
+
+ \li As a general rule, scenes should avoid using separate Shape items when
+ it is not absolutely necessary. Prefer using one Shape item with multiple
+ ShapePath elements over multiple Shape items. Scenes that cannot avoid
+ using a large number of individual Shape items should consider setting
+ Shape.vendorExtensionsEnabled to \c false.
+ \endlist
+
+ \sa {Qt Quick Examples - Shapes}, Path, PathMove, PathLine, PathQuad, PathCubic, PathArc, PathSvg
+*/
+
+QQuickShapePrivate::QQuickShapePrivate()
+ : effectRefCount(0)
+{
+}
+
+QQuickShapePrivate::~QQuickShapePrivate()
+{
+ delete renderer;
+}
+
+void QQuickShapePrivate::_q_shapePathChanged()
+{
+ Q_Q(QQuickShape);
+ spChanged = true;
+ q->polish();
+}
+
+void QQuickShapePrivate::setStatus(QQuickShape::Status newStatus)
+{
+ Q_Q(QQuickShape);
+ if (status != newStatus) {
+ status = newStatus;
+ emit q->statusChanged();
+ }
+}
+
+QQuickShape::QQuickShape(QQuickItem *parent)
+ : QQuickItem(*(new QQuickShapePrivate), parent)
+{
+ setFlag(ItemHasContents);
+}
+
+QQuickShape::~QQuickShape()
+{
+}
+
+/*!
+ \qmlproperty enumeration QtQuick.Shapes::Shape::rendererType
+
+ This property determines which path rendering backend is active.
+
+ \value Shape.UnknownRenderer
+ The renderer is unknown.
+
+ \value Shape.GeometryRenderer
+ The generic, driver independent solution for OpenGL. Uses the same
+ CPU-based triangulation approach as QPainter's OpenGL 2 paint
+ engine. This is the default on non-NVIDIA hardware when the default,
+ OpenGL Qt Quick scenegraph backend is in use.
+
+ \value Shape.NvprRenderer
+ Path items are rendered by performing OpenGL calls using the
+ \c{GL_NV_path_rendering} extension. This is the default on NVIDIA
+ hardware when the default, OpenGL Qt Quick scenegraph backend is in
+ use.
+
+ \value Shape.SoftwareRenderer
+ Pure QPainter drawing using the raster paint engine. This is the
+ default, and only, option when the Qt Quick scenegraph is running
+ with the \c software backend.
+*/
+
+QQuickShape::RendererType QQuickShape::rendererType() const
+{
+ Q_D(const QQuickShape);
+ return d->rendererType;
+}
+
+/*!
+ \qmlproperty bool QtQuick.Shapes::Shape::asynchronous
+
+ When rendererType is \c Shape.GeometryRenderer, the input path is
+ triangulated on the CPU during the polishing phase of the Shape. This is
+ potentially expensive. To offload this work to separate worker threads,
+ set this property to \c true.
+
+ When enabled, making a Shape visible will not wait for the content to
+ become available. Instead, the gui/main thread is not blocked and the
+ results of the path rendering are shown only when all the asynchronous
+ work has been finished.
+
+ The default value is \c false.
+ */
+
+bool QQuickShape::asynchronous() const
+{
+ Q_D(const QQuickShape);
+ return d->async;
+}
+
+void QQuickShape::setAsynchronous(bool async)
+{
+ Q_D(QQuickShape);
+ if (d->async != async) {
+ d->async = async;
+ emit asynchronousChanged();
+ if (d->componentComplete)
+ d->_q_shapePathChanged();
+ }
+}
+
+/*!
+ \qmlproperty bool QtQuick.Shapes::Shape::vendorExtensionsEnabled
+
+ This property controls the usage of non-standard OpenGL extensions like
+ \c GL_NV_path_rendering. To disable Shape.NvprRenderer and force a uniform
+ behavior regardless of the graphics card and drivers, set this property to
+ \c false.
+
+ The default value is \c true.
+ */
+
+bool QQuickShape::vendorExtensionsEnabled() const
+{
+ Q_D(const QQuickShape);
+ return d->enableVendorExts;
+}
+
+void QQuickShape::setVendorExtensionsEnabled(bool enable)
+{
+ Q_D(QQuickShape);
+ if (d->enableVendorExts != enable) {
+ d->enableVendorExts = enable;
+ emit vendorExtensionsEnabledChanged();
+ }
+}
+
+/*!
+ \qmlproperty enumeration QtQuick.Shapes::Shape::status
+
+ This property determines the status of the Shape and is relevant when
+ Shape.asynchronous is set to \c true.
+
+ \value Shape.Null
+ Not yet initialized.
+
+ \value Shape.Ready
+ The Shape has finished processing.
+
+ \value Shape.Processing
+ The path is being processed.
+ */
+
+QQuickShape::Status QQuickShape::status() const
+{
+ Q_D(const QQuickShape);
+ return d->status;
+}
+
+/*!
+ \qmlproperty enumeration QtQuick.Shapes::Shape::containsMode
+ \since QtQuick.Shapes 1.11
+
+ This property determines the definition of \l {QQuickItem::contains()}{contains()}
+ for the Shape. It is useful in case you add
+ \l {Qt Quick Pointer Handlers QML Types}{Pointer Handlers} and you
+ want to react only when the mouse or touchpoint is fully inside the Shape.
+
+ \value Shape.BoundingRectContains
+ The default implementation of \l QQuickItem::contains() checks only
+ whether the given point is inside the rectangular bounding box. This is
+ the most efficient implementation, which is why it's the default.
+
+ \value Shape.FillContains
+ Check whether the interior (the part that would be filled if you are
+ rendering it with fill) of any \l ShapePath that makes up this Shape
+ contains the given point. The more complex and numerous ShapePaths you
+ add, the less efficient this is to check, which can potentially slow
+ down event delivery in your application. So it should be used with care.
+
+ One way to speed up the \c FillContains check is to generate an approximate
+ outline with as few points as possible, place that in a transparent Shape
+ on top, and add your Pointer Handlers to that, so that the containment
+ check is cheaper during event delivery.
+*/
+QQuickShape::ContainsMode QQuickShape::containsMode() const
+{
+ Q_D(const QQuickShape);
+ return d->containsMode;
+}
+
+void QQuickShape::setContainsMode(QQuickShape::ContainsMode containsMode)
+{
+ Q_D(QQuickShape);
+ if (d->containsMode == containsMode)
+ return;
+
+ d->containsMode = containsMode;
+ emit containsModeChanged();
+}
+
+bool QQuickShape::contains(const QPointF &point) const
+{
+ Q_D(const QQuickShape);
+ switch (d->containsMode) {
+ case BoundingRectContains:
+ return QQuickItem::contains(point);
+ case FillContains:
+ for (QQuickShapePath *path : d->sp) {
+ if (path->path().contains(point))
+ return true;
+ }
+ }
+ return false;
+}
+
+static void vpe_append(QQmlListProperty<QObject> *property, QObject *obj)
+{
+ QQuickShape *item = static_cast<QQuickShape *>(property->object);
+ QQuickShapePrivate *d = QQuickShapePrivate::get(item);
+ QQuickShapePath *path = qobject_cast<QQuickShapePath *>(obj);
+ if (path)
+ d->sp.append(path);
+
+ QQuickItemPrivate::data_append(property, obj);
+
+ if (path && d->componentComplete) {
+ QObject::connect(path, SIGNAL(shapePathChanged()), item, SLOT(_q_shapePathChanged()));
+ d->_q_shapePathChanged();
+ }
+}
+
+static void vpe_clear(QQmlListProperty<QObject> *property)
+{
+ QQuickShape *item = static_cast<QQuickShape *>(property->object);
+ QQuickShapePrivate *d = QQuickShapePrivate::get(item);
+
+ for (QQuickShapePath *p : d->sp)
+ QObject::disconnect(p, SIGNAL(shapePathChanged()), item, SLOT(_q_shapePathChanged()));
+
+ d->sp.clear();
+
+ QQuickItemPrivate::data_clear(property);
+
+ if (d->componentComplete)
+ d->_q_shapePathChanged();
+}
+
+/*!
+ \qmlproperty list<Object> QtQuick.Shapes::Shape::data
+
+ This property holds the ShapePath objects that define the contents of the
+ Shape. It can also contain any other type of objects, since Shape, like
+ Item, allows adding any visual or non-visual objects as children.
+
+ \default
+ */
+
+QQmlListProperty<QObject> QQuickShape::data()
+{
+ return QQmlListProperty<QObject>(this,
+ nullptr,
+ vpe_append,
+ QQuickItemPrivate::data_count,
+ QQuickItemPrivate::data_at,
+ vpe_clear);
+}
+
+void QQuickShape::classBegin()
+{
+ QQuickItem::classBegin();
+}
+
+void QQuickShape::componentComplete()
+{
+ Q_D(QQuickShape);
+
+ QQuickItem::componentComplete();
+
+ for (QQuickShapePath *p : d->sp)
+ connect(p, SIGNAL(shapePathChanged()), this, SLOT(_q_shapePathChanged()));
+
+ d->_q_shapePathChanged();
+}
+
+void QQuickShape::updatePolish()
+{
+ Q_D(QQuickShape);
+
+ const int currentEffectRefCount = d->extra.isAllocated() ? d->extra->recursiveEffectRefCount : 0;
+ if (!d->spChanged && currentEffectRefCount <= d->effectRefCount)
+ return;
+
+ d->spChanged = false;
+ d->effectRefCount = currentEffectRefCount;
+
+ if (!d->renderer) {
+ d->createRenderer();
+ if (!d->renderer)
+ return;
+ emit rendererChanged();
+ }
+
+ // endSync() is where expensive calculations may happen (or get kicked off
+ // on worker threads), depending on the backend. Therefore do this only
+ // when the item is visible.
+ if (isVisible() || d->effectRefCount > 0)
+ d->sync();
+
+ update();
+}
+
+void QQuickShape::itemChange(ItemChange change, const ItemChangeData &data)
+{
+ Q_D(QQuickShape);
+
+ // sync may have been deferred; do it now if the item became visible
+ if (change == ItemVisibleHasChanged && data.boolValue)
+ d->_q_shapePathChanged();
+
+ QQuickItem::itemChange(change, data);
+}
+
+QSGNode *QQuickShape::updatePaintNode(QSGNode *node, UpdatePaintNodeData *)
+{
+ // Called on the render thread, with the gui thread blocked. We can now
+ // safely access gui thread data.
+
+ Q_D(QQuickShape);
+ if (d->renderer) {
+ if (!node)
+ node = d->createNode();
+ d->renderer->updateNode();
+ }
+ return node;
+}
+
+// the renderer object lives on the gui thread
+void QQuickShapePrivate::createRenderer()
+{
+ Q_Q(QQuickShape);
+ QSGRendererInterface *ri = q->window()->rendererInterface();
+ if (!ri)
+ return;
+
+ switch (ri->graphicsApi()) {
+#if QT_CONFIG(opengl)
+ case QSGRendererInterface::OpenGL:
+ if (enableVendorExts && QQuickShapeNvprRenderNode::isSupported()) {
+ rendererType = QQuickShape::NvprRenderer;
+ renderer = new QQuickShapeNvprRenderer;
+ } else {
+ rendererType = QQuickShape::GeometryRenderer;
+ renderer = new QQuickShapeGenericRenderer(q);
+ }
+ break;
+#endif
+ case QSGRendererInterface::Software:
+ rendererType = QQuickShape::SoftwareRenderer;
+ renderer = new QQuickShapeSoftwareRenderer;
+ break;
+ default:
+ qWarning("No path backend for this graphics API yet");
+ break;
+ }
+}
+
+// the node lives on the render thread
+QSGNode *QQuickShapePrivate::createNode()
+{
+ Q_Q(QQuickShape);
+ QSGNode *node = nullptr;
+ if (!q->window())
+ return node;
+ QSGRendererInterface *ri = q->window()->rendererInterface();
+ if (!ri)
+ return node;
+
+ switch (ri->graphicsApi()) {
+#if QT_CONFIG(opengl)
+ case QSGRendererInterface::OpenGL:
+ if (enableVendorExts && QQuickShapeNvprRenderNode::isSupported()) {
+ node = new QQuickShapeNvprRenderNode;
+ static_cast<QQuickShapeNvprRenderer *>(renderer)->setNode(
+ static_cast<QQuickShapeNvprRenderNode *>(node));
+ } else {
+ node = new QQuickShapeGenericNode;
+ static_cast<QQuickShapeGenericRenderer *>(renderer)->setRootNode(
+ static_cast<QQuickShapeGenericNode *>(node));
+ }
+ break;
+#endif
+ case QSGRendererInterface::Software:
+ node = new QQuickShapeSoftwareRenderNode(q);
+ static_cast<QQuickShapeSoftwareRenderer *>(renderer)->setNode(
+ static_cast<QQuickShapeSoftwareRenderNode *>(node));
+ break;
+ default:
+ qWarning("No path backend for this graphics API yet");
+ break;
+ }
+
+ return node;
+}
+
+void QQuickShapePrivate::asyncShapeReady(void *data)
+{
+ QQuickShapePrivate *self = static_cast<QQuickShapePrivate *>(data);
+ self->setStatus(QQuickShape::Ready);
+ if (self->syncTimingActive)
+ qDebug("[Shape %p] [%d] [dirty=0x%x] async update took %lld ms",
+ self->q_func(), self->syncTimeCounter, self->syncTimingTotalDirty, self->syncTimer.elapsed());
+}
+
+void QQuickShapePrivate::sync()
+{
+ syncTimingTotalDirty = 0;
+ syncTimingActive = QQSHAPE_LOG_TIME_DIRTY_SYNC().isDebugEnabled();
+ if (syncTimingActive)
+ syncTimer.start();
+
+ const bool useAsync = async && renderer->flags().testFlag(QQuickAbstractPathRenderer::SupportsAsync);
+ if (useAsync) {
+ setStatus(QQuickShape::Processing);
+ renderer->setAsyncCallback(asyncShapeReady, this);
+ }
+
+ const int count = sp.count();
+ renderer->beginSync(count);
+
+ for (int i = 0; i < count; ++i) {
+ QQuickShapePath *p = sp[i];
+ int &dirty(QQuickShapePathPrivate::get(p)->dirty);
+ syncTimingTotalDirty |= dirty;
+
+ if (dirty & QQuickShapePathPrivate::DirtyPath)
+ renderer->setPath(i, p);
+ if (dirty & QQuickShapePathPrivate::DirtyStrokeColor)
+ renderer->setStrokeColor(i, p->strokeColor());
+ if (dirty & QQuickShapePathPrivate::DirtyStrokeWidth)
+ renderer->setStrokeWidth(i, p->strokeWidth());
+ if (dirty & QQuickShapePathPrivate::DirtyFillColor)
+ renderer->setFillColor(i, p->fillColor());
+ if (dirty & QQuickShapePathPrivate::DirtyFillRule)
+ renderer->setFillRule(i, p->fillRule());
+ if (dirty & QQuickShapePathPrivate::DirtyStyle) {
+ renderer->setJoinStyle(i, p->joinStyle(), p->miterLimit());
+ renderer->setCapStyle(i, p->capStyle());
+ }
+ if (dirty & QQuickShapePathPrivate::DirtyDash)
+ renderer->setStrokeStyle(i, p->strokeStyle(), p->dashOffset(), p->dashPattern());
+ if (dirty & QQuickShapePathPrivate::DirtyFillGradient)
+ renderer->setFillGradient(i, p->fillGradient());
+
+ dirty = 0;
+ }
+
+ if (syncTimingTotalDirty)
+ ++syncTimeCounter;
+ else
+ syncTimingActive = false;
+
+ renderer->endSync(useAsync);
+
+ if (!useAsync) {
+ setStatus(QQuickShape::Ready);
+ if (syncTimingActive)
+ qDebug("[Shape %p] [%d] [dirty=0x%x] update took %lld ms",
+ q_func(), syncTimeCounter, syncTimingTotalDirty, syncTimer.elapsed());
+ }
+}
+
+// ***** gradient support *****
+
+/*!
+ \qmltype ShapeGradient
+ \instantiates QQuickShapeGradient
+ \inqmlmodule QtQuick.Shapes
+ \ingroup qtquick-paths
+ \ingroup qtquick-views
+ \inherits Gradient
+ \brief Base type of Shape fill gradients.
+ \since 5.10
+
+ This is an abstract base class for gradients like LinearGradient and
+ cannot be created directly. It extends \l Gradient with properties like the
+ spread mode.
+ */
+
+QQuickShapeGradient::QQuickShapeGradient(QObject *parent)
+ : QQuickGradient(parent),
+ m_spread(PadSpread)
+{
+}
+
+/*!
+ \qmlproperty enumeration QtQuick.Shapes::ShapeGradient::spread
+
+ Specifies how the area outside the gradient area should be filled. The
+ default value is \c ShapeGradient.PadSpread.
+
+ \value ShapeGradient.PadSpread
+ The area is filled with the closest stop color.
+
+ \value ShapeGradient.RepeatSpread
+ The gradient is repeated outside the gradient area.
+
+ \value ShapeGradient.ReflectSpread
+ The gradient is reflected outside the gradient area.
+ */
+
+QQuickShapeGradient::SpreadMode QQuickShapeGradient::spread() const
+{
+ return m_spread;
+}
+
+void QQuickShapeGradient::setSpread(SpreadMode mode)
+{
+ if (m_spread != mode) {
+ m_spread = mode;
+ emit spreadChanged();
+ emit updated();
+ }
+}
+
+/*!
+ \qmltype LinearGradient
+ \instantiates QQuickShapeLinearGradient
+ \inqmlmodule QtQuick.Shapes
+ \ingroup qtquick-paths
+ \ingroup qtquick-views
+ \inherits ShapeGradient
+ \brief Linear gradient.
+ \since 5.10
+
+ Linear gradients interpolate colors between start and end points in Shape
+ items. Outside these points the gradient is either padded, reflected or
+ repeated depending on the spread type.
+
+ \note LinearGradient is only supported in combination with Shape items. It
+ is not compatible with \l Rectangle, as that only supports \l Gradient.
+
+ \sa QLinearGradient
+ */
+
+QQuickShapeLinearGradient::QQuickShapeLinearGradient(QObject *parent)
+ : QQuickShapeGradient(parent)
+{
+}
+
+/*!
+ \qmlproperty real QtQuick.Shapes::LinearGradient::x1
+ \qmlproperty real QtQuick.Shapes::LinearGradient::y1
+ \qmlproperty real QtQuick.Shapes::LinearGradient::x2
+ \qmlproperty real QtQuick.Shapes::LinearGradient::y2
+
+ These properties define the start and end points between which color
+ interpolation occurs. By default both points are set to (0, 0).
+ */
+
+qreal QQuickShapeLinearGradient::x1() const
+{
+ return m_start.x();
+}
+
+void QQuickShapeLinearGradient::setX1(qreal v)
+{
+ if (m_start.x() != v) {
+ m_start.setX(v);
+ emit x1Changed();
+ emit updated();
+ }
+}
+
+qreal QQuickShapeLinearGradient::y1() const
+{
+ return m_start.y();
+}
+
+void QQuickShapeLinearGradient::setY1(qreal v)
+{
+ if (m_start.y() != v) {
+ m_start.setY(v);
+ emit y1Changed();
+ emit updated();
+ }
+}
+
+qreal QQuickShapeLinearGradient::x2() const
+{
+ return m_end.x();
+}
+
+void QQuickShapeLinearGradient::setX2(qreal v)
+{
+ if (m_end.x() != v) {
+ m_end.setX(v);
+ emit x2Changed();
+ emit updated();
+ }
+}
+
+qreal QQuickShapeLinearGradient::y2() const
+{
+ return m_end.y();
+}
+
+void QQuickShapeLinearGradient::setY2(qreal v)
+{
+ if (m_end.y() != v) {
+ m_end.setY(v);
+ emit y2Changed();
+ emit updated();
+ }
+}
+
+/*!
+ \qmltype RadialGradient
+ \instantiates QQuickShapeRadialGradient
+ \inqmlmodule QtQuick.Shapes
+ \ingroup qtquick-paths
+ \ingroup qtquick-views
+ \inherits ShapeGradient
+ \brief Radial gradient.
+ \since 5.10
+
+ Radial gradients interpolate colors between a focal circle and a center
+ circle in Shape items. Points outside the cone defined by the two circles
+ will be transparent.
+
+ Outside the end points the gradient is either padded, reflected or repeated
+ depending on the spread type.
+
+ Below is an example of a simple radial gradient. Here the colors are
+ interpolated between the specified point and the end points on a circle
+ specified by the radius:
+
+ \code
+ fillGradient: RadialGradient {
+ centerX: 50; centerY: 50
+ centerRadius: 100
+ focalX: centerX; focalY: centerY
+ GradientStop { position: 0; color: "blue" }
+ GradientStop { position: 0.2; color: "green" }
+ GradientStop { position: 0.4; color: "red" }
+ GradientStop { position: 0.6; color: "yellow" }
+ GradientStop { position: 1; color: "cyan" }
+ }
+ \endcode
+
+ \image shape-radial-gradient.png
+
+ Extended radial gradients, where a separate focal circle is specified, are
+ also supported.
+
+ \note RadialGradient is only supported in combination with Shape items. It
+ is not compatible with \l Rectangle, as that only supports \l Gradient.
+
+ \sa QRadialGradient
+ */
+
+QQuickShapeRadialGradient::QQuickShapeRadialGradient(QObject *parent)
+ : QQuickShapeGradient(parent)
+{
+}
+
+/*!
+ \qmlproperty real QtQuick.Shapes::RadialGradient::centerX
+ \qmlproperty real QtQuick.Shapes::RadialGradient::centerY
+ \qmlproperty real QtQuick.Shapes::RadialGradient::focalX
+ \qmlproperty real QtQuick.Shapes::RadialGradient::focalY
+
+ These properties define the center and focal points. To specify a simple
+ radial gradient, set focalX and focalY to the value of centerX and
+ centerY, respectively.
+ */
+
+qreal QQuickShapeRadialGradient::centerX() const
+{
+ return m_centerPoint.x();
+}
+
+void QQuickShapeRadialGradient::setCenterX(qreal v)
+{
+ if (m_centerPoint.x() != v) {
+ m_centerPoint.setX(v);
+ emit centerXChanged();
+ emit updated();
+ }
+}
+
+qreal QQuickShapeRadialGradient::centerY() const
+{
+ return m_centerPoint.y();
+}
+
+void QQuickShapeRadialGradient::setCenterY(qreal v)
+{
+ if (m_centerPoint.y() != v) {
+ m_centerPoint.setY(v);
+ emit centerYChanged();
+ emit updated();
+ }
+}
+
+/*!
+ \qmlproperty real QtQuick.Shapes::RadialGradient::centerRadius
+ \qmlproperty real QtQuick.Shapes::RadialGradient::focalRadius
+
+ These properties define the center and focal radius. For simple radial
+ gradients, focalRadius should be set to \c 0 (the default value).
+ */
+
+qreal QQuickShapeRadialGradient::centerRadius() const
+{
+ return m_centerRadius;
+}
+
+void QQuickShapeRadialGradient::setCenterRadius(qreal v)
+{
+ if (m_centerRadius != v) {
+ m_centerRadius = v;
+ emit centerRadiusChanged();
+ emit updated();
+ }
+}
+
+qreal QQuickShapeRadialGradient::focalX() const
+{
+ return m_focalPoint.x();
+}
+
+void QQuickShapeRadialGradient::setFocalX(qreal v)
+{
+ if (m_focalPoint.x() != v) {
+ m_focalPoint.setX(v);
+ emit focalXChanged();
+ emit updated();
+ }
+}
+
+qreal QQuickShapeRadialGradient::focalY() const
+{
+ return m_focalPoint.y();
+}
+
+void QQuickShapeRadialGradient::setFocalY(qreal v)
+{
+ if (m_focalPoint.y() != v) {
+ m_focalPoint.setY(v);
+ emit focalYChanged();
+ emit updated();
+ }
+}
+
+qreal QQuickShapeRadialGradient::focalRadius() const
+{
+ return m_focalRadius;
+}
+
+void QQuickShapeRadialGradient::setFocalRadius(qreal v)
+{
+ if (m_focalRadius != v) {
+ m_focalRadius = v;
+ emit focalRadiusChanged();
+ emit updated();
+ }
+}
+
+/*!
+ \qmltype ConicalGradient
+ \instantiates QQuickShapeConicalGradient
+ \inqmlmodule QtQuick.Shapes
+ \ingroup qtquick-paths
+ \ingroup qtquick-views
+ \inherits ShapeGradient
+ \brief Conical gradient.
+ \since 5.10
+
+ Conical gradients interpolate colors counter-clockwise around a center
+ point in Shape items.
+
+ \note The \l{ShapeGradient.spread}{spread mode} setting has no effect for
+ conical gradients.
+
+ \note ConicalGradient is only supported in combination with Shape items. It
+ is not compatible with \l Rectangle, as that only supports \l Gradient.
+
+ \sa QConicalGradient
+ */
+
+QQuickShapeConicalGradient::QQuickShapeConicalGradient(QObject *parent)
+ : QQuickShapeGradient(parent)
+{
+}
+
+/*!
+ \qmlproperty real QtQuick.Shapes::ConicalGradient::centerX
+ \qmlproperty real QtQuick.Shapes::ConicalGradient::centerY
+
+ These properties define the center point of the conical gradient.
+ */
+
+qreal QQuickShapeConicalGradient::centerX() const
+{
+ return m_centerPoint.x();
+}
+
+void QQuickShapeConicalGradient::setCenterX(qreal v)
+{
+ if (m_centerPoint.x() != v) {
+ m_centerPoint.setX(v);
+ emit centerXChanged();
+ emit updated();
+ }
+}
+
+qreal QQuickShapeConicalGradient::centerY() const
+{
+ return m_centerPoint.y();
+}
+
+void QQuickShapeConicalGradient::setCenterY(qreal v)
+{
+ if (m_centerPoint.y() != v) {
+ m_centerPoint.setY(v);
+ emit centerYChanged();
+ emit updated();
+ }
+}
+
+/*!
+ \qmlproperty real QtQuick.Shapes::ConicalGradient::angle
+
+ This property defines the start angle for the conical gradient. The value
+ is in degrees (0-360).
+ */
+
+qreal QQuickShapeConicalGradient::angle() const
+{
+ return m_angle;
+}
+
+void QQuickShapeConicalGradient::setAngle(qreal v)
+{
+ if (m_angle != v) {
+ m_angle = v;
+ emit angleChanged();
+ emit updated();
+ }
+}
+
+#if QT_CONFIG(opengl)
+
+// contexts sharing with each other get the same cache instance
+class QQuickShapeGradientCacheWrapper
+{
+public:
+ QQuickShapeGradientCache *get(QOpenGLContext *context)
+ {
+ return m_resource.value<QQuickShapeGradientCache>(context);
+ }
+
+private:
+ QOpenGLMultiGroupSharedResource m_resource;
+};
+
+QQuickShapeGradientCache *QQuickShapeGradientCache::currentCache()
+{
+ static QQuickShapeGradientCacheWrapper qt_path_gradient_caches;
+ return qt_path_gradient_caches.get(QOpenGLContext::currentContext());
+}
+
+// let QOpenGLContext manage the lifetime of the cached textures
+QQuickShapeGradientCache::~QQuickShapeGradientCache()
+{
+ m_cache.clear();
+}
+
+void QQuickShapeGradientCache::invalidateResource()
+{
+ m_cache.clear();
+}
+
+void QQuickShapeGradientCache::freeResource(QOpenGLContext *)
+{
+ qDeleteAll(m_cache);
+ m_cache.clear();
+}
+
+static void generateGradientColorTable(const QQuickShapeGradientCache::Key &gradient,
+ uint *colorTable, int size, float opacity)
+{
+ int pos = 0;
+ const QGradientStops &s = gradient.stops;
+ const bool colorInterpolation = true;
+
+ uint alpha = qRound(opacity * 256);
+ uint current_color = ARGB_COMBINE_ALPHA(s[0].second.rgba(), alpha);
+ qreal incr = 1.0 / qreal(size);
+ qreal fpos = 1.5 * incr;
+ colorTable[pos++] = ARGB2RGBA(qPremultiply(current_color));
+
+ while (fpos <= s.first().first) {
+ colorTable[pos] = colorTable[pos - 1];
+ pos++;
+ fpos += incr;
+ }
+
+ if (colorInterpolation)
+ current_color = qPremultiply(current_color);
+
+ const int sLast = s.size() - 1;
+ for (int i = 0; i < sLast; ++i) {
+ qreal delta = 1/(s[i+1].first - s[i].first);
+ uint next_color = ARGB_COMBINE_ALPHA(s[i + 1].second.rgba(), alpha);
+ if (colorInterpolation)
+ next_color = qPremultiply(next_color);
+
+ while (fpos < s[i+1].first && pos < size) {
+ int dist = int(256 * ((fpos - s[i].first) * delta));
+ int idist = 256 - dist;
+ if (colorInterpolation)
+ colorTable[pos] = ARGB2RGBA(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
+ else
+ colorTable[pos] = ARGB2RGBA(qPremultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist)));
+ ++pos;
+ fpos += incr;
+ }
+ current_color = next_color;
+ }
+
+ Q_ASSERT(s.size() > 0);
+
+ uint last_color = ARGB2RGBA(qPremultiply(ARGB_COMBINE_ALPHA(s[sLast].second.rgba(), alpha)));
+ for ( ; pos < size; ++pos)
+ colorTable[pos] = last_color;
+
+ colorTable[size-1] = last_color;
+}
+
+QSGTexture *QQuickShapeGradientCache::get(const Key &grad)
+{
+ QSGPlainTexture *tx = m_cache[grad];
+ if (!tx) {
+ QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
+ GLuint id;
+ f->glGenTextures(1, &id);
+ f->glBindTexture(GL_TEXTURE_2D, id);
+ static const uint W = 1024; // texture size is 1024x1
+ uint buf[W];
+ generateGradientColorTable(grad, buf, W, 1.0f);
+ f->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, W, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
+ tx = new QSGPlainTexture;
+ tx->setTextureId(id);
+ switch (grad.spread) {
+ case QQuickShapeGradient::PadSpread:
+ tx->setHorizontalWrapMode(QSGTexture::ClampToEdge);
+ tx->setVerticalWrapMode(QSGTexture::ClampToEdge);
+ break;
+ case QQuickShapeGradient::RepeatSpread:
+ tx->setHorizontalWrapMode(QSGTexture::Repeat);
+ tx->setVerticalWrapMode(QSGTexture::Repeat);
+ break;
+ case QQuickShapeGradient::ReflectSpread:
+ tx->setHorizontalWrapMode(QSGTexture::MirroredRepeat);
+ tx->setVerticalWrapMode(QSGTexture::MirroredRepeat);
+ break;
+ default:
+ qWarning("Unknown gradient spread mode %d", grad.spread);
+ break;
+ }
+ tx->setFiltering(QSGTexture::Linear);
+ m_cache[grad] = tx;
+ }
+ return tx;
+}
+
+#endif // QT_CONFIG(opengl)
+
+QT_END_NAMESPACE
+
+#include "moc_qquickshape_p.cpp"
diff --git a/src/imports/shapes/qquickshape_p.h b/src/imports/shapes/qquickshape_p.h
new file mode 100644
index 0000000000..1dfeaf9228
--- /dev/null
+++ b/src/imports/shapes/qquickshape_p.h
@@ -0,0 +1,376 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKSHAPE_P_H
+#define QQUICKSHAPE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qquickitem.h"
+
+#include <private/qtquickglobal_p.h>
+#include <private/qquickpath_p_p.h>
+#include <private/qquickrectangle_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickShapePathPrivate;
+class QQuickShapePrivate;
+
+class QQuickShapeGradient : public QQuickGradient
+{
+ Q_OBJECT
+ Q_PROPERTY(SpreadMode spread READ spread WRITE setSpread NOTIFY spreadChanged)
+ Q_CLASSINFO("DefaultProperty", "stops")
+
+public:
+ enum SpreadMode {
+ PadSpread,
+ RepeatSpread,
+ ReflectSpread
+ };
+ Q_ENUM(SpreadMode)
+
+ QQuickShapeGradient(QObject *parent = nullptr);
+
+ SpreadMode spread() const;
+ void setSpread(SpreadMode mode);
+
+signals:
+ void spreadChanged();
+
+private:
+ SpreadMode m_spread;
+};
+
+class QQuickShapeLinearGradient : public QQuickShapeGradient
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal x1 READ x1 WRITE setX1 NOTIFY x1Changed)
+ Q_PROPERTY(qreal y1 READ y1 WRITE setY1 NOTIFY y1Changed)
+ Q_PROPERTY(qreal x2 READ x2 WRITE setX2 NOTIFY x2Changed)
+ Q_PROPERTY(qreal y2 READ y2 WRITE setY2 NOTIFY y2Changed)
+ Q_CLASSINFO("DefaultProperty", "stops")
+
+public:
+ QQuickShapeLinearGradient(QObject *parent = nullptr);
+
+ qreal x1() const;
+ void setX1(qreal v);
+ qreal y1() const;
+ void setY1(qreal v);
+ qreal x2() const;
+ void setX2(qreal v);
+ qreal y2() const;
+ void setY2(qreal v);
+
+signals:
+ void x1Changed();
+ void y1Changed();
+ void x2Changed();
+ void y2Changed();
+
+private:
+ QPointF m_start;
+ QPointF m_end;
+};
+
+class QQuickShapeRadialGradient : public QQuickShapeGradient
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal centerX READ centerX WRITE setCenterX NOTIFY centerXChanged)
+ Q_PROPERTY(qreal centerY READ centerY WRITE setCenterY NOTIFY centerYChanged)
+ Q_PROPERTY(qreal centerRadius READ centerRadius WRITE setCenterRadius NOTIFY centerRadiusChanged)
+ Q_PROPERTY(qreal focalX READ focalX WRITE setFocalX NOTIFY focalXChanged)
+ Q_PROPERTY(qreal focalY READ focalY WRITE setFocalY NOTIFY focalYChanged)
+ Q_PROPERTY(qreal focalRadius READ focalRadius WRITE setFocalRadius NOTIFY focalRadiusChanged)
+ Q_CLASSINFO("DefaultProperty", "stops")
+
+public:
+ QQuickShapeRadialGradient(QObject *parent = nullptr);
+
+ qreal centerX() const;
+ void setCenterX(qreal v);
+
+ qreal centerY() const;
+ void setCenterY(qreal v);
+
+ qreal centerRadius() const;
+ void setCenterRadius(qreal v);
+
+ qreal focalX() const;
+ void setFocalX(qreal v);
+
+ qreal focalY() const;
+ void setFocalY(qreal v);
+
+ qreal focalRadius() const;
+ void setFocalRadius(qreal v);
+
+signals:
+ void centerXChanged();
+ void centerYChanged();
+ void focalXChanged();
+ void focalYChanged();
+ void centerRadiusChanged();
+ void focalRadiusChanged();
+
+private:
+ QPointF m_centerPoint;
+ QPointF m_focalPoint;
+ qreal m_centerRadius = 0;
+ qreal m_focalRadius = 0;
+};
+
+class QQuickShapeConicalGradient : public QQuickShapeGradient
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal centerX READ centerX WRITE setCenterX NOTIFY centerXChanged)
+ Q_PROPERTY(qreal centerY READ centerY WRITE setCenterY NOTIFY centerYChanged)
+ Q_PROPERTY(qreal angle READ angle WRITE setAngle NOTIFY angleChanged)
+ Q_CLASSINFO("DefaultProperty", "stops")
+
+public:
+ QQuickShapeConicalGradient(QObject *parent = nullptr);
+
+ qreal centerX() const;
+ void setCenterX(qreal v);
+
+ qreal centerY() const;
+ void setCenterY(qreal v);
+
+ qreal angle() const;
+ void setAngle(qreal v);
+
+signals:
+ void centerXChanged();
+ void centerYChanged();
+ void angleChanged();
+
+private:
+ QPointF m_centerPoint;
+ qreal m_angle = 0;
+};
+
+class QQuickShapePath : public QQuickPath
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QColor strokeColor READ strokeColor WRITE setStrokeColor NOTIFY strokeColorChanged)
+ Q_PROPERTY(qreal strokeWidth READ strokeWidth WRITE setStrokeWidth NOTIFY strokeWidthChanged)
+ Q_PROPERTY(QColor fillColor READ fillColor WRITE setFillColor NOTIFY fillColorChanged)
+ Q_PROPERTY(FillRule fillRule READ fillRule WRITE setFillRule NOTIFY fillRuleChanged)
+ Q_PROPERTY(JoinStyle joinStyle READ joinStyle WRITE setJoinStyle NOTIFY joinStyleChanged)
+ Q_PROPERTY(int miterLimit READ miterLimit WRITE setMiterLimit NOTIFY miterLimitChanged)
+ Q_PROPERTY(CapStyle capStyle READ capStyle WRITE setCapStyle NOTIFY capStyleChanged)
+ Q_PROPERTY(StrokeStyle strokeStyle READ strokeStyle WRITE setStrokeStyle NOTIFY strokeStyleChanged)
+ Q_PROPERTY(qreal dashOffset READ dashOffset WRITE setDashOffset NOTIFY dashOffsetChanged)
+ Q_PROPERTY(QVector<qreal> dashPattern READ dashPattern WRITE setDashPattern NOTIFY dashPatternChanged)
+ Q_PROPERTY(QQuickShapeGradient *fillGradient READ fillGradient WRITE setFillGradient RESET resetFillGradient)
+
+public:
+ enum FillRule {
+ OddEvenFill = Qt::OddEvenFill,
+ WindingFill = Qt::WindingFill
+ };
+ Q_ENUM(FillRule)
+
+ enum JoinStyle {
+ MiterJoin = Qt::MiterJoin,
+ BevelJoin = Qt::BevelJoin,
+ RoundJoin = Qt::RoundJoin
+ };
+ Q_ENUM(JoinStyle)
+
+ enum CapStyle {
+ FlatCap = Qt::FlatCap,
+ SquareCap = Qt::SquareCap,
+ RoundCap = Qt::RoundCap
+ };
+ Q_ENUM(CapStyle)
+
+ enum StrokeStyle {
+ SolidLine = Qt::SolidLine,
+ DashLine = Qt::DashLine
+ };
+ Q_ENUM(StrokeStyle)
+
+ QQuickShapePath(QObject *parent = nullptr);
+ ~QQuickShapePath();
+
+ QColor strokeColor() const;
+ void setStrokeColor(const QColor &color);
+
+ qreal strokeWidth() const;
+ void setStrokeWidth(qreal w);
+
+ QColor fillColor() const;
+ void setFillColor(const QColor &color);
+
+ FillRule fillRule() const;
+ void setFillRule(FillRule fillRule);
+
+ JoinStyle joinStyle() const;
+ void setJoinStyle(JoinStyle style);
+
+ int miterLimit() const;
+ void setMiterLimit(int limit);
+
+ CapStyle capStyle() const;
+ void setCapStyle(CapStyle style);
+
+ StrokeStyle strokeStyle() const;
+ void setStrokeStyle(StrokeStyle style);
+
+ qreal dashOffset() const;
+ void setDashOffset(qreal offset);
+
+ QVector<qreal> dashPattern() const;
+ void setDashPattern(const QVector<qreal> &array);
+
+ QQuickShapeGradient *fillGradient() const;
+ void setFillGradient(QQuickShapeGradient *gradient);
+ void resetFillGradient();
+
+Q_SIGNALS:
+ void shapePathChanged();
+ void strokeColorChanged();
+ void strokeWidthChanged();
+ void fillColorChanged();
+ void fillRuleChanged();
+ void joinStyleChanged();
+ void miterLimitChanged();
+ void capStyleChanged();
+ void strokeStyleChanged();
+ void dashOffsetChanged();
+ void dashPatternChanged();
+
+private:
+ Q_DISABLE_COPY(QQuickShapePath)
+ Q_DECLARE_PRIVATE(QQuickShapePath)
+ Q_PRIVATE_SLOT(d_func(), void _q_fillGradientChanged())
+};
+
+class QQuickShape : public QQuickItem
+{
+ Q_OBJECT
+ Q_PROPERTY(RendererType rendererType READ rendererType NOTIFY rendererChanged)
+ Q_PROPERTY(bool asynchronous READ asynchronous WRITE setAsynchronous NOTIFY asynchronousChanged)
+ Q_PROPERTY(bool vendorExtensionsEnabled READ vendorExtensionsEnabled WRITE setVendorExtensionsEnabled NOTIFY vendorExtensionsEnabledChanged)
+ Q_PROPERTY(Status status READ status NOTIFY statusChanged)
+ Q_PROPERTY(ContainsMode containsMode READ containsMode WRITE setContainsMode NOTIFY containsModeChanged REVISION 11)
+ Q_PROPERTY(QQmlListProperty<QObject> data READ data)
+ Q_CLASSINFO("DefaultProperty", "data")
+
+public:
+ enum RendererType {
+ UnknownRenderer,
+ GeometryRenderer,
+ NvprRenderer,
+ SoftwareRenderer
+ };
+ Q_ENUM(RendererType)
+
+ enum Status {
+ Null,
+ Ready,
+ Processing
+ };
+ Q_ENUM(Status)
+
+ enum ContainsMode {
+ BoundingRectContains,
+ FillContains
+ };
+ Q_ENUM(ContainsMode)
+
+ QQuickShape(QQuickItem *parent = nullptr);
+ ~QQuickShape();
+
+ RendererType rendererType() const;
+
+ bool asynchronous() const;
+ void setAsynchronous(bool async);
+
+ bool vendorExtensionsEnabled() const;
+ void setVendorExtensionsEnabled(bool enable);
+
+ Status status() const;
+
+ ContainsMode containsMode() const;
+ void setContainsMode(ContainsMode containsMode);
+
+ bool contains(const QPointF &point) const override;
+
+ QQmlListProperty<QObject> data();
+
+protected:
+ QSGNode *updatePaintNode(QSGNode *node, UpdatePaintNodeData *) override;
+ void updatePolish() override;
+ void itemChange(ItemChange change, const ItemChangeData &data) override;
+ void componentComplete() override;
+ void classBegin() override;
+
+Q_SIGNALS:
+ void rendererChanged();
+ void asynchronousChanged();
+ void vendorExtensionsEnabledChanged();
+ void statusChanged();
+ Q_REVISION(11) void containsModeChanged();
+
+private:
+ Q_DISABLE_COPY(QQuickShape)
+ Q_DECLARE_PRIVATE(QQuickShape)
+ Q_PRIVATE_SLOT(d_func(), void _q_shapePathChanged())
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickShape)
+
+#endif // QQUICKSHAPE_P_H
diff --git a/src/imports/shapes/qquickshape_p_p.h b/src/imports/shapes/qquickshape_p_p.h
new file mode 100644
index 0000000000..ef2775885e
--- /dev/null
+++ b/src/imports/shapes/qquickshape_p_p.h
@@ -0,0 +1,231 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKSHAPE_P_P_H
+#define QQUICKSHAPE_P_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qquickshape_p.h"
+#include <QtQuick/private/qquickitem_p.h>
+#include <QPainterPath>
+#include <QColor>
+#include <QBrush>
+#include <QElapsedTimer>
+#include <private/qopenglcontext_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSGPlainTexture;
+
+class QQuickAbstractPathRenderer
+{
+public:
+ enum Flag {
+ SupportsAsync = 0x01
+ };
+ Q_DECLARE_FLAGS(Flags, Flag)
+
+ enum FillGradientType { NoGradient = 0, LinearGradient, RadialGradient, ConicalGradient };
+ struct GradientDesc { // can fully describe a linear/radial/conical gradient
+ QGradientStops stops;
+ QQuickShapeGradient::SpreadMode spread;
+ QPointF a; // start (L) or center point (R/C)
+ QPointF b; // end (L) or focal point (R)
+ qreal v0; // center radius (R) or start angle (C)
+ qreal v1; // focal radius (R)
+ };
+
+ virtual ~QQuickAbstractPathRenderer() { }
+
+ // Gui thread
+ virtual void beginSync(int totalCount) = 0;
+ virtual void endSync(bool async) = 0;
+ virtual void setAsyncCallback(void (*)(void *), void *) { }
+ virtual Flags flags() const { return 0; }
+ virtual void setPath(int index, const QQuickPath *path) = 0;
+ virtual void setStrokeColor(int index, const QColor &color) = 0;
+ virtual void setStrokeWidth(int index, qreal w) = 0;
+ virtual void setFillColor(int index, const QColor &color) = 0;
+ virtual void setFillRule(int index, QQuickShapePath::FillRule fillRule) = 0;
+ virtual void setJoinStyle(int index, QQuickShapePath::JoinStyle joinStyle, int miterLimit) = 0;
+ virtual void setCapStyle(int index, QQuickShapePath::CapStyle capStyle) = 0;
+ virtual void setStrokeStyle(int index, QQuickShapePath::StrokeStyle strokeStyle,
+ qreal dashOffset, const QVector<qreal> &dashPattern) = 0;
+ virtual void setFillGradient(int index, QQuickShapeGradient *gradient) = 0;
+
+ // Render thread, with gui blocked
+ virtual void updateNode() = 0;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickAbstractPathRenderer::Flags)
+
+struct QQuickShapeStrokeFillParams
+{
+ QQuickShapeStrokeFillParams();
+
+ QColor strokeColor;
+ qreal strokeWidth;
+ QColor fillColor;
+ QQuickShapePath::FillRule fillRule;
+ QQuickShapePath::JoinStyle joinStyle;
+ int miterLimit;
+ QQuickShapePath::CapStyle capStyle;
+ QQuickShapePath::StrokeStyle strokeStyle;
+ qreal dashOffset;
+ QVector<qreal> dashPattern;
+ QQuickShapeGradient *fillGradient;
+};
+
+class QQuickShapePathPrivate : public QQuickPathPrivate
+{
+ Q_DECLARE_PUBLIC(QQuickShapePath)
+
+public:
+ enum Dirty {
+ DirtyPath = 0x01,
+ DirtyStrokeColor = 0x02,
+ DirtyStrokeWidth = 0x04,
+ DirtyFillColor = 0x08,
+ DirtyFillRule = 0x10,
+ DirtyStyle = 0x20,
+ DirtyDash = 0x40,
+ DirtyFillGradient = 0x80,
+
+ DirtyAll = 0xFF
+ };
+
+ QQuickShapePathPrivate();
+
+ void _q_pathChanged();
+ void _q_fillGradientChanged();
+
+ static QQuickShapePathPrivate *get(QQuickShapePath *p) { return p->d_func(); }
+
+ int dirty;
+ QQuickShapeStrokeFillParams sfp;
+};
+
+class QQuickShapePrivate : public QQuickItemPrivate
+{
+ Q_DECLARE_PUBLIC(QQuickShape)
+
+public:
+ QQuickShapePrivate();
+ ~QQuickShapePrivate();
+
+ void createRenderer();
+ QSGNode *createNode();
+ void sync();
+
+ void _q_shapePathChanged();
+ void setStatus(QQuickShape::Status newStatus);
+
+ static QQuickShapePrivate *get(QQuickShape *item) { return item->d_func(); }
+
+ static void asyncShapeReady(void *data);
+
+ int effectRefCount;
+ QVector<QQuickShapePath *> sp;
+ QElapsedTimer syncTimer;
+ QQuickAbstractPathRenderer *renderer = nullptr;
+ int syncTimingTotalDirty = 0;
+ int syncTimeCounter = 0;
+ QQuickShape::Status status = QQuickShape::Null;
+ QQuickShape::RendererType rendererType = QQuickShape::UnknownRenderer;
+ QQuickShape::ContainsMode containsMode = QQuickShape::BoundingRectContains;
+ bool spChanged = false;
+ bool async = false;
+ bool enableVendorExts = true;
+ bool syncTimingActive = false;
+};
+
+#if QT_CONFIG(opengl)
+
+class QQuickShapeGradientCache : public QOpenGLSharedResource
+{
+public:
+ struct Key {
+ Key(const QGradientStops &stops, QQuickShapeGradient::SpreadMode spread)
+ : stops(stops), spread(spread)
+ { }
+ QGradientStops stops;
+ QQuickShapeGradient::SpreadMode spread;
+ bool operator==(const Key &other) const
+ {
+ return spread == other.spread && stops == other.stops;
+ }
+ };
+
+ QQuickShapeGradientCache(QOpenGLContext *context) : QOpenGLSharedResource(context->shareGroup()) { }
+ ~QQuickShapeGradientCache();
+
+ void invalidateResource() override;
+ void freeResource(QOpenGLContext *) override;
+
+ QSGTexture *get(const Key &grad);
+
+ static QQuickShapeGradientCache *currentCache();
+
+private:
+ QHash<Key, QSGPlainTexture *> m_cache;
+};
+
+inline uint qHash(const QQuickShapeGradientCache::Key &v, uint seed = 0)
+{
+ uint h = seed + v.spread;
+ for (int i = 0; i < 3 && i < v.stops.count(); ++i)
+ h += v.stops[i].second.rgba();
+ return h;
+}
+
+#endif // QT_CONFIG(opengl)
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/imports/shapes/qquickshapegenericrenderer.cpp b/src/imports/shapes/qquickshapegenericrenderer.cpp
new file mode 100644
index 0000000000..8131f02f1a
--- /dev/null
+++ b/src/imports/shapes/qquickshapegenericrenderer.cpp
@@ -0,0 +1,1006 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickshapegenericrenderer_p.h"
+#include <QtGui/private/qtriangulator_p.h>
+#include <QtGui/private/qtriangulatingstroker_p.h>
+#include <QThreadPool>
+
+#if QT_CONFIG(opengl)
+#include <QSGVertexColorMaterial>
+#include <QOpenGLContext>
+#include <QOffscreenSurface>
+#include <QtGui/private/qopenglextensions_p.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+static const qreal TRI_SCALE = 1;
+
+struct ColoredVertex // must match QSGGeometry::ColoredPoint2D
+{
+ float x, y;
+ QQuickShapeGenericRenderer::Color4ub color;
+ void set(float nx, float ny, QQuickShapeGenericRenderer::Color4ub ncolor)
+ {
+ x = nx; y = ny; color = ncolor;
+ }
+};
+
+static inline QQuickShapeGenericRenderer::Color4ub colorToColor4ub(const QColor &c)
+{
+ QQuickShapeGenericRenderer::Color4ub color = {
+ uchar(qRound(c.redF() * c.alphaF() * 255)),
+ uchar(qRound(c.greenF() * c.alphaF() * 255)),
+ uchar(qRound(c.blueF() * c.alphaF() * 255)),
+ uchar(qRound(c.alphaF() * 255))
+ };
+ return color;
+}
+
+QQuickShapeGenericStrokeFillNode::QQuickShapeGenericStrokeFillNode(QQuickWindow *window)
+ : m_material(nullptr)
+{
+ setFlag(QSGNode::OwnsGeometry, true);
+ setGeometry(new QSGGeometry(QSGGeometry::defaultAttributes_ColoredPoint2D(), 0, 0));
+ activateMaterial(window, MatSolidColor);
+#ifdef QSG_RUNTIME_DESCRIPTION
+ qsgnode_set_description(this, QLatin1String("stroke-fill"));
+#endif
+}
+
+void QQuickShapeGenericStrokeFillNode::activateMaterial(QQuickWindow *window, Material m)
+{
+ switch (m) {
+ case MatSolidColor:
+ // Use vertexcolor material. Items with different colors remain batchable
+ // this way, at the expense of having to provide per-vertex color values.
+ m_material.reset(QQuickShapeGenericMaterialFactory::createVertexColor(window));
+ break;
+ case MatLinearGradient:
+ m_material.reset(QQuickShapeGenericMaterialFactory::createLinearGradient(window, this));
+ break;
+ case MatRadialGradient:
+ m_material.reset(QQuickShapeGenericMaterialFactory::createRadialGradient(window, this));
+ break;
+ case MatConicalGradient:
+ m_material.reset(QQuickShapeGenericMaterialFactory::createConicalGradient(window, this));
+ break;
+ default:
+ qWarning("Unknown material %d", m);
+ return;
+ }
+
+ if (material() != m_material.data())
+ setMaterial(m_material.data());
+}
+
+static bool q_supportsElementIndexUint(QSGRendererInterface::GraphicsApi api)
+{
+ static bool elementIndexUint = true;
+#if QT_CONFIG(opengl)
+ if (api == QSGRendererInterface::OpenGL) {
+ static bool elementIndexUintChecked = false;
+ if (!elementIndexUintChecked) {
+ elementIndexUintChecked = true;
+ QOpenGLContext *context = QOpenGLContext::currentContext();
+ QScopedPointer<QOpenGLContext> dummyContext;
+ QScopedPointer<QOffscreenSurface> dummySurface;
+ bool ok = true;
+ if (!context) {
+ dummyContext.reset(new QOpenGLContext);
+ dummyContext->create();
+ context = dummyContext.data();
+ dummySurface.reset(new QOffscreenSurface);
+ dummySurface->setFormat(context->format());
+ dummySurface->create();
+ ok = context->makeCurrent(dummySurface.data());
+ }
+ if (ok) {
+ elementIndexUint = static_cast<QOpenGLExtensions *>(context->functions())->hasOpenGLExtension(
+ QOpenGLExtensions::ElementIndexUint);
+ }
+ }
+ }
+#else
+ Q_UNUSED(api);
+#endif
+ return elementIndexUint;
+}
+
+QQuickShapeGenericRenderer::~QQuickShapeGenericRenderer()
+{
+ for (ShapePathData &d : m_sp) {
+ if (d.pendingFill)
+ d.pendingFill->orphaned = true;
+ if (d.pendingStroke)
+ d.pendingStroke->orphaned = true;
+ }
+}
+
+// sync, and so triangulation too, happens on the gui thread
+// - except when async is set, in which case triangulation is moved to worker threads
+
+void QQuickShapeGenericRenderer::beginSync(int totalCount)
+{
+ if (m_sp.count() != totalCount) {
+ m_sp.resize(totalCount);
+ m_accDirty |= DirtyList;
+ }
+ for (ShapePathData &d : m_sp)
+ d.syncDirty = 0;
+}
+
+void QQuickShapeGenericRenderer::setPath(int index, const QQuickPath *path)
+{
+ ShapePathData &d(m_sp[index]);
+ d.path = path ? path->path() : QPainterPath();
+ d.syncDirty |= DirtyFillGeom | DirtyStrokeGeom;
+}
+
+void QQuickShapeGenericRenderer::setStrokeColor(int index, const QColor &color)
+{
+ ShapePathData &d(m_sp[index]);
+ d.strokeColor = colorToColor4ub(color);
+ d.syncDirty |= DirtyColor;
+}
+
+void QQuickShapeGenericRenderer::setStrokeWidth(int index, qreal w)
+{
+ ShapePathData &d(m_sp[index]);
+ d.strokeWidth = w;
+ if (w >= 0.0f)
+ d.pen.setWidthF(w);
+ d.syncDirty |= DirtyStrokeGeom;
+}
+
+void QQuickShapeGenericRenderer::setFillColor(int index, const QColor &color)
+{
+ ShapePathData &d(m_sp[index]);
+ d.fillColor = colorToColor4ub(color);
+ d.syncDirty |= DirtyColor;
+}
+
+void QQuickShapeGenericRenderer::setFillRule(int index, QQuickShapePath::FillRule fillRule)
+{
+ ShapePathData &d(m_sp[index]);
+ d.fillRule = Qt::FillRule(fillRule);
+ d.syncDirty |= DirtyFillGeom;
+}
+
+void QQuickShapeGenericRenderer::setJoinStyle(int index, QQuickShapePath::JoinStyle joinStyle, int miterLimit)
+{
+ ShapePathData &d(m_sp[index]);
+ d.pen.setJoinStyle(Qt::PenJoinStyle(joinStyle));
+ d.pen.setMiterLimit(miterLimit);
+ d.syncDirty |= DirtyStrokeGeom;
+}
+
+void QQuickShapeGenericRenderer::setCapStyle(int index, QQuickShapePath::CapStyle capStyle)
+{
+ ShapePathData &d(m_sp[index]);
+ d.pen.setCapStyle(Qt::PenCapStyle(capStyle));
+ d.syncDirty |= DirtyStrokeGeom;
+}
+
+void QQuickShapeGenericRenderer::setStrokeStyle(int index, QQuickShapePath::StrokeStyle strokeStyle,
+ qreal dashOffset, const QVector<qreal> &dashPattern)
+{
+ ShapePathData &d(m_sp[index]);
+ d.pen.setStyle(Qt::PenStyle(strokeStyle));
+ if (strokeStyle == QQuickShapePath::DashLine) {
+ d.pen.setDashPattern(dashPattern);
+ d.pen.setDashOffset(dashOffset);
+ }
+ d.syncDirty |= DirtyStrokeGeom;
+}
+
+void QQuickShapeGenericRenderer::setFillGradient(int index, QQuickShapeGradient *gradient)
+{
+ ShapePathData &d(m_sp[index]);
+ if (gradient) {
+ d.fillGradient.stops = gradient->gradientStops(); // sorted
+ d.fillGradient.spread = gradient->spread();
+ if (QQuickShapeLinearGradient *g = qobject_cast<QQuickShapeLinearGradient *>(gradient)) {
+ d.fillGradientActive = LinearGradient;
+ d.fillGradient.a = QPointF(g->x1(), g->y1());
+ d.fillGradient.b = QPointF(g->x2(), g->y2());
+ } else if (QQuickShapeRadialGradient *g = qobject_cast<QQuickShapeRadialGradient *>(gradient)) {
+ d.fillGradientActive = RadialGradient;
+ d.fillGradient.a = QPointF(g->centerX(), g->centerY());
+ d.fillGradient.b = QPointF(g->focalX(), g->focalY());
+ d.fillGradient.v0 = g->centerRadius();
+ d.fillGradient.v1 = g->focalRadius();
+ } else if (QQuickShapeConicalGradient *g = qobject_cast<QQuickShapeConicalGradient *>(gradient)) {
+ d.fillGradientActive = ConicalGradient;
+ d.fillGradient.a = QPointF(g->centerX(), g->centerY());
+ d.fillGradient.v0 = g->angle();
+ } else {
+ Q_UNREACHABLE();
+ }
+ } else {
+ d.fillGradientActive = NoGradient;
+ }
+ d.syncDirty |= DirtyFillGradient;
+}
+
+void QQuickShapeFillRunnable::run()
+{
+ QQuickShapeGenericRenderer::triangulateFill(path, fillColor, &fillVertices, &fillIndices, &indexType, supportsElementIndexUint);
+ emit done(this);
+}
+
+void QQuickShapeStrokeRunnable::run()
+{
+ QQuickShapeGenericRenderer::triangulateStroke(path, pen, strokeColor, &strokeVertices, clipSize);
+ emit done(this);
+}
+
+void QQuickShapeGenericRenderer::setAsyncCallback(void (*callback)(void *), void *data)
+{
+ m_asyncCallback = callback;
+ m_asyncCallbackData = data;
+}
+
+static QThreadPool *pathWorkThreadPool = nullptr;
+
+static void deletePathWorkThreadPool()
+{
+ delete pathWorkThreadPool;
+ pathWorkThreadPool = nullptr;
+}
+
+void QQuickShapeGenericRenderer::endSync(bool async)
+{
+ bool didKickOffAsync = false;
+
+ for (int i = 0; i < m_sp.count(); ++i) {
+ ShapePathData &d(m_sp[i]);
+ if (!d.syncDirty)
+ continue;
+
+ m_accDirty |= d.syncDirty;
+
+ // Use a shadow dirty flag in order to avoid losing state in case there are
+ // multiple syncs with different dirty flags before we get to updateNode()
+ // on the render thread (with the gui thread blocked). For our purposes
+ // here syncDirty is still required since geometry regeneration must only
+ // happen when there was an actual change in this particular sync round.
+ d.effectiveDirty |= d.syncDirty;
+
+ if (d.path.isEmpty()) {
+ d.fillVertices.clear();
+ d.fillIndices.clear();
+ d.strokeVertices.clear();
+ continue;
+ }
+
+ if (async && !pathWorkThreadPool) {
+ qAddPostRoutine(deletePathWorkThreadPool);
+ pathWorkThreadPool = new QThreadPool;
+ const int idealCount = QThread::idealThreadCount();
+ pathWorkThreadPool->setMaxThreadCount(idealCount > 0 ? idealCount * 2 : 4);
+ }
+
+ if ((d.syncDirty & DirtyFillGeom) && d.fillColor.a) {
+ d.path.setFillRule(d.fillRule);
+ if (m_api == QSGRendererInterface::Unknown)
+ m_api = m_item->window()->rendererInterface()->graphicsApi();
+ if (async) {
+ QQuickShapeFillRunnable *r = new QQuickShapeFillRunnable;
+ r->setAutoDelete(false);
+ if (d.pendingFill)
+ d.pendingFill->orphaned = true;
+ d.pendingFill = r;
+ r->path = d.path;
+ r->fillColor = d.fillColor;
+ r->supportsElementIndexUint = q_supportsElementIndexUint(m_api);
+ // Unlikely in practice but in theory m_sp could be
+ // resized. Therefore, capture 'i' instead of 'd'.
+ QObject::connect(r, &QQuickShapeFillRunnable::done, qApp, [this, i](QQuickShapeFillRunnable *r) {
+ // Bail out when orphaned (meaning either another run was
+ // started after this one, or the renderer got destroyed).
+ if (!r->orphaned && i < m_sp.count()) {
+ ShapePathData &d(m_sp[i]);
+ d.fillVertices = r->fillVertices;
+ d.fillIndices = r->fillIndices;
+ d.indexType = r->indexType;
+ d.pendingFill = nullptr;
+ d.effectiveDirty |= DirtyFillGeom;
+ maybeUpdateAsyncItem();
+ }
+ r->deleteLater();
+ });
+ didKickOffAsync = true;
+ pathWorkThreadPool->start(r);
+ } else {
+ triangulateFill(d.path, d.fillColor, &d.fillVertices, &d.fillIndices, &d.indexType, q_supportsElementIndexUint(m_api));
+ }
+ }
+
+ if ((d.syncDirty & DirtyStrokeGeom) && d.strokeWidth >= 0.0f && d.strokeColor.a) {
+ if (async) {
+ QQuickShapeStrokeRunnable *r = new QQuickShapeStrokeRunnable;
+ r->setAutoDelete(false);
+ if (d.pendingStroke)
+ d.pendingStroke->orphaned = true;
+ d.pendingStroke = r;
+ r->path = d.path;
+ r->pen = d.pen;
+ r->strokeColor = d.strokeColor;
+ r->clipSize = QSize(m_item->width(), m_item->height());
+ QObject::connect(r, &QQuickShapeStrokeRunnable::done, qApp, [this, i](QQuickShapeStrokeRunnable *r) {
+ if (!r->orphaned && i < m_sp.count()) {
+ ShapePathData &d(m_sp[i]);
+ d.strokeVertices = r->strokeVertices;
+ d.pendingStroke = nullptr;
+ d.effectiveDirty |= DirtyStrokeGeom;
+ maybeUpdateAsyncItem();
+ }
+ r->deleteLater();
+ });
+ didKickOffAsync = true;
+ pathWorkThreadPool->start(r);
+ } else {
+ triangulateStroke(d.path, d.pen, d.strokeColor, &d.strokeVertices,
+ QSize(m_item->width(), m_item->height()));
+ }
+ }
+ }
+
+ if (!didKickOffAsync && async && m_asyncCallback)
+ m_asyncCallback(m_asyncCallbackData);
+}
+
+void QQuickShapeGenericRenderer::maybeUpdateAsyncItem()
+{
+ for (const ShapePathData &d : qAsConst(m_sp)) {
+ if (d.pendingFill || d.pendingStroke)
+ return;
+ }
+ m_accDirty |= DirtyFillGeom | DirtyStrokeGeom;
+ m_item->update();
+ if (m_asyncCallback)
+ m_asyncCallback(m_asyncCallbackData);
+}
+
+// the stroke/fill triangulation functions may be invoked either on the gui
+// thread or some worker thread and must thus be self-contained.
+void QQuickShapeGenericRenderer::triangulateFill(const QPainterPath &path,
+ const Color4ub &fillColor,
+ VertexContainerType *fillVertices,
+ IndexContainerType *fillIndices,
+ QSGGeometry::Type *indexType,
+ bool supportsElementIndexUint)
+{
+ const QVectorPath &vp = qtVectorPathForPath(path);
+
+ QTriangleSet ts = qTriangulate(vp, QTransform::fromScale(TRI_SCALE, TRI_SCALE), 1, supportsElementIndexUint);
+ const int vertexCount = ts.vertices.count() / 2; // just a qreal vector with x,y hence the / 2
+ fillVertices->resize(vertexCount);
+ ColoredVertex *vdst = reinterpret_cast<ColoredVertex *>(fillVertices->data());
+ const qreal *vsrc = ts.vertices.constData();
+ for (int i = 0; i < vertexCount; ++i)
+ vdst[i].set(vsrc[i * 2] / TRI_SCALE, vsrc[i * 2 + 1] / TRI_SCALE, fillColor);
+
+ size_t indexByteSize;
+ if (ts.indices.type() == QVertexIndexVector::UnsignedShort) {
+ *indexType = QSGGeometry::UnsignedShortType;
+ // fillIndices is still QVector<quint32>. Just resize to N/2 and pack
+ // the N quint16s into it.
+ fillIndices->resize(ts.indices.size() / 2);
+ indexByteSize = ts.indices.size() * sizeof(quint16);
+ } else {
+ *indexType = QSGGeometry::UnsignedIntType;
+ fillIndices->resize(ts.indices.size());
+ indexByteSize = ts.indices.size() * sizeof(quint32);
+ }
+ memcpy(fillIndices->data(), ts.indices.data(), indexByteSize);
+}
+
+void QQuickShapeGenericRenderer::triangulateStroke(const QPainterPath &path,
+ const QPen &pen,
+ const Color4ub &strokeColor,
+ VertexContainerType *strokeVertices,
+ const QSize &clipSize)
+{
+ const QVectorPath &vp = qtVectorPathForPath(path);
+ const QRectF clip(QPointF(0, 0), clipSize);
+ const qreal inverseScale = 1.0 / TRI_SCALE;
+
+ QTriangulatingStroker stroker;
+ stroker.setInvScale(inverseScale);
+
+ if (pen.style() == Qt::SolidLine) {
+ stroker.process(vp, pen, clip, 0);
+ } else {
+ QDashedStrokeProcessor dashStroker;
+ dashStroker.setInvScale(inverseScale);
+ dashStroker.process(vp, pen, clip, 0);
+ QVectorPath dashStroke(dashStroker.points(), dashStroker.elementCount(),
+ dashStroker.elementTypes(), 0);
+ stroker.process(dashStroke, pen, clip, 0);
+ }
+
+ if (!stroker.vertexCount()) {
+ strokeVertices->clear();
+ return;
+ }
+
+ const int vertexCount = stroker.vertexCount() / 2; // just a float vector with x,y hence the / 2
+ strokeVertices->resize(vertexCount);
+ ColoredVertex *vdst = reinterpret_cast<ColoredVertex *>(strokeVertices->data());
+ const float *vsrc = stroker.vertices();
+ for (int i = 0; i < vertexCount; ++i)
+ vdst[i].set(vsrc[i * 2], vsrc[i * 2 + 1], strokeColor);
+}
+
+void QQuickShapeGenericRenderer::setRootNode(QQuickShapeGenericNode *node)
+{
+ if (m_rootNode != node) {
+ m_rootNode = node;
+ m_accDirty |= DirtyList;
+ }
+}
+
+// on the render thread with gui blocked
+void QQuickShapeGenericRenderer::updateNode()
+{
+ if (!m_rootNode || !m_accDirty)
+ return;
+
+// [ m_rootNode ]
+// / / /
+// #0 [ fill ] [ stroke ] [ next ]
+// / / |
+// #1 [ fill ] [ stroke ] [ next ]
+// / / |
+// #2 [ fill ] [ stroke ] [ next ]
+// ...
+// ...
+
+ QQuickShapeGenericNode **nodePtr = &m_rootNode;
+ QQuickShapeGenericNode *prevNode = nullptr;
+
+ for (ShapePathData &d : m_sp) {
+ if (!*nodePtr) {
+ Q_ASSERT(prevNode);
+ *nodePtr = new QQuickShapeGenericNode;
+ prevNode->m_next = *nodePtr;
+ prevNode->appendChildNode(*nodePtr);
+ }
+
+ QQuickShapeGenericNode *node = *nodePtr;
+
+ if (m_accDirty & DirtyList)
+ d.effectiveDirty |= DirtyFillGeom | DirtyStrokeGeom | DirtyColor | DirtyFillGradient;
+
+ if (!d.effectiveDirty) {
+ prevNode = node;
+ nodePtr = &node->m_next;
+ continue;
+ }
+
+ if (d.fillColor.a == 0) {
+ delete node->m_fillNode;
+ node->m_fillNode = nullptr;
+ } else if (!node->m_fillNode) {
+ node->m_fillNode = new QQuickShapeGenericStrokeFillNode(m_item->window());
+ if (node->m_strokeNode)
+ node->removeChildNode(node->m_strokeNode);
+ node->appendChildNode(node->m_fillNode);
+ if (node->m_strokeNode)
+ node->appendChildNode(node->m_strokeNode);
+ d.effectiveDirty |= DirtyFillGeom;
+ }
+
+ if (d.strokeWidth < 0.0f || d.strokeColor.a == 0) {
+ delete node->m_strokeNode;
+ node->m_strokeNode = nullptr;
+ } else if (!node->m_strokeNode) {
+ node->m_strokeNode = new QQuickShapeGenericStrokeFillNode(m_item->window());
+ node->appendChildNode(node->m_strokeNode);
+ d.effectiveDirty |= DirtyStrokeGeom;
+ }
+
+ updateFillNode(&d, node);
+ updateStrokeNode(&d, node);
+
+ d.effectiveDirty = 0;
+
+ prevNode = node;
+ nodePtr = &node->m_next;
+ }
+
+ if (*nodePtr && prevNode) {
+ prevNode->removeChildNode(*nodePtr);
+ delete *nodePtr;
+ *nodePtr = nullptr;
+ }
+
+ m_accDirty = 0;
+}
+
+void QQuickShapeGenericRenderer::updateShadowDataInNode(ShapePathData *d, QQuickShapeGenericStrokeFillNode *n)
+{
+ if (d->fillGradientActive) {
+ if (d->effectiveDirty & DirtyFillGradient)
+ n->m_fillGradient = d->fillGradient;
+ }
+}
+
+void QQuickShapeGenericRenderer::updateFillNode(ShapePathData *d, QQuickShapeGenericNode *node)
+{
+ if (!node->m_fillNode)
+ return;
+ if (!(d->effectiveDirty & (DirtyFillGeom | DirtyColor | DirtyFillGradient)))
+ return;
+
+ // Make a copy of the data that will be accessed by the material on
+ // the render thread. This must be done even when we bail out below.
+ QQuickShapeGenericStrokeFillNode *n = node->m_fillNode;
+ updateShadowDataInNode(d, n);
+
+ QSGGeometry *g = n->geometry();
+ if (d->fillVertices.isEmpty()) {
+ if (g->vertexCount() || g->indexCount()) {
+ g->allocate(0, 0);
+ n->markDirty(QSGNode::DirtyGeometry);
+ }
+ return;
+ }
+
+ if (d->fillGradientActive) {
+ QQuickShapeGenericStrokeFillNode::Material gradMat;
+ switch (d->fillGradientActive) {
+ case LinearGradient:
+ gradMat = QQuickShapeGenericStrokeFillNode::MatLinearGradient;
+ break;
+ case RadialGradient:
+ gradMat = QQuickShapeGenericStrokeFillNode::MatRadialGradient;
+ break;
+ case ConicalGradient:
+ gradMat = QQuickShapeGenericStrokeFillNode::MatConicalGradient;
+ break;
+ default:
+ Q_UNREACHABLE();
+ }
+ n->activateMaterial(m_item->window(), gradMat);
+ if (d->effectiveDirty & DirtyFillGradient) {
+ // Gradients are implemented via a texture-based material.
+ n->markDirty(QSGNode::DirtyMaterial);
+ // stop here if only the gradient changed; no need to touch the geometry
+ if (!(d->effectiveDirty & DirtyFillGeom))
+ return;
+ }
+ } else {
+ n->activateMaterial(m_item->window(), QQuickShapeGenericStrokeFillNode::MatSolidColor);
+ // fast path for updating only color values when no change in vertex positions
+ if ((d->effectiveDirty & DirtyColor) && !(d->effectiveDirty & DirtyFillGeom)) {
+ ColoredVertex *vdst = reinterpret_cast<ColoredVertex *>(g->vertexData());
+ for (int i = 0; i < g->vertexCount(); ++i)
+ vdst[i].set(vdst[i].x, vdst[i].y, d->fillColor);
+ n->markDirty(QSGNode::DirtyGeometry);
+ return;
+ }
+ }
+
+ const int indexCount = d->indexType == QSGGeometry::UnsignedShortType
+ ? d->fillIndices.count() * 2 : d->fillIndices.count();
+ if (g->indexType() != d->indexType) {
+ g = new QSGGeometry(QSGGeometry::defaultAttributes_ColoredPoint2D(),
+ d->fillVertices.count(), indexCount, d->indexType);
+ n->setGeometry(g);
+ } else {
+ g->allocate(d->fillVertices.count(), indexCount);
+ }
+ g->setDrawingMode(QSGGeometry::DrawTriangles);
+ memcpy(g->vertexData(), d->fillVertices.constData(), g->vertexCount() * g->sizeOfVertex());
+ memcpy(g->indexData(), d->fillIndices.constData(), g->indexCount() * g->sizeOfIndex());
+
+ n->markDirty(QSGNode::DirtyGeometry);
+}
+
+void QQuickShapeGenericRenderer::updateStrokeNode(ShapePathData *d, QQuickShapeGenericNode *node)
+{
+ if (!node->m_strokeNode)
+ return;
+ if (!(d->effectiveDirty & (DirtyStrokeGeom | DirtyColor)))
+ return;
+
+ QQuickShapeGenericStrokeFillNode *n = node->m_strokeNode;
+ QSGGeometry *g = n->geometry();
+ if (d->strokeVertices.isEmpty()) {
+ if (g->vertexCount() || g->indexCount()) {
+ g->allocate(0, 0);
+ n->markDirty(QSGNode::DirtyGeometry);
+ }
+ return;
+ }
+
+ n->markDirty(QSGNode::DirtyGeometry);
+
+ // Async loading runs update once, bails out above, then updates again once
+ // ready. Set the material dirty then. This is in-line with fill where the
+ // first activateMaterial() achieves the same.
+ if (!g->vertexCount())
+ n->markDirty(QSGNode::DirtyMaterial);
+
+ if ((d->effectiveDirty & DirtyColor) && !(d->effectiveDirty & DirtyStrokeGeom)) {
+ ColoredVertex *vdst = reinterpret_cast<ColoredVertex *>(g->vertexData());
+ for (int i = 0; i < g->vertexCount(); ++i)
+ vdst[i].set(vdst[i].x, vdst[i].y, d->strokeColor);
+ return;
+ }
+
+ g->allocate(d->strokeVertices.count(), 0);
+ g->setDrawingMode(QSGGeometry::DrawTriangleStrip);
+ memcpy(g->vertexData(), d->strokeVertices.constData(), g->vertexCount() * g->sizeOfVertex());
+}
+
+QSGMaterial *QQuickShapeGenericMaterialFactory::createVertexColor(QQuickWindow *window)
+{
+ QSGRendererInterface::GraphicsApi api = window->rendererInterface()->graphicsApi();
+
+#if QT_CONFIG(opengl)
+ if (api == QSGRendererInterface::OpenGL)
+ return new QSGVertexColorMaterial;
+#endif
+
+ qWarning("Vertex-color material: Unsupported graphics API %d", api);
+ return nullptr;
+}
+
+QSGMaterial *QQuickShapeGenericMaterialFactory::createLinearGradient(QQuickWindow *window,
+ QQuickShapeGenericStrokeFillNode *node)
+{
+ QSGRendererInterface::GraphicsApi api = window->rendererInterface()->graphicsApi();
+
+#if QT_CONFIG(opengl)
+ if (api == QSGRendererInterface::OpenGL)
+ return new QQuickShapeLinearGradientMaterial(node);
+#else
+ Q_UNUSED(node);
+#endif
+
+ qWarning("Linear gradient material: Unsupported graphics API %d", api);
+ return nullptr;
+}
+
+QSGMaterial *QQuickShapeGenericMaterialFactory::createRadialGradient(QQuickWindow *window,
+ QQuickShapeGenericStrokeFillNode *node)
+{
+ QSGRendererInterface::GraphicsApi api = window->rendererInterface()->graphicsApi();
+
+#if QT_CONFIG(opengl)
+ if (api == QSGRendererInterface::OpenGL)
+ return new QQuickShapeRadialGradientMaterial(node);
+#else
+ Q_UNUSED(node);
+#endif
+
+ qWarning("Radial gradient material: Unsupported graphics API %d", api);
+ return nullptr;
+}
+
+QSGMaterial *QQuickShapeGenericMaterialFactory::createConicalGradient(QQuickWindow *window,
+ QQuickShapeGenericStrokeFillNode *node)
+{
+ QSGRendererInterface::GraphicsApi api = window->rendererInterface()->graphicsApi();
+
+#if QT_CONFIG(opengl)
+ if (api == QSGRendererInterface::OpenGL)
+ return new QQuickShapeConicalGradientMaterial(node);
+#else
+ Q_UNUSED(node);
+#endif
+
+ qWarning("Conical gradient material: Unsupported graphics API %d", api);
+ return nullptr;
+}
+
+#if QT_CONFIG(opengl)
+
+QSGMaterialType QQuickShapeLinearGradientShader::type;
+
+QQuickShapeLinearGradientShader::QQuickShapeLinearGradientShader()
+{
+ setShaderSourceFile(QOpenGLShader::Vertex,
+ QStringLiteral(":/qt-project.org/shapes/shaders/lineargradient.vert"));
+ setShaderSourceFile(QOpenGLShader::Fragment,
+ QStringLiteral(":/qt-project.org/shapes/shaders/lineargradient.frag"));
+}
+
+void QQuickShapeLinearGradientShader::initialize()
+{
+ m_opacityLoc = program()->uniformLocation("opacity");
+ m_matrixLoc = program()->uniformLocation("matrix");
+ m_gradStartLoc = program()->uniformLocation("gradStart");
+ m_gradEndLoc = program()->uniformLocation("gradEnd");
+}
+
+void QQuickShapeLinearGradientShader::updateState(const RenderState &state, QSGMaterial *mat, QSGMaterial *)
+{
+ QQuickShapeLinearGradientMaterial *m = static_cast<QQuickShapeLinearGradientMaterial *>(mat);
+
+ if (state.isOpacityDirty())
+ program()->setUniformValue(m_opacityLoc, state.opacity());
+
+ if (state.isMatrixDirty())
+ program()->setUniformValue(m_matrixLoc, state.combinedMatrix());
+
+ QQuickShapeGenericStrokeFillNode *node = m->node();
+ program()->setUniformValue(m_gradStartLoc, QVector2D(node->m_fillGradient.a));
+ program()->setUniformValue(m_gradEndLoc, QVector2D(node->m_fillGradient.b));
+
+ const QQuickShapeGradientCache::Key cacheKey(node->m_fillGradient.stops, node->m_fillGradient.spread);
+ QSGTexture *tx = QQuickShapeGradientCache::currentCache()->get(cacheKey);
+ tx->bind();
+}
+
+char const *const *QQuickShapeLinearGradientShader::attributeNames() const
+{
+ static const char *const attr[] = { "vertexCoord", "vertexColor", nullptr };
+ return attr;
+}
+
+int QQuickShapeLinearGradientMaterial::compare(const QSGMaterial *other) const
+{
+ Q_ASSERT(other && type() == other->type());
+ const QQuickShapeLinearGradientMaterial *m = static_cast<const QQuickShapeLinearGradientMaterial *>(other);
+
+ QQuickShapeGenericStrokeFillNode *a = node();
+ QQuickShapeGenericStrokeFillNode *b = m->node();
+ Q_ASSERT(a && b);
+ if (a == b)
+ return 0;
+
+ const QQuickAbstractPathRenderer::GradientDesc *ga = &a->m_fillGradient;
+ const QQuickAbstractPathRenderer::GradientDesc *gb = &b->m_fillGradient;
+
+ if (int d = ga->spread - gb->spread)
+ return d;
+
+ if (int d = ga->a.x() - gb->a.x())
+ return d;
+ if (int d = ga->a.y() - gb->a.y())
+ return d;
+ if (int d = ga->b.x() - gb->b.x())
+ return d;
+ if (int d = ga->b.y() - gb->b.y())
+ return d;
+
+ if (int d = ga->stops.count() - gb->stops.count())
+ return d;
+
+ for (int i = 0; i < ga->stops.count(); ++i) {
+ if (int d = ga->stops[i].first - gb->stops[i].first)
+ return d;
+ if (int d = ga->stops[i].second.rgba() - gb->stops[i].second.rgba())
+ return d;
+ }
+
+ return 0;
+}
+
+QSGMaterialType QQuickShapeRadialGradientShader::type;
+
+QQuickShapeRadialGradientShader::QQuickShapeRadialGradientShader()
+{
+ setShaderSourceFile(QOpenGLShader::Vertex,
+ QStringLiteral(":/qt-project.org/shapes/shaders/radialgradient.vert"));
+ setShaderSourceFile(QOpenGLShader::Fragment,
+ QStringLiteral(":/qt-project.org/shapes/shaders/radialgradient.frag"));
+}
+
+void QQuickShapeRadialGradientShader::initialize()
+{
+ QOpenGLShaderProgram *prog = program();
+ m_opacityLoc = prog->uniformLocation("opacity");
+ m_matrixLoc = prog->uniformLocation("matrix");
+ m_translationPointLoc = prog->uniformLocation("translationPoint");
+ m_focalToCenterLoc = prog->uniformLocation("focalToCenter");
+ m_centerRadiusLoc = prog->uniformLocation("centerRadius");
+ m_focalRadiusLoc = prog->uniformLocation("focalRadius");
+}
+
+void QQuickShapeRadialGradientShader::updateState(const RenderState &state, QSGMaterial *mat, QSGMaterial *)
+{
+ QQuickShapeRadialGradientMaterial *m = static_cast<QQuickShapeRadialGradientMaterial *>(mat);
+
+ if (state.isOpacityDirty())
+ program()->setUniformValue(m_opacityLoc, state.opacity());
+
+ if (state.isMatrixDirty())
+ program()->setUniformValue(m_matrixLoc, state.combinedMatrix());
+
+ QQuickShapeGenericStrokeFillNode *node = m->node();
+
+ const QPointF centerPoint = node->m_fillGradient.a;
+ const QPointF focalPoint = node->m_fillGradient.b;
+ const QPointF focalToCenter = centerPoint - focalPoint;
+ const GLfloat centerRadius = node->m_fillGradient.v0;
+ const GLfloat focalRadius = node->m_fillGradient.v1;
+
+ program()->setUniformValue(m_translationPointLoc, focalPoint);
+ program()->setUniformValue(m_centerRadiusLoc, centerRadius);
+ program()->setUniformValue(m_focalRadiusLoc, focalRadius);
+ program()->setUniformValue(m_focalToCenterLoc, focalToCenter);
+
+ const QQuickShapeGradientCache::Key cacheKey(node->m_fillGradient.stops, node->m_fillGradient.spread);
+ QSGTexture *tx = QQuickShapeGradientCache::currentCache()->get(cacheKey);
+ tx->bind();
+}
+
+char const *const *QQuickShapeRadialGradientShader::attributeNames() const
+{
+ static const char *const attr[] = { "vertexCoord", "vertexColor", nullptr };
+ return attr;
+}
+
+int QQuickShapeRadialGradientMaterial::compare(const QSGMaterial *other) const
+{
+ Q_ASSERT(other && type() == other->type());
+ const QQuickShapeRadialGradientMaterial *m = static_cast<const QQuickShapeRadialGradientMaterial *>(other);
+
+ QQuickShapeGenericStrokeFillNode *a = node();
+ QQuickShapeGenericStrokeFillNode *b = m->node();
+ Q_ASSERT(a && b);
+ if (a == b)
+ return 0;
+
+ const QQuickAbstractPathRenderer::GradientDesc *ga = &a->m_fillGradient;
+ const QQuickAbstractPathRenderer::GradientDesc *gb = &b->m_fillGradient;
+
+ if (int d = ga->spread - gb->spread)
+ return d;
+
+ if (int d = ga->a.x() - gb->a.x())
+ return d;
+ if (int d = ga->a.y() - gb->a.y())
+ return d;
+ if (int d = ga->b.x() - gb->b.x())
+ return d;
+ if (int d = ga->b.y() - gb->b.y())
+ return d;
+
+ if (int d = ga->v0 - gb->v0)
+ return d;
+ if (int d = ga->v1 - gb->v1)
+ return d;
+
+ if (int d = ga->stops.count() - gb->stops.count())
+ return d;
+
+ for (int i = 0; i < ga->stops.count(); ++i) {
+ if (int d = ga->stops[i].first - gb->stops[i].first)
+ return d;
+ if (int d = ga->stops[i].second.rgba() - gb->stops[i].second.rgba())
+ return d;
+ }
+
+ return 0;
+}
+
+QSGMaterialType QQuickShapeConicalGradientShader::type;
+
+QQuickShapeConicalGradientShader::QQuickShapeConicalGradientShader()
+{
+ setShaderSourceFile(QOpenGLShader::Vertex,
+ QStringLiteral(":/qt-project.org/shapes/shaders/conicalgradient.vert"));
+ setShaderSourceFile(QOpenGLShader::Fragment,
+ QStringLiteral(":/qt-project.org/shapes/shaders/conicalgradient.frag"));
+}
+
+void QQuickShapeConicalGradientShader::initialize()
+{
+ QOpenGLShaderProgram *prog = program();
+ m_opacityLoc = prog->uniformLocation("opacity");
+ m_matrixLoc = prog->uniformLocation("matrix");
+ m_angleLoc = prog->uniformLocation("angle");
+ m_translationPointLoc = prog->uniformLocation("translationPoint");
+}
+
+void QQuickShapeConicalGradientShader::updateState(const RenderState &state, QSGMaterial *mat, QSGMaterial *)
+{
+ QQuickShapeConicalGradientMaterial *m = static_cast<QQuickShapeConicalGradientMaterial *>(mat);
+
+ if (state.isOpacityDirty())
+ program()->setUniformValue(m_opacityLoc, state.opacity());
+
+ if (state.isMatrixDirty())
+ program()->setUniformValue(m_matrixLoc, state.combinedMatrix());
+
+ QQuickShapeGenericStrokeFillNode *node = m->node();
+
+ const QPointF centerPoint = node->m_fillGradient.a;
+ const GLfloat angle = -qDegreesToRadians(node->m_fillGradient.v0);
+
+ program()->setUniformValue(m_angleLoc, angle);
+ program()->setUniformValue(m_translationPointLoc, centerPoint);
+
+ const QQuickShapeGradientCache::Key cacheKey(node->m_fillGradient.stops, QQuickShapeGradient::RepeatSpread);
+ QSGTexture *tx = QQuickShapeGradientCache::currentCache()->get(cacheKey);
+ tx->bind();
+}
+
+char const *const *QQuickShapeConicalGradientShader::attributeNames() const
+{
+ static const char *const attr[] = { "vertexCoord", "vertexColor", nullptr };
+ return attr;
+}
+
+int QQuickShapeConicalGradientMaterial::compare(const QSGMaterial *other) const
+{
+ Q_ASSERT(other && type() == other->type());
+ const QQuickShapeConicalGradientMaterial *m = static_cast<const QQuickShapeConicalGradientMaterial *>(other);
+
+ QQuickShapeGenericStrokeFillNode *a = node();
+ QQuickShapeGenericStrokeFillNode *b = m->node();
+ Q_ASSERT(a && b);
+ if (a == b)
+ return 0;
+
+ const QQuickAbstractPathRenderer::GradientDesc *ga = &a->m_fillGradient;
+ const QQuickAbstractPathRenderer::GradientDesc *gb = &b->m_fillGradient;
+
+ if (int d = ga->a.x() - gb->a.x())
+ return d;
+ if (int d = ga->a.y() - gb->a.y())
+ return d;
+
+ if (int d = ga->v0 - gb->v0)
+ return d;
+
+ if (int d = ga->stops.count() - gb->stops.count())
+ return d;
+
+ for (int i = 0; i < ga->stops.count(); ++i) {
+ if (int d = ga->stops[i].first - gb->stops[i].first)
+ return d;
+ if (int d = ga->stops[i].second.rgba() - gb->stops[i].second.rgba())
+ return d;
+ }
+
+ return 0;
+}
+
+#endif // QT_CONFIG(opengl)
+
+QT_END_NAMESPACE
diff --git a/src/imports/shapes/qquickshapegenericrenderer_p.h b/src/imports/shapes/qquickshapegenericrenderer_p.h
new file mode 100644
index 0000000000..11070ae7dc
--- /dev/null
+++ b/src/imports/shapes/qquickshapegenericrenderer_p.h
@@ -0,0 +1,392 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKSHAPEGENERICRENDERER_P_H
+#define QQUICKSHAPEGENERICRENDERER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of a number of Qt sources files. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qquickshape_p_p.h"
+#include <qsgnode.h>
+#include <qsggeometry.h>
+#include <qsgmaterial.h>
+#include <qsgrendererinterface.h>
+#include <QtCore/qrunnable.h>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickShapeGenericNode;
+class QQuickShapeGenericStrokeFillNode;
+class QQuickShapeFillRunnable;
+class QQuickShapeStrokeRunnable;
+
+class QQuickShapeGenericRenderer : public QQuickAbstractPathRenderer
+{
+public:
+ enum Dirty {
+ DirtyFillGeom = 0x01,
+ DirtyStrokeGeom = 0x02,
+ DirtyColor = 0x04,
+ DirtyFillGradient = 0x08,
+ DirtyList = 0x10 // only for accDirty
+ };
+
+ QQuickShapeGenericRenderer(QQuickItem *item)
+ : m_item(item),
+ m_api(QSGRendererInterface::Unknown),
+ m_rootNode(nullptr),
+ m_accDirty(0),
+ m_asyncCallback(nullptr),
+ m_asyncCallbackData(nullptr)
+ { }
+ ~QQuickShapeGenericRenderer();
+
+ void beginSync(int totalCount) override;
+ void setPath(int index, const QQuickPath *path) override;
+ void setStrokeColor(int index, const QColor &color) override;
+ void setStrokeWidth(int index, qreal w) override;
+ void setFillColor(int index, const QColor &color) override;
+ void setFillRule(int index, QQuickShapePath::FillRule fillRule) override;
+ void setJoinStyle(int index, QQuickShapePath::JoinStyle joinStyle, int miterLimit) override;
+ void setCapStyle(int index, QQuickShapePath::CapStyle capStyle) override;
+ void setStrokeStyle(int index, QQuickShapePath::StrokeStyle strokeStyle,
+ qreal dashOffset, const QVector<qreal> &dashPattern) override;
+ void setFillGradient(int index, QQuickShapeGradient *gradient) override;
+ void endSync(bool async) override;
+ void setAsyncCallback(void (*)(void *), void *) override;
+ Flags flags() const override { return SupportsAsync; }
+
+ void updateNode() override;
+
+ void setRootNode(QQuickShapeGenericNode *node);
+
+ struct Color4ub { unsigned char r, g, b, a; };
+ typedef QVector<QSGGeometry::ColoredPoint2D> VertexContainerType;
+ typedef QVector<quint32> IndexContainerType;
+
+ static void triangulateFill(const QPainterPath &path,
+ const Color4ub &fillColor,
+ VertexContainerType *fillVertices,
+ IndexContainerType *fillIndices,
+ QSGGeometry::Type *indexType,
+ bool supportsElementIndexUint);
+ static void triangulateStroke(const QPainterPath &path,
+ const QPen &pen,
+ const Color4ub &strokeColor,
+ VertexContainerType *strokeVertices,
+ const QSize &clipSize);
+
+private:
+ void maybeUpdateAsyncItem();
+
+ struct ShapePathData {
+ float strokeWidth;
+ QPen pen;
+ Color4ub strokeColor;
+ Color4ub fillColor;
+ Qt::FillRule fillRule;
+ QPainterPath path;
+ FillGradientType fillGradientActive;
+ GradientDesc fillGradient;
+ VertexContainerType fillVertices;
+ IndexContainerType fillIndices;
+ QSGGeometry::Type indexType;
+ VertexContainerType strokeVertices;
+ int syncDirty;
+ int effectiveDirty = 0;
+ QQuickShapeFillRunnable *pendingFill = nullptr;
+ QQuickShapeStrokeRunnable *pendingStroke = nullptr;
+ };
+
+ void updateShadowDataInNode(ShapePathData *d, QQuickShapeGenericStrokeFillNode *n);
+ void updateFillNode(ShapePathData *d, QQuickShapeGenericNode *node);
+ void updateStrokeNode(ShapePathData *d, QQuickShapeGenericNode *node);
+
+ QQuickItem *m_item;
+ QSGRendererInterface::GraphicsApi m_api;
+ QQuickShapeGenericNode *m_rootNode;
+ QVector<ShapePathData> m_sp;
+ int m_accDirty;
+ void (*m_asyncCallback)(void *);
+ void *m_asyncCallbackData;
+};
+
+class QQuickShapeFillRunnable : public QObject, public QRunnable
+{
+ Q_OBJECT
+
+public:
+ void run() override;
+
+ bool orphaned = false;
+
+ // input
+ QPainterPath path;
+ QQuickShapeGenericRenderer::Color4ub fillColor;
+ bool supportsElementIndexUint;
+
+ // output
+ QQuickShapeGenericRenderer::VertexContainerType fillVertices;
+ QQuickShapeGenericRenderer::IndexContainerType fillIndices;
+ QSGGeometry::Type indexType;
+
+Q_SIGNALS:
+ void done(QQuickShapeFillRunnable *self);
+};
+
+class QQuickShapeStrokeRunnable : public QObject, public QRunnable
+{
+ Q_OBJECT
+
+public:
+ void run() override;
+
+ bool orphaned = false;
+
+ // input
+ QPainterPath path;
+ QPen pen;
+ QQuickShapeGenericRenderer::Color4ub strokeColor;
+ QSize clipSize;
+
+ // output
+ QQuickShapeGenericRenderer::VertexContainerType strokeVertices;
+
+Q_SIGNALS:
+ void done(QQuickShapeStrokeRunnable *self);
+};
+
+class QQuickShapeGenericStrokeFillNode : public QSGGeometryNode
+{
+public:
+ QQuickShapeGenericStrokeFillNode(QQuickWindow *window);
+
+ enum Material {
+ MatSolidColor,
+ MatLinearGradient,
+ MatRadialGradient,
+ MatConicalGradient
+ };
+
+ void activateMaterial(QQuickWindow *window, Material m);
+
+ // shadow data for custom materials
+ QQuickAbstractPathRenderer::GradientDesc m_fillGradient;
+
+private:
+ QScopedPointer<QSGMaterial> m_material;
+
+ friend class QQuickShapeGenericRenderer;
+};
+
+class QQuickShapeGenericNode : public QSGNode
+{
+public:
+ QQuickShapeGenericStrokeFillNode *m_fillNode = nullptr;
+ QQuickShapeGenericStrokeFillNode *m_strokeNode = nullptr;
+ QQuickShapeGenericNode *m_next = nullptr;
+};
+
+class QQuickShapeGenericMaterialFactory
+{
+public:
+ static QSGMaterial *createVertexColor(QQuickWindow *window);
+ static QSGMaterial *createLinearGradient(QQuickWindow *window, QQuickShapeGenericStrokeFillNode *node);
+ static QSGMaterial *createRadialGradient(QQuickWindow *window, QQuickShapeGenericStrokeFillNode *node);
+ static QSGMaterial *createConicalGradient(QQuickWindow *window, QQuickShapeGenericStrokeFillNode *node);
+};
+
+#if QT_CONFIG(opengl)
+
+class QQuickShapeLinearGradientShader : public QSGMaterialShader
+{
+public:
+ QQuickShapeLinearGradientShader();
+
+ void initialize() override;
+ void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
+ char const *const *attributeNames() const override;
+
+ static QSGMaterialType type;
+
+private:
+ int m_opacityLoc = -1;
+ int m_matrixLoc = -1;
+ int m_gradStartLoc = -1;
+ int m_gradEndLoc = -1;
+};
+
+class QQuickShapeLinearGradientMaterial : public QSGMaterial
+{
+public:
+ QQuickShapeLinearGradientMaterial(QQuickShapeGenericStrokeFillNode *node)
+ : m_node(node)
+ {
+ // Passing RequiresFullMatrix is essential in order to prevent the
+ // batch renderer from baking in simple, translate-only transforms into
+ // the vertex data. The shader will rely on the fact that
+ // vertexCoord.xy is the Shape-space coordinate and so no modifications
+ // are welcome.
+ setFlag(Blending | RequiresFullMatrix);
+ }
+
+ QSGMaterialType *type() const override
+ {
+ return &QQuickShapeLinearGradientShader::type;
+ }
+
+ int compare(const QSGMaterial *other) const override;
+
+ QSGMaterialShader *createShader() const override
+ {
+ return new QQuickShapeLinearGradientShader;
+ }
+
+ QQuickShapeGenericStrokeFillNode *node() const { return m_node; }
+
+private:
+ QQuickShapeGenericStrokeFillNode *m_node;
+};
+
+class QQuickShapeRadialGradientShader : public QSGMaterialShader
+{
+public:
+ QQuickShapeRadialGradientShader();
+
+ void initialize() override;
+ void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
+ char const *const *attributeNames() const override;
+
+ static QSGMaterialType type;
+
+private:
+ int m_opacityLoc = -1;
+ int m_matrixLoc = -1;
+ int m_translationPointLoc = -1;
+ int m_focalToCenterLoc = -1;
+ int m_centerRadiusLoc = -1;
+ int m_focalRadiusLoc = -1;
+};
+
+class QQuickShapeRadialGradientMaterial : public QSGMaterial
+{
+public:
+ QQuickShapeRadialGradientMaterial(QQuickShapeGenericStrokeFillNode *node)
+ : m_node(node)
+ {
+ setFlag(Blending | RequiresFullMatrix);
+ }
+
+ QSGMaterialType *type() const override
+ {
+ return &QQuickShapeRadialGradientShader::type;
+ }
+
+ int compare(const QSGMaterial *other) const override;
+
+ QSGMaterialShader *createShader() const override
+ {
+ return new QQuickShapeRadialGradientShader;
+ }
+
+ QQuickShapeGenericStrokeFillNode *node() const { return m_node; }
+
+private:
+ QQuickShapeGenericStrokeFillNode *m_node;
+};
+
+class QQuickShapeConicalGradientShader : public QSGMaterialShader
+{
+public:
+ QQuickShapeConicalGradientShader();
+
+ void initialize() override;
+ void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
+ char const *const *attributeNames() const override;
+
+ static QSGMaterialType type;
+
+private:
+ int m_opacityLoc = -1;
+ int m_matrixLoc = -1;
+ int m_angleLoc = -1;
+ int m_translationPointLoc = -1;
+};
+
+class QQuickShapeConicalGradientMaterial : public QSGMaterial
+{
+public:
+ QQuickShapeConicalGradientMaterial(QQuickShapeGenericStrokeFillNode *node)
+ : m_node(node)
+ {
+ setFlag(Blending | RequiresFullMatrix);
+ }
+
+ QSGMaterialType *type() const override
+ {
+ return &QQuickShapeConicalGradientShader::type;
+ }
+
+ int compare(const QSGMaterial *other) const override;
+
+ QSGMaterialShader *createShader() const override
+ {
+ return new QQuickShapeConicalGradientShader;
+ }
+
+ QQuickShapeGenericStrokeFillNode *node() const { return m_node; }
+
+private:
+ QQuickShapeGenericStrokeFillNode *m_node;
+};
+
+#endif // QT_CONFIG(opengl)
+
+QT_END_NAMESPACE
+
+#endif // QQUICKSHAPEGENERICRENDERER_P_H
diff --git a/src/imports/shapes/qquickshapenvprrenderer.cpp b/src/imports/shapes/qquickshapenvprrenderer.cpp
new file mode 100644
index 0000000000..88f367fe70
--- /dev/null
+++ b/src/imports/shapes/qquickshapenvprrenderer.cpp
@@ -0,0 +1,1001 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickshapenvprrenderer_p.h"
+#include <QOpenGLExtraFunctions>
+#include <QOpenGLFramebufferObject>
+#include <QOpenGLShaderProgram>
+#include <QOpenGLBuffer>
+#include <qmath.h>
+#include <private/qpainterpath_p.h>
+#include <private/qquickpath_p_p.h>
+
+QT_BEGIN_NAMESPACE
+
+void QQuickShapeNvprRenderer::beginSync(int totalCount)
+{
+ if (m_sp.count() != totalCount) {
+ m_sp.resize(totalCount);
+ m_accDirty |= DirtyList;
+ }
+}
+
+void QQuickShapeNvprRenderer::setPath(int index, const QQuickPath *path)
+{
+ ShapePathGuiData &d(m_sp[index]);
+ convertPath(path, &d);
+ d.dirty |= DirtyPath;
+ m_accDirty |= DirtyPath;
+}
+
+void QQuickShapeNvprRenderer::setStrokeColor(int index, const QColor &color)
+{
+ ShapePathGuiData &d(m_sp[index]);
+ d.strokeColor = color;
+ d.dirty |= DirtyStyle;
+ m_accDirty |= DirtyStyle;
+}
+
+void QQuickShapeNvprRenderer::setStrokeWidth(int index, qreal w)
+{
+ ShapePathGuiData &d(m_sp[index]);
+ d.strokeWidth = w;
+ d.dirty |= DirtyStyle;
+ m_accDirty |= DirtyStyle;
+}
+
+void QQuickShapeNvprRenderer::setFillColor(int index, const QColor &color)
+{
+ ShapePathGuiData &d(m_sp[index]);
+ d.fillColor = color;
+ d.dirty |= DirtyStyle;
+ m_accDirty |= DirtyStyle;
+}
+
+void QQuickShapeNvprRenderer::setFillRule(int index, QQuickShapePath::FillRule fillRule)
+{
+ ShapePathGuiData &d(m_sp[index]);
+ d.fillRule = fillRule;
+ d.dirty |= DirtyFillRule;
+ m_accDirty |= DirtyFillRule;
+}
+
+void QQuickShapeNvprRenderer::setJoinStyle(int index, QQuickShapePath::JoinStyle joinStyle, int miterLimit)
+{
+ ShapePathGuiData &d(m_sp[index]);
+ d.joinStyle = joinStyle;
+ d.miterLimit = miterLimit;
+ d.dirty |= DirtyStyle;
+ m_accDirty |= DirtyStyle;
+}
+
+void QQuickShapeNvprRenderer::setCapStyle(int index, QQuickShapePath::CapStyle capStyle)
+{
+ ShapePathGuiData &d(m_sp[index]);
+ d.capStyle = capStyle;
+ d.dirty |= DirtyStyle;
+ m_accDirty |= DirtyStyle;
+}
+
+void QQuickShapeNvprRenderer::setStrokeStyle(int index, QQuickShapePath::StrokeStyle strokeStyle,
+ qreal dashOffset, const QVector<qreal> &dashPattern)
+{
+ ShapePathGuiData &d(m_sp[index]);
+ d.dashActive = strokeStyle == QQuickShapePath::DashLine;
+ d.dashOffset = dashOffset;
+ d.dashPattern = dashPattern;
+ d.dirty |= DirtyDash;
+ m_accDirty |= DirtyDash;
+}
+
+void QQuickShapeNvprRenderer::setFillGradient(int index, QQuickShapeGradient *gradient)
+{
+ ShapePathGuiData &d(m_sp[index]);
+ if (gradient) {
+ d.fillGradient.stops = gradient->gradientStops(); // sorted
+ d.fillGradient.spread = gradient->spread();
+ if (QQuickShapeLinearGradient *g = qobject_cast<QQuickShapeLinearGradient *>(gradient)) {
+ d.fillGradientActive = LinearGradient;
+ d.fillGradient.a = QPointF(g->x1(), g->y1());
+ d.fillGradient.b = QPointF(g->x2(), g->y2());
+ } else if (QQuickShapeRadialGradient *g = qobject_cast<QQuickShapeRadialGradient *>(gradient)) {
+ d.fillGradientActive = RadialGradient;
+ d.fillGradient.a = QPointF(g->centerX(), g->centerY());
+ d.fillGradient.b = QPointF(g->focalX(), g->focalY());
+ d.fillGradient.v0 = g->centerRadius();
+ d.fillGradient.v1 = g->focalRadius();
+ } else if (QQuickShapeConicalGradient *g = qobject_cast<QQuickShapeConicalGradient *>(gradient)) {
+ d.fillGradientActive = ConicalGradient;
+ d.fillGradient.a = QPointF(g->centerX(), g->centerY());
+ d.fillGradient.v0 = g->angle();
+ } else {
+ Q_UNREACHABLE();
+ }
+ } else {
+ d.fillGradientActive = NoGradient;
+ }
+ d.dirty |= DirtyFillGradient;
+ m_accDirty |= DirtyFillGradient;
+}
+
+void QQuickShapeNvprRenderer::endSync(bool)
+{
+}
+
+void QQuickShapeNvprRenderer::setNode(QQuickShapeNvprRenderNode *node)
+{
+ if (m_node != node) {
+ m_node = node;
+ m_accDirty |= DirtyList;
+ }
+}
+
+QDebug operator<<(QDebug debug, const QQuickShapeNvprRenderer::NvprPath &path)
+{
+ QDebugStateSaver saver(debug);
+ debug.space().noquote();
+ if (!path.str.isEmpty()) {
+ debug << "Path with SVG string" << path.str;
+ return debug;
+ }
+ debug << "Path with" << path.cmd.count() << "commands";
+ int ci = 0;
+ for (GLubyte cmd : path.cmd) {
+ static struct { GLubyte cmd; const char *s; int coordCount; } nameTab[] = {
+ { GL_MOVE_TO_NV, "moveTo", 2 },
+ { GL_LINE_TO_NV, "lineTo", 2 },
+ { GL_QUADRATIC_CURVE_TO_NV, "quadTo", 4 },
+ { GL_CUBIC_CURVE_TO_NV, "cubicTo", 6 },
+ { GL_LARGE_CW_ARC_TO_NV, "arcTo-large-CW", 5 },
+ { GL_LARGE_CCW_ARC_TO_NV, "arcTo-large-CCW", 5 },
+ { GL_SMALL_CW_ARC_TO_NV, "arcTo-small-CW", 5 },
+ { GL_SMALL_CCW_ARC_TO_NV, "arcTo-small-CCW", 5 },
+ { GL_CLOSE_PATH_NV, "closePath", 0 } };
+ for (size_t i = 0; i < sizeof(nameTab) / sizeof(nameTab[0]); ++i) {
+ if (nameTab[i].cmd == cmd) {
+ QByteArray cs;
+ for (int j = 0; j < nameTab[i].coordCount; ++j) {
+ cs.append(QByteArray::number(path.coord[ci++]));
+ cs.append(' ');
+ }
+ debug << "\n " << nameTab[i].s << " " << cs;
+ break;
+ }
+ }
+ }
+ return debug;
+}
+
+static inline void appendCoords(QVector<GLfloat> *v, QQuickCurve *c, QPointF *pos)
+{
+ QPointF p(c->hasRelativeX() ? pos->x() + c->relativeX() : c->x(),
+ c->hasRelativeY() ? pos->y() + c->relativeY() : c->y());
+ v->append(p.x());
+ v->append(p.y());
+ *pos = p;
+}
+
+static inline void appendControlCoords(QVector<GLfloat> *v, QQuickPathQuad *c, const QPointF &pos)
+{
+ QPointF p(c->hasRelativeControlX() ? pos.x() + c->relativeControlX() : c->controlX(),
+ c->hasRelativeControlY() ? pos.y() + c->relativeControlY() : c->controlY());
+ v->append(p.x());
+ v->append(p.y());
+}
+
+static inline void appendControl1Coords(QVector<GLfloat> *v, QQuickPathCubic *c, const QPointF &pos)
+{
+ QPointF p(c->hasRelativeControl1X() ? pos.x() + c->relativeControl1X() : c->control1X(),
+ c->hasRelativeControl1Y() ? pos.y() + c->relativeControl1Y() : c->control1Y());
+ v->append(p.x());
+ v->append(p.y());
+}
+
+static inline void appendControl2Coords(QVector<GLfloat> *v, QQuickPathCubic *c, const QPointF &pos)
+{
+ QPointF p(c->hasRelativeControl2X() ? pos.x() + c->relativeControl2X() : c->control2X(),
+ c->hasRelativeControl2Y() ? pos.y() + c->relativeControl2Y() : c->control2Y());
+ v->append(p.x());
+ v->append(p.y());
+}
+
+void QQuickShapeNvprRenderer::convertPath(const QQuickPath *path, ShapePathGuiData *d)
+{
+ d->path = NvprPath();
+ if (!path)
+ return;
+
+ const QList<QQuickPathElement *> &pp(QQuickPathPrivate::get(path)->_pathElements);
+ if (pp.isEmpty())
+ return;
+
+ QPointF startPos(path->startX(), path->startY());
+ QPointF pos(startPos);
+ if (!qFuzzyIsNull(pos.x()) || !qFuzzyIsNull(pos.y())) {
+ d->path.cmd.append(GL_MOVE_TO_NV);
+ d->path.coord.append(pos.x());
+ d->path.coord.append(pos.y());
+ }
+
+ for (QQuickPathElement *e : pp) {
+ if (QQuickPathMove *o = qobject_cast<QQuickPathMove *>(e)) {
+ d->path.cmd.append(GL_MOVE_TO_NV);
+ appendCoords(&d->path.coord, o, &pos);
+ startPos = pos;
+ } else if (QQuickPathLine *o = qobject_cast<QQuickPathLine *>(e)) {
+ d->path.cmd.append(GL_LINE_TO_NV);
+ appendCoords(&d->path.coord, o, &pos);
+ } else if (QQuickPathQuad *o = qobject_cast<QQuickPathQuad *>(e)) {
+ d->path.cmd.append(GL_QUADRATIC_CURVE_TO_NV);
+ appendControlCoords(&d->path.coord, o, pos);
+ appendCoords(&d->path.coord, o, &pos);
+ } else if (QQuickPathCubic *o = qobject_cast<QQuickPathCubic *>(e)) {
+ d->path.cmd.append(GL_CUBIC_CURVE_TO_NV);
+ appendControl1Coords(&d->path.coord, o, pos);
+ appendControl2Coords(&d->path.coord, o, pos);
+ appendCoords(&d->path.coord, o, &pos);
+ } else if (QQuickPathArc *o = qobject_cast<QQuickPathArc *>(e)) {
+ const bool sweepFlag = o->direction() == QQuickPathArc::Clockwise; // maps to CCW, not a typo
+ GLenum cmd;
+ if (o->useLargeArc())
+ cmd = sweepFlag ? GL_LARGE_CCW_ARC_TO_NV : GL_LARGE_CW_ARC_TO_NV;
+ else
+ cmd = sweepFlag ? GL_SMALL_CCW_ARC_TO_NV : GL_SMALL_CW_ARC_TO_NV;
+ d->path.cmd.append(cmd);
+ d->path.coord.append(o->radiusX());
+ d->path.coord.append(o->radiusY());
+ d->path.coord.append(o->xAxisRotation());
+ appendCoords(&d->path.coord, o, &pos);
+ } else if (QQuickPathSvg *o = qobject_cast<QQuickPathSvg *>(e)) {
+ // PathSvg cannot be combined with other elements. But take at
+ // least startX and startY into account.
+ if (d->path.str.isEmpty())
+ d->path.str = QString(QStringLiteral("M %1 %2 ")).arg(pos.x()).arg(pos.y()).toUtf8();
+ d->path.str.append(o->path().toUtf8());
+ } else if (QQuickPathAngleArc *o = qobject_cast<QQuickPathAngleArc *>(e)) {
+ QRectF rect(o->centerX() - o->radiusX(), o->centerY() - o->radiusY(), o->radiusX() * 2, o->radiusY() * 2);
+ QPointF startPoint;
+ QPointF endPoint;
+ qt_find_ellipse_coords(rect, o->startAngle(), -o->sweepAngle(), &startPoint, &endPoint);
+
+ // get to our starting position
+ if (o->moveToStart())
+ d->path.cmd.append(GL_MOVE_TO_NV);
+ else
+ d->path.cmd.append(GL_LINE_TO_NV); // ### should we check if startPoint == pos?
+ d->path.coord.append(startPoint.x());
+ d->path.coord.append(startPoint.y());
+
+ const bool sweepFlag = o->sweepAngle() > 0; // maps to CCW, not a typo
+ d->path.cmd.append(qAbs(o->sweepAngle()) > 180.0
+ ? (sweepFlag ? GL_LARGE_CCW_ARC_TO_NV : GL_LARGE_CW_ARC_TO_NV)
+ : (sweepFlag ? GL_SMALL_CCW_ARC_TO_NV : GL_SMALL_CW_ARC_TO_NV));
+ d->path.coord.append(o->radiusX());
+ d->path.coord.append(o->radiusY());
+ d->path.coord.append(0); // xAxisRotation
+ d->path.coord.append(endPoint.x());
+ d->path.coord.append(endPoint.y());
+ pos = endPoint;
+ } else {
+ qWarning() << "Shape/NVPR: unsupported Path element" << e;
+ }
+ }
+
+ // For compatibility with QTriangulatingStroker. SVG and others would not
+ // implicitly close the path when end_pos == start_pos (start_pos being the
+ // last moveTo pos); that would still need an explicit 'z' or similar. We
+ // don't have an explicit close command, so just fake a close when the
+ // positions match.
+ if (pos == startPos)
+ d->path.cmd.append(GL_CLOSE_PATH_NV);
+}
+
+static inline QVector4D qsg_premultiply(const QColor &c, float globalOpacity)
+{
+ const float o = c.alphaF() * globalOpacity;
+ return QVector4D(c.redF() * o, c.greenF() * o, c.blueF() * o, o);
+}
+
+void QQuickShapeNvprRenderer::updateNode()
+{
+ // Called on the render thread with gui blocked -> update the node with its
+ // own copy of all relevant data.
+
+ if (!m_accDirty)
+ return;
+
+ const int count = m_sp.count();
+ const bool listChanged = m_accDirty & DirtyList;
+ if (listChanged)
+ m_node->m_sp.resize(count);
+
+ for (int i = 0; i < count; ++i) {
+ ShapePathGuiData &src(m_sp[i]);
+ QQuickShapeNvprRenderNode::ShapePathRenderData &dst(m_node->m_sp[i]);
+
+ int dirty = src.dirty;
+ src.dirty = 0;
+ if (listChanged)
+ dirty |= DirtyPath | DirtyStyle | DirtyFillRule | DirtyDash | DirtyFillGradient;
+
+ // updateNode() can be called several times with different dirty
+ // states before render() gets invoked. So accumulate.
+ dst.dirty |= dirty;
+
+ if (dirty & DirtyPath)
+ dst.source = src.path;
+
+ if (dirty & DirtyStyle) {
+ dst.strokeWidth = src.strokeWidth;
+ dst.strokeColor = qsg_premultiply(src.strokeColor, 1.0f);
+ dst.fillColor = qsg_premultiply(src.fillColor, 1.0f);
+ switch (src.joinStyle) {
+ case QQuickShapePath::MiterJoin:
+ dst.joinStyle = GL_MITER_TRUNCATE_NV;
+ break;
+ case QQuickShapePath::BevelJoin:
+ dst.joinStyle = GL_BEVEL_NV;
+ break;
+ case QQuickShapePath::RoundJoin:
+ dst.joinStyle = GL_ROUND_NV;
+ break;
+ default:
+ Q_UNREACHABLE();
+ }
+ dst.miterLimit = src.miterLimit;
+ switch (src.capStyle) {
+ case QQuickShapePath::FlatCap:
+ dst.capStyle = GL_FLAT;
+ break;
+ case QQuickShapePath::SquareCap:
+ dst.capStyle = GL_SQUARE_NV;
+ break;
+ case QQuickShapePath::RoundCap:
+ dst.capStyle = GL_ROUND_NV;
+ break;
+ default:
+ Q_UNREACHABLE();
+ }
+ }
+
+ if (dirty & DirtyFillRule) {
+ switch (src.fillRule) {
+ case QQuickShapePath::OddEvenFill:
+ dst.fillRule = GL_INVERT;
+ break;
+ case QQuickShapePath::WindingFill:
+ dst.fillRule = GL_COUNT_UP_NV;
+ break;
+ default:
+ Q_UNREACHABLE();
+ }
+ }
+
+ if (dirty & DirtyDash) {
+ // Multiply by strokeWidth because the Shape API follows QPen
+ // meaning the input dash pattern and dash offset here are in width units.
+ dst.dashOffset = src.dashOffset * src.strokeWidth;
+ if (src.dashActive) {
+ if (src.dashPattern.isEmpty()) {
+ // default values for DashLine as defined in qpen.cpp
+ dst.dashPattern.resize(2);
+ dst.dashPattern[0] = 4 * src.strokeWidth; // dash
+ dst.dashPattern[1] = 2 * src.strokeWidth; // space
+ } else {
+ dst.dashPattern.resize(src.dashPattern.count());
+ for (int i = 0; i < src.dashPattern.count(); ++i)
+ dst.dashPattern[i] = GLfloat(src.dashPattern[i]) * src.strokeWidth;
+
+ // QPen expects a dash pattern of even length and so should we
+ if (src.dashPattern.count() % 2 != 0) {
+ qWarning("QQuickShapeNvprRenderNode: dash pattern not of even length");
+ dst.dashPattern << src.strokeWidth;
+ }
+ }
+ } else {
+ dst.dashPattern.clear();
+ }
+ }
+
+ if (dirty & DirtyFillGradient) {
+ dst.fillGradientActive = src.fillGradientActive;
+ if (src.fillGradientActive)
+ dst.fillGradient = src.fillGradient;
+ }
+ }
+
+ m_node->markDirty(QSGNode::DirtyMaterial);
+ m_accDirty = 0;
+}
+
+bool QQuickShapeNvprRenderNode::nvprInited = false;
+QQuickNvprFunctions QQuickShapeNvprRenderNode::nvpr;
+QQuickNvprMaterialManager QQuickShapeNvprRenderNode::mtlmgr;
+
+QQuickShapeNvprRenderNode::~QQuickShapeNvprRenderNode()
+{
+ releaseResources();
+}
+
+void QQuickShapeNvprRenderNode::releaseResources()
+{
+ for (ShapePathRenderData &d : m_sp) {
+ if (d.path) {
+ nvpr.deletePaths(d.path, 1);
+ d.path = 0;
+ }
+ if (d.fallbackFbo) {
+ delete d.fallbackFbo;
+ d.fallbackFbo = nullptr;
+ }
+ }
+
+ m_fallbackBlitter.destroy();
+}
+
+void QQuickNvprMaterialManager::create(QQuickNvprFunctions *nvpr)
+{
+ m_nvpr = nvpr;
+}
+
+void QQuickNvprMaterialManager::releaseResources()
+{
+ QOpenGLExtraFunctions *f = QOpenGLContext::currentContext()->extraFunctions();
+ for (MaterialDesc &mtl : m_materials) {
+ if (mtl.ppl) {
+ f->glDeleteProgramPipelines(1, &mtl.ppl);
+ mtl = MaterialDesc();
+ }
+ }
+}
+
+QQuickNvprMaterialManager::MaterialDesc *QQuickNvprMaterialManager::activateMaterial(Material m)
+{
+ QOpenGLExtraFunctions *f = QOpenGLContext::currentContext()->extraFunctions();
+ MaterialDesc &mtl(m_materials[m]);
+
+ if (!mtl.ppl) {
+ if (m == MatSolid) {
+ static const char *fragSrc =
+ "#version 310 es\n"
+ "precision highp float;\n"
+ "out vec4 fragColor;\n"
+ "uniform vec4 color;\n"
+ "uniform float opacity;\n"
+ "void main() {\n"
+ " fragColor = color * opacity;\n"
+ "}\n";
+ if (!m_nvpr->createFragmentOnlyPipeline(fragSrc, &mtl.ppl, &mtl.prg)) {
+ qWarning("NVPR: Failed to create shader pipeline for solid fill");
+ return nullptr;
+ }
+ Q_ASSERT(mtl.ppl && mtl.prg);
+ mtl.uniLoc[0] = f->glGetProgramResourceLocation(mtl.prg, GL_UNIFORM, "color");
+ Q_ASSERT(mtl.uniLoc[0] >= 0);
+ mtl.uniLoc[1] = f->glGetProgramResourceLocation(mtl.prg, GL_UNIFORM, "opacity");
+ Q_ASSERT(mtl.uniLoc[1] >= 0);
+ } else if (m == MatLinearGradient) {
+ static const char *fragSrc =
+ "#version 310 es\n"
+ "precision highp float;\n"
+ "layout(location = 0) in vec2 uv;"
+ "uniform float opacity;\n"
+ "uniform sampler2D gradTab;\n"
+ "uniform vec2 gradStart;\n"
+ "uniform vec2 gradEnd;\n"
+ "out vec4 fragColor;\n"
+ "void main() {\n"
+ " vec2 gradVec = gradEnd - gradStart;\n"
+ " float gradTabIndex = dot(gradVec, uv - gradStart) / (gradVec.x * gradVec.x + gradVec.y * gradVec.y);\n"
+ " fragColor = texture(gradTab, vec2(gradTabIndex, 0.5)) * opacity;\n"
+ "}\n";
+ if (!m_nvpr->createFragmentOnlyPipeline(fragSrc, &mtl.ppl, &mtl.prg)) {
+ qWarning("NVPR: Failed to create shader pipeline for linear gradient");
+ return nullptr;
+ }
+ Q_ASSERT(mtl.ppl && mtl.prg);
+ mtl.uniLoc[1] = f->glGetProgramResourceLocation(mtl.prg, GL_UNIFORM, "opacity");
+ Q_ASSERT(mtl.uniLoc[1] >= 0);
+ mtl.uniLoc[2] = f->glGetProgramResourceLocation(mtl.prg, GL_UNIFORM, "gradStart");
+ Q_ASSERT(mtl.uniLoc[2] >= 0);
+ mtl.uniLoc[3] = f->glGetProgramResourceLocation(mtl.prg, GL_UNIFORM, "gradEnd");
+ Q_ASSERT(mtl.uniLoc[3] >= 0);
+ } else if (m == MatRadialGradient) {
+ static const char *fragSrc =
+ "#version 310 es\n"
+ "precision highp float;\n"
+ "uniform sampler2D gradTab;\n"
+ "uniform float opacity;\n"
+ "uniform vec2 focalToCenter;\n"
+ "uniform float centerRadius;\n"
+ "uniform float focalRadius;\n"
+ "uniform vec2 translationPoint;\n"
+ "layout(location = 0) in vec2 uv;\n"
+ "out vec4 fragColor;\n"
+ "void main() {\n"
+ " vec2 coord = uv - translationPoint;\n"
+ " float rd = centerRadius - focalRadius;\n"
+ " float b = 2.0 * (rd * focalRadius + dot(coord, focalToCenter));\n"
+ " float fmp2_m_radius2 = -focalToCenter.x * focalToCenter.x - focalToCenter.y * focalToCenter.y + rd * rd;\n"
+ " float inverse_2_fmp2_m_radius2 = 1.0 / (2.0 * fmp2_m_radius2);\n"
+ " float det = b * b - 4.0 * fmp2_m_radius2 * ((focalRadius * focalRadius) - dot(coord, coord));\n"
+ " vec4 result = vec4(0.0);\n"
+ " if (det >= 0.0) {\n"
+ " float detSqrt = sqrt(det);\n"
+ " float w = max((-b - detSqrt) * inverse_2_fmp2_m_radius2, (-b + detSqrt) * inverse_2_fmp2_m_radius2);\n"
+ " if (focalRadius + w * (centerRadius - focalRadius) >= 0.0)\n"
+ " result = texture(gradTab, vec2(w, 0.5)) * opacity;\n"
+ " }\n"
+ " fragColor = result;\n"
+ "}\n";
+ if (!m_nvpr->createFragmentOnlyPipeline(fragSrc, &mtl.ppl, &mtl.prg)) {
+ qWarning("NVPR: Failed to create shader pipeline for radial gradient");
+ return nullptr;
+ }
+ Q_ASSERT(mtl.ppl && mtl.prg);
+ mtl.uniLoc[1] = f->glGetProgramResourceLocation(mtl.prg, GL_UNIFORM, "opacity");
+ Q_ASSERT(mtl.uniLoc[1] >= 0);
+ mtl.uniLoc[2] = f->glGetProgramResourceLocation(mtl.prg, GL_UNIFORM, "focalToCenter");
+ Q_ASSERT(mtl.uniLoc[2] >= 0);
+ mtl.uniLoc[3] = f->glGetProgramResourceLocation(mtl.prg, GL_UNIFORM, "centerRadius");
+ Q_ASSERT(mtl.uniLoc[3] >= 0);
+ mtl.uniLoc[4] = f->glGetProgramResourceLocation(mtl.prg, GL_UNIFORM, "focalRadius");
+ Q_ASSERT(mtl.uniLoc[4] >= 0);
+ mtl.uniLoc[5] = f->glGetProgramResourceLocation(mtl.prg, GL_UNIFORM, "translationPoint");
+ Q_ASSERT(mtl.uniLoc[5] >= 0);
+ } else if (m == MatConicalGradient) {
+ static const char *fragSrc =
+ "#version 310 es\n"
+ "precision highp float;\n"
+ "#define INVERSE_2PI 0.1591549430918953358\n"
+ "uniform sampler2D gradTab;\n"
+ "uniform float opacity;\n"
+ "uniform float angle;\n"
+ "uniform vec2 translationPoint;\n"
+ "layout(location = 0) in vec2 uv;\n"
+ "out vec4 fragColor;\n"
+ "void main() {\n"
+ " vec2 coord = uv - translationPoint;\n"
+ " float t;\n"
+ " if (abs(coord.y) == abs(coord.x))\n"
+ " t = (atan(-coord.y + 0.002, coord.x) + angle) * INVERSE_2PI;\n"
+ " else\n"
+ " t = (atan(-coord.y, coord.x) + angle) * INVERSE_2PI;\n"
+ " fragColor = texture(gradTab, vec2(t - floor(t), 0.5)) * opacity;\n"
+ "}\n";
+ if (!m_nvpr->createFragmentOnlyPipeline(fragSrc, &mtl.ppl, &mtl.prg)) {
+ qWarning("NVPR: Failed to create shader pipeline for conical gradient");
+ return nullptr;
+ }
+ Q_ASSERT(mtl.ppl && mtl.prg);
+ mtl.uniLoc[1] = f->glGetProgramResourceLocation(mtl.prg, GL_UNIFORM, "opacity");
+ Q_ASSERT(mtl.uniLoc[1] >= 0);
+ mtl.uniLoc[2] = f->glGetProgramResourceLocation(mtl.prg, GL_UNIFORM, "angle");
+ Q_ASSERT(mtl.uniLoc[2] >= 0);
+ mtl.uniLoc[3] = f->glGetProgramResourceLocation(mtl.prg, GL_UNIFORM, "translationPoint");
+ Q_ASSERT(mtl.uniLoc[3] >= 0);
+ } else {
+ Q_UNREACHABLE();
+ }
+ }
+
+ f->glBindProgramPipeline(mtl.ppl);
+
+ return &mtl;
+}
+
+void QQuickShapeNvprRenderNode::updatePath(ShapePathRenderData *d)
+{
+ if (d->dirty & QQuickShapeNvprRenderer::DirtyPath) {
+ if (!d->path) {
+ d->path = nvpr.genPaths(1);
+ Q_ASSERT(d->path != 0);
+ }
+ if (d->source.str.isEmpty()) {
+ nvpr.pathCommands(d->path, d->source.cmd.count(), d->source.cmd.constData(),
+ d->source.coord.count(), GL_FLOAT, d->source.coord.constData());
+ } else {
+ nvpr.pathString(d->path, GL_PATH_FORMAT_SVG_NV, d->source.str.count(), d->source.str.constData());
+ }
+ }
+
+ if (d->dirty & QQuickShapeNvprRenderer::DirtyStyle) {
+ nvpr.pathParameterf(d->path, GL_PATH_STROKE_WIDTH_NV, d->strokeWidth);
+ nvpr.pathParameteri(d->path, GL_PATH_JOIN_STYLE_NV, d->joinStyle);
+ nvpr.pathParameteri(d->path, GL_PATH_MITER_LIMIT_NV, d->miterLimit);
+ nvpr.pathParameteri(d->path, GL_PATH_END_CAPS_NV, d->capStyle);
+ nvpr.pathParameteri(d->path, GL_PATH_DASH_CAPS_NV, d->capStyle);
+ }
+
+ if (d->dirty & QQuickShapeNvprRenderer::DirtyDash) {
+ nvpr.pathParameterf(d->path, GL_PATH_DASH_OFFSET_NV, d->dashOffset);
+ // count == 0 -> no dash
+ nvpr.pathDashArray(d->path, d->dashPattern.count(), d->dashPattern.constData());
+ }
+
+ if (d->dirty)
+ d->fallbackValid = false;
+}
+
+void QQuickShapeNvprRenderNode::renderStroke(ShapePathRenderData *d, int strokeStencilValue, int writeMask)
+{
+ QQuickNvprMaterialManager::MaterialDesc *mtl = mtlmgr.activateMaterial(QQuickNvprMaterialManager::MatSolid);
+ f->glProgramUniform4f(mtl->prg, mtl->uniLoc[0],
+ d->strokeColor.x(), d->strokeColor.y(), d->strokeColor.z(), d->strokeColor.w());
+ f->glProgramUniform1f(mtl->prg, mtl->uniLoc[1], inheritedOpacity());
+
+ nvpr.stencilThenCoverStrokePath(d->path, strokeStencilValue, writeMask, GL_CONVEX_HULL_NV);
+}
+
+void QQuickShapeNvprRenderNode::renderFill(ShapePathRenderData *d)
+{
+ QQuickNvprMaterialManager::MaterialDesc *mtl = nullptr;
+ if (d->fillGradientActive) {
+ QQuickShapeGradient::SpreadMode spread = d->fillGradient.spread;
+ if (d->fillGradientActive == QQuickAbstractPathRenderer::LinearGradient) {
+ mtl = mtlmgr.activateMaterial(QQuickNvprMaterialManager::MatLinearGradient);
+ // uv = vec2(coeff[0] * x + coeff[1] * y + coeff[2], coeff[3] * x + coeff[4] * y + coeff[5])
+ // where x and y are in path coordinate space, which is just what
+ // we need since the gradient's start and stop are in that space too.
+ GLfloat coeff[6] = { 1, 0, 0,
+ 0, 1, 0 };
+ nvpr.programPathFragmentInputGen(mtl->prg, 0, GL_OBJECT_LINEAR_NV, 2, coeff);
+ f->glProgramUniform2f(mtl->prg, mtl->uniLoc[2], d->fillGradient.a.x(), d->fillGradient.a.y());
+ f->glProgramUniform2f(mtl->prg, mtl->uniLoc[3], d->fillGradient.b.x(), d->fillGradient.b.y());
+ } else if (d->fillGradientActive == QQuickAbstractPathRenderer::RadialGradient) {
+ mtl = mtlmgr.activateMaterial(QQuickNvprMaterialManager::MatRadialGradient);
+ // simply drive uv (location 0) with x and y, just like for the linear gradient
+ GLfloat coeff[6] = { 1, 0, 0,
+ 0, 1, 0 };
+ nvpr.programPathFragmentInputGen(mtl->prg, 0, GL_OBJECT_LINEAR_NV, 2, coeff);
+
+ const QPointF centerPoint = d->fillGradient.a;
+ const QPointF focalPoint = d->fillGradient.b;
+ const QPointF focalToCenter = centerPoint - focalPoint;
+ const GLfloat centerRadius = d->fillGradient.v0;
+ const GLfloat focalRadius = d->fillGradient.v1;
+
+ f->glProgramUniform2f(mtl->prg, mtl->uniLoc[2], focalToCenter.x(), focalToCenter.y());
+ f->glProgramUniform1f(mtl->prg, mtl->uniLoc[3], centerRadius);
+ f->glProgramUniform1f(mtl->prg, mtl->uniLoc[4], focalRadius);
+ f->glProgramUniform2f(mtl->prg, mtl->uniLoc[5], focalPoint.x(), focalPoint.y());
+ } else if (d->fillGradientActive == QQuickAbstractPathRenderer::ConicalGradient) {
+ mtl = mtlmgr.activateMaterial(QQuickNvprMaterialManager::MatConicalGradient);
+ // same old
+ GLfloat coeff[6] = { 1, 0, 0,
+ 0, 1, 0 };
+ nvpr.programPathFragmentInputGen(mtl->prg, 0, GL_OBJECT_LINEAR_NV, 2, coeff);
+
+ const QPointF centerPoint = d->fillGradient.a;
+ const GLfloat angle = -qDegreesToRadians(d->fillGradient.v0);
+
+ f->glProgramUniform1f(mtl->prg, mtl->uniLoc[2], angle);
+ f->glProgramUniform2f(mtl->prg, mtl->uniLoc[3], centerPoint.x(), centerPoint.y());
+
+ spread = QQuickShapeGradient::RepeatSpread;
+ } else {
+ Q_UNREACHABLE();
+ }
+ const QQuickShapeGradientCache::Key cacheKey(d->fillGradient.stops, spread);
+ QSGTexture *tx = QQuickShapeGradientCache::currentCache()->get(cacheKey);
+ tx->bind();
+ } else {
+ mtl = mtlmgr.activateMaterial(QQuickNvprMaterialManager::MatSolid);
+ f->glProgramUniform4f(mtl->prg, mtl->uniLoc[0],
+ d->fillColor.x(), d->fillColor.y(), d->fillColor.z(), d->fillColor.w());
+ }
+ f->glProgramUniform1f(mtl->prg, mtl->uniLoc[1], inheritedOpacity());
+
+ const int writeMask = 0xFF;
+ nvpr.stencilThenCoverFillPath(d->path, d->fillRule, writeMask, GL_BOUNDING_BOX_NV);
+}
+
+void QQuickShapeNvprRenderNode::renderOffscreenFill(ShapePathRenderData *d)
+{
+ if (d->fallbackValid && d->fallbackFbo)
+ return;
+
+ GLfloat bb[4];
+ nvpr.getPathParameterfv(d->path, GL_PATH_STROKE_BOUNDING_BOX_NV, bb);
+ QSize sz = QSizeF(bb[2] - bb[0] + 1, bb[3] - bb[1] + 1).toSize();
+ d->fallbackSize = QSize(qMax(32, sz.width()), qMax(32, sz.height()));
+ d->fallbackTopLeft = QPointF(bb[0], bb[1]);
+
+ if (d->fallbackFbo && d->fallbackFbo->size() != d->fallbackSize) {
+ delete d->fallbackFbo;
+ d->fallbackFbo = nullptr;
+ }
+ if (!d->fallbackFbo)
+ d->fallbackFbo = new QOpenGLFramebufferObject(d->fallbackSize, QOpenGLFramebufferObject::CombinedDepthStencil);
+ if (!d->fallbackFbo->bind())
+ return;
+
+ GLint prevViewport[4];
+ f->glGetIntegerv(GL_VIEWPORT, prevViewport);
+
+ f->glViewport(0, 0, d->fallbackSize.width(), d->fallbackSize.height());
+ f->glDisable(GL_DEPTH_TEST);
+ f->glClearColor(0, 0, 0, 0);
+ f->glClearStencil(0);
+ f->glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ f->glStencilFunc(GL_NOTEQUAL, 0, 0xFF);
+ f->glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+
+ QMatrix4x4 mv;
+ mv.translate(-d->fallbackTopLeft.x(), -d->fallbackTopLeft.y());
+ nvpr.matrixLoadf(GL_PATH_MODELVIEW_NV, mv.constData());
+ QMatrix4x4 proj;
+ proj.ortho(0, d->fallbackSize.width(), d->fallbackSize.height(), 0, 1, -1);
+ nvpr.matrixLoadf(GL_PATH_PROJECTION_NV, proj.constData());
+
+ renderFill(d);
+
+ d->fallbackFbo->release();
+ f->glEnable(GL_DEPTH_TEST);
+ f->glViewport(prevViewport[0], prevViewport[1], prevViewport[2], prevViewport[3]);
+
+ d->fallbackValid = true;
+}
+
+void QQuickShapeNvprRenderNode::setupStencilForCover(bool stencilClip, int sv)
+{
+ if (!stencilClip) {
+ // Assume stencil buffer is cleared to 0 for each frame.
+ // Within the frame dppass=GL_ZERO for glStencilOp ensures stencil is reset and so no need to clear.
+ f->glStencilFunc(GL_NOTEQUAL, 0, 0xFF);
+ f->glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO);
+ } else {
+ f->glStencilFunc(GL_LESS, sv, 0xFF); // pass if (sv & 0xFF) < (stencil_value & 0xFF)
+ f->glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); // dppass: replace with the original value (clip's stencil ref value)
+ }
+}
+
+void QQuickShapeNvprRenderNode::render(const RenderState *state)
+{
+ f = QOpenGLContext::currentContext()->extraFunctions();
+
+ if (!nvprInited) {
+ if (!nvpr.create()) {
+ qWarning("NVPR init failed");
+ return;
+ }
+ mtlmgr.create(&nvpr);
+ nvprInited = true;
+ }
+
+ f->glUseProgram(0);
+ f->glStencilMask(~0);
+ f->glEnable(GL_STENCIL_TEST);
+
+ const bool stencilClip = state->stencilEnabled();
+ // when true, the stencil buffer already has a clip path with a ref value of sv
+ const int sv = state->stencilValue();
+ const bool hasScissor = state->scissorEnabled();
+
+ if (hasScissor) {
+ // scissor rect is already set, just enable scissoring
+ f->glEnable(GL_SCISSOR_TEST);
+ }
+
+ // Depth test against the opaque batches rendered before.
+ f->glEnable(GL_DEPTH_TEST);
+ f->glDepthFunc(GL_LESS);
+ nvpr.pathCoverDepthFunc(GL_LESS);
+ nvpr.pathStencilDepthOffset(-0.05f, -1);
+
+ bool reloadMatrices = true;
+
+ for (ShapePathRenderData &d : m_sp) {
+ updatePath(&d);
+
+ const bool hasFill = d.hasFill();
+ const bool hasStroke = d.hasStroke();
+
+ if (hasFill && stencilClip) {
+ // Fall back to a texture when complex clipping is in use and we have
+ // to fill. Reconciling glStencilFillPath's and the scenegraph's clip
+ // stencil semantics has not succeeded so far...
+ if (hasScissor)
+ f->glDisable(GL_SCISSOR_TEST);
+ renderOffscreenFill(&d);
+ reloadMatrices = true;
+ if (hasScissor)
+ f->glEnable(GL_SCISSOR_TEST);
+ }
+
+ if (reloadMatrices) {
+ reloadMatrices = false;
+ nvpr.matrixLoadf(GL_PATH_MODELVIEW_NV, matrix()->constData());
+ nvpr.matrixLoadf(GL_PATH_PROJECTION_NV, state->projectionMatrix()->constData());
+ }
+
+ // Fill!
+ if (hasFill) {
+ if (!stencilClip) {
+ setupStencilForCover(false, 0);
+ renderFill(&d);
+ } else {
+ if (!m_fallbackBlitter.isCreated())
+ m_fallbackBlitter.create();
+ f->glStencilFunc(GL_EQUAL, sv, 0xFF);
+ f->glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+ QMatrix4x4 mv = *matrix();
+ mv.translate(d.fallbackTopLeft.x(), d.fallbackTopLeft.y());
+ m_fallbackBlitter.texturedQuad(d.fallbackFbo->texture(), d.fallbackFbo->size(),
+ *state->projectionMatrix(), mv,
+ inheritedOpacity());
+ }
+ }
+
+ // Stroke!
+ if (hasStroke) {
+ const int strokeStencilValue = 0x80;
+ const int writeMask = 0x80;
+
+ setupStencilForCover(stencilClip, sv);
+ if (stencilClip) {
+ // for the stencil step (eff. read mask == 0xFF & ~writeMask)
+ nvpr.pathStencilFunc(GL_EQUAL, sv, 0xFF);
+ // With stencilCLip == true the read mask for the stencil test before the stencil step is 0x7F.
+ // This assumes the clip stencil value is <= 127.
+ if (sv >= strokeStencilValue)
+ qWarning("Shape/NVPR: stencil clip ref value %d too large; expect rendering errors", sv);
+ }
+
+ renderStroke(&d, strokeStencilValue, writeMask);
+ }
+
+ if (stencilClip)
+ nvpr.pathStencilFunc(GL_ALWAYS, 0, ~0);
+
+ d.dirty = 0;
+ }
+
+ f->glBindProgramPipeline(0);
+}
+
+QSGRenderNode::StateFlags QQuickShapeNvprRenderNode::changedStates() const
+{
+ return BlendState | StencilState | DepthState | ScissorState;
+}
+
+QSGRenderNode::RenderingFlags QQuickShapeNvprRenderNode::flags() const
+{
+ return DepthAwareRendering; // avoid hitting the less optimal no-opaque-batch path in the renderer
+}
+
+bool QQuickShapeNvprRenderNode::isSupported()
+{
+ static const bool nvprDisabled = qEnvironmentVariableIntValue("QT_NO_NVPR") != 0;
+ return !nvprDisabled && QQuickNvprFunctions::isSupported();
+}
+
+bool QQuickNvprBlitter::create()
+{
+ if (isCreated())
+ destroy();
+
+ m_program = new QOpenGLShaderProgram;
+ if (QOpenGLContext::currentContext()->format().profile() == QSurfaceFormat::CoreProfile) {
+ m_program->addCacheableShaderFromSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/shapes/shaders/blit_core.vert"));
+ m_program->addCacheableShaderFromSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/shapes/shaders/blit_core.frag"));
+ } else {
+ m_program->addCacheableShaderFromSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/shapes/shaders/blit.vert"));
+ m_program->addCacheableShaderFromSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/shapes/shaders/blit.frag"));
+ }
+ m_program->bindAttributeLocation("qt_Vertex", 0);
+ m_program->bindAttributeLocation("qt_MultiTexCoord0", 1);
+ if (!m_program->link())
+ return false;
+
+ m_matrixLoc = m_program->uniformLocation("qt_Matrix");
+ m_opacityLoc = m_program->uniformLocation("qt_Opacity");
+
+ m_buffer = new QOpenGLBuffer;
+ if (!m_buffer->create())
+ return false;
+ m_buffer->bind();
+ m_buffer->allocate(4 * sizeof(GLfloat) * 6);
+ m_buffer->release();
+
+ return true;
+}
+
+void QQuickNvprBlitter::destroy()
+{
+ if (m_program) {
+ delete m_program;
+ m_program = nullptr;
+ }
+ if (m_buffer) {
+ delete m_buffer;
+ m_buffer = nullptr;
+ }
+}
+
+void QQuickNvprBlitter::texturedQuad(GLuint textureId, const QSize &size,
+ const QMatrix4x4 &proj, const QMatrix4x4 &modelview,
+ float opacity)
+{
+ QOpenGLExtraFunctions *f = QOpenGLContext::currentContext()->extraFunctions();
+
+ m_program->bind();
+
+ QMatrix4x4 m = proj * modelview;
+ m_program->setUniformValue(m_matrixLoc, m);
+ m_program->setUniformValue(m_opacityLoc, opacity);
+
+ m_buffer->bind();
+
+ if (size != m_prevSize) {
+ m_prevSize = size;
+
+ QPointF p0(size.width() - 1, size.height() - 1);
+ QPointF p1(0, 0);
+ QPointF p2(0, size.height() - 1);
+ QPointF p3(size.width() - 1, 0);
+
+ GLfloat vertices[6 * 4] = {
+ GLfloat(p0.x()), GLfloat(p0.y()), 1, 0,
+ GLfloat(p1.x()), GLfloat(p1.y()), 0, 1,
+ GLfloat(p2.x()), GLfloat(p2.y()), 0, 0,
+
+ GLfloat(p0.x()), GLfloat(p0.y()), 1, 0,
+ GLfloat(p3.x()), GLfloat(p3.y()), 1, 1,
+ GLfloat(p1.x()), GLfloat(p1.y()), 0, 1,
+ };
+
+ m_buffer->write(0, vertices, sizeof(vertices));
+ }
+
+ m_program->enableAttributeArray(0);
+ m_program->enableAttributeArray(1);
+ f->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);
+ f->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (const void *) (2 * sizeof(GLfloat)));
+
+ f->glBindTexture(GL_TEXTURE_2D, textureId);
+
+ f->glDrawArrays(GL_TRIANGLES, 0, 6);
+
+ f->glBindTexture(GL_TEXTURE_2D, 0);
+ m_buffer->release();
+ m_program->release();
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/shapes/qquickshapenvprrenderer_p.h b/src/imports/shapes/qquickshapenvprrenderer_p.h
new file mode 100644
index 0000000000..f6c9fc169e
--- /dev/null
+++ b/src/imports/shapes/qquickshapenvprrenderer_p.h
@@ -0,0 +1,237 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKSHAPENVPRRENDERER_P_H
+#define QQUICKSHAPENVPRRENDERER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of a number of Qt sources files. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qquickshape_p_p.h"
+#include "qquicknvprfunctions_p.h"
+#include <qsgrendernode.h>
+#include <QColor>
+#include <QVector4D>
+#include <QDebug>
+
+#if QT_CONFIG(opengl)
+
+QT_BEGIN_NAMESPACE
+
+class QQuickShapeNvprRenderNode;
+class QOpenGLFramebufferObject;
+class QOpenGLBuffer;
+class QOpenGLExtraFunctions;
+
+class QQuickShapeNvprRenderer : public QQuickAbstractPathRenderer
+{
+public:
+ enum Dirty {
+ DirtyPath = 0x01,
+ DirtyStyle = 0x02,
+ DirtyFillRule = 0x04,
+ DirtyDash = 0x08,
+ DirtyFillGradient = 0x10,
+ DirtyList = 0x20
+ };
+
+ void beginSync(int totalCount) override;
+ void setPath(int index, const QQuickPath *path) override;
+ void setStrokeColor(int index, const QColor &color) override;
+ void setStrokeWidth(int index, qreal w) override;
+ void setFillColor(int index, const QColor &color) override;
+ void setFillRule(int index, QQuickShapePath::FillRule fillRule) override;
+ void setJoinStyle(int index, QQuickShapePath::JoinStyle joinStyle, int miterLimit) override;
+ void setCapStyle(int index, QQuickShapePath::CapStyle capStyle) override;
+ void setStrokeStyle(int index, QQuickShapePath::StrokeStyle strokeStyle,
+ qreal dashOffset, const QVector<qreal> &dashPattern) override;
+ void setFillGradient(int index, QQuickShapeGradient *gradient) override;
+ void endSync(bool async) override;
+
+ void updateNode() override;
+
+ void setNode(QQuickShapeNvprRenderNode *node);
+
+ struct NvprPath {
+ QVector<GLubyte> cmd;
+ QVector<GLfloat> coord;
+ QByteArray str;
+ };
+
+private:
+ struct ShapePathGuiData {
+ int dirty = 0;
+ NvprPath path;
+ qreal strokeWidth;
+ QColor strokeColor;
+ QColor fillColor;
+ QQuickShapePath::JoinStyle joinStyle;
+ int miterLimit;
+ QQuickShapePath::CapStyle capStyle;
+ QQuickShapePath::FillRule fillRule;
+ bool dashActive;
+ qreal dashOffset;
+ QVector<qreal> dashPattern;
+ FillGradientType fillGradientActive;
+ GradientDesc fillGradient;
+ };
+
+ void convertPath(const QQuickPath *path, ShapePathGuiData *d);
+
+ QQuickShapeNvprRenderNode *m_node = nullptr;
+ int m_accDirty = 0;
+
+ QVector<ShapePathGuiData> m_sp;
+};
+
+QDebug operator<<(QDebug debug, const QQuickShapeNvprRenderer::NvprPath &path);
+
+class QQuickNvprMaterialManager
+{
+public:
+ enum Material {
+ MatSolid,
+ MatLinearGradient,
+ MatRadialGradient,
+ MatConicalGradient,
+
+ NMaterials
+ };
+
+ struct MaterialDesc {
+ GLuint ppl = 0;
+ GLuint prg = 0;
+ int uniLoc[8];
+ };
+
+ void create(QQuickNvprFunctions *nvpr);
+ MaterialDesc *activateMaterial(Material m);
+ void releaseResources();
+
+private:
+ QQuickNvprFunctions *m_nvpr = nullptr;
+ MaterialDesc m_materials[NMaterials];
+};
+
+class QQuickNvprBlitter
+{
+public:
+ bool create();
+ void destroy();
+ bool isCreated() const { return m_program != nullptr; }
+ void texturedQuad(GLuint textureId, const QSize &size,
+ const QMatrix4x4 &proj, const QMatrix4x4 &modelview,
+ float opacity);
+
+private:
+ QOpenGLShaderProgram *m_program = nullptr;
+ QOpenGLBuffer *m_buffer = nullptr;
+ int m_matrixLoc = -1;
+ int m_opacityLoc = -1;
+ QSize m_prevSize;
+};
+
+class QQuickShapeNvprRenderNode : public QSGRenderNode
+{
+public:
+ ~QQuickShapeNvprRenderNode();
+
+ void render(const RenderState *state) override;
+ void releaseResources() override;
+ StateFlags changedStates() const override;
+ RenderingFlags flags() const override;
+
+ static bool isSupported();
+
+private:
+ struct ShapePathRenderData {
+ GLuint path = 0;
+ int dirty = 0;
+ QQuickShapeNvprRenderer::NvprPath source;
+ GLfloat strokeWidth;
+ QVector4D strokeColor;
+ QVector4D fillColor;
+ GLenum joinStyle;
+ GLint miterLimit;
+ GLenum capStyle;
+ GLenum fillRule;
+ GLfloat dashOffset;
+ QVector<GLfloat> dashPattern;
+ QQuickAbstractPathRenderer::FillGradientType fillGradientActive;
+ QQuickAbstractPathRenderer::GradientDesc fillGradient;
+ QOpenGLFramebufferObject *fallbackFbo = nullptr;
+ bool fallbackValid = false;
+ QSize fallbackSize;
+ QPointF fallbackTopLeft;
+
+ bool hasFill() const { return !qFuzzyIsNull(fillColor.w()) || fillGradientActive; }
+ bool hasStroke() const { return strokeWidth >= 0.0f && !qFuzzyIsNull(strokeColor.w()); }
+ };
+
+ void updatePath(ShapePathRenderData *d);
+ void renderStroke(ShapePathRenderData *d, int strokeStencilValue, int writeMask);
+ void renderFill(ShapePathRenderData *d);
+ void renderOffscreenFill(ShapePathRenderData *d);
+ void setupStencilForCover(bool stencilClip, int sv);
+
+ static bool nvprInited;
+ static QQuickNvprFunctions nvpr;
+ static QQuickNvprMaterialManager mtlmgr;
+
+ QQuickNvprBlitter m_fallbackBlitter;
+ QOpenGLExtraFunctions *f = nullptr;
+
+ QVector<ShapePathRenderData> m_sp;
+
+ friend class QQuickShapeNvprRenderer;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_CONFIG(opengl)
+
+#endif // QQUICKSHAPENVPRRENDERER_P_H
diff --git a/src/imports/shapes/qquickshapesoftwarerenderer.cpp b/src/imports/shapes/qquickshapesoftwarerenderer.cpp
new file mode 100644
index 0000000000..ed13afbc7e
--- /dev/null
+++ b/src/imports/shapes/qquickshapesoftwarerenderer.cpp
@@ -0,0 +1,282 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickshapesoftwarerenderer_p.h"
+#include <private/qquickpath_p_p.h>
+
+QT_BEGIN_NAMESPACE
+
+void QQuickShapeSoftwareRenderer::beginSync(int totalCount)
+{
+ if (m_sp.count() != totalCount) {
+ m_sp.resize(totalCount);
+ m_accDirty |= DirtyList;
+ }
+}
+
+void QQuickShapeSoftwareRenderer::setPath(int index, const QQuickPath *path)
+{
+ ShapePathGuiData &d(m_sp[index]);
+ d.path = path ? path->path() : QPainterPath();
+ d.dirty |= DirtyPath;
+ m_accDirty |= DirtyPath;
+}
+
+void QQuickShapeSoftwareRenderer::setStrokeColor(int index, const QColor &color)
+{
+ ShapePathGuiData &d(m_sp[index]);
+ d.pen.setColor(color);
+ d.dirty |= DirtyPen;
+ m_accDirty |= DirtyPen;
+}
+
+void QQuickShapeSoftwareRenderer::setStrokeWidth(int index, qreal w)
+{
+ ShapePathGuiData &d(m_sp[index]);
+ d.strokeWidth = w;
+ if (w >= 0.0f)
+ d.pen.setWidthF(w);
+ d.dirty |= DirtyPen;
+ m_accDirty |= DirtyPen;
+}
+
+void QQuickShapeSoftwareRenderer::setFillColor(int index, const QColor &color)
+{
+ ShapePathGuiData &d(m_sp[index]);
+ d.fillColor = color;
+ d.brush.setColor(color);
+ d.dirty |= DirtyBrush;
+ m_accDirty |= DirtyBrush;
+}
+
+void QQuickShapeSoftwareRenderer::setFillRule(int index, QQuickShapePath::FillRule fillRule)
+{
+ ShapePathGuiData &d(m_sp[index]);
+ d.fillRule = Qt::FillRule(fillRule);
+ d.dirty |= DirtyFillRule;
+ m_accDirty |= DirtyFillRule;
+}
+
+void QQuickShapeSoftwareRenderer::setJoinStyle(int index, QQuickShapePath::JoinStyle joinStyle, int miterLimit)
+{
+ ShapePathGuiData &d(m_sp[index]);
+ d.pen.setJoinStyle(Qt::PenJoinStyle(joinStyle));
+ d.pen.setMiterLimit(miterLimit);
+ d.dirty |= DirtyPen;
+ m_accDirty |= DirtyPen;
+}
+
+void QQuickShapeSoftwareRenderer::setCapStyle(int index, QQuickShapePath::CapStyle capStyle)
+{
+ ShapePathGuiData &d(m_sp[index]);
+ d.pen.setCapStyle(Qt::PenCapStyle(capStyle));
+ d.dirty |= DirtyPen;
+ m_accDirty |= DirtyPen;
+}
+
+void QQuickShapeSoftwareRenderer::setStrokeStyle(int index, QQuickShapePath::StrokeStyle strokeStyle,
+ qreal dashOffset, const QVector<qreal> &dashPattern)
+{
+ ShapePathGuiData &d(m_sp[index]);
+ switch (strokeStyle) {
+ case QQuickShapePath::SolidLine:
+ d.pen.setStyle(Qt::SolidLine);
+ break;
+ case QQuickShapePath::DashLine:
+ d.pen.setStyle(Qt::CustomDashLine);
+ d.pen.setDashPattern(dashPattern);
+ d.pen.setDashOffset(dashOffset);
+ break;
+ default:
+ break;
+ }
+ d.dirty |= DirtyPen;
+ m_accDirty |= DirtyPen;
+}
+
+static inline void setupPainterGradient(QGradient *painterGradient, const QQuickShapeGradient &g)
+{
+ painterGradient->setStops(g.gradientStops()); // sorted
+ switch (g.spread()) {
+ case QQuickShapeGradient::PadSpread:
+ painterGradient->setSpread(QGradient::PadSpread);
+ break;
+ case QQuickShapeGradient::RepeatSpread:
+ painterGradient->setSpread(QGradient::RepeatSpread);
+ break;
+ case QQuickShapeGradient::ReflectSpread:
+ painterGradient->setSpread(QGradient::ReflectSpread);
+ break;
+ default:
+ break;
+ }
+}
+
+void QQuickShapeSoftwareRenderer::setFillGradient(int index, QQuickShapeGradient *gradient)
+{
+ ShapePathGuiData &d(m_sp[index]);
+ if (QQuickShapeLinearGradient *g = qobject_cast<QQuickShapeLinearGradient *>(gradient)) {
+ QLinearGradient painterGradient(g->x1(), g->y1(), g->x2(), g->y2());
+ setupPainterGradient(&painterGradient, *g);
+ d.brush = QBrush(painterGradient);
+ } else if (QQuickShapeRadialGradient *g = qobject_cast<QQuickShapeRadialGradient *>(gradient)) {
+ QRadialGradient painterGradient(g->centerX(), g->centerY(), g->centerRadius(),
+ g->focalX(), g->focalY(), g->focalRadius());
+ setupPainterGradient(&painterGradient, *g);
+ d.brush = QBrush(painterGradient);
+ } else if (QQuickShapeConicalGradient *g = qobject_cast<QQuickShapeConicalGradient *>(gradient)) {
+ QConicalGradient painterGradient(g->centerX(), g->centerY(), g->angle());
+ setupPainterGradient(&painterGradient, *g);
+ d.brush = QBrush(painterGradient);
+ } else {
+ d.brush = QBrush(d.fillColor);
+ }
+ d.dirty |= DirtyBrush;
+ m_accDirty |= DirtyBrush;
+}
+
+void QQuickShapeSoftwareRenderer::endSync(bool)
+{
+}
+
+void QQuickShapeSoftwareRenderer::setNode(QQuickShapeSoftwareRenderNode *node)
+{
+ if (m_node != node) {
+ m_node = node;
+ m_accDirty |= DirtyList;
+ }
+}
+
+void QQuickShapeSoftwareRenderer::updateNode()
+{
+ if (!m_accDirty)
+ return;
+
+ const int count = m_sp.count();
+ const bool listChanged = m_accDirty & DirtyList;
+ if (listChanged)
+ m_node->m_sp.resize(count);
+
+ m_node->m_boundingRect = QRectF();
+
+ for (int i = 0; i < count; ++i) {
+ ShapePathGuiData &src(m_sp[i]);
+ QQuickShapeSoftwareRenderNode::ShapePathRenderData &dst(m_node->m_sp[i]);
+
+ if (listChanged || (src.dirty & DirtyPath)) {
+ dst.path = src.path;
+ dst.path.setFillRule(src.fillRule);
+ }
+
+ if (listChanged || (src.dirty & DirtyFillRule))
+ dst.path.setFillRule(src.fillRule);
+
+ if (listChanged || (src.dirty & DirtyPen)) {
+ dst.pen = src.pen;
+ dst.strokeWidth = src.strokeWidth;
+ }
+
+ if (listChanged || (src.dirty & DirtyBrush))
+ dst.brush = src.brush;
+
+ src.dirty = 0;
+
+ QRectF br = dst.path.boundingRect();
+ const float sw = qMax(1.0f, dst.strokeWidth);
+ br.adjust(-sw, -sw, sw, sw);
+ m_node->m_boundingRect |= br;
+ }
+
+ m_node->markDirty(QSGNode::DirtyMaterial);
+ m_accDirty = 0;
+}
+
+QQuickShapeSoftwareRenderNode::QQuickShapeSoftwareRenderNode(QQuickShape *item)
+ : m_item(item)
+{
+}
+
+QQuickShapeSoftwareRenderNode::~QQuickShapeSoftwareRenderNode()
+{
+ releaseResources();
+}
+
+void QQuickShapeSoftwareRenderNode::releaseResources()
+{
+}
+
+void QQuickShapeSoftwareRenderNode::render(const RenderState *state)
+{
+ if (m_sp.isEmpty())
+ return;
+
+ QSGRendererInterface *rif = m_item->window()->rendererInterface();
+ QPainter *p = static_cast<QPainter *>(rif->getResource(m_item->window(), QSGRendererInterface::PainterResource));
+ Q_ASSERT(p);
+
+ const QRegion *clipRegion = state->clipRegion();
+ if (clipRegion && !clipRegion->isEmpty())
+ p->setClipRegion(*clipRegion, Qt::ReplaceClip); // must be done before setTransform
+
+ p->setTransform(matrix()->toTransform());
+ p->setOpacity(inheritedOpacity());
+
+ for (const ShapePathRenderData &d : qAsConst(m_sp)) {
+ p->setPen(d.strokeWidth >= 0.0f && d.pen.color() != Qt::transparent ? d.pen : Qt::NoPen);
+ p->setBrush(d.brush.color() != Qt::transparent ? d.brush : Qt::NoBrush);
+ p->drawPath(d.path);
+ }
+}
+
+QSGRenderNode::StateFlags QQuickShapeSoftwareRenderNode::changedStates() const
+{
+ return 0;
+}
+
+QSGRenderNode::RenderingFlags QQuickShapeSoftwareRenderNode::flags() const
+{
+ return BoundedRectRendering; // avoid fullscreen updates by saying we won't draw outside rect()
+}
+
+QRectF QQuickShapeSoftwareRenderNode::rect() const
+{
+ return m_boundingRect;
+}
+
+QT_END_NAMESPACE
diff --git a/src/imports/shapes/qquickshapesoftwarerenderer_p.h b/src/imports/shapes/qquickshapesoftwarerenderer_p.h
new file mode 100644
index 0000000000..0abc2e37b0
--- /dev/null
+++ b/src/imports/shapes/qquickshapesoftwarerenderer_p.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKSHAPESOFTWARERENDERER_P_H
+#define QQUICKSHAPESOFTWARERENDERER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of a number of Qt sources files. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qquickshape_p_p.h"
+#include <qsgrendernode.h>
+#include <QPen>
+#include <QBrush>
+
+QT_BEGIN_NAMESPACE
+
+class QQuickShapeSoftwareRenderNode;
+
+class QQuickShapeSoftwareRenderer : public QQuickAbstractPathRenderer
+{
+public:
+ enum Dirty {
+ DirtyPath = 0x01,
+ DirtyPen = 0x02,
+ DirtyFillRule = 0x04,
+ DirtyBrush = 0x08,
+ DirtyList = 0x10
+ };
+
+ void beginSync(int totalCount) override;
+ void setPath(int index, const QQuickPath *path) override;
+ void setStrokeColor(int index, const QColor &color) override;
+ void setStrokeWidth(int index, qreal w) override;
+ void setFillColor(int index, const QColor &color) override;
+ void setFillRule(int index, QQuickShapePath::FillRule fillRule) override;
+ void setJoinStyle(int index, QQuickShapePath::JoinStyle joinStyle, int miterLimit) override;
+ void setCapStyle(int index, QQuickShapePath::CapStyle capStyle) override;
+ void setStrokeStyle(int index, QQuickShapePath::StrokeStyle strokeStyle,
+ qreal dashOffset, const QVector<qreal> &dashPattern) override;
+ void setFillGradient(int index, QQuickShapeGradient *gradient) override;
+ void endSync(bool async) override;
+
+ void updateNode() override;
+
+ void setNode(QQuickShapeSoftwareRenderNode *node);
+
+private:
+ QQuickShapeSoftwareRenderNode *m_node = nullptr;
+ int m_accDirty = 0;
+ struct ShapePathGuiData {
+ int dirty = 0;
+ QPainterPath path;
+ QPen pen;
+ float strokeWidth;
+ QColor fillColor;
+ QBrush brush;
+ Qt::FillRule fillRule;
+ };
+ QVector<ShapePathGuiData> m_sp;
+};
+
+class QQuickShapeSoftwareRenderNode : public QSGRenderNode
+{
+public:
+ QQuickShapeSoftwareRenderNode(QQuickShape *item);
+ ~QQuickShapeSoftwareRenderNode();
+
+ void render(const RenderState *state) override;
+ void releaseResources() override;
+ StateFlags changedStates() const override;
+ RenderingFlags flags() const override;
+ QRectF rect() const override;
+
+private:
+ QQuickShape *m_item;
+
+ struct ShapePathRenderData {
+ QPainterPath path;
+ QPen pen;
+ float strokeWidth;
+ QBrush brush;
+ };
+ QVector<ShapePathRenderData> m_sp;
+ QRectF m_boundingRect;
+
+ friend class QQuickShapeSoftwareRenderer;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQUICKSHAPESOFTWARERENDERER_P_H
diff --git a/src/imports/shapes/qtquickshapesplugin.qrc b/src/imports/shapes/qtquickshapesplugin.qrc
new file mode 100644
index 0000000000..f139861693
--- /dev/null
+++ b/src/imports/shapes/qtquickshapesplugin.qrc
@@ -0,0 +1,20 @@
+<RCC>
+ <qresource prefix="/qt-project.org/shapes">
+ <file>shaders/blit.vert</file>
+ <file>shaders/blit.frag</file>
+ <file>shaders/blit_core.frag</file>
+ <file>shaders/blit_core.vert</file>
+ <file>shaders/lineargradient.vert</file>
+ <file>shaders/lineargradient.frag</file>
+ <file>shaders/lineargradient_core.vert</file>
+ <file>shaders/lineargradient_core.frag</file>
+ <file>shaders/radialgradient.vert</file>
+ <file>shaders/radialgradient.frag</file>
+ <file>shaders/radialgradient_core.vert</file>
+ <file>shaders/radialgradient_core.frag</file>
+ <file>shaders/conicalgradient.vert</file>
+ <file>shaders/conicalgradient.frag</file>
+ <file>shaders/conicalgradient_core.vert</file>
+ <file>shaders/conicalgradient_core.frag</file>
+ </qresource>
+</RCC>
diff --git a/src/imports/shapes/shaders/blit.frag b/src/imports/shapes/shaders/blit.frag
new file mode 100644
index 0000000000..505f0db179
--- /dev/null
+++ b/src/imports/shapes/shaders/blit.frag
@@ -0,0 +1,9 @@
+varying highp vec2 qt_TexCoord0;
+
+uniform sampler2D source;
+uniform lowp float qt_Opacity;
+
+void main()
+{
+ gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity;
+}
diff --git a/src/imports/shapes/shaders/blit.vert b/src/imports/shapes/shaders/blit.vert
new file mode 100644
index 0000000000..f8306bd945
--- /dev/null
+++ b/src/imports/shapes/shaders/blit.vert
@@ -0,0 +1,12 @@
+uniform highp mat4 qt_Matrix;
+
+attribute highp vec4 qt_Vertex;
+attribute highp vec2 qt_MultiTexCoord0;
+
+varying highp vec2 qt_TexCoord0;
+
+void main()
+{
+ qt_TexCoord0 = qt_MultiTexCoord0;
+ gl_Position = qt_Matrix * qt_Vertex;
+}
diff --git a/src/imports/shapes/shaders/blit_core.frag b/src/imports/shapes/shaders/blit_core.frag
new file mode 100644
index 0000000000..7073808fba
--- /dev/null
+++ b/src/imports/shapes/shaders/blit_core.frag
@@ -0,0 +1,13 @@
+#version 150 core
+
+in vec2 qt_TexCoord0;
+
+out vec4 fragColor;
+
+uniform sampler2D source;
+uniform float qt_Opacity;
+
+void main()
+{
+ fragColor = texture(source, qt_TexCoord0) * qt_Opacity;
+}
diff --git a/src/imports/shapes/shaders/blit_core.vert b/src/imports/shapes/shaders/blit_core.vert
new file mode 100644
index 0000000000..5246441da3
--- /dev/null
+++ b/src/imports/shapes/shaders/blit_core.vert
@@ -0,0 +1,14 @@
+#version 150 core
+
+in vec4 qt_Vertex;
+in vec2 qt_MultiTexCoord0;
+
+out vec2 qt_TexCoord0;
+
+uniform mat4 qt_Matrix;
+
+void main()
+{
+ qt_TexCoord0 = qt_MultiTexCoord0;
+ gl_Position = qt_Matrix * qt_Vertex;
+}
diff --git a/src/imports/shapes/shaders/conicalgradient.frag b/src/imports/shapes/shaders/conicalgradient.frag
new file mode 100644
index 0000000000..af5fdd5ee0
--- /dev/null
+++ b/src/imports/shapes/shaders/conicalgradient.frag
@@ -0,0 +1,19 @@
+#define INVERSE_2PI 0.1591549430918953358
+
+uniform sampler2D gradTabTexture;
+uniform lowp float opacity;
+
+uniform highp float angle;
+
+varying highp vec2 coord;
+
+void main()
+{
+ highp float t;
+ if (abs(coord.y) == abs(coord.x))
+ t = (atan(-coord.y + 0.002, coord.x) + angle) * INVERSE_2PI;
+ else
+ t = (atan(-coord.y, coord.x) + angle) * INVERSE_2PI;
+ gl_FragColor = texture2D(gradTabTexture, vec2(t - floor(t), 0.5)) * opacity;
+
+}
diff --git a/src/imports/shapes/shaders/conicalgradient.vert b/src/imports/shapes/shaders/conicalgradient.vert
new file mode 100644
index 0000000000..3350b0675a
--- /dev/null
+++ b/src/imports/shapes/shaders/conicalgradient.vert
@@ -0,0 +1,13 @@
+attribute vec4 vertexCoord;
+attribute vec4 vertexColor;
+
+uniform mat4 matrix;
+uniform vec2 translationPoint;
+
+varying vec2 coord;
+
+void main()
+{
+ coord = vertexCoord.xy - translationPoint;
+ gl_Position = matrix * vertexCoord;
+}
diff --git a/src/imports/shapes/shaders/conicalgradient_core.frag b/src/imports/shapes/shaders/conicalgradient_core.frag
new file mode 100644
index 0000000000..e18b80159a
--- /dev/null
+++ b/src/imports/shapes/shaders/conicalgradient_core.frag
@@ -0,0 +1,22 @@
+#version 150 core
+
+#define INVERSE_2PI 0.1591549430918953358
+
+uniform sampler2D gradTabTexture;
+uniform float opacity;
+
+uniform float angle;
+
+in vec2 coord;
+
+out vec4 fragColor;
+
+void main()
+{
+ float t;
+ if (abs(coord.y) == abs(coord.x))
+ t = (atan(-coord.y + 0.002, coord.x) + angle) * INVERSE_2PI;
+ else
+ t = (atan(-coord.y, coord.x) + angle) * INVERSE_2PI;
+ fragColor = texture(gradTabTexture, vec2(t - floor(t), 0.5)) * opacity;
+}
diff --git a/src/imports/shapes/shaders/conicalgradient_core.vert b/src/imports/shapes/shaders/conicalgradient_core.vert
new file mode 100644
index 0000000000..f94a56401b
--- /dev/null
+++ b/src/imports/shapes/shaders/conicalgradient_core.vert
@@ -0,0 +1,15 @@
+#version 150 core
+
+in vec4 vertexCoord;
+in vec4 vertexColor;
+
+uniform mat4 matrix;
+uniform vec2 translationPoint;
+
+out vec2 coord;
+
+void main()
+{
+ coord = vertexCoord.xy - translationPoint;
+ gl_Position = matrix * vertexCoord;
+}
diff --git a/src/imports/shapes/shaders/lineargradient.frag b/src/imports/shapes/shaders/lineargradient.frag
new file mode 100644
index 0000000000..7f4a739109
--- /dev/null
+++ b/src/imports/shapes/shaders/lineargradient.frag
@@ -0,0 +1,9 @@
+uniform sampler2D gradTabTexture;
+uniform highp float opacity;
+
+varying highp float gradTabIndex;
+
+void main()
+{
+ gl_FragColor = texture2D(gradTabTexture, vec2(gradTabIndex, 0.5)) * opacity;
+}
diff --git a/src/imports/shapes/shaders/lineargradient.vert b/src/imports/shapes/shaders/lineargradient.vert
new file mode 100644
index 0000000000..eb21b8886b
--- /dev/null
+++ b/src/imports/shapes/shaders/lineargradient.vert
@@ -0,0 +1,15 @@
+attribute vec4 vertexCoord;
+attribute vec4 vertexColor;
+
+uniform mat4 matrix;
+uniform vec2 gradStart;
+uniform vec2 gradEnd;
+
+varying float gradTabIndex;
+
+void main()
+{
+ vec2 gradVec = gradEnd - gradStart;
+ gradTabIndex = dot(gradVec, vertexCoord.xy - gradStart) / (gradVec.x * gradVec.x + gradVec.y * gradVec.y);
+ gl_Position = matrix * vertexCoord;
+}
diff --git a/src/imports/shapes/shaders/lineargradient_core.frag b/src/imports/shapes/shaders/lineargradient_core.frag
new file mode 100644
index 0000000000..5908acfa67
--- /dev/null
+++ b/src/imports/shapes/shaders/lineargradient_core.frag
@@ -0,0 +1,12 @@
+#version 150 core
+
+uniform sampler2D gradTabTexture;
+uniform float opacity;
+
+in float gradTabIndex;
+out vec4 fragColor;
+
+void main()
+{
+ fragColor = texture(gradTabTexture, vec2(gradTabIndex, 0.5)) * opacity;
+}
diff --git a/src/imports/shapes/shaders/lineargradient_core.vert b/src/imports/shapes/shaders/lineargradient_core.vert
new file mode 100644
index 0000000000..60b56f38e3
--- /dev/null
+++ b/src/imports/shapes/shaders/lineargradient_core.vert
@@ -0,0 +1,17 @@
+#version 150 core
+
+in vec4 vertexCoord;
+in vec4 vertexColor;
+
+uniform mat4 matrix;
+uniform vec2 gradStart;
+uniform vec2 gradEnd;
+
+out float gradTabIndex;
+
+void main()
+{
+ vec2 gradVec = gradEnd - gradStart;
+ gradTabIndex = dot(gradVec, vertexCoord.xy - gradStart) / (gradVec.x * gradVec.x + gradVec.y * gradVec.y);
+ gl_Position = matrix * vertexCoord;
+}
diff --git a/src/imports/shapes/shaders/radialgradient.frag b/src/imports/shapes/shaders/radialgradient.frag
new file mode 100644
index 0000000000..0f503bc0f7
--- /dev/null
+++ b/src/imports/shapes/shaders/radialgradient.frag
@@ -0,0 +1,25 @@
+uniform sampler2D gradTabTexture;
+uniform lowp float opacity;
+
+uniform highp vec2 focalToCenter;
+uniform highp float centerRadius;
+uniform highp float focalRadius;
+
+varying highp vec2 coord;
+
+void main()
+{
+ highp float rd = centerRadius - focalRadius;
+ highp float b = 2.0 * (rd * focalRadius + dot(coord, focalToCenter));
+ highp float fmp2_m_radius2 = -focalToCenter.x * focalToCenter.x - focalToCenter.y * focalToCenter.y + rd * rd;
+ highp float inverse_2_fmp2_m_radius2 = 1.0 / (2.0 * fmp2_m_radius2);
+ highp float det = b * b - 4.0 * fmp2_m_radius2 * ((focalRadius * focalRadius) - dot(coord, coord));
+ lowp vec4 result = vec4(0.0);
+ if (det >= 0.0) {
+ highp float detSqrt = sqrt(det);
+ highp float w = max((-b - detSqrt) * inverse_2_fmp2_m_radius2, (-b + detSqrt) * inverse_2_fmp2_m_radius2);
+ if (focalRadius + w * (centerRadius - focalRadius) >= 0.0)
+ result = texture2D(gradTabTexture, vec2(w, 0.5)) * opacity;
+ }
+ gl_FragColor = result;
+}
diff --git a/src/imports/shapes/shaders/radialgradient.vert b/src/imports/shapes/shaders/radialgradient.vert
new file mode 100644
index 0000000000..3350b0675a
--- /dev/null
+++ b/src/imports/shapes/shaders/radialgradient.vert
@@ -0,0 +1,13 @@
+attribute vec4 vertexCoord;
+attribute vec4 vertexColor;
+
+uniform mat4 matrix;
+uniform vec2 translationPoint;
+
+varying vec2 coord;
+
+void main()
+{
+ coord = vertexCoord.xy - translationPoint;
+ gl_Position = matrix * vertexCoord;
+}
diff --git a/src/imports/shapes/shaders/radialgradient_core.frag b/src/imports/shapes/shaders/radialgradient_core.frag
new file mode 100644
index 0000000000..706ce53e4d
--- /dev/null
+++ b/src/imports/shapes/shaders/radialgradient_core.frag
@@ -0,0 +1,29 @@
+#version 150 core
+
+uniform sampler2D gradTabTexture;
+uniform float opacity;
+
+uniform vec2 focalToCenter;
+uniform float centerRadius;
+uniform float focalRadius;
+
+in vec2 coord;
+
+out vec4 fragColor;
+
+void main()
+{
+ float rd = centerRadius - focalRadius;
+ float b = 2.0 * (rd * focalRadius + dot(coord, focalToCenter));
+ float fmp2_m_radius2 = -focalToCenter.x * focalToCenter.x - focalToCenter.y * focalToCenter.y + rd * rd;
+ float inverse_2_fmp2_m_radius2 = 1.0 / (2.0 * fmp2_m_radius2);
+ float det = b * b - 4.0 * fmp2_m_radius2 * ((focalRadius * focalRadius) - dot(coord, coord));
+ vec4 result = vec4(0.0);
+ if (det >= 0.0) {
+ float detSqrt = sqrt(det);
+ float w = max((-b - detSqrt) * inverse_2_fmp2_m_radius2, (-b + detSqrt) * inverse_2_fmp2_m_radius2);
+ if (focalRadius + w * (centerRadius - focalRadius) >= 0.0)
+ result = texture(gradTabTexture, vec2(w, 0.5)) * opacity;
+ }
+ fragColor = result;
+}
diff --git a/src/imports/shapes/shaders/radialgradient_core.vert b/src/imports/shapes/shaders/radialgradient_core.vert
new file mode 100644
index 0000000000..f94a56401b
--- /dev/null
+++ b/src/imports/shapes/shaders/radialgradient_core.vert
@@ -0,0 +1,15 @@
+#version 150 core
+
+in vec4 vertexCoord;
+in vec4 vertexColor;
+
+uniform mat4 matrix;
+uniform vec2 translationPoint;
+
+out vec2 coord;
+
+void main()
+{
+ coord = vertexCoord.xy - translationPoint;
+ gl_Position = matrix * vertexCoord;
+}
diff --git a/src/imports/shapes/shapes.pro b/src/imports/shapes/shapes.pro
new file mode 100644
index 0000000000..4d6e9508af
--- /dev/null
+++ b/src/imports/shapes/shapes.pro
@@ -0,0 +1,33 @@
+CXX_MODULE = qml
+TARGET = qmlshapesplugin
+TARGETPATH = QtQuick/Shapes
+IMPORT_VERSION = 1.11
+
+QT = core gui-private qml quick-private
+
+HEADERS += \
+ qquickshape_p.h \
+ qquickshape_p_p.h \
+ qquickshapegenericrenderer_p.h \
+ qquickshapesoftwarerenderer_p.h
+
+SOURCES += \
+ plugin.cpp \
+ qquickshape.cpp \
+ qquickshapegenericrenderer.cpp \
+ qquickshapesoftwarerenderer.cpp
+
+qtConfig(opengl) {
+ HEADERS += \
+ qquicknvprfunctions_p.h \
+ qquicknvprfunctions_p_p.h \
+ qquickshapenvprrenderer_p.h
+
+ SOURCES += \
+ qquicknvprfunctions.cpp \
+ qquickshapenvprrenderer.cpp
+}
+
+RESOURCES += qtquickshapesplugin.qrc
+
+load(qml_plugin)
diff --git a/src/imports/sharedimage/plugins.qmltypes b/src/imports/sharedimage/plugins.qmltypes
new file mode 100644
index 0000000000..46fa24df1a
--- /dev/null
+++ b/src/imports/sharedimage/plugins.qmltypes
@@ -0,0 +1,11 @@
+import QtQuick.tooling 1.2
+
+// This file describes the plugin-supplied types contained in the library.
+// It is used for QML tooling purposes only.
+//
+// This file was auto-generated by:
+// 'qmlplugindump -nonrelocatable Qt.labs.sharedimage 1.0'
+
+Module {
+ dependencies: ["QtQuick 2.8"]
+}
diff --git a/src/imports/sharedimage/qsharedimageloader.cpp b/src/imports/sharedimage/qsharedimageloader.cpp
index fb96a79187..ee862b6a77 100644
--- a/src/imports/sharedimage/qsharedimageloader.cpp
+++ b/src/imports/sharedimage/qsharedimageloader.cpp
@@ -117,7 +117,7 @@ void QSharedImageLoaderPrivate::storeImageToMem(void *data, const QImage &img)
h->format = img.format();
uchar *p = static_cast<uchar *>(data) + sizeof(SharedImageHeader);
- memcpy(p, img.constBits(), img.byteCount());
+ memcpy(p, img.constBits(), img.sizeInBytes());
}
@@ -174,8 +174,11 @@ QImage QSharedImageLoaderPrivate::load(const QString &path, QSharedImageLoader::
QImage img = q->loadFile(path, params);
if (img.isNull())
return nil;
- int size = sizeof(SharedImageHeader) + img.byteCount();
- if (shm->create(size)) {
+ size_t size = sizeof(SharedImageHeader) + img.sizeInBytes();
+ if (size > std::numeric_limits<int>::max()) {
+ qCDebug(lcSharedImage) << "Image" << path << "to large to load";
+ return nil;
+ } else if (shm->create(int(size))) {
qCDebug(lcSharedImage) << "Created new shm segment of size" << size << "for image" << path;
if (!shm->lock()) {
qCDebug(lcSharedImage) << "Lock1 failed!?" << shm->errorString();
diff --git a/src/imports/sharedimage/qsharedimageloader_p.h b/src/imports/sharedimage/qsharedimageloader_p.h
index 38e2bd4d54..4b0e989c29 100644
--- a/src/imports/sharedimage/qsharedimageloader_p.h
+++ b/src/imports/sharedimage/qsharedimageloader_p.h
@@ -58,10 +58,10 @@ class QSharedImageLoader : public QObject
public:
typedef QVector<QVariant> ImageParameters;
- QSharedImageLoader(QObject *parent = Q_NULLPTR);
+ QSharedImageLoader(QObject *parent = nullptr);
~QSharedImageLoader();
- QImage load(const QString &path, ImageParameters *params = Q_NULLPTR);
+ QImage load(const QString &path, ImageParameters *params = nullptr);
protected:
virtual QImage loadFile(const QString &path, ImageParameters *params);
diff --git a/src/imports/sharedimage/sharedimageprovider.cpp b/src/imports/sharedimage/sharedimageprovider.cpp
index f33057936d..aad6ea3b78 100644
--- a/src/imports/sharedimage/sharedimageprovider.cpp
+++ b/src/imports/sharedimage/sharedimageprovider.cpp
@@ -60,7 +60,7 @@ public:
NumImageParameters
};
- QuickSharedImageLoader(QObject *parent = Q_NULLPTR)
+ QuickSharedImageLoader(QObject *parent = nullptr)
: QSharedImageLoader(parent)
{
}
diff --git a/src/imports/statemachine/plugin.cpp b/src/imports/statemachine/plugin.cpp
index ae32f6446a..7308df8964 100644
--- a/src/imports/statemachine/plugin.cpp
+++ b/src/imports/statemachine/plugin.cpp
@@ -63,7 +63,7 @@ class QtQmlStateMachinePlugin : public QQmlExtensionPlugin
public:
QtQmlStateMachinePlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); }
- void registerTypes(const char *uri) Q_DECL_OVERRIDE
+ void registerTypes(const char *uri) override
{
qmlRegisterType<State>(uri, 1, 0, "State");
qmlRegisterType<StateMachine>(uri, 1, 0, "StateMachine");
diff --git a/src/imports/statemachine/signaltransition.cpp b/src/imports/statemachine/signaltransition.cpp
index 0f88ec641b..3c3142cce8 100644
--- a/src/imports/statemachine/signaltransition.cpp
+++ b/src/imports/statemachine/signaltransition.cpp
@@ -54,7 +54,7 @@
#include <private/qqmlboundsignal_p.h>
SignalTransition::SignalTransition(QState *parent)
- : QSignalTransition(this, SIGNAL(invokeYourself()), parent), m_complete(false), m_signalExpression(Q_NULLPTR)
+ : QSignalTransition(this, SIGNAL(invokeYourself()), parent), m_complete(false), m_signalExpression(nullptr)
{
connect(this, SIGNAL(signalChanged()), SIGNAL(qmlSignalChanged()));
}
@@ -109,7 +109,7 @@ void SignalTransition::setSignal(const QJSValue &signal)
m_signal = signal;
- QV4::ExecutionEngine *jsEngine = QV8Engine::getV4(QQmlEngine::contextForObject(this)->engine());
+ QV4::ExecutionEngine *jsEngine = QQmlEngine::contextForObject(this)->engine()->handle();
QV4::Scope scope(jsEngine);
QObject *sender;
@@ -169,7 +169,7 @@ void SignalTransition::connectTriggered()
const QV4::CompiledData::Binding *binding = m_bindings.at(0);
Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_Script);
- QV4::ExecutionEngine *jsEngine = QV8Engine::getV4(QQmlEngine::contextForObject(this)->engine());
+ QV4::ExecutionEngine *jsEngine = QQmlEngine::contextForObject(this)->engine()->handle();
QV4::Scope scope(jsEngine);
QV4::Scoped<QV4::QObjectMethod> qobjectSignal(scope, QJSValuePrivate::convertedToValue(jsEngine, m_signal));
Q_ASSERT(qobjectSignal);
diff --git a/src/imports/statemachine/signaltransition.h b/src/imports/statemachine/signaltransition.h
index c6512e2b19..d7a3b7b618 100644
--- a/src/imports/statemachine/signaltransition.h
+++ b/src/imports/statemachine/signaltransition.h
@@ -59,13 +59,13 @@ class SignalTransition : public QSignalTransition, public QQmlParserStatus
Q_PROPERTY(QQmlScriptString guard READ guard WRITE setGuard NOTIFY guardChanged)
public:
- explicit SignalTransition(QState *parent = Q_NULLPTR);
+ explicit SignalTransition(QState *parent = nullptr);
QQmlScriptString guard() const;
void setGuard(const QQmlScriptString &guard);
- bool eventTest(QEvent *event) Q_DECL_OVERRIDE;
- void onTransition(QEvent *event) Q_DECL_OVERRIDE;
+ bool eventTest(QEvent *event) override;
+ void onTransition(QEvent *event) override;
const QJSValue &signal();
void setSignal(const QJSValue &signal);
@@ -81,8 +81,8 @@ Q_SIGNALS:
void qmlSignalChanged();
private:
- void classBegin() Q_DECL_OVERRIDE { m_complete = false; }
- void componentComplete() Q_DECL_OVERRIDE { m_complete = true; connectTriggered(); }
+ void classBegin() override { m_complete = false; }
+ void componentComplete() override { m_complete = true; connectTriggered(); }
void connectTriggered();
friend class SignalTransitionParser;
@@ -97,8 +97,8 @@ private:
class SignalTransitionParser : public QQmlCustomParser
{
public:
- void verifyBindings(const QV4::CompiledData::Unit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &props) Q_DECL_OVERRIDE;
- void applyBindings(QObject *object, QV4::CompiledData::CompilationUnit *compilationUnit, const QList<const QV4::CompiledData::Binding *> &bindings) Q_DECL_OVERRIDE;
+ void verifyBindings(const QV4::CompiledData::Unit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &props) override;
+ void applyBindings(QObject *object, QV4::CompiledData::CompilationUnit *compilationUnit, const QList<const QV4::CompiledData::Binding *> &bindings) override;
};
QT_END_NAMESPACE
diff --git a/src/imports/statemachine/timeouttransition.h b/src/imports/statemachine/timeouttransition.h
index 0e5f5377e3..2fc850fc70 100644
--- a/src/imports/statemachine/timeouttransition.h
+++ b/src/imports/statemachine/timeouttransition.h
@@ -53,7 +53,7 @@ class TimeoutTransition : public QSignalTransition, public QQmlParserStatus
Q_INTERFACES(QQmlParserStatus)
public:
- TimeoutTransition(QState *parent = Q_NULLPTR);
+ TimeoutTransition(QState *parent = nullptr);
~TimeoutTransition();
int timeout() const;
diff --git a/src/imports/testlib/SignalSpy.qml b/src/imports/testlib/SignalSpy.qml
index 8a8e844a21..85908091a0 100644
--- a/src/imports/testlib/SignalSpy.qml
+++ b/src/imports/testlib/SignalSpy.qml
@@ -74,7 +74,7 @@ import QtTest 1.1
synchronously. For asynchronous signals, the wait() method can be
used to block the test until the signal occurs (or a timeout expires).
- \sa {QtTest::TestCase}{TestCase}, {Qt Quick Test Reference Documentation}
+ \sa {QtTest::TestCase}{TestCase}, {Qt Quick Test}
*/
Item {
diff --git a/src/imports/testlib/TestCase.qml b/src/imports/testlib/TestCase.qml
index 3fc3c0860a..8e9b016444 100644
--- a/src/imports/testlib/TestCase.qml
+++ b/src/imports/testlib/TestCase.qml
@@ -38,7 +38,8 @@
****************************************************************************/
import QtQuick 2.0
-import QtTest 1.1
+import QtQuick.Window 2.0 // used for qtest_verifyItem
+import QtTest 1.2
import "testlogger.js" as TestLogger
import Qt.test.qtestroot 1.0
@@ -56,7 +57,7 @@ import Qt.test.qtestroot 1.0
\code
import QtQuick 2.0
- import QtTest 1.0
+ import QtTest 1.2
TestCase {
name: "MathTests"
@@ -107,7 +108,7 @@ import Qt.test.qtestroot 1.0
\code
import QtQuick 2.0
- import QtTest 1.1
+ import QtTest 1.2
TestCase {
name: "DataTests"
@@ -259,7 +260,7 @@ import Qt.test.qtestroot 1.0
For objects that are created via the \l {Component::}{createObject()} function
of \l Component, the \l createTemporaryObject() function can be used.
- \sa {QtTest::SignalSpy}{SignalSpy}, {Qt Quick Test Reference Documentation}
+ \sa {QtTest::SignalSpy}{SignalSpy}, {Qt Quick Test}
*/
@@ -443,6 +444,9 @@ Item {
or \c{QVERIFY2(condition, message)} in C++.
*/
function verify(cond, msg) {
+ if (arguments.length > 2)
+ qtest_fail("More than two arguments given to verify(). Did you mean tryVerify() or tryCompare()?", 1)
+
if (msg === undefined)
msg = "";
if (!qtest_results.verify(cond, msg, util.callerFile(), util.callerLine()))
@@ -837,7 +841,14 @@ Item {
Returns a snapshot image object of the given \a item.
- The returned image object has the following methods:
+ The returned image object has the following properties:
+ \list
+ \li width Returns the width of the underlying image (since 5.10)
+ \li height Returns the height of the underlying image (since 5.10)
+ \li size Returns the size of the underlying image (since 5.10)
+ \endlist
+
+ Additionally, the returned image object has the following methods:
\list
\li red(x, y) Returns the red channel value of the pixel at \a x, \a y position
\li green(x, y) Returns the green channel value of the pixel at \a x, \a y position
@@ -858,6 +869,21 @@ Item {
var newImage = grabImage(rect);
verify(!newImage.equals(image));
\endcode
+ \li save(path) Saves the image to the given \a path. If the image cannot
+ be saved, an exception will be thrown. (since 5.10)
+
+ This can be useful to perform postmortem analysis on failing tests, for
+ example:
+
+ \code
+ var image = grabImage(rect);
+ try {
+ compare(image.width, 100);
+ } catch (ex) {
+ image.save("debug.png");
+ throw ex;
+ }
+ \endcode
\endlist
@@ -1089,8 +1115,8 @@ Item {
function waitForRendering(item, timeout) {
if (timeout === undefined)
timeout = 5000
- if (!item)
- qtest_fail("No item given to waitForRendering", 1)
+ if (!qtest_verifyItem(item, "waitForRendering"))
+ return
return qtest_results.waitForRendering(item, timeout)
}
@@ -1186,6 +1212,26 @@ Item {
}
/*!
+ \since 5.10
+ \qmlmethod TestCase::keySequence(keySequence)
+
+ Simulates typing of \a keySequence. The key sequence can be set
+ to one of the \l{QKeySequence::StandardKey}{standard keyboard shortcuts}, or
+ it can be described with a string containing a sequence of up to four key
+ presses.
+
+ Each event shall be sent to the TestCase window or, in case of multiple windows,
+ to the current active window. See \l QGuiApplication::focusWindow() for more details.
+
+ \sa keyPress(), keyRelease(), {GNU Emacs Style Key Sequences},
+ {QtQuick::Shortcut::sequence}{Shortcut.sequence}
+ */
+ function keySequence(keySequence) {
+ if (!qtest_events.keySequence(keySequence))
+ qtest_fail("window not shown", 2)
+ }
+
+ /*!
\qmlmethod TestCase::mousePress(item, x = item.width / 2, y = item.height / 2, button = Qt.LeftButton, modifiers = Qt.NoModifier, delay = -1)
Simulates pressing a mouse \a button with an optional \a modifier
@@ -1202,8 +1248,8 @@ Item {
\sa mouseRelease(), mouseClick(), mouseDoubleClick(), mouseDoubleClickSequence(), mouseMove(), mouseDrag(), mouseWheel()
*/
function mousePress(item, x, y, button, modifiers, delay) {
- if (!item)
- qtest_fail("No item given to mousePress", 1)
+ if (!qtest_verifyItem(item, "mousePress"))
+ return
if (button === undefined)
button = Qt.LeftButton
@@ -1236,8 +1282,8 @@ Item {
\sa mousePress(), mouseClick(), mouseDoubleClick(), mouseDoubleClickSequence(), mouseMove(), mouseDrag(), mouseWheel()
*/
function mouseRelease(item, x, y, button, modifiers, delay) {
- if (!item)
- qtest_fail("No item given to mouseRelease", 1)
+ if (!qtest_verifyItem(item, "mouseRelease"))
+ return
if (button === undefined)
button = Qt.LeftButton
@@ -1272,8 +1318,8 @@ Item {
\sa mousePress(), mouseClick(), mouseDoubleClick(), mouseDoubleClickSequence(), mouseMove(), mouseRelease(), mouseWheel()
*/
function mouseDrag(item, x, y, dx, dy, button, modifiers, delay) {
- if (!item)
- qtest_fail("No item given to mouseDrag", 1)
+ if (!qtest_verifyItem(item, "mouseDrag"))
+ return
if (item.x === undefined || item.y === undefined)
return
@@ -1323,8 +1369,8 @@ Item {
\sa mousePress(), mouseRelease(), mouseDoubleClick(), mouseDoubleClickSequence(), mouseMove(), mouseDrag(), mouseWheel()
*/
function mouseClick(item, x, y, button, modifiers, delay) {
- if (!item)
- qtest_fail("No item given to mouseClick", 1)
+ if (!qtest_verifyItem(item, "mouseClick"))
+ return
if (button === undefined)
button = Qt.LeftButton
@@ -1357,8 +1403,8 @@ Item {
\sa mouseDoubleClickSequence(), mousePress(), mouseRelease(), mouseClick(), mouseMove(), mouseDrag(), mouseWheel()
*/
function mouseDoubleClick(item, x, y, button, modifiers, delay) {
- if (!item)
- qtest_fail("No item given to mouseDoubleClick", 1)
+ if (!qtest_verifyItem(item, "mouseDoubleClick"))
+ return
if (button === undefined)
button = Qt.LeftButton
@@ -1398,8 +1444,8 @@ Item {
\sa mouseDoubleClick(), mousePress(), mouseRelease(), mouseClick(), mouseMove(), mouseDrag(), mouseWheel()
*/
function mouseDoubleClickSequence(item, x, y, button, modifiers, delay) {
- if (!item)
- qtest_fail("No item given to mouseDoubleClickSequence", 1)
+ if (!qtest_verifyItem(item, "mouseDoubleClickSequence"))
+ return
if (button === undefined)
button = Qt.LeftButton
@@ -1430,8 +1476,8 @@ Item {
\sa mousePress(), mouseRelease(), mouseClick(), mouseDoubleClick(), mouseDoubleClickSequence(), mouseDrag(), mouseWheel()
*/
function mouseMove(item, x, y, delay, buttons) {
- if (!item)
- qtest_fail("No item given to mouseMove", 1)
+ if (!qtest_verifyItem(item, "mouseMove"))
+ return
if (delay == undefined)
delay = -1
@@ -1458,8 +1504,8 @@ Item {
\sa mousePress(), mouseClick(), mouseDoubleClick(), mouseDoubleClickSequence(), mouseMove(), mouseRelease(), mouseDrag(), QWheelEvent::angleDelta()
*/
function mouseWheel(item, x, y, xDelta, yDelta, buttons, modifiers, delay) {
- if (!item)
- qtest_fail("No item given to mouseWheel", 1)
+ if (!qtest_verifyItem(item, "mouseWheel"))
+ return
if (delay == undefined)
delay = -1
@@ -1519,8 +1565,8 @@ Item {
*/
function touchEvent(item) {
- if (!item)
- qtest_fail("No item given to touchEvent", 1)
+ if (!qtest_verifyItem(item, "touchEvent"))
+ return
return {
_defaultItem: item,
@@ -1629,6 +1675,23 @@ Item {
function cleanup() {}
/*! \internal */
+ function qtest_verifyItem(item, method) {
+ try {
+ if (!(item instanceof Item) &&
+ !(item instanceof Window)) {
+ // it's a QObject, but not a type
+ qtest_fail("TypeError: %1 requires an Item or Window type".arg(method), 2);
+ return false;
+ }
+ } catch (e) { // it's not a QObject
+ qtest_fail("TypeError: %1 requires an Item or Window type".arg(method), 3);
+ return false;
+ }
+
+ return true;
+ }
+
+ /*! \internal */
function qtest_runInternal(prop, arg) {
try {
qtest_testCaseResult = testCase[prop](arg)
@@ -1696,11 +1759,6 @@ Item {
/*! \internal */
function qtest_run() {
- if (util.printAvailableFunctions) {
- completed = true
- return
- }
-
if (TestLogger.log_start_test()) {
qtest_results.reset()
qtest_results.testCaseName = name
@@ -1851,29 +1909,9 @@ Item {
}
}
-
Component.onCompleted: {
QTestRootObject.hasTestCase = true;
qtest_componentCompleted = true;
-
- if (util.printAvailableFunctions) {
- var testList = []
- for (var prop in testCase) {
- if (prop.indexOf("test_") != 0 && prop.indexOf("benchmark_") != 0)
- continue
- var tail = prop.lastIndexOf("_data");
- if (tail != -1 && tail == (prop.length - 5))
- continue
- // Note: cannot run functions in TestCase elements
- // that lack a name.
- if (name.length > 0)
- testList.push(name + "::" + prop + "()")
- }
- testList.sort()
- for (var index in testList)
- console.log(testList[index])
- return
- }
qtest_testId = TestLogger.log_register_test(name)
if (optional)
TestLogger.log_optional_test(qtest_testId)
diff --git a/src/imports/testlib/main.cpp b/src/imports/testlib/main.cpp
index fc013d5afc..ab84d83ff7 100644
--- a/src/imports/testlib/main.cpp
+++ b/src/imports/testlib/main.cpp
@@ -103,7 +103,7 @@ public Q_SLOTS:
}
QQmlEngine *engine = qmlEngine(this);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine->handle());
+ QV4::ExecutionEngine *v4 = engine->handle();
QV4::Scope scope(v4);
QV4::ScopedValue s(scope, v4->newString(name));
return QQmlV4Handle(s);
@@ -116,7 +116,7 @@ public Q_SLOTS:
QQmlV4Handle callerFile(int frameIndex = 0) const
{
QQmlEngine *engine = qmlEngine(this);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine->handle());
+ QV4::ExecutionEngine *v4 = engine->handle();
QV4::Scope scope(v4);
QVector<QV4::StackFrame> stack = v4->stackTrace(frameIndex + 2);
@@ -129,7 +129,7 @@ public Q_SLOTS:
int callerLine(int frameIndex = 0) const
{
QQmlEngine *engine = qmlEngine(this);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine->handle());
+ QV4::ExecutionEngine *v4 = engine->handle();
QVector<QV4::StackFrame> stack = v4->stackTrace(frameIndex + 2);
if (stack.size() > frameIndex + 1)
@@ -151,12 +151,13 @@ class QTestQmlModule : public QQmlExtensionPlugin
public:
QTestQmlModule(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); }
- void registerTypes(const char *uri) Q_DECL_OVERRIDE
+ void registerTypes(const char *uri) override
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("QtTest"));
qmlRegisterType<QuickTestResult, 0>(uri,1,0,"TestResult");
qmlRegisterType<QuickTestResult, 1>(uri,1,1,"TestResult");
qmlRegisterType<QuickTestEvent>(uri,1,0,"TestEvent");
+ qmlRegisterType<QuickTestEvent>(uri,1,2,"TestEvent");
qmlRegisterType<QuickTestUtil>(uri,1,0,"TestUtil");
qmlRegisterType<QQuickTouchEventSequence>();
}
diff --git a/src/imports/testlib/plugins.qmltypes b/src/imports/testlib/plugins.qmltypes
index 5d7ca51adc..7f3140d86b 100644
--- a/src/imports/testlib/plugins.qmltypes
+++ b/src/imports/testlib/plugins.qmltypes
@@ -7,7 +7,7 @@ import QtQuick.tooling 1.2
// 'qmlplugindump -nonrelocatable -noforceqtquick QtTest 1.2'
Module {
- dependencies: ["QtQuick 2.0"]
+ dependencies: ["QtQuick 2.0", "QtQuick.Window 2.0"]
Component {
name: "QQuickTouchEventSequence"
prototype: "QObject"
@@ -45,8 +45,8 @@ Module {
Component {
name: "QuickTestEvent"
prototype: "QObject"
- exports: ["QtTest/TestEvent 1.0"]
- exportMetaObjectRevisions: [0]
+ exports: ["QtTest/TestEvent 1.0", "QtTest/TestEvent 1.2"]
+ exportMetaObjectRevisions: [0, 0]
Property { name: "defaultMouseDelay"; type: "int"; isReadonly: true }
Method {
name: "keyPress"
@@ -91,6 +91,12 @@ Module {
Parameter { name: "delay"; type: "int" }
}
Method {
+ name: "keySequence"
+ revision: 2
+ type: "bool"
+ Parameter { name: "keySequence"; type: "QVariant" }
+ }
+ Method {
name: "mousePress"
type: "bool"
Parameter { name: "item"; type: "QObject"; isPointer: true }
diff --git a/src/imports/window/plugin.cpp b/src/imports/window/plugin.cpp
index 200f6f7b08..c4ea9a1d04 100644
--- a/src/imports/window/plugin.cpp
+++ b/src/imports/window/plugin.cpp
@@ -73,7 +73,7 @@ class QtQuick2WindowPlugin : public QQmlExtensionPlugin
Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
public:
QtQuick2WindowPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); }
- void registerTypes(const char *uri) Q_DECL_OVERRIDE
+ void registerTypes(const char *uri) override
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.Window"));
Q_UNUSED(uri);
diff --git a/src/imports/window/plugins.qmltypes b/src/imports/window/plugins.qmltypes
index cea2a910a7..4ae23a093e 100644
--- a/src/imports/window/plugins.qmltypes
+++ b/src/imports/window/plugins.qmltypes
@@ -4,7 +4,7 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable QtQuick.Window 2.3'
+// 'qmlplugindump -nonrelocatable QtQuick.Window 2.10'
Module {
dependencies: ["QtQuick 2.8"]
@@ -43,10 +43,16 @@ Module {
Component {
name: "QQuickScreenInfo"
prototype: "QObject"
- exports: ["QtQuick.Window/ScreenInfo 2.3"]
+ exports: [
+ "QtQuick.Window/ScreenInfo 2.10",
+ "QtQuick.Window/ScreenInfo 2.3"
+ ]
isCreatable: false
- exportMetaObjectRevisions: [2]
+ exportMetaObjectRevisions: [10, 2]
Property { name: "name"; type: "string"; isReadonly: true }
+ Property { name: "manufacturer"; revision: 10; type: "string"; isReadonly: true }
+ Property { name: "model"; revision: 10; type: "string"; isReadonly: true }
+ Property { name: "serialNumber"; revision: 10; type: "string"; isReadonly: true }
Property { name: "width"; type: "int"; isReadonly: true }
Property { name: "height"; type: "int"; isReadonly: true }
Property { name: "desktopAvailableWidth"; type: "int"; isReadonly: true }
@@ -58,6 +64,9 @@ Module {
Property { name: "orientation"; type: "Qt::ScreenOrientation"; isReadonly: true }
Property { name: "virtualX"; revision: 1; type: "int"; isReadonly: true }
Property { name: "virtualY"; revision: 1; type: "int"; isReadonly: true }
+ Signal { name: "manufacturerChanged"; revision: 10 }
+ Signal { name: "modelChanged"; revision: 10 }
+ Signal { name: "serialNumberChanged"; revision: 10 }
Signal { name: "desktopGeometryChanged" }
Signal { name: "virtualXChanged"; revision: 1 }
Signal { name: "virtualYChanged"; revision: 1 }
@@ -74,6 +83,13 @@ Module {
"ContextNotAvailable": 1
}
}
+ Enum {
+ name: "TextRenderType"
+ values: {
+ "QtTextRendering": 0,
+ "NativeTextRendering": 1
+ }
+ }
Property { name: "data"; type: "QObject"; isList: true; isReadonly: true }
Property { name: "color"; type: "QColor" }
Property { name: "contentItem"; type: "QQuickItem"; isReadonly: true; isPointer: true }
@@ -296,6 +312,17 @@ Module {
Parameter { name: "arg"; type: "int" }
}
Method {
+ name: "setGeometry"
+ Parameter { name: "posx"; type: "int" }
+ Parameter { name: "posy"; type: "int" }
+ Parameter { name: "w"; type: "int" }
+ Parameter { name: "h"; type: "int" }
+ }
+ Method {
+ name: "setGeometry"
+ Parameter { name: "rect"; type: "QRect" }
+ }
+ Method {
name: "setMinimumWidth"
Parameter { name: "w"; type: "int" }
}
diff --git a/src/imports/xmllistmodel/plugin.cpp b/src/imports/xmllistmodel/plugin.cpp
index af7625c96a..dc6a02918b 100644
--- a/src/imports/xmllistmodel/plugin.cpp
+++ b/src/imports/xmllistmodel/plugin.cpp
@@ -58,7 +58,7 @@ class QmlXmlListModelPlugin : public QQmlExtensionPlugin
public:
QmlXmlListModelPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); }
- void registerTypes(const char *uri) Q_DECL_OVERRIDE
+ void registerTypes(const char *uri) override
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.XmlListModel"));
qmlRegisterType<QQuickXmlListModel>(uri,2,0,"XmlListModel");
diff --git a/src/imports/xmllistmodel/qqmlxmllistmodel.cpp b/src/imports/xmllistmodel/qqmlxmllistmodel.cpp
index fc9f73a881..d14810a01b 100644
--- a/src/imports/xmllistmodel/qqmlxmllistmodel.cpp
+++ b/src/imports/xmllistmodel/qqmlxmllistmodel.cpp
@@ -923,8 +923,7 @@ QQmlV4Handle QQuickXmlListModel::get(int index) const
return QQmlV4Handle(Encode::undefined());
QQmlEngine *engine = qmlContext(this)->engine();
- QV8Engine *v8engine = QQmlEnginePrivate::getV8Engine(engine);
- ExecutionEngine *v4engine = QV8Engine::getV4(v8engine);
+ ExecutionEngine *v4engine = engine->handle();
Scope scope(v4engine);
Scoped<Object> o(scope, v4engine->newObject());
ScopedString name(scope);
@@ -1152,8 +1151,6 @@ void QQuickXmlListModel::queryCompleted(const QQuickXmlQueryResult &result)
int origCount = d->size;
bool sizeChanged = result.size != d->size;
- d->size = result.size;
- d->data = result.data;
d->keyRoleResultsCache = result.keyRoleResultsCache;
if (d->src.isEmpty() && d->xml.isEmpty())
d->status = Null;
@@ -1174,6 +1171,8 @@ void QQuickXmlListModel::queryCompleted(const QQuickXmlQueryResult &result)
beginRemoveRows(QModelIndex(), 0, origCount - 1);
endRemoveRows();
}
+ d->size = result.size;
+ d->data = result.data;
if (d->size > 0) {
beginInsertRows(QModelIndex(), 0, d->size - 1);
endInsertRows();
@@ -1187,6 +1186,8 @@ void QQuickXmlListModel::queryCompleted(const QQuickXmlQueryResult &result)
endRemoveRows();
}
}
+ d->size = result.size;
+ d->data = result.data;
for (int i=0; i<result.inserted.count(); i++) {
const int index = result.inserted[i].first;
const int count = result.inserted[i].second;
diff --git a/src/particles/qquickangledirection.cpp b/src/particles/qquickangledirection.cpp
index debf52e49b..34afd9ce84 100644
--- a/src/particles/qquickangledirection.cpp
+++ b/src/particles/qquickangledirection.cpp
@@ -38,7 +38,7 @@
****************************************************************************/
#include "qquickangledirection_p.h"
-#include <stdlib.h>
+#include <QRandomGenerator>
#include <qmath.h>
QT_BEGIN_NAMESPACE
@@ -108,8 +108,8 @@ QPointF QQuickAngleDirection::sample(const QPointF &from)
{
Q_UNUSED(from);
QPointF ret;
- qreal theta = m_angle*CONV - m_angleVariation*CONV + rand()/float(RAND_MAX) * m_angleVariation*CONV * 2;
- qreal mag = m_magnitude- m_magnitudeVariation + rand()/float(RAND_MAX) * m_magnitudeVariation * 2;
+ qreal theta = m_angle*CONV - m_angleVariation*CONV + QRandomGenerator::global()->generateDouble() * m_angleVariation*CONV * 2;
+ qreal mag = m_magnitude- m_magnitudeVariation + QRandomGenerator::global()->generateDouble() * m_magnitudeVariation * 2;
ret.setX(mag * qCos(theta));
ret.setY(mag * qSin(theta));
return ret;
diff --git a/src/particles/qquickcustomaffector.cpp b/src/particles/qquickcustomaffector.cpp
index e152c436db..53557e1d0b 100644
--- a/src/particles/qquickcustomaffector.cpp
+++ b/src/particles/qquickcustomaffector.cpp
@@ -148,7 +148,7 @@ void QQuickCustomAffector::affectSystem(qreal dt)
dt = 1.0;
QQmlEngine *qmlEngine = ::qmlEngine(this);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(qmlEngine->handle());
+ QV4::ExecutionEngine *v4 = qmlEngine->handle();
QV4::Scope scope(v4);
QV4::ScopedArrayObject array(scope, v4->newArrayObject(toAffect.size()));
diff --git a/src/particles/qquickcustomparticle.cpp b/src/particles/qquickcustomparticle.cpp
index a9645461a5..e344fea1fa 100644
--- a/src/particles/qquickcustomparticle.cpp
+++ b/src/particles/qquickcustomparticle.cpp
@@ -38,10 +38,10 @@
****************************************************************************/
#include "qquickcustomparticle_p.h"
+#include <QtCore/qrandom.h>
#include <QtQuick/private/qquickshadereffectmesh_p.h>
#include <QtQuick/private/qsgshadersourcebuilder_p.h>
#include <QtQml/qqmlinfo.h>
-#include <cstdlib>
QT_BEGIN_NAMESPACE
@@ -425,7 +425,7 @@ void QQuickCustomParticle::buildData(QQuickOpenGLShaderEffectNode *rootNode)
void QQuickCustomParticle::initialize(int gIdx, int pIdx)
{
QQuickParticleData* datum = m_system->groupData[gIdx]->data[pIdx];
- datum->r = rand()/(qreal)RAND_MAX;
+ datum->r = QRandomGenerator::global()->generateDouble();
}
void QQuickCustomParticle::commit(int gIdx, int pIdx)
diff --git a/src/particles/qquickellipseextruder.cpp b/src/particles/qquickellipseextruder.cpp
index bd3a95d684..52fccd6da9 100644
--- a/src/particles/qquickellipseextruder.cpp
+++ b/src/particles/qquickellipseextruder.cpp
@@ -39,7 +39,7 @@
#include "qquickellipseextruder_p.h"
#include <qmath.h>
-#include <stdlib.h>
+#include <qrandom.h>
QT_BEGIN_NAMESPACE
/*!
@@ -68,8 +68,8 @@ QQuickEllipseExtruder::QQuickEllipseExtruder(QObject *parent) :
QPointF QQuickEllipseExtruder::extrude(const QRectF & r)
{
- qreal theta = ((qreal)rand()/RAND_MAX) * 6.2831853071795862;
- qreal mag = m_fill ? ((qreal)rand()/RAND_MAX) : 1;
+ qreal theta = QRandomGenerator::global()->bounded(2 * M_PI);
+ qreal mag = m_fill ? QRandomGenerator::global()->generateDouble() : 1;
return QPointF(r.x() + r.width()/2 + mag * (r.width()/2) * qCos(theta),
r.y() + r.height()/2 + mag * (r.height()/2) * qSin(theta));
}
diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp
index d817e24866..37bf323f42 100644
--- a/src/particles/qquickimageparticle.cpp
+++ b/src/particles/qquickimageparticle.cpp
@@ -44,6 +44,7 @@
#include <QtQuick/qsgtexturematerial.h>
#include <QtQuick/qsgtexture.h>
#include <QFile>
+#include <QRandomGenerator>
#include "qquickimageparticle_p.h"
#include "qquickparticleemitter_p.h"
#include <private/qquicksprite_p.h>
@@ -118,15 +119,15 @@ public:
Q_ASSERT(!m_fragment_code.isNull());
}
- const char *vertexShader() const { return m_vertex_code.constData(); }
- const char *fragmentShader() const { return m_fragment_code.constData(); }
+ const char *vertexShader() const override { return m_vertex_code.constData(); }
+ const char *fragmentShader() const override { return m_fragment_code.constData(); }
- QList<QByteArray> attributes() const {
+ QList<QByteArray> attributes() const override {
return QList<QByteArray>() << "vPosTex" << "vData" << "vVec"
<< "vColor" << "vDeformVec" << "vRotation";
};
- void initialize() {
+ void initialize() override {
QSGSimpleMaterialShader<TabledMaterialData>::initialize();
program()->bind();
program()->setUniformValue("_qt_texture", 0);
@@ -138,7 +139,7 @@ public:
m_opacitytable_id = program()->uniformLocation("opacitytable");
}
- void updateState(const TabledMaterialData* d, const TabledMaterialData*) {
+ void updateState(const TabledMaterialData* d, const TabledMaterialData*) override {
glFuncs->glActiveTexture(GL_TEXTURE1);
d->colorTable->bind();
@@ -192,15 +193,15 @@ public:
Q_ASSERT(!m_fragment_code.isNull());
}
- const char *vertexShader() const { return m_vertex_code.constData(); }
- const char *fragmentShader() const { return m_fragment_code.constData(); }
+ const char *vertexShader() const override { return m_vertex_code.constData(); }
+ const char *fragmentShader() const override { return m_fragment_code.constData(); }
- QList<QByteArray> attributes() const {
+ QList<QByteArray> attributes() const override {
return QList<QByteArray>() << "vPosTex" << "vData" << "vVec"
<< "vColor" << "vDeformVec" << "vRotation";
};
- void initialize() {
+ void initialize() override {
QSGSimpleMaterialShader<DeformableMaterialData>::initialize();
program()->bind();
program()->setUniformValue("_qt_texture", 0);
@@ -209,7 +210,7 @@ public:
m_entry_id = program()->uniformLocation("entry");
}
- void updateState(const DeformableMaterialData* d, const DeformableMaterialData*) {
+ void updateState(const DeformableMaterialData* d, const DeformableMaterialData*) override {
d->texture->bind();
program()->setUniformValue(m_timestamp_id, (float) d->timestamp);
@@ -259,15 +260,15 @@ public:
Q_ASSERT(!m_fragment_code.isNull());
}
- const char *vertexShader() const { return m_vertex_code.constData(); }
- const char *fragmentShader() const { return m_fragment_code.constData(); }
+ const char *vertexShader() const override { return m_vertex_code.constData(); }
+ const char *fragmentShader() const override { return m_fragment_code.constData(); }
- QList<QByteArray> attributes() const {
+ QList<QByteArray> attributes() const override {
return QList<QByteArray>() << "vPosTex" << "vData" << "vVec"
<< "vColor" << "vDeformVec" << "vRotation" << "vAnimData" << "vAnimPos";
}
- void initialize() {
+ void initialize() override {
QSGSimpleMaterialShader<SpriteMaterialData>::initialize();
program()->bind();
program()->setUniformValue("_qt_texture", 0);
@@ -280,7 +281,7 @@ public:
m_opacitytable_id = program()->uniformLocation("opacitytable");
}
- void updateState(const SpriteMaterialData* d, const SpriteMaterialData*) {
+ void updateState(const SpriteMaterialData* d, const SpriteMaterialData*) override {
glFuncs->glActiveTexture(GL_TEXTURE1);
d->colorTable->bind();
@@ -333,10 +334,10 @@ public:
Q_ASSERT(!m_fragment_code.isNull());
}
- const char *vertexShader() const { return m_vertex_code.constData(); }
- const char *fragmentShader() const { return m_fragment_code.constData(); }
+ const char *vertexShader() const override { return m_vertex_code.constData(); }
+ const char *fragmentShader() const override { return m_fragment_code.constData(); }
- void activate() {
+ void activate() override {
QSGSimpleMaterialShader<ColoredMaterialData>::activate();
#if !defined(QT_OPENGL_ES_2) && !defined(Q_OS_WIN)
glEnable(GL_POINT_SPRITE);
@@ -344,7 +345,7 @@ public:
#endif
}
- void deactivate() {
+ void deactivate() override {
QSGSimpleMaterialShader<ColoredMaterialData>::deactivate();
#if !defined(QT_OPENGL_ES_2) && !defined(Q_OS_WIN)
glDisable(GL_POINT_SPRITE);
@@ -352,11 +353,11 @@ public:
#endif
}
- QList<QByteArray> attributes() const {
+ QList<QByteArray> attributes() const override {
return QList<QByteArray>() << "vPos" << "vData" << "vVec" << "vColor";
}
- void initialize() {
+ void initialize() override {
QSGSimpleMaterialShader<ColoredMaterialData>::initialize();
program()->bind();
program()->setUniformValue("_qt_texture", 0);
@@ -365,7 +366,7 @@ public:
m_entry_id = program()->uniformLocation("entry");
}
- void updateState(const ColoredMaterialData* d, const ColoredMaterialData*) {
+ void updateState(const ColoredMaterialData* d, const ColoredMaterialData*) override {
d->texture->bind();
program()->setUniformValue(m_timestamp_id, (float) d->timestamp);
@@ -407,10 +408,10 @@ public:
Q_ASSERT(!m_fragment_code.isNull());
}
- const char *vertexShader() const { return m_vertex_code.constData(); }
- const char *fragmentShader() const { return m_fragment_code.constData(); }
+ const char *vertexShader() const override { return m_vertex_code.constData(); }
+ const char *fragmentShader() const override { return m_fragment_code.constData(); }
- void activate() {
+ void activate() override {
QSGSimpleMaterialShader<SimpleMaterialData>::activate();
#if !defined(QT_OPENGL_ES_2) && !defined(Q_OS_WIN)
glEnable(GL_POINT_SPRITE);
@@ -418,7 +419,7 @@ public:
#endif
}
- void deactivate() {
+ void deactivate() override {
QSGSimpleMaterialShader<SimpleMaterialData>::deactivate();
#if !defined(QT_OPENGL_ES_2) && !defined(Q_OS_WIN)
glDisable(GL_POINT_SPRITE);
@@ -426,11 +427,11 @@ public:
#endif
}
- QList<QByteArray> attributes() const {
+ QList<QByteArray> attributes() const override {
return QList<QByteArray>() << "vPos" << "vData" << "vVec";
}
- void initialize() {
+ void initialize() override {
QSGSimpleMaterialShader<SimpleMaterialData>::initialize();
program()->bind();
program()->setUniformValue("_qt_texture", 0);
@@ -439,7 +440,7 @@ public:
m_entry_id = program()->uniformLocation("entry");
}
- void updateState(const SimpleMaterialData* d, const SimpleMaterialData*) {
+ void updateState(const SimpleMaterialData* d, const SimpleMaterialData*) override {
d->texture->bind();
program()->setUniformValue(m_timestamp_id, (float) d->timestamp);
@@ -1729,9 +1730,9 @@ void QQuickImageParticle::initialize(int gIdx, int pIdx)
if (!datum->rotationOwner)
datum->rotationOwner = this;
rotation =
- (m_rotation + (m_rotationVariation - 2*((qreal)rand()/RAND_MAX)*m_rotationVariation) ) * CONV;
+ (m_rotation + (m_rotationVariation - 2*QRandomGenerator::global()->bounded(m_rotationVariation)) ) * CONV;
rotationVelocity =
- (m_rotationVelocity + (m_rotationVelocityVariation - 2*((qreal)rand()/RAND_MAX)*m_rotationVelocityVariation) ) * CONV;
+ (m_rotationVelocity + (m_rotationVelocityVariation - 2*QRandomGenerator::global()->bounded(m_rotationVelocityVariation)) ) * CONV;
autoRotate = m_autoRotation?1.0:0.0;
if (datum->rotationOwner == this) {
datum->rotation = rotation;
@@ -1750,10 +1751,10 @@ void QQuickImageParticle::initialize(int gIdx, int pIdx)
if (m_explicitColor) {
if (!datum->colorOwner)
datum->colorOwner = this;
- color.r = m_color.red() * (1 - redVariation) + rand() % 256 * redVariation;
- color.g = m_color.green() * (1 - greenVariation) + rand() % 256 * greenVariation;
- color.b = m_color.blue() * (1 - blueVariation) + rand() % 256 * blueVariation;
- color.a = m_alpha * m_color.alpha() * (1 - m_alphaVariation) + rand() % 256 * m_alphaVariation;
+ color.r = m_color.red() * (1 - redVariation) + QRandomGenerator::global()->bounded(256) * redVariation;
+ color.g = m_color.green() * (1 - greenVariation) + QRandomGenerator::global()->bounded(256) * greenVariation;
+ color.b = m_color.blue() * (1 - blueVariation) + QRandomGenerator::global()->bounded(256) * blueVariation;
+ color.a = m_alpha * m_color.alpha() * (1 - m_alphaVariation) + QRandomGenerator::global()->bounded(256) * m_alphaVariation;
if (datum->colorOwner == this)
datum->color = color;
else
diff --git a/src/particles/qquicklineextruder.cpp b/src/particles/qquicklineextruder.cpp
index 4bcd63543c..670e656b8e 100644
--- a/src/particles/qquicklineextruder.cpp
+++ b/src/particles/qquicklineextruder.cpp
@@ -37,7 +37,7 @@
**
****************************************************************************/
#include "qquicklineextruder_p.h"
-#include <stdlib.h>
+#include <QRandomGenerator>
#include <cmath>
/*!
@@ -69,10 +69,10 @@ QPointF QQuickLineExtruder::extrude(const QRectF &r)
{
qreal x,y;
if (!r.height()){
- x = r.width() * ((qreal)rand())/RAND_MAX;
+ x = r.width() * QRandomGenerator::global()->generateDouble();
y = 0;
}else{
- y = r.height() * ((qreal)rand())/RAND_MAX;
+ y = r.height() * QRandomGenerator::global()->generateDouble();
if (!r.width()){
x = 0;
}else{
diff --git a/src/particles/qquickmaskextruder.cpp b/src/particles/qquickmaskextruder.cpp
index 93eaaf1a6f..6ab6dcc6a4 100644
--- a/src/particles/qquickmaskextruder.cpp
+++ b/src/particles/qquickmaskextruder.cpp
@@ -42,6 +42,7 @@
#include <QtQml/qqmlinfo.h>
#include <QImage>
#include <QDebug>
+#include <QRandomGenerator>
QT_BEGIN_NAMESPACE
/*!
\qmltype MaskShape
@@ -102,7 +103,7 @@ QPointF QQuickMaskExtruder::extrude(const QRectF &r)
ensureInitialized(r);
if (!m_mask.count() || m_img.isNull())
return r.topLeft();
- const QPointF p = m_mask[rand() % m_mask.count()];
+ const QPointF p = m_mask[QRandomGenerator::global()->bounded(m_mask.count())];
//### Should random sub-pixel positioning be added?
return p + r.topLeft();
}
diff --git a/src/particles/qquickparticleemitter.cpp b/src/particles/qquickparticleemitter.cpp
index 9bed25dba6..d17c8fc2ba 100644
--- a/src/particles/qquickparticleemitter.cpp
+++ b/src/particles/qquickparticleemitter.cpp
@@ -40,6 +40,7 @@
#include "qquickparticleemitter_p.h"
#include <private/qqmlengine_p.h>
#include <private/qqmlglobal_p.h>
+#include <QRandomGenerator>
QT_BEGIN_NAMESPACE
@@ -424,7 +425,7 @@ void QQuickParticleEmitter::emitWindow(int timeStamp)
datum->t = pt;
datum->lifeSpan =
(m_particleDuration
- + ((rand() % ((m_particleDurationVariation*2) + 1)) - m_particleDurationVariation))
+ + (QRandomGenerator::global()->bounded((m_particleDurationVariation*2) + 1) - m_particleDurationVariation))
/ 1000.0;
if (datum->lifeSpan >= m_system->maxLife){
@@ -461,7 +462,7 @@ void QQuickParticleEmitter::emitWindow(int timeStamp)
// Particle size
float sizeVariation = -m_particleSizeVariation
- + rand() / float(RAND_MAX) * m_particleSizeVariation * 2;
+ + QRandomGenerator::global()->bounded(m_particleSizeVariation * 2);
float size = qMax((qreal)0.0 , m_particleSize + sizeVariation);
float endSize = qMax((qreal)0.0 , sizeAtEnd + sizeVariation);
@@ -485,7 +486,7 @@ void QQuickParticleEmitter::emitWindow(int timeStamp)
if (isEmitConnected()) {
QQmlEngine *qmlEngine = ::qmlEngine(this);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(qmlEngine->handle());
+ QV4::ExecutionEngine *v4 = qmlEngine->handle();
QV4::Scope scope(v4);
//Done after emitParticle so that the Painter::load is done first, this allows you to customize its static variables
diff --git a/src/particles/qquickparticleextruder.cpp b/src/particles/qquickparticleextruder.cpp
index f1fef58884..816ff34960 100644
--- a/src/particles/qquickparticleextruder.cpp
+++ b/src/particles/qquickparticleextruder.cpp
@@ -38,7 +38,7 @@
****************************************************************************/
#include "qquickparticleextruder_p.h"
-#include <stdlib.h>
+#include <QRandomGenerator>
QT_BEGIN_NAMESPACE
@@ -59,8 +59,8 @@ QQuickParticleExtruder::QQuickParticleExtruder(QObject *parent) :
QPointF QQuickParticleExtruder::extrude(const QRectF &rect)
{
- return QPointF(((qreal)rand() / RAND_MAX) * rect.width() + rect.x(),
- ((qreal)rand() / RAND_MAX) * rect.height() + rect.y());
+ return QPointF(QRandomGenerator::global()->generateDouble() * rect.width() + rect.x(),
+ QRandomGenerator::global()->generateDouble() * rect.height() + rect.y());
}
bool QQuickParticleExtruder::contains(const QRectF &bounds, const QPointF &point)
diff --git a/src/particles/qquickparticlesystem.cpp b/src/particles/qquickparticlesystem.cpp
index cc7d9edbc8..5e613c484a 100644
--- a/src/particles/qquickparticlesystem.cpp
+++ b/src/particles/qquickparticlesystem.cpp
@@ -526,7 +526,7 @@ void QQuickParticleData::clone(const QQuickParticleData& other)
QQmlV4Handle QQuickParticleData::v4Value(QQuickParticleSystem* particleSystem)
{
if (!v8Datum)
- v8Datum = new QQuickV4ParticleData(QQmlEnginePrivate::getV8Engine(qmlEngine(particleSystem)), this, particleSystem);
+ v8Datum = new QQuickV4ParticleData(qmlEngine(particleSystem)->handle(), this, particleSystem);
return v8Datum->v4Value();
}
diff --git a/src/particles/qquickpointdirection.cpp b/src/particles/qquickpointdirection.cpp
index 8d602204b5..f22eea2a76 100644
--- a/src/particles/qquickpointdirection.cpp
+++ b/src/particles/qquickpointdirection.cpp
@@ -38,7 +38,7 @@
****************************************************************************/
#include "qquickpointdirection_p.h"
-#include <stdlib.h>
+#include <QRandomGenerator>
QT_BEGIN_NAMESPACE
@@ -78,8 +78,8 @@ QQuickPointDirection::QQuickPointDirection(QObject *parent) :
QPointF QQuickPointDirection::sample(const QPointF &)
{
QPointF ret;
- ret.setX(m_x - m_xVariation + rand() / float(RAND_MAX) * m_xVariation * 2);
- ret.setY(m_y - m_yVariation + rand() / float(RAND_MAX) * m_yVariation * 2);
+ ret.setX(m_x - m_xVariation + QRandomGenerator::global()->generateDouble() * m_xVariation * 2);
+ ret.setY(m_y - m_yVariation + QRandomGenerator::global()->generateDouble() * m_yVariation * 2);
return ret;
}
diff --git a/src/particles/qquickrectangleextruder.cpp b/src/particles/qquickrectangleextruder.cpp
index cb166f1d50..36e4871d29 100644
--- a/src/particles/qquickrectangleextruder.cpp
+++ b/src/particles/qquickrectangleextruder.cpp
@@ -38,7 +38,7 @@
****************************************************************************/
#include "qquickrectangleextruder_p.h"
-#include <stdlib.h>
+#include <QRandomGenerator>
QT_BEGIN_NAMESPACE
@@ -60,21 +60,21 @@ QQuickRectangleExtruder::QQuickRectangleExtruder(QObject *parent) :
QPointF QQuickRectangleExtruder::extrude(const QRectF &rect)
{
if (m_fill)
- return QPointF(((qreal)rand() / RAND_MAX) * rect.width() + rect.x(),
- ((qreal)rand() / RAND_MAX) * rect.height() + rect.y());
- int side = rand() % 4;
+ return QPointF(QRandomGenerator::global()->generateDouble() * rect.width() + rect.x(),
+ QRandomGenerator::global()->generateDouble() * rect.height() + rect.y());
+ int side = QRandomGenerator::global()->bounded(4);
switch (side){//TODO: Doesn't this overlap the corners?
case 0:
return QPointF(rect.x(),
- ((qreal)rand() / RAND_MAX) * rect.height() + rect.y());
+ QRandomGenerator::global()->generateDouble() * rect.height() + rect.y());
case 1:
return QPointF(rect.width() + rect.x(),
- ((qreal)rand() / RAND_MAX) * rect.height() + rect.y());
+ QRandomGenerator::global()->generateDouble() * rect.height() + rect.y());
case 2:
- return QPointF(((qreal)rand() / RAND_MAX) * rect.width() + rect.x(),
+ return QPointF(QRandomGenerator::global()->generateDouble() * rect.width() + rect.x(),
rect.y());
default:
- return QPointF(((qreal)rand() / RAND_MAX) * rect.width() + rect.x(),
+ return QPointF(QRandomGenerator::global()->generateDouble() * rect.width() + rect.x(),
rect.height() + rect.y());
}
}
diff --git a/src/particles/qquicktargetdirection.cpp b/src/particles/qquicktargetdirection.cpp
index ee805b4e39..a113b7c04a 100644
--- a/src/particles/qquicktargetdirection.cpp
+++ b/src/particles/qquicktargetdirection.cpp
@@ -41,6 +41,7 @@
#include "qquickparticleemitter_p.h"
#include <cmath>
#include <QDebug>
+#include <QRandomGenerator>
QT_BEGIN_NAMESPACE
/*!
@@ -117,10 +118,10 @@ QPointF QQuickTargetDirection::sample(const QPointF &from)
targetX = m_targetX;
targetY = m_targetY;
}
- targetX += 0 - from.x() - m_targetVariation + rand()/(float)RAND_MAX * m_targetVariation*2;
- targetY += 0 - from.y() - m_targetVariation + rand()/(float)RAND_MAX * m_targetVariation*2;
+ targetX += 0 - from.x() - m_targetVariation + QRandomGenerator::global()->generateDouble() * m_targetVariation*2;
+ targetY += 0 - from.y() - m_targetVariation + QRandomGenerator::global()->generateDouble() * m_targetVariation*2;
qreal theta = std::atan2(targetY, targetX);
- qreal mag = m_magnitude + rand()/(float)RAND_MAX * m_magnitudeVariation * 2 - m_magnitudeVariation;
+ qreal mag = m_magnitude + QRandomGenerator::global()->generateDouble() * m_magnitudeVariation * 2 - m_magnitudeVariation;
if (m_proportionalMagnitude)
mag *= std::sqrt(targetX * targetX + targetY * targetY);
ret.setX(mag * std::cos(theta));
diff --git a/src/particles/qquicktrailemitter.cpp b/src/particles/qquicktrailemitter.cpp
index a5bf0e9d21..16b87f0e51 100644
--- a/src/particles/qquicktrailemitter.cpp
+++ b/src/particles/qquicktrailemitter.cpp
@@ -40,6 +40,7 @@
#include "qquicktrailemitter_p.h"
#include <private/qqmlengine_p.h>
#include <private/qqmlglobal_p.h>
+#include <QRandomGenerator>
#include <cmath>
QT_BEGIN_NAMESPACE
@@ -207,7 +208,7 @@ void QQuickTrailEmitter::emitWindow(int timeStamp)
datum->t = pt;
datum->lifeSpan =
(m_particleDuration
- + ((rand() % ((m_particleDurationVariation*2) + 1)) - m_particleDurationVariation))
+ + (QRandomGenerator::global()->bounded((m_particleDurationVariation*2) + 1) - m_particleDurationVariation))
/ 1000.0;
// Particle position
@@ -240,7 +241,7 @@ void QQuickTrailEmitter::emitWindow(int timeStamp)
// Particle size
float sizeVariation = -m_particleSizeVariation
- + rand() / float(RAND_MAX) * m_particleSizeVariation * 2;
+ + QRandomGenerator::global()->generateDouble() * m_particleSizeVariation * 2;
float size = qMax((qreal)0.0, m_particleSize + sizeVariation);
float endSize = qMax((qreal)0.0, sizeAtEnd + sizeVariation);
@@ -266,7 +267,7 @@ void QQuickTrailEmitter::emitWindow(int timeStamp)
if (isEmitConnected() || isEmitFollowConnected()) {
QQmlEngine *qmlEngine = ::qmlEngine(this);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(qmlEngine->handle());
+ QV4::ExecutionEngine *v4 = qmlEngine->handle();
QV4::Scope scope(v4);
QV4::ScopedArrayObject array(scope, v4->newArrayObject(toEmit.size()));
diff --git a/src/particles/qquickv4particledata.cpp b/src/particles/qquickv4particledata.cpp
index e8376f1c27..fb674e1b64 100644
--- a/src/particles/qquickv4particledata.cpp
+++ b/src/particles/qquickv4particledata.cpp
@@ -267,22 +267,25 @@ QT_BEGIN_NAMESPACE
The currentSize of the particle, interpolating between startSize and endSize based on the currentTime.
*/
-
+namespace QV4 {
+namespace Heap {
+struct QV4ParticleData : QV4::Object::Data {
+ void init(QQuickParticleData *datum, QQuickParticleSystem* particleSystem)
+ {
+ Object::init();
+ this->datum = datum;
+ this->particleSystem = particleSystem;
+ }
+ QQuickParticleData* datum;//TODO: Guard needed?
+ QQuickParticleSystem* particleSystem;
+};
+}
+}
//### Particle data handles are not locked to within certain scopes like QQuickContext2D, but there's no way to reload either...
struct QV4ParticleData : public QV4::Object
{
- struct Data : QV4::Object::Data {
- void init(QQuickParticleData *datum, QQuickParticleSystem* particleSystem)
- {
- Object::init();
- this->datum = datum;
- this->particleSystem = particleSystem;
- }
- QQuickParticleData* datum;//TODO: Guard needed?
- QQuickParticleSystem* particleSystem;
- };
- V4_OBJECT(QV4::Object)
+ V4_OBJECT2(QV4ParticleData, QV4::Object)
};
DEFINE_OBJECT_VTABLE(QV4ParticleData);
@@ -296,9 +299,10 @@ public:
QV4::PersistentValue proto;
};
-static void particleData_discard(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+static QV4::ReturnedValue particleData_discard(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QV4ParticleData> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QV4ParticleData> r(scope, *thisObject);
if (!r || !r->d()->datum)
RETURN_RESULT(scope.engine->throwError(QStringLiteral("Not a valid ParticleData object")));
@@ -307,9 +311,10 @@ static void particleData_discard(const QV4::BuiltinFunction *, QV4::Scope &scope
RETURN_RESULT(QV4::Encode::undefined());
}
-static void particleData_lifeLeft(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+static QV4::ReturnedValue particleData_lifeLeft(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QV4ParticleData> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QV4ParticleData> r(scope, *thisObject);
if (!r || !r->d()->datum)
RETURN_RESULT(scope.engine->throwError(QStringLiteral("Not a valid ParticleData object")));
@@ -317,90 +322,99 @@ static void particleData_lifeLeft(const QV4::BuiltinFunction *, QV4::Scope &scop
RETURN_RESULT(QV4::Encode(r->d()->datum->lifeLeft(r->d()->particleSystem)));
}
-static void particleData_curSize(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+static QV4::ReturnedValue particleData_curSize(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QV4ParticleData> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QV4ParticleData> r(scope, *thisObject);
if (!r || !r->d()->datum)
RETURN_RESULT(scope.engine->throwError(QStringLiteral("Not a valid ParticleData object")));
RETURN_RESULT(QV4::Encode(r->d()->datum->curSize(r->d()->particleSystem)));
}
-#define COLOR_GETTER_AND_SETTER(VAR, NAME) static void particleData_get_ ## NAME (const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) \
+#define COLOR_GETTER_AND_SETTER(VAR, NAME) static QV4::ReturnedValue particleData_get_ ## NAME (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) \
{ \
- QV4::Scoped<QV4ParticleData> r(scope, callData->thisObject); \
+ QV4::Scope scope(b); \
+ QV4::Scoped<QV4ParticleData> r(scope, *thisObject); \
if (!r || !r->d()->datum) \
RETURN_RESULT(scope.engine->throwError(QStringLiteral("Not a valid ParticleData object"))); \
\
RETURN_RESULT(QV4::Encode((r->d()->datum->color. VAR )/255.0));\
}\
\
-static void particleData_set_ ## NAME (const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)\
+static QV4::ReturnedValue particleData_set_ ## NAME (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)\
{\
- QV4::Scoped<QV4ParticleData> r(scope, callData->thisObject); \
+ QV4::Scope scope(b); \
+ QV4::Scoped<QV4ParticleData> r(scope, *thisObject); \
if (!r || !r->d()->datum)\
RETURN_RESULT(scope.engine->throwError(QStringLiteral("Not a valid ParticleData object")));\
\
- double d = callData->argc ? callData->args[0].toNumber() : 0; \
+ double d = argc ? argv[0].toNumber() : 0; \
r->d()->datum->color. VAR = qMin(255, qMax(0, (int)::floor(d * 255.0)));\
RETURN_UNDEFINED(); \
}
-#define SEMIBOOL_GETTER_AND_SETTER(VARIABLE) static void particleData_get_ ## VARIABLE (const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) \
+#define SEMIBOOL_GETTER_AND_SETTER(VARIABLE) static QV4::ReturnedValue particleData_get_ ## VARIABLE (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) \
{ \
- QV4::Scoped<QV4ParticleData> r(scope, callData->thisObject); \
+ QV4::Scope scope(b); \
+ QV4::Scoped<QV4ParticleData> r(scope, *thisObject); \
if (!r || !r->d()->datum) \
RETURN_RESULT(scope.engine->throwError(QStringLiteral("Not a valid ParticleData object"))); \
\
RETURN_RESULT(QV4::Encode(r->d()->datum-> VARIABLE));\
}\
\
-static void particleData_set_ ## VARIABLE (const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)\
+static QV4::ReturnedValue particleData_set_ ## VARIABLE (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)\
{\
- QV4::Scoped<QV4ParticleData> r(scope, callData->thisObject); \
+ QV4::Scope scope(b); \
+ QV4::Scoped<QV4ParticleData> r(scope, *thisObject); \
if (!r || !r->d()->datum)\
RETURN_RESULT(scope.engine->throwError(QStringLiteral("Not a valid ParticleData object")));\
\
- r->d()->datum-> VARIABLE = (callData->argc && callData->args[0].toBoolean()) ? 1.0 : 0.0;\
+ r->d()->datum-> VARIABLE = (argc && argv[0].toBoolean()) ? 1.0 : 0.0;\
RETURN_UNDEFINED(); \
}
-#define FLOAT_GETTER_AND_SETTER(VARIABLE) static void particleData_get_ ## VARIABLE (const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) \
+#define FLOAT_GETTER_AND_SETTER(VARIABLE) static QV4::ReturnedValue particleData_get_ ## VARIABLE (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) \
{ \
- QV4::Scoped<QV4ParticleData> r(scope, callData->thisObject); \
+ QV4::Scope scope(b); \
+ QV4::Scoped<QV4ParticleData> r(scope, *thisObject); \
if (!r || !r->d()->datum) \
RETURN_RESULT(scope.engine->throwError(QStringLiteral("Not a valid ParticleData object"))); \
\
RETURN_RESULT(QV4::Encode(r->d()->datum-> VARIABLE));\
}\
\
-static void particleData_set_ ## VARIABLE (const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)\
+static QV4::ReturnedValue particleData_set_ ## VARIABLE (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)\
{\
- QV4::Scoped<QV4ParticleData> r(scope, callData->thisObject); \
+ QV4::Scope scope(b); \
+ QV4::Scoped<QV4ParticleData> r(scope, *thisObject); \
if (!r || !r->d()->datum)\
RETURN_RESULT(scope.engine->throwError(QStringLiteral("Not a valid ParticleData object")));\
\
- r->d()->datum-> VARIABLE = callData->argc ? callData->args[0].toNumber() : qt_qnan();\
+ r->d()->datum-> VARIABLE = argc ? argv[0].toNumber() : qt_qnan();\
RETURN_UNDEFINED(); \
}
-#define FAKE_FLOAT_GETTER_AND_SETTER(VARIABLE, GETTER, SETTER) static void particleData_get_ ## VARIABLE (const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) \
+#define FAKE_FLOAT_GETTER_AND_SETTER(VARIABLE, GETTER, SETTER) static QV4::ReturnedValue particleData_get_ ## VARIABLE (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) \
{ \
- QV4::Scoped<QV4ParticleData> r(scope, callData->thisObject); \
+ QV4::Scope scope(b); \
+ QV4::Scoped<QV4ParticleData> r(scope, *thisObject); \
if (!r || !r->d()->datum) \
RETURN_RESULT(scope.engine->throwError(QStringLiteral("Not a valid ParticleData object"))); \
\
RETURN_RESULT(QV4::Encode(r->d()->datum-> GETTER (r->d()->particleSystem)));\
}\
\
-static void particleData_set_ ## VARIABLE (const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)\
+static QV4::ReturnedValue particleData_set_ ## VARIABLE (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)\
{\
- QV4::Scoped<QV4ParticleData> r(scope, callData->thisObject); \
+ QV4::Scope scope(b); \
+ QV4::Scoped<QV4ParticleData> r(scope, *thisObject); \
if (!r || !r->d()->datum)\
RETURN_RESULT(scope.engine->throwError(QStringLiteral("Not a valid ParticleData object")));\
\
- r->d()->datum-> SETTER (callData->argc ? callData->args[0].toNumber() : qt_qnan(), r->d()->particleSystem);\
+ r->d()->datum-> SETTER (argc ? argv[0].toNumber() : qt_qnan(), r->d()->particleSystem);\
RETURN_UNDEFINED(); \
}
@@ -496,12 +510,12 @@ QV4ParticleDataDeletable::~QV4ParticleDataDeletable()
V4_DEFINE_EXTENSION(QV4ParticleDataDeletable, particleV4Data);
-QQuickV4ParticleData::QQuickV4ParticleData(QV8Engine* engine, QQuickParticleData* datum, QQuickParticleSystem *system)
+QQuickV4ParticleData::QQuickV4ParticleData(QV4::ExecutionEngine* v4, QQuickParticleData* datum,
+ QQuickParticleSystem *system)
{
- if (!engine || !datum)
+ if (!v4 || !datum)
return;
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
QV4::Scope scope(v4);
QV4ParticleDataDeletable *d = particleV4Data(scope.engine);
QV4::ScopedObject o(scope, v4->memoryManager->allocObject<QV4ParticleData>(datum, system));
diff --git a/src/particles/qquickv4particledata_p.h b/src/particles/qquickv4particledata_p.h
index d73e3b644d..3d682ab297 100644
--- a/src/particles/qquickv4particledata_p.h
+++ b/src/particles/qquickv4particledata_p.h
@@ -61,7 +61,7 @@ class QQuickParticleData;
class QQuickParticleSystem;
class QQuickV4ParticleData {
public:
- QQuickV4ParticleData(QV8Engine*, QQuickParticleData*, QQuickParticleSystem *system);
+ QQuickV4ParticleData(QV4::ExecutionEngine*, QQuickParticleData*, QQuickParticleSystem *system);
~QQuickV4ParticleData();
QQmlV4Handle v4Value() const;
private:
diff --git a/src/particles/qquickwander.cpp b/src/particles/qquickwander.cpp
index 099b453808..a78482ec84 100644
--- a/src/particles/qquickwander.cpp
+++ b/src/particles/qquickwander.cpp
@@ -39,6 +39,7 @@
#include "qquickwander_p.h"
#include "qquickparticlesystem_p.h"//for ParticlesVertices
+#include <QRandomGenerator>
QT_BEGIN_NAMESPACE
/*!
\qmltype Wander
@@ -102,8 +103,8 @@ WanderData* QQuickWanderAffector::getData(int idx)
d->y_vel = 0;
d->x_peak = m_xVariance;
d->y_peak = m_yVariance;
- d->x_var = m_pace * qreal(qrand()) / RAND_MAX;
- d->y_var = m_pace * qreal(qrand()) / RAND_MAX;
+ d->x_var = m_pace * QRandomGenerator::global()->generateDouble();
+ d->y_var = m_pace * QRandomGenerator::global()->generateDouble();
m_wanderData.insert(idx, d);
return d;
@@ -124,7 +125,7 @@ bool QQuickWanderAffector::affectParticle(QQuickParticleData* data, qreal dt)
if (m_xVariance != 0.) {
if ((d->x_vel > d->x_peak && d->x_var > 0.0) || (d->x_vel < -d->x_peak && d->x_var < 0.0)) {
d->x_var = -d->x_var;
- d->x_peak = m_xVariance + m_xVariance * qreal(qrand()) / RAND_MAX;
+ d->x_peak = m_xVariance + m_xVariance * QRandomGenerator::global()->generateDouble();
}
d->x_vel += d->x_var * dt;
}
@@ -133,7 +134,7 @@ bool QQuickWanderAffector::affectParticle(QQuickParticleData* data, qreal dt)
if (m_yVariance != 0.) {
if ((d->y_vel > d->y_peak && d->y_var > 0.0) || (d->y_vel < -d->y_peak && d->y_var < 0.0)) {
d->y_var = -d->y_var;
- d->y_peak = m_yVariance + m_yVariance * qreal(qrand()) / RAND_MAX;
+ d->y_peak = m_yVariance + m_yVariance * QRandomGenerator::global()->generateDouble();
}
d->y_vel += d->y_var * dt;
}
@@ -146,8 +147,8 @@ bool QQuickWanderAffector::affectParticle(QQuickParticleData* data, qreal dt)
p->y += dy;
return true;
*/
- qreal dx = dt * m_pace * (2 * qreal(qrand())/RAND_MAX - 1);
- qreal dy = dt * m_pace * (2 * qreal(qrand())/RAND_MAX - 1);
+ qreal dx = dt * m_pace * (2 * QRandomGenerator::global()->generateDouble() - 1);
+ qreal dy = dt * m_pace * (2 * QRandomGenerator::global()->generateDouble() - 1);
qreal newX, newY;
switch (m_affectedParameter){
case Position:
diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro
index 2467239be2..0afd71767e 100644
--- a/src/plugins/plugins.pro
+++ b/src/plugins/plugins.pro
@@ -1,4 +1,5 @@
TEMPLATE = subdirs
+QT_FOR_CONFIG += qml
-!contains(QT_CONFIG, no-qml-debug):SUBDIRS += qmltooling
+qtConfig(qml-debug):SUBDIRS += qmltooling
qtHaveModule(quick):SUBDIRS += scenegraph
diff --git a/src/plugins/qmltooling/packetprotocol/packetprotocol.pro b/src/plugins/qmltooling/packetprotocol/packetprotocol.pro
index 383e32b54e..990d3169ad 100644
--- a/src/plugins/qmltooling/packetprotocol/packetprotocol.pro
+++ b/src/plugins/qmltooling/packetprotocol/packetprotocol.pro
@@ -4,7 +4,8 @@ CONFIG += static internal_module
HEADERS = \
qpacketprotocol_p.h \
- qpacket_p.h
+ qpacket_p.h \
+ qqmldebugpacket_p.h
SOURCES = \
qpacketprotocol.cpp \
diff --git a/src/plugins/qmltooling/shared/qqmldebugpacket.h b/src/plugins/qmltooling/packetprotocol/qqmldebugpacket_p.h
index f1c21e0a2b..9a0f8cd82d 100644
--- a/src/plugins/qmltooling/shared/qqmldebugpacket.h
+++ b/src/plugins/qmltooling/packetprotocol/qqmldebugpacket_p.h
@@ -40,9 +40,10 @@
#ifndef QQMLDEBUGPACKET_P_H
#define QQMLDEBUGPACKET_P_H
+#include "qpacket_p.h"
+
#include <QtCore/qbuffer.h>
#include <QtQml/private/qqmldebugconnector_p.h>
-#include <QtPacketProtocol/private/qpacket_p.h>
//
// W A R N I N G
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qmldbg_debugger.pro b/src/plugins/qmltooling/qmldbg_debugger/qmldbg_debugger.pro
index f3f8a21ff8..2d8f0ceda2 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qmldbg_debugger.pro
+++ b/src/plugins/qmltooling/qmldbg_debugger/qmldbg_debugger.pro
@@ -12,8 +12,6 @@ SOURCES += \
$$PWD/qv4debugjob.cpp
HEADERS += \
- $$PWD/../shared/qqmlconfigurabledebugservice.h \
- $$PWD/../shared/qqmldebugpacket.h \
$$PWD/qqmldebuggerservicefactory.h \
$$PWD/qqmlenginedebugservice.h \
$$PWD/qqmlwatcher.h \
@@ -23,9 +21,6 @@ HEADERS += \
$$PWD/qv4datacollector.h \
$$PWD/qv4debugjob.h
-INCLUDEPATH += $$PWD \
- $$PWD/../shared
-
OTHER_FILES += \
$$PWD/qqmldebuggerservice.json
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
index d2934ba034..80da09d718 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
@@ -39,7 +39,6 @@
#include "qqmlenginedebugservice.h"
#include "qqmlwatcher.h"
-#include "qqmldebugpacket.h"
#include <private/qqmldebugstatesdelegate_p.h>
#include <private/qqmlboundsignal_p.h>
@@ -57,6 +56,7 @@
#include <QtCore/qmetaobject.h>
#include <QtCore/qfileinfo.h>
#include <private/qmetaobject_p.h>
+#include <private/qqmldebugpacket_p.h>
QT_BEGIN_NAMESPACE
@@ -771,7 +771,7 @@ bool QQmlEngineDebugServiceImpl::setMethodBody(int objectId, const QString &meth
QQmlVMEMetaObject *vmeMetaObject = QQmlVMEMetaObject::get(object);
Q_ASSERT(vmeMetaObject); // the fact we found the property above should guarentee this
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(qmlEngine(object)->handle());
+ QV4::ExecutionEngine *v4 = qmlEngine(object)->handle();
QV4::Scope scope(v4);
int lineNumber = 0;
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.h b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.h
index 2e40eb4de8..c0c24058eb 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.h
+++ b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.h
@@ -95,17 +95,17 @@ public:
bool hasNotifySignal;
};
- void engineAboutToBeAdded(QJSEngine *) Q_DECL_OVERRIDE;
- void engineAboutToBeRemoved(QJSEngine *) Q_DECL_OVERRIDE;
- void objectCreated(QJSEngine *, QObject *) Q_DECL_OVERRIDE;
+ void engineAboutToBeAdded(QJSEngine *) override;
+ void engineAboutToBeRemoved(QJSEngine *) override;
+ void objectCreated(QJSEngine *, QObject *) override;
- void setStatesDelegate(QQmlDebugStatesDelegate *) Q_DECL_OVERRIDE;
+ void setStatesDelegate(QQmlDebugStatesDelegate *) override;
signals:
void scheduleMessage(const QByteArray &);
protected:
- virtual void messageReceived(const QByteArray &) Q_DECL_OVERRIDE;
+ void messageReceived(const QByteArray &) override;
private:
friend class QQmlDebuggerServiceFactory;
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
index 755235a3a7..a538956e8e 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.cpp
@@ -55,47 +55,43 @@
QT_BEGIN_NAMESPACE
-QV4::CallContext *QV4DataCollector::findContext(int frame)
+QV4::CppStackFrame *QV4DataCollector::findFrame(int frame)
{
- QV4::ExecutionContext *ctx = engine()->currentContext;
- while (ctx) {
- QV4::CallContext *cCtxt = ctx->asCallContext();
- if (cCtxt && cCtxt->d()->v4Function) {
- if (frame < 1)
- return cCtxt;
- --frame;
- }
- ctx = engine()->parentContext(ctx);
+ QV4::CppStackFrame *f = engine()->currentStackFrame;
+ while (f && frame) {
+ --frame;
+ f = f->parent;
}
+ return f;
+}
+
+QV4::Heap::ExecutionContext *QV4DataCollector::findContext(int frame)
+{
+ QV4::CppStackFrame *f = findFrame(frame);
- return 0;
+ return f ? f->context()->d() : 0;
}
-QV4::Heap::CallContext *QV4DataCollector::findScope(QV4::ExecutionContext *ctxt, int scope)
+QV4::Heap::CallContext *QV4DataCollector::findScope(QV4::Heap::ExecutionContext *ctx, int scope)
{
- if (!ctxt)
+ if (!ctx)
return 0;
- QV4::Scope s(ctxt);
- QV4::ScopedContext ctx(s, ctxt);
for (; scope > 0 && ctx; --scope)
- ctx = ctx->d()->outer;
+ ctx = ctx->outer;
- return (ctx && ctx->d()) ? ctx->asCallContext()->d() : 0;
+ return (ctx && ctx->type == QV4::Heap::ExecutionContext::Type_CallContext) ?
+ static_cast<QV4::Heap::CallContext *>(ctx) : 0;
}
QVector<QV4::Heap::ExecutionContext::ContextType> QV4DataCollector::getScopeTypes(int frame)
{
QVector<QV4::Heap::ExecutionContext::ContextType> types;
- QV4::Scope scope(engine());
- QV4::CallContext *sctxt = findContext(frame);
- if (!sctxt || sctxt->d()->type < QV4::Heap::ExecutionContext::Type_QmlContext)
- return types;
+ QV4::Heap::ExecutionContext *it = findFrame(frame)->context()->d();
- QV4::ScopedContext it(scope, sctxt);
- for (; it; it = it->d()->outer)
- types.append(QV4::Heap::ExecutionContext::ContextType(it->d()->type));
+ for (; it; it = it->outer)
+ types.append(QV4::Heap::ExecutionContext::ContextType(it->type));
return types;
}
@@ -109,7 +105,6 @@ int QV4DataCollector::encodeScopeType(QV4::Heap::ExecutionContext::ContextType s
return 4;
case QV4::Heap::ExecutionContext::Type_WithContext:
return 2;
- case QV4::Heap::ExecutionContext::Type_SimpleCallContext:
case QV4::Heap::ExecutionContext::Type_CallContext:
return 1;
case QV4::Heap::ExecutionContext::Type_QmlContext:
@@ -149,8 +144,6 @@ const QV4::Object *collectProperty(const QV4::ScopedValue &value, QV4::Execution
dict.insert(valueKey, QJsonValue::Undefined);
return 0;
case QV4::Value::Null_Type:
- // "null" is not the correct type, but we leave this in until QtC can deal with "object"
- dict.insert(QStringLiteral("type"), QStringLiteral("null"));
dict.insert(valueKey, QJsonValue::Null);
return 0;
case QV4::Value::Boolean_Type:
@@ -269,27 +262,17 @@ bool QV4DataCollector::collectScope(QJsonObject *dict, int frameNr, int scopeNr)
QStringList names;
QV4::Scope scope(engine());
+
QV4::Scoped<QV4::CallContext> ctxt(scope, findScope(findContext(frameNr), scopeNr));
if (!ctxt)
return false;
Refs collectedRefs;
QV4::ScopedValue v(scope);
- int nFormals = ctxt->formalCount();
- for (unsigned i = 0, ei = nFormals; i != ei; ++i) {
- QString qName;
- if (QV4::Identifier *name = ctxt->formals()[nFormals - i - 1])
- qName = name->string;
- names.append(qName);
- v = ctxt->argument(i);
- collectedRefs.append(collect(v));
- }
-
- for (unsigned i = 0, ei = ctxt->variableCount(); i != ei; ++i) {
- QString qName;
- if (QV4::Identifier *name = ctxt->variables()[i])
- qName = name->string;
- names.append(qName);
+ QV4::InternalClass *ic = ctxt->internalClass();
+ for (uint i = 0; i < ic->size; ++i) {
+ QString name = ic->nameMap[i]->string;
+ names.append(name);
v = ctxt->d()->locals[i];
collectedRefs.append(collect(v));
}
@@ -297,9 +280,11 @@ bool QV4DataCollector::collectScope(QJsonObject *dict, int frameNr, int scopeNr)
QV4::ScopedObject scopeObject(scope, engine()->newObject());
Q_ASSERT(names.size() == collectedRefs.size());
- for (int i = 0, ei = collectedRefs.size(); i != ei; ++i)
- scopeObject->put(engine(), names.at(i),
- QV4::Value::fromReturnedValue(getValue(collectedRefs.at(i))));
+ QV4::ScopedString propName(scope);
+ for (int i = 0, ei = collectedRefs.size(); i != ei; ++i) {
+ propName = engine()->newString(names.at(i));
+ scopeObject->put(propName, QV4::Value::fromReturnedValue(getValue(collectedRefs.at(i))));
+ }
Ref scopeObjectRef = addRef(scopeObject);
if (m_redundantRefs) {
@@ -346,7 +331,7 @@ QJsonObject QV4DataCollector::buildFrame(const QV4::StackFrame &stackFrame, int
}
if (ctxt) {
- QV4::ScopedValue o(scope, ctxt->asCallContext()->d()->activation);
+ QV4::ScopedValue o(scope, ctxt->d()->activation);
frame[QLatin1String("receiver")] = toRef(collect(o));
}
@@ -398,8 +383,8 @@ QV4DataCollector::Ref QV4DataCollector::addRef(QV4::Value value, bool deduplicat
{
class ExceptionStateSaver
{
- quint32 *hasExceptionLoc;
- quint32 hadException;
+ quint8 *hasExceptionLoc;
+ quint8 hadException;
public:
ExceptionStateSaver(QV4::ExecutionEngine *engine)
@@ -432,7 +417,7 @@ QV4::ReturnedValue QV4DataCollector::getValue(Ref ref)
QV4::Scope scope(engine());
QV4::ScopedObject array(scope, m_values.value());
Q_ASSERT(ref < array->getLength());
- return array->getIndexed(ref, Q_NULLPTR);
+ return array->getIndexed(ref, nullptr);
}
// TODO: Drop this method once we don't need to support namesAsObjects anymore
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h
index 2c2514a1b3..87be009de5 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4datacollector.h
@@ -58,11 +58,12 @@ public:
typedef uint Ref;
typedef QVector<uint> Refs;
- static QV4::Heap::CallContext *findScope(QV4::ExecutionContext *ctxt, int scope);
+ static QV4::Heap::CallContext *findScope(QV4::Heap::ExecutionContext *ctxt, int scope);
static int encodeScopeType(QV4::Heap::ExecutionContext::ContextType scopeType);
QVector<QV4::Heap::ExecutionContext::ContextType> getScopeTypes(int frame);
- QV4::CallContext *findContext(int frame);
+ QV4::Heap::ExecutionContext *findContext(int frame);
+ QV4::CppStackFrame *findFrame(int frame);
QV4DataCollector(QV4::ExecutionEngine *engine);
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp
index b82df9c6a9..45817ea38e 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp
@@ -115,7 +115,7 @@ void QV4Debugger::resume(Speed speed)
if (!m_returnedValue.isUndefined())
m_returnedValue.set(m_engine, QV4::Encode::undefined());
- m_currentContext.set(m_engine, *m_engine->currentContext);
+ m_currentFrame = m_engine->currentStackFrame;
m_stepping = speed;
m_runningCondition.wakeAll();
}
@@ -158,7 +158,7 @@ QV4Debugger::ExecutionState QV4Debugger::currentExecutionState() const
{
ExecutionState state;
state.fileName = getFunction()->sourceFile();
- state.lineNumber = engine()->current->lineNumber;
+ state.lineNumber = engine()->currentStackFrame->lineNumber();
return state;
}
@@ -187,9 +187,9 @@ void QV4Debugger::maybeBreakAtInstruction()
switch (m_stepping) {
case StepOver:
- if (m_currentContext.asManaged()->d() != m_engine->current)
+ if (m_currentFrame != m_engine->currentStackFrame)
break;
- // fall through
+ Q_FALLTHROUGH();
case StepIn:
pauseAndWait(Step);
return;
@@ -203,7 +203,8 @@ void QV4Debugger::maybeBreakAtInstruction()
pauseAndWait(PauseRequest);
} else if (m_haveBreakPoints) {
if (QV4::Function *f = getFunction()) {
- const int lineNumber = engine()->current->lineNumber;
+ // lineNumber will be negative for Ret instructions, so those won't match
+ const int lineNumber = engine()->currentStackFrame->lineNumber();
if (reallyHitTheBreakPoint(f->sourceFile(), lineNumber))
pauseAndWait(BreakPointHit);
}
@@ -216,9 +217,8 @@ void QV4Debugger::enteringFunction()
return;
QMutexLocker locker(&m_lock);
- if (m_stepping == StepIn) {
- m_currentContext.set(m_engine, *m_engine->currentContext);
- }
+ if (m_stepping == StepIn)
+ m_currentFrame = m_engine->currentStackFrame;
}
void QV4Debugger::leavingFunction(const QV4::ReturnedValue &retVal)
@@ -229,13 +229,8 @@ void QV4Debugger::leavingFunction(const QV4::ReturnedValue &retVal)
QMutexLocker locker(&m_lock);
- if (m_stepping != NotStepping && m_currentContext.asManaged()->d() == m_engine->current) {
- if (QV4::ExecutionContext *parentContext
- = m_engine->parentContext(m_engine->currentContext)) {
- m_currentContext.set(m_engine, *parentContext);
- } else {
- m_currentContext.clear();
- }
+ if (m_stepping != NotStepping && m_currentFrame == m_engine->currentStackFrame) {
+ m_currentFrame = m_currentFrame->parent;
m_stepping = StepOver;
m_returnedValue.set(m_engine, retVal);
}
@@ -255,10 +250,8 @@ void QV4Debugger::aboutToThrow()
QV4::Function *QV4Debugger::getFunction() const
{
- QV4::Scope scope(m_engine);
- QV4::ExecutionContext *context = m_engine->currentContext;
- if (QV4::Function *function = context->getFunction())
- return function;
+ if (m_engine->currentStackFrame)
+ return m_engine->currentStackFrame->v4Function;
else
return m_engine->globalCode;
}
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.h b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.h
index cd412e573d..4a755f2b72 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.h
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.h
@@ -129,14 +129,14 @@ public:
void runInEngine(QV4DebugJob *job);
// compile-time interface
- void maybeBreakAtInstruction() Q_DECL_OVERRIDE;
+ void maybeBreakAtInstruction() override;
// execution hooks
- void enteringFunction() Q_DECL_OVERRIDE;
- void leavingFunction(const QV4::ReturnedValue &retVal) Q_DECL_OVERRIDE;
- void aboutToThrow() Q_DECL_OVERRIDE;
+ void enteringFunction() override;
+ void leavingFunction(const QV4::ReturnedValue &retVal) override;
+ void aboutToThrow() override;
- bool pauseAtNextOpportunity() const Q_DECL_OVERRIDE;
+ bool pauseAtNextOpportunity() const override;
signals:
void debuggerPaused(QV4Debugger *self, QV4Debugger::PauseReason reason);
@@ -150,7 +150,7 @@ private:
void runJobUnpaused();
QV4::ExecutionEngine *m_engine;
- QV4::PersistentValue m_currentContext;
+ QV4::CppStackFrame *m_currentFrame = 0;
QMutex m_lock;
QWaitCondition m_runningCondition;
State m_state;
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp
index 9a34d5770a..87e75c49b5 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp
@@ -79,20 +79,19 @@ void QV4DebuggerAgent::debuggerPaused(QV4Debugger *debugger, QV4Debugger::PauseR
case QV4Debugger::PauseRequest:
case QV4Debugger::BreakPointHit: {
event.insert(QStringLiteral("event"), QStringLiteral("break"));
- QVector<QV4::StackFrame> frames = debugger->stackTrace(1);
- if (frames.isEmpty())
+ QV4::CppStackFrame *frame = debugger->engine()->currentStackFrame;
+ if (!frame)
break;
- const QV4::StackFrame &topFrame = frames.first();
- body.insert(QStringLiteral("invocationText"), topFrame.function);
- body.insert(QStringLiteral("sourceLine"), topFrame.line - 1);
- if (topFrame.column > 0)
- body.insert(QStringLiteral("sourceColumn"), topFrame.column);
+ body.insert(QStringLiteral("invocationText"), frame->function());
+ body.insert(QStringLiteral("sourceLine"), qAbs(frame->lineNumber()) - 1);
+// if (frame->column > 0)
+// body.insert(QStringLiteral("sourceColumn"), frame->column);
QJsonArray breakPoints;
- foreach (int breakPointId, breakPointIds(topFrame.source, topFrame.line))
+ foreach (int breakPointId, breakPointIds(frame->source(), frame->lineNumber()))
breakPoints.push_back(breakPointId);
body.insert(QStringLiteral("breakpoints"), breakPoints);
- script.insert(QStringLiteral("name"), topFrame.source);
+ script.insert(QStringLiteral("name"), frame->source());
} break;
case QV4Debugger::Throwing:
// TODO: complete this!
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
index a58604526b..6f254c9e28 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugjob.cpp
@@ -44,6 +44,7 @@
#include <private/qv4qmlcontext_p.h>
#include <private/qv4qobjectwrapper_p.h>
#include <private/qqmldebugservice_p.h>
+#include <private/qv4jscall_p.h>
#include <QtQml/qqmlengine.h>
@@ -63,26 +64,21 @@ void JavaScriptJob::run()
{
QV4::Scope scope(engine);
- QV4::ExecutionContextSaver saver(scope);
-
- QV4::ExecutionContext *ctx = engine->currentContext;
+ QV4::ScopedContext ctx(scope, engine->currentStackFrame ? engine->currentContext()
+ : engine->rootContext());
QObject scopeObject;
- if (frameNr > 0) {
- for (int i = 0; i < frameNr; ++i) {
- ctx = engine->parentContext(ctx);
- }
- engine->pushContext(ctx);
- ctx = engine->currentContext;
- }
+ QV4::CppStackFrame *frame = engine->currentStackFrame;
+
+ for (int i = 0; frame && i < frameNr; ++i)
+ frame = frame->parent;
+ if (frameNr > 0 && frame)
+ ctx = static_cast<QV4::ExecutionContext *>(&frame->jsFrame->context);
if (context >= 0) {
QQmlContext *extraContext = qmlContext(QQmlDebugService::objectForId(context));
- if (extraContext) {
- engine->pushContext(QV4::QmlContext::create(ctx, QQmlContextData::get(extraContext),
- &scopeObject));
- ctx = engine->currentContext;
- }
+ if (extraContext)
+ ctx = QV4::QmlContext::create(ctx, QQmlContextData::get(extraContext), &scopeObject);
} else if (frameNr < 0) { // Use QML context if available
QQmlEngine *qmlEngine = engine->qmlEngine();
if (qmlEngine) {
@@ -90,27 +86,27 @@ void JavaScriptJob::run()
QQmlContextPrivate *ctxtPriv = QQmlContextPrivate::get(qmlRootContext);
QV4::ScopedObject withContext(scope, engine->newObject());
+ QV4::ScopedString k(scope);
+ QV4::ScopedValue v(scope);
for (int ii = 0; ii < ctxtPriv->instances.count(); ++ii) {
QObject *object = ctxtPriv->instances.at(ii);
if (QQmlContext *context = qmlContext(object)) {
if (QQmlContextData *cdata = QQmlContextData::get(context)) {
- QV4::ScopedValue v(scope, QV4::QObjectWrapper::wrap(engine, object));
- withContext->put(engine, cdata->findObjectId(object), v);
+ v = QV4::QObjectWrapper::wrap(engine, object);
+ k = engine->newString(cdata->findObjectId(object));
+ withContext->put(k, v);
}
}
}
- if (!engine->qmlContext()) {
- engine->pushContext(QV4::QmlContext::create(ctx, QQmlContextData::get(qmlRootContext),
- &scopeObject));
- ctx = engine->currentContext;
- }
- engine->pushContext(ctx->newWithContext(withContext->toObject(engine)));
- ctx = engine->currentContext;
+ if (!engine->qmlContext())
+ ctx = QV4::QmlContext::create(ctx, QQmlContextData::get(qmlRootContext), &scopeObject);
}
}
- QV4::Script script(ctx, this->script);
- script.strictMode = ctx->d()->strictMode;
+ QV4::Script script(ctx, QV4::Compiler::EvalCode, this->script);
+ if (const QV4::Function *function = frame ? frame->v4Function : engine->globalCode)
+ script.strictMode = function->isStrict();
+
// In order for property lookups in QML to work, we need to disable fast v4 lookups. That
// is a side-effect of inheritContext.
script.inheritContext = true;
@@ -211,12 +207,15 @@ void ValueLookupJob::run()
// set if the engine is currently executing QML code.
QScopedPointer<QObject> scopeObject;
QV4::ExecutionEngine *engine = collector->engine();
+ QV4::Scope scope(engine);
+ QV4::Heap::ExecutionContext *qmlContext = 0;
if (engine->qmlEngine() && !engine->qmlContext()) {
scopeObject.reset(new QObject);
- engine->pushContext(QV4::QmlContext::create(engine->currentContext,
+ qmlContext = QV4::QmlContext::create(engine->currentContext(),
QQmlContextData::get(engine->qmlEngine()->rootContext()),
- scopeObject.data()));
+ scopeObject.data());
}
+ QV4::ScopedStackFrame frame(scope, qmlContext);
for (const QJsonValue &handle : handles) {
QV4DataCollector::Ref ref = handle.toInt();
if (!collector->isValidRef(ref)) {
@@ -226,8 +225,6 @@ void ValueLookupJob::run()
result[QString::number(ref)] = collector->lookupRef(ref, true);
}
flushRedundantRefs();
- if (scopeObject)
- engine->popContext();
}
const QString &ValueLookupJob::exceptionMessage() const
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
index 168a08865c..99a57be5d6 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp
@@ -40,13 +40,12 @@
#include "qv4debugservice.h"
#include "qv4debugjob.h"
#include "qqmlengine.h"
-#include "qqmldebugpacket.h"
#include <private/qv4engine_p.h>
-#include <private/qv4isel_moth_p.h>
#include <private/qv4function_p.h>
#include <private/qqmldebugconnector_p.h>
#include <private/qv8engine_p.h>
+#include <private/qqmldebugpacket_p.h>
#include <QtCore/QJsonArray>
#include <QtCore/QJsonDocument>
@@ -703,10 +702,9 @@ void QV4DebugServiceImpl::engineAdded(QJSEngine *engine)
{
QMutexLocker lock(&m_configMutex);
if (engine) {
- QV4::ExecutionEngine *ee = QV8Engine::getV4(engine->handle());
+ QV4::ExecutionEngine *ee = engine->handle();
if (QQmlDebugConnector *server = QQmlDebugConnector::instance()) {
if (ee) {
- ee->iselFactory.reset(new QV4::Moth::ISelFactory);
QV4Debugger *debugger = new QV4Debugger(ee);
if (state() == Enabled)
ee->setDebugger(debugger);
@@ -722,7 +720,7 @@ void QV4DebugServiceImpl::engineAboutToBeRemoved(QJSEngine *engine)
{
QMutexLocker lock(&m_configMutex);
if (engine){
- const QV4::ExecutionEngine *ee = QV8Engine::getV4(engine->handle());
+ const QV4::ExecutionEngine *ee = engine->handle();
if (ee) {
QV4Debugger *debugger = qobject_cast<QV4Debugger *>(ee->debugger());
if (debugger)
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h
index bb13890ae4..5401956994 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h
+++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.h
@@ -51,9 +51,9 @@
// We mean it.
//
-#include "qqmlconfigurabledebugservice.h"
#include "qv4debuggeragent.h"
#include "qv4datacollector.h"
+#include <private/qqmlconfigurabledebugservice_p.h>
#include <private/qqmldebugserviceinterfaces_p.h>
#include <private/qv4debugging_p.h>
@@ -73,14 +73,14 @@ class QV4DebugServiceImpl : public QQmlConfigurableDebugService<QV4DebugService>
Q_OBJECT
public:
explicit QV4DebugServiceImpl(QObject *parent = 0);
- ~QV4DebugServiceImpl() Q_DECL_OVERRIDE;
+ ~QV4DebugServiceImpl() override;
- void engineAdded(QJSEngine *engine) Q_DECL_OVERRIDE;
- void engineAboutToBeRemoved(QJSEngine *engine) Q_DECL_OVERRIDE;
+ void engineAdded(QJSEngine *engine) override;
+ void engineAboutToBeRemoved(QJSEngine *engine) override;
- void stateAboutToBeChanged(State state) Q_DECL_OVERRIDE;
+ void stateAboutToBeChanged(State state) override;
- void signalEmitted(const QString &signal) Q_DECL_OVERRIDE;
+ void signalEmitted(const QString &signal) override;
void send(QJsonObject v8Payload);
int selectedFrame() const;
@@ -92,7 +92,7 @@ public:
QV4DebuggerAgent debuggerAgent;
protected:
- void messageReceived(const QByteArray &) Q_DECL_OVERRIDE;
+ void messageReceived(const QByteArray &) override;
void sendSomethingToSomebody(const char *type, int magicNumber = 1);
private:
diff --git a/src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp b/src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp
index 7145645609..7ce83daed6 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp
+++ b/src/plugins/qmltooling/qmldbg_inspector/globalinspector.cpp
@@ -40,11 +40,11 @@
#include "globalinspector.h"
#include "highlight.h"
#include "inspecttool.h"
-#include "qqmldebugpacket.h"
#include <private/qqmldebugserviceinterfaces_p.h>
#include <private/qabstractanimation_p.h>
#include <private/qqmlcomponent_p.h>
+#include <private/qqmldebugpacket_p.h>
#include <QtGui/qwindow.h>
diff --git a/src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro b/src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro
index a8844944e0..18a61f15b7 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro
+++ b/src/plugins/qmltooling/qmldbg_inspector/qmldbg_inspector.pro
@@ -1,8 +1,6 @@
TARGET = qmldbg_inspector
QT += qml-private quick-private core-private gui-private packetprotocol-private
-INCLUDEPATH *= $$PWD $$PWD/../shared
-
SOURCES += \
$$PWD/globalinspector.cpp \
$$PWD/highlight.cpp \
@@ -11,7 +9,6 @@ SOURCES += \
$$PWD/qquickwindowinspector.cpp
HEADERS += \
- $$PWD/../shared/qqmldebugpacket.h \
$$PWD/globalinspector.h \
$$PWD/highlight.h \
$$PWD/inspecttool.h\
diff --git a/src/plugins/qmltooling/qmldbg_inspector/qqmlinspectorservice.cpp b/src/plugins/qmltooling/qmldbg_inspector/qqmlinspectorservice.cpp
index ab1aeebf64..d0d8d62615 100644
--- a/src/plugins/qmltooling/qmldbg_inspector/qqmlinspectorservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_inspector/qqmlinspectorservice.cpp
@@ -51,15 +51,15 @@ class QQmlInspectorServiceImpl : public QQmlInspectorService
public:
QQmlInspectorServiceImpl(QObject *parent = 0);
- void addWindow(QQuickWindow *window) Q_DECL_OVERRIDE;
- void setParentWindow(QQuickWindow *window, QWindow *parent) Q_DECL_OVERRIDE;
- void removeWindow(QQuickWindow *window) Q_DECL_OVERRIDE;
+ void addWindow(QQuickWindow *window) override;
+ void setParentWindow(QQuickWindow *window, QWindow *parent) override;
+ void removeWindow(QQuickWindow *window) override;
signals:
void scheduleMessage(const QByteArray &message);
protected:
- virtual void messageReceived(const QByteArray &) Q_DECL_OVERRIDE;
+ void messageReceived(const QByteArray &) override;
private:
friend class QQmlInspectorServiceFactory;
diff --git a/src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp b/src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp
index 6152853917..e60644518f 100644
--- a/src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp
+++ b/src/plugins/qmltooling/qmldbg_local/qlocalclientconnection.cpp
@@ -38,10 +38,10 @@
****************************************************************************/
#include "qlocalclientconnectionfactory.h"
-#include "qqmldebugserver.h"
#include <QtCore/qplugin.h>
#include <QtNetwork/qlocalsocket.h>
+#include <private/qqmldebugserver_p.h>
Q_DECLARE_METATYPE(QLocalSocket::LocalSocketError)
@@ -57,15 +57,15 @@ public:
QLocalClientConnection();
~QLocalClientConnection();
- void setServer(QQmlDebugServer *server);
- bool setPortRange(int portFrom, int portTo, bool block, const QString &hostaddress);
- bool setFileName(const QString &filename, bool block);
+ void setServer(QQmlDebugServer *server) override;
+ bool setPortRange(int portFrom, int portTo, bool block, const QString &hostaddress) override;
+ bool setFileName(const QString &filename, bool block) override;
- bool isConnected() const;
- void disconnect();
+ bool isConnected() const override;
+ void disconnect() override;
- void waitForConnection();
- void flush();
+ void waitForConnection() override;
+ void flush() override;
private:
void connectionEstablished();
diff --git a/src/plugins/qmltooling/qmldbg_local/qlocalclientconnectionfactory.h b/src/plugins/qmltooling/qmldbg_local/qlocalclientconnectionfactory.h
index b64a1fff95..95bbd8956a 100644
--- a/src/plugins/qmltooling/qmldbg_local/qlocalclientconnectionfactory.h
+++ b/src/plugins/qmltooling/qmldbg_local/qlocalclientconnectionfactory.h
@@ -40,7 +40,7 @@
#ifndef QLOCALCLIENTCONNECTIONFACTORY_H
#define QLOCALCLIENTCONNECTIONFACTORY_H
-#include "qqmldebugserverconnection.h"
+#include <private/qqmldebugserverconnection_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_local/qmldbg_local.pro b/src/plugins/qmltooling/qmldbg_local/qmldbg_local.pro
index d731e47b7e..71dba262da 100644
--- a/src/plugins/qmltooling/qmldbg_local/qmldbg_local.pro
+++ b/src/plugins/qmltooling/qmldbg_local/qmldbg_local.pro
@@ -5,12 +5,7 @@ SOURCES += \
$$PWD/qlocalclientconnection.cpp
HEADERS += \
- $$PWD/qlocalclientconnectionfactory.h \
- $$PWD/../shared/qqmldebugserver.h \
- $$PWD/../shared/qqmldebugserverconnection.h
-
-INCLUDEPATH += $$PWD \
- $$PWD/../shared
+ $$PWD/qlocalclientconnectionfactory.h
OTHER_FILES += \
$$PWD/qlocalclientconnection.json
diff --git a/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservice.cpp b/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservice.cpp
index b0f59717ac..bdfed03a40 100644
--- a/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservice.cpp
@@ -38,8 +38,9 @@
****************************************************************************/
#include "qdebugmessageservice.h"
-#include "qqmldebugpacket.h"
+
#include <private/qqmldebugconnector_p.h>
+#include <private/qqmldebugpacket_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_messages/qmldbg_messages.pro b/src/plugins/qmltooling/qmldbg_messages/qmldbg_messages.pro
index 5ddf7c615d..eda6df1a16 100644
--- a/src/plugins/qmltooling/qmldbg_messages/qmldbg_messages.pro
+++ b/src/plugins/qmltooling/qmldbg_messages/qmldbg_messages.pro
@@ -6,13 +6,9 @@ SOURCES += \
$$PWD/qdebugmessageservicefactory.cpp
HEADERS += \
- $$PWD/../shared/qqmldebugpacket.h \
$$PWD/qdebugmessageservice.h \
$$PWD/qdebugmessageservicefactory.h
-INCLUDEPATH += $$PWD \
- $$PWD/../shared
-
OTHER_FILES += \
$$PWD/qdebugmessageservice.json
diff --git a/src/plugins/qmltooling/qmldbg_native/qmldbg_native.pro b/src/plugins/qmltooling/qmldbg_native/qmldbg_native.pro
index e5489574be..6630a394a0 100644
--- a/src/plugins/qmltooling/qmldbg_native/qmldbg_native.pro
+++ b/src/plugins/qmltooling/qmldbg_native/qmldbg_native.pro
@@ -2,15 +2,11 @@ TARGET = qmldbg_native
QT = qml-private core-private packetprotocol-private
HEADERS += \
- $$PWD/../shared/qqmldebugpacket.h \
$$PWD/qqmlnativedebugconnector.h
SOURCES += \
$$PWD/qqmlnativedebugconnector.cpp
-INCLUDEPATH += $$PWD \
- $$PWD/../shared
-
OTHER_FILES += \
$$PWD/qqmlnativedebugconnector.json
diff --git a/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp
index 388d2e3b22..a4b3455eff 100644
--- a/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp
+++ b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp
@@ -38,9 +38,9 @@
****************************************************************************/
#include "qqmlnativedebugconnector.h"
-#include "qqmldebugpacket.h"
#include <private/qhooks_p.h>
+#include <private/qqmldebugpacket_p.h>
#include <QtQml/qjsengine.h>
#include <QtCore/qdebug.h>
diff --git a/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.h b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.h
index f8b7e1d527..a7f37b0f1e 100644
--- a/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.h
+++ b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.h
@@ -51,16 +51,16 @@ class QQmlNativeDebugConnector : public QQmlDebugConnector
public:
QQmlNativeDebugConnector();
- ~QQmlNativeDebugConnector() Q_DECL_OVERRIDE;
+ ~QQmlNativeDebugConnector() override;
- bool blockingMode() const Q_DECL_OVERRIDE;
- QQmlDebugService *service(const QString &name) const Q_DECL_OVERRIDE;
- void addEngine(QJSEngine *engine) Q_DECL_OVERRIDE;
- void removeEngine(QJSEngine *engine) Q_DECL_OVERRIDE;
- bool hasEngine(QJSEngine *engine) const Q_DECL_OVERRIDE;
- bool addService(const QString &name, QQmlDebugService *service) Q_DECL_OVERRIDE;
- bool removeService(const QString &name) Q_DECL_OVERRIDE;
- bool open(const QVariantHash &configuration) Q_DECL_OVERRIDE;
+ bool blockingMode() const override;
+ QQmlDebugService *service(const QString &name) const override;
+ void addEngine(QJSEngine *engine) override;
+ void removeEngine(QJSEngine *engine) override;
+ bool hasEngine(QJSEngine *engine) const override;
+ bool addService(const QString &name, QQmlDebugService *service) override;
+ bool removeService(const QString &name) override;
+ bool open(const QVariantHash &configuration) override;
static void setDataStreamVersion(int version);
private:
diff --git a/src/plugins/qmltooling/qmldbg_nativedebugger/qmldbg_nativedebugger.pro b/src/plugins/qmltooling/qmldbg_nativedebugger/qmldbg_nativedebugger.pro
index 1873a6a77c..1cb5525622 100644
--- a/src/plugins/qmltooling/qmldbg_nativedebugger/qmldbg_nativedebugger.pro
+++ b/src/plugins/qmltooling/qmldbg_nativedebugger/qmldbg_nativedebugger.pro
@@ -6,13 +6,9 @@ SOURCES += \
$$PWD/qqmlnativedebugservice.cpp
HEADERS += \
- $$PWD/../shared/qqmldebugpacket.h \
$$PWD/qqmlnativedebugservicefactory.h \
$$PWD/qqmlnativedebugservice.h \
-INCLUDEPATH += $$PWD \
- $$PWD/../shared
-
OTHER_FILES += \
$$PWD/qqmlnativedebugservice.json
diff --git a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
index 2015118d95..ba33de9714 100644
--- a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp
@@ -38,7 +38,6 @@
****************************************************************************/
#include "qqmlnativedebugservice.h"
-#include "qqmldebugpacket.h"
#include <private/qqmldebugconnector_p.h>
#include <private/qv4debugging_p.h>
@@ -50,7 +49,7 @@
#include <private/qv4objectiterator_p.h>
#include <private/qv4identifier_p.h>
#include <private/qv4runtime_p.h>
-#include <private/qv4isel_moth_p.h>
+#include <private/qqmldebugpacket_p.h>
#include <private/qqmldebugserviceinterfaces_p.h>
#include <QtQml/qjsengine.h>
@@ -188,16 +187,16 @@ public:
QV4::ExecutionEngine *engine() const { return m_engine; }
- bool pauseAtNextOpportunity() const Q_DECL_OVERRIDE {
+ bool pauseAtNextOpportunity() const override {
return m_pauseRequested
|| m_service->m_breakHandler->m_haveBreakPoints
|| m_stepping >= StepOver;
}
- void maybeBreakAtInstruction() Q_DECL_OVERRIDE;
- void enteringFunction() Q_DECL_OVERRIDE;
- void leavingFunction(const QV4::ReturnedValue &retVal) Q_DECL_OVERRIDE;
- void aboutToThrow() Q_DECL_OVERRIDE;
+ void maybeBreakAtInstruction() override;
+ void enteringFunction() override;
+ void leavingFunction(const QV4::ReturnedValue &retVal) override;
+ void aboutToThrow() override;
void handleCommand(QJsonObject *response, const QString &cmd, const QJsonObject &arguments);
@@ -208,7 +207,7 @@ private:
void handleDebuggerDeleted(QObject *debugger);
- void evaluateExpression(QV4::Scope &scope, const QString &expression);
+ QV4::ReturnedValue evaluateExpression(const QString &expression);
bool checkCondition(const QString &expression);
QStringList breakOnSignals;
@@ -230,7 +229,7 @@ private:
QV4::ExecutionEngine *m_engine;
QQmlNativeDebugServiceImpl *m_service;
- QV4::PersistentValue m_currentContext;
+ QV4::CppStackFrame *m_currentFrame = 0;
Speed m_stepping;
bool m_pauseRequested;
bool m_runningJob;
@@ -241,29 +240,31 @@ private:
bool NativeDebugger::checkCondition(const QString &expression)
{
QV4::Scope scope(m_engine);
- evaluateExpression(scope, expression);
- return scope.result.booleanValue();
+ QV4::ScopedValue r(scope, evaluateExpression(expression));
+ return r->booleanValue();
}
-void NativeDebugger::evaluateExpression(QV4::Scope &scope, const QString &expression)
+QV4::ReturnedValue NativeDebugger::evaluateExpression(const QString &expression)
{
+ QV4::Scope scope(m_engine);
m_runningJob = true;
- QV4::ExecutionContextSaver saver(scope);
-
- QV4::ExecutionContext *ctx = m_engine->currentContext;
- m_engine->pushContext(ctx);
+ QV4::ExecutionContext *ctx = m_engine->currentStackFrame ? m_engine->currentContext()
+ : m_engine->rootContext();
- QV4::Script script(ctx, expression);
- script.strictMode = ctx->d()->strictMode;
+ QV4::Script script(ctx, QV4::Compiler::EvalCode, expression);
+ if (const QV4::Function *function = m_engine->currentStackFrame
+ ? m_engine->currentStackFrame->v4Function : m_engine->globalCode)
+ script.strictMode = function->isStrict();
// In order for property lookups in QML to work, we need to disable fast v4 lookups.
// That is a side-effect of inheritContext.
script.inheritContext = true;
script.parse();
if (!m_engine->hasException)
- scope.result = script.run();
+ return script.run();
m_runningJob = false;
+ return QV4::Encode::undefined();
}
NativeDebugger::NativeDebugger(QQmlNativeDebugServiceImpl *service, QV4::ExecutionEngine *engine)
@@ -314,19 +315,19 @@ void NativeDebugger::handleCommand(QJsonObject *response, const QString &cmd,
handleContinue(response, NotStepping);
}
-static QString encodeContext(QV4::ExecutionContext *executionContext)
+static QString encodeFrame(QV4::CppStackFrame *f)
{
QQmlDebugPacket ds;
- ds << quintptr(executionContext);
+ ds << quintptr(f);
return QString::fromLatin1(ds.data().toHex());
}
-static void decodeContext(const QString &context, QV4::ExecutionContext **executionContext)
+static void decodeFrame(const QString &f, QV4::CppStackFrame **frame)
{
- quintptr rawContext;
- QQmlDebugPacket ds(QByteArray::fromHex(context.toLatin1()));
- ds >> rawContext;
- *executionContext = reinterpret_cast<QV4::ExecutionContext *>(rawContext);
+ quintptr rawFrame;
+ QQmlDebugPacket ds(QByteArray::fromHex(f.toLatin1()));
+ ds >> rawFrame;
+ *frame = reinterpret_cast<QV4::CppStackFrame *>(rawFrame);
}
void NativeDebugger::handleBacktrace(QJsonObject *response, const QJsonObject &arguments)
@@ -334,25 +335,24 @@ void NativeDebugger::handleBacktrace(QJsonObject *response, const QJsonObject &a
int limit = arguments.value(QLatin1String("limit")).toInt(0);
QJsonArray frameArray;
- QV4::ExecutionContext *executionContext = m_engine->currentContext;
- for (int i = 0; i < limit && executionContext; ++i) {
- if (QV4::Function *function = executionContext->getFunction()) {
+ QV4::CppStackFrame *f= m_engine->currentStackFrame;
+ for (int i = 0; i < limit && f; ++i) {
+ QV4::Function *function = f->v4Function;
- QJsonObject frame;
- frame.insert(QStringLiteral("language"), QStringLiteral("js"));
- frame.insert(QStringLiteral("context"), encodeContext(executionContext));
+ QJsonObject frame;
+ frame.insert(QStringLiteral("language"), QStringLiteral("js"));
+ frame.insert(QStringLiteral("context"), encodeFrame(f));
- if (QV4::Heap::String *functionName = function->name())
- frame.insert(QStringLiteral("function"), functionName->toQString());
- frame.insert(QStringLiteral("file"), function->sourceFile());
+ if (QV4::Heap::String *functionName = function->name())
+ frame.insert(QStringLiteral("function"), functionName->toQString());
+ frame.insert(QStringLiteral("file"), function->sourceFile());
- int line = executionContext->d()->lineNumber;
- frame.insert(QStringLiteral("line"), (line < 0 ? -line : line));
+ int line = f->lineNumber();
+ frame.insert(QStringLiteral("line"), (line < 0 ? -line : line));
- frameArray.push_back(frame);
- }
+ frameArray.push_back(frame);
- executionContext = m_engine->parentContext(executionContext);
+ f = f->parent;
}
response->insert(QStringLiteral("frames"), frameArray);
@@ -457,15 +457,15 @@ void Collector::collect(QJsonArray *out, const QString &parentIName, const QStri
void NativeDebugger::handleVariables(QJsonObject *response, const QJsonObject &arguments)
{
TRACE_PROTOCOL("Build variables");
- QV4::ExecutionContext *executionContext = 0;
- decodeContext(arguments.value(QLatin1String("context")).toString(), &executionContext);
- if (!executionContext) {
- setError(response, QStringLiteral("No execution context passed"));
+ QV4::CppStackFrame *frame = 0;
+ decodeFrame(arguments.value(QLatin1String("context")).toString(), &frame);
+ if (!frame) {
+ setError(response, QStringLiteral("No stack frame passed"));
return;
}
- TRACE_PROTOCOL("Context: " << executionContext);
+ TRACE_PROTOCOL("Context: " << frame);
- QV4::ExecutionEngine *engine = executionContext->engine();
+ QV4::ExecutionEngine *engine = frame->v4Function->internalClass->engine;
if (!engine) {
setError(response, QStringLiteral("No execution engine passed"));
return;
@@ -481,25 +481,16 @@ void NativeDebugger::handleVariables(QJsonObject *response, const QJsonObject &a
QJsonArray output;
QV4::Scope scope(engine);
- if (QV4::CallContext *callContext = executionContext->asCallContext()) {
- QV4::Value thisObject = callContext->thisObject();
- collector.collect(&output, QString(), QStringLiteral("this"), thisObject);
- QV4::Identifier *const *variables = callContext->variables();
- QV4::Identifier *const *formals = callContext->formals();
- for (unsigned i = 0, ei = callContext->variableCount(); i != ei; ++i) {
- QString qName;
- if (QV4::Identifier *name = variables[i])
- qName = name->string;
- QV4::Value val = callContext->d()->locals[i];
- collector.collect(&output, QString(), qName, val);
- }
- for (unsigned i = 0, ei = callContext->formalCount(); i != ei; ++i) {
- QString qName;
- if (QV4::Identifier *name = formals[i])
- qName = name->string;
- QV4::ReturnedValue rval = callContext->argument(i);
- QV4::ScopedValue sval(scope, rval);
- collector.collect(&output, QString(), qName, *sval);
+ QV4::ScopedValue thisObject(scope, frame->thisObject());
+ collector.collect(&output, QString(), QStringLiteral("this"), thisObject);
+ QV4::Scoped<QV4::CallContext> callContext(scope, frame->callContext());
+ if (callContext) {
+ QV4::InternalClass *ic = callContext->internalClass();
+ QV4::ScopedValue v(scope);
+ for (uint i = 0; i < ic->size; ++i) {
+ QString name = ic->nameMap[i]->string;
+ v = callContext->d()->locals[i];
+ collector.collect(&output, QString(), name, v);
}
}
@@ -509,15 +500,15 @@ void NativeDebugger::handleVariables(QJsonObject *response, const QJsonObject &a
void NativeDebugger::handleExpressions(QJsonObject *response, const QJsonObject &arguments)
{
TRACE_PROTOCOL("Evaluate expressions");
- QV4::ExecutionContext *executionContext = 0;
- decodeContext(arguments.value(QLatin1String("context")).toString(), &executionContext);
- if (!executionContext) {
- setError(response, QStringLiteral("No execution context passed"));
+ QV4::CppStackFrame *frame = 0;
+ decodeFrame(arguments.value(QLatin1String("context")).toString(), &frame);
+ if (!frame) {
+ setError(response, QStringLiteral("No stack frame passed"));
return;
}
TRACE_PROTOCOL("Context: " << executionContext);
- QV4::ExecutionEngine *engine = executionContext->engine();
+ QV4::ExecutionEngine *engine = frame->v4Function->internalClass->engine;
if (!engine) {
setError(response, QStringLiteral("No execution engine passed"));
return;
@@ -540,8 +531,7 @@ void NativeDebugger::handleExpressions(QJsonObject *response, const QJsonObject
TRACE_PROTOCOL("Evaluate expression: " << expression);
m_runningJob = true;
- evaluateExpression(scope, expression);
- QV4::ScopedValue result(scope, scope.result);
+ QV4::ScopedValue result(scope, evaluateExpression(expression));
m_runningJob = false;
if (result->isUndefined()) {
@@ -592,7 +582,7 @@ void NativeDebugger::handleContinue(QJsonObject *response, Speed speed)
if (!m_returnedValue.isUndefined())
m_returnedValue.set(m_engine, QV4::Encode::undefined());
- m_currentContext.set(m_engine, *m_engine->currentContext);
+ m_currentFrame = m_engine->currentStackFrame;
m_stepping = speed;
}
@@ -602,7 +592,7 @@ void NativeDebugger::maybeBreakAtInstruction()
return;
if (m_stepping == StepOver) {
- if (m_currentContext.asManaged()->d() == m_engine->current)
+ if (m_currentFrame == m_engine->currentStackFrame)
pauseAndWait();
return;
}
@@ -620,7 +610,8 @@ void NativeDebugger::maybeBreakAtInstruction()
if (m_service->m_breakHandler->m_haveBreakPoints) {
if (QV4::Function *function = getFunction()) {
- const int lineNumber = m_engine->current->lineNumber;
+ // lineNumber will be negative for Ret instructions, so those won't match
+ const int lineNumber = m_engine->currentStackFrame->lineNumber();
if (reallyHitTheBreakPoint(function, lineNumber))
pauseAndWait();
}
@@ -633,7 +624,7 @@ void NativeDebugger::enteringFunction()
return;
if (m_stepping == StepIn) {
- m_currentContext.set(m_engine, *m_engine->currentContext);
+ m_currentFrame = m_engine->currentStackFrame;
}
}
@@ -642,8 +633,8 @@ void NativeDebugger::leavingFunction(const QV4::ReturnedValue &retVal)
if (m_runningJob)
return;
- if (m_stepping != NotStepping && m_currentContext.asManaged()->d() == m_engine->current) {
- m_currentContext.set(m_engine, *m_engine->parentContext(m_engine->currentContext));
+ if (m_stepping != NotStepping && m_currentFrame == m_engine->currentStackFrame) {
+ m_currentFrame = m_currentFrame->parent;
m_stepping = StepOver;
m_returnedValue.set(m_engine, retVal);
}
@@ -665,9 +656,8 @@ void NativeDebugger::aboutToThrow()
QV4::Function *NativeDebugger::getFunction() const
{
- QV4::ExecutionContext *context = m_engine->currentContext;
- if (QV4::Function *function = context->getFunction())
- return function;
+ if (m_engine->currentStackFrame)
+ return m_engine->currentStackFrame->v4Function;
else
return m_engine->globalCode;
}
@@ -678,12 +668,11 @@ void NativeDebugger::pauseAndWait()
event.insert(QStringLiteral("event"), QStringLiteral("break"));
event.insert(QStringLiteral("language"), QStringLiteral("js"));
- if (QV4::ExecutionContext *executionContext = m_engine->currentContext) {
- if (QV4::Function *function = executionContext->getFunction()) {
- event.insert(QStringLiteral("file"), function->sourceFile());
- int line = executionContext->d()->lineNumber;
- event.insert(QStringLiteral("line"), (line < 0 ? -line : line));
- }
+ if (QV4::CppStackFrame *frame = m_engine->currentStackFrame) {
+ QV4::Function *function = frame->v4Function;
+ event.insert(QStringLiteral("file"), function->sourceFile());
+ int line = frame->lineNumber();
+ event.insert(QStringLiteral("line"), (line < 0 ? -line : line));
}
m_service->emitAsynchronousMessageToClient(event);
@@ -724,11 +713,10 @@ void QQmlNativeDebugServiceImpl::engineAboutToBeAdded(QJSEngine *engine)
{
TRACE_PROTOCOL("Adding engine" << engine);
if (engine) {
- QV4::ExecutionEngine *ee = QV8Engine::getV4(engine->handle());
+ QV4::ExecutionEngine *ee = engine->handle();
TRACE_PROTOCOL("Adding execution engine" << ee);
if (ee) {
NativeDebugger *debugger = new NativeDebugger(this, ee);
- ee->iselFactory.reset(new QV4::Moth::ISelFactory);
if (state() == Enabled)
ee->setDebugger(debugger);
m_debuggers.append(QPointer<NativeDebugger>(debugger));
@@ -741,7 +729,7 @@ void QQmlNativeDebugServiceImpl::engineAboutToBeRemoved(QJSEngine *engine)
{
TRACE_PROTOCOL("Removing engine" << engine);
if (engine) {
- QV4::ExecutionEngine *executionEngine = QV8Engine::getV4(engine->handle());
+ QV4::ExecutionEngine *executionEngine = engine->handle();
const auto debuggersCopy = m_debuggers;
for (NativeDebugger *debugger : debuggersCopy) {
if (debugger->engine() == executionEngine)
diff --git a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.h b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.h
index 58bf1bc94a..4b4661be2f 100644
--- a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.h
+++ b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.h
@@ -73,14 +73,14 @@ class QQmlNativeDebugServiceImpl : public QQmlNativeDebugService
public:
QQmlNativeDebugServiceImpl(QObject *parent);
- ~QQmlNativeDebugServiceImpl() Q_DECL_OVERRIDE;
+ ~QQmlNativeDebugServiceImpl() override;
- void engineAboutToBeAdded(QJSEngine *engine) Q_DECL_OVERRIDE;
- void engineAboutToBeRemoved(QJSEngine *engine) Q_DECL_OVERRIDE;
+ void engineAboutToBeAdded(QJSEngine *engine) override;
+ void engineAboutToBeRemoved(QJSEngine *engine) override;
- void stateAboutToBeChanged(State state) Q_DECL_OVERRIDE;
+ void stateAboutToBeChanged(State state) override;
- void messageReceived(const QByteArray &message) Q_DECL_OVERRIDE;
+ void messageReceived(const QByteArray &message) override;
void emitAsynchronousMessageToClient(const QJsonObject &message);
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qmldbg_profiler.pro b/src/plugins/qmltooling/qmldbg_profiler/qmldbg_profiler.pro
index 4629a7b81e..ac874b079e 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qmldbg_profiler.pro
+++ b/src/plugins/qmltooling/qmldbg_profiler/qmldbg_profiler.pro
@@ -9,17 +9,12 @@ SOURCES += \
$$PWD/qv4profileradapter.cpp
HEADERS += \
- $$PWD/../shared/qqmlconfigurabledebugservice.h \
- $$PWD/../shared/qqmldebugpacket.h \
$$PWD/qqmlenginecontrolservice.h \
$$PWD/qqmlprofileradapter.h \
$$PWD/qqmlprofilerservice.h \
$$PWD/qqmlprofilerservicefactory.h \
$$PWD/qv4profileradapter.h
-INCLUDEPATH += $$PWD \
- $$PWD/../shared
-
OTHER_FILES += \
$$PWD/qqmlprofilerservice.json
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp
index 9918a95116..4eedb4bd51 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.cpp
@@ -38,7 +38,7 @@
****************************************************************************/
#include "qqmlenginecontrolservice.h"
-#include "qqmldebugpacket.h"
+#include <private/qqmldebugpacket_p.h>
#include <QJSEngine>
QT_BEGIN_NAMESPACE
@@ -53,8 +53,8 @@ void QQmlEngineControlServiceImpl::messageReceived(const QByteArray &message)
{
QMutexLocker lock(&dataMutex);
QQmlDebugPacket d(message);
- int command;
- int engineId;
+ qint32 command;
+ qint32 engineId;
d >> command >> engineId;
QJSEngine *engine = qobject_cast<QJSEngine *>(objectForId(engineId));
if (command == StartWaitingEngine && startingEngines.contains(engine)) {
@@ -112,10 +112,11 @@ void QQmlEngineControlServiceImpl::engineRemoved(QJSEngine *engine)
}
}
-void QQmlEngineControlServiceImpl::sendMessage(QQmlEngineControlServiceImpl::MessageType type, QJSEngine *engine)
+void QQmlEngineControlServiceImpl::sendMessage(QQmlEngineControlServiceImpl::MessageType type,
+ QJSEngine *engine)
{
QQmlDebugPacket d;
- d << int(type) << idForObject(engine);
+ d << static_cast<qint32>(type) << idForObject(engine);
emit messageToClient(name(), d.data());
}
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.h b/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.h
index 6392944519..3c5daa0f4f 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.h
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlenginecontrolservice.h
@@ -81,15 +81,15 @@ protected:
QList<QJSEngine *> stoppingEngines;
bool blockingMode;
- void messageReceived(const QByteArray &) Q_DECL_OVERRIDE;
- void engineAboutToBeAdded(QJSEngine *) Q_DECL_OVERRIDE;
- void engineAboutToBeRemoved(QJSEngine *) Q_DECL_OVERRIDE;
- void engineAdded(QJSEngine *) Q_DECL_OVERRIDE;
- void engineRemoved(QJSEngine *) Q_DECL_OVERRIDE;
+ void messageReceived(const QByteArray &) override;
+ void engineAboutToBeAdded(QJSEngine *) override;
+ void engineAboutToBeRemoved(QJSEngine *) override;
+ void engineAdded(QJSEngine *) override;
+ void engineRemoved(QJSEngine *) override;
void sendMessage(MessageType type, QJSEngine *engine);
- void stateChanged(State) Q_DECL_OVERRIDE;
+ void stateChanged(State) override;
};
QT_END_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp
index d676731ba7..5ff1b1f97e 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.cpp
@@ -38,8 +38,8 @@
****************************************************************************/
#include "qqmlprofileradapter.h"
-#include "qqmldebugpacket.h"
+#include <private/qqmldebugpacket_p.h>
#include <private/qqmldebugserviceinterfaces_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.h b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.h
index 7531cd1dff..b14b72d254 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.h
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofileradapter.h
@@ -62,7 +62,7 @@ public:
QQmlProfilerAdapter(QQmlProfilerService *service, QQmlEnginePrivate *engine);
QQmlProfilerAdapter(QQmlProfilerService *service, QQmlTypeLoader *loader);
qint64 sendMessages(qint64 until, QList<QByteArray> &messages,
- bool trackLocations) Q_DECL_OVERRIDE;
+ bool trackLocations) override;
void receiveData(const QVector<QQmlProfilerData> &new_data,
const QQmlProfiler::LocationHash &locations);
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp
index affd2a417e..1c4daba6af 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp
@@ -41,9 +41,9 @@
#include "qv4profileradapter.h"
#include "qqmlprofileradapter.h"
#include "qqmlprofilerservicefactory.h"
-#include "qqmldebugpacket.h"
#include <private/qjsengine_p.h>
+#include <private/qqmldebugpacket_p.h>
#include <private/qqmldebugpluginmanager_p.h>
#include <QtCore/qurl.h>
@@ -126,7 +126,7 @@ void QQmlProfilerServiceImpl::engineAboutToBeAdded(QJSEngine *engine)
= new QQmlProfilerAdapter(this, &(enginePrivate->typeLoader));
addEngineProfiler(compileAdapter, engine);
}
- QV4ProfilerAdapter *v4Adapter = new QV4ProfilerAdapter(this, QV8Engine::getV4(engine->handle()));
+ QV4ProfilerAdapter *v4Adapter = new QV4ProfilerAdapter(this, engine->handle());
addEngineProfiler(v4Adapter, engine);
QQmlConfigurableDebugService<QQmlProfilerService>::engineAboutToBeAdded(engine);
}
@@ -240,7 +240,7 @@ void QQmlProfilerServiceImpl::startProfiling(QJSEngine *engine, quint64 features
QQmlDebugPacket d;
- d << m_timer.nsecsElapsed() << (int)Event << (int)StartTrace;
+ d << m_timer.nsecsElapsed() << static_cast<qint32>(Event) << static_cast<qint32>(StartTrace);
bool startedAny = false;
if (engine != 0) {
const auto range = qAsConst(m_engineProfilers).equal_range(engine);
@@ -339,7 +339,8 @@ void QQmlProfilerServiceImpl::sendMessages()
QQmlDebugPacket traceEnd;
if (m_waitingForStop) {
- traceEnd << m_timer.nsecsElapsed() << (int)Event << (int)EndTrace;
+ traceEnd << m_timer.nsecsElapsed() << static_cast<qint32>(Event)
+ << static_cast<qint32>(EndTrace);
QSet<QJSEngine *> seen;
for (QQmlAbstractProfilerAdapter *profiler : qAsConst(m_startTimes)) {
@@ -384,7 +385,7 @@ void QQmlProfilerServiceImpl::sendMessages()
if (!stillRunning) {
// Complete is only sent once, when no engines are running anymore.
QQmlDebugPacket ds;
- ds << (qint64)-1 << (int)Complete;
+ ds << static_cast<qint64>(-1) << static_cast<qint32>(Complete);
messages << ds.data();
m_waitingForStop = false;
}
@@ -422,7 +423,7 @@ void QQmlProfilerServiceImpl::messageReceived(const QByteArray &message)
int engineId = -1;
quint64 features = std::numeric_limits<quint64>::max();
bool enabled;
- uint flushInterval = 0;
+ quint32 flushInterval = 0;
stream >> enabled;
if (!stream.atEnd())
stream >> engineId;
@@ -430,7 +431,9 @@ void QQmlProfilerServiceImpl::messageReceived(const QByteArray &message)
stream >> features;
if (!stream.atEnd()) {
stream >> flushInterval;
- m_flushTimer.setInterval(flushInterval);
+ m_flushTimer.setInterval(
+ static_cast<int>(qMin(flushInterval,
+ static_cast<quint32>(std::numeric_limits<int>::max()))));
auto timerStart = static_cast<void(QTimer::*)()>(&QTimer::start);
if (flushInterval > 0) {
connect(&m_flushTimer, &QTimer::timeout, this, &QQmlProfilerServiceImpl::flush);
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h
index bbfc32b681..a5e060a1ab 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h
+++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.h
@@ -51,7 +51,7 @@
// We mean it.
//
-#include "qqmlconfigurabledebugservice.h"
+#include <private/qqmlconfigurabledebugservice_p.h>
#include <private/qqmldebugserviceinterfaces_p.h>
#include <private/qqmlprofilerdefinitions_p.h>
#include <private/qqmlabstractprofileradapter_p.h>
@@ -78,30 +78,30 @@ class QQmlProfilerServiceImpl :
Q_OBJECT
public:
- void engineAboutToBeAdded(QJSEngine *engine) Q_DECL_OVERRIDE;
- void engineAboutToBeRemoved(QJSEngine *engine) Q_DECL_OVERRIDE;
- void engineAdded(QJSEngine *engine) Q_DECL_OVERRIDE;
- void engineRemoved(QJSEngine *engine) Q_DECL_OVERRIDE;
+ void engineAboutToBeAdded(QJSEngine *engine) override;
+ void engineAboutToBeRemoved(QJSEngine *engine) override;
+ void engineAdded(QJSEngine *engine) override;
+ void engineRemoved(QJSEngine *engine) override;
- void addGlobalProfiler(QQmlAbstractProfilerAdapter *profiler) Q_DECL_OVERRIDE;
- void removeGlobalProfiler(QQmlAbstractProfilerAdapter *profiler) Q_DECL_OVERRIDE;
+ void addGlobalProfiler(QQmlAbstractProfilerAdapter *profiler) override;
+ void removeGlobalProfiler(QQmlAbstractProfilerAdapter *profiler) override;
void startProfiling(QJSEngine *engine,
- quint64 features = std::numeric_limits<quint64>::max()) Q_DECL_OVERRIDE;
- void stopProfiling(QJSEngine *engine) Q_DECL_OVERRIDE;
+ quint64 features = std::numeric_limits<quint64>::max()) override;
+ void stopProfiling(QJSEngine *engine) override;
QQmlProfilerServiceImpl(QObject *parent = 0);
- ~QQmlProfilerServiceImpl() Q_DECL_OVERRIDE;
+ ~QQmlProfilerServiceImpl() override;
- void dataReady(QQmlAbstractProfilerAdapter *profiler) Q_DECL_OVERRIDE;
+ void dataReady(QQmlAbstractProfilerAdapter *profiler) override;
signals:
void startFlushTimer();
void stopFlushTimer();
protected:
- virtual void stateAboutToBeChanged(State state) Q_DECL_OVERRIDE;
- virtual void messageReceived(const QByteArray &) Q_DECL_OVERRIDE;
+ void stateAboutToBeChanged(State state) override;
+ void messageReceived(const QByteArray &) override;
private:
friend class QQmlProfilerServiceFactory;
diff --git a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h
index 5d5b83f7ca..7ac378acd9 100644
--- a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h
+++ b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.h
@@ -53,7 +53,7 @@
#include <private/qv4profiling_p.h>
#include <private/qqmlabstractprofileradapter_p.h>
-#include "qqmldebugpacket.h"
+#include <private/qqmldebugpacket_p.h>
#include <QStack>
#include <QList>
diff --git a/src/plugins/qmltooling/qmldbg_quickprofiler/qmldbg_quickprofiler.pro b/src/plugins/qmltooling/qmldbg_quickprofiler/qmldbg_quickprofiler.pro
index 6ca0a184ca..f165917041 100644
--- a/src/plugins/qmltooling/qmldbg_quickprofiler/qmldbg_quickprofiler.pro
+++ b/src/plugins/qmltooling/qmldbg_quickprofiler/qmldbg_quickprofiler.pro
@@ -5,8 +5,6 @@ PLUGIN_TYPE = qmltooling
PLUGIN_CLASS_NAME = QQuickProfilerAdapterFactory
load(qt_plugin)
-INCLUDEPATH += $$PWD/../shared
-
SOURCES += \
$$PWD/qquickprofileradapter.cpp \
$$PWD/qquickprofileradapterfactory.cpp
@@ -14,7 +12,6 @@ SOURCES += \
HEADERS += \
$$PWD/qquickprofileradapter.h \
$$PWD/qquickprofileradapterfactory.h \
- $$PWD/../shared/qqmldebugpacket.h
OTHER_FILES += \
qquickprofileradapter.json
diff --git a/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.cpp b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.cpp
index 35beb0ee0d..a05d11664d 100644
--- a/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.cpp
+++ b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapter.cpp
@@ -38,8 +38,9 @@
****************************************************************************/
#include "qquickprofileradapter.h"
-#include "qqmldebugpacket.h"
+
#include <QCoreApplication>
+#include <private/qqmldebugpacket_p.h>
#include <private/qqmldebugserviceinterfaces_p.h>
#include <private/qquickprofiler_p.h>
diff --git a/src/plugins/qmltooling/qmldbg_server/qmldbg_server.pro b/src/plugins/qmltooling/qmldbg_server/qmldbg_server.pro
index fffdb4c888..d7d24a4d39 100644
--- a/src/plugins/qmltooling/qmldbg_server/qmldbg_server.pro
+++ b/src/plugins/qmltooling/qmldbg_server/qmldbg_server.pro
@@ -5,13 +5,7 @@ SOURCES += \
$$PWD/qqmldebugserver.cpp
HEADERS += \
- $$PWD/qqmldebugserverfactory.h \
- $$PWD/../shared/qqmldebugserver.h \
- $$PWD/../shared/qqmldebugserverconnection.h \
- $$PWD/../shared/qqmldebugpacket.h
-
-INCLUDEPATH += $$PWD \
- $$PWD/../shared
+ $$PWD/qqmldebugserverfactory.h
OTHER_FILES += \
qqmldebugserver.json
diff --git a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
index 9759ad9783..f87ade568b 100644
--- a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
+++ b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp
@@ -37,17 +37,17 @@
**
****************************************************************************/
-#include "qqmldebugserver.h"
#include "qqmldebugserverfactory.h"
-#include "qqmldebugserverconnection.h"
-#include "qqmldebugpacket.h"
+#include <private/qqmldebugserver_p.h>
+#include <private/qqmldebugserverconnection_p.h>
#include <private/qqmldebugservice_p.h>
#include <private/qjsengine_p.h>
#include <private/qqmlglobal_p.h>
#include <private/qqmldebugpluginmanager_p.h>
#include <private/qqmldebugserviceinterfaces_p.h>
#include <private/qpacketprotocol_p.h>
+#include <private/qqmldebugpacket_p.h>
#include <QtCore/QAtomicInt>
#include <QtCore/QDir>
@@ -114,7 +114,7 @@ public:
return m_pluginName;
}
- void run();
+ void run() override;
private:
QQmlDebugServerImpl *m_server;
@@ -131,19 +131,19 @@ class QQmlDebugServerImpl : public QQmlDebugServer
public:
QQmlDebugServerImpl();
- bool blockingMode() const Q_DECL_OVERRIDE;
+ bool blockingMode() const override;
- QQmlDebugService *service(const QString &name) const Q_DECL_OVERRIDE;
+ QQmlDebugService *service(const QString &name) const override;
- void addEngine(QJSEngine *engine) Q_DECL_OVERRIDE;
- void removeEngine(QJSEngine *engine) Q_DECL_OVERRIDE;
- bool hasEngine(QJSEngine *engine) const Q_DECL_OVERRIDE;
+ void addEngine(QJSEngine *engine) override;
+ void removeEngine(QJSEngine *engine) override;
+ bool hasEngine(QJSEngine *engine) const override;
- bool addService(const QString &name, QQmlDebugService *service) Q_DECL_OVERRIDE;
- bool removeService(const QString &name) Q_DECL_OVERRIDE;
+ bool addService(const QString &name, QQmlDebugService *service) override;
+ bool removeService(const QString &name) override;
- bool open(const QVariantHash &configuration) Q_DECL_OVERRIDE;
- void setDevice(QIODevice *socket) Q_DECL_OVERRIDE;
+ bool open(const QVariantHash &configuration) override;
+ void setDevice(QIODevice *socket) override;
void parseArguments();
@@ -767,4 +767,3 @@ QQmlDebugConnector *QQmlDebugServerFactory::create(const QString &key)
QT_END_NAMESPACE
#include "qqmldebugserver.moc"
-#include "moc_qqmldebugserver.cpp"
diff --git a/src/plugins/qmltooling/qmldbg_tcp/qmldbg_tcp.pro b/src/plugins/qmltooling/qmldbg_tcp/qmldbg_tcp.pro
index 1face1813e..a0e9d06fd5 100644
--- a/src/plugins/qmltooling/qmldbg_tcp/qmldbg_tcp.pro
+++ b/src/plugins/qmltooling/qmldbg_tcp/qmldbg_tcp.pro
@@ -5,12 +5,7 @@ SOURCES += \
$$PWD/qtcpserverconnection.cpp
HEADERS += \
- $$PWD/qtcpserverconnectionfactory.h \
- $$PWD/../shared/qqmldebugserver.h \
- $$PWD/../shared/qqmldebugserverconnection.h
-
-INCLUDEPATH += $$PWD \
- $$PWD/../shared
+ $$PWD/qtcpserverconnectionfactory.h
OTHER_FILES += \
$$PWD/qtcpserverconnection.json
diff --git a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp
index b305c3f535..c2aafda863 100644
--- a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp
+++ b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp
@@ -38,7 +38,8 @@
****************************************************************************/
#include "qtcpserverconnectionfactory.h"
-#include "qqmldebugserver.h"
+
+#include <private/qqmldebugserver_p.h>
#include <QtCore/qplugin.h>
#include <QtNetwork/qtcpserver.h>
@@ -55,15 +56,15 @@ public:
QTcpServerConnection();
~QTcpServerConnection();
- void setServer(QQmlDebugServer *server);
- bool setPortRange(int portFrom, int portTo, bool block, const QString &hostaddress);
- bool setFileName(const QString &fileName, bool block);
+ void setServer(QQmlDebugServer *server) override;
+ bool setPortRange(int portFrom, int portTo, bool block, const QString &hostaddress) override;
+ bool setFileName(const QString &fileName, bool block) override;
- bool isConnected() const;
- void disconnect();
+ bool isConnected() const override;
+ void disconnect() override;
- void waitForConnection();
- void flush();
+ void waitForConnection() override;
+ void flush() override;
private:
void newConnection();
diff --git a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnectionfactory.h b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnectionfactory.h
index d3b0e00584..d1282c9d47 100644
--- a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnectionfactory.h
+++ b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnectionfactory.h
@@ -40,7 +40,7 @@
#ifndef QTCPSERVERCONNECTIONFACTORY_H
#define QTCPSERVERCONNECTIONFACTORY_H
-#include "qqmldebugserverconnection.h"
+#include <private/qqmldebugserverconnection_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/qmltooling/qmltooling.pro b/src/plugins/qmltooling/qmltooling.pro
index 27c51b53c8..119415372b 100644
--- a/src/plugins/qmltooling/qmltooling.pro
+++ b/src/plugins/qmltooling/qmltooling.pro
@@ -14,24 +14,23 @@ qmldbg_native.depends = packetprotocol
qmldbg_server.depends = packetprotocol
qtConfig(qml-network) {
+ qtConfig(localserver): SUBDIRS += qmldbg_local
+
SUBDIRS += \
- qmldbg_local \
qmldbg_tcp
}
-qtConfig(qml-interpreter) {
- # Services
- SUBDIRS += \
- qmldbg_debugger \
- qmldbg_profiler \
- qmldbg_messages \
- qmldbg_nativedebugger
-
- qmldbg_debugger.depends = packetprotocol
- qmldbg_profiler.depends = packetprotocol
- qmldbg_messages.depends = packetprotocol
- qmldbg_nativedebugger.depends = packetprotocol
-}
+# Services
+SUBDIRS += \
+ qmldbg_messages \
+ qmldbg_profiler \
+ qmldbg_debugger \
+ qmldbg_nativedebugger
+
+qmldbg_messages.depends = packetprotocol
+qmldbg_profiler.depends = packetprotocol
+qmldbg_debugger.depends = packetprotocol
+qmldbg_nativedebugger.depends = packetprotocol
qtHaveModule(quick) {
SUBDIRS += \
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials.cpp
index 3351486bc6..312e8c19cd 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials.cpp
+++ b/src/plugins/scenegraph/d3d12/qsgd3d12builtinmaterials.cpp
@@ -460,8 +460,8 @@ QSGD3D12Material::UpdateResults QSGD3D12SmoothTextureMaterial::updatePipeline(co
QSGD3D12TextMaterial::QSGD3D12TextMaterial(StyleType styleType, QSGD3D12RenderContext *rc,
const QRawFont &font, QFontEngine::GlyphFormat glyphFormat)
: m_styleType(styleType),
- m_font(font),
- m_rc(rc)
+ m_rc(rc),
+ m_font(font)
{
setFlag(Blending, true);
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp
index 2b4c94b749..75bde2c66b 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp
+++ b/src/plugins/scenegraph/d3d12/qsgd3d12engine.cpp
@@ -2077,7 +2077,7 @@ void QSGD3D12EnginePrivate::queueDraw(const QSGD3D12Engine::DrawParams &params)
? buffers[indexBufIdx].d[currentPFrameIndex].buffer.Get() : nullptr;
if (!skip && params.mode != tframeData.drawingMode) {
- D3D_PRIMITIVE_TOPOLOGY topology;
+ D3D_PRIMITIVE_TOPOLOGY topology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
switch (params.mode) {
case QSGGeometry::DrawPoints:
topology = D3D_PRIMITIVE_TOPOLOGY_POINTLIST;
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12engine_p_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12engine_p_p.h
index 1048ed63e7..a95cbb1cbb 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12engine_p_p.h
+++ b/src/plugins/scenegraph/d3d12/qsgd3d12engine_p_p.h
@@ -105,6 +105,7 @@ public:
struct DeviceLossObserver {
virtual void deviceLost() = 0;
+ virtual ~DeviceLossObserver() = default;
};
void registerDeviceLossObserver(DeviceLossObserver *observer);
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12layer_p.h b/src/plugins/scenegraph/d3d12/qsgd3d12layer_p.h
index f1ab580a84..f828843227 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12layer_p.h
+++ b/src/plugins/scenegraph/d3d12/qsgd3d12layer_p.h
@@ -86,6 +86,7 @@ public:
void setDevicePixelRatio(qreal ratio) override;
void setMirrorHorizontal(bool mirror) override;
void setMirrorVertical(bool mirror) override;
+ void setSamples(int) override { }
public Q_SLOTS:
void markDirtyTexture() override;
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12renderer.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12renderer.cpp
index c0f111ee83..c38c616ae6 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12renderer.cpp
+++ b/src/plugins/scenegraph/d3d12/qsgd3d12renderer.cpp
@@ -69,10 +69,10 @@ public:
QSGD3D12Renderer::QSGD3D12Renderer(QSGRenderContext *context)
: QSGRenderer(context),
- m_renderList(16),
m_vboData(1024),
m_iboData(256),
- m_cboData(4096)
+ m_cboData(4096),
+ m_renderList(16)
{
setNodeUpdater(new DummyUpdater);
}
@@ -447,10 +447,10 @@ void QSGD3D12Renderer::renderElements()
struct RenderNodeState : public QSGRenderNode::RenderState
{
const QMatrix4x4 *projectionMatrix() const override { return m_projectionMatrix; }
- QRect scissorRect() const { return m_scissorRect; }
- bool scissorEnabled() const { return m_scissorEnabled; }
- int stencilValue() const { return m_stencilValue; }
- bool stencilEnabled() const { return m_stencilEnabled; }
+ QRect scissorRect() const override { return m_scissorRect; }
+ bool scissorEnabled() const override { return m_scissorEnabled; }
+ int stencilValue() const override { return m_stencilValue; }
+ bool stencilEnabled() const override { return m_stencilEnabled; }
const QRegion *clipRegion() const override { return nullptr; }
const QMatrix4x4 *m_projectionMatrix;
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12renderloop.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12renderloop.cpp
index 0d3f78d95d..0d501f48c0 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12renderloop.cpp
+++ b/src/plugins/scenegraph/d3d12/qsgd3d12renderloop.cpp
@@ -145,9 +145,6 @@ void QSGD3D12RenderLoop::windowDestroyed(QQuickWindow *window)
rc->invalidate();
- if (m_windows.isEmpty())
- QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
-
delete rc;
delete engine;
diff --git a/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp b/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp
index 62771eb8f9..b4fb721a8b 100644
--- a/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp
+++ b/src/plugins/scenegraph/d3d12/qsgd3d12shadereffectnode.cpp
@@ -171,7 +171,7 @@ void QSGD3D12ShaderLinker::linkTextureSubRects()
// texture bind point.
for (Constant &c : constants) {
if (c.specialType == QSGShaderEffectNode::VariableData::SubRect) {
- if (c.value.type() == QMetaType::QByteArray) {
+ if (c.value.type() == QVariant::ByteArray) {
const QByteArray name = c.value.toByteArray();
if (!textureNameMap.contains(name))
qWarning("ShaderEffect: qt_SubRect_%s refers to unknown source texture", qPrintable(name));
diff --git a/src/plugins/scenegraph/openvg/qsgopenvglayer.h b/src/plugins/scenegraph/openvg/qsgopenvglayer.h
index 2af0bfb40f..8deedc3347 100644
--- a/src/plugins/scenegraph/openvg/qsgopenvglayer.h
+++ b/src/plugins/scenegraph/openvg/qsgopenvglayer.h
@@ -83,6 +83,7 @@ public:
void setDevicePixelRatio(qreal ratio) override;
void setMirrorHorizontal(bool mirror) override;
void setMirrorVertical(bool mirror) override;
+ void setSamples(int) override { }
public slots:
void markDirtyTexture() override;
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgrenderloop.cpp b/src/plugins/scenegraph/openvg/qsgopenvgrenderloop.cpp
index d31156f0eb..9493920100 100644
--- a/src/plugins/scenegraph/openvg/qsgopenvgrenderloop.cpp
+++ b/src/plugins/scenegraph/openvg/qsgopenvgrenderloop.cpp
@@ -91,7 +91,6 @@ void QSGOpenVGRenderLoop::windowDestroyed(QQuickWindow *window)
rc->invalidate();
delete vg;
vg = nullptr;
- QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
} else if (vg && window == vg->window()) {
vg->doneCurrent();
}
diff --git a/src/qml/compiler/compiler.pri b/src/qml/compiler/compiler.pri
index d9b985e33b..2ca0c39acc 100644
--- a/src/qml/compiler/compiler.pri
+++ b/src/qml/compiler/compiler.pri
@@ -2,26 +2,26 @@ INCLUDEPATH += $$PWD
INCLUDEPATH += $$OUT_PWD
HEADERS += \
+ $$PWD/qv4bytecodegenerator_p.h \
$$PWD/qv4compileddata_p.h \
$$PWD/qv4compiler_p.h \
+ $$PWD/qv4compilercontext_p.h \
+ $$PWD/qv4compilercontrolflow_p.h \
+ $$PWD/qv4compilerscanfunctions_p.h \
$$PWD/qv4codegen_p.h \
- $$PWD/qv4isel_p.h \
- $$PWD/qv4jsir_p.h \
- $$PWD/qv4isel_util_p.h \
- $$PWD/qv4ssa_p.h \
$$PWD/qqmlirbuilder_p.h \
$$PWD/qqmltypecompiler_p.h \
- $$PWD/qv4jssimplifier_p.h
+ $$PWD/qv4instr_moth_p.h
SOURCES += \
+ $$PWD/qv4bytecodegenerator.cpp \
$$PWD/qv4compileddata.cpp \
$$PWD/qv4compiler.cpp \
+ $$PWD/qv4compilercontext.cpp \
+ $$PWD/qv4compilerscanfunctions.cpp \
$$PWD/qv4codegen.cpp \
- $$PWD/qv4isel_p.cpp \
- $$PWD/qv4jsir.cpp \
- $$PWD/qv4ssa.cpp \
$$PWD/qqmlirbuilder.cpp \
- $$PWD/qv4jssimplifier.cpp
+ $$PWD/qv4instr_moth.cpp
!qmldevtools_build {
@@ -44,15 +44,6 @@ else: SOURCES += $$PWD/qv4compilationunitmapper_win.cpp
qtConfig(private_tests):qtConfig(dlopen): QMAKE_USE_PRIVATE += libdl
}
-qmldevtools_build|qtConfig(qml-interpreter) {
- HEADERS += \
- $$PWD/qv4instr_moth_p.h \
- $$PWD/qv4isel_moth_p.h
- SOURCES += \
- $$PWD/qv4instr_moth.cpp \
- $$PWD/qv4isel_moth.cpp
-}
-
gcc {
equals(QT_GCC_MAJOR_VERSION, 5): QMAKE_CXXFLAGS += -fno-strict-aliasing
}
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index e82fe71934..6c8ca4bbfc 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -43,8 +43,10 @@
#include <private/qv4compileddata_p.h>
#include <private/qqmljsparser_p.h>
#include <private/qqmljslexer_p.h>
+#include <private/qv4compilerscanfunctions_p.h>
#include <QCoreApplication>
#include <QCryptographicHash>
+#include <cmath>
#ifndef V4_BOOTSTRAP
#include <private/qqmlglobal_p.h>
@@ -60,7 +62,7 @@ QT_USE_NAMESPACE
static const quint32 emptyStringIndex = 0;
-#ifndef V4_BOOTSTRAP
+#if 0 //ndef V4_BOOTSTRAP
DEFINE_BOOL_CONFIG_OPTION(lookupHints, QML_LOOKUP_HINTS);
#endif // V4_BOOTSTRAP
@@ -86,6 +88,7 @@ void Object::init(QQmlJS::MemoryPool *pool, int typeNameIndex, int idIndex, cons
flags = QV4::CompiledData::Object::NoFlag;
properties = pool->New<PoolList<Property> >();
aliases = pool->New<PoolList<Alias> >();
+ qmlEnums = pool->New<PoolList<Enum>>();
qmlSignals = pool->New<PoolList<Signal> >();
bindings = pool->New<PoolList<Binding> >();
functions = pool->New<PoolList<Function> >();
@@ -118,6 +121,21 @@ QString Object::sanityCheckFunctionNames(const QSet<QString> &illegalNames, QQml
return QString(); // no error
}
+QString Object::appendEnum(Enum *enumeration)
+{
+ Object *target = declarationsOverride;
+ if (!target)
+ target = this;
+
+ for (Enum *e = qmlEnums->first; e; e = e->next) {
+ if (e->nameIndex == enumeration->nameIndex)
+ return tr("Duplicate scoped enum name");
+ }
+
+ target->qmlEnums->append(enumeration);
+ return QString(); // no error
+}
+
QString Object::appendSignal(Signal *signal)
{
Object *target = declarationsOverride;
@@ -711,6 +729,52 @@ static QStringList astNodeToStringList(QQmlJS::AST::Node *node)
return QStringList();
}
+bool IRBuilder::visit(QQmlJS::AST::UiEnumDeclaration *node)
+{
+ Enum *enumeration = New<Enum>();
+ QString enumName = node->name.toString();
+ enumeration->nameIndex = registerString(enumName);
+
+ if (enumName.at(0).isLower())
+ COMPILE_EXCEPTION(node->enumToken, tr("Scoped enum names must begin with an upper case letter"));
+
+ enumeration->location.line = node->enumToken.startLine;
+ enumeration->location.column = node->enumToken.startColumn;
+
+ enumeration->enumValues = New<PoolList<EnumValue>>();
+
+ QQmlJS::AST::UiEnumMemberList *e = node->members;
+ while (e) {
+ EnumValue *enumValue = New<EnumValue>();
+ QString member = e->member.toString();
+ enumValue->nameIndex = registerString(member);
+ if (member.at(0).isLower())
+ COMPILE_EXCEPTION(e->memberToken, tr("Enum names must begin with an upper case letter"));
+
+ double part;
+ if (std::modf(e->value, &part) != 0.0)
+ COMPILE_EXCEPTION(e->valueToken, tr("Enum value must be an integer"));
+ if (e->value > std::numeric_limits<qint32>::max() || e->value < std::numeric_limits<qint32>::min())
+ COMPILE_EXCEPTION(e->valueToken, tr("Enum value out of range"));
+ enumValue->value = e->value;
+
+ enumValue->location.line = e->memberToken.startLine;
+ enumValue->location.column = e->memberToken.startColumn;
+ enumeration->enumValues->append(enumValue);
+
+ e = e->next;
+ }
+
+ QString error = _object->appendEnum(enumeration);
+ if (!error.isEmpty()) {
+ recordError(node->enumToken, error);
+ return false;
+ }
+
+ return false;
+}
+
+
bool IRBuilder::visit(QQmlJS::AST::UiPublicMember *node)
{
static const struct TypeNameToType {
@@ -1004,13 +1068,18 @@ void IRBuilder::setBindingValue(QV4::CompiledData::Binding *binding, QQmlJS::AST
} else if (QQmlJS::AST::NumericLiteral *lit = QQmlJS::AST::cast<QQmlJS::AST::NumericLiteral *>(expr)) {
binding->type = QV4::CompiledData::Binding::Type_Number;
binding->setNumberValueInternal(lit->value);
- } else {
-
- if (QQmlJS::AST::UnaryMinusExpression *unaryMinus = QQmlJS::AST::cast<QQmlJS::AST::UnaryMinusExpression *>(expr)) {
- if (QQmlJS::AST::NumericLiteral *lit = QQmlJS::AST::cast<QQmlJS::AST::NumericLiteral *>(unaryMinus->expression)) {
- binding->type = QV4::CompiledData::Binding::Type_Number;
- binding->setNumberValueInternal(-lit->value);
- }
+ } else if (QQmlJS::AST::CallExpression *call = QQmlJS::AST::cast<QQmlJS::AST::CallExpression *>(expr)) {
+ if (QQmlJS::AST::IdentifierExpression *base = QQmlJS::AST::cast<QQmlJS::AST::IdentifierExpression *>(call->base)) {
+ tryGeneratingTranslationBinding(base->name, call->arguments, binding);
+ // If it wasn't a translation binding, a normal script binding will be generated
+ // below.
+ }
+ } else if (QQmlJS::AST::cast<QQmlJS::AST::FunctionExpression *>(expr)) {
+ binding->flags |= QV4::CompiledData::Binding::IsFunctionExpression;
+ } else if (QQmlJS::AST::UnaryMinusExpression *unaryMinus = QQmlJS::AST::cast<QQmlJS::AST::UnaryMinusExpression *>(expr)) {
+ if (QQmlJS::AST::NumericLiteral *lit = QQmlJS::AST::cast<QQmlJS::AST::NumericLiteral *>(unaryMinus->expression)) {
+ binding->type = QV4::CompiledData::Binding::Type_Number;
+ binding->setNumberValueInternal(-lit->value);
}
}
}
@@ -1032,6 +1101,121 @@ void IRBuilder::setBindingValue(QV4::CompiledData::Binding *binding, QQmlJS::AST
}
}
+void IRBuilder::tryGeneratingTranslationBinding(const QStringRef &base, AST::ArgumentList *args, QV4::CompiledData::Binding *binding)
+{
+ if (base == QLatin1String("qsTr")) {
+ QV4::CompiledData::TranslationData translationData;
+ translationData.number = -1;
+ translationData.commentIndex = 0; // empty string
+
+ if (!args || !args->expression)
+ return; // no arguments, stop
+
+ QStringRef translation;
+ if (QQmlJS::AST::StringLiteral *arg1 = QQmlJS::AST::cast<QQmlJS::AST::StringLiteral *>(args->expression)) {
+ translation = arg1->value;
+ } else {
+ return; // first argument is not a string, stop
+ }
+
+ args = args->next;
+
+ if (args) {
+ QQmlJS::AST::StringLiteral *arg2 = QQmlJS::AST::cast<QQmlJS::AST::StringLiteral *>(args->expression);
+ if (!arg2)
+ return; // second argument is not a string, stop
+ translationData.commentIndex = jsGenerator->registerString(arg2->value.toString());
+
+ args = args->next;
+ if (args) {
+ if (QQmlJS::AST::NumericLiteral *arg3 = QQmlJS::AST::cast<QQmlJS::AST::NumericLiteral *>(args->expression)) {
+ translationData.number = int(arg3->value);
+ args = args->next;
+ } else {
+ return; // third argument is not a translation number, stop
+ }
+ }
+ }
+
+ if (args)
+ return; // too many arguments, stop
+
+ binding->type = QV4::CompiledData::Binding::Type_Translation;
+ binding->stringIndex = jsGenerator->registerString(translation.toString());
+ binding->value.translationData = translationData;
+ } else if (base == QLatin1String("qsTrId")) {
+ QV4::CompiledData::TranslationData translationData;
+ translationData.number = -1;
+ translationData.commentIndex = 0; // empty string, but unused
+
+ if (!args || !args->expression)
+ return; // no arguments, stop
+
+ QStringRef id;
+ if (QQmlJS::AST::StringLiteral *arg1 = QQmlJS::AST::cast<QQmlJS::AST::StringLiteral *>(args->expression)) {
+ id = arg1->value;
+ } else {
+ return; // first argument is not a string, stop
+ }
+
+ args = args->next;
+
+ if (args) {
+ if (QQmlJS::AST::NumericLiteral *arg3 = QQmlJS::AST::cast<QQmlJS::AST::NumericLiteral *>(args->expression)) {
+ translationData.number = int(arg3->value);
+ args = args->next;
+ } else {
+ return; // third argument is not a translation number, stop
+ }
+ }
+
+ if (args)
+ return; // too many arguments, stop
+
+ binding->type = QV4::CompiledData::Binding::Type_TranslationById;
+ binding->stringIndex = jsGenerator->registerString(id.toString());
+ binding->value.translationData = translationData;
+ } else if (base == QLatin1String("QT_TR_NOOP") || base == QLatin1String("QT_TRID_NOOP")) {
+ if (!args || !args->expression)
+ return; // no arguments, stop
+
+ QStringRef str;
+ if (QQmlJS::AST::StringLiteral *arg1 = QQmlJS::AST::cast<QQmlJS::AST::StringLiteral *>(args->expression)) {
+ str = arg1->value;
+ } else {
+ return; // first argument is not a string, stop
+ }
+
+ args = args->next;
+ if (args)
+ return; // too many arguments, stop
+
+ binding->type = QV4::CompiledData::Binding::Type_String;
+ binding->stringIndex = jsGenerator->registerString(str.toString());
+ } else if (base == QLatin1String("QT_TRANSLATE_NOOP")) {
+ if (!args || !args->expression)
+ return; // no arguments, stop
+
+ args = args->next;
+ if (!args || !args->expression)
+ return; // no second arguments, stop
+
+ QStringRef str;
+ if (QQmlJS::AST::StringLiteral *arg2 = QQmlJS::AST::cast<QQmlJS::AST::StringLiteral *>(args->expression)) {
+ str = arg2->value;
+ } else {
+ return; // first argument is not a string, stop
+ }
+
+ args = args->next;
+ if (args)
+ return; // too many arguments, stop
+
+ binding->type = QV4::CompiledData::Binding::Type_String;
+ binding->stringIndex = jsGenerator->registerString(str.toString());
+ }
+}
+
void IRBuilder::appendBinding(QQmlJS::AST::UiQualifiedId *name, QQmlJS::AST::Statement *value)
{
const QQmlJS::AST::SourceLocation qualifiedNameLocation = name->identifierToken;
@@ -1377,13 +1561,19 @@ QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, const QV4:
int objectsSize = 0;
for (Object *o : qAsConst(output.objects)) {
objectOffsets.insert(o, unitSize + importSize + objectOffsetTableSize + objectsSize);
- objectsSize += QV4::CompiledData::Object::calculateSizeExcludingSignals(o->functionCount(), o->propertyCount(), o->aliasCount(), o->signalCount(), o->bindingCount(), o->namedObjectsInComponent.count);
+ objectsSize += QV4::CompiledData::Object::calculateSizeExcludingSignalsAndEnums(o->functionCount(), o->propertyCount(), o->aliasCount(), o->enumCount(), o->signalCount(), o->bindingCount(), o->namedObjectsInComponent.count);
int signalTableSize = 0;
for (const Signal *s = o->firstSignal(); s; s = s->next)
signalTableSize += QV4::CompiledData::Signal::calculateSize(s->parameters->count);
objectsSize += signalTableSize;
+
+ int enumTableSize = 0;
+ for (const Enum *e = o->firstEnum(); e; e = e->next)
+ enumTableSize += QV4::CompiledData::Enum::calculateSize(e->enumValues->count);
+
+ objectsSize += enumTableSize;
}
const int totalSize = unitSize + importSize + objectOffsetTableSize + objectsSize + output.jsGenerator.stringTable.sizeOfTableAndData();
@@ -1429,7 +1619,7 @@ QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, const QV4:
}
// write objects
- QV4::CompiledData::LEUInt32 *objectTable = reinterpret_cast<QV4::CompiledData::LEUInt32*>(data + qmlUnit->offsetToObjects);
+ quint32_le *objectTable = reinterpret_cast<quint32_le*>(data + qmlUnit->offsetToObjects);
char *objectPtr = data + qmlUnit->offsetToObjects + objectOffsetTableSize;
for (int i = 0; i < output.objects.count(); ++i) {
const Object *o = output.objects.at(i);
@@ -1459,6 +1649,10 @@ QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, const QV4:
objectToWrite->offsetToAliases = nextOffset;
nextOffset += objectToWrite->nAliases * sizeof(QV4::CompiledData::Alias);
+ objectToWrite->nEnums = o->enumCount();
+ objectToWrite->offsetToEnums = nextOffset;
+ nextOffset += objectToWrite->nEnums * sizeof(quint32);
+
objectToWrite->nSignals = o->signalCount();
objectToWrite->offsetToSignals = nextOffset;
nextOffset += objectToWrite->nSignals * sizeof(quint32);
@@ -1471,7 +1665,7 @@ QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, const QV4:
objectToWrite->offsetToNamedObjectsInComponent = nextOffset;
nextOffset += objectToWrite->nNamedObjectsInComponent * sizeof(quint32);
- QV4::CompiledData::LEUInt32 *functionsTable = reinterpret_cast<QV4::CompiledData::LEUInt32*>(objectPtr + objectToWrite->offsetToFunctions);
+ quint32_le *functionsTable = reinterpret_cast<quint32_le *>(objectPtr + objectToWrite->offsetToFunctions);
for (const Function *f = o->firstFunction(); f; f = f->next)
*functionsTable++ = o->runtimeFunctionIndices.at(f->index);
@@ -1497,7 +1691,7 @@ QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, const QV4:
bindingPtr = writeBindings(bindingPtr, o, &QV4::CompiledData::Binding::isValueBindingToAlias);
Q_ASSERT((bindingPtr - objectToWrite->offsetToBindings - objectPtr) / sizeof(QV4::CompiledData::Binding) == unsigned(o->bindingCount()));
- QV4::CompiledData::LEUInt32 *signalOffsetTable = reinterpret_cast<QV4::CompiledData::LEUInt32*>(objectPtr + objectToWrite->offsetToSignals);
+ quint32_le *signalOffsetTable = reinterpret_cast<quint32_le *>(objectPtr + objectToWrite->offsetToSignals);
quint32 signalTableSize = 0;
char *signalPtr = objectPtr + nextOffset;
for (const Signal *s = o->firstSignal(); s; s = s->next) {
@@ -1516,14 +1710,36 @@ QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, const QV4:
signalTableSize += size;
signalPtr += size;
}
+ nextOffset += signalTableSize;
+
+ quint32_le *enumOffsetTable = reinterpret_cast<quint32_le*>(objectPtr + objectToWrite->offsetToEnums);
+ quint32 enumTableSize = 0;
+ char *enumPtr = objectPtr + nextOffset;
+ for (const Enum *e = o->firstEnum(); e; e = e->next) {
+ *enumOffsetTable++ = enumPtr - objectPtr;
+ QV4::CompiledData::Enum *enumToWrite = reinterpret_cast<QV4::CompiledData::Enum*>(enumPtr);
+
+ enumToWrite->nameIndex = e->nameIndex;
+ enumToWrite->location = e->location;
+ enumToWrite->nEnumValues = e->enumValues->count;
+
+ QV4::CompiledData::EnumValue *enumValueToWrite = reinterpret_cast<QV4::CompiledData::EnumValue*>(enumPtr + sizeof(*enumToWrite));
+ for (EnumValue *enumValue = e->enumValues->first; enumValue; enumValue = enumValue->next, ++enumValueToWrite)
+ *enumValueToWrite = *enumValue;
+
+ int size = QV4::CompiledData::Enum::calculateSize(e->enumValues->count);
+ enumTableSize += size;
+ enumPtr += size;
+ }
- QV4::CompiledData::LEUInt32 *namedObjectInComponentPtr = reinterpret_cast<QV4::CompiledData::LEUInt32*>(objectPtr + objectToWrite->offsetToNamedObjectsInComponent);
+ quint32_le *namedObjectInComponentPtr = reinterpret_cast<quint32_le *>(objectPtr + objectToWrite->offsetToNamedObjectsInComponent);
for (int i = 0; i < o->namedObjectsInComponent.count; ++i) {
*namedObjectInComponentPtr++ = o->namedObjectsInComponent.at(i);
}
- objectPtr += QV4::CompiledData::Object::calculateSizeExcludingSignals(o->functionCount(), o->propertyCount(), o->aliasCount(), o->signalCount(), o->bindingCount(), o->namedObjectsInComponent.count);
+ objectPtr += QV4::CompiledData::Object::calculateSizeExcludingSignalsAndEnums(o->functionCount(), o->propertyCount(), o->aliasCount(), o->enumCount(), o->signalCount(), o->bindingCount(), o->namedObjectsInComponent.count);
objectPtr += signalTableSize;
+ objectPtr += enumTableSize;
}
// enable flag if we encountered pragma Singleton
@@ -1555,11 +1771,11 @@ char *QmlUnitGenerator::writeBindings(char *bindingPtr, const Object *o, Binding
return bindingPtr;
}
-JSCodeGen::JSCodeGen(const QString &fileName, const QString &finalUrl, const QString &sourceCode,
- QV4::IR::Module *jsModule, QQmlJS::Engine *jsEngine,
+JSCodeGen::JSCodeGen(const QString &sourceCode, QV4::Compiler::JSUnitGenerator *jsUnitGenerator,
+ QV4::Compiler::Module *jsModule, QQmlJS::Engine *jsEngine,
QQmlJS::AST::UiProgram *qmlRoot, QQmlTypeNameCache *imports,
const QV4::Compiler::StringTableGenerator *stringPool, const QSet<QString> &globalNames)
- : QQmlJS::Codegen(/*strict mode*/false)
+ : QV4::Compiler::Codegen(jsUnitGenerator, /*strict mode*/false)
, sourceCode(sourceCode)
, jsEngine(jsEngine)
, qmlRoot(qmlRoot)
@@ -1568,13 +1784,11 @@ JSCodeGen::JSCodeGen(const QString &fileName, const QString &finalUrl, const QSt
, _disableAcceleratedLookups(false)
, _contextObject(0)
, _scopeObject(0)
- , _qmlContextTemp(-1)
- , _importedScriptsTemp(-1)
+ , _qmlContextSlot(-1)
+ , _importedScriptsSlot(-1)
, m_globalNames(globalNames)
{
_module = jsModule;
- _module->setFileName(fileName);
- _module->setFinalUrl(finalUrl);
_fileNameIsUrl = true;
}
@@ -1594,8 +1808,8 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil
{
QVector<int> runtimeFunctionIndices(functions.size());
- ScanFunctions scan(this, sourceCode, GlobalCode);
- scan.enterEnvironment(0, QmlBinding);
+ QV4::Compiler::ScanFunctions scan(this, sourceCode, QV4::Compiler::GlobalCode);
+ scan.enterEnvironment(0, QV4::Compiler::QmlBinding);
scan.enterQmlScope(qmlRoot, QStringLiteral("context scope"));
for (const CompiledFunctionOrExpression &f : functions) {
Q_ASSERT(f.node != qmlRoot);
@@ -1604,7 +1818,7 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil
if (function)
scan.enterQmlFunction(function);
else
- scan.enterEnvironment(f.node, QmlBinding);
+ scan.enterEnvironment(f.node, QV4::Compiler::QmlBinding);
scan(function ? function->body : f.node);
scan.leaveEnvironment();
@@ -1612,8 +1826,7 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil
scan.leaveEnvironment();
scan.leaveEnvironment();
- _env = 0;
- _function = _module->functions.at(defineFunction(QStringLiteral("context scope"), qmlRoot, 0, 0));
+ _context = 0;
for (int i = 0; i < functions.count(); ++i) {
const CompiledFunctionOrExpression &qmlFunction = functions.at(i);
@@ -1655,35 +1868,36 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil
runtimeFunctionIndices[i] = idx;
}
- qDeleteAll(_envMap);
- _envMap.clear();
return runtimeFunctionIndices;
}
+int JSCodeGen::defineFunction(const QString &name, AST::Node *ast, AST::FormalParameterList *formals, AST::SourceElements *body)
+{
+ int qmlContextTemp = -1;
+ int importedScriptsTemp = -1;
+ qSwap(_qmlContextSlot, qmlContextTemp);
+ qSwap(_importedScriptsSlot, importedScriptsTemp);
+
+ int result = Codegen::defineFunction(name, ast, formals, body);
+
+ qSwap(_importedScriptsSlot, importedScriptsTemp);
+ qSwap(_qmlContextSlot, qmlContextTemp);
+
+ return result;
+}
+
#ifndef V4_BOOTSTRAP
-QQmlPropertyData *JSCodeGen::lookupQmlCompliantProperty(QQmlPropertyCache *cache, const QString &name, bool *propertyExistsButForceNameLookup)
+QQmlPropertyData *JSCodeGen::lookupQmlCompliantProperty(QQmlPropertyCache *cache, const QString &name)
{
- if (propertyExistsButForceNameLookup)
- *propertyExistsButForceNameLookup = false;
QQmlPropertyData *pd = cache->property(name, /*object*/0, /*context*/0);
// Q_INVOKABLEs can't be FINAL, so we have to look them up at run-time
- if (pd && pd->isFunction()) {
- if (propertyExistsButForceNameLookup)
- *propertyExistsButForceNameLookup = true;
- pd = 0;
- }
+ if (!pd || pd->isFunction())
+ return 0;
- if (pd && !cache->isAllowedInRevision(pd))
- pd = 0;
+ if (!cache->isAllowedInRevision(pd))
+ return 0;
- // Return a copy allocated from our memory pool. Property data pointers can change
- // otherwise when the QQmlPropertyCache changes later in the QML type compilation process.
- if (pd) {
- QQmlPropertyData *copy = pd;
- pd = _function->New<QQmlPropertyData>();
- *pd = *copy;
- }
return pd;
}
@@ -1694,8 +1908,11 @@ enum MetaObjectResolverFlags {
ResolveTypeInformationOnly = 0x8
};
+#if 0
static void initMetaObjectResolver(QV4::IR::MemberExpressionResolver *resolver, QQmlPropertyCache *metaObject);
+static void initScopedEnumResolver(QV4::IR::MemberExpressionResolver *resolver, const QQmlType &qmlType, int index);
+
static QV4::IR::DiscoveredType resolveQmlType(QQmlEnginePrivate *qmlEngine,
const QV4::IR::MemberExpressionResolver *resolver,
QV4::IR::Member *member)
@@ -1710,6 +1927,14 @@ static QV4::IR::DiscoveredType resolveQmlType(QQmlEnginePrivate *qmlEngine,
if (ok) {
member->setEnumValue(value);
return QV4::IR::SInt32Type;
+ } else {
+ int index = type.scopedEnumIndex(qmlEngine, *member->name, &ok);
+ if (ok) {
+ auto newResolver = resolver->owner->New<QV4::IR::MemberExpressionResolver>();
+ newResolver->owner = resolver->owner;
+ initScopedEnumResolver(newResolver, type, index);
+ return QV4::IR::DiscoveredType(newResolver);
+ }
}
}
@@ -1893,33 +2118,66 @@ static void initMetaObjectResolver(QV4::IR::MemberExpressionResolver *resolver,
resolver->flags = 0;
}
+static QV4::IR::DiscoveredType resolveScopedEnum(QQmlEnginePrivate *qmlEngine,
+ const QV4::IR::MemberExpressionResolver *resolver,
+ QV4::IR::Member *member)
+{
+ if (!member->name->constData()->isUpper())
+ return QV4::IR::VarType;
+
+ QQmlType type = resolver->qmlType;
+ int index = resolver->flags;
+
+ bool ok = false;
+ int value = type.scopedEnumValue(qmlEngine, index, *member->name, &ok);
+ if (!ok)
+ return QV4::IR::VarType;
+ member->setEnumValue(value);
+ return QV4::IR::SInt32Type;
+}
+
+static void initScopedEnumResolver(QV4::IR::MemberExpressionResolver *resolver, const QQmlType &qmlType, int index)
+{
+ Q_ASSERT(resolver);
+
+ resolver->resolveMember = &resolveScopedEnum;
+ resolver->qmlType = qmlType;
+ resolver->flags = index;
+}
+#endif
+
#endif // V4_BOOTSTRAP
void JSCodeGen::beginFunctionBodyHook()
{
- _qmlContextTemp = _block->newTemp();
- _importedScriptsTemp = _block->newTemp();
+ _qmlContextSlot = bytecodeGenerator->newRegister();
+ _importedScriptsSlot = bytecodeGenerator->newRegister();
#ifndef V4_BOOTSTRAP
- QV4::IR::Temp *temp = _block->TEMP(_qmlContextTemp);
+ Instruction::LoadQmlContext load;
+ load.result = Reference::fromStackSlot(this, _qmlContextSlot).stackSlot();
+ bytecodeGenerator->addInstruction(load);
+
+#if 0
temp->type = QV4::IR::QObjectType;
temp->memberResolver = _function->New<QV4::IR::MemberExpressionResolver>();
initMetaObjectResolver(temp->memberResolver, _scopeObject);
auto name = _block->NAME(QV4::IR::Name::builtin_qml_context, 0, 0);
name->type = temp->type;
- move(temp, name);
+#endif
- move(_block->TEMP(_importedScriptsTemp), _block->NAME(QV4::IR::Name::builtin_qml_imported_scripts_object, 0, 0));
+ Instruction::LoadQmlImportedScripts loadScripts;
+ loadScripts.result = Reference::fromStackSlot(this, _importedScriptsSlot).stackSlot();
+ bytecodeGenerator->addInstruction(loadScripts);
#endif
}
-QV4::IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int col)
+QV4::Compiler::Codegen::Reference JSCodeGen::fallbackNameLookup(const QString &name)
{
- Q_UNUSED(line)
- Q_UNUSED(col)
#ifndef V4_BOOTSTRAP
if (_disableAcceleratedLookups)
- return 0;
+ return Reference();
+
// Implement QML lookup semantics in the current file context.
//
// Note: We do not check if properties of the qml scope object or context object
@@ -1934,20 +2192,16 @@ QV4::IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int
// Look for IDs first.
for (const IdMapping &mapping : qAsConst(_idObjects)) {
if (name == mapping.name) {
- if (_function->isQmlBinding)
- _function->idObjectDependencies.insert(mapping.idIndex);
-
- QV4::IR::Expr *s = _block->MEMBER(_block->TEMP(_qmlContextTemp), _function->newString(name), 0, QV4::IR::Member::MemberOfIdObjectsArray, mapping.idIndex);
- QV4::IR::Temp *result = _block->TEMP(_block->newTemp());
- _block->MOVE(result, s);
- result = _block->TEMP(result->index);
- if (mapping.type) {
- result->memberResolver = _function->New<QV4::IR::MemberExpressionResolver>();
- result->memberResolver->owner = _function;
- initMetaObjectResolver(result->memberResolver, mapping.type);
- result->memberResolver->flags |= AllPropertiesAreFinal;
- }
- result->isReadOnly = true; // don't allow use as lvalue
+ if (_context->compilationMode == QV4::Compiler::QmlBinding)
+ _context->idObjectDependencies.insert(mapping.idIndex);
+
+ Instruction::LoadIdObject load;
+ load.base = Reference::fromStackSlot(this, _qmlContextSlot).stackSlot();
+ load.index = mapping.idIndex;
+
+ Reference result = Reference::fromAccumulator(this);
+ bytecodeGenerator->addInstruction(load);
+ result.isReadonly = true;
return result;
}
}
@@ -1956,72 +2210,61 @@ QV4::IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int
QQmlTypeNameCache::Result r = imports->query(name);
if (r.isValid()) {
if (r.scriptIndex != -1) {
- return _block->SUBSCRIPT(_block->TEMP(_importedScriptsTemp),
- _block->CONST(QV4::IR::SInt32Type, r.scriptIndex));
+ Reference imports = Reference::fromStackSlot(this, _importedScriptsSlot);
+ return Reference::fromSubscript(imports, Reference::fromConst(this, QV4::Encode(r.scriptIndex)));
} else if (r.type.isValid()) {
- QV4::IR::Name *typeName = _block->NAME(name, line, col);
- // Make sure the run-time loads this through the more efficient singleton getter.
- typeName->qmlSingleton = r.type.isCompositeSingleton();
- typeName->freeOfSideEffects = true;
- QV4::IR::Temp *result = _block->TEMP(_block->newTemp());
- _block->MOVE(result, typeName);
-
- result = _block->TEMP(result->index);
- result->memberResolver = _function->New<QV4::IR::MemberExpressionResolver>();
- result->memberResolver->owner = _function;
- initQmlTypeResolver(result->memberResolver, r.type);
- return result;
+ if (r.type.isCompositeSingleton()) {
+ Instruction::LoadQmlSingleton load;
+ load.name = registerString(name);
+ bytecodeGenerator->addInstruction(load);
+ return Reference::fromAccumulator(this);
+ }
+ return Reference::fromName(this, name);
} else {
Q_ASSERT(r.importNamespace);
- QV4::IR::Name *namespaceName = _block->NAME(name, line, col);
- namespaceName->freeOfSideEffects = true;
- QV4::IR::Temp *result = _block->TEMP(_block->newTemp());
- result->memberResolver = _function->New<QV4::IR::MemberExpressionResolver>();
- result->memberResolver->owner = _function;
- initImportNamespaceResolver(result->memberResolver, imports, r.importNamespace);
-
- _block->MOVE(result, namespaceName);
- return _block->TEMP(result->index);
+ return Reference::fromName(this, name);
}
}
}
if (_scopeObject) {
- bool propertyExistsButForceNameLookup = false;
- QQmlPropertyData *pd = lookupQmlCompliantProperty(_scopeObject, name, &propertyExistsButForceNameLookup);
- if (propertyExistsButForceNameLookup)
- return 0;
- if (pd) {
- QV4::IR::Temp *base = _block->TEMP(_qmlContextTemp);
- base->memberResolver = _function->New<QV4::IR::MemberExpressionResolver>();
- base->memberResolver->owner = _function;
- initMetaObjectResolver(base->memberResolver, _scopeObject);
- return _block->MEMBER(base, _function->newString(name), pd, QV4::IR::Member::MemberOfQmlScopeObject);
- }
+ QQmlPropertyData *data = lookupQmlCompliantProperty(_scopeObject, name);
+ if (!data)
+ return Reference::fromName(this, name);
+
+ Reference base = Reference::fromStackSlot(this, _qmlContextSlot);
+ Reference::PropertyCapturePolicy capturePolicy;
+ if (!data->isConstant() && !data->isQmlBinding())
+ capturePolicy = Reference::CaptureAtRuntime;
+ else
+ capturePolicy = data->isConstant() ? Reference::DontCapture : Reference::CaptureAheadOfTime;
+ return Reference::fromQmlScopeObject(base, data->coreIndex(), data->notifyIndex(), capturePolicy);
}
if (_contextObject) {
- bool propertyExistsButForceNameLookup = false;
- QQmlPropertyData *pd = lookupQmlCompliantProperty(_contextObject, name, &propertyExistsButForceNameLookup);
- if (propertyExistsButForceNameLookup)
- return 0;
- if (pd) {
- QV4::IR::Temp *base = _block->TEMP(_qmlContextTemp);
- base->memberResolver = _function->New<QV4::IR::MemberExpressionResolver>();
- base->memberResolver->owner = _function;
- initMetaObjectResolver(base->memberResolver, _contextObject);
- return _block->MEMBER(base, _function->newString(name), pd, QV4::IR::Member::MemberOfQmlContextObject);
- }
+ QQmlPropertyData *data = lookupQmlCompliantProperty(_contextObject, name);
+ if (!data)
+ return Reference::fromName(this, name);
+
+ Reference base = Reference::fromStackSlot(this, _qmlContextSlot);
+ Reference::PropertyCapturePolicy capturePolicy;
+ if (!data->isConstant() && !data->isQmlBinding())
+ capturePolicy = Reference::CaptureAtRuntime;
+ else
+ capturePolicy = data->isConstant() ? Reference::DontCapture : Reference::CaptureAheadOfTime;
+ return Reference::fromQmlContextObject(base, data->coreIndex(), data->notifyIndex(), capturePolicy);
}
- if (m_globalNames.contains(name))
- return _block->GLOBALNAME(name, line, col, /*forceLookup =*/ true);
-
+ if (m_globalNames.contains(name)) {
+ Reference r = Reference::fromName(this, name);
+ r.global = true;
+ return r;
+ }
#else
Q_UNUSED(name)
#endif // V4_BOOTSTRAP
// fall back to name lookup at run-time.
- return 0;
+ return Reference();
}
#ifndef V4_BOOTSTRAP
@@ -2197,7 +2440,7 @@ QmlIR::Object *IRLoader::loadObject(const QV4::CompiledData::Object *serializedO
QQmlJS::Engine *jsParserEngine = &output->jsParserEngine;
- const QV4::CompiledData::LEUInt32 *functionIdx = serializedObject->functionOffsetTable();
+ const quint32_le *functionIdx = serializedObject->functionOffsetTable();
for (uint i = 0; i < serializedObject->nFunctions; ++i, ++functionIdx) {
QmlIR::Function *f = pool->New<QmlIR::Function>();
const QV4::CompiledData::Function *compiledFunction = unit->functionAt(*functionIdx);
@@ -2208,7 +2451,7 @@ QmlIR::Object *IRLoader::loadObject(const QV4::CompiledData::Object *serializedO
f->nameIndex = compiledFunction->nameIndex;
QQmlJS::AST::FormalParameterList *paramList = 0;
- const QV4::CompiledData::LEUInt32 *formalNameIdx = compiledFunction->formalsTable();
+ const quint32_le *formalNameIdx = compiledFunction->formalsTable();
for (uint i = 0; i < compiledFunction->nFormals; ++i, ++formalNameIdx) {
const QString formal = unit->stringAt(*formalNameIdx);
QStringRef paramNameRef = jsParserEngine->newStringRef(formal);
diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h
index ad34864242..f8f8649fc7 100644
--- a/src/qml/compiler/qqmlirbuilder_p.h
+++ b/src/qml/compiler/qqmlirbuilder_p.h
@@ -265,6 +265,25 @@ public:
struct Object;
+struct EnumValue : public QV4::CompiledData::EnumValue
+{
+ EnumValue *next;
+};
+
+struct Enum
+{
+ int nameIndex;
+ QV4::CompiledData::Location location;
+ PoolList<EnumValue> *enumValues;
+
+ int enumValueCount() const { return enumValues->count; }
+ PoolList<EnumValue>::Iterator enumValuesBegin() const { return enumValues->begin(); }
+ PoolList<EnumValue>::Iterator enumValuesEnd() const { return enumValues->end(); }
+
+ Enum *next;
+};
+
+
struct SignalParameter : public QV4::CompiledData::Parameter
{
SignalParameter *next;
@@ -359,6 +378,8 @@ public:
int propertyCount() const { return properties->count; }
Alias *firstAlias() const { return aliases->first; }
int aliasCount() const { return aliases->count; }
+ const Enum *firstEnum() const { return qmlEnums->first; }
+ int enumCount() const { return qmlEnums->count; }
const Signal *firstSignal() const { return qmlSignals->first; }
int signalCount() const { return qmlSignals->count; }
Binding *firstBinding() const { return bindings->first; }
@@ -372,6 +393,8 @@ public:
PoolList<Property>::Iterator propertiesEnd() const { return properties->end(); }
PoolList<Alias>::Iterator aliasesBegin() const { return aliases->begin(); }
PoolList<Alias>::Iterator aliasesEnd() const { return aliases->end(); }
+ PoolList<Enum>::Iterator enumsBegin() const { return qmlEnums->begin(); }
+ PoolList<Enum>::Iterator enumsEnd() const { return qmlEnums->end(); }
PoolList<Signal>::Iterator signalsBegin() const { return qmlSignals->begin(); }
PoolList<Signal>::Iterator signalsEnd() const { return qmlSignals->end(); }
PoolList<Function>::Iterator functionsBegin() const { return functions->begin(); }
@@ -385,6 +408,7 @@ public:
QString sanityCheckFunctionNames(const QSet<QString> &illegalNames, QQmlJS::AST::SourceLocation *errorLocation);
+ QString appendEnum(Enum *enumeration);
QString appendSignal(Signal *signal);
QString appendProperty(Property *prop, const QString &propertyName, bool isDefaultProperty, const QQmlJS::AST::SourceLocation &defaultToken, QQmlJS::AST::SourceLocation *errorLocation);
QString appendAlias(Alias *prop, const QString &aliasName, bool isDefaultProperty, const QQmlJS::AST::SourceLocation &defaultToken, QQmlJS::AST::SourceLocation *errorLocation);
@@ -408,6 +432,7 @@ private:
PoolList<Property> *properties;
PoolList<Alias> *aliases;
+ PoolList<Enum> *qmlEnums;
PoolList<Signal> *qmlSignals;
PoolList<Binding> *bindings;
PoolList<Function> *functions;
@@ -428,7 +453,7 @@ struct Q_QML_PRIVATE_EXPORT Document
Document(bool debugMode);
QString code;
QQmlJS::Engine jsParserEngine;
- QV4::IR::Module jsModule;
+ QV4::Compiler::Module jsModule;
QList<const QV4::CompiledData::Import *> imports;
QList<Pragma*> pragmas;
QQmlJS::AST::UiProgram *program;
@@ -481,6 +506,7 @@ public:
bool visit(QQmlJS::AST::UiArrayBinding *ast) override;
bool visit(QQmlJS::AST::UiObjectBinding *ast) override;
bool visit(QQmlJS::AST::UiObjectDefinition *ast) override;
+ bool visit(QQmlJS::AST::UiEnumDeclaration *ast) override;
bool visit(QQmlJS::AST::UiPublicMember *ast) override;
bool visit(QQmlJS::AST::UiScriptBinding *ast) override;
bool visit(QQmlJS::AST::UiSourceElement *ast) override;
@@ -501,6 +527,7 @@ public:
const QQmlJS::AST::SourceLocation &last) const;
void setBindingValue(QV4::CompiledData::Binding *binding, QQmlJS::AST::Statement *statement);
+ void tryGeneratingTranslationBinding(const QStringRef &base, QQmlJS::AST::ArgumentList *args, QV4::CompiledData::Binding *binding);
void appendBinding(QQmlJS::AST::UiQualifiedId *name, QQmlJS::AST::Statement *value);
void appendBinding(QQmlJS::AST::UiQualifiedId *name, int objectIndex, bool isOnAssignment = false);
@@ -580,10 +607,10 @@ struct Q_QML_EXPORT PropertyResolver
};
#endif
-struct Q_QML_PRIVATE_EXPORT JSCodeGen : public QQmlJS::Codegen
+struct Q_QML_PRIVATE_EXPORT JSCodeGen : public QV4::Compiler::Codegen
{
- JSCodeGen(const QString &fileName, const QString &finalUrl, const QString &sourceCode,
- QV4::IR::Module *jsModule, QQmlJS::Engine *jsEngine, QQmlJS::AST::UiProgram *qmlRoot,
+ JSCodeGen(const QString &sourceCode, QV4::Compiler::JSUnitGenerator *jsUnitGenerator, QV4::Compiler::Module *jsModule,
+ QQmlJS::Engine *jsEngine, QQmlJS::AST::UiProgram *qmlRoot,
QQmlTypeNameCache *imports, const QV4::Compiler::StringTableGenerator *stringPool, const QSet<QString> &globalNames);
struct IdMapping
@@ -600,12 +627,17 @@ struct Q_QML_PRIVATE_EXPORT JSCodeGen : public QQmlJS::Codegen
// Returns mapping from input functions to index in IR::Module::functions / compiledData->runtimeFunctions
QVector<int> generateJSCodeForFunctionsAndBindings(const QList<CompiledFunctionOrExpression> &functions);
+ int defineFunction(const QString &name, AST::Node *ast,
+ AST::FormalParameterList *formals,
+ AST::SourceElements *body) override;
+
protected:
void beginFunctionBodyHook() override;
- QV4::IR::Expr *fallbackNameLookup(const QString &name, int line, int col) override;
+ Reference fallbackNameLookup(const QString &name) override;
private:
- QQmlPropertyData *lookupQmlCompliantProperty(QQmlPropertyCache *cache, const QString &name, bool *propertyExistsButForceNameLookup = 0);
+ // returns nullptr if lookup needs to happen by name
+ QQmlPropertyData *lookupQmlCompliantProperty(QQmlPropertyCache *cache, const QString &name);
QString sourceCode;
QQmlJS::Engine *jsEngine; // needed for memory pool
@@ -617,8 +649,8 @@ private:
ObjectIdMapping _idObjects;
QQmlPropertyCache *_contextObject;
QQmlPropertyCache *_scopeObject;
- int _qmlContextTemp;
- int _importedScriptsTemp;
+ int _qmlContextSlot;
+ int _importedScriptsSlot;
QSet<QString> m_globalNames;
};
diff --git a/src/qml/compiler/qqmlpropertycachecreator.cpp b/src/qml/compiler/qqmlpropertycachecreator.cpp
index f8d63ec634..4f8b48f52e 100644
--- a/src/qml/compiler/qqmlpropertycachecreator.cpp
+++ b/src/qml/compiler/qqmlpropertycachecreator.cpp
@@ -64,7 +64,7 @@ QQmlBindingInstantiationContext::QQmlBindingInstantiationContext(int referencing
Q_ASSERT(instantiatingBinding->propertyNameIndex != 0);
bool notInRevision = false;
- instantiatingProperty = QmlIR::PropertyResolver(referencingObjectPropertyCache).property(instantiatingPropertyName, &notInRevision);
+ instantiatingProperty = QmlIR::PropertyResolver(referencingObjectPropertyCache).property(instantiatingPropertyName, &notInRevision, QmlIR::PropertyResolver::IgnoreRevision);
}
}
diff --git a/src/qml/compiler/qqmlpropertycachecreator_p.h b/src/qml/compiler/qqmlpropertycachecreator_p.h
index 8743a57d7a..7a52f3a12c 100644
--- a/src/qml/compiler/qqmlpropertycachecreator_p.h
+++ b/src/qml/compiler/qqmlpropertycachecreator_p.h
@@ -116,7 +116,7 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::buildMetaObje
{
const CompiledObject *obj = objectContainer->objectAt(objectIndex);
- bool needVMEMetaObject = obj->propertyCount() != 0 || obj->aliasCount() != 0 || obj->signalCount() != 0 || obj->functionCount() != 0;
+ bool needVMEMetaObject = obj->propertyCount() != 0 || obj->aliasCount() != 0 || obj->signalCount() != 0 || obj->functionCount() != 0 || obj->enumCount() != 0;
if (!needVMEMetaObject) {
auto binding = obj->bindingsBegin();
auto end = obj->bindingsEnd();
@@ -184,7 +184,7 @@ inline QQmlPropertyCache *QQmlPropertyCacheCreator<ObjectContainer>::propertyCac
{
if (context.instantiatingProperty) {
if (context.instantiatingProperty->isQObject()) {
- return enginePrivate->rawPropertyCacheForType(context.instantiatingProperty->propType());
+ return enginePrivate->rawPropertyCacheForType(context.instantiatingProperty->propType(), context.instantiatingProperty->typeMinorVersion());
} else if (const QMetaObject *vtmo = QQmlValueTypeFactory::metaObjectForMetaType(context.instantiatingProperty->propType())) {
return enginePrivate->cache(vtmo);
}
@@ -244,7 +244,7 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
QQmlRefPointer<QQmlPropertyCache> cache;
cache.adopt(baseTypeCache->copyAndReserve(obj->propertyCount() + obj->aliasCount(),
obj->functionCount() + obj->propertyCount() + obj->aliasCount() + obj->signalCount(),
- obj->signalCount() + obj->propertyCount() + obj->aliasCount()));
+ obj->signalCount() + obj->propertyCount() + obj->aliasCount(), obj->enumCount()));
propertyCaches->set(objectIndex, cache);
propertyCaches->setNeedsVMEMetaObject(objectIndex);
@@ -370,6 +370,21 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
cache->appendSignal(changedSigName, flags, effectiveMethodIndex++);
}
+ auto e = obj->enumsBegin();
+ auto eend = obj->enumsEnd();
+ for ( ; e != eend; ++e) {
+ const int enumValueCount = e->enumValueCount();
+ QVector<QQmlEnumValue> values;
+ values.reserve(enumValueCount);
+
+ auto enumValue = e->enumValuesBegin();
+ auto end = e->enumValuesEnd();
+ for ( ; enumValue != end; ++enumValue)
+ values.append(QQmlEnumValue(stringAt(enumValue->nameIndex), enumValue->value));
+
+ cache->appendEnum(stringAt(e->nameIndex), values);
+ }
+
// Dynamic signals
auto s = obj->signalsBegin();
auto send = obj->signalsEnd();
@@ -461,6 +476,7 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
pend = obj->propertiesEnd();
for ( ; p != pend; ++p, ++propertyIdx) {
int propertyType = 0;
+ int propertTypeMinorVersion = 0;
QQmlPropertyData::Flags propertyFlags;
if (p->type == QV4::CompiledData::Property::Var) {
@@ -498,6 +514,7 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
} else {
if (p->type == QV4::CompiledData::Property::Custom) {
propertyType = qmltype.typeId();
+ propertTypeMinorVersion = qmltype.minorVersion();
} else {
propertyType = qmltype.qListTypeId();
}
@@ -517,7 +534,7 @@ inline QQmlCompileError QQmlPropertyCacheCreator<ObjectContainer>::createMetaObj
if (!obj->defaultPropertyIsAlias && propertyIdx == obj->indexOfDefaultPropertyOrAlias)
cache->_defaultPropertyName = propertyName;
cache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++,
- propertyType, effectiveSignalIndex);
+ propertyType, propertTypeMinorVersion, effectiveSignalIndex);
effectiveSignalIndex++;
}
@@ -540,7 +557,7 @@ public:
private:
void appendAliasPropertiesInMetaObjectsWithinComponent(const CompiledObject &component, int firstObjectIndex);
- QQmlCompileError propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, QQmlPropertyRawData::Flags *propertyFlags);
+ QQmlCompileError propertyDataForAlias(const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, int *rev, QQmlPropertyRawData::Flags *propertyFlags);
void collectObjectsWithAliasesRecursively(int objectIndex, QVector<int> *objectsWithAliases) const;
@@ -652,7 +669,7 @@ inline void QQmlPropertyCacheAliasCreator<ObjectContainer>::collectObjectsWithAl
template <typename ObjectContainer>
inline QQmlCompileError QQmlPropertyCacheAliasCreator<ObjectContainer>::propertyDataForAlias(
- const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type,
+ const CompiledObject &component, const QV4::CompiledData::Alias &alias, int *type, int *minorVersion,
QQmlPropertyData::Flags *propertyFlags)
{
const int targetObjectIndex = objectForId(component, alias.targetObjectId);
@@ -670,7 +687,7 @@ inline QQmlCompileError QQmlPropertyCacheAliasCreator<ObjectContainer>::property
auto targetAlias = targetObject.aliasesBegin();
for (uint i = 0; i < alias.localAliasIndex; ++i)
++targetAlias;
- return propertyDataForAlias(component, *targetAlias, type, propertyFlags);
+ return propertyDataForAlias(component, *targetAlias, type, minorVersion, propertyFlags);
} else if (alias.encodedMetaPropertyIndex == -1) {
Q_ASSERT(alias.flags & QV4::CompiledData::Alias::AliasPointsToPointerObject);
auto *typeRef = objectContainer->resolvedTypes.value(targetObject.inheritedTypeNameIndex);
@@ -686,6 +703,8 @@ inline QQmlCompileError QQmlPropertyCacheAliasCreator<ObjectContainer>::property
else
*type = typeRef->compilationUnit->metaTypeId;
+ *minorVersion = typeRef->minorVersion;
+
propertyFlags->type = QQmlPropertyData::Flags::QObjectDerivedType;
} else {
int coreIndex = QQmlPropertyIndex::fromEncoded(alias.encodedMetaPropertyIndex).coreIndex();
@@ -746,8 +765,9 @@ inline QQmlCompileError QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAl
Q_ASSERT(alias->flags & QV4::CompiledData::Alias::Resolved);
int type = 0;
+ int minorVersion = 0;
QQmlPropertyData::Flags propertyFlags;
- QQmlCompileError error = propertyDataForAlias(component, *alias, &type, &propertyFlags);
+ QQmlCompileError error = propertyDataForAlias(component, *alias, &type, &minorVersion, &propertyFlags);
if (error.isSet())
return error;
@@ -757,7 +777,7 @@ inline QQmlCompileError QQmlPropertyCacheAliasCreator<ObjectContainer>::appendAl
propertyCache->_defaultPropertyName = propertyName;
propertyCache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++,
- type, effectiveSignalIndex++);
+ type, minorVersion, effectiveSignalIndex++);
}
return QQmlCompileError();
diff --git a/src/qml/compiler/qqmlpropertyvalidator.cpp b/src/qml/compiler/qqmlpropertyvalidator.cpp
index 7ea89b378d..9fde6848bb 100644
--- a/src/qml/compiler/qqmlpropertyvalidator.cpp
+++ b/src/qml/compiler/qqmlpropertyvalidator.cpp
@@ -665,10 +665,11 @@ QQmlCompileError QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *
} else if (property->propType() == qMetaTypeId<QQmlScriptString>()) {
return QQmlCompileError(binding->valueLocation, tr("Invalid property assignment: script expected"));
} else {
- // We want to raw metaObject here as the raw metaobject is the
+ // We want to use the raw metaObject here as the raw metaobject is the
// actual property type before we applied any extensions that might
// effect the properties on the type, but don't effect assignability
- QQmlPropertyCache *propertyMetaObject = enginePrivate->rawPropertyCacheForType(property->propType());
+ // Using -1 for the minor version ensures that we get the raw metaObject.
+ QQmlPropertyCache *propertyMetaObject = enginePrivate->rawPropertyCacheForType(property->propType(), -1);
// Will be true if the assgned type inherits propertyMetaObject
bool isAssignable = false;
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index 0eae909cf7..ac373aafb4 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -44,10 +44,9 @@
#include <private/qqmlcustomparser_p.h>
#include <private/qqmlvmemetaobject_p.h>
#include <private/qqmlcomponent_p.h>
-#include <private/qv4ssa_p.h>
#include "qqmlpropertycachecreator_p.h"
-#include "qv4jssimplifier_p.h"
+//#include "qv4jssimplifier_p.h"
#define COMPILE_EXCEPTION(token, desc) \
{ \
@@ -140,22 +139,16 @@ QV4::CompiledData::CompilationUnit *QQmlTypeCompiler::compile()
sss.scan();
}
- QmlIR::JSCodeGen v4CodeGenerator(typeData->urlString(), typeData->finalUrlString(),
- document->code, &document->jsModule,
- &document->jsParserEngine, document->program,
- typeNameCache, &document->jsGenerator.stringTable, engine->v8engine()->illegalNames());
+ document->jsModule.fileName = typeData->urlString();
+ document->jsModule.finalUrl = typeData->finalUrlString();
+ QmlIR::JSCodeGen v4CodeGenerator(document->code, &document->jsGenerator, &document->jsModule, &document->jsParserEngine,
+ document->program, typeNameCache, &document->jsGenerator.stringTable, engine->v8engine()->illegalNames());
+ v4CodeGenerator.setUseFastLookups(false);
QQmlJSCodeGenerator jsCodeGen(this, &v4CodeGenerator);
if (!jsCodeGen.generateCodeForComponents())
return nullptr;
- QQmlJavaScriptBindingExpressionSimplificationPass pass(document->objects, &document->jsModule, &document->jsGenerator);
- pass.reduceTranslationBindings();
-
- QV4::ExecutionEngine *v4 = engine->v4engine();
- QScopedPointer<QV4::EvalInstructionSelection> isel(v4->iselFactory->create(engine, v4->executableAllocator, &document->jsModule, &document->jsGenerator));
- isel->setUseFastLookups(false);
- isel->setUseTypeInference(true);
- document->javaScriptCompilationUnit = isel->compile(/*generated unit data*/false);
+ document->javaScriptCompilationUnit = v4CodeGenerator.generateCompilationUnit(/*generated unit data*/false);
}
// Generate QML compiled type data structures
@@ -211,11 +204,6 @@ int QQmlTypeCompiler::registerString(const QString &str)
return document->jsGenerator.registerString(str);
}
-QV4::IR::Module *QQmlTypeCompiler::jsIRModule() const
-{
- return &document->jsModule;
-}
-
const QV4::CompiledData::Unit *QQmlTypeCompiler::qmlUnit() const
{
return document->javaScriptCompilationUnit->data;
@@ -308,7 +296,7 @@ SignalHandlerConverter::SignalHandlerConverter(QQmlTypeCompiler *typeCompiler)
, imports(typeCompiler->imports())
, customParsers(typeCompiler->customParserCache())
, resolvedTypes(typeCompiler->resolvedTypes)
- , illegalNames(QV8Engine::get(QQmlEnginePrivate::get(typeCompiler->enginePrivate()))->illegalNames())
+ , illegalNames(typeCompiler->enginePrivate()->v8engine()->illegalNames())
, propertyCaches(typeCompiler->propertyCaches())
{
}
@@ -504,7 +492,9 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio
QQmlJS::AST::FunctionBody *body = new (pool) QQmlJS::AST::FunctionBody(elements);
functionDeclaration = new (pool) QQmlJS::AST::FunctionDeclaration(compiler->newStringRef(stringAt(binding->propertyNameIndex)), paramList, body);
- functionDeclaration->functionToken = foe->node->firstSourceLocation();
+ functionDeclaration->lbraceToken = functionDeclaration->functionToken
+ = foe->node->firstSourceLocation();
+ functionDeclaration->rbraceToken = foe->node->lastSourceLocation();
}
foe->node = functionDeclaration;
binding->propertyNameIndex = compiler->registerString(propertyName);
@@ -588,21 +578,32 @@ bool QQmlEnumTypeResolver::tryQualifiedEnumAssignment(const QmlIR::Object *obj,
if (!string.constData()->isUpper())
return true;
+ // we support one or two '.' in the enum phrase:
+ // * <TypeName>.<EnumValue>
+ // * <TypeName>.<ScopedEnumName>.<EnumValue>
+
int dot = string.indexOf(QLatin1Char('.'));
if (dot == -1 || dot == string.length()-1)
return true;
- if (string.indexOf(QLatin1Char('.'), dot+1) != -1)
- return true;
+ int dot2 = string.indexOf(QLatin1Char('.'), dot+1);
+ if (dot2 != -1 && dot2 != string.length()-1) {
+ if (!string.at(dot+1).isUpper())
+ return true;
+ if (string.indexOf(QLatin1Char('.'), dot2+1) != -1)
+ return true;
+ }
QHashedStringRef typeName(string.constData(), dot);
const bool isQtObject = (typeName == QLatin1String("Qt"));
- const QStringRef enumValue = string.midRef(dot + 1);
+ const QStringRef scopedEnumName = (dot2 != -1 ? string.midRef(dot + 1, dot2 - dot - 1) : QStringRef());
+ // ### consider supporting scoped enums in Qt namespace
+ const QStringRef enumValue = string.midRef(!isQtObject && dot2 != -1 ? dot2 + 1 : dot + 1);
- if (isIntProp) {
+ if (isIntProp) { // ### C++11 allows enums to be other integral types. Should we support other integral types here?
// Allow enum assignment to ints.
bool ok;
- int enumval = evaluateEnum(typeName.toString(), enumValue.toUtf8(), &ok);
+ int enumval = evaluateEnum(typeName.toString(), scopedEnumName, enumValue, &ok);
if (ok) {
if (!assignEnumToBinding(binding, enumValue, enumval, isQtObject))
return false;
@@ -620,18 +621,25 @@ bool QQmlEnumTypeResolver::tryQualifiedEnumAssignment(const QmlIR::Object *obj,
auto *tr = resolvedTypes->value(obj->inheritedTypeNameIndex);
if (type.isValid() && tr && tr->type == type) {
+ // When these two match, we can short cut the search
QMetaProperty mprop = propertyCache->firstCppMetaObject()->property(prop->coreIndex());
+ QMetaEnum menum = mprop.enumerator();
+ QByteArray enumName = enumValue.toUtf8();
+ if (menum.isScoped() && !scopedEnumName.isEmpty() && enumName != scopedEnumName.toUtf8())
+ return true;
- // When these two match, we can short cut the search
if (mprop.isFlagType()) {
- value = mprop.enumerator().keysToValue(enumValue.toUtf8().constData(), &ok);
+ value = menum.keysToValue(enumName.constData(), &ok);
} else {
- value = mprop.enumerator().keyToValue(enumValue.toUtf8().constData(), &ok);
+ value = menum.keyToValue(enumName.constData(), &ok);
}
} else {
// Otherwise we have to search the whole type
if (type.isValid()) {
- value = type.enumValue(compiler->enginePrivate(), QHashedStringRef(enumValue), &ok);
+ if (!scopedEnumName.isEmpty())
+ value = type.scopedEnumValue(compiler->enginePrivate(), scopedEnumName, enumValue, &ok);
+ else
+ value = type.enumValue(compiler->enginePrivate(), QHashedStringRef(enumValue), &ok);
} else {
QByteArray enumName = enumValue.toUtf8();
const QMetaObject *metaObject = StaticQtMetaObject::get();
@@ -648,7 +656,7 @@ bool QQmlEnumTypeResolver::tryQualifiedEnumAssignment(const QmlIR::Object *obj,
return assignEnumToBinding(binding, enumValue, value, isQtObject);
}
-int QQmlEnumTypeResolver::evaluateEnum(const QString &scope, const QByteArray &enumValue, bool *ok) const
+int QQmlEnumTypeResolver::evaluateEnum(const QString &scope, const QStringRef &enumName, const QStringRef &enumValue, bool *ok) const
{
Q_ASSERT_X(ok, "QQmlEnumTypeResolver::evaluateEnum", "ok must not be a null pointer");
*ok = false;
@@ -656,13 +664,18 @@ int QQmlEnumTypeResolver::evaluateEnum(const QString &scope, const QByteArray &e
if (scope != QLatin1String("Qt")) {
QQmlType type;
imports->resolveType(scope, &type, 0, 0, 0);
- return type.enumValue(compiler->enginePrivate(), QHashedCStringRef(enumValue.constData(), enumValue.length()), ok);
+ if (!type.isValid())
+ return -1;
+ if (!enumName.isEmpty())
+ return type.scopedEnumValue(compiler->enginePrivate(), enumName, enumValue, ok);
+ return type.enumValue(compiler->enginePrivate(), QHashedStringRef(enumValue.constData(), enumValue.length()), ok);
}
const QMetaObject *mo = StaticQtMetaObject::get();
int i = mo->enumeratorCount();
+ const QByteArray ba = enumValue.toUtf8();
while (i--) {
- int v = mo->enumerator(i).keyToValue(enumValue.constData(), ok);
+ int v = mo->enumerator(i).keyToValue(ba.constData(), ok);
if (*ok)
return v;
}
@@ -811,7 +824,7 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI
if (!pd || !pd->isQObject())
continue;
- QQmlPropertyCache *pc = enginePrivate->rawPropertyCacheForType(pd->propType());
+ QQmlPropertyCache *pc = enginePrivate->rawPropertyCacheForType(pd->propType(), pd->typeMinorVersion());
const QMetaObject *mo = pc ? pc->firstCppMetaObject() : 0;
while (mo) {
if (mo == &QQmlComponent::staticMetaObject)
diff --git a/src/qml/compiler/qqmltypecompiler_p.h b/src/qml/compiler/qqmltypecompiler_p.h
index 0e953ec01e..d905b956c7 100644
--- a/src/qml/compiler/qqmltypecompiler_p.h
+++ b/src/qml/compiler/qqmltypecompiler_p.h
@@ -111,8 +111,6 @@ public:
int registerString(const QString &str);
- QV4::IR::Module *jsIRModule() const;
-
const QV4::CompiledData::Unit *qmlUnit() const;
QUrl url() const { return typeData->finalUrl(); }
@@ -208,7 +206,7 @@ private:
bool tryQualifiedEnumAssignment(const QmlIR::Object *obj, const QQmlPropertyCache *propertyCache,
const QQmlPropertyData *prop,
QmlIR::Binding *binding);
- int evaluateEnum(const QString &scope, const QByteArray &enumValue, bool *ok) const;
+ int evaluateEnum(const QString &scope, const QStringRef &enumName, const QStringRef &enumValue, bool *ok) const;
const QVector<QmlIR::Object*> &qmlObjects;
diff --git a/src/qml/compiler/qv4bytecodegenerator.cpp b/src/qml/compiler/qv4bytecodegenerator.cpp
new file mode 100644
index 0000000000..0978e23b17
--- /dev/null
+++ b/src/qml/compiler/qv4bytecodegenerator.cpp
@@ -0,0 +1,225 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <private/qv4bytecodegenerator_p.h>
+#include <private/qv4compilercontext_p.h>
+#include <private/qqmljsastfwd_p.h>
+#include <private/qv4compileddata_p.h>
+
+QT_USE_NAMESPACE
+using namespace QV4;
+using namespace Moth;
+
+void BytecodeGenerator::setLocation(const QQmlJS::AST::SourceLocation &loc)
+{
+ currentLine = static_cast<int>(loc.startLine);
+}
+
+int BytecodeGenerator::newRegister()
+{
+ int t = currentReg++;
+ if (regCount < currentReg)
+ regCount = currentReg;
+ return t;
+}
+
+int BytecodeGenerator::newRegisterArray(int n)
+{
+ int t = currentReg;
+ currentReg += n;
+ if (regCount < currentReg)
+ regCount = currentReg;
+ return t;
+}
+
+void BytecodeGenerator::packInstruction(I &i)
+{
+ uchar type = *reinterpret_cast<uchar *>(i.packed);
+ Q_ASSERT(type >= MOTH_NUM_INSTRUCTIONS());
+ if (type >= MOTH_NUM_INSTRUCTIONS())
+ type -= MOTH_NUM_INSTRUCTIONS();
+ int instructionsAsInts[sizeof(Instr)/sizeof(int)];
+ int nMembers = Moth::InstrInfo::argumentCount[static_cast<int>(i.type)];
+ for (int j = 0; j < nMembers; ++j) {
+ instructionsAsInts[j] = qFromLittleEndian<qint32>(i.packed + 1 + j * sizeof(int));
+ }
+ enum {
+ Normal,
+ Wide
+ } width = Normal;
+ for (int n = 0; n < nMembers; ++n) {
+ if (width == Normal && (static_cast<qint8>(instructionsAsInts[n]) != instructionsAsInts[n])) {
+ width = Wide;
+ break;
+ }
+ }
+ char *code = i.packed;
+ switch (width) {
+ case Normal:
+ *reinterpret_cast<uchar *>(code) = type;
+ ++code;
+ for (int n = 0; n < nMembers; ++n) {
+ qint8 v = static_cast<qint8>(instructionsAsInts[n]);
+ memcpy(code, &v, 1);
+ code += 1;
+ }
+ i.size = code - i.packed;
+ if (i.offsetForJump != -1)
+ i.offsetForJump = i.size - 1;
+ break;
+ case Wide:
+ // nothing to do
+ break;
+ }
+}
+
+void BytecodeGenerator::adjustJumpOffsets()
+{
+ for (int index = 0; index < instructions.size(); ++index) {
+ auto &i = instructions[index];
+ if (i.offsetForJump == -1) // no jump
+ continue;
+ Q_ASSERT(i.linkedLabel != -1 && labels.at(i.linkedLabel) != -1);
+ const auto &linkedInstruction = instructions.at(labels.at(i.linkedLabel));
+ qint8 *c = reinterpret_cast<qint8*>(i.packed + i.offsetForJump);
+ int jumpOffset = linkedInstruction.position - (i.position + i.size);
+// qDebug() << "adjusting jump offset for instruction" << index << i.position << i.size << "offsetForJump" << i.offsetForJump << "target"
+// << labels.at(i.linkedLabel) << linkedInstruction.position << "jumpOffset" << jumpOffset;
+ uchar type = *reinterpret_cast<const uchar *>(i.packed);
+ if (type >= MOTH_NUM_INSTRUCTIONS()) {
+ Q_ASSERT(i.offsetForJump == i.size - 4);
+ qToLittleEndian<qint32>(jumpOffset, c);
+ } else {
+ Q_ASSERT(i.offsetForJump == i.size - 1);
+ qint8 o = jumpOffset;
+ Q_ASSERT(o == jumpOffset);
+ *c = o;
+ }
+ }
+}
+
+void BytecodeGenerator::compressInstructions()
+{
+ // first round: compress all non jump instructions
+ int position = 0;
+ for (auto &i : instructions) {
+ i.position = position;
+ if (i.offsetForJump == -1)
+ packInstruction(i);
+ position += i.size;
+ }
+
+ adjustJumpOffsets();
+
+ // compress all jumps
+ position = 0;
+ for (auto &i : instructions) {
+ i.position = position;
+ if (i.offsetForJump != -1)
+ packInstruction(i);
+ position += i.size;
+ }
+
+ // adjust once again, as the packing above could have changed offsets
+ adjustJumpOffsets();
+}
+
+void BytecodeGenerator::finalize(Compiler::Context *context)
+{
+ compressInstructions();
+
+ // collect content and line numbers
+ QByteArray code;
+ QVector<CompiledData::CodeOffsetToLine> lineNumbers;
+ currentLine = -1;
+ Q_UNUSED(startLine);
+ for (const auto &i : qAsConst(instructions)) {
+ if (i.line != currentLine) {
+ currentLine = i.line;
+ CompiledData::CodeOffsetToLine entry;
+ entry.codeOffset = code.size();
+ entry.line = currentLine;
+ lineNumbers.append(entry);
+ }
+ code.append(i.packed, i.size);
+ }
+
+ context->code = code;
+ context->lineNumberMapping = lineNumbers;
+}
+
+int BytecodeGenerator::addInstructionHelper(Instr::Type type, const Instr &i, int offsetOfOffset) {
+#if QT_CONFIG(qml_debug)
+ if (debugMode && type != Instr::Type::Debug) {
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_GCC("-Wmaybe-uninitialized") // broken gcc warns about Instruction::Debug()
+ if (instructions.isEmpty() || currentLine != instructions.constLast().line) {
+ addInstruction(Instruction::Debug());
+ } else if (type == Instr::Type::Ret) {
+ currentLine = -currentLine;
+ addInstruction(Instruction::Debug());
+ currentLine = -currentLine;
+ }
+QT_WARNING_POP
+ }
+#else
+ Q_UNUSED(debugMode);
+#endif
+
+ const int pos = instructions.size();
+
+ const int argCount = Moth::InstrInfo::argumentCount[static_cast<int>(type)];
+ int s = argCount*sizeof(int);
+ if (offsetOfOffset != -1)
+ offsetOfOffset += 1;
+ I instr{type, static_cast<short>(s + 1), 0, currentLine, offsetOfOffset, -1, "\0\0" };
+ char *code = instr.packed;
+ *reinterpret_cast<uchar *>(code) = static_cast<uchar>(MOTH_NUM_INSTRUCTIONS() + static_cast<int>(type));
+ ++code;
+ Q_ASSERT(MOTH_NUM_INSTRUCTIONS() + static_cast<int>(type) < 256);
+
+ for (int j = 0; j < argCount; ++j) {
+ qToLittleEndian<qint32>(i.argumentsAsInts[j], code);
+ code += sizeof(int);
+ }
+
+ instructions.append(instr);
+
+ return pos;
+}
diff --git a/src/qml/compiler/qv4bytecodegenerator_p.h b/src/qml/compiler/qv4bytecodegenerator_p.h
new file mode 100644
index 0000000000..3d516da922
--- /dev/null
+++ b/src/qml/compiler/qv4bytecodegenerator_p.h
@@ -0,0 +1,282 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QV4BYTECODEGENERATOR_P_H
+#define QV4BYTECODEGENERATOR_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+#include <private/qv4instr_moth_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QQmlJS {
+namespace AST {
+class SourceLocation;
+}
+}
+
+namespace QV4 {
+namespace Moth {
+
+class BytecodeGenerator {
+public:
+ BytecodeGenerator(int line, bool debug)
+ : startLine(line), debugMode(debug) {}
+
+ struct Label {
+ enum LinkMode {
+ LinkNow,
+ LinkLater
+ };
+ Label() = default;
+ Label(BytecodeGenerator *generator, LinkMode mode = LinkNow)
+ : generator(generator),
+ index(generator->labels.size()) {
+ generator->labels.append(mode == LinkNow ? generator->instructions.size() : -1);
+ }
+ static Label returnLabel() {
+ Label l;
+ l.index = INT_MAX;
+ return l;
+ }
+ bool isReturn() const {
+ return index == INT_MAX;
+ }
+
+ void link() {
+ Q_ASSERT(index >= 0);
+ Q_ASSERT(generator->labels[index] == -1);
+ generator->labels[index] = generator->instructions.size();
+ }
+
+ BytecodeGenerator *generator = 0;
+ int index = -1;
+ };
+
+ struct Jump {
+ Jump(BytecodeGenerator *generator, int instruction)
+ : generator(generator),
+ index(instruction)
+ {}
+ ~Jump() {
+ Q_ASSERT(generator->instructions[index].linkedLabel != -1);
+ }
+
+
+ BytecodeGenerator *generator;
+ int index;
+
+ void link() {
+ link(generator->label());
+ }
+ void link(Label l) {
+ Q_ASSERT(l.index >= 0);
+ Q_ASSERT(generator->instructions[index].linkedLabel == -1);
+ generator->instructions[index].linkedLabel = l.index;
+ }
+ };
+
+ struct ExceptionHandler : public Label {
+ ExceptionHandler(BytecodeGenerator *generator)
+ : Label(generator, LinkLater)
+ {
+ }
+ ~ExceptionHandler()
+ {
+ Q_ASSERT(generator->currentExceptionHandler != this);
+ }
+ };
+
+ Label label() {
+ return Label(this, Label::LinkNow);
+ }
+
+ Label newLabel() {
+ return Label(this, Label::LinkLater);
+ }
+
+ ExceptionHandler newExceptionHandler() {
+ return ExceptionHandler(this);
+ }
+
+ template<int InstrT>
+ void addInstruction(const InstrData<InstrT> &data)
+ {
+ Instr genericInstr;
+ InstrMeta<InstrT>::setData(genericInstr, data);
+ addInstructionHelper(Moth::Instr::Type(InstrT), genericInstr);
+ }
+
+ Q_REQUIRED_RESULT Jump jump()
+ {
+ Instruction::Jump data;
+ return addJumpInstruction(data);
+ }
+
+ Q_REQUIRED_RESULT Jump jumpTrue()
+ {
+ Instruction::JumpTrue data;
+ return addJumpInstruction(data);
+ }
+
+ Q_REQUIRED_RESULT Jump jumpFalse()
+ {
+ Instruction::JumpFalse data;
+ return addJumpInstruction(data);
+ }
+
+ void jumpStrictEqual(const StackSlot &lhs, const Label &target)
+ {
+ Instruction::CmpStrictEqual cmp;
+ cmp.lhs = lhs;
+ addInstruction(cmp);
+ addJumpInstruction(Instruction::JumpTrue()).link(target);
+ }
+
+ void jumpStrictNotEqual(const StackSlot &lhs, const Label &target)
+ {
+ Instruction::CmpStrictNotEqual cmp;
+ cmp.lhs = lhs;
+ addInstruction(cmp);
+ addJumpInstruction(Instruction::JumpTrue()).link(target);
+ }
+
+ Q_REQUIRED_RESULT Jump jumpStrictEqualStackSlotInt(const StackSlot &lhs, int rhs)
+ {
+ Instruction::JumpStrictEqualStackSlotInt data;
+ data.lhs = lhs;
+ data.rhs = rhs;
+ return addJumpInstruction(data);
+ }
+
+ Q_REQUIRED_RESULT Jump jumpStrictNotEqualStackSlotInt(const StackSlot &lhs, int rhs)
+ {
+ Instruction::JumpStrictNotEqualStackSlotInt data;
+ data.lhs = lhs;
+ data.rhs = rhs;
+ return addJumpInstruction(data);
+ }
+
+ void setExceptionHandler(ExceptionHandler *handler)
+ {
+ currentExceptionHandler = handler;
+ Instruction::SetExceptionHandler data;
+ data.offset = 0;
+ if (!handler)
+ addInstruction(data);
+ else
+ addJumpInstruction(data).link(*handler);
+ }
+
+ void setLocation(const QQmlJS::AST::SourceLocation &loc);
+
+ ExceptionHandler *exceptionHandler() const {
+ return currentExceptionHandler;
+ }
+
+ int newRegister();
+ int newRegisterArray(int n);
+ int registerCount() const { return regCount; }
+
+ void finalize(Compiler::Context *context);
+
+ template<int InstrT>
+ Jump addJumpInstruction(const InstrData<InstrT> &data)
+ {
+ Instr genericInstr;
+ InstrMeta<InstrT>::setData(genericInstr, data);
+ return Jump(this, addInstructionHelper(Moth::Instr::Type(InstrT), genericInstr, offsetof(InstrData<InstrT>, offset)));
+ }
+
+ void addCJumpInstruction(bool jumpOnFalse, const Label *trueLabel, const Label *falseLabel)
+ {
+ if (jumpOnFalse)
+ addJumpInstruction(Instruction::JumpFalse()).link(*falseLabel);
+ else
+ addJumpInstruction(Instruction::JumpTrue()).link(*trueLabel);
+ }
+
+private:
+ friend struct Jump;
+ friend struct Label;
+ friend struct ExceptionHandler;
+
+ int addInstructionHelper(Moth::Instr::Type type, const Instr &i, int offsetOfOffset = -1);
+
+ struct I {
+ Moth::Instr::Type type;
+ short size;
+ uint position;
+ int line;
+ int offsetForJump;
+ int linkedLabel;
+ char packed[sizeof(Instr) + 2]; // 2 for instruction and prefix
+ };
+
+ void compressInstructions();
+ void packInstruction(I &i);
+ void adjustJumpOffsets();
+
+ QVector<I> instructions;
+ QVector<int> labels;
+ ExceptionHandler *currentExceptionHandler;
+ int regCount = 0;
+public:
+ int currentReg = 0;
+private:
+ int startLine = 0;
+ int currentLine = 0;
+ bool debugMode = false;
+};
+
+}
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index b07e9f55f5..b2808784a0 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQml module of the Qt Toolkit.
@@ -39,7 +39,6 @@
#include "qv4codegen_p.h"
#include "qv4util_p.h"
-#include "qv4engine_p.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QStringList>
@@ -51,10 +50,10 @@
#include <private/qqmljsast_p.h>
#include <private/qv4string_p.h>
#include <private/qv4value_p.h>
-
-#ifndef V4_BOOTSTRAP
-#include <qv4context_p.h>
-#endif
+#include <private/qv4compilercontext_p.h>
+#include <private/qv4compilercontrolflow_p.h>
+#include <private/qv4bytecodegenerator_p.h>
+#include <private/qv4compilerscanfunctions_p.h>
#include <cmath>
#include <iostream>
@@ -63,37 +62,13 @@
#undef CONST
#endif
+QT_USE_NAMESPACE
using namespace QV4;
-using namespace QQmlJS;
-using namespace AST;
-
-static inline void setLocation(IR::Stmt *s, const SourceLocation &loc)
-{
- if (s && loc.isValid())
- s->location = loc;
-}
-
-static bool cjumpCanHandle(IR::AluOp op)
-{
- switch (op) {
- case IR::OpIn:
- case IR::OpInstanceof:
- case IR::OpEqual:
- case IR::OpNotEqual:
- case IR::OpGe:
- case IR::OpGt:
- case IR::OpLe:
- case IR::OpLt:
- case IR::OpStrictEqual:
- case IR::OpStrictNotEqual:
- return true;
- default:
- return false;
- }
-}
+using namespace QV4::Compiler;
+using namespace QQmlJS::AST;
-static inline void setJumpOutLocation(IR::Stmt *s, const Statement *body,
- const SourceLocation &fallback)
+static inline void setJumpOutLocation(QV4::Moth::BytecodeGenerator *bytecodeGenerator,
+ const Statement *body, const SourceLocation &fallback)
{
switch (body->kind) {
// Statements where we might never execute the last line.
@@ -105,664 +80,175 @@ static inline void setJumpOutLocation(IR::Stmt *s, const Statement *body,
case Statement::Kind_LocalForEachStatement:
case Statement::Kind_LocalForStatement:
case Statement::Kind_WhileStatement:
- setLocation(s, fallback);
+ bytecodeGenerator->setLocation(fallback);
break;
default:
- setLocation(s, body->lastSourceLocation());
+ bytecodeGenerator->setLocation(body->lastSourceLocation());
break;
}
}
-static inline bool isSimpleExpr(IR::Expr *e)
-{
- switch (e->exprKind) {
- case IR::Expr::TempExpr:
- case IR::Expr::ArgLocalExpr:
- case IR::Expr::ConstExpr:
- return true;
- default:
- return false;
- }
-}
-
-Codegen::ScanFunctions::ScanFunctions(Codegen *cg, const QString &sourceCode, CompilationMode defaultProgramMode)
- : _cg(cg)
- , _sourceCode(sourceCode)
- , _env(0)
- , _allowFuncDecls(true)
- , defaultProgramMode(defaultProgramMode)
-{
-}
-
-void Codegen::ScanFunctions::operator()(Node *node)
-{
- if (node)
- node->accept(this);
-}
-
-void Codegen::ScanFunctions::enterEnvironment(Node *node, CompilationMode compilationMode)
-{
- Environment *e = _cg->newEnvironment(node, _env, compilationMode);
- if (!e->isStrict)
- e->isStrict = _cg->_strictMode;
- _envStack.append(e);
- _env = e;
-}
-
-void Codegen::ScanFunctions::leaveEnvironment()
-{
- _envStack.pop();
- _env = _envStack.isEmpty() ? 0 : _envStack.top();
-}
-
-void Codegen::ScanFunctions::checkDirectivePrologue(SourceElements *ast)
-{
- for (SourceElements *it = ast; it; it = it->next) {
- if (StatementSourceElement *stmt = cast<StatementSourceElement *>(it->element)) {
- if (ExpressionStatement *expr = cast<ExpressionStatement *>(stmt->statement)) {
- if (StringLiteral *strLit = cast<StringLiteral *>(expr->expression)) {
- // Use the source code, because the StringLiteral's
- // value might have escape sequences in it, which is not
- // allowed.
- if (strLit->literalToken.length < 2)
- continue;
- QStringRef str = _sourceCode.midRef(strLit->literalToken.offset + 1, strLit->literalToken.length - 2);
- if (str == QLatin1String("use strict")) {
- _env->isStrict = true;
- } else {
- // TODO: give a warning.
- }
- continue;
- }
- }
- }
-
- break;
- }
-}
-
-void Codegen::ScanFunctions::checkName(const QStringRef &name, const SourceLocation &loc)
-{
- if (_env->isStrict) {
- if (name == QLatin1String("implements")
- || name == QLatin1String("interface")
- || name == QLatin1String("let")
- || name == QLatin1String("package")
- || name == QLatin1String("private")
- || name == QLatin1String("protected")
- || name == QLatin1String("public")
- || name == QLatin1String("static")
- || name == QLatin1String("yield")) {
- _cg->throwSyntaxError(loc, QStringLiteral("Unexpected strict mode reserved word"));
- }
- }
-}
-void Codegen::ScanFunctions::checkForArguments(AST::FormalParameterList *parameters)
-{
- while (parameters) {
- if (parameters->name == QLatin1String("arguments"))
- _env->usesArgumentsObject = Environment::ArgumentsObjectNotUsed;
- parameters = parameters->next;
- }
-}
-
-bool Codegen::ScanFunctions::visit(Program *ast)
-{
- enterEnvironment(ast, defaultProgramMode);
- checkDirectivePrologue(ast->elements);
- return true;
-}
-
-void Codegen::ScanFunctions::endVisit(Program *)
-{
- leaveEnvironment();
-}
-
-bool Codegen::ScanFunctions::visit(CallExpression *ast)
-{
- if (! _env->hasDirectEval) {
- if (IdentifierExpression *id = cast<IdentifierExpression *>(ast->base)) {
- if (id->name == QLatin1String("eval")) {
- if (_env->usesArgumentsObject == Environment::ArgumentsObjectUnknown)
- _env->usesArgumentsObject = Environment::ArgumentsObjectUsed;
- _env->hasDirectEval = true;
- }
- }
- }
- int argc = 0;
- for (ArgumentList *it = ast->arguments; it; it = it->next)
- ++argc;
- _env->maxNumberOfArguments = qMax(_env->maxNumberOfArguments, argc);
- return true;
-}
-
-bool Codegen::ScanFunctions::visit(NewMemberExpression *ast)
-{
- int argc = 0;
- for (ArgumentList *it = ast->arguments; it; it = it->next)
- ++argc;
- _env->maxNumberOfArguments = qMax(_env->maxNumberOfArguments, argc);
- return true;
-}
-
-bool Codegen::ScanFunctions::visit(ArrayLiteral *ast)
-{
- int index = 0;
- for (ElementList *it = ast->elements; it; it = it->next) {
- for (Elision *elision = it->elision; elision; elision = elision->next)
- ++index;
- ++index;
- }
- if (ast->elision) {
- for (Elision *elision = ast->elision->next; elision; elision = elision->next)
- ++index;
- }
- _env->maxNumberOfArguments = qMax(_env->maxNumberOfArguments, index);
- return true;
-}
-
-bool Codegen::ScanFunctions::visit(VariableDeclaration *ast)
-{
- if (_env->isStrict && (ast->name == QLatin1String("eval") || ast->name == QLatin1String("arguments")))
- _cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Variable name may not be eval or arguments in strict mode"));
- checkName(ast->name, ast->identifierToken);
- if (ast->name == QLatin1String("arguments"))
- _env->usesArgumentsObject = Environment::ArgumentsObjectNotUsed;
- _env->enter(ast->name.toString(), ast->expression ? Environment::VariableDefinition : Environment::VariableDeclaration);
- return true;
-}
-
-bool Codegen::ScanFunctions::visit(IdentifierExpression *ast)
-{
- checkName(ast->name, ast->identifierToken);
- if (_env->usesArgumentsObject == Environment::ArgumentsObjectUnknown && ast->name == QLatin1String("arguments"))
- _env->usesArgumentsObject = Environment::ArgumentsObjectUsed;
- return true;
-}
-
-bool Codegen::ScanFunctions::visit(ExpressionStatement *ast)
-{
- if (FunctionExpression* expr = AST::cast<AST::FunctionExpression*>(ast->expression)) {
- if (!_allowFuncDecls)
- _cg->throwSyntaxError(expr->functionToken, QStringLiteral("conditional function or closure declaration"));
-
- enterFunction(expr, /*enterName*/ true);
- Node::accept(expr->formals, this);
- Node::accept(expr->body, this);
- leaveEnvironment();
- return false;
- } else {
- SourceLocation firstToken = ast->firstSourceLocation();
- if (_sourceCode.midRef(firstToken.offset, firstToken.length) == QLatin1String("function")) {
- _cg->throwSyntaxError(firstToken, QStringLiteral("unexpected token"));
- }
- }
- return true;
-}
-
-bool Codegen::ScanFunctions::visit(FunctionExpression *ast)
-{
- enterFunction(ast, /*enterName*/ false);
- return true;
-}
-
-void Codegen::ScanFunctions::enterFunction(FunctionExpression *ast, bool enterName, bool isExpression)
-{
- if (_env->isStrict && (ast->name == QLatin1String("eval") || ast->name == QLatin1String("arguments")))
- _cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Function name may not be eval or arguments in strict mode"));
- enterFunction(ast, ast->name.toString(), ast->formals, ast->body, enterName ? ast : 0, isExpression);
-}
-
-void Codegen::ScanFunctions::endVisit(FunctionExpression *)
-{
- leaveEnvironment();
-}
-
-bool Codegen::ScanFunctions::visit(ObjectLiteral *ast)
-{
- int argc = 0;
- for (PropertyAssignmentList *it = ast->properties; it; it = it->next) {
- QString key = it->assignment->name->asString();
- if (QV4::String::toArrayIndex(key) != UINT_MAX)
- ++argc;
- ++argc;
- if (AST::cast<AST::PropertyGetterSetter *>(it->assignment))
- ++argc;
- }
- _env->maxNumberOfArguments = qMax(_env->maxNumberOfArguments, argc);
-
- TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, true);
- Node::accept(ast->properties, this);
- return false;
-}
-
-bool Codegen::ScanFunctions::visit(PropertyGetterSetter *ast)
-{
- TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, true);
- enterFunction(ast, QString(), ast->formals, ast->functionBody, /*FunctionExpression*/0, /*isExpression*/false);
- return true;
-}
-
-void Codegen::ScanFunctions::endVisit(PropertyGetterSetter *)
-{
- leaveEnvironment();
-}
-
-bool Codegen::ScanFunctions::visit(FunctionDeclaration *ast)
-{
- enterFunction(ast, /*enterName*/ true, /*isExpression */false);
- return true;
-}
-
-void Codegen::ScanFunctions::endVisit(FunctionDeclaration *)
-{
- leaveEnvironment();
-}
-
-bool Codegen::ScanFunctions::visit(WithStatement *ast)
-{
- if (_env->isStrict) {
- _cg->throwSyntaxError(ast->withToken, QStringLiteral("'with' statement is not allowed in strict mode"));
- return false;
- }
-
- return true;
-}
-
-bool Codegen::ScanFunctions::visit(DoWhileStatement *ast) {
- {
- TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, !_env->isStrict);
- Node::accept(ast->statement, this);
- }
- Node::accept(ast->expression, this);
- return false;
-}
-
-bool Codegen::ScanFunctions::visit(ForStatement *ast) {
- Node::accept(ast->initialiser, this);
- Node::accept(ast->condition, this);
- Node::accept(ast->expression, this);
-
- TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, !_env->isStrict);
- Node::accept(ast->statement, this);
-
- return false;
-}
-
-bool Codegen::ScanFunctions::visit(LocalForStatement *ast) {
- Node::accept(ast->declarations, this);
- Node::accept(ast->condition, this);
- Node::accept(ast->expression, this);
-
- TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, !_env->isStrict);
- Node::accept(ast->statement, this);
-
- return false;
-}
-
-bool Codegen::ScanFunctions::visit(ForEachStatement *ast) {
- Node::accept(ast->initialiser, this);
- Node::accept(ast->expression, this);
-
- TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, !_env->isStrict);
- Node::accept(ast->statement, this);
-
- return false;
-}
-
-bool Codegen::ScanFunctions::visit(LocalForEachStatement *ast) {
- Node::accept(ast->declaration, this);
- Node::accept(ast->expression, this);
-
- TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, !_env->isStrict);
- Node::accept(ast->statement, this);
-
- return false;
-}
-
-bool Codegen::ScanFunctions::visit(ThisExpression *)
-{
- _env->usesThis = true;
- return false;
-}
-
-bool Codegen::ScanFunctions::visit(Block *ast) {
- TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, _env->isStrict ? false : _allowFuncDecls);
- Node::accept(ast->statements, this);
- return false;
-}
-
-void Codegen::ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParameterList *formals, FunctionBody *body, FunctionExpression *expr, bool isExpression)
-{
- bool wasStrict = false;
- if (_env) {
- _env->hasNestedFunctions = true;
- // The identifier of a function expression cannot be referenced from the enclosing environment.
- if (expr)
- _env->enter(name, Environment::FunctionDefinition, expr);
- if (name == QLatin1String("arguments"))
- _env->usesArgumentsObject = Environment::ArgumentsObjectNotUsed;
- wasStrict = _env->isStrict;
- }
-
- enterEnvironment(ast, FunctionCode);
- checkForArguments(formals);
-
- _env->isNamedFunctionExpression = isExpression && !name.isEmpty();
- _env->formals = formals;
-
- if (body)
- checkDirectivePrologue(body->elements);
-
- if (wasStrict || _env->isStrict) {
- QStringList args;
- for (FormalParameterList *it = formals; it; it = it->next) {
- QString arg = it->name.toString();
- if (args.contains(arg)) {
- _cg->throwSyntaxError(it->identifierToken, QStringLiteral("Duplicate parameter name '%1' is not allowed in strict mode").arg(arg));
- return;
- }
- if (arg == QLatin1String("eval") || arg == QLatin1String("arguments")) {
- _cg->throwSyntaxError(it->identifierToken, QStringLiteral("'%1' cannot be used as parameter name in strict mode").arg(arg));
- return;
- }
- args += arg;
- }
- }
-}
-
-
-Codegen::Codegen(bool strict)
+Codegen::Codegen(QV4::Compiler::JSUnitGenerator *jsUnitGenerator, bool strict)
: _module(0)
- , _function(0)
- , _block(0)
- , _exitBlock(0)
, _returnAddress(0)
- , _env(0)
- , _loop(0)
+ , _context(0)
, _labelledStatement(0)
- , _scopeAndFinally(0)
+ , jsUnitGenerator(jsUnitGenerator)
, _strictMode(strict)
, _fileNameIsUrl(false)
, hasError(false)
{
+ jsUnitGenerator->codeGeneratorName = QStringLiteral("moth");
}
void Codegen::generateFromProgram(const QString &fileName,
const QString &finalUrl,
const QString &sourceCode,
Program *node,
- QV4::IR::Module *module,
- CompilationMode mode,
- const QStringList &inheritedLocals)
+ Module *module,
+ CompilationMode mode)
{
Q_ASSERT(node);
_module = module;
- _env = 0;
+ _context = 0;
- _module->setFileName(fileName);
- _module->setFinalUrl(finalUrl);
+ // ### should be set on the module outside of this method
+ _module->fileName = fileName;
+ _module->finalUrl = finalUrl;
ScanFunctions scan(this, sourceCode, mode);
scan(node);
- defineFunction(QStringLiteral("%entry"), node, 0, node->elements, inheritedLocals);
- qDeleteAll(_envMap);
- _envMap.clear();
+ defineFunction(QStringLiteral("%entry"), node, 0, node->elements);
}
-void Codegen::generateFromFunctionExpression(const QString &fileName,
- const QString &finalUrl,
- const QString &sourceCode,
- AST::FunctionExpression *ast,
- QV4::IR::Module *module)
+void Codegen::enterContext(Node *node)
{
- _module = module;
- _module->setFileName(fileName);
- _module->setFinalUrl(finalUrl);
- _env = 0;
-
- ScanFunctions scan(this, sourceCode, GlobalCode);
- // fake a global environment
- scan.enterEnvironment(0, FunctionCode);
- scan(ast);
- scan.leaveEnvironment();
-
- defineFunction(ast->name.toString(), ast, ast->formals, ast->body ? ast->body->elements : 0);
-
- qDeleteAll(_envMap);
- _envMap.clear();
-}
-
-
-void Codegen::enterEnvironment(Node *node)
-{
- _env = _envMap.value(node);
- Q_ASSERT(_env);
-}
-
-void Codegen::leaveEnvironment()
-{
- Q_ASSERT(_env);
- _env = _env->parent;
-}
-
-void Codegen::enterLoop(Statement *node, IR::BasicBlock *breakBlock, IR::BasicBlock *continueBlock)
-{
- _loop = new Loop(node, breakBlock, continueBlock, _loop);
- _loop->labelledStatement = _labelledStatement; // consume the enclosing labelled statement
- _loop->scopeAndFinally = _scopeAndFinally;
- _labelledStatement = 0;
-}
-
-void Codegen::leaveLoop()
-{
- Loop *current = _loop;
- _loop = _loop->parent;
- delete current;
+ _context = _module->contextMap.value(node);
+ Q_ASSERT(_context);
}
-IR::Expr *Codegen::member(IR::Expr *base, const QString *name)
+int Codegen::leaveContext()
{
- if (hasError)
- return 0;
-
- if (base->asTemp() || base->asArgLocal())
- return _block->MEMBER(base, name);
- else {
- const unsigned t = _block->newTemp();
- move(_block->TEMP(t), base);
- return _block->MEMBER(_block->TEMP(t), name);
- }
-}
-
-IR::Expr *Codegen::argument(IR::Expr *expr)
-{
- if (expr && !expr->asTemp()) {
- const unsigned t = _block->newTemp();
- move(_block->TEMP(t), expr);
- expr = _block->TEMP(t);
- }
- return expr;
-}
-
-// keeps references alive, converts other expressions to temps
-IR::Expr *Codegen::reference(IR::Expr *expr)
-{
- if (hasError)
- return 0;
-
- if (expr && !expr->asTemp() && !expr->asArgLocal() && !expr->asName() && !expr->asMember() && !expr->asSubscript()) {
- const unsigned t = _block->newTemp();
- move(_block->TEMP(t), expr);
- expr = _block->TEMP(t);
- }
- return expr;
+ Q_ASSERT(_context);
+ Q_ASSERT(!_context->controlFlow);
+ int functionIndex = _context->functionIndex;
+ _context = _context->parent;
+ return functionIndex;
}
-IR::Expr *Codegen::unop(IR::AluOp op, IR::Expr *expr, const SourceLocation &loc)
+Codegen::Reference Codegen::unop(UnaryOperation op, const Reference &expr)
{
if (hasError)
- return 0;
-
- Q_ASSERT(op != IR::OpIncrement);
- Q_ASSERT(op != IR::OpDecrement);
+ return _expr.result();
- if (IR::Const *c = expr->asConst()) {
- if (c->type == IR::NumberType) {
+#ifndef V4_BOOTSTRAP
+ if (expr.isConst()) {
+ auto v = Value::fromReturnedValue(expr.constant);
+ if (v.isNumber()) {
switch (op) {
- case IR::OpNot:
- return _block->CONST(IR::BoolType, !c->value);
- case IR::OpUMinus:
- return _block->CONST(IR::NumberType, -c->value);
- case IR::OpUPlus:
+ case Not:
+ return Reference::fromConst(this, Encode(!v.toBoolean()));
+ case UMinus:
+ return Reference::fromConst(this, Runtime::method_uMinus(v));
+ case UPlus:
return expr;
- case IR::OpCompl:
- return _block->CONST(IR::NumberType, ~QV4::Primitive::toInt32(c->value));
- case IR::OpIncrement:
- return _block->CONST(IR::NumberType, c->value + 1);
- case IR::OpDecrement:
- return _block->CONST(IR::NumberType, c->value - 1);
+ case Compl:
+ return Reference::fromConst(this, Encode((int)~v.toInt32()));
default:
break;
}
}
}
+#endif // V4_BOOTSTRAP
- TempScope scope(_function);
- if (isSimpleExpr(expr))
- return _block->UNOP(op, expr);
-
- const unsigned t = _block->newTemp();
- setLocation(move(_block->TEMP(t), expr), loc);
- expr = _block->TEMP(t);
- return _block->UNOP(op, expr);
-}
-
-IR::Expr *Codegen::binop(IR::AluOp op, IR::Expr *left, IR::Expr *right, const AST::SourceLocation &loc)
-{
- if (hasError)
- return 0;
-
- TempScope scope(_function);
-
- if (IR::Const *c1 = left->asConst()) {
- if (IR::Const *c2 = right->asConst()) {
- if ((c1->type & IR::NumberType) && (c2->type & IR::NumberType)) {
- switch (op) {
- case IR::OpAdd: return _block->CONST(IR::NumberType, c1->value + c2->value);
- case IR::OpAnd: return _block->CONST(IR::BoolType, c1->value ? c2->value : 0);
- case IR::OpBitAnd: return _block->CONST(IR::NumberType, int(c1->value) & int(c2->value));
- case IR::OpBitOr: return _block->CONST(IR::NumberType, int(c1->value) | int(c2->value));
- case IR::OpBitXor: return _block->CONST(IR::NumberType, int(c1->value) ^ int(c2->value));
- case IR::OpDiv: return _block->CONST(IR::NumberType, c1->value / c2->value);
- case IR::OpEqual: return _block->CONST(IR::BoolType, c1->value == c2->value);
- case IR::OpNotEqual: return _block->CONST(IR::BoolType, c1->value != c2->value);
- case IR::OpStrictEqual: return _block->CONST(IR::BoolType, c1->value == c2->value);
- case IR::OpStrictNotEqual: return _block->CONST(IR::BoolType, c1->value != c2->value);
- case IR::OpGe: return _block->CONST(IR::BoolType, c1->value >= c2->value);
- case IR::OpGt: return _block->CONST(IR::BoolType, c1->value > c2->value);
- case IR::OpLe: return _block->CONST(IR::BoolType, c1->value <= c2->value);
- case IR::OpLt: return _block->CONST(IR::BoolType, c1->value < c2->value);
- case IR::OpLShift: return _block->CONST(IR::NumberType, QV4::Primitive::toInt32(c1->value) << (QV4::Primitive::toUInt32(c2->value) & 0x1f));
- case IR::OpMod: return _block->CONST(IR::NumberType, std::fmod(c1->value, c2->value));
- case IR::OpMul: return _block->CONST(IR::NumberType, c1->value * c2->value);
- case IR::OpOr: return _block->CONST(IR::NumberType, c1->value ? c1->value : c2->value);
- case IR::OpRShift: return _block->CONST(IR::NumberType, QV4::Primitive::toInt32(c1->value) >> (QV4::Primitive::toUInt32(c2->value) & 0x1f));
- case IR::OpSub: return _block->CONST(IR::NumberType, c1->value - c2->value);
- case IR::OpURShift: return _block->CONST(IR::NumberType,QV4::Primitive::toUInt32(c1->value) >> (QV4::Primitive::toUInt32(c2->value) & 0x1f));
-
- case IR::OpInstanceof:
- case IR::OpIn:
- break;
-
- case IR::OpIfTrue: // unary ops
- case IR::OpNot:
- case IR::OpUMinus:
- case IR::OpUPlus:
- case IR::OpCompl:
- case IR::OpIncrement:
- case IR::OpDecrement:
- case IR::OpInvalid:
- break;
- }
- }
+ switch (op) {
+ case UMinus: {
+ expr.loadInAccumulator();
+ Instruction::UMinus uminus;
+ bytecodeGenerator->addInstruction(uminus);
+ return Reference::fromAccumulator(this);
+ }
+ case UPlus: {
+ expr.loadInAccumulator();
+ Instruction::UPlus uplus;
+ bytecodeGenerator->addInstruction(uplus);
+ return Reference::fromAccumulator(this);
+ }
+ case Not: {
+ expr.loadInAccumulator();
+ Instruction::UNot unot;
+ bytecodeGenerator->addInstruction(unot);
+ return Reference::fromAccumulator(this);
+ }
+ case Compl: {
+ expr.loadInAccumulator();
+ Instruction::UCompl ucompl;
+ bytecodeGenerator->addInstruction(ucompl);
+ return Reference::fromAccumulator(this);
+ }
+ case PostIncrement:
+ if (!_expr.accept(nx) || requiresReturnValue) {
+ Reference e = expr.asLValue();
+ e.loadInAccumulator();
+ Instruction::UPlus uplus;
+ bytecodeGenerator->addInstruction(uplus);
+ Reference originalValue = Reference::fromStackSlot(this).storeRetainAccumulator();
+ Instruction::Increment inc;
+ bytecodeGenerator->addInstruction(inc);
+ e.storeConsumeAccumulator();
+ return originalValue;
+ } else {
+ // intentionally fall-through: the result is never used, so it's equivalent to
+ // "expr += 1", which is what a pre-increment does as well.
+ Q_FALLTHROUGH();
}
- } else if (op == IR::OpAdd) {
- if (IR::String *s1 = left->asString()) {
- if (IR::String *s2 = right->asString()) {
- return _block->STRING(_function->newString(*s1->value + *s2->value));
- }
+ case PreIncrement: {
+ Reference e = expr.asLValue();
+ e.loadInAccumulator();
+ Instruction::Increment inc;
+ bytecodeGenerator->addInstruction(inc);
+ if (_expr.accept(nx))
+ return e.storeConsumeAccumulator();
+ else
+ return e.storeRetainAccumulator();
+ }
+ case PostDecrement:
+ if (!_expr.accept(nx) || requiresReturnValue) {
+ Reference e = expr.asLValue();
+ e.loadInAccumulator();
+ Instruction::UPlus uplus;
+ bytecodeGenerator->addInstruction(uplus);
+ Reference originalValue = Reference::fromStackSlot(this).storeRetainAccumulator();
+ Instruction::Decrement dec;
+ bytecodeGenerator->addInstruction(dec);
+ e.storeConsumeAccumulator();
+ return originalValue;
+ } else {
+ // intentionally fall-through: the result is never used, so it's equivalent to
+ // "expr -= 1", which is what a pre-decrement does as well.
+ Q_FALLTHROUGH();
}
+ case PreDecrement: {
+ Reference e = expr.asLValue();
+ e.loadInAccumulator();
+ Instruction::Decrement dec;
+ bytecodeGenerator->addInstruction(dec);
+ if (_expr.accept(nx))
+ return e.storeConsumeAccumulator();
+ else
+ return e.storeRetainAccumulator();
}
-
- if (!left->asTemp() && !left->asArgLocal() && !left->asConst()) {
- const unsigned t = _block->newTemp();
- setLocation(move(_block->TEMP(t), left), loc);
- left = _block->TEMP(t);
- }
-
- if (!right->asTemp() && !right->asArgLocal() && !right->asConst()) {
- const unsigned t = _block->newTemp();
- setLocation(move(_block->TEMP(t), right), loc);
- right = _block->TEMP(t);
}
- Q_ASSERT(left->asTemp() || left->asArgLocal() || left->asConst());
- Q_ASSERT(right->asTemp() || right->asArgLocal() || right->asConst());
-
- return _block->BINOP(op, left, right);
+ Q_UNREACHABLE();
}
-IR::Expr *Codegen::call(IR::Expr *base, IR::ExprList *args)
+void Codegen::addCJump()
{
- if (hasError)
- return 0;
- base = reference(base);
- return _block->CALL(base, args);
-}
-
-IR::Stmt *Codegen::move(IR::Expr *target, IR::Expr *source, IR::AluOp op)
-{
- if (hasError)
- return 0;
-
- Q_ASSERT(target->isLValue());
-
- if (op != IR::OpInvalid) {
- return move(target, binop(op, target, source));
- }
-
- TempScope scope(_function);
-
- if (!source->asTemp() && !source->asConst() && !target->asTemp() && !source->asArgLocal() && !target->asArgLocal()) {
- unsigned t = _block->newTemp();
- _block->MOVE(_block->TEMP(t), source);
- source = _block->TEMP(t);
- }
- if (source->asConst() && !target->asTemp() && !target->asArgLocal()) {
- unsigned t = _block->newTemp();
- _block->MOVE(_block->TEMP(t), source);
- source = _block->TEMP(t);
- }
-
- return _block->MOVE(target, source);
-}
-
-IR::Stmt *Codegen::cjump(IR::Expr *cond, IR::BasicBlock *iftrue, IR::BasicBlock *iffalse)
-{
- if (hasError)
- return 0;
-
- TempScope scope(_function);
-
- if (! (cond->asTemp() || (cond->asBinop() && cjumpCanHandle(cond->asBinop()->op)) )) {
- const unsigned t = _block->newTemp();
- move(_block->TEMP(t), cond);
- cond = _block->TEMP(t);
- }
- return _block->CJUMP(cond, iftrue, iffalse);
+ bytecodeGenerator->addCJumpInstruction(_expr.trueBlockFollowsCondition(),
+ _expr.iftrue(), _expr.iffalse());
}
void Codegen::accept(Node *node)
@@ -776,52 +262,71 @@ void Codegen::accept(Node *node)
void Codegen::statement(Statement *ast)
{
- TempScope scope(_function);
+ RegisterScope scope(this);
+
+ bytecodeGenerator->setLocation(ast->firstSourceLocation());
- _block->nextLocation = ast->firstSourceLocation();
+ VolatileMemoryLocations vLocs = scanVolatileMemoryLocations(ast);
+ qSwap(_volataleMemoryLocations, vLocs);
accept(ast);
+ qSwap(_volataleMemoryLocations, vLocs);
}
void Codegen::statement(ExpressionNode *ast)
{
- TempScope scope(_function);
+ RegisterScope scope(this);
if (! ast) {
return;
} else {
Result r(nx);
qSwap(_expr, r);
+ VolatileMemoryLocations vLocs = scanVolatileMemoryLocations(ast);
+ qSwap(_volataleMemoryLocations, vLocs);
+
accept(ast);
+
+ qSwap(_volataleMemoryLocations, vLocs);
+ qSwap(_expr, r);
+
if (hasError)
return;
- qSwap(_expr, r);
- if (r.format == ex) {
- if (r->asCall()) {
- _block->EXP(*r); // the nest nx representation for calls is EXP(CALL(c..))
- } else if (r->asTemp() || r->asArgLocal()) {
- // there is nothing to do
- } else {
- unsigned t = _block->newTemp();
- move(_block->TEMP(t), *r);
- }
- }
+ if (r.result().loadTriggersSideEffect())
+ r.result().loadInAccumulator(); // triggers side effects
}
}
-void Codegen::condition(ExpressionNode *ast, IR::BasicBlock *iftrue, IR::BasicBlock *iffalse)
+void Codegen::condition(ExpressionNode *ast, const BytecodeGenerator::Label *iftrue,
+ const BytecodeGenerator::Label *iffalse, bool trueBlockFollowsCondition)
{
- if (ast) {
- Result r(iftrue, iffalse);
- qSwap(_expr, r);
- accept(ast);
- qSwap(_expr, r);
- if (r.format == ex) {
- setLocation(cjump(*r, r.iftrue, r.iffalse), ast->firstSourceLocation());
- }
+ if (hasError)
+ return;
+
+ if (!ast)
+ return;
+
+ Result r(iftrue, iffalse, trueBlockFollowsCondition);
+ qSwap(_expr, r);
+ accept(ast);
+ qSwap(_expr, r);
+
+ if (hasError)
+ return;
+
+ if (r.format() == ex) {
+ Q_ASSERT(iftrue == r.iftrue());
+ Q_ASSERT(iffalse == r.iffalse());
+ Q_ASSERT(r.result().isValid());
+ bytecodeGenerator->setLocation(ast->firstSourceLocation());
+ r.result().loadInAccumulator();
+ if (r.trueBlockFollowsCondition())
+ bytecodeGenerator->jumpFalse().link(*r.iffalse());
+ else
+ bytecodeGenerator->jumpTrue().link(*r.iftrue());
}
}
-Codegen::Result Codegen::expression(ExpressionNode *ast)
+Codegen::Reference Codegen::expression(ExpressionNode *ast)
{
Result r;
if (ast) {
@@ -829,7 +334,7 @@ Codegen::Result Codegen::expression(ExpressionNode *ast)
accept(ast);
qSwap(_expr, r);
}
- return r;
+ return r.result();
}
Codegen::Result Codegen::sourceElement(SourceElement *ast)
@@ -843,17 +348,6 @@ Codegen::Result Codegen::sourceElement(SourceElement *ast)
return r;
}
-Codegen::UiMember Codegen::uiObjectMember(UiObjectMember *ast)
-{
- UiMember m;
- if (ast) {
- qSwap(_uiMember, m);
- accept(ast);
- qSwap(_uiMember, m);
- }
- return m;
-}
-
void Codegen::functionBody(FunctionBody *ast)
{
if (ast)
@@ -869,36 +363,58 @@ void Codegen::program(Program *ast)
void Codegen::sourceElements(SourceElements *ast)
{
+ bool _requiresReturnValue = false;
+ qSwap(_requiresReturnValue, requiresReturnValue);
for (SourceElements *it = ast; it; it = it->next) {
+ if (!it->next)
+ qSwap(_requiresReturnValue, requiresReturnValue);
sourceElement(it->element);
if (hasError)
return;
+ if (StatementSourceElement *sse = AST::cast<StatementSourceElement *>(it->element)) {
+ if (AST::cast<ThrowStatement *>(sse->statement) ||
+ AST::cast<ReturnStatement *>(sse->statement))
+ return;
+ }
+ }
+}
+
+void Codegen::statementList(StatementList *ast)
+{
+ bool _requiresReturnValue = requiresReturnValue;
+ requiresReturnValue = false;
+ for (StatementList *it = ast; it; it = it->next) {
+ if (!it->next ||
+ it->next->statement->kind == Statement::Kind_BreakStatement ||
+ it->next->statement->kind == Statement::Kind_ContinueStatement ||
+ it->next->statement->kind == Statement::Kind_ReturnStatement)
+ requiresReturnValue = _requiresReturnValue;
+ statement(it->statement);
+ requiresReturnValue = false;
+ if (it->statement->kind == Statement::Kind_ThrowStatement ||
+ it->statement->kind == Statement::Kind_BreakStatement ||
+ it->statement->kind == Statement::Kind_ContinueStatement ||
+ it->statement->kind == Statement::Kind_ReturnStatement)
+ // any code after those statements is unreachable
+ break;
}
+ requiresReturnValue = _requiresReturnValue;
}
void Codegen::variableDeclaration(VariableDeclaration *ast)
{
- IR::Expr *initializer = 0;
+ RegisterScope scope(this);
+
if (!ast->expression)
return;
- Result expr = expression(ast->expression);
+ Reference rhs = expression(ast->expression);
if (hasError)
return;
- Q_ASSERT(expr.code);
- initializer = *expr;
-
- IR::Expr *lhs = identifier(ast->name.toString(), ast->identifierToken.startLine,
- ast->identifierToken.startColumn);
-
- if (lhs->asArgLocal()) {
- move(lhs, initializer);
- } else {
- TempScope scope(_function);
- int initialized = _block->newTemp();
- move(_block->TEMP(initialized), initializer);
- move(lhs, _block->TEMP(initialized));
- }
+ Reference lhs = referenceForName(ast->name.toString(), true);
+ //### if lhs is a temp, this won't generate a temp-to-temp move. Same for when rhs is a const
+ rhs.loadInAccumulator();
+ lhs.storeConsumeAccumulator();
}
void Codegen::variableDeclarationList(VariableDeclarationList *ast)
@@ -911,175 +427,175 @@ void Codegen::variableDeclarationList(VariableDeclarationList *ast)
bool Codegen::visit(ArgumentList *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(CaseBlock *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(CaseClause *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(CaseClauses *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(Catch *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(DefaultClause *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(ElementList *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(Elision *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(Finally *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(FormalParameterList *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(FunctionBody *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(Program *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(PropertyAssignmentList *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(PropertyNameAndValue *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(PropertyGetterSetter *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(SourceElements *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(StatementList *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(UiArrayMemberList *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(UiImport *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(UiHeaderItemList *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(UiPragma *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(UiObjectInitializer *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(UiObjectMemberList *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(UiParameterList *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(UiProgram *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(UiQualifiedId *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(UiQualifiedPragmaId *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(VariableDeclaration *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
bool Codegen::visit(VariableDeclarationList *)
{
- Q_ASSERT(!"unreachable");
+ Q_UNREACHABLE();
return false;
}
@@ -1098,57 +614,47 @@ bool Codegen::visit(ArrayLiteral *ast)
if (hasError)
return false;
- const unsigned t = _block->newTemp();
+ RegisterScope scope(this);
- TempScope scope(_function);
+ int argc = 0;
+ int args = -1;
+ auto push = [this, &argc, &args](AST::ExpressionNode *arg) {
+ int temp = bytecodeGenerator->newRegister();
+ if (args == -1)
+ args = temp;
+ if (!arg) {
+ auto c = Reference::fromConst(this, Primitive::emptyValue().asReturnedValue());
+ (void) c.storeOnStack(temp);
+ } else {
+ RegisterScope scope(this);
+ (void) expression(arg).storeOnStack(temp);
+ }
+ ++argc;
+ };
- IR::ExprList *args = 0;
- IR::ExprList *current = 0;
for (ElementList *it = ast->elements; it; it = it->next) {
- for (Elision *elision = it->elision; elision; elision = elision->next) {
- IR::ExprList *arg = _function->New<IR::ExprList>();
- if (!current) {
- args = arg;
- } else {
- current->next = arg;
- }
- current = arg;
- current->expr = _block->CONST(IR::MissingType, 0);
- }
- Result expr = expression(it->expression);
- if (hasError)
- return false;
- IR::ExprList *arg = _function->New<IR::ExprList>();
- if (!current) {
- args = arg;
- } else {
- current->next = arg;
- }
- current = arg;
+ for (Elision *elision = it->elision; elision; elision = elision->next)
+ push(0);
- IR::Expr *exp = *expr;
- if (exp->asTemp() || expr->asArgLocal() || exp->asConst()) {
- current->expr = exp;
- } else {
- unsigned value = _block->newTemp();
- move(_block->TEMP(value), exp);
- current->expr = _block->TEMP(value);
- }
+ push(it->expression);
+ if (hasError)
+ return false;
}
- for (Elision *elision = ast->elision; elision; elision = elision->next) {
- IR::ExprList *arg = _function->New<IR::ExprList>();
- if (!current) {
- args = arg;
- } else {
- current->next = arg;
- }
- current = arg;
- current->expr = _block->CONST(IR::MissingType, 0);
+ for (Elision *elision = ast->elision; elision; elision = elision->next)
+ push(0);
+
+ if (args == -1) {
+ Q_ASSERT(argc == 0);
+ args = 0;
}
- move(_block->TEMP(t), _block->CALL(_block->NAME(IR::Name::builtin_define_array, 0, 0), args));
- _expr.code = _block->TEMP(t);
+ Instruction::DefineArray call;
+ call.argc = argc;
+ call.args = Moth::StackSlot::createRegister(args);
+ bytecodeGenerator->addInstruction(call);
+ _expr.setResult(Reference::fromAccumulator(this));
+
return false;
}
@@ -1157,43 +663,41 @@ bool Codegen::visit(ArrayMemberExpression *ast)
if (hasError)
return false;
- IR::Expr *base = *expression(ast->base);
+ Reference base = expression(ast->base);
if (hasError)
return false;
- if (!isSimpleExpr(base)) {
- const unsigned t = _block->newTemp();
- move(_block->TEMP(t), base);
- base = _block->TEMP(t);
- }
-
- IR::Expr *index = *expression(ast->expression);
- if (hasError)
+ base = base.storeOnStack();
+ if (AST::StringLiteral *str = AST::cast<AST::StringLiteral *>(ast->expression)) {
+ QString s = str->value.toString();
+ uint arrayIndex = QV4::String::toArrayIndex(s);
+ if (arrayIndex == UINT_MAX) {
+ _expr.setResult(Reference::fromMember(base, str->value.toString()));
+ return false;
+ }
+ Reference index = Reference::fromConst(this, QV4::Encode(arrayIndex));
+ _expr.setResult(Reference::fromSubscript(base, index));
return false;
- if (!isSimpleExpr(index)) {
- const unsigned t = _block->newTemp();
- move(_block->TEMP(t), index);
- index = _block->TEMP(t);
}
-
- _expr.code = _block->SUBSCRIPT(base, index);
+ Reference index = expression(ast->expression);
+ _expr.setResult(Reference::fromSubscript(base, index));
return false;
}
-static IR::AluOp baseOp(int op)
+static QSOperator::Op baseOp(int op)
{
switch ((QSOperator::Op) op) {
- case QSOperator::InplaceAnd: return IR::OpBitAnd;
- case QSOperator::InplaceSub: return IR::OpSub;
- case QSOperator::InplaceDiv: return IR::OpDiv;
- case QSOperator::InplaceAdd: return IR::OpAdd;
- case QSOperator::InplaceLeftShift: return IR::OpLShift;
- case QSOperator::InplaceMod: return IR::OpMod;
- case QSOperator::InplaceMul: return IR::OpMul;
- case QSOperator::InplaceOr: return IR::OpBitOr;
- case QSOperator::InplaceRightShift: return IR::OpRShift;
- case QSOperator::InplaceURightShift: return IR::OpURShift;
- case QSOperator::InplaceXor: return IR::OpBitXor;
- default: return IR::OpInvalid;
+ case QSOperator::InplaceAnd: return QSOperator::BitAnd;
+ case QSOperator::InplaceSub: return QSOperator::Sub;
+ case QSOperator::InplaceDiv: return QSOperator::Div;
+ case QSOperator::InplaceAdd: return QSOperator::Add;
+ case QSOperator::InplaceLeftShift: return QSOperator::LShift;
+ case QSOperator::InplaceMod: return QSOperator::Mod;
+ case QSOperator::InplaceMul: return QSOperator::Mul;
+ case QSOperator::InplaceOr: return QSOperator::BitOr;
+ case QSOperator::InplaceRightShift: return QSOperator::RShift;
+ case QSOperator::InplaceURightShift: return QSOperator::URShift;
+ case QSOperator::InplaceXor: return QSOperator::BitXor;
+ default: return QSOperator::Invalid;
}
}
@@ -1204,89 +708,89 @@ bool Codegen::visit(BinaryExpression *ast)
if (ast->op == QSOperator::And) {
if (_expr.accept(cx)) {
- IR::BasicBlock *iftrue = _function->newBasicBlock(exceptionHandler());
- condition(ast->left, iftrue, _expr.iffalse);
- _block = iftrue;
- condition(ast->right, _expr.iftrue, _expr.iffalse);
+ auto iftrue = bytecodeGenerator->newLabel();
+ condition(ast->left, &iftrue, _expr.iffalse(), true);
+ iftrue.link();
+ condition(ast->right, _expr.iftrue(), _expr.iffalse(), _expr.trueBlockFollowsCondition());
} else {
- IR::BasicBlock *iftrue = _function->newBasicBlock(exceptionHandler());
- IR::BasicBlock *endif = _function->newBasicBlock(exceptionHandler());
-
- const unsigned r = _block->newTemp();
+ auto iftrue = bytecodeGenerator->newLabel();
+ auto endif = bytecodeGenerator->newLabel();
- Result lhs = expression(ast->left);
+ Reference left = expression(ast->left);
if (hasError)
return false;
- move(_block->TEMP(r), *lhs);
- setLocation(cjump(_block->TEMP(r), iftrue, endif), ast->operatorToken);
- _block = iftrue;
- Result rhs = expression(ast->right);
+ left.loadInAccumulator();
+
+ bytecodeGenerator->setLocation(ast->operatorToken);
+ bytecodeGenerator->jumpFalse().link(endif);
+ iftrue.link();
+
+ Reference right = expression(ast->right);
if (hasError)
return false;
- move(_block->TEMP(r), *rhs);
- _block->JUMP(endif);
+ right.loadInAccumulator();
- _expr.code = _block->TEMP(r);
- _block = endif;
+ endif.link();
+
+ _expr.setResult(Reference::fromAccumulator(this));
}
return false;
} else if (ast->op == QSOperator::Or) {
if (_expr.accept(cx)) {
- IR::BasicBlock *iffalse = _function->newBasicBlock(exceptionHandler());
- condition(ast->left, _expr.iftrue, iffalse);
- _block = iffalse;
- condition(ast->right, _expr.iftrue, _expr.iffalse);
+ auto iffalse = bytecodeGenerator->newLabel();
+ condition(ast->left, _expr.iftrue(), &iffalse, false);
+ iffalse.link();
+ condition(ast->right, _expr.iftrue(), _expr.iffalse(), _expr.trueBlockFollowsCondition());
} else {
- IR::BasicBlock *iffalse = _function->newBasicBlock(exceptionHandler());
- IR::BasicBlock *endif = _function->newBasicBlock(exceptionHandler());
+ auto iffalse = bytecodeGenerator->newLabel();
+ auto endif = bytecodeGenerator->newLabel();
- const unsigned r = _block->newTemp();
- Result lhs = expression(ast->left);
+ Reference left = expression(ast->left);
if (hasError)
return false;
- move(_block->TEMP(r), *lhs);
- setLocation(cjump(_block->TEMP(r), endif, iffalse), ast->operatorToken);
- _block = iffalse;
- Result rhs = expression(ast->right);
+ left.loadInAccumulator();
+
+ bytecodeGenerator->setLocation(ast->operatorToken);
+ bytecodeGenerator->jumpTrue().link(endif);
+ iffalse.link();
+
+ Reference right = expression(ast->right);
if (hasError)
return false;
- move(_block->TEMP(r), *rhs);
- _block->JUMP(endif);
+ right.loadInAccumulator();
+
+ endif.link();
- _block = endif;
- _expr.code = _block->TEMP(r);
+ _expr.setResult(Reference::fromAccumulator(this));
}
return false;
}
- IR::Expr* left = *expression(ast->left);
+ Reference left = expression(ast->left);
if (hasError)
return false;
switch (ast->op) {
case QSOperator::Or:
case QSOperator::And:
+ Q_UNREACHABLE(); // handled separately above
break;
case QSOperator::Assign: {
+ if (!left.isLValue()) {
+ throwReferenceError(ast->operatorToken, QStringLiteral("left-hand side of assignment operator is not an lvalue"));
+ return false;
+ }
+ left = left.asLValue();
if (throwSyntaxErrorOnEvalOrArgumentsInStrictMode(left, ast->left->lastSourceLocation()))
return false;
- Result right = expression(ast->right);
+ expression(ast->right).loadInAccumulator();
if (hasError)
return false;
- if (!left->isLValue()) {
- throwReferenceError(ast->operatorToken, QStringLiteral("left-hand side of assignment operator is not an lvalue"));
- return false;
- }
-
- if (_expr.accept(nx)) {
- move(left, *right);
- } else {
- const unsigned t = _block->newTemp();
- move(_block->TEMP(t), *right);
- move(left, _block->TEMP(t));
- _expr.code = _block->TEMP(t);
- }
+ if (_expr.accept(nx))
+ _expr.setResult(left.storeConsumeAccumulator());
+ else
+ _expr.setResult(left.storeRetainAccumulator());
break;
}
@@ -1303,23 +807,36 @@ bool Codegen::visit(BinaryExpression *ast)
case QSOperator::InplaceXor: {
if (throwSyntaxErrorOnEvalOrArgumentsInStrictMode(left, ast->left->lastSourceLocation()))
return false;
- Result right = expression(ast->right);
- if (hasError)
- return false;
- if (!left->isLValue()) {
+
+ if (!left.isLValue()) {
throwSyntaxError(ast->operatorToken, QStringLiteral("left-hand side of inplace operator is not an lvalue"));
return false;
}
+ left = left.asLValue();
+
+ Reference tempLeft = left.storeOnStack();
+ Reference right = expression(ast->right);
+
+ if (hasError)
+ return false;
+
+ binopHelper(baseOp(ast->op), tempLeft, right).loadInAccumulator();
+ _expr.setResult(left.storeRetainAccumulator());
- TempScope scope(_function);
- const unsigned t = _block->newTemp();
- move(_block->TEMP(t), *right);
- move(left, _block->TEMP(t), baseOp(ast->op));
- if (!_expr.accept(nx))
- _expr.code = left;
break;
}
+ case QSOperator::BitAnd:
+ case QSOperator::BitOr:
+ case QSOperator::BitXor:
+ if (left.isConst()) {
+ Reference right = expression(ast->right);
+ if (hasError)
+ return false;
+ _expr.setResult(binopHelper(static_cast<QSOperator::Op>(ast->op), right, left));
+ break;
+ }
+ // intentional fall-through!
case QSOperator::In:
case QSOperator::InstanceOf:
case QSOperator::Equal:
@@ -1329,55 +846,408 @@ bool Codegen::visit(BinaryExpression *ast)
case QSOperator::Le:
case QSOperator::Lt:
case QSOperator::StrictEqual:
- case QSOperator::StrictNotEqual: {
- TempScope scope(_function);
- if (!left->asTemp() && !left->asArgLocal() && !left->asConst()) {
- const unsigned t = _block->newTemp();
- setLocation(move(_block->TEMP(t), left), ast->operatorToken);
- left = _block->TEMP(t);
+ case QSOperator::StrictNotEqual:
+ case QSOperator::Add:
+ case QSOperator::Div:
+ case QSOperator::Mod:
+ case QSOperator::Mul:
+ case QSOperator::Sub:
+ case QSOperator::LShift:
+ case QSOperator::RShift:
+ case QSOperator::URShift: {
+ Reference right;
+ if (AST::NumericLiteral *rhs = AST::cast<AST::NumericLiteral *>(ast->right)) {
+ visit(rhs);
+ right = _expr.result();
+ } else {
+ left = left.storeOnStack(); // force any loads of the lhs, so the rhs won't clobber it
+ right = expression(ast->right);
}
-
- Result right = expression(ast->right);
if (hasError)
return false;
- if (_expr.accept(cx)) {
- setLocation(cjump(binop(IR::binaryOperator(ast->op), left, *right, ast->operatorToken), _expr.iftrue, _expr.iffalse), ast->operatorToken);
+ _expr.setResult(binopHelper(static_cast<QSOperator::Op>(ast->op), left, right));
+
+ break;
+ }
+
+ } // switch
+
+ return false;
+}
+
+Codegen::Reference Codegen::binopHelper(QSOperator::Op oper, Reference &left, Reference &right)
+{
+ switch (oper) {
+ case QSOperator::Add: {
+ //### Todo: when we add type hints, we can generate an Increment when both the lhs is a number and the rhs == 1
+ left = left.storeOnStack();
+ right.loadInAccumulator();
+ Instruction::Add add;
+ add.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(add);
+ break;
+ }
+ case QSOperator::Sub: {
+ if (right.isConst() && right.constant == Encode(int(1))) {
+ left.loadInAccumulator();
+ bytecodeGenerator->addInstruction(Instruction::Decrement());
} else {
- _expr.code = binop(IR::binaryOperator(ast->op), left, *right, ast->operatorToken);
+ left = left.storeOnStack();
+ right.loadInAccumulator();
+ Instruction::Sub sub;
+ sub.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(sub);
}
break;
}
-
- case QSOperator::Add:
+ case QSOperator::Mul: {
+ left = left.storeOnStack();
+ right.loadInAccumulator();
+ Instruction::Mul mul;
+ mul.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(mul);
+ break;
+ }
+ case QSOperator::Div: {
+ left = left.storeOnStack();
+ right.loadInAccumulator();
+ Instruction::Div div;
+ div.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(div);
+ break;
+ }
+ case QSOperator::Mod: {
+ left = left.storeOnStack();
+ right.loadInAccumulator();
+ Instruction::Mod mod;
+ mod.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(mod);
+ break;
+ }
case QSOperator::BitAnd:
+ if (right.isConst()) {
+ int rightAsInt = Primitive::fromReturnedValue(right.constant).toInt32();
+ if (left.isConst()) {
+ int result = Primitive::fromReturnedValue(left.constant).toInt32() & rightAsInt;
+ return Reference::fromConst(this, Encode(result));
+ }
+ left.loadInAccumulator();
+ Instruction::BitAndConst bitAnd;
+ bitAnd.rhs = rightAsInt;
+ bytecodeGenerator->addInstruction(bitAnd);
+ } else {
+ right.loadInAccumulator();
+ Instruction::BitAnd bitAnd;
+ bitAnd.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(bitAnd);
+ }
+ break;
case QSOperator::BitOr:
+ if (right.isConst()) {
+ int rightAsInt = Primitive::fromReturnedValue(right.constant).toInt32();
+ if (left.isConst()) {
+ int result = Primitive::fromReturnedValue(left.constant).toInt32() | rightAsInt;
+ return Reference::fromConst(this, Encode(result));
+ }
+ left.loadInAccumulator();
+ Instruction::BitOrConst bitOr;
+ bitOr.rhs = rightAsInt;
+ bytecodeGenerator->addInstruction(bitOr);
+ } else {
+ right.loadInAccumulator();
+ Instruction::BitOr bitOr;
+ bitOr.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(bitOr);
+ }
+ break;
case QSOperator::BitXor:
- case QSOperator::Div:
- case QSOperator::LShift:
- case QSOperator::Mod:
- case QSOperator::Mul:
+ if (right.isConst()) {
+ int rightAsInt = Primitive::fromReturnedValue(right.constant).toInt32();
+ if (left.isConst()) {
+ int result = Primitive::fromReturnedValue(left.constant).toInt32() ^ rightAsInt;
+ return Reference::fromConst(this, Encode(result));
+ }
+ left.loadInAccumulator();
+ Instruction::BitXorConst bitXor;
+ bitXor.rhs = rightAsInt;
+ bytecodeGenerator->addInstruction(bitXor);
+ } else {
+ right.loadInAccumulator();
+ Instruction::BitXor bitXor;
+ bitXor.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(bitXor);
+ }
+ break;
+ case QSOperator::URShift:
+ if (right.isConst()) {
+ left.loadInAccumulator();
+ Instruction::UShrConst ushr;
+ ushr.rhs = Primitive::fromReturnedValue(right.constant).toInt32() & 0x1f;
+ bytecodeGenerator->addInstruction(ushr);
+ } else {
+ right.loadInAccumulator();
+ Instruction::UShr ushr;
+ ushr.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(ushr);
+ }
+ break;
case QSOperator::RShift:
- case QSOperator::Sub:
- case QSOperator::URShift: {
- TempScope scope(_function);
- if (!left->asTemp() && !left->asArgLocal() && !left->asConst()) {
- const unsigned t = _block->newTemp();
- setLocation(move(_block->TEMP(t), left), ast->operatorToken);
- left = _block->TEMP(t);
+ if (right.isConst()) {
+ left.loadInAccumulator();
+ Instruction::ShrConst shr;
+ shr.rhs = Primitive::fromReturnedValue(right.constant).toInt32() & 0x1f;
+ bytecodeGenerator->addInstruction(shr);
+ } else {
+ right.loadInAccumulator();
+ Instruction::Shr shr;
+ shr.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(shr);
+ }
+ break;
+ case QSOperator::LShift:
+ if (right.isConst()) {
+ left.loadInAccumulator();
+ Instruction::ShlConst shl;
+ shl.rhs = Primitive::fromReturnedValue(right.constant).toInt32() & 0x1f;
+ bytecodeGenerator->addInstruction(shl);
+ } else {
+ right.loadInAccumulator();
+ Instruction::Shl shl;
+ shl.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(shl);
}
+ break;
+ case QSOperator::InstanceOf: {
+ Instruction::CmpInstanceOf binop;
+ left = left.storeOnStack();
+ right.loadInAccumulator();
+ binop.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(binop);
+ break;
+ }
+ case QSOperator::In: {
+ Instruction::CmpIn binop;
+ left = left.storeOnStack();
+ right.loadInAccumulator();
+ binop.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(binop);
+ break;
+ }
+ case QSOperator::StrictEqual: {
+ if (_expr.accept(cx))
+ return jumpBinop(oper, left, right);
- Result right = expression(ast->right);
- if (hasError)
- return false;
+ Instruction::CmpStrictEqual cmp;
+ left = left.storeOnStack();
+ right.loadInAccumulator();
+ cmp.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(cmp);
+ break;
+ }
+ case QSOperator::StrictNotEqual: {
+ if (_expr.accept(cx))
+ return jumpBinop(oper, left, right);
+
+ Instruction::CmpStrictNotEqual cmp;
+ left = left.storeOnStack();
+ right.loadInAccumulator();
+ cmp.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(cmp);
+ break;
+ }
+ case QSOperator::Equal: {
+ if (_expr.accept(cx))
+ return jumpBinop(oper, left, right);
- _expr.code = binop(IR::binaryOperator(ast->op), left, *right, ast->operatorToken);
+ Instruction::CmpEq cmp;
+ left = left.storeOnStack();
+ right.loadInAccumulator();
+ cmp.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(cmp);
break;
}
+ case QSOperator::NotEqual: {
+ if (_expr.accept(cx))
+ return jumpBinop(oper, left, right);
- } // switch
+ Instruction::CmpNe cmp;
+ left = left.storeOnStack();
+ right.loadInAccumulator();
+ cmp.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(cmp);
+ break;
+ }
+ case QSOperator::Gt: {
+ if (_expr.accept(cx))
+ return jumpBinop(oper, left, right);
- return false;
+ Instruction::CmpGt cmp;
+ left = left.storeOnStack();
+ right.loadInAccumulator();
+ cmp.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(cmp);
+ break;
+ }
+ case QSOperator::Ge: {
+ if (_expr.accept(cx))
+ return jumpBinop(oper, left, right);
+
+ Instruction::CmpGe cmp;
+ left = left.storeOnStack();
+ right.loadInAccumulator();
+ cmp.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(cmp);
+ break;
+ }
+ case QSOperator::Lt: {
+ if (_expr.accept(cx))
+ return jumpBinop(oper, left, right);
+
+ Instruction::CmpLt cmp;
+ left = left.storeOnStack();
+ right.loadInAccumulator();
+ cmp.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(cmp);
+ break;
+ }
+ case QSOperator::Le:
+ if (_expr.accept(cx))
+ return jumpBinop(oper, left, right);
+
+ Instruction::CmpLe cmp;
+ left = left.storeOnStack();
+ right.loadInAccumulator();
+ cmp.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(cmp);
+ break;
+ default:
+ Q_UNREACHABLE();
+ }
+
+ return Reference::fromAccumulator(this);
+}
+
+static QSOperator::Op operatorForSwappedOperands(QSOperator::Op oper)
+{
+ switch (oper) {
+ case QSOperator::StrictEqual: return QSOperator::StrictEqual;
+ case QSOperator::StrictNotEqual: return QSOperator::StrictNotEqual;
+ case QSOperator::Equal: return QSOperator::Equal;
+ case QSOperator::NotEqual: return QSOperator::NotEqual;
+ case QSOperator::Gt: return QSOperator::Le;
+ case QSOperator::Ge: return QSOperator::Lt;
+ case QSOperator::Lt: return QSOperator::Ge;
+ case QSOperator::Le: return QSOperator::Gt;
+ default: Q_UNIMPLEMENTED(); return QSOperator::Invalid;
+ }
+}
+
+Codegen::Reference Codegen::jumpBinop(QSOperator::Op oper, Reference &left, Reference &right)
+{
+ if (left.isConst()) {
+ oper = operatorForSwappedOperands(oper);
+ qSwap(left, right);
+ }
+
+ if (right.isConst() && (oper == QSOperator::Equal || oper == QSOperator::NotEqual)) {
+ Value c = Primitive::fromReturnedValue(right.constant);
+ if (c.isNull() || c.isUndefined()) {
+ left.loadInAccumulator();
+ if (oper == QSOperator::Equal) {
+ Instruction::CmpEqNull cmp;
+ bytecodeGenerator->addInstruction(cmp);
+ addCJump();
+ return Reference();
+ } else if (oper == QSOperator::NotEqual) {
+ Instruction::CmpNeNull cmp;
+ bytecodeGenerator->addInstruction(cmp);
+ addCJump();
+ return Reference();
+ }
+ } else if (c.isInt32()) {
+ left.loadInAccumulator();
+ if (oper == QSOperator::Equal) {
+ Instruction::CmpEqInt cmp;
+ cmp.lhs = c.int_32();
+ bytecodeGenerator->addInstruction(cmp);
+ addCJump();
+ return Reference();
+ } else if (oper == QSOperator::NotEqual) {
+ Instruction::CmpNeInt cmp;
+ cmp.lhs = c.int_32();
+ bytecodeGenerator->addInstruction(cmp);
+ addCJump();
+ return Reference();
+ }
+
+ }
+ }
+
+ left = left.storeOnStack();
+ right.loadInAccumulator();
+
+ switch (oper) {
+ case QSOperator::StrictEqual: {
+ Instruction::CmpStrictEqual cmp;
+ cmp.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(cmp);
+ addCJump();
+ break;
+ }
+ case QSOperator::StrictNotEqual: {
+ Instruction::CmpStrictNotEqual cmp;
+ cmp.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(cmp);
+ addCJump();
+ break;
+ }
+ case QSOperator::Equal: {
+ Instruction::CmpEq cmp;
+ cmp.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(cmp);
+ addCJump();
+ break;
+ }
+ case QSOperator::NotEqual: {
+ Instruction::CmpNe cmp;
+ cmp.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(cmp);
+ addCJump();
+ break;
+ }
+ case QSOperator::Gt: {
+ Instruction::CmpGt cmp;
+ cmp.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(cmp);
+ addCJump();
+ break;
+ }
+ case QSOperator::Ge: {
+ Instruction::CmpGe cmp;
+ cmp.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(cmp);
+ addCJump();
+ break;
+ }
+ case QSOperator::Lt: {
+ Instruction::CmpLt cmp;
+ cmp.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(cmp);
+ addCJump();
+ break;
+ }
+ case QSOperator::Le: {
+ Instruction::CmpLe cmp;
+ cmp.lhs = left.stackSlot();
+ bytecodeGenerator->addInstruction(cmp);
+ addCJump();
+ break;
+ }
+ default:
+ Q_UNREACHABLE();
+ }
+ return Reference();
}
bool Codegen::visit(CallExpression *ast)
@@ -1385,54 +1255,138 @@ bool Codegen::visit(CallExpression *ast)
if (hasError)
return false;
- Result base = expression(ast->base);
- IR::ExprList *args = 0, **args_it = &args;
- for (ArgumentList *it = ast->arguments; it; it = it->next) {
- Result arg = expression(it->expression);
- if (hasError)
- return false;
- IR::Expr *actual = argument(*arg);
- *args_it = _function->New<IR::ExprList>();
- (*args_it)->init(actual);
- args_it = &(*args_it)->next;
+ RegisterScope scope(this);
+
+ Reference base = expression(ast->base);
+ if (hasError)
+ return false;
+ switch (base.type) {
+ case Reference::Member:
+ case Reference::Subscript:
+ base = base.asLValue();
+ break;
+ case Reference::Name:
+ break;
+ default:
+ base = base.storeOnStack();
+ break;
}
+
+ auto calldata = pushArgs(ast->arguments);
if (hasError)
return false;
- _expr.code = call(*base, args);
+
+ //### Do we really need all these call instructions? can's we load the callee in a temp?
+ if (base.type == Reference::Member) {
+ if (useFastLookups) {
+ Instruction::CallPropertyLookup call;
+ call.base = base.propertyBase.stackSlot();
+ call.lookupIndex = registerGetterLookup(base.propertyNameIndex);
+ call.argc = calldata.argc;
+ call.argv = calldata.argv;
+ bytecodeGenerator->addInstruction(call);
+ } else {
+ Instruction::CallProperty call;
+ call.base = base.propertyBase.stackSlot();
+ call.name = base.propertyNameIndex;
+ call.argc = calldata.argc;
+ call.argv = calldata.argv;
+ bytecodeGenerator->addInstruction(call);
+ }
+ } else if (base.type == Reference::Subscript) {
+ Instruction::CallElement call;
+ call.base = base.elementBase;
+ call.index = base.elementSubscript.stackSlot();
+ call.argc = calldata.argc;
+ call.argv = calldata.argv;
+ bytecodeGenerator->addInstruction(call);
+ } else if (base.type == Reference::Name) {
+ if (base.name == QStringLiteral("eval")) {
+ Instruction::CallPossiblyDirectEval call;
+ call.argc = calldata.argc;
+ call.argv = calldata.argv;
+ bytecodeGenerator->addInstruction(call);
+ } else if (useFastLookups && base.global) {
+ Instruction::CallGlobalLookup call;
+ call.index = registerGlobalGetterLookup(base.nameAsIndex());
+ call.argc = calldata.argc;
+ call.argv = calldata.argv;
+ bytecodeGenerator->addInstruction(call);
+ } else {
+ Instruction::CallName call;
+ call.name = base.nameAsIndex();
+ call.argc = calldata.argc;
+ call.argv = calldata.argv;
+ bytecodeGenerator->addInstruction(call);
+ }
+ } else {
+ Q_ASSERT(base.isStackSlot());
+ Instruction::CallValue call;
+ call.name = base.stackSlot();
+ call.argc = calldata.argc;
+ call.argv = calldata.argv;
+ bytecodeGenerator->addInstruction(call);
+ }
+
+ _expr.setResult(Reference::fromAccumulator(this));
return false;
}
+Codegen::Arguments Codegen::pushArgs(ArgumentList *args)
+{
+ int argc = 0;
+ for (ArgumentList *it = args; it; it = it->next)
+ ++argc;
+
+ if (!argc)
+ return { 0, 0 };
+
+ int calldata = bytecodeGenerator->newRegisterArray(argc);
+
+ argc = 0;
+ for (ArgumentList *it = args; it; it = it->next) {
+ RegisterScope scope(this);
+ Reference e = expression(it->expression);
+ if (hasError)
+ break;
+ if (!argc && !it->next) {
+ // avoid copy for functions taking a single argument
+ if (e.isStackSlot())
+ return { 1, e.stackSlot() };
+ }
+ (void) e.storeOnStack(calldata + argc);
+ ++argc;
+ }
+
+ return { argc, calldata };
+}
+
bool Codegen::visit(ConditionalExpression *ast)
{
if (hasError)
return true;
- IR::BasicBlock *iftrue = _function->newBasicBlock(exceptionHandler());
- IR::BasicBlock *iffalse = _function->newBasicBlock(exceptionHandler());
- IR::BasicBlock *endif = _function->newBasicBlock(exceptionHandler());
+ RegisterScope scope(this);
- const unsigned t = _block->newTemp();
- TempScope scope(_function);
+ BytecodeGenerator::Label iftrue = bytecodeGenerator->newLabel();
+ BytecodeGenerator::Label iffalse = bytecodeGenerator->newLabel();
+ condition(ast->expression, &iftrue, &iffalse, true);
- condition(ast->expression, iftrue, iffalse);
-
- _block = iftrue;
- Result ok = expression(ast->ok);
+ iftrue.link();
+ Reference ok = expression(ast->ok);
if (hasError)
return false;
- move(_block->TEMP(t), *ok);
- _block->JUMP(endif);
+ ok.loadInAccumulator();
+ BytecodeGenerator::Jump jump_endif = bytecodeGenerator->jump();
- _block = iffalse;
- Result ko = expression(ast->ko);
+ iffalse.link();
+ Reference ko = expression(ast->ko);
if (hasError)
return false;
- move(_block->TEMP(t), *ko);
- _block->JUMP(endif);
-
- _block = endif;
+ ko.loadInAccumulator();
- _expr.code = _block->TEMP(t);
+ jump_endif.link();
+ _expr.setResult(Reference::fromAccumulator(this));
return false;
}
@@ -1442,48 +1396,59 @@ bool Codegen::visit(DeleteExpression *ast)
if (hasError)
return false;
- IR::Expr* expr = *expression(ast->expression);
+ Reference expr = expression(ast->expression);
if (hasError)
return false;
- // Temporaries cannot be deleted
- IR::ArgLocal *al = expr->asArgLocal();
- if (al && al->index < static_cast<unsigned>(_env->members.size())) {
+
+ switch (expr.type) {
+ case Reference::StackSlot:
+ if (!expr.stackSlotIsLocalOrArgument)
+ break;
+ // fall through
+ case Reference::ScopedLocal:
// Trying to delete a function argument might throw.
- if (_function->isStrict) {
+ if (_context->isStrict) {
throwSyntaxError(ast->deleteToken, QStringLiteral("Delete of an unqualified identifier in strict mode."));
return false;
}
- _expr.code = _block->CONST(IR::BoolType, 0);
+ _expr.setResult(Reference::fromConst(this, QV4::Encode(false)));
return false;
- }
- if (_function->isStrict && expr->asName()) {
- throwSyntaxError(ast->deleteToken, QStringLiteral("Delete of an unqualified identifier in strict mode."));
+ case Reference::Name: {
+ if (_context->isStrict) {
+ throwSyntaxError(ast->deleteToken, QStringLiteral("Delete of an unqualified identifier in strict mode."));
+ return false;
+ }
+ Instruction::DeleteName del;
+ del.name = expr.nameAsIndex();
+ bytecodeGenerator->addInstruction(del);
+ _expr.setResult(Reference::fromAccumulator(this));
return false;
}
-
- // [[11.4.1]] Return true if it's not a reference
- if (expr->asConst() || expr->asString()) {
- _expr.code = _block->CONST(IR::BoolType, 1);
+ case Reference::Member: {
+ //### maybe add a variant where the base can be in the accumulator?
+ expr = expr.asLValue();
+ Instruction::DeleteMember del;
+ del.base = expr.propertyBase.stackSlot();
+ del.member = expr.propertyNameIndex;
+ bytecodeGenerator->addInstruction(del);
+ _expr.setResult(Reference::fromAccumulator(this));
return false;
}
-
- // Return values from calls are also not a reference, but we have to
- // perform the call to allow for side effects.
- if (expr->asCall()) {
- _block->EXP(expr);
- _expr.code = _block->CONST(IR::BoolType, 1);
+ case Reference::Subscript: {
+ //### maybe add a variant where the index can be in the accumulator?
+ expr = expr.asLValue();
+ Instruction::DeleteSubscript del;
+ del.base = expr.elementBase;
+ del.index = expr.elementSubscript.stackSlot();
+ bytecodeGenerator->addInstruction(del);
+ _expr.setResult(Reference::fromAccumulator(this));
return false;
}
- if (expr->asTemp() ||
- (expr->asArgLocal() &&
- expr->asArgLocal()->index >= static_cast<unsigned>(_env->members.size()))) {
- _expr.code = _block->CONST(IR::BoolType, 1);
- return false;
+ default:
+ break;
}
-
- IR::ExprList *args = _function->New<IR::ExprList>();
- args->init(reference(expr));
- _expr.code = call(_block->NAME(IR::Name::builtin_delete, ast->deleteToken.startLine, ast->deleteToken.startColumn), args);
+ // [[11.4.1]] Return true if it's not a reference
+ _expr.setResult(Reference::fromConst(this, QV4::Encode(true)));
return false;
}
@@ -1492,11 +1457,7 @@ bool Codegen::visit(FalseLiteral *)
if (hasError)
return false;
- if (_expr.accept(cx)) {
- _block->JUMP(_expr.iffalse);
- } else {
- _expr.code = _block->CONST(IR::BoolType, 0);
- }
+ _expr.setResult(Reference::fromConst(this, QV4::Encode(false)));
return false;
}
@@ -1505,9 +1466,10 @@ bool Codegen::visit(FieldMemberExpression *ast)
if (hasError)
return false;
- Result base = expression(ast->base);
- if (!hasError)
- _expr.code = member(*base, _function->newString(ast->name.toString()));
+ Reference base = expression(ast->base);
+ if (hasError)
+ return false;
+ _expr.setResult(Reference::fromMember(base, ast->name.toString()));
return false;
}
@@ -1516,64 +1478,109 @@ bool Codegen::visit(FunctionExpression *ast)
if (hasError)
return false;
- TempScope scope(_function);
+ RegisterScope scope(this);
int function = defineFunction(ast->name.toString(), ast, ast->formals, ast->body ? ast->body->elements : 0);
- _expr.code = _block->CLOSURE(function);
+ loadClosure(function);
+ _expr.setResult(Reference::fromAccumulator(this));
return false;
}
-IR::Expr *Codegen::identifier(const QString &name, int line, int col)
+Codegen::Reference Codegen::referenceForName(const QString &name, bool isLhs)
{
- if (hasError)
- return 0;
-
- uint scope = 0;
- Environment *e = _env;
- IR::Function *f = _function;
+ int scope = 0;
+ Context *c = _context;
- while (f && e->parent) {
- if (f->insideWithOrCatch || (f->isNamedExpression && QStringRef(f->name) == name))
- return _block->NAME(name, line, col);
-
- int index = e->findMember(name);
- Q_ASSERT (index < e->members.size());
- if (index != -1) {
- IR::ArgLocal *al = _block->LOCAL(index, scope);
- if (name == QLatin1String("arguments") || name == QLatin1String("eval"))
- al->isArgumentsOrEval = true;
- return al;
+ // skip the innermost context if it's simple (as the runtime won't
+ // create a context for it
+ if (c->canUseSimpleCall()) {
+ Context::Member m = c->findMember(name);
+ if (m.type != Context::UndefinedMember) {
+ Q_ASSERT((!m.canEscape));
+ Reference r = Reference::fromStackSlot(this, m.index, true /*isLocal*/);
+ if (name == QLatin1String("arguments") || name == QLatin1String("eval")) {
+ r.isArgOrEval = true;
+ if (isLhs && c->isStrict)
+ // ### add correct source location
+ throwSyntaxError(SourceLocation(), QStringLiteral("Variable name may not be eval or arguments in strict mode"));
+ }
+ return r;
+ }
+ const int argIdx = c->findArgument(name);
+ if (argIdx != -1) {
+ Q_ASSERT(!c->argumentsCanEscape && (c->usesArgumentsObject != Context::ArgumentsObjectUsed || c->isStrict));
+ return Reference::fromArgument(this, argIdx, _volataleMemoryLocations.isVolatile(name));
+ }
+ c = c->parent;
+ }
+
+ while (c->parent) {
+ if (c->forceLookupByName())
+ goto loadByName;
+
+ Context::Member m = c->findMember(name);
+ if (m.type != Context::UndefinedMember) {
+ Reference r = m.canEscape ? Reference::fromScopedLocal(this, m.index, scope)
+ : Reference::fromStackSlot(this, m.index, true /*isLocal*/);
+ if (name == QLatin1String("arguments") || name == QLatin1String("eval")) {
+ r.isArgOrEval = true;
+ if (isLhs && c->isStrict)
+ // ### add correct source location
+ throwSyntaxError(SourceLocation(), QStringLiteral("Variable name may not be eval or arguments in strict mode"));
+ }
+ return r;
+ }
+ const int argIdx = c->findArgument(name);
+ if (argIdx != -1) {
+ if (c->argumentsCanEscape || c->usesArgumentsObject == Context::ArgumentsObjectUsed) {
+ int idx = argIdx + c->locals.size();
+ return Reference::fromScopedLocal(this, idx, scope);
+ } else {
+ Q_ASSERT(scope == 0);
+ return Reference::fromArgument(this, argIdx, _volataleMemoryLocations.isVolatile(name));
+ }
}
- const int argIdx = f->indexOfArgument(QStringRef(&name));
- if (argIdx != -1)
- return _block->ARG(argIdx, scope);
- if (!f->isStrict && f->hasDirectEval)
- return _block->NAME(name, line, col);
+ if (!c->isStrict && c->hasDirectEval)
+ goto loadByName;
++scope;
- e = e->parent;
- f = f->outer;
+ c = c->parent;
}
- // This hook allows implementing QML lookup semantics
- if (IR::Expr *fallback = fallbackNameLookup(name, line, col))
- return fallback;
+ {
+ // This hook allows implementing QML lookup semantics
+ Reference fallback = fallbackNameLookup(name);
+ if (fallback.type != Reference::Invalid)
+ return fallback;
+ }
- if (!e->parent && (!f || !f->insideWithOrCatch) && _env->compilationMode != EvalCode && e->compilationMode != QmlBinding)
- return _block->GLOBALNAME(name, line, col);
+ if (!c->parent && !c->forceLookupByName() && _context->compilationMode != EvalCode && c->compilationMode != QmlBinding) {
+ Reference r = Reference::fromName(this, name);
+ r.global = true;
+ return r;
+ }
// global context or with. Lookup by name
- return _block->NAME(name, line, col);
+ loadByName:
+ return Reference::fromName(this, name);
+}
+void Codegen::loadClosure(int closureId)
+{
+ if (closureId >= 0) {
+ Instruction::LoadClosure load;
+ load.value = closureId;
+ bytecodeGenerator->addInstruction(load);
+ } else {
+ Reference::fromConst(this, Encode::undefined()).loadInAccumulator();
+ }
}
-IR::Expr *Codegen::fallbackNameLookup(const QString &name, int line, int col)
+Codegen::Reference Codegen::fallbackNameLookup(const QString &name)
{
Q_UNUSED(name)
- Q_UNUSED(line)
- Q_UNUSED(col)
- return 0;
+ return Reference();
}
bool Codegen::visit(IdentifierExpression *ast)
@@ -1581,7 +1588,7 @@ bool Codegen::visit(IdentifierExpression *ast)
if (hasError)
return false;
- _expr.code = identifier(ast->name.toString(), ast->identifierToken.startLine, ast->identifierToken.startColumn);
+ _expr.setResult(referenceForName(ast->name.toString(), false));
return false;
}
@@ -1598,18 +1605,21 @@ bool Codegen::visit(NewExpression *ast)
{
if (hasError)
return false;
- TempScope scope(_function);
- Result base = expression(ast->expression);
+ RegisterScope scope(this);
+
+ Reference base = expression(ast->expression);
if (hasError)
return false;
- IR::Expr *expr = *base;
- if (expr && !expr->asTemp() && !expr->asArgLocal() && !expr->asName() && !expr->asMember()) {
- const unsigned t = _block->newTemp();
- move(_block->TEMP(t), expr);
- expr = _block->TEMP(t);
- }
- _expr.code = _block->NEW(expr, 0);
+ //### Maybe create a ConstructA that takes an accumulator?
+ base = base.storeOnStack();
+
+ Instruction::Construct create;
+ create.func = base.stackSlot();
+ create.argc = 0;
+ create.argv = 0;
+ bytecodeGenerator->addInstruction(create);
+ _expr.setResult(Reference::fromAccumulator(this));
return false;
}
@@ -1618,32 +1628,23 @@ bool Codegen::visit(NewMemberExpression *ast)
if (hasError)
return false;
- const unsigned t = _block->newTemp();
+ RegisterScope scope(this);
- TempScope scope(_function);
+ Reference base = expression(ast->base);
+ if (hasError)
+ return false;
+ base = base.storeOnStack();
- Result base = expression(ast->base);
+ auto calldata = pushArgs(ast->arguments);
if (hasError)
return false;
- IR::Expr *expr = *base;
- if (expr && !expr->asTemp() && !expr->asArgLocal() && !expr->asName() && !expr->asMember()) {
- const unsigned t = _block->newTemp();
- move(_block->TEMP(t), expr);
- expr = _block->TEMP(t);
- }
- IR::ExprList *args = 0, **args_it = &args;
- for (ArgumentList *it = ast->arguments; it; it = it->next) {
- Result arg = expression(it->expression);
- if (hasError)
- return false;
- IR::Expr *actual = argument(*arg);
- *args_it = _function->New<IR::ExprList>();
- (*args_it)->init(actual);
- args_it = &(*args_it)->next;
- }
- move(_block->TEMP(t), _block->NEW(expr, args));
- _expr.code = _block->TEMP(t);
+ Instruction::Construct create;
+ create.func = base.stackSlot();
+ create.argc = calldata.argc;
+ create.argv = calldata.argv;
+ bytecodeGenerator->addInstruction(create);
+ _expr.setResult(Reference::fromAccumulator(this));
return false;
}
@@ -1652,14 +1653,7 @@ bool Codegen::visit(NotExpression *ast)
if (hasError)
return false;
- const unsigned r = _block->newTemp();
- TempScope scope(_function);
-
- Result expr = expression(ast->expression);
- if (hasError)
- return false;
- setLocation(move(_block->TEMP(r), unop(IR::OpNot, *expr, ast->notToken)), ast->notToken);
- _expr.code = _block->TEMP(r);
+ _expr.setResult(unop(Not, expression(ast->expression)));
return false;
}
@@ -1668,8 +1662,10 @@ bool Codegen::visit(NullExpression *)
if (hasError)
return false;
- if (_expr.accept(cx)) _block->JUMP(_expr.iffalse);
- else _expr.code = _block->CONST(IR::NullType, 0);
+ if (_expr.accept(cx))
+ bytecodeGenerator->jump().link(*_expr.iffalse());
+ else
+ _expr.setResult(Reference::fromConst(this, Encode::null()));
return false;
}
@@ -1679,30 +1675,10 @@ bool Codegen::visit(NumericLiteral *ast)
if (hasError)
return false;
- if (_expr.accept(cx)) {
- if (ast->value) _block->JUMP(_expr.iftrue);
- else _block->JUMP(_expr.iffalse);
- } else {
- _expr.code = _block->CONST(IR::NumberType, ast->value);
- }
+ _expr.setResult(Reference::fromConst(this, QV4::Encode::smallestNumber(ast->value)));
return false;
}
-struct ObjectPropertyValue {
- ObjectPropertyValue()
- : value(0)
- , getter(-1)
- , setter(-1)
- {}
-
- IR::Expr *value;
- int getter; // index in _module->functions or -1 if not set
- int setter;
-
- bool hasGetter() const { return getter >= 0; }
- bool hasSetter() const { return setter >= 0; }
-};
-
bool Codegen::visit(ObjectLiteral *ast)
{
if (hasError)
@@ -1710,33 +1686,27 @@ bool Codegen::visit(ObjectLiteral *ast)
QMap<QString, ObjectPropertyValue> valueMap;
- const unsigned t = _block->newTemp();
- TempScope scope(_function);
+ RegisterScope scope(this);
for (PropertyAssignmentList *it = ast->properties; it; it = it->next) {
QString name = it->assignment->name->asString();
if (PropertyNameAndValue *nv = AST::cast<AST::PropertyNameAndValue *>(it->assignment)) {
- Result value = expression(nv->value);
+ Reference value = expression(nv->value);
if (hasError)
return false;
+
ObjectPropertyValue &v = valueMap[name];
- if (v.hasGetter() || v.hasSetter() || (_function->isStrict && v.value)) {
+ if (v.hasGetter() || v.hasSetter() || (_context->isStrict && v.rvalue.isValid())) {
throwSyntaxError(nv->lastSourceLocation(),
QStringLiteral("Illegal duplicate key '%1' in object literal").arg(name));
return false;
}
- if (IR::Const *c = (*value)->asConst()) {
- valueMap[name].value = c;
- } else {
- unsigned t = _block->newTemp();
- move(_block->TEMP(t), *value);
- valueMap[name].value = _block->TEMP(t);
- }
+ v.rvalue = value.storeOnStack();
} else if (PropertyGetterSetter *gs = AST::cast<AST::PropertyGetterSetter *>(it->assignment)) {
const int function = defineFunction(name, gs, gs->formals, gs->functionBody ? gs->functionBody->elements : 0);
ObjectPropertyValue &v = valueMap[name];
- if (v.value ||
+ if (v.rvalue.isValid() ||
(gs->type == PropertyGetterSetter::Getter && v.hasGetter()) ||
(gs->type == PropertyGetterSetter::Setter && v.hasSetter())) {
throwSyntaxError(gs->lastSourceLocation(),
@@ -1752,96 +1722,90 @@ bool Codegen::visit(ObjectLiteral *ast)
}
}
- // The linked-list arguments to builtin_define_object_literal
- // begin with a CONST counting the number of key/value pairs, followed by the
- // key value pairs, followed by the array entries.
- IR::ExprList *args = _function->New<IR::ExprList>();
-
- IR::Const *entryCountParam = _function->New<IR::Const>();
- entryCountParam->init(IR::SInt32Type, 0);
- args->expr = entryCountParam;
- args->next = 0;
-
- IR::ExprList *keyValueEntries = 0;
- IR::ExprList *currentKeyValueEntry = 0;
- int keyValueEntryCount = 0;
- IR::ExprList *arrayEntries = 0;
+ QVector<QString> nonArrayKey, arrayKeyWithValue, arrayKeyWithGetterSetter;
+ bool needSparseArray = false; // set to true if any array index is bigger than 16
- IR::ExprList *currentArrayEntry = 0;
-
- for (QMap<QString, ObjectPropertyValue>::iterator it = valueMap.begin(); it != valueMap.end(); ) {
- IR::ExprList **currentPtr = 0;
- uint keyAsIndex = QV4::String::toArrayIndex(it.key());
- if (keyAsIndex != UINT_MAX) {
- if (!arrayEntries) {
- arrayEntries = _function->New<IR::ExprList>();
- currentArrayEntry = arrayEntries;
- } else {
- currentArrayEntry->next = _function->New<IR::ExprList>();
- currentArrayEntry = currentArrayEntry->next;
- }
- currentPtr = &currentArrayEntry;
- IR::Const *idx = _function->New<IR::Const>();
- idx->init(IR::UInt32Type, keyAsIndex);
- (*currentPtr)->expr = idx;
+ for (QMap<QString, ObjectPropertyValue>::iterator it = valueMap.begin(), eit = valueMap.end();
+ it != eit; ++it) {
+ QString name = it.key();
+ uint keyAsIndex = QV4::String::toArrayIndex(name);
+ if (keyAsIndex != std::numeric_limits<uint>::max()) {
+ it->keyAsIndex = keyAsIndex;
+ if (keyAsIndex > 16)
+ needSparseArray = true;
+ if (it->hasSetter() || it->hasGetter())
+ arrayKeyWithGetterSetter.append(name);
+ else
+ arrayKeyWithValue.append(name);
} else {
- if (!keyValueEntries) {
- keyValueEntries = _function->New<IR::ExprList>();
- currentKeyValueEntry = keyValueEntries;
- } else {
- currentKeyValueEntry->next = _function->New<IR::ExprList>();
- currentKeyValueEntry = currentKeyValueEntry->next;
- }
- currentPtr = &currentKeyValueEntry;
- (*currentPtr)->expr = _block->NAME(it.key(), 0, 0);
- keyValueEntryCount++;
+ nonArrayKey.append(name);
}
+ }
- IR::ExprList *&current = *currentPtr;
- if (it->value) {
- current->next = _function->New<IR::ExprList>();
- current = current->next;
- current->expr = _block->CONST(IR::BoolType, true);
-
- current->next = _function->New<IR::ExprList>();
- current = current->next;
- current->expr = it->value;
+ int args = -1;
+ auto push = [this, &args](const Reference &arg) {
+ int temp = bytecodeGenerator->newRegister();
+ if (args == -1)
+ args = temp;
+ (void) arg.storeOnStack(temp);
+ };
+
+ QVector<QV4::Compiler::JSUnitGenerator::MemberInfo> members;
+
+ Reference acc = Reference::fromAccumulator(this);
+ // generate the key/value pairs
+ for (const QString &key : qAsConst(nonArrayKey)) {
+ const ObjectPropertyValue &prop = valueMap[key];
+
+ if (prop.hasGetter() || prop.hasSetter()) {
+ Q_ASSERT(!prop.rvalue.isValid());
+ loadClosure(prop.getter);
+ push(acc);
+ loadClosure(prop.setter);
+ push(acc);
+ members.append({ key, true });
} else {
- current->next = _function->New<IR::ExprList>();
- current = current->next;
- current->expr = _block->CONST(IR::BoolType, false);
-
- unsigned getter = _block->newTemp();
- unsigned setter = _block->newTemp();
- move(_block->TEMP(getter), it->hasGetter() ? _block->CLOSURE(it->getter) : _block->CONST(IR::UndefinedType, 0));
- move(_block->TEMP(setter), it->hasSetter() ? _block->CLOSURE(it->setter) : _block->CONST(IR::UndefinedType, 0));
-
- current->next = _function->New<IR::ExprList>();
- current = current->next;
- current->expr = _block->TEMP(getter);
- current->next = _function->New<IR::ExprList>();
- current = current->next;
- current->expr = _block->TEMP(setter);
+ Q_ASSERT(prop.rvalue.isValid());
+ push(prop.rvalue);
+ members.append({ key, false });
}
-
- it = valueMap.erase(it);
}
- entryCountParam->value = keyValueEntryCount;
+ // generate array entries with values
+ for (const QString &key : qAsConst(arrayKeyWithValue)) {
+ const ObjectPropertyValue &prop = valueMap[key];
+ Q_ASSERT(!prop.hasGetter() && !prop.hasSetter());
+ push(Reference::fromConst(this, Encode(prop.keyAsIndex)));
+ push(prop.rvalue);
+ }
- if (keyValueEntries)
- args->next = keyValueEntries;
- if (arrayEntries) {
- if (currentKeyValueEntry)
- currentKeyValueEntry->next = arrayEntries;
- else
- args->next = arrayEntries;
+ // generate array entries with both a value and a setter
+ for (const QString &key : qAsConst(arrayKeyWithGetterSetter)) {
+ const ObjectPropertyValue &prop = valueMap[key];
+ Q_ASSERT(!prop.rvalue.isValid());
+ push(Reference::fromConst(this, Encode(prop.keyAsIndex)));
+ loadClosure(prop.getter);
+ push(acc);
+ loadClosure(prop.setter);
+ push(acc);
}
- move(_block->TEMP(t), _block->CALL(_block->NAME(IR::Name::builtin_define_object_literal,
- ast->firstSourceLocation().startLine, ast->firstSourceLocation().startColumn), args));
+ int classId = jsUnitGenerator->registerJSClass(members);
+
+ uint arrayGetterSetterCountAndFlags = arrayKeyWithGetterSetter.size();
+ arrayGetterSetterCountAndFlags |= needSparseArray << 30;
- _expr.code = _block->TEMP(t);
+ if (args == -1)
+ args = 0;
+
+ Instruction::DefineObjectLiteral call;
+ call.internalClassId = classId;
+ call.arrayValueCount = arrayKeyWithValue.size();
+ call.arrayGetterSetterCountAndFlags = arrayGetterSetterCountAndFlags;
+ call.args = Moth::StackSlot::createRegister(args);
+ bytecodeGenerator->addInstruction(call);
+
+ _expr.setResult(Reference::fromAccumulator(this));
return false;
}
@@ -1850,26 +1814,17 @@ bool Codegen::visit(PostDecrementExpression *ast)
if (hasError)
return false;
- Result expr = expression(ast->base);
+ Reference expr = expression(ast->base);
if (hasError)
return false;
- if (!expr->isLValue()) {
+ if (!expr.isLValue()) {
throwReferenceError(ast->base->lastSourceLocation(), QStringLiteral("Invalid left-hand side expression in postfix operation"));
return false;
}
- if (throwSyntaxErrorOnEvalOrArgumentsInStrictMode(*expr, ast->decrementToken))
+ if (throwSyntaxErrorOnEvalOrArgumentsInStrictMode(expr, ast->decrementToken))
return false;
- const unsigned oldValue = _block->newTemp();
- setLocation(move(_block->TEMP(oldValue), unop(IR::OpUPlus, *expr, ast->decrementToken)), ast->decrementToken);
-
- TempScope scope(_function);
- const unsigned newValue = _block->newTemp();
- setLocation(move(_block->TEMP(newValue), binop(IR::OpSub, _block->TEMP(oldValue), _block->CONST(IR::NumberType, 1), ast->decrementToken)), ast->decrementToken);
- setLocation(move(*expr, _block->TEMP(newValue)), ast->decrementToken);
-
- if (!_expr.accept(nx))
- _expr.code = _block->TEMP(oldValue);
+ _expr.setResult(unop(PostDecrement, expr));
return false;
}
@@ -1879,54 +1834,35 @@ bool Codegen::visit(PostIncrementExpression *ast)
if (hasError)
return false;
- Result expr = expression(ast->base);
+ Reference expr = expression(ast->base);
if (hasError)
return false;
- if (!expr->isLValue()) {
+ if (!expr.isLValue()) {
throwReferenceError(ast->base->lastSourceLocation(), QStringLiteral("Invalid left-hand side expression in postfix operation"));
return false;
}
- if (throwSyntaxErrorOnEvalOrArgumentsInStrictMode(*expr, ast->incrementToken))
+ if (throwSyntaxErrorOnEvalOrArgumentsInStrictMode(expr, ast->incrementToken))
return false;
- const unsigned oldValue = _block->newTemp();
- setLocation(move(_block->TEMP(oldValue), unop(IR::OpUPlus, *expr, ast->incrementToken)), ast->incrementToken);
-
- TempScope scope(_function);
- const unsigned newValue = _block->newTemp();
- setLocation(move(_block->TEMP(newValue), binop(IR::OpAdd, _block->TEMP(oldValue), _block->CONST(IR::NumberType, 1), ast->incrementToken)), ast->incrementToken);
- setLocation(move(*expr, _block->TEMP(newValue)), ast->incrementToken);
-
- if (!_expr.accept(nx))
- _expr.code = _block->TEMP(oldValue);
-
+ _expr.setResult(unop(PostIncrement, expr));
return false;
}
bool Codegen::visit(PreDecrementExpression *ast)
-{
- if (hasError)
+{ if (hasError)
return false;
- Result expr = expression(ast->expression);
+ Reference expr = expression(ast->expression);
if (hasError)
return false;
- if (!expr->isLValue()) {
+ if (!expr.isLValue()) {
throwReferenceError(ast->expression->lastSourceLocation(), QStringLiteral("Prefix ++ operator applied to value that is not a reference."));
return false;
}
- if (throwSyntaxErrorOnEvalOrArgumentsInStrictMode(*expr, ast->decrementToken))
+ if (throwSyntaxErrorOnEvalOrArgumentsInStrictMode(expr, ast->decrementToken))
return false;
- IR::Expr *op = binop(IR::OpSub, *expr, _block->CONST(IR::NumberType, 1), ast->decrementToken);
- if (_expr.accept(nx)) {
- setLocation(move(*expr, op), ast->decrementToken);
- } else {
- const unsigned t = _block->newTemp();
- setLocation(move(_block->TEMP(t), op), ast->decrementToken);
- setLocation(move(*expr, _block->TEMP(t)), ast->decrementToken);
- _expr.code = _block->TEMP(t);
- }
+ _expr.setResult(unop(PreDecrement, expr));
return false;
}
@@ -1935,25 +1871,17 @@ bool Codegen::visit(PreIncrementExpression *ast)
if (hasError)
return false;
- Result expr = expression(ast->expression);
+ Reference expr = expression(ast->expression);
if (hasError)
return false;
- if (!expr->isLValue()) {
+ if (!expr.isLValue()) {
throwReferenceError(ast->expression->lastSourceLocation(), QStringLiteral("Prefix ++ operator applied to value that is not a reference."));
return false;
}
- if (throwSyntaxErrorOnEvalOrArgumentsInStrictMode(*expr, ast->incrementToken))
+ if (throwSyntaxErrorOnEvalOrArgumentsInStrictMode(expr, ast->incrementToken))
return false;
- IR::Expr *op = binop(IR::OpAdd, unop(IR::OpUPlus, *expr, ast->incrementToken), _block->CONST(IR::NumberType, 1), ast->incrementToken);
- if (_expr.accept(nx)) {
- setLocation(move(*expr, op), ast->incrementToken);
- } else {
- const unsigned t = _block->newTemp();
- setLocation(move(_block->TEMP(t), op), ast->incrementToken);
- setLocation(move(*expr, _block->TEMP(t)), ast->incrementToken);
- _expr.code = _block->TEMP(t);
- }
+ _expr.setResult(unop(PreIncrement, expr));
return false;
}
@@ -1962,7 +1890,14 @@ bool Codegen::visit(RegExpLiteral *ast)
if (hasError)
return false;
- _expr.code = _block->REGEXP(_function->newString(ast->pattern.toString()), ast->flags);
+ auto r = Reference::fromStackSlot(this);
+ r.isReadonly = true;
+ _expr.setResult(r);
+
+ Instruction::MoveRegExp instr;
+ instr.regExpId = jsUnitGenerator->registerRegExp(ast);
+ instr.destReg = r.stackSlot();
+ bytecodeGenerator->addInstruction(instr);
return false;
}
@@ -1971,16 +1906,22 @@ bool Codegen::visit(StringLiteral *ast)
if (hasError)
return false;
- _expr.code = _block->STRING(_function->newString(ast->value.toString()));
+ auto r = Reference::fromAccumulator(this);
+ r.isReadonly = true;
+ _expr.setResult(r);
+
+ Instruction::LoadRuntimeString instr;
+ instr.stringId = registerString(ast->value.toString());
+ bytecodeGenerator->addInstruction(instr);
return false;
}
-bool Codegen::visit(ThisExpression *ast)
+bool Codegen::visit(ThisExpression *)
{
if (hasError)
return false;
- _expr.code = _block->NAME(QStringLiteral("this"), ast->thisToken.startLine, ast->thisToken.startColumn);
+ _expr.setResult(Reference::fromThis(this));
return false;
}
@@ -1989,14 +1930,7 @@ bool Codegen::visit(TildeExpression *ast)
if (hasError)
return false;
- const unsigned t = _block->newTemp();
- TempScope scope(_function);
-
- Result expr = expression(ast->expression);
- if (hasError)
- return false;
- setLocation(move(_block->TEMP(t), unop(IR::OpCompl, *expr, ast->tildeToken)), ast->tildeToken);
- _expr.code = _block->TEMP(t);
+ _expr.setResult(unop(Compl, expression(ast->expression)));
return false;
}
@@ -2005,11 +1939,7 @@ bool Codegen::visit(TrueLiteral *)
if (hasError)
return false;
- if (_expr.accept(cx)) {
- _block->JUMP(_expr.iftrue);
- } else {
- _expr.code = _block->CONST(IR::BoolType, 1);
- }
+ _expr.setResult(Reference::fromConst(this, QV4::Encode(true)));
return false;
}
@@ -2018,14 +1948,24 @@ bool Codegen::visit(TypeOfExpression *ast)
if (hasError)
return false;
- TempScope scope(_function);
+ RegisterScope scope(this);
- Result expr = expression(ast->expression);
+ Reference expr = expression(ast->expression);
if (hasError)
return false;
- IR::ExprList *args = _function->New<IR::ExprList>();
- args->init(reference(*expr));
- _expr.code = call(_block->NAME(IR::Name::builtin_typeof, ast->typeofToken.startLine, ast->typeofToken.startColumn), args);
+
+ if (expr.type == Reference::Name) {
+ // special handling as typeof doesn't throw here
+ Instruction::TypeofName instr;
+ instr.name = expr.nameAsIndex();
+ bytecodeGenerator->addInstruction(instr);
+ } else {
+ expr.loadInAccumulator();
+ Instruction::TypeofValue instr;
+ bytecodeGenerator->addInstruction(instr);
+ }
+ _expr.setResult(Reference::fromAccumulator(this));
+
return false;
}
@@ -2034,12 +1974,7 @@ bool Codegen::visit(UnaryMinusExpression *ast)
if (hasError)
return false;
- Result expr = expression(ast->expression);
- if (hasError)
- return false;
- const unsigned t = _block->newTemp();
- setLocation(move(_block->TEMP(t), unop(IR::OpUMinus, *expr, ast->minusToken)), ast->minusToken);
- _expr.code = _block->TEMP(t);
+ _expr.setResult(unop(UMinus, expression(ast->expression)));
return false;
}
@@ -2048,12 +1983,7 @@ bool Codegen::visit(UnaryPlusExpression *ast)
if (hasError)
return false;
- Result expr = expression(ast->expression);
- if (hasError)
- return false;
- const unsigned t = _block->newTemp();
- setLocation(move(_block->TEMP(t), unop(IR::OpUPlus, *expr, ast->plusToken)), ast->plusToken);
- _expr.code = _block->TEMP(t);
+ _expr.setResult(unop(UPlus, expression(ast->expression)));
return false;
}
@@ -2062,10 +1992,10 @@ bool Codegen::visit(VoidExpression *ast)
if (hasError)
return false;
- TempScope scope(_function);
+ RegisterScope scope(this);
statement(ast->expression);
- _expr.code = _block->CONST(IR::UndefinedType, 0);
+ _expr.setResult(Reference::fromConst(this, Encode::undefined()));
return false;
}
@@ -2074,145 +2004,190 @@ bool Codegen::visit(FunctionDeclaration * ast)
if (hasError)
return false;
- TempScope scope(_function);
+ RegisterScope scope(this);
- if (_env->compilationMode == QmlBinding)
- move(_block->TEMP(_returnAddress), _block->NAME(ast->name.toString(), 0, 0));
+ if (_context->compilationMode == QmlBinding)
+ Reference::fromName(this, ast->name.toString()).loadInAccumulator();
_expr.accept(nx);
return false;
}
+static bool endsWithReturn(Node *node)
+{
+ if (!node)
+ return false;
+ if (AST::cast<ReturnStatement *>(node))
+ return true;
+ if (AST::cast<ThrowStatement *>(node))
+ return true;
+ if (Program *p = AST::cast<Program *>(node))
+ return endsWithReturn(p->elements);
+ if (SourceElements *se = AST::cast<SourceElements *>(node)) {
+ while (se->next)
+ se = se->next;
+ return endsWithReturn(se->element);
+ }
+ if (StatementSourceElement *sse = AST::cast<StatementSourceElement *>(node))
+ return endsWithReturn(sse->statement);
+ if (StatementList *sl = AST::cast<StatementList *>(node)) {
+ while (sl->next)
+ sl = sl->next;
+ return endsWithReturn(sl->statement);
+ }
+ if (Block *b = AST::cast<Block *>(node))
+ return endsWithReturn(b->statements);
+ if (IfStatement *is = AST::cast<IfStatement *>(node))
+ return is->ko && endsWithReturn(is->ok) && endsWithReturn(is->ko);
+ return false;
+}
+
int Codegen::defineFunction(const QString &name, AST::Node *ast,
AST::FormalParameterList *formals,
- AST::SourceElements *body,
- const QStringList &inheritedLocals)
-{
- Loop *loop = 0;
- qSwap(_loop, loop);
- QStack<IR::BasicBlock *> exceptionHandlers;
- qSwap(_exceptionHandlers, exceptionHandlers);
-
- ScopeAndFinally *scopeAndFinally = 0;
-
- enterEnvironment(ast);
- IR::Function *function = _module->newFunction(name, _function);
- int functionIndex = _module->functions.count() - 1;
-
- IR::BasicBlock *entryBlock = function->newBasicBlock(0);
- IR::BasicBlock *exitBlock = function->newBasicBlock(0, IR::Function::DontInsertBlock);
- function->hasDirectEval = _env->hasDirectEval || _env->compilationMode == EvalCode
- || _module->debugMode; // Conditional breakpoints are like eval in the function
- function->usesArgumentsObject = _env->parent && (_env->usesArgumentsObject == Environment::ArgumentsObjectUsed);
- function->usesThis = _env->usesThis;
- function->maxNumberOfArguments = qMax(_env->maxNumberOfArguments, (int)QV4::Global::ReservedArgumentCount);
- function->isStrict = _env->isStrict;
- function->isNamedExpression = _env->isNamedFunctionExpression;
- function->isQmlBinding = _env->compilationMode == QmlBinding;
-
- AST::SourceLocation loc = ast->firstSourceLocation();
- function->line = loc.startLine;
- function->column = loc.startColumn;
-
- if (function->usesArgumentsObject)
- _env->enter(QStringLiteral("arguments"), Environment::VariableDeclaration);
+ AST::SourceElements *body)
+{
+ Q_UNUSED(formals);
+
+ enterContext(ast);
+
+ if (_context->functionIndex >= 0)
+ // already defined
+ return leaveContext();
+
+ _context->name = name;
+ _module->functions.append(_context);
+ _context->functionIndex = _module->functions.count() - 1;
+
+ _context->hasDirectEval |= (_context->compilationMode == EvalCode || _context->compilationMode == GlobalCode || _module->debugMode); // Conditional breakpoints are like eval in the function
+
+ BytecodeGenerator bytecode(_context->line, _module->debugMode);
+ BytecodeGenerator *savedBytecodeGenerator;
+ savedBytecodeGenerator = bytecodeGenerator;
+ bytecodeGenerator = &bytecode;
+ bytecodeGenerator->setLocation(ast->firstSourceLocation());
+
+ // reserve the js stack frame (Context & js Function & accumulator)
+ bytecodeGenerator->newRegisterArray(sizeof(CallData)/sizeof(Value) - 1 + _context->arguments.size());
+
+ int returnAddress = -1;
+ bool _requiresReturnValue = (_context->compilationMode == QmlBinding || _context->compilationMode == EvalCode || _context->compilationMode == GlobalCode);
+ qSwap(requiresReturnValue, _requiresReturnValue);
+ if (requiresReturnValue)
+ returnAddress = bytecodeGenerator->newRegister();
+ if (!_context->parent || _context->usesArgumentsObject == Context::ArgumentsObjectUnknown)
+ _context->usesArgumentsObject = Context::ArgumentsObjectNotUsed;
+ if (_context->usesArgumentsObject == Context::ArgumentsObjectUsed)
+ _context->addLocalVar(QStringLiteral("arguments"), Context::VariableDeclaration, AST::VariableDeclaration::FunctionScope);
+
+ bool allVarsEscape = _context->hasWith || _context->hasTry || _context->hasDirectEval;
+ if (_context->compilationMode == QmlBinding // we don't really need this for bindings, but we do for signal handlers, and we don't know if the code is a signal handler or not.
+ || (!_context->canUseSimpleCall() && _context->compilationMode != GlobalCode &&
+ (_context->compilationMode != EvalCode || _context->isStrict))) {
+ Instruction::CreateCallContext createContext;
+ bytecodeGenerator->addInstruction(createContext);
+ }
// variables in global code are properties of the global context object, not locals as with other functions.
- if (_env->compilationMode == FunctionCode || _env->compilationMode == QmlBinding) {
- unsigned t = 0;
- for (Environment::MemberMap::iterator it = _env->members.begin(), end = _env->members.end(); it != end; ++it) {
+ if (_context->compilationMode == FunctionCode || _context->compilationMode == QmlBinding) {
+ for (Context::MemberMap::iterator it = _context->members.begin(), end = _context->members.end(); it != end; ++it) {
const QString &local = it.key();
- function->LOCAL(local);
- (*it).index = t;
- entryBlock->MOVE(entryBlock->LOCAL(t, 0), entryBlock->CONST(IR::UndefinedType, 0));
- ++t;
- }
- } else {
- if (!_env->isStrict) {
- for (const QString &inheritedLocal : qAsConst(inheritedLocals)) {
- function->LOCAL(inheritedLocal);
- unsigned tempIndex = entryBlock->newTemp();
- Environment::Member member = { Environment::UndefinedMember,
- static_cast<int>(tempIndex), 0 };
- _env->members.insert(inheritedLocal, member);
+ if (allVarsEscape)
+ it->canEscape = true;
+ if (it->canEscape) {
+ it->index = _context->locals.size();
+ _context->locals.append(local);
+ if (it->type == Context::ThisFunctionName) {
+ // move the name from the stack to the call context
+ Instruction::LoadReg load;
+ load.reg = CallData::Function;
+ bytecodeGenerator->addInstruction(load);
+ Instruction::StoreLocal store;
+ store.index = it->index;
+ bytecodeGenerator->addInstruction(store);
+ }
+ } else {
+ if (it->type == Context::ThisFunctionName)
+ it->index = CallData::Function;
+ else
+ it->index = bytecodeGenerator->newRegister();
}
}
-
- IR::ExprList *args = 0;
- for (Environment::MemberMap::const_iterator it = _env->members.constBegin(), cend = _env->members.constEnd(); it != cend; ++it) {
+ } else {
+ for (Context::MemberMap::const_iterator it = _context->members.constBegin(), cend = _context->members.constEnd(); it != cend; ++it) {
const QString &local = it.key();
- IR::ExprList *next = function->New<IR::ExprList>();
- next->expr = entryBlock->NAME(local, 0, 0);
- next->next = args;
- args = next;
- }
- if (args) {
- IR::ExprList *next = function->New<IR::ExprList>();
- next->expr = entryBlock->CONST(IR::BoolType, false); // ### Investigate removal of bool deletable
- next->next = args;
- args = next;
- entryBlock->EXP(entryBlock->CALL(entryBlock->NAME(IR::Name::builtin_declare_vars, 0, 0), args));
+ Instruction::DeclareVar declareVar;
+ declareVar.isDeletable = false;
+ declareVar.varName = registerString(local);
+ bytecodeGenerator->addInstruction(declareVar);
}
}
- unsigned returnAddress = entryBlock->newTemp();
-
- entryBlock->MOVE(entryBlock->TEMP(returnAddress), entryBlock->CONST(IR::UndefinedType, 0));
- setLocation(exitBlock->RET(exitBlock->TEMP(returnAddress)), ast->lastSourceLocation());
-
- qSwap(_function, function);
- qSwap(_block, entryBlock);
- qSwap(_exitBlock, exitBlock);
qSwap(_returnAddress, returnAddress);
- qSwap(_scopeAndFinally, scopeAndFinally);
-
- for (FormalParameterList *it = formals; it; it = it->next) {
- _function->RECEIVE(it->name.toString());
- }
-
- for (const Environment::Member &member : qAsConst(_env->members)) {
+ for (const Context::Member &member : qAsConst(_context->members)) {
if (member.function) {
const int function = defineFunction(member.function->name.toString(), member.function, member.function->formals,
member.function->body ? member.function->body->elements : 0);
- if (! _env->parent) {
- move(_block->NAME(member.function->name.toString(), member.function->identifierToken.startLine, member.function->identifierToken.startColumn),
- _block->CLOSURE(function));
+ loadClosure(function);
+ if (! _context->parent) {
+ Reference::fromName(this, member.function->name.toString()).storeConsumeAccumulator();
} else {
Q_ASSERT(member.index >= 0);
- move(_block->LOCAL(member.index, 0), _block->CLOSURE(function));
+ Reference local = member.canEscape ? Reference::fromScopedLocal(this, member.index, 0)
+ : Reference::fromStackSlot(this, member.index, true);
+ local.storeConsumeAccumulator();
}
}
}
- if (_function->usesArgumentsObject) {
- move(identifier(QStringLiteral("arguments"), ast->firstSourceLocation().startLine, ast->firstSourceLocation().startColumn),
- _block->CALL(_block->NAME(IR::Name::builtin_setup_argument_object,
- ast->firstSourceLocation().startLine, ast->firstSourceLocation().startColumn), 0));
+ if (_context->usesArgumentsObject == Context::ArgumentsObjectUsed) {
+ if (_context->isStrict) {
+ Instruction::CreateUnmappedArgumentsObject setup;
+ bytecodeGenerator->addInstruction(setup);
+ } else {
+ Instruction::CreateMappedArgumentsObject setup;
+ bytecodeGenerator->addInstruction(setup);
+ }
+ referenceForName(QStringLiteral("arguments"), false).storeConsumeAccumulator();
}
- if (_function->usesThis && !_function->isStrict) {
+ if (_context->usesThis && !_context->isStrict) {
// make sure we convert this to an object
- _block->EXP(_block->CALL(_block->NAME(IR::Name::builtin_convert_this_to_object,
- ast->firstSourceLocation().startLine, ast->firstSourceLocation().startColumn), 0));
+ Instruction::ConvertThisToObject convert;
+ bytecodeGenerator->addInstruction(convert);
}
beginFunctionBodyHook();
sourceElements(body);
- _function->addBasicBlock(_exitBlock);
+ if (hasError || !endsWithReturn(body)) {
+ bytecodeGenerator->setLocation(ast->lastSourceLocation());
+ if (requiresReturnValue) {
+ if (_returnAddress >= 0) {
+ Instruction::LoadReg load;
+ load.reg = Moth::StackSlot::createRegister(_returnAddress);
+ bytecodeGenerator->addInstruction(load);
+ }
+ } else {
+ Reference::fromConst(this, Encode::undefined()).loadInAccumulator();
+ }
+ bytecodeGenerator->addInstruction(Instruction::Ret());
+ }
- _block->JUMP(_exitBlock);
+ bytecodeGenerator->finalize(_context);
+ _context->registerCount = bytecodeGenerator->registerCount();
+ static const bool showCode = qEnvironmentVariableIsSet("QV4_SHOW_BYTECODE");
+ if (showCode) {
+ qDebug() << "=== Bytecode for" << _context->name << "strict mode" << _context->isStrict
+ << "register count" << _context->registerCount;
+ QV4::Moth::dumpBytecode(_context->code, _context->locals.size(), _context->arguments.size(),
+ _context->line, _context->lineNumberMapping);
+ qDebug();
+ }
- qSwap(_function, function);
- qSwap(_block, entryBlock);
- qSwap(_exitBlock, exitBlock);
qSwap(_returnAddress, returnAddress);
- qSwap(_scopeAndFinally, scopeAndFinally);
- qSwap(_exceptionHandlers, exceptionHandlers);
- qSwap(_loop, loop);
-
- leaveEnvironment();
+ qSwap(requiresReturnValue, _requiresReturnValue);
+ bytecodeGenerator = savedBytecodeGenerator;
- return functionIndex;
+ return leaveContext();
}
bool Codegen::visit(FunctionSourceElement *ast)
@@ -2238,11 +2213,9 @@ bool Codegen::visit(Block *ast)
if (hasError)
return false;
- TempScope scope(_function);
+ RegisterScope scope(this);
- for (StatementList *it = ast->statements; it; it = it->next) {
- statement(it->statement);
- }
+ statementList(ast->statements);
return false;
}
@@ -2251,27 +2224,22 @@ bool Codegen::visit(BreakStatement *ast)
if (hasError)
return false;
- TempScope scope(_function);
-
- if (!_loop) {
+ if (!_context->controlFlow) {
throwSyntaxError(ast->lastSourceLocation(), QStringLiteral("Break outside of loop"));
return false;
}
- Loop *loop = 0;
- if (ast->label.isEmpty())
- loop = _loop;
- else {
- for (loop = _loop; loop; loop = loop->parent) {
- if (loop->labelledStatement && loop->labelledStatement->label == ast->label)
- break;
- }
- if (!loop) {
+
+ ControlFlow::Handler h = _context->controlFlow->getHandler(ControlFlow::Break, ast->label.toString());
+ if (h.type == ControlFlow::Invalid) {
+ if (ast->label.isEmpty())
+ throwSyntaxError(ast->lastSourceLocation(), QStringLiteral("Break outside of loop"));
+ else
throwSyntaxError(ast->lastSourceLocation(), QStringLiteral("Undefined label '%1'").arg(ast->label.toString()));
- return false;
- }
+ return false;
}
- unwindException(loop->scopeAndFinally);
- _block->JUMP(loop->breakBlock);
+
+ _context->controlFlow->jumpToHandler(h);
+
return false;
}
@@ -2280,33 +2248,24 @@ bool Codegen::visit(ContinueStatement *ast)
if (hasError)
return false;
- TempScope scope(_function);
+ RegisterScope scope(this);
- Loop *loop = 0;
- if (ast->label.isEmpty()) {
- for (loop = _loop; loop; loop = loop->parent) {
- if (loop->continueBlock)
- break;
- }
- } else {
- for (loop = _loop; loop; loop = loop->parent) {
- if (loop->labelledStatement && loop->labelledStatement->label == ast->label) {
- if (!loop->continueBlock)
- loop = 0;
- break;
- }
- }
- if (!loop) {
- throwSyntaxError(ast->lastSourceLocation(), QStringLiteral("Undefined label '%1'").arg(ast->label.toString()));
- return false;
- }
+ if (!_context->controlFlow) {
+ throwSyntaxError(ast->lastSourceLocation(), QStringLiteral("Continue outside of loop"));
+ return false;
}
- if (!loop) {
- throwSyntaxError(ast->lastSourceLocation(), QStringLiteral("continue outside of loop"));
+
+ ControlFlow::Handler h = _context->controlFlow->getHandler(ControlFlow::Continue, ast->label.toString());
+ if (h.type == ControlFlow::Invalid) {
+ if (ast->label.isEmpty())
+ throwSyntaxError(ast->lastSourceLocation(), QStringLiteral("Undefined label '%1'").arg(ast->label.toString()));
+ else
+ throwSyntaxError(ast->lastSourceLocation(), QStringLiteral("continue outside of loop"));
return false;
}
- unwindException(loop->scopeAndFinally);
- _block->JUMP(loop->continueBlock);
+
+ _context->controlFlow->jumpToHandler(h);
+
return false;
}
@@ -2321,26 +2280,27 @@ bool Codegen::visit(DoWhileStatement *ast)
if (hasError)
return true;
- TempScope scope(_function);
+ RegisterScope scope(this);
- IR::BasicBlock *loopbody = _function->newBasicBlock(exceptionHandler());
- IR::BasicBlock *loopcond = _function->newBasicBlock(exceptionHandler());
- IR::BasicBlock *loopend = _function->newBasicBlock(exceptionHandler());
+ BytecodeGenerator::Label body = bytecodeGenerator->label();
+ BytecodeGenerator::Label cond = bytecodeGenerator->newLabel();
+ BytecodeGenerator::Label end = bytecodeGenerator->newLabel();
- enterLoop(ast, loopend, loopcond);
+ ControlFlowLoop flow(this, &end, &cond);
- _block->JUMP(loopbody);
-
- _block = loopbody;
statement(ast->statement);
- setJumpOutLocation(_block->JUMP(loopcond), ast->statement, ast->semicolonToken);
+ setJumpOutLocation(bytecodeGenerator, ast->statement, ast->semicolonToken);
- _block = loopcond;
- condition(ast->expression, loopbody, loopend);
+ cond.link();
- _block = loopend;
+ if (!AST::cast<FalseLiteral *>(ast->expression)) {
+ if (AST::cast<TrueLiteral *>(ast->expression))
+ bytecodeGenerator->jump().link(body);
+ else
+ condition(ast->expression, &body, &end, false);
+ }
- leaveLoop();
+ end.link();
return false;
}
@@ -2358,12 +2318,13 @@ bool Codegen::visit(ExpressionStatement *ast)
if (hasError)
return true;
- TempScope scope(_function);
+ RegisterScope scope(this);
- if (_env->compilationMode == EvalCode || _env->compilationMode == QmlBinding) {
- Result e = expression(ast->expression);
- if (*e)
- move(_block->TEMP(_returnAddress), *e);
+ if (requiresReturnValue) {
+ Reference e = expression(ast->expression);
+ if (hasError)
+ return false;
+ (void) e.storeOnStack(_returnAddress);
} else {
statement(ast->expression);
}
@@ -2375,46 +2336,48 @@ bool Codegen::visit(ForEachStatement *ast)
if (hasError)
return true;
- TempScope scope(_function);
-
- IR::BasicBlock *foreachin = _function->newBasicBlock(exceptionHandler());
- IR::BasicBlock *foreachbody = _function->newBasicBlock(exceptionHandler());
- IR::BasicBlock *foreachend = _function->newBasicBlock(exceptionHandler());
+ RegisterScope scope(this);
- int objectToIterateOn = _block->newTemp();
- Result expr = expression(ast->expression);
+ Reference nextIterObj = Reference::fromStackSlot(this);
+ Reference iterObj = Reference::fromStackSlot(this);
+ Reference expr = expression(ast->expression);
if (hasError)
- return false;
- move(_block->TEMP(objectToIterateOn), *expr);
- IR::ExprList *args = _function->New<IR::ExprList>();
- args->init(_block->TEMP(objectToIterateOn));
+ return true;
- int iterator = _block->newTemp();
- move(_block->TEMP(iterator), _block->CALL(_block->NAME(IR::Name::builtin_foreach_iterator_object, 0, 0), args));
+ expr.loadInAccumulator();
+ Instruction::ForeachIteratorObject iteratorObjInstr;
+ bytecodeGenerator->addInstruction(iteratorObjInstr);
+ iterObj.storeConsumeAccumulator();
- enterLoop(ast, foreachend, foreachin);
- _block->JUMP(foreachin);
+ Reference lhs = expression(ast->initialiser).asLValue();
+
+ BytecodeGenerator::Label in = bytecodeGenerator->newLabel();
+ BytecodeGenerator::Label end = bytecodeGenerator->newLabel();
+
+ bytecodeGenerator->jump().link(in);
+
+ ControlFlowLoop flow(this, &end, &in);
+
+ BytecodeGenerator::Label body = bytecodeGenerator->label();
+
+ nextIterObj.loadInAccumulator();
+ lhs.storeConsumeAccumulator();
- _block = foreachbody;
- int temp = _block->newTemp();
- Result init = expression(ast->initialiser);
- if (hasError)
- return false;
- move(*init, _block->TEMP(temp));
statement(ast->statement);
- setJumpOutLocation(_block->JUMP(foreachin), ast->statement, ast->forToken);
+ setJumpOutLocation(bytecodeGenerator, ast->statement, ast->forToken);
- _block = foreachin;
+ in.link();
- args = _function->New<IR::ExprList>();
- args->init(_block->TEMP(iterator));
- move(_block->TEMP(temp), _block->CALL(_block->NAME(IR::Name::builtin_foreach_next_property_name, 0, 0), args));
- int null = _block->newTemp();
- move(_block->TEMP(null), _block->CONST(IR::NullType, 0));
- setLocation(cjump(_block->BINOP(IR::OpStrictNotEqual, _block->TEMP(temp), _block->TEMP(null)), foreachbody, foreachend), ast->forToken);
- _block = foreachend;
+ iterObj.loadInAccumulator();
+ Instruction::ForeachNextPropertyName nextPropInstr;
+ bytecodeGenerator->addInstruction(nextPropInstr);
+ nextIterObj.storeConsumeAccumulator();
+
+ Reference::fromConst(this, QV4::Encode::null()).loadInAccumulator();
+ bytecodeGenerator->jumpStrictNotEqual(nextIterObj.stackSlot(), body);
+
+ end.link();
- leaveLoop();
return false;
}
@@ -2423,35 +2386,28 @@ bool Codegen::visit(ForStatement *ast)
if (hasError)
return true;
- TempScope scope(_function);
-
- IR::BasicBlock *forcond = _function->newBasicBlock(exceptionHandler());
- IR::BasicBlock *forbody = _function->newBasicBlock(exceptionHandler());
- IR::BasicBlock *forstep = _function->newBasicBlock(exceptionHandler());
- IR::BasicBlock *forend = _function->newBasicBlock(exceptionHandler());
+ RegisterScope scope(this);
statement(ast->initialiser);
- _block->JUMP(forcond);
- enterLoop(ast, forend, forstep);
+ BytecodeGenerator::Label cond = bytecodeGenerator->label();
+ BytecodeGenerator::Label body = bytecodeGenerator->newLabel();
+ BytecodeGenerator::Label step = bytecodeGenerator->newLabel();
+ BytecodeGenerator::Label end = bytecodeGenerator->newLabel();
- _block = forcond;
- if (ast->condition)
- condition(ast->condition, forbody, forend);
- else
- _block->JUMP(forbody);
+ ControlFlowLoop flow(this, &end, &step);
- _block = forbody;
+ condition(ast->condition, &body, &end, true);
+
+ body.link();
statement(ast->statement);
- setJumpOutLocation(_block->JUMP(forstep), ast->statement, ast->forToken);
+ setJumpOutLocation(bytecodeGenerator, ast->statement, ast->forToken);
- _block = forstep;
+ step.link();
statement(ast->expression);
- _block->JUMP(forcond);
-
- _block = forend;
+ bytecodeGenerator->jump().link(cond);
- leaveLoop();
+ end.link();
return false;
}
@@ -2461,26 +2417,28 @@ bool Codegen::visit(IfStatement *ast)
if (hasError)
return true;
- TempScope scope(_function);
+ RegisterScope scope(this);
- IR::BasicBlock *iftrue = _function->newBasicBlock(exceptionHandler());
- IR::BasicBlock *iffalse = ast->ko ? _function->newBasicBlock(exceptionHandler()) : 0;
- IR::BasicBlock *endif = _function->newBasicBlock(exceptionHandler());
+ BytecodeGenerator::Label trueLabel = bytecodeGenerator->newLabel();
+ BytecodeGenerator::Label falseLabel = bytecodeGenerator->newLabel();
+ condition(ast->expression, &trueLabel, &falseLabel, true);
- condition(ast->expression, iftrue, ast->ko ? iffalse : endif);
-
- _block = iftrue;
+ trueLabel.link();
statement(ast->ok);
- setJumpOutLocation(_block->JUMP(endif), ast->ok, ast->ifToken);
-
if (ast->ko) {
- _block = iffalse;
- statement(ast->ko);
- setJumpOutLocation(_block->JUMP(endif), ast->ko, ast->elseToken);
+ if (endsWithReturn(ast)) {
+ falseLabel.link();
+ statement(ast->ko);
+ } else {
+ BytecodeGenerator::Jump jump_endif = bytecodeGenerator->jump();
+ falseLabel.link();
+ statement(ast->ko);
+ jump_endif.link();
+ }
+ } else {
+ falseLabel.link();
}
- _block = endif;
-
return false;
}
@@ -2489,12 +2447,12 @@ bool Codegen::visit(LabelledStatement *ast)
if (hasError)
return true;
- TempScope scope(_function);
+ RegisterScope scope(this);
// check that no outer loop contains the label
- Loop *l = _loop;
+ ControlFlow *l = _context->controlFlow;
while (l) {
- if (l->labelledStatement && l->labelledStatement->label == ast->label) {
+ if (l->label() == ast->label) {
QString error = QString(QStringLiteral("Label '%1' has already been declared")).arg(ast->label.toString());
throwSyntaxError(ast->firstSourceLocation(), error);
return false;
@@ -2512,12 +2470,10 @@ bool Codegen::visit(LabelledStatement *ast)
AST::cast<AST::LocalForEachStatement *>(ast->statement)) {
statement(ast->statement); // labelledStatement will be associated with the ast->statement's loop.
} else {
- IR::BasicBlock *breakBlock = _function->newBasicBlock(exceptionHandler());
- enterLoop(ast->statement, breakBlock, /*continueBlock*/ 0);
+ BytecodeGenerator::Label breakLabel = bytecodeGenerator->newLabel();
+ ControlFlowLoop flow(this, &breakLabel);
statement(ast->statement);
- _block->JUMP(breakBlock);
- _block = breakBlock;
- leaveLoop();
+ breakLabel.link();
}
return false;
@@ -2528,40 +2484,49 @@ bool Codegen::visit(LocalForEachStatement *ast)
if (hasError)
return true;
- TempScope scope(_function);
+ RegisterScope scope(this);
- IR::BasicBlock *foreachin = _function->newBasicBlock(exceptionHandler());
- IR::BasicBlock *foreachbody = _function->newBasicBlock(exceptionHandler());
- IR::BasicBlock *foreachend = _function->newBasicBlock(exceptionHandler());
+ Reference nextIterObj = Reference::fromStackSlot(this);
+ Reference iterObj = Reference::fromStackSlot(this);
+ Reference expr = expression(ast->expression);
+ if (hasError)
+ return true;
variableDeclaration(ast->declaration);
- int iterator = _block->newTemp();
- move(_block->TEMP(iterator), *expression(ast->expression));
- IR::ExprList *args = _function->New<IR::ExprList>();
- args->init(_block->TEMP(iterator));
- move(_block->TEMP(iterator), _block->CALL(_block->NAME(IR::Name::builtin_foreach_iterator_object, 0, 0), args));
+ expr.loadInAccumulator();
+ Instruction::ForeachIteratorObject iteratorObjInstr;
+ bytecodeGenerator->addInstruction(iteratorObjInstr);
+ iterObj.storeConsumeAccumulator();
+
+ BytecodeGenerator::Label in = bytecodeGenerator->newLabel();
+ BytecodeGenerator::Label end = bytecodeGenerator->newLabel();
+
+ bytecodeGenerator->jump().link(in);
+ ControlFlowLoop flow(this, &end, &in);
- _block->JUMP(foreachin);
- enterLoop(ast, foreachend, foreachin);
+ BytecodeGenerator::Label body = bytecodeGenerator->label();
+
+ Reference it = referenceForName(ast->declaration->name.toString(), true).asLValue();
+
+ nextIterObj.loadInAccumulator();
+ it.storeConsumeAccumulator();
- _block = foreachbody;
- int temp = _block->newTemp();
- move(identifier(ast->declaration->name.toString()), _block->TEMP(temp));
statement(ast->statement);
- setJumpOutLocation(_block->JUMP(foreachin), ast->statement, ast->forToken);
+ setJumpOutLocation(bytecodeGenerator, ast->statement, ast->forToken);
+
+ in.link();
+
+ iterObj.loadInAccumulator();
+ Instruction::ForeachNextPropertyName nextPropInstr;
+ bytecodeGenerator->addInstruction(nextPropInstr);
+ nextIterObj.storeConsumeAccumulator();
- _block = foreachin;
+ Reference::fromConst(this, QV4::Encode::null()).loadInAccumulator();
+ bytecodeGenerator->jumpStrictNotEqual(nextIterObj.stackSlot(), body);
- args = _function->New<IR::ExprList>();
- args->init(_block->TEMP(iterator));
- move(_block->TEMP(temp), _block->CALL(_block->NAME(IR::Name::builtin_foreach_next_property_name, 0, 0), args));
- int null = _block->newTemp();
- move(_block->TEMP(null), _block->CONST(IR::NullType, 0));
- setLocation(cjump(_block->BINOP(IR::OpStrictNotEqual, _block->TEMP(temp), _block->TEMP(null)), foreachbody, foreachend), ast->forToken);
- _block = foreachend;
+ end.link();
- leaveLoop();
return false;
}
@@ -2570,35 +2535,27 @@ bool Codegen::visit(LocalForStatement *ast)
if (hasError)
return true;
- TempScope scope(_function);
-
- IR::BasicBlock *forcond = _function->newBasicBlock(exceptionHandler());
- IR::BasicBlock *forbody = _function->newBasicBlock(exceptionHandler());
- IR::BasicBlock *forstep = _function->newBasicBlock(exceptionHandler());
- IR::BasicBlock *forend = _function->newBasicBlock(exceptionHandler());
+ RegisterScope scope(this);
variableDeclarationList(ast->declarations);
- _block->JUMP(forcond);
- enterLoop(ast, forend, forstep);
+ BytecodeGenerator::Label cond = bytecodeGenerator->label();
+ BytecodeGenerator::Label body = bytecodeGenerator->newLabel();
+ BytecodeGenerator::Label step = bytecodeGenerator->newLabel();
+ BytecodeGenerator::Label end = bytecodeGenerator->newLabel();
- _block = forcond;
- if (ast->condition)
- condition(ast->condition, forbody, forend);
- else
- _block->JUMP(forbody);
+ ControlFlowLoop flow(this, &end, &step);
- _block = forbody;
+ condition(ast->condition, &body, &end, true);
+
+ body.link();
statement(ast->statement);
- setJumpOutLocation(_block->JUMP(forstep), ast->statement, ast->forToken);
+ setJumpOutLocation(bytecodeGenerator, ast->statement, ast->forToken);
- _block = forstep;
+ step.link();
statement(ast->expression);
- _block->JUMP(forcond);
-
- _block = forend;
-
- leaveLoop();
+ bytecodeGenerator->jump().link(cond);
+ end.link();
return false;
}
@@ -2608,24 +2565,30 @@ bool Codegen::visit(ReturnStatement *ast)
if (hasError)
return true;
- if (_env->compilationMode != FunctionCode && _env->compilationMode != QmlBinding) {
+ if (_context->compilationMode != FunctionCode && _context->compilationMode != QmlBinding) {
throwSyntaxError(ast->returnToken, QStringLiteral("Return statement outside of function"));
return false;
}
+ Reference expr;
if (ast->expression) {
- Result expr = expression(ast->expression);
- move(_block->TEMP(_returnAddress), *expr);
+ expr = expression(ast->expression);
+ if (hasError)
+ return false;
+ } else {
+ expr = Reference::fromConst(this, Encode::undefined());
}
- // Since we're leaving, don't let any finally statements we emit as part of the unwinding
- // jump to exception handlers at run-time if they throw.
- IR::BasicBlock *unwindBlock = _function->newBasicBlock(/*no exception handler*/Q_NULLPTR);
- _block->JUMP(unwindBlock);
- _block = unwindBlock;
-
- unwindException(0);
-
- _block->JUMP(_exitBlock);
+ if (_context->controlFlow && _context->controlFlow->returnRequiresUnwind()) {
+ if (_returnAddress >= 0)
+ (void) expr.storeOnStack(_returnAddress);
+ else
+ expr.loadInAccumulator();
+ ControlFlow::Handler h = _context->controlFlow->getHandler(ControlFlow::Return);
+ _context->controlFlow->jumpToHandler(h);
+ } else {
+ expr.loadInAccumulator();
+ bytecodeGenerator->addInstruction(Instruction::Ret());
+ }
return false;
}
@@ -2634,245 +2597,151 @@ bool Codegen::visit(SwitchStatement *ast)
if (hasError)
return true;
- TempScope scope(_function);
-
- IR::BasicBlock *switchend = _function->newBasicBlock(exceptionHandler());
+ RegisterScope scope(this);
if (ast->block) {
- int lhs = _block->newTemp();
- move(_block->TEMP(lhs), *expression(ast->expression));
- IR::BasicBlock *switchcond = _function->newBasicBlock(exceptionHandler());
- _block->JUMP(switchcond);
- IR::BasicBlock *previousBlock = 0;
-
- QHash<Node *, IR::BasicBlock *> blockMap;
-
- enterLoop(ast, switchend, 0);
+ BytecodeGenerator::Label switchEnd = bytecodeGenerator->newLabel();
+ Reference lhs = expression(ast->expression);
+ if (hasError)
+ return false;
+ lhs = lhs.storeOnStack();
+
+ // set up labels for all clauses
+ QHash<Node *, BytecodeGenerator::Label> blockMap;
+ for (CaseClauses *it = ast->block->clauses; it; it = it->next)
+ blockMap[it->clause] = bytecodeGenerator->newLabel();
+ if (ast->block->defaultClause)
+ blockMap[ast->block->defaultClause] = bytecodeGenerator->newLabel();
+ for (CaseClauses *it = ast->block->moreClauses; it; it = it->next)
+ blockMap[it->clause] = bytecodeGenerator->newLabel();
+
+ // do the switch conditions
for (CaseClauses *it = ast->block->clauses; it; it = it->next) {
CaseClause *clause = it->clause;
-
- _block = _function->newBasicBlock(exceptionHandler());
- blockMap[clause] = _block;
-
- if (previousBlock && !previousBlock->isTerminated())
- previousBlock->JUMP(_block);
-
- for (StatementList *it2 = clause->statements; it2; it2 = it2->next)
- statement(it2->statement);
-
- previousBlock = _block;
- }
-
- if (ast->block->defaultClause) {
- _block = _function->newBasicBlock(exceptionHandler());
- blockMap[ast->block->defaultClause] = _block;
-
- if (previousBlock && !previousBlock->isTerminated())
- previousBlock->JUMP(_block);
-
- for (StatementList *it2 = ast->block->defaultClause->statements; it2; it2 = it2->next)
- statement(it2->statement);
-
- previousBlock = _block;
+ Reference rhs = expression(clause->expression);
+ if (hasError)
+ return false;
+ rhs.loadInAccumulator();
+ bytecodeGenerator->jumpStrictEqual(lhs.stackSlot(), blockMap.value(clause));
}
for (CaseClauses *it = ast->block->moreClauses; it; it = it->next) {
CaseClause *clause = it->clause;
+ Reference rhs = expression(clause->expression);
+ if (hasError)
+ return false;
+ rhs.loadInAccumulator();
+ bytecodeGenerator->jumpStrictEqual(lhs.stackSlot(), blockMap.value(clause));
+ }
- _block = _function->newBasicBlock(exceptionHandler());
- blockMap[clause] = _block;
+ if (DefaultClause *defaultClause = ast->block->defaultClause)
+ bytecodeGenerator->jump().link(blockMap.value(defaultClause));
+ else
+ bytecodeGenerator->jump().link(switchEnd);
- if (previousBlock && !previousBlock->isTerminated())
- previousBlock->JUMP(_block);
+ ControlFlowLoop flow(this, &switchEnd);
- for (StatementList *it2 = clause->statements; it2; it2 = it2->next)
- statement(it2->statement);
+ for (CaseClauses *it = ast->block->clauses; it; it = it->next) {
+ CaseClause *clause = it->clause;
+ blockMap[clause].link();
- previousBlock = _block;
+ statementList(clause->statements);
}
- leaveLoop();
-
- _block->JUMP(switchend);
+ if (ast->block->defaultClause) {
+ DefaultClause *clause = ast->block->defaultClause;
+ blockMap[clause].link();
- _block = switchcond;
- for (CaseClauses *it = ast->block->clauses; it; it = it->next) {
- CaseClause *clause = it->clause;
- Result rhs = expression(clause->expression);
- IR::BasicBlock *iftrue = blockMap[clause];
- IR::BasicBlock *iffalse = _function->newBasicBlock(exceptionHandler());
- setLocation(cjump(binop(IR::OpStrictEqual, _block->TEMP(lhs), *rhs), iftrue, iffalse), clause->caseToken);
- _block = iffalse;
+ statementList(clause->statements);
}
for (CaseClauses *it = ast->block->moreClauses; it; it = it->next) {
CaseClause *clause = it->clause;
- Result rhs = expression(clause->expression);
- IR::BasicBlock *iftrue = blockMap[clause];
- IR::BasicBlock *iffalse = _function->newBasicBlock(exceptionHandler());
- setLocation(cjump(binop(IR::OpStrictEqual, _block->TEMP(lhs), *rhs), iftrue, iffalse), clause->caseToken);
- _block = iffalse;
- }
+ blockMap[clause].link();
- if (DefaultClause *defaultClause = ast->block->defaultClause) {
- setLocation(_block->JUMP(blockMap[ast->block->defaultClause]), defaultClause->defaultToken);
+ statementList(clause->statements);
}
- }
- _block->JUMP(switchend);
+ switchEnd.link();
+
+ }
- _block = switchend;
return false;
}
bool Codegen::visit(ThrowStatement *ast)
{
if (hasError)
- return true;
+ return false;
- TempScope scope(_function);
+ RegisterScope scope(this);
- Result expr = expression(ast->expression);
- move(_block->TEMP(_returnAddress), *expr);
- IR::ExprList *throwArgs = _function->New<IR::ExprList>();
- throwArgs->expr = _block->TEMP(_returnAddress);
- _block->EXP(_block->CALL(_block->NAME(IR::Name::builtin_throw, /*line*/0, /*column*/0), throwArgs));
+ Reference expr = expression(ast->expression);
+ if (hasError)
+ return false;
+
+ if (_context->controlFlow) {
+ _context->controlFlow->handleThrow(expr);
+ } else {
+ expr.loadInAccumulator();
+ Instruction::ThrowException instr;
+ bytecodeGenerator->addInstruction(instr);
+ }
return false;
}
-bool Codegen::visit(TryStatement *ast)
+void Codegen::handleTryCatch(TryStatement *ast)
{
- if (hasError)
- return true;
-
- TempScope scope(_function);
-
- _function->hasTry = true;
-
- if (_function->isStrict && ast->catchExpression &&
- (ast->catchExpression->name == QLatin1String("eval") || ast->catchExpression->name == QLatin1String("arguments"))) {
+ Q_ASSERT(ast);
+ if (_context->isStrict &&
+ (ast->catchExpression->name == QLatin1String("eval") || ast->catchExpression->name == QLatin1String("arguments"))) {
throwSyntaxError(ast->catchExpression->identifierToken, QStringLiteral("Catch variable name may not be eval or arguments in strict mode"));
- return false;
+ return;
}
- IR::BasicBlock *surroundingExceptionHandler = exceptionHandler();
-
- // We always need a finally body to clean up the exception handler
- // exceptions thrown in finally get caught by the surrounding catch block
- IR::BasicBlock *finallyBody = 0;
- IR::BasicBlock *catchBody = 0;
- IR::BasicBlock *catchExceptionHandler = 0;
- IR::BasicBlock *end = _function->newBasicBlock(surroundingExceptionHandler, IR::Function::DontInsertBlock);
-
- if (ast->finallyExpression)
- finallyBody = _function->newBasicBlock(surroundingExceptionHandler, IR::Function::DontInsertBlock);
-
- if (ast->catchExpression) {
- // exception handler for the catch body
- catchExceptionHandler = _function->newBasicBlock(0, IR::Function::DontInsertBlock);
- pushExceptionHandler(catchExceptionHandler);
- catchBody = _function->newBasicBlock(catchExceptionHandler, IR::Function::DontInsertBlock);
- popExceptionHandler();
- pushExceptionHandler(catchBody);
- } else {
- Q_ASSERT(finallyBody);
- pushExceptionHandler(finallyBody);
+ RegisterScope scope(this);
+ BytecodeGenerator::Label noException = bytecodeGenerator->newLabel();
+ {
+ ControlFlowCatch catchFlow(this, ast->catchExpression);
+ RegisterScope scope(this);
+ statement(ast->statement);
+ bytecodeGenerator->jump().link(noException);
}
+ noException.link();
+}
- IR::BasicBlock *tryBody = _function->newBasicBlock(exceptionHandler());
- _block->JUMP(tryBody);
-
- ScopeAndFinally tcf(_scopeAndFinally, ast->finallyExpression);
- _scopeAndFinally = &tcf;
-
- _block = tryBody;
- statement(ast->statement);
- _block->JUMP(finallyBody ? finallyBody : end);
-
- popExceptionHandler();
+void Codegen::handleTryFinally(TryStatement *ast)
+{
+ RegisterScope scope(this);
+ ControlFlowFinally finally(this, ast->finallyExpression);
if (ast->catchExpression) {
- pushExceptionHandler(catchExceptionHandler);
- _function->addBasicBlock(catchBody);
- _block = catchBody;
-
- ++_function->insideWithOrCatch;
- IR::ExprList *catchArgs = _function->New<IR::ExprList>();
- catchArgs->init(_block->STRING(_function->newString(ast->catchExpression->name.toString())));
- _block->EXP(_block->CALL(_block->NAME(IR::Name::builtin_push_catch_scope, 0, 0), catchArgs));
- {
- ScopeAndFinally scope(_scopeAndFinally, ScopeAndFinally::CatchScope);
- _scopeAndFinally = &scope;
- statement(ast->catchExpression->statement);
- _scopeAndFinally = scope.parent;
- }
- _block->EXP(_block->CALL(_block->NAME(IR::Name::builtin_pop_scope, 0, 0), 0));
- --_function->insideWithOrCatch;
- _block->JUMP(finallyBody ? finallyBody : end);
- popExceptionHandler();
-
- _function->addBasicBlock(catchExceptionHandler);
- catchExceptionHandler->EXP(catchExceptionHandler->CALL(catchExceptionHandler->NAME(IR::Name::builtin_pop_scope, 0, 0), 0));
- if (finallyBody || surroundingExceptionHandler)
- catchExceptionHandler->JUMP(finallyBody ? finallyBody : surroundingExceptionHandler);
- else
- catchExceptionHandler->EXP(catchExceptionHandler->CALL(catchExceptionHandler->NAME(IR::Name::builtin_rethrow, 0, 0), 0));
+ handleTryCatch(ast);
+ } else {
+ RegisterScope scope(this);
+ statement(ast->statement);
}
+}
- _scopeAndFinally = tcf.parent;
-
- if (finallyBody) {
- _function->addBasicBlock(finallyBody);
- _block = finallyBody;
-
- TempScope scope(_function);
+bool Codegen::visit(TryStatement *ast)
+{
+ if (hasError)
+ return true;
- int hasException = _block->newTemp();
- move(_block->TEMP(hasException), _block->CALL(_block->NAME(IR::Name::builtin_unwind_exception, /*line*/0, /*column*/0), 0));
+ Q_ASSERT(_context->hasTry);
- if (ast->finallyExpression && ast->finallyExpression->statement)
- statement(ast->finallyExpression->statement);
+ RegisterScope scope(this);
- IR::ExprList *arg = _function->New<IR::ExprList>();
- arg->expr = _block->TEMP(hasException);
- _block->EXP(_block->CALL(_block->NAME(IR::Name::builtin_throw, /*line*/0, /*column*/0), arg));
- _block->JUMP(end);
+ if (ast->finallyExpression && ast->finallyExpression->statement) {
+ handleTryFinally(ast);
+ } else {
+ handleTryCatch(ast);
}
- _function->addBasicBlock(end);
- _block = end;
-
return false;
}
-void Codegen::unwindException(Codegen::ScopeAndFinally *outest)
-{
- int savedDepthForWidthOrCatch = _function->insideWithOrCatch;
- ScopeAndFinally *scopeAndFinally = _scopeAndFinally;
- qSwap(_scopeAndFinally, scopeAndFinally);
- while (_scopeAndFinally != outest) {
- switch (_scopeAndFinally->type) {
- case ScopeAndFinally::WithScope:
- // fall through
- case ScopeAndFinally::CatchScope:
- _block->EXP(_block->CALL(_block->NAME(IR::Name::builtin_pop_scope, 0, 0)));
- _scopeAndFinally = _scopeAndFinally->parent;
- --_function->insideWithOrCatch;
- break;
- case ScopeAndFinally::TryScope: {
- ScopeAndFinally *tc = _scopeAndFinally;
- _scopeAndFinally = tc->parent;
- if (tc->finally && tc->finally->statement)
- statement(tc->finally->statement);
- break;
- }
- }
- }
- qSwap(_scopeAndFinally, scopeAndFinally);
- _function->insideWithOrCatch = savedDepthForWidthOrCatch;
-}
-
bool Codegen::visit(VariableStatement *ast)
{
if (hasError)
@@ -2887,23 +2756,25 @@ bool Codegen::visit(WhileStatement *ast)
if (hasError)
return true;
- IR::BasicBlock *whilecond = _function->newBasicBlock(exceptionHandler());
- IR::BasicBlock *whilebody = _function->newBasicBlock(exceptionHandler());
- IR::BasicBlock *whileend = _function->newBasicBlock(exceptionHandler());
+ if (AST::cast<FalseLiteral *>(ast->expression))
+ return false;
- enterLoop(ast, whileend, whilecond);
+ RegisterScope scope(this);
- _block->JUMP(whilecond);
- _block = whilecond;
- condition(ast->expression, whilebody, whileend);
+ BytecodeGenerator::Label start = bytecodeGenerator->newLabel();
+ BytecodeGenerator::Label end = bytecodeGenerator->newLabel();
+ BytecodeGenerator::Label cond = bytecodeGenerator->label();
+ ControlFlowLoop flow(this, &end, &cond);
- _block = whilebody;
- statement(ast->statement);
- setJumpOutLocation(_block->JUMP(whilecond), ast->statement, ast->whileToken);
+ if (!AST::cast<TrueLiteral *>(ast->expression))
+ condition(ast->expression, &start, &end, true);
- _block = whileend;
- leaveLoop();
+ start.link();
+ statement(ast->statement);
+ setJumpOutLocation(bytecodeGenerator, ast->statement, ast->whileToken);
+ bytecodeGenerator->jump().link(cond);
+ end.link();
return false;
}
@@ -2912,103 +2783,75 @@ bool Codegen::visit(WithStatement *ast)
if (hasError)
return true;
- TempScope scope(_function);
+ RegisterScope scope(this);
- _function->hasWith = true;
+ _context->hasWith = true;
- const int withObject = _block->newTemp();
- Result src = expression(ast->expression);
+ Reference src = expression(ast->expression);
if (hasError)
return false;
- _block->MOVE(_block->TEMP(withObject), *src);
-
- // need an exception handler for with to cleanup the with scope
- IR::BasicBlock *withExceptionHandler = _function->newBasicBlock(exceptionHandler());
- withExceptionHandler->EXP(withExceptionHandler->CALL(withExceptionHandler->NAME(IR::Name::builtin_pop_scope, 0, 0), 0));
- if (!exceptionHandler())
- withExceptionHandler->EXP(withExceptionHandler->CALL(withExceptionHandler->NAME(IR::Name::builtin_rethrow, 0, 0), 0));
- else
- withExceptionHandler->JUMP(exceptionHandler());
+ src = src.storeOnStack(); // trigger load before we setup the exception handler, so exceptions here go to the right place
+ src.loadInAccumulator();
- pushExceptionHandler(withExceptionHandler);
+ ControlFlowWith flow(this);
- IR::BasicBlock *withBlock = _function->newBasicBlock(exceptionHandler());
-
- _block->JUMP(withBlock);
- _block = withBlock;
- IR::ExprList *args = _function->New<IR::ExprList>();
- args->init(_block->TEMP(withObject));
- _block->EXP(_block->CALL(_block->NAME(IR::Name::builtin_push_with_scope, 0, 0), args));
-
- ++_function->insideWithOrCatch;
- {
- ScopeAndFinally scope(_scopeAndFinally);
- _scopeAndFinally = &scope;
- statement(ast->statement);
- _scopeAndFinally = scope.parent;
- }
- --_function->insideWithOrCatch;
- _block->EXP(_block->CALL(_block->NAME(IR::Name::builtin_pop_scope, 0, 0), 0));
- popExceptionHandler();
-
- IR::BasicBlock *next = _function->newBasicBlock(exceptionHandler());
- _block->JUMP(next);
- _block = next;
+ statement(ast->statement);
return false;
}
bool Codegen::visit(UiArrayBinding *)
{
- Q_ASSERT(!"not implemented");
+ Q_UNIMPLEMENTED();
return false;
}
bool Codegen::visit(UiObjectBinding *)
{
- Q_ASSERT(!"not implemented");
+ Q_UNIMPLEMENTED();
return false;
}
bool Codegen::visit(UiObjectDefinition *)
{
- Q_ASSERT(!"not implemented");
+ Q_UNIMPLEMENTED();
return false;
}
bool Codegen::visit(UiPublicMember *)
{
- Q_ASSERT(!"not implemented");
+ Q_UNIMPLEMENTED();
return false;
}
bool Codegen::visit(UiScriptBinding *)
{
- Q_ASSERT(!"not implemented");
+ Q_UNIMPLEMENTED();
return false;
}
bool Codegen::visit(UiSourceElement *)
{
- Q_ASSERT(!"not implemented");
+ Q_UNIMPLEMENTED();
return false;
}
-bool Codegen::throwSyntaxErrorOnEvalOrArgumentsInStrictMode(IR::Expr *expr, const SourceLocation& loc)
+bool Codegen::throwSyntaxErrorOnEvalOrArgumentsInStrictMode(const Reference &r, const SourceLocation& loc)
{
- if (!_env->isStrict)
- return false;
- if (IR::Name *n = expr->asName()) {
- if (*n->id != QLatin1String("eval") && *n->id != QLatin1String("arguments"))
- return false;
- } else if (IR::ArgLocal *al = expr->asArgLocal()) {
- if (!al->isArgumentsOrEval)
- return false;
- } else {
+ if (!_context->isStrict)
return false;
+ bool isArgOrEval = false;
+ if (r.type == Reference::Name) {
+ QString str = jsUnitGenerator->stringForIndex(r.nameAsIndex());
+ if (str == QLatin1String("eval") || str == QLatin1String("arguments")) {
+ isArgOrEval = true;
+ }
+ } else if (r.type == Reference::ScopedLocal || r.isRegister()) {
+ isArgOrEval = r.isArgOrEval;
}
- throwSyntaxError(loc, QStringLiteral("Variable name may not be eval or arguments in strict mode"));
- return true;
+ if (isArgOrEval)
+ throwSyntaxError(loc, QStringLiteral("Variable name may not be eval or arguments in strict mode"));
+ return isArgOrEval;
}
void Codegen::throwSyntaxError(const SourceLocation &loc, const QString &detail)
@@ -3040,6 +2883,116 @@ QList<QQmlJS::DiagnosticMessage> Codegen::errors() const
return _errors;
}
+QQmlRefPointer<CompiledData::CompilationUnit> Codegen::generateCompilationUnit(bool generateUnitData)
+{
+ CompiledData::CompilationUnit *compilationUnit = new CompiledData::CompilationUnit;
+ if (generateUnitData)
+ compilationUnit->data = jsUnitGenerator->generateUnit();
+
+ QQmlRefPointer<CompiledData::CompilationUnit> unit;
+ unit.adopt(compilationUnit);
+ return unit;
+}
+
+QQmlRefPointer<CompiledData::CompilationUnit> Codegen::createUnitForLoading()
+{
+ QQmlRefPointer<CompiledData::CompilationUnit> result;
+ result.adopt(new CompiledData::CompilationUnit);
+ return result;
+}
+
+class Codegen::VolatileMemoryLocationScanner: protected QQmlJS::AST::Visitor
+{
+ VolatileMemoryLocations locs;
+
+public:
+ Codegen::VolatileMemoryLocations scan(AST::Node *s)
+ {
+ s->accept(this);
+ return locs;
+ }
+
+ bool visit(ArrayMemberExpression *) Q_DECL_OVERRIDE
+ {
+ locs.setAllVolatile();
+ return false;
+ }
+
+ bool visit(FieldMemberExpression *) Q_DECL_OVERRIDE
+ {
+ locs.setAllVolatile();
+ return false;
+ }
+
+ bool visit(PostIncrementExpression *e) Q_DECL_OVERRIDE
+ {
+ collectIdentifiers(locs.specificLocations, e->base);
+ return false;
+ }
+
+ bool visit(PostDecrementExpression *e) Q_DECL_OVERRIDE
+ {
+ collectIdentifiers(locs.specificLocations, e->base);
+ return false;
+ }
+
+ bool visit(PreIncrementExpression *e) Q_DECL_OVERRIDE
+ {
+ collectIdentifiers(locs.specificLocations, e->expression);
+ return false;
+ }
+
+ bool visit(PreDecrementExpression *e) Q_DECL_OVERRIDE
+ {
+ collectIdentifiers(locs.specificLocations, e->expression);
+ return false;
+ }
+
+ bool visit(BinaryExpression *e) Q_DECL_OVERRIDE
+ {
+ switch (e->op) {
+ case QSOperator::InplaceAnd:
+ case QSOperator::InplaceSub:
+ case QSOperator::InplaceDiv:
+ case QSOperator::InplaceAdd:
+ case QSOperator::InplaceLeftShift:
+ case QSOperator::InplaceMod:
+ case QSOperator::InplaceMul:
+ case QSOperator::InplaceOr:
+ case QSOperator::InplaceRightShift:
+ case QSOperator::InplaceURightShift:
+ case QSOperator::InplaceXor:
+ collectIdentifiers(locs.specificLocations, e);
+ return false;
+
+ default:
+ return true;
+ }
+ }
+
+private:
+ void collectIdentifiers(QVector<QStringView> &ids, AST::Node *node) const {
+ class Collector: public QQmlJS::AST::Visitor {
+ QVector<QStringView> &ids;
+ public:
+ Collector(QVector<QStringView> &ids): ids(ids) {}
+ virtual bool visit(IdentifierExpression *ie) {
+ ids.append(ie->name);
+ return false;
+ }
+ };
+ Collector collector(ids);
+ node->accept(&collector);
+ }
+};
+
+Codegen::VolatileMemoryLocations Codegen::scanVolatileMemoryLocations(AST::Node *ast) const
+{
+ VolatileMemoryLocationScanner scanner;
+ return scanner.scan(ast);
+}
+
+
#ifndef V4_BOOTSTRAP
QList<QQmlError> Codegen::qmlErrors() const
@@ -3065,20 +3018,458 @@ QList<QQmlError> Codegen::qmlErrors() const
return qmlErrors;
}
-void RuntimeCodegen::throwSyntaxError(const AST::SourceLocation &loc, const QString &detail)
+#endif // V4_BOOTSTRAP
+
+bool Codegen::RValue::operator==(const RValue &other) const
{
- if (hasError)
- return;
- hasError = true;
- engine->throwSyntaxError(detail, _module->fileName, loc.startLine, loc.startColumn);
+ switch (type) {
+ case Accumulator:
+ return other.isAccumulator();
+ case StackSlot:
+ return other.isStackSlot() && theStackSlot == other.theStackSlot;
+ case Const:
+ return other.isConst() && constant == other.constant;
+ default:
+ return false;
+ }
}
-void RuntimeCodegen::throwReferenceError(const AST::SourceLocation &loc, const QString &detail)
+Codegen::RValue Codegen::RValue::storeOnStack() const
{
- if (hasError)
+ switch (type) {
+ case Accumulator:
+ return RValue::fromStackSlot(codegen, Reference::fromAccumulator(codegen).storeOnStack().stackSlot());
+ case StackSlot:
+ return *this;
+ case Const:
+ return RValue::fromStackSlot(codegen, Reference::storeConstOnStack(codegen, constant).stackSlot());
+ default:
+ Q_UNREACHABLE();
+ }
+}
+
+Codegen::Reference::Reference(const Codegen::Reference &other)
+{
+ *this = other;
+}
+
+Codegen::Reference &Codegen::Reference::operator =(const Reference &other)
+{
+ type = other.type;
+
+ switch (type) {
+ case Invalid:
+ case Accumulator:
+ break;
+ case StackSlot:
+ theStackSlot = other.theStackSlot;
+ break;
+ case ScopedLocal:
+ index = other.index;
+ scope = other.scope;
+ break;
+ case Name:
+ name = other.name;
+ break;
+ case Member:
+ propertyBase = other.propertyBase;
+ propertyNameIndex = other.propertyNameIndex;
+ break;
+ case Subscript:
+ elementBase = other.elementBase;
+ elementSubscript = other.elementSubscript;
+ break;
+ case Const:
+ constant = other.constant;
+ break;
+ case QmlScopeObject:
+ case QmlContextObject:
+ qmlBase = other.qmlBase;
+ qmlCoreIndex = other.qmlCoreIndex;
+ qmlNotifyIndex = other.qmlNotifyIndex;
+ capturePolicy = other.capturePolicy;
+ break;
+ }
+
+ // keep loaded reference
+ isArgOrEval = other.isArgOrEval;
+ codegen = other.codegen;
+ isReadonly = other.isReadonly;
+ stackSlotIsLocalOrArgument = other.stackSlotIsLocalOrArgument;
+ isVolatile = other.isVolatile;
+ global = other.global;
+ return *this;
+}
+
+bool Codegen::Reference::operator==(const Codegen::Reference &other) const
+{
+ if (type != other.type)
+ return false;
+ switch (type) {
+ case Invalid:
+ case Accumulator:
+ break;
+ case StackSlot:
+ return theStackSlot == other.theStackSlot;
+ case ScopedLocal:
+ return index == other.index && scope == other.scope;
+ case Name:
+ return nameAsIndex() == other.nameAsIndex();
+ case Member:
+ return propertyBase == other.propertyBase && propertyNameIndex == other.propertyNameIndex;
+ case Subscript:
+ return elementBase == other.elementBase && elementSubscript == other.elementSubscript;
+ case Const:
+ return constant == other.constant;
+ case QmlScopeObject:
+ case QmlContextObject:
+ return qmlCoreIndex == other.qmlCoreIndex && qmlNotifyIndex == other.qmlNotifyIndex
+ && capturePolicy == other.capturePolicy;
+ }
+ return true;
+}
+
+Codegen::RValue Codegen::Reference::asRValue() const
+{
+ switch (type) {
+ case Invalid:
+ Q_UNREACHABLE();
+ case Accumulator:
+ return RValue::fromAccumulator(codegen);
+ case StackSlot:
+ return RValue::fromStackSlot(codegen, stackSlot());
+ case Const:
+ return RValue::fromConst(codegen, constant);
+ default:
+ loadInAccumulator();
+ return RValue::fromAccumulator(codegen);
+ }
+}
+
+Codegen::Reference Codegen::Reference::asLValue() const
+{
+ switch (type) {
+ case Invalid:
+ case Accumulator:
+ Q_UNREACHABLE();
+ case Member:
+ if (!propertyBase.isStackSlot()) {
+ Reference r = *this;
+ r.propertyBase = propertyBase.storeOnStack();
+ return r;
+ }
+ return *this;
+ case Subscript:
+ if (!elementSubscript.isStackSlot()) {
+ Reference r = *this;
+ r.elementSubscript = elementSubscript.storeOnStack();
+ return r;
+ }
+ return *this;
+ default:
+ return *this;
+ }
+}
+
+Codegen::Reference Codegen::Reference::storeConsumeAccumulator() const
+{
+ storeAccumulator(); // it doesn't matter what happens here, just do it.
+ return Reference();
+}
+
+Codegen::Reference Codegen::Reference::storeOnStack() const
+{ return doStoreOnStack(-1); }
+
+void Codegen::Reference::storeOnStack(int slotIndex) const
+{ doStoreOnStack(slotIndex); }
+
+Codegen::Reference Codegen::Reference::doStoreOnStack(int slotIndex) const
+{
+ if (isStackSlot() && slotIndex == -1 && !(stackSlotIsLocalOrArgument && isVolatile))
+ return *this;
+
+ if (isStackSlot()) { // temp-to-temp move
+ Reference dest = Reference::fromStackSlot(codegen, slotIndex);
+ Instruction::MoveReg move;
+ move.srcReg = stackSlot();
+ move.destReg = dest.stackSlot();
+ codegen->bytecodeGenerator->addInstruction(move);
+ return dest;
+ }
+
+ Reference slot = Reference::fromStackSlot(codegen, slotIndex);
+ if (isConst()) {
+ Instruction::MoveConst move;
+ move.constIndex = codegen->registerConstant(constant);
+ move.destTemp = slot.stackSlot();
+ codegen->bytecodeGenerator->addInstruction(move);
+ } else {
+ loadInAccumulator();
+ slot.storeConsumeAccumulator();
+ }
+ return slot;
+}
+
+Codegen::Reference Codegen::Reference::storeRetainAccumulator() const
+{
+ if (storeWipesAccumulator()) {
+ // a store will
+ auto tmp = Reference::fromStackSlot(codegen);
+ tmp.storeAccumulator(); // this is safe, and won't destory the accumulator
+ storeAccumulator();
+ return tmp;
+ } else {
+ // ok, this is safe, just do the store.
+ storeAccumulator();
+ return *this;
+ }
+}
+
+bool Codegen::Reference::storeWipesAccumulator() const
+{
+ switch (type) {
+ default:
+ case Invalid:
+ case Const:
+ case Accumulator:
+ Q_UNREACHABLE();
+ return false;
+ case StackSlot:
+ case ScopedLocal:
+ return false;
+ case Name:
+ case Member:
+ case Subscript:
+ case QmlScopeObject:
+ case QmlContextObject:
+ return true;
+ }
+}
+
+void Codegen::Reference::storeAccumulator() const
+{
+ switch (type) {
+ case StackSlot: {
+ Instruction::StoreReg store;
+ store.reg = theStackSlot;
+ codegen->bytecodeGenerator->addInstruction(store);
return;
- hasError = true;
- engine->throwReferenceError(detail, _module->fileName, loc.startLine, loc.startColumn);
+ }
+ case ScopedLocal: {
+ if (scope == 0) {
+ Instruction::StoreLocal store;
+ store.index = index;
+ codegen->bytecodeGenerator->addInstruction(store);
+ } else {
+ Instruction::StoreScopedLocal store;
+ store.index = index;
+ store.scope = scope;
+ codegen->bytecodeGenerator->addInstruction(store);
+ }
+ return;
+ }
+ case Name: {
+ Context *c = codegen->currentContext();
+ if (c->isStrict) {
+ Instruction::StoreNameStrict store;
+ store.name = nameAsIndex();
+ codegen->bytecodeGenerator->addInstruction(store);
+ } else {
+ Instruction::StoreNameSloppy store;
+ store.name = nameAsIndex();
+ codegen->bytecodeGenerator->addInstruction(store);
+ }
+ } return;
+ case Member:
+ if (codegen->useFastLookups) {
+ Instruction::SetLookup store;
+ store.base = propertyBase.stackSlot();
+ store.index = codegen->registerSetterLookup(propertyNameIndex);
+ codegen->bytecodeGenerator->addInstruction(store);
+ } else {
+ Instruction::StoreProperty store;
+ store.base = propertyBase.stackSlot();
+ store.name = propertyNameIndex;
+ codegen->bytecodeGenerator->addInstruction(store);
+ }
+ return;
+ case Subscript: {
+ Instruction::StoreElement store;
+ store.base = elementBase;
+ store.index = elementSubscript.stackSlot();
+ codegen->bytecodeGenerator->addInstruction(store);
+ } return;
+ case QmlScopeObject: {
+ Instruction::StoreScopeObjectProperty store;
+ store.base = qmlBase;
+ store.propertyIndex = qmlCoreIndex;
+ codegen->bytecodeGenerator->addInstruction(store);
+ } return;
+ case QmlContextObject: {
+ Instruction::StoreContextObjectProperty store;
+ store.base = qmlBase;
+ store.propertyIndex = qmlCoreIndex;
+ codegen->bytecodeGenerator->addInstruction(store);
+ } return;
+ case Invalid:
+ case Accumulator:
+ case Const:
+ break;
+ }
+
+ Q_ASSERT(false);
+ Q_UNREACHABLE();
}
-#endif // V4_BOOTSTRAP
+void Codegen::Reference::loadInAccumulator() const
+{
+ switch (type) {
+ case Accumulator:
+ return;
+ case Const: {
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_GCC("-Wmaybe-uninitialized") // the loads below are empty structs.
+ if (constant == Encode::null()) {
+ Instruction::LoadNull load;
+ codegen->bytecodeGenerator->addInstruction(load);
+ } else if (constant == Encode(true)) {
+ Instruction::LoadTrue load;
+ codegen->bytecodeGenerator->addInstruction(load);
+ } else if (constant == Encode(false)) {
+ Instruction::LoadFalse load;
+ codegen->bytecodeGenerator->addInstruction(load);
+ } else if (constant == Encode::undefined()) {
+ Instruction::LoadUndefined load;
+ codegen->bytecodeGenerator->addInstruction(load);
+ } else {
+ Value p = Primitive::fromReturnedValue(constant);
+ if (p.isNumber()) {
+ double d = p.asDouble();
+ int i = static_cast<int>(d);
+ if (d == i && (d != 0 || !std::signbit(d))) {
+ if (!i) {
+ Instruction::LoadZero load;
+ codegen->bytecodeGenerator->addInstruction(load);
+ return;
+ }
+ Instruction::LoadInt load;
+ load.value = Primitive::fromReturnedValue(constant).toInt32();
+ codegen->bytecodeGenerator->addInstruction(load);
+ return;
+ }
+ }
+ Instruction::LoadConst load;
+ load.index = codegen->registerConstant(constant);
+ codegen->bytecodeGenerator->addInstruction(load);
+ }
+QT_WARNING_POP
+ } return;
+ case StackSlot: {
+ Instruction::LoadReg load;
+ load.reg = stackSlot();
+ codegen->bytecodeGenerator->addInstruction(load);
+ } return;
+ case ScopedLocal: {
+ if (!scope) {
+ Instruction::LoadLocal load;
+ load.index = index;
+ codegen->bytecodeGenerator->addInstruction(load);
+ } else {
+ Instruction::LoadScopedLocal load;
+ load.index = index;
+ load.scope = scope;
+ codegen->bytecodeGenerator->addInstruction(load);
+ }
+ return;
+ }
+ case Name:
+ if (global) {
+ // these value properties of the global object are immutable, we we can directly convert them
+ // to their numeric value here
+ if (name == QStringLiteral("undefined")) {
+ Reference::fromConst(codegen, Encode::undefined()).loadInAccumulator();
+ return;
+ } else if (name == QStringLiteral("Infinity")) {
+ Reference::fromConst(codegen, Encode(qInf())).loadInAccumulator();
+ return;
+ } else if (name == QStringLiteral("Nan")) {
+ Reference::fromConst(codegen, Encode(qQNaN())).loadInAccumulator();
+ return;
+ }
+ }
+ if (codegen->useFastLookups && global) {
+ Instruction::LoadGlobalLookup load;
+ load.index = codegen->registerGlobalGetterLookup(nameAsIndex());
+ codegen->bytecodeGenerator->addInstruction(load);
+ } else {
+ Instruction::LoadName load;
+ load.name = nameAsIndex();
+ codegen->bytecodeGenerator->addInstruction(load);
+ }
+ return;
+ case Member:
+ if (codegen->useFastLookups) {
+ if (propertyBase.isAccumulator()) {
+ Instruction::GetLookupA load;
+ load.index = codegen->registerGetterLookup(propertyNameIndex);
+ codegen->bytecodeGenerator->addInstruction(load);
+ } else {
+ Instruction::GetLookup load;
+ load.base = propertyBase.storeOnStack().stackSlot();
+ load.index = codegen->registerGetterLookup(propertyNameIndex);
+ codegen->bytecodeGenerator->addInstruction(load);
+ }
+ } else {
+ if (propertyBase.isAccumulator()) {
+ Instruction::LoadPropertyA load;
+ load.name = propertyNameIndex;
+ codegen->bytecodeGenerator->addInstruction(load);
+ } else {
+ Instruction::LoadProperty load;
+ load.base = propertyBase.storeOnStack().stackSlot();
+ load.name = propertyNameIndex;
+ codegen->bytecodeGenerator->addInstruction(load);
+ }
+ }
+ return;
+ case Subscript: {
+ if (elementSubscript.isAccumulator()) {
+ Instruction::LoadElementA load;
+ load.base = elementBase;
+ codegen->bytecodeGenerator->addInstruction(load);
+ } else if (elementSubscript.isConst()) {
+ Reference::fromConst(codegen, elementSubscript.constantValue()).loadInAccumulator();
+ Instruction::LoadElementA load;
+ load.base = elementBase;
+ codegen->bytecodeGenerator->addInstruction(load);
+ } else {
+ Instruction::LoadElement load;
+ load.base = elementBase;
+ load.index = elementSubscript.storeOnStack().stackSlot();
+ codegen->bytecodeGenerator->addInstruction(load);
+ }
+ } return;
+ case QmlScopeObject: {
+ Instruction::LoadScopeObjectProperty load;
+ load.base = qmlBase;
+ load.propertyIndex = qmlCoreIndex;
+ load.captureRequired = capturePolicy == CaptureAtRuntime;
+ codegen->bytecodeGenerator->addInstruction(load);
+ if (capturePolicy == CaptureAheadOfTime)
+ codegen->_context->scopeObjectPropertyDependencies.insert(qmlCoreIndex, qmlNotifyIndex);
+ } return;
+ case QmlContextObject: {
+ Instruction::LoadContextObjectProperty load;
+ load.base = qmlBase;
+ load.propertyIndex = qmlCoreIndex;
+ load.captureRequired = capturePolicy == CaptureAtRuntime;
+ codegen->bytecodeGenerator->addInstruction(load);
+ if (capturePolicy == CaptureAheadOfTime)
+ codegen->_context->contextObjectPropertyDependencies.insert(qmlCoreIndex, qmlNotifyIndex);
+ } return;
+ case Invalid:
+ break;
+ }
+ Q_ASSERT(false);
+ Q_UNREACHABLE();
+}
diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h
index a08b9c1d68..e52f63e1f4 100644
--- a/src/qml/compiler/qv4codegen_p.h
+++ b/src/qml/compiler/qv4codegen_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQml module of the Qt Toolkit.
@@ -51,295 +51,488 @@
//
#include "private/qv4global_p.h"
-#include "qv4jsir_p.h"
#include <private/qqmljsastvisitor_p.h>
#include <private/qqmljsast_p.h>
#include <private/qqmljsengine_p.h>
+#include <private/qv4instr_moth_p.h>
+#include <private/qv4compiler_p.h>
+#include <private/qv4compilercontext_p.h>
+#include <private/qqmlrefcount_p.h>
#include <QtCore/QStringList>
+#include <QtCore/QDateTime>
#include <QStack>
#ifndef V4_BOOTSTRAP
#include <qqmlerror.h>
#endif
#include <private/qv4util_p.h>
+#include <private/qv4bytecodegenerator_p.h>
QT_BEGIN_NAMESPACE
-namespace QQmlJS {
-namespace AST {
-class UiParameterList;
+using namespace QQmlJS;
+
+namespace QV4 {
+
+namespace Moth {
+struct Instruction;
}
+namespace CompiledData {
+struct CompilationUnit;
+}
+
+namespace Compiler {
+
+struct ControlFlow;
+struct ControlFlowCatch;
+struct ControlFlowFinally;
-class Q_QML_PRIVATE_EXPORT Codegen: protected AST::Visitor
+class Q_QML_PRIVATE_EXPORT Codegen: protected QQmlJS::AST::Visitor
{
+protected:
+ using BytecodeGenerator = QV4::Moth::BytecodeGenerator;
+ using Instruction = QV4::Moth::Instruction;
public:
- Codegen(bool strict);
-
- enum CompilationMode {
- GlobalCode,
- EvalCode,
- FunctionCode,
- QmlBinding // This is almost the same as EvalCode, except:
- // * function declarations are moved to the return address when encountered
- // * return statements are allowed everywhere (like in FunctionCode)
- // * variable declarations are treated as true locals (like in FunctionCode)
- };
+ Codegen(QV4::Compiler::JSUnitGenerator *jsUnitGenerator, bool strict);
+
void generateFromProgram(const QString &fileName,
const QString &finalUrl,
const QString &sourceCode,
AST::Program *ast,
- QV4::IR::Module *module,
- CompilationMode mode = GlobalCode,
- const QStringList &inheritedLocals = QStringList());
- void generateFromFunctionExpression(const QString &fileName,
- const QString &finalUrl,
- const QString &sourceCode,
- AST::FunctionExpression *ast,
- QV4::IR::Module *module);
+ Module *module,
+ CompilationMode mode = GlobalCode);
-protected:
- enum Format { ex, cx, nx };
- struct Result {
- QV4::IR::Expr *code;
- QV4::IR::BasicBlock *iftrue;
- QV4::IR::BasicBlock *iffalse;
- Format format;
- Format requested;
+public:
+ class VolatileMemoryLocationScanner;
+ class VolatileMemoryLocations {
+ friend VolatileMemoryLocationScanner;
+ bool allVolatile = false;
+ QVector<QStringView> specificLocations;
+ public:
+ bool isVolatile(const QStringView &name) {
+ if (allVolatile)
+ return true;
+ return specificLocations.contains(name);
+ }
- explicit Result(Format requested = ex)
- : code(0)
- , iftrue(0)
- , iffalse(0)
- , format(ex)
- , requested(requested) {}
-
- explicit Result(QV4::IR::BasicBlock *iftrue, QV4::IR::BasicBlock *iffalse)
- : code(0)
- , iftrue(iftrue)
- , iffalse(iffalse)
- , format(ex)
- , requested(cx) {}
-
- inline QV4::IR::Expr *operator*() const { Q_ASSERT(format == ex); return code; }
- inline QV4::IR::Expr *operator->() const { Q_ASSERT(format == ex); return code; }
+ void add(const QStringRef &name) { if (!allVolatile) specificLocations.append(name); }
+ void setAllVolatile() { allVolatile = true; }
+ };
+ class RValue {
+ Codegen *codegen;
+ enum Type {
+ Invalid,
+ Accumulator,
+ StackSlot,
+ Const
+ } type;
+ union {
+ Moth::StackSlot theStackSlot;
+ QV4::ReturnedValue constant;
+ };
- bool accept(Format f)
- {
- if (requested == f) {
- format = f;
- return true;
- }
- return false;
+ public:
+ static RValue fromStackSlot(Codegen *codegen, Moth::StackSlot stackSlot) {
+ RValue r;
+ r.codegen = codegen;
+ r.type = StackSlot;
+ r.theStackSlot = stackSlot;
+ return r;
}
+ static RValue fromAccumulator(Codegen *codegen) {
+ RValue r;
+ r.codegen = codegen;
+ r.type = Accumulator;
+ return r;
+ }
+ static RValue fromConst(Codegen *codegen, QV4::ReturnedValue value) {
+ RValue r;
+ r.codegen = codegen;
+ r.type = Const;
+ r.constant = value;
+ return r;
+ }
+
+ bool operator==(const RValue &other) const;
+
+ bool isValid() const { return type != Invalid; }
+ bool isAccumulator() const { return type == Accumulator; }
+ bool isStackSlot() const { return type == StackSlot; }
+ bool isConst() const { return type == Const; }
+
+ Moth::StackSlot stackSlot() const {
+ Q_ASSERT(isStackSlot());
+ return theStackSlot;
+ }
+
+ QV4::ReturnedValue constantValue() const {
+ Q_ASSERT(isConst());
+ return constant;
+ }
+
+ Q_REQUIRED_RESULT RValue storeOnStack() const;
};
+ struct Reference {
+ enum Type {
+ Invalid,
+ Accumulator,
+ StackSlot,
+ ScopedLocal,
+ Name,
+ Member,
+ Subscript,
+ QmlScopeObject,
+ QmlContextObject,
+ LastLValue = QmlContextObject,
+ Const
+ } type = Invalid;
+
+ bool isLValue() const { return !isReadonly; }
+
+ Reference(Codegen *cg, Type type = Invalid) : type(type), codegen(cg) {}
+ Reference()
+ : type(Invalid)
+ , codegen(nullptr)
+ {}
+ Reference(const Reference &other);
- struct Environment {
- Environment *parent;
+ Reference &operator =(const Reference &other);
- enum MemberType {
- UndefinedMember,
- VariableDefinition,
- VariableDeclaration,
- FunctionDefinition
- };
- struct Member {
- MemberType type;
- int index;
- AST::FunctionExpression *function;
+ bool operator==(const Reference &other) const;
+
+ bool isValid() const { return type != Invalid; }
+ bool loadTriggersSideEffect() const {
+ switch (type) {
+ case Name:
+ case Member:
+ case Subscript:
+ return true;
+ default:
+ return false;
+ }
+ }
+ bool isConst() const { return type == Const; }
+ bool isAccumulator() const { return type == Accumulator; }
+ bool isStackSlot() const { return type == StackSlot; }
+ bool isRegister() const {
+ return isStackSlot();
+ }
+
+ enum PropertyCapturePolicy {
+ /*
+ We're reading a property from the scope or context object, but it's a CONSTANT property,
+ so we don't need to register a dependency at all.
+ */
+ DontCapture,
+ /*
+ We're reading the property of a QObject, and we know that it's the
+ scope object or context object, which we know very well. Instead of registering a
+ property capture every time, we can do that ahead of time and then register all those
+ captures in one shot in registerQmlDependencies().
+ */
+ CaptureAheadOfTime,
+ /*
+ We're reading the property of a QObject, and we're not quite sure where
+ the QObject comes from or what it is. So, when reading that property at run-time,
+ make sure that we capture where we read that property so that if it changes we can
+ re-evaluate the entire expression.
+ */
+ CaptureAtRuntime
};
- typedef QMap<QString, Member> MemberMap;
-
- MemberMap members;
- AST::FormalParameterList *formals;
- int maxNumberOfArguments;
- bool hasDirectEval;
- bool hasNestedFunctions;
- bool isStrict;
- bool isNamedFunctionExpression;
- bool usesThis;
- enum UsesArgumentsObject {
- ArgumentsObjectUnknown,
- ArgumentsObjectNotUsed,
- ArgumentsObjectUsed
+
+ static Reference fromAccumulator(Codegen *cg) {
+ return Reference(cg, Accumulator);
+ }
+ static Reference fromStackSlot(Codegen *cg, int tempIndex = -1, bool isLocal = false) {
+ Reference r(cg, StackSlot);
+ if (tempIndex == -1)
+ tempIndex = cg->bytecodeGenerator->newRegister();
+ r.theStackSlot = Moth::StackSlot::createRegister(tempIndex);
+ r.stackSlotIsLocalOrArgument = isLocal;
+ return r;
+ }
+ static Reference fromArgument(Codegen *cg, int index, bool isVolatile) {
+ Reference r(cg, StackSlot);
+ r.theStackSlot = Moth::StackSlot::createRegister(index + sizeof(CallData)/sizeof(Value) - 1);
+ r.stackSlotIsLocalOrArgument = true;
+ r.isVolatile = isVolatile;
+ return r;
+ }
+ static Reference fromScopedLocal(Codegen *cg, int index, int scope) {
+ Reference r(cg, ScopedLocal);
+ r.index = index;
+ r.scope = scope;
+ return r;
+ }
+ static Reference fromName(Codegen *cg, const QString &name) {
+ Reference r(cg, Name);
+ r.name = name;
+ return r;
+ }
+ static Reference fromMember(const Reference &baseRef, const QString &name) {
+ Reference r(baseRef.codegen, Member);
+ r.propertyBase = baseRef.asRValue();
+ r.propertyNameIndex = r.codegen->registerString(name);
+ return r;
+ }
+ static Reference fromSubscript(const Reference &baseRef, const Reference &subscript) {
+ Q_ASSERT(baseRef.isStackSlot());
+ Reference r(baseRef.codegen, Subscript);
+ r.elementBase = baseRef.stackSlot();
+ r.elementSubscript = subscript.asRValue();
+ return r;
+ }
+ static Reference fromConst(Codegen *cg, QV4::ReturnedValue constant) {
+ Reference r(cg, Const);
+ r.constant = constant;
+ r.isReadonly = true;
+ return r;
+ }
+ static Reference fromQmlScopeObject(const Reference &base, qint16 coreIndex, qint16 notifyIndex, PropertyCapturePolicy capturePolicy) {
+ Reference r(base.codegen, QmlScopeObject);
+ r.qmlBase = base.storeOnStack().stackSlot();
+ r.qmlCoreIndex = coreIndex;
+ r.qmlNotifyIndex = notifyIndex;
+ r.capturePolicy = capturePolicy;
+ return r;
+ }
+ static Reference fromQmlContextObject(const Reference &base, qint16 coreIndex, qint16 notifyIndex, PropertyCapturePolicy capturePolicy) {
+ Reference r(base.codegen, QmlContextObject);
+ r.qmlBase = base.storeOnStack().stackSlot();
+ r.qmlCoreIndex = coreIndex;
+ r.qmlNotifyIndex = notifyIndex;
+ r.capturePolicy = capturePolicy;
+ return r;
+ }
+ static Reference fromThis(Codegen *cg) {
+ Reference r = fromStackSlot(cg, CallData::This);
+ r.isReadonly = true;
+ return r;
+ }
+
+ RValue asRValue() const;
+ Reference asLValue() const;
+
+ Q_REQUIRED_RESULT static Reference storeConstOnStack(Codegen *cg, QV4::ReturnedValue constant)
+ { return Reference::fromConst(cg, constant).storeOnStack(); }
+
+ static void storeConstOnStack(Codegen *cg, QV4::ReturnedValue constant, int stackSlot)
+ { Reference::fromConst(cg, constant).storeOnStack(stackSlot); }
+
+ Q_REQUIRED_RESULT Reference storeOnStack() const;
+ void storeOnStack(int tempIndex) const;
+ Q_REQUIRED_RESULT Reference storeRetainAccumulator() const;
+ Reference storeConsumeAccumulator() const;
+
+ bool storeWipesAccumulator() const;
+ void loadInAccumulator() const;
+
+ int nameAsIndex() const {
+ Q_ASSERT(type == Name);
+ return codegen->registerString(name);
+ }
+
+ Moth::StackSlot stackSlot() const {
+ if (Q_UNLIKELY(!isStackSlot()))
+ Q_UNREACHABLE();
+ return theStackSlot;
+ }
+
+ union {
+ Moth::StackSlot theStackSlot;
+ QV4::ReturnedValue constant;
+ struct { // Scoped arguments/Local
+ int index;
+ int scope;
+ };
+ struct {
+ RValue propertyBase;
+ int propertyNameIndex;
+ };
+ struct {
+ Moth::StackSlot elementBase;
+ RValue elementSubscript;
+ };
+ struct { // QML scope/context object case
+ Moth::StackSlot qmlBase;
+ qint16 qmlCoreIndex;
+ qint16 qmlNotifyIndex;
+ PropertyCapturePolicy capturePolicy;
+ };
};
+ QString name;
+ mutable bool isArgOrEval = false;
+ bool isReadonly = false;
+ bool stackSlotIsLocalOrArgument = false;
+ bool isVolatile = false;
+ bool global = false;
+ Codegen *codegen;
+
+ private:
+ void storeAccumulator() const;
+ Reference doStoreOnStack(int tempIndex) const;
+ };
- UsesArgumentsObject usesArgumentsObject;
-
- CompilationMode compilationMode;
-
- Environment(Environment *parent, CompilationMode mode)
- : parent(parent)
- , formals(0)
- , maxNumberOfArguments(0)
- , hasDirectEval(false)
- , hasNestedFunctions(false)
- , isStrict(false)
- , isNamedFunctionExpression(false)
- , usesThis(false)
- , usesArgumentsObject(ArgumentsObjectUnknown)
- , compilationMode(mode)
- {
- if (parent && parent->isStrict)
- isStrict = true;
+ struct RegisterScope {
+ RegisterScope(Codegen *cg)
+ : generator(cg->bytecodeGenerator),
+ regCountForScope(generator->currentReg) {}
+ ~RegisterScope() {
+ generator->currentReg = regCountForScope;
}
+ BytecodeGenerator *generator;
+ int regCountForScope;
+ };
+
+ struct ObjectPropertyValue {
+ ObjectPropertyValue()
+ : getter(-1)
+ , setter(-1)
+ , keyAsIndex(UINT_MAX)
+ {}
+
+ Reference rvalue;
+ int getter; // index in _module->functions or -1 if not set
+ int setter;
+ uint keyAsIndex;
- int findMember(const QString &name) const
+ bool hasGetter() const { return getter >= 0; }
+ bool hasSetter() const { return setter >= 0; }
+ };
+protected:
+
+ enum Format { ex, cx, nx };
+ class Result {
+ Reference _result;
+
+ const BytecodeGenerator::Label *_iftrue;
+ const BytecodeGenerator::Label *_iffalse;
+ Format _format;
+ Format _requested;
+ bool _trueBlockFollowsCondition = false;
+
+ public:
+ explicit Result(const Reference &lrvalue)
+ : _result(lrvalue)
+ , _iftrue(nullptr)
+ , _iffalse(nullptr)
+ , _format(ex)
+ , _requested(ex)
{
- MemberMap::const_iterator it = members.find(name);
- if (it == members.end())
- return -1;
- Q_ASSERT((*it).index != -1 || !parent);
- return (*it).index;
}
- bool lookupMember(const QString &name, Environment **scope, int *index, int *distance)
+ explicit Result(Format requested = ex)
+ : _iftrue(0)
+ , _iffalse(0)
+ , _format(ex)
+ , _requested(requested) {}
+
+ explicit Result(const BytecodeGenerator::Label *iftrue,
+ const BytecodeGenerator::Label *iffalse,
+ bool trueBlockFollowsCondition)
+ : _iftrue(iftrue)
+ , _iffalse(iffalse)
+ , _format(ex)
+ , _requested(cx)
+ , _trueBlockFollowsCondition(trueBlockFollowsCondition)
{
- Environment *it = this;
- *distance = 0;
- for (; it; it = it->parent, ++(*distance)) {
- int idx = it->findMember(name);
- if (idx != -1) {
- *scope = it;
- *index = idx;
- return true;
- }
- }
- return false;
+ Q_ASSERT(iftrue);
+ Q_ASSERT(iffalse);
+ }
+
+ const BytecodeGenerator::Label *iftrue() const {
+ Q_ASSERT(_requested == cx);
+ return _iftrue;
+ }
+
+ const BytecodeGenerator::Label *iffalse() const {
+ Q_ASSERT(_requested == cx);
+ return _iffalse;
+ }
+
+ Format format() const {
+ return _format;
}
- void enter(const QString &name, MemberType type, AST::FunctionExpression *function = 0)
+ bool accept(Format f)
{
- if (! name.isEmpty()) {
- if (type != FunctionDefinition) {
- for (AST::FormalParameterList *it = formals; it; it = it->next)
- if (it->name == name)
- return;
- }
- MemberMap::iterator it = members.find(name);
- if (it == members.end()) {
- Member m;
- m.index = -1;
- m.type = type;
- m.function = function;
- members.insert(name, m);
- } else {
- if ((*it).type <= type) {
- (*it).type = type;
- (*it).function = function;
- }
- }
+ if (_requested == f) {
+ _format = f;
+ return true;
}
+ return false;
}
- };
- struct TempScope {
- TempScope(QV4::IR::Function *f)
- : function(f),
- tempCountForScope(f->currentTemp) {}
- ~TempScope() {
- function->currentTemp = tempCountForScope;
+ bool trueBlockFollowsCondition() const {
+ return _trueBlockFollowsCondition;
}
- QV4::IR::Function *function;
- int tempCountForScope;
- };
- Environment *newEnvironment(AST::Node *node, Environment *parent, CompilationMode compilationMode)
- {
- Environment *env = new Environment(parent, compilationMode);
- _envMap.insert(node, env);
- return env;
- }
+ const Reference &result() const {
+ return _result;
+ }
- struct UiMember {
+ void setResult(const Reference &result) {
+ _result = result;
+ }
};
- struct ScopeAndFinally {
- enum ScopeType {
- WithScope,
- TryScope,
- CatchScope
- };
+ void enterContext(AST::Node *node);
+ int leaveContext();
- ScopeAndFinally *parent;
- AST::Finally *finally;
- ScopeType type;
+ void leaveLoop();
- ScopeAndFinally(ScopeAndFinally *parent, ScopeType t = WithScope) : parent(parent), finally(0), type(t) {}
- ScopeAndFinally(ScopeAndFinally *parent, AST::Finally *finally)
- : parent(parent), finally(finally), type(TryScope)
- {}
+ enum UnaryOperation {
+ UPlus,
+ UMinus,
+ PreIncrement,
+ PreDecrement,
+ PostIncrement,
+ PostDecrement,
+ Not,
+ Compl
};
- struct Loop {
- AST::LabelledStatement *labelledStatement;
- AST::Statement *node;
- QV4::IR::BasicBlock *breakBlock;
- QV4::IR::BasicBlock *continueBlock;
- Loop *parent;
- ScopeAndFinally *scopeAndFinally;
-
- Loop(AST::Statement *node, QV4::IR::BasicBlock *breakBlock, QV4::IR::BasicBlock *continueBlock, Loop *parent)
- : labelledStatement(0), node(node), breakBlock(breakBlock), continueBlock(continueBlock), parent(parent) {}
- };
+ Reference unop(UnaryOperation op, const Reference &expr);
- void enterEnvironment(AST::Node *node);
- void leaveEnvironment();
+ void addCJump();
- void enterLoop(AST::Statement *node, QV4::IR::BasicBlock *breakBlock, QV4::IR::BasicBlock *continueBlock);
- void leaveLoop();
- QV4::IR::BasicBlock *exceptionHandler() const
- {
- if (_exceptionHandlers.isEmpty())
- return 0;
- return _exceptionHandlers.top();
- }
- void pushExceptionHandler(QV4::IR::BasicBlock *handler)
- {
- handler->setExceptionHandler(true);
- _exceptionHandlers.push(handler);
+ int registerString(const QString &name) {
+ return jsUnitGenerator->registerString(name);
}
- void popExceptionHandler()
- {
- Q_ASSERT(!_exceptionHandlers.isEmpty());
- _exceptionHandlers.pop();
- }
-
- QV4::IR::Expr *member(QV4::IR::Expr *base, const QString *name);
- QV4::IR::Expr *argument(QV4::IR::Expr *expr);
- QV4::IR::Expr *reference(QV4::IR::Expr *expr);
- QV4::IR::Expr *unop(QV4::IR::AluOp op, QV4::IR::Expr *expr, const AST::SourceLocation &loc = AST::SourceLocation());
- QV4::IR::Expr *binop(QV4::IR::AluOp op, QV4::IR::Expr *left, QV4::IR::Expr *right, const AST::SourceLocation &loc = AST::SourceLocation());
- QV4::IR::Expr *call(QV4::IR::Expr *base, QV4::IR::ExprList *args);
- QV4::IR::Stmt *move(QV4::IR::Expr *target, QV4::IR::Expr *source, QV4::IR::AluOp op = QV4::IR::OpInvalid);
- QV4::IR::Stmt *cjump(QV4::IR::Expr *cond, QV4::IR::BasicBlock *iftrue, QV4::IR::BasicBlock *iffalse);
+ int registerConstant(QV4::ReturnedValue v) { return jsUnitGenerator->registerConstant(v); }
+ int registerGetterLookup(int nameIndex) { return jsUnitGenerator->registerGetterLookup(nameIndex); }
+ int registerSetterLookup(int nameIndex) { return jsUnitGenerator->registerSetterLookup(nameIndex); }
+ int registerGlobalGetterLookup(int nameIndex) { return jsUnitGenerator->registerGlobalGetterLookup(nameIndex); }
// Returns index in _module->functions
- int defineFunction(const QString &name, AST::Node *ast,
- AST::FormalParameterList *formals,
- AST::SourceElements *body,
- const QStringList &inheritedLocals = QStringList());
-
- void unwindException(ScopeAndFinally *outest);
+ virtual int defineFunction(const QString &name, AST::Node *ast,
+ AST::FormalParameterList *formals,
+ AST::SourceElements *body);
void statement(AST::Statement *ast);
void statement(AST::ExpressionNode *ast);
- void condition(AST::ExpressionNode *ast, QV4::IR::BasicBlock *iftrue, QV4::IR::BasicBlock *iffalse);
- Result expression(AST::ExpressionNode *ast);
+ void condition(AST::ExpressionNode *ast, const BytecodeGenerator::Label *iftrue,
+ const BytecodeGenerator::Label *iffalse,
+ bool trueBlockFollowsCondition);
+ Reference expression(AST::ExpressionNode *ast);
Result sourceElement(AST::SourceElement *ast);
- UiMember uiObjectMember(AST::UiObjectMember *ast);
void accept(AST::Node *node);
void functionBody(AST::FunctionBody *ast);
void program(AST::Program *ast);
void sourceElements(AST::SourceElements *ast);
+ void statementList(AST::StatementList *ast);
void variableDeclaration(AST::VariableDeclaration *ast);
void variableDeclarationList(AST::VariableDeclarationList *ast);
- QV4::IR::Expr *identifier(const QString &name, int line = 0, int col = 0);
+ Reference referenceForName(const QString &name, bool lhs);
+
+ void loadClosure(int index);
+
// Hook provided to implement QML lookup semantics
- virtual QV4::IR::Expr *fallbackNameLookup(const QString &name, int line, int col);
+ virtual Reference fallbackNameLookup(const QString &name);
virtual void beginFunctionBodyHook() {}
// nodes
@@ -441,7 +634,7 @@ protected:
bool visit(AST::UiScriptBinding *ast) override;
bool visit(AST::UiSourceElement *ast) override;
- bool throwSyntaxErrorOnEvalOrArgumentsInStrictMode(QV4::IR::Expr* expr, const AST::SourceLocation &loc);
+ bool throwSyntaxErrorOnEvalOrArgumentsInStrictMode(const Reference &r, const AST::SourceLocation &loc);
virtual void throwSyntaxError(const AST::SourceLocation &loc, const QString &detail);
virtual void throwReferenceError(const AST::SourceLocation &loc, const QString &detail);
@@ -451,117 +644,47 @@ public:
QList<QQmlError> qmlErrors() const;
#endif
+ Reference binopHelper(QSOperator::Op oper, Reference &left, Reference &right);
+ Reference jumpBinop(QSOperator::Op oper, Reference &left, Reference &right);
+ struct Arguments { int argc; int argv; };
+ Arguments pushArgs(AST::ArgumentList *args);
+
+ void setUseFastLookups(bool b) { useFastLookups = b; }
+
+ void handleTryCatch(AST::TryStatement *ast);
+ void handleTryFinally(AST::TryStatement *ast);
+
+ QQmlRefPointer<QV4::CompiledData::CompilationUnit> generateCompilationUnit(bool generateUnitData = true);
+ static QQmlRefPointer<QV4::CompiledData::CompilationUnit> createUnitForLoading();
+
+ Context *currentContext() const { return _context; }
+
protected:
+ friend class ScanFunctions;
+ friend struct ControlFlow;
+ friend struct ControlFlowCatch;
+ friend struct ControlFlowFinally;
Result _expr;
- QString _property;
- UiMember _uiMember;
- QV4::IR::Module *_module;
- QV4::IR::Function *_function;
- QV4::IR::BasicBlock *_block;
- QV4::IR::BasicBlock *_exitBlock;
- unsigned _returnAddress;
- Environment *_env;
- Loop *_loop;
+ VolatileMemoryLocations _volataleMemoryLocations;
+ Module *_module;
+ int _returnAddress;
+ Context *_context;
AST::LabelledStatement *_labelledStatement;
- ScopeAndFinally *_scopeAndFinally;
- QHash<AST::Node *, Environment *> _envMap;
- QHash<AST::FunctionExpression *, int> _functionMap;
- QStack<QV4::IR::BasicBlock *> _exceptionHandlers;
+ QV4::Compiler::JSUnitGenerator *jsUnitGenerator;
+ BytecodeGenerator *bytecodeGenerator = 0;
bool _strictMode;
+ bool useFastLookups = true;
+ bool requiresReturnValue = false;
bool _fileNameIsUrl;
bool hasError;
QList<QQmlJS::DiagnosticMessage> _errors;
- class ScanFunctions: protected Visitor
- {
- typedef QV4::TemporaryAssignment<bool> TemporaryBoolAssignment;
- public:
- ScanFunctions(Codegen *cg, const QString &sourceCode, CompilationMode defaultProgramMode);
- void operator()(AST::Node *node);
-
- void enterEnvironment(AST::Node *node, CompilationMode compilationMode);
- void leaveEnvironment();
-
- void enterQmlScope(AST::Node *ast, const QString &name)
- { enterFunction(ast, name, /*formals*/0, /*body*/0, /*expr*/0, /*isExpression*/false); }
-
- void enterQmlFunction(AST::FunctionDeclaration *ast)
- { enterFunction(ast, false, false); }
-
- protected:
- using Visitor::visit;
- using Visitor::endVisit;
-
- void checkDirectivePrologue(AST::SourceElements *ast);
-
- void checkName(const QStringRef &name, const AST::SourceLocation &loc);
- void checkForArguments(AST::FormalParameterList *parameters);
-
- bool visit(AST::Program *ast) override;
- void endVisit(AST::Program *) override;
-
- bool visit(AST::CallExpression *ast) override;
- bool visit(AST::NewMemberExpression *ast) override;
- bool visit(AST::ArrayLiteral *ast) override;
- bool visit(AST::VariableDeclaration *ast) override;
- bool visit(AST::IdentifierExpression *ast) override;
- bool visit(AST::ExpressionStatement *ast) override;
- bool visit(AST::FunctionExpression *ast) override;
-
- void enterFunction(AST::FunctionExpression *ast, bool enterName, bool isExpression = true);
-
- void endVisit(AST::FunctionExpression *) override;
-
- bool visit(AST::ObjectLiteral *ast) override;
-
- bool visit(AST::PropertyGetterSetter *ast) override;
- void endVisit(AST::PropertyGetterSetter *) override;
-
- bool visit(AST::FunctionDeclaration *ast) override;
- void endVisit(AST::FunctionDeclaration *) override;
-
- bool visit(AST::WithStatement *ast) override;
-
- bool visit(AST::DoWhileStatement *ast) override;
- bool visit(AST::ForStatement *ast) override;
- bool visit(AST::LocalForStatement *ast) override;
- bool visit(AST::ForEachStatement *ast) override;
- bool visit(AST::LocalForEachStatement *ast) override;
- bool visit(AST::ThisExpression *ast) override;
-
- bool visit(AST::Block *ast) override;
-
- protected:
- void enterFunction(AST::Node *ast, const QString &name, AST::FormalParameterList *formals, AST::FunctionBody *body, AST::FunctionExpression *expr, bool isExpression);
-
- // fields:
- Codegen *_cg;
- const QString _sourceCode;
- Environment *_env;
- QStack<Environment *> _envStack;
-
- bool _allowFuncDecls;
- CompilationMode defaultProgramMode;
- };
-
-};
-
-#ifndef V4_BOOTSTRAP
-class RuntimeCodegen : public Codegen
-{
-public:
- RuntimeCodegen(QV4::ExecutionEngine *engine, bool strict)
- : Codegen(strict)
- , engine(engine)
- {}
-
- void throwSyntaxError(const AST::SourceLocation &loc, const QString &detail) override;
- void throwReferenceError(const AST::SourceLocation &loc, const QString &detail) override;
private:
- QV4::ExecutionEngine *engine;
+ VolatileMemoryLocations scanVolatileMemoryLocations(AST::Node *ast) const;
};
-#endif // V4_BOOTSTRAP
+
+}
}
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index 7735cd03d8..86200d7df7 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -38,7 +38,6 @@
****************************************************************************/
#include "qv4compileddata_p.h"
-#include "qv4jsir_p.h"
#include <private/qv4value_p.h>
#ifndef V4_BOOTSTRAP
#include <private/qv4engine_p.h>
@@ -50,6 +49,7 @@
#include <private/qqmlpropertycache_p.h>
#include <private/qqmltypeloader_p.h>
#include <private/qqmlengine_p.h>
+#include <private/qv4vme_moth_p.h>
#include "qv4compilationunitmapper_p.h"
#include <QQmlPropertyMap>
#include <QDateTime>
@@ -84,8 +84,10 @@ static QString cacheFilePath(const QUrl &url)
{
const QString localSourcePath = QQmlFile::urlToLocalFileOrQrc(url);
const QString localCachePath = localSourcePath + QLatin1Char('c');
+#ifndef Q_OS_ANDROID
if (QFile::exists(localCachePath) || QFileInfo(QFileInfo(localSourcePath).dir().absolutePath()).isWritable())
return localCachePath;
+#endif
QCryptographicHash fileNameHash(QCryptographicHash::Sha1);
fileNameHash.addData(localSourcePath.toUtf8());
QString directory = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + QLatin1String("/qmlcache/");
@@ -94,23 +96,11 @@ static QString cacheFilePath(const QUrl &url)
}
#endif
-#ifndef V4_BOOTSTRAP
-CompilationUnit::CompilationUnit()
- : data(0)
- , engine(0)
- , qmlEngine(0)
- , runtimeLookups(0)
- , runtimeRegularExpressions(0)
- , runtimeClasses(0)
- , constants(nullptr)
- , totalBindingsCount(0)
- , totalParserStatusCount(0)
- , totalObjectCount(0)
- , metaTypeId(-1)
- , listMetaTypeId(-1)
- , isRegisteredWithEngine(false)
+CompilationUnit::CompilationUnit(const Unit *unitData)
+ : data(unitData)
{}
+#ifndef V4_BOOTSTRAP
CompilationUnit::~CompilationUnit()
{
unlink();
@@ -163,18 +153,7 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
l->setter = QV4::Lookup::setterGeneric;
else if (type == CompiledData::Lookup::Type_GlobalGetter)
l->globalGetter = QV4::Lookup::globalGetterGeneric;
- else if (type == CompiledData::Lookup::Type_IndexedGetter)
- l->indexedGetter = QV4::Lookup::indexedGetterGeneric;
- else if (type == CompiledData::Lookup::Type_IndexedSetter)
- l->indexedSetter = QV4::Lookup::indexedSetterGeneric;
-
- for (int j = 0; j < QV4::Lookup::Size; ++j)
- l->classList[j] = 0;
- l->level = -1;
- l->index = UINT_MAX;
l->nameIndex = compiledLookups[i].nameIndex;
- if (type == CompiledData::Lookup::Type_IndexedGetter || type == CompiledData::Lookup::Type_IndexedSetter)
- l->engine = engine;
}
}
@@ -193,7 +172,7 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
Value *bigEndianConstants = new Value[data->constantTableSize];
- const LEUInt64 *littleEndianConstants = data->constants();
+ const quint64_le *littleEndianConstants = data->constants();
for (uint i = 0; i < data->constantTableSize; ++i)
bigEndianConstants[i] = Value::fromReturnedValue(littleEndianConstants[i]);
constants = bigEndianConstants;
@@ -203,6 +182,19 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
linkBackendToEngine(engine);
+ static const bool showCode = qEnvironmentVariableIsSet("QV4_SHOW_BYTECODE");
+ if (showCode) {
+ qDebug() << "=== Constant table";
+ Moth::dumpConstantTable(constants, data->constantTableSize);
+ qDebug() << "=== String table";
+ for (uint i = 0; i < data->stringTableSize; ++i)
+ qDebug() << " " << i << ":" << runtimeStrings[i]->toQString();
+ qDebug() << "=== Closure table";
+ for (uint i = 0; i < data->functionTableSize; ++i)
+ qDebug() << " " << i << ":" << runtimeFunctions[i]->name()->toQString();
+ qDebug() << "root function at index " << (data->indexOfRootFunction != -1 ? data->indexOfRootFunction : 0);
+ }
+
if (data->indexOfRootFunction != -1)
return runtimeFunctions[data->indexOfRootFunction];
else
@@ -251,32 +243,24 @@ void CompilationUnit::unlink()
#endif
}
-void CompilationUnit::markObjects(QV4::ExecutionEngine *e)
+void CompilationUnit::markObjects(QV4::MarkStack *markStack)
{
for (uint i = 0; i < data->stringTableSize; ++i)
if (runtimeStrings[i])
- runtimeStrings[i]->mark(e);
+ runtimeStrings[i]->mark(markStack);
if (runtimeRegularExpressions) {
for (uint i = 0; i < data->regexpTableSize; ++i)
- runtimeRegularExpressions[i].mark(e);
+ runtimeRegularExpressions[i].mark(markStack);
}
}
-void CompilationUnit::destroy()
-{
- if (qmlEngine)
- QQmlEnginePrivate::deleteInEngineThread(qmlEngine, this);
- else
- delete this;
-}
-
-IdentifierHash<int> CompilationUnit::namedObjectsPerComponent(int componentObjectIndex)
+IdentifierHash CompilationUnit::namedObjectsPerComponent(int componentObjectIndex)
{
auto it = namedObjectsPerComponentCache.find(componentObjectIndex);
if (it == namedObjectsPerComponentCache.end()) {
- IdentifierHash<int> namedObjectCache(engine);
+ IdentifierHash namedObjectCache(engine);
const CompiledData::Object *component = data->objectAt(componentObjectIndex);
- const LEUInt32 *namedObjectIndexPtr = component->namedObjectsInComponentTable();
+ const quint32_le *namedObjectIndexPtr = component->namedObjectsInComponentTable();
for (quint32 i = 0; i < component->nNamedObjectsInComponent; ++i, ++namedObjectIndexPtr) {
const CompiledData::Object *namedObject = data->objectAt(*namedObjectIndexPtr);
namedObjectCache.add(runtimeStrings[namedObject->idNameIndex], namedObject->id);
@@ -351,7 +335,7 @@ bool CompilationUnit::verifyChecksum(const DependentTypesHasher &dependencyHashe
sizeof(data->dependencyMD5Checksum)) == 0;
}
-bool CompilationUnit::loadFromDisk(const QUrl &url, const QDateTime &sourceTimeStamp, EvalISelFactory *iselFactory, QString *errorString)
+bool CompilationUnit::loadFromDisk(const QUrl &url, const QDateTime &sourceTimeStamp, QString *errorString)
{
if (!QQmlFile::isLocalFile(url)) {
*errorString = QStringLiteral("File has to be a local file.");
@@ -373,37 +357,19 @@ bool CompilationUnit::loadFromDisk(const QUrl &url, const QDateTime &sourceTimeS
return false;
}
- {
- const QString foundArchitecture = stringAt(data->architectureIndex);
- const QString expectedArchitecture = QSysInfo::buildAbi();
- if (foundArchitecture != expectedArchitecture) {
- *errorString = QString::fromUtf8("Architecture mismatch. Found %1 expected %2").arg(foundArchitecture).arg(expectedArchitecture);
- return false;
- }
- }
-
- {
- const QString foundCodeGenerator = stringAt(data->codeGeneratorIndex);
- const QString expectedCodeGenerator = iselFactory->codeGeneratorName;
- if (foundCodeGenerator != expectedCodeGenerator) {
- *errorString = QString::fromUtf8("Code generator mismatch. Found code generated by %1 but expected %2").arg(foundCodeGenerator).arg(expectedCodeGenerator);
- return false;
- }
- }
-
- if (!memoryMapCode(errorString))
- return false;
-
dataPtrChange.commit();
free(const_cast<Unit*>(oldDataPtr));
backingFile.reset(cacheFile.take());
return true;
}
-bool CompilationUnit::memoryMapCode(QString *errorString)
+void CompilationUnit::linkBackendToEngine(ExecutionEngine *engine)
{
- *errorString = QStringLiteral("Missing code mapping backend");
- return false;
+ runtimeFunctions.resize(data->functionTableSize);
+ for (int i = 0 ;i < runtimeFunctions.size(); ++i) {
+ const QV4::CompiledData::Function *compiledFunction = data->functionAt(i);
+ runtimeFunctions[i] = new QV4::Function(engine, this, compiledFunction, &Moth::VME::exec);
+ }
}
#endif // V4_BOOTSTRAP
@@ -445,17 +411,12 @@ bool CompilationUnit::saveToDisk(const QUrl &unitUrl, QString *errorString)
memcpy(&unitPtr, &dataPtr, sizeof(unitPtr));
unitPtr->flags |= Unit::StaticData;
- prepareCodeOffsetsForDiskStorage(unitPtr);
-
qint64 headerWritten = cacheFile.write(modifiedUnit);
if (headerWritten != modifiedUnit.size()) {
*errorString = cacheFile.errorString();
return false;
}
- if (!saveCodeToDisk(&cacheFile, unitPtr, errorString))
- return false;
-
if (!cacheFile.commit()) {
*errorString = cacheFile.errorString();
return false;
@@ -469,19 +430,6 @@ bool CompilationUnit::saveToDisk(const QUrl &unitUrl, QString *errorString)
#endif // QT_CONFIG(temporaryfile)
}
-void CompilationUnit::prepareCodeOffsetsForDiskStorage(Unit *unit)
-{
- Q_UNUSED(unit);
-}
-
-bool CompilationUnit::saveCodeToDisk(QIODevice *device, const Unit *unit, QString *errorString)
-{
- Q_UNUSED(device);
- Q_UNUSED(unit);
- *errorString = QStringLiteral("Saving code to disk is not supported in this configuration");
- return false;
-}
-
Unit *CompilationUnit::createUnitData(QmlIR::Document *irDocument)
{
if (!irDocument->javaScriptCompilationUnit->data)
@@ -777,6 +725,17 @@ bool ResolvedTypeReferenceMap::addToHash(QCryptographicHash *hash, QQmlEngine *e
#endif
+void CompilationUnit::destroy()
+{
+#if !defined(V4_BOOTSTRAP)
+ if (qmlEngine)
+ QQmlEnginePrivate::deleteInEngineThread(qmlEngine, this);
+ else
+#endif
+ delete this;
+}
+
+
void Unit::generateChecksum()
{
#ifndef V4_BOOTSTRAP
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index 188a571394..2c0320f7f1 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -62,7 +62,7 @@
#include <private/qqmlnullablevalue_p.h>
#include <private/qv4identifier_p.h>
#include <private/qflagpointer_p.h>
-#include <private/qjson_p.h>
+#include <private/qendian_p.h>
#ifndef V4_BOOTSTRAP
#include <private/qqmltypenamecache_p.h>
#include <private/qqmlpropertycache_p.h>
@@ -72,7 +72,7 @@
QT_BEGIN_NAMESPACE
// Bump this whenever the compiler data structures change in an incompatible way.
-#define QV4_DATA_STRUCTURE_VERSION 0x14
+#define QV4_DATA_STRUCTURE_VERSION 0x17
class QIODevice;
class QQmlPropertyCache;
@@ -87,9 +87,6 @@ struct Document;
}
namespace QV4 {
-namespace IR {
-struct Function;
-}
struct Function;
class EvalISelFactory;
@@ -97,13 +94,6 @@ class CompilationUnitMapper;
namespace CompiledData {
-typedef QJsonPrivate::q_littleendian<qint16> LEInt16;
-typedef QJsonPrivate::q_littleendian<quint16> LEUInt16;
-typedef QJsonPrivate::q_littleendian<quint32> LEUInt32;
-typedef QJsonPrivate::q_littleendian<qint32> LEInt32;
-typedef QJsonPrivate::q_littleendian<quint64> LEUInt64;
-typedef QJsonPrivate::q_littleendian<qint64> LEInt64;
-
struct String;
struct Function;
struct Lookup;
@@ -126,11 +116,12 @@ struct TableIterator
struct Location
{
union {
- QJsonPrivate::qle_bitfield<0, 20> line;
- QJsonPrivate::qle_bitfield<20, 12> column;
+ quint32 _dummy;
+ quint32_le_bitfield<0, 20> line;
+ quint32_le_bitfield<20, 12> column;
};
- Location() { line.val = 0; column.val = 0; }
+ Location() : _dummy(0) { }
inline bool operator<(const Location &other) const {
return line < other.line ||
@@ -147,11 +138,12 @@ struct RegExp
RegExp_Multiline = 0x04
};
union {
- QJsonPrivate::qle_bitfield<0, 4> flags;
- QJsonPrivate::qle_bitfield<4, 28> stringIndex;
+ quint32 _dummy;
+ quint32_le_bitfield<0, 4> flags;
+ quint32_le_bitfield<4, 28> stringIndex;
};
- RegExp() { flags.val = 0; stringIndex.val = 0; }
+ RegExp() : _dummy(0) { }
};
static_assert(sizeof(RegExp) == 4, "RegExp structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
@@ -160,34 +152,34 @@ struct Lookup
enum Type : unsigned int {
Type_Getter = 0x0,
Type_Setter = 0x1,
- Type_GlobalGetter = 2,
- Type_IndexedGetter = 3,
- Type_IndexedSetter = 4
+ Type_GlobalGetter = 2
};
union {
- QJsonPrivate::qle_bitfield<0, 4> type_and_flags;
- QJsonPrivate::qle_bitfield<4, 28> nameIndex;
+ quint32 _dummy;
+ quint32_le_bitfield<0, 4> type_and_flags;
+ quint32_le_bitfield<4, 28> nameIndex;
};
- Lookup() { type_and_flags.val = 0; nameIndex.val = 0; }
+ Lookup() : _dummy(0) { }
};
static_assert(sizeof(Lookup) == 4, "Lookup structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct JSClassMember
{
union {
- QJsonPrivate::qle_bitfield<0, 31> nameOffset;
- QJsonPrivate::qle_bitfield<31, 1> isAccessor;
+ quint32 _dummy;
+ quint32_le_bitfield<0, 31> nameOffset;
+ quint32_le_bitfield<31, 1> isAccessor;
};
- JSClassMember() { nameOffset = 0; isAccessor = 0; }
+ JSClassMember() : _dummy(0) { }
};
static_assert(sizeof(JSClassMember) == 4, "JSClassMember structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct JSClass
{
- LEUInt32 nMembers;
+ quint32_le nMembers;
// JSClassMember[nMembers]
static int calculateSize(int nMembers) { return (sizeof(JSClass) + nMembers * sizeof(JSClassMember) + 7) & ~7; }
@@ -196,7 +188,7 @@ static_assert(sizeof(JSClass) == 4, "JSClass structure needs to have the expecte
struct String
{
- LEInt32 size;
+ qint32_le size;
// uint16 strdata[]
static int calculateSize(const QString &str) {
@@ -205,6 +197,11 @@ struct String
};
static_assert(sizeof(String) == 4, "String structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
+struct CodeOffsetToLine {
+ quint32_le codeOffset;
+ quint32_le line;
+};
+
// Function is aligned on an 8-byte boundary to make sure there are no bus errors or penalties
// for unaligned access. The ordering of the fields is also from largest to smallest.
struct Function
@@ -213,30 +210,32 @@ struct Function
IsStrict = 0x1,
HasDirectEval = 0x2,
UsesArgumentsObject = 0x4,
- IsNamedExpression = 0x8,
+// Unused = 0x8,
HasCatchOrWith = 0x10
};
- // Absolute offset into file where the code for this function is located. Only used when the function
- // is serialized.
- LEUInt64 codeOffset;
- LEUInt64 codeSize;
-
- LEUInt32 nameIndex;
- LEUInt32 nFormals;
- LEUInt32 formalsOffset;
- LEUInt32 nLocals;
- LEUInt32 localsOffset;
- LEUInt32 nInnerFunctions;
+ // Absolute offset into file where the code for this function is located.
+ quint32_le codeOffset;
+ quint32_le codeSize;
+
+ quint32_le nameIndex;
+ quint32_le nFormals;
+ quint32_le formalsOffset;
+ quint32_le nLocals;
+ quint32_le localsOffset;
+ quint32_le nLineNumbers;
+ quint32_le lineNumberOffset;
+ quint32_le nInnerFunctions;
+ quint32_le nRegisters;
Location location;
// Qml Extensions Begin
- LEUInt32 nDependingIdObjects;
- LEUInt32 dependingIdObjectsOffset; // Array of resolved ID objects
- LEUInt32 nDependingContextProperties;
- LEUInt32 dependingContextPropertiesOffset; // Array of int pairs (property index and notify index)
- LEUInt32 nDependingScopeProperties;
- LEUInt32 dependingScopePropertiesOffset; // Array of int pairs (property index and notify index)
+ quint32_le nDependingIdObjects;
+ quint32_le dependingIdObjectsOffset; // Array of resolved ID objects
+ quint32_le nDependingContextProperties;
+ quint32_le dependingContextPropertiesOffset; // Array of int pairs (property index and notify index)
+ quint32_le nDependingScopeProperties;
+ quint32_le dependingScopePropertiesOffset; // Array of int pairs (property index and notify index)
// Qml Extensions End
// quint32 formalsIndex[nFormals]
@@ -247,38 +246,49 @@ struct Function
// Keep all unaligned data at the end
quint8 flags;
quint8 padding1;
- LEUInt16 padding2;
+ quint16_le padding2;
- const LEUInt32 *formalsTable() const { return reinterpret_cast<const LEUInt32 *>(reinterpret_cast<const char *>(this) + formalsOffset); }
- const LEUInt32 *localsTable() const { return reinterpret_cast<const LEUInt32 *>(reinterpret_cast<const char *>(this) + localsOffset); }
- const LEUInt32 *qmlIdObjectDependencyTable() const { return reinterpret_cast<const LEUInt32 *>(reinterpret_cast<const char *>(this) + dependingIdObjectsOffset); }
- const LEUInt32 *qmlContextPropertiesDependencyTable() const { return reinterpret_cast<const LEUInt32 *>(reinterpret_cast<const char *>(this) + dependingContextPropertiesOffset); }
- const LEUInt32 *qmlScopePropertiesDependencyTable() const { return reinterpret_cast<const LEUInt32 *>(reinterpret_cast<const char *>(this) + dependingScopePropertiesOffset); }
+ const quint32_le *formalsTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + formalsOffset); }
+ const quint32_le *localsTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + localsOffset); }
+ const CodeOffsetToLine *lineNumberTable() const { return reinterpret_cast<const CodeOffsetToLine *>(reinterpret_cast<const char *>(this) + lineNumberOffset); }
+ const quint32_le *qmlIdObjectDependencyTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + dependingIdObjectsOffset); }
+ const quint32_le *qmlContextPropertiesDependencyTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + dependingContextPropertiesOffset); }
+ const quint32_le *qmlScopePropertiesDependencyTable() const { return reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + dependingScopePropertiesOffset); }
// --- QQmlPropertyCacheCreator interface
- const LEUInt32 *formalsBegin() const { return formalsTable(); }
- const LEUInt32 *formalsEnd() const { return formalsTable() + nFormals; }
+ const quint32_le *formalsBegin() const { return formalsTable(); }
+ const quint32_le *formalsEnd() const { return formalsTable() + nFormals; }
// ---
+ const uchar *code() const { return reinterpret_cast<const uchar *>(this) + codeOffset; }
+
inline bool hasQmlDependencies() const { return nDependingIdObjects > 0 || nDependingContextProperties > 0 || nDependingScopeProperties > 0; }
- static int calculateSize(int nFormals, int nLocals, int nInnerfunctions, int nIdObjectDependencies, int nPropertyDependencies) {
- return (sizeof(Function) + (nFormals + nLocals + nInnerfunctions + nIdObjectDependencies + 2 * nPropertyDependencies) * sizeof(quint32) + 7) & ~0x7;
+ static int calculateSize(int nFormals, int nLocals, int nLines, int nInnerfunctions, int nIdObjectDependencies, int nPropertyDependencies, int codeSize) {
+ int trailingData = (nFormals + nLocals + nInnerfunctions + nIdObjectDependencies +
+ 2 * nPropertyDependencies)*sizeof (quint32) + nLines*sizeof(CodeOffsetToLine);
+ size_t size = align(align(sizeof(Function)) + size_t(trailingData)) + align(codeSize);
+ Q_ASSERT(size < INT_MAX);
+ return int(size);
+ }
+
+ static size_t align(size_t a) {
+ return (a + 7) & ~size_t(7);
}
};
-static_assert(sizeof(Function) == 72, "Function structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
+static_assert(sizeof(Function) == 76, "Function structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
// Qml data structures
struct Q_QML_EXPORT TranslationData {
- LEUInt32 commentIndex;
- LEInt32 number;
+ quint32_le commentIndex;
+ qint32_le number;
};
static_assert(sizeof(TranslationData) == 8, "TranslationData structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct Q_QML_PRIVATE_EXPORT Binding
{
- LEUInt32 propertyNameIndex;
+ quint32_le propertyNameIndex;
enum ValueType : unsigned int {
Type_Invalid,
@@ -303,26 +313,26 @@ struct Q_QML_PRIVATE_EXPORT Binding
IsBindingToAlias = 0x40,
IsDeferredBinding = 0x80,
IsCustomParserBinding = 0x100,
+ IsFunctionExpression = 0x200
};
- LEUInt32 stringIndex; // Set for Type_String, Type_Translation and Type_Script (the latter because of script strings)
+ union {
+ quint32_le_bitfield<0, 16> flags;
+ quint32_le_bitfield<16, 16> type;
+ };
union {
bool b;
quint64 doubleValue; // do not access directly, needs endian protected access
- LEUInt32 compiledScriptIndex; // used when Type_Script
- LEUInt32 objectIndex;
+ quint32_le compiledScriptIndex; // used when Type_Script
+ quint32_le objectIndex;
TranslationData translationData; // used when Type_Translation
} value;
-
- union {
- QJsonPrivate::qle_bitfield<0, 16> flags;
- QJsonPrivate::qle_bitfield<16, 16> type;
- };
+ quint32_le stringIndex; // Set for Type_String, Type_Translation and Type_Script (the latter because of script strings)
Location location;
Location valueLocation;
- LEUInt32 padding;
+ quint32_le padding;
bool isValueBinding() const
{
@@ -371,9 +381,12 @@ struct Q_QML_PRIVATE_EXPORT Binding
return false;
}
+ bool isFunctionExpression() const { return (flags & IsFunctionExpression); }
+
static QString escapedString(const QString &string);
- bool evaluatesToString() const { return type == Type_String || type == Type_Translation || type == Type_TranslationById; }
+ bool containsTranslations() const { return type == Type_Translation || type == Type_TranslationById; }
+ bool evaluatesToString() const { return type == Type_String || containsTranslations(); }
QString valueAsString(const Unit *unit) const;
QString valueAsScriptString(const Unit *unit) const;
@@ -404,19 +417,49 @@ struct Q_QML_PRIVATE_EXPORT Binding
static_assert(sizeof(Binding) == 32, "Binding structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
+struct EnumValue
+{
+ quint32_le nameIndex;
+ qint32_le value;
+ Location location;
+};
+
+struct Enum
+{
+ quint32_le nameIndex;
+ quint32_le nEnumValues;
+ Location location;
+
+ const EnumValue *enumValueAt(int idx) const {
+ return reinterpret_cast<const EnumValue*>(this + 1) + idx;
+ }
+
+ static int calculateSize(int nEnumValues) {
+ return (sizeof(Enum)
+ + nEnumValues * sizeof(EnumValue)
+ + 7) & ~0x7;
+ }
+
+ // --- QQmlPropertyCacheCreatorInterface
+ const EnumValue *enumValuesBegin() const { return enumValueAt(0); }
+ const EnumValue *enumValuesEnd() const { return enumValueAt(nEnumValues); }
+ int enumValueCount() const { return nEnumValues; }
+ // ---
+};
+
struct Parameter
{
- LEUInt32 nameIndex;
- LEUInt32 type;
- LEUInt32 customTypeNameIndex;
+ quint32_le nameIndex;
+ quint32_le type;
+ quint32_le customTypeNameIndex;
Location location;
};
static_assert(sizeof(Parameter) == 16, "Parameter structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct Signal
{
- LEUInt32 nameIndex;
- LEUInt32 nParameters;
+ quint32_le nameIndex;
+ quint32_le nParameters;
Location location;
// Parameter parameters[1];
@@ -449,12 +492,12 @@ struct Property
IsReadOnly = 0x1
};
- LEUInt32 nameIndex;
+ quint32_le nameIndex;
union {
- QJsonPrivate::qle_bitfield<0, 31> type;
- QJsonPrivate::qle_bitfield<31, 1> flags; // readonly
+ quint32_le_bitfield<0, 31> type;
+ quint32_le_bitfield<31, 1> flags; // readonly
};
- LEUInt32 customTypeNameIndex; // If type >= Custom
+ quint32_le customTypeNameIndex; // If type >= Custom
Location location;
};
static_assert(sizeof(Property) == 16, "Property structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
@@ -466,18 +509,18 @@ struct Alias {
AliasPointsToPointerObject = 0x4
};
union {
- QJsonPrivate::qle_bitfield<0, 29> nameIndex;
- QJsonPrivate::qle_bitfield<29, 3> flags;
+ quint32_le_bitfield<0, 29> nameIndex;
+ quint32_le_bitfield<29, 3> flags;
};
union {
- LEUInt32 idIndex; // string index
- QJsonPrivate::qle_bitfield<0, 31> targetObjectId; // object id index (in QQmlContextData::idValues)
- QJsonPrivate::qle_bitfield<31, 1> aliasToLocalAlias;
+ quint32_le idIndex; // string index
+ quint32_le_bitfield<0, 31> targetObjectId; // object id index (in QQmlContextData::idValues)
+ quint32_le_bitfield<31, 1> aliasToLocalAlias;
};
union {
- LEUInt32 propertyNameIndex; // string index
- LEInt32 encodedMetaPropertyIndex;
- LEUInt32 localAliasIndex; // index in list of aliases local to the object (if targetObjectId == objectId)
+ quint32_le propertyNameIndex; // string index
+ qint32_le encodedMetaPropertyIndex;
+ quint32_le localAliasIndex; // index in list of aliases local to the object (if targetObjectId == objectId)
};
Location location;
Location referenceLocation;
@@ -501,26 +544,28 @@ struct Object
// Depending on the use, this may be the type name to instantiate before instantiating this
// object. For grouped properties the type name will be empty and for attached properties
// it will be the name of the attached type.
- LEUInt32 inheritedTypeNameIndex;
- LEUInt32 idNameIndex;
+ quint32_le inheritedTypeNameIndex;
+ quint32_le idNameIndex;
union {
- QJsonPrivate::qle_bitfield<0, 15> flags;
- QJsonPrivate::qle_bitfield<15, 1> defaultPropertyIsAlias;
- QJsonPrivate::qle_signedbitfield<16, 16> id;
+ quint32_le_bitfield<0, 15> flags;
+ quint32_le_bitfield<15, 1> defaultPropertyIsAlias;
+ qint32_le_bitfield<16, 16> id;
};
- LEInt32 indexOfDefaultPropertyOrAlias; // -1 means no default property declared in this object
- LEUInt32 nFunctions;
- LEUInt32 offsetToFunctions;
- LEUInt32 nProperties;
- LEUInt32 offsetToProperties;
- LEUInt32 nAliases;
- LEUInt32 offsetToAliases;
- LEUInt32 nSignals;
- LEUInt32 offsetToSignals; // which in turn will be a table with offsets to variable-sized Signal objects
- LEUInt32 nBindings;
- LEUInt32 offsetToBindings;
- LEUInt32 nNamedObjectsInComponent;
- LEUInt32 offsetToNamedObjectsInComponent;
+ qint32_le indexOfDefaultPropertyOrAlias; // -1 means no default property declared in this object
+ quint32_le nFunctions;
+ quint32_le offsetToFunctions;
+ quint32_le nProperties;
+ quint32_le offsetToProperties;
+ quint32_le nAliases;
+ quint32_le offsetToAliases;
+ quint32_le nEnums;
+ quint32_le offsetToEnums; // which in turn will be a table with offsets to variable-sized Enum objects
+ quint32_le nSignals;
+ quint32_le offsetToSignals; // which in turn will be a table with offsets to variable-sized Signal objects
+ quint32_le nBindings;
+ quint32_le offsetToBindings;
+ quint32_le nNamedObjectsInComponent;
+ quint32_le offsetToNamedObjectsInComponent;
Location location;
Location locationOfIdProperty;
// Function[]
@@ -528,12 +573,13 @@ struct Object
// Signal[]
// Binding[]
- static int calculateSizeExcludingSignals(int nFunctions, int nProperties, int nAliases, int nSignals, int nBindings, int nNamedObjectsInComponent)
+ static int calculateSizeExcludingSignalsAndEnums(int nFunctions, int nProperties, int nAliases, int nEnums, int nSignals, int nBindings, int nNamedObjectsInComponent)
{
return ( sizeof(Object)
+ nFunctions * sizeof(quint32)
+ nProperties * sizeof(Property)
+ nAliases * sizeof(Alias)
+ + nEnums * sizeof(quint32)
+ nSignals * sizeof(quint32)
+ nBindings * sizeof(Binding)
+ nNamedObjectsInComponent * sizeof(int)
@@ -541,9 +587,9 @@ struct Object
) & ~0x7;
}
- const LEUInt32 *functionOffsetTable() const
+ const quint32_le *functionOffsetTable() const
{
- return reinterpret_cast<const LEUInt32*>(reinterpret_cast<const char *>(this) + offsetToFunctions);
+ return reinterpret_cast<const quint32_le*>(reinterpret_cast<const char *>(this) + offsetToFunctions);
}
const Property *propertyTable() const
@@ -561,21 +607,29 @@ struct Object
return reinterpret_cast<const Binding*>(reinterpret_cast<const char *>(this) + offsetToBindings);
}
+ const Enum *enumAt(int idx) const
+ {
+ const quint32_le *offsetTable = reinterpret_cast<const quint32_le*>((reinterpret_cast<const char *>(this)) + offsetToEnums);
+ const quint32_le offset = offsetTable[idx];
+ return reinterpret_cast<const Enum*>(reinterpret_cast<const char*>(this) + offset);
+ }
+
const Signal *signalAt(int idx) const
{
- const LEUInt32 *offsetTable = reinterpret_cast<const LEUInt32*>((reinterpret_cast<const char *>(this)) + offsetToSignals);
- const LEUInt32 offset = offsetTable[idx];
+ const quint32_le *offsetTable = reinterpret_cast<const quint32_le*>((reinterpret_cast<const char *>(this)) + offsetToSignals);
+ const quint32_le offset = offsetTable[idx];
return reinterpret_cast<const Signal*>(reinterpret_cast<const char*>(this) + offset);
}
- const LEUInt32 *namedObjectsInComponentTable() const
+ const quint32_le *namedObjectsInComponentTable() const
{
- return reinterpret_cast<const LEUInt32*>(reinterpret_cast<const char *>(this) + offsetToNamedObjectsInComponent);
+ return reinterpret_cast<const quint32_le*>(reinterpret_cast<const char *>(this) + offsetToNamedObjectsInComponent);
}
// --- QQmlPropertyCacheCreator interface
int propertyCount() const { return nProperties; }
int aliasCount() const { return nAliases; }
+ int enumCount() const { return nEnums; }
int signalCount() const { return nSignals; }
int functionCount() const { return nFunctions; }
@@ -588,6 +642,10 @@ struct Object
const Alias *aliasesBegin() const { return aliasTable(); }
const Alias *aliasesEnd() const { return aliasTable() + nAliases; }
+ typedef TableIterator<Enum, Object, &Object::enumAt> EnumIterator;
+ EnumIterator enumsBegin() const { return EnumIterator(this, 0); }
+ EnumIterator enumsEnd() const { return EnumIterator(this, nEnums); }
+
typedef TableIterator<Signal, Object, &Object::signalAt> SignalIterator;
SignalIterator signalsBegin() const { return SignalIterator(this, 0); }
SignalIterator signalsEnd() const { return SignalIterator(this, nSignals); }
@@ -595,7 +653,7 @@ struct Object
int namedObjectsInComponentCount() const { return nNamedObjectsInComponent; }
// ---
};
-static_assert(sizeof(Object) == 72, "Object structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
+static_assert(sizeof(Object) == 80, "Object structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct Import
{
@@ -604,13 +662,13 @@ struct Import
ImportFile = 0x2,
ImportScript = 0x3
};
- LEUInt32 type;
+ quint32_le type;
- LEUInt32 uriIndex;
- LEUInt32 qualifierIndex;
+ quint32_le uriIndex;
+ quint32_le qualifierIndex;
- LEInt32 majorVersion;
- LEInt32 minorVersion;
+ qint32_le majorVersion;
+ qint32_le minorVersion;
Location location;
@@ -624,17 +682,15 @@ struct Unit
{
// DO NOT CHANGE THESE FIELDS EVER
char magic[8];
- LEUInt32 version;
- LEUInt32 qtVersion;
- LEInt64 sourceTimeStamp;
- LEUInt32 unitSize; // Size of the Unit and any depending data.
+ quint32_le version;
+ quint32_le qtVersion;
+ qint64_le sourceTimeStamp;
+ quint32_le unitSize; // Size of the Unit and any depending data.
// END DO NOT CHANGE THESE FIELDS EVER
char md5Checksum[16]; // checksum of all bytes following this field.
void generateChecksum();
- LEUInt32 architectureIndex; // string index to QSysInfo::buildAbi()
- LEUInt32 codeGeneratorIndex;
char dependencyMD5Checksum[16];
enum : unsigned int {
@@ -646,38 +702,38 @@ struct Unit
ContainsMachineCode = 0x20, // used to determine if we need to mmap with execute permissions
PendingTypeCompilation = 0x40 // the QML data structures present are incomplete and require type compilation
};
- LEUInt32 flags;
- LEUInt32 stringTableSize;
- LEUInt32 offsetToStringTable;
- LEUInt32 functionTableSize;
- LEUInt32 offsetToFunctionTable;
- LEUInt32 lookupTableSize;
- LEUInt32 offsetToLookupTable;
- LEUInt32 regexpTableSize;
- LEUInt32 offsetToRegexpTable;
- LEUInt32 constantTableSize;
- LEUInt32 offsetToConstantTable;
- LEUInt32 jsClassTableSize;
- LEUInt32 offsetToJSClassTable;
- LEInt32 indexOfRootFunction;
- LEUInt32 sourceFileIndex;
- LEUInt32 finalUrlIndex;
+ quint32_le flags;
+ quint32_le stringTableSize;
+ quint32_le offsetToStringTable;
+ quint32_le functionTableSize;
+ quint32_le offsetToFunctionTable;
+ quint32_le lookupTableSize;
+ quint32_le offsetToLookupTable;
+ quint32_le regexpTableSize;
+ quint32_le offsetToRegexpTable;
+ quint32_le constantTableSize;
+ quint32_le offsetToConstantTable;
+ quint32_le jsClassTableSize;
+ quint32_le offsetToJSClassTable;
+ qint32_le indexOfRootFunction;
+ quint32_le sourceFileIndex;
+ quint32_le finalUrlIndex;
/* QML specific fields */
- LEUInt32 nImports;
- LEUInt32 offsetToImports;
- LEUInt32 nObjects;
- LEUInt32 offsetToObjects;
+ quint32_le nImports;
+ quint32_le offsetToImports;
+ quint32_le nObjects;
+ quint32_le offsetToObjects;
- LEUInt32 padding;
+ quint32_le padding;
const Import *importAt(int idx) const {
return reinterpret_cast<const Import*>((reinterpret_cast<const char *>(this)) + offsetToImports + idx * sizeof(Import));
}
const Object *objectAt(int idx) const {
- const LEUInt32 *offsetTable = reinterpret_cast<const LEUInt32*>((reinterpret_cast<const char *>(this)) + offsetToObjects);
- const LEUInt32 offset = offsetTable[idx];
+ const quint32_le *offsetTable = reinterpret_cast<const quint32_le*>((reinterpret_cast<const char *>(this)) + offsetToObjects);
+ const quint32_le offset = offsetTable[idx];
return reinterpret_cast<const Object*>(reinterpret_cast<const char*>(this) + offset);
}
@@ -687,8 +743,8 @@ struct Unit
/* end QML specific fields*/
QString stringAt(int idx) const {
- const LEUInt32 *offsetTable = reinterpret_cast<const LEUInt32*>((reinterpret_cast<const char *>(this)) + offsetToStringTable);
- const LEUInt32 offset = offsetTable[idx];
+ const quint32_le *offsetTable = reinterpret_cast<const quint32_le*>((reinterpret_cast<const char *>(this)) + offsetToStringTable);
+ const quint32_le offset = offsetTable[idx];
const String *str = reinterpret_cast<const String*>(reinterpret_cast<const char *>(this) + offset);
if (str->size == 0)
return QString();
@@ -700,7 +756,7 @@ struct Unit
// return QString::fromRawData(characters, str->size);
return QString(characters, str->size);
#else
- const LEUInt16 *characters = reinterpret_cast<const LEUInt16 *>(str + 1);
+ const quint16_le *characters = reinterpret_cast<const quint16_le *>(str + 1);
QString qstr(str->size, Qt::Uninitialized);
QChar *ch = qstr.data();
for (int i = 0; i < str->size; ++i)
@@ -709,11 +765,11 @@ struct Unit
#endif
}
- const LEUInt32 *functionOffsetTable() const { return reinterpret_cast<const LEUInt32*>((reinterpret_cast<const char *>(this)) + offsetToFunctionTable); }
+ const quint32_le *functionOffsetTable() const { return reinterpret_cast<const quint32_le*>((reinterpret_cast<const char *>(this)) + offsetToFunctionTable); }
const Function *functionAt(int idx) const {
- const LEUInt32 *offsetTable = functionOffsetTable();
- const LEUInt32 offset = offsetTable[idx];
+ const quint32_le *offsetTable = functionOffsetTable();
+ const quint32_le offset = offsetTable[idx];
return reinterpret_cast<const Function*>(reinterpret_cast<const char *>(this) + offset);
}
@@ -721,13 +777,13 @@ struct Unit
const RegExp *regexpAt(int index) const {
return reinterpret_cast<const RegExp*>(reinterpret_cast<const char *>(this) + offsetToRegexpTable + index * sizeof(RegExp));
}
- const LEUInt64 *constants() const {
- return reinterpret_cast<const LEUInt64*>(reinterpret_cast<const char *>(this) + offsetToConstantTable);
+ const quint64_le *constants() const {
+ return reinterpret_cast<const quint64_le*>(reinterpret_cast<const char *>(this) + offsetToConstantTable);
}
const JSClassMember *jsClassAt(int idx, int *nMembers) const {
- const LEUInt32 *offsetTable = reinterpret_cast<const LEUInt32 *>(reinterpret_cast<const char *>(this) + offsetToJSClassTable);
- const LEUInt32 offset = offsetTable[idx];
+ const quint32_le *offsetTable = reinterpret_cast<const quint32_le *>(reinterpret_cast<const char *>(this) + offsetToJSClassTable);
+ const quint32_le offset = offsetTable[idx];
const char *ptr = reinterpret_cast<const char *>(this) + offset;
const JSClass *klass = reinterpret_cast<const JSClass *>(ptr);
*nMembers = klass->nMembers;
@@ -735,7 +791,7 @@ struct Unit
}
};
-static_assert(sizeof(Unit) == 152, "Unit structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
+static_assert(sizeof(Unit) == 144, "Unit structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct TypeReference
{
@@ -817,33 +873,53 @@ typedef QVector<QQmlPropertyData*> BindingPropertyData;
struct Q_QML_PRIVATE_EXPORT CompilationUnitBase
{
- QV4::Heap::String **runtimeStrings = 0; // Array
+ // pointers either to data->constants() or little-endian memory copy.
+ QV4::Heap::String **runtimeStrings = nullptr; // Array
+ const Value* constants = nullptr;
+ QV4::Value *runtimeRegularExpressions = nullptr;
};
Q_STATIC_ASSERT(std::is_standard_layout<CompilationUnitBase>::value);
Q_STATIC_ASSERT(offsetof(CompilationUnitBase, runtimeStrings) == 0);
+Q_STATIC_ASSERT(offsetof(CompilationUnitBase, constants) == sizeof(QV4::Heap::String **));
+Q_STATIC_ASSERT(offsetof(CompilationUnitBase, runtimeRegularExpressions) == offsetof(CompilationUnitBase, constants) + sizeof(const Value *));
-struct Q_QML_PRIVATE_EXPORT CompilationUnit : public CompilationUnitBase, public QQmlRefCount
+struct Q_QML_PRIVATE_EXPORT CompilationUnit final : public CompilationUnitBase
{
+public:
+ CompilationUnit(const Unit *unitData = nullptr);
#ifdef V4_BOOTSTRAP
- CompilationUnit()
- : data(0)
- {}
- virtual ~CompilationUnit() {}
+ ~CompilationUnit() {}
#else
- CompilationUnit();
- virtual ~CompilationUnit();
+ ~CompilationUnit();
#endif
- const Unit *data;
+ void addref()
+ {
+ Q_ASSERT(refCount.load() > 0);
+ refCount.ref();
+ }
+
+ void release()
+ {
+ Q_ASSERT(refCount.load() > 0);
+ if (!refCount.deref())
+ destroy();
+ }
+ int count() const
+ {
+ return refCount.load();
+ }
+
+ const Unit *data = nullptr;
// Called only when building QML, when we build the header for JS first and append QML data
- virtual QV4::CompiledData::Unit *createUnitData(QmlIR::Document *irDocument);
+ QV4::CompiledData::Unit *createUnitData(QmlIR::Document *irDocument);
#ifndef V4_BOOTSTRAP
QIntrusiveListNode nextCompilationUnit;
- ExecutionEngine *engine;
- QQmlEnginePrivate *qmlEngine; // only used in QML environment for composite types, not in plain QJSEngine case.
+ ExecutionEngine *engine = nullptr;
+ QQmlEnginePrivate *qmlEngine = nullptr; // only used in QML environment for composite types, not in plain QJSEngine case.
// url() and fileName() shall be used to load the actual QML/JS code or to show errors or
// warnings about that code. They include any potential URL interceptions and thus represent the
@@ -862,9 +938,8 @@ struct Q_QML_PRIVATE_EXPORT CompilationUnit : public CompilationUnitBase, public
return m_finalUrl;
}
- QV4::Lookup *runtimeLookups;
- QV4::Value *runtimeRegularExpressions;
- QV4::InternalClass **runtimeClasses;
+ QV4::Lookup *runtimeLookups = nullptr;
+ QV4::InternalClass **runtimeClasses = nullptr;
QVector<QV4::Function *> runtimeFunctions;
mutable QQmlNullableValue<QUrl> m_url;
mutable QQmlNullableValue<QUrl> m_finalUrl;
@@ -882,26 +957,23 @@ struct Q_QML_PRIVATE_EXPORT CompilationUnit : public CompilationUnitBase, public
// mapping from component object index (CompiledData::Unit object index that points to component) to identifier hash of named objects
// this is initialized on-demand by QQmlContextData
- QHash<int, IdentifierHash<int>> namedObjectsPerComponentCache;
- IdentifierHash<int> namedObjectsPerComponent(int componentObjectIndex);
-
- // pointers either to data->constants() or little-endian memory copy.
- const Value* constants;
+ QHash<int, IdentifierHash> namedObjectsPerComponentCache;
+ IdentifierHash namedObjectsPerComponent(int componentObjectIndex);
void finalizeCompositeType(QQmlEnginePrivate *qmlEngine);
- int totalBindingsCount; // Number of bindings used in this type
- int totalParserStatusCount; // Number of instantiated types that are QQmlParserStatus subclasses
- int totalObjectCount; // Number of objects explicitly instantiated
+ int totalBindingsCount = 0; // Number of bindings used in this type
+ int totalParserStatusCount = 0; // Number of instantiated types that are QQmlParserStatus subclasses
+ int totalObjectCount = 0; // Number of objects explicitly instantiated
QVector<QQmlScriptData *> dependentScripts;
ResolvedTypeReferenceMap resolvedTypes;
bool verifyChecksum(const DependentTypesHasher &dependencyHasher) const;
- int metaTypeId;
- int listMetaTypeId;
- bool isRegisteredWithEngine;
+ int metaTypeId = -1;
+ int listMetaTypeId = -1;
+ bool isRegisteredWithEngine = false;
QScopedPointer<CompilationUnitMapper> backingFile;
@@ -930,27 +1002,25 @@ struct Q_QML_PRIVATE_EXPORT CompilationUnit : public CompilationUnitBase, public
QV4::Function *linkToEngine(QV4::ExecutionEngine *engine);
void unlink();
- void markObjects(QV4::ExecutionEngine *e);
-
- void destroy() Q_DECL_OVERRIDE;
+ void markObjects(MarkStack *markStack);
- bool loadFromDisk(const QUrl &url, const QDateTime &sourceTimeStamp, EvalISelFactory *iselFactory, QString *errorString);
+ bool loadFromDisk(const QUrl &url, const QDateTime &sourceTimeStamp, QString *errorString);
protected:
- virtual void linkBackendToEngine(QV4::ExecutionEngine *engine) = 0;
- virtual bool memoryMapCode(QString *errorString);
+ void linkBackendToEngine(QV4::ExecutionEngine *engine);
#endif // V4_BOOTSTRAP
+private:
+ void destroy();
+
+ QAtomicInt refCount = 1;
+
public:
#if defined(V4_BOOTSTRAP)
bool saveToDisk(const QString &outputFileName, QString *errorString);
#else
bool saveToDisk(const QUrl &unitUrl, QString *errorString);
#endif
-
-protected:
- virtual void prepareCodeOffsetsForDiskStorage(CompiledData::Unit *unit);
- virtual bool saveCodeToDisk(QIODevice *device, const CompiledData::Unit *unit, QString *errorString);
};
#ifndef V4_BOOTSTRAP
diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp
index 0dc40d9698..f2e1f4a0de 100644
--- a/src/qml/compiler/qv4compiler.cpp
+++ b/src/qml/compiler/qv4compiler.cpp
@@ -39,10 +39,12 @@
#include <qv4compiler_p.h>
#include <qv4compileddata_p.h>
-#include <qv4isel_p.h>
+#include <qv4codegen_p.h>
#include <private/qv4string_p.h>
#include <private/qv4value_p.h>
#include <private/qv4alloca_p.h>
+#include <private/qqmljslexer_p.h>
+#include <private/qqmljsast_p.h>
#include <wtf/MathExtras.h>
#include <QCryptographicHash>
@@ -78,7 +80,7 @@ void QV4::Compiler::StringTableGenerator::clear()
void QV4::Compiler::StringTableGenerator::serialize(CompiledData::Unit *unit)
{
char *dataStart = reinterpret_cast<char *>(unit);
- CompiledData::LEUInt32 *stringTable = reinterpret_cast<CompiledData::LEUInt32 *>(dataStart + unit->offsetToStringTable);
+ quint32_le *stringTable = reinterpret_cast<quint32_le *>(dataStart + unit->offsetToStringTable);
char *stringData = dataStart + unit->offsetToStringTable + unit->stringTableSize * sizeof(uint);
for (int i = 0; i < strings.size(); ++i) {
stringTable[i] = stringData - dataStart;
@@ -98,70 +100,66 @@ void QV4::Compiler::StringTableGenerator::serialize(CompiledData::Unit *unit)
}
}
-QV4::Compiler::JSUnitGenerator::JSUnitGenerator(QV4::IR::Module *module)
- : irModule(module)
+QV4::Compiler::JSUnitGenerator::JSUnitGenerator(QV4::Compiler::Module *module)
+ : module(module)
{
// Make sure the empty string always gets index 0
registerString(QString());
}
-uint QV4::Compiler::JSUnitGenerator::registerIndexedGetterLookup()
+int QV4::Compiler::JSUnitGenerator::registerGetterLookup(const QString &name)
{
- CompiledData::Lookup l;
- l.type_and_flags = CompiledData::Lookup::Type_IndexedGetter;
- l.nameIndex = 0;
- lookups << l;
- return lookups.size() - 1;
+ return registerGetterLookup(registerString(name));
}
-uint QV4::Compiler::JSUnitGenerator::registerIndexedSetterLookup()
+int QV4::Compiler::JSUnitGenerator::registerGetterLookup(int nameIndex)
{
CompiledData::Lookup l;
- l.type_and_flags = CompiledData::Lookup::Type_IndexedSetter;
- l.nameIndex = 0;
+ l.type_and_flags = CompiledData::Lookup::Type_Getter;
+ l.nameIndex = nameIndex;
lookups << l;
return lookups.size() - 1;
}
-uint QV4::Compiler::JSUnitGenerator::registerGetterLookup(const QString &name)
+int QV4::Compiler::JSUnitGenerator::registerSetterLookup(const QString &name)
{
- CompiledData::Lookup l;
- l.type_and_flags = CompiledData::Lookup::Type_Getter;
- l.nameIndex = registerString(name);
- lookups << l;
- return lookups.size() - 1;
+ return registerSetterLookup(registerString(name));
}
-
-uint QV4::Compiler::JSUnitGenerator::registerSetterLookup(const QString &name)
+int QV4::Compiler::JSUnitGenerator::registerSetterLookup(int nameIndex)
{
CompiledData::Lookup l;
l.type_and_flags = CompiledData::Lookup::Type_Setter;
- l.nameIndex = registerString(name);
+ l.nameIndex = nameIndex;
lookups << l;
return lookups.size() - 1;
}
-uint QV4::Compiler::JSUnitGenerator::registerGlobalGetterLookup(const QString &name)
+int QV4::Compiler::JSUnitGenerator::registerGlobalGetterLookup(const QString &name)
+{
+ return registerGlobalGetterLookup(registerString(name));
+}
+
+int QV4::Compiler::JSUnitGenerator::registerGlobalGetterLookup(int nameIndex)
{
CompiledData::Lookup l;
l.type_and_flags = CompiledData::Lookup::Type_GlobalGetter;
- l.nameIndex = registerString(name);
+ l.nameIndex = nameIndex;
lookups << l;
return lookups.size() - 1;
}
-int QV4::Compiler::JSUnitGenerator::registerRegExp(QV4::IR::RegExp *regexp)
+int QV4::Compiler::JSUnitGenerator::registerRegExp(QQmlJS::AST::RegExpLiteral *regexp)
{
CompiledData::RegExp re;
- re.stringIndex = registerString(*regexp->value);
+ re.stringIndex = registerString(regexp->pattern.toString());
re.flags = 0;
- if (regexp->flags & QV4::IR::RegExp::RegExp_Global)
+ if (regexp->flags & QQmlJS::Lexer::RegExp_Global)
re.flags |= CompiledData::RegExp::RegExp_Global;
- if (regexp->flags & QV4::IR::RegExp::RegExp_IgnoreCase)
+ if (regexp->flags & QQmlJS::Lexer::RegExp_IgnoreCase)
re.flags |= CompiledData::RegExp::RegExp_IgnoreCase;
- if (regexp->flags & QV4::IR::RegExp::RegExp_Multiline)
+ if (regexp->flags & QQmlJS::Lexer::RegExp_Multiline)
re.flags |= CompiledData::RegExp::RegExp_Multiline;
regexps.append(re);
@@ -177,51 +175,63 @@ int QV4::Compiler::JSUnitGenerator::registerConstant(QV4::ReturnedValue v)
return constants.size() - 1;
}
-int QV4::Compiler::JSUnitGenerator::registerJSClass(int count, IR::ExprList *args)
+QV4::ReturnedValue QV4::Compiler::JSUnitGenerator::constant(int idx)
+{
+ return constants.at(idx);
+}
+
+int QV4::Compiler::JSUnitGenerator::registerJSClass(const QVector<MemberInfo> &members)
{
// ### re-use existing class definitions.
- const int size = CompiledData::JSClass::calculateSize(count);
+ const int size = CompiledData::JSClass::calculateSize(members.size());
jsClassOffsets.append(jsClassData.size());
const int oldSize = jsClassData.size();
jsClassData.resize(jsClassData.size() + size);
memset(jsClassData.data() + oldSize, 0, size);
CompiledData::JSClass *jsClass = reinterpret_cast<CompiledData::JSClass*>(jsClassData.data() + oldSize);
- jsClass->nMembers = count;
+ jsClass->nMembers = members.size();
CompiledData::JSClassMember *member = reinterpret_cast<CompiledData::JSClassMember*>(jsClass + 1);
- IR::ExprList *it = args;
- for (int i = 0; i < count; ++i, it = it->next, ++member) {
- QV4::IR::Name *name = it->expr->asName();
- it = it->next;
+ for (const MemberInfo &memberInfo : members) {
+ member->nameOffset = registerString(memberInfo.name);
+ member->isAccessor = memberInfo.isAccessor;
+ ++member;
+ }
- const bool isData = it->expr->asConst()->value;
- it = it->next;
+ return jsClassOffsets.size() - 1;
+}
- member->nameOffset = registerString(*name->id);
- member->isAccessor = !isData;
+int QV4::Compiler::JSUnitGenerator::registerJSClass(int count, CompiledData::JSClassMember *members)
+{
+ const int size = CompiledData::JSClass::calculateSize(count);
+ jsClassOffsets.append(jsClassData.size());
+ const int oldSize = jsClassData.size();
+ jsClassData.resize(jsClassData.size() + size);
+ memset(jsClassData.data() + oldSize, 0, size);
- if (!isData)
- it = it->next;
- }
+ CompiledData::JSClass *jsClass = reinterpret_cast<CompiledData::JSClass*>(jsClassData.data() + oldSize);
+ jsClass->nMembers = count;
+ CompiledData::JSClassMember *jsClassMembers = reinterpret_cast<CompiledData::JSClassMember*>(jsClass + 1);
+ memcpy(jsClassMembers, members, sizeof(CompiledData::JSClassMember)*count);
return jsClassOffsets.size() - 1;
}
QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit(GeneratorOption option)
{
- registerString(irModule->fileName);
- registerString(irModule->finalUrl);
- for (QV4::IR::Function *f : qAsConst(irModule->functions)) {
- registerString(*f->name);
- for (int i = 0; i < f->formals.size(); ++i)
- registerString(*f->formals.at(i));
+ registerString(module->fileName);
+ registerString(module->finalUrl);
+ for (Context *f : qAsConst(module->functions)) {
+ registerString(f->name);
+ for (int i = 0; i < f->arguments.size(); ++i)
+ registerString(f->arguments.at(i));
for (int i = 0; i < f->locals.size(); ++i)
- registerString(*f->locals.at(i));
+ registerString(f->locals.at(i));
}
- Q_ALLOCA_VAR(CompiledData::LEUInt32, functionOffsets, irModule->functions.size() * sizeof(CompiledData::LEUInt32));
+ Q_ALLOCA_VAR(quint32_le, functionOffsets, module->functions.size() * sizeof(quint32_le));
uint jsClassDataOffset = 0;
char *dataPtr;
@@ -234,11 +244,11 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit(GeneratorO
memcpy(unit, &tempHeader, sizeof(tempHeader));
}
- memcpy(dataPtr + unit->offsetToFunctionTable, functionOffsets, unit->functionTableSize * sizeof(CompiledData::LEUInt32));
+ memcpy(dataPtr + unit->offsetToFunctionTable, functionOffsets, unit->functionTableSize * sizeof(quint32_le));
- for (int i = 0; i < irModule->functions.size(); ++i) {
- QV4::IR::Function *function = irModule->functions.at(i);
- if (function == irModule->rootFunction)
+ for (int i = 0; i < module->functions.size(); ++i) {
+ Context *function = module->functions.at(i);
+ if (function == module->rootContext)
unit->indexOfRootFunction = i;
writeFunction(dataPtr + functionOffsets[i], function);
@@ -255,7 +265,7 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit(GeneratorO
ReturnedValue *constantTable = reinterpret_cast<ReturnedValue *>(dataPtr + unit->offsetToConstantTable);
memcpy(constantTable, constants.constData(), constants.size() * sizeof(ReturnedValue));
#else
- CompiledData::LEUInt64 *constantTable = reinterpret_cast<CompiledData::LEUInt64 *>(dataPtr + unit->offsetToConstantTable);
+ quint64_le *constantTable = reinterpret_cast<quint64_le *>(dataPtr + unit->offsetToConstantTable);
for (int i = 0; i < constants.count(); ++i)
constantTable[i] = constants.at(i);
#endif
@@ -264,7 +274,7 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit(GeneratorO
memcpy(dataPtr + jsClassDataOffset, jsClassData.constData(), jsClassData.size());
// write js classes and js class lookup table
- CompiledData::LEUInt32 *jsClassOffsetTable = reinterpret_cast<CompiledData::LEUInt32 *>(dataPtr + unit->offsetToJSClassTable);
+ quint32_le *jsClassOffsetTable = reinterpret_cast<quint32_le *>(dataPtr + unit->offsetToJSClassTable);
for (int i = 0; i < jsClassOffsets.count(); ++i)
jsClassOffsetTable[i] = jsClassDataOffset + jsClassOffsets.at(i);
}
@@ -278,14 +288,14 @@ QV4::CompiledData::Unit *QV4::Compiler::JSUnitGenerator::generateUnit(GeneratorO
return unit;
}
-void QV4::Compiler::JSUnitGenerator::writeFunction(char *f, QV4::IR::Function *irFunction) const
+void QV4::Compiler::JSUnitGenerator::writeFunction(char *f, QV4::Compiler::Context *irFunction) const
{
QV4::CompiledData::Function *function = (QV4::CompiledData::Function *)f;
quint32 currentOffset = sizeof(QV4::CompiledData::Function);
currentOffset = (currentOffset + 7) & ~quint32(0x7);
- function->nameIndex = getStringId(*irFunction->name);
+ function->nameIndex = getStringId(irFunction->name);
function->flags = 0;
if (irFunction->hasDirectEval)
function->flags |= CompiledData::Function::HasDirectEval;
@@ -293,11 +303,9 @@ void QV4::Compiler::JSUnitGenerator::writeFunction(char *f, QV4::IR::Function *i
function->flags |= CompiledData::Function::UsesArgumentsObject;
if (irFunction->isStrict)
function->flags |= CompiledData::Function::IsStrict;
- if (irFunction->isNamedExpression)
- function->flags |= CompiledData::Function::IsNamedExpression;
if (irFunction->hasTry || irFunction->hasWith)
function->flags |= CompiledData::Function::HasCatchOrWith;
- function->nFormals = irFunction->formals.size();
+ function->nFormals = irFunction->arguments.size();
function->formalsOffset = currentOffset;
currentOffset += function->nFormals * sizeof(quint32);
@@ -305,7 +313,13 @@ void QV4::Compiler::JSUnitGenerator::writeFunction(char *f, QV4::IR::Function *i
function->localsOffset = currentOffset;
currentOffset += function->nLocals * sizeof(quint32);
- function->nInnerFunctions = irFunction->nestedFunctions.size();
+ function->nLineNumbers = irFunction->lineNumberMapping.size();
+ function->lineNumberOffset = currentOffset;
+ currentOffset += function->nLineNumbers * sizeof(CompiledData::CodeOffsetToLine);
+
+ function->nInnerFunctions = irFunction->nestedContexts.size();
+
+ function->nRegisters = irFunction->registerCount;
function->nDependingIdObjects = 0;
function->nDependingContextProperties = 0;
@@ -332,56 +346,60 @@ void QV4::Compiler::JSUnitGenerator::writeFunction(char *f, QV4::IR::Function *i
function->location.line = irFunction->line;
function->location.column = irFunction->column;
- function->codeOffset = 0;
- function->codeSize = 0;
+ function->codeOffset = currentOffset;
+ function->codeSize = irFunction->code.size();
// write formals
- CompiledData::LEUInt32 *formals = (CompiledData::LEUInt32 *)(f + function->formalsOffset);
- for (int i = 0; i < irFunction->formals.size(); ++i)
- formals[i] = getStringId(*irFunction->formals.at(i));
+ quint32_le *formals = (quint32_le *)(f + function->formalsOffset);
+ for (int i = 0; i < irFunction->arguments.size(); ++i)
+ formals[i] = getStringId(irFunction->arguments.at(i));
// write locals
- CompiledData::LEUInt32 *locals = (CompiledData::LEUInt32 *)(f + function->localsOffset);
+ quint32_le *locals = (quint32_le *)(f + function->localsOffset);
for (int i = 0; i < irFunction->locals.size(); ++i)
- locals[i] = getStringId(*irFunction->locals.at(i));
+ locals[i] = getStringId(irFunction->locals.at(i));
+
+ // write line numbers
+ memcpy(f + function->lineNumberOffset, irFunction->lineNumberMapping.constData(), irFunction->lineNumberMapping.size()*sizeof(CompiledData::CodeOffsetToLine));
// write QML dependencies
- CompiledData::LEUInt32 *writtenDeps = (CompiledData::LEUInt32 *)(f + function->dependingIdObjectsOffset);
+ quint32_le *writtenDeps = (quint32_le *)(f + function->dependingIdObjectsOffset);
for (int id : irFunction->idObjectDependencies) {
Q_ASSERT(id >= 0);
*writtenDeps++ = static_cast<quint32>(id);
}
- writtenDeps = (CompiledData::LEUInt32 *)(f + function->dependingContextPropertiesOffset);
+ writtenDeps = (quint32_le *)(f + function->dependingContextPropertiesOffset);
for (auto property : irFunction->contextObjectPropertyDependencies) {
*writtenDeps++ = property.key(); // property index
*writtenDeps++ = property.value(); // notify index
}
- writtenDeps = (CompiledData::LEUInt32 *)(f + function->dependingScopePropertiesOffset);
+ writtenDeps = (quint32_le *)(f + function->dependingScopePropertiesOffset);
for (auto property : irFunction->scopeObjectPropertyDependencies) {
*writtenDeps++ = property.key(); // property index
*writtenDeps++ = property.value(); // notify index
}
+
+ // write byte code
+ memcpy(f + function->codeOffset, irFunction->code.constData(), irFunction->code.size());
}
-QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Compiler::JSUnitGenerator::GeneratorOption option, QJsonPrivate::q_littleendian<quint32> *functionOffsets, uint *jsClassDataOffset)
+QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Compiler::JSUnitGenerator::GeneratorOption option, quint32_le *functionOffsets, uint *jsClassDataOffset)
{
CompiledData::Unit unit;
memset(&unit, 0, sizeof(unit));
memcpy(unit.magic, CompiledData::magic_str, sizeof(unit.magic));
unit.flags = QV4::CompiledData::Unit::IsJavascript;
- unit.flags |= irModule->unitFlags;
+ unit.flags |= module->unitFlags;
unit.version = QV4_DATA_STRUCTURE_VERSION;
unit.qtVersion = QT_VERSION;
memset(unit.md5Checksum, 0, sizeof(unit.md5Checksum));
- unit.architectureIndex = registerString(irModule->targetABI.isEmpty() ? QSysInfo::buildAbi() : irModule->targetABI);
- unit.codeGeneratorIndex = registerString(codeGeneratorName);
memset(unit.dependencyMD5Checksum, 0, sizeof(unit.dependencyMD5Checksum));
quint32 nextOffset = sizeof(CompiledData::Unit);
- unit.functionTableSize = irModule->functions.size();
+ unit.functionTableSize = module->functions.size();
unit.offsetToFunctionTable = nextOffset;
nextOffset += unit.functionTableSize * sizeof(uint);
@@ -409,13 +427,14 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp
nextOffset = (nextOffset + 7) & ~quint32(0x7);
- for (int i = 0; i < irModule->functions.size(); ++i) {
- QV4::IR::Function *f = irModule->functions.at(i);
+ for (int i = 0; i < module->functions.size(); ++i) {
+ Context *f = module->functions.at(i);
functionOffsets[i] = nextOffset;
const int qmlIdDepsCount = f->idObjectDependencies.count();
const int qmlPropertyDepsCount = f->scopeObjectPropertyDependencies.count() + f->contextObjectPropertyDependencies.count();
- nextOffset += QV4::CompiledData::Function::calculateSize(f->formals.size(), f->locals.size(), f->nestedFunctions.size(), qmlIdDepsCount, qmlPropertyDepsCount);
+ nextOffset += QV4::CompiledData::Function::calculateSize(f->arguments.size(), f->locals.size(), f->lineNumberMapping.size(), f->nestedContexts.size(),
+ qmlIdDepsCount, qmlPropertyDepsCount, f->code.size());
}
if (option == GenerateWithStringTable) {
@@ -427,9 +446,9 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp
unit.offsetToStringTable = 0;
}
unit.indexOfRootFunction = -1;
- unit.sourceFileIndex = getStringId(irModule->fileName);
- unit.finalUrlIndex = getStringId(irModule->finalUrl);
- unit.sourceTimeStamp = irModule->sourceTimeStamp.isValid() ? irModule->sourceTimeStamp.toMSecsSinceEpoch() : 0;
+ unit.sourceFileIndex = getStringId(module->fileName);
+ unit.finalUrlIndex = getStringId(module->finalUrl);
+ unit.sourceTimeStamp = module->sourceTimeStamp.isValid() ? module->sourceTimeStamp.toMSecsSinceEpoch() : 0;
unit.nImports = 0;
unit.offsetToImports = 0;
unit.nObjects = 0;
diff --git a/src/qml/compiler/qv4compiler_p.h b/src/qml/compiler/qv4compiler_p.h
index 49b8664513..360af6540f 100644
--- a/src/qml/compiler/qv4compiler_p.h
+++ b/src/qml/compiler/qv4compiler_p.h
@@ -51,8 +51,11 @@
//
#include <QtCore/qstring.h>
-#include "qv4jsir_p.h"
-#include <private/qjson_p.h>
+#include <QtCore/qhash.h>
+#include <QtCore/qstringlist.h>
+#include <private/qv4global_p.h>
+#include <private/qqmljsastfwd_p.h>
+#include <private/qv4compileddata_p.h>
QT_BEGIN_NAMESPACE
@@ -90,23 +93,31 @@ private:
};
struct Q_QML_PRIVATE_EXPORT JSUnitGenerator {
- JSUnitGenerator(IR::Module *module);
+ struct MemberInfo {
+ QString name;
+ bool isAccessor;
+ };
+
+ JSUnitGenerator(Module *module);
int registerString(const QString &str) { return stringTable.registerString(str); }
int getStringId(const QString &string) const { return stringTable.getStringId(string); }
QString stringForIndex(int index) const { return stringTable.stringForIndex(index); }
- uint registerGetterLookup(const QString &name);
- uint registerSetterLookup(const QString &name);
- uint registerGlobalGetterLookup(const QString &name);
- uint registerIndexedGetterLookup();
- uint registerIndexedSetterLookup();
+ int registerGetterLookup(const QString &name);
+ int registerGetterLookup(int nameIndex);
+ int registerSetterLookup(const QString &name);
+ int registerSetterLookup(int nameIndex);
+ int registerGlobalGetterLookup(const QString &name);
+ int registerGlobalGetterLookup(int nameIndex);
- int registerRegExp(IR::RegExp *regexp);
+ int registerRegExp(QQmlJS::AST::RegExpLiteral *regexp);
int registerConstant(ReturnedValue v);
+ ReturnedValue constant(int idx);
- int registerJSClass(int count, IR::ExprList *args);
+ int registerJSClass(const QVector<MemberInfo> &members);
+ int registerJSClass(int count, CompiledData::JSClassMember *members);
enum GeneratorOption {
GenerateWithStringTable,
@@ -115,14 +126,14 @@ struct Q_QML_PRIVATE_EXPORT JSUnitGenerator {
QV4::CompiledData::Unit *generateUnit(GeneratorOption option = GenerateWithStringTable);
// Returns bytes written
- void writeFunction(char *f, IR::Function *irFunction) const;
+ void writeFunction(char *f, Context *irFunction) const;
StringTableGenerator stringTable;
QString codeGeneratorName;
private:
- CompiledData::Unit generateHeader(GeneratorOption option, QJsonPrivate::q_littleendian<quint32> *functionOffsets, uint *jsClassDataOffset);
+ CompiledData::Unit generateHeader(GeneratorOption option, quint32_le *functionOffsets, uint *jsClassDataOffset);
- IR::Module *irModule;
+ Module *module;
QList<CompiledData::Lookup> lookups;
QVector<CompiledData::RegExp> regexps;
diff --git a/src/qml/compiler/qv4compilercontext.cpp b/src/qml/compiler/qv4compilercontext.cpp
new file mode 100644
index 0000000000..3293dc53c8
--- /dev/null
+++ b/src/qml/compiler/qv4compilercontext.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qv4compilercontext_p.h"
+#include "qv4compilercontrolflow_p.h"
+
+QT_USE_NAMESPACE
+using namespace QV4;
+using namespace QV4::Compiler;
+using namespace QQmlJS::AST;
+
+QT_BEGIN_NAMESPACE
+
+Context *Module::newContext(Node *node, Context *parent, CompilationMode compilationMode)
+{
+ Context *c = new Context(parent, compilationMode);
+ if (node) {
+ SourceLocation loc = node->firstSourceLocation();
+ c->line = loc.startLine;
+ c->column = loc.startColumn;
+ }
+
+ contextMap.insert(node, c);
+
+ if (!parent)
+ rootContext = c;
+ else {
+ parent->nestedContexts.append(c);
+ c->isStrict = parent->isStrict;
+ }
+
+ return c;
+}
+
+bool Context::forceLookupByName()
+{
+ ControlFlow *flow = controlFlow;
+ while (flow) {
+ if (flow->needsLookupByName)
+ return true;
+ flow = flow->parent;
+ }
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/qml/compiler/qv4compilercontext_p.h b/src/qml/compiler/qv4compilercontext_p.h
new file mode 100644
index 0000000000..bd68ea513e
--- /dev/null
+++ b/src/qml/compiler/qv4compilercontext_p.h
@@ -0,0 +1,290 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QV4COMPILERCONTEXT_P_H
+#define QV4COMPILERCONTEXT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "private/qv4global_p.h"
+#include <private/qqmljsast_p.h>
+#include <private/qv4compileddata_p.h>
+#include <QtCore/QStringList>
+#include <QtCore/QDateTime>
+#include <QtCore/QStack>
+#include <QtCore/QHash>
+
+QT_BEGIN_NAMESPACE
+
+namespace QV4 {
+
+namespace Compiler {
+
+struct ControlFlow;
+
+enum CompilationMode {
+ GlobalCode,
+ EvalCode,
+ FunctionCode,
+ QmlBinding // This is almost the same as EvalCode, except:
+ // * function declarations are moved to the return address when encountered
+ // * return statements are allowed everywhere (like in FunctionCode)
+ // * variable declarations are treated as true locals (like in FunctionCode)
+};
+
+struct Context;
+
+struct Module {
+ Module(bool debugMode)
+ : debugMode(debugMode)
+ {}
+ ~Module() {
+ qDeleteAll(contextMap);
+ }
+
+ Context *newContext(QQmlJS::AST::Node *node, Context *parent, CompilationMode compilationMode);
+
+ QHash<QQmlJS::AST::Node *, Context *> contextMap;
+ QList<Context *> functions;
+ Context *rootContext;
+ QString fileName;
+ QString finalUrl;
+ QDateTime sourceTimeStamp;
+ uint unitFlags = 0; // flags merged into CompiledData::Unit::flags
+ bool debugMode = false;
+};
+
+
+struct Context {
+ Context *parent;
+ QString name;
+ int line = 0;
+ int column = 0;
+ int registerCount = 0;
+ int functionIndex = -1;
+
+ enum MemberType {
+ UndefinedMember,
+ ThisFunctionName,
+ VariableDefinition,
+ VariableDeclaration,
+ FunctionDefinition
+ };
+
+ struct Member {
+ MemberType type = UndefinedMember;
+ int index = -1;
+ QQmlJS::AST::VariableDeclaration::VariableScope scope = QQmlJS::AST::VariableDeclaration::FunctionScope;
+ mutable bool canEscape = false;
+ QQmlJS::AST::FunctionExpression *function = 0;
+
+ bool isLexicallyScoped() const { return this->scope != QQmlJS::AST::VariableDeclaration::FunctionScope; }
+ };
+ typedef QMap<QString, Member> MemberMap;
+
+ MemberMap members;
+ QSet<QString> usedVariables;
+ QQmlJS::AST::FormalParameterList *formals = 0;
+ QStringList arguments;
+ QStringList locals;
+ QVector<Context *> nestedContexts;
+
+ ControlFlow *controlFlow = 0;
+ QByteArray code;
+ QVector<CompiledData::CodeOffsetToLine> lineNumberMapping;
+
+ int maxNumberOfArguments = 0;
+ bool hasDirectEval = false;
+ bool hasNestedFunctions = false;
+ bool isStrict = false;
+ bool usesThis = false;
+ bool hasTry = false;
+ bool hasWith = false;
+ mutable bool argumentsCanEscape = false;
+
+ enum UsesArgumentsObject {
+ ArgumentsObjectUnknown,
+ ArgumentsObjectNotUsed,
+ ArgumentsObjectUsed
+ };
+
+ UsesArgumentsObject usesArgumentsObject = ArgumentsObjectUnknown;
+
+ CompilationMode compilationMode;
+
+ template <typename T>
+ class SmallSet: public QVarLengthArray<T, 8>
+ {
+ public:
+ void insert(int value)
+ {
+ for (auto it : *this) {
+ if (it == value)
+ return;
+ }
+ this->append(value);
+ }
+ };
+
+ // Map from meta property index (existence implies dependency) to notify signal index
+ struct KeyValuePair
+ {
+ quint32 _key;
+ quint32 _value;
+
+ KeyValuePair(): _key(0), _value(0) {}
+ KeyValuePair(quint32 key, quint32 value): _key(key), _value(value) {}
+
+ quint32 key() const { return _key; }
+ quint32 value() const { return _value; }
+ };
+
+ class PropertyDependencyMap: public QVarLengthArray<KeyValuePair, 8>
+ {
+ public:
+ void insert(quint32 key, quint32 value)
+ {
+ for (auto it = begin(), eit = end(); it != eit; ++it) {
+ if (it->_key == key) {
+ it->_value = value;
+ return;
+ }
+ }
+ append(KeyValuePair(key, value));
+ }
+ };
+
+ // Qml extension:
+ SmallSet<int> idObjectDependencies;
+ PropertyDependencyMap contextObjectPropertyDependencies;
+ PropertyDependencyMap scopeObjectPropertyDependencies;
+
+ Context(Context *parent, CompilationMode mode)
+ : parent(parent)
+ , compilationMode(mode)
+ {
+ if (parent && parent->isStrict)
+ isStrict = true;
+ }
+
+ bool forceLookupByName();
+
+
+ bool canUseSimpleCall() const {
+ return nestedContexts.isEmpty() &&
+ locals.isEmpty() &&
+ !hasTry && !hasWith &&
+ (usesArgumentsObject == ArgumentsObjectNotUsed || isStrict) && !hasDirectEval;
+ }
+
+ int findArgument(const QString &name)
+ {
+ // search backwards to handle duplicate argument names correctly
+ for (int i = arguments.size() - 1; i >= 0; --i) {
+ if (arguments.at(i) == name)
+ return i;
+ }
+ return -1;
+ }
+
+ Member findMember(const QString &name) const
+ {
+ MemberMap::const_iterator it = members.find(name);
+ if (it == members.end())
+ return Member();
+ Q_ASSERT(it->index != -1 || !parent);
+ return (*it);
+ }
+
+ bool memberInfo(const QString &name, const Member **m) const
+ {
+ Q_ASSERT(m);
+ MemberMap::const_iterator it = members.find(name);
+ if (it == members.end()) {
+ *m = 0;
+ return false;
+ }
+ *m = &(*it);
+ return true;
+ }
+
+ void addUsedVariable(const QString &name) {
+ usedVariables.insert(name);
+ }
+
+ void addLocalVar(const QString &name, MemberType type, QQmlJS::AST::VariableDeclaration::VariableScope scope, QQmlJS::AST::FunctionExpression *function = 0)
+ {
+ if (! name.isEmpty()) {
+ if (type != FunctionDefinition) {
+ for (QQmlJS::AST::FormalParameterList *it = formals; it; it = it->next)
+ if (it->name == name)
+ return;
+ }
+ MemberMap::iterator it = members.find(name);
+ if (it == members.end()) {
+ Member m;
+ m.type = type;
+ m.function = function;
+ m.scope = scope;
+ members.insert(name, m);
+ } else {
+ Q_ASSERT(scope == (*it).scope);
+ if ((*it).type <= type) {
+ (*it).type = type;
+ (*it).function = function;
+ }
+ }
+ }
+ }
+};
+
+
+} } // namespace QV4::Compiler
+
+QT_END_NAMESPACE
+
+#endif // QV4CODEGEN_P_H
diff --git a/src/qml/compiler/qv4compilercontrolflow_p.h b/src/qml/compiler/qv4compilercontrolflow_p.h
new file mode 100644
index 0000000000..13716fe29f
--- /dev/null
+++ b/src/qml/compiler/qv4compilercontrolflow_p.h
@@ -0,0 +1,467 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QV4COMPILERCONTROLFLOW_P_H
+#define QV4COMPILERCONTROLFLOW_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qv4global_p.h>
+#include <private/qv4codegen_p.h>
+#include <private/qqmljsast_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QV4 {
+
+namespace Compiler {
+
+struct ControlFlow {
+ using Reference = Codegen::Reference;
+ using BytecodeGenerator = Moth::BytecodeGenerator;
+ using Instruction = Moth::Instruction;
+
+ enum Type {
+ Loop,
+ With,
+ Finally,
+ Catch
+ };
+
+ enum HandlerType {
+ Invalid,
+ Break,
+ Continue,
+ Return,
+ Throw
+ };
+
+ struct Handler {
+ HandlerType type;
+ QString label;
+ BytecodeGenerator::Label linkLabel;
+ int tempIndex;
+ int value;
+ };
+
+ Codegen *cg;
+ ControlFlow *parent;
+ Type type;
+ bool needsLookupByName = false;
+
+ ControlFlow(Codegen *cg, Type type)
+ : cg(cg), parent(cg->_context->controlFlow), type(type)
+ {
+ cg->_context->controlFlow = this;
+ }
+
+ virtual ~ControlFlow() {
+ cg->_context->controlFlow = parent;
+ }
+
+ void emitReturnStatement() const {
+ if (cg->_returnAddress >= 0) {
+ Instruction::LoadReg load;
+ load.reg = Moth::StackSlot::createRegister(cg->_returnAddress);
+ generator()->addInstruction(load);
+ }
+ Instruction::Ret ret;
+ cg->bytecodeGenerator->addInstruction(ret);
+ }
+
+ void jumpToHandler(const Handler &h) {
+ if (h.linkLabel.isReturn()) {
+ emitReturnStatement();
+ } else {
+ if (h.tempIndex >= 0)
+ Reference::storeConstOnStack(cg, QV4::Encode(h.value), h.tempIndex);
+ cg->bytecodeGenerator->jump().link(h.linkLabel);
+ }
+ }
+
+ bool returnRequiresUnwind() const {
+ const ControlFlow *f = this;
+ while (f) {
+ if (f->type == Finally)
+ return true;
+ f = f->parent;
+ }
+ return false;
+ }
+
+ virtual QString label() const { return QString(); }
+
+ bool isSimple() const {
+ return type == Loop;
+ }
+
+ Handler getParentHandler(HandlerType type, const QString &label = QString()) {
+ if (parent)
+ return parent->getHandler(type, label);
+ switch (type) {
+ case Break:
+ case Continue:
+ return { Invalid, QString(), {}, -1, 0 };
+ case Return:
+ case Throw:
+ return { type, QString(), BytecodeGenerator::Label::returnLabel(), -1, 0 };
+ case Invalid:
+ break;
+ }
+ Q_ASSERT(false);
+ Q_UNREACHABLE();
+ }
+
+ virtual Handler getHandler(HandlerType type, const QString &label = QString()) = 0;
+
+ BytecodeGenerator::ExceptionHandler *parentExceptionHandler() {
+ return parent ? parent->exceptionHandler() : 0;
+ }
+
+ virtual BytecodeGenerator::ExceptionHandler *exceptionHandler() {
+ return parentExceptionHandler();
+ }
+
+
+ virtual void handleThrow(const Reference &expr) {
+ Reference e = expr;
+ Handler h = getHandler(ControlFlow::Throw);
+ if (h.tempIndex >= 0) {
+ e = e.storeOnStack();
+ Reference::storeConstOnStack(cg, QV4::Encode(h.value), h.tempIndex);
+ }
+ e.loadInAccumulator();
+ Instruction::ThrowException instr;
+ generator()->addInstruction(instr);
+ }
+
+protected:
+ QString loopLabel() const {
+ QString label;
+ if (cg->_labelledStatement) {
+ label = cg->_labelledStatement->label.toString();
+ cg->_labelledStatement = 0;
+ }
+ return label;
+ }
+ BytecodeGenerator *generator() const {
+ return cg->bytecodeGenerator;
+ }
+};
+
+struct ControlFlowLoop : public ControlFlow
+{
+ QString loopLabel;
+ BytecodeGenerator::Label *breakLabel = 0;
+ BytecodeGenerator::Label *continueLabel = 0;
+
+ ControlFlowLoop(Codegen *cg, BytecodeGenerator::Label *breakLabel, BytecodeGenerator::Label *continueLabel = 0)
+ : ControlFlow(cg, Loop), loopLabel(ControlFlow::loopLabel()), breakLabel(breakLabel), continueLabel(continueLabel)
+ {
+ }
+
+ virtual QString label() const { return loopLabel; }
+
+ virtual Handler getHandler(HandlerType type, const QString &label = QString()) {
+ switch (type) {
+ case Break:
+ if (breakLabel && (label.isEmpty() || label == loopLabel))
+ return { type, loopLabel, *breakLabel, -1, 0 };
+ break;
+ case Continue:
+ if (continueLabel && (label.isEmpty() || label == loopLabel))
+ return { type, loopLabel, *continueLabel, -1, 0 };
+ break;
+ case Return:
+ case Throw:
+ break;
+ case Invalid:
+ Q_ASSERT(false);
+ Q_UNREACHABLE();
+ }
+ return getParentHandler(type, label);
+ }
+
+};
+
+struct ControlFlowUnwind : public ControlFlow
+{
+ BytecodeGenerator::ExceptionHandler unwindLabel;
+ int controlFlowTemp;
+ QVector<Handler> handlers;
+
+ ControlFlowUnwind(Codegen *cg, Type type)
+ : ControlFlow(cg, type), unwindLabel(generator()->newExceptionHandler())
+ {
+ Q_ASSERT(type != Loop);
+ controlFlowTemp = static_cast<int>(generator()->newRegister());
+ Reference::storeConstOnStack(cg, QV4::Encode::undefined(), controlFlowTemp);
+ // we'll need at least a handler for throw
+ getHandler(Throw);
+ }
+
+ void emitUnwindHandler()
+ {
+ Q_ASSERT(!isSimple());
+
+ Reference temp = Reference::fromStackSlot(cg, controlFlowTemp);
+ for (const auto &h : qAsConst(handlers)) {
+ Handler parentHandler = getParentHandler(h.type, h.label);
+
+ if (h.type == Throw || parentHandler.tempIndex >= 0) {
+ BytecodeGenerator::Label skip = generator()->newLabel();
+ generator()->jumpStrictNotEqualStackSlotInt(temp.stackSlot(), h.value).link(skip);
+ if (h.type == Throw)
+ emitForThrowHandling();
+ jumpToHandler(parentHandler);
+ skip.link();
+ } else {
+ if (parentHandler.linkLabel.isReturn()) {
+ BytecodeGenerator::Label skip = generator()->newLabel();
+ generator()->jumpStrictNotEqualStackSlotInt(temp.stackSlot(), h.value).link(skip);
+ emitReturnStatement();
+ skip.link();
+ } else {
+ generator()->jumpStrictEqualStackSlotInt(temp.stackSlot(), h.value).link(parentHandler.linkLabel);
+ }
+ }
+ }
+ }
+
+ virtual Handler getHandler(HandlerType type, const QString &label = QString()) {
+ for (const auto &h : qAsConst(handlers)) {
+ if (h.type == type && h.label == label)
+ return h;
+ }
+ Handler h = {
+ type,
+ label,
+ unwindLabel,
+ controlFlowTemp,
+ handlers.size()
+ };
+ handlers.append(h);
+ return h;
+ }
+
+ virtual BytecodeGenerator::ExceptionHandler *exceptionHandler() {
+ return &unwindLabel;
+ }
+
+ virtual void emitForThrowHandling() { }
+};
+
+struct ControlFlowWith : public ControlFlowUnwind
+{
+ ControlFlowWith(Codegen *cg)
+ : ControlFlowUnwind(cg, With)
+ {
+ needsLookupByName = true;
+
+ savedContextRegister = Moth::StackSlot::createRegister(generator()->newRegister());
+
+ // assumes the with object is in the accumulator
+ Instruction::PushWithContext pushScope;
+ pushScope.reg = savedContextRegister;
+ generator()->addInstruction(pushScope);
+ generator()->setExceptionHandler(&unwindLabel);
+ }
+
+ virtual ~ControlFlowWith() {
+ // emit code for unwinding
+ unwindLabel.link();
+
+ generator()->setExceptionHandler(parentExceptionHandler());
+ Instruction::PopContext pop;
+ pop.reg = savedContextRegister;
+ generator()->addInstruction(pop);
+
+ emitUnwindHandler();
+ }
+ Moth::StackSlot savedContextRegister;
+};
+
+struct ControlFlowCatch : public ControlFlowUnwind
+{
+ AST::Catch *catchExpression;
+ bool insideCatch = false;
+ BytecodeGenerator::ExceptionHandler exceptionLabel;
+ BytecodeGenerator::ExceptionHandler catchUnwindLabel;
+
+ ControlFlowCatch(Codegen *cg, AST::Catch *catchExpression)
+ : ControlFlowUnwind(cg, Catch), catchExpression(catchExpression),
+ exceptionLabel(generator()->newExceptionHandler()),
+ catchUnwindLabel(generator()->newExceptionHandler())
+ {
+ generator()->setExceptionHandler(&exceptionLabel);
+ }
+
+ virtual Handler getHandler(HandlerType type, const QString &label = QString()) {
+ Handler h = getParentHandler(type, label);
+ if (h.type == Invalid)
+ return h;
+ h = ControlFlowUnwind::getHandler(type, label);
+ if (insideCatch)
+ // if we're inside the catch block, we need to jump to the pop scope
+ // instruction at the end of the catch block, not the unwind handler
+ h.linkLabel = catchUnwindLabel;
+ else if (type == Throw)
+ // if we're inside the try block, we need to jump to the catch block,
+ // not the unwind handler
+ h.linkLabel = exceptionLabel;
+ return h;
+ }
+
+ virtual BytecodeGenerator::ExceptionHandler *exceptionHandler() {
+ return insideCatch ? &catchUnwindLabel : &exceptionLabel;
+ }
+
+ ~ControlFlowCatch() {
+ // emit code for unwinding
+
+ needsLookupByName = true;
+ insideCatch = true;
+
+ Codegen::RegisterScope scope(cg);
+
+ // exceptions inside the try block go here
+ exceptionLabel.link();
+ Moth::StackSlot savedContextReg = Moth::StackSlot::createRegister(generator()->newRegister());
+ Instruction::PushCatchContext pushCatch;
+ pushCatch.name = cg->registerString(catchExpression->name.toString());
+ pushCatch.reg = savedContextReg;
+ generator()->addInstruction(pushCatch);
+ // clear the unwind temp for exceptions, we want to resume normal code flow afterwards
+ Reference::storeConstOnStack(cg, QV4::Encode::undefined(), controlFlowTemp);
+ generator()->setExceptionHandler(&catchUnwindLabel);
+
+ cg->statement(catchExpression->statement);
+
+ insideCatch = false;
+ needsLookupByName = false;
+
+ // exceptions inside catch and break/return statements go here
+ catchUnwindLabel.link();
+ Instruction::PopContext pop;
+ pop.reg = savedContextReg;
+ generator()->addInstruction(pop);
+
+ // break/continue/return statements in try go here
+ unwindLabel.link();
+ generator()->setExceptionHandler(parentExceptionHandler());
+
+ emitUnwindHandler();
+ }
+};
+
+struct ControlFlowFinally : public ControlFlowUnwind
+{
+ AST::Finally *finally;
+ bool insideFinally = false;
+ int exceptionTemp = -1;
+
+ ControlFlowFinally(Codegen *cg, AST::Finally *finally)
+ : ControlFlowUnwind(cg, Finally), finally(finally)
+ {
+ Q_ASSERT(finally != 0);
+ generator()->setExceptionHandler(&unwindLabel);
+ }
+
+ virtual Handler getHandler(HandlerType type, const QString &label = QString()) {
+ // if we're inside the finally block, any exceptions etc. should
+ // go directly to the parent handler
+ if (insideFinally)
+ return getParentHandler(type, label);
+ return ControlFlowUnwind::getHandler(type, label);
+ }
+
+ virtual BytecodeGenerator::ExceptionHandler *exceptionHandler() {
+ return insideFinally ? parentExceptionHandler() : ControlFlowUnwind::exceptionHandler();
+ }
+
+ ~ControlFlowFinally() {
+ // emit code for unwinding
+ unwindLabel.link();
+
+ Codegen::RegisterScope scope(cg);
+
+ Moth::StackSlot retVal = Moth::StackSlot::createRegister(generator()->newRegister());
+ Instruction::StoreReg storeRetVal;
+ storeRetVal.reg = retVal;
+ generator()->addInstruction(storeRetVal);
+
+ insideFinally = true;
+ exceptionTemp = generator()->newRegister();
+ Instruction::GetException instr;
+ generator()->addInstruction(instr);
+ Reference::fromStackSlot(cg, exceptionTemp).storeConsumeAccumulator();
+
+ generator()->setExceptionHandler(parentExceptionHandler());
+ cg->statement(finally->statement);
+ insideFinally = false;
+
+ Instruction::LoadReg loadRetVal;
+ loadRetVal.reg = retVal;
+ generator()->addInstruction(loadRetVal);
+
+ emitUnwindHandler();
+ }
+
+ virtual void emitForThrowHandling() {
+ // reset the exception flag, that got cleared before executing the statements in finally
+ Reference::fromStackSlot(cg, exceptionTemp).loadInAccumulator();
+ Instruction::SetException setException;
+ Q_ASSERT(exceptionTemp != -1);
+ generator()->addInstruction(setException);
+ }
+};
+
+} } // QV4::Compiler namespace
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qml/compiler/qv4compilerscanfunctions.cpp b/src/qml/compiler/qv4compilerscanfunctions.cpp
new file mode 100644
index 0000000000..808e79959d
--- /dev/null
+++ b/src/qml/compiler/qv4compilerscanfunctions.cpp
@@ -0,0 +1,479 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qv4compilerscanfunctions_p.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QStringList>
+#include <QtCore/QSet>
+#include <QtCore/QBuffer>
+#include <QtCore/QBitArray>
+#include <QtCore/QLinkedList>
+#include <QtCore/QStack>
+#include <private/qqmljsast_p.h>
+#include <private/qv4compilercontext_p.h>
+#include <private/qv4codegen_p.h>
+#include <private/qv4string_p.h>
+
+QT_USE_NAMESPACE
+using namespace QV4;
+using namespace QV4::Compiler;
+using namespace QQmlJS::AST;
+
+ScanFunctions::ScanFunctions(Codegen *cg, const QString &sourceCode, CompilationMode defaultProgramMode)
+ : _cg(cg)
+ , _sourceCode(sourceCode)
+ , _context(0)
+ , _allowFuncDecls(true)
+ , defaultProgramMode(defaultProgramMode)
+{
+}
+
+void ScanFunctions::operator()(Node *node)
+{
+ if (node)
+ node->accept(this);
+
+ calcEscapingVariables();
+}
+
+void ScanFunctions::enterEnvironment(Node *node, CompilationMode compilationMode)
+{
+ Context *e = _cg->_module->newContext(node, _context, compilationMode);
+ if (!e->isStrict)
+ e->isStrict = _cg->_strictMode;
+ _contextStack.append(e);
+ _context = e;
+}
+
+void ScanFunctions::leaveEnvironment()
+{
+ _contextStack.pop();
+ _context = _contextStack.isEmpty() ? 0 : _contextStack.top();
+}
+
+void ScanFunctions::checkDirectivePrologue(SourceElements *ast)
+{
+ for (SourceElements *it = ast; it; it = it->next) {
+ if (StatementSourceElement *stmt = cast<StatementSourceElement *>(it->element)) {
+ if (ExpressionStatement *expr = cast<ExpressionStatement *>(stmt->statement)) {
+ if (StringLiteral *strLit = cast<StringLiteral *>(expr->expression)) {
+ // Use the source code, because the StringLiteral's
+ // value might have escape sequences in it, which is not
+ // allowed.
+ if (strLit->literalToken.length < 2)
+ continue;
+ QStringRef str = _sourceCode.midRef(strLit->literalToken.offset + 1, strLit->literalToken.length - 2);
+ if (str == QLatin1String("use strict")) {
+ _context->isStrict = true;
+ } else {
+ // TODO: give a warning.
+ }
+ continue;
+ }
+ }
+ }
+
+ break;
+ }
+}
+
+void ScanFunctions::checkName(const QStringRef &name, const SourceLocation &loc)
+{
+ if (_context->isStrict) {
+ if (name == QLatin1String("implements")
+ || name == QLatin1String("interface")
+ || name == QLatin1String("let")
+ || name == QLatin1String("package")
+ || name == QLatin1String("private")
+ || name == QLatin1String("protected")
+ || name == QLatin1String("public")
+ || name == QLatin1String("static")
+ || name == QLatin1String("yield")) {
+ _cg->throwSyntaxError(loc, QStringLiteral("Unexpected strict mode reserved word"));
+ }
+ }
+}
+
+bool ScanFunctions::formalsContainName(AST::FormalParameterList *parameters, const QString &name)
+{
+ while (parameters) {
+ if (parameters->name == name)
+ return true;
+ parameters = parameters->next;
+ }
+ return false;
+}
+
+bool ScanFunctions::visit(Program *ast)
+{
+ enterEnvironment(ast, defaultProgramMode);
+ checkDirectivePrologue(ast->elements);
+ return true;
+}
+
+void ScanFunctions::endVisit(Program *)
+{
+ leaveEnvironment();
+}
+
+bool ScanFunctions::visit(CallExpression *ast)
+{
+ if (! _context->hasDirectEval) {
+ if (IdentifierExpression *id = cast<IdentifierExpression *>(ast->base)) {
+ if (id->name == QLatin1String("eval")) {
+ if (_context->usesArgumentsObject == Context::ArgumentsObjectUnknown)
+ _context->usesArgumentsObject = Context::ArgumentsObjectUsed;
+ _context->hasDirectEval = true;
+ }
+ }
+ }
+ int argc = 0;
+ for (ArgumentList *it = ast->arguments; it; it = it->next)
+ ++argc;
+ _context->maxNumberOfArguments = qMax(_context->maxNumberOfArguments, argc);
+ return true;
+}
+
+bool ScanFunctions::visit(NewMemberExpression *ast)
+{
+ int argc = 0;
+ for (ArgumentList *it = ast->arguments; it; it = it->next)
+ ++argc;
+ _context->maxNumberOfArguments = qMax(_context->maxNumberOfArguments, argc);
+ return true;
+}
+
+bool ScanFunctions::visit(ArrayLiteral *ast)
+{
+ int index = 0;
+ for (ElementList *it = ast->elements; it; it = it->next) {
+ for (Elision *elision = it->elision; elision; elision = elision->next)
+ ++index;
+ ++index;
+ }
+ if (ast->elision) {
+ for (Elision *elision = ast->elision->next; elision; elision = elision->next)
+ ++index;
+ }
+ _context->maxNumberOfArguments = qMax(_context->maxNumberOfArguments, index);
+ return true;
+}
+
+bool ScanFunctions::visit(VariableDeclaration *ast)
+{
+ if (_context->isStrict && (ast->name == QLatin1String("eval") || ast->name == QLatin1String("arguments")))
+ _cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Variable name may not be eval or arguments in strict mode"));
+ checkName(ast->name, ast->identifierToken);
+ if (ast->name == QLatin1String("arguments"))
+ _context->usesArgumentsObject = Context::ArgumentsObjectNotUsed;
+ if (ast->scope == AST::VariableDeclaration::VariableScope::ReadOnlyBlockScope && !ast->expression) {
+ _cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Missing initializer in const declaration"));
+ return false;
+ }
+ QString name = ast->name.toString();
+ const Context::Member *m = 0;
+ if (_context->memberInfo(name, &m)) {
+ if (m->isLexicallyScoped() || ast->isLexicallyScoped()) {
+ _cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Identifier %1 has already been declared").arg(name));
+ return false;
+ }
+ }
+ _context->addLocalVar(ast->name.toString(), ast->expression ? Context::VariableDefinition : Context::VariableDeclaration, ast->scope);
+ return true;
+}
+
+bool ScanFunctions::visit(IdentifierExpression *ast)
+{
+ checkName(ast->name, ast->identifierToken);
+ if (_context->usesArgumentsObject == Context::ArgumentsObjectUnknown && ast->name == QLatin1String("arguments"))
+ _context->usesArgumentsObject = Context::ArgumentsObjectUsed;
+ _context->addUsedVariable(ast->name.toString());
+ return true;
+}
+
+bool ScanFunctions::visit(ExpressionStatement *ast)
+{
+ if (FunctionExpression* expr = AST::cast<AST::FunctionExpression*>(ast->expression)) {
+ if (!_allowFuncDecls)
+ _cg->throwSyntaxError(expr->functionToken, QStringLiteral("conditional function or closure declaration"));
+
+ enterFunction(expr, /*enterName*/ true);
+ Node::accept(expr->formals, this);
+ Node::accept(expr->body, this);
+ leaveEnvironment();
+ return false;
+ } else {
+ SourceLocation firstToken = ast->firstSourceLocation();
+ if (_sourceCode.midRef(firstToken.offset, firstToken.length) == QLatin1String("function")) {
+ _cg->throwSyntaxError(firstToken, QStringLiteral("unexpected token"));
+ }
+ }
+ return true;
+}
+
+bool ScanFunctions::visit(FunctionExpression *ast)
+{
+ enterFunction(ast, /*enterName*/ false);
+ return true;
+}
+
+void ScanFunctions::enterFunction(FunctionExpression *ast, bool enterName)
+{
+ if (_context->isStrict && (ast->name == QLatin1String("eval") || ast->name == QLatin1String("arguments")))
+ _cg->throwSyntaxError(ast->identifierToken, QStringLiteral("Function name may not be eval or arguments in strict mode"));
+ enterFunction(ast, ast->name.toString(), ast->formals, ast->body, enterName ? ast : 0);
+}
+
+void ScanFunctions::endVisit(FunctionExpression *)
+{
+ leaveEnvironment();
+}
+
+bool ScanFunctions::visit(ObjectLiteral *ast)
+{
+ int argc = 0;
+ for (PropertyAssignmentList *it = ast->properties; it; it = it->next) {
+ QString key = it->assignment->name->asString();
+ if (QV4::String::toArrayIndex(key) != UINT_MAX)
+ ++argc;
+ ++argc;
+ if (AST::cast<AST::PropertyGetterSetter *>(it->assignment))
+ ++argc;
+ }
+ _context->maxNumberOfArguments = qMax(_context->maxNumberOfArguments, argc);
+
+ TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, true);
+ Node::accept(ast->properties, this);
+ return false;
+}
+
+bool ScanFunctions::visit(PropertyGetterSetter *ast)
+{
+ TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, true);
+ enterFunction(ast, QString(), ast->formals, ast->functionBody, /*FunctionExpression*/0);
+ return true;
+}
+
+void ScanFunctions::endVisit(PropertyGetterSetter *)
+{
+ leaveEnvironment();
+}
+
+bool ScanFunctions::visit(FunctionDeclaration *ast)
+{
+ enterFunction(ast, /*enterName*/ true);
+ return true;
+}
+
+void ScanFunctions::endVisit(FunctionDeclaration *)
+{
+ leaveEnvironment();
+}
+
+bool ScanFunctions::visit(TryStatement *)
+{
+ // ### should limit to catch(), as try{} finally{} should be ok without
+ _context->hasTry = true;
+ return true;
+}
+
+bool ScanFunctions::visit(WithStatement *ast)
+{
+ if (_context->isStrict) {
+ _cg->throwSyntaxError(ast->withToken, QStringLiteral("'with' statement is not allowed in strict mode"));
+ return false;
+ }
+
+ _context->hasWith = true;
+ return true;
+}
+
+bool ScanFunctions::visit(DoWhileStatement *ast) {
+ {
+ TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, !_context->isStrict);
+ Node::accept(ast->statement, this);
+ }
+ Node::accept(ast->expression, this);
+ return false;
+}
+
+bool ScanFunctions::visit(ForStatement *ast) {
+ Node::accept(ast->initialiser, this);
+ Node::accept(ast->condition, this);
+ Node::accept(ast->expression, this);
+
+ TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, !_context->isStrict);
+ Node::accept(ast->statement, this);
+
+ return false;
+}
+
+bool ScanFunctions::visit(LocalForStatement *ast) {
+ Node::accept(ast->declarations, this);
+ Node::accept(ast->condition, this);
+ Node::accept(ast->expression, this);
+
+ TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, !_context->isStrict);
+ Node::accept(ast->statement, this);
+
+ return false;
+}
+
+bool ScanFunctions::visit(ForEachStatement *ast) {
+ Node::accept(ast->initialiser, this);
+ Node::accept(ast->expression, this);
+
+ TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, !_context->isStrict);
+ Node::accept(ast->statement, this);
+
+ return false;
+}
+
+bool ScanFunctions::visit(LocalForEachStatement *ast) {
+ Node::accept(ast->declaration, this);
+ Node::accept(ast->expression, this);
+
+ TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, !_context->isStrict);
+ Node::accept(ast->statement, this);
+
+ return false;
+}
+
+bool ScanFunctions::visit(ThisExpression *)
+{
+ _context->usesThis = true;
+ return false;
+}
+
+bool ScanFunctions::visit(Block *ast) {
+ TemporaryBoolAssignment allowFuncDecls(_allowFuncDecls, _context->isStrict ? false : _allowFuncDecls);
+ Node::accept(ast->statements, this);
+ return false;
+}
+
+void ScanFunctions::enterFunction(Node *ast, const QString &name, FormalParameterList *formals, FunctionBody *body, FunctionExpression *expr)
+{
+ if (_context) {
+ _context->hasNestedFunctions = true;
+ // The identifier of a function expression cannot be referenced from the enclosing environment.
+ if (expr)
+ _context->addLocalVar(name, Context::FunctionDefinition, AST::VariableDeclaration::FunctionScope, expr);
+ if (name == QLatin1String("arguments"))
+ _context->usesArgumentsObject = Context::ArgumentsObjectNotUsed;
+ }
+
+ enterEnvironment(ast, FunctionCode);
+ if (formalsContainName(formals, QStringLiteral("arguments")))
+ _context->usesArgumentsObject = Context::ArgumentsObjectNotUsed;
+
+
+ if (!name.isEmpty() && !formalsContainName(formals, name))
+ _context->addLocalVar(name, Context::ThisFunctionName, QQmlJS::AST::VariableDeclaration::FunctionScope);
+ _context->formals = formals;
+
+ if (body && !_context->isStrict)
+ checkDirectivePrologue(body->elements);
+
+ for (FormalParameterList *it = formals; it; it = it->next) {
+ QString arg = it->name.toString();
+ int duplicateIndex = _context->arguments.indexOf(arg);
+ if (duplicateIndex != -1) {
+ if (_context->isStrict) {
+ _cg->throwSyntaxError(it->identifierToken, QStringLiteral("Duplicate parameter name '%1' is not allowed in strict mode").arg(arg));
+ return;
+ } else {
+ // change the name of the earlier argument to enforce the specified lookup semantics
+ QString modified = arg;
+ while (_context->arguments.contains(modified))
+ modified += QString(0xfffe);
+ _context->arguments[duplicateIndex] = modified;
+ }
+ }
+ if (_context->isStrict) {
+ if (arg == QLatin1String("eval") || arg == QLatin1String("arguments")) {
+ _cg->throwSyntaxError(it->identifierToken, QStringLiteral("'%1' cannot be used as parameter name in strict mode").arg(arg));
+ return;
+ }
+ }
+ _context->arguments += arg;
+ }
+}
+
+void ScanFunctions::calcEscapingVariables()
+{
+ Module *m = _cg->_module;
+
+ for (Context *inner : m->contextMap) {
+ for (const QString &var : qAsConst(inner->usedVariables)) {
+ Context *c = inner;
+ while (c) {
+ Context::MemberMap::const_iterator it = c->members.find(var);
+ if (it != c->members.end()) {
+ if (c != inner)
+ it->canEscape = true;
+ break;
+ }
+ if (c->findArgument(var) != -1) {
+ if (c != inner)
+ c->argumentsCanEscape = true;
+ break;
+ }
+ c = c->parent;
+ }
+ }
+ Context *c = inner->parent;
+ while (c) {
+ c->hasDirectEval |= inner->hasDirectEval;
+ c = c->parent;
+ }
+ }
+
+ static const bool showEscapingVars = qEnvironmentVariableIsSet("QV4_SHOW_ESCAPING_VARS");
+ if (showEscapingVars) {
+ qDebug() << "==== escaping variables ====";
+ for (Context *c : m->contextMap) {
+ qDebug() << "Context" << c->name << ":";
+ qDebug() << " Arguments escape" << c->argumentsCanEscape;
+ for (auto it = c->members.constBegin(); it != c->members.constEnd(); ++it) {
+ qDebug() << " " << it.key() << it.value().canEscape;
+ }
+ }
+ }
+}
diff --git a/src/qml/compiler/qv4compilerscanfunctions_p.h b/src/qml/compiler/qv4compilerscanfunctions_p.h
new file mode 100644
index 0000000000..526278fdd8
--- /dev/null
+++ b/src/qml/compiler/qv4compilerscanfunctions_p.h
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QV4COMPILERSCANFUNCTIONS_P_H
+#define QV4COMPILERSCANFUNCTIONS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "private/qv4global_p.h"
+#include <private/qqmljsastvisitor_p.h>
+#include <private/qqmljsast_p.h>
+#include <private/qqmljsengine_p.h>
+#include <private/qv4compilercontext_p.h>
+#include <private/qv4util_p.h>
+#include <QtCore/QStringList>
+#include <QStack>
+
+QT_BEGIN_NAMESPACE
+
+using namespace QQmlJS;
+
+namespace QV4 {
+
+namespace Moth {
+struct Instruction;
+}
+
+namespace CompiledData {
+struct CompilationUnit;
+}
+
+namespace Compiler {
+
+class Codegen;
+
+class ScanFunctions: protected QQmlJS::AST::Visitor
+{
+ typedef QV4::TemporaryAssignment<bool> TemporaryBoolAssignment;
+public:
+ ScanFunctions(Codegen *cg, const QString &sourceCode, CompilationMode defaultProgramMode);
+ void operator()(AST::Node *node);
+
+ void enterEnvironment(AST::Node *node, CompilationMode compilationMode);
+ void leaveEnvironment();
+
+ void enterQmlScope(AST::Node *ast, const QString &name)
+ { enterFunction(ast, name, /*formals*/0, /*body*/0, /*expr*/0); }
+
+ void enterQmlFunction(AST::FunctionDeclaration *ast)
+ { enterFunction(ast, false); }
+
+protected:
+ using Visitor::visit;
+ using Visitor::endVisit;
+
+ void checkDirectivePrologue(AST::SourceElements *ast);
+
+ void checkName(const QStringRef &name, const AST::SourceLocation &loc);
+ bool formalsContainName(AST::FormalParameterList *parameters, const QString &name);
+
+ bool visit(AST::Program *ast) override;
+ void endVisit(AST::Program *) override;
+
+ bool visit(AST::CallExpression *ast) override;
+ bool visit(AST::NewMemberExpression *ast) override;
+ bool visit(AST::ArrayLiteral *ast) override;
+ bool visit(AST::VariableDeclaration *ast) override;
+ bool visit(AST::IdentifierExpression *ast) override;
+ bool visit(AST::ExpressionStatement *ast) override;
+ bool visit(AST::FunctionExpression *ast) override;
+
+ void enterFunction(AST::FunctionExpression *ast, bool enterName);
+
+ void endVisit(AST::FunctionExpression *) override;
+
+ bool visit(AST::ObjectLiteral *ast) override;
+
+ bool visit(AST::PropertyGetterSetter *ast) override;
+ void endVisit(AST::PropertyGetterSetter *) override;
+
+ bool visit(AST::FunctionDeclaration *ast) override;
+ void endVisit(AST::FunctionDeclaration *) override;
+
+ bool visit(AST::TryStatement *ast) override;
+ bool visit(AST::WithStatement *ast) override;
+
+ bool visit(AST::DoWhileStatement *ast) override;
+ bool visit(AST::ForStatement *ast) override;
+ bool visit(AST::LocalForStatement *ast) override;
+ bool visit(AST::ForEachStatement *ast) override;
+ bool visit(AST::LocalForEachStatement *ast) override;
+ bool visit(AST::ThisExpression *ast) override;
+
+ bool visit(AST::Block *ast) override;
+
+protected:
+ void enterFunction(AST::Node *ast, const QString &name, AST::FormalParameterList *formals, AST::FunctionBody *body, AST::FunctionExpression *expr);
+
+ void calcEscapingVariables();
+// fields:
+ Codegen *_cg;
+ const QString _sourceCode;
+ Context *_context;
+ QStack<Context *> _contextStack;
+
+ bool _allowFuncDecls;
+ CompilationMode defaultProgramMode;
+};
+
+}
+
+}
+
+QT_END_NAMESPACE
+
+#endif // QV4CODEGEN_P_H
diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp
index cf8cf623bc..3a81aca7f6 100644
--- a/src/qml/compiler/qv4instr_moth.cpp
+++ b/src/qml/compiler/qv4instr_moth.cpp
@@ -38,17 +38,601 @@
****************************************************************************/
#include "qv4instr_moth_p.h"
+#include <private/qv4compileddata_p.h>
using namespace QV4;
using namespace QV4::Moth;
-int Instr::size(Type type)
+int InstrInfo::size(Instr::Type type)
{
-#define MOTH_RETURN_INSTR_SIZE(I, FMT) case I: return InstrMeta<(int)I>::Size;
+#define MOTH_RETURN_INSTR_SIZE(I) case Instr::Type::I: return InstrMeta<int(Instr::Type::I)>::Size;
switch (type) {
FOR_EACH_MOTH_INSTR(MOTH_RETURN_INSTR_SIZE)
- default: return 0;
}
#undef MOTH_RETURN_INSTR_SIZE
+ Q_UNREACHABLE();
}
+static QByteArray alignedNumber(int n) {
+ QByteArray number = QByteArray::number(n);
+ while (number.size() < 8)
+ number.prepend(' ');
+ return number;
+}
+
+static QByteArray alignedLineNumber(int line) {
+ if (line > 0)
+ return alignedNumber(static_cast<int>(line));
+ return QByteArray(" ");
+}
+
+static QByteArray rawBytes(const char *data, int n)
+{
+ QByteArray ba;
+ while (n) {
+ uint num = *reinterpret_cast<const uchar *>(data);
+ if (num < 16)
+ ba += '0';
+ ba += QByteArray::number(num, 16) + " ";
+ ++data;
+ --n;
+ }
+ while (ba.size() < 25)
+ ba += ' ';
+ return ba;
+}
+
+static QString toString(QV4::ReturnedValue v)
+{
+#ifdef V4_BOOTSTRAP
+ return QStringLiteral("string-const(%1)").arg(v);
+#else // !V4_BOOTSTRAP
+ Value val = Value::fromReturnedValue(v);
+ QString result;
+ if (val.isInt32())
+ result = QLatin1String("int ");
+ else if (val.isDouble())
+ result = QLatin1String("double ");
+ if (val.isEmpty())
+ result += QLatin1String("empty");
+ else
+ result += val.toQStringNoThrow();
+ return result;
+#endif // V4_BOOTSTRAP
+}
+
+#define ABSOLUTE_OFFSET() \
+ (code - start + offset)
+
+#define MOTH_BEGIN_INSTR(instr) \
+ { \
+ INSTR_##instr(MOTH_DECODE_WITH_BASE) \
+ QDebug d = qDebug(); \
+ d.noquote(); \
+ d.nospace(); \
+ d << alignedLineNumber(line) << alignedNumber(codeOffset).constData() << ": " \
+ << rawBytes(base_ptr, int(code - base_ptr)) << #instr << " ";
+
+#define MOTH_END_INSTR(instr) \
+ continue; \
+ }
+
+QT_BEGIN_NAMESPACE
+namespace QV4 {
+namespace Moth {
+
+const int InstrInfo::argumentCount[] = {
+ FOR_EACH_MOTH_INSTR(MOTH_COLLECT_NARGS)
+};
+
+
+void dumpConstantTable(const Value *constants, uint count)
+{
+ QDebug d = qDebug();
+ d.nospace();
+ for (uint i = 0; i < count; ++i)
+ d << alignedNumber(int(i)).constData() << ": "
+ << toString(constants[i].asReturnedValue()).toUtf8().constData() << "\n";
+}
+
+QString dumpRegister(int reg, int nFormals)
+{
+ Q_STATIC_ASSERT(offsetof(CallData, function) == 0);
+ Q_STATIC_ASSERT(offsetof(CallData, context) == sizeof(Value));
+ Q_STATIC_ASSERT(offsetof(CallData, accumulator) == 2*sizeof(Value));
+ Q_STATIC_ASSERT(offsetof(CallData, thisObject) == 3*sizeof(Value));
+ if (reg == CallData::Function)
+ return QStringLiteral("(function)");
+ else if (reg == CallData::Context)
+ return QStringLiteral("(context)");
+ else if (reg == CallData::Accumulator)
+ return QStringLiteral("(accumulator)");
+ else if (reg == CallData::This)
+ return QStringLiteral("(this)");
+ else if (reg == CallData::Argc)
+ return QStringLiteral("(argc)");
+ reg -= 4;
+ if (reg <= nFormals)
+ return QStringLiteral("a%1").arg(reg);
+ reg -= nFormals;
+ return QStringLiteral("r%1").arg(reg);
+
+}
+
+QString dumpArguments(int argc, int argv, int nFormals)
+{
+ if (!argc)
+ return QStringLiteral("()");
+ return QStringLiteral("(") + dumpRegister(argv, nFormals) + QStringLiteral(", ") + QString::number(argc) + QStringLiteral(")");
+}
+
+
+void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*startLine*/, const QVector<CompiledData::CodeOffsetToLine> &lineNumberMapping)
+{
+ MOTH_JUMP_TABLE;
+
+ auto findLine = [](const CompiledData::CodeOffsetToLine &entry, uint offset) {
+ return entry.codeOffset < offset;
+ };
+
+ int lastLine = -1;
+ const char *start = code;
+ const char *end = code + len;
+ while (code < end) {
+ const CompiledData::CodeOffsetToLine *codeToLine = std::lower_bound(lineNumberMapping.constBegin(), lineNumberMapping.constEnd(), static_cast<uint>(code - start) + 1, findLine) - 1;
+ int line = int(codeToLine->line);
+ if (line != lastLine)
+ lastLine = line;
+ else
+ line = -1;
+
+ int codeOffset = int(code - start);
+
+ MOTH_DISPATCH()
+
+ MOTH_BEGIN_INSTR(LoadReg)
+ d << dumpRegister(reg, nFormals);
+ MOTH_END_INSTR(LoadReg)
+
+ MOTH_BEGIN_INSTR(StoreReg)
+ d << dumpRegister(reg, nFormals);
+ MOTH_END_INSTR(StoreReg)
+
+ MOTH_BEGIN_INSTR(MoveReg)
+ d << dumpRegister(destReg, nFormals) << ", " << dumpRegister(srcReg, nFormals);
+ MOTH_END_INSTR(MoveReg)
+
+ MOTH_BEGIN_INSTR(LoadConst)
+ d << "C" << index;
+ MOTH_END_INSTR(LoadConst)
+
+ MOTH_BEGIN_INSTR(LoadNull)
+ MOTH_END_INSTR(LoadNull)
+
+ MOTH_BEGIN_INSTR(LoadZero)
+ MOTH_END_INSTR(LoadZero)
+
+ MOTH_BEGIN_INSTR(LoadTrue)
+ MOTH_END_INSTR(LoadTrue)
+
+ MOTH_BEGIN_INSTR(LoadFalse)
+ MOTH_END_INSTR(LoadFalse)
+
+ MOTH_BEGIN_INSTR(LoadUndefined)
+ MOTH_END_INSTR(LoadUndefined)
+
+ MOTH_BEGIN_INSTR(LoadInt)
+ d << value;
+ MOTH_END_INSTR(LoadInt)
+
+ MOTH_BEGIN_INSTR(MoveConst)
+ d << dumpRegister(destTemp, nFormals) << ", C" << constIndex;
+ MOTH_END_INSTR(MoveConst)
+
+ MOTH_BEGIN_INSTR(LoadLocal)
+ if (index < nLocals)
+ d << "l" << index;
+ else
+ d << "a" << (index - nLocals);
+ MOTH_END_INSTR(LoadLocal)
+
+ MOTH_BEGIN_INSTR(StoreLocal)
+ if (index < nLocals)
+ d << "l" << index;
+ else
+ d << "a" << (index - nLocals);
+ MOTH_END_INSTR(StoreLocal)
+
+ MOTH_BEGIN_INSTR(LoadScopedLocal)
+ if (index < nLocals)
+ d << "l" << index << "@" << scope;
+ else
+ d << "a" << (index - nLocals) << "@" << scope;
+ MOTH_END_INSTR(LoadScopedLocal)
+
+ MOTH_BEGIN_INSTR(StoreScopedLocal)
+ if (index < nLocals)
+ d << ", " << "l" << index << "@" << scope;
+ else
+ d << ", " << "a" << (index - nLocals) << "@" << scope;
+ MOTH_END_INSTR(StoreScopedLocal)
+
+ MOTH_BEGIN_INSTR(LoadRuntimeString)
+ d << stringId;
+ MOTH_END_INSTR(LoadRuntimeString)
+
+ MOTH_BEGIN_INSTR(MoveRegExp)
+ d << dumpRegister(destReg, nFormals) << ", " <<regExpId;
+ MOTH_END_INSTR(MoveRegExp)
+
+ MOTH_BEGIN_INSTR(LoadClosure)
+ d << value;
+ MOTH_END_INSTR(LoadClosure)
+
+ MOTH_BEGIN_INSTR(LoadName)
+ d << name;
+ MOTH_END_INSTR(LoadName)
+
+ MOTH_BEGIN_INSTR(LoadGlobalLookup)
+ d << index;
+ MOTH_END_INSTR(LoadGlobalLookup)
+
+ MOTH_BEGIN_INSTR(StoreNameSloppy)
+ d << name;
+ MOTH_END_INSTR(StoreNameSloppy)
+
+ MOTH_BEGIN_INSTR(StoreNameStrict)
+ d << name;
+ MOTH_END_INSTR(StoreNameStrict)
+
+ MOTH_BEGIN_INSTR(LoadElement)
+ d << dumpRegister(base, nFormals) << "[" << dumpRegister(index, nFormals) << "]";
+ MOTH_END_INSTR(LoadElement)
+
+ MOTH_BEGIN_INSTR(LoadElementA)
+ d << dumpRegister(base, nFormals) << "[acc]";
+ MOTH_END_INSTR(LoadElement)
+
+ MOTH_BEGIN_INSTR(StoreElement)
+ d << dumpRegister(base, nFormals) << "[" << dumpRegister(index, nFormals) << "]";
+ MOTH_END_INSTR(StoreElement)
+
+ MOTH_BEGIN_INSTR(LoadProperty)
+ d << dumpRegister(base, nFormals) << "[" << name << "]";
+ MOTH_END_INSTR(LoadProperty)
+
+ MOTH_BEGIN_INSTR(LoadPropertyA)
+ d << "acc[" << name << "]";
+ MOTH_END_INSTR(LoadElementA)
+
+ MOTH_BEGIN_INSTR(GetLookup)
+ d << dumpRegister(base, nFormals) << "(" << index << ")";
+ MOTH_END_INSTR(GetLookup)
+
+ MOTH_BEGIN_INSTR(GetLookupA)
+ d << "acc(" << index << ")";
+ MOTH_END_INSTR(GetLookupA)
+
+ MOTH_BEGIN_INSTR(StoreProperty)
+ d << dumpRegister(base, nFormals) << "[" << name<< "]";
+ MOTH_END_INSTR(StoreProperty)
+
+ MOTH_BEGIN_INSTR(SetLookup)
+ d << dumpRegister(base, nFormals) << "(" << index << ")";
+ MOTH_END_INSTR(SetLookup)
+
+ MOTH_BEGIN_INSTR(StoreScopeObjectProperty)
+ d << dumpRegister(base, nFormals) << "[" << propertyIndex << "]";
+ MOTH_END_INSTR(StoreScopeObjectProperty)
+
+ MOTH_BEGIN_INSTR(LoadScopeObjectProperty)
+ d << dumpRegister(base, nFormals) << "[" << propertyIndex << "]" << (captureRequired ? " (capture)" : " (no capture)");
+ MOTH_END_INSTR(LoadScopeObjectProperty)
+
+ MOTH_BEGIN_INSTR(StoreContextObjectProperty)
+ d << dumpRegister(base, nFormals) << "[" << propertyIndex << "]";
+ MOTH_END_INSTR(StoreContextObjectProperty)
+
+ MOTH_BEGIN_INSTR(LoadContextObjectProperty)
+ d << dumpRegister(base, nFormals) << "[" << propertyIndex << "]" << (captureRequired ? " (capture)" : " (no capture)");
+ MOTH_END_INSTR(LoadContextObjectProperty)
+
+ MOTH_BEGIN_INSTR(LoadIdObject)
+ d << dumpRegister(base, nFormals) << "[" << index << "]";
+ MOTH_END_INSTR(LoadIdObject)
+
+ MOTH_BEGIN_INSTR(CallValue)
+ d << dumpRegister(name, nFormals) << dumpArguments(argc, argv, nFormals);
+ MOTH_END_INSTR(CallValue)
+
+ MOTH_BEGIN_INSTR(CallProperty)
+ d << dumpRegister(base, nFormals) << "." << name << dumpArguments(argc, argv, nFormals);
+ MOTH_END_INSTR(CallProperty)
+
+ MOTH_BEGIN_INSTR(CallPropertyLookup)
+ d << dumpRegister(base, nFormals) << "." << lookupIndex << dumpArguments(argc, argv, nFormals);
+ MOTH_END_INSTR(CallPropertyLookup)
+
+ MOTH_BEGIN_INSTR(CallElement)
+ d << dumpRegister(base, nFormals) << "[" << dumpRegister(index, nFormals) << "]" << dumpArguments(argc, argv, nFormals);
+ MOTH_END_INSTR(CallElement)
+
+ MOTH_BEGIN_INSTR(CallName)
+ d << name << dumpArguments(argc, argv, nFormals);
+ MOTH_END_INSTR(CallName)
+
+ MOTH_BEGIN_INSTR(CallPossiblyDirectEval)
+ d << dumpArguments(argc, argv, nFormals);
+ MOTH_END_INSTR(CallPossiblyDirectEval)
+
+ MOTH_BEGIN_INSTR(CallGlobalLookup)
+ d << index << dumpArguments(argc, argv, nFormals);
+ MOTH_END_INSTR(CallGlobalLookup)
+
+ MOTH_BEGIN_INSTR(SetExceptionHandler)
+ if (offset)
+ d << ABSOLUTE_OFFSET();
+ else
+ d << "<null>";
+ MOTH_END_INSTR(SetExceptionHandler)
+
+ MOTH_BEGIN_INSTR(ThrowException)
+ MOTH_END_INSTR(ThrowException)
+
+ MOTH_BEGIN_INSTR(GetException)
+ MOTH_END_INSTR(HasException)
+
+ MOTH_BEGIN_INSTR(SetException)
+ MOTH_END_INSTR(SetExceptionFlag)
+
+ MOTH_BEGIN_INSTR(CreateCallContext)
+ MOTH_END_INSTR(CreateCallContext)
+
+ MOTH_BEGIN_INSTR(PushCatchContext)
+ d << dumpRegister(reg, nFormals) << ", " << name;
+ MOTH_END_INSTR(PushCatchContext)
+
+ MOTH_BEGIN_INSTR(PushWithContext)
+ d << dumpRegister(reg, nFormals);
+ MOTH_END_INSTR(PushWithContext)
+
+ MOTH_BEGIN_INSTR(PopContext)
+ d << dumpRegister(reg, nFormals);
+ MOTH_END_INSTR(PopContext)
+
+ MOTH_BEGIN_INSTR(ForeachIteratorObject)
+ MOTH_END_INSTR(ForeachIteratorObject)
+
+ MOTH_BEGIN_INSTR(ForeachNextPropertyName)
+ MOTH_END_INSTR(ForeachNextPropertyName)
+
+ MOTH_BEGIN_INSTR(DeleteMember)
+ d << dumpRegister(base, nFormals) << "[" << member << "]";
+ MOTH_END_INSTR(DeleteMember)
+
+ MOTH_BEGIN_INSTR(DeleteSubscript)
+ d << dumpRegister(base, nFormals) << "[" << dumpRegister(index, nFormals) << "]";
+ MOTH_END_INSTR(DeleteSubscript)
+
+ MOTH_BEGIN_INSTR(DeleteName)
+ d << name;
+ MOTH_END_INSTR(DeleteName)
+
+ MOTH_BEGIN_INSTR(TypeofName)
+ d << name;
+ MOTH_END_INSTR(TypeofName)
+
+ MOTH_BEGIN_INSTR(TypeofValue)
+ MOTH_END_INSTR(TypeofValue)
+
+ MOTH_BEGIN_INSTR(DeclareVar)
+ d << isDeletable << ", " << varName;
+ MOTH_END_INSTR(DeclareVar)
+
+ MOTH_BEGIN_INSTR(DefineArray)
+ d << dumpRegister(args, nFormals) << ", " << argc;
+ MOTH_END_INSTR(DefineArray)
+
+ MOTH_BEGIN_INSTR(DefineObjectLiteral)
+ d << dumpRegister(args, nFormals)
+ << ", " << internalClassId
+ << ", " << arrayValueCount
+ << ", " << arrayGetterSetterCountAndFlags;
+ MOTH_END_INSTR(DefineObjectLiteral)
+
+ MOTH_BEGIN_INSTR(CreateMappedArgumentsObject)
+ MOTH_END_INSTR(CreateMappedArgumentsObject)
+
+ MOTH_BEGIN_INSTR(CreateUnmappedArgumentsObject)
+ MOTH_END_INSTR(CreateUnmappedArgumentsObject)
+
+ MOTH_BEGIN_INSTR(ConvertThisToObject)
+ MOTH_END_INSTR(ConvertThisToObject)
+
+ MOTH_BEGIN_INSTR(Construct)
+ d << "new" << dumpRegister(func, nFormals) << dumpArguments(argc, argv, nFormals);
+ MOTH_END_INSTR(Construct)
+
+ MOTH_BEGIN_INSTR(Jump)
+ d << ABSOLUTE_OFFSET();
+ MOTH_END_INSTR(Jump)
+
+ MOTH_BEGIN_INSTR(JumpTrue)
+ d << ABSOLUTE_OFFSET();
+ MOTH_END_INSTR(JumpTrue)
+
+ MOTH_BEGIN_INSTR(JumpFalse)
+ d << ABSOLUTE_OFFSET();
+ MOTH_END_INSTR(JumpFalse)
+
+ MOTH_BEGIN_INSTR(CmpEqNull)
+ MOTH_END_INSTR(CmpEqNull)
+
+ MOTH_BEGIN_INSTR(CmpNeNull)
+ MOTH_END_INSTR(CmpNeNull)
+
+ MOTH_BEGIN_INSTR(CmpEqInt)
+ d << lhs;
+ MOTH_END_INSTR(CmpEq)
+
+ MOTH_BEGIN_INSTR(CmpNeInt)
+ d << lhs;
+ MOTH_END_INSTR(CmpNeInt)
+
+ MOTH_BEGIN_INSTR(CmpEq)
+ d << dumpRegister(lhs, nFormals);
+ MOTH_END_INSTR(CmpEq)
+
+ MOTH_BEGIN_INSTR(CmpNe)
+ d << dumpRegister(lhs, nFormals);
+ MOTH_END_INSTR(CmpNe)
+
+ MOTH_BEGIN_INSTR(CmpGt)
+ d << dumpRegister(lhs, nFormals);
+ MOTH_END_INSTR(CmpGt)
+
+ MOTH_BEGIN_INSTR(CmpGe)
+ d << dumpRegister(lhs, nFormals);
+ MOTH_END_INSTR(CmpGe)
+
+ MOTH_BEGIN_INSTR(CmpLt)
+ d << dumpRegister(lhs, nFormals);
+ MOTH_END_INSTR(CmpLt)
+
+ MOTH_BEGIN_INSTR(CmpLe)
+ d << dumpRegister(lhs, nFormals);
+ MOTH_END_INSTR(CmpLe)
+
+ MOTH_BEGIN_INSTR(CmpStrictEqual)
+ d << dumpRegister(lhs, nFormals);
+ MOTH_END_INSTR(CmpStrictEqual)
+
+ MOTH_BEGIN_INSTR(CmpStrictNotEqual)
+ d << dumpRegister(lhs, nFormals);
+ MOTH_END_INSTR(CmpStrictNotEqual)
+
+ MOTH_BEGIN_INSTR(JumpStrictEqualStackSlotInt)
+ d << dumpRegister(lhs, nFormals) << ", " << rhs << " " << ABSOLUTE_OFFSET();
+ MOTH_END_INSTR(JumpStrictEqualStackSlotInt)
+
+ MOTH_BEGIN_INSTR(JumpStrictNotEqualStackSlotInt)
+ d << dumpRegister(lhs, nFormals) << ", " << rhs << " " << ABSOLUTE_OFFSET();
+ MOTH_END_INSTR(JumpStrictNotEqualStackSlotInt)
+
+ MOTH_BEGIN_INSTR(UNot)
+ MOTH_END_INSTR(UNot)
+
+ MOTH_BEGIN_INSTR(UPlus)
+ MOTH_END_INSTR(UPlus)
+
+ MOTH_BEGIN_INSTR(UMinus)
+ MOTH_END_INSTR(UMinus)
+
+ MOTH_BEGIN_INSTR(UCompl)
+ MOTH_END_INSTR(UCompl)
+
+ MOTH_BEGIN_INSTR(Increment)
+ MOTH_END_INSTR(PreIncrement)
+
+ MOTH_BEGIN_INSTR(Decrement)
+ MOTH_END_INSTR(PreDecrement)
+
+ MOTH_BEGIN_INSTR(Add)
+ d << dumpRegister(lhs, nFormals) << ", acc";
+ MOTH_END_INSTR(Add)
+
+ MOTH_BEGIN_INSTR(BitAnd)
+ d << dumpRegister(lhs, nFormals) << ", acc";
+ MOTH_END_INSTR(BitAnd)
+
+ MOTH_BEGIN_INSTR(BitOr)
+ d << dumpRegister(lhs, nFormals) << ", acc";
+ MOTH_END_INSTR(BitOr)
+
+ MOTH_BEGIN_INSTR(BitXor)
+ d << dumpRegister(lhs, nFormals) << ", acc";
+ MOTH_END_INSTR(BitXor)
+
+ MOTH_BEGIN_INSTR(UShr)
+ d << dumpRegister(lhs, nFormals) << ", acc";
+ MOTH_END_INSTR(UShr)
+
+ MOTH_BEGIN_INSTR(Shr)
+ d << dumpRegister(lhs, nFormals) << ", acc";
+ MOTH_END_INSTR(Shr)
+
+ MOTH_BEGIN_INSTR(Shl)
+ d << dumpRegister(lhs, nFormals) << ", acc";
+ MOTH_END_INSTR(Shl)
+
+ MOTH_BEGIN_INSTR(BitAndConst)
+ d << "acc, " << rhs;
+ MOTH_END_INSTR(BitAndConst)
+
+ MOTH_BEGIN_INSTR(BitOrConst)
+ d << "acc, " << rhs;
+ MOTH_END_INSTR(BitOr)
+
+ MOTH_BEGIN_INSTR(BitXorConst)
+ d << "acc, " << rhs;
+ MOTH_END_INSTR(BitXor)
+
+ MOTH_BEGIN_INSTR(UShrConst)
+ d << "acc, " << rhs;
+ MOTH_END_INSTR(UShrConst)
+
+ MOTH_BEGIN_INSTR(ShrConst)
+ d << "acc, " << rhs;
+ MOTH_END_INSTR(ShrConst)
+
+ MOTH_BEGIN_INSTR(ShlConst)
+ d << "acc, " << rhs;
+ MOTH_END_INSTR(ShlConst)
+
+ MOTH_BEGIN_INSTR(Mul)
+ d << dumpRegister(lhs, nFormals) << ", acc";
+ MOTH_END_INSTR(Mul)
+
+ MOTH_BEGIN_INSTR(Div)
+ d << dumpRegister(lhs, nFormals) << ", acc";
+ MOTH_END_INSTR(Div)
+
+ MOTH_BEGIN_INSTR(Mod)
+ d << dumpRegister(lhs, nFormals) << ", acc";
+ MOTH_END_INSTR(Mod)
+
+ MOTH_BEGIN_INSTR(Sub)
+ d << dumpRegister(lhs, nFormals) << ", acc";
+ MOTH_END_INSTR(Sub)
+
+ MOTH_BEGIN_INSTR(CmpIn)
+ d << dumpRegister(lhs, nFormals) << ", acc";
+ MOTH_END_INSTR(CmpIn)
+
+ MOTH_BEGIN_INSTR(CmpInstanceOf)
+ d << dumpRegister(lhs, nFormals) << ", acc";
+ MOTH_END_INSTR(CmpInstanceOf)
+
+ MOTH_BEGIN_INSTR(Ret)
+ MOTH_END_INSTR(Ret)
+
+ MOTH_BEGIN_INSTR(Debug)
+ MOTH_END_INSTR(Debug)
+
+ MOTH_BEGIN_INSTR(LoadQmlContext)
+ d << dumpRegister(result, nFormals);
+ MOTH_END_INSTR(LoadQmlContext)
+
+ MOTH_BEGIN_INSTR(LoadQmlImportedScripts)
+ d << dumpRegister(result, nFormals);
+ MOTH_END_INSTR(LoadQmlImportedScripts)
+
+ MOTH_BEGIN_INSTR(LoadQmlSingleton)
+ d << name;
+ MOTH_END_INSTR(LoadQmlSingleton)
+ }
+}
+
+}
+}
+QT_END_NAMESPACE
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index 5f46e90ec7..4eeeed1fbc 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -54,861 +54,455 @@
#include <private/qv4value_p.h>
#include <private/qv4runtime_p.h>
-#if !defined(V4_BOOTSTRAP)
-QT_REQUIRE_CONFIG(qml_interpreter);
-#endif
-
QT_BEGIN_NAMESPACE
-#ifdef QT_NO_QML_DEBUGGER
-#define MOTH_DEBUG_INSTR(F)
-#else
-#define MOTH_DEBUG_INSTR(F) \
- F(Line, line) \
- F(Debug, debug)
-#endif
+#define INSTRUCTION(op, name, nargs, ...) \
+ op##_INSTRUCTION(name, nargs, __VA_ARGS__)
+
+/* for all jump instructions, the offset has to come last, to simplify the job of the bytecode generator */
+#define INSTR_Ret(op) INSTRUCTION(op, Ret, 0)
+#define INSTR_Debug(op) INSTRUCTION(op, Debug, 0)
+#define INSTR_LoadConst(op) INSTRUCTION(op, LoadConst, 1, index)
+#define INSTR_LoadZero(op) INSTRUCTION(op, LoadZero, 0)
+#define INSTR_LoadTrue(op) INSTRUCTION(op, LoadTrue, 0)
+#define INSTR_LoadFalse(op) INSTRUCTION(op, LoadFalse, 0)
+#define INSTR_LoadNull(op) INSTRUCTION(op, LoadNull, 0)
+#define INSTR_LoadUndefined(op) INSTRUCTION(op, LoadUndefined, 0)
+#define INSTR_LoadInt(op) INSTRUCTION(op, LoadInt, 1, value)
+#define INSTR_MoveConst(op) INSTRUCTION(op, MoveConst, 2, constIndex, destTemp)
+#define INSTR_LoadReg(op) INSTRUCTION(op, LoadReg, 1, reg)
+#define INSTR_StoreReg(op) INSTRUCTION(op, StoreReg, 1, reg)
+#define INSTR_MoveReg(op) INSTRUCTION(op, MoveReg, 2, srcReg, destReg)
+#define INSTR_LoadLocal(op) INSTRUCTION(op, LoadLocal, 1, index)
+#define INSTR_StoreLocal(op) INSTRUCTION(op, StoreLocal, 1, index)
+#define INSTR_LoadScopedLocal(op) INSTRUCTION(op, LoadScopedLocal, 2, scope, index)
+#define INSTR_StoreScopedLocal(op) INSTRUCTION(op, StoreScopedLocal, 2, scope, index)
+#define INSTR_LoadRuntimeString(op) INSTRUCTION(op, LoadRuntimeString, 1, stringId)
+#define INSTR_MoveRegExp(op) INSTRUCTION(op, MoveRegExp, 2, regExpId, destReg)
+#define INSTR_LoadClosure(op) INSTRUCTION(op, LoadClosure, 1, value)
+#define INSTR_LoadName(op) INSTRUCTION(op, LoadName, 1, name)
+#define INSTR_LoadGlobalLookup(op) INSTRUCTION(op, LoadGlobalLookup, 1, index)
+#define INSTR_StoreNameSloppy(op) INSTRUCTION(op, StoreNameSloppy, 1, name)
+#define INSTR_StoreNameStrict(op) INSTRUCTION(op, StoreNameStrict, 1, name)
+#define INSTR_LoadProperty(op) INSTRUCTION(op, LoadProperty, 2, name, base)
+#define INSTR_LoadPropertyA(op) INSTRUCTION(op, LoadPropertyA, 1, name)
+#define INSTR_GetLookup(op) INSTRUCTION(op, GetLookup, 2, index, base)
+#define INSTR_GetLookupA(op) INSTRUCTION(op, GetLookupA, 1, index)
+#define INSTR_LoadScopeObjectProperty(op) INSTRUCTION(op, LoadScopeObjectProperty, 3, propertyIndex, base, captureRequired)
+#define INSTR_LoadContextObjectProperty(op) INSTRUCTION(op, LoadContextObjectProperty, 3, propertyIndex, base, captureRequired)
+#define INSTR_LoadIdObject(op) INSTRUCTION(op, LoadIdObject, 2, index, base)
+#define INSTR_StoreProperty(op) INSTRUCTION(op, StoreProperty, 2, name, base)
+#define INSTR_SetLookup(op) INSTRUCTION(op, SetLookup, 2, index, base)
+#define INSTR_StoreScopeObjectProperty(op) INSTRUCTION(op, StoreScopeObjectProperty, 2, base, propertyIndex)
+#define INSTR_StoreContextObjectProperty(op) INSTRUCTION(op, StoreContextObjectProperty, 2, base, propertyIndex)
+#define INSTR_LoadElement(op) INSTRUCTION(op, LoadElement, 2, base, index)
+#define INSTR_LoadElementA(op) INSTRUCTION(op, LoadElementA, 1, base)
+#define INSTR_StoreElement(op) INSTRUCTION(op, StoreElement, 2, base, index)
+#define INSTR_CallValue(op) INSTRUCTION(op, CallValue, 3, name, argc, argv)
+#define INSTR_CallProperty(op) INSTRUCTION(op, CallProperty, 4, name, base, argc, argv)
+#define INSTR_CallPropertyLookup(op) INSTRUCTION(op, CallPropertyLookup, 4, lookupIndex, base, argc, argv)
+#define INSTR_CallElement(op) INSTRUCTION(op, CallElement, 4, base, index, argc, argv)
+#define INSTR_CallName(op) INSTRUCTION(op, CallName, 3, name, argc, argv)
+#define INSTR_CallPossiblyDirectEval(op) INSTRUCTION(op, CallPossiblyDirectEval, 2, argc, argv)
+#define INSTR_CallGlobalLookup(op) INSTRUCTION(op, CallGlobalLookup, 3, index, argc, argv)
+#define INSTR_SetExceptionHandler(op) INSTRUCTION(op, SetExceptionHandler, 1, offset)
+#define INSTR_ThrowException(op) INSTRUCTION(op, ThrowException, 0)
+#define INSTR_GetException(op) INSTRUCTION(op, GetException, 0)
+#define INSTR_SetException(op) INSTRUCTION(op, SetException, 0)
+#define INSTR_CreateCallContext(op) INSTRUCTION(op, CreateCallContext, 0)
+#define INSTR_PushCatchContext(op) INSTRUCTION(op, PushCatchContext, 2, name, reg)
+#define INSTR_PushWithContext(op) INSTRUCTION(op, PushWithContext, 1, reg)
+#define INSTR_PopContext(op) INSTRUCTION(op, PopContext, 1, reg)
+#define INSTR_ForeachIteratorObject(op) INSTRUCTION(op, ForeachIteratorObject, 0)
+#define INSTR_ForeachNextPropertyName(op) INSTRUCTION(op, ForeachNextPropertyName, 0)
+#define INSTR_DeleteMember(op) INSTRUCTION(op, DeleteMember, 2, member, base)
+#define INSTR_DeleteSubscript(op) INSTRUCTION(op, DeleteSubscript, 2, base, index)
+#define INSTR_DeleteName(op) INSTRUCTION(op, DeleteName, 1, name)
+#define INSTR_TypeofName(op) INSTRUCTION(op, TypeofName, 1, name)
+#define INSTR_TypeofValue(op) INSTRUCTION(op, TypeofValue, 0)
+#define INSTR_DeclareVar(op) INSTRUCTION(op, DeclareVar, 2, varName, isDeletable)
+#define INSTR_DefineArray(op) INSTRUCTION(op, DefineArray, 2, argc, args)
+// arrayGetterSetterCountAndFlags contains 30 bits for count, 1 bit for needsSparseArray boolean
+#define INSTR_DefineObjectLiteral(op) INSTRUCTION(op, DefineObjectLiteral, 4, internalClassId, arrayValueCount, arrayGetterSetterCountAndFlags, args)
+#define INSTR_CreateMappedArgumentsObject(op) INSTRUCTION(op, CreateMappedArgumentsObject, 0)
+#define INSTR_CreateUnmappedArgumentsObject(op) INSTRUCTION(op, CreateUnmappedArgumentsObject, 0)
+#define INSTR_ConvertThisToObject(op) INSTRUCTION(op, ConvertThisToObject, 0)
+#define INSTR_Construct(op) INSTRUCTION(op, Construct, 3, func, argc, argv)
+#define INSTR_Jump(op) INSTRUCTION(op, Jump, 1, offset)
+#define INSTR_JumpTrue(op) INSTRUCTION(op, JumpTrue, 1, offset)
+#define INSTR_JumpFalse(op) INSTRUCTION(op, JumpFalse, 1, offset)
+#define INSTR_CmpEqNull(op) INSTRUCTION(op, CmpEqNull, 0)
+#define INSTR_CmpNeNull(op) INSTRUCTION(op, CmpNeNull, 0)
+#define INSTR_CmpEqInt(op) INSTRUCTION(op, CmpEqInt, 1, lhs)
+#define INSTR_CmpNeInt(op) INSTRUCTION(op, CmpNeInt, 1, lhs)
+#define INSTR_CmpEq(op) INSTRUCTION(op, CmpEq, 1, lhs)
+#define INSTR_CmpNe(op) INSTRUCTION(op, CmpNe, 1, lhs)
+#define INSTR_CmpGt(op) INSTRUCTION(op, CmpGt, 1, lhs)
+#define INSTR_CmpGe(op) INSTRUCTION(op, CmpGe, 1, lhs)
+#define INSTR_CmpLt(op) INSTRUCTION(op, CmpLt, 1, lhs)
+#define INSTR_CmpLe(op) INSTRUCTION(op, CmpLe, 1, lhs)
+#define INSTR_CmpStrictEqual(op) INSTRUCTION(op, CmpStrictEqual, 1, lhs)
+#define INSTR_CmpStrictNotEqual(op) INSTRUCTION(op, CmpStrictNotEqual, 1, lhs)
+#define INSTR_CmpIn(op) INSTRUCTION(op, CmpIn, 1, lhs)
+#define INSTR_CmpInstanceOf(op) INSTRUCTION(op, CmpInstanceOf, 1, lhs)
+#define INSTR_JumpStrictEqualStackSlotInt(op) INSTRUCTION(op, JumpStrictEqualStackSlotInt, 3, lhs, rhs, offset)
+#define INSTR_JumpStrictNotEqualStackSlotInt(op) INSTRUCTION(op, JumpStrictNotEqualStackSlotInt, 3, lhs, rhs, offset)
+#define INSTR_UNot(op) INSTRUCTION(op, UNot, 0)
+#define INSTR_UPlus(op) INSTRUCTION(op, UPlus, 0)
+#define INSTR_UMinus(op) INSTRUCTION(op, UMinus, 0)
+#define INSTR_UCompl(op) INSTRUCTION(op, UCompl, 0)
+#define INSTR_Increment(op) INSTRUCTION(op, Increment, 0)
+#define INSTR_Decrement(op) INSTRUCTION(op, Decrement, 0)
+#define INSTR_Add(op) INSTRUCTION(op, Add, 1, lhs)
+#define INSTR_BitAnd(op) INSTRUCTION(op, BitAnd, 1, lhs)
+#define INSTR_BitOr(op) INSTRUCTION(op, BitOr, 1, lhs)
+#define INSTR_BitXor(op) INSTRUCTION(op, BitXor, 1, lhs)
+#define INSTR_UShr(op) INSTRUCTION(op, UShr, 1, lhs)
+#define INSTR_Shr(op) INSTRUCTION(op, Shr, 1, lhs)
+#define INSTR_Shl(op) INSTRUCTION(op, Shl, 1, lhs)
+#define INSTR_BitAndConst(op) INSTRUCTION(op, BitAndConst, 1, rhs)
+#define INSTR_BitOrConst(op) INSTRUCTION(op, BitOrConst, 1, rhs)
+#define INSTR_BitXorConst(op) INSTRUCTION(op, BitXorConst, 1, rhs)
+#define INSTR_UShrConst(op) INSTRUCTION(op, UShrConst, 1, rhs)
+#define INSTR_ShrConst(op) INSTRUCTION(op, ShrConst, 1, rhs)
+#define INSTR_ShlConst(op) INSTRUCTION(op, ShlConst, 1, rhs)
+#define INSTR_Mul(op) INSTRUCTION(op, Mul, 1, lhs)
+#define INSTR_Div(op) INSTRUCTION(op, Div, 1, lhs)
+#define INSTR_Mod(op) INSTRUCTION(op, Mod, 1, lhs)
+#define INSTR_Sub(op) INSTRUCTION(op, Sub, 1, lhs)
+#define INSTR_LoadQmlContext(op) INSTRUCTION(op, LoadQmlContext, 1, result)
+#define INSTR_LoadQmlImportedScripts(op) INSTRUCTION(op, LoadQmlImportedScripts, 1, result)
+#define INSTR_LoadQmlSingleton(op) INSTRUCTION(op, LoadQmlSingleton, 1, name)
+
#define FOR_EACH_MOTH_INSTR(F) \
- F(Ret, ret) \
- MOTH_DEBUG_INSTR(F) \
- F(LoadRuntimeString, loadRuntimeString) \
- F(LoadRegExp, loadRegExp) \
- F(LoadClosure, loadClosure) \
- F(Move, move) \
- F(MoveConst, moveConst) \
- F(SwapTemps, swapTemps) \
- F(LoadName, loadName) \
- F(GetGlobalLookup, getGlobalLookup) \
- F(StoreName, storeName) \
- F(LoadElement, loadElement) \
- F(LoadElementLookup, loadElementLookup) \
- F(StoreElement, storeElement) \
- F(StoreElementLookup, storeElementLookup) \
- F(LoadProperty, loadProperty) \
- F(GetLookup, getLookup) \
- F(StoreProperty, storeProperty) \
- F(SetLookup, setLookup) \
- F(StoreQObjectProperty, storeQObjectProperty) \
- F(LoadQObjectProperty, loadQObjectProperty) \
- F(StoreScopeObjectProperty, storeScopeObjectProperty) \
- F(StoreContextObjectProperty, storeContextObjectProperty) \
- F(LoadScopeObjectProperty, loadScopeObjectProperty) \
- F(LoadContextObjectProperty, loadContextObjectProperty) \
- F(LoadIdObject, loadIdObject) \
- F(LoadAttachedQObjectProperty, loadAttachedQObjectProperty) \
- F(LoadSingletonQObjectProperty, loadQObjectProperty) \
- F(Push, push) \
- F(CallValue, callValue) \
- F(CallProperty, callProperty) \
- F(CallPropertyLookup, callPropertyLookup) \
- F(CallScopeObjectProperty, callScopeObjectProperty) \
- F(CallContextObjectProperty, callContextObjectProperty) \
- F(CallElement, callElement) \
- F(CallActivationProperty, callActivationProperty) \
- F(CallGlobalLookup, callGlobalLookup) \
- F(SetExceptionHandler, setExceptionHandler) \
- F(CallBuiltinThrow, callBuiltinThrow) \
- F(CallBuiltinUnwindException, callBuiltinUnwindException) \
- F(CallBuiltinPushCatchScope, callBuiltinPushCatchScope) \
- F(CallBuiltinPushScope, callBuiltinPushScope) \
- F(CallBuiltinPopScope, callBuiltinPopScope) \
- F(CallBuiltinForeachIteratorObject, callBuiltinForeachIteratorObject) \
- F(CallBuiltinForeachNextPropertyName, callBuiltinForeachNextPropertyName) \
- F(CallBuiltinDeleteMember, callBuiltinDeleteMember) \
- F(CallBuiltinDeleteSubscript, callBuiltinDeleteSubscript) \
- F(CallBuiltinDeleteName, callBuiltinDeleteName) \
- F(CallBuiltinTypeofScopeObjectProperty, callBuiltinTypeofScopeObjectProperty) \
- F(CallBuiltinTypeofContextObjectProperty, callBuiltinTypeofContextObjectProperty) \
- F(CallBuiltinTypeofMember, callBuiltinTypeofMember) \
- F(CallBuiltinTypeofSubscript, callBuiltinTypeofSubscript) \
- F(CallBuiltinTypeofName, callBuiltinTypeofName) \
- F(CallBuiltinTypeofValue, callBuiltinTypeofValue) \
- F(CallBuiltinDeclareVar, callBuiltinDeclareVar) \
- F(CallBuiltinDefineArray, callBuiltinDefineArray) \
- F(CallBuiltinDefineObjectLiteral, callBuiltinDefineObjectLiteral) \
- F(CallBuiltinSetupArgumentsObject, callBuiltinSetupArgumentsObject) \
- F(CallBuiltinConvertThisToObject, callBuiltinConvertThisToObject) \
- F(CreateValue, createValue) \
- F(CreateProperty, createProperty) \
- F(ConstructPropertyLookup, constructPropertyLookup) \
- F(CreateActivationProperty, createActivationProperty) \
- F(ConstructGlobalLookup, constructGlobalLookup) \
- F(Jump, jump) \
- F(JumpEq, jumpEq) \
- F(JumpNe, jumpNe) \
- F(UNot, unot) \
- F(UNotBool, unotBool) \
- F(UPlus, uplus) \
- F(UMinus, uminus) \
- F(UCompl, ucompl) \
- F(UComplInt, ucomplInt) \
- F(Increment, increment) \
- F(Decrement, decrement) \
- F(Binop, binop) \
- F(Add, add) \
- F(BitAnd, bitAnd) \
- F(BitOr, bitOr) \
- F(BitXor, bitXor) \
- F(Shr, shr) \
- F(Shl, shl) \
- F(BitAndConst, bitAndConst) \
- F(BitOrConst, bitOrConst) \
- F(BitXorConst, bitXorConst) \
- F(ShrConst, shrConst) \
- F(ShlConst, shlConst) \
- F(Mul, mul) \
- F(Sub, sub) \
- F(BinopContext, binopContext) \
- F(LoadThis, loadThis) \
- F(LoadQmlContext, loadQmlContext) \
- F(LoadQmlImportedScripts, loadQmlImportedScripts) \
- F(LoadQmlSingleton, loadQmlSingleton)
-
-#if defined(Q_CC_GNU) && (!defined(Q_CC_INTEL) || __INTEL_COMPILER >= 1200)
-# define MOTH_THREADED_INTERPRETER
+ F(Ret) \
+ F(Debug) \
+ F(LoadConst) \
+ F(LoadZero) \
+ F(LoadTrue) \
+ F(LoadFalse) \
+ F(LoadNull) \
+ F(LoadUndefined) \
+ F(LoadInt) \
+ F(MoveConst) \
+ F(LoadReg) \
+ F(StoreReg) \
+ F(MoveReg) \
+ F(LoadLocal) \
+ F(StoreLocal) \
+ F(LoadScopedLocal) \
+ F(StoreScopedLocal) \
+ F(LoadRuntimeString) \
+ F(MoveRegExp) \
+ F(LoadClosure) \
+ F(LoadName) \
+ F(LoadGlobalLookup) \
+ F(StoreNameSloppy) \
+ F(StoreNameStrict) \
+ F(LoadElement) \
+ F(LoadElementA) \
+ F(StoreElement) \
+ F(LoadProperty) \
+ F(LoadPropertyA) \
+ F(GetLookup) \
+ F(GetLookupA) \
+ F(StoreProperty) \
+ F(SetLookup) \
+ F(StoreScopeObjectProperty) \
+ F(StoreContextObjectProperty) \
+ F(LoadScopeObjectProperty) \
+ F(LoadContextObjectProperty) \
+ F(LoadIdObject) \
+ F(CallValue) \
+ F(CallProperty) \
+ F(CallPropertyLookup) \
+ F(CallElement) \
+ F(CallName) \
+ F(CallPossiblyDirectEval) \
+ F(CallGlobalLookup) \
+ F(SetExceptionHandler) \
+ F(ThrowException) \
+ F(GetException) \
+ F(SetException) \
+ F(CreateCallContext) \
+ F(PushCatchContext) \
+ F(PushWithContext) \
+ F(PopContext) \
+ F(ForeachIteratorObject) \
+ F(ForeachNextPropertyName) \
+ F(DeleteMember) \
+ F(DeleteSubscript) \
+ F(DeleteName) \
+ F(TypeofName) \
+ F(TypeofValue) \
+ F(DeclareVar) \
+ F(DefineArray) \
+ F(DefineObjectLiteral) \
+ F(CreateMappedArgumentsObject) \
+ F(CreateUnmappedArgumentsObject) \
+ F(ConvertThisToObject) \
+ F(Construct) \
+ F(Jump) \
+ F(JumpTrue) \
+ F(JumpFalse) \
+ F(CmpEqNull) \
+ F(CmpNeNull) \
+ F(CmpEqInt) \
+ F(CmpNeInt) \
+ F(CmpEq) \
+ F(CmpNe) \
+ F(CmpGt) \
+ F(CmpGe) \
+ F(CmpLt) \
+ F(CmpLe) \
+ F(CmpStrictEqual) \
+ F(CmpStrictNotEqual) \
+ F(CmpIn) \
+ F(CmpInstanceOf) \
+ F(JumpStrictEqualStackSlotInt) \
+ F(JumpStrictNotEqualStackSlotInt) \
+ F(UNot) \
+ F(UPlus) \
+ F(UMinus) \
+ F(UCompl) \
+ F(Increment) \
+ F(Decrement) \
+ F(Add) \
+ F(BitAnd) \
+ F(BitOr) \
+ F(BitXor) \
+ F(UShr) \
+ F(Shr) \
+ F(Shl) \
+ F(BitAndConst) \
+ F(BitOrConst) \
+ F(BitXorConst) \
+ F(UShrConst) \
+ F(ShrConst) \
+ F(ShlConst) \
+ F(Mul) \
+ F(Div) \
+ F(Mod) \
+ F(Sub) \
+ F(LoadQmlContext) \
+ F(LoadQmlImportedScripts) \
+ F(LoadQmlSingleton)
+#define MOTH_NUM_INSTRUCTIONS() (static_cast<int>(Moth::Instr::Type::LoadQmlSingleton) + 1)
+
+#if defined(Q_CC_GNU) && !defined(Q_CC_INTEL)
+// icc before version 1200 doesn't support computed goto, and at least up to version 18.0.0 the
+// current use results in an internal compiler error. We could enable this if/when it gets fixed
+// in a later version.
+# define MOTH_COMPUTED_GOTO
#endif
#define MOTH_INSTR_ALIGN_MASK (Q_ALIGNOF(QV4::Moth::Instr) - 1)
-#define MOTH_INSTR_HEADER quint32 instructionType;
+#define MOTH_INSTR_ENUM(I) I,
+#define MOTH_INSTR_SIZE(I) (sizeof(QV4::Moth::Instr::instr_##I))
+
+#define MOTH_EXPAND_FOR_MSVC(x) x
+#define MOTH_DEFINE_ARGS(nargs, ...) \
+ MOTH_EXPAND_FOR_MSVC(MOTH_DEFINE_ARGS##nargs(__VA_ARGS__))
+
+#define MOTH_DEFINE_ARGS0()
+#define MOTH_DEFINE_ARGS1(arg) \
+ int arg;
+#define MOTH_DEFINE_ARGS2(arg1, arg2) \
+ int arg1; \
+ int arg2;
+#define MOTH_DEFINE_ARGS3(arg1, arg2, arg3) \
+ int arg1; \
+ int arg2; \
+ int arg3;
+#define MOTH_DEFINE_ARGS4(arg1, arg2, arg3, arg4) \
+ int arg1; \
+ int arg2; \
+ int arg3; \
+ int arg4;
+
+#define MOTH_COLLECT_ENUMS(instr) \
+ INSTR_##instr(MOTH_GET_ENUM)
+#define MOTH_GET_ENUM_INSTRUCTION(name, ...) \
+ name,
+
+#define MOTH_EMIT_STRUCTS(instr) \
+ INSTR_##instr(MOTH_EMIT_STRUCT)
+#define MOTH_EMIT_STRUCT_INSTRUCTION(name, nargs, ...) \
+ struct instr_##name { \
+ MOTH_DEFINE_ARGS(nargs, __VA_ARGS__) \
+ };
+
+#define MOTH_EMIT_INSTR_MEMBERS(instr) \
+ INSTR_##instr(MOTH_EMIT_INSTR_MEMBER)
+#define MOTH_EMIT_INSTR_MEMBER_INSTRUCTION(name, nargs, ...) \
+ instr_##name name;
+
+#define MOTH_COLLECT_NARGS(instr) \
+ INSTR_##instr(MOTH_COLLECT_ARG_COUNT)
+#define MOTH_COLLECT_ARG_COUNT_INSTRUCTION(name, nargs, ...) \
+ nargs,
+
+#define MOTH_DECODE_ARG(arg, type, nargs, offset) \
+ arg = qFromLittleEndian<type>(reinterpret_cast<const type *>(code)[-nargs + offset]);
+#define MOTH_ADJUST_CODE(type, nargs) \
+ code += static_cast<quintptr>(nargs*sizeof(type) + 1)
+
+#define MOTH_DECODE_INSTRUCTION(name, nargs, ...) \
+ MOTH_DEFINE_ARGS(nargs, __VA_ARGS__) \
+ op_int_##name: \
+ MOTH_ADJUST_CODE(int, nargs); \
+ MOTH_DECODE_ARGS(name, int, nargs, __VA_ARGS__) \
+ goto op_main_##name; \
+ op_byte_##name: \
+ MOTH_ADJUST_CODE(qint8, nargs); \
+ MOTH_DECODE_ARGS(name, qint8, nargs, __VA_ARGS__) \
+ op_main_##name: \
+ ; \
+
+#define MOTH_DECODE_WITH_BASE_INSTRUCTION(name, nargs, ...) \
+ MOTH_DEFINE_ARGS(nargs, __VA_ARGS__) \
+ const char *base_ptr; \
+ op_int_##name: \
+ base_ptr = code; \
+ MOTH_ADJUST_CODE(int, nargs); \
+ MOTH_DECODE_ARGS(name, int, nargs, __VA_ARGS__) \
+ goto op_main_##name; \
+ op_byte_##name: \
+ base_ptr = code; \
+ MOTH_ADJUST_CODE(qint8, nargs); \
+ MOTH_DECODE_ARGS(name, qint8, nargs, __VA_ARGS__) \
+ op_main_##name: \
+ ; \
+
+#define MOTH_DECODE_ARGS(name, type, nargs, ...) \
+ MOTH_EXPAND_FOR_MSVC(MOTH_DECODE_ARGS##nargs(name, type, nargs, __VA_ARGS__))
+
+#define MOTH_DECODE_ARGS0(name, type, nargs, dummy)
+#define MOTH_DECODE_ARGS1(name, type, nargs, arg) \
+ MOTH_DECODE_ARG(arg, type, nargs, 0);
+#define MOTH_DECODE_ARGS2(name, type, nargs, arg1, arg2) \
+ MOTH_DECODE_ARGS1(name, type, nargs, arg1); \
+ MOTH_DECODE_ARG(arg2, type, nargs, 1);
+#define MOTH_DECODE_ARGS3(name, type, nargs, arg1, arg2, arg3) \
+ MOTH_DECODE_ARGS2(name, type, nargs, arg1, arg2); \
+ MOTH_DECODE_ARG(arg3, type, nargs, 2);
+#define MOTH_DECODE_ARGS4(name, type, nargs, arg1, arg2, arg3, arg4) \
+ MOTH_DECODE_ARGS3(name, type, nargs, arg1, arg2, arg3); \
+ MOTH_DECODE_ARG(arg4, type, nargs, 3);
+
+#ifdef MOTH_COMPUTED_GOTO
+/* collect jump labels */
+#define COLLECT_LABELS(instr) \
+ INSTR_##instr(GET_LABEL)
+#define GET_LABEL_INSTRUCTION(name, ...) \
+ &&op_byte_##name,
+#define COLLECT_LABELS_WIDE(instr) \
+ INSTR_##instr(GET_LABEL_WIDE)
+#define GET_LABEL_WIDE_INSTRUCTION(name, ...) \
+ &&op_int_##name,
+
+#define MOTH_JUMP_TABLE \
+ static const void *jumpTable[] = { \
+ FOR_EACH_MOTH_INSTR(COLLECT_LABELS) \
+ FOR_EACH_MOTH_INSTR(COLLECT_LABELS_WIDE) \
+ };
+
+#define MOTH_DISPATCH() \
+ goto *jumpTable[*reinterpret_cast<const uchar *>(code)];
+#else
+#define MOTH_JUMP_TABLE
+
+#define MOTH_INSTR_CASE_AND_JUMP(instr) \
+ INSTR_##instr(GET_CASE_AND_JUMP)
+#define GET_CASE_AND_JUMP_INSTRUCTION(name, ...) \
+ case static_cast<uchar>(Instr::Type::name): goto op_byte_##name;
+#define MOTH_INSTR_CASE_AND_JUMP_WIDE(instr) \
+ INSTR_##instr(GET_CASE_AND_JUMP_WIDE)
+#define GET_CASE_AND_JUMP_WIDE_INSTRUCTION(name, ...) \
+ case (static_cast<uchar>(Instr::Type::name) + MOTH_NUM_INSTRUCTIONS()): goto op_int_##name;
+
+#define MOTH_DISPATCH() \
+ switch (static_cast<uchar>(*code)) { \
+ FOR_EACH_MOTH_INSTR(MOTH_INSTR_CASE_AND_JUMP) \
+ FOR_EACH_MOTH_INSTR(MOTH_INSTR_CASE_AND_JUMP_WIDE) \
+ }
+#endif
-#define MOTH_INSTR_ENUM(I, FMT) I,
-#define MOTH_INSTR_SIZE(I, FMT) ((sizeof(QV4::Moth::Instr::instr_##FMT) + MOTH_INSTR_ALIGN_MASK) & ~MOTH_INSTR_ALIGN_MASK)
+namespace QV4 {
+namespace CompiledData {
+struct CodeOffsetToLine;
+}
-namespace QV4 {
namespace Moth {
- // When making changes to the instructions, make sure to bump QV4_DATA_STRUCTURE_VERSION in qv4compileddata_p.h
-
-struct Param {
- // Params are looked up as follows:
- // Constant: 0
- // Temp: 1
- // Argument: 2
- // Local: 3
- // Arg(outer): 4
- // Local(outer): 5
- // ...
- unsigned scope : 12;
- unsigned index : 20;
-
- bool isConstant() const { return !scope; }
- bool isArgument() const { return scope >= 2 && !(scope &1); }
- bool isLocal() const { return scope == 3; }
- bool isTemp() const { return scope == 1; }
- bool isScopedLocal() const { return scope >= 3 && (scope & 1); }
-
- static Param createConstant(int index)
- {
- Param p;
- p.scope = 0;
- p.index = index;
- return p;
- }
+class StackSlot {
+ int index;
- static Param createArgument(unsigned idx, uint scope)
- {
- Param p;
- p.scope = 2 + 2*scope;
- p.index = idx;
- return p;
+public:
+ static StackSlot createRegister(int index) {
+ Q_ASSERT(index >= 0);
+ StackSlot t;
+ t.index = index;
+ return t;
}
- static Param createLocal(unsigned idx)
- {
- Param p;
- p.scope = 3;
- p.index = idx;
- return p;
- }
-
- static Param createTemp(unsigned idx)
- {
- Param p;
- p.scope = 1;
- p.index = idx;
- return p;
- }
+ int stackSlot() const { return index; }
+ operator int() const { return index; }
+};
- static Param createScopedLocal(unsigned idx, uint scope)
- {
- Param p;
- p.scope = 3 + 2*scope;
- p.index = idx;
- return p;
- }
+inline bool operator==(const StackSlot &l, const StackSlot &r) { return l.stackSlot() == r.stackSlot(); }
+inline bool operator!=(const StackSlot &l, const StackSlot &r) { return l.stackSlot() != r.stackSlot(); }
- inline bool operator==(const Param &other) const
- { return scope == other.scope && index == other.index; }
+// When making changes to the instructions, make sure to bump QV4_DATA_STRUCTURE_VERSION in qv4compileddata_p.h
- inline bool operator!=(const Param &other) const
- { return !(*this == other); }
-};
+void dumpConstantTable(const Value *constants, uint count);
+void dumpBytecode(const char *bytecode, int len, int nLocals, int nFormals, int startLine = 1,
+ const QVector<CompiledData::CodeOffsetToLine> &lineNumberMapping = QVector<CompiledData::CodeOffsetToLine>());
+inline void dumpBytecode(const QByteArray &bytecode, int nLocals, int nFormals, int startLine = 1,
+ const QVector<CompiledData::CodeOffsetToLine> &lineNumberMapping = QVector<CompiledData::CodeOffsetToLine>()) {
+ dumpBytecode(bytecode.constData(), bytecode.length(), nLocals, nFormals, startLine, lineNumberMapping);
+}
union Instr
{
- enum Type {
+ enum class Type {
FOR_EACH_MOTH_INSTR(MOTH_INSTR_ENUM)
- LastInstruction
};
- struct instr_common {
- MOTH_INSTR_HEADER
- };
- struct instr_ret {
- MOTH_INSTR_HEADER
- Param result;
- };
+ FOR_EACH_MOTH_INSTR(MOTH_EMIT_STRUCTS)
-#ifndef QT_NO_QML_DEBUGGING
- struct instr_line {
- MOTH_INSTR_HEADER
- qint32 lineNumber;
- };
- struct instr_debug {
- MOTH_INSTR_HEADER
- qint32 lineNumber;
- };
-#endif // QT_NO_QML_DEBUGGING
+ FOR_EACH_MOTH_INSTR(MOTH_EMIT_INSTR_MEMBERS)
- struct instr_loadRuntimeString {
- MOTH_INSTR_HEADER
- int stringId;
- Param result;
- };
- struct instr_loadRegExp {
- MOTH_INSTR_HEADER
- int regExpId;
- Param result;
- };
- struct instr_move {
- MOTH_INSTR_HEADER
- Param source;
- Param result;
- };
- struct instr_moveConst {
- MOTH_INSTR_HEADER
- QV4::ReturnedValue source;
- Param result;
- };
- struct instr_swapTemps {
- MOTH_INSTR_HEADER
- Param left;
- Param right;
- };
- struct instr_loadClosure {
- MOTH_INSTR_HEADER
- int value;
- Param result;
- };
- struct instr_loadName {
- MOTH_INSTR_HEADER
- int name;
- Param result;
- };
- struct instr_getGlobalLookup {
- MOTH_INSTR_HEADER
- int index;
- Param result;
- };
- struct instr_storeName {
- MOTH_INSTR_HEADER
- int name;
- Param source;
- };
- struct instr_loadProperty {
- MOTH_INSTR_HEADER
- int name;
- Param base;
- Param result;
- };
- struct instr_getLookup {
- MOTH_INSTR_HEADER
- int index;
- Param base;
- Param result;
- };
- struct instr_loadScopeObjectProperty {
- MOTH_INSTR_HEADER
- int propertyIndex;
- Param base;
- Param result;
- bool captureRequired;
- };
- struct instr_loadContextObjectProperty {
- MOTH_INSTR_HEADER
- int propertyIndex;
- Param base;
- Param result;
- bool captureRequired;
- };
- struct instr_loadIdObject {
- MOTH_INSTR_HEADER
- int index;
- Param base;
- Param result;
- };
- struct instr_loadQObjectProperty {
- MOTH_INSTR_HEADER
- int propertyIndex;
- Param base;
- Param result;
- bool captureRequired;
- };
- struct instr_loadAttachedQObjectProperty {
- MOTH_INSTR_HEADER
- int propertyIndex;
- Param result;
- int attachedPropertiesId;
- };
- struct instr_storeProperty {
- MOTH_INSTR_HEADER
- int name;
- Param base;
- Param source;
- };
- struct instr_setLookup {
- MOTH_INSTR_HEADER
- int index;
- Param base;
- Param source;
- };
- struct instr_storeScopeObjectProperty {
- MOTH_INSTR_HEADER
- Param base;
- int propertyIndex;
- Param source;
- };
- struct instr_storeContextObjectProperty {
- MOTH_INSTR_HEADER
- Param base;
- int propertyIndex;
- Param source;
- };
- struct instr_storeQObjectProperty {
- MOTH_INSTR_HEADER
- Param base;
- int propertyIndex;
- Param source;
- };
- struct instr_loadElement {
- MOTH_INSTR_HEADER
- Param base;
- Param index;
- Param result;
- };
- struct instr_loadElementLookup {
- MOTH_INSTR_HEADER
- uint lookup;
- Param base;
- Param index;
- Param result;
- };
- struct instr_storeElement {
- MOTH_INSTR_HEADER
- Param base;
- Param index;
- Param source;
- };
- struct instr_storeElementLookup {
- MOTH_INSTR_HEADER
- uint lookup;
- Param base;
- Param index;
- Param source;
- };
- struct instr_push {
- MOTH_INSTR_HEADER
- quint32 value;
- };
- struct instr_callValue {
- MOTH_INSTR_HEADER
- quint32 argc;
- quint32 callData;
- Param dest;
- Param result;
- };
- struct instr_callProperty {
- MOTH_INSTR_HEADER
- int name;
- quint32 argc;
- quint32 callData;
- Param base;
- Param result;
- };
- struct instr_callPropertyLookup {
- MOTH_INSTR_HEADER
- int lookupIndex;
- quint32 argc;
- quint32 callData;
- Param base;
- Param result;
- };
- struct instr_callScopeObjectProperty {
- MOTH_INSTR_HEADER
- int index;
- quint32 argc;
- quint32 callData;
- Param base;
- Param result;
- };
- struct instr_callContextObjectProperty {
- MOTH_INSTR_HEADER
- int index;
- quint32 argc;
- quint32 callData;
- Param base;
- Param result;
- };
- struct instr_callElement {
- MOTH_INSTR_HEADER
- Param base;
- Param index;
- quint32 argc;
- quint32 callData;
- Param result;
- };
- struct instr_callActivationProperty {
- MOTH_INSTR_HEADER
- int name;
- quint32 argc;
- quint32 callData;
- Param result;
- };
- struct instr_callGlobalLookup {
- MOTH_INSTR_HEADER
- int index;
- quint32 argc;
- quint32 callData;
- Param result;
- };
- struct instr_setExceptionHandler {
- MOTH_INSTR_HEADER
- qptrdiff offset;
- };
- struct instr_callBuiltinThrow {
- MOTH_INSTR_HEADER
- Param arg;
- };
- struct instr_callBuiltinUnwindException {
- MOTH_INSTR_HEADER
- Param result;
- };
- struct instr_callBuiltinPushCatchScope {
- MOTH_INSTR_HEADER
- int name;
- };
- struct instr_callBuiltinPushScope {
- MOTH_INSTR_HEADER
- Param arg;
- };
- struct instr_callBuiltinPopScope {
- MOTH_INSTR_HEADER
- };
- struct instr_callBuiltinForeachIteratorObject {
- MOTH_INSTR_HEADER
- Param arg;
- Param result;
- };
- struct instr_callBuiltinForeachNextPropertyName {
- MOTH_INSTR_HEADER
- Param arg;
- Param result;
- };
- struct instr_callBuiltinDeleteMember {
- MOTH_INSTR_HEADER
- int member;
- Param base;
- Param result;
- };
- struct instr_callBuiltinDeleteSubscript {
- MOTH_INSTR_HEADER
- Param base;
- Param index;
- Param result;
- };
- struct instr_callBuiltinDeleteName {
- MOTH_INSTR_HEADER
- int name;
- Param result;
- };
- struct instr_callBuiltinTypeofScopeObjectProperty {
- MOTH_INSTR_HEADER
- int index;
- Param base;
- Param result;
- };
- struct instr_callBuiltinTypeofContextObjectProperty {
- MOTH_INSTR_HEADER
- int index;
- Param base;
- Param result;
- };
- struct instr_callBuiltinTypeofMember {
- MOTH_INSTR_HEADER
- int member;
- Param base;
- Param result;
- };
- struct instr_callBuiltinTypeofSubscript {
- MOTH_INSTR_HEADER
- Param base;
- Param index;
- Param result;
- };
- struct instr_callBuiltinTypeofName {
- MOTH_INSTR_HEADER
- int name;
- Param result;
- };
- struct instr_callBuiltinTypeofValue {
- MOTH_INSTR_HEADER
- Param value;
- Param result;
- };
- struct instr_callBuiltinDeclareVar {
- MOTH_INSTR_HEADER
- int varName;
- bool isDeletable;
- };
- struct instr_callBuiltinDefineArray {
- MOTH_INSTR_HEADER
- quint32 argc;
- quint32 args;
- Param result;
- };
- struct instr_callBuiltinDefineObjectLiteral {
- MOTH_INSTR_HEADER
- int internalClassId;
- uint arrayValueCount;
- uint arrayGetterSetterCountAndFlags; // 30 bits for count, 1 bit for needsSparseArray boolean
- quint32 args;
- Param result;
- };
- struct instr_callBuiltinSetupArgumentsObject {
- MOTH_INSTR_HEADER
- Param result;
- };
- struct instr_callBuiltinConvertThisToObject {
- MOTH_INSTR_HEADER
- };
- struct instr_createValue {
- MOTH_INSTR_HEADER
- quint32 argc;
- quint32 callData;
- Param func;
- Param result;
- };
- struct instr_createProperty {
- MOTH_INSTR_HEADER
- int name;
- quint32 argc;
- quint32 callData;
- Param base;
- Param result;
- };
- struct instr_constructPropertyLookup {
- MOTH_INSTR_HEADER
- int index;
- quint32 argc;
- quint32 callData;
- Param base;
- Param result;
- };
- struct instr_createActivationProperty {
- MOTH_INSTR_HEADER
- int name;
- quint32 argc;
- quint32 callData;
- Param result;
- };
- struct instr_constructGlobalLookup {
- MOTH_INSTR_HEADER
- int index;
- quint32 argc;
- quint32 callData;
- Param result;
- };
- struct instr_jump {
- MOTH_INSTR_HEADER
- ptrdiff_t offset;
- };
- struct instr_jumpEq {
- MOTH_INSTR_HEADER
- ptrdiff_t offset;
- Param condition;
- };
- struct instr_jumpNe {
- MOTH_INSTR_HEADER
- ptrdiff_t offset;
- Param condition;
- };
- struct instr_unot {
- MOTH_INSTR_HEADER
- Param source;
- Param result;
- };
- struct instr_unotBool {
- MOTH_INSTR_HEADER
- Param source;
- Param result;
- };
- struct instr_uplus {
- MOTH_INSTR_HEADER
- Param source;
- Param result;
- };
- struct instr_uminus {
- MOTH_INSTR_HEADER
- Param source;
- Param result;
- };
- struct instr_ucompl {
- MOTH_INSTR_HEADER
- Param source;
- Param result;
- };
- struct instr_ucomplInt {
- MOTH_INSTR_HEADER
- Param source;
- Param result;
- };
- struct instr_increment {
- MOTH_INSTR_HEADER
- Param source;
- Param result;
- };
- struct instr_decrement {
- MOTH_INSTR_HEADER
- Param source;
- Param result;
- };
- struct instr_binop {
- MOTH_INSTR_HEADER
- int alu; // QV4::Runtime::RuntimeMethods enum value
- Param lhs;
- Param rhs;
- Param result;
- };
- struct instr_add {
- MOTH_INSTR_HEADER
- Param lhs;
- Param rhs;
- Param result;
- };
- struct instr_bitAnd {
- MOTH_INSTR_HEADER
- Param lhs;
- Param rhs;
- Param result;
- };
- struct instr_bitOr {
- MOTH_INSTR_HEADER
- Param lhs;
- Param rhs;
- Param result;
- };
- struct instr_bitXor {
- MOTH_INSTR_HEADER
- Param lhs;
- Param rhs;
- Param result;
- };
- struct instr_shr {
- MOTH_INSTR_HEADER
- Param lhs;
- Param rhs;
- Param result;
- };
- struct instr_shl {
- MOTH_INSTR_HEADER
- Param lhs;
- Param rhs;
- Param result;
- };
- struct instr_bitAndConst {
- MOTH_INSTR_HEADER
- Param lhs;
- int rhs;
- Param result;
- };
- struct instr_bitOrConst {
- MOTH_INSTR_HEADER
- Param lhs;
- int rhs;
- Param result;
- };
- struct instr_bitXorConst {
- MOTH_INSTR_HEADER
- Param lhs;
- int rhs;
- Param result;
- };
- struct instr_shrConst {
- MOTH_INSTR_HEADER
- Param lhs;
- int rhs;
- Param result;
- };
- struct instr_shlConst {
- MOTH_INSTR_HEADER
- Param lhs;
- int rhs;
- Param result;
- };
- struct instr_mul {
- MOTH_INSTR_HEADER
- Param lhs;
- Param rhs;
- Param result;
- };
- struct instr_sub {
- MOTH_INSTR_HEADER
- Param lhs;
- Param rhs;
- Param result;
- };
- struct instr_binopContext {
- MOTH_INSTR_HEADER
- uint alu; // offset inside the runtime methods
- Param lhs;
- Param rhs;
- Param result;
- };
- struct instr_loadThis {
- MOTH_INSTR_HEADER
- Param result;
- };
- struct instr_loadQmlContext {
- MOTH_INSTR_HEADER
- Param result;
- };
- struct instr_loadQmlImportedScripts {
- MOTH_INSTR_HEADER
- Param result;
- };
- struct instr_loadQmlSingleton {
- MOTH_INSTR_HEADER
- Param result;
- int name;
- };
+ int argumentsAsInts[4];
+};
- instr_common common;
- instr_ret ret;
- instr_line line;
- instr_debug debug;
- instr_loadRuntimeString loadRuntimeString;
- instr_loadRegExp loadRegExp;
- instr_move move;
- instr_moveConst moveConst;
- instr_swapTemps swapTemps;
- instr_loadClosure loadClosure;
- instr_loadName loadName;
- instr_getGlobalLookup getGlobalLookup;
- instr_storeName storeName;
- instr_loadElement loadElement;
- instr_loadElementLookup loadElementLookup;
- instr_storeElement storeElement;
- instr_storeElementLookup storeElementLookup;
- instr_loadProperty loadProperty;
- instr_getLookup getLookup;
- instr_loadScopeObjectProperty loadScopeObjectProperty;
- instr_loadContextObjectProperty loadContextObjectProperty;
- instr_loadIdObject loadIdObject;
- instr_loadQObjectProperty loadQObjectProperty;
- instr_loadAttachedQObjectProperty loadAttachedQObjectProperty;
- instr_storeProperty storeProperty;
- instr_setLookup setLookup;
- instr_storeScopeObjectProperty storeScopeObjectProperty;
- instr_storeContextObjectProperty storeContextObjectProperty;
- instr_storeQObjectProperty storeQObjectProperty;
- instr_push push;
- instr_callValue callValue;
- instr_callProperty callProperty;
- instr_callPropertyLookup callPropertyLookup;
- instr_callScopeObjectProperty callScopeObjectProperty;
- instr_callContextObjectProperty callContextObjectProperty;
- instr_callElement callElement;
- instr_callActivationProperty callActivationProperty;
- instr_callGlobalLookup callGlobalLookup;
- instr_callBuiltinThrow callBuiltinThrow;
- instr_setExceptionHandler setExceptionHandler;
- instr_callBuiltinUnwindException callBuiltinUnwindException;
- instr_callBuiltinPushCatchScope callBuiltinPushCatchScope;
- instr_callBuiltinPushScope callBuiltinPushScope;
- instr_callBuiltinPopScope callBuiltinPopScope;
- instr_callBuiltinForeachIteratorObject callBuiltinForeachIteratorObject;
- instr_callBuiltinForeachNextPropertyName callBuiltinForeachNextPropertyName;
- instr_callBuiltinDeleteMember callBuiltinDeleteMember;
- instr_callBuiltinDeleteSubscript callBuiltinDeleteSubscript;
- instr_callBuiltinDeleteName callBuiltinDeleteName;
- instr_callBuiltinTypeofScopeObjectProperty callBuiltinTypeofScopeObjectProperty;
- instr_callBuiltinTypeofContextObjectProperty callBuiltinTypeofContextObjectProperty;
- instr_callBuiltinTypeofMember callBuiltinTypeofMember;
- instr_callBuiltinTypeofSubscript callBuiltinTypeofSubscript;
- instr_callBuiltinTypeofName callBuiltinTypeofName;
- instr_callBuiltinTypeofValue callBuiltinTypeofValue;
- instr_callBuiltinDeclareVar callBuiltinDeclareVar;
- instr_callBuiltinDefineArray callBuiltinDefineArray;
- instr_callBuiltinDefineObjectLiteral callBuiltinDefineObjectLiteral;
- instr_callBuiltinSetupArgumentsObject callBuiltinSetupArgumentsObject;
- instr_callBuiltinConvertThisToObject callBuiltinConvertThisToObject;
- instr_createValue createValue;
- instr_createProperty createProperty;
- instr_constructPropertyLookup constructPropertyLookup;
- instr_createActivationProperty createActivationProperty;
- instr_constructGlobalLookup constructGlobalLookup;
- instr_jump jump;
- instr_jumpEq jumpEq;
- instr_jumpNe jumpNe;
- instr_unot unot;
- instr_unotBool unotBool;
- instr_uplus uplus;
- instr_uminus uminus;
- instr_ucompl ucompl;
- instr_ucomplInt ucomplInt;
- instr_increment increment;
- instr_decrement decrement;
- instr_binop binop;
- instr_add add;
- instr_bitAnd bitAnd;
- instr_bitOr bitOr;
- instr_bitXor bitXor;
- instr_shr shr;
- instr_shl shl;
- instr_bitAndConst bitAndConst;
- instr_bitOrConst bitOrConst;
- instr_bitXorConst bitXorConst;
- instr_shrConst shrConst;
- instr_shlConst shlConst;
- instr_mul mul;
- instr_sub sub;
- instr_binopContext binopContext;
- instr_loadThis loadThis;
- instr_loadQmlContext loadQmlContext;
- instr_loadQmlImportedScripts loadQmlImportedScripts;
- instr_loadQmlSingleton loadQmlSingleton;
-
- static int size(Type type);
+struct InstrInfo
+{
+ static const int argumentCount[];
+ static int size(Instr::Type type);
};
+Q_STATIC_ASSERT(MOTH_NUM_INSTRUCTIONS() < 128);
+
template<int N>
struct InstrMeta {
};
QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Wuninitialized")
-#define MOTH_INSTR_META_TEMPLATE(I, FMT) \
- template<> struct InstrMeta<(int)Instr::I> { \
- enum { Size = MOTH_INSTR_SIZE(I, FMT) }; \
- typedef Instr::instr_##FMT DataType; \
- static const DataType &data(const Instr &instr) { return instr.FMT; } \
- static void setData(Instr &instr, const DataType &v) { instr.FMT = v; } \
- static void setDataNoCommon(Instr &instr, const DataType &v) \
- { memcpy(reinterpret_cast<char *>(&instr.FMT) + sizeof(Instr::instr_common), \
- reinterpret_cast<const char *>(&v) + sizeof(Instr::instr_common), \
- Size - sizeof(Instr::instr_common)); } \
+QT_WARNING_DISABLE_GCC("-Wmaybe-uninitialized")
+#define MOTH_INSTR_META_TEMPLATE(I) \
+ template<> struct InstrMeta<int(Instr::Type::I)> { \
+ enum { Size = MOTH_INSTR_SIZE(I) }; \
+ typedef Instr::instr_##I DataType; \
+ static const DataType &data(const Instr &instr) { return instr.I; } \
+ static void setData(Instr &instr, const DataType &v) \
+ { memcpy(reinterpret_cast<char *>(&instr.I), \
+ reinterpret_cast<const char *>(&v), \
+ Size); } \
};
FOR_EACH_MOTH_INSTR(MOTH_INSTR_META_TEMPLATE);
#undef MOTH_INSTR_META_TEMPLATE
@@ -919,6 +513,14 @@ class InstrData : public InstrMeta<InstrType>::DataType
{
};
+struct Instruction {
+#define MOTH_INSTR_DATA_TYPEDEF(I) typedef InstrData<int(Instr::Type::I)> I;
+FOR_EACH_MOTH_INSTR(MOTH_INSTR_DATA_TYPEDEF)
+#undef MOTH_INSTR_DATA_TYPEDEF
+private:
+ Instruction();
+};
+
} // namespace Moth
} // namespace QV4
diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp
deleted file mode 100644
index c29ffa10c2..0000000000
--- a/src/qml/compiler/qv4isel_moth.cpp
+++ /dev/null
@@ -1,1522 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qv4isel_util_p.h"
-#include "qv4isel_moth_p.h"
-#include "qv4ssa_p.h"
-#include <private/qv4compileddata_p.h>
-#include <wtf/MathExtras.h>
-
-#if !defined(V4_BOOTSTRAP)
-#include "qv4vme_moth_p.h"
-#include <private/qv4function_p.h>
-#endif
-
-#undef USE_TYPE_INFO
-
-using namespace QV4;
-using namespace QV4::Moth;
-
-namespace {
-
-inline QV4::Runtime::RuntimeMethods aluOpFunction(IR::AluOp op)
-{
- switch (op) {
- case IR::OpInvalid:
- return QV4::Runtime::InvalidRuntimeMethod;
- case IR::OpIfTrue:
- return QV4::Runtime::InvalidRuntimeMethod;
- case IR::OpNot:
- return QV4::Runtime::InvalidRuntimeMethod;
- case IR::OpUMinus:
- return QV4::Runtime::InvalidRuntimeMethod;
- case IR::OpUPlus:
- return QV4::Runtime::InvalidRuntimeMethod;
- case IR::OpCompl:
- return QV4::Runtime::InvalidRuntimeMethod;
- case IR::OpBitAnd:
- return QV4::Runtime::bitAnd;
- case IR::OpBitOr:
- return QV4::Runtime::bitOr;
- case IR::OpBitXor:
- return QV4::Runtime::bitXor;
- case IR::OpAdd:
- return QV4::Runtime::InvalidRuntimeMethod;
- case IR::OpSub:
- return QV4::Runtime::sub;
- case IR::OpMul:
- return QV4::Runtime::mul;
- case IR::OpDiv:
- return QV4::Runtime::div;
- case IR::OpMod:
- return QV4::Runtime::mod;
- case IR::OpLShift:
- return QV4::Runtime::shl;
- case IR::OpRShift:
- return QV4::Runtime::shr;
- case IR::OpURShift:
- return QV4::Runtime::ushr;
- case IR::OpGt:
- return QV4::Runtime::greaterThan;
- case IR::OpLt:
- return QV4::Runtime::lessThan;
- case IR::OpGe:
- return QV4::Runtime::greaterEqual;
- case IR::OpLe:
- return QV4::Runtime::lessEqual;
- case IR::OpEqual:
- return QV4::Runtime::equal;
- case IR::OpNotEqual:
- return QV4::Runtime::notEqual;
- case IR::OpStrictEqual:
- return QV4::Runtime::strictEqual;
- case IR::OpStrictNotEqual:
- return QV4::Runtime::strictNotEqual;
- case IR::OpInstanceof:
- return QV4::Runtime::InvalidRuntimeMethod;
- case IR::OpIn:
- return QV4::Runtime::InvalidRuntimeMethod;
- case IR::OpAnd:
- return QV4::Runtime::InvalidRuntimeMethod;
- case IR::OpOr:
- return QV4::Runtime::InvalidRuntimeMethod;
- default:
- Q_ASSERT(!"Unknown AluOp");
- return QV4::Runtime::InvalidRuntimeMethod;
- }
-};
-
-inline bool isNumberType(IR::Expr *e)
-{
- switch (e->type) {
- case IR::SInt32Type:
- case IR::UInt32Type:
- case IR::DoubleType:
- return true;
- default:
- return false;
- }
-}
-
-inline bool isIntegerType(IR::Expr *e)
-{
- switch (e->type) {
- case IR::SInt32Type:
- case IR::UInt32Type:
- return true;
- default:
- return false;
- }
-}
-
-inline bool isBoolType(IR::Expr *e)
-{
- return (e->type == IR::BoolType);
-}
-
-} // anonymous namespace
-
-InstructionSelection::InstructionSelection(QQmlEnginePrivate *qmlEngine, QV4::ExecutableAllocator *execAllocator, IR::Module *module, QV4::Compiler::JSUnitGenerator *jsGenerator, EvalISelFactory *iselFactory)
- : EvalInstructionSelection(execAllocator, module, jsGenerator, iselFactory)
- , qmlEngine(qmlEngine)
- , _block(0)
- , _codeStart(0)
- , _codeNext(0)
- , _codeEnd(0)
- , _currentStatement(0)
- , compilationUnit(new CompilationUnit)
-{
- setUseTypeInference(false);
-}
-
-InstructionSelection::~InstructionSelection()
-{
-}
-
-void InstructionSelection::run(int functionIndex)
-{
- IR::Function *function = irModule->functions[functionIndex];
- IR::BasicBlock *block = 0, *nextBlock = 0;
-
- QHash<IR::BasicBlock *, QVector<ptrdiff_t> > patches;
- QHash<IR::BasicBlock *, ptrdiff_t> addrs;
-
- int codeSize = 4096;
- uchar *codeStart = new uchar[codeSize];
- memset(codeStart, 0, codeSize);
- uchar *codeNext = codeStart;
- uchar *codeEnd = codeStart + codeSize;
-
- qSwap(_function, function);
- qSwap(block, _block);
- qSwap(nextBlock, _nextBlock);
- qSwap(patches, _patches);
- qSwap(addrs, _addrs);
- qSwap(codeStart, _codeStart);
- qSwap(codeNext, _codeNext);
- qSwap(codeEnd, _codeEnd);
-
- IR::Optimizer opt(_function);
- opt.run(qmlEngine, useTypeInference, /*peelLoops =*/ false);
- if (opt.isInSSA()) {
- static const bool doStackSlotAllocation =
- qEnvironmentVariableIsEmpty("QV4_NO_INTERPRETER_STACK_SLOT_ALLOCATION");
-
- if (doStackSlotAllocation) {
- IR::AllocateStackSlots(opt.lifeTimeIntervals()).forFunction(_function);
- } else {
- opt.convertOutOfSSA();
- ConvertTemps().toStackSlots(_function);
- }
- opt.showMeTheCode(_function, "After stack slot allocation");
- } else {
- ConvertTemps().toStackSlots(_function);
- }
-
- BitVector removableJumps = opt.calculateOptionalJumps();
- qSwap(_removableJumps, removableJumps);
-
- IR::Stmt *cs = 0;
- qSwap(_currentStatement, cs);
-
- int locals = frameSize();
- Q_ASSERT(locals >= 0);
-
- IR::BasicBlock *exceptionHandler = 0;
-
- Instruction::Push push;
- push.value = quint32(locals);
- addInstruction(push);
-
- currentLine = 0;
- const QVector<IR::BasicBlock *> &basicBlocks = _function->basicBlocks();
- for (int i = 0, ei = basicBlocks.size(); i != ei; ++i) {
- blockNeedsDebugInstruction = irModule->debugMode;
- _block = basicBlocks[i];
- _nextBlock = (i < ei - 1) ? basicBlocks[i + 1] : 0;
- _addrs.insert(_block, _codeNext - _codeStart);
-
- if (_block->catchBlock != exceptionHandler) {
- Instruction::SetExceptionHandler set;
- set.offset = 0;
- if (_block->catchBlock) {
- ptrdiff_t loc = addInstruction(set) + (((const char *)&set.offset) - ((const char *)&set));
- _patches[_block->catchBlock].append(loc);
- } else {
- addInstruction(set);
- }
- exceptionHandler = _block->catchBlock;
- } else if (_block->catchBlock == nullptr && _block->index() != 0 && _block->in.isEmpty()) {
- exceptionHandler = nullptr;
- Instruction::SetExceptionHandler set;
- set.offset = 0;
- addInstruction(set);
- }
-
- for (IR::Stmt *s : _block->statements()) {
- _currentStatement = s;
-
- if (s->location.isValid()) {
- if (s->location.startLine != currentLine) {
- blockNeedsDebugInstruction = false;
- currentLine = s->location.startLine;
-#ifndef QT_NO_QML_DEBUGGER
- if (irModule->debugMode) {
- Instruction::Debug debug;
- debug.lineNumber = currentLine;
- addInstruction(debug);
- } else {
- Instruction::Line line;
- line.lineNumber = currentLine;
- addInstruction(line);
- }
-#endif
- }
- }
-
- visit(s);
- }
- }
-
- // TODO: patch stack size (the push instruction)
- patchJumpAddresses();
-
- codeRefs.insert(_function, squeezeCode());
-
- qSwap(_currentStatement, cs);
- qSwap(_removableJumps, removableJumps);
- qSwap(_function, function);
- qSwap(block, _block);
- qSwap(nextBlock, _nextBlock);
- qSwap(patches, _patches);
- qSwap(addrs, _addrs);
- qSwap(codeStart, _codeStart);
- qSwap(codeNext, _codeNext);
- qSwap(codeEnd, _codeEnd);
-
- delete[] codeStart;
-}
-
-QQmlRefPointer<QV4::CompiledData::CompilationUnit> InstructionSelection::backendCompileStep()
-{
- compilationUnit->codeRefs.resize(irModule->functions.size());
- int i = 0;
- for (IR::Function *irFunction : qAsConst(irModule->functions))
- compilationUnit->codeRefs[i++] = codeRefs[irFunction];
- QQmlRefPointer<QV4::CompiledData::CompilationUnit> result;
- result.adopt(compilationUnit.take());
- return result;
-}
-
-void InstructionSelection::callValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result)
-{
- Instruction::CallValue call;
- prepareCallArgs(args, call.argc);
- call.callData = callDataStart();
- call.dest = getParam(value);
- call.result = getResultParam(result);
- addInstruction(call);
-}
-
-void InstructionSelection::callQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int propertyIndex, IR::ExprList *args, IR::Expr *result)
-{
- if (kind == IR::Member::MemberOfQmlScopeObject) {
- Instruction::CallScopeObjectProperty call;
- call.base = getParam(base);
- call.index = propertyIndex;
- prepareCallArgs(args, call.argc);
- call.callData = callDataStart();
- call.result = getResultParam(result);
- addInstruction(call);
- } else if (kind == IR::Member::MemberOfQmlContextObject) {
- Instruction::CallContextObjectProperty call;
- call.base = getParam(base);
- call.index = propertyIndex;
- prepareCallArgs(args, call.argc);
- call.callData = callDataStart();
- call.result = getResultParam(result);
- addInstruction(call);
- } else {
- Q_ASSERT(false);
- }
-}
-
-void InstructionSelection::callProperty(IR::Expr *base, const QString &name, IR::ExprList *args,
- IR::Expr *result)
-{
- if (useFastLookups) {
- Instruction::CallPropertyLookup call;
- call.base = getParam(base);
- call.lookupIndex = registerGetterLookup(name);
- prepareCallArgs(args, call.argc);
- call.callData = callDataStart();
- call.result = getResultParam(result);
- addInstruction(call);
- } else {
- // call the property on the loaded base
- Instruction::CallProperty call;
- call.base = getParam(base);
- call.name = registerString(name);
- prepareCallArgs(args, call.argc);
- call.callData = callDataStart();
- call.result = getResultParam(result);
- addInstruction(call);
- }
-}
-
-void InstructionSelection::callSubscript(IR::Expr *base, IR::Expr *index, IR::ExprList *args,
- IR::Expr *result)
-{
- // call the property on the loaded base
- Instruction::CallElement call;
- call.base = getParam(base);
- call.index = getParam(index);
- prepareCallArgs(args, call.argc);
- call.callData = callDataStart();
- call.result = getResultParam(result);
- addInstruction(call);
-}
-
-void InstructionSelection::convertType(IR::Expr *source, IR::Expr *target)
-{
- // FIXME: do something more useful with this info
- if (target->type & IR::NumberType && !(source->type & IR::NumberType))
- unop(IR::OpUPlus, source, target);
- else
- copyValue(source, target);
-}
-
-void InstructionSelection::constructActivationProperty(IR::Name *func,
- IR::ExprList *args,
- IR::Expr *target)
-{
- if ((useFastLookups || func->forceLookup) && func->global) {
- Instruction::ConstructGlobalLookup call;
- call.index = registerGlobalGetterLookup(*func->id);
- prepareCallArgs(args, call.argc);
- call.callData = callDataStart();
- call.result = getResultParam(target);
- addInstruction(call);
- return;
- }
- Instruction::CreateActivationProperty create;
- create.name = registerString(*func->id);
- prepareCallArgs(args, create.argc);
- create.callData = callDataStart();
- create.result = getResultParam(target);
- addInstruction(create);
-}
-
-void InstructionSelection::constructProperty(IR::Expr *base, const QString &name, IR::ExprList *args, IR::Expr *target)
-{
- if (useFastLookups) {
- Instruction::ConstructPropertyLookup call;
- call.base = getParam(base);
- call.index = registerGetterLookup(name);
- prepareCallArgs(args, call.argc);
- call.callData = callDataStart();
- call.result = getResultParam(target);
- addInstruction(call);
- return;
- }
- Instruction::CreateProperty create;
- create.base = getParam(base);
- create.name = registerString(name);
- prepareCallArgs(args, create.argc);
- create.callData = callDataStart();
- create.result = getResultParam(target);
- addInstruction(create);
-}
-
-void InstructionSelection::constructValue(IR::Expr *value, IR::ExprList *args, IR::Expr *target)
-{
- Instruction::CreateValue create;
- create.func = getParam(value);
- prepareCallArgs(args, create.argc);
- create.callData = callDataStart();
- create.result = getResultParam(target);
- addInstruction(create);
-}
-
-void InstructionSelection::loadThisObject(IR::Expr *e)
-{
- Instruction::LoadThis load;
- load.result = getResultParam(e);
- addInstruction(load);
-}
-
-void InstructionSelection::loadQmlContext(IR::Expr *e)
-{
- Instruction::LoadQmlContext load;
- load.result = getResultParam(e);
- addInstruction(load);
-}
-
-void InstructionSelection::loadQmlImportedScripts(IR::Expr *e)
-{
- Instruction::LoadQmlImportedScripts load;
- load.result = getResultParam(e);
- addInstruction(load);
-}
-
-void InstructionSelection::loadQmlSingleton(const QString &name, IR::Expr *e)
-{
- Instruction::LoadQmlSingleton load;
- load.result = getResultParam(e);
- load.name = registerString(name);
- addInstruction(load);
-}
-
-void InstructionSelection::loadConst(IR::Const *sourceConst, IR::Expr *e)
-{
- Q_ASSERT(sourceConst);
-
- Instruction::MoveConst move;
- move.source = convertToValue(sourceConst).asReturnedValue();
- move.result = getResultParam(e);
- addInstruction(move);
-}
-
-void InstructionSelection::loadString(const QString &str, IR::Expr *target)
-{
- Instruction::LoadRuntimeString load;
- load.stringId = registerString(str);
- load.result = getResultParam(target);
- addInstruction(load);
-}
-
-void InstructionSelection::loadRegexp(IR::RegExp *sourceRegexp, IR::Expr *target)
-{
- Instruction::LoadRegExp load;
- load.regExpId = registerRegExp(sourceRegexp);
- load.result = getResultParam(target);
- addInstruction(load);
-}
-
-void InstructionSelection::getActivationProperty(const IR::Name *name, IR::Expr *target)
-{
- if ((useFastLookups || name->forceLookup) && name->global) {
- Instruction::GetGlobalLookup load;
- load.index = registerGlobalGetterLookup(*name->id);
- load.result = getResultParam(target);
- addInstruction(load);
- return;
- }
- Instruction::LoadName load;
- load.name = registerString(*name->id);
- load.result = getResultParam(target);
- addInstruction(load);
-}
-
-void InstructionSelection::setActivationProperty(IR::Expr *source, const QString &targetName)
-{
- Instruction::StoreName store;
- store.source = getParam(source);
- store.name = registerString(targetName);
- addInstruction(store);
-}
-
-void InstructionSelection::initClosure(IR::Closure *closure, IR::Expr *target)
-{
- int id = closure->value;
- Instruction::LoadClosure load;
- load.value = id;
- load.result = getResultParam(target);
- addInstruction(load);
-}
-
-void InstructionSelection::getProperty(IR::Expr *base, const QString &name, IR::Expr *target)
-{
- if (useFastLookups) {
- Instruction::GetLookup load;
- load.base = getParam(base);
- load.index = registerGetterLookup(name);
- load.result = getResultParam(target);
- addInstruction(load);
- return;
- }
- Instruction::LoadProperty load;
- load.base = getParam(base);
- load.name = registerString(name);
- load.result = getResultParam(target);
- addInstruction(load);
-}
-
-void InstructionSelection::setProperty(IR::Expr *source, IR::Expr *targetBase,
- const QString &targetName)
-{
- if (useFastLookups) {
- Instruction::SetLookup store;
- store.base = getParam(targetBase);
- store.index = registerSetterLookup(targetName);
- store.source = getParam(source);
- addInstruction(store);
- return;
- }
- Instruction::StoreProperty store;
- store.base = getParam(targetBase);
- store.name = registerString(targetName);
- store.source = getParam(source);
- addInstruction(store);
-}
-
-void InstructionSelection::setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase, IR::Member::MemberKind kind, int propertyIndex)
-{
- if (kind == IR::Member::MemberOfQmlScopeObject) {
- Instruction::StoreScopeObjectProperty store;
- store.base = getParam(targetBase);
- store.propertyIndex = propertyIndex;
- store.source = getParam(source);
- addInstruction(store);
- } else if (kind == IR::Member::MemberOfQmlContextObject) {
- Instruction::StoreContextObjectProperty store;
- store.base = getParam(targetBase);
- store.propertyIndex = propertyIndex;
- store.source = getParam(source);
- addInstruction(store);
- } else {
- Q_ASSERT(false);
- }
-}
-
-void InstructionSelection::setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int propertyIndex)
-{
- Instruction::StoreQObjectProperty store;
- store.base = getParam(targetBase);
- store.propertyIndex = propertyIndex;
- store.source = getParam(source);
- addInstruction(store);
-}
-
-void InstructionSelection::getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, int index, bool captureRequired, IR::Expr *target)
-{
- if (kind == IR::Member::MemberOfQmlScopeObject) {
- Instruction::LoadScopeObjectProperty load;
- load.base = getParam(source);
- load.propertyIndex = index;
- load.captureRequired = captureRequired;
- load.result = getResultParam(target);
- addInstruction(load);
- } else if (kind == IR::Member::MemberOfQmlContextObject) {
- Instruction::LoadContextObjectProperty load;
- load.base = getParam(source);
- load.propertyIndex = index;
- load.captureRequired = captureRequired;
- load.result = getResultParam(target);
- addInstruction(load);
- } else if (kind == IR::Member::MemberOfIdObjectsArray) {
- Instruction::LoadIdObject load;
- load.base = getParam(source);
- load.index = index;
- load.result = getResultParam(target);
- addInstruction(load);
- } else {
- Q_ASSERT(false);
- }
-}
-
-void InstructionSelection::getQObjectProperty(IR::Expr *base, int propertyIndex, bool captureRequired, bool isSingletonProperty, int attachedPropertiesId, IR::Expr *target)
-{
- if (attachedPropertiesId != 0) {
- Instruction::LoadAttachedQObjectProperty load;
- load.propertyIndex = propertyIndex;
- load.result = getResultParam(target);
- load.attachedPropertiesId = attachedPropertiesId;
- addInstruction(load);
- } else if (isSingletonProperty) {
- Instruction::LoadSingletonQObjectProperty load;
- load.base = getParam(base);
- load.propertyIndex = propertyIndex;
- load.result = getResultParam(target);
- load.captureRequired = captureRequired;
- addInstruction(load);
- } else {
- Instruction::LoadQObjectProperty load;
- load.base = getParam(base);
- load.propertyIndex = propertyIndex;
- load.result = getResultParam(target);
- load.captureRequired = captureRequired;
- addInstruction(load);
- }
-}
-
-void InstructionSelection::getElement(IR::Expr *base, IR::Expr *index, IR::Expr *target)
-{
- if (0 && useFastLookups) {
- Instruction::LoadElementLookup load;
- load.lookup = registerIndexedGetterLookup();
- load.base = getParam(base);
- load.index = getParam(index);
- load.result = getResultParam(target);
- addInstruction(load);
- return;
- }
- Instruction::LoadElement load;
- load.base = getParam(base);
- load.index = getParam(index);
- load.result = getResultParam(target);
- addInstruction(load);
-}
-
-void InstructionSelection::setElement(IR::Expr *source, IR::Expr *targetBase,
- IR::Expr *targetIndex)
-{
- if (0 && useFastLookups) {
- Instruction::StoreElementLookup store;
- store.lookup = registerIndexedSetterLookup();
- store.base = getParam(targetBase);
- store.index = getParam(targetIndex);
- store.source = getParam(source);
- addInstruction(store);
- return;
- }
- Instruction::StoreElement store;
- store.base = getParam(targetBase);
- store.index = getParam(targetIndex);
- store.source = getParam(source);
- addInstruction(store);
-}
-
-void InstructionSelection::copyValue(IR::Expr *source, IR::Expr *target)
-{
- Instruction::Move move;
- move.source = getParam(source);
- move.result = getResultParam(target);
- if (move.source != move.result)
- addInstruction(move);
-}
-
-void InstructionSelection::swapValues(IR::Expr *source, IR::Expr *target)
-{
- Instruction::SwapTemps swap;
- swap.left = getParam(source);
- swap.right = getParam(target);
- addInstruction(swap);
-}
-
-void InstructionSelection::unop(IR::AluOp oper, IR::Expr *source, IR::Expr *target)
-{
- switch (oper) {
- case IR::OpIfTrue:
- Q_ASSERT(!"unreachable"); break;
- case IR::OpNot: {
- // ### enabling this fails in some cases, where apparently the value is not a bool at runtime
- if (0 && isBoolType(source)) {
- Instruction::UNotBool unot;
- unot.source = getParam(source);
- unot.result = getResultParam(target);
- addInstruction(unot);
- return;
- }
- Instruction::UNot unot;
- unot.source = getParam(source);
- unot.result = getResultParam(target);
- addInstruction(unot);
- return;
- }
- case IR::OpUMinus: {
- Instruction::UMinus uminus;
- uminus.source = getParam(source);
- uminus.result = getResultParam(target);
- addInstruction(uminus);
- return;
- }
- case IR::OpUPlus: {
- if (isNumberType(source)) {
- // use a move
- Instruction::Move move;
- move.source = getParam(source);
- move.result = getResultParam(target);
- if (move.source != move.result)
- addInstruction(move);
- return;
- }
- Instruction::UPlus uplus;
- uplus.source = getParam(source);
- uplus.result = getResultParam(target);
- addInstruction(uplus);
- return;
- }
- case IR::OpCompl: {
- // ### enabling this fails in some cases, where apparently the value is not a int at runtime
- if (0 && isIntegerType(source)) {
- Instruction::UComplInt unot;
- unot.source = getParam(source);
- unot.result = getResultParam(target);
- addInstruction(unot);
- return;
- }
- Instruction::UCompl ucompl;
- ucompl.source = getParam(source);
- ucompl.result = getResultParam(target);
- addInstruction(ucompl);
- return;
- }
- case IR::OpIncrement: {
- Instruction::Increment inc;
- inc.source = getParam(source);
- inc.result = getResultParam(target);
- addInstruction(inc);
- return;
- }
- case IR::OpDecrement: {
- Instruction::Decrement dec;
- dec.source = getParam(source);
- dec.result = getResultParam(target);
- addInstruction(dec);
- return;
- }
- default: break;
- } // switch
-
- Q_ASSERT(!"unreachable");
-}
-
-void InstructionSelection::binop(IR::AluOp oper, IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target)
-{
- binopHelper(oper, leftSource, rightSource, target);
-}
-
-Param InstructionSelection::binopHelper(IR::AluOp oper, IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target)
-{
- if (oper == IR::OpAdd) {
- Instruction::Add add;
- add.lhs = getParam(leftSource);
- add.rhs = getParam(rightSource);
- add.result = getResultParam(target);
- addInstruction(add);
- return add.result;
- }
- if (oper == IR::OpSub) {
- Instruction::Sub sub;
- sub.lhs = getParam(leftSource);
- sub.rhs = getParam(rightSource);
- sub.result = getResultParam(target);
- addInstruction(sub);
- return sub.result;
- }
- if (oper == IR::OpMul) {
- Instruction::Mul mul;
- mul.lhs = getParam(leftSource);
- mul.rhs = getParam(rightSource);
- mul.result = getResultParam(target);
- addInstruction(mul);
- return mul.result;
- }
- if (oper == IR::OpBitAnd) {
- if (leftSource->asConst())
- qSwap(leftSource, rightSource);
- if (IR::Const *c = rightSource->asConst()) {
- Instruction::BitAndConst bitAnd;
- bitAnd.lhs = getParam(leftSource);
- bitAnd.rhs = convertToValue(c).Value::toInt32();
- bitAnd.result = getResultParam(target);
- addInstruction(bitAnd);
- return bitAnd.result;
- }
- Instruction::BitAnd bitAnd;
- bitAnd.lhs = getParam(leftSource);
- bitAnd.rhs = getParam(rightSource);
- bitAnd.result = getResultParam(target);
- addInstruction(bitAnd);
- return bitAnd.result;
- }
- if (oper == IR::OpBitOr) {
- if (leftSource->asConst())
- qSwap(leftSource, rightSource);
- if (IR::Const *c = rightSource->asConst()) {
- Instruction::BitOrConst bitOr;
- bitOr.lhs = getParam(leftSource);
- bitOr.rhs = convertToValue(c).Value::toInt32();
- bitOr.result = getResultParam(target);
- addInstruction(bitOr);
- return bitOr.result;
- }
- Instruction::BitOr bitOr;
- bitOr.lhs = getParam(leftSource);
- bitOr.rhs = getParam(rightSource);
- bitOr.result = getResultParam(target);
- addInstruction(bitOr);
- return bitOr.result;
- }
- if (oper == IR::OpBitXor) {
- if (leftSource->asConst())
- qSwap(leftSource, rightSource);
- if (IR::Const *c = rightSource->asConst()) {
- Instruction::BitXorConst bitXor;
- bitXor.lhs = getParam(leftSource);
- bitXor.rhs = convertToValue(c).Value::toInt32();
- bitXor.result = getResultParam(target);
- addInstruction(bitXor);
- return bitXor.result;
- }
- Instruction::BitXor bitXor;
- bitXor.lhs = getParam(leftSource);
- bitXor.rhs = getParam(rightSource);
- bitXor.result = getResultParam(target);
- addInstruction(bitXor);
- return bitXor.result;
- }
- if (oper == IR::OpRShift) {
- if (IR::Const *c = rightSource->asConst()) {
- Instruction::ShrConst shr;
- shr.lhs = getParam(leftSource);
- shr.rhs = convertToValue(c).Value::toInt32() & 0x1f;
- shr.result = getResultParam(target);
- addInstruction(shr);
- return shr.result;
- }
- Instruction::Shr shr;
- shr.lhs = getParam(leftSource);
- shr.rhs = getParam(rightSource);
- shr.result = getResultParam(target);
- addInstruction(shr);
- return shr.result;
- }
- if (oper == IR::OpLShift) {
- if (IR::Const *c = rightSource->asConst()) {
- Instruction::ShlConst shl;
- shl.lhs = getParam(leftSource);
- shl.rhs = convertToValue(c).Value::toInt32() & 0x1f;
- shl.result = getResultParam(target);
- addInstruction(shl);
- return shl.result;
- }
- Instruction::Shl shl;
- shl.lhs = getParam(leftSource);
- shl.rhs = getParam(rightSource);
- shl.result = getResultParam(target);
- addInstruction(shl);
- return shl.result;
- }
-
- if (oper == IR::OpInstanceof || oper == IR::OpIn || oper == IR::OpAdd) {
- Instruction::BinopContext binop;
- if (oper == IR::OpInstanceof)
- binop.alu = QV4::Runtime::instanceof;
- else if (oper == IR::OpIn)
- binop.alu = QV4::Runtime::in;
- else
- binop.alu = QV4::Runtime::add;
- binop.lhs = getParam(leftSource);
- binop.rhs = getParam(rightSource);
- binop.result = getResultParam(target);
- Q_ASSERT(binop.alu != QV4::Runtime::InvalidRuntimeMethod);
- addInstruction(binop);
- return binop.result;
- } else {
- auto binopFunc = aluOpFunction(oper);
- Q_ASSERT(binopFunc != QV4::Runtime::InvalidRuntimeMethod);
- Instruction::Binop binop;
- binop.alu = binopFunc;
- binop.lhs = getParam(leftSource);
- binop.rhs = getParam(rightSource);
- binop.result = getResultParam(target);
- addInstruction(binop);
- return binop.result;
- }
-}
-
-void InstructionSelection::prepareCallArgs(IR::ExprList *e, quint32 &argc, quint32 *args)
-{
- int argLocation = outgoingArgumentTempStart();
- argc = 0;
- if (args)
- *args = argLocation;
- if (e) {
- // We need to move all the temps into the function arg array
- Q_ASSERT(argLocation >= 0);
- while (e) {
- if (IR::Const *c = e->expr->asConst()) {
- Instruction::MoveConst move;
- move.source = convertToValue(c).asReturnedValue();
- move.result = Param::createTemp(argLocation);
- addInstruction(move);
- } else {
- Instruction::Move move;
- move.source = getParam(e->expr);
- move.result = Param::createTemp(argLocation);
- addInstruction(move);
- }
- ++argLocation;
- ++argc;
- e = e->next;
- }
- }
-}
-
-void InstructionSelection::addDebugInstruction()
-{
-#ifndef QT_NO_QML_DEBUGGER
- if (blockNeedsDebugInstruction) {
- Instruction::Debug debug;
- debug.lineNumber = -int(currentLine);
- addInstruction(debug);
- }
-#endif
-}
-
-void InstructionSelection::visitJump(IR::Jump *s)
-{
- if (s->target == _nextBlock)
- return;
- if (_removableJumps.at(_block->index()))
- return;
-
- addDebugInstruction();
-
- Instruction::Jump jump;
- jump.offset = 0;
- ptrdiff_t loc = addInstruction(jump) + (((const char *)&jump.offset) - ((const char *)&jump));
-
- _patches[s->target].append(loc);
-}
-
-void InstructionSelection::visitCJump(IR::CJump *s)
-{
- addDebugInstruction();
-
- Param condition;
- if (IR::Temp *t = s->cond->asTemp()) {
- condition = getResultParam(t);
- } else if (IR::Binop *b = s->cond->asBinop()) {
- condition = binopHelper(b->op, b->left, b->right, /*target*/0);
- } else {
- Q_UNIMPLEMENTED();
- }
-
- if (s->iftrue == _nextBlock) {
- Instruction::JumpNe jump;
- jump.offset = 0;
- jump.condition = condition;
- ptrdiff_t falseLoc = addInstruction(jump) + (((const char *)&jump.offset) - ((const char *)&jump));
- _patches[s->iffalse].append(falseLoc);
- } else {
- Instruction::JumpEq jump;
- jump.offset = 0;
- jump.condition = condition;
- ptrdiff_t trueLoc = addInstruction(jump) + (((const char *)&jump.offset) - ((const char *)&jump));
- _patches[s->iftrue].append(trueLoc);
-
- if (s->iffalse != _nextBlock) {
- Instruction::Jump jump;
- jump.offset = 0;
- ptrdiff_t falseLoc = addInstruction(jump) + (((const char *)&jump.offset) - ((const char *)&jump));
- _patches[s->iffalse].append(falseLoc);
- }
- }
-}
-
-void InstructionSelection::visitRet(IR::Ret *s)
-{
- // this is required so stepOut will always be guaranteed to stop in every stack frame
- addDebugInstruction();
-
- Instruction::Ret ret;
- ret.result = getParam(s->expr);
- addInstruction(ret);
-}
-
-void InstructionSelection::callBuiltinInvalid(IR::Name *func, IR::ExprList *args, IR::Expr *result)
-{
- if ((useFastLookups || func->forceLookup) && func->global) {
- Instruction::CallGlobalLookup call;
- call.index = registerGlobalGetterLookup(*func->id);
- prepareCallArgs(args, call.argc);
- call.callData = callDataStart();
- call.result = getResultParam(result);
- addInstruction(call);
- return;
- }
- Instruction::CallActivationProperty call;
- call.name = registerString(*func->id);
- prepareCallArgs(args, call.argc);
- call.callData = callDataStart();
- call.result = getResultParam(result);
- addInstruction(call);
-}
-
-void InstructionSelection::callBuiltinTypeofQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int propertyIndex, IR::Expr *result)
-{
- if (kind == IR::Member::MemberOfQmlScopeObject) {
- Instruction::CallBuiltinTypeofScopeObjectProperty call;
- call.base = getParam(base);
- call.index = propertyIndex;
- call.result = getResultParam(result);
- addInstruction(call);
- } else if (kind == IR::Member::MemberOfQmlContextObject) {
- Instruction::CallBuiltinTypeofContextObjectProperty call;
- call.base = getParam(base);
- call.index = propertyIndex;
- call.result = getResultParam(result);
- addInstruction(call);
- } else {
- Q_UNREACHABLE();
- }
-}
-
-void InstructionSelection::callBuiltinTypeofMember(IR::Expr *base, const QString &name,
- IR::Expr *result)
-{
- Instruction::CallBuiltinTypeofMember call;
- call.base = getParam(base);
- call.member = registerString(name);
- call.result = getResultParam(result);
- addInstruction(call);
-}
-
-void InstructionSelection::callBuiltinTypeofSubscript(IR::Expr *base, IR::Expr *index,
- IR::Expr *result)
-{
- Instruction::CallBuiltinTypeofSubscript call;
- call.base = getParam(base);
- call.index = getParam(index);
- call.result = getResultParam(result);
- addInstruction(call);
-}
-
-void InstructionSelection::callBuiltinTypeofName(const QString &name, IR::Expr *result)
-{
- Instruction::CallBuiltinTypeofName call;
- call.name = registerString(name);
- call.result = getResultParam(result);
- addInstruction(call);
-}
-
-void InstructionSelection::callBuiltinTypeofValue(IR::Expr *value, IR::Expr *result)
-{
- Instruction::CallBuiltinTypeofValue call;
- call.value = getParam(value);
- call.result = getResultParam(result);
- addInstruction(call);
-}
-
-void InstructionSelection::callBuiltinDeleteMember(IR::Expr *base, const QString &name, IR::Expr *result)
-{
- Instruction::CallBuiltinDeleteMember call;
- call.base = getParam(base);
- call.member = registerString(name);
- call.result = getResultParam(result);
- addInstruction(call);
-}
-
-void InstructionSelection::callBuiltinDeleteSubscript(IR::Expr *base, IR::Expr *index,
- IR::Expr *result)
-{
- Instruction::CallBuiltinDeleteSubscript call;
- call.base = getParam(base);
- call.index = getParam(index);
- call.result = getResultParam(result);
- addInstruction(call);
-}
-
-void InstructionSelection::callBuiltinDeleteName(const QString &name, IR::Expr *result)
-{
- Instruction::CallBuiltinDeleteName call;
- call.name = registerString(name);
- call.result = getResultParam(result);
- addInstruction(call);
-}
-
-void InstructionSelection::callBuiltinDeleteValue(IR::Expr *result)
-{
- Instruction::MoveConst move;
- move.source = QV4::Encode(false);
- move.result = getResultParam(result);
- addInstruction(move);
-}
-
-void InstructionSelection::callBuiltinThrow(IR::Expr *arg)
-{
- Instruction::CallBuiltinThrow call;
- call.arg = getParam(arg);
- addInstruction(call);
-}
-
-void InstructionSelection::callBuiltinReThrow()
-{
- if (_block->catchBlock) {
- // jump to exception handler
- Instruction::Jump jump;
- jump.offset = 0;
- ptrdiff_t loc = addInstruction(jump) + (((const char *)&jump.offset) - ((const char *)&jump));
-
- _patches[_block->catchBlock].append(loc);
- } else {
- Instruction::Ret ret;
- int idx = jsUnitGenerator()->registerConstant(QV4::Encode::undefined());
- ret.result = Param::createConstant(idx);
- addInstruction(ret);
- }
-}
-
-void InstructionSelection::callBuiltinUnwindException(IR::Expr *result)
-{
- Instruction::CallBuiltinUnwindException call;
- call.result = getResultParam(result);
- addInstruction(call);
-}
-
-
-void InstructionSelection::callBuiltinPushCatchScope(const QString &exceptionName)
-{
- Instruction::CallBuiltinPushCatchScope call;
- call.name = registerString(exceptionName);
- addInstruction(call);
-}
-
-void InstructionSelection::callBuiltinForeachIteratorObject(IR::Expr *arg, IR::Expr *result)
-{
- Instruction::CallBuiltinForeachIteratorObject call;
- call.arg = getParam(arg);
- call.result = getResultParam(result);
- addInstruction(call);
-}
-
-void InstructionSelection::callBuiltinForeachNextPropertyname(IR::Expr *arg, IR::Expr *result)
-{
- Instruction::CallBuiltinForeachNextPropertyName call;
- call.arg = getParam(arg);
- call.result = getResultParam(result);
- addInstruction(call);
-}
-
-void InstructionSelection::callBuiltinPushWithScope(IR::Expr *arg)
-{
- Instruction::CallBuiltinPushScope call;
- call.arg = getParam(arg);
- addInstruction(call);
-}
-
-void InstructionSelection::callBuiltinPopScope()
-{
- QT_WARNING_PUSH
- QT_WARNING_DISABLE_GCC("-Wuninitialized")
- Instruction::CallBuiltinPopScope call;
- addInstruction(call);
- QT_WARNING_POP
-}
-
-void InstructionSelection::callBuiltinDeclareVar(bool deletable, const QString &name)
-{
- Instruction::CallBuiltinDeclareVar call;
- call.isDeletable = deletable;
- call.varName = registerString(name);
- addInstruction(call);
-}
-
-void InstructionSelection::callBuiltinDefineArray(IR::Expr *result, IR::ExprList *args)
-{
- Instruction::CallBuiltinDefineArray call;
- prepareCallArgs(args, call.argc, &call.args);
- call.result = getResultParam(result);
- addInstruction(call);
-}
-
-void InstructionSelection::callBuiltinDefineObjectLiteral(IR::Expr *result, int keyValuePairCount, IR::ExprList *keyValuePairs, IR::ExprList *arrayEntries, bool needSparseArray)
-{
- int argLocation = outgoingArgumentTempStart();
-
- const int classId = registerJSClass(keyValuePairCount, keyValuePairs);
-
- // Process key/value pairs first
- IR::ExprList *it = keyValuePairs;
- for (int i = 0; i < keyValuePairCount; ++i, it = it->next) {
- // Skip name
- it = it->next;
-
- bool isData = it->expr->asConst()->value;
- it = it->next;
-
- if (IR::Const *c = it->expr->asConst()) {
- Instruction::MoveConst move;
- move.source = convertToValue(c).asReturnedValue();
- move.result = Param::createTemp(argLocation);
- addInstruction(move);
- } else {
- Instruction::Move move;
- move.source = getParam(it->expr);
- move.result = Param::createTemp(argLocation);
- addInstruction(move);
- }
- ++argLocation;
-
- if (!isData) {
- it = it->next;
-
- Instruction::Move move;
- move.source = getParam(it->expr);
- move.result = Param::createTemp(argLocation);
- addInstruction(move);
- ++argLocation;
- }
- }
-
- // Process array values
- uint arrayValueCount = 0;
- it = arrayEntries;
- while (it) {
- IR::Const *index = it->expr->asConst();
- it = it->next;
-
- bool isData = it->expr->asConst()->value;
- it = it->next;
-
- if (!isData) {
- it = it->next; // getter
- it = it->next; // setter
- continue;
- }
-
- ++arrayValueCount;
-
- Instruction::MoveConst indexMove;
- indexMove.source = convertToValue(index).asReturnedValue();
- indexMove.result = Param::createTemp(argLocation);
- addInstruction(indexMove);
- ++argLocation;
-
- Instruction::Move move;
- move.source = getParam(it->expr);
- move.result = Param::createTemp(argLocation);
- addInstruction(move);
- ++argLocation;
- it = it->next;
- }
-
- // Process array getter/setter pairs
- uint arrayGetterSetterCount = 0;
- it = arrayEntries;
- while (it) {
- IR::Const *index = it->expr->asConst();
- it = it->next;
-
- bool isData = it->expr->asConst()->value;
- it = it->next;
-
- if (isData) {
- it = it->next; // value
- continue;
- }
-
- ++arrayGetterSetterCount;
-
- Instruction::MoveConst indexMove;
- indexMove.source = convertToValue(index).asReturnedValue();
- indexMove.result = Param::createTemp(argLocation);
- addInstruction(indexMove);
- ++argLocation;
-
- // getter
- Instruction::Move moveGetter;
- moveGetter.source = getParam(it->expr);
- moveGetter.result = Param::createTemp(argLocation);
- addInstruction(moveGetter);
- ++argLocation;
- it = it->next;
-
- // setter
- Instruction::Move moveSetter;
- moveSetter.source = getParam(it->expr);
- moveSetter.result = Param::createTemp(argLocation);
- addInstruction(moveSetter);
- ++argLocation;
- it = it->next;
- }
-
- Instruction::CallBuiltinDefineObjectLiteral call;
- call.internalClassId = classId;
- call.arrayValueCount = arrayValueCount;
- call.arrayGetterSetterCountAndFlags = arrayGetterSetterCount | (needSparseArray << 30);
- call.args = outgoingArgumentTempStart();
- call.result = getResultParam(result);
- addInstruction(call);
-}
-
-void InstructionSelection::callBuiltinSetupArgumentObject(IR::Expr *result)
-{
- Instruction::CallBuiltinSetupArgumentsObject call;
- call.result = getResultParam(result);
- addInstruction(call);
-}
-
-
-void QV4::Moth::InstructionSelection::callBuiltinConvertThisToObject()
-{
- QT_WARNING_PUSH
- QT_WARNING_DISABLE_GCC("-Wuninitialized")
- Instruction::CallBuiltinConvertThisToObject call;
- addInstruction(call);
- QT_WARNING_POP
-}
-
-ptrdiff_t InstructionSelection::addInstructionHelper(Instr::Type type, Instr &instr)
-{
- instr.common.instructionType = type;
-
- int instructionSize = Instr::size(type);
- if (_codeEnd - _codeNext < instructionSize) {
- int currSize = _codeEnd - _codeStart;
- uchar *newCode = new uchar[currSize * 2];
- ::memset(newCode + currSize, 0, currSize);
- ::memcpy(newCode, _codeStart, currSize);
- _codeNext = _codeNext - _codeStart + newCode;
- delete[] _codeStart;
- _codeStart = newCode;
- _codeEnd = _codeStart + currSize * 2;
- }
-
- ::memcpy(_codeNext, reinterpret_cast<const char *>(&instr), instructionSize);
- ptrdiff_t ptrOffset = _codeNext - _codeStart;
- _codeNext += instructionSize;
-
- return ptrOffset;
-}
-
-void InstructionSelection::patchJumpAddresses()
-{
- typedef QHash<IR::BasicBlock *, QVector<ptrdiff_t> >::ConstIterator PatchIt;
- for (PatchIt i = _patches.cbegin(), ei = _patches.cend(); i != ei; ++i) {
- Q_ASSERT(_addrs.contains(i.key()));
- ptrdiff_t target = _addrs.value(i.key());
-
- const QVector<ptrdiff_t> &patchList = i.value();
- for (int ii = 0, eii = patchList.count(); ii < eii; ++ii) {
- ptrdiff_t patch = patchList.at(ii);
-
- *((ptrdiff_t *)(_codeStart + patch)) = target - patch;
- }
- }
-
- _patches.clear();
- _addrs.clear();
-}
-
-QByteArray InstructionSelection::squeezeCode() const
-{
- int codeSize = _codeNext - _codeStart;
- QByteArray squeezed;
- squeezed.resize(codeSize);
- ::memcpy(squeezed.data(), _codeStart, codeSize);
- return squeezed;
-}
-
-Param InstructionSelection::getParam(IR::Expr *e) {
- Q_ASSERT(e);
-
- if (IR::Const *c = e->asConst()) {
- int idx = jsUnitGenerator()->registerConstant(convertToValue(c).asReturnedValue());
- return Param::createConstant(idx);
- } else if (IR::Temp *t = e->asTemp()) {
- switch (t->kind) {
- case IR::Temp::StackSlot:
- return Param::createTemp(t->index);
- default:
- Q_UNREACHABLE();
- return Param();
- }
- } else if (IR::ArgLocal *al = e->asArgLocal()) {
- switch (al->kind) {
- case IR::ArgLocal::Formal:
- case IR::ArgLocal::ScopedFormal: return Param::createArgument(al->index, al->scope);
- case IR::ArgLocal::Local: return Param::createLocal(al->index);
- case IR::ArgLocal::ScopedLocal: return Param::createScopedLocal(al->index, al->scope);
- default:
- Q_UNREACHABLE();
- return Param();
- }
- } else {
- Q_UNIMPLEMENTED();
- return Param();
- }
-}
-
-
-CompilationUnit::~CompilationUnit()
-{
-}
-
-#if !defined(V4_BOOTSTRAP)
-
-void CompilationUnit::linkBackendToEngine(QV4::ExecutionEngine *engine)
-{
- runtimeFunctions.resize(data->functionTableSize);
- runtimeFunctions.fill(0);
- for (int i = 0 ;i < runtimeFunctions.size(); ++i) {
- const QV4::CompiledData::Function *compiledFunction = data->functionAt(i);
-
- QV4::Function *runtimeFunction = new QV4::Function(engine, this, compiledFunction, &VME::exec);
- runtimeFunction->codeData = reinterpret_cast<const uchar *>(codeRefs.at(i).constData());
- runtimeFunctions[i] = runtimeFunction;
- }
-}
-
-bool CompilationUnit::memoryMapCode(QString *errorString)
-{
- Q_UNUSED(errorString);
- codeRefs.resize(data->functionTableSize);
-
- const char *basePtr = reinterpret_cast<const char *>(data);
-
- for (uint i = 0; i < data->functionTableSize; ++i) {
- const CompiledData::Function *compiledFunction = data->functionAt(i);
- const char *codePtr = const_cast<const char *>(reinterpret_cast<const char *>(basePtr + compiledFunction->codeOffset));
- QByteArray code = QByteArray::fromRawData(codePtr, compiledFunction->codeSize);
- codeRefs[i] = code;
- }
-
- return true;
-}
-
-#endif // V4_BOOTSTRAP
-
-void CompilationUnit::prepareCodeOffsetsForDiskStorage(CompiledData::Unit *unit)
-{
- const int codeAlignment = 16;
- quint64 offset = WTF::roundUpToMultipleOf(codeAlignment, unit->unitSize);
- Q_ASSERT(int(unit->functionTableSize) == codeRefs.size());
- for (int i = 0; i < codeRefs.size(); ++i) {
- CompiledData::Function *compiledFunction = const_cast<CompiledData::Function *>(unit->functionAt(i));
- compiledFunction->codeOffset = offset;
- compiledFunction->codeSize = codeRefs.at(i).size();
- offset = WTF::roundUpToMultipleOf(codeAlignment, offset + compiledFunction->codeSize);
- }
-}
-
-bool CompilationUnit::saveCodeToDisk(QIODevice *device, const CompiledData::Unit *unit, QString *errorString)
-{
- Q_ASSERT(device->pos() == unit->unitSize);
- Q_ASSERT(device->atEnd());
- Q_ASSERT(int(unit->functionTableSize) == codeRefs.size());
-
- QByteArray padding;
-
- for (int i = 0; i < codeRefs.size(); ++i) {
- const CompiledData::Function *compiledFunction = unit->functionAt(i);
-
- if (device->pos() > qint64(compiledFunction->codeOffset)) {
- *errorString = QStringLiteral("Invalid state of cache file to write.");
- return false;
- }
-
- const quint64 paddingSize = compiledFunction->codeOffset - device->pos();
- padding.fill(0, paddingSize);
- qint64 written = device->write(padding);
- if (written != padding.size()) {
- *errorString = device->errorString();
- return false;
- }
-
- QByteArray code = codeRefs.at(i);
-
- written = device->write(code.constData(), compiledFunction->codeSize);
- if (written != qint64(compiledFunction->codeSize)) {
- *errorString = device->errorString();
- return false;
- }
- }
- return true;
-}
-
-QQmlRefPointer<CompiledData::CompilationUnit> ISelFactory::createUnitForLoading()
-{
- QQmlRefPointer<CompiledData::CompilationUnit> result;
- result.adopt(new Moth::CompilationUnit);
- return result;
-}
diff --git a/src/qml/compiler/qv4isel_moth_p.h b/src/qml/compiler/qv4isel_moth_p.h
deleted file mode 100644
index 4b84bd2831..0000000000
--- a/src/qml/compiler/qv4isel_moth_p.h
+++ /dev/null
@@ -1,240 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QV4ISEL_MOTH_P_H
-#define QV4ISEL_MOTH_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <private/qv4global_p.h>
-#include <private/qv4isel_p.h>
-#include <private/qv4isel_util_p.h>
-#include <private/qv4util_p.h>
-#include <private/qv4jsir_p.h>
-#include <private/qv4value_p.h>
-#include "qv4instr_moth_p.h"
-
-#if !defined(V4_BOOTSTRAP)
-QT_REQUIRE_CONFIG(qml_interpreter);
-#endif
-
-QT_BEGIN_NAMESPACE
-
-namespace QV4 {
-namespace Moth {
-
-struct CompilationUnit : public QV4::CompiledData::CompilationUnit
-{
- virtual ~CompilationUnit();
-#if !defined(V4_BOOTSTRAP)
- void linkBackendToEngine(QV4::ExecutionEngine *engine) Q_DECL_OVERRIDE;
- bool memoryMapCode(QString *errorString) Q_DECL_OVERRIDE;
-#endif
- void prepareCodeOffsetsForDiskStorage(CompiledData::Unit *unit) Q_DECL_OVERRIDE;
- bool saveCodeToDisk(QIODevice *device, const CompiledData::Unit *unit, QString *errorString) Q_DECL_OVERRIDE;
-
- QVector<QByteArray> codeRefs;
-
-};
-
-class Q_QML_EXPORT InstructionSelection:
- public IR::IRDecoder,
- public EvalInstructionSelection
-{
-public:
- InstructionSelection(QQmlEnginePrivate *qmlEngine, QV4::ExecutableAllocator *execAllocator, IR::Module *module, QV4::Compiler::JSUnitGenerator *jsGenerator, EvalISelFactory *iselFactory);
- ~InstructionSelection();
-
- void run(int functionIndex) override;
-
-protected:
- QQmlRefPointer<CompiledData::CompilationUnit> backendCompileStep() override;
-
- void visitJump(IR::Jump *) override;
- void visitCJump(IR::CJump *) override;
- void visitRet(IR::Ret *) override;
-
- void callBuiltinInvalid(IR::Name *func, IR::ExprList *args, IR::Expr *result) override;
- void callBuiltinTypeofQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int propertyIndex, IR::Expr *result) override;
- void callBuiltinTypeofMember(IR::Expr *base, const QString &name, IR::Expr *result) override;
- void callBuiltinTypeofSubscript(IR::Expr *base, IR::Expr *index, IR::Expr *result) override;
- void callBuiltinTypeofName(const QString &name, IR::Expr *result) override;
- void callBuiltinTypeofValue(IR::Expr *value, IR::Expr *result) override;
- void callBuiltinDeleteMember(IR::Expr *base, const QString &name, IR::Expr *result) override;
- void callBuiltinDeleteSubscript(IR::Expr *base, IR::Expr *index, IR::Expr *result) override;
- void callBuiltinDeleteName(const QString &name, IR::Expr *result) override;
- void callBuiltinDeleteValue(IR::Expr *result) override;
- void callBuiltinThrow(IR::Expr *arg) override;
- void callBuiltinReThrow() override;
- void callBuiltinUnwindException(IR::Expr *) override;
- void callBuiltinPushCatchScope(const QString &exceptionName) override;
- void callBuiltinForeachIteratorObject(IR::Expr *arg, IR::Expr *result) override;
- void callBuiltinForeachNextPropertyname(IR::Expr *arg, IR::Expr *result) override;
- void callBuiltinPushWithScope(IR::Expr *arg) override;
- void callBuiltinPopScope() override;
- void callBuiltinDeclareVar(bool deletable, const QString &name) override;
- void callBuiltinDefineArray(IR::Expr *result, IR::ExprList *args) override;
- void callBuiltinDefineObjectLiteral(IR::Expr *result, int keyValuePairCount, IR::ExprList *keyValuePairs, IR::ExprList *arrayEntries, bool needSparseArray) override;
- void callBuiltinSetupArgumentObject(IR::Expr *result) override;
- void callBuiltinConvertThisToObject() override;
- void callValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result) override;
- void callQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int propertyIndex, IR::ExprList *args, IR::Expr *result) override;
- void callProperty(IR::Expr *base, const QString &name, IR::ExprList *args, IR::Expr *result) override;
- void callSubscript(IR::Expr *base, IR::Expr *index, IR::ExprList *args, IR::Expr *result) override;
- void convertType(IR::Expr *source, IR::Expr *target) override;
- void constructActivationProperty(IR::Name *func, IR::ExprList *args, IR::Expr *result) override;
- void constructProperty(IR::Expr *base, const QString &name, IR::ExprList *args, IR::Expr *result) override;
- void constructValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result) override;
- void loadThisObject(IR::Expr *e) override;
- void loadQmlContext(IR::Expr *e) override;
- void loadQmlImportedScripts(IR::Expr *e) override;
- void loadQmlSingleton(const QString &name, IR::Expr *e) override;
- void loadConst(IR::Const *sourceConst, IR::Expr *e) override;
- void loadString(const QString &str, IR::Expr *target) override;
- void loadRegexp(IR::RegExp *sourceRegexp, IR::Expr *target) override;
- void getActivationProperty(const IR::Name *name, IR::Expr *target) override;
- void setActivationProperty(IR::Expr *source, const QString &targetName) override;
- void initClosure(IR::Closure *closure, IR::Expr *target) override;
- void getProperty(IR::Expr *base, const QString &name, IR::Expr *target) override;
- void setProperty(IR::Expr *source, IR::Expr *targetBase, const QString &targetName) override;
- void setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase, IR::Member::MemberKind kind, int propertyIndex) override;
- void setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int propertyIndex) override;
- void getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, int index, bool captureRequired, IR::Expr *target) override;
- void getQObjectProperty(IR::Expr *base, int propertyIndex, bool captureRequired, bool isSingleton, int attachedPropertiesId, IR::Expr *target) override;
- void getElement(IR::Expr *base, IR::Expr *index, IR::Expr *target) override;
- void setElement(IR::Expr *source, IR::Expr *targetBase, IR::Expr *targetIndex) override;
- void copyValue(IR::Expr *source, IR::Expr *target) override;
- void swapValues(IR::Expr *source, IR::Expr *target) override;
- void unop(IR::AluOp oper, IR::Expr *source, IR::Expr *target) override;
- void binop(IR::AluOp oper, IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target) override;
-
-private:
- Param binopHelper(IR::AluOp oper, IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target);
-
- struct Instruction {
-#define MOTH_INSTR_DATA_TYPEDEF(I, FMT) typedef InstrData<Instr::I> I;
- FOR_EACH_MOTH_INSTR(MOTH_INSTR_DATA_TYPEDEF)
-#undef MOTH_INSTR_DATA_TYPEDEF
- private:
- Instruction();
- };
-
- Param getParam(IR::Expr *e);
-
- Param getResultParam(IR::Expr *result)
- {
- if (result)
- return getParam(result);
- else
- return Param::createTemp(scratchTempIndex());
- }
-
- void simpleMove(IR::Move *);
- void prepareCallArgs(IR::ExprList *, quint32 &, quint32 * = 0);
-
- int scratchTempIndex() const { return _function->tempCount; }
- int callDataStart() const { return scratchTempIndex() + 1; }
- int outgoingArgumentTempStart() const { return callDataStart() + offsetof(QV4::CallData, args)/sizeof(QV4::Value); }
- int frameSize() const { return outgoingArgumentTempStart() + _function->maxNumberOfArguments; }
-
- template <int Instr>
- inline ptrdiff_t addInstruction(const InstrData<Instr> &data);
- inline void addDebugInstruction();
-
- ptrdiff_t addInstructionHelper(Instr::Type type, Instr &instr);
- void patchJumpAddresses();
- QByteArray squeezeCode() const;
-
- QQmlEnginePrivate *qmlEngine;
-
- bool blockNeedsDebugInstruction;
- uint currentLine;
- IR::BasicBlock *_block;
- IR::BasicBlock *_nextBlock;
-
- QHash<IR::BasicBlock *, QVector<ptrdiff_t> > _patches;
- QHash<IR::BasicBlock *, ptrdiff_t> _addrs;
-
- uchar *_codeStart;
- uchar *_codeNext;
- uchar *_codeEnd;
-
- BitVector _removableJumps;
- IR::Stmt *_currentStatement;
-
- QScopedPointer<CompilationUnit> compilationUnit;
- QHash<IR::Function *, QByteArray> codeRefs;
-};
-
-class Q_QML_EXPORT ISelFactory: public EvalISelFactory
-{
-public:
- ISelFactory() : EvalISelFactory(QStringLiteral("moth")) {}
- virtual ~ISelFactory() {}
- EvalInstructionSelection *create(QQmlEnginePrivate *qmlEngine, QV4::ExecutableAllocator *execAllocator, IR::Module *module, QV4::Compiler::JSUnitGenerator *jsGenerator) Q_DECL_OVERRIDE Q_DECL_FINAL
- { return new InstructionSelection(qmlEngine, execAllocator, module, jsGenerator, this); }
- bool jitCompileRegexps() const Q_DECL_OVERRIDE Q_DECL_FINAL
- { return false; }
- QQmlRefPointer<QV4::CompiledData::CompilationUnit> createUnitForLoading() Q_DECL_OVERRIDE;
-
-};
-
-template<int InstrT>
-ptrdiff_t InstructionSelection::addInstruction(const InstrData<InstrT> &data)
-{
- Instr genericInstr;
- InstrMeta<InstrT>::setDataNoCommon(genericInstr, data);
- return addInstructionHelper(static_cast<Instr::Type>(InstrT), genericInstr);
-}
-
-} // namespace Moth
-} // namespace QV4
-
-QT_END_NAMESPACE
-
-#endif // QV4ISEL_MOTH_P_H
diff --git a/src/qml/compiler/qv4isel_p.cpp b/src/qml/compiler/qv4isel_p.cpp
deleted file mode 100644
index efcfb9bd77..0000000000
--- a/src/qml/compiler/qv4isel_p.cpp
+++ /dev/null
@@ -1,446 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/QDebug>
-#include <QtCore/QBuffer>
-#include "qv4jsir_p.h"
-#include "qv4isel_p.h"
-#include "qv4isel_util_p.h"
-#include <private/qv4value_p.h>
-#ifndef V4_BOOTSTRAP
-#include <private/qqmlpropertycache_p.h>
-#endif
-
-#include <QString>
-
-using namespace QV4;
-using namespace QV4::IR;
-
-EvalInstructionSelection::EvalInstructionSelection(QV4::ExecutableAllocator *execAllocator, Module *module, QV4::Compiler::JSUnitGenerator *jsGenerator, EvalISelFactory *iselFactory)
- : useFastLookups(true)
- , useTypeInference(true)
- , executableAllocator(execAllocator)
- , irModule(module)
-{
- if (!jsGenerator) {
- jsGenerator = new QV4::Compiler::JSUnitGenerator(module);
- ownJSGenerator.reset(jsGenerator);
- }
- this->jsGenerator = jsGenerator;
-#ifndef V4_BOOTSTRAP
- Q_ASSERT(execAllocator);
-#endif
- Q_ASSERT(module);
- jsGenerator->codeGeneratorName = iselFactory->codeGeneratorName;
-}
-
-EvalInstructionSelection::~EvalInstructionSelection()
-{}
-
-EvalISelFactory::~EvalISelFactory()
-{}
-
-QQmlRefPointer<CompiledData::CompilationUnit> EvalInstructionSelection::compile(bool generateUnitData)
-{
- for (int i = 0; i < irModule->functions.size(); ++i)
- run(i);
-
- QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = backendCompileStep();
- if (generateUnitData)
- unit->data = jsGenerator->generateUnit();
- return unit;
-}
-
-void IRDecoder::visitMove(IR::Move *s)
-{
- if (IR::Name *n = s->target->asName()) {
- if (s->source->asTemp() || s->source->asConst() || s->source->asArgLocal()) {
- setActivationProperty(s->source, *n->id);
- return;
- }
- } else if (s->target->asTemp() || s->target->asArgLocal()) {
- if (IR::Name *n = s->source->asName()) {
- if (n->id && *n->id == QLatin1String("this")) // TODO: `this' should be a builtin.
- loadThisObject(s->target);
- else if (n->builtin == IR::Name::builtin_qml_context)
- loadQmlContext(s->target);
- else if (n->builtin == IR::Name::builtin_qml_imported_scripts_object)
- loadQmlImportedScripts(s->target);
- else if (n->qmlSingleton)
- loadQmlSingleton(*n->id, s->target);
- else
- getActivationProperty(n, s->target);
- return;
- } else if (IR::Const *c = s->source->asConst()) {
- loadConst(c, s->target);
- return;
- } else if (s->source->asTemp() || s->source->asArgLocal()) {
- if (s->swap)
- swapValues(s->source, s->target);
- else
- copyValue(s->source, s->target);
- return;
- } else if (IR::String *str = s->source->asString()) {
- loadString(*str->value, s->target);
- return;
- } else if (IR::RegExp *re = s->source->asRegExp()) {
- loadRegexp(re, s->target);
- return;
- } else if (IR::Closure *clos = s->source->asClosure()) {
- initClosure(clos, s->target);
- return;
- } else if (IR::New *ctor = s->source->asNew()) {
- if (Name *func = ctor->base->asName()) {
- constructActivationProperty(func, ctor->args, s->target);
- return;
- } else if (IR::Member *member = ctor->base->asMember()) {
- constructProperty(member->base, *member->name, ctor->args, s->target);
- return;
- } else if (ctor->base->asTemp() || ctor->base->asArgLocal()) {
- constructValue(ctor->base, ctor->args, s->target);
- return;
- }
- } else if (IR::Member *m = s->source->asMember()) {
- if (m->property) {
-#ifdef V4_BOOTSTRAP
- Q_UNIMPLEMENTED();
-#else
- bool captureRequired = true;
-
- Q_ASSERT(m->kind != IR::Member::MemberOfEnum && m->kind != IR::Member::MemberOfIdObjectsArray);
- const int attachedPropertiesId = m->attachedPropertiesId;
- const bool isSingletonProperty = m->kind == IR::Member::MemberOfSingletonObject;
-
- if (_function && attachedPropertiesId == 0 && !m->property->isConstant() && _function->isQmlBinding) {
- if (m->kind == IR::Member::MemberOfQmlContextObject) {
- _function->contextObjectPropertyDependencies.insert(m->property->coreIndex(), m->property->notifyIndex());
- captureRequired = false;
- } else if (m->kind == IR::Member::MemberOfQmlScopeObject) {
- _function->scopeObjectPropertyDependencies.insert(m->property->coreIndex(), m->property->notifyIndex());
- captureRequired = false;
- }
- }
- if (m->kind == IR::Member::MemberOfQmlScopeObject || m->kind == IR::Member::MemberOfQmlContextObject) {
- getQmlContextProperty(m->base, (IR::Member::MemberKind)m->kind, m->property->coreIndex(), captureRequired, s->target);
- return;
- }
- getQObjectProperty(m->base, m->property->coreIndex(), captureRequired, isSingletonProperty, attachedPropertiesId, s->target);
-#endif // V4_BOOTSTRAP
- return;
- } else if (m->kind == IR::Member::MemberOfIdObjectsArray) {
- getQmlContextProperty(m->base, (IR::Member::MemberKind)m->kind, m->idIndex, /*captureRequired*/false, s->target);
- return;
- } else if (m->base->asTemp() || m->base->asConst() || m->base->asArgLocal()) {
- getProperty(m->base, *m->name, s->target);
- return;
- }
- } else if (IR::Subscript *ss = s->source->asSubscript()) {
- getElement(ss->base, ss->index, s->target);
- return;
- } else if (IR::Unop *u = s->source->asUnop()) {
- unop(u->op, u->expr, s->target);
- return;
- } else if (IR::Binop *b = s->source->asBinop()) {
- binop(b->op, b->left, b->right, s->target);
- return;
- } else if (IR::Call *c = s->source->asCall()) {
- if (c->base->asName()) {
- callBuiltin(c, s->target);
- return;
- } else if (Member *member = c->base->asMember()) {
-#ifndef V4_BOOTSTRAP
- Q_ASSERT(member->kind != IR::Member::MemberOfIdObjectsArray);
- if (member->kind == IR::Member::MemberOfQmlScopeObject || member->kind == IR::Member::MemberOfQmlContextObject) {
- callQmlContextProperty(member->base, (IR::Member::MemberKind)member->kind, member->property->coreIndex(), c->args, s->target);
- return;
- }
-#endif
- callProperty(member->base, *member->name, c->args, s->target);
- return;
- } else if (Subscript *ss = c->base->asSubscript()) {
- callSubscript(ss->base, ss->index, c->args, s->target);
- return;
- } else if (c->base->asTemp() || c->base->asArgLocal() || c->base->asConst()) {
- callValue(c->base, c->args, s->target);
- return;
- }
- } else if (IR::Convert *c = s->source->asConvert()) {
- Q_ASSERT(c->expr->asTemp() || c->expr->asArgLocal());
- convertType(c->expr, s->target);
- return;
- }
- } else if (IR::Member *m = s->target->asMember()) {
- if (m->base->asTemp() || m->base->asConst() || m->base->asArgLocal()) {
- if (s->source->asTemp() || s->source->asConst() || s->source->asArgLocal()) {
- Q_ASSERT(m->kind != IR::Member::MemberOfEnum);
- Q_ASSERT(m->kind != IR::Member::MemberOfIdObjectsArray);
- const int attachedPropertiesId = m->attachedPropertiesId;
- if (m->property && attachedPropertiesId == 0) {
-#ifdef V4_BOOTSTRAP
- Q_UNIMPLEMENTED();
-#else
- if (m->kind == IR::Member::MemberOfQmlScopeObject || m->kind == IR::Member::MemberOfQmlContextObject) {
- setQmlContextProperty(s->source, m->base, (IR::Member::MemberKind)m->kind, m->property->coreIndex());
- return;
- }
- setQObjectProperty(s->source, m->base, m->property->coreIndex());
-#endif
- return;
- } else {
- setProperty(s->source, m->base, *m->name);
- return;
- }
- }
- }
- } else if (IR::Subscript *ss = s->target->asSubscript()) {
- if (s->source->asTemp() || s->source->asConst() || s->source->asArgLocal()) {
- setElement(s->source, ss->base, ss->index);
- return;
- }
- }
-
- // For anything else...:
- Q_UNIMPLEMENTED();
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream qout(&buf);
- IRPrinter(&qout).print(s);
- qout << endl;
- qDebug("%s", buf.data().constData());
- Q_ASSERT(!"TODO");
-}
-
-IRDecoder::~IRDecoder()
-{
-}
-
-void IRDecoder::visitExp(IR::Exp *s)
-{
- if (IR::Call *c = s->expr->asCall()) {
- // These are calls where the result is ignored.
- if (c->base->asName()) {
- callBuiltin(c, 0);
- } else if (c->base->asTemp() || c->base->asArgLocal() || c->base->asConst()) {
- callValue(c->base, c->args, 0);
- } else if (Member *member = c->base->asMember()) {
- Q_ASSERT(member->base->asTemp() || member->base->asArgLocal());
-#ifndef V4_BOOTSTRAP
- Q_ASSERT(member->kind != IR::Member::MemberOfIdObjectsArray);
- if (member->kind == IR::Member::MemberOfQmlScopeObject || member->kind == IR::Member::MemberOfQmlContextObject) {
- callQmlContextProperty(member->base, (IR::Member::MemberKind)member->kind, member->property->coreIndex(), c->args, 0);
- return;
- }
-#endif
- callProperty(member->base, *member->name, c->args, 0);
- } else if (Subscript *s = c->base->asSubscript()) {
- callSubscript(s->base, s->index, c->args, 0);
- } else {
- Q_UNREACHABLE();
- }
- } else {
- Q_UNREACHABLE();
- }
-}
-
-void IRDecoder::callBuiltin(IR::Call *call, Expr *result)
-{
- IR::Name *baseName = call->base->asName();
- Q_ASSERT(baseName != 0);
-
- switch (baseName->builtin) {
- case IR::Name::builtin_invalid:
- callBuiltinInvalid(baseName, call->args, result);
- return;
-
- case IR::Name::builtin_typeof: {
- if (IR::Member *member = call->args->expr->asMember()) {
-#ifndef V4_BOOTSTRAP
- Q_ASSERT(member->kind != IR::Member::MemberOfIdObjectsArray);
- if (member->kind == IR::Member::MemberOfQmlScopeObject || member->kind == IR::Member::MemberOfQmlContextObject) {
- callBuiltinTypeofQmlContextProperty(member->base,
- IR::Member::MemberKind(member->kind),
- member->property->coreIndex(), result);
- return;
- }
-#endif
- callBuiltinTypeofMember(member->base, *member->name, result);
- return;
- } else if (IR::Subscript *ss = call->args->expr->asSubscript()) {
- callBuiltinTypeofSubscript(ss->base, ss->index, result);
- return;
- } else if (IR::Name *n = call->args->expr->asName()) {
- callBuiltinTypeofName(*n->id, result);
- return;
- } else if (call->args->expr->asTemp() ||
- call->args->expr->asConst() ||
- call->args->expr->asArgLocal()) {
- callBuiltinTypeofValue(call->args->expr, result);
- return;
- }
- } break;
-
- case IR::Name::builtin_delete: {
- if (IR::Member *m = call->args->expr->asMember()) {
- callBuiltinDeleteMember(m->base, *m->name, result);
- return;
- } else if (IR::Subscript *ss = call->args->expr->asSubscript()) {
- callBuiltinDeleteSubscript(ss->base, ss->index, result);
- return;
- } else if (IR::Name *n = call->args->expr->asName()) {
- callBuiltinDeleteName(*n->id, result);
- return;
- } else if (call->args->expr->asTemp() ||
- call->args->expr->asArgLocal()) {
- // TODO: should throw in strict mode
- callBuiltinDeleteValue(result);
- return;
- }
- } break;
-
- case IR::Name::builtin_throw: {
- IR::Expr *arg = call->args->expr;
- Q_ASSERT(arg->asTemp() || arg->asConst() || arg->asArgLocal());
- callBuiltinThrow(arg);
- } return;
-
- case IR::Name::builtin_rethrow: {
- callBuiltinReThrow();
- } return;
-
- case IR::Name::builtin_unwind_exception: {
- callBuiltinUnwindException(result);
- } return;
-
- case IR::Name::builtin_push_catch_scope: {
- IR::String *s = call->args->expr->asString();
- Q_ASSERT(s);
- callBuiltinPushCatchScope(*s->value);
- } return;
-
- case IR::Name::builtin_foreach_iterator_object: {
- IR::Expr *arg = call->args->expr;
- Q_ASSERT(arg != 0);
- callBuiltinForeachIteratorObject(arg, result);
- } return;
-
- case IR::Name::builtin_foreach_next_property_name: {
- IR::Expr *arg = call->args->expr;
- Q_ASSERT(arg != 0);
- callBuiltinForeachNextPropertyname(arg, result);
- } return;
- case IR::Name::builtin_push_with_scope: {
- if (call->args->expr->asTemp() || call->args->expr->asArgLocal())
- callBuiltinPushWithScope(call->args->expr);
- else
- Q_UNIMPLEMENTED();
- } return;
-
- case IR::Name::builtin_pop_scope:
- callBuiltinPopScope();
- return;
-
- case IR::Name::builtin_declare_vars: {
- if (!call->args)
- return;
- IR::Const *deletable = call->args->expr->asConst();
- Q_ASSERT(deletable->type == IR::BoolType);
- for (IR::ExprList *it = call->args->next; it; it = it->next) {
- IR::Name *arg = it->expr->asName();
- Q_ASSERT(arg != 0);
- callBuiltinDeclareVar(deletable->value != 0, *arg->id);
- }
- } return;
-
- case IR::Name::builtin_define_array:
- callBuiltinDefineArray(result, call->args);
- return;
-
- case IR::Name::builtin_define_object_literal: {
- IR::ExprList *args = call->args;
- const int keyValuePairsCount = args->expr->asConst()->value;
- args = args->next;
-
- IR::ExprList *keyValuePairs = args;
- for (int i = 0; i < keyValuePairsCount; ++i) {
- args = args->next; // name
- bool isData = args->expr->asConst()->value;
- args = args->next; // isData flag
- args = args->next; // value or getter
- if (!isData)
- args = args->next; // setter
- }
-
- IR::ExprList *arrayEntries = args;
- bool needSparseArray = false;
- for (IR::ExprList *it = arrayEntries; it; it = it->next) {
- uint index = it->expr->asConst()->value;
- if (index > 16) {
- needSparseArray = true;
- break;
- }
- it = it->next;
- bool isData = it->expr->asConst()->value;
- it = it->next;
- if (!isData)
- it = it->next;
- }
-
- callBuiltinDefineObjectLiteral(result, keyValuePairsCount, keyValuePairs, arrayEntries, needSparseArray);
- } return;
-
- case IR::Name::builtin_setup_argument_object:
- callBuiltinSetupArgumentObject(result);
- return;
-
- case IR::Name::builtin_convert_this_to_object:
- callBuiltinConvertThisToObject();
- return;
-
- default:
- break;
- }
-
- Q_UNIMPLEMENTED();
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream qout(&buf);
- IRPrinter(&qout).print(call); qout << endl;
- qDebug("%s", buf.data().constData());
- Q_UNREACHABLE();
-}
diff --git a/src/qml/compiler/qv4isel_p.h b/src/qml/compiler/qv4isel_p.h
deleted file mode 100644
index 037c02e5ea..0000000000
--- a/src/qml/compiler/qv4isel_p.h
+++ /dev/null
@@ -1,218 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QV4ISEL_P_H
-#define QV4ISEL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qv4global_p.h"
-#include "qv4jsir_p.h"
-#include <private/qv4compileddata_p.h>
-#include <private/qv4compiler_p.h>
-
-#include <qglobal.h>
-#include <QHash>
-
-QT_BEGIN_NAMESPACE
-
-class QQmlEnginePrivate;
-
-namespace QV4 {
-
-class EvalISelFactory;
-class ExecutableAllocator;
-struct Function;
-
-class Q_QML_PRIVATE_EXPORT EvalInstructionSelection
-{
-public:
- EvalInstructionSelection(QV4::ExecutableAllocator *execAllocator, IR::Module *module, QV4::Compiler::JSUnitGenerator *jsGenerator, EvalISelFactory *iselFactory);
- virtual ~EvalInstructionSelection() = 0;
-
- QQmlRefPointer<QV4::CompiledData::CompilationUnit> compile(bool generateUnitData = true);
-
- void setUseFastLookups(bool b) { useFastLookups = b; }
- void setUseTypeInference(bool onoff) { useTypeInference = onoff; }
-
- int registerString(const QString &str) { return jsGenerator->registerString(str); }
- uint registerIndexedGetterLookup() { return jsGenerator->registerIndexedGetterLookup(); }
- uint registerIndexedSetterLookup() { return jsGenerator->registerIndexedSetterLookup(); }
- uint registerGetterLookup(const QString &name) { return jsGenerator->registerGetterLookup(name); }
- uint registerSetterLookup(const QString &name) { return jsGenerator->registerSetterLookup(name); }
- uint registerGlobalGetterLookup(const QString &name) { return jsGenerator->registerGlobalGetterLookup(name); }
- int registerRegExp(IR::RegExp *regexp) { return jsGenerator->registerRegExp(regexp); }
- int registerJSClass(int count, IR::ExprList *args) { return jsGenerator->registerJSClass(count, args); }
- QV4::Compiler::JSUnitGenerator *jsUnitGenerator() const { return jsGenerator; }
-
-protected:
- virtual void run(int functionIndex) = 0;
- virtual QQmlRefPointer<QV4::CompiledData::CompilationUnit> backendCompileStep() = 0;
-
- bool useFastLookups;
- bool useTypeInference;
- QV4::ExecutableAllocator *executableAllocator;
- QV4::Compiler::JSUnitGenerator *jsGenerator;
- QScopedPointer<QV4::Compiler::JSUnitGenerator> ownJSGenerator;
- IR::Module *irModule;
-};
-
-class Q_QML_PRIVATE_EXPORT EvalISelFactory
-{
-public:
- EvalISelFactory(const QString &codeGeneratorName) : codeGeneratorName(codeGeneratorName) {}
- virtual ~EvalISelFactory() = 0;
- virtual EvalInstructionSelection *create(QQmlEnginePrivate *qmlEngine, QV4::ExecutableAllocator *execAllocator, IR::Module *module, QV4::Compiler::JSUnitGenerator *jsGenerator) = 0;
- virtual bool jitCompileRegexps() const = 0;
- virtual QQmlRefPointer<QV4::CompiledData::CompilationUnit> createUnitForLoading() = 0;
-
- const QString codeGeneratorName;
-};
-
-namespace IR {
-class Q_QML_PRIVATE_EXPORT IRDecoder
-{
-public:
- IRDecoder() : _function(0) {}
- virtual ~IRDecoder() = 0;
-
- void visit(Stmt *s)
- {
- if (auto e = s->asExp()) {
- visitExp(e);
- } else if (auto m = s->asMove()) {
- visitMove(m);
- } else if (auto j = s->asJump()) {
- visitJump(j);
- } else if (auto c = s->asCJump()) {
- visitCJump(c);
- } else if (auto r = s->asRet()) {
- visitRet(r);
- } else if (auto p = s->asPhi()) {
- visitPhi(p);
- } else {
- Q_UNREACHABLE();
- }
- }
-
-private: // visitor methods for StmtVisitor:
- void visitMove(IR::Move *s);
- void visitExp(IR::Exp *s);
-
-public: // to implement by subclasses:
- virtual void callBuiltinInvalid(IR::Name *func, IR::ExprList *args, IR::Expr *result) = 0;
- virtual void callBuiltinTypeofQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int propertyIndex, IR::Expr *result) = 0;
- virtual void callBuiltinTypeofMember(IR::Expr *base, const QString &name, IR::Expr *result) = 0;
- virtual void callBuiltinTypeofSubscript(IR::Expr *base, IR::Expr *index, IR::Expr *result) = 0;
- virtual void callBuiltinTypeofName(const QString &name, IR::Expr *result) = 0;
- virtual void callBuiltinTypeofValue(IR::Expr *value, IR::Expr *result) = 0;
- virtual void callBuiltinDeleteMember(IR::Expr *base, const QString &name, IR::Expr *result) = 0;
- virtual void callBuiltinDeleteSubscript(IR::Expr *base, IR::Expr *index, IR::Expr *result) = 0;
- virtual void callBuiltinDeleteName(const QString &name, IR::Expr *result) = 0;
- virtual void callBuiltinDeleteValue(IR::Expr *result) = 0;
- virtual void callBuiltinThrow(IR::Expr *arg) = 0;
- virtual void callBuiltinReThrow() = 0;
- virtual void callBuiltinUnwindException(IR::Expr *) = 0;
- virtual void callBuiltinPushCatchScope(const QString &exceptionName) = 0;
- virtual void callBuiltinForeachIteratorObject(IR::Expr *arg, IR::Expr *result) = 0;
- virtual void callBuiltinForeachNextPropertyname(IR::Expr *arg, IR::Expr *result) = 0;
- virtual void callBuiltinPushWithScope(IR::Expr *arg) = 0;
- virtual void callBuiltinPopScope() = 0;
- virtual void callBuiltinDeclareVar(bool deletable, const QString &name) = 0;
- virtual void callBuiltinDefineArray(IR::Expr *result, IR::ExprList *args) = 0;
- virtual void callBuiltinDefineObjectLiteral(IR::Expr *result, int keyValuePairCount, IR::ExprList *keyValuePairs, IR::ExprList *arrayEntries, bool needSparseArray) = 0;
- virtual void callBuiltinSetupArgumentObject(IR::Expr *result) = 0;
- virtual void callBuiltinConvertThisToObject() = 0;
- virtual void callValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result) = 0;
- virtual void callQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int propertyIndex, IR::ExprList *args, IR::Expr *result) = 0;
- virtual void callProperty(IR::Expr *base, const QString &name, IR::ExprList *args, IR::Expr *result) = 0;
- virtual void callSubscript(IR::Expr *base, IR::Expr *index, IR::ExprList *args, IR::Expr *result) = 0;
- virtual void convertType(IR::Expr *source, IR::Expr *target) = 0;
- virtual void constructActivationProperty(IR::Name *func, IR::ExprList *args, IR::Expr *result) = 0;
- virtual void constructProperty(IR::Expr *base, const QString &name, IR::ExprList *args, IR::Expr *result) = 0;
- virtual void constructValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result) = 0;
- virtual void loadThisObject(IR::Expr *target) = 0;
- virtual void loadQmlContext(IR::Expr *target) = 0;
- virtual void loadQmlImportedScripts(IR::Expr *target) = 0;
- virtual void loadQmlSingleton(const QString &name, IR::Expr *target) = 0;
- virtual void loadConst(IR::Const *sourceConst, IR::Expr *target) = 0;
- virtual void loadString(const QString &str, IR::Expr *target) = 0;
- virtual void loadRegexp(IR::RegExp *sourceRegexp, IR::Expr *target) = 0;
- virtual void getActivationProperty(const IR::Name *name, IR::Expr *target) = 0;
- virtual void setActivationProperty(IR::Expr *source, const QString &targetName) = 0;
- virtual void initClosure(IR::Closure *closure, IR::Expr *target) = 0;
- virtual void getProperty(IR::Expr *base, const QString &name, IR::Expr *target) = 0;
- virtual void getQObjectProperty(IR::Expr *base, int propertyIndex, bool captureRequired, bool isSingletonProperty, int attachedPropertiesId, IR::Expr *target) = 0;
- virtual void getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, int index, bool captureRequired, IR::Expr *target) = 0;
- virtual void setProperty(IR::Expr *source, IR::Expr *targetBase, const QString &targetName) = 0;
- virtual void setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase, IR::Member::MemberKind kind, int propertyIndex) = 0;
- virtual void setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int propertyIndex) = 0;
- virtual void getElement(IR::Expr *base, IR::Expr *index, IR::Expr *target) = 0;
- virtual void setElement(IR::Expr *source, IR::Expr *targetBase, IR::Expr *targetIndex) = 0;
- virtual void copyValue(IR::Expr *source, IR::Expr *target) = 0;
- virtual void swapValues(IR::Expr *source, IR::Expr *target) = 0;
- virtual void unop(IR::AluOp oper, IR::Expr *source, IR::Expr *target) = 0;
- virtual void binop(IR::AluOp oper, IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target) = 0;
-
-protected:
- virtual void visitJump(IR::Jump *) = 0;
- virtual void visitCJump(IR::CJump *) = 0;
- virtual void visitRet(IR::Ret *) = 0;
- virtual void visitPhi(IR::Phi *) {}
-
- virtual void callBuiltin(IR::Call *c, IR::Expr *result);
-
- IR::Function *_function; // subclass needs to set
-};
-} // namespace IR
-
-} // namespace QV4
-
-QT_END_NAMESPACE
-
-#endif // QV4ISEL_P_H
diff --git a/src/qml/compiler/qv4isel_util_p.h b/src/qml/compiler/qv4isel_util_p.h
deleted file mode 100644
index e949e6f0ad..0000000000
--- a/src/qml/compiler/qv4isel_util_p.h
+++ /dev/null
@@ -1,241 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QV4ISEL_UTIL_P_H
-#define QV4ISEL_UTIL_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qv4value_p.h"
-#include "qv4jsir_p.h"
-
-QT_BEGIN_NAMESPACE
-
-namespace QV4 {
-
-struct TargetPrimitive32 {
- static TargetPrimitive32 emptyValue() { TargetPrimitive32 p; p._val = quint64(Value::ValueTypeInternal_32::Empty) << 32; return p; }
- static TargetPrimitive32 nullValue() { TargetPrimitive32 p; p._val = quint64(Value::ValueTypeInternal_32::Null) << 32; return p; }
- static TargetPrimitive32 undefinedValue() { TargetPrimitive32 p; p._val = quint64(Value::Managed_Type_Internal_32) << 32; return p; }
- static TargetPrimitive32 fromBoolean(bool b) { TargetPrimitive32 p; p._val = quint64(Value::ValueTypeInternal_32::Boolean) << 32 | quint64(b); return p; }
- static TargetPrimitive32 fromInt32(int v) { TargetPrimitive32 p; p._val = quint64(Value::ValueTypeInternal_32::Integer) << 32 | quint32(v); return p; }
- static TargetPrimitive32 fromDouble(double v) {
- TargetPrimitive32 p;
- memcpy(&p._val, &v, 8);
- return p;
- }
- static TargetPrimitive32 fromUInt32(uint v) {
- if (v < INT_MAX)
- return fromInt32(qint32(v));
- return fromDouble(double(v));
- }
-
- quint32 value() const { return _val & quint64(~quint32(0)); }
- quint32 tag() const { return _val >> 32; }
-
- quint64 rawValue() const { return _val; }
-
-private:
- quint64 _val;
-};
-
-struct TargetPrimitive64 {
- static TargetPrimitive64 emptyValue() { TargetPrimitive64 p; p._val = quint64(Value::ValueTypeInternal_64::Empty) << 32; return p; }
- static TargetPrimitive64 nullValue() { TargetPrimitive64 p; p._val = quint64(Value::ValueTypeInternal_64::Null) << 32; return p; }
- static TargetPrimitive64 undefinedValue() { TargetPrimitive64 p; p._val = 0; return p; }
- static TargetPrimitive64 fromBoolean(bool b) { TargetPrimitive64 p; p._val = quint64(Value::ValueTypeInternal_64::Boolean) << 32 | quint64(b); return p; }
- static TargetPrimitive64 fromInt32(int v) { TargetPrimitive64 p; p._val = quint64(Value::ValueTypeInternal_64::Integer) << 32 | quint32(v); return p; }
- static TargetPrimitive64 fromDouble(double v) {
- TargetPrimitive64 p;
- memcpy(&p._val, &v, 8);
- p._val ^= Value::NaNEncodeMask;
- return p;
- }
- static TargetPrimitive64 fromUInt32(uint v) {
- if (v < INT_MAX)
- return fromInt32(qint32(v));
- return fromDouble(double(v));
- }
-
- quint32 value() const { return _val & quint64(~quint32(0)); }
- quint32 tag() const { return _val >> 32; }
-
- quint64 rawValue() const { return _val; }
-
-private:
- quint64 _val;
-};
-
-inline bool canConvertToSignedInteger(double value)
-{
- int ival = (int) value;
- // +0 != -0, so we need to convert to double when negating 0
- return ival == value && !(value == 0 && isNegative(value));
-}
-
-inline bool canConvertToUnsignedInteger(double value)
-{
- unsigned uval = (unsigned) value;
- // +0 != -0, so we need to convert to double when negating 0
- return uval == value && !(value == 0 && isNegative(value));
-}
-
-template <typename PrimitiveType = Primitive>
-inline PrimitiveType convertToValue(IR::Const *c)
-{
- switch (c->type) {
- case IR::MissingType:
- return PrimitiveType::emptyValue();
- case IR::NullType:
- return PrimitiveType::nullValue();
- case IR::UndefinedType:
- return PrimitiveType::undefinedValue();
- case IR::BoolType:
- return PrimitiveType::fromBoolean(c->value != 0);
- case IR::SInt32Type:
- return PrimitiveType::fromInt32(int(c->value));
- case IR::UInt32Type:
- return PrimitiveType::fromUInt32(unsigned(c->value));
- case IR::DoubleType:
- return PrimitiveType::fromDouble(c->value);
- case IR::NumberType: {
- int ival = (int)c->value;
- if (canConvertToSignedInteger(c->value)) {
- return PrimitiveType::fromInt32(ival);
- } else {
- return PrimitiveType::fromDouble(c->value);
- }
- }
- default:
- Q_UNREACHABLE();
- }
- // unreachable, but the function must return something
- return PrimitiveType::undefinedValue();
-}
-
-class ConvertTemps
-{
- void renumber(IR::Temp *t)
- {
- if (t->kind != IR::Temp::VirtualRegister)
- return;
-
- int stackSlot = _stackSlotForTemp.value(t->index, -1);
- if (stackSlot == -1) {
- stackSlot = allocateFreeSlot();
- _stackSlotForTemp[t->index] = stackSlot;
- }
-
- t->kind = IR::Temp::StackSlot;
- t->index = stackSlot;
- }
-
-protected:
- int _nextUnusedStackSlot;
- QHash<int, int> _stackSlotForTemp;
- IR::BasicBlock *_currentBasicBlock;
- virtual int allocateFreeSlot()
- {
- return _nextUnusedStackSlot++;
- }
-
- virtual void process(IR::Stmt *s)
- {
- visit(s);
- }
-
-public:
- ConvertTemps()
- : _nextUnusedStackSlot(0)
- , _currentBasicBlock(0)
- {}
-
- void toStackSlots(IR::Function *function)
- {
- _stackSlotForTemp.reserve(function->tempCount);
-
- for (IR::BasicBlock *bb : function->basicBlocks()) {
- if (bb->isRemoved())
- continue;
- _currentBasicBlock = bb;
- for (IR::Stmt *s : bb->statements())
- process(s);
- }
-
- function->tempCount = _nextUnusedStackSlot;
- }
-
-protected:
- void visit(IR::Stmt *s) {
- switch (s->stmtKind) {
- case IR::Stmt::PhiStmt:
- visitPhi(s->asPhi());
- break;
- default:
- STMT_VISIT_ALL_KINDS(s);
- break;
- }
- }
-
- virtual void visitPhi(IR::Phi *)
- { Q_UNREACHABLE(); }
-
-private:
- void visit(IR::Expr *e) {
- if (auto temp = e->asTemp()) {
- renumber(temp);
- } else {
- EXPR_VISIT_ALL_KINDS(e);
- }
- }
-};
-} // namespace QV4
-
-QT_END_NAMESPACE
-
-#endif // QV4ISEL_UTIL_P_H
diff --git a/src/qml/compiler/qv4jsir.cpp b/src/qml/compiler/qv4jsir.cpp
deleted file mode 100644
index a4038f827a..0000000000
--- a/src/qml/compiler/qv4jsir.cpp
+++ /dev/null
@@ -1,1001 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qv4jsir_p.h"
-#include <private/qqmljsast_p.h>
-
-#ifndef V4_BOOTSTRAP
-#include <private/qqmlpropertycache_p.h>
-#endif
-
-#include <QtCore/QBuffer>
-#include <QtCore/qtextstream.h>
-#include <QtCore/qdebug.h>
-#include <QtCore/qset.h>
-#include <cmath>
-
-#include <vector>
-
-#ifdef CONST
-#undef CONST
-#endif
-
-QT_BEGIN_NAMESPACE
-
-namespace QV4 {
-namespace IR {
-
-QString typeName(Type t)
-{
- switch (t) {
- case UnknownType: return QStringLiteral("");
- case MissingType: return QStringLiteral("missing");
- case UndefinedType: return QStringLiteral("undefined");
- case NullType: return QStringLiteral("null");
- case BoolType: return QStringLiteral("bool");
- case UInt32Type: return QStringLiteral("uint32");
- case SInt32Type: return QStringLiteral("int32");
- case DoubleType: return QStringLiteral("double");
- case NumberType: return QStringLiteral("number");
- case StringType: return QStringLiteral("string");
- case VarType: return QStringLiteral("var");
- case QObjectType: return QStringLiteral("qobject");
- default: return QStringLiteral("multiple");
- }
-}
-
-const char *opname(AluOp op)
-{
- switch (op) {
- case OpInvalid: return "?";
-
- case OpIfTrue: return "(bool)";
- case OpNot: return "not";
- case OpUMinus: return "neg";
- case OpUPlus: return "plus";
- case OpCompl: return "invert";
- case OpIncrement: return "incr";
- case OpDecrement: return "decr";
-
- case OpBitAnd: return "bitand";
- case OpBitOr: return "bitor";
- case OpBitXor: return "bitxor";
-
- case OpAdd: return "add";
- case OpSub: return "sub";
- case OpMul: return "mul";
- case OpDiv: return "div";
- case OpMod: return "mod";
-
- case OpLShift: return "shl";
- case OpRShift: return "shr";
- case OpURShift: return "asr";
-
- case OpGt: return "gt";
- case OpLt: return "lt";
- case OpGe: return "ge";
- case OpLe: return "le";
- case OpEqual: return "eq";
- case OpNotEqual: return "ne";
- case OpStrictEqual: return "se";
- case OpStrictNotEqual: return "sne";
-
- case OpInstanceof: return "instanceof";
- case OpIn: return "in";
-
- case OpAnd: return "and";
- case OpOr: return "or";
-
- default: return "?";
-
- } // switch
-}
-
-AluOp binaryOperator(int op)
-{
- switch (static_cast<QSOperator::Op>(op)) {
- case QSOperator::Add: return OpAdd;
- case QSOperator::And: return OpAnd;
- case QSOperator::BitAnd: return OpBitAnd;
- case QSOperator::BitOr: return OpBitOr;
- case QSOperator::BitXor: return OpBitXor;
- case QSOperator::Div: return OpDiv;
- case QSOperator::Equal: return OpEqual;
- case QSOperator::Ge: return OpGe;
- case QSOperator::Gt: return OpGt;
- case QSOperator::Le: return OpLe;
- case QSOperator::LShift: return OpLShift;
- case QSOperator::Lt: return OpLt;
- case QSOperator::Mod: return OpMod;
- case QSOperator::Mul: return OpMul;
- case QSOperator::NotEqual: return OpNotEqual;
- case QSOperator::Or: return OpOr;
- case QSOperator::RShift: return OpRShift;
- case QSOperator::StrictEqual: return OpStrictEqual;
- case QSOperator::StrictNotEqual: return OpStrictNotEqual;
- case QSOperator::Sub: return OpSub;
- case QSOperator::URShift: return OpURShift;
- case QSOperator::InstanceOf: return OpInstanceof;
- case QSOperator::In: return OpIn;
- default: return OpInvalid;
- }
-}
-
-class RemoveSharedExpressions
-{
- CloneExpr clone;
- std::vector<Expr *> subexpressions; // contains all the non-cloned subexpressions in the given function. sorted using std::lower_bound.
- Expr *uniqueExpr;
-
-public:
- RemoveSharedExpressions(): uniqueExpr(0) {}
-
- void operator()(IR::Function *function)
- {
- subexpressions.clear();
- subexpressions.reserve(function->basicBlockCount() * 8);
-
- for (BasicBlock *block : function->basicBlocks()) {
- if (block->isRemoved())
- continue;
- clone.setBasicBlock(block);
-
- for (Stmt *s : block->statements()) {
- visit(s);
- }
- }
- }
-
-private:
- template <typename Expr_>
- Expr_ *cleanup(Expr_ *expr)
- {
- std::vector<Expr *>::iterator it = std::lower_bound(subexpressions.begin(), subexpressions.end(), expr);
- if (it == subexpressions.end() || *it != expr) {
- subexpressions.insert(it, expr);
- IR::Expr *e = expr;
- qSwap(uniqueExpr, e);
- visit(expr);
- qSwap(uniqueExpr, e);
- return static_cast<Expr_ *>(e);
- }
-
- // the cloned expression is unique by definition
- // so we don't need to add it to `subexpressions'.
- return clone(expr);
- }
-
- void visit(Stmt *s)
- {
- if (auto e = s->asExp()) {
- e->expr = cleanup(e->expr);
- } else if (auto m = s->asMove()) {
- m->target = cleanup(m->target);
- m->source = cleanup(m->source);
- } else if (auto c = s->asCJump()) {
- c->cond = cleanup(c->cond);
- } else if (auto r = s->asRet()) {
- r->expr = cleanup(r->expr);
- }
- }
-
- void visit(Expr *e)
- {
- if (auto c = e->asConvert()) {
- c->expr = cleanup(c->expr);
- } else if (auto u = e->asUnop()) {
- u->expr = cleanup(u->expr);
- } else if (auto b = e->asBinop()) {
- b->left = cleanup(b->left);
- b->right = cleanup(b->right);
- } else if (auto c = e->asCall()) {
- c->base = cleanup(c->base);
- for (IR::ExprList *it = c->args; it; it = it->next) {
- it->expr = cleanup(it->expr);
- }
- } else if (auto n = e->asNew()) {
- n->base = cleanup(n->base);
- for (IR::ExprList *it = n->args; it; it = it->next) {
- it->expr = cleanup(it->expr);
- }
- } else if (auto s = e->asSubscript()) {
- s->base = cleanup(s->base);
- s->index = cleanup(s->index);
- } else if (auto m = e->asMember()) {
- m->base = cleanup(m->base);
- }
- }
-};
-
-void Name::initGlobal(const QString *id, quint32 line, quint32 column, bool forceLookup)
-{
- this->id = id;
- this->builtin = builtin_invalid;
- this->global = true;
- this->forceLookup = forceLookup;
- this->qmlSingleton = false;
- this->freeOfSideEffects = false;
- this->line = line;
- this->column = column;
-}
-
-void Name::init(const QString *id, quint32 line, quint32 column)
-{
- this->id = id;
- this->builtin = builtin_invalid;
- this->global = false;
- this->forceLookup = false;
- this->qmlSingleton = false;
- this->freeOfSideEffects = false;
- this->line = line;
- this->column = column;
-}
-
-void Name::init(Builtin builtin, quint32 line, quint32 column)
-{
- this->id = 0;
- this->builtin = builtin;
- this->global = false;
- this->forceLookup = false;
- this->qmlSingleton = false;
- this->freeOfSideEffects = false;
- this->line = line;
- this->column = column;
-}
-
-const char *builtin_to_string(Name::Builtin b)
-{
- switch (b) {
- case Name::builtin_invalid:
- return "builtin_invalid";
- case Name::builtin_typeof:
- return "builtin_typeof";
- case Name::builtin_delete:
- return "builtin_delete";
- case Name::builtin_throw:
- return "builtin_throw";
- case Name::builtin_rethrow:
- return "builtin_rethrow";
- case Name::builtin_unwind_exception:
- return "builtin_unwind_exception";
- case Name::builtin_push_catch_scope:
- return "builtin_push_catch_scope";
- case IR::Name::builtin_foreach_iterator_object:
- return "builtin_foreach_iterator_object";
- case IR::Name::builtin_foreach_next_property_name:
- return "builtin_foreach_next_property_name";
- case IR::Name::builtin_push_with_scope:
- return "builtin_push_with_scope";
- case IR::Name::builtin_pop_scope:
- return "builtin_pop_scope";
- case IR::Name::builtin_declare_vars:
- return "builtin_declare_vars";
- case IR::Name::builtin_define_array:
- return "builtin_define_array";
- case IR::Name::builtin_define_object_literal:
- return "builtin_define_object_literal";
- case IR::Name::builtin_setup_argument_object:
- return "builtin_setup_argument_object";
- case IR::Name::builtin_convert_this_to_object:
- return "builtin_convert_this_to_object";
- case IR::Name::builtin_qml_context:
- return "builtin_qml_context";
- case IR::Name::builtin_qml_imported_scripts_object:
- return "builtin_qml_imported_scripts_object";
- }
- return "builtin_(###FIXME)";
-};
-
-bool operator<(const Temp &t1, const Temp &t2) Q_DECL_NOTHROW
-{
- if (t1.kind < t2.kind) return true;
- if (t1.kind > t2.kind) return false;
- return t1.index < t2.index;
-}
-
-Function *Module::newFunction(const QString &name, Function *outer)
-{
- Function *f = new Function(this, outer, name);
- functions.append(f);
- if (!outer) {
- if (!isQmlModule) {
- Q_ASSERT(!rootFunction);
- rootFunction = f;
- }
- } else {
- outer->nestedFunctions.append(f);
- }
- return f;
-}
-
-Module::~Module()
-{
- qDeleteAll(functions);
-}
-
-void Module::setFileName(const QString &name)
-{
- fileName = name;
-}
-
-void Module::setFinalUrl(const QString &url)
-{
- finalUrl = url;
-}
-
-Function::Function(Module *module, Function *outer, const QString &name)
- : module(module)
- , pool(&module->pool)
- , tempCount(0)
- , maxNumberOfArguments(0)
- , outer(outer)
- , insideWithOrCatch(0)
- , hasDirectEval(false)
- , usesArgumentsObject(false)
- , usesThis(false)
- , isStrict(false)
- , isNamedExpression(false)
- , hasTry(false)
- , hasWith(false)
- , isQmlBinding(false)
- , unused(0)
- , line(0)
- , column(0)
- , _allBasicBlocks(0)
- , _statementCount(0)
-{
- this->name = newString(name);
- _basicBlocks.reserve(8);
-}
-
-Function::~Function()
-{
- if (_allBasicBlocks) {
- qDeleteAll(*_allBasicBlocks);
- delete _allBasicBlocks;
- } else {
- qDeleteAll(_basicBlocks);
- }
-
- pool = 0;
- module = 0;
-}
-
-
-const QString *Function::newString(const QString &text)
-{
- return &*strings.insert(text);
-}
-
-BasicBlock *Function::newBasicBlock(BasicBlock *catchBlock, BasicBlockInsertMode mode)
-{
- BasicBlock *block = new BasicBlock(this, catchBlock);
- return mode == InsertBlock ? addBasicBlock(block) : block;
-}
-
-BasicBlock *Function::addBasicBlock(BasicBlock *block)
-{
- Q_ASSERT(block->index() < 0);
- block->setIndex(_basicBlocks.size());
- _basicBlocks.append(block);
- return block;
-}
-
-void Function::removeBasicBlock(BasicBlock *block)
-{
- block->markAsRemoved();
- block->in.clear();
- block->out.clear();
-}
-
-int Function::liveBasicBlocksCount() const
-{
- int count = 0;
- for (BasicBlock *bb : basicBlocks())
- if (!bb->isRemoved())
- ++count;
- return count;
-}
-
-void Function::removeSharedExpressions()
-{
- RemoveSharedExpressions removeSharedExpressions;
- removeSharedExpressions(this);
-}
-
-int Function::indexOfArgument(const QStringRef &string) const
-{
- for (int i = formals.size() - 1; i >= 0; --i) {
- if (*formals.at(i) == string)
- return i;
- }
- return -1;
-}
-
-void Function::setScheduledBlocks(const QVector<BasicBlock *> &scheduled)
-{
- Q_ASSERT(!_allBasicBlocks);
- _allBasicBlocks = new QVector<BasicBlock *>(basicBlocks());
- _basicBlocks = scheduled;
- for (int i = 0, ei = basicBlockCount(); i != ei; ++i)
- basicBlock(i)->changeIndex(i);
-}
-
-BasicBlock *Function::getOrCreateBasicBlock(int index)
-{
- if (_basicBlocks.size() <= index) {
- const int oldSize = _basicBlocks.size();
- _basicBlocks.resize(index + 1);
- for (int i = oldSize; i <= index; ++i) {
- BasicBlock *block = new BasicBlock(this, 0);
- block->setIndex(i);
- _basicBlocks[i] = block;
- }
- }
-
- return _basicBlocks.at(index);
-}
-
-void Function::setStatementCount(int cnt)
-{
- _statementCount = cnt;
-}
-
-void BasicBlock::setStatements(const QVector<Stmt *> &newStatements)
-{
- Q_ASSERT(!isRemoved());
- Q_ASSERT(newStatements.size() >= _statements.size());
- for (Stmt *s : qAsConst(_statements)) {
- if (Phi *p = s->asPhi()) {
- if (!newStatements.contains(p)) {
- // phi-node was not copied over, so:
- p->destroyData();
- }
- } else {
- break;
- }
- }
- _statements = newStatements;
-}
-
-CloneExpr::CloneExpr(BasicBlock *block)
- : block(block), cloned(0)
-{
-}
-
-void CloneExpr::setBasicBlock(BasicBlock *block)
-{
- this->block = block;
-}
-
-ExprList *CloneExpr::clone(ExprList *list)
-{
- if (! list)
- return 0;
-
- ExprList *clonedList = block->function->New<IR::ExprList>();
- clonedList->init(clone(list->expr), clone(list->next));
- return clonedList;
-}
-
-void CloneExpr::visit(Expr *e)
-{
- if (auto c = e->asConst()) {
- cloned = cloneConst(c, block->function);
- } else if (auto s = e->asString()) {
- cloned = block->STRING(s->value);
- } else if (auto r = e->asRegExp()) {
- cloned = block->REGEXP(r->value, r->flags);
- } else if (auto n = e->asName()) {
- cloned = cloneName(n, block->function);
- } else if (auto t = e->asTemp()) {
- cloned = cloneTemp(t, block->function);
- } else if (auto a = e->asArgLocal()) {
- cloned = cloneArgLocal(a, block->function);
- } else if (auto c = e->asClosure()) {
- cloned = block->CLOSURE(c->value);
- } else if (auto c = e->asConvert()) {
- cloned = block->CONVERT(clone(c->expr), c->type);
- } else if (auto u = e->asUnop()) {
- cloned = block->UNOP(u->op, clone(u->expr));
- } else if (auto b = e->asBinop()) {
- cloned = block->BINOP(b->op, clone(b->left), clone(b->right));
- } else if (auto c = e->asCall()) {
- cloned = block->CALL(clone(c->base), clone(c->args));
- } else if (auto n = e->asNew()) {
- cloned = block->NEW(clone(n->base), clone(n->args));
- } else if (auto s = e->asSubscript()) {
- cloned = block->SUBSCRIPT(clone(s->base), clone(s->index));
- } else if (auto m = e->asMember()) {
- cloned = block->MEMBER(clone(m->base), m->name, m->property, m->kind, m->idIndex);
- } else {
- Q_UNREACHABLE();
- }
-}
-
-IRPrinter::IRPrinter(QTextStream *out)
- : out(out)
- , positionSize(Stmt::InvalidId)
- , currentBB(0)
-{
-}
-
-IRPrinter::~IRPrinter()
-{
-}
-
-void IRPrinter::print(Stmt *s)
-{
- visit(s);
-}
-
-void IRPrinter::print(const Expr &e)
-{
- visit(const_cast<Expr *>(&e));
-}
-
-void IRPrinter::print(Expr *e)
-{
- visit(e);
-}
-
-void IRPrinter::print(Function *f)
-{
- if (positionSize == Stmt::InvalidId)
- positionSize = QString::number(f->statementCount()).size();
-
- QString n = f->name ? *f->name : QString();
- if (n.isEmpty())
- n.sprintf("%p", f);
- *out << "function " << n << '(';
-
- for (int i = 0; i < f->formals.size(); ++i) {
- if (i != 0)
- *out << ", ";
- *out << *f->formals.at(i);
- }
- *out << ')' << endl
- << '{' << endl;
-
- for (const QString *local : qAsConst(f->locals))
- *out << " local var " << *local << endl;
-
- bool needsSeperator = !f->locals.isEmpty();
- for (BasicBlock *bb : f->basicBlocks()) {
- if (bb->isRemoved())
- continue;
-
- if (needsSeperator)
- *out << endl;
- else
- needsSeperator = true;
- print(bb);
- }
- *out << '}' << endl;
-}
-
-void IRPrinter::print(BasicBlock *bb)
-{
- std::swap(currentBB, bb);
- printBlockStart();
-
- for (Stmt *s : currentBB->statements()) {
- if (!s)
- continue;
-
- QByteArray str;
- QBuffer buf(&str);
- buf.open(QIODevice::WriteOnly);
- QTextStream os(&buf);
- QTextStream *prevOut = &os;
- std::swap(out, prevOut);
- addStmtNr(s);
- visit(s);
- if (s->location.startLine) {
- out->flush();
- for (int i = 58 - str.length(); i > 0; --i)
- *out << ' ';
- *out << " ; line: " << s->location.startLine << ", column: " << s->location.startColumn;
- }
-
- out->flush();
- std::swap(out, prevOut);
-
- *out << " " << str << endl;
- }
-
- std::swap(currentBB, bb);
-}
-
-void IRPrinter::visit(Stmt *s)
-{
- if (auto e = s->asExp()) {
- visitExp(e);
- } else if (auto m = s->asMove()) {
- visitMove(m);
- } else if (auto j = s->asJump()) {
- visitJump(j);
- } else if (auto c = s->asCJump()) {
- visitCJump(c);
- } else if (auto r = s->asRet()) {
- visitRet(r);
- } else if (auto p = s->asPhi()) {
- visitPhi(p);
- } else {
- Q_UNREACHABLE();
- }
-}
-
-void IRPrinter::visitExp(Exp *s)
-{
- *out << "void ";
- visit(s->expr);
-}
-
-void IRPrinter::visitMove(Move *s)
-{
- if (Temp *targetTemp = s->target->asTemp())
- if (!s->swap && targetTemp->type != UnknownType)
- *out << typeName(targetTemp->type) << ' ';
-
- visit(s->target);
- *out << ' ';
- if (s->swap)
- *out << "<=> ";
- else
- *out << "= ";
- visit(s->source);
-}
-
-void IRPrinter::visitJump(Jump *s)
-{
- *out << "goto L" << s->target->index();
-}
-
-void IRPrinter::visitCJump(CJump *s)
-{
- *out << "if ";
- visit(s->cond);
- *out << " goto L" << s->iftrue->index()
- << " else goto L" << s->iffalse->index();
-}
-
-void IRPrinter::visitRet(Ret *s)
-{
- *out << "return";
- if (s->expr) {
- *out << ' ';
- visit(s->expr);
- }
-}
-
-void IRPrinter::visitPhi(Phi *s)
-{
- if (s->targetTemp->type != UnknownType)
- *out << typeName(s->targetTemp->type) << ' ';
-
- visit(s->targetTemp);
- *out << " = phi ";
- for (int i = 0, ei = s->incoming.size(); i < ei; ++i) {
- if (i > 0)
- *out << ", ";
- if (currentBB)
- *out << 'L' << currentBB->in.at(i)->index() << ": ";
- if (s->incoming[i])
- visit(s->incoming[i]);
- }
-}
-
-void IRPrinter::visit(Expr *e)
-{
- if (auto c = e->asConst()) {
- visitConst(c);
- } else if (auto s = e->asString()) {
- visitString(s);
- } else if (auto r = e->asRegExp()) {
- visitRegExp(r);
- } else if (auto n = e->asName()) {
- visitName(n);
- } else if (auto t = e->asTemp()) {
- visitTemp(t);
- } else if (auto a = e->asArgLocal()) {
- visitArgLocal(a);
- } else if (auto c = e->asClosure()) {
- visitClosure(c);
- } else if (auto c = e->asConvert()) {
- visitConvert(c);
- } else if (auto u = e->asUnop()) {
- visitUnop(u);
- } else if (auto b = e->asBinop()) {
- visitBinop(b);
- } else if (auto c = e->asCall()) {
- visitCall(c);
- } else if (auto n = e->asNew()) {
- visitNew(n);
- } else if (auto s = e->asSubscript()) {
- visitSubscript(s);
- } else if (auto m = e->asMember()) {
- visitMember(m);
- } else {
- Q_UNREACHABLE();
- }
-}
-
-void IRPrinter::visitConst(Const *e)
-{
- switch (e->type) {
- case QV4::IR::UndefinedType:
- *out << "undefined";
- break;
- case QV4::IR::NullType:
- *out << "null";
- break;
- case QV4::IR::BoolType:
- *out << (e->value ? "true" : "false");
- break;
- case QV4::IR::MissingType:
- *out << "missing";
- break;
- default:
- if (int(e->value) == 0 && int(e->value) == e->value) {
- if (isNegative(e->value))
- *out << "-0";
- else
- *out << "0";
- } else {
- *out << QString::number(e->value, 'g', 16);
- }
- break;
- }
-}
-
-void IRPrinter::visitString(String *e)
-{
- *out << '"' << escape(*e->value) << '"';
-}
-
-void IRPrinter::visitRegExp(RegExp *e)
-{
- char f[3];
- int i = 0;
- if (e->flags & RegExp::RegExp_Global)
- f[i++] = 'g';
- if (e->flags & RegExp::RegExp_IgnoreCase)
- f[i++] = 'i';
- if (e->flags & RegExp::RegExp_Multiline)
- f[i++] = 'm';
- f[i] = 0;
-
- *out << '/' << *e->value << '/' << f;
-}
-
-void IRPrinter::visitName(Name *e)
-{
- if (e->id) {
- if (*e->id != QLatin1String("this"))
- *out << '.';
- *out << *e->id;
- } else {
- *out << builtin_to_string(e->builtin);
- }
-}
-
-void IRPrinter::visitTemp(Temp *e)
-{
- switch (e->kind) {
- case Temp::VirtualRegister: *out << '%' << e->index; break;
- case Temp::PhysicalRegister: *out << (e->type == DoubleType ? "fp" : "r")
- << e->index; break;
- case Temp::StackSlot: *out << '&' << e->index; break;
- default: *out << "INVALID";
- }
-}
-
-void IRPrinter::visitArgLocal(ArgLocal *e)
-{
- switch (e->kind) {
- case ArgLocal::Formal: *out << '#' << e->index; break;
- case ArgLocal::ScopedFormal: *out << '#' << e->index
- << '@' << e->scope; break;
- case ArgLocal::Local: *out << '$' << e->index; break;
- case ArgLocal::ScopedLocal: *out << '$' << e->index
- << '@' << e->scope; break;
- default: *out << "INVALID";
- }
-}
-
-void IRPrinter::visitClosure(Closure *e)
-{
- QString name = e->functionName ? *e->functionName : QString();
- if (name.isEmpty())
- name.sprintf("%x", e->value);
- *out << "closure " << name;
-}
-
-void IRPrinter::visitConvert(Convert *e)
-{
- *out << "convert " << typeName(e->expr->type) << " to " << typeName(e->type) << ' ';
- visit(e->expr);
-}
-
-void IRPrinter::visitUnop(Unop *e)
-{
- *out << opname(e->op) << ' ';
- visit(e->expr);
-}
-
-void IRPrinter::visitBinop(Binop *e)
-{
- *out << opname(e->op) << ' ';
- visit(e->left);
- *out << ", ";
- visit(e->right);
-}
-
-void IRPrinter::visitCall(Call *e)
-{
- *out << "call ";
- visit(e->base);
- *out << '(';
- for (ExprList *it = e->args; it; it = it->next) {
- if (it != e->args)
- *out << ", ";
- visit(it->expr);
- }
- *out << ')';
-}
-
-void IRPrinter::visitNew(New *e)
-{
- *out << "new ";
- visit(e->base);
- *out << '(';
- for (ExprList *it = e->args; it; it = it->next) {
- if (it != e->args)
- *out << ", ";
- visit(it->expr);
- }
- *out << ')';
-}
-
-void IRPrinter::visitSubscript(Subscript *e)
-{
- visit(e->base);
- *out << '[';
- visit(e->index);
- *out << ']';
-}
-
-void IRPrinter::visitMember(Member *e)
-{
- if (e->kind != Member::MemberOfEnum && e->kind != Member::MemberOfIdObjectsArray
- && e->attachedPropertiesId != 0 && !e->base->asTemp())
- *out << "[[attached property from " << e->attachedPropertiesId << "]]";
- else
- visit(e->base);
- *out << '.' << *e->name;
-#ifndef V4_BOOTSTRAP
- if (e->property)
- *out << " (meta-property " << e->property->coreIndex()
- << " <" << QMetaType::typeName(e->property->propType())
- << ">)";
- else if (e->kind == Member::MemberOfIdObjectsArray)
- *out << "(id object " << e->idIndex << ")";
-#endif
-}
-
-QString IRPrinter::escape(const QString &s)
-{
- QString r;
- for (int i = 0; i < s.length(); ++i) {
- const QChar ch = s.at(i);
- if (ch == QLatin1Char('\n'))
- r += QLatin1String("\\n");
- else if (ch == QLatin1Char('\r'))
- r += QLatin1String("\\r");
- else if (ch == QLatin1Char('\\'))
- r += QLatin1String("\\\\");
- else if (ch == QLatin1Char('"'))
- r += QLatin1String("\\\"");
- else if (ch == QLatin1Char('\''))
- r += QLatin1String("\\'");
- else
- r += ch;
- }
- return r;
-}
-
-void IRPrinter::addStmtNr(Stmt *s)
-{
- if (s->id() >= 0)
- addJustifiedNr(s->id());
-}
-
-void IRPrinter::addJustifiedNr(int pos)
-{
- if (positionSize == Stmt::InvalidId) {
- *out << pos << ": ";
- } else {
- QString posStr;
- if (pos != Stmt::InvalidId)
- posStr = QString::number(pos);
- *out << posStr.rightJustified(positionSize);
- if (pos == Stmt::InvalidId)
- *out << " ";
- else
- *out << ": ";
- }
-}
-
-void IRPrinter::printBlockStart()
-{
- if (currentBB->isRemoved()) {
- *out << "(block has been removed)";
- return;
- }
-
- QByteArray str;
- str.append('L');
- str.append(QByteArray::number(currentBB->index()));
- str.append(':');
- if (currentBB->catchBlock) {
- str.append(" (exception handler L");
- str.append(QByteArray::number(currentBB->catchBlock->index()));
- str.append(')');
- }
- for (int i = 66 - str.length(); i; --i)
- str.append(' ');
- *out << str;
-
- *out << "; predecessors:";
- for (BasicBlock *in : qAsConst(currentBB->in))
- *out << " L" << in->index();
- if (currentBB->in.isEmpty())
- *out << " none";
- if (BasicBlock *container = currentBB->containingGroup())
- *out << ", container: L" << container->index();
- if (currentBB->isGroupStart())
- *out << ", loop_header: yes";
- *out << endl;
-}
-
-} // end of namespace IR
-} // end of namespace QV4
-
-QT_END_NAMESPACE
diff --git a/src/qml/compiler/qv4jsir_p.h b/src/qml/compiler/qv4jsir_p.h
deleted file mode 100644
index 317abd09bb..0000000000
--- a/src/qml/compiler/qv4jsir_p.h
+++ /dev/null
@@ -1,1790 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#ifndef QV4JSIR_P_H
-#define QV4JSIR_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qv4global_p.h"
-#include <private/qqmljsmemorypool_p.h>
-#include <private/qqmljsastfwd_p.h>
-#include <private/qflagpointer_p.h>
-#ifndef V4_BOOTSTRAP
-#include <private/qqmlmetatype_p.h>
-#endif
-
-#include <QtCore/private/qnumeric_p.h>
-#include <QtCore/QVector>
-#include <QtCore/QString>
-#include <QtCore/QBitArray>
-#include <QtCore/qurl.h>
-#include <QtCore/QVarLengthArray>
-#include <QtCore/QDateTime>
-#include <qglobal.h>
-
-#if defined(CONST) && defined(Q_OS_WIN)
-# define QT_POP_CONST
-# pragma push_macro("CONST")
-# undef CONST // CONST conflicts with our own identifier
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QTextStream;
-class QQmlType;
-class QQmlPropertyData;
-class QQmlPropertyCache;
-class QQmlEnginePrivate;
-struct QQmlImportRef;
-class QQmlTypeNameCache;
-
-namespace QV4 {
-
-inline bool isNegative(double d)
-{
- uchar *dch = (uchar *)&d;
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian)
- return (dch[0] & 0x80);
- else
- return (dch[7] & 0x80);
-
-}
-
-namespace IR {
-
-struct BasicBlock;
-struct Function;
-struct Module;
-
-struct Stmt;
-struct Expr;
-
-// expressions
-struct Const;
-struct String;
-struct RegExp;
-struct Name;
-struct Temp;
-struct ArgLocal;
-struct Closure;
-struct Convert;
-struct Unop;
-struct Binop;
-struct Call;
-struct New;
-struct Subscript;
-struct Member;
-
-// statements
-struct Exp;
-struct Move;
-struct Jump;
-struct CJump;
-struct Ret;
-struct Phi;
-
-template<class T, int Prealloc>
-class VarLengthArray: public QVarLengthArray<T, Prealloc>
-{
-public:
- bool removeOne(const T &element)
- {
- for (int i = 0; i < this->size(); ++i) {
- if (this->at(i) == element) {
- this->remove(i);
- return true;
- }
- }
-
- return false;
- }
-};
-
-// Flag pointer:
-// * The first flag indicates whether the meta object is final.
-// If final, then none of its properties themselves need to
-// be final when considering for lookups in QML.
-// * The second flag indicates whether enums should be included
-// in the lookup of properties or not. The default is false.
-typedef QFlagPointer<QQmlPropertyCache> IRMetaObject;
-
-enum AluOp {
- OpInvalid = 0,
-
- OpIfTrue,
- OpNot,
- OpUMinus,
- OpUPlus,
- OpCompl,
- OpIncrement,
- OpDecrement,
-
- OpBitAnd,
- OpBitOr,
- OpBitXor,
-
- OpAdd,
- OpSub,
- OpMul,
- OpDiv,
- OpMod,
-
- OpLShift,
- OpRShift,
- OpURShift,
-
- OpGt,
- OpLt,
- OpGe,
- OpLe,
- OpEqual,
- OpNotEqual,
- OpStrictEqual,
- OpStrictNotEqual,
-
- OpInstanceof,
- OpIn,
-
- OpAnd,
- OpOr,
-
- LastAluOp = OpOr
-};
-AluOp binaryOperator(int op);
-const char *opname(IR::AluOp op);
-
-enum Type : quint16 {
- UnknownType = 0,
-
- MissingType = 1 << 0,
- UndefinedType = 1 << 1,
- NullType = 1 << 2,
- BoolType = 1 << 3,
-
- SInt32Type = 1 << 4,
- UInt32Type = 1 << 5,
- DoubleType = 1 << 6,
- NumberType = SInt32Type | UInt32Type | DoubleType,
-
- StringType = 1 << 7,
- QObjectType = 1 << 8,
- VarType = 1 << 9
-};
-
-inline bool strictlyEqualTypes(Type t1, Type t2)
-{
- return t1 == t2 || ((t1 & NumberType) && (t2 & NumberType));
-}
-
-QString typeName(Type t);
-
-struct MemberExpressionResolver;
-
-struct DiscoveredType {
- int type;
- MemberExpressionResolver *memberResolver;
-
- DiscoveredType() : type(UnknownType), memberResolver(0) {}
- DiscoveredType(Type t) : type(t), memberResolver(0) { Q_ASSERT(type != QObjectType); }
- explicit DiscoveredType(int t) : type(t), memberResolver(0) { Q_ASSERT(type != QObjectType); }
- explicit DiscoveredType(MemberExpressionResolver *memberResolver)
- : type(QObjectType)
- , memberResolver(memberResolver)
- { Q_ASSERT(memberResolver); }
-
- bool test(Type t) const { return type & t; }
- bool isNumber() const { return (type & NumberType) && !(type & ~NumberType); }
-
- bool operator!=(Type other) const { return type != other; }
- bool operator==(Type other) const { return type == other; }
- bool operator==(const DiscoveredType &other) const { return type == other.type; }
- bool operator!=(const DiscoveredType &other) const { return type != other.type; }
-};
-
-struct MemberExpressionResolver
-{
- typedef DiscoveredType (*ResolveFunction)(QQmlEnginePrivate *engine,
- const MemberExpressionResolver *resolver,
- Member *member);
-
- MemberExpressionResolver()
- : resolveMember(0), import(nullptr), propertyCache(nullptr), typenameCache(nullptr), owner(nullptr), flags(0) {}
-
- bool isValid() const { return !!resolveMember; }
- void clear() { *this = MemberExpressionResolver(); }
-
- ResolveFunction resolveMember;
-#ifndef V4_BOOTSTRAP
- QQmlType qmlType;
-#endif
- const QQmlImportRef *import;
- QQmlPropertyCache *propertyCache;
- QQmlTypeNameCache *typenameCache;
- Function *owner;
- unsigned int flags;
-};
-
-struct Q_AUTOTEST_EXPORT Expr {
- enum ExprKind : quint8 {
- NameExpr,
- TempExpr,
- ArgLocalExpr,
- SubscriptExpr,
- MemberExpr,
-
- LastLValue = MemberExpr,
-
- ConstExpr,
- StringExpr,
- RegExpExpr,
- ClosureExpr,
- ConvertExpr,
- UnopExpr,
- BinopExpr,
- CallExpr,
- NewExpr
- };
-
- Type type;
- const ExprKind exprKind;
-
- Expr &operator=(const Expr &other) {
- Q_ASSERT(exprKind == other.exprKind);
- type = other.type;
- return *this;
- }
-
- template <typename To>
- inline bool isa() const {
- return To::classof(this);
- }
-
- template <typename To>
- inline To *as() {
- if (isa<To>()) {
- return static_cast<To *>(this);
- } else {
- return nullptr;
- }
- }
-
- template <typename To>
- inline const To *as() const {
- if (isa<To>()) {
- return static_cast<const To *>(this);
- } else {
- return nullptr;
- }
- }
-
- Expr(ExprKind exprKind): type(UnknownType), exprKind(exprKind) {}
- bool isLValue() const;
-
- Const *asConst();
- String *asString();
- RegExp *asRegExp();
- Name *asName();
- Temp *asTemp();
- ArgLocal *asArgLocal();
- Closure *asClosure();
- Convert *asConvert();
- Unop *asUnop();
- Binop *asBinop();
- Call *asCall();
- New *asNew();
- Subscript *asSubscript();
- Member *asMember();
-};
-
-#define EXPR_VISIT_ALL_KINDS(e) \
- switch (e->exprKind) { \
- case QV4::IR::Expr::ConstExpr: \
- break; \
- case QV4::IR::Expr::StringExpr: \
- break; \
- case QV4::IR::Expr::RegExpExpr: \
- break; \
- case QV4::IR::Expr::NameExpr: \
- break; \
- case QV4::IR::Expr::TempExpr: \
- break; \
- case QV4::IR::Expr::ArgLocalExpr: \
- break; \
- case QV4::IR::Expr::ClosureExpr: \
- break; \
- case QV4::IR::Expr::ConvertExpr: { \
- auto casted = e->asConvert(); \
- visit(casted->expr); \
- } break; \
- case QV4::IR::Expr::UnopExpr: { \
- auto casted = e->asUnop(); \
- visit(casted->expr); \
- } break; \
- case QV4::IR::Expr::BinopExpr: { \
- auto casted = e->asBinop(); \
- visit(casted->left); \
- visit(casted->right); \
- } break; \
- case QV4::IR::Expr::CallExpr: { \
- auto casted = e->asCall(); \
- visit(casted->base); \
- for (QV4::IR::ExprList *it = casted->args; it; it = it->next) \
- visit(it->expr); \
- } break; \
- case QV4::IR::Expr::NewExpr: { \
- auto casted = e->asNew(); \
- visit(casted->base); \
- for (QV4::IR::ExprList *it = casted->args; it; it = it->next) \
- visit(it->expr); \
- } break; \
- case QV4::IR::Expr::SubscriptExpr: { \
- auto casted = e->asSubscript(); \
- visit(casted->base); \
- visit(casted->index); \
- } break; \
- case QV4::IR::Expr::MemberExpr: { \
- auto casted = e->asMember(); \
- visit(casted->base); \
- } break; \
- }
-
-struct ExprList {
- Expr *expr;
- ExprList *next;
-
- ExprList(): expr(0), next(0) {}
-
- void init(Expr *expr, ExprList *next = 0)
- {
- this->expr = expr;
- this->next = next;
- }
-};
-
-struct Const: Expr {
- double value;
-
- Const(): Expr(ConstExpr) {}
-
- void init(Type type, double value)
- {
- this->type = type;
- this->value = value;
- }
-
- static bool classof(const Expr *c) { return c->exprKind == ConstExpr; }
-};
-
-struct String: Expr {
- const QString *value;
-
- String(): Expr(StringExpr) {}
-
- void init(const QString *value)
- {
- this->value = value;
- }
-
- static bool classof(const Expr *c) { return c->exprKind == StringExpr; }
-};
-
-struct RegExp: Expr {
- // needs to be compatible with the flags in the lexer, and in RegExpObject
- enum Flags {
- RegExp_Global = 0x01,
- RegExp_IgnoreCase = 0x02,
- RegExp_Multiline = 0x04
- };
-
- const QString *value;
- int flags;
-
- RegExp(): Expr(RegExpExpr) {}
-
- void init(const QString *value, int flags)
- {
- this->value = value;
- this->flags = flags;
- }
-
- static bool classof(const Expr *c) { return c->exprKind == RegExpExpr; }
-};
-
-struct Name: Expr {
- enum Builtin {
- builtin_invalid,
- builtin_typeof,
- builtin_delete,
- builtin_throw,
- builtin_rethrow,
- builtin_unwind_exception,
- builtin_push_catch_scope,
- builtin_foreach_iterator_object,
- builtin_foreach_next_property_name,
- builtin_push_with_scope,
- builtin_pop_scope,
- builtin_declare_vars,
- builtin_define_array,
- builtin_define_object_literal,
- builtin_setup_argument_object,
- builtin_convert_this_to_object,
- builtin_qml_context,
- builtin_qml_imported_scripts_object
- };
-
- const QString *id;
- Builtin builtin;
- bool global : 1;
- bool forceLookup : 1;
- bool qmlSingleton : 1;
- bool freeOfSideEffects : 1;
- quint32 line;
- quint32 column;
-
- Name(): Expr(NameExpr) {}
-
- void initGlobal(const QString *id, quint32 line, quint32 column, bool forceLookup = false);
- void init(const QString *id, quint32 line, quint32 column);
- void init(Builtin builtin, quint32 line, quint32 column);
-
- static bool classof(const Expr *c) { return c->exprKind == NameExpr; }
-};
-
-struct Q_AUTOTEST_EXPORT Temp: Expr {
- enum Kind {
- Invalid = 0,
- VirtualRegister,
- PhysicalRegister,
- StackSlot
- };
-
- unsigned index : 28;
- unsigned isReadOnly : 1;
- unsigned kind : 3;
-
- // Used when temp is used as base in member expression
- MemberExpressionResolver *memberResolver;
-
- Temp()
- : Expr(TempExpr)
- , index((1 << 28) - 1)
- , isReadOnly(0)
- , kind(Invalid)
- , memberResolver(0)
- {}
-
- Temp(Type type, Kind kind, unsigned index)
- : Expr(TempExpr)
- , index(index)
- , isReadOnly(0)
- , kind(kind)
- , memberResolver(0)
- {
- this->type = type;
- }
-
- void init(unsigned kind, unsigned index)
- {
- this->index = index;
- this->isReadOnly = false;
- this->kind = kind;
- }
-
- bool isInvalid() const { return kind == Invalid; }
-
- static bool classof(const Expr *c) { return c->exprKind == TempExpr; }
-};
-
-inline bool operator==(const Temp &t1, const Temp &t2) Q_DECL_NOTHROW
-{ return t1.index == t2.index && t1.kind == t2.kind && t1.type == t2.type; }
-
-inline bool operator!=(const Temp &t1, const Temp &t2) Q_DECL_NOTHROW
-{ return !(t1 == t2); }
-
-inline uint qHash(const Temp &t, uint seed = 0) Q_DECL_NOTHROW
-{ return t.index ^ t.kind ^ seed; }
-
-bool operator<(const Temp &t1, const Temp &t2) Q_DECL_NOTHROW;
-
-struct Q_AUTOTEST_EXPORT ArgLocal: Expr {
- enum Kind {
- Formal = 0,
- ScopedFormal,
- Local,
- ScopedLocal
- };
-
- unsigned index;
- unsigned scope : 29; // how many scopes outside the current one?
- unsigned kind : 2;
- unsigned isArgumentsOrEval : 1;
-
- void init(unsigned kind, unsigned index, unsigned scope)
- {
- Q_ASSERT((kind == ScopedLocal && scope != 0) ||
- (kind == ScopedFormal && scope != 0) ||
- (scope == 0));
-
- this->kind = kind;
- this->index = index;
- this->scope = scope;
- this->isArgumentsOrEval = false;
- }
-
- ArgLocal(): Expr(ArgLocalExpr) {}
-
- bool operator==(const ArgLocal &other) const
- { return index == other.index && scope == other.scope && kind == other.kind; }
-
- static bool classof(const Expr *c) { return c->exprKind == ArgLocalExpr; }
-};
-
-struct Closure: Expr {
- int value; // index in _module->functions
- const QString *functionName;
-
- Closure(): Expr(ClosureExpr) {}
-
- void init(int functionInModule, const QString *functionName)
- {
- this->value = functionInModule;
- this->functionName = functionName;
- }
-
- static bool classof(const Expr *c) { return c->exprKind == ClosureExpr; }
-};
-
-struct Convert: Expr {
- Expr *expr;
-
- Convert(): Expr(ConvertExpr) {}
-
- void init(Expr *expr, Type type)
- {
- this->expr = expr;
- this->type = type;
- }
-
- static bool classof(const Expr *c) { return c->exprKind == ConvertExpr; }
-};
-
-struct Unop: Expr {
- Expr *expr;
- AluOp op;
-
- Unop(): Expr(UnopExpr) {}
-
- void init(AluOp op, Expr *expr)
- {
- this->op = op;
- this->expr = expr;
- }
-
- static bool classof(const Expr *c) { return c->exprKind == UnopExpr; }
-};
-
-struct Binop: Expr {
- Expr *left; // Temp or Const
- Expr *right; // Temp or Const
- AluOp op;
-
- Binop(): Expr(BinopExpr) {}
-
- void init(AluOp op, Expr *left, Expr *right)
- {
- this->op = op;
- this->left = left;
- this->right = right;
- }
-
- static bool classof(const Expr *c) { return c->exprKind == BinopExpr; }
-};
-
-struct Call: Expr {
- Expr *base; // Name, Member, Temp
- ExprList *args; // List of Temps
-
- Call(): Expr(CallExpr) {}
-
- void init(Expr *base, ExprList *args)
- {
- this->base = base;
- this->args = args;
- }
-
- Expr *onlyArgument() const {
- if (args && ! args->next)
- return args->expr;
- return 0;
- }
-
- static bool classof(const Expr *c) { return c->exprKind == CallExpr; }
-};
-
-struct New: Expr {
- Expr *base; // Name, Member, Temp
- ExprList *args; // List of Temps
-
- New(): Expr(NewExpr) {}
-
- void init(Expr *base, ExprList *args)
- {
- this->base = base;
- this->args = args;
- }
-
- Expr *onlyArgument() const {
- if (args && ! args->next)
- return args->expr;
- return 0;
- }
-
- static bool classof(const Expr *c) { return c->exprKind == NewExpr; }
-};
-
-struct Subscript: Expr {
- Expr *base;
- Expr *index;
-
- Subscript(): Expr(SubscriptExpr) {}
-
- void init(Expr *base, Expr *index)
- {
- this->base = base;
- this->index = index;
- }
-
- static bool classof(const Expr *c) { return c->exprKind == SubscriptExpr; }
-};
-
-struct Member: Expr {
- // Used for property dependency tracking
- enum MemberKind {
- UnspecifiedMember,
- MemberOfEnum,
- MemberOfQmlScopeObject,
- MemberOfQmlContextObject,
- MemberOfIdObjectsArray,
- MemberOfSingletonObject,
- };
-
- Expr *base;
- const QString *name;
- QQmlPropertyData *property;
- union { // depending on kind
- int attachedPropertiesId;
- int enumValue;
- int idIndex;
- };
- uchar freeOfSideEffects : 1;
-
- // This is set for example for for QObject properties. All sorts of extra behavior
- // is defined when writing to them, for example resettable properties are reset
- // when writing undefined to them, and an exception is thrown when they're missing
- // a reset function. And then there's also Qt.binding().
- uchar inhibitTypeConversionOnWrite: 1;
-
- uchar kind: 3; // MemberKind
-
- Member(): Expr(MemberExpr) {}
-
- void setEnumValue(int value) {
- kind = MemberOfEnum;
- enumValue = value;
- }
-
- void setAttachedPropertiesId(int id) {
- Q_ASSERT(kind != MemberOfEnum && kind != MemberOfIdObjectsArray);
- attachedPropertiesId = id;
- }
-
- void init(Expr *base, const QString *name, QQmlPropertyData *property = 0, uchar kind = UnspecifiedMember, int index = 0)
- {
- this->base = base;
- this->name = name;
- this->property = property;
- this->idIndex = index;
- this->freeOfSideEffects = false;
- this->inhibitTypeConversionOnWrite = property != 0;
- this->kind = kind;
- }
-
- static bool classof(const Expr *c) { return c->exprKind == MemberExpr; }
-};
-
-inline bool Expr::isLValue() const {
- if (auto t = as<Temp>())
- return !t->isReadOnly;
- return exprKind <= LastLValue;
-}
-
-struct Stmt {
- enum StmtKind: quint8 {
- MoveStmt,
- ExpStmt,
- JumpStmt,
- CJumpStmt,
- RetStmt,
- PhiStmt
- };
-
- template <typename To>
- inline bool isa() const {
- return To::classof(this);
- }
-
- template <typename To>
- inline To *as() {
- if (isa<To>())
- return static_cast<To *>(this);
- else
- return nullptr;
- }
-
- enum { InvalidId = -1 };
-
- QQmlJS::AST::SourceLocation location;
-
- explicit Stmt(int id, StmtKind stmtKind): _id(id), stmtKind(stmtKind) {}
-
- Stmt *asTerminator();
-
- Exp *asExp();
- Move *asMove();
- Jump *asJump();
- CJump *asCJump();
- Ret *asRet();
- Phi *asPhi();
-
- int id() const { return _id; }
-
-private: // For memory management in BasicBlock
- friend struct BasicBlock;
-
-private:
- friend struct Function;
- int _id;
-
-public:
- const StmtKind stmtKind;
-};
-
-#define STMT_VISIT_ALL_KINDS(s) \
- switch (s->stmtKind) { \
- case QV4::IR::Stmt::MoveStmt: { \
- auto casted = s->asMove(); \
- visit(casted->target); \
- visit(casted->source); \
- } break; \
- case QV4::IR::Stmt::ExpStmt: { \
- auto casted = s->asExp(); \
- visit(casted->expr); \
- } break; \
- case QV4::IR::Stmt::JumpStmt: \
- break; \
- case QV4::IR::Stmt::CJumpStmt: { \
- auto casted = s->asCJump(); \
- visit(casted->cond); \
- } break; \
- case QV4::IR::Stmt::RetStmt: { \
- auto casted = s->asRet(); \
- visit(casted->expr); \
- } break; \
- case QV4::IR::Stmt::PhiStmt: { \
- auto casted = s->asPhi(); \
- visit(casted->targetTemp); \
- for (auto *e : casted->incoming) { \
- visit(e); \
- } \
- } break; \
- }
-
-struct Exp: Stmt {
- Expr *expr;
-
- Exp(int id): Stmt(id, ExpStmt) {}
-
- void init(Expr *expr)
- {
- this->expr = expr;
- }
-
- static bool classof(const Stmt *c) { return c->stmtKind == ExpStmt; }
-};
-
-struct Move: Stmt {
- Expr *target; // LHS - Temp, Name, Member or Subscript
- Expr *source;
- bool swap;
-
- Move(int id): Stmt(id, MoveStmt) {}
-
- void init(Expr *target, Expr *source)
- {
- this->target = target;
- this->source = source;
- this->swap = false;
- }
-
- static bool classof(const Stmt *c) { return c->stmtKind == MoveStmt; }
-};
-
-struct Jump: Stmt {
- BasicBlock *target;
-
- Jump(int id): Stmt(id, JumpStmt) {}
-
- void init(BasicBlock *target)
- {
- this->target = target;
- }
-
- static bool classof(const Stmt *c) { return c->stmtKind == JumpStmt; }
-};
-
-struct CJump: Stmt {
- Expr *cond; // Temp, Binop
- BasicBlock *iftrue;
- BasicBlock *iffalse;
- BasicBlock *parent;
-
- CJump(int id): Stmt(id, CJumpStmt) {}
-
- void init(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse, BasicBlock *parent)
- {
- this->cond = cond;
- this->iftrue = iftrue;
- this->iffalse = iffalse;
- this->parent = parent;
- }
-
- static bool classof(const Stmt *c) { return c->stmtKind == CJumpStmt; }
-};
-
-struct Ret: Stmt {
- Expr *expr;
-
- Ret(int id): Stmt(id, RetStmt) {}
-
- void init(Expr *expr)
- {
- this->expr = expr;
- }
-
- static bool classof(const Stmt *c) { return c->stmtKind == RetStmt; }
-};
-
-// Phi nodes can only occur at the start of a basic block. If there are any, they need to be
-// subsequent to eachother, and the first phi node should be the first statement in the basic-block.
-// A number of loops rely on this behavior, so they don't need to walk through the whole list
-// of instructions in a basic-block (e.g. the calls to destroyData in BasicBlock::~BasicBlock).
-struct Phi: Stmt {
- Temp *targetTemp;
- VarLengthArray<Expr *, 4> incoming;
-
- Phi(int id): Stmt(id, PhiStmt) {}
-
- static bool classof(const Stmt *c) { return c->stmtKind == PhiStmt; }
-
- void destroyData()
- { incoming.~VarLengthArray(); }
-};
-
-inline Stmt *Stmt::asTerminator()
-{
- if (auto s = asJump()) {
- return s;
- } else if (auto s = asCJump()) {
- return s;
- } else if (auto s = asRet()) {
- return s;
- } else {
- return nullptr;
- }
-}
-
-struct Q_QML_PRIVATE_EXPORT Module {
- QQmlJS::MemoryPool pool;
- QVector<Function *> functions;
- Function *rootFunction;
- QString fileName;
- QString finalUrl;
- QDateTime sourceTimeStamp;
- bool isQmlModule; // implies rootFunction is always 0
- uint unitFlags; // flags merged into CompiledData::Unit::flags
- QString targetABI; // fallback to QSysInfo::buildAbi() if empty
-#ifdef QT_NO_QML_DEBUGGER
- static const bool debugMode = false;
-#else
- bool debugMode;
-#endif
-
- Function *newFunction(const QString &name, Function *outer);
-
- Module(bool debugMode)
- : rootFunction(0)
- , isQmlModule(false)
- , unitFlags(0)
-#ifndef QT_NO_QML_DEBUGGER
- , debugMode(debugMode)
- {}
-#else
- { Q_UNUSED(debugMode); }
-#endif
- ~Module();
-
- void setFileName(const QString &name);
- void setFinalUrl(const QString &url);
-};
-
-struct BasicBlock {
-private:
- Q_DISABLE_COPY(BasicBlock)
-
-public:
- typedef VarLengthArray<BasicBlock *, 4> IncomingEdges;
- typedef VarLengthArray<BasicBlock *, 2> OutgoingEdges;
-
- Function *function;
- BasicBlock *catchBlock;
- IncomingEdges in;
- OutgoingEdges out;
- QQmlJS::AST::SourceLocation nextLocation;
-
- BasicBlock(Function *function, BasicBlock *catcher)
- : function(function)
- , catchBlock(catcher)
- , _containingGroup(0)
- , _index(-1)
- , _isExceptionHandler(false)
- , _groupStart(false)
- , _isRemoved(false)
- {}
-
- ~BasicBlock()
- {
- for (Stmt *s : qAsConst(_statements)) {
- if (Phi *p = s->asPhi()) {
- p->destroyData();
- } else {
- break;
- }
- }
- }
-
- const QVector<Stmt *> &statements() const
- {
- Q_ASSERT(!isRemoved());
- return _statements;
- }
-
- int statementCount() const
- {
- Q_ASSERT(!isRemoved());
- return _statements.size();
- }
-
- void setStatements(const QVector<Stmt *> &newStatements);
-
- template <typename Instr> inline Instr i(Instr i)
- {
- Q_ASSERT(!isRemoved());
- appendStatement(i);
- return i;
- }
-
- void appendStatement(Stmt *statement)
- {
- Q_ASSERT(!isRemoved());
- if (nextLocation.startLine)
- statement->location = nextLocation;
- _statements.append(statement);
- }
-
- void prependStatement(Stmt *stmt)
- {
- Q_ASSERT(!isRemoved());
- _statements.prepend(stmt);
- }
-
- void prependStatements(const QVector<Stmt *> &stmts)
- {
- Q_ASSERT(!isRemoved());
- QVector<Stmt *> newStmts = stmts;
- newStmts += _statements;
- _statements = newStmts;
- }
-
- void insertStatementBefore(Stmt *before, Stmt *newStmt)
- {
- int idx = _statements.indexOf(before);
- Q_ASSERT(idx >= 0);
- _statements.insert(idx, newStmt);
- }
-
- void insertStatementBefore(int index, Stmt *newStmt)
- {
- Q_ASSERT(index >= 0);
- _statements.insert(index, newStmt);
- }
-
- void insertStatementBeforeTerminator(Stmt *stmt)
- {
- Q_ASSERT(!isRemoved());
- _statements.insert(_statements.size() - 1, stmt);
- }
-
- void replaceStatement(int index, Stmt *newStmt)
- {
- Q_ASSERT(!isRemoved());
- if (Phi *p = _statements[index]->asPhi()) {
- p->destroyData();
- }
- _statements[index] = newStmt;
- }
-
- void removeStatement(Stmt *stmt)
- {
- Q_ASSERT(!isRemoved());
- if (Phi *p = stmt->asPhi()) {
- p->destroyData();
- }
- _statements.remove(_statements.indexOf(stmt));
- }
-
- void removeStatement(int idx)
- {
- Q_ASSERT(!isRemoved());
- if (Phi *p = _statements[idx]->asPhi()) {
- p->destroyData();
- }
- _statements.remove(idx);
- }
-
- inline bool isEmpty() const {
- Q_ASSERT(!isRemoved());
- return _statements.isEmpty();
- }
-
- inline Stmt *terminator() const {
- Q_ASSERT(!isRemoved());
- if (! _statements.isEmpty() && _statements.last()->asTerminator() != 0)
- return _statements.last();
- return 0;
- }
-
- inline bool isTerminated() const {
- Q_ASSERT(!isRemoved());
- if (terminator() != 0)
- return true;
- return false;
- }
-
- enum TempForWhom {
- NewTempForCodegen,
- NewTempForOptimizer
- };
- unsigned newTemp(TempForWhom tfw = NewTempForCodegen);
-
- Temp *TEMP(unsigned kind);
- ArgLocal *ARG(unsigned index, unsigned scope);
- ArgLocal *LOCAL(unsigned index, unsigned scope);
-
- Expr *CONST(Type type, double value);
- Expr *STRING(const QString *value);
- Expr *REGEXP(const QString *value, int flags);
-
- Name *NAME(const QString &id, quint32 line, quint32 column);
- Name *NAME(Name::Builtin builtin, quint32 line, quint32 column);
-
- Name *GLOBALNAME(const QString &id, quint32 line, quint32 column, bool forceLookup = false);
-
- Closure *CLOSURE(int functionInModule);
-
- Expr *CONVERT(Expr *expr, Type type);
- Expr *UNOP(AluOp op, Expr *expr);
- Expr *BINOP(AluOp op, Expr *left, Expr *right);
- Expr *CALL(Expr *base, ExprList *args = 0);
- Expr *NEW(Expr *base, ExprList *args = 0);
- Expr *SUBSCRIPT(Expr *base, Expr *index);
- Expr *MEMBER(Expr *base, const QString *name, QQmlPropertyData *property = 0, uchar kind = Member::UnspecifiedMember, int attachedPropertiesIdOrEnumValue = 0);
-
- Stmt *EXP(Expr *expr);
-
- Stmt *MOVE(Expr *target, Expr *source);
-
- Stmt *JUMP(BasicBlock *target);
- Stmt *CJUMP(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse);
- Stmt *RET(Expr *expr);
-
- BasicBlock *containingGroup() const
- {
- Q_ASSERT(!isRemoved());
- return _containingGroup;
- }
-
- void setContainingGroup(BasicBlock *loopHeader)
- {
- Q_ASSERT(!isRemoved());
- _containingGroup = loopHeader;
- }
-
- bool isGroupStart() const
- {
- Q_ASSERT(!isRemoved());
- return _groupStart;
- }
-
- void markAsGroupStart(bool mark = true)
- {
- Q_ASSERT(!isRemoved());
- _groupStart = mark;
- }
-
- // Returns the index of the basic-block.
- // See Function for the full description.
- int index() const
- {
- Q_ASSERT(!isRemoved());
- return _index;
- }
-
- bool isExceptionHandler() const
- { return _isExceptionHandler; }
-
- void setExceptionHandler(bool onoff)
- { _isExceptionHandler = onoff; }
-
- bool isRemoved() const
- { return _isRemoved; }
-
-private: // For Function's eyes only.
- friend struct Function;
- void setIndex(int index)
- {
- Q_ASSERT(_index < 0);
- changeIndex(index);
- }
-
- void changeIndex(int index)
- {
- Q_ASSERT(index >= 0);
- _index = index;
- }
-
- void markAsRemoved()
- {
- _isRemoved = true;
- _index = -1;
- }
-
-private:
- QVector<Stmt *> _statements;
- BasicBlock *_containingGroup;
- int _index;
- unsigned _isExceptionHandler : 1;
- unsigned _groupStart : 1;
- unsigned _isRemoved : 1;
-};
-
-template <typename T>
-class SmallSet: public QVarLengthArray<T, 8>
-{
-public:
- void insert(int value)
- {
- for (auto it : *this) {
- if (it == value)
- return;
- }
- this->append(value);
- }
-};
-
-// Map from meta property index (existence implies dependency) to notify signal index
-struct KeyValuePair
-{
- quint32 _key;
- quint32 _value;
-
- KeyValuePair(): _key(0), _value(0) {}
- KeyValuePair(quint32 key, quint32 value): _key(key), _value(value) {}
-
- quint32 key() const { return _key; }
- quint32 value() const { return _value; }
-};
-
-class PropertyDependencyMap: public QVarLengthArray<KeyValuePair, 8>
-{
-public:
- void insert(quint32 key, quint32 value)
- {
- for (auto it = begin(), eit = end(); it != eit; ++it) {
- if (it->_key == key) {
- it->_value = value;
- return;
- }
- }
- append(KeyValuePair(key, value));
- }
-};
-
-// The Function owns (manages), among things, a list of basic-blocks. All the blocks have an index,
-// which corresponds to the index in the entry/index in the vector in which they are stored. This
-// means that algorithms/classes can also store any information about a basic block in an array,
-// where the index corresponds to the index of the basic block, which can then be used to query
-// the function for a pointer to a basic block. This also means that basic-blocks cannot be removed
-// or renumbered.
-//
-// Note that currently there is one exception: after optimization and block scheduling, the
-// method setScheduledBlocks can be called once, to register a newly ordered list. For debugging
-// purposes, these blocks are not immediately renumbered, so renumberBasicBlocks should be called
-// immediately after changing the order. That will restore the property of having a corresponding
-// block-index and block-position-in-basicBlocks-vector.
-//
-// In order for optimization/transformation passes to skip uninteresting basic blocks that will be
-// removed, the block can be marked as such. After doing so, any access will result in a failing
-// assertion.
-struct Function {
- Module *module;
- QQmlJS::MemoryPool *pool;
- const QString *name;
- int currentTemp = 0;
- int tempCount;
- int maxNumberOfArguments;
- QSet<QString> strings;
- QList<const QString *> formals;
- QList<const QString *> locals;
- QVector<Function *> nestedFunctions;
- Function *outer;
-
- int insideWithOrCatch;
-
- uint hasDirectEval: 1;
- uint usesArgumentsObject : 1;
- uint usesThis : 1;
- uint isStrict: 1;
- uint isNamedExpression : 1;
- uint hasTry: 1;
- uint hasWith: 1;
- uint isQmlBinding: 1;
- uint unused : 24;
-
- // Location of declaration in source code (0 if not specified)
- uint line;
- uint column;
-
- // Qml extension:
- SmallSet<int> idObjectDependencies;
- PropertyDependencyMap contextObjectPropertyDependencies;
- PropertyDependencyMap scopeObjectPropertyDependencies;
-
- template <typename T> T *New() { return new (pool->allocate(sizeof(T))) T(); }
- template <typename T> T *NewStmt() {
- return new (pool->allocate(sizeof(T))) T(getNewStatementId());
- }
-
- Function(Module *module, Function *outer, const QString &name);
- ~Function();
-
- enum BasicBlockInsertMode {
- InsertBlock,
- DontInsertBlock
- };
-
- BasicBlock *newBasicBlock(BasicBlock *catchBlock, BasicBlockInsertMode mode = InsertBlock);
- const QString *newString(const QString &text);
-
- void RECEIVE(const QString &name) { formals.append(newString(name)); }
- void LOCAL(const QString &name) { locals.append(newString(name)); }
-
- BasicBlock *addBasicBlock(BasicBlock *block);
- void removeBasicBlock(BasicBlock *block);
-
- const QVector<BasicBlock *> &basicBlocks() const
- { return _basicBlocks; }
-
- BasicBlock *basicBlock(int idx) const
- { return _basicBlocks.at(idx); }
-
- int basicBlockCount() const
- { return _basicBlocks.size(); }
-
- int liveBasicBlocksCount() const;
-
- void removeSharedExpressions();
-
- int indexOfArgument(const QStringRef &string) const;
-
- bool variablesCanEscape() const
- { return hasDirectEval || !nestedFunctions.isEmpty() || module->debugMode; }
-
- void setScheduledBlocks(const QVector<BasicBlock *> &scheduled);
-
- int getNewStatementId() { return _statementCount++; }
- int statementCount() const { return _statementCount; }
-
-private:
- BasicBlock *getOrCreateBasicBlock(int index);
- void setStatementCount(int cnt);
-
-private:
- QVector<BasicBlock *> _basicBlocks;
- QVector<BasicBlock *> *_allBasicBlocks;
- int _statementCount;
-};
-
-class CloneExpr
-{
-public:
- explicit CloneExpr(IR::BasicBlock *block = 0);
-
- void setBasicBlock(IR::BasicBlock *block);
-
- template <typename ExprSubclass>
- ExprSubclass *operator()(ExprSubclass *expr)
- {
- return clone(expr);
- }
-
- template <typename ExprSubclass>
- ExprSubclass *clone(ExprSubclass *expr)
- {
- Expr *c = expr;
- qSwap(cloned, c);
- visit(expr);
- qSwap(cloned, c);
- return static_cast<ExprSubclass *>(c);
- }
-
- static Const *cloneConst(Const *c, Function *f)
- {
- Const *newConst = f->New<Const>();
- newConst->init(c->type, c->value);
- return newConst;
- }
-
- static Name *cloneName(Name *n, Function *f)
- {
- Name *newName = f->New<Name>();
- newName->type = n->type;
- newName->id = n->id;
- newName->builtin = n->builtin;
- newName->global = n->global;
- newName->qmlSingleton = n->qmlSingleton;
- newName->freeOfSideEffects = n->freeOfSideEffects;
- newName->line = n->line;
- newName->column = n->column;
- return newName;
- }
-
- static Temp *cloneTemp(Temp *t, Function *f)
- {
- Temp *newTemp = f->New<Temp>();
- newTemp->init(t->kind, t->index);
- newTemp->type = t->type;
- newTemp->memberResolver = t->memberResolver;
- return newTemp;
- }
-
- static ArgLocal *cloneArgLocal(ArgLocal *argLocal, Function *f)
- {
- ArgLocal *newArgLocal = f->New<ArgLocal>();
- newArgLocal->init(argLocal->kind, argLocal->index, argLocal->scope);
- newArgLocal->type = argLocal->type;
- return newArgLocal;
- }
-
-private:
- IR::ExprList *clone(IR::ExprList *list);
-
- void visit(Expr *e);
-
-protected:
- IR::BasicBlock *block;
-
-private:
- IR::Expr *cloned;
-};
-
-class Q_AUTOTEST_EXPORT IRPrinter
-{
-public:
- IRPrinter(QTextStream *out);
- virtual ~IRPrinter();
-
- void print(Stmt *s);
- void print(Expr *e);
- void print(const Expr &e);
-
- virtual void print(Function *f);
- virtual void print(BasicBlock *bb);
-
- void visit(Stmt *s);
- virtual void visitExp(Exp *s);
- virtual void visitMove(Move *s);
- virtual void visitJump(Jump *s);
- virtual void visitCJump(CJump *s);
- virtual void visitRet(Ret *s);
- virtual void visitPhi(Phi *s);
-
- void visit(Expr *e);
- virtual void visitConst(Const *e);
- virtual void visitString(String *e);
- virtual void visitRegExp(RegExp *e);
- virtual void visitName(Name *e);
- virtual void visitTemp(Temp *e);
- virtual void visitArgLocal(ArgLocal *e);
- virtual void visitClosure(Closure *e);
- virtual void visitConvert(Convert *e);
- virtual void visitUnop(Unop *e);
- virtual void visitBinop(Binop *e);
- virtual void visitCall(Call *e);
- virtual void visitNew(New *e);
- virtual void visitSubscript(Subscript *e);
- virtual void visitMember(Member *e);
-
- static QString escape(const QString &s);
-
-protected:
- virtual void addStmtNr(Stmt *s);
- void addJustifiedNr(int pos);
- void printBlockStart();
-
-protected:
- QTextStream *out;
- int positionSize;
- BasicBlock *currentBB;
-};
-
-inline unsigned BasicBlock::newTemp(TempForWhom tfw)
-{
- Q_ASSERT(!isRemoved());
-
- if (tfw == NewTempForOptimizer)
- return function->tempCount++;
-
- int t = function->currentTemp++;
- if (function->tempCount < function->currentTemp)
- function->tempCount = function->currentTemp;
- return t;
-}
-
-inline Temp *BasicBlock::TEMP(unsigned index)
-{
- Q_ASSERT(!isRemoved());
- Temp *e = function->New<Temp>();
- e->init(Temp::VirtualRegister, index);
- return e;
-}
-
-inline ArgLocal *BasicBlock::ARG(unsigned index, unsigned scope)
-{
- Q_ASSERT(!isRemoved());
- ArgLocal *e = function->New<ArgLocal>();
- e->init(scope ? ArgLocal::ScopedFormal : ArgLocal::Formal, index, scope);
- return e;
-}
-
-inline ArgLocal *BasicBlock::LOCAL(unsigned index, unsigned scope)
-{
- Q_ASSERT(!isRemoved());
- ArgLocal *e = function->New<ArgLocal>();
- e->init(scope ? ArgLocal::ScopedLocal : ArgLocal::Local, index, scope);
- return e;
-}
-
-inline Expr *BasicBlock::CONST(Type type, double value)
-{
- Q_ASSERT(!isRemoved());
- Const *e = function->New<Const>();
- if (type == NumberType) {
- int ival = (int)value;
- // +0 != -0, so we need to convert to double when negating 0
- if (ival == value && !(value == 0 && isNegative(value)))
- type = SInt32Type;
- else
- type = DoubleType;
- } else if (type == NullType) {
- value = 0;
- } else if (type == UndefinedType) {
- value = qt_qnan();
- }
-
- e->init(type, value);
- return e;
-}
-
-inline Expr *BasicBlock::STRING(const QString *value)
-{
- Q_ASSERT(!isRemoved());
- String *e = function->New<String>();
- e->init(value);
- return e;
-}
-
-inline Expr *BasicBlock::REGEXP(const QString *value, int flags)
-{
- Q_ASSERT(!isRemoved());
- RegExp *e = function->New<RegExp>();
- e->init(value, flags);
- return e;
-}
-
-inline Name *BasicBlock::NAME(const QString &id, quint32 line, quint32 column)
-{
- Q_ASSERT(!isRemoved());
- Name *e = function->New<Name>();
- e->init(function->newString(id), line, column);
- return e;
-}
-
-inline Name *BasicBlock::GLOBALNAME(const QString &id, quint32 line, quint32 column, bool forceLookup)
-{
- Q_ASSERT(!isRemoved());
- Name *e = function->New<Name>();
- e->initGlobal(function->newString(id), line, column, forceLookup);
- return e;
-}
-
-
-inline Name *BasicBlock::NAME(Name::Builtin builtin, quint32 line, quint32 column)
-{
- Q_ASSERT(!isRemoved());
- Name *e = function->New<Name>();
- e->init(builtin, line, column);
- return e;
-}
-
-inline Closure *BasicBlock::CLOSURE(int functionInModule)
-{
- Q_ASSERT(!isRemoved());
- Closure *clos = function->New<Closure>();
- clos->init(functionInModule, function->module->functions.at(functionInModule)->name);
- return clos;
-}
-
-inline Expr *BasicBlock::CONVERT(Expr *expr, Type type)
-{
- Q_ASSERT(!isRemoved());
- Convert *e = function->New<Convert>();
- e->init(expr, type);
- return e;
-}
-
-inline Expr *BasicBlock::UNOP(AluOp op, Expr *expr)
-{
- Q_ASSERT(!isRemoved());
- Unop *e = function->New<Unop>();
- e->init(op, expr);
- return e;
-}
-
-inline Expr *BasicBlock::BINOP(AluOp op, Expr *left, Expr *right)
-{
- Q_ASSERT(!isRemoved());
- Binop *e = function->New<Binop>();
- e->init(op, left, right);
- return e;
-}
-
-inline Expr *BasicBlock::CALL(Expr *base, ExprList *args)
-{
- Q_ASSERT(!isRemoved());
- Call *e = function->New<Call>();
- e->init(base, args);
- int argc = 0;
- for (ExprList *it = args; it; it = it->next)
- ++argc;
- function->maxNumberOfArguments = qMax(function->maxNumberOfArguments, argc);
- return e;
-}
-
-inline Expr *BasicBlock::NEW(Expr *base, ExprList *args)
-{
- Q_ASSERT(!isRemoved());
- New *e = function->New<New>();
- e->init(base, args);
- return e;
-}
-
-inline Expr *BasicBlock::SUBSCRIPT(Expr *base, Expr *index)
-{
- Q_ASSERT(!isRemoved());
- Subscript *e = function->New<Subscript>();
- e->init(base, index);
- return e;
-}
-
-inline Expr *BasicBlock::MEMBER(Expr *base, const QString *name, QQmlPropertyData *property, uchar kind, int attachedPropertiesIdOrEnumValue)
-{
- Q_ASSERT(!isRemoved());
- Member*e = function->New<Member>();
- e->init(base, name, property, kind, attachedPropertiesIdOrEnumValue);
- return e;
-}
-
-inline Stmt *BasicBlock::EXP(Expr *expr)
-{
- Q_ASSERT(!isRemoved());
- if (isTerminated())
- return 0;
-
- Exp *s = function->NewStmt<Exp>();
- s->init(expr);
- appendStatement(s);
- return s;
-}
-
-inline Stmt *BasicBlock::MOVE(Expr *target, Expr *source)
-{
- Q_ASSERT(!isRemoved());
- if (isTerminated())
- return 0;
-
- Move *s = function->NewStmt<Move>();
- s->init(target, source);
- appendStatement(s);
- return s;
-}
-
-inline Stmt *BasicBlock::JUMP(BasicBlock *target)
-{
- Q_ASSERT(!isRemoved());
- if (isTerminated())
- return 0;
-
- Jump *s = function->NewStmt<Jump>();
- s->init(target);
- appendStatement(s);
-
- Q_ASSERT(! out.contains(target));
- out.append(target);
-
- Q_ASSERT(! target->in.contains(this));
- target->in.append(this);
-
- return s;
-}
-
-inline Stmt *BasicBlock::CJUMP(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse)
-{
- Q_ASSERT(!isRemoved());
- if (isTerminated())
- return 0;
-
- if (iftrue == iffalse) {
- MOVE(TEMP(newTemp()), cond);
- return JUMP(iftrue);
- }
-
- CJump *s = function->NewStmt<CJump>();
- s->init(cond, iftrue, iffalse, this);
- appendStatement(s);
-
- Q_ASSERT(! out.contains(iftrue));
- out.append(iftrue);
-
- Q_ASSERT(! iftrue->in.contains(this));
- iftrue->in.append(this);
-
- Q_ASSERT(! out.contains(iffalse));
- out.append(iffalse);
-
- Q_ASSERT(! iffalse->in.contains(this));
- iffalse->in.append(this);
-
- return s;
-}
-
-inline Stmt *BasicBlock::RET(Expr *expr)
-{
- Q_ASSERT(!isRemoved());
- if (isTerminated())
- return 0;
-
- Ret *s = function->NewStmt<Ret>();
- s->init(expr);
- appendStatement(s);
- return s;
-}
-
-inline Const *Expr::asConst() { return as<Const>(); }
-inline String *Expr::asString() { return as<String>(); }
-inline RegExp *Expr::asRegExp() { return as<RegExp>(); }
-inline Name *Expr::asName() { return as<Name>(); }
-inline Temp *Expr::asTemp() { return as<Temp>(); }
-inline ArgLocal *Expr::asArgLocal() { return as<ArgLocal>(); }
-inline Closure *Expr::asClosure() { return as<Closure>(); }
-inline Convert *Expr::asConvert() { return as<Convert>(); }
-inline Unop *Expr::asUnop() { return as<Unop>(); }
-inline Binop *Expr::asBinop() { return as<Binop>(); }
-inline Call *Expr::asCall() { return as<Call>(); }
-inline New *Expr::asNew() { return as<New>(); }
-inline Subscript *Expr::asSubscript() { return as<Subscript>(); }
-inline Member *Expr::asMember() { return as<Member>(); }
-
-inline Exp *Stmt::asExp() { return as<Exp>(); }
-inline Move *Stmt::asMove() { return as<Move>(); }
-inline Jump *Stmt::asJump() { return as<Jump>(); }
-inline CJump *Stmt::asCJump() { return as<CJump>(); }
-inline Ret *Stmt::asRet() { return as<Ret>(); }
-inline Phi *Stmt::asPhi() { return as<Phi>(); }
-
-} // end of namespace IR
-
-} // end of namespace QV4
-
-QT_END_NAMESPACE
-
-#if defined(QT_POP_CONST)
-# pragma pop_macro("CONST") // Restore peace
-# undef QT_POP_CONST
-#endif
-
-#endif // QV4IR_P_H
diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp
deleted file mode 100644
index 8cf5fac760..0000000000
--- a/src/qml/compiler/qv4ssa.cpp
+++ /dev/null
@@ -1,5848 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// When building with debug code, the macro below will enable debug helpers when using libc++.
-// For example, the std::vector<T>::operator[] will use _LIBCPP_ASSERT to check if the index is
-// within the array bounds. Note that this only works reliably with OSX 10.9 or later.
-//#define _LIBCPP_DEBUG2 2
-
-#include "qv4ssa_p.h"
-#include "qv4isel_util_p.h"
-#include "qv4util_p.h"
-
-#include <QtCore/QBuffer>
-#include <QtCore/QCoreApplication>
-#include <QtCore/QStringList>
-#include <QtCore/QSet>
-#include <QtCore/QLinkedList>
-#include <QtCore/QStack>
-#include <qv4runtime_p.h>
-#include <cmath>
-#include <iostream>
-#include <cassert>
-
-QT_USE_NAMESPACE
-
-using namespace QV4;
-using namespace IR;
-
-namespace {
-
-enum { DebugMoveMapping = 0 };
-
-#ifdef QT_NO_DEBUG
-enum { DoVerification = 0 };
-#else
-enum { DoVerification = 1 };
-#endif
-
-static void showMeTheCode(IR::Function *function, const char *marker)
-{
- static const bool showCode = qEnvironmentVariableIsSet("QV4_SHOW_IR");
- if (showCode) {
- qDebug() << marker;
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream stream(&buf);
- IRPrinter(&stream).print(function);
- stream << endl;
- qDebug("%s", buf.data().constData());
- }
-}
-
-class ProcessedBlocks
-{
- BitVector processed;
-
-public:
- ProcessedBlocks(IR::Function *function)
- : processed(function->basicBlockCount(), false)
- {}
-
- bool alreadyProcessed(BasicBlock *bb) const
- {
- Q_ASSERT(bb);
-
- return processed.at(bb->index());
- }
-
- void markAsProcessed(BasicBlock *bb)
- {
- processed.setBit(bb->index());
- }
-};
-
-class BasicBlockSet
-{
- typedef BitVector Flags;
-
- QVarLengthArray<int, 8> blockNumbers;
- Flags *blockFlags;
- IR::Function *function;
- enum { MaxVectorCapacity = 8 };
-
-public:
- class const_iterator
- {
- const BasicBlockSet &set;
- // ### These two members could go into a union, but clang won't compile (https://codereview.qt-project.org/#change,74259)
- QVarLengthArray<int, 8>::const_iterator numberIt;
- int flagIt;
-
- friend class BasicBlockSet;
- const_iterator(const BasicBlockSet &set, bool end)
- : set(set)
- {
- if (end || !set.function) {
- if (!set.blockFlags)
- numberIt = set.blockNumbers.end();
- else
- flagIt = set.blockFlags->size();
- } else {
- if (!set.blockFlags)
- numberIt = set.blockNumbers.begin();
- else
- findNextWithFlags(0);
- }
- }
-
- void findNextWithFlags(int start)
- {
- flagIt = set.blockFlags->findNext(start, true, /*wrapAround = */false);
- Q_ASSERT(flagIt <= set.blockFlags->size());
- }
-
- public:
- BasicBlock *operator*() const
- {
- if (!set.blockFlags) {
- return set.function->basicBlock(*numberIt);
- } else {
- Q_ASSERT(flagIt <= set.function->basicBlockCount());
- return set.function->basicBlock(flagIt);
- }
- }
-
- bool operator==(const const_iterator &other) const
- {
- if (&set != &other.set)
- return false;
- if (!set.blockFlags)
- return numberIt == other.numberIt;
- else
- return flagIt == other.flagIt;
- }
-
- bool operator!=(const const_iterator &other) const
- { return !(*this == other); }
-
- const_iterator &operator++()
- {
- if (!set.blockFlags)
- ++numberIt;
- else
- findNextWithFlags(flagIt + 1);
-
- return *this;
- }
- };
-
- friend class const_iterator;
-
-public:
- BasicBlockSet(IR::Function *f = 0): blockFlags(0), function(0)
- {
- if (f)
- init(f);
- }
-
-#ifdef Q_COMPILER_RVALUE_REFS
- BasicBlockSet(BasicBlockSet &&other): blockFlags(0)
- {
- std::swap(blockNumbers, other.blockNumbers);
- std::swap(blockFlags, other.blockFlags);
- std::swap(function, other.function);
- }
-#endif // Q_COMPILER_RVALUE_REFS
-
- BasicBlockSet(const BasicBlockSet &other)
- : blockFlags(0)
- , function(other.function)
- {
- if (other.blockFlags)
- blockFlags = new Flags(*other.blockFlags);
- blockNumbers = other.blockNumbers;
- }
-
- BasicBlockSet &operator=(const BasicBlockSet &other)
- {
- if (blockFlags) {
- delete blockFlags;
- blockFlags = 0;
- }
- function = other.function;
- if (other.blockFlags)
- blockFlags = new Flags(*other.blockFlags);
- blockNumbers = other.blockNumbers;
- return *this;
- }
-
- ~BasicBlockSet()
- {
- delete blockFlags;
- }
-
- void init(IR::Function *f)
- {
- Q_ASSERT(!function);
- Q_ASSERT(f);
- function = f;
- }
-
- bool empty() const
- {
- return begin() == end();
- }
-
- void insert(BasicBlock *bb)
- {
- Q_ASSERT(function);
-
- if (blockFlags) {
- blockFlags->setBit(bb->index());
- return;
- }
-
- for (int i = 0; i < blockNumbers.size(); ++i) {
- if (blockNumbers[i] == bb->index())
- return;
- }
-
- if (blockNumbers.size() == MaxVectorCapacity) {
- blockFlags = new Flags(function->basicBlockCount(), false);
- for (int i = 0; i < blockNumbers.size(); ++i) {
- blockFlags->setBit(blockNumbers[i]);
- }
- blockNumbers.clear();
- blockFlags->setBit(bb->index());
- } else {
- blockNumbers.append(bb->index());
- }
- }
-
- void remove(BasicBlock *bb)
- {
- Q_ASSERT(function);
-
- if (blockFlags) {
- blockFlags->clearBit(bb->index());
- return;
- }
-
- for (int i = 0; i < blockNumbers.size(); ++i) {
- if (blockNumbers[i] == bb->index()) {
- blockNumbers.remove(i);
- return;
- }
- }
- }
-
- const_iterator begin() const { return const_iterator(*this, false); }
- const_iterator end() const { return const_iterator(*this, true); }
-
- void collectValues(std::vector<BasicBlock *> &bbs) const
- {
- Q_ASSERT(function);
-
- for (const_iterator it = begin(), eit = end(); it != eit; ++it)
- bbs.push_back(*it);
- }
-
- bool contains(BasicBlock *bb) const
- {
- Q_ASSERT(function);
-
- if (blockFlags)
- return blockFlags->at(bb->index());
-
- for (int i = 0; i < blockNumbers.size(); ++i) {
- if (blockNumbers[i] == bb->index())
- return true;
- }
-
- return false;
- }
-};
-
-class DominatorTree
-{
- enum {
- DebugDominatorFrontiers = 0,
- DebugImmediateDominators = 0,
-
- DebugCodeCanUseLotsOfCpu = 0
- };
-
- typedef int BasicBlockIndex;
- enum { InvalidBasicBlockIndex = -1 };
-
- struct Data
- {
- int N;
- std::vector<int> dfnum; // BasicBlock index -> dfnum
- std::vector<int> vertex;
- std::vector<BasicBlockIndex> parent; // BasicBlock index -> parent BasicBlock index
- std::vector<BasicBlockIndex> ancestor; // BasicBlock index -> ancestor BasicBlock index
- std::vector<BasicBlockIndex> best; // BasicBlock index -> best BasicBlock index
- std::vector<BasicBlockIndex> semi; // BasicBlock index -> semi dominator BasicBlock index
- std::vector<BasicBlockIndex> samedom; // BasicBlock index -> same dominator BasicBlock index
-
- Data(): N(0) {}
- };
-
- IR::Function *function;
- QScopedPointer<Data> d;
- std::vector<BasicBlockIndex> idom; // BasicBlock index -> immediate dominator BasicBlock index
- std::vector<BasicBlockSet> DF; // BasicBlock index -> dominator frontier
-
- struct DFSTodo {
- BasicBlockIndex node, parent;
-
- DFSTodo()
- : node(InvalidBasicBlockIndex)
- , parent(InvalidBasicBlockIndex)
- {}
-
- DFSTodo(BasicBlockIndex node, BasicBlockIndex parent)
- : node(node)
- , parent(parent)
- {}
- };
-
- void DFS(BasicBlockIndex node) {
- std::vector<DFSTodo> worklist;
- worklist.reserve(d->vertex.capacity() / 2);
- DFSTodo todo(node, InvalidBasicBlockIndex);
-
- while (true) {
- BasicBlockIndex n = todo.node;
-
- if (d->dfnum[n] == 0) {
- d->dfnum[n] = d->N;
- d->vertex[d->N] = n;
- d->parent[n] = todo.parent;
- ++d->N;
- const BasicBlock::OutgoingEdges &out = function->basicBlock(n)->out;
- for (int i = out.size() - 1; i > 0; --i)
- worklist.push_back(DFSTodo(out[i]->index(), n));
-
- if (out.size() > 0) {
- todo.node = out.first()->index();
- todo.parent = n;
- continue;
- }
- }
-
- if (worklist.empty())
- break;
-
- todo = worklist.back();
- worklist.pop_back();
- }
- }
-
- BasicBlockIndex ancestorWithLowestSemi(BasicBlockIndex v, std::vector<BasicBlockIndex> &worklist) {
- worklist.clear();
- for (BasicBlockIndex it = v; it != InvalidBasicBlockIndex; it = d->ancestor[it])
- worklist.push_back(it);
-
- if (worklist.size() < 2)
- return d->best[v];
-
- BasicBlockIndex b = InvalidBasicBlockIndex;
- BasicBlockIndex last = worklist.back();
- Q_ASSERT(worklist.size() <= INT_MAX);
- for (int it = static_cast<int>(worklist.size()) - 2; it >= 0; --it) {
- BasicBlockIndex bbIt = worklist[it];
- d->ancestor[bbIt] = last;
- BasicBlockIndex &best_it = d->best[bbIt];
- if (b != InvalidBasicBlockIndex && d->dfnum[d->semi[b]] < d->dfnum[d->semi[best_it]])
- best_it = b;
- else
- b = best_it;
- }
- return b;
- }
-
- void link(BasicBlockIndex p, BasicBlockIndex n) {
- d->ancestor[n] = p;
- d->best[n] = n;
- }
-
- void calculateIDoms() {
- Q_ASSERT(function->basicBlock(0)->in.isEmpty());
-
- const int bbCount = function->basicBlockCount();
- d->vertex = std::vector<int>(bbCount, InvalidBasicBlockIndex);
- d->parent = std::vector<int>(bbCount, InvalidBasicBlockIndex);
- d->dfnum = std::vector<int>(size_t(bbCount), 0);
- d->semi = std::vector<BasicBlockIndex>(bbCount, InvalidBasicBlockIndex);
- d->ancestor = std::vector<BasicBlockIndex>(bbCount, InvalidBasicBlockIndex);
- idom = std::vector<BasicBlockIndex>(bbCount, InvalidBasicBlockIndex);
- d->samedom = std::vector<BasicBlockIndex>(bbCount, InvalidBasicBlockIndex);
- d->best = std::vector<BasicBlockIndex>(bbCount, InvalidBasicBlockIndex);
-
- QHash<BasicBlockIndex, std::vector<BasicBlockIndex> > bucket;
- bucket.reserve(bbCount);
-
- DFS(function->basicBlock(0)->index());
- Q_ASSERT(d->N == function->liveBasicBlocksCount());
-
- std::vector<BasicBlockIndex> worklist;
- worklist.reserve(d->vertex.capacity() / 2);
-
- for (int i = d->N - 1; i > 0; --i) {
- BasicBlockIndex n = d->vertex[i];
- BasicBlockIndex p = d->parent[n];
- BasicBlockIndex s = p;
-
- for (BasicBlock *v : function->basicBlock(n)->in) {
- BasicBlockIndex ss = InvalidBasicBlockIndex;
- if (d->dfnum[v->index()] <= d->dfnum[n])
- ss = v->index();
- else
- ss = d->semi[ancestorWithLowestSemi(v->index(), worklist)];
- if (d->dfnum[ss] < d->dfnum[s])
- s = ss;
- }
- d->semi[n] = s;
- bucket[s].push_back(n);
- link(p, n);
- if (bucket.contains(p)) {
- for (BasicBlockIndex v : bucket[p]) {
- BasicBlockIndex y = ancestorWithLowestSemi(v, worklist);
- BasicBlockIndex semi_v = d->semi[v];
- if (d->semi[y] == semi_v)
- idom[v] = semi_v;
- else
- d->samedom[v] = y;
- }
- bucket.remove(p);
- }
- }
-
- for (int i = 1; i < d->N; ++i) {
- BasicBlockIndex n = d->vertex[i];
- Q_ASSERT(n != InvalidBasicBlockIndex);
- Q_ASSERT(!bucket.contains(n));
- Q_ASSERT(d->ancestor[n] != InvalidBasicBlockIndex
- && ((d->semi[n] != InvalidBasicBlockIndex
- && d->dfnum[d->ancestor[n]] <= d->dfnum[d->semi[n]]) || d->semi[n] == n));
- BasicBlockIndex sdn = d->samedom[n];
- if (sdn != InvalidBasicBlockIndex)
- idom[n] = idom[sdn];
- }
-
- dumpImmediateDominators();
- }
-
- struct NodeProgress {
- std::vector<BasicBlockIndex> children;
- std::vector<BasicBlockIndex> todo;
- };
-
-public:
- DominatorTree(IR::Function *function)
- : function(function)
- , d(new Data)
- {
- calculateIDoms();
- d.reset();
- }
-
- void computeDF() {
- DF.resize(function->basicBlockCount());
-
- // compute children of each node in the dominator tree
- std::vector<std::vector<BasicBlockIndex> > children; // BasicBlock index -> children
- children.resize(function->basicBlockCount());
- for (BasicBlock *n : function->basicBlocks()) {
- if (n->isRemoved())
- continue;
- const BasicBlockIndex nodeIndex = n->index();
- Q_ASSERT(function->basicBlock(nodeIndex) == n);
- const BasicBlockIndex nodeDominator = idom[nodeIndex];
- if (nodeDominator == InvalidBasicBlockIndex)
- continue; // there is no dominator to add this node to as a child (e.g. the start node)
- children[nodeDominator].push_back(nodeIndex);
- }
-
- // Fill the worklist and initialize the node status for each basic-block
- std::vector<NodeProgress> nodeStatus;
- nodeStatus.resize(function->basicBlockCount());
- std::vector<BasicBlockIndex> worklist;
- worklist.reserve(function->basicBlockCount());
- for (BasicBlock *bb : function->basicBlocks()) {
- if (bb->isRemoved())
- continue;
- BasicBlockIndex nodeIndex = bb->index();
- worklist.push_back(nodeIndex);
- NodeProgress &np = nodeStatus[nodeIndex];
- np.children = children[nodeIndex];
- np.todo = children[nodeIndex];
- }
-
- BitVector DF_done(function->basicBlockCount(), false);
-
- while (!worklist.empty()) {
- BasicBlockIndex node = worklist.back();
-
- if (DF_done.at(node)) {
- worklist.pop_back();
- continue;
- }
-
- NodeProgress &np = nodeStatus[node];
- std::vector<BasicBlockIndex>::iterator it = np.todo.begin();
- while (it != np.todo.end()) {
- if (DF_done.at(*it)) {
- it = np.todo.erase(it);
- } else {
- worklist.push_back(*it);
- break;
- }
- }
-
- if (np.todo.empty()) {
- BasicBlockSet &S = DF[node];
- S.init(function);
- for (BasicBlock *y : function->basicBlock(node)->out)
- if (idom[y->index()] != node)
- S.insert(y);
- for (BasicBlockIndex child : np.children) {
- const BasicBlockSet &ws = DF[child];
- for (BasicBlockSet::const_iterator it = ws.begin(), eit = ws.end(); it != eit; ++it) {
- BasicBlock *w = *it;
- const BasicBlockIndex wIndex = w->index();
- if (node == wIndex || !dominates(node, w->index()))
- S.insert(w);
- }
- }
- DF_done.setBit(node);
- worklist.pop_back();
- }
- }
-
- if (DebugDominatorFrontiers) {
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream qout(&buf);
- qout << "Dominator Frontiers:" << endl;
- for (BasicBlock *n : function->basicBlocks()) {
- if (n->isRemoved())
- continue;
-
- qout << "\tDF[" << n->index() << "]: {";
- const BasicBlockSet &SList = DF[n->index()];
- for (BasicBlockSet::const_iterator i = SList.begin(), ei = SList.end(); i != ei; ++i) {
- if (i != SList.begin())
- qout << ", ";
- qout << (*i)->index();
- }
- qout << "}" << endl;
- }
- qDebug("%s", buf.data().constData());
- }
-
- if (DebugDominatorFrontiers && DebugCodeCanUseLotsOfCpu) {
- for (BasicBlock *n : function->basicBlocks()) {
- if (n->isRemoved())
- continue;
- const BasicBlockSet &fBlocks = DF[n->index()];
- for (BasicBlockSet::const_iterator it = fBlocks.begin(), eit = fBlocks.end(); it != eit; ++it) {
- BasicBlock *fBlock = *it;
- Q_ASSERT(!dominates(n, fBlock) || fBlock == n);
- bool hasDominatedSucc = false;
- for (BasicBlock *succ : fBlock->in) {
- if (dominates(n, succ)) {
- hasDominatedSucc = true;
- break;
- }
- }
- if (!hasDominatedSucc) {
- qDebug("%d in DF[%d] has no dominated predecessors", fBlock->index(), n->index());
- }
- Q_ASSERT(hasDominatedSucc);
- }
- }
- }
- }
-
- const BasicBlockSet &dominatorFrontier(BasicBlock *n) const {
- return DF[n->index()];
- }
-
- BasicBlock *immediateDominator(BasicBlock *bb) const {
- const BasicBlockIndex idx = idom[bb->index()];
- if (idx == -1)
- return 0;
- return function->basicBlock(idx);
- }
-
- void dumpImmediateDominators() const
- {
- if (DebugImmediateDominators) {
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream qout(&buf);
- qout << "Immediate dominators:" << endl;
- for (BasicBlock *to : function->basicBlocks()) {
- if (to->isRemoved())
- continue;
-
- qout << '\t';
- BasicBlockIndex from = idom.at(to->index());
- if (from != InvalidBasicBlockIndex)
- qout << from;
- else
- qout << "(none)";
- qout << " dominates " << to->index() << endl;
- }
- qDebug("%s", buf.data().constData());
- }
- }
-
- void setImmediateDominator(BasicBlock *bb, BasicBlock *newDominator)
- {
- Q_ASSERT(bb->index() >= 0);
- Q_ASSERT(!newDominator || newDominator->index() >= 0);
-
- if (static_cast<std::vector<BasicBlockIndex>::size_type>(bb->index()) >= idom.size()) {
- // This is a new block, probably introduced by edge splitting. So, we'll have to grow
- // the array before inserting the immediate dominator.
- idom.resize(function->basicBlockCount(), InvalidBasicBlockIndex);
- }
-
- const BasicBlockIndex newIdx = newDominator ? newDominator->index() : InvalidBasicBlockIndex;
- if (DebugImmediateDominators)
- qDebug() << "Setting idom of" << bb->index() << "from" << idom[bb->index()] << "to" << newIdx;
- idom[bb->index()] = newIdx;
- }
-
- void collectSiblings(BasicBlock *node, BasicBlockSet &siblings)
- {
- siblings.insert(node);
- const BasicBlockIndex dominator = idom[node->index()];
- if (dominator == InvalidBasicBlockIndex)
- return;
- for (size_t i = 0, ei = idom.size(); i != ei; ++i) {
- if (idom[i] == dominator) {
- BasicBlock *bb = function->basicBlock(int(i));
- if (!bb->isRemoved())
- siblings.insert(bb);
- }
- }
- }
-
- void recalculateIDoms(const BasicBlockSet &nodes, BasicBlock *limit = 0)
- {
- const BasicBlockIndex limitIndex = limit ? limit->index() : InvalidBasicBlockIndex;
- BasicBlockSet todo(nodes), postponed(function);
- while (!todo.empty())
- recalculateIDom(*todo.begin(), todo, postponed, limitIndex);
- }
-
- bool dominates(BasicBlock *dominator, BasicBlock *dominated) const {
- return dominates(dominator->index(), dominated->index());
- }
-
- struct Cmp {
- std::vector<int> *nodeDepths;
- Cmp(std::vector<int> *nodeDepths)
- : nodeDepths(nodeDepths)
- { Q_ASSERT(nodeDepths); }
- bool operator()(BasicBlock *one, BasicBlock *two) const
- {
- if (one->isRemoved())
- return false;
- if (two->isRemoved())
- return true;
- return nodeDepths->at(one->index()) > nodeDepths->at(two->index());
- }
- };
-
- // Calculate a depth-first iteration order on the nodes of the dominator tree.
- //
- // The order of the nodes in the vector is not the same as one where a recursive depth-first
- // iteration is done on a tree. Rather, the nodes are (reverse) sorted on tree depth.
- // So for the:
- // 1 dominates 2
- // 2 dominates 3
- // 3 dominates 4
- // 2 dominates 5
- // the order will be:
- // 4, 3, 5, 2, 1
- // or:
- // 4, 5, 3, 2, 1
- // So the order of nodes on the same depth is undefined, but it will be after the nodes
- // they dominate, and before the nodes that dominate them.
- //
- // The reason for this order is that a proper DFS pre-/post-order would require inverting
- // the idom vector by either building a real tree datastructure or by searching the idoms
- // for siblings and children. Both have a higher time complexity than sorting by depth.
- QVector<BasicBlock *> calculateDFNodeIterOrder() const
- {
- std::vector<int> depths = calculateNodeDepths();
- QVector<BasicBlock *> order = function->basicBlocks();
- std::sort(order.begin(), order.end(), Cmp(&depths));
- for (int i = 0; i < order.size(); ) {
- if (order[i]->isRemoved())
- order.remove(i);
- else
- ++i;
- }
- return order;
- }
-
- void mergeIntoPredecessor(BasicBlock *successor)
- {
- int succIdx = successor->index();
- if (succIdx == InvalidBasicBlockIndex) {
- return;
- }
-
- int succDom = idom[unsigned(succIdx)];
- for (BasicBlockIndex &idx : idom) {
- if (idx == succIdx) {
- idx = succDom;
- }
- }
- }
-
-private:
- bool dominates(BasicBlockIndex dominator, BasicBlockIndex dominated) const {
- // dominator can be Invalid when the dominated block has no dominator (i.e. the start node)
- Q_ASSERT(dominated != InvalidBasicBlockIndex);
-
- if (dominator == dominated)
- return false;
-
- for (BasicBlockIndex it = idom[dominated]; it != InvalidBasicBlockIndex; it = idom[it]) {
- if (it == dominator)
- return true;
- }
-
- return false;
- }
-
- // Algorithm:
- // - for each node:
- // - get the depth of a node. If it's unknown (-1):
- // - get the depth of the immediate dominator.
- // - if that's unknown too, calculate it by calling calculateNodeDepth
- // - set the current node's depth to that of immediate dominator + 1
- std::vector<int> calculateNodeDepths() const
- {
- std::vector<int> nodeDepths(size_t(function->basicBlockCount()), -1);
- nodeDepths[0] = 0;
- for (BasicBlock *bb : function->basicBlocks()) {
- if (bb->isRemoved())
- continue;
-
- int &bbDepth = nodeDepths[bb->index()];
- if (bbDepth == -1) {
- const int immDom = idom[bb->index()];
- int immDomDepth = nodeDepths[immDom];
- if (immDomDepth == -1)
- immDomDepth = calculateNodeDepth(immDom, nodeDepths);
- bbDepth = immDomDepth + 1;
- }
- }
- return nodeDepths;
- }
-
- // Algorithm:
- // - search for the first dominator of a node that has a known depth. As all nodes are
- // reachable from the start node, and that node's depth is 0, this is finite.
- // - while doing that search, put all unknown nodes in the worklist
- // - pop all nodes from the worklist, and set their depth to the previous' (== dominating)
- // node's depth + 1
- // This way every node's depth is calculated once, and the complexity is O(n).
- int calculateNodeDepth(int nodeIdx, std::vector<int> &nodeDepths) const
- {
- std::vector<int> worklist;
- worklist.reserve(8);
- int depth = -1;
-
- do {
- worklist.push_back(nodeIdx);
- nodeIdx = idom[nodeIdx];
- depth = nodeDepths[nodeIdx];
- } while (depth == -1);
-
- for (std::vector<int>::const_reverse_iterator it = worklist.rbegin(), eit = worklist.rend(); it != eit; ++it)
- nodeDepths[*it] = ++depth;
-
- return depth;
- }
-
- // The immediate-dominator recalculation is used when edges are removed from the CFG. See
- // [Ramalingam] for a description. Note that instead of calculating the priority, a recursive
- // algorithm is used: when recalculating the immediate dominator of a node by looking for the
- // least-common ancestor, and a node is hit that also needs recalculation, a recursive call
- // is done to calculate that nodes immediate dominator first.
- //
- // Note that this simplified algorithm cannot cope with back-edges. It only works for
- // non-looping edges (which is our use-case).
- void recalculateIDom(BasicBlock *node, BasicBlockSet &todo, BasicBlockSet &postponed, BasicBlockIndex limit) {
- Q_ASSERT(!postponed.contains(node));
- Q_ASSERT(todo.contains(node));
- todo.remove(node);
-
- if (node->in.size() == 1) {
- // Special case: if the node has only one incoming edge, then that is the immediate
- // dominator.
- setImmediateDominator(node, node->in.first());
- return;
- }
-
- std::vector<BasicBlockIndex> prefix;
- prefix.reserve(32);
-
- for (BasicBlock *in : node->in) {
- if (node == in) // back-edge to self
- continue;
- if (dominates(node->index(), in->index())) // a known back-edge
- continue;
-
- if (prefix.empty()) {
- calculatePrefix(node, in, prefix, todo, postponed, limit);
-
- if (!prefix.empty()) {
- std::reverse(prefix.begin(), prefix.end());
- Q_ASSERT(!prefix.empty());
- Q_ASSERT(prefix.front() == limit || limit == InvalidBasicBlockIndex);
- }
- } else {
- std::vector<BasicBlockIndex> anotherPrefix;
- anotherPrefix.reserve(prefix.size());
- calculatePrefix(node, in, anotherPrefix, todo, postponed, limit);
-
- if (!anotherPrefix.empty())
- commonPrefix(prefix, anotherPrefix);
- }
- }
-
- Q_ASSERT(!prefix.empty());
- idom[node->index()] = prefix.back();
- }
-
- void calculatePrefix(BasicBlock *node, BasicBlock *in, std::vector<BasicBlockIndex> &prefix, BasicBlockSet &todo, BasicBlockSet &postponed, BasicBlockIndex limit)
- {
- for (BasicBlockIndex it = in->index(); it != InvalidBasicBlockIndex; it = idom[it]) {
- prefix.push_back(it);
- if (it == limit)
- return;
- BasicBlock *n = function->basicBlock(it);
- if (postponed.contains(n)) { // possible back-edge, bail out.
- prefix.clear();
- return;
- }
- if (todo.contains(n)) {
- postponed.insert(node);
- recalculateIDom(n, todo, postponed, limit);
- postponed.remove(node);
- }
- }
- }
-
- // Calculate the LCA (Least Common Ancestor) by finding the longest common prefix between two
- // dominator chains. Note that "anotherPrefix" has the node's immediate dominator first, while
- // "bestPrefix" has it last (meaning: is in reverse order). The reason for this is that removing
- // nodes from "bestPrefix" is cheaper because it's done at the end of the vector, while
- // reversing all "anotherPrefix" nodes would take unnecessary time.
- static void commonPrefix(std::vector<BasicBlockIndex> &bestPrefix, const std::vector<BasicBlockIndex> &anotherPrefix)
- {
- const size_t anotherSize = anotherPrefix.size();
- size_t minLen = qMin(bestPrefix.size(), anotherPrefix.size());
- while (minLen != 0) {
- --minLen;
- if (bestPrefix[minLen] == anotherPrefix[anotherSize - minLen - 1]) {
- ++minLen;
- break;
- }
- }
- if (minLen != bestPrefix.size())
- bestPrefix.erase(bestPrefix.begin() + minLen, bestPrefix.end());
- }
-};
-
-class VariableCollector {
- std::vector<Temp> _allTemps;
- std::vector<BasicBlockSet> _defsites;
- std::vector<std::vector<int> > A_orig;
- BitVector nonLocals;
- BitVector killed;
-
- BasicBlock *currentBB;
- bool isCollectable(Temp *t) const
- {
- Q_UNUSED(t);
- Q_ASSERT(t->kind != Temp::PhysicalRegister && t->kind != Temp::StackSlot);
- return true;
- }
-
- void addDefInCurrentBlock(Temp *t)
- {
- std::vector<int> &temps = A_orig[currentBB->index()];
- if (std::find(temps.begin(), temps.end(), t->index) == temps.end())
- temps.push_back(t->index);
- }
-
- void addTemp(Temp *t)
- {
- if (_allTemps[t->index].kind == Temp::Invalid)
- _allTemps[t->index] = *t;
- }
-
-public:
- VariableCollector(IR::Function *function)
- {
- _allTemps.resize(function->tempCount);
- _defsites.resize(function->tempCount);
- for (int i = 0; i < function->tempCount; ++i)
- _defsites[i].init(function);
- nonLocals.resize(function->tempCount);
- const size_t ei = function->basicBlockCount();
- A_orig.resize(ei);
- for (size_t i = 0; i != ei; ++i)
- A_orig[i].reserve(8);
-
- for (BasicBlock *bb : function->basicBlocks()) {
- if (bb->isRemoved())
- continue;
-
- currentBB = bb;
- killed.assign(function->tempCount, false);
- for (Stmt *s : bb->statements())
- visit(s);
- }
- }
-
- const std::vector<Temp> &allTemps() const
- { return _allTemps; }
-
- void collectDefSites(const Temp &n, std::vector<BasicBlock *> &bbs) const {
- Q_ASSERT(!n.isInvalid());
- Q_ASSERT(n.index < _defsites.size());
- _defsites[n.index].collectValues(bbs);
- }
-
- const std::vector<int> &inBlock(BasicBlock *n) const
- {
- return A_orig.at(n->index());
- }
-
- bool isNonLocal(const Temp &var) const
- {
- Q_ASSERT(!var.isInvalid());
- Q_ASSERT(static_cast<int>(var.index) < nonLocals.size());
- return nonLocals.at(var.index);
- }
-
-private:
- void visit(Stmt *s)
- {
- if (s->asPhi()) {
- // nothing to do
- } else if (auto move = s->asMove()) {
- visit(move->source);
-
- if (Temp *t = move->target->asTemp()) {
- addTemp(t);
-
- if (isCollectable(t)) {
- _defsites[t->index].insert(currentBB);
- addDefInCurrentBlock(t);
-
- // For semi-pruned SSA:
- killed.setBit(t->index);
- }
- } else {
- visit(move->target);
- }
- } else {
- STMT_VISIT_ALL_KINDS(s)
- }
- }
-
- void visit(Expr *e)
- {
- if (auto t = e->asTemp()) {
- addTemp(t);
-
- if (isCollectable(t)) {
- if (!killed.at(t->index)) {
- nonLocals.setBit(t->index);
- }
- }
- } else {
- EXPR_VISIT_ALL_KINDS(e);
- }
- }
-};
-
-struct UntypedTemp {
- Temp temp;
- UntypedTemp() {}
- UntypedTemp(const Temp &t): temp(t) {}
-};
-inline bool operator==(const UntypedTemp &t1, const UntypedTemp &t2) Q_DECL_NOTHROW
-{ return t1.temp.index == t2.temp.index && t1.temp.kind == t2.temp.kind; }
-inline bool operator!=(const UntypedTemp &t1, const UntypedTemp &t2) Q_DECL_NOTHROW
-{ return !(t1 == t2); }
-
-class DefUses
-{
-public:
- struct DefUse {
- DefUse()
- : defStmt(0)
- , blockOfStatement(0)
- { uses.reserve(8); }
- Temp temp;
- Stmt *defStmt;
- BasicBlock *blockOfStatement;
- QVector<Stmt *> uses;
-
- bool isValid() const
- { return temp.kind != Temp::Invalid; }
-
- void clear()
- { defStmt = 0; blockOfStatement = 0; uses.clear(); }
- };
-
-private:
- std::vector<DefUse> _defUses;
- typedef QVarLengthArray<Temp, 4> Temps;
- std::vector<Temps> _usesPerStatement;
-
- void ensure(Temp *newTemp)
- {
- if (_defUses.size() <= newTemp->index) {
- _defUses.resize(newTemp->index + 1);
- }
- }
-
- void ensure(Stmt *s)
- {
- Q_ASSERT(s->id() >= 0);
- if (static_cast<unsigned>(s->id()) >= _usesPerStatement.size()) {
- _usesPerStatement.resize(s->id() + 1);
- }
- }
-
- void addUseForStatement(Stmt *s, const Temp &var)
- {
- ensure(s);
- _usesPerStatement[s->id()].push_back(var);
- }
-
-public:
- DefUses(IR::Function *function)
- {
- _usesPerStatement.resize(function->statementCount());
- _defUses.resize(function->tempCount);
- }
-
- void cleanup()
- {
- for (size_t i = 0, ei = _defUses.size(); i != ei; ++i) {
- DefUse &defUse = _defUses[i];
- if (defUse.isValid() && !defUse.defStmt)
- defUse.clear();
- }
- }
-
- unsigned statementCount() const
- { return unsigned(_usesPerStatement.size()); }
-
- unsigned tempCount() const
- { return unsigned(_defUses.size()); }
-
- const Temp &temp(int idx) const
- { return _defUses[idx].temp; }
-
- void addDef(Temp *newTemp, Stmt *defStmt, BasicBlock *defBlock)
- {
- ensure(newTemp);
- DefUse &defUse = _defUses[newTemp->index];
- Q_ASSERT(!defUse.isValid());
- defUse.temp = *newTemp;
- defUse.defStmt = defStmt;
- defUse.blockOfStatement = defBlock;
- }
-
- QVector<UntypedTemp> defsUntyped() const
- {
- QVector<UntypedTemp> res;
- res.reserve(tempCount());
- for (const DefUse &du : _defUses)
- if (du.isValid())
- res.append(UntypedTemp(du.temp));
- return res;
- }
-
- std::vector<const Temp *> defs() const {
- std::vector<const Temp *> res;
- const size_t ei = _defUses.size();
- res.reserve(ei);
- for (size_t i = 0; i != ei; ++i) {
- const DefUse &du = _defUses.at(i);
- if (du.isValid())
- res.push_back(&du.temp);
- }
- return res;
- }
-
- void removeDef(const Temp &variable) {
- Q_ASSERT(static_cast<unsigned>(variable.index) < _defUses.size());
- _defUses[variable.index].clear();
- }
-
- void addUses(const Temp &variable, const QVector<Stmt *> &newUses)
- {
- Q_ASSERT(static_cast<unsigned>(variable.index) < _defUses.size());
- QVector<Stmt *> &uses = _defUses[variable.index].uses;
- for (Stmt *stmt : newUses)
- if (std::find(uses.begin(), uses.end(), stmt) == uses.end())
- uses.push_back(stmt);
- }
-
- void addUse(const Temp &variable, Stmt *newUse)
- {
- if (_defUses.size() <= variable.index) {
- _defUses.resize(variable.index + 1);
- DefUse &du = _defUses[variable.index];
- du.temp = variable;
- du.uses.push_back(newUse);
- addUseForStatement(newUse, variable);
- return;
- }
-
- QVector<Stmt *> &uses = _defUses[variable.index].uses;
- if (std::find(uses.begin(), uses.end(), newUse) == uses.end())
- uses.push_back(newUse);
- addUseForStatement(newUse, variable);
- }
-
- int useCount(const Temp &variable) const
- {
- Q_ASSERT(static_cast<unsigned>(variable.index) < _defUses.size());
- return _defUses[variable.index].uses.size();
- }
-
- Stmt *defStmt(const Temp &variable) const
- {
- Q_ASSERT(static_cast<unsigned>(variable.index) < _defUses.size());
- return _defUses[variable.index].defStmt;
- }
-
- BasicBlock *defStmtBlock(const Temp &variable) const
- {
- Q_ASSERT(static_cast<unsigned>(variable.index) < _defUses.size());
- return _defUses[variable.index].blockOfStatement;
- }
-
- void replaceBasicBlock(BasicBlock *from, BasicBlock *to)
- {
- for (auto &du : _defUses) {
- if (du.blockOfStatement == from) {
- du.blockOfStatement = to;
- }
- }
- }
-
- void removeUse(Stmt *usingStmt, const Temp &var)
- {
- Q_ASSERT(static_cast<unsigned>(var.index) < _defUses.size());
- QVector<Stmt *> &uses = _defUses[var.index].uses;
- uses.erase(std::remove(uses.begin(), uses.end(), usingStmt), uses.end());
- }
-
- void registerNewStatement(Stmt *s)
- {
- ensure(s);
- }
-
- const Temps &usedVars(Stmt *s) const
- {
- Q_ASSERT(s->id() >= 0);
- Q_ASSERT(static_cast<unsigned>(s->id()) < _usesPerStatement.size());
- return _usesPerStatement[s->id()];
- }
-
- const QVector<Stmt *> &uses(const Temp &var) const
- {
- return _defUses[var.index].uses;
- }
-
- QVector<Stmt*> removeDefUses(Stmt *s)
- {
- QVector<Stmt*> defStmts;
- for (const Temp &usedVar : usedVars(s)) {
- if (Stmt *ds = defStmt(usedVar))
- defStmts += ds;
- removeUse(s, usedVar);
- }
- if (Move *m = s->asMove()) {
- if (Temp *t = m->target->asTemp())
- removeDef(*t);
- } else if (Phi *p = s->asPhi()) {
- removeDef(*p->targetTemp);
- }
-
- return defStmts;
- }
-
- void dump() const
- {
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream qout(&buf);
- qout << "Defines and uses:" << endl;
- for (const DefUse &du : _defUses) {
- if (!du.isValid())
- continue;
- qout << '%' << du.temp.index;
- qout << " -> defined in block " << du.blockOfStatement->index()
- << ", statement: " << du.defStmt->id()
- << endl;
- qout << " uses:";
- for (Stmt *s : du.uses)
- qout << ' ' << s->id();
- qout << endl;
- }
- qout << "Uses per statement:" << endl;
- for (size_t i = 0, ei = _usesPerStatement.size(); i != ei; ++i) {
- qout << " " << i << ":";
- for (const Temp &t : _usesPerStatement[i])
- qout << ' ' << t.index;
- qout << endl;
- }
- qDebug("%s", buf.data().constData());
- }
-};
-
-void insertPhiNode(const Temp &a, BasicBlock *y, IR::Function *f) {
- Phi *phiNode = f->NewStmt<Phi>();
- phiNode->targetTemp = f->New<Temp>();
- phiNode->targetTemp->init(a.kind, a.index);
- y->prependStatement(phiNode);
-
- phiNode->incoming.resize(y->in.size());
- for (int i = 0, ei = y->in.size(); i < ei; ++i) {
- Temp *t = f->New<Temp>();
- t->init(a.kind, a.index);
- phiNode->incoming[i] = t;
- }
-}
-
-// High-level (recursive) algorithm:
-// Mapping: old temp number -> new temp number
-//
-// Start:
-// Rename(start-node)
-//
-// Rename(node, mapping):
-// for each statement S in block n
-// if S not in a phi-function
-// for each use of some variable x in S
-// y = mapping[x]
-// replace the use of x with y in S
-// for each definition of some variable a in S [1]
-// a_new = generate new/unique temp
-// mapping[a] = a_new
-// replace definition of a with definition of a_new in S
-// for each successor Y of block n
-// Suppose n is the j-th predecessor of Y
-// for each phi function in Y
-// suppose the j-th operand of the phi-function is a
-// i = mapping[a]
-// replace the j-th operand with a_i
-// for each child X of n [2]
-// Rename(X)
-// for each newly generated temp from step [1] restore the old value [3]
-//
-// This algorithm can run out of CPU stack space when there are lots of basic-blocks, like in a
-// switch statement with 8000 cases that all fall-through. The iterativer version below uses a
-// work-item stack, where step [1] from the algorithm above also pushes an "undo mapping change",
-// and step [2] pushes a "rename(X)" action. This eliminates step [3].
-//
-// Iterative version:
-// Mapping: old temp number -> new temp number
-//
-// The stack can hold two kinds of actions:
-// "Rename basic block n"
-// "Restore count for temp"
-//
-// Start:
-// counter = 0
-// push "Rename start node" onto the stack
-// while the stack is not empty:
-// take the last item, and process it
-//
-// Rename(n) =
-// for each statement S in block n
-// if S not in a phi-function
-// for each use of some variable x in S
-// y = mapping[x]
-// replace the use of x with y in S
-// for each definition of some variable a in S
-// old = mapping[a]
-// push Undo(a, old)
-// counter = counter + 1
-// new = counter;
-// mapping[a] = new
-// replace definition of a with definition of a_new in S
-// for each successor Y of block n
-// Suppose n is the j-th predecessor of Y
-// for each phi function in Y
-// suppose the j-th operand of the phi-function is a
-// i = mapping[a]
-// replace the j-th operand with a_i
-// for each child X of n
-// push Rename(X)
-//
-// Undo(t, c) =
-// mapping[t] = c
-class VariableRenamer
-{
- Q_DISABLE_COPY(VariableRenamer)
-
- IR::Function *function;
- DefUses &defUses;
- unsigned tempCount;
-
- typedef std::vector<int> Mapping; // maps from existing/old temp number to the new and unique temp number.
- enum { Absent = -1 };
- Mapping vregMapping;
- ProcessedBlocks processed;
-
- BasicBlock *currentBB;
- Stmt *currentStmt;
-
- struct TodoAction {
- enum { RestoreVReg, Rename } action;
- union {
- struct {
- unsigned temp;
- int previous;
- } restoreData;
- struct {
- BasicBlock *basicBlock;
- } renameData;
- };
-
- bool isValid() const { return action != Rename || renameData.basicBlock != 0; }
-
- TodoAction()
- {
- action = Rename;
- renameData.basicBlock = 0;
- }
-
- TodoAction(const Temp &t, int prev)
- {
- Q_ASSERT(t.kind == Temp::VirtualRegister);
-
- action = RestoreVReg;
- restoreData.temp = t.index;
- restoreData.previous = prev;
- }
-
- TodoAction(BasicBlock *bb)
- {
- Q_ASSERT(bb);
-
- action = Rename;
- renameData.basicBlock = bb;
- }
- };
-
- QVector<TodoAction> todo;
-
-public:
- VariableRenamer(IR::Function *f, DefUses &defUses)
- : function(f)
- , defUses(defUses)
- , tempCount(0)
- , processed(f)
- {
- vregMapping.assign(f->tempCount, Absent);
- todo.reserve(f->basicBlockCount());
- }
-
- void run() {
- todo.append(TodoAction(function->basicBlock(0)));
-
- while (!todo.isEmpty()) {
- TodoAction todoAction = todo.back();
- Q_ASSERT(todoAction.isValid());
- todo.pop_back();
-
- switch (todoAction.action) {
- case TodoAction::Rename:
- rename(todoAction.renameData.basicBlock);
- break;
- case TodoAction::RestoreVReg:
- restore(vregMapping, todoAction.restoreData.temp, todoAction.restoreData.previous);
- break;
- default:
- Q_UNREACHABLE();
- }
- }
-
- function->tempCount = tempCount;
- }
-
-private:
- static inline void restore(Mapping &mapping, int temp, int previous)
- {
- mapping[temp] = previous;
- }
-
- void rename(BasicBlock *bb)
- {
- while (bb && !processed.alreadyProcessed(bb)) {
- renameStatementsAndPhis(bb);
- processed.markAsProcessed(bb);
-
- BasicBlock *next = 0;
- for (BasicBlock *out : bb->out) {
- if (processed.alreadyProcessed(out))
- continue;
- if (!next)
- next = out;
- else
- todo.append(TodoAction(out));
- }
- bb = next;
- }
- }
-
- void renameStatementsAndPhis(BasicBlock *bb)
- {
- currentBB = bb;
-
- for (Stmt *s : bb->statements()) {
- currentStmt = s;
- visit(s);
- }
-
- for (BasicBlock *Y : bb->out) {
- const int j = Y->in.indexOf(bb);
- Q_ASSERT(j >= 0 && j < Y->in.size());
- for (Stmt *s : Y->statements()) {
- if (Phi *phi = s->asPhi()) {
- Temp *t = phi->incoming[j]->asTemp();
- unsigned newTmp = currentNumber(*t);
-// qDebug()<<"I: replacing phi use"<<a<<"with"<<newTmp<<"in L"<<Y->index;
- t->index = newTmp;
- t->kind = Temp::VirtualRegister;
- defUses.addUse(*t, phi);
- } else {
- break;
- }
- }
- }
- }
-
- unsigned currentNumber(const Temp &t)
- {
- int nr = Absent;
- switch (t.kind) {
- case Temp::VirtualRegister:
- nr = vregMapping[t.index];
- break;
- default:
- Q_UNREACHABLE();
- nr = Absent;
- break;
- }
- if (nr == Absent) {
- // Special case: we didn't prune the Phi nodes yet, so for proper temps (virtual
- // registers) the SSA algorithm might insert superfluous Phis that have uses without
- // definition. E.g.: if a temporary got introduced in the "then" clause, it "could"
- // reach the "end-if" block, so there will be a phi node for that temp. A later pass
- // will clean this up by looking for uses-without-defines in phi nodes. So, what we do
- // is to generate a new unique number, and leave it dangling.
- nr = nextFreeTemp(t);
- }
-
- return nr;
- }
-
- unsigned nextFreeTemp(const Temp &t)
- {
- unsigned newIndex = tempCount++;
- Q_ASSERT(newIndex <= INT_MAX);
- int oldIndex = Absent;
-
- switch (t.kind) {
- case Temp::VirtualRegister:
- oldIndex = vregMapping[t.index];
- vregMapping[t.index] = newIndex;
- break;
- default:
- Q_UNREACHABLE();
- }
-
- todo.append(TodoAction(t, oldIndex));
-
- return newIndex;
- }
-
-private:
- void visit(Stmt *s)
- {
- if (auto move = s->asMove()) {
- // uses:
- visit(move->source);
-
- // defs:
- if (Temp *t = move->target->asTemp()) {
- renameTemp(t);
- } else {
- visit(move->target);
- }
- } else if (auto phi = s->asPhi()) {
- renameTemp(phi->targetTemp);
- } else {
- STMT_VISIT_ALL_KINDS(s);
- }
- }
-
- void visit(Expr *e)
- {
- if (auto temp = e->asTemp()) {
- temp->index = currentNumber(*temp);
- temp->kind = Temp::VirtualRegister;
- defUses.addUse(*temp, currentStmt);
- } else {
- EXPR_VISIT_ALL_KINDS(e);
- }
- }
-
- void renameTemp(Temp *t) { // only called for defs, not uses
- const int newIdx = nextFreeTemp(*t);
-// qDebug()<<"I: replacing def of"<<a<<"with"<<newIdx;
- t->kind = Temp::VirtualRegister;
- t->index = newIdx;
- defUses.addDef(t, currentStmt, currentBB);
- }
-};
-
-// This function converts the IR to semi-pruned SSA form. For details about SSA and the algorightm,
-// see [Appel]. For the changes needed for semi-pruned SSA form, and for its advantages, see [Briggs].
-void convertToSSA(IR::Function *function, const DominatorTree &df, DefUses &defUses)
-{
- // Collect all applicable variables:
- VariableCollector variables(function);
-
- // Prepare for phi node insertion:
- std::vector<BitVector > A_phi;
- const size_t ei = function->basicBlockCount();
- A_phi.resize(ei);
- for (size_t i = 0; i != ei; ++i)
- A_phi[i].assign(function->tempCount, false);
-
- std::vector<BasicBlock *> W;
- W.reserve(8);
-
- // Place phi functions:
- for (const Temp &a : variables.allTemps()) {
- if (a.isInvalid())
- continue;
- if (!variables.isNonLocal(a))
- continue; // for semi-pruned SSA
-
- W.clear();
- variables.collectDefSites(a, W);
- while (!W.empty()) {
- BasicBlock *n = W.back();
- W.pop_back();
- const BasicBlockSet &dominatorFrontierForN = df.dominatorFrontier(n);
- for (BasicBlockSet::const_iterator it = dominatorFrontierForN.begin(), eit = dominatorFrontierForN.end();
- it != eit; ++it) {
- BasicBlock *y = *it;
- if (!A_phi.at(y->index()).at(a.index)) {
- insertPhiNode(a, y, function);
- A_phi[y->index()].setBit(a.index);
- const std::vector<int> &varsInBlockY = variables.inBlock(y);
- if (std::find(varsInBlockY.begin(), varsInBlockY.end(), a.index) == varsInBlockY.end())
- W.push_back(y);
- }
- }
- }
- }
-
- // Rename variables:
- VariableRenamer(function, defUses).run();
-}
-
-/// Calculate if a phi node result is used only by other phi nodes, and if those uses are
-/// in turn also used by other phi nodes.
-bool hasPhiOnlyUses(Phi *phi, const DefUses &defUses, QBitArray &collectedPhis)
-{
- collectedPhis.setBit(phi->id());
-
- for (Stmt *use : defUses.uses(*phi->targetTemp)) {
- Phi *dependentPhi = use->asPhi();
- if (!dependentPhi)
- return false; // there is a use by a non-phi node
-
- if (collectedPhis.at(dependentPhi->id()))
- continue; // we already found this node
-
- if (!hasPhiOnlyUses(dependentPhi, defUses, collectedPhis))
- return false;
- }
-
- return true;
-}
-
-void cleanupPhis(DefUses &defUses)
-{
- QBitArray toRemove(defUses.statementCount());
- QBitArray collectedPhis(defUses.statementCount());
- std::vector<Phi *> allPhis;
- allPhis.reserve(32);
-
- for (const Temp *def : defUses.defs()) {
- Stmt *defStmt = defUses.defStmt(*def);
- if (!defStmt)
- continue;
-
- Phi *phi = defStmt->asPhi();
- if (!phi)
- continue;
- allPhis.push_back(phi);
- if (toRemove.at(phi->id()))
- continue;
-
- collectedPhis.fill(false);
- if (hasPhiOnlyUses(phi, defUses, collectedPhis))
- toRemove |= collectedPhis;
- }
-
- for (Phi *phi : allPhis) {
- if (!toRemove.at(phi->id()))
- continue;
-
- const Temp &targetVar = *phi->targetTemp;
- defUses.defStmtBlock(targetVar)->removeStatement(phi);
-
- for (const Temp &usedVar : defUses.usedVars(phi))
- defUses.removeUse(phi, usedVar);
- defUses.removeDef(targetVar);
- }
-
- defUses.cleanup();
-}
-
-class StatementWorklist
-{
- IR::Function *theFunction;
- std::vector<Stmt *> stmts;
- BitVector worklist;
- unsigned worklistSize;
- std::vector<int> replaced;
- BitVector removed;
-
- Q_DISABLE_COPY(StatementWorklist)
-
-public:
- StatementWorklist(IR::Function *function)
- : theFunction(function)
- , stmts(function->statementCount(), static_cast<Stmt *>(0))
- , worklist(function->statementCount(), false)
- , worklistSize(0)
- , replaced(function->statementCount(), Stmt::InvalidId)
- , removed(function->statementCount())
- {
- grow();
-
- for (BasicBlock *bb : function->basicBlocks()) {
- if (bb->isRemoved())
- continue;
-
- for (Stmt *s : bb->statements()) {
- if (!s)
- continue;
-
- stmts[s->id()] = s;
- worklist.setBit(s->id());
- ++worklistSize;
- }
- }
- }
-
- void reset()
- {
- worklist.assign(worklist.size(), false);
- worklistSize = 0;
-
- for (Stmt *s : stmts) {
- if (!s)
- continue;
-
- worklist.setBit(s->id());
- ++worklistSize;
- }
-
- replaced.assign(replaced.size(), Stmt::InvalidId);
- removed.assign(removed.size(), false);
- }
-
- void remove(Stmt *stmt)
- {
- replaced[stmt->id()] = Stmt::InvalidId;
- removed.setBit(stmt->id());
- if (worklist.at(stmt->id())) {
- worklist.clearBit(stmt->id());
- Q_ASSERT(worklistSize > 0);
- --worklistSize;
- }
- }
-
- void replace(Stmt *oldStmt, Stmt *newStmt)
- {
- Q_ASSERT(oldStmt);
- Q_ASSERT(replaced[oldStmt->id()] == Stmt::InvalidId);
- Q_ASSERT(removed.at(oldStmt->id()) == false);
-
- Q_ASSERT(newStmt);
- registerNewStatement(newStmt);
- Q_ASSERT(replaced[newStmt->id()] == Stmt::InvalidId);
- Q_ASSERT(removed.at(newStmt->id()) == false);
-
- replaced[oldStmt->id()] = newStmt->id();
- worklist.clearBit(oldStmt->id());
- }
-
- void applyToFunction()
- {
- for (BasicBlock *bb : theFunction->basicBlocks()) {
- if (bb->isRemoved())
- continue;
-
- for (int i = 0; i < bb->statementCount();) {
- Stmt *stmt = bb->statements().at(i);
-
- int id = stmt->id();
- Q_ASSERT(id != Stmt::InvalidId);
- Q_ASSERT(static_cast<unsigned>(stmt->id()) < stmts.size());
-
- for (int replacementId = replaced[id]; replacementId != Stmt::InvalidId; replacementId = replaced[replacementId])
- id = replacementId;
- Q_ASSERT(id != Stmt::InvalidId);
- Q_ASSERT(static_cast<unsigned>(stmt->id()) < stmts.size());
-
- if (removed.at(id)) {
- bb->removeStatement(i);
- } else {
- if (id != stmt->id())
- bb->replaceStatement(i, stmts[id]);
-
- ++i;
- }
- }
- }
-
- replaced.assign(replaced.size(), Stmt::InvalidId);
- removed.assign(removed.size(), false);
- }
-
- StatementWorklist &operator+=(const QVector<Stmt *> &stmts)
- {
- for (Stmt *s : stmts)
- this->operator+=(s);
-
- return *this;
- }
-
- StatementWorklist &operator+=(Stmt *s)
- {
- if (!s)
- return *this;
-
- Q_ASSERT(s->id() >= 0);
- Q_ASSERT(s->id() < worklist.size());
-
- if (!worklist.at(s->id())) {
- worklist.setBit(s->id());
- ++worklistSize;
- }
-
- return *this;
- }
-
- StatementWorklist &operator-=(Stmt *s)
- {
- Q_ASSERT(s->id() >= 0);
- Q_ASSERT(s->id() < worklist.size());
-
- if (worklist.at(s->id())) {
- worklist.clearBit(s->id());
- Q_ASSERT(worklistSize > 0);
- --worklistSize;
- }
-
- return *this;
- }
-
- unsigned size() const
- {
- return worklistSize;
- }
-
- Stmt *takeNext(Stmt *last)
- {
- if (worklistSize == 0)
- return 0;
-
- const int startAt = last ? last->id() + 1 : 0;
- Q_ASSERT(startAt >= 0);
- Q_ASSERT(startAt <= worklist.size());
-
- Q_ASSERT(static_cast<size_t>(worklist.size()) == stmts.size());
-
- int pos = worklist.findNext(startAt, true, /*wrapAround = */true);
-
- worklist.clearBit(pos);
- Q_ASSERT(worklistSize > 0);
- --worklistSize;
- Stmt *s = stmts.at(pos);
- Q_ASSERT(s);
-
- if (removed.at(s->id()))
- return takeNext(s);
-
- return s;
- }
-
- IR::Function *function() const
- {
- return theFunction;
- }
-
- void registerNewStatement(Stmt *s)
- {
- Q_ASSERT(s->id() >= 0);
- if (static_cast<unsigned>(s->id()) >= stmts.size()) {
- if (static_cast<unsigned>(s->id()) >= stmts.capacity())
- grow();
-
- int newSize = s->id() + 1;
- stmts.resize(newSize, 0);
- worklist.resize(newSize);
- replaced.resize(newSize, Stmt::InvalidId);
- removed.resize(newSize);
- }
-
- stmts[s->id()] = s;
- }
-
-private:
- void grow()
- {
- Q_ASSERT(stmts.capacity() < INT_MAX / 2);
- int newCapacity = ((static_cast<int>(stmts.capacity()) + 1) * 3) / 2;
- stmts.reserve(newCapacity);
- worklist.reserve(newCapacity);
- replaced.reserve(newCapacity);
- removed.reserve(newCapacity);
- }
-};
-
-class SideEffectsChecker
-{
- bool _sideEffect;
-
-public:
- SideEffectsChecker()
- : _sideEffect(false)
- {}
-
- ~SideEffectsChecker()
- {}
-
- bool hasSideEffects(Expr *expr)
- {
- bool sideEffect = false;
- qSwap(_sideEffect, sideEffect);
- visit(expr);
- qSwap(_sideEffect, sideEffect);
- return sideEffect;
- }
-
-protected:
- void markAsSideEffect()
- {
- _sideEffect = true;
- }
-
- bool seenSideEffects() const { return _sideEffect; }
-
- void visit(Expr *e)
- {
- if (auto n = e->asName()) {
- visitName(n);
- } else if (auto t = e->asTemp()) {
- visitTemp(t);
- } else if (auto c = e->asClosure()) {
- visitClosure(c);
- } else if (auto c = e->asConvert()) {
- visitConvert(c);
- } else if (auto u = e->asUnop()) {
- visitUnop(u);
- } else if (auto b = e->asBinop()) {
- visitBinop(b);
- } else if (auto c = e->asCall()) {
- visitCall(c);
- } else if (auto n = e->asNew()) {
- visitNew(n);
- } else if (auto s = e->asSubscript()) {
- visitSubscript(s);
- } else if (auto m = e->asMember()) {
- visitMember(m);
- }
- }
-
- virtual void visitTemp(Temp *) {}
-
-private:
- void visitName(Name *e) {
- if (e->freeOfSideEffects)
- return;
- // TODO: maybe we can distinguish between built-ins of which we know that they do not have
- // a side-effect.
- if (e->builtin == Name::builtin_invalid || (e->id && *e->id != QLatin1String("this")))
- markAsSideEffect();
- }
-
- void visitClosure(Closure *) {
- markAsSideEffect();
- }
-
- void visitConvert(Convert *e) {
- visit(e->expr);
-
- switch (e->expr->type) {
- case QObjectType:
- case StringType:
- case VarType:
- markAsSideEffect();
- break;
- default:
- break;
- }
- }
-
- void visitUnop(Unop *e) {
- visit(e->expr);
-
- switch (e->op) {
- case OpUPlus:
- case OpUMinus:
- case OpNot:
- case OpIncrement:
- case OpDecrement:
- if (e->expr->type == VarType || e->expr->type == StringType || e->expr->type == QObjectType)
- markAsSideEffect();
- break;
-
- default:
- break;
- }
- }
-
- void visitBinop(Binop *e) {
- // TODO: prune parts that don't have a side-effect. For example, in:
- // function f(x) { +x+1; return 0; }
- // we can prune the binop and leave the unop/conversion.
- _sideEffect = hasSideEffects(e->left);
- _sideEffect |= hasSideEffects(e->right);
-
- if (e->left->type == VarType || e->left->type == StringType || e->left->type == QObjectType
- || e->right->type == VarType || e->right->type == StringType || e->right->type == QObjectType)
- markAsSideEffect();
- }
-
- void visitSubscript(Subscript *e) {
- visit(e->base);
- visit(e->index);
- markAsSideEffect();
- }
-
- void visitMember(Member *e) {
- visit(e->base);
- if (e->freeOfSideEffects)
- return;
- markAsSideEffect();
- }
-
- void visitCall(Call *e) {
- visit(e->base);
- for (ExprList *args = e->args; args; args = args->next)
- visit(args->expr);
- markAsSideEffect(); // TODO: there are built-in functions that have no side effect.
- }
-
- void visitNew(New *e) {
- visit(e->base);
- for (ExprList *args = e->args; args; args = args->next)
- visit(args->expr);
- markAsSideEffect(); // TODO: there are built-in types that have no side effect.
- }
-};
-
-class EliminateDeadCode: public SideEffectsChecker
-{
- DefUses &_defUses;
- StatementWorklist &_worklist;
- QVarLengthArray<Temp *, 8> _collectedTemps;
-
-public:
- EliminateDeadCode(DefUses &defUses, StatementWorklist &worklist)
- : _defUses(defUses)
- , _worklist(worklist)
- {}
-
- void run(Expr *&expr, Stmt *stmt) {
- _collectedTemps.clear();
- if (!hasSideEffects(expr)) {
- expr = 0;
- for (Temp *t : _collectedTemps) {
- _defUses.removeUse(stmt, *t);
- _worklist += _defUses.defStmt(*t);
- }
- }
- }
-
-protected:
- void visitTemp(Temp *e) Q_DECL_OVERRIDE Q_DECL_FINAL
- {
- _collectedTemps.append(e);
- }
-};
-
-class PropagateTempTypes
-{
- const DefUses &defUses;
- UntypedTemp theTemp;
- DiscoveredType newType;
-
-public:
- PropagateTempTypes(const DefUses &defUses)
- : defUses(defUses)
- {}
-
- void run(const UntypedTemp &temp, const DiscoveredType &type)
- {
- newType = type;
- theTemp = temp;
- if (Stmt *defStmt = defUses.defStmt(temp.temp))
- visit(defStmt);
- for (Stmt *use : defUses.uses(temp.temp))
- visit(use);
- }
-
-private:
- void visit(Stmt *s)
- {
- STMT_VISIT_ALL_KINDS(s);
- }
-
- void visit(Expr *e)
- {
- if (auto temp = e->asTemp()) {
- if (theTemp == UntypedTemp(*temp)) {
- temp->type = static_cast<Type>(newType.type);
- temp->memberResolver = newType.memberResolver;
- }
- } else {
- EXPR_VISIT_ALL_KINDS(e);
- }
- }
-};
-
-class TypeInference
-{
- enum { DebugTypeInference = 0 };
-
- QQmlEnginePrivate *qmlEngine;
- const DefUses &_defUses;
- typedef std::vector<DiscoveredType> TempTypes;
- TempTypes _tempTypes;
- StatementWorklist *_worklist;
- struct TypingResult {
- DiscoveredType type;
- bool fullyTyped;
-
- TypingResult(const DiscoveredType &type = DiscoveredType()) {
-#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 6
- // avoid optimization bug in gcc 4.6.3 armhf
- ((int volatile &) this->type.type) = type.type;
-#endif
- this->type = type;
- fullyTyped = type.type != UnknownType;
- }
- explicit TypingResult(MemberExpressionResolver *memberResolver)
- : type(memberResolver)
- , fullyTyped(true)
- {}
- };
- TypingResult _ty;
- Stmt *_currentStmt;
-
-public:
- TypeInference(QQmlEnginePrivate *qmlEngine, const DefUses &defUses)
- : qmlEngine(qmlEngine)
- , _defUses(defUses)
- , _tempTypes(_defUses.tempCount())
- , _worklist(0)
- , _ty(UnknownType)
- , _currentStmt(nullptr)
- {}
-
- void run(StatementWorklist &w) {
- _worklist = &w;
-
- Stmt *s = 0;
- while ((s = _worklist->takeNext(s))) {
- if (s->asJump())
- continue;
-
- if (DebugTypeInference) {
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream qout(&buf);
- qout<<"Typing stmt ";
- IRPrinter(&qout).print(s);
- qout.flush();
- qDebug("%s", buf.data().constData());
-
- qDebug("%u left in the worklist", _worklist->size());
- }
-
- if (!run(s)) {
- *_worklist += s;
- if (DebugTypeInference) {
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream qout(&buf);
- qout<<"Pushing back stmt: ";
- IRPrinter(&qout).print(s);
- qout.flush();
- qDebug("%s", buf.data().constData());
- }
- } else {
- if (DebugTypeInference) {
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream qout(&buf);
- qout<<"Finished: ";
- IRPrinter(&qout).print(s);
- qout.flush();
- qDebug("%s", buf.data().constData());
- }
- }
- }
-
- PropagateTempTypes propagator(_defUses);
- for (size_t i = 0, ei = _tempTypes.size(); i != ei; ++i) {
- const Temp &temp = _defUses.temp(int(i));
- if (temp.kind == Temp::Invalid)
- continue;
- const DiscoveredType &tempType = _tempTypes[i];
- if (tempType.type == UnknownType)
- continue;
- propagator.run(temp, tempType);
- }
-
- _worklist = 0;
- }
-
-private:
- bool run(Stmt *s) {
- TypingResult ty;
- std::swap(_ty, ty);
- std::swap(_currentStmt, s);
- visit(_currentStmt);
- std::swap(_currentStmt, s);
- std::swap(_ty, ty);
- return ty.fullyTyped;
- }
-
- TypingResult run(Expr *e) {
- TypingResult ty;
- std::swap(_ty, ty);
- visit(e);
- std::swap(_ty, ty);
-
- if (ty.type != UnknownType)
- setType(e, ty.type);
- return ty;
- }
-
- void setType(Expr *e, DiscoveredType ty) {
- if (Temp *t = e->asTemp()) {
- if (DebugTypeInference)
- qDebug() << "Setting type for temp" << t->index
- << " to " << typeName(Type(ty.type)) << "(" << ty.type << ")"
- << endl;
-
- DiscoveredType &it = _tempTypes[t->index];
- if (it != ty) {
- it = ty;
-
- if (DebugTypeInference) {
- for (Stmt *s : _defUses.uses(*t)) {
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream qout(&buf);
- qout << "Pushing back dependent stmt: ";
- IRPrinter(&qout).print(s);
- qout.flush();
- qDebug("%s", buf.data().constData());
- }
- }
-
- for (Stmt *s : qAsConst(_defUses.uses(*t))) {
- if (s != _currentStmt) {
- *_worklist += s;
- }
- }
- }
- } else {
- e->type = (Type) ty.type;
- }
- }
-
-private:
- void visit(Expr *e)
- {
- if (auto c = e->asConst()) {
- visitConst(c);
- } else if (auto s = e->asString()) {
- visitString(s);
- } else if (auto r = e->asRegExp()) {
- visitRegExp(r);
- } else if (auto n = e->asName()) {
- visitName(n);
- } else if (auto t = e->asTemp()) {
- visitTemp(t);
- } else if (auto a = e->asArgLocal()) {
- visitArgLocal(a);
- } else if (auto c = e->asClosure()) {
- visitClosure(c);
- } else if (auto c = e->asConvert()) {
- visitConvert(c);
- } else if (auto u = e->asUnop()) {
- visitUnop(u);
- } else if (auto b = e->asBinop()) {
- visitBinop(b);
- } else if (auto c = e->asCall()) {
- visitCall(c);
- } else if (auto n = e->asNew()) {
- visitNew(n);
- } else if (auto s = e->asSubscript()) {
- visitSubscript(s);
- } else if (auto m = e->asMember()) {
- visitMember(m);
- } else {
- Q_UNREACHABLE();
- }
- }
-
- void visitConst(Const *c) {
- if (c->type & NumberType) {
- if (canConvertToSignedInteger(c->value))
- _ty = TypingResult(SInt32Type);
- else if (canConvertToUnsignedInteger(c->value))
- _ty = TypingResult(UInt32Type);
- else
- _ty = TypingResult(c->type);
- } else
- _ty = TypingResult(c->type);
- }
- void visitString(IR::String *) { _ty = TypingResult(StringType); }
- void visitRegExp(IR::RegExp *) { _ty = TypingResult(VarType); }
- void visitName(Name *) { _ty = TypingResult(VarType); }
- void visitTemp(Temp *e) {
- if (e->memberResolver && e->memberResolver->isValid())
- _ty = TypingResult(e->memberResolver);
- else
- _ty = TypingResult(_tempTypes[e->index]);
- setType(e, _ty.type);
- }
- void visitArgLocal(ArgLocal *e) {
- _ty = TypingResult(VarType);
- setType(e, _ty.type);
- }
-
- void visitClosure(Closure *) { _ty = TypingResult(VarType); }
- void visitConvert(Convert *e) {
- _ty = TypingResult(e->type);
- }
-
- void visitUnop(Unop *e) {
- _ty = run(e->expr);
- switch (e->op) {
- case OpUPlus: _ty.type = DoubleType; return;
- case OpUMinus: _ty.type = DoubleType; return;
- case OpCompl: _ty.type = SInt32Type; return;
- case OpNot: _ty.type = BoolType; return;
-
- case OpIncrement:
- case OpDecrement:
- Q_ASSERT(!"Inplace operators should have been removed!");
- Q_UNREACHABLE();
- default:
- Q_UNIMPLEMENTED();
- Q_UNREACHABLE();
- }
- }
-
- void visitBinop(Binop *e) {
- TypingResult leftTy = run(e->left);
- TypingResult rightTy = run(e->right);
- _ty.fullyTyped = leftTy.fullyTyped && rightTy.fullyTyped;
-
- switch (e->op) {
- case OpAdd:
- if (leftTy.type.test(VarType) || leftTy.type.test(QObjectType) || rightTy.type.test(VarType) || rightTy.type.test(QObjectType))
- _ty.type = VarType;
- else if (leftTy.type.test(StringType) || rightTy.type.test(StringType))
- _ty.type = StringType;
- else if (leftTy.type != UnknownType && rightTy.type != UnknownType)
- _ty.type = DoubleType;
- else
- _ty.type = UnknownType;
- break;
- case OpSub:
- _ty.type = DoubleType;
- break;
-
- case OpMul:
- case OpDiv:
- case OpMod:
- _ty.type = DoubleType;
- break;
-
- case OpBitAnd:
- case OpBitOr:
- case OpBitXor:
- case OpLShift:
- case OpRShift:
- _ty.type = SInt32Type;
- break;
- case OpURShift:
- _ty.type = UInt32Type;
- break;
-
- case OpGt:
- case OpLt:
- case OpGe:
- case OpLe:
- case OpEqual:
- case OpNotEqual:
- case OpStrictEqual:
- case OpStrictNotEqual:
- case OpAnd:
- case OpOr:
- case OpInstanceof:
- case OpIn:
- _ty.type = BoolType;
- break;
-
- default:
- Q_UNIMPLEMENTED();
- Q_UNREACHABLE();
- }
- }
-
- void visitCall(Call *e) {
- _ty = run(e->base);
- for (ExprList *it = e->args; it; it = it->next)
- _ty.fullyTyped &= run(it->expr).fullyTyped;
- _ty.type = VarType;
- }
- void visitNew(New *e) {
- _ty = run(e->base);
- for (ExprList *it = e->args; it; it = it->next)
- _ty.fullyTyped &= run(it->expr).fullyTyped;
- _ty.type = VarType;
- }
- void visitSubscript(Subscript *e) {
- _ty.fullyTyped = run(e->base).fullyTyped && run(e->index).fullyTyped;
- _ty.type = VarType;
- }
-
- void visitMember(Member *e) {
- _ty = run(e->base);
-
- if (_ty.fullyTyped && _ty.type.memberResolver && _ty.type.memberResolver->isValid()) {
- MemberExpressionResolver *resolver = _ty.type.memberResolver;
- _ty.type = resolver->resolveMember(qmlEngine, resolver, e);
- } else
- _ty.type = VarType;
- }
-
- void visit(Stmt *s)
- {
- if (auto e = s->asExp()) {
- visitExp(e);
- } else if (auto m = s->asMove()) {
- visitMove(m);
- } else if (auto j = s->asJump()) {
- visitJump(j);
- } else if (auto c = s->asCJump()) {
- visitCJump(c);
- } else if (auto r = s->asRet()) {
- visitRet(r);
- } else if (auto p = s->asPhi()) {
- visitPhi(p);
- } else {
- Q_UNREACHABLE();
- }
- }
-
- void visitExp(Exp *s) { _ty = run(s->expr); }
- void visitMove(Move *s) {
- if (Temp *t = s->target->asTemp()) {
- if (Name *n = s->source->asName()) {
- if (n->builtin == Name::builtin_qml_context) {
- _ty = TypingResult(t->memberResolver);
- setType(n, _ty.type);
- setType(t, _ty.type);
- return;
- }
- }
- TypingResult sourceTy = run(s->source);
- setType(t, sourceTy.type);
- _ty = sourceTy;
- return;
- }
-
- TypingResult sourceTy = run(s->source);
- _ty = run(s->target);
- _ty.fullyTyped &= sourceTy.fullyTyped;
- }
-
- void visitJump(Jump *) { _ty = TypingResult(MissingType); }
- void visitCJump(CJump *s) { _ty = run(s->cond); }
- void visitRet(Ret *s) { _ty = run(s->expr); }
- void visitPhi(Phi *s) {
- _ty = run(s->incoming[0]);
- for (int i = 1, ei = s->incoming.size(); i != ei; ++i) {
- TypingResult ty = run(s->incoming[i]);
- if (!ty.fullyTyped && _ty.fullyTyped) {
- // When one of the temps not fully typed, we already know that we cannot completely type this node.
- // So, pick the type we calculated upto this point, and wait until the unknown one will be typed.
- // At that point, this statement will be re-scheduled, and then we can fully type this node.
- _ty.fullyTyped = false;
- break;
- }
- _ty.type.type |= ty.type.type;
- _ty.fullyTyped &= ty.fullyTyped;
- if (_ty.type.test(QObjectType) && _ty.type.memberResolver)
- _ty.type.memberResolver->clear(); // ### TODO: find common ancestor meta-object
- }
-
- switch (_ty.type.type) {
- case UnknownType:
- case UndefinedType:
- case NullType:
- case BoolType:
- case SInt32Type:
- case UInt32Type:
- case DoubleType:
- case StringType:
- case QObjectType:
- case VarType:
- // The type is not a combination of two or more types, so we're done.
- break;
-
- default:
- // There are multiple types involved, so:
- if (_ty.type.isNumber())
- // The type is any combination of double/int32/uint32, but nothing else. So we can
- // type it as double.
- _ty.type = DoubleType;
- else
- // There just is no single type that can hold this combination, so:
- _ty.type = VarType;
- }
-
- setType(s->targetTemp, _ty.type);
- }
-};
-
-class ReverseInference
-{
- const DefUses &_defUses;
-
-public:
- ReverseInference(const DefUses &defUses)
- : _defUses(defUses)
- {}
-
- void run(IR::Function *f)
- {
- Q_UNUSED(f);
-
- QVector<UntypedTemp> knownOk;
- QVector<UntypedTemp> candidates = _defUses.defsUntyped();
- while (!candidates.isEmpty()) {
- UntypedTemp temp = candidates.last();
- candidates.removeLast();
-
- if (knownOk.contains(temp))
- continue;
-
- if (!isUsedAsInt32(temp, knownOk))
- continue;
-
- Stmt *s = _defUses.defStmt(temp.temp);
- Move *m = s->asMove();
- if (!m)
- continue;
- Temp *target = m->target->asTemp();
- if (!target || temp != UntypedTemp(*target) || target->type == SInt32Type)
- continue;
- if (Temp *t = m->source->asTemp()) {
- candidates.append(*t);
- } else if (m->source->asConvert()) {
- break;
- } else if (Binop *b = m->source->asBinop()) {
- bool iterateOnOperands = true;
-
- switch (b->op) {
- case OpSub:
- case OpMul:
- case OpAdd:
- if (b->left->type == SInt32Type && b->right->type == SInt32Type) {
- iterateOnOperands = false;
- break;
- } else {
- continue;
- }
- case OpBitAnd:
- case OpBitOr:
- case OpBitXor:
- case OpLShift:
- case OpRShift:
- case OpURShift:
- break;
- default:
- continue;
- }
-
- if (iterateOnOperands) {
- if (Temp *lt = b->left->asTemp())
- candidates.append(*lt);
- if (Temp *rt = b->right->asTemp())
- candidates.append(*rt);
- }
- } else if (Unop *u = m->source->asUnop()) {
- if (u->op == OpCompl || u->op == OpUPlus) {
- if (Temp *t = u->expr->asTemp())
- candidates.append(*t);
- }
- } else {
- continue;
- }
-
- knownOk.append(temp);
- }
-
- PropagateTempTypes propagator(_defUses);
- for (const UntypedTemp &t : qAsConst(knownOk)) {
- propagator.run(t, SInt32Type);
- if (Stmt *defStmt = _defUses.defStmt(t.temp)) {
- if (Move *m = defStmt->asMove()) {
- if (Convert *c = m->source->asConvert()) {
- c->type = SInt32Type;
- } else if (Unop *u = m->source->asUnop()) {
- if (u->op != OpUMinus)
- u->type = SInt32Type;
- } else if (Binop *b = m->source->asBinop()) {
- b->type = SInt32Type;
- }
- }
- }
- }
- }
-
-private:
- bool isUsedAsInt32(const UntypedTemp &t, const QVector<UntypedTemp> &knownOk) const
- {
- const QVector<Stmt *> &uses = _defUses.uses(t.temp);
- if (uses.isEmpty())
- return false;
-
- for (Stmt *use : uses) {
- if (Move *m = use->asMove()) {
- Temp *targetTemp = m->target->asTemp();
-
- if (m->source->asTemp()) {
- if (!targetTemp || !knownOk.contains(*targetTemp))
- return false;
- } else if (m->source->asConvert()) {
- continue;
- } else if (Binop *b = m->source->asBinop()) {
- switch (b->op) {
- case OpAdd:
- case OpSub:
- case OpMul:
- if (!targetTemp || !knownOk.contains(*targetTemp))
- return false;
- Q_FALLTHROUGH();
- case OpBitAnd:
- case OpBitOr:
- case OpBitXor:
- case OpRShift:
- case OpLShift:
- case OpURShift:
- continue;
- default:
- return false;
- }
- } else if (Unop *u = m->source->asUnop()) {
- if (u->op == OpUPlus) {
- if (!targetTemp || !knownOk.contains(*targetTemp))
- return false;
- } else if (u->op != OpCompl) {
- return false;
- }
- } else {
- return false;
- }
- } else
- return false;
- }
-
- return true;
- }
-};
-
-void convertConst(Const *c, Type targetType)
-{
- switch (targetType) {
- case DoubleType:
- break;
- case SInt32Type:
- c->value = QV4::Primitive::toInt32(c->value);
- break;
- case UInt32Type:
- c->value = QV4::Primitive::toUInt32(c->value);
- break;
- case BoolType:
- c->value = !(c->value == 0 || std::isnan(c->value));
- break;
- case NullType:
- case UndefinedType:
- c->value = qt_qnan();
- c->type = targetType;
- break;
- default:
- Q_UNIMPLEMENTED();
- Q_ASSERT(!"Unimplemented!");
- break;
- }
- c->type = targetType;
-}
-
-class TypePropagation
-{
- DefUses &_defUses;
- Type _ty;
- IR::Function *_f;
-
- bool run(Expr *&e, Type requestedType = UnknownType, bool insertConversion = true) {
- qSwap(_ty, requestedType);
- visit(e);
- qSwap(_ty, requestedType);
-
- if (requestedType != UnknownType) {
- if (e->type != requestedType) {
- if (requestedType & NumberType || requestedType == BoolType) {
- if (insertConversion)
- addConversion(e, requestedType);
- return true;
- }
- }
- }
-
- return false;
- }
-
- struct Conversion {
- Expr **expr;
- Type targetType;
- Stmt *stmt;
-
- Conversion(Expr **expr = 0, Type targetType = UnknownType, Stmt *stmt = 0)
- : expr(expr)
- , targetType(targetType)
- , stmt(stmt)
- {}
- };
-
- Stmt *_currStmt;
- QVector<Conversion> _conversions;
-
- void addConversion(Expr *&expr, Type targetType) {
- _conversions.append(Conversion(&expr, targetType, _currStmt));
- }
-
-public:
- TypePropagation(DefUses &defUses) : _defUses(defUses), _ty(UnknownType) {}
-
- void run(IR::Function *f, StatementWorklist &worklist) {
- _f = f;
- for (BasicBlock *bb : f->basicBlocks()) {
- if (bb->isRemoved())
- continue;
- _conversions.clear();
-
- for (Stmt *s : bb->statements()) {
- _currStmt = s;
- visit(s);
- }
-
- for (const Conversion &conversion : qAsConst(_conversions)) {
- IR::Move *move = conversion.stmt->asMove();
-
- // Note: isel only supports move into member when source is a temp, so convert
- // is not a supported source.
- if (move && move->source->asTemp() && !move->target->asMember()) {
- *conversion.expr = bb->CONVERT(*conversion.expr, conversion.targetType);
- } else if (Const *c = (*conversion.expr)->asConst()) {
- convertConst(c, conversion.targetType);
- } else if (ArgLocal *al = (*conversion.expr)->asArgLocal()) {
- Temp *target = bb->TEMP(bb->newTemp(BasicBlock::NewTempForOptimizer));
- target->type = conversion.targetType;
- Expr *convert = bb->CONVERT(al, conversion.targetType);
- Move *convCall = f->NewStmt<Move>();
- worklist.registerNewStatement(convCall);
- convCall->init(target, convert);
- _defUses.addDef(target, convCall, bb);
-
- Temp *source = bb->TEMP(target->index);
- source->type = conversion.targetType;
- _defUses.addUse(*source, conversion.stmt);
-
- if (conversion.stmt->asPhi()) {
- // Only temps can be used as arguments to phi nodes, so this is a sanity check...:
- Q_UNREACHABLE();
- } else {
- bb->insertStatementBefore(conversion.stmt, convCall);
- }
-
- *conversion.expr = source;
- } else if (Temp *t = (*conversion.expr)->asTemp()) {
- Temp *target = bb->TEMP(bb->newTemp(BasicBlock::NewTempForOptimizer));
- target->type = conversion.targetType;
- Expr *convert = bb->CONVERT(t, conversion.targetType);
- Move *convCall = f->NewStmt<Move>();
- worklist.registerNewStatement(convCall);
- convCall->init(target, convert);
- _defUses.addDef(target, convCall, bb);
- _defUses.addUse(*t, convCall);
-
- Temp *source = bb->TEMP(target->index);
- source->type = conversion.targetType;
- _defUses.removeUse(conversion.stmt, *t);
- _defUses.addUse(*source, conversion.stmt);
-
- if (Phi *phi = conversion.stmt->asPhi()) {
- int idx = phi->incoming.indexOf(t);
- Q_ASSERT(idx != -1);
- bb->in[idx]->insertStatementBeforeTerminator(convCall);
- } else {
- bb->insertStatementBefore(conversion.stmt, convCall);
- }
-
- *conversion.expr = source;
- } else if (Unop *u = (*conversion.expr)->asUnop()) {
- // convert:
- // int32{%2} = double{-double{%1}};
- // to:
- // double{%3} = double{-double{%1}};
- // int32{%2} = int32{convert(double{%3})};
- Temp *tmp = bb->TEMP(bb->newTemp(BasicBlock::NewTempForOptimizer));
- tmp->type = u->type;
- Move *extraMove = f->NewStmt<Move>();
- worklist.registerNewStatement(extraMove);
- extraMove->init(tmp, u);
- _defUses.addDef(tmp, extraMove, bb);
-
- if (Temp *unopOperand = u->expr->asTemp()) {
- _defUses.addUse(*unopOperand, extraMove);
- _defUses.removeUse(move, *unopOperand);
- }
-
- bb->insertStatementBefore(conversion.stmt, extraMove);
-
- *conversion.expr = bb->CONVERT(CloneExpr::cloneTemp(tmp, f), conversion.targetType);
- _defUses.addUse(*tmp, move);
- } else {
- Q_UNREACHABLE();
- }
- }
- }
- }
-
-private:
- void visit(Expr *e)
- {
- if (auto c = e->asConst()) {
- visitConst(c);
- } else if (auto c = e->asConvert()) {
- run(c->expr, c->type);
- } else if (auto u = e->asUnop()) {
- run(u->expr, u->type);
- } else if (auto b = e->asBinop()) {
- visitBinop(b);
- } else if (auto c = e->asCall()) {
- visitCall(c);
- } else if (auto n = e->asNew()) {
- visitNew(n);
- } else if (auto s = e->asSubscript()) {
- visitSubscript(s);
- } else if (auto m = e->asMember()) {
- visitMember(m);
- }
- }
-
- void visitConst(Const *c) {
- if (_ty & NumberType && c->type & NumberType) {
- if (_ty == SInt32Type)
- c->value = QV4::Primitive::toInt32(c->value);
- else if (_ty == UInt32Type)
- c->value = QV4::Primitive::toUInt32(c->value);
- c->type = _ty;
- }
- }
-
- void visitBinop(Binop *e) {
- // FIXME: This routine needs more tuning!
- switch (e->op) {
- case OpAdd:
- case OpSub:
- case OpMul:
- case OpDiv:
- case OpMod:
- case OpBitAnd:
- case OpBitOr:
- case OpBitXor:
- run(e->left, e->type);
- run(e->right, e->type);
- break;
-
- case OpLShift:
- case OpRShift:
- case OpURShift:
- run(e->left, SInt32Type);
- run(e->right, SInt32Type);
- break;
-
- case OpGt:
- case OpLt:
- case OpGe:
- case OpLe:
- case OpEqual:
- case OpNotEqual:
- if (e->left->type == DoubleType) {
- run(e->right, DoubleType);
- } else if (e->right->type == DoubleType) {
- run(e->left, DoubleType);
- } else {
- run(e->left, e->left->type);
- run(e->right, e->right->type);
- }
- break;
-
- case OpStrictEqual:
- case OpStrictNotEqual:
- case OpInstanceof:
- case OpIn:
- run(e->left, e->left->type);
- run(e->right, e->right->type);
- break;
-
- default:
- Q_UNIMPLEMENTED();
- Q_UNREACHABLE();
- }
- }
- void visitCall(Call *e) {
- run(e->base);
- for (ExprList *it = e->args; it; it = it->next)
- run(it->expr);
- }
- void visitNew(New *e) {
- run(e->base);
- for (ExprList *it = e->args; it; it = it->next)
- run(it->expr);
- }
- void visitSubscript(Subscript *e) { run(e->base); run(e->index); }
- void visitMember(Member *e) { run(e->base); }
-
- void visit(Stmt *s)
- {
- if (auto e = s->asExp()) {
- visitExp(e);
- } else if (auto m = s->asMove()) {
- visitMove(m);
- } else if (auto c = s->asCJump()) {
- visitCJump(c);
- } else if (auto r = s->asRet()) {
- visitRet(r);
- } else if (auto p = s->asPhi()) {
- visitPhi(p);
- }
- }
-
- void visitExp(Exp *s) { run(s->expr); }
- void visitMove(Move *s) {
- if (s->source->asConvert())
- return; // this statement got inserted for a phi-node type conversion
-
- run(s->target);
-
- if (Unop *u = s->source->asUnop()) {
- if (u->op == OpUPlus) {
- if (run(u->expr, s->target->type, false)) {
- Convert *convert = _f->New<Convert>();
- convert->init(u->expr, s->target->type);
- s->source = convert;
- } else {
- s->source = u->expr;
- }
-
- return;
- }
- }
-
- const Member *targetMember = s->target->asMember();
- const bool inhibitConversion = targetMember && targetMember->inhibitTypeConversionOnWrite;
-
- run(s->source, s->target->type, !inhibitConversion);
- }
- void visitCJump(CJump *s) {
- run(s->cond, BoolType);
- }
- void visitRet(Ret *s) { run(s->expr); }
- void visitPhi(Phi *s) {
- Type ty = s->targetTemp->type;
- for (int i = 0, ei = s->incoming.size(); i != ei; ++i)
- run(s->incoming[i], ty);
- }
-};
-
-void splitCriticalEdges(IR::Function *f, DominatorTree &df, StatementWorklist &worklist, DefUses &defUses)
-{
- const QVector<BasicBlock *> copy = f->basicBlocks();
- for (BasicBlock *toBB : copy) {
- if (toBB->isRemoved())
- continue;
- if (toBB->in.size() < 2)
- continue;
-
- for (int inIdx = 0, eInIdx = toBB->in.size(); inIdx != eInIdx; ++inIdx) {
- BasicBlock *fromBB = toBB->in[inIdx];
- if (fromBB->out.size() < 2)
- continue;
-
- // We found a critical edge.
- // create the basic block:
- BasicBlock *newBB = f->newBasicBlock(toBB->catchBlock);
- Jump *s = f->NewStmt<Jump>();
- worklist.registerNewStatement(s);
- defUses.registerNewStatement(s);
- s->init(toBB);
- newBB->appendStatement(s);
-
- // rewire the old outgoing edge
- int outIdx = fromBB->out.indexOf(toBB);
- fromBB->out[outIdx] = newBB;
- newBB->in.append(fromBB);
-
- // rewire the old incoming edge
- toBB->in[inIdx] = newBB;
- newBB->out.append(toBB);
-
- // add newBB to the correct loop group
- if (toBB->isGroupStart()) {
- if (fromBB == toBB) {
- // special case: the loop header points back to itself (so it's a small loop).
- newBB->setContainingGroup(toBB);
- } else {
- BasicBlock *container;
- for (container = fromBB->containingGroup(); container; container = container->containingGroup())
- if (container == toBB)
- break;
- if (container == toBB) // if we were already inside the toBB loop
- newBB->setContainingGroup(toBB);
- else
- newBB->setContainingGroup(toBB->containingGroup());
- }
- } else {
- newBB->setContainingGroup(toBB->containingGroup());
- }
-
- // patch the terminator
- Stmt *terminator = fromBB->terminator();
- if (Jump *j = terminator->asJump()) {
- Q_ASSERT(outIdx == 0);
- j->target = newBB;
- } else if (CJump *j = terminator->asCJump()) {
- if (outIdx == 0)
- j->iftrue = newBB;
- else if (outIdx == 1)
- j->iffalse = newBB;
- else
- Q_ASSERT(!"Invalid out edge index for CJUMP!");
- } else if (terminator->asRet()) {
- Q_ASSERT(!"A block with a RET at the end cannot have outgoing edges.");
- } else {
- Q_ASSERT(!"Unknown terminator!");
- }
-
-// qDebug() << "splitting edge" << fromBB->index() << "->" << toBB->index()
-// << "by inserting block" << newBB->index();
-
- // Set the immediate dominator of the new block to inBB
- df.setImmediateDominator(newBB, fromBB);
-
- bool toNeedsNewIdom = true;
- for (BasicBlock *bb : toBB->in) {
- if (bb != newBB && bb != toBB && !df.dominates(toBB, bb)) {
- toNeedsNewIdom = false;
- break;
- }
- }
- if (toNeedsNewIdom)
- df.setImmediateDominator(toBB, newBB);
- }
- }
-}
-
-// Detect all (sub-)loops in a function.
-//
-// Doing loop detection on the CFG is better than relying on the statement information in
-// order to mark loops. Although JavaScript only has natural loops, it can still be the case
-// that something is not a loop even though a loop-like-statement is in the source. For
-// example:
-// while (true) {
-// if (i > 0)
-// break;
-// else
-// break;
-// }
-//
-// Algorithm:
-// - do a DFS on the dominator tree, where for each node:
-// - collect all back-edges
-// - if there are back-edges, the node is a loop-header for a new loop, so:
-// - walk the CFG is reverse-direction, and for every node:
-// - if the node already belongs to a loop, we've found a nested loop:
-// - get the loop-header for the (outermost) nested loop
-// - add that loop-header to the current loop
-// - continue by walking all incoming edges that do not yet belong to the current loop
-// - if the node does not belong to a loop yet, add it to the current loop, and
-// go on with all incoming edges
-//
-// Loop-header detection by checking for back-edges is very straight forward: a back-edge is
-// an incoming edge where the other node is dominated by the current node. Meaning: all
-// execution paths that reach that other node have to go through the current node, that other
-// node ends with a (conditional) jump back to the loop header.
-//
-// The exact order of the DFS on the dominator tree is not important. The only property has to
-// be that a node is only visited when all the nodes it dominates have been visited before.
-// The reason for the DFS is that for nested loops, the inner loop's loop-header is dominated
-// by the outer loop's header. So, by visiting depth-first, sub-loops are identified before
-// their containing loops, which makes nested-loop identification free. An added benefit is
-// that the nodes for those sub-loops are only processed once.
-//
-// Note: independent loops that share the same header are merged together. For example, in
-// the code snippet below, there are 2 back-edges into the loop-header, but only one single
-// loop will be detected.
-// while (a) {
-// if (b)
-// continue;
-// else
-// continue;
-// }
-class LoopDetection
-{
- enum { DebugLoopDetection = 0 };
-
- Q_DISABLE_COPY(LoopDetection)
-
-public:
- struct LoopInfo
- {
- BasicBlock *loopHeader;
- QVector<BasicBlock *> loopBody;
- QVector<LoopInfo *> nestedLoops;
- LoopInfo *parentLoop;
-
- LoopInfo(BasicBlock *loopHeader = 0)
- : loopHeader(loopHeader)
- , parentLoop(0)
- {}
-
- bool isValid() const
- { return loopHeader != 0; }
-
- void addNestedLoop(LoopInfo *nested)
- {
- Q_ASSERT(nested);
- Q_ASSERT(!nestedLoops.contains(nested));
- Q_ASSERT(nested->parentLoop == 0);
- nested->parentLoop = this;
- nestedLoops.append(nested);
- }
- };
-
-public:
- LoopDetection(const DominatorTree &dt)
- : dt(dt)
- {}
-
- ~LoopDetection()
- {
- qDeleteAll(loopInfos);
- }
-
- void run(IR::Function *function)
- {
- std::vector<BasicBlock *> backedges;
- backedges.reserve(4);
-
- const auto order = dt.calculateDFNodeIterOrder();
- for (BasicBlock *bb : order) {
- Q_ASSERT(!bb->isRemoved());
-
- backedges.clear();
-
- for (BasicBlock *in : bb->in)
- if (bb == in || dt.dominates(bb, in))
- backedges.push_back(in);
-
- if (!backedges.empty()) {
- subLoop(bb, backedges);
- }
- }
-
- createLoopInfos(function);
- dumpLoopInfo();
- }
-
- void dumpLoopInfo() const
- {
- if (!DebugLoopDetection)
- return;
-
- qDebug() << "Found" << loopInfos.size() << "loops";
- for (const LoopInfo *info : loopInfos) {
- qDebug() << "Loop header:" << info->loopHeader->index()
- << "for loop" << quint64(info);
- for (BasicBlock *bb : info->loopBody)
- qDebug() << " " << bb->index();
- for (LoopInfo *nested : info->nestedLoops)
- qDebug() << " sub loop:" << quint64(nested);
- qDebug() << " parent loop:" << quint64(info->parentLoop);
- }
- }
-
- QVector<LoopInfo *> allLoops() const
- { return loopInfos; }
-
- // returns all loop headers for loops that have no nested loops.
- QVector<LoopInfo *> innermostLoops() const
- {
- QVector<LoopInfo *> inner(loopInfos);
-
- for (int i = 0; i < inner.size(); ) {
- if (inner.at(i)->nestedLoops.isEmpty())
- ++i;
- else
- inner.remove(i);
- }
-
- return inner;
- }
-
-private:
- void subLoop(BasicBlock *loopHead, const std::vector<BasicBlock *> &backedges)
- {
- loopHead->markAsGroupStart();
- LoopInfo *info = new LoopInfo;
- info->loopHeader = loopHead;
- loopInfos.append(info);
-
- std::vector<BasicBlock *> worklist;
- worklist.reserve(backedges.size() + 8);
- worklist.insert(worklist.end(), backedges.begin(), backedges.end());
- while (!worklist.empty()) {
- BasicBlock *predIt = worklist.back();
- worklist.pop_back();
-
- BasicBlock *subloop = predIt->containingGroup();
- if (subloop) {
- // This is a discovered block. Find its outermost discovered loop.
- while (BasicBlock *parentLoop = subloop->containingGroup())
- subloop = parentLoop;
-
- // If it is already discovered to be a subloop of this loop, continue.
- if (subloop == loopHead)
- continue;
-
- // Yay, it's a subloop of this loop.
- subloop->setContainingGroup(loopHead);
- predIt = subloop;
-
- // Add all predecessors of the subloop header to the worklist, as long as
- // those predecessors are not in the current subloop. It might be the case
- // that they are in other loops, which we will then add as a subloop to the
- // current loop.
- for (BasicBlock *predIn : predIt->in)
- if (predIn->containingGroup() != subloop)
- worklist.push_back(predIn);
- } else {
- if (predIt == loopHead)
- continue;
-
- // This is an undiscovered block. Map it to the current loop.
- predIt->setContainingGroup(loopHead);
-
- // Add all incoming edges to the worklist.
- for (BasicBlock *bb : predIt->in)
- worklist.push_back(bb);
- }
- }
- }
-
-private:
- const DominatorTree &dt;
- QVector<LoopInfo *> loopInfos;
-
- void createLoopInfos(IR::Function *function)
- {
- for (BasicBlock *bb : function->basicBlocks()) {
- if (bb->isRemoved())
- continue;
- if (BasicBlock *loopHeader = bb->containingGroup())
- findLoop(loopHeader)->loopBody.append(bb);
- }
-
- for (int i = 0, size = loopInfos.size(); i < size; ++i) {
- if (BasicBlock *containingLoopHeader = loopInfos.at(i)->loopHeader->containingGroup())
- findLoop(containingLoopHeader)->addNestedLoop(loopInfos.at(i));
- }
- }
-
- LoopInfo *findLoop(BasicBlock *loopHeader)
- {
- for (LoopInfo *info : qAsConst(loopInfos)) {
- if (info->loopHeader == loopHeader)
- return info;
- }
-
- Q_UNREACHABLE();
- return nullptr;
- }
-};
-
-// High-level algorithm:
-// 0. start with the first node (the start node) of a function
-// 1. emit the node
-// 2. add all outgoing edges that are not yet emitted to the postponed stack
-// 3. When the postponed stack is empty, pop a stack from the loop stack. If that is empty too,
-// we're done.
-// 4. pop a node from the postponed stack, and check if it can be scheduled:
-// a. if all incoming edges are scheduled, go to 4.
-// b. if an incoming edge is unscheduled, but it's a back-edge (an edge in a loop that jumps
-// back to the start of the loop), ignore it
-// c. if there is any unscheduled edge that is not a back-edge, ignore this node, and go to 4.
-// 5. if this node is the start of a loop, push the postponed stack on the loop stack.
-// 6. go back to 1.
-//
-// The postponing action in step 2 will put the node into its containing group. The case where this
-// is important is when a (labeled) continue or a (labeled) break statement occur in a loop: the
-// outgoing edge points to a node that is not part of the current loop (and possibly not of the
-// parent loop).
-//
-// Linear scan register allocation benefits greatly from short life-time intervals with few holes
-// (see for example section 4 (Lifetime Analysis) of [Wimmer1]). This algorithm makes sure that the
-// blocks of a group are scheduled together, with no non-loop blocks in between. This applies
-// recursively for nested loops. It also schedules groups of if-then-else-endif blocks together for
-// the same reason.
-class BlockScheduler
-{
- enum { DebugBlockScheduler = 0 };
-
- IR::Function *function;
- const DominatorTree &dominatorTree;
-
- struct WorkForGroup
- {
- BasicBlock *group;
- QStack<BasicBlock *> postponed;
-
- WorkForGroup(BasicBlock *group = 0): group(group) {}
- };
- WorkForGroup currentGroup;
- QStack<WorkForGroup> postponedGroups;
- QVector<BasicBlock *> sequence;
- ProcessedBlocks emitted;
- QHash<BasicBlock *, BasicBlock *> loopsStartEnd;
-
- bool checkCandidate(BasicBlock *candidate)
- {
- Q_ASSERT(candidate->containingGroup() == currentGroup.group);
-
- for (BasicBlock *in : candidate->in) {
- if (emitted.alreadyProcessed(in))
- continue;
-
- if (dominatorTree.dominates(candidate, in))
- // this is a loop, where there in -> candidate edge is the jump back to the top of the loop.
- continue;
-
- if (in == candidate)
- // this is a very tight loop, e.g.:
- // L1: ...
- // goto L1
- // This can happen when, for example, the basic-block merging gets rid of the empty
- // body block. In this case, we can safely schedule this block (if all other
- // incoming edges are either loop-back edges, or have been scheduled already).
- continue;
-
- return false; // an incoming edge that is not yet emitted, and is not a back-edge
- }
-
- if (candidate->isGroupStart()) {
- // postpone everything, and schedule the loop first.
- postponedGroups.push(currentGroup);
- currentGroup = WorkForGroup(candidate);
- }
-
- return true;
- }
-
- BasicBlock *pickNext()
- {
- while (true) {
- while (currentGroup.postponed.isEmpty()) {
- if (postponedGroups.isEmpty())
- return 0;
- if (currentGroup.group) // record the first and the last node of a group
- loopsStartEnd.insert(currentGroup.group, sequence.last());
- currentGroup = postponedGroups.pop();
- }
-
- BasicBlock *next = currentGroup.postponed.pop();
- if (checkCandidate(next))
- return next;
- }
-
- Q_UNREACHABLE();
- return 0;
- }
-
- void emitBlock(BasicBlock *bb)
- {
- Q_ASSERT(!bb->isRemoved());
- if (emitted.alreadyProcessed(bb))
- return;
-
- sequence.append(bb);
- emitted.markAsProcessed(bb);
- }
-
- void schedule(BasicBlock *functionEntryPoint)
- {
- BasicBlock *next = functionEntryPoint;
-
- while (next) {
- emitBlock(next);
- for (int i = next->out.size(); i != 0; ) {
- // postpone all outgoing edges, if they were not already processed
- --i;
- BasicBlock *out = next->out[i];
- if (!emitted.alreadyProcessed(out))
- postpone(out);
- }
- next = pickNext();
- }
- }
-
- void postpone(BasicBlock *bb)
- {
- if (currentGroup.group == bb->containingGroup()) {
- currentGroup.postponed.append(bb);
- return;
- }
-
- for (int i = postponedGroups.size(); i != 0; ) {
- --i;
- WorkForGroup &g = postponedGroups[i];
- if (g.group == bb->containingGroup()) {
- g.postponed.append(bb);
- return;
- }
- }
-
- Q_UNREACHABLE();
- }
-
- void dumpLoopStartsEnds() const
- {
- qDebug() << "Found" << loopsStartEnd.size() << "loops:";
- for (auto key : loopsStartEnd.keys())
- qDebug("Loop starting at L%d ends at L%d.", key->index(),
- loopsStartEnd.value(key)->index());
- }
-
-public:
- BlockScheduler(IR::Function *function, const DominatorTree &dominatorTree)
- : function(function)
- , dominatorTree(dominatorTree)
- , sequence(0)
- , emitted(function)
- {}
-
- QHash<BasicBlock *, BasicBlock *> go()
- {
- showMeTheCode(function, "Before block scheduling");
- if (DebugBlockScheduler)
- dominatorTree.dumpImmediateDominators();
-
- schedule(function->basicBlock(0));
-
- Q_ASSERT(function->liveBasicBlocksCount() == sequence.size());
- function->setScheduledBlocks(sequence);
- if (DebugBlockScheduler)
- dumpLoopStartsEnds();
- return loopsStartEnd;
- }
-};
-
-#ifndef QT_NO_DEBUG
-void checkCriticalEdges(const QVector<BasicBlock *> &basicBlocks) {
- for (BasicBlock *bb : basicBlocks) {
- if (bb && bb->out.size() > 1) {
- for (BasicBlock *bb2 : bb->out) {
- if (bb2 && bb2->in.size() > 1) {
- qDebug() << "found critical edge between block"
- << bb->index() << "and block" << bb2->index();
- Q_ASSERT(false);
- }
- }
- }
- }
-}
-#endif
-
-static void cleanupBasicBlocks(IR::Function *function)
-{
- showMeTheCode(function, "Before basic block cleanup");
-
- // Algorithm: this is the iterative version of a depth-first search for all blocks that are
- // reachable through outgoing edges, starting with the start block and all exception handler
- // blocks.
- QBitArray reachableBlocks(function->basicBlockCount());
- QVarLengthArray<BasicBlock *, 16> postponed;
- for (int i = 0, ei = function->basicBlockCount(); i != ei; ++i) {
- BasicBlock *bb = function->basicBlock(i);
- if (i == 0 || bb->isExceptionHandler())
- postponed.append(bb);
- }
-
- while (!postponed.isEmpty()) {
- BasicBlock *bb = postponed.back();
- postponed.pop_back();
- if (bb->isRemoved()) // this block was removed before, we don't need to clean it up.
- continue;
-
- reachableBlocks.setBit(bb->index());
-
- for (BasicBlock *outBB : bb->out) {
- if (!reachableBlocks.at(outBB->index()))
- postponed.append(outBB);
- }
- }
-
- for (BasicBlock *bb : function->basicBlocks()) {
- if (bb->isRemoved()) // the block has already been removed, so ignore it
- continue;
- if (reachableBlocks.at(bb->index())) // the block is reachable, so ignore it
- continue;
-
- for (BasicBlock *outBB : bb->out) {
- if (outBB->isRemoved() || !reachableBlocks.at(outBB->index()))
- continue; // We do not need to unlink from blocks that are scheduled to be removed.
-
- int idx = outBB->in.indexOf(bb);
- if (idx != -1) {
- outBB->in.remove(idx);
- for (Stmt *s : outBB->statements()) {
- if (Phi *phi = s->asPhi())
- phi->incoming.remove(idx);
- else
- break;
- }
- }
- }
-
- function->removeBasicBlock(bb);
- }
-
- showMeTheCode(function, "After basic block cleanup");
-}
-
-inline Const *isConstPhi(Phi *phi)
-{
- if (Const *c = phi->incoming[0]->asConst()) {
- for (int i = 1, ei = phi->incoming.size(); i != ei; ++i) {
- if (Const *cc = phi->incoming[i]->asConst()) {
- if (c->value != cc->value)
- return 0;
- if (!(c->type == cc->type || (c->type & NumberType && cc->type & NumberType)))
- return 0;
- if (int(c->value) == 0 && int(cc->value) == 0)
- if (isNegative(c->value) != isNegative(cc->value))
- return 0;
- } else {
- return 0;
- }
- }
- return c;
- }
- return 0;
-}
-
-static Expr *clone(Expr *e, IR::Function *function) {
- if (Temp *t = e->asTemp()) {
- return CloneExpr::cloneTemp(t, function);
- } else if (Const *c = e->asConst()) {
- return CloneExpr::cloneConst(c, function);
- } else if (Name *n = e->asName()) {
- return CloneExpr::cloneName(n, function);
- } else {
- Q_UNREACHABLE();
- return e;
- }
-}
-
-class ExprReplacer
-{
- DefUses &_defUses;
- IR::Function* _function;
- Temp *_toReplace;
- Expr *_replacement;
-
-public:
- ExprReplacer(DefUses &defUses, IR::Function *function)
- : _defUses(defUses)
- , _function(function)
- , _toReplace(0)
- , _replacement(0)
- {}
-
- bool operator()(Temp *toReplace, Expr *replacement, StatementWorklist &W, QVector<Stmt *> *newUses = 0)
- {
- Q_ASSERT(replacement->asTemp() || replacement->asConst() || replacement->asName());
-
- qSwap(_toReplace, toReplace);
- qSwap(_replacement, replacement);
-
- const QVector<Stmt *> &uses = _defUses.uses(*_toReplace);
-
- // Prevent the following:
- // L3:
- // %1 = phi L1: %2, L2: %3
- // %4 = phi L1: %5, L2: %6
- // %6 = %1
- // From turning into:
- // L3:
- // %1 = phi L1: %2, L2: %3
- // %4 = phi L1: %5, L2: %1
- //
- // Because both phi nodes are "executed in parallel", we cannot replace %6 by %1 in the
- // second phi node. So, if the defining statement for a temp is a phi node, and one of the
- // uses of the to-be-replaced statement is a phi node in the same block as the defining
- // statement, bail out.
- if (Temp *r = _replacement->asTemp()) {
- if (_defUses.defStmt(*r)->asPhi()) {
- BasicBlock *replacementDefBlock = _defUses.defStmtBlock(*r);
- for (Stmt *use : uses) {
- if (Phi *usePhi = use->asPhi()) {
- if (_defUses.defStmtBlock(*usePhi->targetTemp) == replacementDefBlock)
- return false;
- }
- }
- }
- }
-
-// qout << "Replacing ";toReplace->dump(qout);qout<<" by ";replacement->dump(qout);qout<<endl;
-
- if (newUses)
- newUses->reserve(uses.size());
-
-// qout << " " << uses.size() << " uses:"<<endl;
- for (Stmt *use : uses) {
-// qout<<" ";use->dump(qout);qout<<"\n";
- visit(use);
-// qout<<" -> ";use->dump(qout);qout<<"\n";
- W += use;
- if (newUses)
- newUses->push_back(use);
- }
-
- qSwap(_replacement, replacement);
- qSwap(_toReplace, toReplace);
- return true;
- }
-
-private:
- void visit(Expr *e)
- {
- if (auto c = e->asConst()) {
- visitConst(c);
- } else if (auto s = e->asString()) {
- visitString(s);
- } else if (auto r = e->asRegExp()) {
- visitRegExp(r);
- } else if (auto n = e->asName()) {
- visitName(n);
- } else if (auto t = e->asTemp()) {
- visitTemp(t);
- } else if (auto a = e->asArgLocal()) {
- visitArgLocal(a);
- } else if (auto c = e->asClosure()) {
- visitClosure(c);
- } else if (auto c = e->asConvert()) {
- visitConvert(c);
- } else if (auto u = e->asUnop()) {
- visitUnop(u);
- } else if (auto b = e->asBinop()) {
- visitBinop(b);
- } else if (auto c = e->asCall()) {
- visitCall(c);
- } else if (auto n = e->asNew()) {
- visitNew(n);
- } else if (auto s = e->asSubscript()) {
- visitSubscript(s);
- } else if (auto m = e->asMember()) {
- visitMember(m);
- } else {
- Q_UNREACHABLE();
- }
- }
-
- void visitConst(Const *) {}
- void visitString(IR::String *) {}
- void visitRegExp(IR::RegExp *) {}
- void visitName(Name *) {}
- void visitTemp(Temp *) {}
- void visitArgLocal(ArgLocal *) {}
- void visitClosure(Closure *) {}
- void visitConvert(Convert *e) { check(e->expr); }
- void visitUnop(Unop *e) { check(e->expr); }
- void visitBinop(Binop *e) { check(e->left); check(e->right); }
- void visitCall(Call *e) {
- check(e->base);
- for (ExprList *it = e->args; it; it = it->next)
- check(it->expr);
- }
- void visitNew(New *e) {
- check(e->base);
- for (ExprList *it = e->args; it; it = it->next)
- check(it->expr);
- }
- void visitSubscript(Subscript *e) { check(e->base); check(e->index); }
- void visitMember(Member *e) { check(e->base); }
-
- void visit(Stmt *s)
- {
- if (auto e = s->asExp()) {
- visitExp(e);
- } else if (auto m = s->asMove()) {
- visitMove(m);
- } else if (auto j = s->asJump()) {
- visitJump(j);
- } else if (auto c = s->asCJump()) {
- visitCJump(c);
- } else if (auto r = s->asRet()) {
- visitRet(r);
- } else if (auto p = s->asPhi()) {
- visitPhi(p);
- } else {
- Q_UNREACHABLE();
- }
- }
-
- void visitExp(Exp *s) { check(s->expr); }
- void visitMove(Move *s) { check(s->target); check(s->source); }
- void visitJump(Jump *) {}
- void visitCJump(CJump *s) { check(s->cond); }
- void visitRet(Ret *s) { check(s->expr); }
- void visitPhi(Phi *s) {
- for (int i = 0, ei = s->incoming.size(); i != ei; ++i)
- check(s->incoming[i]);
- }
-
-private:
- void check(Expr *&e) {
- if (equals(e, _toReplace)) {
- e = clone(_replacement, _function);
- } else {
- visit(e);
- }
- }
-
- // This only calculates equality for everything needed by constant propagation
- bool equals(Expr *e1, Expr *e2) const {
- if (e1 == e2)
- return true;
-
- if (Const *c1 = e1->asConst()) {
- if (Const *c2 = e2->asConst())
- return c1->value == c2->value && (c1->type == c2->type || (c1->type & NumberType && c2->type & NumberType));
- } else if (Temp *t1 = e1->asTemp()) {
- if (Temp *t2 = e2->asTemp())
- return *t1 == *t2;
- } else if (Name *n1 = e1->asName()) {
- if (Name *n2 = e2->asName()) {
- if (n1->id) {
- if (n2->id)
- return *n1->id == *n2->id;
- } else {
- return n1->builtin == n2->builtin;
- }
- }
- }
-
- if (e1->type == IR::NullType && e2->type == IR::NullType)
- return true;
- if (e1->type == IR::UndefinedType && e2->type == IR::UndefinedType)
- return true;
-
- return false;
- }
-};
-
-namespace {
-/// This function removes the basic-block from the function's list, unlinks any uses and/or defs,
-/// and removes unreachable staements from the worklist, so that optimiseSSA won't consider them
-/// anymore.
-void unlink(BasicBlock *from, BasicBlock *to, IR::Function *func, DefUses &defUses,
- StatementWorklist &W, DominatorTree &dt)
-{
- enum { DebugUnlinking = 0 };
-
- struct Util {
- static void removeIncomingEdge(BasicBlock *from, BasicBlock *to, DefUses &defUses, StatementWorklist &W)
- {
- int idx = to->in.indexOf(from);
- if (idx == -1)
- return;
-
- to->in.remove(idx);
- for (Stmt *outStmt : to->statements()) {
- if (!outStmt)
- continue;
- if (Phi *phi = outStmt->asPhi()) {
- if (Temp *t = phi->incoming[idx]->asTemp()) {
- defUses.removeUse(phi, *t);
- W += defUses.defStmt(*t);
- }
- phi->incoming.remove(idx);
- W += phi;
- } else {
- break;
- }
- }
- }
-
- static bool isReachable(BasicBlock *bb, const DominatorTree &dt)
- {
- for (BasicBlock *in : bb->in) {
- if (in->isRemoved())
- continue;
- if (dt.dominates(bb, in)) // a back-edge, not interesting
- continue;
- return true;
- }
-
- return false;
- }
- };
-
- Q_ASSERT(!from->isRemoved());
- Q_ASSERT(!to->isRemoved());
-
- // don't purge blocks that are entry points for catch statements. They might not be directly
- // connected, but are required anyway
- if (to->isExceptionHandler())
- return;
-
- if (DebugUnlinking)
- qDebug("Unlinking L%d -> L%d...", from->index(), to->index());
-
- // First, unlink the edge
- from->out.removeOne(to);
- Util::removeIncomingEdge(from, to, defUses, W);
-
- BasicBlockSet siblings;
- siblings.init(func);
-
- // Check if the target is still reachable...
- if (Util::isReachable(to, dt)) { // yes, recalculate the immediate dominator, and we're done.
- if (DebugUnlinking)
- qDebug(".. L%d is still reachable, recalulate idom.", to->index());
- dt.collectSiblings(to, siblings);
- } else {
- if (DebugUnlinking)
- qDebug(".. L%d is unreachable, purging it:", to->index());
- // The target is unreachable, so purge it:
- QVector<BasicBlock *> toPurge;
- toPurge.reserve(8);
- toPurge.append(to);
- while (!toPurge.isEmpty()) {
- BasicBlock *bb = toPurge.first();
- toPurge.removeFirst();
- if (DebugUnlinking)
- qDebug("... purging L%d", bb->index());
-
- if (bb->isRemoved())
- continue;
-
- // unlink all incoming edges
- for (BasicBlock *in : bb->in) {
- int idx = in->out.indexOf(bb);
- if (idx != -1)
- in->out.remove(idx);
- }
-
- // unlink all outgoing edges, including "arguments" to phi statements
- for (BasicBlock *out : bb->out) {
- if (out->isRemoved())
- continue;
-
- Util::removeIncomingEdge(bb, out, defUses, W);
-
- if (Util::isReachable(out, dt)) {
- dt.collectSiblings(out, siblings);
- } else {
- // if a successor has no incoming edges after unlinking the current basic block,
- // then it is unreachable, and can be purged too
- toPurge.append(out);
- }
- }
-
- // unlink all defs/uses from the statements in the basic block
- for (Stmt *s : bb->statements()) {
- if (!s)
- continue;
-
- W += defUses.removeDefUses(s);
- W -= s;
- }
-
- siblings.remove(bb);
- dt.setImmediateDominator(bb, 0);
- func->removeBasicBlock(bb);
- }
- }
-
- dt.recalculateIDoms(siblings);
- if (DebugUnlinking)
- qDebug("Unlinking done.");
-}
-
-bool tryOptimizingComparison(Expr *&expr)
-{
- Binop *b = expr->asBinop();
- if (!b)
- return false;
- Const *leftConst = b->left->asConst();
- if (!leftConst || leftConst->type == StringType || leftConst->type == VarType || leftConst->type == QObjectType)
- return false;
- Const *rightConst = b->right->asConst();
- if (!rightConst || rightConst->type == StringType || rightConst->type == VarType || rightConst->type == QObjectType)
- return false;
-
- QV4::Primitive l = convertToValue(leftConst);
- QV4::Primitive r = convertToValue(rightConst);
-
- switch (b->op) {
- case OpGt:
- leftConst->value = Runtime::method_compareGreaterThan(l, r);
- leftConst->type = BoolType;
- expr = leftConst;
- return true;
- case OpLt:
- leftConst->value = Runtime::method_compareLessThan(l, r);
- leftConst->type = BoolType;
- expr = leftConst;
- return true;
- case OpGe:
- leftConst->value = Runtime::method_compareGreaterEqual(l, r);
- leftConst->type = BoolType;
- expr = leftConst;
- return true;
- case OpLe:
- leftConst->value = Runtime::method_compareLessEqual(l, r);
- leftConst->type = BoolType;
- expr = leftConst;
- return true;
- case OpStrictEqual:
- leftConst->value = Runtime::method_compareStrictEqual(l, r);
- leftConst->type = BoolType;
- expr = leftConst;
- return true;
- case OpEqual:
- leftConst->value = Runtime::method_compareEqual(l, r);
- leftConst->type = BoolType;
- expr = leftConst;
- return true;
- case OpStrictNotEqual:
- leftConst->value = Runtime::method_compareStrictNotEqual(l, r);
- leftConst->type = BoolType;
- expr = leftConst;
- return true;
- case OpNotEqual:
- leftConst->value = Runtime::method_compareNotEqual(l, r);
- leftConst->type = BoolType;
- expr = leftConst;
- return true;
- default:
- break;
- }
-
- return false;
-}
-
-void cfg2dot(IR::Function *f, const QVector<LoopDetection::LoopInfo *> &loops = QVector<LoopDetection::LoopInfo *>())
-{
- static const bool showCode = qEnvironmentVariableIsSet("QV4_SHOW_IR");
- if (!showCode)
- return;
-
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream qout(&buf);
-
- struct Util {
- QTextStream &qout;
- Util(QTextStream &qout): qout(qout) {}
- void genLoop(const LoopDetection::LoopInfo *loop)
- {
- qout << " subgraph \"cluster" << quint64(loop) << "\" {\n";
- qout << " L" << loop->loopHeader->index() << ";\n";
- for (BasicBlock *bb : loop->loopBody)
- qout << " L" << bb->index() << ";\n";
- for (LoopDetection::LoopInfo *nested : loop->nestedLoops)
- genLoop(nested);
- qout << " }\n";
- }
- };
-
- QString name;
- if (f->name) name = *f->name;
- else name = QStringLiteral("%1").arg((unsigned long long)f);
- qout << "digraph \"" << name << "\" { ordering=out;\n";
-
- for (LoopDetection::LoopInfo *l : loops) {
- if (l->parentLoop == 0)
- Util(qout).genLoop(l);
- }
-
- for (BasicBlock *bb : f->basicBlocks()) {
- if (bb->isRemoved())
- continue;
-
- int idx = bb->index();
- qout << " L" << idx << " [label=\"L" << idx << "\"";
- if (idx == 0 || bb->terminator()->asRet())
- qout << ", shape=doublecircle";
- else
- qout << ", shape=circle";
- qout << "];\n";
- for (BasicBlock *out : bb->out)
- qout << " L" << idx << " -> L" << out->index() << "\n";
- }
-
- qout << "}\n";
- buf.close();
- qDebug("%s", buf.data().constData());
-}
-
-} // anonymous namespace
-
-void optimizeSSA(StatementWorklist &W, DefUses &defUses, DominatorTree &df)
-{
- IR::Function *function = W.function();
- ExprReplacer replaceUses(defUses, function);
-
- Stmt *s = 0;
- while ((s = W.takeNext(s))) {
-
- if (Phi *phi = s->asPhi()) {
- // dead code elimination:
- if (defUses.useCount(*phi->targetTemp) == 0) {
- W += defUses.removeDefUses(phi);
- W.remove(s);
- continue;
- }
-
- // constant propagation:
- if (Const *c = isConstPhi(phi)) {
- replaceUses(phi->targetTemp, c, W);
- defUses.removeDef(*phi->targetTemp);
- W.remove(s);
- continue;
- }
-
- // copy propagation:
- if (phi->incoming.size() == 1) {
- Temp *t = phi->targetTemp;
- Expr *e = phi->incoming.first();
-
- QVector<Stmt *> newT2Uses;
- replaceUses(t, e, W, &newT2Uses);
- if (Temp *t2 = e->asTemp()) {
- defUses.removeUse(s, *t2);
- defUses.addUses(*t2, newT2Uses);
- W += defUses.defStmt(*t2);
- }
- defUses.removeDef(*t);
- W.remove(s);
- continue;
- }
- } else if (Move *m = s->asMove()) {
- if (Convert *convert = m->source->asConvert()) {
- if (Const *sourceConst = convert->expr->asConst()) {
- convertConst(sourceConst, convert->type);
- m->source = sourceConst;
- W += m;
- continue;
- } else if (Temp *sourceTemp = convert->expr->asTemp()) {
- if (sourceTemp->type == convert->type) {
- m->source = sourceTemp;
- W += m;
- continue;
- }
- }
- }
-
- if (Temp *targetTemp = m->target->asTemp()) {
- // dead code elimination:
- if (defUses.useCount(*targetTemp) == 0) {
- EliminateDeadCode(defUses, W).run(m->source, s);
- if (!m->source)
- W.remove(s);
- continue;
- }
-
- // constant propagation:
- if (Const *sourceConst = m->source->asConst()) {
- Q_ASSERT(sourceConst->type != UnknownType);
- replaceUses(targetTemp, sourceConst, W);
- defUses.removeDef(*targetTemp);
- W.remove(s);
- continue;
- }
- if (Member *member = m->source->asMember()) {
- if (member->kind == Member::MemberOfEnum) {
- Const *c = function->New<Const>();
- const int enumValue = member->enumValue;
- c->init(SInt32Type, enumValue);
- replaceUses(targetTemp, c, W);
- defUses.removeDef(*targetTemp);
- W.remove(s);
- defUses.removeUse(s, *member->base->asTemp());
- continue;
- } else if (member->kind != IR::Member::MemberOfIdObjectsArray && member->attachedPropertiesId != 0 && member->property && member->base->asTemp()) {
- // Attached properties have no dependency on their base. Isel doesn't
- // need it and we can eliminate the temp used to initialize it.
- defUses.removeUse(s, *member->base->asTemp());
- Const *c = function->New<Const>();
- c->init(SInt32Type, 0);
- member->base = c;
- continue;
- }
- }
-
- // copy propagation:
- if (Temp *sourceTemp = m->source->asTemp()) {
- QVector<Stmt *> newT2Uses;
- if (replaceUses(targetTemp, sourceTemp, W, &newT2Uses)) {
- defUses.removeUse(s, *sourceTemp);
- defUses.addUses(*sourceTemp, newT2Uses);
- defUses.removeDef(*targetTemp);
- W.remove(s);
- }
- continue;
- }
-
- if (Unop *unop = m->source->asUnop()) {
- // Constant unary expression evaluation:
- if (Const *constOperand = unop->expr->asConst()) {
- if (constOperand->type & NumberType || constOperand->type == BoolType) {
- // TODO: implement unop propagation for other constant types
- bool doneSomething = false;
- switch (unop->op) {
- case OpNot:
- constOperand->value = !constOperand->value;
- constOperand->type = BoolType;
- doneSomething = true;
- break;
- case OpUMinus:
- if (int(constOperand->value) == 0 && int(constOperand->value) == constOperand->value) {
- if (isNegative(constOperand->value))
- constOperand->value = 0;
- else
- constOperand->value = -1 / Q_INFINITY;
- constOperand->type = DoubleType;
- doneSomething = true;
- break;
- }
-
- constOperand->value = -constOperand->value;
- doneSomething = true;
- break;
- case OpUPlus:
- if (unop->type != UnknownType)
- constOperand->type = unop->type;
- doneSomething = true;
- break;
- case OpCompl:
- constOperand->value = ~QV4::Primitive::toInt32(constOperand->value);
- constOperand->type = SInt32Type;
- doneSomething = true;
- break;
- case OpIncrement:
- constOperand->value = constOperand->value + 1;
- doneSomething = true;
- break;
- case OpDecrement:
- constOperand->value = constOperand->value - 1;
- doneSomething = true;
- break;
- default:
- break;
- };
-
- if (doneSomething) {
- m->source = constOperand;
- W += m;
- }
- }
- }
- // TODO: if the result of a unary not operation is only used in a cjump,
- // then inline it.
-
- continue;
- }
-
- if (Binop *binop = m->source->asBinop()) {
- Const *leftConst = binop->left->asConst();
- Const *rightConst = binop->right->asConst();
-
- { // Typical casts to int32:
- Expr *casted = 0;
- switch (binop->op) {
- case OpBitAnd:
- if (leftConst && !rightConst && QV4::Primitive::toUInt32(leftConst->value) == 0xffffffff)
- casted = binop->right;
- else if (!leftConst && rightConst && QV4::Primitive::toUInt32(rightConst->value) == 0xffffffff)
- casted = binop->left;
- break;
- case OpBitOr:
- if (leftConst && !rightConst && QV4::Primitive::toInt32(leftConst->value) == 0)
- casted = binop->right;
- else if (!leftConst && rightConst && QV4::Primitive::toUInt32(rightConst->value) == 0)
- casted = binop->left;
- break;
- default:
- break;
- }
- if (casted && casted->type == SInt32Type) {
- m->source = casted;
- W += m;
- continue;
- }
- }
- if (rightConst) {
- switch (binop->op) {
- case OpLShift:
- case OpRShift:
- if (double v = QV4::Primitive::toInt32(rightConst->value) & 0x1f) {
- // mask right hand side of shift operations
- rightConst->value = v;
- rightConst->type = SInt32Type;
- } else {
- // shifting a value over 0 bits is a move:
- if (rightConst->value == 0) {
- m->source = binop->left;
- W += m;
- }
- }
-
- break;
- default:
- break;
- }
- }
-
- // TODO: More constant binary expression evaluation
- // TODO: If the result of the move is only used in one single cjump, then
- // inline the binop into the cjump.
- if (!leftConst || leftConst->type == StringType || leftConst->type == VarType || leftConst->type == QObjectType)
- continue;
- if (!rightConst || rightConst->type == StringType || rightConst->type == VarType || rightConst->type == QObjectType)
- continue;
-
- QV4::Primitive lc = convertToValue(leftConst);
- QV4::Primitive rc = convertToValue(rightConst);
- double l = lc.toNumber();
- double r = rc.toNumber();
-
- switch (binop->op) {
- case OpMul:
- leftConst->value = l * r;
- leftConst->type = DoubleType;
- m->source = leftConst;
- W += m;
- break;
- case OpAdd:
- leftConst->value = l + r;
- leftConst->type = DoubleType;
- m->source = leftConst;
- W += m;
- break;
- case OpSub:
- leftConst->value = l - r;
- leftConst->type = DoubleType;
- m->source = leftConst;
- W += m;
- break;
- case OpDiv:
- leftConst->value = l / r;
- leftConst->type = DoubleType;
- m->source = leftConst;
- W += m;
- break;
- case OpMod:
- leftConst->value = std::fmod(l, r);
- leftConst->type = DoubleType;
- m->source = leftConst;
- W += m;
- break;
- default:
- if (tryOptimizingComparison(m->source))
- W += m;
- break;
- }
-
- continue;
- }
- } // TODO: var{#0} = double{%10} where %10 is defined once and used once. E.g.: function(t){t = t % 2; return t; }
-
- } else if (CJump *cjump = s->asCJump()) {
- if (Const *constantCondition = cjump->cond->asConst()) {
- // Note: this assumes that there are no critical edges! Meaning, we can safely purge
- // any basic blocks that are found to be unreachable.
- Jump *jump = function->NewStmt<Jump>();
- W.registerNewStatement(jump);
- if (convertToValue(constantCondition).toBoolean()) {
- jump->target = cjump->iftrue;
- unlink(cjump->parent, cjump->iffalse, function, defUses, W, df);
- } else {
- jump->target = cjump->iffalse;
- unlink(cjump->parent, cjump->iftrue, function, defUses, W, df);
- }
- W.replace(s, jump);
-
- continue;
- } else if (cjump->cond->asBinop()) {
- if (tryOptimizingComparison(cjump->cond))
- W += cjump;
- continue;
- }
- // TODO: Constant unary expression evaluation
- // TODO: if the expression is an unary not operation, lift the expression, and switch
- // the then/else blocks.
- }
- }
-
- W.applyToFunction();
-}
-
-//### TODO: use DefUses from the optimizer, because it already has all this information
-class InputOutputCollector
-{
- void setOutput(Temp *out)
- {
- Q_ASSERT(!output);
- output = out;
- }
-
-public:
- std::vector<Temp *> inputs;
- Temp *output;
-
- InputOutputCollector()
- { inputs.reserve(4); }
-
- void collect(Stmt *s) {
- inputs.resize(0);
- output = 0;
- visit(s);
- }
-
-private:
- void visit(Expr *e)
- {
- if (auto t = e->asTemp()) {
- inputs.push_back(t);
- } else {
- EXPR_VISIT_ALL_KINDS(e);
- }
- }
-
- void visit(Stmt *s)
- {
- if (auto m = s->asMove()) {
- visit(m->source);
- if (Temp *t = m->target->asTemp()) {
- setOutput(t);
- } else {
- visit(m->target);
- }
- } else if (s->asPhi()) {
- // Handled separately
- } else {
- STMT_VISIT_ALL_KINDS(s);
- }
- }
-};
-
-/*
- * The algorithm is described in:
- *
- * Linear Scan Register Allocation on SSA Form
- * Christian Wimmer & Michael Franz, CGO'10, April 24-28, 2010
- *
- * See LifeTimeIntervals::renumber for details on the numbering.
- */
-class LifeRanges {
- class LiveRegs
- {
- typedef std::vector<int> Storage;
- Storage regs;
-
- public:
- void insert(int r)
- {
- if (find(r) == end())
- regs.push_back(r);
- }
-
- void unite(const LiveRegs &other)
- {
- if (other.empty())
- return;
- if (empty()) {
- regs = other.regs;
- return;
- }
- for (int r : other.regs)
- insert(r);
- }
-
- typedef Storage::iterator iterator;
- iterator find(int r)
- { return std::find(regs.begin(), regs.end(), r); }
-
- iterator begin()
- { return regs.begin(); }
-
- iterator end()
- { return regs.end(); }
-
- void erase(iterator it)
- { regs.erase(it); }
-
- void remove(int r)
- {
- iterator it = find(r);
- if (it != end())
- erase(it);
- }
-
- bool empty() const
- { return regs.empty(); }
-
- int size() const
- { return int(regs.size()); }
-
- int at(int idx) const
- { return regs.at(idx); }
- };
-
- std::vector<LiveRegs> _liveIn;
- std::vector<LifeTimeInterval *> _intervals;
- LifeTimeIntervals::Ptr _sortedIntervals;
-
- LifeTimeInterval &interval(const Temp *temp)
- {
- LifeTimeInterval *lti = _intervals[temp->index];
- Q_ASSERT(lti);
- return *lti;
- }
-
- void ensureInterval(const IR::Temp &temp)
- {
- Q_ASSERT(!temp.isInvalid());
- LifeTimeInterval *&lti = _intervals[temp.index];
- if (lti)
- return;
- lti = new LifeTimeInterval;
- lti->setTemp(temp);
- }
-
- int defPosition(IR::Stmt *s) const
- {
- return usePosition(s) + 1;
- }
-
- int usePosition(IR::Stmt *s) const
- {
- return _sortedIntervals->positionForStatement(s);
- }
-
- int start(IR::BasicBlock *bb) const
- {
- return _sortedIntervals->startPosition(bb);
- }
-
- int end(IR::BasicBlock *bb) const
- {
- return _sortedIntervals->endPosition(bb);
- }
-
-public:
- LifeRanges(IR::Function *function, const QHash<BasicBlock *, BasicBlock *> &startEndLoops)
- : _intervals(function->tempCount)
- {
- _sortedIntervals = LifeTimeIntervals::create(function);
- _liveIn.resize(function->basicBlockCount());
-
- for (int i = function->basicBlockCount() - 1; i >= 0; --i) {
- BasicBlock *bb = function->basicBlock(i);
- buildIntervals(bb, startEndLoops.value(bb, 0));
- }
-
- _intervals.clear();
- }
-
- LifeTimeIntervals::Ptr intervals() const { return _sortedIntervals; }
-
- void dump() const
- {
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream qout(&buf);
-
- qout << "Life ranges:" << endl;
- qout << "Intervals:" << endl;
- const auto intervals = _sortedIntervals->intervals();
- for (const LifeTimeInterval *range : intervals) {
- range->dump(qout);
- qout << endl;
- }
-
- IRPrinter printer(&qout);
- for (size_t i = 0, ei = _liveIn.size(); i != ei; ++i) {
- qout << "L" << i <<" live-in: ";
- auto live = _liveIn.at(i);
- if (live.empty())
- qout << "(none)";
- std::sort(live.begin(), live.end());
- for (int i = 0; i < live.size(); ++i) {
- if (i > 0) qout << ", ";
- qout << '%' << live.at(i);
- }
- qout << endl;
- }
- buf.close();
- qDebug("%s", buf.data().constData());
- }
-
-private:
- void buildIntervals(BasicBlock *bb, BasicBlock *loopEnd)
- {
- LiveRegs live;
- for (BasicBlock *successor : bb->out) {
- live.unite(_liveIn[successor->index()]);
- const int bbIndex = successor->in.indexOf(bb);
- Q_ASSERT(bbIndex >= 0);
-
- for (Stmt *s : successor->statements()) {
- if (Phi *phi = s->asPhi()) {
- if (Temp *t = phi->incoming.at(bbIndex)->asTemp()) {
- ensureInterval(*t);
- live.insert(t->index);
- }
- } else {
- break;
- }
- }
- }
-
- const QVector<Stmt *> &statements = bb->statements();
-
- for (int reg : live)
- _intervals[reg]->addRange(start(bb), end(bb));
-
- InputOutputCollector collector;
- for (int i = statements.size() - 1; i >= 0; --i) {
- Stmt *s = statements.at(i);
- if (Phi *phi = s->asPhi()) {
- ensureInterval(*phi->targetTemp);
- LiveRegs::iterator it = live.find(phi->targetTemp->index);
- if (it == live.end()) {
- // a phi node target that is only defined, but never used
- interval(phi->targetTemp).setFrom(start(bb));
- } else {
- live.erase(it);
- }
- _sortedIntervals->add(&interval(phi->targetTemp));
- continue;
- }
- collector.collect(s);
- //### TODO: use DefUses from the optimizer, because it already has all this information
- if (Temp *opd = collector.output) {
- ensureInterval(*opd);
- LifeTimeInterval &lti = interval(opd);
- lti.setFrom(defPosition(s));
- live.remove(lti.temp().index);
- _sortedIntervals->add(&lti);
- }
- //### TODO: use DefUses from the optimizer, because it already has all this information
- for (size_t i = 0, ei = collector.inputs.size(); i != ei; ++i) {
- Temp *opd = collector.inputs[i];
- ensureInterval(*opd);
- interval(opd).addRange(start(bb), usePosition(s));
- live.insert(opd->index);
- }
- }
-
- if (loopEnd) { // Meaning: bb is a loop header, because loopEnd is set to non-null.
- for (int reg : live)
- _intervals[reg]->addRange(start(bb), usePosition(loopEnd->terminator()));
- }
-
- _liveIn[bb->index()] = std::move(live);
- }
-};
-
-void removeUnreachleBlocks(IR::Function *function)
-{
- QVector<BasicBlock *> newSchedule;
- newSchedule.reserve(function->basicBlockCount());
- for (BasicBlock *bb : function->basicBlocks())
- if (!bb->isRemoved())
- newSchedule.append(bb);
- function->setScheduledBlocks(newSchedule);
-}
-
-class ConvertArgLocals
-{
-public:
- ConvertArgLocals(IR::Function *function)
- : function(function)
- , convertArgs(!function->usesArgumentsObject)
- {
- tempForFormal.resize(function->formals.size(), -1);
- tempForLocal.resize(function->locals.size(), -1);
- }
-
- void toTemps()
- {
- if (function->variablesCanEscape())
- return;
-
- QVector<Stmt *> extraMoves;
- if (convertArgs) {
- const int formalCount = function->formals.size();
- extraMoves.reserve(formalCount + function->basicBlock(0)->statementCount());
- extraMoves.resize(formalCount);
-
- for (int i = 0; i != formalCount; ++i) {
- const int newTemp = function->tempCount++;
- tempForFormal[i] = newTemp;
-
- ArgLocal *source = function->New<ArgLocal>();
- source->init(ArgLocal::Formal, i, 0);
-
- Temp *target = function->New<Temp>();
- target->init(Temp::VirtualRegister, newTemp);
-
- Move *m = function->NewStmt<Move>();
- m->init(target, source);
- extraMoves[i] = m;
- }
- }
-
- for (BasicBlock *bb : function->basicBlocks()) {
- if (!bb->isRemoved()) {
- for (Stmt *s : bb->statements()) {
- visit(s);
- }
- }
- }
-
- if (convertArgs && function->formals.size() > 0)
- function->basicBlock(0)->prependStatements(extraMoves);
-
- function->locals.clear();
- }
-
-private:
- void visit(Stmt *s)
- {
- if (auto e = s->asExp()) {
- check(e->expr);
- } else if (auto m = s->asMove()) {
- check(m->target); check(m->source);
- } else if (auto c = s->asCJump()) {
- check(c->cond);
- } else if (auto r = s->asRet()) {
- check(r->expr);
- }
- }
-
- void visit(Expr *e)
- {
- if (auto c = e->asConvert()) {
- check(c->expr);
- } else if (auto u = e->asUnop()) {
- check(u->expr);
- } else if (auto b = e->asBinop()) {
- check(b->left); check(b->right);
- } else if (auto c = e->asCall()) {
- check(c->base);
- for (ExprList *it = c->args; it; it = it->next) {
- check(it->expr);
- }
- } else if (auto n = e->asNew()) {
- check(n->base);
- for (ExprList *it = n->args; it; it = it->next) {
- check(it->expr);
- }
- } else if (auto s = e->asSubscript()) {
- check(s->base); check(s->index);
- } else if (auto m = e->asMember()) {
- check(m->base);
- }
- }
-
- void check(Expr *&e) {
- if (ArgLocal *al = e->asArgLocal()) {
- if (al->kind == ArgLocal::Local) {
- Temp *t = function->New<Temp>();
- t->init(Temp::VirtualRegister, fetchTempForLocal(al->index));
- e = t;
- } else if (convertArgs && al->kind == ArgLocal::Formal) {
- Temp *t = function->New<Temp>();
- t->init(Temp::VirtualRegister, fetchTempForFormal(al->index));
- e = t;
- }
- } else {
- visit(e);
- }
- }
-
- int fetchTempForLocal(int local)
- {
- int &ref = tempForLocal[local];
- if (ref == -1)
- ref = function->tempCount++;
- return ref;
- }
-
- int fetchTempForFormal(int formal)
- {
- return tempForFormal[formal];
- }
-
- IR::Function *function;
- bool convertArgs;
- std::vector<int> tempForFormal;
- std::vector<int> tempForLocal;
-};
-
-class CloneBasicBlock: protected CloneExpr
-{
-public:
- BasicBlock *operator()(IR::BasicBlock *originalBlock)
- {
- block = new BasicBlock(originalBlock->function, 0);
-
- for (Stmt *s : originalBlock->statements()) {
- visit(s);
- clonedStmt->location = s->location;
- }
-
- return block;
- }
-
-private:
- void visit(Stmt *s)
- {
- if (auto e = s->asExp()) {
- clonedStmt = block->EXP(clone(e->expr));
- } else if (auto m = s->asMove()) {
- clonedStmt = block->MOVE(clone(m->target), clone(m->source));
- } else if (auto j = s->asJump()) {
- clonedStmt = block->JUMP(j->target);
- } else if (auto c = s->asCJump()) {
- clonedStmt = block->CJUMP(clone(c->cond), c->iftrue, c->iffalse);
- } else if (auto r = s->asRet()) {
- clonedStmt = block->RET(clone(r->expr));
- } else if (auto p = s->asPhi()) {
- Phi *phi = block->function->NewStmt<Phi>();
- clonedStmt = phi;
-
- phi->targetTemp = clone(p->targetTemp);
- for (Expr *in : p->incoming)
- phi->incoming.append(clone(in));
- block->appendStatement(phi);
- } else {
- Q_UNREACHABLE();
- }
- }
-
-private:
- IR::Stmt *clonedStmt;
-};
-
-static void verifyCFG(IR::Function *function)
-{
- if (!DoVerification)
- return;
-
- for (BasicBlock *bb : function->basicBlocks()) {
- if (bb->isRemoved()) {
- Q_ASSERT(bb->in.isEmpty());
- Q_ASSERT(bb->out.isEmpty());
- continue;
- }
-
- Q_ASSERT(function->basicBlock(bb->index()) == bb);
-
- // Check the terminators:
- Stmt *terminator = bb->terminator();
- if (terminator == nullptr) {
- Stmt *last = bb->statements().last();
- Call *call = last->asExp()->expr->asCall();
- Name *baseName = call->base->asName();
- Q_ASSERT(baseName->builtin == Name::builtin_rethrow);
- Q_UNUSED(baseName);
- } else if (Jump *jump = terminator->asJump()) {
- Q_UNUSED(jump);
- Q_ASSERT(jump->target);
- Q_ASSERT(!jump->target->isRemoved());
- Q_ASSERT(bb->out.size() == 1);
- Q_ASSERT(bb->out.first() == jump->target);
- } else if (CJump *cjump = terminator->asCJump()) {
- Q_UNUSED(cjump);
- Q_ASSERT(bb->out.size() == 2);
- Q_ASSERT(cjump->iftrue);
- Q_ASSERT(!cjump->iftrue->isRemoved());
- Q_ASSERT(cjump->iftrue == bb->out[0]);
- Q_ASSERT(cjump->iffalse);
- Q_ASSERT(!cjump->iffalse->isRemoved());
- Q_ASSERT(cjump->iffalse == bb->out[1]);
- } else if (terminator->asRet()) {
- Q_ASSERT(bb->out.size() == 0);
- } else {
- Q_UNREACHABLE();
- }
-
- // Check the outgoing edges:
- for (BasicBlock *out : bb->out) {
- Q_UNUSED(out);
- Q_ASSERT(!out->isRemoved());
- Q_ASSERT(out->in.contains(bb));
- }
-
- // Check the incoming edges:
- for (BasicBlock *in : bb->in) {
- Q_UNUSED(in);
- Q_ASSERT(!in->isRemoved());
- Q_ASSERT(in->out.contains(bb));
- }
- }
-}
-
-static void verifyImmediateDominators(const DominatorTree &dt, IR::Function *function)
-{
- if (!DoVerification)
- return;
-
- cfg2dot(function);
- dt.dumpImmediateDominators();
- DominatorTree referenceTree(function);
-
- for (BasicBlock *bb : function->basicBlocks()) {
- if (bb->isRemoved())
- continue;
-
- BasicBlock *idom = dt.immediateDominator(bb);
- BasicBlock *referenceIdom = referenceTree.immediateDominator(bb);
- Q_UNUSED(idom);
- Q_UNUSED(referenceIdom);
- Q_ASSERT(idom == referenceIdom);
- }
-}
-
-static void verifyNoPointerSharing(IR::Function *function)
-{
- if (!DoVerification)
- return;
-
- class {
- public:
- void operator()(IR::Function *f)
- {
- for (BasicBlock *bb : f->basicBlocks()) {
- if (bb->isRemoved())
- continue;
-
- for (Stmt *s : bb->statements()) {
- visit(s);
- }
- }
- }
-
- private:
- void visit(Stmt *s)
- {
- check(s);
- STMT_VISIT_ALL_KINDS(s);
- }
-
- void visit(Expr *e)
- {
- check(e);
- EXPR_VISIT_ALL_KINDS(e);
- }
-
- private:
- void check(Stmt *s)
- {
- Q_ASSERT(!stmts.contains(s));
- stmts.insert(s);
- }
-
- void check(Expr *e)
- {
- Q_ASSERT(!exprs.contains(e));
- exprs.insert(e);
- }
-
- QSet<Stmt *> stmts;
- QSet<Expr *> exprs;
- } V;
- V(function);
-}
-
-// Loop-peeling is done by unfolding the loop once. The "original" loop basic blocks stay where they
-// are, and a copy of the loop is placed after it. Special care is taken while copying the loop body:
-// by having the copies of the basic-blocks point to the same nodes as the "original" basic blocks,
-// updating the immediate dominators is easy: if the edge of a copied basic-block B points to a
-// block C that has also been copied, set the immediate dominator of B to the corresponding
-// immediate dominator of C. Finally, for any node outside the loop that gets a new edge attached,
-// the immediate dominator has to be re-calculated.
-class LoopPeeling
-{
- DominatorTree &dt;
-
-public:
- LoopPeeling(DominatorTree &dt)
- : dt(dt)
- {}
-
- void run(const QVector<LoopDetection::LoopInfo *> &loops)
- {
- for (LoopDetection::LoopInfo *loopInfo : loops)
- peelLoop(loopInfo);
- }
-
-private:
- // All copies have their outgoing edges pointing to the same successor block as the originals.
- // For each copied block, check where the outgoing edges point to. If it's a block inside the
- // (original) loop, rewire it to the corresponding copy. Otherwise, which is when it points
- // out of the loop, leave it alone.
- // As an extra, collect all edges that point out of the copied loop, because the targets need
- // to have their immediate dominator rechecked.
- void rewire(BasicBlock *newLoopBlock, const QVector<BasicBlock *> &from, const QVector<BasicBlock *> &to, QVector<BasicBlock *> &loopExits)
- {
- for (int i = 0, ei = newLoopBlock->out.size(); i != ei; ++i) {
- BasicBlock *&out = newLoopBlock->out[i];
- const int idx = from.indexOf(out);
- if (idx == -1) {
- if (!loopExits.contains(out))
- loopExits.append(out);
- } else {
- out->in.removeOne(newLoopBlock);
- BasicBlock *newTo = to.at(idx);
- newTo->in.append(newLoopBlock);
- out = newTo;
-
- Stmt *terminator = newLoopBlock->terminator();
- if (Jump *jump = terminator->asJump()) {
- Q_ASSERT(i == 0);
- jump->target = newTo;
- } else if (CJump *cjump = terminator->asCJump()) {
- Q_ASSERT(i == 0 || i == 1);
- if (i == 0)
- cjump->iftrue = newTo;
- else
- cjump->iffalse = newTo;
- }
- }
- }
- }
-
- void peelLoop(LoopDetection::LoopInfo *loop)
- {
- IR::Function *f = loop->loopHeader->function;
- CloneBasicBlock clone;
-
- LoopDetection::LoopInfo unpeeled(*loop);
- unpeeled.loopHeader = clone(unpeeled.loopHeader);
- unpeeled.loopHeader->setContainingGroup(loop->loopHeader->containingGroup());
- unpeeled.loopHeader->markAsGroupStart(true);
- f->addBasicBlock(unpeeled.loopHeader);
- for (int i = 0, ei = unpeeled.loopBody.size(); i != ei; ++i) {
- BasicBlock *&bodyBlock = unpeeled.loopBody[i];
- bodyBlock = clone(bodyBlock);
- bodyBlock->setContainingGroup(unpeeled.loopHeader);
- Q_ASSERT(bodyBlock->statementCount() == loop->loopBody[i]->statementCount());
- }
-
- // The cloned blocks will have no incoming edges, but they do have outgoing ones (copying
- // the terminators will automatically insert that edge). The blocks where the originals
- // pointed to will have an extra incoming edge from the copied blocks.
-
- BasicBlock::IncomingEdges inCopy = loop->loopHeader->in;
- for (BasicBlock *in : inCopy) {
- if (loop->loopHeader != in // this can happen for really tight loops (where there are no body blocks). This is a back-edge in that case.
- && unpeeled.loopHeader != in && !unpeeled.loopBody.contains(in) // if the edge is not coming from within the copied set, leave it alone
- && !dt.dominates(loop->loopHeader, in)) // an edge coming from within the loop (so a back-edge): this is handled when rewiring all outgoing edges
- continue;
-
- unpeeled.loopHeader->in.append(in);
- loop->loopHeader->in.removeOne(in);
-
- Stmt *terminator = in->terminator();
- if (Jump *jump = terminator->asJump()) {
- jump->target = unpeeled.loopHeader;
- in->out[0] = unpeeled.loopHeader;
- } else if (CJump *cjump = terminator->asCJump()) {
- if (cjump->iftrue == loop->loopHeader) {
- cjump->iftrue = unpeeled.loopHeader;
- Q_ASSERT(in->out[0] == loop->loopHeader);
- in->out[0] = unpeeled.loopHeader;
- } else if (cjump->iffalse == loop->loopHeader) {
- cjump->iffalse = unpeeled.loopHeader;
- Q_ASSERT(in->out[1] == loop->loopHeader);
- in->out[1] = unpeeled.loopHeader;
- } else {
- Q_UNREACHABLE();
- }
- }
- }
-
- QVector<BasicBlock *> loopExits;
- loopExits.reserve(8);
- loopExits.append(unpeeled.loopHeader);
-
- rewire(unpeeled.loopHeader, loop->loopBody, unpeeled.loopBody, loopExits);
- for (int i = 0, ei = unpeeled.loopBody.size(); i != ei; ++i) {
- BasicBlock *bodyBlock = unpeeled.loopBody.at(i);
- rewire(bodyBlock, loop->loopBody, unpeeled.loopBody, loopExits);
- f->addBasicBlock(bodyBlock);
- }
-
- // The original loop is now peeled off, and won't jump back to the loop header. Meaning, it
- // is not a loop anymore, so unmark it.
- loop->loopHeader->markAsGroupStart(false);
- for (BasicBlock *bb : qAsConst(loop->loopBody))
- bb->setContainingGroup(loop->loopHeader->containingGroup());
-
- // Set the immediate dominator of the new loop header to the old one. The real immediate
- // dominator will be calculated later.
- dt.setImmediateDominator(unpeeled.loopHeader, loop->loopHeader);
- // calculate the idoms in a separate loop, because addBasicBlock in the previous loop will
- // set the block index, which in turn is used by the dominator tree.
- for (int i = 0, ei = unpeeled.loopBody.size(); i != ei; ++i) {
- BasicBlock *bodyBlock = unpeeled.loopBody.at(i);
- BasicBlock *idom = dt.immediateDominator(loop->loopBody.at(i));
- const int idx = loop->loopBody.indexOf(idom);
- if (idom == loop->loopHeader)
- idom = unpeeled.loopHeader;
- else if (idx != -1)
- idom = unpeeled.loopBody.at(idx);
- Q_ASSERT(idom);
- dt.setImmediateDominator(bodyBlock, idom);
- }
-
- BasicBlockSet siblings(f);
- for (BasicBlock *bb : qAsConst(loopExits))
- dt.collectSiblings(bb, siblings);
-
- siblings.insert(unpeeled.loopHeader);
- dt.recalculateIDoms(siblings, loop->loopHeader);
- dt.dumpImmediateDominators();
- verifyImmediateDominators(dt, f);
- }
-};
-
-class RemoveLineNumbers: private SideEffectsChecker
-{
-public:
- static void run(IR::Function *function)
- {
- for (BasicBlock *bb : function->basicBlocks()) {
- if (bb->isRemoved())
- continue;
-
- for (Stmt *s : bb->statements()) {
- if (!hasSideEffects(s)) {
- s->location = QQmlJS::AST::SourceLocation();
- }
- }
- }
- }
-
-private:
- ~RemoveLineNumbers() {}
-
- static bool hasSideEffects(Stmt *stmt)
- {
- RemoveLineNumbers checker;
- if (auto e = stmt->asExp()) {
- checker.visit(e->expr);
- } else if (auto m = stmt->asMove()) {
- checker.visit(m->source);
- if (!checker.seenSideEffects()) {
- checker.visit(m->target);
- }
- } else if (auto c = stmt->asCJump()) {
- checker.visit(c->cond);
- } else if (auto r = stmt->asRet()) {
- checker.visit(r->expr);
- }
- return checker.seenSideEffects();
- }
-
- void visitTemp(Temp *) Q_DECL_OVERRIDE Q_DECL_FINAL {}
-};
-
-void mergeBasicBlocks(IR::Function *function, DefUses *du, DominatorTree *dt)
-{
- enum { DebugBlockMerging = 0 };
-
- if (function->hasTry)
- return;
-
- showMeTheCode(function, "Before basic block merging");
-
- // Now merge a basic block with its successor when there is one outgoing edge, and the
- // successor has one incoming edge.
- for (int i = 0, ei = function->basicBlockCount(); i != ei; ++i) {
- BasicBlock *bb = function->basicBlock(i);
-
- bb->nextLocation = QQmlJS::AST::SourceLocation(); // make sure appendStatement doesn't mess with the line info
-
- if (bb->isRemoved()) continue; // the block has been removed, so ignore it
- if (bb->out.size() != 1) continue; // more than one outgoing edge
- BasicBlock *successor = bb->out.first();
- if (successor->in.size() != 1) continue; // more than one incoming edge
-
- // Loop header? No efficient way to update the other blocks that refer to this as containing group,
- // so don't do merging yet.
- if (successor->isGroupStart()) continue;
-
- // Ok, we can merge the two basic blocks.
- if (DebugBlockMerging) {
- qDebug("Merging L%d into L%d", successor->index(), bb->index());
- }
- Q_ASSERT(bb->terminator()->asJump());
- bb->removeStatement(bb->statementCount() - 1); // remove the terminator, and replace it with:
- for (Stmt *s : successor->statements()) {
- bb->appendStatement(s); // add all statements from the successor to the current basic block
- if (auto cjump = s->asCJump())
- cjump->parent = bb;
- }
- bb->out = successor->out; // set the outgoing edges to the successor's so they're now in sync with our new terminator
- for (auto newSuccessor : bb->out) {
- for (auto &backlink : newSuccessor->in) {
- if (backlink == successor) {
- backlink = bb; // for all successors of our successor: set the incoming edges to come from bb, because we'll now jump there.
- }
- }
- }
- if (du) {
- // all statements in successor have moved to bb, so make sure that the containing blocks
- // stored in DefUses get updated (meaning: point to bb)
- du->replaceBasicBlock(successor, bb);
- }
- if (dt) {
- // update the immediate dominators to: any block that was dominated by the successor
- // will now need to point to bb's immediate dominator. The reason is that bb itself
- // won't be anyones immediate dominator, because it had just one outgoing edge.
- dt->mergeIntoPredecessor(successor);
- }
- function->removeBasicBlock(successor);
- --i; // re-run on the current basic-block, so any chain gets collapsed.
- }
-
- showMeTheCode(function, "After basic block merging");
- verifyCFG(function);
-}
-
-} // anonymous namespace
-
-void LifeTimeInterval::setFrom(int from) {
- Q_ASSERT(from > 0);
-
- if (_ranges.isEmpty()) { // this is the case where there is no use, only a define
- _ranges.prepend(LifeTimeIntervalRange(from, from));
- if (_end == InvalidPosition)
- _end = from;
- } else {
- _ranges.first().start = from;
- }
-}
-
-void LifeTimeInterval::addRange(int from, int to) {
- Q_ASSERT(from > 0);
- Q_ASSERT(to > 0);
- Q_ASSERT(to >= from);
-
- if (_ranges.isEmpty()) {
- _ranges.prepend(LifeTimeIntervalRange(from, to));
- _end = to;
- return;
- }
-
- LifeTimeIntervalRange *p = &_ranges.first();
- if (to + 1 >= p->start && p->end + 1 >= from) {
- p->start = qMin(p->start, from);
- p->end = qMax(p->end, to);
- while (_ranges.count() > 1) {
- LifeTimeIntervalRange *p1 = p + 1;
- if (p->end + 1 < p1->start || p1->end + 1 < p->start)
- break;
- p1->start = qMin(p->start, p1->start);
- p1->end = qMax(p->end, p1->end);
- _ranges.remove(0);
- p = &_ranges.first();
- }
- } else {
- if (to < p->start) {
- _ranges.prepend(LifeTimeIntervalRange(from, to));
- } else {
- Q_ASSERT(from > _ranges.last().end);
- _ranges.push_back(LifeTimeIntervalRange(from, to));
- }
- }
-
- _end = _ranges.last().end;
-}
-
-LifeTimeInterval LifeTimeInterval::split(int atPosition, int newStart)
-{
- Q_ASSERT(atPosition < newStart || newStart == InvalidPosition);
- Q_ASSERT(atPosition <= _end);
- Q_ASSERT(newStart <= _end || newStart == InvalidPosition);
-
- if (_ranges.isEmpty() || atPosition < _ranges.first().start)
- return LifeTimeInterval();
-
- LifeTimeInterval newInterval = *this;
- newInterval.setSplitFromInterval(true);
-
- // search where to split the interval
- for (int i = 0, ei = _ranges.size(); i < ei; ++i) {
- if (_ranges.at(i).start <= atPosition) {
- if (_ranges.at(i).end >= atPosition) {
- // split happens in the middle of a range. Keep this range in both the old and the
- // new interval, and correct the end/start later
- _ranges.resize(i + 1);
- newInterval._ranges.remove(0, i);
- break;
- }
- } else {
- // split happens between two ranges.
- _ranges.resize(i);
- newInterval._ranges.remove(0, i);
- break;
- }
- }
-
- if (newInterval._ranges.first().end == atPosition)
- newInterval._ranges.remove(0);
-
- if (newStart == InvalidPosition) {
- // the temp stays inactive for the rest of its lifetime
- newInterval = LifeTimeInterval();
- } else {
- // find the first range where the temp will get active again:
- while (!newInterval._ranges.isEmpty()) {
- const LifeTimeIntervalRange &range = newInterval._ranges.first();
- if (range.start > newStart) {
- // The split position is before the start of the range. Either we managed to skip
- // over the correct range, or we got an invalid split request. Either way, this
- // Should Never Happen <TM>.
- Q_ASSERT(range.start > newStart);
- return LifeTimeInterval();
- } else if (range.start <= newStart && range.end >= newStart) {
- // yay, we found the range that should be the new first range in the new interval!
- break;
- } else {
- // the temp stays inactive for this interval, so remove it.
- newInterval._ranges.remove(0);
- }
- }
- Q_ASSERT(!newInterval._ranges.isEmpty());
- newInterval._ranges.first().start = newStart;
- _end = newStart;
- }
-
- // if we're in the middle of a range, set the end to the split position
- if (_ranges.last().end > atPosition)
- _ranges.last().end = atPosition;
-
- validate();
- newInterval.validate();
-
- return newInterval;
-}
-
-void LifeTimeInterval::dump(QTextStream &out) const {
- IRPrinter(&out).print(const_cast<Temp *>(&_temp));
- out << ": ends at " << _end << " with ranges ";
- if (_ranges.isEmpty())
- out << "(none)";
- for (int i = 0; i < _ranges.size(); ++i) {
- if (i > 0) out << ", ";
- out << _ranges[i].start << " - " << _ranges[i].end;
- }
- if (_reg != InvalidRegister)
- out << " (register " << _reg << ")";
-}
-
-
-bool LifeTimeInterval::lessThanForTemp(const LifeTimeInterval *r1, const LifeTimeInterval *r2)
-{
- return r1->temp() < r2->temp();
-}
-
-LifeTimeIntervals::LifeTimeIntervals(IR::Function *function)
- : _basicBlockPosition(function->basicBlockCount())
- , _positionForStatement(function->statementCount(), IR::Stmt::InvalidId)
- , _lastPosition(0)
-{
- _intervals.reserve(function->tempCount + 32); // we reserve a bit more space for intervals, because the register allocator will add intervals with fixed ranges for each register.
- renumber(function);
-}
-
-// Renumbering works as follows:
-// - phi statements are not numbered
-// - statement numbers start at 0 (zero) and increment get an even number (lastPosition + 2)
-// - basic blocks start at firstStatementNumber - 1, or rephrased: lastPosition + 1
-// - basic blocks end at the number of the last statement
-// And during life-time calculation the next rule is used:
-// - any temporary starts its life-time at definingStatementPosition + 1
-//
-// This numbering simulates half-open intervals. For example:
-// 0: %1 = 1
-// 2: %2 = 2
-// 4: %3 = %1 + %2
-// 6: print(%3)
-// Here the half-open life-time intervals would be:
-// %1: (0-4]
-// %2: (2-4]
-// %3: (4-6]
-// Instead, we use the even statement positions for uses of temporaries, and the odd positions for
-// their definitions:
-// %1: [1-4]
-// %2: [3-4]
-// %3: [5-6]
-// This has the nice advantage that placing %3 (for example) is really easy: the start will
-// never overlap with the end of the uses of the operands used in the defining statement.
-//
-// The reason to start a basic-block at firstStatementPosition - 1 is to have correct start
-// positions for target temporaries of phi-nodes. Those temporaries will now start before the
-// first statement. This also means that any moves that get generated when transforming out of SSA
-// form, will not interfere with (read: overlap) any defining statements in the preceding
-// basic-block.
-void LifeTimeIntervals::renumber(IR::Function *function)
-{
- for (BasicBlock *bb : function->basicBlocks()) {
- if (bb->isRemoved())
- continue;
-
- _basicBlockPosition[bb->index()].start = _lastPosition + 1;
-
- for (Stmt *s : bb->statements()) {
- if (s->asPhi())
- continue;
-
- _lastPosition += 2;
- _positionForStatement[s->id()] = _lastPosition;
- }
-
- _basicBlockPosition[bb->index()].end = _lastPosition;
- }
-}
-
-LifeTimeIntervals::~LifeTimeIntervals()
-{
- qDeleteAll(_intervals);
-}
-
-Optimizer::Optimizer(IR::Function *function)
- : function(function)
- , inSSA(false)
-{}
-
-void Optimizer::run(QQmlEnginePrivate *qmlEngine, bool doTypeInference, bool peelLoops)
-{
- showMeTheCode(function, "Before running the optimizer");
-
- cleanupBasicBlocks(function);
-
- function->removeSharedExpressions();
- int statementCount = 0;
- for (BasicBlock *bb : function->basicBlocks())
- if (!bb->isRemoved())
- statementCount += bb->statementCount();
-// showMeTheCode(function);
-
- static bool doSSA = qEnvironmentVariableIsEmpty("QV4_NO_SSA");
-
- if (!function->hasTry && !function->hasWith && !function->module->debugMode && doSSA && statementCount <= 300) {
-// qout << "SSA for " << (function->name ? qPrintable(*function->name) : "<anonymous>") << endl;
-
- mergeBasicBlocks(function, nullptr, nullptr);
-
- ConvertArgLocals(function).toTemps();
- showMeTheCode(function, "After converting arguments to locals");
-
- // Calculate the dominator tree:
- DominatorTree df(function);
-
- {
- // This is in a separate scope, because loop-peeling doesn't (yet) update the LoopInfo
- // calculated by the LoopDetection. So by putting it in a separate scope, it is not
- // available after peeling.
-
- LoopDetection loopDetection(df);
- loopDetection.run(function);
- showMeTheCode(function, "After loop detection");
-// cfg2dot(function, loopDetection.allLoops());
-
- // ### disable loop peeling for now. It doesn't give any measurable performance
- // improvements at this time, but significantly increases the size of the
- // JIT generated code
- Q_UNUSED(peelLoops);
- if (0 && peelLoops) {
- QVector<LoopDetection::LoopInfo *> innerLoops = loopDetection.innermostLoops();
- LoopPeeling(df).run(innerLoops);
-
-// cfg2dot(function, loopDetection.allLoops());
- showMeTheCode(function, "After loop peeling");
- if (!innerLoops.isEmpty())
- verifyImmediateDominators(df, function);
- }
- }
-
- verifyCFG(function);
- verifyNoPointerSharing(function);
-
- df.computeDF();
-
- verifyCFG(function);
- verifyImmediateDominators(df, function);
-
- DefUses defUses(function);
-
-// qout << "Converting to SSA..." << endl;
- convertToSSA(function, df, defUses);
-// showMeTheCode(function);
-// defUses.dump();
-
-// qout << "Cleaning up phi nodes..." << endl;
- cleanupPhis(defUses);
- showMeTheCode(function, "After cleaning up phi-nodes");
-
- StatementWorklist worklist(function);
-
- if (doTypeInference) {
-// qout << "Running type inference..." << endl;
- TypeInference(qmlEngine, defUses).run(worklist);
- showMeTheCode(function, "After type inference");
-
-// qout << "Doing reverse inference..." << endl;
- ReverseInference(defUses).run(function);
-// showMeTheCode(function);
-
-// qout << "Doing type propagation..." << endl;
- TypePropagation(defUses).run(function, worklist);
-// showMeTheCode(function);
- verifyNoPointerSharing(function);
- }
-
- static const bool doOpt = qEnvironmentVariableIsEmpty("QV4_NO_OPT");
- if (doOpt) {
-// qout << "Running SSA optimization..." << endl;
- worklist.reset();
- optimizeSSA(worklist, defUses, df);
- showMeTheCode(function, "After optimization");
-
- verifyImmediateDominators(df, function);
- verifyCFG(function);
- }
-
- verifyNoPointerSharing(function);
- mergeBasicBlocks(function, &defUses, &df);
-
- verifyImmediateDominators(df, function);
- verifyCFG(function);
-
- // Basic-block cycles that are unreachable (i.e. for loops in a then-part where the
- // condition is calculated to be always false) are not yet removed. This will choke the
- // block scheduling, so remove those now.
-// qout << "Cleaning up unreachable basic blocks..." << endl;
- cleanupBasicBlocks(function);
-// showMeTheCode(function);
-
- verifyImmediateDominators(df, function);
- verifyCFG(function);
-
- // Transform the CFG into edge-split SSA.
- showMeTheCode(function, "Before edge splitting");
- splitCriticalEdges(function, df, worklist, defUses);
- showMeTheCode(function, "After edge splitting");
-
- verifyImmediateDominators(df, function);
- verifyCFG(function);
-
-// qout << "Doing block scheduling..." << endl;
-// df.dumpImmediateDominators();
- startEndLoops = BlockScheduler(function, df).go();
- showMeTheCode(function, "After basic block scheduling");
-// cfg2dot(function);
-
-#ifndef QT_NO_DEBUG
- checkCriticalEdges(function->basicBlocks());
-#endif
-
- if (!function->module->debugMode) {
- RemoveLineNumbers::run(function);
- showMeTheCode(function, "After line number removal");
- }
-
-// qout << "Finished SSA." << endl;
- inSSA = true;
- } else {
- removeUnreachleBlocks(function);
- inSSA = false;
- }
-}
-
-void Optimizer::convertOutOfSSA() {
- if (!inSSA)
- return;
-
- // There should be no critical edges at this point.
-
- for (BasicBlock *bb : function->basicBlocks()) {
- MoveMapping moves;
-
- for (BasicBlock *successor : bb->out) {
- const int inIdx = successor->in.indexOf(bb);
- Q_ASSERT(inIdx >= 0);
- for (Stmt *s : successor->statements()) {
- if (Phi *phi = s->asPhi()) {
- moves.add(clone(phi->incoming[inIdx], function),
- clone(phi->targetTemp, function)->asTemp());
- } else {
- break;
- }
- }
- }
-
- if (DebugMoveMapping) {
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream os(&buf);
- os << "Move mapping for function ";
- if (function->name)
- os << *function->name;
- else
- os << (void *) function;
- os << " on basic-block L" << bb->index() << ":" << endl;
- moves.dump();
- buf.close();
- qDebug("%s", buf.data().constData());
- }
-
- moves.order();
-
- moves.insertMoves(bb, function, true);
- }
-
- for (BasicBlock *bb : function->basicBlocks()) {
- while (!bb->isEmpty()) {
- if (bb->statements().first()->asPhi()) {
- bb->removeStatement(0);
- } else {
- break;
- }
- }
- }
-}
-
-LifeTimeIntervals::Ptr Optimizer::lifeTimeIntervals() const
-{
- Q_ASSERT(isInSSA());
-
- LifeRanges lifeRanges(function, startEndLoops);
-// lifeRanges.dump();
-// showMeTheCode(function);
- return lifeRanges.intervals();
-}
-
-static int countPhis(BasicBlock *bb)
-{
- int count = 0;
- for (Stmt *s : bb->statements()) {
- if (s->isa<Phi>())
- ++count;
- else
- break;
- }
-
- return count;
-}
-
-// Basic blocks can have only 1 terminator. This function returns a bit vector, where a 1 on a
-// certain index indicates that the terminator (jump) at the end of the basic block with that index
-// can be omitted.
-BitVector Optimizer::calculateOptionalJumps()
-{
- const int maxSize = function->basicBlockCount();
- BitVector optional(maxSize, false);
- if (maxSize < 2)
- return optional;
-
- BitVector reachableWithoutJump(maxSize, false);
-
- for (int i = maxSize - 1; i >= 0; --i) {
- BasicBlock *bb = function->basicBlock(i);
- if (bb->isRemoved())
- continue;
-
- if (Jump *jump = bb->statements().last()->asJump()) {
- if (reachableWithoutJump.at(jump->target->index())) {
- if (bb->statements().size() - countPhis(bb)> 1)
- reachableWithoutJump.clear();
- optional.setBit(bb->index());
- reachableWithoutJump.setBit(bb->index());
- continue;
- }
- }
-
- reachableWithoutJump.clear();
- reachableWithoutJump.setBit(bb->index());
- }
-
- return optional;
-}
-
-void Optimizer::showMeTheCode(IR::Function *function, const char *marker)
-{
- ::showMeTheCode(function, marker);
-}
-
-static inline bool overlappingStorage(const Temp &t1, const Temp &t2)
-{
- // This is the same as the operator==, but for one detail: memory locations are not sensitive
- // to types, and neither are general-purpose registers.
-
- if (t1.index != t2.index)
- return false; // different position, where-ever that may (physically) be.
- if (t1.kind != t2.kind)
- return false; // formal/local/(physical-)register/stack do never overlap
- if (t1.kind != Temp::PhysicalRegister) // Other than registers, ...
- return t1.kind == t2.kind; // ... everything else overlaps: any memory location can hold everything.
-
- // So now the index is the same, and we know that both stored in a register. If both are
- // floating-point registers, they are the same. Or, if both are non-floating-point registers,
- // generally called general-purpose registers, they are also the same.
- return (t1.type == DoubleType && t2.type == DoubleType)
- || (t1.type != DoubleType && t2.type != DoubleType);
-}
-
-MoveMapping::Moves MoveMapping::sourceUsages(Expr *e, const Moves &moves)
-{
- Moves usages;
-
- if (Temp *t = e->asTemp()) {
- for (int i = 0, ei = moves.size(); i != ei; ++i) {
- const Move &move = moves[i];
- if (Temp *from = move.from->asTemp())
- if (overlappingStorage(*from, *t))
- usages.append(move);
- }
- }
-
- return usages;
-}
-
-void MoveMapping::add(Expr *from, Temp *to) {
- if (Temp *t = from->asTemp()) {
- if (overlappingStorage(*t, *to)) {
- // assignments like fp1 = fp1 or var{&1} = double{&1} can safely be skipped.
- if (DebugMoveMapping) {
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream os(&buf);
- IRPrinter printer(&os);
- os << "Skipping ";
- printer.print(to);
- os << " <- ";
- printer.print(from);
- buf.close();
- qDebug("%s", buf.data().constData());
- }
- return;
- }
- }
-
- Move m(from, to);
- if (_moves.contains(m))
- return;
- _moves.append(m);
-}
-
-// Order the moves that are generated when resolving edges during register allocation (see [Wimmer1]
-// section 6 for details). Now these moves form one or more graphs, so we have to output them in
-// such an order that values don't get overwritten:
-// r1 <- r0
-// r2 <- r1
-// That input has to be ordered as follows in order to prevent the value in r1 from being lost:
-// r2 <- r1
-// r1 <- r0
-//
-// So, the algorithm is to output the leaves first, and take them out of the input. This will result
-// in some moves to become leaves (in the above example: when leaf r2 <- r1 is generated and taken
-// away, the r1 <- r0 is now a leaf), so we can output those and take those out, and repeat until
-// there are no more leafs.
-//
-// The tricky part is that there might be cycles:
-// r4 <- r5
-// r5 <- r4
-// These have to be turned into a "register swap":
-// r4 <=> r5
-//
-// So after running the above algorithm where we progressively remove the leaves, we are left with
-// zero or more cycles. To resolve those, we break one of the edges of the cycle, and for all other
-// edges we generate swaps. Note that the swaps will always occur as the last couple of moves,
-// because otherwise they might clobber sources for moves:
-// r4 <=> r5
-// r6 <- r5
-// Here, the value of r5 is already overwritten with the one in r4, so the correct order is:
-// r6 <- r5
-// r4 <=> r5
-void MoveMapping::order()
-{
- QList<Move> output;
- output.reserve(_moves.size());
-
- while (!_moves.isEmpty()) {
- // Take out all leaf edges, because we can output them without any problems.
- int nextLeaf = findLeaf();
- if (nextLeaf == -1)
- break; // No more leafs left, we're done here.
- output.append(_moves.takeAt(nextLeaf));
- // Now there might be new leaf edges: any move that had the input of the previously found
- // leaf as an output, so loop around.
- }
-
- while (!_moves.isEmpty()) {
- // We're now left with one or more cycles.
- // Step one: break the/a cycle.
- _moves.removeFirst();
- // Step two: find the other edges of the cycle, starting with the one of that is now a leaf.
- while (!_moves.isEmpty()) {
- int nextLeaf = findLeaf();
- if (nextLeaf == -1)
- break; // We're done with this cycle.
- Move m = _moves.takeAt(nextLeaf);
- // Step three: get the edges from the cycle and turn it into a swap
- m.needsSwap = true;
- output.append(m);
- // Because we took out a leaf, find the next one.
- }
- // We're done with the cycle, let's see if there are more.
- }
-
- _moves = output;
-}
-
-int MoveMapping::findLeaf() const
-{
- for (int i = 0, e = _moves.size(); i != e; ++i) {
- // Take an edge from the list...
- const Temp *target = _moves.at(i).to;
- // ... and see if its target is used as a source...
- bool targetUsedAsSource = false;
- for (int j = 0; j != e; ++j) {
- if (i == j)
- continue;
-
- Expr *source = _moves.at(j).from;
- if (const Temp *sourceTemp = source->asTemp()) {
- if (overlappingStorage(*target, *sourceTemp)) {
- targetUsedAsSource = true;
- break;
- }
- }
- }
- // ... if not, we have a leaf edge ...
- if (!targetUsedAsSource)
- return i;
- // .. otherwise we try the next one.
- }
-
- return -1; // No leaf found
-}
-
-QList<IR::Move *> MoveMapping::insertMoves(BasicBlock *bb, IR::Function *function, bool atEnd) const
-{
- QList<IR::Move *> newMoves;
- newMoves.reserve(_moves.size());
-
- int insertionPoint = atEnd ? bb->statements().size() - 1 : 0;
- for (const Move &m : _moves) {
- IR::Move *move = function->NewStmt<IR::Move>();
- move->init(clone(m.to, function), clone(m.from, function));
- move->swap = m.needsSwap;
- bb->insertStatementBefore(insertionPoint++, move);
- newMoves.append(move);
- }
-
- return newMoves;
-}
-
-void MoveMapping::dump() const
-{
- if (DebugMoveMapping) {
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream os(&buf);
- IRPrinter printer(&os);
- os << "Move mapping has " << _moves.size() << " moves..." << endl;
- for (const Move &m : _moves) {
- os << "\t";
- printer.print(m.to);
- if (m.needsSwap)
- os << " <-> ";
- else
- os << " <-- ";
- printer.print(m.from);
- os << endl;
- }
- qDebug("%s", buf.data().constData());
- }
-}
-
-// References:
-// [Wimmer1] C. Wimmer and M. Franz. Linear Scan Register Allocation on SSA Form. In Proceedings of
-// CGO'10, ACM Press, 2010
-// [Wimmer2] C. Wimmer and H. Mossenbock. Optimized Interval Splitting in a Linear Scan Register
-// Allocator. In Proceedings of the ACM/USENIX International Conference on Virtual
-// Execution Environments, pages 132-141. ACM Press, 2005.
-// [Briggs] P. Briggs, K.D. Cooper, T.J. Harvey, and L.T. Simpson. Practical Improvements to the
-// Construction and Destruction of Static Single Assignment Form.
-// [Appel] A.W. Appel. Modern Compiler Implementation in Java. Second edition, Cambridge
-// University Press.
-// [Ramalingam] G. Ramalingam and T. Reps. An Incremental Algorithm for Maintaining the Dominator
-// Tree of a Reducible Flowgraph.
diff --git a/src/qml/compiler/qv4ssa_p.h b/src/qml/compiler/qv4ssa_p.h
deleted file mode 100644
index b9d8ae0a6c..0000000000
--- a/src/qml/compiler/qv4ssa_p.h
+++ /dev/null
@@ -1,472 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QV4SSA_P_H
-#define QV4SSA_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qv4jsir_p.h"
-#include "qv4isel_util_p.h"
-#include <private/qv4util_p.h>
-#include <QtCore/QSharedPointer>
-
-QT_BEGIN_NAMESPACE
-class QTextStream;
-class QQmlEnginePrivate;
-
-namespace QV4 {
-namespace IR {
-
-struct LifeTimeIntervalRange {
- int start;
- int end;
-
- LifeTimeIntervalRange(int start = -1, int end = -1)
- : start(start)
- , end(end)
- {}
-
- bool covers(int position) const { return start <= position && position <= end; }
-};
-} // IR namespace
-} // QV4 namespace
-
-Q_DECLARE_TYPEINFO(QV4::IR::LifeTimeIntervalRange, Q_PRIMITIVE_TYPE);
-
-namespace QV4 {
-namespace IR {
-
-class Q_AUTOTEST_EXPORT LifeTimeInterval {
-public:
- typedef QVarLengthArray<LifeTimeIntervalRange, 4> Ranges;
-
-private:
- Temp _temp;
- Ranges _ranges;
- int _end;
- int _reg;
- unsigned _isFixedInterval : 1;
- unsigned _isSplitFromInterval : 1;
-
-public:
- enum { InvalidPosition = -1 };
- enum { InvalidRegister = -1 };
-
- explicit LifeTimeInterval(int rangeCapacity = 4)
- : _end(InvalidPosition)
- , _reg(InvalidRegister)
- , _isFixedInterval(0)
- , _isSplitFromInterval(0)
- { _ranges.reserve(rangeCapacity); }
-
- bool isValid() const { return _end != InvalidRegister; }
-
- void setTemp(const Temp &temp) { this->_temp = temp; }
- Temp temp() const { return _temp; }
- bool isFP() const { return _temp.type == IR::DoubleType; }
-
- void setFrom(int from);
- void addRange(int from, int to);
- const Ranges &ranges() const { return _ranges; }
-
- int start() const { return _ranges.first().start; }
- int end() const { return _end; }
- bool covers(int position) const
- {
- for (int i = 0, ei = _ranges.size(); i != ei; ++i) {
- if (_ranges.at(i).covers(position))
- return true;
- }
- return false;
- }
-
- int reg() const { return _reg; }
- void setReg(int reg) { Q_ASSERT(!_isFixedInterval); _reg = reg; }
-
- bool isFixedInterval() const { return _isFixedInterval; }
- void setFixedInterval(bool isFixedInterval) { _isFixedInterval = isFixedInterval; }
-
- LifeTimeInterval split(int atPosition, int newStart);
- bool isSplitFromInterval() const { return _isSplitFromInterval; }
- void setSplitFromInterval(bool isSplitFromInterval) { _isSplitFromInterval = isSplitFromInterval; }
-
- void dump(QTextStream &out) const;
- static bool lessThan(const LifeTimeInterval *r1, const LifeTimeInterval *r2);
- static bool lessThanForTemp(const LifeTimeInterval *r1, const LifeTimeInterval *r2);
-
- void validate() const {
-#if !defined(QT_NO_DEBUG)
- // Validate the new range
- if (_end != InvalidPosition) {
- Q_ASSERT(!_ranges.isEmpty());
- for (const LifeTimeIntervalRange &range : qAsConst(_ranges)) {
- Q_ASSERT(range.start >= 0);
- Q_ASSERT(range.end >= 0);
- Q_ASSERT(range.start <= range.end);
- }
- }
-#endif
- }
-};
-
-inline bool LifeTimeInterval::lessThan(const LifeTimeInterval *r1, const LifeTimeInterval *r2)
-{
- if (r1->_ranges.first().start == r2->_ranges.first().start) {
- if (r1->isSplitFromInterval() == r2->isSplitFromInterval())
- return r1->_ranges.last().end < r2->_ranges.last().end;
- else
- return r1->isSplitFromInterval();
- } else
- return r1->_ranges.first().start < r2->_ranges.first().start;
-}
-
-class LifeTimeIntervals
-{
- Q_DISABLE_COPY(LifeTimeIntervals)
-
- LifeTimeIntervals(IR::Function *function);
- void renumber(IR::Function *function);
-
-public:
- typedef QSharedPointer<LifeTimeIntervals> Ptr;
- static Ptr create(IR::Function *function)
- { return Ptr(new LifeTimeIntervals(function)); }
-
- ~LifeTimeIntervals();
-
- // takes ownership of the pointer
- void add(LifeTimeInterval *interval)
- { _intervals.append(interval); }
-
- // After calling Optimizer::lifeTimeIntervals() the result will have all intervals in descending order of start position.
- QVector<LifeTimeInterval *> intervals() const
- { return _intervals; }
-
- int size() const
- { return _intervals.size(); }
-
- int positionForStatement(Stmt *stmt) const
- {
- Q_ASSERT(stmt->id() >= 0);
- if (static_cast<unsigned>(stmt->id()) < _positionForStatement.size())
- return _positionForStatement[stmt->id()];
-
- return Stmt::InvalidId;
- }
-
- int startPosition(BasicBlock *bb) const
- {
- Q_ASSERT(bb->index() >= 0);
- Q_ASSERT(static_cast<unsigned>(bb->index()) < _basicBlockPosition.size());
-
- return _basicBlockPosition.at(bb->index()).start;
- }
-
- int endPosition(BasicBlock *bb) const
- {
- Q_ASSERT(bb->index() >= 0);
- Q_ASSERT(static_cast<unsigned>(bb->index()) < _basicBlockPosition.size());
-
- return _basicBlockPosition.at(bb->index()).end;
- }
-
- int lastPosition() const
- {
- return _lastPosition;
- }
-
-private:
- struct BasicBlockPositions {
- int start;
- int end;
-
- BasicBlockPositions()
- : start(IR::Stmt::InvalidId)
- , end(IR::Stmt::InvalidId)
- {}
- };
-
- std::vector<BasicBlockPositions> _basicBlockPosition;
- std::vector<int> _positionForStatement;
- QVector<LifeTimeInterval *> _intervals;
- int _lastPosition;
-};
-
-class Q_QML_PRIVATE_EXPORT Optimizer
-{
- Q_DISABLE_COPY(Optimizer)
-
-public:
- Optimizer(Function *function);
-
- void run(QQmlEnginePrivate *qmlEngine, bool doTypeInference = true, bool peelLoops = true);
- void convertOutOfSSA();
-
- bool isInSSA() const
- { return inSSA; }
-
- QHash<BasicBlock *, BasicBlock *> loopStartEndBlocks() const { return startEndLoops; }
-
- LifeTimeIntervals::Ptr lifeTimeIntervals() const;
-
- BitVector calculateOptionalJumps();
-
- static void showMeTheCode(Function *function, const char *marker);
-
-private:
- Function *function;
- bool inSSA;
- QHash<BasicBlock *, BasicBlock *> startEndLoops;
-};
-
-class Q_QML_AUTOTEST_EXPORT MoveMapping
-{
-#ifdef V4_AUTOTEST
-public:
-#endif
- struct Move {
- Expr *from;
- Temp *to;
- bool needsSwap;
-
- Move(Expr *from, Temp *to, bool needsSwap = false)
- : from(from), to(to), needsSwap(needsSwap)
- {}
-
- bool operator==(const Move &other) const
- { return from == other.from && to == other.to; }
- };
- typedef QList<Move> Moves;
-
- Moves _moves;
-
- static Moves sourceUsages(Expr *e, const Moves &moves);
-
-public:
- void add(Expr *from, Temp *to);
- void order();
- QList<IR::Move *> insertMoves(BasicBlock *bb, Function *function, bool atEnd) const;
-
- void dump() const;
-
-private:
- int findLeaf() const;
-};
-
-/*
- * stack slot allocation:
- *
- * foreach bb do
- * foreach stmt do
- * if the current statement is not a phi-node:
- * purge ranges that end before the current statement
- * check for life ranges to activate, and if they don't have a stackslot associated then allocate one
- * renumber temps to stack
- * for phi nodes: check if all temps (src+dst) are assigned stack slots and marked as allocated
- * if it's a jump:
- * foreach phi node in the successor:
- * allocate slots for each temp (both sources and targets) if they don't have one allocated already
- * insert moves before the jump
- */
-class AllocateStackSlots: protected ConvertTemps
-{
- IR::LifeTimeIntervals::Ptr _intervals;
- QVector<IR::LifeTimeInterval *> _unhandled;
- QVector<IR::LifeTimeInterval *> _live;
- QBitArray _slotIsInUse;
- IR::Function *_function;
-
- int defPosition(IR::Stmt *s) const
- {
- return usePosition(s) + 1;
- }
-
- int usePosition(IR::Stmt *s) const
- {
- return _intervals->positionForStatement(s);
- }
-
-public:
- AllocateStackSlots(const IR::LifeTimeIntervals::Ptr &intervals)
- : _intervals(intervals)
- , _slotIsInUse(intervals->size(), false)
- , _function(0)
- {
- _live.reserve(8);
- _unhandled = _intervals->intervals();
- }
-
- void forFunction(IR::Function *function)
- {
- IR::Optimizer::showMeTheCode(function, "Before stack slot allocation");
- _function = function;
- toStackSlots(function);
- }
-
-protected:
- int allocateFreeSlot() override
- {
- for (int i = 0, ei = _slotIsInUse.size(); i != ei; ++i) {
- if (!_slotIsInUse[i]) {
- if (_nextUnusedStackSlot <= i) {
- Q_ASSERT(_nextUnusedStackSlot == i);
- _nextUnusedStackSlot = i + 1;
- }
- _slotIsInUse[i] = true;
- return i;
- }
- }
-
- Q_UNREACHABLE();
- return -1;
- }
-
- void process(IR::Stmt *s) override
- {
-// qDebug("L%d statement %d:", _currentBasicBlock->index, s->id);
-
- if (IR::Phi *phi = s->asPhi()) {
- visitPhi(phi);
- } else {
- // purge ranges no longer alive:
- for (int i = 0; i < _live.size(); ) {
- const IR::LifeTimeInterval *lti = _live.at(i);
- if (lti->end() < usePosition(s)) {
-// qDebug() << "\t - moving temp" << lti->temp().index << "to handled, freeing slot" << _stackSlotForTemp[lti->temp().index];
- _live.remove(i);
- Q_ASSERT(_slotIsInUse[_stackSlotForTemp[lti->temp().index]]);
- _slotIsInUse[_stackSlotForTemp[lti->temp().index]] = false;
- continue;
- } else {
- ++i;
- }
- }
-
- // active new ranges:
- while (!_unhandled.isEmpty()) {
- IR::LifeTimeInterval *lti = _unhandled.last();
- if (lti->start() > defPosition(s))
- break; // we're done
- Q_ASSERT(!_stackSlotForTemp.contains(lti->temp().index));
- _stackSlotForTemp[lti->temp().index] = allocateFreeSlot();
-// qDebug() << "\t - activating temp" << lti->temp().index << "on slot" << _stackSlotForTemp[lti->temp().index];
- _live.append(lti);
- _unhandled.removeLast();
- }
-
- visit(s);
- }
-
- if (IR::Jump *jump = s->asJump()) {
- IR::MoveMapping moves;
- for (IR::Stmt *succStmt : jump->target->statements()) {
- if (IR::Phi *phi = succStmt->asPhi()) {
- forceActivation(*phi->targetTemp);
- for (int i = 0, ei = phi->incoming.size(); i != ei; ++i) {
- IR::Expr *e = phi->incoming[i];
- if (IR::Temp *t = e->asTemp()) {
- forceActivation(*t);
- }
- if (jump->target->in[i] == _currentBasicBlock)
- moves.add(phi->incoming[i], phi->targetTemp);
- }
- } else {
- break;
- }
- }
- moves.order();
- const QList<IR::Move *> newMoves = moves.insertMoves(_currentBasicBlock, _function, true);
- for (IR::Move *move : newMoves)
- visit(move);
- }
- }
-
- void forceActivation(const IR::Temp &t)
- {
- if (_stackSlotForTemp.contains(t.index))
- return;
-
- int i = _unhandled.size() - 1;
- for (; i >= 0; --i) {
- IR::LifeTimeInterval *lti = _unhandled[i];
- if (lti->temp() == t) {
- _live.append(lti);
- _unhandled.remove(i);
- break;
- }
- }
- Q_ASSERT(i >= 0); // check that we always found the entry
-
- _stackSlotForTemp[t.index] = allocateFreeSlot();
-// qDebug() << "\t - force activating temp" << t.index << "on slot" << _stackSlotForTemp[t.index];
- }
-
- void visitPhi(IR::Phi *phi) override
- {
- Q_UNUSED(phi);
-#if !defined(QT_NO_DEBUG)
- Q_ASSERT(_stackSlotForTemp.contains(phi->targetTemp->index));
- Q_ASSERT(_slotIsInUse[_stackSlotForTemp[phi->targetTemp->index]]);
- for (IR::Expr *e : phi->incoming) {
- if (IR::Temp *t = e->asTemp())
- Q_ASSERT(_stackSlotForTemp.contains(t->index));
- }
-#endif // defined(QT_NO_DEBUG)
- }
-};
-
-} // IR namespace
-} // QV4 namespace
-
-
-Q_DECLARE_TYPEINFO(QV4::IR::LifeTimeInterval, Q_MOVABLE_TYPE);
-
-QT_END_NAMESPACE
-
-#endif // QV4SSA_P_H
diff --git a/src/qml/configure.json b/src/qml/configure.json
index 257bedecbc..b744ea6948 100644
--- a/src/qml/configure.json
+++ b/src/qml/configure.json
@@ -7,22 +7,23 @@
"commandline": {
"options": {
- "qml-interpreter": "boolean",
- "qml-network": "boolean"
+ "qml-network": "boolean",
+ "qml-debug": "boolean"
}
},
"features": {
- "qml-interpreter": {
- "label": "QML interpreter",
- "purpose": "Provides the QML interpreter.",
- "section": "QML",
- "output": [ "privateFeature" ]
- },
"qml-network": {
"label": "QML network support",
"purpose": "Provides network transparency.",
"section": "QML",
+ "condition": "features.network",
+ "output": [ "publicFeature" ]
+ },
+ "qml-debug": {
+ "label": "QML debugging and profiling support",
+ "purpose": "Provides infrastructure and plugins for debugging and profiling.",
+ "section": "QML",
"output": [ "publicFeature" ]
},
"qml-profiler": {
@@ -45,8 +46,8 @@
{
"section": "Qt QML",
"entries": [
- "qml-interpreter",
- "qml-network"
+ "qml-network",
+ "qml-debug"
]
}
]
diff --git a/src/qml/debugger/debugger.pri b/src/qml/debugger/debugger.pri
index da1ab867d4..202a46e550 100644
--- a/src/qml/debugger/debugger.pri
+++ b/src/qml/debugger/debugger.pri
@@ -1,10 +1,13 @@
-contains(QT_CONFIG, no-qml-debug) {
- DEFINES += QT_NO_QML_DEBUGGER
- MODULE_DEFINES += QT_NO_QML_DEBUGGER
-} else {
+qtConfig(qml-debug) {
HEADERS += \
+ $$PWD/qqmlabstractprofileradapter_p.h \
+ $$PWD/qqmlconfigurabledebugservice_p.h \
$$PWD/qqmldebugpluginmanager_p.h \
- $$PWD/qqmldebugservicefactory_p.h
+ $$PWD/qqmldebugservice_p.h \
+ $$PWD/qqmldebugservicefactory_p.h \
+ $$PWD/qqmldebugserver_p.h \
+ $$PWD/qqmldebugserverconnection_p.h \
+ $$PWD/qqmlprofilerdefinitions_p.h
SOURCES += \
$$PWD/qqmldebug.cpp \
@@ -18,13 +21,10 @@ contains(QT_CONFIG, no-qml-debug) {
HEADERS += \
$$PWD/qqmldebugconnector_p.h \
- $$PWD/qqmldebugservice_p.h \
$$PWD/qqmldebugserviceinterfaces_p.h \
$$PWD/qqmldebugstatesdelegate_p.h \
$$PWD/qqmldebug.h \
$$PWD/qqmlmemoryprofiler_p.h \
- $$PWD/qqmlprofilerdefinitions_p.h \
- $$PWD/qqmlabstractprofileradapter_p.h \
$$PWD/qqmlprofiler_p.h
INCLUDEPATH += $$PWD
diff --git a/src/qml/debugger/qqmlabstractprofileradapter_p.h b/src/qml/debugger/qqmlabstractprofileradapter_p.h
index 6a05a80f37..5d1b339324 100644
--- a/src/qml/debugger/qqmlabstractprofileradapter_p.h
+++ b/src/qml/debugger/qqmlabstractprofileradapter_p.h
@@ -59,7 +59,7 @@
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_QML_DEBUGGER
+QT_REQUIRE_CONFIG(qml_debug);
class QQmlProfilerService;
class Q_QML_PRIVATE_EXPORT QQmlAbstractProfilerAdapter : public QObject, public QQmlProfilerDefinitions {
@@ -116,8 +116,6 @@ public:
#define QQmlAbstractProfilerAdapterFactory_iid "org.qt-project.Qt.QQmlAbstractProfilerAdapterFactory"
-#endif // QT_NO_QML_DEBUGGER
-
QT_END_NAMESPACE
#endif // QQMLABSTRACTPROFILERADAPTER_P_H
diff --git a/src/plugins/qmltooling/shared/qqmlconfigurabledebugservice.h b/src/qml/debugger/qqmlconfigurabledebugservice_p.h
index 85ff9b182f..e09d5f779a 100644
--- a/src/plugins/qmltooling/shared/qqmlconfigurabledebugservice.h
+++ b/src/qml/debugger/qqmlconfigurabledebugservice_p.h
@@ -38,8 +38,8 @@
****************************************************************************/
-#ifndef QQMLCONFIGURABLEDEBUGSEVICE_H
-#define QQMLCONFIGURABLEDEBUGSEVICE_H
+#ifndef QQMLCONFIGURABLEDEBUGSEVICE_P_H
+#define QQMLCONFIGURABLEDEBUGSEVICE_P_H
//
// W A R N I N G
@@ -52,8 +52,9 @@
// We mean it.
//
-#include <private/qqmldebugservice_p.h>
-#include <private/qqmldebugconnector_p.h>
+#include "qqmldebugservice_p.h"
+#include "qqmldebugconnector_p.h"
+
#include <QtCore/qmutex.h>
QT_BEGIN_NAMESPACE
@@ -85,7 +86,7 @@ protected:
QQmlDebugConnector::instance()->blockingMode());
}
- void stateChanged(QQmlDebugService::State newState) Q_DECL_OVERRIDE
+ void stateChanged(QQmlDebugService::State newState) override
{
if (newState != QQmlDebugService::Enabled)
stopWaiting();
@@ -93,7 +94,7 @@ protected:
init();
}
- void engineAboutToBeAdded(QJSEngine *engine) Q_DECL_OVERRIDE
+ void engineAboutToBeAdded(QJSEngine *engine) override
{
QMutexLocker lock(&m_configMutex);
if (m_waitingForConfiguration)
@@ -109,4 +110,4 @@ protected:
QT_END_NAMESPACE
-#endif // QQMLCONFIGURABLEDEBUGSEVICE_H
+#endif // QQMLCONFIGURABLEDEBUGSEVICE_P_H
diff --git a/src/qml/debugger/qqmldebug.cpp b/src/qml/debugger/qqmldebug.cpp
index 681dc06215..6246fb4207 100644
--- a/src/qml/debugger/qqmldebug.cpp
+++ b/src/qml/debugger/qqmldebug.cpp
@@ -44,6 +44,8 @@
#include <private/qqmlengine_p.h>
#include <private/qv4compileddata_p.h>
+QT_REQUIRE_CONFIG(qml_debug);
+
QT_BEGIN_NAMESPACE
QQmlDebuggingEnabler::QQmlDebuggingEnabler(bool printWarning)
diff --git a/src/qml/debugger/qqmldebug.h b/src/qml/debugger/qqmldebug.h
index 6a0cfdc709..d0ceb28cdc 100644
--- a/src/qml/debugger/qqmldebug.h
+++ b/src/qml/debugger/qqmldebug.h
@@ -46,7 +46,7 @@
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_QML_DEBUGGER
+#if QT_CONFIG(qml_debug)
struct Q_QML_EXPORT QQmlDebuggingEnabler
{
diff --git a/src/qml/debugger/qqmldebugconnector_p.h b/src/qml/debugger/qqmldebugconnector_p.h
index 0d3e2e2e47..a2a6f5047d 100644
--- a/src/qml/debugger/qqmldebugconnector_p.h
+++ b/src/qml/debugger/qqmldebugconnector_p.h
@@ -44,7 +44,9 @@
#include <QtQml/qjsengine.h>
#include <QtCore/QVariantList>
+#if QT_CONFIG(qml_debug)
#include <private/qqmldebugservice_p.h>
+#endif
//
// W A R N I N G
@@ -59,7 +61,7 @@
QT_BEGIN_NAMESPACE
-#ifdef QT_NO_QML_DEBUGGER
+#if !QT_CONFIG(qml_debug)
class Q_QML_PRIVATE_EXPORT QQmlDebugConnector
{
diff --git a/src/qml/debugger/qqmldebugpluginmanager_p.h b/src/qml/debugger/qqmldebugpluginmanager_p.h
index 8f52b65b17..2575cbb96a 100644
--- a/src/qml/debugger/qqmldebugpluginmanager_p.h
+++ b/src/qml/debugger/qqmldebugpluginmanager_p.h
@@ -57,7 +57,7 @@
QT_BEGIN_NAMESPACE
-#if defined(QT_NO_QML_DEBUGGER)
+#if !QT_CONFIG(qml_debug)
#define Q_QML_DEBUG_PLUGIN_LOADER(interfaceName)\
interfaceName *load##interfaceName(const QString &key)\
@@ -72,7 +72,7 @@ QT_BEGIN_NAMESPACE
}
#define Q_QML_IMPORT_DEBUG_PLUGIN(className)
-#else // QT_NO_QML_DEBUGGER
+#else // QT_CONFIG(qml_debug)
#define Q_QML_DEBUG_PLUGIN_LOADER(interfaceName)\
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, interfaceName##Loader,\
@@ -86,7 +86,7 @@ QT_BEGIN_NAMESPACE
return interfaceName##Loader()->metaData();\
}
-#endif // QT_NO_QML_DEBUGGER
+#endif // QT_CONFIG(qml_debug)
QT_END_NAMESPACE
#endif // QQMLDEBUGPLUGINMANAGER_P_H
diff --git a/src/plugins/qmltooling/shared/qqmldebugserver.h b/src/qml/debugger/qqmldebugserver_p.h
index 109f1e246c..e848b00bda 100644
--- a/src/plugins/qmltooling/shared/qqmldebugserver.h
+++ b/src/qml/debugger/qqmldebugserver_p.h
@@ -37,12 +37,12 @@
**
****************************************************************************/
-#ifndef QQMLDEBUGSERVER_H
-#define QQMLDEBUGSERVER_H
+#ifndef QQMLDEBUGSERVER_P_H
+#define QQMLDEBUGSERVER_P_H
-#include <private/qqmldebugconnector_p.h>
-#include <private/qtqmlglobal_p.h>
+#include "qqmldebugconnector_p.h"
+#include <private/qtqmlglobal_p.h>
#include <QtCore/QIODevice>
//
@@ -58,7 +58,7 @@
QT_BEGIN_NAMESPACE
-class QQmlDebugServer : public QQmlDebugConnector
+class Q_QML_PRIVATE_EXPORT QQmlDebugServer : public QQmlDebugConnector
{
Q_OBJECT
public:
@@ -67,4 +67,4 @@ public:
QT_END_NAMESPACE
-#endif // QQMLDEBUGSERVER_H
+#endif // QQMLDEBUGSERVER_P_H
diff --git a/src/plugins/qmltooling/shared/qqmldebugserverconnection.h b/src/qml/debugger/qqmldebugserverconnection_p.h
index 3fac15acb2..536ad830b4 100644
--- a/src/plugins/qmltooling/shared/qqmldebugserverconnection.h
+++ b/src/qml/debugger/qqmldebugserverconnection_p.h
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef QQMLDEBUGSERVERCONNECTION_H
-#define QQMLDEBUGSERVERCONNECTION_H
+#ifndef QQMLDEBUGSERVERCONNECTION_P_H
+#define QQMLDEBUGSERVERCONNECTION_P_H
#include <private/qtqmlglobal_p.h>
#include <QtCore/qobject.h>
@@ -56,9 +56,8 @@
QT_BEGIN_NAMESPACE
-
class QQmlDebugServer;
-class QQmlDebugServerConnection : public QObject
+class Q_QML_PRIVATE_EXPORT QQmlDebugServerConnection : public QObject
{
Q_OBJECT
public:
@@ -73,7 +72,7 @@ public:
virtual void flush() = 0;
};
-class QQmlDebugServerConnectionFactory : public QObject
+class Q_QML_PRIVATE_EXPORT QQmlDebugServerConnectionFactory : public QObject
{
Q_OBJECT
public:
diff --git a/src/qml/debugger/qqmldebugservice_p.h b/src/qml/debugger/qqmldebugservice_p.h
index 42a57a39f2..34bbd631ec 100644
--- a/src/qml/debugger/qqmldebugservice_p.h
+++ b/src/qml/debugger/qqmldebugservice_p.h
@@ -56,9 +56,9 @@
// We mean it.
//
-QT_BEGIN_NAMESPACE
+QT_REQUIRE_CONFIG(qml_debug);
-#ifndef QT_NO_QML_DEBUGGER
+QT_BEGIN_NAMESPACE
class QJSEngine;
@@ -103,8 +103,6 @@ signals:
void messagesToClient(const QString &name, const QList<QByteArray> &messages);
};
-#endif
-
QT_END_NAMESPACE
#endif // QQMLDEBUGSERVICE_H
diff --git a/src/qml/debugger/qqmldebugserviceinterfaces_p.h b/src/qml/debugger/qqmldebugserviceinterfaces_p.h
index 707ef1a937..01693aee24 100644
--- a/src/qml/debugger/qqmldebugserviceinterfaces_p.h
+++ b/src/qml/debugger/qqmldebugserviceinterfaces_p.h
@@ -53,9 +53,10 @@
#include <QtCore/qstring.h>
#include <private/qtqmlglobal_p.h>
+#if QT_CONFIG(qml_debug)
#include <private/qqmldebugservice_p.h>
+#endif
#include <private/qqmldebugstatesdelegate_p.h>
-#include <private/qqmlabstractprofileradapter_p.h>
#include <private/qqmlboundsignal_p.h>
#include <limits>
@@ -65,7 +66,7 @@ QT_BEGIN_NAMESPACE
class QWindow;
class QQuickWindow;
-#ifdef QT_NO_QML_DEBUGGER
+#if !QT_CONFIG(qml_debug)
class QV4DebugService
{
@@ -116,10 +117,11 @@ public:
protected:
friend class QQmlDebugConnector;
- QV4DebugService(float version, QObject *parent = 0) :
+ QV4DebugService(float version, QObject *parent = nullptr) :
QQmlDebugService(s_key, version, parent) {}
};
+class QQmlAbstractProfilerAdapter;
class Q_QML_PRIVATE_EXPORT QQmlProfilerService : public QQmlDebugService
{
Q_OBJECT
@@ -138,7 +140,7 @@ public:
protected:
friend class QQmlDebugConnector;
- QQmlProfilerService(float version, QObject *parent = 0) :
+ QQmlProfilerService(float version, QObject *parent = nullptr) :
QQmlDebugService(s_key, version, parent) {}
};
@@ -154,7 +156,7 @@ public:
protected:
friend class QQmlDebugConnector;
- QQmlEngineDebugService(float version, QObject *parent = 0) :
+ QQmlEngineDebugService(float version, QObject *parent = nullptr) :
QQmlDebugService(s_key, version, parent) {}
QQmlBoundSignal *nextSignal(QQmlBoundSignal *prev) { return prev->m_nextSignal; }
@@ -173,7 +175,7 @@ public:
protected:
friend class QQmlDebugConnector;
- QQmlInspectorService(float version, QObject *parent = 0) :
+ QQmlInspectorService(float version, QObject *parent = nullptr) :
QQmlDebugService(s_key, version, parent) {}
};
@@ -188,7 +190,7 @@ public:
protected:
friend class QQmlDebugConnector;
- QDebugMessageService(float version, QObject *parent = 0) :
+ QDebugMessageService(float version, QObject *parent = nullptr) :
QQmlDebugService(s_key, version, parent) {}
};
@@ -201,7 +203,7 @@ public:
protected:
friend class QQmlDebugConnector;
- QQmlEngineControlService(float version, QObject *parent = 0) :
+ QQmlEngineControlService(float version, QObject *parent = nullptr) :
QQmlDebugService(s_key, version, parent) {}
};
@@ -215,7 +217,7 @@ public:
protected:
friend class QQmlDebugConnector;
- QQmlNativeDebugService(float version, QObject *parent = 0)
+ QQmlNativeDebugService(float version, QObject *parent = nullptr)
: QQmlDebugService(s_key, version, parent) {}
};
diff --git a/src/qml/debugger/qqmldebugstatesdelegate_p.h b/src/qml/debugger/qqmldebugstatesdelegate_p.h
index 95f727fb2d..b2e14873dc 100644
--- a/src/qml/debugger/qqmldebugstatesdelegate_p.h
+++ b/src/qml/debugger/qqmldebugstatesdelegate_p.h
@@ -57,7 +57,7 @@
QT_BEGIN_NAMESPACE
-#ifdef QT_NO_QML_DEBUGGER
+#if !QT_CONFIG(qml_debug)
class QQmlDebugStatesDelegate {};
diff --git a/src/qml/debugger/qqmlmemoryprofiler_p.h b/src/qml/debugger/qqmlmemoryprofiler_p.h
index fb71c999c3..12a31a851f 100644
--- a/src/qml/debugger/qqmlmemoryprofiler_p.h
+++ b/src/qml/debugger/qqmlmemoryprofiler_p.h
@@ -56,7 +56,7 @@
QT_BEGIN_NAMESPACE
-#ifdef QT_NO_QML_DEBUGGER
+#if !QT_CONFIG(qml_debug)
#define QML_MEMORY_SCOPE_URL(url)
#define QML_MEMORY_SCOPE_STRING(s)
diff --git a/src/qml/debugger/qqmlprofiler_p.h b/src/qml/debugger/qqmlprofiler_p.h
index a220e9cfc8..2e87f10302 100644
--- a/src/qml/debugger/qqmlprofiler_p.h
+++ b/src/qml/debugger/qqmlprofiler_p.h
@@ -55,15 +55,17 @@
#include <private/qqmlboundsignal_p.h>
#include <private/qfinitestack_p.h>
#include <private/qqmlbinding_p.h>
+#if QT_CONFIG(qml_debug)
#include "qqmlprofilerdefinitions_p.h"
#include "qqmlabstractprofileradapter_p.h"
+#endif
#include <QUrl>
#include <QString>
QT_BEGIN_NAMESPACE
-#ifdef QT_NO_QML_DEBUGGER
+#if !QT_CONFIG(qml_debug)
#define Q_QML_PROFILE_IF_ENABLED(feature, profiler, Code)
#define Q_QML_PROFILE(feature, profiler, Method)
@@ -149,82 +151,144 @@ class Q_QML_PRIVATE_EXPORT QQmlProfiler : public QObject, public QQmlProfilerDef
Q_OBJECT
public:
- class FunctionRefCount : public QQmlRefCount {
- public:
- FunctionRefCount(QV4::Function *function):
- m_function(function)
+ struct Location {
+ Location(const QQmlSourceLocation &location = QQmlSourceLocation(),
+ const QUrl &url = QUrl()) :
+ location(location), url(url) {}
+ QQmlSourceLocation location;
+ QUrl url;
+ };
+
+ // Unfortunately we have to resolve the locations right away because the QML context might not
+ // be available anymore when we send the data.
+ struct RefLocation : public Location {
+ RefLocation()
+ : Location(), locationType(MaximumRangeType), something(nullptr), sent(false)
+ {
+ }
+
+ RefLocation(QV4::Function *ref)
+ : Location(ref->sourceLocation()), locationType(Binding), sent(false)
+ {
+ function = ref;
+ function->compilationUnit->addref();
+ }
+
+ RefLocation(QV4::CompiledData::CompilationUnit *ref, const QUrl &url, const QV4::CompiledData::Object *obj, const QString &type)
+ : Location(QQmlSourceLocation(type, obj->location.line, obj->location.column), url),
+ locationType(Creating), sent(false)
+ {
+ unit = ref;
+ unit->addref();
+ }
+
+ RefLocation(QQmlBoundSignalExpression *ref)
+ : Location(ref->sourceLocation()), locationType(HandlingSignal), sent(false)
+ {
+ boundSignal = ref;
+ boundSignal->addref();
+ }
+
+ RefLocation(QQmlDataBlob *ref)
+ : Location(QQmlSourceLocation()), locationType(Compiling), sent(false)
{
- m_function->compilationUnit->addref();
+ blob = ref;
+ blob->addref();
}
- FunctionRefCount(const FunctionRefCount &other) :
- QQmlRefCount(other), m_function(other.m_function)
+ RefLocation(const RefLocation &other)
+ : Location(other),
+ locationType(other.locationType),
+ function(other.function),
+ sent(other.sent)
{
- m_function->compilationUnit->addref();
+ addref();
}
- FunctionRefCount &operator=(const FunctionRefCount &other)
+ RefLocation &operator=(const RefLocation &other)
{
if (this != &other) {
- QQmlRefCount::operator=(other);
- other.m_function->compilationUnit->addref();
- m_function->compilationUnit->release();
- m_function = other.m_function;
+ release();
+ Location::operator=(other);
+ locationType = other.locationType;
+ function = other.function;
+ sent = other.sent;
+ addref();
}
return *this;
}
- ~FunctionRefCount()
+ ~RefLocation()
{
- m_function->compilationUnit->release();
+ release();
}
- private:
- QV4::Function *m_function;
- };
-
- struct Location {
- Location(const QQmlSourceLocation &location = QQmlSourceLocation(),
- const QUrl &url = QUrl()) :
- location(location), url(url) {}
- QQmlSourceLocation location;
- QUrl url;
- };
+ void addref()
+ {
+ if (isNull())
+ return;
+
+ switch (locationType) {
+ case Binding:
+ function->compilationUnit->addref();
+ break;
+ case Creating:
+ unit->addref();
+ break;
+ case HandlingSignal:
+ boundSignal->addref();
+ break;
+ case Compiling:
+ blob->addref();
+ break;
+ default:
+ Q_ASSERT(locationType == MaximumRangeType);
+ break;
+ }
+ }
- // Unfortunately we have to resolve the locations right away because the QML context might not
- // be available anymore when we send the data.
- struct RefLocation : public Location {
- RefLocation() : Location(), locationType(MaximumRangeType), ref(nullptr), sent(false)
- {}
-
- RefLocation(QV4::Function *function) :
- Location(function->sourceLocation()), locationType(Binding),
- ref(new FunctionRefCount(function),
- QQmlRefPointer<QQmlRefCount>::Adopt), sent(false)
- {}
-
- RefLocation(QV4::CompiledData::CompilationUnit *ref, const QUrl &url, const QV4::CompiledData::Object *obj,
- const QString &type) :
- Location(QQmlSourceLocation(type, obj->location.line, obj->location.column), url),
- locationType(Creating), ref(ref), sent(false)
- {}
-
- RefLocation(QQmlBoundSignalExpression *ref) :
- Location(ref->sourceLocation()), locationType(HandlingSignal), ref(ref), sent(false)
- {}
-
- RefLocation(QQmlDataBlob *ref) :
- Location(QQmlSourceLocation(), ref->url()), locationType(Compiling), ref(ref),
- sent(false)
- {}
+ void release()
+ {
+ if (isNull())
+ return;
+
+ switch (locationType) {
+ case Binding:
+ function->compilationUnit->release();
+ break;
+ case Creating:
+ unit->release();
+ break;
+ case HandlingSignal:
+ boundSignal->release();
+ break;
+ case Compiling:
+ blob->release();
+ break;
+ default:
+ Q_ASSERT(locationType == MaximumRangeType);
+ break;
+ }
+ }
bool isValid() const
{
return locationType != MaximumRangeType;
}
+ bool isNull() const
+ {
+ return !something;
+ }
+
RangeType locationType;
- QQmlRefPointer<QQmlRefCount> ref;
+ union {
+ QV4::Function *function;
+ QV4::CompiledData::CompilationUnit *unit;
+ QQmlBoundSignalExpression *boundSignal;
+ QQmlDataBlob *blob;
+ void *something;
+ };
bool sent;
};
@@ -238,14 +302,19 @@ public:
// produce. The +1 makes the pointer point into the middle of the QV4::Function. Thus it
// still points to valid memory but we cannot accidentally create a duplicate key from
// another object.
- quintptr locationId(id(function) + 1);
+ // If there is no function, use a static but valid address: The profiler itself.
+ quintptr locationId = function ? id(function) + 1 : id(this);
m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(),
(1 << RangeStart | 1 << RangeLocation), Binding,
locationId));
RefLocation &location = m_locations[locationId];
- if (!location.isValid())
- location = RefLocation(function);
+ if (!location.isValid()) {
+ if (function)
+ location = RefLocation(function);
+ else // Make it valid without actually providing a location
+ location.locationType = Binding;
+ }
}
// Have toByteArrays() construct another RangeData event from the same QString later.
@@ -461,6 +530,6 @@ QT_END_NAMESPACE
Q_DECLARE_METATYPE(QVector<QQmlProfilerData>)
Q_DECLARE_METATYPE(QQmlProfiler::LocationHash)
-#endif // QT_NO_QML_DEBUGGER
+#endif // QT_CONFIG(qml_debug)
#endif // QQMLPROFILER_P_H
diff --git a/src/qml/debugger/qqmlprofilerdefinitions_p.h b/src/qml/debugger/qqmlprofilerdefinitions_p.h
index c6ae4593a9..f84a2c44e2 100644
--- a/src/qml/debugger/qqmlprofilerdefinitions_p.h
+++ b/src/qml/debugger/qqmlprofilerdefinitions_p.h
@@ -43,6 +43,8 @@
#include <private/qtqmlglobal_p.h>
#include <private/qv4profiling_p.h>
+QT_REQUIRE_CONFIG(qml_debug);
+
//
// W A R N I N G
// -------------
@@ -56,8 +58,6 @@
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_QML_DEBUGGER
-
struct QQmlProfilerDefinitions {
enum Message {
Event,
@@ -69,6 +69,7 @@ struct QQmlProfilerDefinitions {
PixmapCacheEvent,
SceneGraphFrame,
MemoryAllocation,
+ DebugMessage,
MaximumMessage
};
@@ -161,9 +162,27 @@ struct QQmlProfilerDefinitions {
MaximumInputEventType
};
-};
-#endif // QT_NO_QML_DEBUGGER
+ static ProfileFeature featureFromRangeType(RangeType range)
+ {
+ switch (range) {
+ case Painting:
+ return ProfilePainting;
+ case Compiling:
+ return ProfileCompiling;
+ case Creating:
+ return ProfileCreating;
+ case Binding:
+ return ProfileBinding;
+ case HandlingSignal:
+ return ProfileHandlingSignal;
+ case Javascript:
+ return ProfileJavaScript;
+ default:
+ return MaximumProfileFeature;
+ }
+ }
+};
QT_END_NAMESPACE
diff --git a/src/qml/doc/qtqml.qdocconf b/src/qml/doc/qtqml.qdocconf
index 74b61fd6e1..6161760471 100644
--- a/src/qml/doc/qtqml.qdocconf
+++ b/src/qml/doc/qtqml.qdocconf
@@ -53,6 +53,8 @@ manifestmeta.thumbnail.names += "QtQml/Chapter 4*" \
"QtQml/Chapter 6*" \
"QtQml/C++ Extensions: *"
+manifestmeta.highlighted.names = "QtQml/Writing QML Extensions with C++"
+
navigation.landingpage = "Qt QML"
navigation.cppclassespage = "Qt QML C++ Classes"
navigation.qmltypespage = "Qt QML QML Types"
diff --git a/src/qml/doc/snippets/code/src_script_qjsengine.cpp b/src/qml/doc/snippets/code/src_script_qjsengine.cpp
index 0310ae042c..6c58fd8a18 100644
--- a/src/qml/doc/snippets/code/src_script_qjsengine.cpp
+++ b/src/qml/doc/snippets/code/src_script_qjsengine.cpp
@@ -58,7 +58,7 @@ QJSValue three = myEngine.evaluate("1 + 2");
QJSValue fun = myEngine.evaluate("(function(a, b) { return a + b; })");
QJSValueList args;
args << 1 << 2;
-QJSValue threeAgain = fun.call(QJSValue(), args);
+QJSValue threeAgain = fun.call(args);
//! [1]
diff --git a/src/qml/doc/src/cppintegration/data.qdoc b/src/qml/doc/src/cppintegration/data.qdoc
index 3e02bbc458..9b2771c18e 100644
--- a/src/qml/doc/src/cppintegration/data.qdoc
+++ b/src/qml/doc/src/cppintegration/data.qdoc
@@ -271,10 +271,17 @@ In particular, QML currently supports:
\li \c {QList<qreal>}
\li \c {QList<bool>}
\li \c {QList<QString>} and \c{QStringList}
+ \li \c {QVector<QString>}
+ \li \c {std::vector<QString>}
\li \c {QList<QUrl>}
+ \li \c {QVector<QUrl>}
+ \li \c {std::vector<QUrl>}
\li \c {QVector<int>}
\li \c {QVector<qreal>}
\li \c {QVector<bool>}
+ \li \c {std::vector<int>}
+ \li \c {std::vector<qreal>}
+ \li \c {std::vector<bool>}
\endlist
These sequence types are implemented directly in terms of the underlying C++
@@ -294,6 +301,10 @@ If the sequence is returned from a Q_INVOKABLE function, access and mutation
is much cheaper, as no QObject property read or write occurs; instead, the
C++ sequence data is accessed and modified directly.
+In both the Q_PROPERTY and return from Q_INVOKABLE cases, the elements
+of a std::vector are copied. This copying may be an expensive operation,
+so std::vector should be used judiciously.
+
Other sequence types are not supported transparently, and instead an
instance of any other sequence type will be passed between QML and C++ as an
opaque QVariantList.
@@ -316,10 +327,17 @@ The default-constructed values for each sequence type are as follows:
\row \li QList<qreal> \li real value 0.0
\row \li QList<bool> \li boolean value \c {false}
\row \li QList<QString> and QStringList \li empty QString
+\row \li QVector<QString> \li empty QString
+\row \li std::vector<QString> \li empty QString
\row \li QList<QUrl> \li empty QUrl
+\row \li QVector<QUrl> \li empty QUrl
+\row \li std::vector<QUrl> \li empty QUrl
\row \li QVector<int> \li integer value 0
\row \li QVector<qreal> \li real value 0.0
\row \li QVector<bool> \li boolean value \c {false}
+\row \li std::vector<int> \li integer value 0
+\row \li std::vector<qreal> \li real value 0.0
+\row \li std::vector<bool> \li boolean value \c {false}
\endtable
If you wish to remove elements from a sequence rather than simply replace
@@ -327,6 +345,11 @@ them with default constructed values, do not use the indexed delete operator
("delete sequence[i]") but instead use the \c {splice} function
("sequence.splice(startIndex, deleteCount)").
+\section2 QByteArray to JavaScript ArrayBuffer
+
+The QML engine provides automatic type conversion between QByteArray values and
+JavaScript \c ArrayBuffer objects.
+
\section2 Value Types
Some value types in Qt such as QPoint are represented in JavaScript as objects
diff --git a/src/qml/doc/src/cppintegration/definetypes.qdoc b/src/qml/doc/src/cppintegration/definetypes.qdoc
index 7f88dc6836..027e4b9923 100644
--- a/src/qml/doc/src/cppintegration/definetypes.qdoc
+++ b/src/qml/doc/src/cppintegration/definetypes.qdoc
@@ -606,7 +606,6 @@ public:
RandomNumberGenerator(QObject *parent)
: QObject(parent), m_maxValue(100)
{
- qsrand(QDateTime::currentMSecsSinceEpoch() / 1000);
QObject::connect(&m_timer, SIGNAL(timeout()), SLOT(updateProperty()));
m_timer.start(500);
}
@@ -621,7 +620,7 @@ signals:
private slots:
void updateProperty() {
- m_targetProperty.write(qrand() % m_maxValue);
+ m_targetProperty.write(QRandomGenerator::global()->bounded(m_maxValue));
}
private:
diff --git a/src/qml/doc/src/cppintegration/extending-tutorial.qdoc b/src/qml/doc/src/cppintegration/extending-tutorial.qdoc
index ef6f2b52b3..26556644d6 100644
--- a/src/qml/doc/src/cppintegration/extending-tutorial.qdoc
+++ b/src/qml/doc/src/cppintegration/extending-tutorial.qdoc
@@ -150,6 +150,10 @@ Now we can build and run the application:
cannot update the binding if the \c name value changes. This is addressed in
the following chapters.
+The source code from the following files are referred to in this chapter:
+\noautolist
+\generatelist examplefiles .*chapter1.*
+
\section1 Chapter 2: Connecting to C++ Methods and Signals
\c extending-qml/chapter2-methods
@@ -189,6 +193,9 @@ disappears, and the application outputs:
qml: The chart has been cleared
\endcode
+The source code from the following files are referred to in this chapter:
+\generatelist examplefiles .*chapter2.*
+
\section1 Chapter 3: Adding Property Bindings
\c extending-qml/chapter3-bindings
@@ -237,6 +244,9 @@ automatically updated and cannot be used as flexibly in QML. Also, since
bindings are invoked so often and relied upon in QML usage, users of your
custom QML types may see unexpected behavior if bindings are not implemented.
+The source code from the following files are referred to in this chapter:
+\generatelist examplefiles .*chapter3.*
+
\section1 Chapter 4: Using Custom Property Types
\c extending-qml/chapter4-customPropertyTypes
@@ -314,6 +324,9 @@ type to the "Charts" type namespace, version 1.0:
\dots
\snippet tutorials/extending-qml/chapter4-customPropertyTypes/main.cpp 2
+The source code from the following files are referred to in this chapter:
+\generatelist examplefiles .*chapter4.*
+
\section1 Chapter 5: Using List Property Types
\c extending-qml/chapter5-listproperties
@@ -356,6 +369,9 @@ The \c PieSlice class has also been modified to include \c fromAngle and \c angl
properties and to draw the slice according to these values. This is a straightforward
modification if you have read the previous pages in this tutorial, so the code is not shown here.
+The source code from the following files are referred to in this chapter:
+\generatelist examplefiles .*chapter5.*
+
\section1 Chapter 6: Writing an Extension Plugin
\c extending-qml/chapter6-plugins
@@ -429,6 +445,9 @@ import path to the current directory so that it finds the \c qmldir file:
The module "Charts" will be loaded by the QML engine, and the types provided by that
module will be available for use in any QML document which imports it.
+The source code from the following files are referred to in this chapter:
+\generatelist examplefiles .*chapter6.*
+
\section1 Chapter 7: Summary
In this tutorial, we've shown the basic steps for creating a QML extension:
diff --git a/src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc b/src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc
index 4dc32e3588..7c2ff703c6 100644
--- a/src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc
+++ b/src/qml/doc/src/cppintegration/interactqmlfromcpp.qdoc
@@ -114,17 +114,7 @@ multiple children with the same \c objectName. In this case,
QObject::findChildren() can be used to find all children with a matching
\c objectName.
-\warning While it is possible to use C++ to access and manipulate QML objects
-deep into the object tree, we recommend that you do not take this approach
-outside of application testing and prototyping. One strength of QML and C++
-integration is the ability to implement the QML user interface separately
-from the C++ logic and dataset backend, and this strategy breaks if the C++
-side reaches deep into the QML components to manipulate them directly. This
-would make it difficult to, for example, swap a QML view component for
-another view, if the new component was missing a required \c objectName. It
-is better for the C++ implementation to know as little as possible about the
-QML user interface implementation and the composition of the QML object tree.
-
+\include warning.qdocinc
\section1 Accessing Members of a QML Object Type from C++
diff --git a/src/qml/doc/src/cppintegration/topic.qdoc b/src/qml/doc/src/cppintegration/topic.qdoc
index da06c195dc..6b6e308edf 100644
--- a/src/qml/doc/src/cppintegration/topic.qdoc
+++ b/src/qml/doc/src/cppintegration/topic.qdoc
@@ -190,6 +190,8 @@ invoke their methods and receive their signal notifications. This is possible du
all QML object types are implemented using QObject-derived classes, enabling the QML engine to
dynamically load and introspect objects through the Qt meta object system.
+\include warning.qdocinc
+
For more information on accessing QML objects from C++, see the documentation on
\l{qtqml-cppintegration-interactqmlfromcpp.html}{Interacting with QML Objects from C++}.
diff --git a/src/qml/doc/src/cppintegration/warning.qdocinc b/src/qml/doc/src/cppintegration/warning.qdocinc
new file mode 100644
index 0000000000..a5da22b2a7
--- /dev/null
+++ b/src/qml/doc/src/cppintegration/warning.qdocinc
@@ -0,0 +1,6 @@
+\warning Although it is possible to access QML objects from C++ and manipulate
+them, it is not the recommended approach, except for testing and prototyping
+purposes. One of the strengths of QML and C++ integration is the ability to
+implement UIs in QML separate from the C++ logic and dataset backend, and this
+fails if the C++ side starts manipulating QML directly. Such an approach also
+makes changing the QML UI difficult without affecting its C++ counterpart.
diff --git a/src/qml/doc/src/javascript/functionlist.qdoc b/src/qml/doc/src/javascript/functionlist.qdoc
index b99e92cf52..24ff640284 100644
--- a/src/qml/doc/src/javascript/functionlist.qdoc
+++ b/src/qml/doc/src/javascript/functionlist.qdoc
@@ -182,6 +182,7 @@
\li lastIndexOf(searchString, position)
\li localeCompare(that)
\li match(regexp)
+ \li repeat(count) // ECMAScript 6: Added in Qt 5.9
\li replace(searchValue, replaceValue)
\li search(regexp)
\li slice(start, end)
diff --git a/src/qml/doc/src/javascript/hostenvironment.qdoc b/src/qml/doc/src/javascript/hostenvironment.qdoc
index 3c3624f78d..d11e96df2b 100644
--- a/src/qml/doc/src/javascript/hostenvironment.qdoc
+++ b/src/qml/doc/src/javascript/hostenvironment.qdoc
@@ -74,6 +74,19 @@ Note that QML makes the following modifications to native objects:
\li Locale-aware conversion functions are added to the \l Date and \l Number prototypes.
\endlist
+In addition, QML also extends the behavior of the instanceof function to
+allow for type checking against QML types. This means that you may use it to
+verify that a variable is indeed the type you expect, for example:
+
+\qml
+ var v = something();
+ if (!v instanceof Item) {
+ throw new TypeError("I need an Item type!");
+ }
+
+ ...
+\endqml
+
\section1 JavaScript Environment Restrictions
diff --git a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
index 568ad930f2..31650db7c0 100644
--- a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
+++ b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
@@ -50,6 +50,7 @@ The set of QML object-type attribute types is as follows:
\li signal handler attributes
\li method attributes
\li attached properties and attached signal handler attributes
+\li enumeration attributes
\endlist
These attributes are discussed in detail below.
@@ -999,4 +1000,41 @@ ListView {
Now \c delegateItem.ListView.isCurrentItem correctly refers to the
\c isCurrentItem attached property of the delegate.
+\section2 Enumeration Attributes
+
+Enumerations provide a fixed set of named choices. They can be declared in QML using the \c enum keyword:
+
+\qml
+// MyText.qml
+Text {
+ enum TextType {
+ Normal,
+ Heading
+ }
+}
+\endqml
+
+As shown above, enumeration types (e.g. \c TextType) and values (e.g. \c Normal) must begin with an uppercase letter.
+
+Values are referred to via \c {<Type>.<EnumerationType>.<Value>} or \c {<Type>.<Value>}.
+
+\qml
+// MyText.qml
+Text {
+ enum TextType {
+ Normal,
+ Heading
+ }
+
+ property int textType: MyText.TextType.Normal
+
+ font.bold: textType == MyText.TextType.Heading
+ font.pixelSize: textType == MyText.TextType.Heading ? 24 : 12
+}
+\endqml
+
+More information on enumeration usage in QML can be found in the \l {QML Basic Types} \l enumeration documentation.
+
+The ability to declare enumerations in QML was introduced in Qt 5.10.
+
*/
diff --git a/src/qml/doc/src/qmllanguageref/syntax/propertybinding.qdoc b/src/qml/doc/src/qmllanguageref/syntax/propertybinding.qdoc
index b506de471f..a5ad6af4a2 100644
--- a/src/qml/doc/src/qmllanguageref/syntax/propertybinding.qdoc
+++ b/src/qml/doc/src/qmllanguageref/syntax/propertybinding.qdoc
@@ -179,6 +179,26 @@ Rectangle {
Now, after the space key is pressed, the rectangle's height will continue
auto-updating to always be three times its width.
+\section3 Debugging overwriting of bindings
+
+A common cause of bugs in QML applications is accidentally overwriting bindings
+with static values from JavaScript statements. To help developers track down
+problems of this kind, the QML engine is able to emit messages whenever a
+binding is lost due to imperative assignments.
+
+In order to generate such messages, you need to enable the informational output
+for the \c{qt.qml.binding.removal} logging category, for instance by calling:
+
+\code
+QLoggingCategory::setFilterRules(QStringLiteral("qt.qml.binding.removal.info=true"));
+\endcode
+
+Please refer to the QLoggingCategory documentation for more information about
+enabling output from logging categories.
+
+Note that is perfectly reasonable in some circumstances to overwrite bindings.
+Any message generated by the QML engine should be treated as a diagnostic aid,
+and not necessarily as evidence of a problem without further investigation.
\section2 Using \c this with Property Binding
diff --git a/src/qml/jit/jit.pri b/src/qml/jit/jit.pri
index 7ea4e951d5..2080844d93 100644
--- a/src/qml/jit/jit.pri
+++ b/src/qml/jit/jit.pri
@@ -1,22 +1,10 @@
-include(../../3rdparty/masm/masm-defs.pri)
-
INCLUDEPATH += $$PWD
INCLUDEPATH += $$OUT_PWD
-HEADERS += \
- $$PWD/qv4assembler_p.h \
- $$PWD/qv4regalloc_p.h \
- $$PWD/qv4targetplatform_p.h \
- $$PWD/qv4isel_masm_p.h \
- $$PWD/qv4binop_p.h \
- $$PWD/qv4unop_p.h \
- $$PWD/qv4registerinfo_p.h
-
SOURCES += \
- $$PWD/qv4assembler.cpp \
- $$PWD/qv4regalloc.cpp \
- $$PWD/qv4isel_masm.cpp \
- $$PWD/qv4binop.cpp \
- $$PWD/qv4unop.cpp \
+ $$PWD/qv4jit.cpp \
+ $$PWD/qv4assembler.cpp
-include(../../3rdparty/masm/masm.pri)
+HEADERS += \
+ $$PWD/qv4jit_p.h \
+ $$PWD/qv4assembler_p.h
diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp
index 71dabcd590..fdb795be92 100644
--- a/src/qml/jit/qv4assembler.cpp
+++ b/src/qml/jit/qv4assembler.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQml module of the Qt Toolkit.
@@ -37,498 +37,1279 @@
**
****************************************************************************/
-#include "qv4isel_masm_p.h"
-#include "qv4runtime_p.h"
-#include "qv4ssa_p.h"
-#include "qv4regalloc_p.h"
+#include <QBuffer>
+
+#include "qv4engine_p.h"
#include "qv4assembler_p.h"
+#include <private/qv4function_p.h>
+#include <private/qv4runtime_p.h>
+#include <wtf/Vector.h>
+#include <assembler/MacroAssembler.h>
+#include <assembler/MacroAssemblerCodeRef.h>
#include <assembler/LinkBuffer.h>
#include <WTFStubs.h>
-#if !defined(V4_BOOTSTRAP)
-#include "qv4function_p.h"
-#endif
+#undef ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES
-#include <iostream>
-#include <QBuffer>
-#include <QCoreApplication>
+#ifdef V4_ENABLE_JIT
-#if ENABLE(ASSEMBLER)
+QT_BEGIN_NAMESPACE
+namespace QV4 {
+namespace JIT {
-#if USE(UDIS86)
-# include <udis86.h>
-#endif
+#define callHelper(x) PlatformAssemblerCommon::callRuntime(#x, reinterpret_cast<void *>(&x))
-using namespace QV4;
-using namespace QV4::JIT;
+const QV4::Value::ValueTypeInternal IntegerTag = QV4::Value::ValueTypeInternal::Integer;
+const int IsIntegerConvertible_Shift = QV4::Value::IsIntegerConvertible_Shift;
-CompilationUnit::~CompilationUnit()
+static ReturnedValue toNumberHelper(ReturnedValue v)
{
+ return Encode(Value::fromReturnedValue(v).toNumber());
}
-#if !defined(V4_BOOTSTRAP)
+static ReturnedValue toInt32Helper(ReturnedValue v)
+{
+ return Encode(Value::fromReturnedValue(v).toInt32());
+}
+
+#if defined(Q_PROCESSOR_X86_64) || defined(ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES)
+#if defined(Q_OS_LINUX) || defined(Q_OS_QNX) || defined(Q_OS_FREEBSD) || defined(Q_OS_DARWIN)
-void CompilationUnit::linkBackendToEngine(ExecutionEngine *engine)
+struct PlatformAssembler_X86_64_SysV : JSC::MacroAssembler<JSC::MacroAssemblerX86_64>
{
- runtimeFunctions.resize(data->functionTableSize);
- runtimeFunctions.fill(0);
- for (int i = 0 ;i < runtimeFunctions.size(); ++i) {
- const CompiledData::Function *compiledFunction = data->functionAt(i);
+ static const RegisterID NoRegister = RegisterID(-1);
+
+ static const RegisterID ReturnValueRegister = RegisterID::eax;
+ static const RegisterID ReturnValueRegisterValue = ReturnValueRegister;
+ static const RegisterID AccumulatorRegister = RegisterID::eax;
+ static const RegisterID AccumulatorRegisterValue = AccumulatorRegister;
+ static const RegisterID ScratchRegister = RegisterID::r10;
+ static const RegisterID ScratchRegister2 = RegisterID::r9; // Note: overlaps with Arg5Reg, so do not use while setting up a call!
+ static const RegisterID JSStackFrameRegister = RegisterID::r12;
+ static const RegisterID CppStackFrameRegister = RegisterID::r13;
+ static const RegisterID EngineRegister = RegisterID::r14;
+ static const RegisterID StackPointerRegister = RegisterID::esp;
+ static const RegisterID FramePointerRegister = RegisterID::ebp;
+ static const FPRegisterID FPScratchRegister = FPRegisterID::xmm1;
+
+ static const RegisterID Arg0Reg = RegisterID::edi;
+ static const RegisterID Arg1Reg = RegisterID::esi;
+ static const RegisterID Arg2Reg = RegisterID::edx;
+ static const RegisterID Arg3Reg = RegisterID::ecx;
+ static const RegisterID Arg4Reg = RegisterID::r8;
+ static const RegisterID Arg5Reg = RegisterID::r9;
+ static const RegisterID Arg6Reg = NoRegister;
+ static const RegisterID Arg7Reg = NoRegister;
+ static const int ArgInRegCount = 6;
+
+ void popValue()
+ {
+ addPtr(TrustedImmPtr(sizeof(ReturnedValue)), StackPointerRegister);
+ }
- QV4::Function *runtimeFunction = new QV4::Function(engine, this, compiledFunction,
- (ReturnedValue (*)(QV4::ExecutionEngine *, const uchar *)) codeRefs[i].code().executableAddress());
- runtimeFunctions[i] = runtimeFunction;
+ void generatePlatformFunctionEntry()
+ {
+ push(RegisterID::ebp);
+ move(RegisterID::esp, RegisterID::ebp);
+ move(TrustedImmPtr(nullptr), AccumulatorRegister); push(AccumulatorRegister); // exceptionHandler
+ push(JSStackFrameRegister);
+ push(CppStackFrameRegister);
+ push(EngineRegister);
+ move(Arg0Reg, CppStackFrameRegister);
+ move(Arg1Reg, EngineRegister);
}
-}
-bool CompilationUnit::memoryMapCode(QString *errorString)
-{
- Q_UNUSED(errorString);
- codeRefs.resize(data->functionTableSize);
+ void generatePlatformFunctionExit()
+ {
+ pop(EngineRegister);
+ pop(CppStackFrameRegister);
+ pop(JSStackFrameRegister);
+ pop(); // exceptionHandler
+ pop(RegisterID::ebp);
+ ret();
+ }
- const char *basePtr = reinterpret_cast<const char *>(data);
+ void callAbsolute(const void *funcPtr)
+ {
+ move(TrustedImmPtr(funcPtr), ScratchRegister);
+ call(ScratchRegister);
+ }
- for (uint i = 0; i < data->functionTableSize; ++i) {
- const CompiledData::Function *compiledFunction = data->functionAt(i);
- void *codePtr = const_cast<void *>(reinterpret_cast<const void *>(basePtr + compiledFunction->codeOffset));
- JSC::MacroAssemblerCodeRef codeRef = JSC::MacroAssemblerCodeRef::createSelfManagedCodeRef(JSC::MacroAssemblerCodePtr(codePtr));
- JSC::ExecutableAllocator::makeExecutable(codePtr, compiledFunction->codeSize);
- codeRefs[i] = codeRef;
+ void pushAligned(RegisterID reg)
+ {
+ subPtr(TrustedImm32(PointerSize), StackPointerRegister);
+ push(reg);
+ }
- static const bool showCode = qEnvironmentVariableIsSet("QV4_SHOW_ASM");
- if (showCode) {
- WTF::dataLogF("Mapped JIT code for %s\n", qPrintable(stringAt(compiledFunction->nameIndex)));
- disassemble(codeRef.code(), compiledFunction->codeSize, " ", WTF::dataFile());
- }
+ void popAligned(RegisterID reg)
+ {
+ pop(reg);
+ addPtr(TrustedImm32(PointerSize), StackPointerRegister);
}
+};
- return true;
-}
+typedef PlatformAssembler_X86_64_SysV PlatformAssemblerBase;
-#endif // !defined(V4_BOOTSTRAP)
+#endif
+#if defined(Q_OS_WIN)
-void CompilationUnit::prepareCodeOffsetsForDiskStorage(CompiledData::Unit *unit)
+struct PlatformAssembler_Win64 : JSC::MacroAssembler<JSC::MacroAssemblerX86_64>
{
- const int codeAlignment = 16;
- quint64 offset = WTF::roundUpToMultipleOf(codeAlignment, unit->unitSize);
- Q_ASSERT(int(unit->functionTableSize) == codeRefs.size());
- for (int i = 0; i < codeRefs.size(); ++i) {
- CompiledData::Function *compiledFunction = const_cast<CompiledData::Function *>(unit->functionAt(i));
- compiledFunction->codeOffset = offset;
- compiledFunction->codeSize = codeRefs.at(i).size();
- offset = WTF::roundUpToMultipleOf(codeAlignment, offset + compiledFunction->codeSize);
+ static const RegisterID NoRegister = RegisterID(-1);
+
+ static const RegisterID ReturnValueRegister = RegisterID::eax;
+ static const RegisterID ReturnValueRegisterValue = ReturnValueRegister;
+ static const RegisterID AccumulatorRegister = RegisterID::eax;
+ static const RegisterID AccumulatorRegisterValue = AccumulatorRegister;
+ static const RegisterID ScratchRegister = RegisterID::r10;
+ static const RegisterID ScratchRegister2 = RegisterID::r9; // Note: overlaps with Arg3Reg, so do not use while setting up a call!
+ static const RegisterID JSStackFrameRegister = RegisterID::r12;
+ static const RegisterID CppStackFrameRegister = RegisterID::r13;
+ static const RegisterID EngineRegister = RegisterID::r14;
+ static const RegisterID StackPointerRegister = RegisterID::esp;
+ static const RegisterID FramePointerRegister = RegisterID::ebp;
+ static const FPRegisterID FPScratchRegister = FPRegisterID::xmm1;
+
+ static const RegisterID Arg0Reg = RegisterID::ecx;
+ static const RegisterID Arg1Reg = RegisterID::edx;
+ static const RegisterID Arg2Reg = RegisterID::r8;
+ static const RegisterID Arg3Reg = RegisterID::r9;
+ static const RegisterID Arg4Reg = NoRegister;
+ static const RegisterID Arg5Reg = NoRegister;
+ static const RegisterID Arg6Reg = NoRegister;
+ static const RegisterID Arg7Reg = NoRegister;
+ static const int ArgInRegCount = 4;
+
+ void popValue()
+ {
+ addPtr(TrustedImmPtr(sizeof(ReturnedValue)), StackPointerRegister);
}
-}
-bool CompilationUnit::saveCodeToDisk(QIODevice *device, const CompiledData::Unit *unit, QString *errorString)
+ void generatePlatformFunctionEntry()
+ {
+ push(RegisterID::ebp);
+ move(RegisterID::esp, RegisterID::ebp);
+ move(TrustedImmPtr(nullptr), AccumulatorRegister); push(AccumulatorRegister); // exceptionHandler
+ push(JSStackFrameRegister);
+ push(CppStackFrameRegister);
+ push(EngineRegister);
+ move(Arg0Reg, CppStackFrameRegister);
+ move(Arg1Reg, EngineRegister);
+ }
+
+ void generatePlatformFunctionExit()
+ {
+ pop(EngineRegister);
+ pop(CppStackFrameRegister);
+ pop(JSStackFrameRegister);
+ pop(); // exceptionHandler
+ pop(RegisterID::ebp);
+ ret();
+ }
+
+ void callAbsolute(const void *funcPtr)
+ {
+ move(TrustedImmPtr(funcPtr), ScratchRegister);
+ subPtr(TrustedImm32(4 * PointerSize), StackPointerRegister);
+ call(ScratchRegister);
+ addPtr(TrustedImm32(4 * PointerSize), StackPointerRegister);
+ }
+
+ void pushAligned(RegisterID reg)
+ {
+ subPtr(TrustedImm32(PointerSize), StackPointerRegister);
+ push(reg);
+ }
+
+ void popAligned(RegisterID reg)
+ {
+ pop(reg);
+ addPtr(TrustedImm32(PointerSize), StackPointerRegister);
+ }
+};
+
+typedef PlatformAssembler_Win64 PlatformAssemblerBase;
+
+#endif
+#endif
+
+#if (defined(Q_PROCESSOR_X86) && !defined(Q_PROCESSOR_X86_64)) || defined(ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES)
+
+struct PlatformAssembler_X86_All : JSC::MacroAssembler<JSC::MacroAssemblerX86>
{
- Q_ASSERT(device->pos() == unit->unitSize);
- Q_ASSERT(device->atEnd());
- Q_ASSERT(int(unit->functionTableSize) == codeRefs.size());
+ static const RegisterID NoRegister = RegisterID(-1);
+
+ static const RegisterID ReturnValueRegisterValue = RegisterID::eax;
+ static const RegisterID ReturnValueRegisterTag = RegisterID::edx;
+ static const RegisterID ScratchRegister = RegisterID::ecx;
+ static const RegisterID AccumulatorRegisterValue = ReturnValueRegisterValue;
+ static const RegisterID AccumulatorRegisterTag = ReturnValueRegisterTag;
+ static const RegisterID JSStackFrameRegister = RegisterID::ebx;
+ static const RegisterID CppStackFrameRegister = RegisterID::esi;
+ static const RegisterID EngineRegister = RegisterID::edi;
+ static const RegisterID StackPointerRegister = RegisterID::esp;
+ static const RegisterID FramePointerRegister = RegisterID::ebp;
+ static const FPRegisterID FPScratchRegister = FPRegisterID::xmm1;
+
+ static const RegisterID Arg0Reg = NoRegister;
+ static const RegisterID Arg1Reg = NoRegister;
+ static const RegisterID Arg2Reg = NoRegister;
+ static const RegisterID Arg3Reg = NoRegister;
+ static const RegisterID Arg4Reg = NoRegister;
+ static const RegisterID Arg5Reg = NoRegister;
+ static const RegisterID Arg6Reg = NoRegister;
+ static const RegisterID Arg7Reg = NoRegister;
+ static const int ArgInRegCount = 0;
+
+ void popValue()
+ {
+ addPtr(TrustedImmPtr(sizeof(ReturnedValue)), StackPointerRegister);
+ }
- QByteArray padding;
+ void generatePlatformFunctionEntry()
+ {
+ push(RegisterID::ebp);
+ move(RegisterID::esp, RegisterID::ebp);
+ move(TrustedImmPtr(nullptr), AccumulatorRegisterValue); push(AccumulatorRegisterValue); // exceptionHandler
+ push(JSStackFrameRegister);
+ push(CppStackFrameRegister);
+ push(EngineRegister);
+ loadPtr(Address(FramePointerRegister, 2 * PointerSize), CppStackFrameRegister);
+ loadPtr(Address(FramePointerRegister, 3 * PointerSize), EngineRegister);
+ }
- for (int i = 0; i < codeRefs.size(); ++i) {
- const CompiledData::Function *compiledFunction = unit->functionAt(i);
+ void generatePlatformFunctionExit()
+ {
+ pop(EngineRegister);
+ pop(CppStackFrameRegister);
+ pop(JSStackFrameRegister);
+ pop(); // exceptionHandler
+ pop(RegisterID::ebp);
+ ret();
+ }
- if (device->pos() > qint64(compiledFunction->codeOffset)) {
- *errorString = QStringLiteral("Invalid state of cache file to write.");
- return false;
- }
+ void callAbsolute(const void *funcPtr)
+ {
+ move(TrustedImmPtr(funcPtr), ScratchRegister);
+ call(ScratchRegister);
+ }
- const quint64 paddingSize = compiledFunction->codeOffset - device->pos();
- padding.fill(0, paddingSize);
- qint64 written = device->write(padding);
- if (written != padding.size()) {
- *errorString = device->errorString();
- return false;
- }
+ void pushAligned(RegisterID reg)
+ {
+ subPtr(TrustedImm32(PointerSize), StackPointerRegister);
+ push(reg);
+ }
- const void *undecoratedCodePtr = codeRefs.at(i).code().dataLocation();
- written = device->write(reinterpret_cast<const char *>(undecoratedCodePtr), compiledFunction->codeSize);
- if (written != qint64(compiledFunction->codeSize)) {
- *errorString = device->errorString();
- return false;
- }
+ void popAligned(RegisterID reg)
+ {
+ pop(reg);
+ addPtr(TrustedImm32(PointerSize), StackPointerRegister);
}
- return true;
-}
+};
-template <typename TargetConfiguration>
-Assembler<TargetConfiguration>::Assembler(QV4::Compiler::JSUnitGenerator *jsGenerator, IR::Function* function, QV4::ExecutableAllocator *executableAllocator)
- : _function(function)
- , _nextBlock(0)
- , _executableAllocator(executableAllocator)
- , _jsGenerator(jsGenerator)
-{
- _addrs.resize(_function->basicBlockCount());
- _patches.resize(_function->basicBlockCount());
- _labelPatches.resize(_function->basicBlockCount());
-}
+typedef PlatformAssembler_X86_All PlatformAssemblerBase;
-template <typename TargetConfiguration>
-void Assembler<TargetConfiguration>::registerBlock(IR::BasicBlock* block, IR::BasicBlock *nextBlock)
-{
- _addrs[block->index()] = label();
- catchBlock = block->catchBlock;
- _nextBlock = nextBlock;
-}
+#endif
+
+#if defined(Q_PROCESSOR_ARM_64) || defined(ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES)
-template <typename TargetConfiguration>
-void Assembler<TargetConfiguration>::jumpToBlock(IR::BasicBlock* current, IR::BasicBlock *target)
+struct PlatformAssembler_ARM64 : JSC::MacroAssembler<JSC::MacroAssemblerARM64>
{
- Q_UNUSED(current);
+ static const RegisterID NoRegister = RegisterID(-1);
+
+ static const RegisterID ReturnValueRegister = JSC::ARM64Registers::x0;
+ static const RegisterID ReturnValueRegisterValue = ReturnValueRegister;
+ static const RegisterID AccumulatorRegister = JSC::ARM64Registers::x9;
+ static const RegisterID AccumulatorRegisterValue = AccumulatorRegister;
+ static const RegisterID ScratchRegister = JSC::ARM64Registers::x10;
+ static const RegisterID ScratchRegister2 = JSC::ARM64Registers::x7; // Note: overlaps with Arg7Reg, so do not use while setting up a call!
+ static const RegisterID JSStackFrameRegister = JSC::ARM64Registers::x19;
+ static const RegisterID CppStackFrameRegister = JSC::ARM64Registers::x20;
+ static const RegisterID EngineRegister = JSC::ARM64Registers::x21;
+ static const RegisterID StackPointerRegister = JSC::ARM64Registers::sp;
+ static const RegisterID FramePointerRegister = JSC::ARM64Registers::fp;
+ static const FPRegisterID FPScratchRegister = JSC::ARM64Registers::q1;
+
+ static const RegisterID Arg0Reg = JSC::ARM64Registers::x0;
+ static const RegisterID Arg1Reg = JSC::ARM64Registers::x1;
+ static const RegisterID Arg2Reg = JSC::ARM64Registers::x2;
+ static const RegisterID Arg3Reg = JSC::ARM64Registers::x3;
+ static const RegisterID Arg4Reg = JSC::ARM64Registers::x4;
+ static const RegisterID Arg5Reg = JSC::ARM64Registers::x5;
+ static const RegisterID Arg6Reg = JSC::ARM64Registers::x6;
+ static const RegisterID Arg7Reg = JSC::ARM64Registers::x7;
+ static const int ArgInRegCount = 8;
+
+ void push(RegisterID src)
+ {
+ pushToSave(src);
+ }
- if (target != _nextBlock)
- _patches[target->index()].push_back(jump());
-}
+ void pop(RegisterID dest)
+ {
+ popToRestore(dest);
+ }
-template <typename TargetConfiguration>
-void Assembler<TargetConfiguration>::addPatch(IR::BasicBlock* targetBlock, Jump targetJump)
-{
- _patches[targetBlock->index()].push_back(targetJump);
-}
+ void pop()
+ {
+ add64(TrustedImm32(16), stackPointerRegister);
+ }
-template <typename TargetConfiguration>
-void Assembler<TargetConfiguration>::addPatch(DataLabelPtr patch, Label target)
-{
- DataLabelPatch p;
- p.dataLabel = patch;
- p.target = target;
- _dataLabelPatches.push_back(p);
-}
+ void popValue()
+ {
+ pop();
+ }
-template <typename TargetConfiguration>
-void Assembler<TargetConfiguration>::addPatch(DataLabelPtr patch, IR::BasicBlock *target)
-{
- _labelPatches[target->index()].push_back(patch);
-}
+ void generatePlatformFunctionEntry()
+ {
+ pushPair(JSC::ARM64Registers::fp, JSC::ARM64Registers::lr);
+ move(RegisterID::sp, RegisterID::fp);
+ move(TrustedImmPtr(nullptr), AccumulatorRegister); // exceptionHandler
+ pushPair(JSStackFrameRegister, AccumulatorRegister);
+ pushPair(EngineRegister, CppStackFrameRegister);
+ move(Arg0Reg, CppStackFrameRegister);
+ move(Arg1Reg, EngineRegister);
+ }
-template <typename TargetConfiguration>
-void Assembler<TargetConfiguration>::generateCJumpOnNonZero(RegisterID reg, IR::BasicBlock *currentBlock,
- IR::BasicBlock *trueBlock, IR::BasicBlock *falseBlock)
-{
- generateCJumpOnCompare(RelationalCondition::NotEqual, reg, TrustedImm32(0), currentBlock, trueBlock, falseBlock);
-}
+ void generatePlatformFunctionExit()
+ {
+ move(AccumulatorRegister, ReturnValueRegister);
+ popPair(EngineRegister, CppStackFrameRegister);
+ popPair(JSStackFrameRegister, AccumulatorRegister);
+ popPair(JSC::ARM64Registers::fp, JSC::ARM64Registers::lr);
+ ret();
+ }
-template <typename TargetConfiguration>
-void Assembler<TargetConfiguration>::generateCJumpOnCompare(RelationalCondition cond,
- RegisterID left,
- TrustedImm32 right,
- IR::BasicBlock *currentBlock,
- IR::BasicBlock *trueBlock,
- IR::BasicBlock *falseBlock)
-{
- if (trueBlock == _nextBlock) {
- Jump target = branch32(invert(cond), left, right);
- addPatch(falseBlock, target);
- } else {
- Jump target = branch32(cond, left, right);
- addPatch(trueBlock, target);
- jumpToBlock(currentBlock, falseBlock);
+ void callAbsolute(const void *funcPtr)
+ {
+ move(TrustedImmPtr(funcPtr), ScratchRegister);
+ call(ScratchRegister);
}
-}
-template <typename TargetConfiguration>
-void Assembler<TargetConfiguration>::generateCJumpOnCompare(RelationalCondition cond,
- RegisterID left,
- RegisterID right,
- IR::BasicBlock *currentBlock,
- IR::BasicBlock *trueBlock,
- IR::BasicBlock *falseBlock)
-{
- if (trueBlock == _nextBlock) {
- Jump target = branch32(invert(cond), left, right);
- addPatch(falseBlock, target);
- } else {
- Jump target = branch32(cond, left, right);
- addPatch(trueBlock, target);
- jumpToBlock(currentBlock, falseBlock);
+ void pushAligned(RegisterID reg)
+ {
+ pushToSave(reg);
}
-}
-template <typename TargetConfiguration>
-typename Assembler<TargetConfiguration>::Pointer Assembler<TargetConfiguration>::loadAddress(RegisterID tmp, IR::Expr *e)
-{
- IR::Temp *t = e->asTemp();
- if (t)
- return loadTempAddress(t);
- else
- return loadArgLocalAddress(tmp, e->asArgLocal());
-}
+ void popAligned(RegisterID reg)
+ {
+ popToRestore(reg);
+ }
+};
+
+typedef PlatformAssembler_ARM64 PlatformAssemblerBase;
+
+#endif
+
+#if defined(Q_PROCESSOR_ARM_32) || defined(ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES)
-template <typename TargetConfiguration>
-typename Assembler<TargetConfiguration>::Pointer Assembler<TargetConfiguration>::loadTempAddress(IR::Temp *t)
+struct PlatformAssembler_ARM32 : JSC::MacroAssembler<JSC::MacroAssemblerARMv7>
{
- if (t->kind == IR::Temp::StackSlot)
- return stackSlotPointer(t);
- else
- Q_UNREACHABLE();
-}
+ static const RegisterID NoRegister = RegisterID(-1);
+
+ static const RegisterID ReturnValueRegisterValue = JSC::ARMRegisters::r0;
+ static const RegisterID ReturnValueRegisterTag = JSC::ARMRegisters::r1;
+ static const RegisterID ScratchRegister = JSC::ARMRegisters::r2;
+ static const RegisterID AccumulatorRegisterValue = JSC::ARMRegisters::r4;
+ static const RegisterID AccumulatorRegisterTag = JSC::ARMRegisters::r5;
+ // r6 is used by MacroAssemblerARMv7
+ static const RegisterID JSStackFrameRegister = JSC::ARMRegisters::r8;
+ static const RegisterID CppStackFrameRegister = JSC::ARMRegisters::r10;
+#if CPU(ARM_THUMB2) || defined(V4_BOOTSTRAP)
+ static const RegisterID FramePointerRegister = JSC::ARMRegisters::r7;
+ static const RegisterID EngineRegister = JSC::ARMRegisters::r11;
+#else // Thumbs down
+ static const RegisterID FramePointerRegister = JSC::ARMRegisters::r11;
+ static const RegisterID EngineRegister = JSC::ARMRegisters::r7;
+#endif
+ static const RegisterID StackPointerRegister = JSC::ARMRegisters::r13;
+ static const FPRegisterID FPScratchRegister = JSC::ARMRegisters::d1;
+
+ static const RegisterID Arg0Reg = JSC::ARMRegisters::r0;
+ static const RegisterID Arg1Reg = JSC::ARMRegisters::r1;
+ static const RegisterID Arg2Reg = JSC::ARMRegisters::r2;
+ static const RegisterID Arg3Reg = JSC::ARMRegisters::r3;
+ static const RegisterID Arg4Reg = NoRegister;
+ static const RegisterID Arg5Reg = NoRegister;
+ static const RegisterID Arg6Reg = NoRegister;
+ static const RegisterID Arg7Reg = NoRegister;
+ static const int ArgInRegCount = 4;
+
+ void popValue()
+ {
+ addPtr(TrustedImm32(sizeof(ReturnedValue)), StackPointerRegister);
+ }
+
+ void generatePlatformFunctionEntry()
+ {
+ push(JSC::ARMRegisters::lr);
+ push(FramePointerRegister);
+ move(StackPointerRegister, FramePointerRegister);
+ push(TrustedImm32(0)); // exceptionHandler
+ push(AccumulatorRegisterValue);
+ push(AccumulatorRegisterTag);
+ push(addressTempRegister);
+ push(JSStackFrameRegister);
+ push(CppStackFrameRegister);
+ push(EngineRegister);
+ subPtr(TrustedImm32(4), StackPointerRegister); // stack alignment
+ move(Arg0Reg, CppStackFrameRegister);
+ move(Arg1Reg, EngineRegister);
+ }
+
+ void generatePlatformFunctionExit()
+ {
+ move(AccumulatorRegisterValue, ReturnValueRegisterValue);
+ move(AccumulatorRegisterTag, ReturnValueRegisterTag);
+ addPtr(TrustedImm32(4), StackPointerRegister); // stack alignment
+ pop(EngineRegister);
+ pop(CppStackFrameRegister);
+ pop(JSStackFrameRegister);
+ pop(addressTempRegister);
+ pop(AccumulatorRegisterTag);
+ pop(AccumulatorRegisterValue);
+ pop(); // exceptionHandler
+ pop(FramePointerRegister);
+ pop(JSC::ARMRegisters::lr);
+ ret();
+ }
+
+ void callAbsolute(const void *funcPtr)
+ {
+ move(TrustedImmPtr(funcPtr), dataTempRegister);
+ call(dataTempRegister);
+ }
+
+ void pushAligned(RegisterID reg)
+ {
+ subPtr(TrustedImm32(PointerSize), StackPointerRegister);
+ push(reg);
+ }
+
+ void popAligned(RegisterID reg)
+ {
+ pop(reg);
+ addPtr(TrustedImm32(PointerSize), StackPointerRegister);
+ }
+};
-template <typename TargetConfiguration>
-typename Assembler<TargetConfiguration>::Pointer Assembler<TargetConfiguration>::loadArgLocalAddress(RegisterID baseReg, IR::ArgLocal *al)
+typedef PlatformAssembler_ARM32 PlatformAssemblerBase;
+
+#endif
+
+struct PlatformAssemblerCommon : PlatformAssemblerBase
{
- int32_t offset = 0;
- int scope = al->scope;
- loadPtr(Address(EngineRegister, targetStructureOffset(offsetof(EngineBase, current))), baseReg);
+ const Value* constantTable;
+ struct JumpTarget { JSC::MacroAssemblerBase::Jump jump; int offset; };
+ std::vector<JumpTarget> patches;
+ struct ExceptionHanlderTarget { JSC::MacroAssemblerBase::DataLabelPtr label; int offset; };
+ std::vector<ExceptionHanlderTarget> ehTargets;
+ QHash<int, JSC::MacroAssemblerBase::Label> labelsByOffset;
+ QHash<const void *, const char *> functions;
+ std::vector<Jump> catchyJumps;
+ Label functionExit;
+
+ Address exceptionHandlerAddress() const
+ {
+ return Address(FramePointerRegister, -1 * PointerSize);
+ }
- const qint32 outerOffset = targetStructureOffset(Heap::ExecutionContext::baseOffset + offsetof(Heap::ExecutionContextData, outer));
+ Address contextAddress() const
+ {
+ return Address(JSStackFrameRegister, offsetof(CallData, context));
+ }
- if (scope) {
- loadPtr(Address(baseReg, outerOffset), baseReg);
- --scope;
- while (scope) {
- loadPtr(Address(baseReg, outerOffset), baseReg);
- --scope;
+ RegisterID registerForArg(int arg) const
+ {
+ Q_ASSERT(arg >= 0);
+ Q_ASSERT(arg < ArgInRegCount);
+ switch (arg) {
+ case 0: return Arg0Reg;
+ case 1: return Arg1Reg;
+ case 2: return Arg2Reg;
+ case 3: return Arg3Reg;
+ case 4: return Arg4Reg;
+ case 5: return Arg5Reg;
+ case 6: return Arg6Reg;
+ case 7: return Arg7Reg;
+ default:
+ Q_UNIMPLEMENTED();
+ Q_UNREACHABLE();
}
}
- switch (al->kind) {
- case IR::ArgLocal::Formal:
- case IR::ArgLocal::ScopedFormal: {
- const qint32 callDataOffset = targetStructureOffset(Heap::ExecutionContext::baseOffset + offsetof(Heap::ExecutionContextData, callData));
- loadPtr(Address(baseReg, callDataOffset), baseReg);
- offset = sizeof(CallData) + (al->index - 1) * sizeof(Value);
- } break;
- case IR::ArgLocal::Local:
- case IR::ArgLocal::ScopedLocal: {
- const qint32 localsOffset = targetStructureOffset(Heap::CallContext::baseOffset + offsetof(Heap::CallContextData, locals));
- loadPtr(Address(baseReg, localsOffset), baseReg);
- offset = al->index * sizeof(Value);
- } break;
- default:
- Q_UNREACHABLE();
+
+ void callRuntime(const char *functionName, const void *funcPtr)
+ {
+ functions.insert(funcPtr, functionName);
+ callAbsolute(funcPtr);
}
- return Pointer(baseReg, offset);
-}
-template <typename TargetConfiguration>
-typename Assembler<TargetConfiguration>::Pointer Assembler<TargetConfiguration>::loadStringAddress(RegisterID reg, const QString &string)
-{
- loadPtr(Address(Assembler::EngineRegister, targetStructureOffset(offsetof(QV4::EngineBase, current))), Assembler::ScratchRegister);
- loadPtr(Address(Assembler::ScratchRegister, targetStructureOffset(Heap::ExecutionContext::baseOffset + offsetof(Heap::ExecutionContextData, compilationUnit))), Assembler::ScratchRegister);
- loadPtr(Address(Assembler::ScratchRegister, offsetof(CompiledData::CompilationUnitBase, runtimeStrings)), reg);
- const int id = _jsGenerator->registerString(string);
- return Pointer(reg, id * RegisterSize);
-}
+ Address loadFunctionPtr(RegisterID target)
+ {
+ Address addr(CppStackFrameRegister, offsetof(CppStackFrame, v4Function));
+ loadPtr(addr, target);
+ return Address(target);
+ }
-template <typename TargetConfiguration>
-typename Assembler<TargetConfiguration>::Address Assembler<TargetConfiguration>::loadConstant(IR::Const *c, RegisterID baseReg)
-{
- return loadConstant(convertToValue<TargetPrimitive>(c), baseReg);
-}
+ Address loadCompilationUnitPtr(RegisterID target)
+ {
+ Address addr = loadFunctionPtr(target);
+ addr.offset = offsetof(QV4::Function, compilationUnit);
+ loadPtr(addr, target);
+ return Address(target);
+ }
-template <typename TargetConfiguration>
-typename Assembler<TargetConfiguration>::Address Assembler<TargetConfiguration>::loadConstant(const TargetPrimitive &v, RegisterID baseReg)
-{
- loadPtr(Address(Assembler::EngineRegister, targetStructureOffset(offsetof(QV4::EngineBase, current))), baseReg);
- loadPtr(Address(baseReg, targetStructureOffset(Heap::ExecutionContext::baseOffset + offsetof(Heap::ExecutionContextData, constantTable))), baseReg);
- const int index = _jsGenerator->registerConstant(v.rawValue());
- return Address(baseReg, index * sizeof(QV4::Value));
-}
+ Address loadConstAddress(int constIndex, RegisterID baseReg = ScratchRegister)
+ {
+ Address addr = loadCompilationUnitPtr(baseReg);
+ addr.offset = offsetof(QV4::CompiledData::CompilationUnitBase, constants);
+ loadPtr(addr, baseReg);
+ addr.offset = constIndex * int(sizeof(QV4::Value));
+ return addr;
+ }
-template <typename TargetConfiguration>
-void Assembler<TargetConfiguration>::loadStringRef(RegisterID reg, const QString &string)
-{
- const int id = _jsGenerator->registerString(string);
- move(TrustedImm32(id), reg);
-}
+ Address loadStringAddress(int stringId)
+ {
+ Address addr = loadCompilationUnitPtr(ScratchRegister);
+ addr.offset = offsetof(QV4::CompiledData::CompilationUnitBase, runtimeStrings);
+ loadPtr(addr, ScratchRegister);
+ return Address(ScratchRegister, stringId * PointerSize);
+ }
-template <typename TargetConfiguration>
-void Assembler<TargetConfiguration>::storeValue(TargetPrimitive value, IR::Expr *destination)
-{
- Address addr = loadAddress(ScratchRegister, destination);
- storeValue(value, addr);
-}
+ void passAsArg(RegisterID src, int arg)
+ {
+ move(src, registerForArg(arg));
+ }
+
+ void generateCatchTrampoline(std::function<void()> loadUndefined)
+ {
+ for (Jump j : catchyJumps)
+ j.link(this);
+
+ loadPtr(exceptionHandlerAddress(), ScratchRegister);
+ Jump exitFunction = branchPtr(Equal, ScratchRegister, TrustedImmPtr(0));
+ jump(ScratchRegister);
+ exitFunction.link(this);
+ loadUndefined();
+
+ if (functionExit.isSet())
+ jump(functionExit);
+ else
+ generateFunctionExit();
+ }
+
+ void addCatchyJump(Jump j)
+ {
+ Q_ASSERT(j.isSet());
+ catchyJumps.push_back(j);
+ }
+
+ void generateFunctionEntry()
+ {
+ generatePlatformFunctionEntry();
+ loadPtr(Address(CppStackFrameRegister, offsetof(CppStackFrame, jsFrame)), JSStackFrameRegister);
+ }
+
+ void generateFunctionExit()
+ {
+ if (functionExit.isSet()) {
+ jump(functionExit);
+ return;
+ }
+
+ functionExit = label();
+ generatePlatformFunctionExit();
+ }
+};
-template <typename TargetConfiguration>
-void Assembler<TargetConfiguration>::enterStandardStackFrame(const RegisterInformation &regularRegistersToSave,
- const RegisterInformation &fpRegistersToSave)
+#if QT_POINTER_SIZE == 8 || defined(ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES)
+struct PlatformAssembler64 : PlatformAssemblerCommon
{
- platformEnterStandardStackFrame(this);
+ void callRuntime(const char *functionName, const void *funcPtr,
+ Assembler::CallResultDestination dest)
+ {
+ PlatformAssemblerCommon::callRuntime(functionName, funcPtr);
+ if (dest == Assembler::ResultInAccumulator)
+ saveReturnValueInAccumulator();
+ }
- move(StackPointerRegister, JITTargetPlatform::FramePointerRegister);
+ void saveReturnValueInAccumulator()
+ {
+ move(ReturnValueRegister, AccumulatorRegister);
+ }
- const int frameSize = _stackLayout->calculateStackFrameSize();
- subPtr(TrustedImm32(frameSize), StackPointerRegister);
+ void loadUndefined(RegisterID dest = AccumulatorRegister)
+ {
+ move(TrustedImm64(0), dest);
+ }
- Address slotAddr(JITTargetPlatform::FramePointerRegister, 0);
- for (int i = 0, ei = fpRegistersToSave.size(); i < ei; ++i) {
- Q_ASSERT(fpRegistersToSave.at(i).isFloatingPoint());
- slotAddr.offset -= sizeof(double);
- TargetConfiguration::MacroAssembler::storeDouble(fpRegistersToSave.at(i).reg<FPRegisterID>(), slotAddr);
+ void copyConst(int constIndex, Address dest)
+ {
+ //###
+ if (constantTable[constIndex].isUndefined()) {
+ loadUndefined(ScratchRegister);
+ } else {
+ load64(loadConstAddress(constIndex, ScratchRegister), ScratchRegister);
+ }
+ store64(ScratchRegister, dest);
}
- for (int i = 0, ei = regularRegistersToSave.size(); i < ei; ++i) {
- Q_ASSERT(regularRegistersToSave.at(i).isRegularRegister());
- slotAddr.offset -= RegisterSize;
- storePtr(regularRegistersToSave.at(i).reg<RegisterID>(), slotAddr);
+
+ void copyReg(Address src, Address dst)
+ {
+ load64(src, ScratchRegister);
+ store64(ScratchRegister, dst);
}
- platformFinishEnteringStandardStackFrame(this);
-}
+ void loadPointerFromValue(Address addr, RegisterID dest = AccumulatorRegister)
+ {
+ load64(addr, dest);
+ }
-template <typename TargetConfiguration>
-void Assembler<TargetConfiguration>::leaveStandardStackFrame(const RegisterInformation &regularRegistersToSave,
- const RegisterInformation &fpRegistersToSave)
-{
- Address slotAddr(JITTargetPlatform::FramePointerRegister, -regularRegistersToSave.size() * RegisterSize - fpRegistersToSave.size() * sizeof(double));
+ void loadAccumulator(Address addr)
+ {
+ load64(addr, AccumulatorRegister);
+ }
- // restore the callee saved registers
- for (int i = regularRegistersToSave.size() - 1; i >= 0; --i) {
- Q_ASSERT(regularRegistersToSave.at(i).isRegularRegister());
- loadPtr(slotAddr, regularRegistersToSave.at(i).reg<RegisterID>());
- slotAddr.offset += RegisterSize;
+ void storeAccumulator(Address addr)
+ {
+ store64(AccumulatorRegister, addr);
}
- for (int i = fpRegistersToSave.size() - 1; i >= 0; --i) {
- Q_ASSERT(fpRegistersToSave.at(i).isFloatingPoint());
- TargetConfiguration::MacroAssembler::loadDouble(slotAddr, fpRegistersToSave.at(i).reg<FPRegisterID>());
- slotAddr.offset += sizeof(double);
+
+ void loadString(int stringId)
+ {
+ loadAccumulator(loadStringAddress(stringId));
}
- Q_ASSERT(slotAddr.offset == 0);
+ void loadValue(ReturnedValue value)
+ {
+ move(TrustedImm64(value), AccumulatorRegister);
+ }
- const int frameSize = _stackLayout->calculateStackFrameSize();
- platformLeaveStandardStackFrame(this, frameSize);
-}
+ void storeHeapObject(RegisterID source, Address addr)
+ {
+ store64(source, addr);
+ }
+ void generateCatchTrampoline()
+ {
+ PlatformAssemblerCommon::generateCatchTrampoline([this](){loadUndefined();});
+ }
+ void toBoolean(std::function<void(RegisterID)> continuation)
+ {
+ urshift64(AccumulatorRegister, TrustedImm32(Value::IsIntegerConvertible_Shift), ScratchRegister);
+ auto needsConversion = branch32(NotEqual, TrustedImm32(1), ScratchRegister);
+ continuation(AccumulatorRegister);
+ Jump done = jump();
+
+ // slow path:
+ needsConversion.link(this);
+ push(AccumulatorRegister);
+ move(AccumulatorRegister, registerForArg(0));
+ callHelper(Value::toBooleanImpl);
+ and32(TrustedImm32(1), ReturnValueRegister, ScratchRegister);
+ pop(AccumulatorRegister);
+ continuation(ScratchRegister);
+
+ done.link(this);
+ }
+ void toNumber()
+ {
+ urshift64(AccumulatorRegister, TrustedImm32(Value::QuickType_Shift), ScratchRegister);
+ auto isNumber = branch32(GreaterThanOrEqual, ScratchRegister, TrustedImm32(Value::QT_Int));
-// Try to load the source expression into the destination FP register. This assumes that two
-// general purpose (integer) registers are available: the ScratchRegister and the
-// ReturnValueRegister. It returns a Jump if no conversion can be performed.
-template <typename TargetConfiguration>
-typename Assembler<TargetConfiguration>::Jump Assembler<TargetConfiguration>::genTryDoubleConversion(IR::Expr *src, FPRegisterID dest)
-{
- switch (src->type) {
- case IR::DoubleType:
- moveDouble(toDoubleRegister(src, dest), dest);
- return Assembler::Jump();
- case IR::SInt32Type:
- convertInt32ToDouble(toInt32Register(src, Assembler::ScratchRegister),
- dest);
- return Assembler::Jump();
- case IR::UInt32Type:
- convertUInt32ToDouble(toUInt32Register(src, Assembler::ScratchRegister),
- dest, Assembler::ReturnValueRegister);
- return Assembler::Jump();
- case IR::NullType:
- case IR::UndefinedType:
- case IR::BoolType:
- // TODO?
- case IR::StringType:
- return jump();
- default:
- break;
+ move(AccumulatorRegister, registerForArg(0));
+ callHelper(toNumberHelper);
+ saveReturnValueInAccumulator();
+
+ isNumber.link(this);
}
- Q_ASSERT(src->asTemp() || src->asArgLocal());
+ void toInt32LhsAcc(Address lhs, RegisterID lhsTarget)
+ {
+ load64(lhs, lhsTarget);
+ urshift64(lhsTarget, TrustedImm32(Value::QuickType_Shift), ScratchRegister2);
+ auto lhsIsInt = branch32(Equal, TrustedImm32(Value::QT_Int), ScratchRegister2);
+
+ pushAligned(AccumulatorRegister);
+ move(lhsTarget, registerForArg(0));
+ callHelper(toInt32Helper);
+ move(ReturnValueRegister, lhsTarget);
+ popAligned(AccumulatorRegister);
+
+ lhsIsInt.link(this);
+ urshift64(AccumulatorRegister, TrustedImm32(Value::QuickType_Shift), ScratchRegister2);
+ auto isInt = branch32(Equal, TrustedImm32(Value::QT_Int), ScratchRegister2);
+
+ pushAligned(lhsTarget);
+ move(AccumulatorRegister, registerForArg(0));
+ callHelper(toInt32Helper);
+ saveReturnValueInAccumulator();
+ popAligned(lhsTarget);
+
+ isInt.link(this);
+ }
- // It's not a number type, so it cannot be in a register.
- Q_ASSERT(src->asArgLocal() || src->asTemp()->kind != IR::Temp::PhysicalRegister || src->type == IR::BoolType);
+ void toInt32()
+ {
+ urshift64(AccumulatorRegister, TrustedImm32(Value::QuickType_Shift), ScratchRegister2);
+ auto isInt = branch32(Equal, TrustedImm32(Value::QT_Int), ScratchRegister2);
- Assembler::Pointer tagAddr = loadAddress(Assembler::ScratchRegister, src);
- tagAddr.offset += 4;
- load32(tagAddr, Assembler::ScratchRegister);
+ move(AccumulatorRegister, registerForArg(0));
+ callRuntime("toInt32Helper", reinterpret_cast<void *>(&toInt32Helper),
+ Assembler::ResultInAccumulator);
- // check if it's an int32:
- Assembler::Jump isNoInt = branch32(Assembler::NotEqual, Assembler::ScratchRegister,
- Assembler::TrustedImm32(quint32(ValueTypeInternal::Integer)));
- convertInt32ToDouble(toInt32Register(src, Assembler::ScratchRegister), dest);
- Assembler::Jump intDone = jump();
+ isInt.link(this);
+ }
- // not an int, check if it's a double:
- isNoInt.link(this);
- Assembler::Jump isNoDbl = RegisterSizeDependentOps::checkIfTagRegisterIsDouble(this, ScratchRegister);
- toDoubleRegister(src, dest);
- intDone.link(this);
+ void regToInt32(Address srcReg, RegisterID targetReg)
+ {
+ load64(srcReg, targetReg);
+ urshift64(targetReg, TrustedImm32(Value::QuickType_Shift), ScratchRegister2);
+ auto isInt = branch32(Equal, TrustedImm32(Value::QT_Int), ScratchRegister2);
- return isNoDbl;
-}
+ pushAligned(AccumulatorRegister);
+ move(targetReg, registerForArg(0));
+ callHelper(toInt32Helper);
+ move(ReturnValueRegister, targetReg);
+ popAligned(AccumulatorRegister);
-template <typename TargetConfiguration>
-typename Assembler<TargetConfiguration>::Jump Assembler<TargetConfiguration>::branchDouble(bool invertCondition, IR::AluOp op,
- IR::Expr *left, IR::Expr *right)
-{
- DoubleCondition cond;
- switch (op) {
- case IR::OpGt: cond = Assembler::DoubleGreaterThan; break;
- case IR::OpLt: cond = Assembler::DoubleLessThan; break;
- case IR::OpGe: cond = Assembler::DoubleGreaterThanOrEqual; break;
- case IR::OpLe: cond = Assembler::DoubleLessThanOrEqual; break;
- case IR::OpEqual:
- case IR::OpStrictEqual: cond = Assembler::DoubleEqual; break;
- case IR::OpNotEqual:
- case IR::OpStrictNotEqual: cond = Assembler::DoubleNotEqualOrUnordered; break; // No, the inversion of DoubleEqual is NOT DoubleNotEqual.
- default:
- Q_UNREACHABLE();
+ isInt.link(this);
}
- if (invertCondition)
- cond = TargetConfiguration::MacroAssembler::invert(cond);
- return TargetConfiguration::MacroAssembler::branchDouble(cond, toDoubleRegister(left, FPGpr0), toDoubleRegister(right, JITTargetPlatform::FPGpr1));
-}
+ void isNullOrUndefined()
+ {
+ move(AccumulatorRegister, ScratchRegister);
+ compare64(Equal, ScratchRegister, TrustedImm32(0), AccumulatorRegister);
+ Jump isUndef = branch32(NotEqual, TrustedImm32(0), AccumulatorRegister);
+
+ // not undefined
+ rshift64(TrustedImm32(32), ScratchRegister);
+ compare32(Equal, ScratchRegister, TrustedImm32(int(QV4::Value::ValueTypeInternal::Null)),
+ AccumulatorRegister);
+
+ isUndef.link(this);
+ }
+
+ Jump isIntOrBool()
+ {
+ urshift64(AccumulatorRegister, TrustedImm32(Value::IsIntegerOrBool_Shift), ScratchRegister);
+ return branch32(Equal, TrustedImm32(3), ScratchRegister);
+ }
+
+ void jumpStrictEqualStackSlotInt(int lhs, int rhs, int offset)
+ {
+ Address lhsAddr(JSStackFrameRegister, lhs * int(sizeof(Value)));
+ load64(lhsAddr, ScratchRegister);
+ Jump isUndef = branch64(Equal, ScratchRegister, TrustedImm64(0));
+ Jump equal = branch32(Equal, TrustedImm32(rhs), ScratchRegister);
+ patches.push_back({ equal, offset });
+ isUndef.link(this);
+ }
+
+ void jumpStrictNotEqualStackSlotInt(int lhs, int rhs, int offset)
+ {
+ Address lhsAddr(JSStackFrameRegister, lhs * int(sizeof(Value)));
+ load64(lhsAddr, ScratchRegister);
+ Jump isUndef = branch64(Equal, ScratchRegister, TrustedImm64(0));
+ patches.push_back({ isUndef, offset });
+ Jump notEqual = branch32(NotEqual, TrustedImm32(rhs), ScratchRegister);
+ patches.push_back({ notEqual, offset });
+ }
+
+ void setAccumulatorTag(QV4::Value::ValueTypeInternal tag, RegisterID sourceReg = NoRegister)
+ {
+ if (sourceReg == NoRegister)
+ or64(TrustedImm64(int64_t(tag) << 32), AccumulatorRegister);
+ else
+ or64(TrustedImm64(int64_t(tag) << 32), sourceReg, AccumulatorRegister);
+ }
+
+ void encodeDoubleIntoAccumulator(FPRegisterID src)
+ {
+ moveDoubleTo64(src, AccumulatorRegister);
+ move(TrustedImm64(Value::NaNEncodeMask), ScratchRegister);
+ xor64(ScratchRegister, AccumulatorRegister);
+ }
+
+ void pushValueAligned(ReturnedValue v)
+ {
+ loadValue(v);
+ pushAligned(AccumulatorRegister);
+ }
+
+ void popValueAligned()
+ {
+ addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
+ }
+
+ Jump binopBothIntPath(Address lhsAddr, std::function<Jump(void)> fastPath)
+ {
+ urshift64(AccumulatorRegister, TrustedImm32(32), ScratchRegister);
+ Jump accNotInt = branch32(NotEqual, TrustedImm32(int(IntegerTag)), ScratchRegister);
+ load64(lhsAddr, ScratchRegister);
+ urshift64(ScratchRegister, TrustedImm32(32), ScratchRegister2);
+ Jump lhsNotInt = branch32(NotEqual, TrustedImm32(int(IntegerTag)), ScratchRegister2);
+
+ // both integer
+ Jump failure = fastPath();
+ Jump done = jump();
+
+ // all other cases
+ if (failure.isSet())
+ failure.link(this);
+ accNotInt.link(this);
+ lhsNotInt.link(this);
+
+ return done;
+ }
+
+ Jump unopIntPath(std::function<Jump(void)> fastPath)
+ {
+ urshift64(AccumulatorRegister, TrustedImm32(IsIntegerConvertible_Shift), ScratchRegister);
+ Jump accNotIntConvertible = branch32(NotEqual, TrustedImm32(1), ScratchRegister);
+
+ // both integer
+ Jump failure = fastPath();
+ Jump done = jump();
+
+ // all other cases
+ if (failure.isSet())
+ failure.link(this);
+ accNotIntConvertible.link(this);
-template <typename TargetConfiguration>
-typename Assembler<TargetConfiguration>::Jump Assembler<TargetConfiguration>::branchInt32(bool invertCondition, IR::AluOp op, IR::Expr *left, IR::Expr *right)
+ return done;
+ }
+
+ void callWithAccumulatorByValueAsFirstArgument(std::function<void()> doCall)
+ {
+ passAsArg(AccumulatorRegister, 0);
+ doCall();
+ }
+};
+
+typedef PlatformAssembler64 PlatformAssembler;
+#endif
+
+#if QT_POINTER_SIZE == 4 || defined(ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES)
+struct PlatformAssembler32 : PlatformAssemblerCommon
{
- Assembler::RelationalCondition cond;
- switch (op) {
- case IR::OpGt: cond = Assembler::GreaterThan; break;
- case IR::OpLt: cond = Assembler::LessThan; break;
- case IR::OpGe: cond = Assembler::GreaterThanOrEqual; break;
- case IR::OpLe: cond = Assembler::LessThanOrEqual; break;
- case IR::OpEqual:
- case IR::OpStrictEqual: cond = Assembler::Equal; break;
- case IR::OpNotEqual:
- case IR::OpStrictNotEqual: cond = Assembler::NotEqual; break;
- default:
- Q_UNREACHABLE();
+ void callRuntime(const char *functionName, const void *funcPtr,
+ Assembler::CallResultDestination dest)
+ {
+ PlatformAssemblerCommon::callRuntime(functionName, funcPtr);
+ if (dest == Assembler::ResultInAccumulator)
+ saveReturnValueInAccumulator();
}
- if (invertCondition)
- cond = TargetConfiguration::MacroAssembler::invert(cond);
-
- return TargetConfiguration::MacroAssembler::branch32(cond,
- toInt32Register(left, Assembler::ScratchRegister),
- toInt32Register(right, Assembler::ReturnValueRegister));
-}
-
-template <typename TargetConfiguration>
-void Assembler<TargetConfiguration>::setStackLayout(int maxArgCountForBuiltins, int regularRegistersToSave, int fpRegistersToSave)
-{
- _stackLayout.reset(new StackLayout(_function, maxArgCountForBuiltins, regularRegistersToSave, fpRegistersToSave));
-}
-
-template <typename TargetConfiguration>
-void Assembler<TargetConfiguration>::returnFromFunction(IR::Ret *s, RegisterInformation regularRegistersToSave, RegisterInformation fpRegistersToSave)
-{
- if (!s) {
- // this only happens if the method doesn't have a return statement and can
- // only exit through an exception
- } else if (IR::Temp *t = s->expr->asTemp()) {
- RegisterSizeDependentOps::setFunctionReturnValueFromTemp(this, t);
- } else if (IR::Const *c = s->expr->asConst()) {
- auto retVal = convertToValue<TargetPrimitive>(c);
- RegisterSizeDependentOps::setFunctionReturnValueFromConst(this, retVal);
- } else {
- Q_UNREACHABLE();
- Q_UNUSED(s);
+
+ void saveReturnValueInAccumulator()
+ {
+ move(ReturnValueRegisterValue, AccumulatorRegisterValue);
+ move(ReturnValueRegisterTag, AccumulatorRegisterTag);
+ }
+
+ void loadUndefined()
+ {
+ move(TrustedImm32(0), AccumulatorRegisterValue);
+ move(TrustedImm32(0), AccumulatorRegisterTag);
+ }
+
+ void copyConst(int constIndex, Address destRegAddr)
+ {
+ //###
+ if (constantTable[constIndex].isUndefined()) {
+ move(TrustedImm32(0), ScratchRegister);
+ store32(ScratchRegister, destRegAddr);
+ destRegAddr.offset += 4;
+ store32(ScratchRegister, destRegAddr);
+ } else {
+ Address src = loadConstAddress(constIndex);
+ loadDouble(src, FPScratchRegister);
+ storeDouble(FPScratchRegister, destRegAddr);
+ }
+ }
+
+ void copyReg(Address src, Address dest)
+ {
+ loadDouble(src, FPScratchRegister);
+ storeDouble(FPScratchRegister, dest);
+ }
+
+ void loadPointerFromValue(Address addr, RegisterID dest = AccumulatorRegisterValue)
+ {
+ load32(addr, dest);
+ }
+
+ void loadAccumulator(Address src)
+ {
+ load32(src, AccumulatorRegisterValue);
+ src.offset += 4;
+ load32(src, AccumulatorRegisterTag);
+ }
+
+ void storeAccumulator(Address addr)
+ {
+ store32(AccumulatorRegisterValue, addr);
+ addr.offset += 4;
+ store32(AccumulatorRegisterTag, addr);
+ }
+
+ void loadString(int stringId)
+ {
+ load32(loadStringAddress(stringId), AccumulatorRegisterValue);
+ move(TrustedImm32(0), AccumulatorRegisterTag);
+ }
+
+ void loadValue(ReturnedValue value)
+ {
+ move(TrustedImm32(Value::fromReturnedValue(value).value()), AccumulatorRegisterValue);
+ move(TrustedImm32(Value::fromReturnedValue(value).tag()), AccumulatorRegisterTag);
+ }
+
+ void storeHeapObject(RegisterID source, Address addr)
+ {
+ store32(source, addr);
+ addr.offset += 4;
+ store32(TrustedImm32(0), addr);
+ }
+
+
+ void generateCatchTrampoline()
+ {
+ PlatformAssemblerCommon::generateCatchTrampoline([this](){loadUndefined();});
+ }
+
+ void toNumber()
+ {
+ urshift32(AccumulatorRegisterTag, TrustedImm32(Value::QuickType_Shift - 32), ScratchRegister);
+ auto isNumber = branch32(GreaterThanOrEqual, ScratchRegister, TrustedImm32(Value::QT_Int));
+
+ if (ArgInRegCount < 2) {
+ push(AccumulatorRegisterTag);
+ push(AccumulatorRegisterValue);
+ } else {
+ move(AccumulatorRegisterValue, registerForArg(0));
+ move(AccumulatorRegisterTag, registerForArg(1));
+ }
+ callRuntime("toNumberHelper", reinterpret_cast<void *>(&toNumberHelper),
+ Assembler::ResultInAccumulator);
+ saveReturnValueInAccumulator();
+ if (ArgInRegCount < 2)
+ addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
+
+ isNumber.link(this);
+ }
+
+ void toInt32LhsAcc(Address lhs, RegisterID lhsTarget)
+ {
+ bool accumulatorNeedsSaving = AccumulatorRegisterValue == ReturnValueRegisterValue
+ || AccumulatorRegisterTag == ReturnValueRegisterTag;
+ lhs.offset += 4;
+ load32(lhs, lhsTarget);
+ lhs.offset -= 4;
+ auto lhsIsNotInt = branch32(NotEqual, TrustedImm32(int(IntegerTag)), lhsTarget);
+ load32(lhs, lhsTarget);
+ auto lhsIsInt = jump();
+
+ lhsIsNotInt.link(this);
+ if (accumulatorNeedsSaving) {
+ push(AccumulatorRegisterTag);
+ push(AccumulatorRegisterValue);
+ }
+ if (ArgInRegCount < 2) {
+ push(lhsTarget);
+ load32(lhs, lhsTarget);
+ push(lhsTarget);
+ } else {
+ move(lhsTarget, registerForArg(1));
+ load32(lhs, registerForArg(0));
+ }
+ callHelper(toInt32Helper);
+ move(ReturnValueRegisterValue, lhsTarget);
+ if (ArgInRegCount < 2)
+ addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
+ if (accumulatorNeedsSaving) {
+ pop(AccumulatorRegisterValue);
+ pop(AccumulatorRegisterTag);
+ }
+ lhsIsInt.link(this);
+
+ auto rhsIsInt = branch32(Equal, TrustedImm32(int(IntegerTag)), AccumulatorRegisterTag);
+
+ pushAligned(lhsTarget);
+ if (ArgInRegCount < 2) {
+ push(AccumulatorRegisterTag);
+ push(AccumulatorRegisterValue);
+ } else {
+ move(AccumulatorRegisterValue, registerForArg(0));
+ move(AccumulatorRegisterTag, registerForArg(1));
+ }
+ callRuntime("toInt32Helper", reinterpret_cast<void *>(&toInt32Helper),
+ Assembler::ResultInAccumulator);
+ if (ArgInRegCount < 2)
+ addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
+ popAligned(lhsTarget);
+
+ rhsIsInt.link(this);
+ }
+
+ void toInt32()
+ {
+ urshift32(AccumulatorRegisterTag, TrustedImm32(Value::QuickType_Shift - 32), ScratchRegister);
+ auto isInt = branch32(Equal, TrustedImm32(Value::QT_Int), ScratchRegister);
+
+ if (ArgInRegCount < 2) {
+ push(AccumulatorRegisterTag);
+ push(AccumulatorRegisterValue);
+ } else {
+ move(AccumulatorRegisterValue, registerForArg(0));
+ move(AccumulatorRegisterTag, registerForArg(1));
+ }
+ callRuntime("toInt32Helper", reinterpret_cast<void *>(&toInt32Helper),
+ Assembler::ResultInAccumulator);
+ if (ArgInRegCount < 2)
+ addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
+
+ isInt.link(this);
+ }
+
+ void regToInt32(Address srcReg, RegisterID targetReg)
+ {
+ bool accumulatorNeedsSaving = AccumulatorRegisterValue == ReturnValueRegisterValue
+ || AccumulatorRegisterTag == ReturnValueRegisterTag;
+ if (accumulatorNeedsSaving) {
+ push(AccumulatorRegisterTag);
+ push(AccumulatorRegisterValue);
+ }
+ if (ArgInRegCount < 2) {
+ srcReg.offset += 4;
+ load32(srcReg, targetReg);
+ push(targetReg);
+ srcReg.offset -= 4;
+ load32(srcReg, targetReg);
+ push(targetReg);
+ } else {
+ load32(srcReg, registerForArg(0));
+ srcReg.offset += 4;
+ load32(srcReg, registerForArg(1));
+ }
+ callHelper(toInt32Helper);
+ move(ReturnValueRegisterValue, targetReg);
+ if (ArgInRegCount < 2)
+ addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
+ if (accumulatorNeedsSaving) {
+ pop(AccumulatorRegisterValue);
+ pop(AccumulatorRegisterTag);
+ }
+ }
+
+ void isNullOrUndefined()
+ {
+ Jump notUndefOrPtr = branch32(NotEqual, TrustedImm32(0), AccumulatorRegisterTag);
+ compare32(Equal, AccumulatorRegisterValue, TrustedImm32(0), AccumulatorRegisterValue);
+ auto done = jump();
+
+ // not undefined or managed
+ notUndefOrPtr.link(this);
+ compare32(Equal, AccumulatorRegisterTag, TrustedImm32(int(QV4::Value::ValueTypeInternal::Null)),
+ AccumulatorRegisterValue);
+
+ done.link(this);
+ }
+
+ Jump isIntOrBool()
+ {
+ urshift32(AccumulatorRegisterTag, TrustedImm32(Value::IsIntegerOrBool_Shift - 32), ScratchRegister);
+ return branch32(Equal, TrustedImm32(3), ScratchRegister);
+ }
+
+ void pushValue(ReturnedValue v)
+ {
+ push(TrustedImm32(v >> 32));
+ push(TrustedImm32(v));
+ }
+
+ void toBoolean(std::function<void(RegisterID)> continuation)
+ {
+ urshift32(AccumulatorRegisterTag, TrustedImm32(Value::IsIntegerConvertible_Shift - 32),
+ ScratchRegister);
+ auto needsConversion = branch32(NotEqual, TrustedImm32(1), ScratchRegister);
+ continuation(AccumulatorRegisterValue);
+ Jump done = jump();
+
+ // slow path:
+ needsConversion.link(this);
+
+ bool accumulatorNeedsSaving = AccumulatorRegisterValue == ReturnValueRegisterValue
+ || AccumulatorRegisterTag == ReturnValueRegisterTag;
+ if (accumulatorNeedsSaving) {
+ push(AccumulatorRegisterTag);
+ push(AccumulatorRegisterValue);
+ }
+
+ if (ArgInRegCount < 2) {
+ push(AccumulatorRegisterTag);
+ push(AccumulatorRegisterValue);
+ } else {
+ move(AccumulatorRegisterValue, registerForArg(0));
+ move(AccumulatorRegisterTag, registerForArg(1));
+ }
+ callHelper(Value::toBooleanImpl);
+ if (ArgInRegCount < 2)
+ addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
+
+ and32(TrustedImm32(1), ReturnValueRegisterValue, ScratchRegister);
+ if (accumulatorNeedsSaving) {
+ pop(AccumulatorRegisterValue);
+ pop(AccumulatorRegisterTag);
+ }
+ continuation(ScratchRegister);
+
+ done.link(this);
}
- Label leaveStackFrame = label();
+ void jumpStrictEqualStackSlotInt(int lhs, int rhs, int offset)
+ {
+ Address lhsAddr(JSStackFrameRegister, lhs * int(sizeof(Value)));
+ load32(lhsAddr, ScratchRegister);
+ Jump notEqInt = branch32(NotEqual, ScratchRegister, TrustedImm32(rhs));
+ Jump notEqUndefVal = branch32(NotEqual, ScratchRegister, TrustedImm32(0));
+ patches.push_back({ notEqUndefVal, offset });
+ lhsAddr.offset += 4;
+ load32(lhsAddr, ScratchRegister);
+ Jump notEqUndefTag = branch32(NotEqual, ScratchRegister, TrustedImm32(0));
+ patches.push_back({ notEqUndefTag, offset });
+ notEqInt.link(this);
+ }
+
+ void jumpStrictNotEqualStackSlotInt(int lhs, int rhs, int offset)
+ {
+ Address lhsAddr(JSStackFrameRegister, lhs * int(sizeof(Value)));
+ load32(lhsAddr, ScratchRegister);
+ Jump notEqual = branch32(NotEqual, TrustedImm32(rhs), ScratchRegister);
+ patches.push_back({ notEqual, offset });
+ Jump notUndefValue = branch32(NotEqual, TrustedImm32(0), ScratchRegister);
+ lhsAddr.offset += 4;
+ load32(lhsAddr, ScratchRegister);
+ Jump equalUndef = branch32(Equal, TrustedImm32(0), ScratchRegister);
+ patches.push_back({ equalUndef, offset });
+ notUndefValue.link(this);
+ }
+
+ void setAccumulatorTag(QV4::Value::ValueTypeInternal tag, RegisterID sourceReg = NoRegister)
+ {
+ if (sourceReg != NoRegister)
+ move(sourceReg, AccumulatorRegisterValue);
+ move(TrustedImm32(int(tag)), AccumulatorRegisterTag);
+ }
+
+ void encodeDoubleIntoAccumulator(FPRegisterID src)
+ {
+ moveDoubleToInts(src, AccumulatorRegisterValue, AccumulatorRegisterTag);
+ xor32(TrustedImm32(Value::NaNEncodeMask >> 32), AccumulatorRegisterTag);
+ }
+
+ void pushValueAligned(ReturnedValue v)
+ {
+ pushValue(v);
+ }
+
+ void popValueAligned()
+ {
+ popValue();
+ }
+
+ Jump binopBothIntPath(Address lhsAddr, std::function<Jump(void)> fastPath)
+ {
+ Jump accNotInt = branch32(NotEqual, TrustedImm32(int(IntegerTag)), AccumulatorRegisterTag);
+ Address lhsAddrTag = lhsAddr; lhsAddrTag.offset += Value::tagOffset();
+ load32(lhsAddrTag, ScratchRegister);
+ Jump lhsNotInt = branch32(NotEqual, TrustedImm32(int(IntegerTag)), ScratchRegister);
+
+ // both integer
+ Address lhsAddrValue = lhsAddr; lhsAddrValue.offset += Value::valueOffset();
+ load32(lhsAddrValue, ScratchRegister);
+ Jump failure = fastPath();
+ Jump done = jump();
+
+ // all other cases
+ if (failure.isSet())
+ failure.link(this);
+ accNotInt.link(this);
+ lhsNotInt.link(this);
+
+ return done;
+ }
+
+ Jump unopIntPath(std::function<Jump(void)> fastPath)
+ {
+ Jump accNotInt = branch32(NotEqual, TrustedImm32(int(IntegerTag)), AccumulatorRegisterTag);
+
+ // both integer
+ Jump failure = fastPath();
+ Jump done = jump();
+
+ // all other cases
+ if (failure.isSet())
+ failure.link(this);
+ accNotInt.link(this);
+
+ return done;
+ }
+
+ void callWithAccumulatorByValueAsFirstArgument(std::function<void()> doCall)
+ {
+ if (ArgInRegCount < 2) {
+ push(AccumulatorRegisterTag);
+ push(AccumulatorRegisterValue);
+ } else {
+ move(AccumulatorRegisterValue, registerForArg(0));
+ move(AccumulatorRegisterTag, registerForArg(1));
+ }
+ doCall();
+ if (ArgInRegCount < 2)
+ addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
+ }
+};
+
+typedef PlatformAssembler32 PlatformAssembler;
+#endif
+
+typedef PlatformAssembler::TrustedImmPtr TrustedImmPtr;
+typedef PlatformAssembler::TrustedImm32 TrustedImm32;
+typedef PlatformAssembler::TrustedImm64 TrustedImm64;
+typedef PlatformAssembler::Address Address;
+typedef PlatformAssembler::RegisterID RegisterID;
+typedef PlatformAssembler::FPRegisterID FPRegisterID;
- const int locals = stackLayout().calculateJSStackFrameSize();
- subPtr(TrustedImm32(sizeof(QV4::Value)*locals), JITTargetPlatform::LocalsRegister);
- storePtr(JITTargetPlatform::LocalsRegister, Address(JITTargetPlatform::EngineRegister, targetStructureOffset(offsetof(EngineBase, jsStackTop))));
+#define pasm() reinterpret_cast<PlatformAssembler *>(this->d)
- leaveStandardStackFrame(regularRegistersToSave, fpRegistersToSave);
- ret();
+static Address regAddr(int reg)
+{
+ return Address(PlatformAssembler::JSStackFrameRegister, reg * int(sizeof(QV4::Value)));
+}
+
+Assembler::Assembler(const Value *constantTable)
+ : d(new PlatformAssembler)
+{
+ pasm()->constantTable = constantTable;
+}
- exceptionReturnLabel = label();
- auto retVal = TargetPrimitive::undefinedValue();
- RegisterSizeDependentOps::setFunctionReturnValueFromConst(this, retVal);
- jump(leaveStackFrame);
+Assembler::~Assembler()
+{
+ delete pasm();
+}
+
+void Assembler::generatePrologue()
+{
+ pasm()->generateFunctionEntry();
+}
+
+void Assembler::generateEpilogue()
+{
+ pasm()->generateCatchTrampoline();
}
namespace {
@@ -565,150 +1346,847 @@ private:
};
} // anonymous namespace
-static void printDisassembledOutputWithCalls(QByteArray processedOutput, const QHash<void*, const char*>& functions)
+static void printDisassembledOutputWithCalls(QByteArray processedOutput,
+ const QHash<const void*, const char*>& functions)
{
- for (QHash<void*, const char*>::ConstIterator it = functions.begin(), end = functions.end();
+ for (QHash<const void*, const char*>::ConstIterator it = functions.begin(), end = functions.end();
it != end; ++it) {
const QByteArray ptrString = "0x" + QByteArray::number(quintptr(it.key()), 16);
- int idx = processedOutput.indexOf(ptrString);
- if (idx < 0)
- continue;
- idx = processedOutput.lastIndexOf('\n', idx);
- if (idx < 0)
- continue;
- processedOutput = processedOutput.insert(idx, QByteArrayLiteral(" ; call ") + it.value());
+ int idx = 0;
+ while (idx >= 0) {
+ idx = processedOutput.indexOf(ptrString, idx);
+ if (idx < 0)
+ break;
+ idx = processedOutput.indexOf('\n', idx);
+ if (idx < 0)
+ break;
+ processedOutput = processedOutput.insert(idx, QByteArrayLiteral(" ; ") + it.value());
+ }
}
qDebug("%s", processedOutput.constData());
}
-#if defined(Q_OS_LINUX)
-static FILE *pmap;
+void Assembler::link(Function *function)
+{
+ for (const auto &jumpTarget : pasm()->patches)
+ jumpTarget.jump.linkTo(pasm()->labelsByOffset[jumpTarget.offset], pasm());
+
+ JSC::JSGlobalData dummy(function->internalClass->engine->executableAllocator);
+ JSC::LinkBuffer<PlatformAssembler::MacroAssembler> linkBuffer(dummy, pasm(), 0);
+
+ for (const auto &ehTarget : pasm()->ehTargets) {
+ auto targetLabel = pasm()->labelsByOffset.value(ehTarget.offset);
+ linkBuffer.patch(ehTarget.label, linkBuffer.locationOf(targetLabel));
+ }
+
+ JSC::MacroAssemblerCodeRef codeRef;
-static void qt_closePmap()
+ static const bool showCode = qEnvironmentVariableIsSet("QV4_SHOW_ASM");
+ if (showCode) {
+ QBuffer buf;
+ buf.open(QIODevice::WriteOnly);
+ WTF::setDataFile(new QIODevicePrintStream(&buf));
+
+ QByteArray name = function->name()->toQString().toUtf8();
+ if (name.isEmpty()) {
+ name = QByteArray::number(quintptr(function), 16);
+ name.prepend("QV4::Function(0x");
+ name.append(')');
+ }
+ codeRef = linkBuffer.finalizeCodeWithDisassembly("%s", name.data());
+
+ WTF::setDataFile(stderr);
+ printDisassembledOutputWithCalls(buf.data(), pasm()->functions);
+ } else {
+ codeRef = linkBuffer.finalizeCodeWithoutDisassembly();
+ }
+
+ function->codeRef = new JSC::MacroAssemblerCodeRef(codeRef);
+ function->jittedCode = reinterpret_cast<Function::JittedCode>(function->codeRef->code().executableAddress());
+}
+
+void Assembler::addLabel(int offset)
{
- if (pmap) {
- fclose(pmap);
- pmap = 0;
+ pasm()->labelsByOffset[offset] = pasm()->label();
+}
+
+void Assembler::loadConst(int constIndex)
+{
+ //###
+ if (pasm()->constantTable[constIndex].isUndefined()) {
+ pasm()->loadUndefined();
+ } else {
+ pasm()->loadAccumulator(pasm()->loadConstAddress(constIndex));
}
}
-#endif
+void Assembler::copyConst(int constIndex, int destReg)
+{
+ pasm()->copyConst(constIndex, regAddr(destReg));
+}
-template <typename TargetConfiguration>
-JSC::MacroAssemblerCodeRef Assembler<TargetConfiguration>::link(int *codeSize)
+void Assembler::loadReg(int reg)
{
- Label endOfCode = label();
+ pasm()->loadAccumulator(regAddr(reg));
+}
- {
- for (size_t i = 0, ei = _patches.size(); i != ei; ++i) {
- Label target = _addrs.at(i);
- Q_ASSERT(target.isSet());
- for (Jump jump : qAsConst(_patches.at(i)))
- jump.linkTo(target, this);
- }
+void Assembler::storeReg(int reg)
+{
+ pasm()->storeAccumulator(regAddr(reg));
+}
+
+void Assembler::loadLocal(int index, int level)
+{
+ Heap::CallContext ctx;
+ Q_UNUSED(ctx)
+ pasm()->loadPointerFromValue(regAddr(CallData::Context), PlatformAssembler::ScratchRegister);
+ while (level) {
+ pasm()->loadPtr(Address(PlatformAssembler::ScratchRegister, ctx.outer.offset), PlatformAssembler::ScratchRegister);
+ --level;
}
+ pasm()->loadAccumulator(Address(PlatformAssembler::ScratchRegister, ctx.locals.offset + offsetof(ValueArray<0>, values) + sizeof(Value)*index));
+}
- JSC::JSGlobalData dummy(_executableAllocator);
- JSC::LinkBuffer<typename TargetConfiguration::MacroAssembler> linkBuffer(dummy, this, 0);
+void Assembler::storeLocal(int index, int level)
+{
+ Heap::CallContext ctx;
+ Q_UNUSED(ctx)
+ pasm()->loadPtr(regAddr(CallData::Context), PlatformAssembler::ScratchRegister);
+ while (level) {
+ pasm()->loadPtr(Address(PlatformAssembler::ScratchRegister, ctx.outer.offset), PlatformAssembler::ScratchRegister);
+ --level;
+ }
+ pasm()->storeAccumulator(Address(PlatformAssembler::ScratchRegister, ctx.locals.offset + offsetof(ValueArray<0>, values) + sizeof(Value)*index));
+}
- for (const DataLabelPatch &p : qAsConst(_dataLabelPatches))
- linkBuffer.patch(p.dataLabel, linkBuffer.locationOf(p.target));
+void Assembler::loadString(int stringId)
+{
+ pasm()->loadString(stringId);
+}
- // link exception handlers
- for (Jump jump : qAsConst(exceptionPropagationJumps))
- linkBuffer.link(jump, linkBuffer.locationOf(exceptionReturnLabel));
+void Assembler::loadValue(ReturnedValue value)
+{
+ pasm()->loadValue(value);
+}
- {
- for (size_t i = 0, ei = _labelPatches.size(); i != ei; ++i) {
- Label target = _addrs.at(i);
- Q_ASSERT(target.isSet());
- for (DataLabelPtr label : _labelPatches.at(i))
- linkBuffer.patch(label, linkBuffer.locationOf(target));
- }
+void JIT::Assembler::storeHeapObject(int reg)
+{
+ pasm()->storeHeapObject(PlatformAssembler::ReturnValueRegisterValue, regAddr(reg));
+}
+
+void Assembler::toNumber()
+{
+ pasm()->toNumber();
+}
+
+void Assembler::uminus()
+{
+ saveAccumulatorInFrame();
+ prepareCallWithArgCount(1);
+ passAccumulatorAsArg(0);
+ IN_JIT_GENERATE_RUNTIME_CALL(Runtime::method_uMinus, ResultInAccumulator);
+ checkException();
+}
+
+void Assembler::ucompl()
+{
+ pasm()->toInt32();
+ pasm()->xor32(TrustedImm32(-1), PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->setAccumulatorTag(IntegerTag);
+}
+
+static ReturnedValue incHelper(const Value v)
+{
+ double d;
+ if (Q_LIKELY(v.isDouble()))
+ d = v.doubleValue();
+ else
+ d = v.toNumberImpl();
+ return Encode(d + 1.);
+}
+
+void Assembler::inc()
+{
+ auto done = pasm()->unopIntPath([this](){
+ auto overflowed = pasm()->branchAdd32(PlatformAssembler::Overflow,
+ PlatformAssembler::AccumulatorRegisterValue,
+ TrustedImm32(1),
+ PlatformAssembler::ScratchRegister);
+ pasm()->setAccumulatorTag(IntegerTag, PlatformAssembler::ScratchRegister);
+ return overflowed;
+ });
+
+ // slow path:
+ pasm()->callWithAccumulatorByValueAsFirstArgument([this]() {
+ pasm()->callHelper(incHelper);
+ pasm()->saveReturnValueInAccumulator();
+ });
+ checkException();
+
+ // done.
+ done.link(pasm());
+}
+
+static ReturnedValue decHelper(const Value v)
+{
+ double d;
+ if (Q_LIKELY(v.isDouble()))
+ d = v.doubleValue();
+ else
+ d = v.toNumberImpl();
+ return Encode(d - 1.);
+}
+
+void Assembler::dec()
+{
+ auto done = pasm()->unopIntPath([this](){
+ auto overflowed = pasm()->branchSub32(PlatformAssembler::Overflow,
+ PlatformAssembler::AccumulatorRegisterValue,
+ TrustedImm32(1),
+ PlatformAssembler::ScratchRegister);
+ pasm()->setAccumulatorTag(IntegerTag, PlatformAssembler::ScratchRegister);
+ return overflowed;
+ });
+
+ // slow path:
+ pasm()->callWithAccumulatorByValueAsFirstArgument([this]() {
+ pasm()->callHelper(decHelper);
+ pasm()->saveReturnValueInAccumulator();
+ });
+ checkException();
+
+ // done.
+ done.link(pasm());
+}
+
+void Assembler::unot()
+{
+ pasm()->toBoolean([this](PlatformAssembler::RegisterID resultReg){
+ pasm()->compare32(PlatformAssembler::Equal, resultReg,
+ TrustedImm32(0), PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->setAccumulatorTag(QV4::Value::ValueTypeInternal::Boolean);
+ });
+}
+
+void Assembler::add(int lhs)
+{
+ auto done = pasm()->binopBothIntPath(regAddr(lhs), [this](){
+ auto overflowed = pasm()->branchAdd32(PlatformAssembler::Overflow,
+ PlatformAssembler::AccumulatorRegisterValue,
+ PlatformAssembler::ScratchRegister);
+ pasm()->setAccumulatorTag(IntegerTag,
+ PlatformAssembler::ScratchRegister);
+ return overflowed;
+ });
+
+ // slow path:
+ saveAccumulatorInFrame();
+ prepareCallWithArgCount(3);
+ passAccumulatorAsArg(2);
+ passRegAsArg(lhs, 1);
+ passEngineAsArg(0);
+ IN_JIT_GENERATE_RUNTIME_CALL(Runtime::method_add, ResultInAccumulator);
+ checkException();
+
+ // done.
+ done.link(pasm());
+}
+
+void Assembler::bitAnd(int lhs)
+{
+ PlatformAssembler::Address lhsAddr = regAddr(lhs);
+ pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
+ pasm()->and32(PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->setAccumulatorTag(IntegerTag);
+}
+
+void Assembler::bitOr(int lhs)
+{
+ PlatformAssembler::Address lhsAddr = regAddr(lhs);
+ pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
+ pasm()->or32(PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->setAccumulatorTag(IntegerTag);
+}
+
+void Assembler::bitXor(int lhs)
+{
+ PlatformAssembler::Address lhsAddr = regAddr(lhs);
+ pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
+ pasm()->xor32(PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->setAccumulatorTag(IntegerTag);
+}
+
+void Assembler::ushr(int lhs)
+{
+ PlatformAssembler::Address lhsAddr = regAddr(lhs);
+ pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
+ pasm()->and32(TrustedImm32(0x1f), PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->urshift32(PlatformAssembler::AccumulatorRegisterValue, PlatformAssembler::ScratchRegister);
+ pasm()->move(PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegisterValue);
+ auto doubleEncode = pasm()->branch32(PlatformAssembler::LessThan,
+ PlatformAssembler::AccumulatorRegisterValue,
+ TrustedImm32(0));
+ pasm()->setAccumulatorTag(IntegerTag);
+ auto done = pasm()->jump();
+
+ doubleEncode.link(pasm());
+ pasm()->convertUInt32ToDouble(PlatformAssembler::AccumulatorRegisterValue,
+ PlatformAssembler::FPScratchRegister,
+ PlatformAssembler::ScratchRegister);
+ pasm()->encodeDoubleIntoAccumulator(PlatformAssembler::FPScratchRegister);
+ done.link(pasm());
+}
+
+void Assembler::shr(int lhs)
+{
+ PlatformAssembler::Address lhsAddr = regAddr(lhs);
+ pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
+ pasm()->and32(TrustedImm32(0x1f), PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->rshift32(PlatformAssembler::AccumulatorRegisterValue, PlatformAssembler::ScratchRegister);
+ pasm()->move(PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->setAccumulatorTag(IntegerTag);
+}
+
+void Assembler::shl(int lhs)
+{
+ PlatformAssembler::Address lhsAddr = regAddr(lhs);
+ pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
+ pasm()->and32(TrustedImm32(0x1f), PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->lshift32(PlatformAssembler::AccumulatorRegisterValue, PlatformAssembler::ScratchRegister);
+ pasm()->move(PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->setAccumulatorTag(IntegerTag);
+}
+
+void Assembler::bitAndConst(int rhs)
+{
+ pasm()->toInt32();
+ pasm()->and32(TrustedImm32(rhs), PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->setAccumulatorTag(IntegerTag);
+}
+
+void Assembler::bitOrConst(int rhs)
+{
+ pasm()->toInt32();
+ pasm()->or32(TrustedImm32(rhs), PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->setAccumulatorTag(IntegerTag);
+}
+
+void Assembler::bitXorConst(int rhs)
+{
+ pasm()->toInt32();
+ pasm()->xor32(TrustedImm32(rhs), PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->setAccumulatorTag(IntegerTag);
+}
+
+void Assembler::ushrConst(int rhs)
+{
+ rhs &= 0x1f;
+ pasm()->toInt32();
+ if (rhs) {
+ // a non zero shift will always give a number encodable as an int
+ pasm()->urshift32(TrustedImm32(rhs), PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->setAccumulatorTag(IntegerTag);
+ } else {
+ // shift with 0 can lead to a negative result
+ auto doubleEncode = pasm()->branch32(PlatformAssembler::LessThan,
+ PlatformAssembler::AccumulatorRegisterValue,
+ TrustedImm32(0));
+ pasm()->setAccumulatorTag(IntegerTag);
+ auto done = pasm()->jump();
+
+ doubleEncode.link(pasm());
+ pasm()->convertUInt32ToDouble(PlatformAssembler::AccumulatorRegisterValue,
+ PlatformAssembler::FPScratchRegister,
+ PlatformAssembler::ScratchRegister);
+ pasm()->encodeDoubleIntoAccumulator(PlatformAssembler::FPScratchRegister);
+ done.link(pasm());
}
+}
+
+void Assembler::shrConst(int rhs)
+{
+ rhs &= 0x1f;
+ pasm()->toInt32();
+ if (rhs)
+ pasm()->rshift32(TrustedImm32(rhs), PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->setAccumulatorTag(IntegerTag);
+}
- *codeSize = linkBuffer.offsetOf(endOfCode);
+void Assembler::shlConst(int rhs)
+{
+ rhs &= 0x1f;
+ pasm()->toInt32();
+ if (rhs)
+ pasm()->lshift32(TrustedImm32(rhs), PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->setAccumulatorTag(IntegerTag);
+}
- QByteArray name;
+void Assembler::mul(int lhs)
+{
+ auto done = pasm()->binopBothIntPath(regAddr(lhs), [this](){
+ auto overflowed = pasm()->branchMul32(PlatformAssembler::Overflow,
+ PlatformAssembler::AccumulatorRegisterValue,
+ PlatformAssembler::ScratchRegister);
+ pasm()->setAccumulatorTag(IntegerTag,
+ PlatformAssembler::ScratchRegister);
+ return overflowed;
+ });
+
+ // slow path:
+ saveAccumulatorInFrame();
+ prepareCallWithArgCount(2);
+ passAccumulatorAsArg(1);
+ passRegAsArg(lhs, 0);
+ IN_JIT_GENERATE_RUNTIME_CALL(Runtime::method_mul, ResultInAccumulator);
+ checkException();
+
+ // done.
+ done.link(pasm());
+}
- JSC::MacroAssemblerCodeRef codeRef;
+void Assembler::div(int lhs)
+{
+ saveAccumulatorInFrame();
+ prepareCallWithArgCount(2);
+ passAccumulatorAsArg(1);
+ passRegAsArg(lhs, 0);
+ IN_JIT_GENERATE_RUNTIME_CALL(Runtime::method_div, ResultInAccumulator);
+ checkException();
+}
- static const bool showCode = qEnvironmentVariableIsSet("QV4_SHOW_ASM");
- if (showCode) {
- QHash<void*, const char*> functions;
+void Assembler::mod(int lhs)
+{
+ saveAccumulatorInFrame();
+ prepareCallWithArgCount(2);
+ passAccumulatorAsArg(1);
+ passRegAsArg(lhs, 0);
+ IN_JIT_GENERATE_RUNTIME_CALL(Runtime::method_mod, ResultInAccumulator);
+ checkException();
+}
+
+void Assembler::sub(int lhs)
+{
+ auto done = pasm()->binopBothIntPath(regAddr(lhs), [this](){
+ auto overflowed = pasm()->branchSub32(PlatformAssembler::Overflow,
+ PlatformAssembler::AccumulatorRegisterValue,
+ PlatformAssembler::ScratchRegister);
+ pasm()->setAccumulatorTag(IntegerTag,
+ PlatformAssembler::ScratchRegister);
+ return overflowed;
+ });
+
+ // slow path:
+ saveAccumulatorInFrame();
+ prepareCallWithArgCount(2);
+ passAccumulatorAsArg(1);
+ passRegAsArg(lhs, 0);
+ IN_JIT_GENERATE_RUNTIME_CALL(Runtime::method_sub, ResultInAccumulator);
+ checkException();
+
+ // done.
+ done.link(pasm());
+}
+
+void Assembler::cmpeqNull()
+{
+ pasm()->isNullOrUndefined();
+ pasm()->setAccumulatorTag(QV4::Value::ValueTypeInternal::Boolean);
+}
+
+void Assembler::cmpneNull()
+{
+ pasm()->isNullOrUndefined();
+ pasm()->xor32(TrustedImm32(1), PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->setAccumulatorTag(QV4::Value::ValueTypeInternal::Boolean);
+}
+
+void Assembler::cmpeqInt(int lhs)
+{
+ auto isIntOrBool = pasm()->isIntOrBool();
+ saveAccumulatorInFrame();
+ pasm()->pushValueAligned(Encode(lhs));
+ if (PlatformAssembler::ArgInRegCount < 2)
+ pasm()->push(PlatformAssembler::StackPointerRegister);
+ else
+ pasm()->move(PlatformAssembler::StackPointerRegister, pasm()->registerForArg(1));
+ passAccumulatorAsArg_internal(0, true);
+ pasm()->callRuntime("Runtime::method_equal", (void*)Runtime::method_equal, ResultInAccumulator);
+ if (PlatformAssembler::ArgInRegCount < 2)
+ pasm()->addPtr(TrustedImm32(2 * PlatformAssembler::PointerSize), PlatformAssembler::StackPointerRegister);
+ pasm()->popValueAligned();
+ auto done = pasm()->jump();
+ isIntOrBool.link(pasm());
+ pasm()->compare32(PlatformAssembler::Equal, PlatformAssembler::AccumulatorRegisterValue,
+ TrustedImm32(lhs),
+ PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->setAccumulatorTag(QV4::Value::ValueTypeInternal::Boolean);
+ done.link(pasm());
+}
+
+void Assembler::cmpneInt(int lhs)
+{
+ auto isIntOrBool = pasm()->isIntOrBool();
+ saveAccumulatorInFrame();
+ pasm()->pushValueAligned(Encode(lhs));
+ if (PlatformAssembler::ArgInRegCount < 2)
+ pasm()->push(PlatformAssembler::StackPointerRegister);
+ else
+ pasm()->move(PlatformAssembler::StackPointerRegister, pasm()->registerForArg(1));
+ passAccumulatorAsArg_internal(0, true);
+ pasm()->callRuntime("Runtime::method_notEqual", (void*)Runtime::method_notEqual, ResultInAccumulator);
+ if (PlatformAssembler::ArgInRegCount < 2)
+ pasm()->addPtr(TrustedImm32(2 * PlatformAssembler::PointerSize), PlatformAssembler::StackPointerRegister);
+ pasm()->popValueAligned();
+ auto done = pasm()->jump();
+ isIntOrBool.link(pasm());
+ pasm()->compare32(PlatformAssembler::NotEqual, PlatformAssembler::AccumulatorRegisterValue,
+ TrustedImm32(lhs),
+ PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->setAccumulatorTag(QV4::Value::ValueTypeInternal::Boolean);
+ done.link(pasm());
+}
+
+void Assembler::cmp(int cond, CmpFunc function, const char *functionName, int lhs)
+{
+ auto c = static_cast<PlatformAssembler::RelationalCondition>(cond);
+ auto done = pasm()->binopBothIntPath(regAddr(lhs), [this, c](){
+ pasm()->compare32(c, PlatformAssembler::ScratchRegister,
+ PlatformAssembler::AccumulatorRegisterValue,
+ PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->setAccumulatorTag(QV4::Value::ValueTypeInternal::Boolean);
+ return PlatformAssembler::Jump();
+ });
+
+ // slow path:
+ saveAccumulatorInFrame();
+ prepareCallWithArgCount(2);
+ passAccumulatorAsArg(1);
+ passRegAsArg(lhs, 0);
+
+ callRuntime(functionName, reinterpret_cast<void*>(function), ResultInAccumulator);
+ checkException();
+ pasm()->setAccumulatorTag(QV4::Value::ValueTypeInternal::Boolean);
+
+ // done.
+ done.link(pasm());
+}
+
+void Assembler::cmpeq(int lhs)
+{
+ cmp(PlatformAssembler::Equal, &Runtime::method_compareEqual,
+ "Runtime::method_compareEqual", lhs);
+}
+
+void Assembler::cmpne(int lhs)
+{
+ cmp(PlatformAssembler::NotEqual, &Runtime::method_compareNotEqual,
+ "Runtime::method_compareNotEqual", lhs);
+}
+
+void Assembler::cmpgt(int lhs)
+{
+ cmp(PlatformAssembler::GreaterThan, &Runtime::method_compareGreaterThan,
+ "Runtime::method_compareGreaterThan", lhs);
+}
+
+void Assembler::cmpge(int lhs)
+{
+ cmp(PlatformAssembler::GreaterThanOrEqual, &Runtime::method_compareGreaterEqual,
+ "Runtime::method_compareGreaterEqual", lhs);
+}
+
+void Assembler::cmplt(int lhs)
+{
+ cmp(PlatformAssembler::LessThan, &Runtime::method_compareLessThan,
+ "Runtime::method_compareLessThan", lhs);
+}
+
+void Assembler::cmple(int lhs)
+{
+ cmp(PlatformAssembler::LessThanOrEqual, &Runtime::method_compareLessEqual,
+ "Runtime::method_compareLessEqual", lhs);
+}
+
+void Assembler::cmpStrictEqual(int lhs)
+{
+ cmp(PlatformAssembler::Equal, &RuntimeHelpers::strictEqual,
+ "RuntimeHelpers::strictEqual", lhs);
+}
+
+void Assembler::cmpStrictNotEqual(int lhs)
+{
+ cmp(PlatformAssembler::Equal, &RuntimeHelpers::strictEqual,
+ "RuntimeHelpers::strictEqual", lhs);
+ pasm()->xor32(TrustedImm32(1), PlatformAssembler::AccumulatorRegisterValue);
+ pasm()->setAccumulatorTag(QV4::Value::ValueTypeInternal::Boolean);
+}
+
+void Assembler::jump(int offset)
+{
+ pasm()->patches.push_back({ pasm()->jump(), offset });
+}
+
+void Assembler::jumpTrue(int offset)
+{
+ pasm()->toBoolean([this, offset](PlatformAssembler::RegisterID resultReg) {
+ auto jump = pasm()->branch32(PlatformAssembler::NotEqual, TrustedImm32(0), resultReg);
+ pasm()->patches.push_back({ jump, offset });
+ });
+}
+
+void Assembler::jumpFalse(int offset)
+{
+ pasm()->toBoolean([this, offset](PlatformAssembler::RegisterID resultReg) {
+ auto jump = pasm()->branch32(PlatformAssembler::Equal, TrustedImm32(0), resultReg);
+ pasm()->patches.push_back({ jump, offset });
+ });
+}
+
+void Assembler::jumpStrictEqualStackSlotInt(int lhs, int rhs, int offset)
+{
+ pasm()->jumpStrictEqualStackSlotInt(lhs, rhs, offset);
+}
+
+void Assembler::jumpStrictNotEqualStackSlotInt(int lhs, int rhs, int offset)
+{
+ pasm()->jumpStrictNotEqualStackSlotInt(lhs, rhs, offset);
+}
+
+void Assembler::prepareCallWithArgCount(int argc)
+{
#ifndef QT_NO_DEBUG
- for (CallInfo call : qAsConst(_callInfos))
- functions[linkBuffer.locationOf(call.label).dataLocation()] = call.functionName;
+ Q_ASSERT(remainingArgcForCall == NoCall);
+ remainingArgcForCall = argc;
#endif
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- WTF::setDataFile(new QIODevicePrintStream(&buf));
+ if (argc > PlatformAssembler::ArgInRegCount) {
+ argcOnStackForCall = int(WTF::roundUpToMultipleOf(16, size_t(argc - PlatformAssembler::ArgInRegCount) * PlatformAssembler::PointerSize));
+ pasm()->subPtr(TrustedImm32(argcOnStackForCall), PlatformAssembler::StackPointerRegister);
+ }
+}
- name = _function->name->toUtf8();
- if (name.isEmpty())
- name = "IR::Function(0x" + QByteArray::number(quintptr(_function), 16) + ')';
- codeRef = linkBuffer.finalizeCodeWithDisassembly("%s", name.data());
+void Assembler::storeInstructionPointer(int instructionOffset)
+{
+ PlatformAssembler::Address addr(PlatformAssembler::CppStackFrameRegister,
+ offsetof(QV4::CppStackFrame, instructionPointer));
+ pasm()->store32(TrustedImm32(instructionOffset), addr);
+}
- WTF::setDataFile(stderr);
- printDisassembledOutputWithCalls(buf.data(), functions);
+Address argStackAddress(int arg)
+{
+ int offset = arg - PlatformAssembler::ArgInRegCount;
+ Q_ASSERT(offset >= 0);
+ return Address(PlatformAssembler::StackPointerRegister, offset * PlatformAssembler::PointerSize);
+}
+
+void Assembler::passAccumulatorAsArg(int arg)
+{
+#ifndef QT_NO_DEBUG
+ Q_ASSERT(arg < remainingArgcForCall);
+ --remainingArgcForCall;
+#endif
+
+ passAccumulatorAsArg_internal(arg, false);
+}
+
+void Assembler::passAccumulatorAsArg_internal(int arg, bool push)
+{
+ if (arg < PlatformAssembler::ArgInRegCount) {
+ pasm()->addPtr(TrustedImm32(offsetof(CallData, accumulator)),
+ PlatformAssembler::JSStackFrameRegister,
+ pasm()->registerForArg(arg));
} else {
- codeRef = linkBuffer.finalizeCodeWithoutDisassembly();
+ pasm()->addPtr(TrustedImm32(offsetof(CallData, accumulator)),
+ PlatformAssembler::JSStackFrameRegister,
+ PlatformAssembler::ScratchRegister);
+ if (push)
+ pasm()->push(PlatformAssembler::ScratchRegister);
+ else
+ pasm()->storePtr(PlatformAssembler::ScratchRegister,
+ argStackAddress(arg));
}
+}
-#if defined(Q_OS_LINUX)
- // This implements writing of JIT'd addresses so that perf can find the
- // symbol names.
- //
- // Perf expects the mapping to be in a certain place and have certain
- // content, for more information, see:
- // https://github.com/torvalds/linux/blob/master/tools/perf/Documentation/jit-interface.txt
- static bool doProfile = !qEnvironmentVariableIsEmpty("QV4_PROFILE_WRITE_PERF_MAP");
- static bool profileInitialized = false;
- if (doProfile && !profileInitialized) {
- profileInitialized = true;
+void Assembler::passFunctionAsArg(int arg)
+{
+#ifndef QT_NO_DEBUG
+ Q_ASSERT(arg < remainingArgcForCall);
+ --remainingArgcForCall;
+#endif
- char pname[PATH_MAX];
- snprintf(pname, PATH_MAX - 1, "/tmp/perf-%lu.map",
- (unsigned long)QCoreApplication::applicationPid());
+ if (arg < PlatformAssembler::ArgInRegCount) {
+ pasm()->loadFunctionPtr(pasm()->registerForArg(arg));
+ } else {
+ pasm()->loadFunctionPtr(PlatformAssembler::ScratchRegister);
+ pasm()->storePtr(PlatformAssembler::ScratchRegister,
+ argStackAddress(arg));
+ }
+}
- pmap = fopen(pname, "w");
- if (!pmap)
- qWarning("QV4: Can't write %s, call stacks will not contain JavaScript function names", pname);
+void Assembler::passEngineAsArg(int arg)
+{
+#ifndef QT_NO_DEBUG
+ Q_ASSERT(arg < remainingArgcForCall);
+ --remainingArgcForCall;
+#endif
- // make sure we clean up nicely
- std::atexit(qt_closePmap);
+ if (arg < PlatformAssembler::ArgInRegCount) {
+ pasm()->move(PlatformAssembler::EngineRegister, pasm()->registerForArg(arg));
+ } else {
+ pasm()->storePtr(PlatformAssembler::EngineRegister, argStackAddress(arg));
}
+}
- if (pmap) {
- // this may have been pre-populated, if QV4_SHOW_ASM was on
- if (name.isEmpty()) {
- name = _function->name->toUtf8();
- if (name.isEmpty())
- name = "IR::Function(0x" + QByteArray::number(quintptr(_function), 16) + ')';
- }
+void Assembler::passRegAsArg(int reg, int arg)
+{
+#ifndef QT_NO_DEBUG
+ Q_ASSERT(arg < remainingArgcForCall);
+ --remainingArgcForCall;
+#endif
- fprintf(pmap, "%llx %x %.*s\n",
- (long long unsigned int)codeRef.code().executableAddress(),
- *codeSize,
- name.length(),
- name.constData());
- fflush(pmap);
+ if (arg < PlatformAssembler::ArgInRegCount) {
+ pasm()->addPtr(TrustedImm32(reg * int(sizeof(QV4::Value))),
+ PlatformAssembler::JSStackFrameRegister,
+ pasm()->registerForArg(arg));
+ } else {
+ pasm()->addPtr(TrustedImm32(reg * int(sizeof(QV4::Value))),
+ PlatformAssembler::JSStackFrameRegister,
+ PlatformAssembler::ScratchRegister);
+ pasm()->storePtr(PlatformAssembler::ScratchRegister,
+ argStackAddress(arg));
}
+}
+
+void JIT::Assembler::passCppFrameAsArg(int arg)
+{
+#ifndef QT_NO_DEBUG
+ Q_ASSERT(arg < remainingArgcForCall);
+ --remainingArgcForCall;
#endif
- return codeRef;
+ if (arg < PlatformAssembler::ArgInRegCount) {
+ pasm()->move(PlatformAssembler::CppStackFrameRegister, pasm()->registerForArg(arg));
+ } else {
+ pasm()->store32(PlatformAssembler::CppStackFrameRegister, argStackAddress(arg));
+ }
}
-template class QV4::JIT::Assembler<DefaultAssemblerTargetConfiguration>;
-#if defined(V4_BOOTSTRAP)
-#if !CPU(ARM_THUMB2)
-template class QV4::JIT::Assembler<AssemblerTargetConfiguration<JSC::MacroAssemblerARMv7, NoOperatingSystemSpecialization>>;
-#endif
-#if !CPU(ARM64)
-template class QV4::JIT::Assembler<AssemblerTargetConfiguration<JSC::MacroAssemblerARM64, NoOperatingSystemSpecialization>>;
-#endif
+void Assembler::passInt32AsArg(int value, int arg)
+{
+#ifndef QT_NO_DEBUG
+ Q_ASSERT(arg < remainingArgcForCall);
+ --remainingArgcForCall;
#endif
+ if (arg < PlatformAssembler::ArgInRegCount) {
+ pasm()->move(TrustedImm32(value), pasm()->registerForArg(arg));
+ } else {
+ pasm()->store32(TrustedImm32(value), argStackAddress(arg));
+ }
+}
+
+void Assembler::callRuntime(const char *functionName, const void *funcPtr,
+ Assembler::CallResultDestination dest)
+{
+#ifndef QT_NO_DEBUG
+ Q_ASSERT(remainingArgcForCall == 0);
+ remainingArgcForCall = NoCall;
#endif
+ pasm()->callRuntime(functionName, funcPtr, dest);
+ if (argcOnStackForCall > 0) {
+ pasm()->addPtr(TrustedImm32(argcOnStackForCall), PlatformAssembler::StackPointerRegister);
+ argcOnStackForCall = 0;
+ }
+}
+
+void Assembler::saveAccumulatorInFrame()
+{
+ pasm()->storeAccumulator(PlatformAssembler::Address(PlatformAssembler::JSStackFrameRegister,
+ offsetof(CallData, accumulator)));
+}
+
+void Assembler::checkException()
+{
+ pasm()->addCatchyJump(
+ pasm()->branch32(
+ PlatformAssembler::NotEqual,
+ PlatformAssembler::Address(PlatformAssembler::EngineRegister,
+ offsetof(EngineBase, hasException)),
+ TrustedImm32(0)));
+}
+
+void Assembler::gotoCatchException()
+{
+ pasm()->addCatchyJump(pasm()->jump());
+}
+
+void Assembler::getException()
+{
+ Q_STATIC_ASSERT(sizeof(QV4::EngineBase::hasException) == 1);
+
+ Address hasExceptionAddr(PlatformAssembler::EngineRegister,
+ offsetof(EngineBase, hasException));
+ PlatformAssembler::Jump nope = pasm()->branch8(PlatformAssembler::Equal,
+ hasExceptionAddr,
+ TrustedImm32(0));
+ pasm()->loadPtr(Address(PlatformAssembler::EngineRegister,
+ offsetof(EngineBase, exceptionValue)),
+ PlatformAssembler::ScratchRegister);
+ pasm()->loadAccumulator(Address(PlatformAssembler::ScratchRegister));
+ pasm()->store8(TrustedImm32(0), hasExceptionAddr);
+ auto done = pasm()->jump();
+ nope.link(pasm());
+ pasm()->loadValue(Primitive::emptyValue().asReturnedValue());
+
+ done.link(pasm());
+}
+
+void Assembler::setException()
+{
+ Address addr(PlatformAssembler::EngineRegister, offsetof(EngineBase, exceptionValue));
+ pasm()->loadPtr(addr, PlatformAssembler::ScratchRegister);
+ pasm()->storeAccumulator(Address(PlatformAssembler::ScratchRegister));
+ addr.offset = offsetof(EngineBase, hasException);
+ Q_STATIC_ASSERT(sizeof(QV4::EngineBase::hasException) == 1);
+ pasm()->store8(TrustedImm32(1), addr);
+}
+
+void Assembler::setExceptionHandler(int offset)
+{
+ auto l = pasm()->storePtrWithPatch(TrustedImmPtr(nullptr), pasm()->exceptionHandlerAddress());
+ pasm()->ehTargets.push_back({ l, offset });
+}
+
+
+void Assembler::clearExceptionHandler()
+{
+ pasm()->storePtr(TrustedImmPtr(nullptr), pasm()->exceptionHandlerAddress());
+}
+
+void Assembler::pushCatchContext(int name, int reg)
+{
+ pasm()->copyReg(pasm()->contextAddress(), regAddr(reg));
+ prepareCallWithArgCount(2);
+ passInt32AsArg(name, 1);
+ passRegAsArg(CallData::Context, 0);
+ IN_JIT_GENERATE_RUNTIME_CALL(Runtime::method_createCatchContext, ResultInAccumulator);
+ pasm()->storeAccumulator(pasm()->contextAddress());
+}
+
+void Assembler::popContext(int reg)
+{
+ pasm()->copyReg(regAddr(reg), pasm()->contextAddress());
+}
+
+void Assembler::ret()
+{
+ pasm()->generateFunctionExit();
+}
+
+} // JIT namespace
+} // QV4 namepsace
+
+QT_END_NAMESPACE
+
+#endif // V4_ENABLE_JIT
diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h
index 8b5b307e84..37d4232a17 100644
--- a/src/qml/jit/qv4assembler_p.h
+++ b/src/qml/jit/qv4assembler_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQml module of the Qt Toolkit.
@@ -36,6 +36,7 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
#ifndef QV4ASSEMBLER_P_H
#define QV4ASSEMBLER_P_H
@@ -50,1664 +51,141 @@
// We mean it.
//
-#include "private/qv4global_p.h"
-#include "private/qv4jsir_p.h"
-#include "private/qv4isel_p.h"
-#include "private/qv4isel_util_p.h"
-#include "private/qv4value_p.h"
-#include "private/qv4context_p.h"
-#include "private/qv4engine_p.h"
-#include "qv4targetplatform_p.h"
-
-#include <config.h>
-#include <wtf/Vector.h>
-
-#include <climits>
-
-#if ENABLE(ASSEMBLER)
-
-#include <assembler/MacroAssembler.h>
-#include <assembler/MacroAssemblerCodeRef.h>
+#include <private/qv4global_p.h>
+#include <private/qv4function_p.h>
+#include <QHash>
QT_BEGIN_NAMESPACE
namespace QV4 {
namespace JIT {
-struct CompilationUnit : public QV4::CompiledData::CompilationUnit
-{
- virtual ~CompilationUnit();
-
-#if !defined(V4_BOOTSTRAP)
- void linkBackendToEngine(QV4::ExecutionEngine *engine) Q_DECL_OVERRIDE;
- bool memoryMapCode(QString *errorString) Q_DECL_OVERRIDE;
-#endif
- void prepareCodeOffsetsForDiskStorage(CompiledData::Unit *unit) Q_DECL_OVERRIDE;
- bool saveCodeToDisk(QIODevice *device, const CompiledData::Unit *unit, QString *errorString) Q_DECL_OVERRIDE;
-
- // Coderef + execution engine
-
- QVector<JSC::MacroAssemblerCodeRef> codeRefs;
-};
-
-template <typename PlatformAssembler, TargetOperatingSystemSpecialization Specialization>
-struct AssemblerTargetConfiguration
-{
- typedef JSC::MacroAssembler<PlatformAssembler> MacroAssembler;
- typedef TargetPlatform<PlatformAssembler, Specialization> Platform;
- // More things coming here in the future, such as Target OS
-};
-
-#if CPU(ARM_THUMB2)
-typedef JSC::MacroAssemblerARMv7 DefaultPlatformMacroAssembler;
-typedef AssemblerTargetConfiguration<DefaultPlatformMacroAssembler, NoOperatingSystemSpecialization> DefaultAssemblerTargetConfiguration;
-#elif CPU(ARM64)
-typedef JSC::MacroAssemblerARM64 DefaultPlatformMacroAssembler;
-typedef AssemblerTargetConfiguration<DefaultPlatformMacroAssembler, NoOperatingSystemSpecialization> DefaultAssemblerTargetConfiguration;
-#elif CPU(ARM_TRADITIONAL)
-typedef JSC::MacroAssemblerARM DefaultPlatformMacroAssembler;
-typedef AssemblerTargetConfiguration<DefaultPlatformMacroAssembler, NoOperatingSystemSpecialization> DefaultAssemblerTargetConfiguration;
-#elif CPU(MIPS)
-typedef JSC::MacroAssemblerMIPS DefaultPlatformMacroAssembler;
-typedef AssemblerTargetConfiguration<DefaultPlatformMacroAssembler, NoOperatingSystemSpecialization> DefaultAssemblerTargetConfiguration;
-#elif CPU(X86)
-typedef JSC::MacroAssemblerX86 DefaultPlatformMacroAssembler;
-typedef AssemblerTargetConfiguration<DefaultPlatformMacroAssembler, NoOperatingSystemSpecialization> DefaultAssemblerTargetConfiguration;
-#elif CPU(X86_64)
-typedef JSC::MacroAssemblerX86_64 DefaultPlatformMacroAssembler;
-
-#if OS(WINDOWS)
-typedef AssemblerTargetConfiguration<DefaultPlatformMacroAssembler, WindowsSpecialization> DefaultAssemblerTargetConfiguration;
-#else
-typedef AssemblerTargetConfiguration<DefaultPlatformMacroAssembler, NoOperatingSystemSpecialization> DefaultAssemblerTargetConfiguration;
-#endif
-
-#elif CPU(SH4)
-typedef JSC::MacroAssemblerSH4 DefaultPlatformMacroAssembler;
-typedef AssemblerTargetConfiguration<DefaultPlatformMacroAssembler, NoOperatingSystemSpecialization> DefaultAssemblerTargetConfiguration;
-#endif
-
-#define isel_stringIfyx(s) #s
-#define isel_stringIfy(s) isel_stringIfyx(s)
-
-#define generateRuntimeCall(as, t, function, ...) \
- as->generateFunctionCallImp(Runtime::Method_##function##_NeedsExceptionCheck, t, "Runtime::" isel_stringIfy(function), typename JITAssembler::RuntimeCall(QV4::Runtime::function), __VA_ARGS__)
-
-
-template <typename JITAssembler, typename MacroAssembler, typename TargetPlatform, int RegisterSize>
-struct RegisterSizeDependentAssembler
-{
-};
-
-template <typename JITAssembler, typename MacroAssembler, typename TargetPlatform>
-struct RegisterSizeDependentAssembler<JITAssembler, MacroAssembler, TargetPlatform, 4>
-{
- using RegisterID = typename JITAssembler::RegisterID;
- using FPRegisterID = typename JITAssembler::FPRegisterID;
- using RelationalCondition = typename JITAssembler::RelationalCondition;
- using ResultCondition = typename JITAssembler::ResultCondition;
- using Address = typename JITAssembler::Address;
- using Pointer = typename JITAssembler::Pointer;
- using TrustedImm32 = typename JITAssembler::TrustedImm32;
- using TrustedImm64 = typename JITAssembler::TrustedImm64;
- using Jump = typename JITAssembler::Jump;
- using Label = typename JITAssembler::Label;
-
- using ValueTypeInternal = Value::ValueTypeInternal_32;
- using TargetPrimitive = TargetPrimitive32;
-
- static void loadDouble(JITAssembler *as, Address addr, FPRegisterID dest)
- {
- as->MacroAssembler::loadDouble(addr, dest);
- }
-
- static void storeDouble(JITAssembler *as, FPRegisterID source, Address addr)
- {
- as->MacroAssembler::storeDouble(source, addr);
- }
-
- static void storeDouble(JITAssembler *as, FPRegisterID source, IR::Expr* target)
- {
- Pointer ptr = as->loadAddress(TargetPlatform::ScratchRegister, target);
- as->storeDouble(source, ptr);
- }
-
- static void storeValue(JITAssembler *as, TargetPrimitive value, Address destination)
- {
- as->store32(TrustedImm32(value.value()), destination);
- destination.offset += 4;
- as->store32(TrustedImm32(value.tag()), destination);
- }
-
- template <typename Source, typename Destination>
- static void copyValueViaRegisters(JITAssembler *as, Source source, Destination destination)
- {
- as->loadDouble(source, TargetPlatform::FPGpr0);
- as->storeDouble(TargetPlatform::FPGpr0, destination);
- }
-
- static void loadDoubleConstant(JITAssembler *as, IR::Const *c, FPRegisterID target)
- {
- as->MacroAssembler::loadDouble(as->loadConstant(c, TargetPlatform::ScratchRegister), target);
- }
-
- static void storeReturnValue(JITAssembler *as, FPRegisterID dest)
- {
- as->moveIntsToDouble(TargetPlatform::LowReturnValueRegister, TargetPlatform::HighReturnValueRegister, dest, TargetPlatform::FPGpr0);
- }
-
- static void storeReturnValue(JITAssembler *as, const Pointer &dest)
- {
- Address destination = dest;
- as->store32(TargetPlatform::LowReturnValueRegister, destination);
- destination.offset += 4;
- as->store32(TargetPlatform::HighReturnValueRegister, destination);
- }
-
- static void setFunctionReturnValueFromTemp(JITAssembler *as, IR::Temp *t)
- {
- const auto lowReg = TargetPlatform::LowReturnValueRegister;
- const auto highReg = TargetPlatform::HighReturnValueRegister;
-
- if (t->kind == IR::Temp::PhysicalRegister) {
- switch (t->type) {
- case IR::DoubleType:
- as->moveDoubleToInts((FPRegisterID) t->index, lowReg, highReg);
- break;
- case IR::UInt32Type: {
- RegisterID srcReg = (RegisterID) t->index;
- Jump intRange = as->branch32(JITAssembler::GreaterThanOrEqual, srcReg, TrustedImm32(0));
- as->convertUInt32ToDouble(srcReg, TargetPlatform::FPGpr0, TargetPlatform::ReturnValueRegister);
- as->moveDoubleToInts(TargetPlatform::FPGpr0, lowReg, highReg);
- Jump done = as->jump();
- intRange.link(as);
- as->move(srcReg, lowReg);
- as->move(TrustedImm32(quint32(QV4::Value::ValueTypeInternal_32::Integer)), highReg);
- done.link(as);
- } break;
- case IR::SInt32Type:
- as->move((RegisterID) t->index, lowReg);
- as->move(TrustedImm32(quint32(QV4::Value::ValueTypeInternal_32::Integer)), highReg);
- break;
- case IR::BoolType:
- as->move((RegisterID) t->index, lowReg);
- as->move(TrustedImm32(quint32(QV4::Value::ValueTypeInternal_32::Boolean)), highReg);
- break;
- default:
- Q_UNREACHABLE();
- }
- } else {
- Pointer addr = as->loadAddress(TargetPlatform::ScratchRegister, t);
- as->load32(addr, lowReg);
- addr.offset += 4;
- as->load32(addr, highReg);
- }
- }
-
- static void setFunctionReturnValueFromConst(JITAssembler *as, TargetPrimitive retVal)
- {
- as->move(TrustedImm32(retVal.value()), TargetPlatform::LowReturnValueRegister);
- as->move(TrustedImm32(retVal.tag()), TargetPlatform::HighReturnValueRegister);
- }
-
- static void loadArgumentInRegister(JITAssembler *as, IR::Temp* temp, RegisterID dest, int argumentNumber)
- {
- Q_UNUSED(as);
- Q_UNUSED(temp);
- Q_UNUSED(dest);
- Q_UNUSED(argumentNumber);
- }
-
- static void loadArgumentInRegister(JITAssembler *as, IR::ArgLocal* al, RegisterID dest, int argumentNumber)
- {
- Q_UNUSED(as);
- Q_UNUSED(al);
- Q_UNUSED(dest);
- Q_UNUSED(argumentNumber);
- }
-
- static void loadArgumentInRegister(JITAssembler *as, IR::Const* c, RegisterID dest, int argumentNumber)
- {
- Q_UNUSED(as);
- Q_UNUSED(c);
- Q_UNUSED(dest);
- Q_UNUSED(argumentNumber);
- }
-
- static void loadArgumentInRegister(JITAssembler *as, IR::Expr* expr, RegisterID dest, int argumentNumber)
- {
- Q_UNUSED(as);
- Q_UNUSED(expr);
- Q_UNUSED(dest);
- Q_UNUSED(argumentNumber);
- }
-
- static void zeroRegister(JITAssembler *as, RegisterID reg)
- {
- as->move(TrustedImm32(0), reg);
- }
-
- static void zeroStackSlot(JITAssembler *as, int slot)
- {
- as->poke(TrustedImm32(0), slot);
- }
-
- static void generateCJumpOnUndefined(JITAssembler *as,
- RelationalCondition cond, IR::Expr *right,
- RegisterID scratchRegister, RegisterID tagRegister,
- IR::BasicBlock *nextBlock, IR::BasicBlock *currentBlock,
- IR::BasicBlock *trueBlock, IR::BasicBlock *falseBlock)
- {
- Pointer tagAddr = as->loadAddress(scratchRegister, right);
- as->load32(tagAddr, tagRegister);
- Jump j = as->branch32(JITAssembler::invert(cond), tagRegister, TrustedImm32(0));
- as->addPatch(falseBlock, j);
-
- tagAddr.offset += 4;
- as->load32(tagAddr, tagRegister);
- const TrustedImm32 tag(QV4::Value::Managed_Type_Internal);
- Q_ASSERT(nextBlock == as->nextBlock());
- Q_UNUSED(nextBlock);
- as->generateCJumpOnCompare(cond, tagRegister, tag, currentBlock, trueBlock, falseBlock);
- }
-
- static void convertVarToSInt32(JITAssembler *as, IR::Expr *source, IR::Expr *target)
- {
- Q_ASSERT(source->type == IR::VarType);
- // load the tag:
- Pointer addr = as->loadAddress(TargetPlatform::ScratchRegister, source);
- Pointer tagAddr = addr;
- tagAddr.offset += 4;
- as->load32(tagAddr, TargetPlatform::ReturnValueRegister);
-
- // check if it's an int32:
- Jump fallback = as->branch32(RelationalCondition::NotEqual, TargetPlatform::ReturnValueRegister,
- TrustedImm32(quint32(Value::ValueTypeInternal_32::Integer)));
- IR::Temp *targetTemp = target->asTemp();
- if (!targetTemp || targetTemp->kind == IR::Temp::StackSlot) {
- as->load32(addr, TargetPlatform::ReturnValueRegister);
- Pointer targetAddr = as->loadAddress(TargetPlatform::ScratchRegister, target);
- as->store32(TargetPlatform::ReturnValueRegister, targetAddr);
- targetAddr.offset += 4;
- as->store32(TrustedImm32(quint32(Value::ValueTypeInternal_32::Integer)), targetAddr);
- } else {
- as->load32(addr, (RegisterID) targetTemp->index);
- }
- Jump intDone = as->jump();
-
- // not an int:
- fallback.link(as);
- generateRuntimeCall(as, TargetPlatform::ReturnValueRegister, toInt,
- as->loadAddress(TargetPlatform::ScratchRegister, source));
- as->storeInt32(TargetPlatform::ReturnValueRegister, target);
-
- intDone.link(as);
- }
-
- static void loadManagedPointer(JITAssembler *as, RegisterID registerWithPtr, Pointer destAddr)
- {
- as->store32(registerWithPtr, destAddr);
- destAddr.offset += 4;
- as->store32(TrustedImm32(QV4::Value::Managed_Type_Internal_32), destAddr);
- }
-
- static Jump generateIsDoubleCheck(JITAssembler *as, RegisterID tagOrValueRegister)
- {
- as->and32(TrustedImm32(Value::NotDouble_Mask), tagOrValueRegister);
- return as->branch32(RelationalCondition::NotEqual, tagOrValueRegister,
- TrustedImm32(Value::NotDouble_Mask));
- }
-
- static void initializeLocalVariables(JITAssembler *as, int localsCount)
- {
- as->move(TrustedImm32(0), TargetPlatform::ReturnValueRegister);
- as->move(TrustedImm32(localsCount), TargetPlatform::ScratchRegister);
- Label loop = as->label();
- as->store32(TargetPlatform::ReturnValueRegister, Address(TargetPlatform::LocalsRegister));
- as->add32(TrustedImm32(4), TargetPlatform::LocalsRegister);
- as->store32(TargetPlatform::ReturnValueRegister, Address(TargetPlatform::LocalsRegister));
- as->add32(TrustedImm32(4), TargetPlatform::LocalsRegister);
- Jump jump = as->branchSub32(ResultCondition::NonZero, TrustedImm32(1), TargetPlatform::ScratchRegister);
- jump.linkTo(loop, as);
- }
-
- static Jump checkIfTagRegisterIsDouble(JITAssembler *as, RegisterID tagRegister)
- {
- as->and32(TrustedImm32(Value::NotDouble_Mask), tagRegister);
- Jump isNoDbl = as->branch32(RelationalCondition::Equal, tagRegister, TrustedImm32(Value::NotDouble_Mask));
- return isNoDbl;
- }
-};
-
-template <typename JITAssembler, typename MacroAssembler, typename TargetPlatform>
-struct RegisterSizeDependentAssembler<JITAssembler, MacroAssembler, TargetPlatform, 8>
-{
- using RegisterID = typename JITAssembler::RegisterID;
- using FPRegisterID = typename JITAssembler::FPRegisterID;
- using Address = typename JITAssembler::Address;
- using TrustedImm32 = typename JITAssembler::TrustedImm32;
- using TrustedImm64 = typename JITAssembler::TrustedImm64;
- using Pointer = typename JITAssembler::Pointer;
- using RelationalCondition = typename JITAssembler::RelationalCondition;
- using ResultCondition = typename JITAssembler::ResultCondition;
- using BranchTruncateType = typename JITAssembler::BranchTruncateType;
- using Jump = typename JITAssembler::Jump;
- using Label = typename JITAssembler::Label;
-
- using ValueTypeInternal = Value::ValueTypeInternal_64;
- using TargetPrimitive = TargetPrimitive64;
-
- static void loadDouble(JITAssembler *as, Address addr, FPRegisterID dest)
- {
- as->load64(addr, TargetPlatform::ReturnValueRegister);
- as->xor64(TargetPlatform::DoubleMaskRegister, TargetPlatform::ReturnValueRegister);
- as->move64ToDouble(TargetPlatform::ReturnValueRegister, dest);
- }
-
- static void storeDouble(JITAssembler *as, FPRegisterID source, Address addr)
- {
- as->moveDoubleTo64(source, TargetPlatform::ReturnValueRegister);
- as->xor64(TargetPlatform::DoubleMaskRegister, TargetPlatform::ReturnValueRegister);
- as->store64(TargetPlatform::ReturnValueRegister, addr);
- }
-
- static void storeDouble(JITAssembler *as, FPRegisterID source, IR::Expr* target)
- {
- as->moveDoubleTo64(source, TargetPlatform::ReturnValueRegister);
- as->xor64(TargetPlatform::DoubleMaskRegister, TargetPlatform::ReturnValueRegister);
- Pointer ptr = as->loadAddress(TargetPlatform::ScratchRegister, target);
- as->store64(TargetPlatform::ReturnValueRegister, ptr);
- }
-
- static void storeReturnValue(JITAssembler *as, FPRegisterID dest)
- {
- as->xor64(TargetPlatform::DoubleMaskRegister, TargetPlatform::ReturnValueRegister);
- as->move64ToDouble(TargetPlatform::ReturnValueRegister, dest);
- }
-
- static void storeReturnValue(JITAssembler *as, const Pointer &dest)
- {
- as->store64(TargetPlatform::ReturnValueRegister, dest);
- }
-
- static void setFunctionReturnValueFromTemp(JITAssembler *as, IR::Temp *t)
- {
- if (t->kind == IR::Temp::PhysicalRegister) {
- if (t->type == IR::DoubleType) {
- as->moveDoubleTo64((FPRegisterID) t->index,
- TargetPlatform::ReturnValueRegister);
- as->xor64(TargetPlatform::DoubleMaskRegister, TargetPlatform::ReturnValueRegister);
- } else if (t->type == IR::UInt32Type) {
- RegisterID srcReg = (RegisterID) t->index;
- Jump intRange = as->branch32(RelationalCondition::GreaterThanOrEqual, srcReg, TrustedImm32(0));
- as->convertUInt32ToDouble(srcReg, TargetPlatform::FPGpr0, TargetPlatform::ReturnValueRegister);
- as->moveDoubleTo64(TargetPlatform::FPGpr0, TargetPlatform::ReturnValueRegister);
- as->xor64(TargetPlatform::DoubleMaskRegister, TargetPlatform::ReturnValueRegister);
- Jump done = as->jump();
- intRange.link(as);
- as->zeroExtend32ToPtr(srcReg, TargetPlatform::ReturnValueRegister);
- quint64 tag = quint64(QV4::Value::ValueTypeInternal_64::Integer);
- as->or64(TrustedImm64(tag << 32),
- TargetPlatform::ReturnValueRegister);
- done.link(as);
- } else {
- as->zeroExtend32ToPtr((RegisterID) t->index, TargetPlatform::ReturnValueRegister);
- quint64 tag;
- switch (t->type) {
- case IR::SInt32Type:
- tag = quint64(QV4::Value::ValueTypeInternal_64::Integer);
- break;
- case IR::BoolType:
- tag = quint64(QV4::Value::ValueTypeInternal_64::Boolean);
- break;
- default:
- tag = 31337; // bogus value
- Q_UNREACHABLE();
- }
- as->or64(TrustedImm64(tag << 32),
- TargetPlatform::ReturnValueRegister);
- }
- } else {
- as->copyValue(TargetPlatform::ReturnValueRegister, t);
- }
- }
-
- static void setFunctionReturnValueFromConst(JITAssembler *as, TargetPrimitive retVal)
- {
- as->move(TrustedImm64(retVal.rawValue()), TargetPlatform::ReturnValueRegister);
- }
-
- static void storeValue(JITAssembler *as, TargetPrimitive value, Address destination)
- {
- as->store64(TrustedImm64(value.rawValue()), destination);
- }
-
- template <typename Source, typename Destination>
- static void copyValueViaRegisters(JITAssembler *as, Source source, Destination destination)
- {
- // Use ReturnValueRegister as "scratch" register because loadArgument
- // and storeArgument are functions that may need a scratch register themselves.
- loadArgumentInRegister(as, source, TargetPlatform::ReturnValueRegister, 0);
- as->storeReturnValue(destination);
- }
+#define JIT_STRINGIFYx(s) #s
+#define JIT_STRINGIFY(s) JIT_STRINGIFYx(s)
- static void loadDoubleConstant(JITAssembler *as, IR::Const *c, FPRegisterID target)
- {
- Q_STATIC_ASSERT(sizeof(int64_t) == sizeof(double));
- int64_t i;
- memcpy(&i, &c->value, sizeof(double));
- as->move(TrustedImm64(i), TargetPlatform::ReturnValueRegister);
- as->move64ToDouble(TargetPlatform::ReturnValueRegister, target);
- }
-
- static void loadArgumentInRegister(JITAssembler *as, Address addressOfValue, RegisterID dest, int argumentNumber)
- {
- Q_UNUSED(argumentNumber);
- as->load64(addressOfValue, dest);
- }
-
- static void loadArgumentInRegister(JITAssembler *as, IR::Temp* temp, RegisterID dest, int argumentNumber)
- {
- Q_UNUSED(argumentNumber);
-
- if (temp) {
- Pointer addr = as->loadTempAddress(temp);
- as->load64(addr, dest);
- } else {
- auto undefined = TargetPrimitive::undefinedValue();
- as->move(TrustedImm64(undefined.rawValue()), dest);
- }
- }
-
- static void loadArgumentInRegister(JITAssembler *as, IR::ArgLocal* al, RegisterID dest, int argumentNumber)
- {
- Q_UNUSED(argumentNumber);
-
- if (al) {
- Pointer addr = as->loadArgLocalAddress(dest, al);
- as->load64(addr, dest);
- } else {
- auto undefined = TargetPrimitive::undefinedValue();
- as->move(TrustedImm64(undefined.rawValue()), dest);
- }
- }
-
- static void loadArgumentInRegister(JITAssembler *as, IR::Const* c, RegisterID dest, int argumentNumber)
- {
- Q_UNUSED(argumentNumber);
-
- auto v = convertToValue<TargetPrimitive64>(c);
- as->move(TrustedImm64(v.rawValue()), dest);
- }
-
- static void loadArgumentInRegister(JITAssembler *as, IR::Expr* expr, RegisterID dest, int argumentNumber)
- {
- Q_UNUSED(argumentNumber);
-
- if (!expr) {
- auto undefined = TargetPrimitive::undefinedValue();
- as->move(TrustedImm64(undefined.rawValue()), dest);
- } else if (IR::Temp *t = expr->asTemp()){
- loadArgumentInRegister(as, t, dest, argumentNumber);
- } else if (IR::ArgLocal *al = expr->asArgLocal()) {
- loadArgumentInRegister(as, al, dest, argumentNumber);
- } else if (IR::Const *c = expr->asConst()) {
- loadArgumentInRegister(as, c, dest, argumentNumber);
- } else {
- Q_ASSERT(!"unimplemented expression type in loadArgument");
- }
- }
-
- static void zeroRegister(JITAssembler *as, RegisterID reg)
- {
- as->move(TrustedImm64(0), reg);
- }
-
- static void zeroStackSlot(JITAssembler *as, int slot)
- {
- as->store64(TrustedImm64(0), as->addressForPoke(slot));
- }
-
- static void generateCJumpOnCompare(JITAssembler *as,
- RelationalCondition cond,
- RegisterID left,
- TrustedImm64 right,
- IR::BasicBlock *nextBlock,
- IR::BasicBlock *currentBlock,
- IR::BasicBlock *trueBlock,
- IR::BasicBlock *falseBlock)
- {
- if (trueBlock == nextBlock) {
- Jump target = as->branch64(as->invert(cond), left, right);
- as->addPatch(falseBlock, target);
- } else {
- Jump target = as->branch64(cond, left, right);
- as->addPatch(trueBlock, target);
- as->jumpToBlock(currentBlock, falseBlock);
- }
- }
-
- static void generateCJumpOnUndefined(JITAssembler *as,
- RelationalCondition cond, IR::Expr *right,
- RegisterID scratchRegister, RegisterID tagRegister,
- IR::BasicBlock *nextBlock, IR::BasicBlock *currentBlock,
- IR::BasicBlock *trueBlock, IR::BasicBlock *falseBlock)
- {
- Pointer addr = as->loadAddress(scratchRegister, right);
- as->load64(addr, tagRegister);
- const TrustedImm64 tag(0);
- generateCJumpOnCompare(as, cond, tagRegister, tag, nextBlock, currentBlock, trueBlock, falseBlock);
- }
-
- static void convertVarToSInt32(JITAssembler *as, IR::Expr *source, IR::Expr *target)
- {
- Q_ASSERT(source->type == IR::VarType);
- Pointer addr = as->loadAddress(TargetPlatform::ScratchRegister, source);
- as->load64(addr, TargetPlatform::ScratchRegister);
- as->move(TargetPlatform::ScratchRegister, TargetPlatform::ReturnValueRegister);
-
- // check if it's integer convertible
- as->urshift64(TrustedImm32(QV4::Value::IsIntegerConvertible_Shift), TargetPlatform::ScratchRegister);
- Jump isIntConvertible = as->branch32(RelationalCondition::Equal, TargetPlatform::ScratchRegister, TrustedImm32(3));
-
- // nope, not integer convertible, so check for a double:
- as->urshift64(TrustedImm32(
- QV4::Value::IsDoubleTag_Shift - QV4::Value::IsIntegerConvertible_Shift),
- TargetPlatform::ScratchRegister);
- Jump fallback = as->branch32(RelationalCondition::GreaterThan, TargetPlatform::ScratchRegister, TrustedImm32(0));
-
- // it's a double
- as->xor64(TargetPlatform::DoubleMaskRegister, TargetPlatform::ReturnValueRegister);
- as->move64ToDouble(TargetPlatform::ReturnValueRegister, TargetPlatform::FPGpr0);
- Jump success =
- as->branchTruncateDoubleToInt32(TargetPlatform::FPGpr0, TargetPlatform::ReturnValueRegister,
- BranchTruncateType::BranchIfTruncateSuccessful);
-
- // not an int:
- fallback.link(as);
- generateRuntimeCall(as, TargetPlatform::ReturnValueRegister, toInt,
- as->loadAddress(TargetPlatform::ScratchRegister, source));
-
-
- isIntConvertible.link(as);
- success.link(as);
- IR::Temp *targetTemp = target->asTemp();
- if (!targetTemp || targetTemp->kind == IR::Temp::StackSlot) {
- Pointer targetAddr = as->loadAddress(TargetPlatform::ScratchRegister, target);
- as->store32(TargetPlatform::ReturnValueRegister, targetAddr);
- targetAddr.offset += 4;
- as->store32(TrustedImm32(quint32(Value::ValueTypeInternal_64::Integer)), targetAddr);
- } else {
- as->storeInt32(TargetPlatform::ReturnValueRegister, target);
- }
- }
-
- static void loadManagedPointer(JITAssembler *as, RegisterID registerWithPtr, Pointer destAddr)
- {
- as->store64(registerWithPtr, destAddr);
- }
-
- static Jump generateIsDoubleCheck(JITAssembler *as, RegisterID tagOrValueRegister)
- {
- as->rshift32(TrustedImm32(Value::IsDoubleTag_Shift), tagOrValueRegister);
- return as->branch32(RelationalCondition::NotEqual, tagOrValueRegister,
- TrustedImm32(0));
- }
-
- static void initializeLocalVariables(JITAssembler *as, int localsCount)
- {
- as->move(TrustedImm64(0), TargetPlatform::ReturnValueRegister);
- as->move(TrustedImm32(localsCount), TargetPlatform::ScratchRegister);
- Label loop = as->label();
- as->store64(TargetPlatform::ReturnValueRegister, Address(TargetPlatform::LocalsRegister));
- as->add64(TrustedImm32(8), TargetPlatform::LocalsRegister);
- Jump jump = as->branchSub32(ResultCondition::NonZero, TrustedImm32(1), TargetPlatform::ScratchRegister);
- jump.linkTo(loop, as);
- }
-
- static Jump checkIfTagRegisterIsDouble(JITAssembler *as, RegisterID tagRegister)
- {
- as->rshift32(TrustedImm32(Value::IsDoubleTag_Shift), tagRegister);
- Jump isNoDbl = as->branch32(RelationalCondition::Equal, tagRegister, TrustedImm32(0));
- return isNoDbl;
- }
-};
-
-template <typename TargetConfiguration>
-class Assembler : public TargetConfiguration::MacroAssembler, public TargetConfiguration::Platform
-{
- Q_DISABLE_COPY(Assembler)
+#define IN_JIT_GENERATE_RUNTIME_CALL(function, destination) \
+ callRuntime(JIT_STRINGIFY(function), \
+ reinterpret_cast<void *>(&function), \
+ destination)
+#define JIT_GENERATE_RUNTIME_CALL(function, destination) \
+ as->IN_JIT_GENERATE_RUNTIME_CALL(function, destination)
+class Assembler {
public:
- Assembler(QV4::Compiler::JSUnitGenerator *jsGenerator, IR::Function* function, QV4::ExecutableAllocator *executableAllocator);
-
- using MacroAssembler = typename TargetConfiguration::MacroAssembler;
- using RegisterID = typename MacroAssembler::RegisterID;
- using FPRegisterID = typename MacroAssembler::FPRegisterID;
- using Address = typename MacroAssembler::Address;
- using Label = typename MacroAssembler::Label;
- using Jump = typename MacroAssembler::Jump;
- using DataLabelPtr = typename MacroAssembler::DataLabelPtr;
- using TrustedImm32 = typename MacroAssembler::TrustedImm32;
- using TrustedImm64 = typename MacroAssembler::TrustedImm64;
- using TrustedImmPtr = typename MacroAssembler::TrustedImmPtr;
- using RelationalCondition = typename MacroAssembler::RelationalCondition;
- using typename MacroAssembler::DoubleCondition;
- using MacroAssembler::label;
- using MacroAssembler::move;
- using MacroAssembler::jump;
- using MacroAssembler::add32;
- using MacroAssembler::and32;
- using MacroAssembler::store32;
- using MacroAssembler::loadPtr;
- using MacroAssembler::load32;
- using MacroAssembler::branch32;
- using MacroAssembler::subDouble;
- using MacroAssembler::subPtr;
- using MacroAssembler::addPtr;
- using MacroAssembler::call;
- using MacroAssembler::poke;
- using MacroAssembler::branchTruncateDoubleToUint32;
- using MacroAssembler::or32;
- using MacroAssembler::moveDouble;
- using MacroAssembler::convertUInt32ToDouble;
- using MacroAssembler::invert;
- using MacroAssembler::convertInt32ToDouble;
- using MacroAssembler::rshift32;
- using MacroAssembler::storePtr;
- using MacroAssembler::ret;
-
- using JITTargetPlatform = typename TargetConfiguration::Platform;
- using JITTargetPlatform::RegisterArgumentCount;
- using JITTargetPlatform::StackSpaceAllocatedUponFunctionEntry;
- using JITTargetPlatform::RegisterSize;
- using JITTargetPlatform::StackAlignment;
- using JITTargetPlatform::ReturnValueRegister;
- using JITTargetPlatform::StackPointerRegister;
- using JITTargetPlatform::ScratchRegister;
- using JITTargetPlatform::EngineRegister;
- using JITTargetPlatform::StackShadowSpace;
- using JITTargetPlatform::registerForArgument;
- using JITTargetPlatform::FPGpr0;
- using JITTargetPlatform::platformEnterStandardStackFrame;
- using JITTargetPlatform::platformFinishEnteringStandardStackFrame;
- using JITTargetPlatform::platformLeaveStandardStackFrame;
-
- static qint32 targetStructureOffset(qint32 hostOffset)
- {
- Q_ASSERT(hostOffset % QT_POINTER_SIZE == 0);
- return (hostOffset * RegisterSize) / QT_POINTER_SIZE;
- }
-
- struct LookupCall {
- Address addr;
- uint getterSetterOffset;
-
- LookupCall(const Address &addr, uint getterSetterOffset)
- : addr(addr)
- , getterSetterOffset(getterSetterOffset)
- {}
+ enum CallResultDestination {
+ IgnoreResult,
+ ResultInAccumulator,
};
- struct RuntimeCall {
- Address addr;
-
- inline RuntimeCall(Runtime::RuntimeMethods method = Runtime::InvalidRuntimeMethod);
- bool isValid() const { return addr.offset >= 0; }
- };
-
- // Explicit type to allow distinguishing between
- // pushing an address itself or the value it points
- // to onto the stack when calling functions.
- struct Pointer : public Address
- {
- explicit Pointer(const Address& addr)
- : Address(addr)
- {}
- explicit Pointer(RegisterID reg, int32_t offset)
- : Address(reg, offset)
- {}
- };
-
- using RegisterSizeDependentOps = RegisterSizeDependentAssembler<Assembler<TargetConfiguration>, MacroAssembler, JITTargetPlatform, RegisterSize>;
- using ValueTypeInternal = typename RegisterSizeDependentOps::ValueTypeInternal;
- using TargetPrimitive = typename RegisterSizeDependentOps::TargetPrimitive;
-
- // V4 uses two stacks: one stack with QV4::Value items, which is checked by the garbage
- // collector, and one stack used by the native C/C++/ABI code. This C++ stack is not scanned
- // by the garbage collector, so if any JS object needs to be retained, it should be put on the
- // JS stack.
- //
- // The "saved reg arg X" are on the C++ stack is used to store values in registers that need to
- // be passed by reference to native functions. It is fine to use the C++ stack, because only
- // non-object values can be stored in registers.
- //
- // Stack layout for the C++ stack:
- // return address
- // old FP <- FP
- // callee saved reg n
- // ...
- // callee saved reg 0
- // saved reg arg n
- // ...
- // saved reg arg 0 <- SP
- //
- // Stack layout for the JS stack:
- // function call argument n <- LocalsRegister
- // ...
- // function call argument 0
- // local 0
- // ...
- // local n
- class StackLayout
- {
- public:
- StackLayout(IR::Function *function, int maxArgCountForBuiltins, int normalRegistersToSave, int fpRegistersToSave)
- : normalRegistersToSave(normalRegistersToSave)
- , fpRegistersToSave(fpRegistersToSave)
- , maxOutgoingArgumentCount(function->maxNumberOfArguments)
- , localCount(function->tempCount)
- , savedRegCount(maxArgCountForBuiltins)
- {
-#if 0 // debug code
- qDebug("calleeSavedRegCount.....: %d",calleeSavedRegCount);
- qDebug("maxOutgoingArgumentCount: %d",maxOutgoingArgumentCount);
- qDebug("localCount..............: %d",localCount);
- qDebug("savedConstCount.........: %d",savedRegCount);
- for (int i = 0; i < maxOutgoingArgumentCount; ++i)
- qDebug("argumentAddressForCall(%d) = 0x%x / -0x%x", i,
- argumentAddressForCall(i).offset, -argumentAddressForCall(i).offset);
- for (int i = 0; i < localCount; ++i)
- qDebug("local(%d) = 0x%x / -0x%x", i, stackSlotPointer(i).offset,
- -stackSlotPointer(i).offset);
- qDebug("savedReg(0) = 0x%x / -0x%x", savedRegPointer(0).offset, -savedRegPointer(0).offset);
- qDebug("savedReg(1) = 0x%x / -0x%x", savedRegPointer(1).offset, -savedRegPointer(1).offset);
- qDebug("savedReg(2) = 0x%x / -0x%x", savedRegPointer(2).offset, -savedRegPointer(2).offset);
- qDebug("savedReg(3) = 0x%x / -0x%x", savedRegPointer(3).offset, -savedRegPointer(3).offset);
- qDebug("savedReg(4) = 0x%x / -0x%x", savedRegPointer(4).offset, -savedRegPointer(4).offset);
- qDebug("savedReg(5) = 0x%x / -0x%x", savedRegPointer(5).offset, -savedRegPointer(5).offset);
-
- qDebug("callDataAddress(0) = 0x%x", callDataAddress(0).offset);
-#endif
- }
-
- int calculateStackFrameSize() const
- {
- // sp was aligned before executing the call instruction. So, calculate all contents
- // that were saved after that aligned stack...:
- const int stackSpaceAllocatedOtherwise = StackSpaceAllocatedUponFunctionEntry
- + RegisterSize; // saved FramePointerRegister
-
- // ... then calculate the stuff we want to store ...:
- int frameSize = RegisterSize * normalRegistersToSave + sizeof(double) * fpRegistersToSave;
- frameSize += savedRegCount * sizeof(QV4::Value); // (these get written out as Values, not as native registers)
-
- Q_ASSERT(frameSize + stackSpaceAllocatedOtherwise < INT_MAX);
- // .. then align that chunk ..:
- frameSize = static_cast<int>(WTF::roundUpToMultipleOf(StackAlignment, frameSize + stackSpaceAllocatedOtherwise));
- // ... which now holds our frame size + the extra stuff that was pushed due to the call.
- // So subtract that extra stuff, and we have our frame size:
- frameSize -= stackSpaceAllocatedOtherwise;
-
- return frameSize;
- }
-
- /// \return the stack frame size in number of Value items.
- int calculateJSStackFrameSize() const
- {
- return (localCount + sizeof(QV4::CallData)/sizeof(QV4::Value) - 1 + maxOutgoingArgumentCount) + 1;
- }
-
- Address stackSlotPointer(int idx) const
- {
- Q_ASSERT(idx >= 0);
- Q_ASSERT(idx < localCount);
-
- Pointer addr = callDataAddress(0);
- addr.offset -= sizeof(QV4::Value) * (idx + 1);
- return addr;
- }
-
- // Some run-time functions take (Value* args, int argc). This function is for populating
- // the args.
- Pointer argumentAddressForCall(int argument) const
- {
- Q_ASSERT(argument >= 0);
- Q_ASSERT(argument < maxOutgoingArgumentCount);
-
- const int index = maxOutgoingArgumentCount - argument;
- return Pointer(Assembler::LocalsRegister, sizeof(QV4::Value) * (-index));
- }
-
- Pointer callDataAddress(int offset = 0) const {
- return Pointer(Assembler::LocalsRegister, offset - (sizeof(QV4::CallData) + sizeof(QV4::Value) * (maxOutgoingArgumentCount - 1)));
- }
-
- Address savedRegPointer(int offset) const
- {
- Q_ASSERT(offset >= 0);
- Q_ASSERT(offset < savedRegCount);
-
- // Get the address of the bottom-most element of our frame:
- Address ptr(Assembler::FramePointerRegister, -calculateStackFrameSize());
- // This now is the element with offset 0. So:
- ptr.offset += offset * sizeof(QV4::Value);
- // and we're done!
- return ptr;
- }
-
- private:
- int normalRegistersToSave;
- int fpRegistersToSave;
-
- /// arg count for calls to JS functions
- int maxOutgoingArgumentCount;
-
- /// the number of spill slots needed by this function
- int localCount;
-
- /// used by built-ins to save arguments (e.g. constants) to the stack when they need to be
- /// passed by reference.
- int savedRegCount;
- };
-
- struct VoidType { VoidType() {} };
- static const VoidType Void;
-
- typedef JSC::FunctionPtr FunctionPtr;
+ Assembler(const Value* constantTable);
+ ~Assembler();
+
+ // codegen infrastructure
+ void generatePrologue();
+ void generateEpilogue();
+ void link(Function *function);
+ void addLabel(int offset);
+
+ // loads/stores/moves
+ void loadConst(int constIndex);
+ void copyConst(int constIndex, int destReg);
+ void loadReg(int reg);
+ void storeReg(int reg);
+ void loadLocal(int index, int level = 0);
+ void storeLocal(int index, int level = 0);
+ void loadString(int stringId);
+ void loadValue(ReturnedValue value);
+ void storeHeapObject(int reg);
+
+ // numeric ops
+ void unot();
+ void toNumber();
+ void uminus();
+ void ucompl();
+ void inc();
+ void dec();
+ void add(int lhs);
+ void bitAnd(int lhs);
+ void bitOr(int lhs);
+ void bitXor(int lhs);
+ void ushr(int lhs);
+ void shr(int lhs);
+ void shl(int lhs);
+ void bitAndConst(int rhs);
+ void bitOrConst(int rhs);
+ void bitXorConst(int rhs);
+ void ushrConst(int rhs);
+ void shrConst(int rhs);
+ void shlConst(int rhs);
+ void mul(int lhs);
+ void div(int lhs);
+ void mod(int lhs);
+ void sub(int lhs);
+
+ // comparissons
+ void cmpeqNull();
+ void cmpneNull();
+ void cmpeqInt(int lhs);
+ void cmpneInt(int lhs);
+ void cmpeq(int lhs);
+ void cmpne(int lhs);
+ void cmpgt(int lhs);
+ void cmpge(int lhs);
+ void cmplt(int lhs);
+ void cmple(int lhs);
+ void cmpStrictEqual(int lhs);
+ void cmpStrictNotEqual(int lhs);
+
+ // jumps
+ void jump(int offset);
+ void jumpTrue(int offset);
+ void jumpFalse(int offset);
+ void jumpStrictEqualStackSlotInt(int lhs, int rhs, int offset);
+ void jumpStrictNotEqualStackSlotInt(int lhs, int rhs, int offset);
+
+ // stuff for runtime calls
+ void prepareCallWithArgCount(int argc);
+ void storeInstructionPointer(int instructionOffset);
+ void passAccumulatorAsArg(int arg);
+ void passFunctionAsArg(int arg);
+ void passEngineAsArg(int arg);
+ void passRegAsArg(int reg, int arg);
+ void passCppFrameAsArg(int arg);
+ void passInt32AsArg(int value, int arg);
+ void callRuntime(const char *functionName, const void *funcPtr, Assembler::CallResultDestination dest);
+ void saveAccumulatorInFrame();
+
+ // exception/context stuff
+ void checkException();
+ void gotoCatchException();
+ void getException();
+ void setException();
+ void setExceptionHandler(int offset);
+ void clearExceptionHandler();
+ void pushCatchContext(int name, int reg);
+ void popContext(int reg);
+
+ // other stuff
+ void ret();
+
+protected:
+ void *d;
#ifndef QT_NO_DEBUG
- struct CallInfo {
- Label label;
- const char* functionName;
- };
+ enum { NoCall = -1 };
+ int remainingArgcForCall = NoCall;
#endif
- struct PointerToValue {
- PointerToValue(IR::Expr *value)
- : value(value)
- {}
- IR::Expr *value;
- };
- struct StringToIndex {
- explicit StringToIndex(const QString &string) : string(string) {}
- QString string;
- };
- struct Reference {
- Reference(IR::Expr *value) : value(value) {
- Q_ASSERT(value->asTemp() || value->asArgLocal());
- }
- IR::Expr *value;
- };
-
- void callAbsolute(const char* /*functionName*/, const LookupCall &lookupCall)
- {
- call(lookupCall.addr);
- }
+ int argcOnStackForCall = 0;
- void callAbsolute(const char *functionName, const RuntimeCall &runtimeCall)
- {
- call(runtimeCall.addr);
-#ifndef QT_NO_DEBUG
- // the code below is to get proper function names in the disassembly
- CallInfo info;
- info.functionName = functionName;
- info.label = label();
- _callInfos.append(info);
-#else
- Q_UNUSED(functionName)
-#endif
- }
-
- void registerBlock(IR::BasicBlock*, IR::BasicBlock *nextBlock);
- IR::BasicBlock *nextBlock() const { return _nextBlock; }
- void jumpToBlock(IR::BasicBlock* current, IR::BasicBlock *target);
- void addPatch(IR::BasicBlock* targetBlock, Jump targetJump);
- void addPatch(DataLabelPtr patch, Label target);
- void addPatch(DataLabelPtr patch, IR::BasicBlock *target);
- void generateCJumpOnNonZero(RegisterID reg, IR::BasicBlock *currentBlock,
- IR::BasicBlock *trueBlock, IR::BasicBlock *falseBlock);
- void generateCJumpOnCompare(RelationalCondition cond, RegisterID left, TrustedImm32 right,
- IR::BasicBlock *currentBlock, IR::BasicBlock *trueBlock,
- IR::BasicBlock *falseBlock);
- void generateCJumpOnCompare(RelationalCondition cond, RegisterID left, RegisterID right,
- IR::BasicBlock *currentBlock, IR::BasicBlock *trueBlock,
- IR::BasicBlock *falseBlock);
- void generateCJumpOnUndefined(RelationalCondition cond, IR::Expr *right,
- RegisterID scratchRegister, RegisterID tagRegister,
- IR::BasicBlock *currentBlock, IR::BasicBlock *trueBlock,
- IR::BasicBlock *falseBlock)
- {
- RegisterSizeDependentOps::generateCJumpOnUndefined(this, cond, right, scratchRegister, tagRegister,
- _nextBlock, currentBlock, trueBlock, falseBlock);
- }
-
- Jump generateIsDoubleCheck(RegisterID tagOrValueRegister)
- {
- return RegisterSizeDependentOps::generateIsDoubleCheck(this, tagOrValueRegister);
- }
-
- Jump genTryDoubleConversion(IR::Expr *src, FPRegisterID dest);
- Jump branchDouble(bool invertCondition, IR::AluOp op, IR::Expr *left, IR::Expr *right);
- Jump branchInt32(bool invertCondition, IR::AluOp op, IR::Expr *left, IR::Expr *right);
-
- Pointer loadAddress(RegisterID tmp, IR::Expr *t);
- Pointer loadTempAddress(IR::Temp *t);
- Pointer loadArgLocalAddress(RegisterID baseReg, IR::ArgLocal *al);
- Pointer loadStringAddress(RegisterID reg, const QString &string);
- Address loadConstant(IR::Const *c, RegisterID baseReg);
- Address loadConstant(const TargetPrimitive &v, RegisterID baseReg);
- void loadStringRef(RegisterID reg, const QString &string);
- Pointer stackSlotPointer(IR::Temp *t) const
- {
- Q_ASSERT(t->kind == IR::Temp::StackSlot);
-
- return Pointer(_stackLayout->stackSlotPointer(t->index));
- }
-
- template <int argumentNumber>
- void saveOutRegister(PointerToValue arg)
- {
- if (!arg.value)
- return;
- if (IR::Temp *t = arg.value->asTemp()) {
- if (t->kind == IR::Temp::PhysicalRegister) {
- Pointer addr(_stackLayout->savedRegPointer(argumentNumber));
- switch (t->type) {
- case IR::BoolType:
- storeBool((RegisterID) t->index, addr);
- break;
- case IR::SInt32Type:
- storeInt32((RegisterID) t->index, addr);
- break;
- case IR::UInt32Type:
- storeUInt32((RegisterID) t->index, addr);
- break;
- case IR::DoubleType:
- storeDouble((FPRegisterID) t->index, addr);
- break;
- default:
- Q_UNIMPLEMENTED();
- }
- }
- }
- }
-
- template <int, typename ArgType>
- void saveOutRegister(ArgType)
- {}
-
- void loadArgumentInRegister(RegisterID source, RegisterID dest, int argumentNumber)
- {
- Q_UNUSED(argumentNumber);
-
- move(source, dest);
- }
-
- void loadArgumentInRegister(const Pointer& ptr, RegisterID dest, int argumentNumber)
- {
- Q_UNUSED(argumentNumber);
- addPtr(TrustedImm32(ptr.offset), ptr.base, dest);
- }
-
- void loadArgumentInRegister(PointerToValue temp, RegisterID dest, int argumentNumber)
- {
- if (!temp.value) {
- RegisterSizeDependentOps::zeroRegister(this, dest);
- } else {
- Pointer addr = toAddress(dest, temp.value, argumentNumber);
- loadArgumentInRegister(addr, dest, argumentNumber);
- }
- }
- void loadArgumentInRegister(StringToIndex temp, RegisterID dest, int argumentNumber)
- {
- Q_UNUSED(argumentNumber);
- loadStringRef(dest, temp.string);
- }
-
- void loadArgumentInRegister(Reference temp, RegisterID dest, int argumentNumber)
- {
- Q_ASSERT(temp.value);
- Pointer addr = loadAddress(dest, temp.value);
- loadArgumentInRegister(addr, dest, argumentNumber);
- }
-
- void loadArgumentInRegister(IR::Temp* temp, RegisterID dest, int argumentNumber)
- {
- RegisterSizeDependentOps::loadArgumentInRegister(this, temp, dest, argumentNumber);
- }
-
- void loadArgumentInRegister(IR::ArgLocal* al, RegisterID dest, int argumentNumber)
- {
- RegisterSizeDependentOps::loadArgumentInRegister(this, al, dest, argumentNumber);
- }
-
- void loadArgumentInRegister(IR::Const* c, RegisterID dest, int argumentNumber)
- {
- RegisterSizeDependentOps::loadArgumentInRegister(this, c, dest, argumentNumber);
- }
-
- void loadArgumentInRegister(IR::Expr* expr, RegisterID dest, int argumentNumber)
- {
- RegisterSizeDependentOps::loadArgumentInRegister(this, expr, dest, argumentNumber);
- }
-
- void loadArgumentInRegister(TrustedImm32 imm32, RegisterID dest, int argumentNumber)
- {
- Q_UNUSED(argumentNumber);
-
- RegisterSizeDependentOps::zeroRegister(this, dest);
- if (imm32.m_value)
- move(imm32, dest);
- }
-
- void storeReturnValue(RegisterID dest)
- {
- move(ReturnValueRegister, dest);
- }
-
- void storeUInt32ReturnValue(RegisterID dest)
- {
- subPtr(TrustedImm32(sizeof(QV4::Value)), StackPointerRegister);
- Pointer tmp(StackPointerRegister, 0);
- storeReturnValue(tmp);
- toUInt32Register(tmp, dest);
- addPtr(TrustedImm32(sizeof(QV4::Value)), StackPointerRegister);
- }
-
- void storeReturnValue(FPRegisterID dest)
- {
- RegisterSizeDependentOps::storeReturnValue(this, dest);
- }
-
- void storeReturnValue(const Pointer &dest)
- {
- RegisterSizeDependentOps::storeReturnValue(this, dest);
- }
-
- void storeReturnValue(IR::Expr *target)
- {
- if (!target)
- return;
-
- if (IR::Temp *temp = target->asTemp()) {
- if (temp->kind == IR::Temp::PhysicalRegister) {
- if (temp->type == IR::DoubleType)
- storeReturnValue((FPRegisterID) temp->index);
- else if (temp->type == IR::UInt32Type)
- storeUInt32ReturnValue((RegisterID) temp->index);
- else
- storeReturnValue((RegisterID) temp->index);
- return;
- } else {
- Pointer addr = loadTempAddress(temp);
- storeReturnValue(addr);
- }
- } else if (IR::ArgLocal *al = target->asArgLocal()) {
- Pointer addr = loadArgLocalAddress(ScratchRegister, al);
- storeReturnValue(addr);
- }
- }
-
- void storeReturnValue(VoidType)
- {
- }
-
- template <int StackSlot>
- void loadArgumentOnStack(RegisterID reg, int argumentNumber)
- {
- Q_UNUSED(argumentNumber);
-
- poke(reg, StackSlot);
- }
-
- template <int StackSlot>
- void loadArgumentOnStack(TrustedImm32 value, int argumentNumber)
- {
- Q_UNUSED(argumentNumber);
-
- poke(value, StackSlot);
- }
-
- template <int StackSlot>
- void loadArgumentOnStack(const Pointer& ptr, int argumentNumber)
- {
- Q_UNUSED(argumentNumber);
-
- addPtr(TrustedImm32(ptr.offset), ptr.base, ScratchRegister);
- poke(ScratchRegister, StackSlot);
- }
-
- template <int StackSlot>
- void loadArgumentOnStack(PointerToValue temp, int argumentNumber)
- {
- if (temp.value) {
- Pointer ptr = toAddress(ScratchRegister, temp.value, argumentNumber);
- loadArgumentOnStack<StackSlot>(ptr, argumentNumber);
- } else {
- RegisterSizeDependentOps::zeroStackSlot(this, StackSlot);
- }
- }
-
- template <int StackSlot>
- void loadArgumentOnStack(StringToIndex temp, int argumentNumber)
- {
- Q_UNUSED(argumentNumber);
- loadStringRef(ScratchRegister, temp.string);
- poke(ScratchRegister, StackSlot);
- }
-
- template <int StackSlot>
- void loadArgumentOnStack(Reference temp, int argumentNumber)
- {
- Q_ASSERT (temp.value);
-
- Pointer ptr = loadAddress(ScratchRegister, temp.value);
- loadArgumentOnStack<StackSlot>(ptr, argumentNumber);
- }
-
- void loadDouble(IR::Expr *source, FPRegisterID dest)
- {
- IR::Temp *sourceTemp = source->asTemp();
- if (sourceTemp && sourceTemp->kind == IR::Temp::PhysicalRegister) {
- moveDouble((FPRegisterID) sourceTemp->index, dest);
- return;
- }
- Pointer ptr = loadAddress(ScratchRegister, source);
- loadDouble(ptr, dest);
- }
-
- void storeDouble(FPRegisterID source, IR::Expr* target)
- {
- IR::Temp *targetTemp = target->asTemp();
- if (targetTemp && targetTemp->kind == IR::Temp::PhysicalRegister) {
- moveDouble(source, (FPRegisterID) targetTemp->index);
- return;
- }
- RegisterSizeDependentOps::storeDouble(this, source, target);
- }
-
- void loadDouble(Address addr, FPRegisterID dest)
- {
- RegisterSizeDependentOps::loadDouble(this, addr, dest);
- }
-
- void storeDouble(FPRegisterID source, Address addr)
- {
- RegisterSizeDependentOps::storeDouble(this, source, addr);
- }
-
- template <typename Result, typename Source>
- void copyValue(Result result, Source source);
- template <typename Result>
- void copyValue(Result result, IR::Expr* source);
-
- // The scratch register is used to calculate the temp address for the source.
- void memcopyValue(Pointer target, IR::Expr *source, RegisterID scratchRegister)
- {
- Q_ASSERT(!source->asTemp() || source->asTemp()->kind != IR::Temp::PhysicalRegister);
- Q_ASSERT(target.base != scratchRegister);
- TargetConfiguration::MacroAssembler::loadDouble(loadAddress(scratchRegister, source), FPGpr0);
- TargetConfiguration::MacroAssembler::storeDouble(FPGpr0, target);
- }
-
- // The scratch register is used to calculate the temp address for the source.
- void memcopyValue(IR::Expr *target, Pointer source, FPRegisterID fpScratchRegister, RegisterID scratchRegister)
- {
- TargetConfiguration::MacroAssembler::loadDouble(source, fpScratchRegister);
- TargetConfiguration::MacroAssembler::storeDouble(fpScratchRegister, loadAddress(scratchRegister, target));
- }
-
- void storeValue(TargetPrimitive value, Address destination)
- {
- RegisterSizeDependentOps::storeValue(this, value, destination);
- }
-
- void storeValue(TargetPrimitive value, IR::Expr* temp);
-
- void enterStandardStackFrame(const RegisterInformation &regularRegistersToSave,
- const RegisterInformation &fpRegistersToSave);
- void leaveStandardStackFrame(const RegisterInformation &regularRegistersToSave,
- const RegisterInformation &fpRegistersToSave);
-
- void checkException() {
- load32(Address(EngineRegister, targetStructureOffset(offsetof(QV4::EngineBase, hasException))), ScratchRegister);
- Jump exceptionThrown = branch32(RelationalCondition::NotEqual, ScratchRegister, TrustedImm32(0));
- if (catchBlock)
- addPatch(catchBlock, exceptionThrown);
- else
- exceptionPropagationJumps.append(exceptionThrown);
- }
- void jumpToExceptionHandler() {
- Jump exceptionThrown = jump();
- if (catchBlock)
- addPatch(catchBlock, exceptionThrown);
- else
- exceptionPropagationJumps.append(exceptionThrown);
- }
-
- template <int argumentNumber, typename T>
- void loadArgumentOnStackOrRegister(const T &value)
- {
- if (argumentNumber < RegisterArgumentCount)
- loadArgumentInRegister(value, registerForArgument(argumentNumber), argumentNumber);
- else
- loadArgumentOnStack<argumentNumber - RegisterArgumentCount + (StackShadowSpace / RegisterSize)>(value, argumentNumber);
- }
-
- template <int argumentNumber>
- void loadArgumentOnStackOrRegister(const VoidType &value)
- {
- Q_UNUSED(value);
- }
-
- template <bool selectFirst, int First, int Second>
- struct Select
- {
- enum { Chosen = First };
- };
-
- template <int First, int Second>
- struct Select<false, First, Second>
- {
- enum { Chosen = Second };
- };
-
- template <int ArgumentIndex, typename Parameter>
- struct SizeOnStack
- {
- enum { Size = Select<ArgumentIndex >= RegisterArgumentCount, RegisterSize, 0>::Chosen };
- };
-
- template <int ArgumentIndex>
- struct SizeOnStack<ArgumentIndex, VoidType>
- {
- enum { Size = 0 };
- };
-
- template <typename T> bool prepareCall(T &)
- { return true; }
-
- bool prepareCall(LookupCall &lookupCall)
- {
- // IMPORTANT! See generateLookupCall in qv4isel_masm_p.h for details!
-
- // load the table from the context
- loadPtr(Address(EngineRegister, targetStructureOffset(offsetof(QV4::EngineBase, current))), ScratchRegister);
- loadPtr(Address(ScratchRegister, targetStructureOffset(Heap::ExecutionContext::baseOffset + offsetof(Heap::ExecutionContextData, lookups))),
- lookupCall.addr.base);
- // pre-calculate the indirect address for the lookupCall table:
- if (lookupCall.addr.offset)
- addPtr(TrustedImm32(lookupCall.addr.offset), lookupCall.addr.base);
- // store it as the first argument
- loadArgumentOnStackOrRegister<0>(lookupCall.addr.base);
- // set the destination addresses offset to the getterSetterOffset. The base is the lookupCall table's address
- lookupCall.addr.offset = lookupCall.getterSetterOffset;
- return false;
- }
-
- template <typename ArgRet, typename Callable, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6>
- void generateFunctionCallImp(bool needsExceptionCheck, ArgRet r, const char* functionName, Callable function, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6)
- {
- int stackSpaceNeeded = SizeOnStack<0, Arg1>::Size
- + SizeOnStack<1, Arg2>::Size
- + SizeOnStack<2, Arg3>::Size
- + SizeOnStack<3, Arg4>::Size
- + SizeOnStack<4, Arg5>::Size
- + SizeOnStack<5, Arg6>::Size
- + StackShadowSpace;
-
- if (stackSpaceNeeded) {
- Q_ASSERT(stackSpaceNeeded < (INT_MAX - StackAlignment));
- stackSpaceNeeded = static_cast<int>(WTF::roundUpToMultipleOf(StackAlignment, stackSpaceNeeded));
- subPtr(TrustedImm32(stackSpaceNeeded), StackPointerRegister);
- }
-
- // First save any arguments that reside in registers, because they could be overwritten
- // if that register is also used to pass arguments.
- saveOutRegister<5>(arg6);
- saveOutRegister<4>(arg5);
- saveOutRegister<3>(arg4);
- saveOutRegister<2>(arg3);
- saveOutRegister<1>(arg2);
- saveOutRegister<0>(arg1);
-
- loadArgumentOnStackOrRegister<5>(arg6);
- loadArgumentOnStackOrRegister<4>(arg5);
- loadArgumentOnStackOrRegister<3>(arg4);
- loadArgumentOnStackOrRegister<2>(arg3);
- loadArgumentOnStackOrRegister<1>(arg2);
-
- if (prepareCall(function))
- loadArgumentOnStackOrRegister<0>(arg1);
-
- if (JITTargetPlatform::gotRegister != -1)
- load32(Address(JITTargetPlatform::FramePointerRegister, JITTargetPlatform::savedGOTRegisterSlotOnStack()), static_cast<RegisterID>(JITTargetPlatform::gotRegister)); // restore the GOT ptr
-
- callAbsolute(functionName, function);
-
- if (stackSpaceNeeded)
- addPtr(TrustedImm32(stackSpaceNeeded), StackPointerRegister);
-
- if (needsExceptionCheck) {
- checkException();
- }
-
- storeReturnValue(r);
-
- }
-
- template <typename ArgRet, typename Callable, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
- void generateFunctionCallImp(bool needsExceptionCheck, ArgRet r, const char* functionName, Callable function, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5)
- {
- generateFunctionCallImp(needsExceptionCheck, r, functionName, function, arg1, arg2, arg3, arg4, arg5, VoidType());
- }
-
- template <typename ArgRet, typename Callable, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
- void generateFunctionCallImp(bool needsExceptionCheck, ArgRet r, const char* functionName, Callable function, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4)
- {
- generateFunctionCallImp(needsExceptionCheck, r, functionName, function, arg1, arg2, arg3, arg4, VoidType(), VoidType());
- }
-
- template <typename ArgRet, typename Callable, typename Arg1, typename Arg2, typename Arg3>
- void generateFunctionCallImp(bool needsExceptionCheck, ArgRet r, const char* functionName, Callable function, Arg1 arg1, Arg2 arg2, Arg3 arg3)
- {
- generateFunctionCallImp(needsExceptionCheck, r, functionName, function, arg1, arg2, arg3, VoidType(), VoidType(), VoidType());
- }
-
- template <typename ArgRet, typename Callable, typename Arg1, typename Arg2>
- void generateFunctionCallImp(bool needsExceptionCheck, ArgRet r, const char* functionName, Callable function, Arg1 arg1, Arg2 arg2)
- {
- generateFunctionCallImp(needsExceptionCheck, r, functionName, function, arg1, arg2, VoidType(), VoidType(), VoidType(), VoidType());
- }
-
- template <typename ArgRet, typename Callable, typename Arg1>
- void generateFunctionCallImp(bool needsExceptionCheck, ArgRet r, const char* functionName, Callable function, Arg1 arg1)
- {
- generateFunctionCallImp(needsExceptionCheck, r, functionName, function, arg1, VoidType(), VoidType(), VoidType(), VoidType(), VoidType());
- }
-
- Pointer toAddress(RegisterID tmpReg, IR::Expr *e, int offset)
- {
- if (IR::Const *c = e->asConst()) {
- Address addr = _stackLayout->savedRegPointer(offset);
- Address tagAddr = addr;
- tagAddr.offset += 4;
-
- auto v = convertToValue<TargetPrimitive>(c);
- store32(TrustedImm32(v.value()), addr);
- store32(TrustedImm32(v.tag()), tagAddr);
- return Pointer(addr);
- }
-
- if (IR::Temp *t = e->asTemp())
- if (t->kind == IR::Temp::PhysicalRegister)
- return Pointer(_stackLayout->savedRegPointer(offset));
-
- return loadAddress(tmpReg, e);
- }
-
- void storeBool(RegisterID reg, Pointer addr)
- {
- store32(reg, addr);
- addr.offset += 4;
- store32(TrustedImm32(TargetPrimitive::fromBoolean(0).tag()), addr);
- }
-
- void storeBool(RegisterID src, RegisterID dest)
- {
- move(src, dest);
- }
-
- void storeBool(RegisterID reg, IR::Expr *target)
- {
- if (IR::Temp *targetTemp = target->asTemp()) {
- if (targetTemp->kind == IR::Temp::PhysicalRegister) {
- move(reg, (RegisterID) targetTemp->index);
- return;
- }
- }
-
- Pointer addr = loadAddress(ScratchRegister, target);
- storeBool(reg, addr);
- }
-
- void storeBool(bool value, IR::Expr *target) {
- TrustedImm32 trustedValue(value ? 1 : 0);
-
- if (IR::Temp *targetTemp = target->asTemp()) {
- if (targetTemp->kind == IR::Temp::PhysicalRegister) {
- move(trustedValue, (RegisterID) targetTemp->index);
- return;
- }
- }
-
- move(trustedValue, ScratchRegister);
- storeBool(ScratchRegister, target);
- }
-
- void storeInt32(RegisterID src, RegisterID dest)
- {
- move(src, dest);
- }
-
- void storeInt32(RegisterID reg, Pointer addr)
- {
- store32(reg, addr);
- addr.offset += 4;
- store32(TrustedImm32(TargetPrimitive::fromInt32(0).tag()), addr);
- }
-
- void storeInt32(RegisterID reg, IR::Expr *target)
- {
- if (IR::Temp *targetTemp = target->asTemp()) {
- if (targetTemp->kind == IR::Temp::PhysicalRegister) {
- move(reg, (RegisterID) targetTemp->index);
- } else {
- Pointer addr = loadTempAddress(targetTemp);
- storeInt32(reg, addr);
- }
- } else if (IR::ArgLocal *al = target->asArgLocal()) {
- Pointer addr = loadArgLocalAddress(ScratchRegister, al);
- storeInt32(reg, addr);
- }
- }
-
- void storeUInt32(RegisterID src, RegisterID dest)
- {
- move(src, dest);
- }
-
- void storeUInt32(RegisterID reg, Pointer addr)
- {
- // The UInt32 representation in QV4::Value is really convoluted. See also toUInt32Register.
- Jump intRange = branch32(RelationalCondition::GreaterThanOrEqual, reg, TrustedImm32(0));
- convertUInt32ToDouble(reg, FPGpr0, ReturnValueRegister);
- storeDouble(FPGpr0, addr);
- Jump done = jump();
- intRange.link(this);
- storeInt32(reg, addr);
- done.link(this);
- }
-
- void storeUInt32(RegisterID reg, IR::Expr *target)
- {
- IR::Temp *targetTemp = target->asTemp();
- if (targetTemp && targetTemp->kind == IR::Temp::PhysicalRegister) {
- move(reg, (RegisterID) targetTemp->index);
- } else {
- Pointer addr = loadAddress(ScratchRegister, target);
- storeUInt32(reg, addr);
- }
- }
-
- FPRegisterID toDoubleRegister(IR::Expr *e, FPRegisterID target = FPGpr0)
- {
- if (IR::Const *c = e->asConst()) {
- RegisterSizeDependentOps::loadDoubleConstant(this, c, target);
- return target;
- }
-
- if (IR::Temp *t = e->asTemp())
- if (t->kind == IR::Temp::PhysicalRegister)
- return (FPRegisterID) t->index;
-
- loadDouble(e, target);
- return target;
- }
-
- RegisterID toBoolRegister(IR::Expr *e, RegisterID scratchReg)
- {
- return toInt32Register(e, scratchReg);
- }
-
- RegisterID toInt32Register(IR::Expr *e, RegisterID scratchReg)
- {
- if (IR::Const *c = e->asConst()) {
- move(TrustedImm32(convertToValue<Primitive>(c).int_32()), scratchReg);
- return scratchReg;
- }
-
- if (IR::Temp *t = e->asTemp())
- if (t->kind == IR::Temp::PhysicalRegister)
- return (RegisterID) t->index;
-
- return toInt32Register(loadAddress(scratchReg, e), scratchReg);
- }
-
- RegisterID toInt32Register(Pointer addr, RegisterID scratchReg)
- {
- load32(addr, scratchReg);
- return scratchReg;
- }
-
- RegisterID toUInt32Register(IR::Expr *e, RegisterID scratchReg)
- {
- if (IR::Const *c = e->asConst()) {
- move(TrustedImm32(unsigned(c->value)), scratchReg);
- return scratchReg;
- }
-
- if (IR::Temp *t = e->asTemp())
- if (t->kind == IR::Temp::PhysicalRegister)
- return (RegisterID) t->index;
-
- return toUInt32Register(loadAddress(scratchReg, e), scratchReg);
- }
-
- RegisterID toUInt32Register(Pointer addr, RegisterID scratchReg)
- {
- Q_ASSERT(addr.base != scratchReg);
-
- // The UInt32 representation in QV4::Value is really convoluted. See also storeUInt32.
- Pointer tagAddr = addr;
- tagAddr.offset += 4;
- load32(tagAddr, scratchReg);
- Jump inIntRange = branch32(RelationalCondition::Equal, scratchReg, TrustedImm32(quint32(ValueTypeInternal::Integer)));
-
- // it's not in signed int range, so load it as a double, and truncate it down
- loadDouble(addr, FPGpr0);
- Address inversionAddress = loadConstant(TargetPrimitive::fromDouble(double(INT_MAX) + 1), scratchReg);
- subDouble(inversionAddress, FPGpr0);
- Jump canNeverHappen = branchTruncateDoubleToUint32(FPGpr0, scratchReg);
- canNeverHappen.link(this);
- or32(TrustedImm32(1 << 31), scratchReg);
- Jump done = jump();
-
- inIntRange.link(this);
- load32(addr, scratchReg);
-
- done.link(this);
- return scratchReg;
- }
-
- void returnFromFunction(IR::Ret *s, RegisterInformation regularRegistersToSave, RegisterInformation fpRegistersToSave);
-
- JSC::MacroAssemblerCodeRef link(int *codeSize);
-
- void setStackLayout(int maxArgCountForBuiltins, int regularRegistersToSave, int fpRegistersToSave);
- const StackLayout &stackLayout() const { return *_stackLayout.data(); }
- void initializeLocalVariables()
- {
- const int locals = _stackLayout->calculateJSStackFrameSize();
- if (locals <= 0)
- return;
- loadPtr(Address(JITTargetPlatform::EngineRegister, targetStructureOffset(offsetof(EngineBase, jsStackTop))), JITTargetPlatform::LocalsRegister);
- RegisterSizeDependentOps::initializeLocalVariables(this, locals);
- storePtr(JITTargetPlatform::LocalsRegister, Address(JITTargetPlatform::EngineRegister, targetStructureOffset(offsetof(EngineBase, jsStackTop))));
- }
-
- Label exceptionReturnLabel;
- IR::BasicBlock * catchBlock;
- QVector<Jump> exceptionPropagationJumps;
private:
- QScopedPointer<const StackLayout> _stackLayout;
- IR::Function *_function;
- std::vector<Label> _addrs;
- std::vector<std::vector<Jump>> _patches;
-#ifndef QT_NO_DEBUG
- QVector<CallInfo> _callInfos;
-#endif
-
- struct DataLabelPatch {
- DataLabelPtr dataLabel;
- Label target;
- };
- std::vector<DataLabelPatch> _dataLabelPatches;
-
- std::vector<std::vector<DataLabelPtr>> _labelPatches;
- IR::BasicBlock *_nextBlock;
-
- QV4::ExecutableAllocator *_executableAllocator;
- QV4::Compiler::JSUnitGenerator *_jsGenerator;
+ typedef unsigned(*CmpFunc)(const Value&,const Value&);
+ void cmp(int cond, CmpFunc function, const char *functionName, int lhs);
+ void passAccumulatorAsArg_internal(int arg, bool push);
};
-template <typename TargetConfiguration>
-const typename Assembler<TargetConfiguration>::VoidType Assembler<TargetConfiguration>::Void;
-
-template <typename TargetConfiguration>
-template <typename Result, typename Source>
-void Assembler<TargetConfiguration>::copyValue(Result result, Source source)
-{
- RegisterSizeDependentOps::copyValueViaRegisters(this, source, result);
-}
-
-template <typename TargetConfiguration>
-template <typename Result>
-void Assembler<TargetConfiguration>::copyValue(Result result, IR::Expr* source)
-{
- if (source->type == IR::BoolType) {
- RegisterID reg = toInt32Register(source, ScratchRegister);
- storeBool(reg, result);
- } else if (source->type == IR::SInt32Type) {
- RegisterID reg = toInt32Register(source, ScratchRegister);
- storeInt32(reg, result);
- } else if (source->type == IR::UInt32Type) {
- RegisterID reg = toUInt32Register(source, ScratchRegister);
- storeUInt32(reg, result);
- } else if (source->type == IR::DoubleType) {
- storeDouble(toDoubleRegister(source), result);
- } else if (source->asTemp() || source->asArgLocal()) {
- RegisterSizeDependentOps::copyValueViaRegisters(this, source, result);
- } else if (IR::Const *c = source->asConst()) {
- auto v = convertToValue<TargetPrimitive>(c);
- storeValue(v, result);
- } else {
- Q_UNREACHABLE();
- }
-}
-
-template <typename TargetConfiguration>
-inline Assembler<TargetConfiguration>::RuntimeCall::RuntimeCall(Runtime::RuntimeMethods method)
- : addr(Assembler::EngineRegister,
- method == Runtime::InvalidRuntimeMethod ? -1 : (Assembler<TargetConfiguration>::targetStructureOffset(offsetof(EngineBase, runtime) + Runtime::runtimeMethodOffset(method))))
-{
-}
-
-} // end of namespace JIT
-} // end of namespace QV4
+} // namespace JIT
+} // namespace QV4
QT_END_NAMESPACE
-#endif // ENABLE(ASSEMBLER)
-
-#endif // QV4ISEL_MASM_P_H
+#endif // QV4ASSEMBLER_P_H
diff --git a/src/qml/jit/qv4binop.cpp b/src/qml/jit/qv4binop.cpp
deleted file mode 100644
index feb30ee298..0000000000
--- a/src/qml/jit/qv4binop.cpp
+++ /dev/null
@@ -1,665 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include <qv4binop_p.h>
-#include <qv4assembler_p.h>
-
-#if ENABLE(ASSEMBLER)
-
-QT_BEGIN_NAMESPACE
-
-namespace QV4 {
-namespace JIT {
-
-template <typename JITAssembler>
-struct ArchitectureSpecificBinaryOperation
-{
- using FPRegisterID = typename JITAssembler::FPRegisterID;
-
- static bool doubleAdd(JITAssembler *as, IR::Expr *lhs, IR::Expr *rhs, FPRegisterID targetReg)
- {
- Q_UNUSED(as);
- Q_UNUSED(lhs);
- Q_UNUSED(rhs);
- Q_UNUSED(targetReg);
- return false;
- }
- static bool doubleMul(JITAssembler *as, IR::Expr *lhs, IR::Expr *rhs, FPRegisterID targetReg)
- {
- Q_UNUSED(as);
- Q_UNUSED(lhs);
- Q_UNUSED(rhs);
- Q_UNUSED(targetReg);
- return false;
- }
- static bool doubleSub(JITAssembler *as, IR::Expr *lhs, IR::Expr *rhs, FPRegisterID targetReg)
- {
- Q_UNUSED(as);
- Q_UNUSED(lhs);
- Q_UNUSED(rhs);
- Q_UNUSED(targetReg);
- return false;
- }
- static bool doubleDiv(JITAssembler *as, IR::Expr *lhs, IR::Expr *rhs, FPRegisterID targetReg)
- {
- Q_UNUSED(as);
- Q_UNUSED(lhs);
- Q_UNUSED(rhs);
- Q_UNUSED(targetReg);
- return false;
- }
-};
-
-#if CPU(X86)
-template <>
-struct ArchitectureSpecificBinaryOperation<Assembler<AssemblerTargetConfiguration<JSC::MacroAssemblerX86, NoOperatingSystemSpecialization>>>
-{
- using JITAssembler = Assembler<AssemblerTargetConfiguration<JSC::MacroAssemblerX86, NoOperatingSystemSpecialization>>;
- using FPRegisterID = JITAssembler::FPRegisterID;
- using Address = JITAssembler::Address;
-
- static bool doubleAdd(JITAssembler *as, IR::Expr *lhs, IR::Expr *rhs, FPRegisterID targetReg)
- {
- if (IR::Const *c = rhs->asConst()) { // Y = X + constant -> Y = X; Y += [constant-address]
- as->moveDouble(as->toDoubleRegister(lhs, targetReg), targetReg);
- Address addr = as->loadConstant(c, JITAssembler::ScratchRegister);
- as->addDouble(addr, targetReg);
- return true;
- }
- if (IR::Temp *t = rhs->asTemp()) { // Y = X + [temp-memory-address] -> Y = X; Y += [temp-memory-address]
- if (t->kind != IR::Temp::PhysicalRegister) {
- as->moveDouble(as->toDoubleRegister(lhs, targetReg), targetReg);
- as->addDouble(as->loadTempAddress(t), targetReg);
- return true;
- }
- }
- return false;
- }
- static bool doubleMul(JITAssembler *as, IR::Expr *lhs, IR::Expr *rhs, FPRegisterID targetReg)
- {
- if (IR::Const *c = rhs->asConst()) { // Y = X * constant -> Y = X; Y *= [constant-address]
- as->moveDouble(as->toDoubleRegister(lhs, targetReg), targetReg);
- Address addr = as->loadConstant(c, JITAssembler::ScratchRegister);
- as->mulDouble(addr, targetReg);
- return true;
- }
- if (IR::Temp *t = rhs->asTemp()) { // Y = X * [temp-memory-address] -> Y = X; Y *= [temp-memory-address]
- if (t->kind != IR::Temp::PhysicalRegister) {
- as->moveDouble(as->toDoubleRegister(lhs, targetReg), targetReg);
- as->mulDouble(as->loadTempAddress(t), targetReg);
- return true;
- }
- }
- return false;
- }
- static bool doubleSub(JITAssembler *as, IR::Expr *lhs, IR::Expr *rhs, FPRegisterID targetReg)
- {
- if (IR::Const *c = rhs->asConst()) { // Y = X - constant -> Y = X; Y -= [constant-address]
- as->moveDouble(as->toDoubleRegister(lhs, targetReg), targetReg);
- Address addr = as->loadConstant(c, JITAssembler::ScratchRegister);
- as->subDouble(addr, targetReg);
- return true;
- }
- if (IR::Temp *t = rhs->asTemp()) { // Y = X - [temp-memory-address] -> Y = X; Y -= [temp-memory-address]
- if (t->kind != IR::Temp::PhysicalRegister) {
- as->moveDouble(as->toDoubleRegister(lhs, targetReg), targetReg);
- as->subDouble(as->loadTempAddress(t), targetReg);
- return true;
- }
- }
- return false;
- }
- static bool doubleDiv(JITAssembler *as, IR::Expr *lhs, IR::Expr *rhs, FPRegisterID targetReg)
- {
- if (IR::Const *c = rhs->asConst()) { // Y = X / constant -> Y = X; Y /= [constant-address]
- as->moveDouble(as->toDoubleRegister(lhs, targetReg), targetReg);
- Address addr = as->loadConstant(c, JITAssembler::ScratchRegister);
- as->divDouble(addr, targetReg);
- return true;
- }
- if (IR::Temp *t = rhs->asTemp()) { // Y = X / [temp-memory-address] -> Y = X; Y /= [temp-memory-address]
- if (t->kind != IR::Temp::PhysicalRegister) {
- as->moveDouble(as->toDoubleRegister(lhs, targetReg), targetReg);
- as->divDouble(as->loadTempAddress(t), targetReg);
- return true;
- }
- }
- return false;
- }
-};
-#endif
-
-#define OP(op) \
- { "Runtime::" isel_stringIfy(op), QV4::Runtime::op, QV4::Runtime::InvalidRuntimeMethod, 0, 0, QV4::Runtime::Method_##op##_NeedsExceptionCheck }
-#define OPCONTEXT(op) \
- { "Runtime::" isel_stringIfy(op), QV4::Runtime::InvalidRuntimeMethod, QV4::Runtime::op, 0, 0, QV4::Runtime::Method_##op##_NeedsExceptionCheck }
-
-#define INLINE_OP(op, memOp, immOp) \
- { "Runtime::" isel_stringIfy(op), QV4::Runtime::op, QV4::Runtime::InvalidRuntimeMethod, memOp, immOp, QV4::Runtime::Method_##op##_NeedsExceptionCheck }
-#define INLINE_OPCONTEXT(op, memOp, immOp) \
- { "Runtime::" isel_stringIfy(op), QV4::Runtime::InvalidRuntimeMethod, QV4::Runtime::op, memOp, immOp, QV4::Runtime::Method_##op##_NeedsExceptionCheck }
-
-#define NULL_OP \
- { 0, QV4::Runtime::InvalidRuntimeMethod, QV4::Runtime::InvalidRuntimeMethod, 0, 0, false }
-
-template <typename JITAssembler>
-const typename Binop<JITAssembler>::OpInfo Binop<JITAssembler>::operations[IR::LastAluOp + 1] = {
- NULL_OP, // OpInvalid
- NULL_OP, // OpIfTrue
- NULL_OP, // OpNot
- NULL_OP, // OpUMinus
- NULL_OP, // OpUPlus
- NULL_OP, // OpCompl
- NULL_OP, // OpIncrement
- NULL_OP, // OpDecrement
-
- INLINE_OP(bitAnd, &Binop<JITAssembler>::inline_and32, &Binop<JITAssembler>::inline_and32), // OpBitAnd
- INLINE_OP(bitOr, &Binop<JITAssembler>::inline_or32, &Binop<JITAssembler>::inline_or32), // OpBitOr
- INLINE_OP(bitXor, &Binop<JITAssembler>::inline_xor32, &Binop<JITAssembler>::inline_xor32), // OpBitXor
-
- INLINE_OPCONTEXT(add, &Binop<JITAssembler>::inline_add32, &Binop<JITAssembler>::inline_add32), // OpAdd
- INLINE_OP(sub, &Binop<JITAssembler>::inline_sub32, &Binop<JITAssembler>::inline_sub32), // OpSub
- INLINE_OP(mul, &Binop<JITAssembler>::inline_mul32, &Binop<JITAssembler>::inline_mul32), // OpMul
-
- OP(div), // OpDiv
- OP(mod), // OpMod
-
- INLINE_OP(shl, &Binop<JITAssembler>::inline_shl32, &Binop<JITAssembler>::inline_shl32), // OpLShift
- INLINE_OP(shr, &Binop<JITAssembler>::inline_shr32, &Binop<JITAssembler>::inline_shr32), // OpRShift
- INLINE_OP(ushr, &Binop<JITAssembler>::inline_ushr32, &Binop<JITAssembler>::inline_ushr32), // OpURShift
-
- OP(greaterThan), // OpGt
- OP(lessThan), // OpLt
- OP(greaterEqual), // OpGe
- OP(lessEqual), // OpLe
- OP(equal), // OpEqual
- OP(notEqual), // OpNotEqual
- OP(strictEqual), // OpStrictEqual
- OP(strictNotEqual), // OpStrictNotEqual
-
- OPCONTEXT(instanceof), // OpInstanceof
- OPCONTEXT(in), // OpIn
-
- NULL_OP, // OpAnd
- NULL_OP // OpOr
-};
-
-
-
-template <typename JITAssembler>
-void Binop<JITAssembler>::generate(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target)
-{
- if (op != IR::OpMod
- && lhs->type == IR::DoubleType && rhs->type == IR::DoubleType) {
- doubleBinop(lhs, rhs, target);
- return;
- }
- if (lhs->type == IR::SInt32Type && rhs->type == IR::SInt32Type) {
- if (int32Binop(lhs, rhs, target))
- return;
- }
-
- Jump done;
- if (lhs->type != IR::StringType && rhs->type != IR::StringType)
- done = genInlineBinop(lhs, rhs, target);
-
- // TODO: inline var===null and var!==null
- Binop::OpInfo info = Binop::operation(op);
-
- if (op == IR::OpAdd &&
- (lhs->type == IR::StringType || rhs->type == IR::StringType)) {
- const Binop::OpInfo stringAdd = OPCONTEXT(addString);
- info = stringAdd;
- }
-
- typename JITAssembler::RuntimeCall fallBack(info.fallbackImplementation);
- typename JITAssembler::RuntimeCall context(info.contextImplementation);
- if (fallBack.isValid()) {
- as->generateFunctionCallImp(info.needsExceptionCheck, target, info.name, fallBack,
- PointerToValue(lhs),
- PointerToValue(rhs));
- } else if (context.isValid()) {
- as->generateFunctionCallImp(info.needsExceptionCheck, target, info.name, context,
- JITAssembler::EngineRegister,
- PointerToValue(lhs),
- PointerToValue(rhs));
- } else {
- Q_ASSERT(!"unreachable");
- }
-
- if (done.isSet())
- done.link(as);
-
-}
-
-template <typename JITAssembler>
-void Binop<JITAssembler>::doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target)
-{
- IR::Temp *targetTemp = target->asTemp();
- FPRegisterID targetReg;
- if (targetTemp && targetTemp->kind == IR::Temp::PhysicalRegister)
- targetReg = (FPRegisterID) targetTemp->index;
- else
- targetReg = JITAssembler::FPGpr0;
-
- switch (op) {
- case IR::OpAdd:
- if (lhs->asConst())
- std::swap(lhs, rhs); // Y = constant + X -> Y = X + constant
-
- if (ArchitectureSpecificBinaryOperation<JITAssembler>::doubleAdd(as, lhs, rhs, targetReg))
- break;
-
- as->addDouble(as->toDoubleRegister(lhs, JITAssembler::FPGpr0), as->toDoubleRegister(rhs, JITAssembler::FPGpr1), targetReg);
- break;
-
- case IR::OpMul:
- if (lhs->asConst())
- std::swap(lhs, rhs); // Y = constant * X -> Y = X * constant
-
- if (ArchitectureSpecificBinaryOperation<JITAssembler>::doubleMul(as, lhs, rhs, targetReg))
- break;
-
- as->mulDouble(as->toDoubleRegister(lhs, JITAssembler::FPGpr0), as->toDoubleRegister(rhs, JITAssembler::FPGpr1), targetReg);
- break;
-
- case IR::OpSub:
- if (ArchitectureSpecificBinaryOperation<JITAssembler>::doubleSub(as, lhs, rhs, targetReg))
- break;
-
- if (rhs->asTemp() && rhs->asTemp()->kind == IR::Temp::PhysicalRegister
- && targetTemp
- && targetTemp->kind == IR::Temp::PhysicalRegister
- && targetTemp->index == rhs->asTemp()->index) { // Y = X - Y -> Tmp = Y; Y = X - Tmp
- as->moveDouble(as->toDoubleRegister(rhs, JITAssembler::FPGpr1), JITAssembler::FPGpr1);
- as->subDouble(as->toDoubleRegister(lhs, JITAssembler::FPGpr0), JITAssembler::FPGpr1, targetReg);
- break;
- }
-
- as->subDouble(as->toDoubleRegister(lhs, JITAssembler::FPGpr0), as->toDoubleRegister(rhs, JITAssembler::FPGpr1), targetReg);
- break;
-
- case IR::OpDiv:
- if (ArchitectureSpecificBinaryOperation<JITAssembler>::doubleDiv(as, lhs, rhs, targetReg))
- break;
-
- if (rhs->asTemp() && rhs->asTemp()->kind == IR::Temp::PhysicalRegister
- && targetTemp
- && targetTemp->kind == IR::Temp::PhysicalRegister
- && targetTemp->index == rhs->asTemp()->index) { // Y = X / Y -> Tmp = Y; Y = X / Tmp
- as->moveDouble(as->toDoubleRegister(rhs, JITAssembler::FPGpr1), JITAssembler::FPGpr1);
- as->divDouble(as->toDoubleRegister(lhs, JITAssembler::FPGpr0), JITAssembler::FPGpr1, targetReg);
- break;
- }
-
- as->divDouble(as->toDoubleRegister(lhs, JITAssembler::FPGpr0), as->toDoubleRegister(rhs, JITAssembler::FPGpr1), targetReg);
- break;
-
- default: {
- Jump trueCase = as->branchDouble(false, op, lhs, rhs);
- as->storeBool(false, target);
- Jump done = as->jump();
- trueCase.link(as);
- as->storeBool(true, target);
- done.link(as);
- } return;
- }
-
- if (!targetTemp || targetTemp->kind != IR::Temp::PhysicalRegister)
- as->storeDouble(targetReg, target);
-}
-
-template <typename JITAssembler>
-bool Binop<JITAssembler>::int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target)
-{
- Q_ASSERT(leftSource->type == IR::SInt32Type);
- Q_ASSERT(rightSource->type == IR::SInt32Type);
-
- switch (op) {
- case IR::OpBitAnd:
- case IR::OpBitOr:
- case IR::OpBitXor:
- case IR::OpAdd:
- case IR::OpMul:
- if (leftSource->asConst()) // X = Const op Y -> X = Y op Const
- std::swap(leftSource, rightSource);
- else if (IR::Temp *t = leftSource->asTemp()) {
- if (t->kind != IR::Temp::PhysicalRegister) // X = [address] op Y -> X = Y op [address]
- std::swap(leftSource, rightSource);
- }
- break;
-
- case IR::OpLShift:
- case IR::OpRShift:
- case IR::OpURShift:
- case IR::OpSub:
- // handled by this method, but we can't flip operands.
- break;
-
- default:
- return false; // not handled by this method, stop here.
- }
-
- bool inplaceOpWithAddress = false;
-
- IR::Temp *targetTemp = target->asTemp();
- RegisterID targetReg = JITAssembler::ReturnValueRegister;
- if (targetTemp && targetTemp->kind == IR::Temp::PhysicalRegister) {
- IR::Temp *rhs = rightSource->asTemp();
- if (!rhs || rhs->kind != IR::Temp::PhysicalRegister || rhs->index != targetTemp->index) {
- // We try to load leftSource into the target's register, but we can't do that if
- // the target register is the same as rightSource.
- targetReg = (RegisterID) targetTemp->index;
- } else if (rhs && rhs->kind == IR::Temp::PhysicalRegister && targetTemp->index == rhs->index) {
- // However, if the target register is the same as the rightSource register, we can flip
- // the operands for certain operations.
- switch (op) {
- case IR::OpBitAnd:
- case IR::OpBitOr:
- case IR::OpBitXor:
- case IR::OpAdd:
- case IR::OpMul:
- // X = Y op X -> X = X op Y (or rephrased: X op= Y (so an in-place operation))
- std::swap(leftSource, rightSource);
- targetReg = (RegisterID) targetTemp->index;
- break;
-
- case IR::OpLShift:
- case IR::OpRShift:
- case IR::OpURShift:
- case IR::OpSub:
- break;
-
- default:
- Q_UNREACHABLE();
- return false;
- }
- }
-
- // determine if we have X op= [address]
- if (IR::Temp *lhs = leftSource->asTemp()) {
- if (lhs->kind == IR::Temp::PhysicalRegister && lhs->index == targetTemp->index) {
- if (IR::Temp *rhs = rightSource->asTemp()) {
- if (rhs->kind != IR::Temp::PhysicalRegister) {
- switch (op) {
- case IR::OpBitAnd:
- case IR::OpBitOr:
- case IR::OpBitXor:
- case IR::OpAdd:
- case IR::OpMul:
- inplaceOpWithAddress = true;
- break;
- default:
- break;
- }
- }
- }
- }
- }
- }
-
- // Special cases:
- switch (op) {
- case IR::OpSub:
- if (rightSource->asTemp() && rightSource->asTemp()->kind == IR::Temp::PhysicalRegister
- && targetTemp
- && targetTemp->kind == IR::Temp::PhysicalRegister
- && targetTemp->index == rightSource->asTemp()->index) {
- // X = Y - X -> Tmp = X; X = Y; X -= Tmp
- targetReg = (RegisterID) targetTemp->index;
- as->move(targetReg, JITAssembler::ScratchRegister);
- as->move(as->toInt32Register(leftSource, targetReg), targetReg);
- as->sub32(JITAssembler::ScratchRegister, targetReg);
- } else {
- as->move(as->toInt32Register(leftSource, targetReg), targetReg);
- as->sub32(as->toInt32Register(rightSource, JITAssembler::ScratchRegister), targetReg);
- }
- as->storeInt32(targetReg, target);
- return true;
-
- case IR::OpLShift:
- case IR::OpRShift:
- case IR::OpURShift:
- if (IR::Const *c = rightSource->asConst()) {
- if ((QV4::Primitive::toUInt32(c->value) & 0x1f) == 0) {
- RegisterID r = as->toInt32Register(leftSource, targetReg);
- as->storeInt32(r, target);
- return true;
- }
- }
- break;
-
- default:
- break;
- }
-
- RegisterID l = as->toInt32Register(leftSource, targetReg);
- if (IR::Const *c = rightSource->asConst()) { // All cases of Y = X op Const
- TrustedImm32 r(int(c->value));
- TrustedImm32 ur(QV4::Primitive::toUInt32(c->value) & 0x1f);
-
- switch (op) {
- case IR::OpBitAnd: as->and32(r, l, targetReg); break;
- case IR::OpBitOr: as->or32 (r, l, targetReg); break;
- case IR::OpBitXor: as->xor32(r, l, targetReg); break;
- case IR::OpAdd: as->add32(r, l, targetReg); break;
- case IR::OpMul: as->mul32(r, l, targetReg); break;
-
- case IR::OpLShift: as->lshift32(l, ur, targetReg); break;
- case IR::OpRShift: as->rshift32(l, ur, targetReg); break;
- case IR::OpURShift: as->urshift32(l, ur, targetReg);
- as->storeUInt32(targetReg, target); // IMPORTANT: do NOT do a break here! The stored type of an urshift is different from the other binary operations!
- return true;
-
- case IR::OpSub: // already handled before
- default: // not handled by this method:
- Q_UNREACHABLE();
- return false;
- }
- } else if (inplaceOpWithAddress) { // All cases of X = X op [address-of-Y]
- Pointer rhsAddr = as->loadAddress(JITAssembler::ScratchRegister, rightSource);
- switch (op) {
- case IR::OpBitAnd: as->and32(rhsAddr, targetReg); break;
- case IR::OpBitOr: as->or32 (rhsAddr, targetReg); break;
- case IR::OpBitXor: as->xor32(rhsAddr, targetReg); break;
- case IR::OpAdd: as->add32(rhsAddr, targetReg); break;
- case IR::OpMul: as->mul32(rhsAddr, targetReg); break;
- break;
-
- default: // not handled by this method:
- Q_UNREACHABLE();
- return false;
- }
- } else { // All cases of Z = X op Y
- RegisterID r = as->toInt32Register(rightSource, JITAssembler::ScratchRegister);
- switch (op) {
- case IR::OpBitAnd: as->and32(l, r, targetReg); break;
- case IR::OpBitOr: as->or32 (l, r, targetReg); break;
- case IR::OpBitXor: as->xor32(l, r, targetReg); break;
- case IR::OpAdd: as->add32(l, r, targetReg); break;
- case IR::OpMul: as->mul32(l, r, targetReg); break;
-
-#if CPU(X86) || CPU(X86_64)
- // Intel does the & 0x1f on the CPU, so:
- case IR::OpLShift: as->lshift32(l, r, targetReg); break;
- case IR::OpRShift: as->rshift32(l, r, targetReg); break;
- case IR::OpURShift: as->urshift32(l, r, targetReg);
- as->storeUInt32(targetReg, target); // IMPORTANT: do NOT do a break here! The stored type of an urshift is different from the other binary operations!
- return true;
-#else
- // Not all CPUs accept shifts over more than 31 bits, and some CPUs (like ARM) will do
- // surprising stuff when shifting over 0 bits.
-#define CHECK_RHS(op) { \
- as->and32(TrustedImm32(0x1f), r, JITAssembler::ScratchRegister); \
- Jump notZero = as->branch32(RelationalCondition::NotEqual, JITAssembler::ScratchRegister, TrustedImm32(0)); \
- as->move(l, targetReg); \
- Jump done = as->jump(); \
- notZero.link(as); \
- op; \
- done.link(as); \
-}
- case IR::OpLShift: CHECK_RHS(as->lshift32(l, JITAssembler::ScratchRegister, targetReg)); break;
- case IR::OpRShift: CHECK_RHS(as->rshift32(l, JITAssembler::ScratchRegister, targetReg)); break;
- case IR::OpURShift:
- CHECK_RHS(as->urshift32(l, JITAssembler::ScratchRegister, targetReg));
- as->storeUInt32(targetReg, target);
- // IMPORTANT: do NOT do a break here! The stored type of an urshift is different from the other binary operations!
- return true;
-#undef CHECK_RHS
-#endif
-
- case IR::OpSub: // already handled before
- default: // not handled by this method:
- Q_UNREACHABLE();
- return false;
- }
- }
-
- as->storeInt32(targetReg, target);
- return true;
-}
-
-template <typename JITAssembler>
-inline typename JITAssembler::FPRegisterID getFreeFPReg(IR::Expr *shouldNotOverlap, unsigned hint)
-{
- if (IR::Temp *t = shouldNotOverlap->asTemp())
- if (t->type == IR::DoubleType)
- if (t->kind == IR::Temp::PhysicalRegister)
- if (t->index == hint)
- return typename JITAssembler::FPRegisterID(hint + 1);
- return typename JITAssembler::FPRegisterID(hint);
-}
-
-template <typename JITAssembler>
-typename JITAssembler::Jump Binop<JITAssembler>::genInlineBinop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target)
-{
- Jump done;
-
- // Try preventing a call for a few common binary operations. This is used in two cases:
- // - no register allocation was performed (not available for the platform, or the IR was
- // not transformed into SSA)
- // - type inference found that either or both operands can be of non-number type, and the
- // register allocator will have prepared for a call (meaning: all registers that do not
- // hold operands are spilled to the stack, which makes them available here)
- // Note: FPGPr0 can still not be used, because uint32->double conversion uses it as a scratch
- // register.
- switch (op) {
- case IR::OpAdd: {
- FPRegisterID lReg = getFreeFPReg<JITAssembler>(rightSource, 2);
- FPRegisterID rReg = getFreeFPReg<JITAssembler>(leftSource, 4);
- Jump leftIsNoDbl = as->genTryDoubleConversion(leftSource, lReg);
- Jump rightIsNoDbl = as->genTryDoubleConversion(rightSource, rReg);
-
- as->addDouble(rReg, lReg);
- as->storeDouble(lReg, target);
- done = as->jump();
-
- if (leftIsNoDbl.isSet())
- leftIsNoDbl.link(as);
- if (rightIsNoDbl.isSet())
- rightIsNoDbl.link(as);
- } break;
- case IR::OpMul: {
- FPRegisterID lReg = getFreeFPReg<JITAssembler>(rightSource, 2);
- FPRegisterID rReg = getFreeFPReg<JITAssembler>(leftSource, 4);
- Jump leftIsNoDbl = as->genTryDoubleConversion(leftSource, lReg);
- Jump rightIsNoDbl = as->genTryDoubleConversion(rightSource, rReg);
-
- as->mulDouble(rReg, lReg);
- as->storeDouble(lReg, target);
- done = as->jump();
-
- if (leftIsNoDbl.isSet())
- leftIsNoDbl.link(as);
- if (rightIsNoDbl.isSet())
- rightIsNoDbl.link(as);
- } break;
- case IR::OpSub: {
- FPRegisterID lReg = getFreeFPReg<JITAssembler>(rightSource, 2);
- FPRegisterID rReg = getFreeFPReg<JITAssembler>(leftSource, 4);
- Jump leftIsNoDbl = as->genTryDoubleConversion(leftSource, lReg);
- Jump rightIsNoDbl = as->genTryDoubleConversion(rightSource, rReg);
-
- as->subDouble(rReg, lReg);
- as->storeDouble(lReg, target);
- done = as->jump();
-
- if (leftIsNoDbl.isSet())
- leftIsNoDbl.link(as);
- if (rightIsNoDbl.isSet())
- rightIsNoDbl.link(as);
- } break;
- case IR::OpDiv: {
- FPRegisterID lReg = getFreeFPReg<JITAssembler>(rightSource, 2);
- FPRegisterID rReg = getFreeFPReg<JITAssembler>(leftSource, 4);
- Jump leftIsNoDbl = as->genTryDoubleConversion(leftSource, lReg);
- Jump rightIsNoDbl = as->genTryDoubleConversion(rightSource, rReg);
-
- as->divDouble(rReg, lReg);
- as->storeDouble(lReg, target);
- done = as->jump();
-
- if (leftIsNoDbl.isSet())
- leftIsNoDbl.link(as);
- if (rightIsNoDbl.isSet())
- rightIsNoDbl.link(as);
- } break;
- default:
- break;
- }
-
- return done;
-}
-
-template struct QV4::JIT::Binop<QV4::JIT::Assembler<DefaultAssemblerTargetConfiguration>>;
-#if defined(V4_BOOTSTRAP)
-#if !CPU(ARM_THUMB2)
-template struct QV4::JIT::Binop<QV4::JIT::Assembler<AssemblerTargetConfiguration<JSC::MacroAssemblerARMv7, NoOperatingSystemSpecialization>>>;
-#endif
-#if !CPU(ARM64)
-template struct QV4::JIT::Binop<QV4::JIT::Assembler<AssemblerTargetConfiguration<JSC::MacroAssemblerARM64, NoOperatingSystemSpecialization>>>;
-#endif
-#endif
-
-} // end of namespace JIT
-} // end of namespace QV4
-
-QT_END_NAMESPACE
-
-
-#endif
diff --git a/src/qml/jit/qv4binop_p.h b/src/qml/jit/qv4binop_p.h
deleted file mode 100644
index 1b1ab7f24d..0000000000
--- a/src/qml/jit/qv4binop_p.h
+++ /dev/null
@@ -1,256 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#ifndef QV4BINOP_P_H
-#define QV4BINOP_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <qv4jsir_p.h>
-#include <qv4isel_masm_p.h>
-#include <qv4assembler_p.h>
-
-QT_BEGIN_NAMESPACE
-
-#if ENABLE(ASSEMBLER)
-
-namespace QV4 {
-namespace JIT {
-
-template <typename JITAssembler>
-struct Binop {
- Binop(JITAssembler *assembler, IR::AluOp operation)
- : as(assembler)
- , op(operation)
- {}
-
- using Jump = typename JITAssembler::Jump;
- using Address = typename JITAssembler::Address;
- using RegisterID = typename JITAssembler::RegisterID;
- using FPRegisterID = typename JITAssembler::FPRegisterID;
- using TrustedImm32 = typename JITAssembler::TrustedImm32;
- using ResultCondition = typename JITAssembler::ResultCondition;
- using RelationalCondition = typename JITAssembler::RelationalCondition;
- using Pointer = typename JITAssembler::Pointer;
- using PointerToValue = typename JITAssembler::PointerToValue;
-
- void generate(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target);
- void doubleBinop(IR::Expr *lhs, IR::Expr *rhs, IR::Expr *target);
- bool int32Binop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target);
- Jump genInlineBinop(IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target);
-
- typedef Jump (Binop::*MemRegOp)(Address, RegisterID);
- typedef Jump (Binop::*ImmRegOp)(TrustedImm32, RegisterID);
-
- struct OpInfo {
- const char *name;
- Runtime::RuntimeMethods fallbackImplementation;
- Runtime::RuntimeMethods contextImplementation;
- MemRegOp inlineMemRegOp;
- ImmRegOp inlineImmRegOp;
- bool needsExceptionCheck;
- };
-
- static const OpInfo operations[IR::LastAluOp + 1];
- static const OpInfo &operation(IR::AluOp operation)
- { return operations[operation]; }
-
- Jump inline_add32(Address addr, RegisterID reg)
- {
-#if HAVE(ALU_OPS_WITH_MEM_OPERAND)
- return as->branchAdd32(ResultCondition::Overflow, addr, reg);
-#else
- as->load32(addr, JITAssembler::ScratchRegister);
- return as->branchAdd32(ResultCondition::Overflow, JITAssembler::ScratchRegister, reg);
-#endif
- }
-
- Jump inline_add32(TrustedImm32 imm, RegisterID reg)
- {
- return as->branchAdd32(ResultCondition::Overflow, imm, reg);
- }
-
- Jump inline_sub32(Address addr, RegisterID reg)
- {
-#if HAVE(ALU_OPS_WITH_MEM_OPERAND)
- return as->branchSub32(ResultCondition::Overflow, addr, reg);
-#else
- as->load32(addr, JITAssembler::ScratchRegister);
- return as->branchSub32(ResultCondition::Overflow, JITAssembler::ScratchRegister, reg);
-#endif
- }
-
- Jump inline_sub32(TrustedImm32 imm, RegisterID reg)
- {
- return as->branchSub32(ResultCondition::Overflow, imm, reg);
- }
-
- Jump inline_mul32(Address addr, RegisterID reg)
- {
-#if HAVE(ALU_OPS_WITH_MEM_OPERAND)
- return as->branchMul32(JITAssembler::Overflow, addr, reg);
-#else
- as->load32(addr, JITAssembler::ScratchRegister);
- return as->branchMul32(ResultCondition::Overflow, JITAssembler::ScratchRegister, reg);
-#endif
- }
-
- Jump inline_mul32(TrustedImm32 imm, RegisterID reg)
- {
- return as->branchMul32(ResultCondition::Overflow, imm, reg, reg);
- }
-
- Jump inline_shl32(Address addr, RegisterID reg)
- {
- as->load32(addr, JITAssembler::ScratchRegister);
- as->and32(TrustedImm32(0x1f), JITAssembler::ScratchRegister);
- as->lshift32(JITAssembler::ScratchRegister, reg);
- return Jump();
- }
-
- Jump inline_shl32(TrustedImm32 imm, RegisterID reg)
- {
- imm.m_value &= 0x1f;
- as->lshift32(imm, reg);
- return Jump();
- }
-
- Jump inline_shr32(Address addr, RegisterID reg)
- {
- as->load32(addr, JITAssembler::ScratchRegister);
- as->and32(TrustedImm32(0x1f), JITAssembler::ScratchRegister);
- as->rshift32(JITAssembler::ScratchRegister, reg);
- return Jump();
- }
-
- Jump inline_shr32(TrustedImm32 imm, RegisterID reg)
- {
- imm.m_value &= 0x1f;
- as->rshift32(imm, reg);
- return Jump();
- }
-
- Jump inline_ushr32(Address addr, RegisterID reg)
- {
- as->load32(addr, JITAssembler::ScratchRegister);
- as->and32(TrustedImm32(0x1f), JITAssembler::ScratchRegister);
- as->urshift32(JITAssembler::ScratchRegister, reg);
- return as->branchTest32(ResultCondition::Signed, reg, reg);
- }
-
- Jump inline_ushr32(TrustedImm32 imm, RegisterID reg)
- {
- imm.m_value &= 0x1f;
- as->urshift32(imm, reg);
- return as->branchTest32(ResultCondition::Signed, reg, reg);
- }
-
- Jump inline_and32(Address addr, RegisterID reg)
- {
-#if HAVE(ALU_OPS_WITH_MEM_OPERAND)
- as->and32(addr, reg);
-#else
- as->load32(addr, JITAssembler::ScratchRegister);
- as->and32(JITAssembler::ScratchRegister, reg);
-#endif
- return Jump();
- }
-
- Jump inline_and32(TrustedImm32 imm, RegisterID reg)
- {
- as->and32(imm, reg);
- return Jump();
- }
-
- Jump inline_or32(Address addr, RegisterID reg)
- {
-#if HAVE(ALU_OPS_WITH_MEM_OPERAND)
- as->or32(addr, reg);
-#else
- as->load32(addr, JITAssembler::ScratchRegister);
- as->or32(JITAssembler::ScratchRegister, reg);
-#endif
- return Jump();
- }
-
- Jump inline_or32(TrustedImm32 imm, RegisterID reg)
- {
- as->or32(imm, reg);
- return Jump();
- }
-
- Jump inline_xor32(Address addr, RegisterID reg)
- {
-#if HAVE(ALU_OPS_WITH_MEM_OPERAND)
- as->xor32(addr, reg);
-#else
- as->load32(addr, JITAssembler::ScratchRegister);
- as->xor32(JITAssembler::ScratchRegister, reg);
-#endif
- return Jump();
- }
-
- Jump inline_xor32(TrustedImm32 imm, RegisterID reg)
- {
- as->xor32(imm, reg);
- return Jump();
- }
-
-
-
- JITAssembler *as;
- IR::AluOp op;
-};
-
-}
-}
-
-#endif
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp
deleted file mode 100644
index 9ddab8f838..0000000000
--- a/src/qml/jit/qv4isel_masm.cpp
+++ /dev/null
@@ -1,1676 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qv4isel_masm_p.h"
-#include "qv4runtime_p.h"
-#include "qv4lookup_p.h"
-#include "qv4ssa_p.h"
-#include "qv4regalloc_p.h"
-#include "qv4assembler_p.h"
-#include "qv4unop_p.h"
-#include "qv4binop_p.h"
-
-#include <QtCore/QBuffer>
-#include <QtCore/QCoreApplication>
-
-#include <assembler/LinkBuffer.h>
-#include <WTFStubs.h>
-
-#include <iostream>
-
-#if ENABLE(ASSEMBLER)
-
-#if USE(UDIS86)
-# include <udis86.h>
-#endif
-
-using namespace QV4;
-using namespace QV4::JIT;
-
-
-template <typename JITAssembler>
-InstructionSelection<JITAssembler>::InstructionSelection(QQmlEnginePrivate *qmlEngine, QV4::ExecutableAllocator *execAllocator, IR::Module *module, Compiler::JSUnitGenerator *jsGenerator, EvalISelFactory *iselFactory)
- : EvalInstructionSelection(execAllocator, module, jsGenerator, iselFactory)
- , _block(0)
- , _as(0)
- , compilationUnit(new CompilationUnit)
- , qmlEngine(qmlEngine)
-{
- compilationUnit->codeRefs.resize(module->functions.size());
- module->unitFlags |= QV4::CompiledData::Unit::ContainsMachineCode;
-}
-
-template <typename JITAssembler>
-InstructionSelection<JITAssembler>::~InstructionSelection()
-{
- delete _as;
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::run(int functionIndex)
-{
- IR::Function *function = irModule->functions[functionIndex];
- qSwap(_function, function);
-
- IR::Optimizer opt(_function);
- opt.run(qmlEngine);
-
- static const bool withRegisterAllocator = qEnvironmentVariableIsEmpty("QV4_NO_REGALLOC");
- if (JITTargetPlatform::RegAllocIsSupported && opt.isInSSA() && withRegisterAllocator) {
- RegisterAllocator regalloc(JITTargetPlatform::getRegisterInfo());
- regalloc.run(_function, opt);
- calculateRegistersToSave(regalloc.usedRegisters());
- } else {
- if (opt.isInSSA())
- // No register allocator available for this platform, or env. var was set, so:
- opt.convertOutOfSSA();
- ConvertTemps().toStackSlots(_function);
- IR::Optimizer::showMeTheCode(_function, "After stack slot allocation");
- calculateRegistersToSave(JITTargetPlatform::getRegisterInfo()); // FIXME: this saves all registers. We can probably do with a subset: those that are not used by the register allocator.
- }
- BitVector removableJumps = opt.calculateOptionalJumps();
- qSwap(_removableJumps, removableJumps);
-
- JITAssembler* oldAssembler = _as;
- _as = new JITAssembler(jsGenerator, _function, executableAllocator);
- _as->setStackLayout(6, // 6 == max argc for calls to built-ins with an argument array
- regularRegistersToSave.size(),
- fpRegistersToSave.size());
- _as->enterStandardStackFrame(regularRegistersToSave, fpRegistersToSave);
-
- if (JITTargetPlatform::RegisterArgumentCount > 0)
- _as->move(_as->registerForArgument(0), JITTargetPlatform::EngineRegister);
- else
- _as->loadPtr(addressForArgument(0), JITTargetPlatform::EngineRegister);
-
- _as->initializeLocalVariables();
-
- int lastLine = 0;
- for (int i = 0, ei = _function->basicBlockCount(); i != ei; ++i) {
- IR::BasicBlock *nextBlock = (i < ei - 1) ? _function->basicBlock(i + 1) : 0;
- _block = _function->basicBlock(i);
- if (_block->isRemoved())
- continue;
- _as->registerBlock(_block, nextBlock);
-
- for (IR::Stmt *s : _block->statements()) {
- if (s->location.isValid()) {
- if (int(s->location.startLine) != lastLine) {
- _as->loadPtr(Address(JITTargetPlatform::EngineRegister, JITAssembler::targetStructureOffset(offsetof(QV4::EngineBase, current))), JITTargetPlatform::ScratchRegister);
- Address lineAddr(JITTargetPlatform::ScratchRegister, JITAssembler::targetStructureOffset(Heap::ExecutionContext::baseOffset + offsetof(Heap::ExecutionContextData, lineNumber)));
- _as->store32(TrustedImm32(s->location.startLine), lineAddr);
- lastLine = s->location.startLine;
- }
- }
- visit(s);
- }
- }
-
- if (!_as->exceptionReturnLabel.isSet())
- visitRet(0);
-
- int dummySize;
- JSC::MacroAssemblerCodeRef codeRef =_as->link(&dummySize);
- compilationUnit->codeRefs[functionIndex] = codeRef;
-
- qSwap(_function, function);
- delete _as;
- _as = oldAssembler;
- qSwap(_removableJumps, removableJumps);
-}
-
-template <typename JITAssembler>
-QQmlRefPointer<QV4::CompiledData::CompilationUnit> InstructionSelection<JITAssembler>::backendCompileStep()
-{
- QQmlRefPointer<QV4::CompiledData::CompilationUnit> result;
- result.adopt(compilationUnit.take());
- return result;
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callBuiltinInvalid(IR::Name *func, IR::ExprList *args, IR::Expr *result)
-{
- prepareCallData(args, 0);
-
- if ((useFastLookups || func->forceLookup) && func->global) {
- uint index = registerGlobalGetterLookup(*func->id);
- generateRuntimeCall(_as, result, callGlobalLookup,
- JITTargetPlatform::EngineRegister,
- TrustedImm32(index),
- baseAddressForCallData());
- } else {
- generateRuntimeCall(_as, result, callActivationProperty,
- JITTargetPlatform::EngineRegister,
- StringToIndex(*func->id),
- baseAddressForCallData());
- }
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callBuiltinTypeofQmlContextProperty(IR::Expr *base,
- IR::Member::MemberKind kind,
- int propertyIndex, IR::Expr *result)
-{
- if (kind == IR::Member::MemberOfQmlScopeObject) {
- generateRuntimeCall(_as, result, typeofScopeObjectProperty, JITTargetPlatform::EngineRegister,
- PointerToValue(base),
- TrustedImm32(propertyIndex));
- } else if (kind == IR::Member::MemberOfQmlContextObject) {
- generateRuntimeCall(_as, result, typeofContextObjectProperty,
- JITTargetPlatform::EngineRegister, PointerToValue(base),
- TrustedImm32(propertyIndex));
- } else {
- Q_UNREACHABLE();
- }
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callBuiltinTypeofMember(IR::Expr *base, const QString &name,
- IR::Expr *result)
-{
- generateRuntimeCall(_as, result, typeofMember, JITTargetPlatform::EngineRegister,
- PointerToValue(base), StringToIndex(name));
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callBuiltinTypeofSubscript(IR::Expr *base, IR::Expr *index,
- IR::Expr *result)
-{
- generateRuntimeCall(_as, result, typeofElement,
- JITTargetPlatform::EngineRegister,
- PointerToValue(base), PointerToValue(index));
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callBuiltinTypeofName(const QString &name, IR::Expr *result)
-{
- generateRuntimeCall(_as, result, typeofName, JITTargetPlatform::EngineRegister,
- StringToIndex(name));
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callBuiltinTypeofValue(IR::Expr *value, IR::Expr *result)
-{
- generateRuntimeCall(_as, result, typeofValue, JITTargetPlatform::EngineRegister,
- PointerToValue(value));
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callBuiltinDeleteMember(IR::Expr *base, const QString &name, IR::Expr *result)
-{
- generateRuntimeCall(_as, result, deleteMember, JITTargetPlatform::EngineRegister,
- Reference(base), StringToIndex(name));
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callBuiltinDeleteSubscript(IR::Expr *base, IR::Expr *index,
- IR::Expr *result)
-{
- generateRuntimeCall(_as, result, deleteElement, JITTargetPlatform::EngineRegister,
- Reference(base), PointerToValue(index));
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callBuiltinDeleteName(const QString &name, IR::Expr *result)
-{
- generateRuntimeCall(_as, result, deleteName, JITTargetPlatform::EngineRegister,
- StringToIndex(name));
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callBuiltinDeleteValue(IR::Expr *result)
-{
- _as->storeValue(JITAssembler::TargetPrimitive::fromBoolean(false), result);
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callBuiltinThrow(IR::Expr *arg)
-{
- generateRuntimeCall(_as, JITTargetPlatform::ReturnValueRegister, throwException, JITTargetPlatform::EngineRegister,
- PointerToValue(arg));
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callBuiltinReThrow()
-{
- _as->jumpToExceptionHandler();
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callBuiltinUnwindException(IR::Expr *result)
-{
- generateRuntimeCall(_as, result, unwindException, JITTargetPlatform::EngineRegister);
-
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callBuiltinPushCatchScope(const QString &exceptionName)
-{
- generateRuntimeCall(_as, JITAssembler::Void, pushCatchScope, JITTargetPlatform::EngineRegister, StringToIndex(exceptionName));
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callBuiltinForeachIteratorObject(IR::Expr *arg, IR::Expr *result)
-{
- Q_ASSERT(arg);
- Q_ASSERT(result);
-
- generateRuntimeCall(_as, result, foreachIterator, JITTargetPlatform::EngineRegister, PointerToValue(arg));
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callBuiltinForeachNextPropertyname(IR::Expr *arg, IR::Expr *result)
-{
- Q_ASSERT(arg);
- Q_ASSERT(result);
-
- generateRuntimeCall(_as, result, foreachNextPropertyName, Reference(arg));
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callBuiltinPushWithScope(IR::Expr *arg)
-{
- Q_ASSERT(arg);
-
- generateRuntimeCall(_as, JITAssembler::Void, pushWithScope, Reference(arg), JITTargetPlatform::EngineRegister);
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callBuiltinPopScope()
-{
- generateRuntimeCall(_as, JITAssembler::Void, popScope, JITTargetPlatform::EngineRegister);
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callBuiltinDeclareVar(bool deletable, const QString &name)
-{
- generateRuntimeCall(_as, JITAssembler::Void, declareVar, JITTargetPlatform::EngineRegister,
- TrustedImm32(deletable), StringToIndex(name));
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callBuiltinDefineArray(IR::Expr *result, IR::ExprList *args)
-{
- Q_ASSERT(result);
-
- int length = prepareVariableArguments(args);
- generateRuntimeCall(_as, result, arrayLiteral, JITTargetPlatform::EngineRegister,
- baseAddressForCallArguments(), TrustedImm32(length));
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callBuiltinDefineObjectLiteral(IR::Expr *result, int keyValuePairCount, IR::ExprList *keyValuePairs, IR::ExprList *arrayEntries, bool needSparseArray)
-{
- Q_ASSERT(result);
-
- int argc = 0;
-
- const int classId = registerJSClass(keyValuePairCount, keyValuePairs);
-
- IR::ExprList *it = keyValuePairs;
- for (int i = 0; i < keyValuePairCount; ++i, it = it->next) {
- it = it->next;
-
- bool isData = it->expr->asConst()->value;
- it = it->next;
-
- _as->copyValue(_as->stackLayout().argumentAddressForCall(argc++), it->expr);
-
- if (!isData) {
- it = it->next;
- _as->copyValue(_as->stackLayout().argumentAddressForCall(argc++), it->expr);
- }
- }
-
- it = arrayEntries;
- uint arrayValueCount = 0;
- while (it) {
- uint index = it->expr->asConst()->value;
- it = it->next;
-
- bool isData = it->expr->asConst()->value;
- it = it->next;
-
- if (!isData) {
- it = it->next; // getter
- it = it->next; // setter
- continue;
- }
-
- ++arrayValueCount;
-
- // Index
- _as->storeValue(JITAssembler::TargetPrimitive::fromUInt32(index), _as->stackLayout().argumentAddressForCall(argc++));
-
- // Value
- _as->copyValue(_as->stackLayout().argumentAddressForCall(argc++), it->expr);
- it = it->next;
- }
-
- it = arrayEntries;
- uint arrayGetterSetterCount = 0;
- while (it) {
- uint index = it->expr->asConst()->value;
- it = it->next;
-
- bool isData = it->expr->asConst()->value;
- it = it->next;
-
- if (isData) {
- it = it->next; // value
- continue;
- }
-
- ++arrayGetterSetterCount;
-
- // Index
- _as->storeValue(JITAssembler::TargetPrimitive::fromUInt32(index), _as->stackLayout().argumentAddressForCall(argc++));
-
- // Getter
- _as->copyValue(_as->stackLayout().argumentAddressForCall(argc++), it->expr);
- it = it->next;
-
- // Setter
- _as->copyValue(_as->stackLayout().argumentAddressForCall(argc++), it->expr);
- it = it->next;
- }
-
- generateRuntimeCall(_as, result, objectLiteral, JITTargetPlatform::EngineRegister,
- baseAddressForCallArguments(), TrustedImm32(classId),
- TrustedImm32(arrayValueCount), TrustedImm32(arrayGetterSetterCount | (needSparseArray << 30)));
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callBuiltinSetupArgumentObject(IR::Expr *result)
-{
- generateRuntimeCall(_as, result, setupArgumentsObject, JITTargetPlatform::EngineRegister);
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callBuiltinConvertThisToObject()
-{
- generateRuntimeCall(_as, JITAssembler::Void, convertThisToObject, JITTargetPlatform::EngineRegister);
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result)
-{
- Q_ASSERT(value);
-
- prepareCallData(args, 0);
- if (value->asConst())
- generateRuntimeCall(_as, result, callValue, JITTargetPlatform::EngineRegister,
- PointerToValue(value),
- baseAddressForCallData());
- else
- generateRuntimeCall(_as, result, callValue, JITTargetPlatform::EngineRegister,
- Reference(value),
- baseAddressForCallData());
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::loadThisObject(IR::Expr *temp)
-{
- _as->loadPtr(Address(JITTargetPlatform::EngineRegister, JITAssembler::targetStructureOffset(offsetof(QV4::EngineBase, current))), JITTargetPlatform::ScratchRegister);
- _as->loadPtr(Address(JITTargetPlatform::ScratchRegister, JITAssembler::targetStructureOffset(Heap::ExecutionContext::baseOffset + offsetof(Heap::ExecutionContextData, callData))), JITTargetPlatform::ScratchRegister);
- _as->copyValue(temp, Address(JITTargetPlatform::ScratchRegister, offsetof(CallData, thisObject)));
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::loadQmlContext(IR::Expr *temp)
-{
- generateRuntimeCall(_as, temp, getQmlContext, JITTargetPlatform::EngineRegister);
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::loadQmlImportedScripts(IR::Expr *temp)
-{
- generateRuntimeCall(_as, temp, getQmlImportedScripts, JITTargetPlatform::EngineRegister);
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::loadQmlSingleton(const QString &name, IR::Expr *temp)
-{
- generateRuntimeCall(_as, temp, getQmlSingleton, JITTargetPlatform::EngineRegister, StringToIndex(name));
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::loadConst(IR::Const *sourceConst, IR::Expr *target)
-{
- if (IR::Temp *targetTemp = target->asTemp()) {
- if (targetTemp->kind == IR::Temp::PhysicalRegister) {
- if (targetTemp->type == IR::DoubleType) {
- Q_ASSERT(sourceConst->type == IR::DoubleType);
- _as->toDoubleRegister(sourceConst, (FPRegisterID) targetTemp->index);
- } else if (targetTemp->type == IR::SInt32Type) {
- Q_ASSERT(sourceConst->type == IR::SInt32Type);
- _as->toInt32Register(sourceConst, (RegisterID) targetTemp->index);
- } else if (targetTemp->type == IR::UInt32Type) {
- Q_ASSERT(sourceConst->type == IR::UInt32Type);
- _as->toUInt32Register(sourceConst, (RegisterID) targetTemp->index);
- } else if (targetTemp->type == IR::BoolType) {
- Q_ASSERT(sourceConst->type == IR::BoolType);
- _as->move(TrustedImm32(convertToValue<Primitive>(sourceConst).int_32()),
- (RegisterID) targetTemp->index);
- } else {
- Q_UNREACHABLE();
- }
- return;
- }
- }
-
- _as->storeValue(convertToValue<typename JITAssembler::TargetPrimitive>(sourceConst), target);
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::loadString(const QString &str, IR::Expr *target)
-{
- Pointer srcAddr = _as->loadStringAddress(JITTargetPlatform::ReturnValueRegister, str);
- _as->loadPtr(srcAddr, JITTargetPlatform::ReturnValueRegister);
- Pointer destAddr = _as->loadAddress(JITTargetPlatform::ScratchRegister, target);
- JITAssembler::RegisterSizeDependentOps::loadManagedPointer(_as, JITTargetPlatform::ReturnValueRegister, destAddr);
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::loadRegexp(IR::RegExp *sourceRegexp, IR::Expr *target)
-{
- int id = registerRegExp(sourceRegexp);
- generateRuntimeCall(_as, target, regexpLiteral, JITTargetPlatform::EngineRegister, TrustedImm32(id));
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::getActivationProperty(const IR::Name *name, IR::Expr *target)
-{
- if ((useFastLookups || name->forceLookup) && name->global) {
- uint index = registerGlobalGetterLookup(*name->id);
- generateLookupCall(target, index, offsetof(QV4::Lookup, globalGetter), JITTargetPlatform::EngineRegister, JITAssembler::Void);
- return;
- }
- generateRuntimeCall(_as, target, getActivationProperty, JITTargetPlatform::EngineRegister, StringToIndex(*name->id));
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::setActivationProperty(IR::Expr *source, const QString &targetName)
-{
- // ### should use a lookup call here
- generateRuntimeCall(_as, JITAssembler::Void, setActivationProperty,
- JITTargetPlatform::EngineRegister, StringToIndex(targetName), PointerToValue(source));
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::initClosure(IR::Closure *closure, IR::Expr *target)
-{
- int id = closure->value;
- generateRuntimeCall(_as, target, closure, JITTargetPlatform::EngineRegister, TrustedImm32(id));
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::getProperty(IR::Expr *base, const QString &name, IR::Expr *target)
-{
- if (useFastLookups) {
- uint index = registerGetterLookup(name);
- generateLookupCall(target, index, offsetof(QV4::Lookup, getter), JITTargetPlatform::EngineRegister, PointerToValue(base), JITAssembler::Void);
- } else {
- generateRuntimeCall(_as, target, getProperty, JITTargetPlatform::EngineRegister,
- PointerToValue(base), StringToIndex(name));
- }
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::getQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int index, bool captureRequired, IR::Expr *target)
-{
- if (kind == IR::Member::MemberOfQmlScopeObject)
- generateRuntimeCall(_as, target, getQmlScopeObjectProperty, JITTargetPlatform::EngineRegister, PointerToValue(base), TrustedImm32(index), TrustedImm32(captureRequired));
- else if (kind == IR::Member::MemberOfQmlContextObject)
- generateRuntimeCall(_as, target, getQmlContextObjectProperty, JITTargetPlatform::EngineRegister, PointerToValue(base), TrustedImm32(index), TrustedImm32(captureRequired));
- else if (kind == IR::Member::MemberOfIdObjectsArray)
- generateRuntimeCall(_as, target, getQmlIdObject, JITTargetPlatform::EngineRegister, PointerToValue(base), TrustedImm32(index));
- else
- Q_ASSERT(false);
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::getQObjectProperty(IR::Expr *base, int propertyIndex, bool captureRequired, bool isSingleton, int attachedPropertiesId, IR::Expr *target)
-{
- if (attachedPropertiesId != 0)
- generateRuntimeCall(_as, target, getQmlAttachedProperty, JITTargetPlatform::EngineRegister, TrustedImm32(attachedPropertiesId), TrustedImm32(propertyIndex));
- else if (isSingleton)
- generateRuntimeCall(_as, target, getQmlSingletonQObjectProperty, JITTargetPlatform::EngineRegister, PointerToValue(base), TrustedImm32(propertyIndex),
- TrustedImm32(captureRequired));
- else
- generateRuntimeCall(_as, target, getQmlQObjectProperty, JITTargetPlatform::EngineRegister, PointerToValue(base), TrustedImm32(propertyIndex),
- TrustedImm32(captureRequired));
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::setProperty(IR::Expr *source, IR::Expr *targetBase,
- const QString &targetName)
-{
- if (useFastLookups) {
- uint index = registerSetterLookup(targetName);
- generateLookupCall(JITAssembler::Void, index, offsetof(QV4::Lookup, setter),
- JITTargetPlatform::EngineRegister,
- PointerToValue(targetBase),
- PointerToValue(source));
- } else {
- generateRuntimeCall(_as, JITAssembler::Void, setProperty, JITTargetPlatform::EngineRegister,
- PointerToValue(targetBase), StringToIndex(targetName),
- PointerToValue(source));
- }
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase, IR::Member::MemberKind kind, int propertyIndex)
-{
- if (kind == IR::Member::MemberOfQmlScopeObject)
- generateRuntimeCall(_as, JITAssembler::Void, setQmlScopeObjectProperty, JITTargetPlatform::EngineRegister, PointerToValue(targetBase),
- TrustedImm32(propertyIndex), PointerToValue(source));
- else if (kind == IR::Member::MemberOfQmlContextObject)
- generateRuntimeCall(_as, JITAssembler::Void, setQmlContextObjectProperty, JITTargetPlatform::EngineRegister, PointerToValue(targetBase),
- TrustedImm32(propertyIndex), PointerToValue(source));
- else
- Q_ASSERT(false);
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int propertyIndex)
-{
- generateRuntimeCall(_as, JITAssembler::Void, setQmlQObjectProperty, JITTargetPlatform::EngineRegister, PointerToValue(targetBase),
- TrustedImm32(propertyIndex), PointerToValue(source));
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::getElement(IR::Expr *base, IR::Expr *index, IR::Expr *target)
-{
- if (0 && useFastLookups) {
- uint lookup = registerIndexedGetterLookup();
- generateLookupCall(target, lookup, offsetof(QV4::Lookup, indexedGetter),
- PointerToValue(base),
- PointerToValue(index));
- return;
- }
-
- generateRuntimeCall(_as, target, getElement, JITTargetPlatform::EngineRegister,
- PointerToValue(base), PointerToValue(index));
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::setElement(IR::Expr *source, IR::Expr *targetBase, IR::Expr *targetIndex)
-{
- if (0 && useFastLookups) {
- uint lookup = registerIndexedSetterLookup();
- generateLookupCall(JITAssembler::Void, lookup, offsetof(QV4::Lookup, indexedSetter),
- PointerToValue(targetBase), PointerToValue(targetIndex),
- PointerToValue(source));
- return;
- }
- generateRuntimeCall(_as, JITAssembler::Void, setElement, JITTargetPlatform::EngineRegister,
- PointerToValue(targetBase), PointerToValue(targetIndex),
- PointerToValue(source));
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::copyValue(IR::Expr *source, IR::Expr *target)
-{
- IR::Temp *sourceTemp = source->asTemp();
- IR::Temp *targetTemp = target->asTemp();
-
- if (sourceTemp && targetTemp && *sourceTemp == *targetTemp)
- return;
- if (IR::ArgLocal *sal = source->asArgLocal())
- if (IR::ArgLocal *tal = target->asArgLocal())
- if (*sal == *tal)
- return;
-
- if (sourceTemp && sourceTemp->kind == IR::Temp::PhysicalRegister) {
- if (targetTemp && targetTemp->kind == IR::Temp::PhysicalRegister) {
- if (sourceTemp->type == IR::DoubleType)
- _as->moveDouble((FPRegisterID) sourceTemp->index,
- (FPRegisterID) targetTemp->index);
- else
- _as->move((RegisterID) sourceTemp->index,
- (RegisterID) targetTemp->index);
- return;
- } else {
- switch (sourceTemp->type) {
- case IR::DoubleType:
- _as->storeDouble((FPRegisterID) sourceTemp->index, target);
- break;
- case IR::SInt32Type:
- _as->storeInt32((RegisterID) sourceTemp->index, target);
- break;
- case IR::UInt32Type:
- _as->storeUInt32((RegisterID) sourceTemp->index, target);
- break;
- case IR::BoolType:
- _as->storeBool((RegisterID) sourceTemp->index, target);
- break;
- default:
- Q_ASSERT(!"Unreachable");
- break;
- }
- return;
- }
- } else if (targetTemp && targetTemp->kind == IR::Temp::PhysicalRegister) {
- switch (targetTemp->type) {
- case IR::DoubleType:
- Q_ASSERT(source->type == IR::DoubleType);
- _as->toDoubleRegister(source, (FPRegisterID) targetTemp->index);
- return;
- case IR::BoolType:
- Q_ASSERT(source->type == IR::BoolType);
- _as->toInt32Register(source, (RegisterID) targetTemp->index);
- return;
- case IR::SInt32Type:
- Q_ASSERT(source->type == IR::SInt32Type);
- _as->toInt32Register(source, (RegisterID) targetTemp->index);
- return;
- case IR::UInt32Type:
- Q_ASSERT(source->type == IR::UInt32Type);
- _as->toUInt32Register(source, (RegisterID) targetTemp->index);
- return;
- default:
- Q_ASSERT(!"Unreachable");
- break;
- }
- }
-
- // The target is not a physical register, nor is the source. So we can do a memory-to-memory copy:
- _as->memcopyValue(_as->loadAddress(JITTargetPlatform::ReturnValueRegister, target), source, JITTargetPlatform::ScratchRegister);
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::swapValues(IR::Expr *source, IR::Expr *target)
-{
- IR::Temp *sourceTemp = source->asTemp();
- IR::Temp *targetTemp = target->asTemp();
-
- if (sourceTemp && sourceTemp->kind == IR::Temp::PhysicalRegister) {
- if (targetTemp && targetTemp->kind == IR::Temp::PhysicalRegister) {
- Q_ASSERT(sourceTemp->type == targetTemp->type);
-
- if (sourceTemp->type == IR::DoubleType) {
- _as->moveDouble((FPRegisterID) targetTemp->index, JITTargetPlatform::FPGpr0);
- _as->moveDouble((FPRegisterID) sourceTemp->index,
- (FPRegisterID) targetTemp->index);
- _as->moveDouble(JITTargetPlatform::FPGpr0, (FPRegisterID) sourceTemp->index);
- } else {
- _as->swap((RegisterID) sourceTemp->index,
- (RegisterID) targetTemp->index);
- }
- return;
- }
- } else if (!sourceTemp || sourceTemp->kind == IR::Temp::StackSlot) {
- if (!targetTemp || targetTemp->kind == IR::Temp::StackSlot) {
- // Note: a swap for two stack-slots can involve different types.
- Pointer sAddr = _as->loadAddress(JITTargetPlatform::ScratchRegister, source);
- Pointer tAddr = _as->loadAddress(JITTargetPlatform::ReturnValueRegister, target);
- // use the implementation in JSC::MacroAssembler, as it doesn't do bit swizzling
- auto platformAs = static_cast<typename JITAssembler::MacroAssembler*>(_as);
- platformAs->loadDouble(sAddr, JITTargetPlatform::FPGpr0);
- platformAs->loadDouble(tAddr, JITTargetPlatform::FPGpr1);
- platformAs->storeDouble(JITTargetPlatform::FPGpr1, sAddr);
- platformAs->storeDouble(JITTargetPlatform::FPGpr0, tAddr);
- return;
- }
- }
-
- IR::Expr *memExpr = !sourceTemp || sourceTemp->kind == IR::Temp::StackSlot ? source : target;
- IR::Temp *regTemp = sourceTemp && sourceTemp->kind == IR::Temp::PhysicalRegister ? sourceTemp
- : targetTemp;
- Q_ASSERT(memExpr);
- Q_ASSERT(regTemp);
-
- Pointer addr = _as->loadAddress(JITTargetPlatform::ReturnValueRegister, memExpr);
- if (regTemp->type == IR::DoubleType) {
- _as->loadDouble(addr, JITTargetPlatform::FPGpr0);
- _as->storeDouble((FPRegisterID) regTemp->index, addr);
- _as->moveDouble(JITTargetPlatform::FPGpr0, (FPRegisterID) regTemp->index);
- } else if (regTemp->type == IR::UInt32Type) {
- _as->toUInt32Register(addr, JITTargetPlatform::ScratchRegister);
- _as->storeUInt32((RegisterID) regTemp->index, addr);
- _as->move(JITTargetPlatform::ScratchRegister, (RegisterID) regTemp->index);
- } else {
- _as->load32(addr, JITTargetPlatform::ScratchRegister);
- _as->store32((RegisterID) regTemp->index, addr);
- if (regTemp->type != memExpr->type) {
- addr.offset += 4;
- quint32 tag;
- switch (regTemp->type) {
- case IR::BoolType:
- tag = quint32(JITAssembler::ValueTypeInternal::Boolean);
- break;
- case IR::SInt32Type:
- tag = quint32(JITAssembler::ValueTypeInternal::Integer);
- break;
- default:
- tag = 31337; // bogus value
- Q_UNREACHABLE();
- }
- _as->store32(TrustedImm32(tag), addr);
- }
- _as->move(JITTargetPlatform::ScratchRegister, (RegisterID) regTemp->index);
- }
-}
-
-#define setOp(op, opName, operation) \
- do { \
- op = typename JITAssembler::RuntimeCall(QV4::Runtime::operation); opName = "Runtime::" isel_stringIfy(operation); \
- needsExceptionCheck = QV4::Runtime::Method_##operation##_NeedsExceptionCheck; \
- } while (0)
-#define setOpContext(op, opName, operation) \
- do { \
- opContext = typename JITAssembler::RuntimeCall(QV4::Runtime::operation); opName = "Runtime::" isel_stringIfy(operation); \
- needsExceptionCheck = QV4::Runtime::Method_##operation##_NeedsExceptionCheck; \
- } while (0)
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::unop(IR::AluOp oper, IR::Expr *source, IR::Expr *target)
-{
- QV4::JIT::Unop<JITAssembler> unop(_as, oper);
- unop.generate(source, target);
-}
-
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::binop(IR::AluOp oper, IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target)
-{
- QV4::JIT::Binop<JITAssembler> binop(_as, oper);
- binop.generate(leftSource, rightSource, target);
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int propertyIndex, IR::ExprList *args, IR::Expr *result)
-{
- prepareCallData(args, base);
-
- if (kind == IR::Member::MemberOfQmlScopeObject)
- generateRuntimeCall(_as, result, callQmlScopeObjectProperty,
- JITTargetPlatform::EngineRegister,
- TrustedImm32(propertyIndex),
- baseAddressForCallData());
- else if (kind == IR::Member::MemberOfQmlContextObject)
- generateRuntimeCall(_as, result, callQmlContextObjectProperty,
- JITTargetPlatform::EngineRegister,
- TrustedImm32(propertyIndex),
- baseAddressForCallData());
- else
- Q_ASSERT(false);
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callProperty(IR::Expr *base, const QString &name, IR::ExprList *args,
- IR::Expr *result)
-{
- Q_ASSERT(base != 0);
-
- prepareCallData(args, base);
-
- if (useFastLookups) {
- uint index = registerGetterLookup(name);
- generateRuntimeCall(_as, result, callPropertyLookup,
- JITTargetPlatform::EngineRegister,
- TrustedImm32(index),
- baseAddressForCallData());
- } else {
- generateRuntimeCall(_as, result, callProperty, JITTargetPlatform::EngineRegister,
- StringToIndex(name),
- baseAddressForCallData());
- }
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::callSubscript(IR::Expr *base, IR::Expr *index, IR::ExprList *args,
- IR::Expr *result)
-{
- Q_ASSERT(base != 0);
-
- prepareCallData(args, base);
- generateRuntimeCall(_as, result, callElement, JITTargetPlatform::EngineRegister,
- PointerToValue(index),
- baseAddressForCallData());
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::convertType(IR::Expr *source, IR::Expr *target)
-{
- switch (target->type) {
- case IR::DoubleType:
- convertTypeToDouble(source, target);
- break;
- case IR::BoolType:
- convertTypeToBool(source, target);
- break;
- case IR::SInt32Type:
- convertTypeToSInt32(source, target);
- break;
- case IR::UInt32Type:
- convertTypeToUInt32(source, target);
- break;
- default:
- convertTypeSlowPath(source, target);
- break;
- }
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::convertTypeSlowPath(IR::Expr *source, IR::Expr *target)
-{
- Q_ASSERT(target->type != IR::BoolType);
-
- if (target->type & IR::NumberType)
- unop(IR::OpUPlus, source, target);
- else
- copyValue(source, target);
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::convertTypeToDouble(IR::Expr *source, IR::Expr *target)
-{
- switch (source->type) {
- case IR::SInt32Type:
- case IR::BoolType:
- case IR::NullType:
- convertIntToDouble(source, target);
- break;
- case IR::UInt32Type:
- convertUIntToDouble(source, target);
- break;
- case IR::UndefinedType:
- _as->loadDouble(_as->loadAddress(JITTargetPlatform::ScratchRegister, source), JITTargetPlatform::FPGpr0);
- _as->storeDouble(JITTargetPlatform::FPGpr0, target);
- break;
- case IR::StringType:
- case IR::VarType: {
- // load the tag:
- Pointer tagAddr = _as->loadAddress(JITTargetPlatform::ScratchRegister, source);
- tagAddr.offset += 4;
- _as->load32(tagAddr, JITTargetPlatform::ScratchRegister);
-
- // check if it's an int32:
- Jump isNoInt = _as->branch32(RelationalCondition::NotEqual, JITTargetPlatform::ScratchRegister,
- TrustedImm32(quint32(JITAssembler::ValueTypeInternal::Integer)));
- convertIntToDouble(source, target);
- Jump intDone = _as->jump();
-
- // not an int, check if it's NOT a double:
- isNoInt.link(_as);
- Jump isDbl = _as->generateIsDoubleCheck(JITTargetPlatform::ScratchRegister);
-
- generateRuntimeCall(_as, target, toDouble, PointerToValue(source));
- Jump noDoubleDone = _as->jump();
-
- // it is a double:
- isDbl.link(_as);
- Pointer addr2 = _as->loadAddress(JITTargetPlatform::ScratchRegister, source);
- IR::Temp *targetTemp = target->asTemp();
- if (!targetTemp || targetTemp->kind == IR::Temp::StackSlot) {
- _as->memcopyValue(target, addr2, JITTargetPlatform::FPGpr0, JITTargetPlatform::ReturnValueRegister);
- } else {
- _as->loadDouble(addr2, (FPRegisterID) targetTemp->index);
- }
-
- noDoubleDone.link(_as);
- intDone.link(_as);
- } break;
- default:
- convertTypeSlowPath(source, target);
- break;
- }
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::convertTypeToBool(IR::Expr *source, IR::Expr *target)
-{
- IR::Temp *sourceTemp = source->asTemp();
- switch (source->type) {
- case IR::SInt32Type:
- case IR::UInt32Type:
- convertIntToBool(source, target);
- break;
- case IR::DoubleType: {
- // The source is in a register if the register allocator is used. If the register
- // allocator was not used, then that means that we can use any register for to
- // load the double into.
- FPRegisterID reg;
- if (sourceTemp && sourceTemp->kind == IR::Temp::PhysicalRegister)
- reg = (FPRegisterID) sourceTemp->index;
- else
- reg = _as->toDoubleRegister(source, (FPRegisterID) 1);
- Jump nonZero = _as->branchDoubleNonZero(reg, JITTargetPlatform::FPGpr0);
-
- // it's 0, so false:
- _as->storeBool(false, target);
- Jump done = _as->jump();
-
- // it's non-zero, so true:
- nonZero.link(_as);
- _as->storeBool(true, target);
-
- // done:
- done.link(_as);
- } break;
- case IR::UndefinedType:
- case IR::NullType:
- _as->storeBool(false, target);
- break;
- case IR::StringType:
- generateRuntimeCall(_as, JITTargetPlatform::ReturnValueRegister, toBoolean,
- PointerToValue(source));
- _as->storeBool(JITTargetPlatform::ReturnValueRegister, target);
- Q_FALLTHROUGH();
- case IR::VarType:
- default:
- Pointer addr = _as->loadAddress(JITTargetPlatform::ScratchRegister, source);
- Pointer tagAddr = addr;
- tagAddr.offset += 4;
- _as->load32(tagAddr, JITTargetPlatform::ReturnValueRegister);
-
- // checkif it's a bool:
- Jump notBool = _as->branch32(RelationalCondition::NotEqual, JITTargetPlatform::ReturnValueRegister,
- TrustedImm32(quint32(JITAssembler::ValueTypeInternal::Boolean)));
- _as->load32(addr, JITTargetPlatform::ReturnValueRegister);
- Jump boolDone = _as->jump();
- // check if it's an int32:
- notBool.link(_as);
- Jump fallback = _as->branch32(RelationalCondition::NotEqual, JITTargetPlatform::ReturnValueRegister,
- TrustedImm32(quint32(JITAssembler::ValueTypeInternal::Integer)));
- _as->load32(addr, JITTargetPlatform::ReturnValueRegister);
- Jump isZero = _as->branch32(RelationalCondition::Equal, JITTargetPlatform::ReturnValueRegister,
- TrustedImm32(0));
- _as->move(TrustedImm32(1), JITTargetPlatform::ReturnValueRegister);
- Jump intDone = _as->jump();
-
- // not an int:
- fallback.link(_as);
- generateRuntimeCall(_as, JITTargetPlatform::ReturnValueRegister, toBoolean,
- PointerToValue(source));
-
- isZero.link(_as);
- intDone.link(_as);
- boolDone.link(_as);
- _as->storeBool(JITTargetPlatform::ReturnValueRegister, target);
-
- break;
- }
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::convertTypeToSInt32(IR::Expr *source, IR::Expr *target)
-{
- switch (source->type) {
- case IR::VarType: {
- JITAssembler::RegisterSizeDependentOps::convertVarToSInt32(_as, source, target);
- } break;
- case IR::DoubleType: {
- Jump success =
- _as->branchTruncateDoubleToInt32(_as->toDoubleRegister(source),
- JITTargetPlatform::ReturnValueRegister,
- BranchTruncateType::BranchIfTruncateSuccessful);
- generateRuntimeCall(_as, JITTargetPlatform::ReturnValueRegister, doubleToInt,
- PointerToValue(source));
- success.link(_as);
- _as->storeInt32(JITTargetPlatform::ReturnValueRegister, target);
- } break;
- case IR::UInt32Type:
- _as->storeInt32(_as->toUInt32Register(source, JITTargetPlatform::ReturnValueRegister), target);
- break;
- case IR::NullType:
- case IR::UndefinedType:
- _as->move(TrustedImm32(0), JITTargetPlatform::ReturnValueRegister);
- _as->storeInt32(JITTargetPlatform::ReturnValueRegister, target);
- break;
- case IR::BoolType:
- _as->storeInt32(_as->toInt32Register(source, JITTargetPlatform::ReturnValueRegister), target);
- break;
- case IR::StringType:
- default:
- generateRuntimeCall(_as, JITTargetPlatform::ReturnValueRegister, toInt,
- _as->loadAddress(JITTargetPlatform::ScratchRegister, source));
- _as->storeInt32(JITTargetPlatform::ReturnValueRegister, target);
- break;
- } // switch (source->type)
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::convertTypeToUInt32(IR::Expr *source, IR::Expr *target)
-{
- switch (source->type) {
- case IR::VarType: {
- // load the tag:
- Pointer tagAddr = _as->loadAddress(JITTargetPlatform::ScratchRegister, source);
- tagAddr.offset += 4;
- _as->load32(tagAddr, JITTargetPlatform::ScratchRegister);
-
- // check if it's an int32:
- Jump isNoInt = _as->branch32(RelationalCondition::NotEqual, JITTargetPlatform::ScratchRegister,
- TrustedImm32(quint32(JITAssembler::ValueTypeInternal::Integer)));
- Pointer addr = _as->loadAddress(JITTargetPlatform::ScratchRegister, source);
- _as->storeUInt32(_as->toInt32Register(addr, JITTargetPlatform::ScratchRegister), target);
- Jump intDone = _as->jump();
-
- // not an int:
- isNoInt.link(_as);
- generateRuntimeCall(_as, JITTargetPlatform::ReturnValueRegister, toUInt,
- _as->loadAddress(JITTargetPlatform::ScratchRegister, source));
- _as->storeInt32(JITTargetPlatform::ReturnValueRegister, target);
-
- intDone.link(_as);
- } break;
- case IR::DoubleType: {
- FPRegisterID reg = _as->toDoubleRegister(source);
- Jump success =
- _as->branchTruncateDoubleToUint32(reg, JITTargetPlatform::ReturnValueRegister,
- BranchTruncateType::BranchIfTruncateSuccessful);
- generateRuntimeCall(_as, JITTargetPlatform::ReturnValueRegister, doubleToUInt,
- PointerToValue(source));
- success.link(_as);
- _as->storeUInt32(JITTargetPlatform::ReturnValueRegister, target);
- } break;
- case IR::NullType:
- case IR::UndefinedType:
- _as->move(TrustedImm32(0), JITTargetPlatform::ReturnValueRegister);
- _as->storeUInt32(JITTargetPlatform::ReturnValueRegister, target);
- break;
- case IR::StringType:
- generateRuntimeCall(_as, JITTargetPlatform::ReturnValueRegister, toUInt,
- PointerToValue(source));
- _as->storeUInt32(JITTargetPlatform::ReturnValueRegister, target);
- break;
- case IR::SInt32Type:
- case IR::BoolType:
- _as->storeUInt32(_as->toInt32Register(source, JITTargetPlatform::ReturnValueRegister), target);
- break;
- default:
- break;
- } // switch (source->type)
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::constructActivationProperty(IR::Name *func, IR::ExprList *args, IR::Expr *result)
-{
- Q_ASSERT(func != 0);
- prepareCallData(args, 0);
-
- if ((useFastLookups || func->forceLookup) && func->global) {
- uint index = registerGlobalGetterLookup(*func->id);
- generateRuntimeCall(_as, result, constructGlobalLookup,
- JITTargetPlatform::EngineRegister,
- TrustedImm32(index), baseAddressForCallData());
- return;
- }
-
- generateRuntimeCall(_as, result, constructActivationProperty,
- JITTargetPlatform::EngineRegister,
- StringToIndex(*func->id),
- baseAddressForCallData());
-}
-
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::constructProperty(IR::Expr *base, const QString &name, IR::ExprList *args, IR::Expr *result)
-{
- prepareCallData(args, base);
- if (useFastLookups) {
- uint index = registerGetterLookup(name);
- generateRuntimeCall(_as, result, constructPropertyLookup,
- JITTargetPlatform::EngineRegister,
- TrustedImm32(index),
- baseAddressForCallData());
- return;
- }
-
- generateRuntimeCall(_as, result, constructProperty, JITTargetPlatform::EngineRegister,
- StringToIndex(name),
- baseAddressForCallData());
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::constructValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result)
-{
- Q_ASSERT(value != 0);
-
- prepareCallData(args, 0);
- generateRuntimeCall(_as, result, constructValue,
- JITTargetPlatform::EngineRegister,
- Reference(value),
- baseAddressForCallData());
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::visitJump(IR::Jump *s)
-{
- if (!_removableJumps.at(_block->index()))
- _as->jumpToBlock(_block, s->target);
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::visitCJump(IR::CJump *s)
-{
- IR::Temp *t = s->cond->asTemp();
- if (t || s->cond->asArgLocal()) {
- RegisterID reg;
- if (t && t->kind == IR::Temp::PhysicalRegister) {
- Q_ASSERT(t->type == IR::BoolType);
- reg = (RegisterID) t->index;
- } else if (t && t->kind == IR::Temp::StackSlot && t->type == IR::BoolType) {
- reg = JITTargetPlatform::ReturnValueRegister;
- _as->toInt32Register(t, reg);
- } else {
- Address temp = _as->loadAddress(JITTargetPlatform::ScratchRegister, s->cond);
- Address tag = temp;
- tag.offset += QV4::Value::tagOffset();
- Jump booleanConversion = _as->branch32(RelationalCondition::NotEqual, tag,
- TrustedImm32(quint32(JITAssembler::ValueTypeInternal::Boolean)));
-
- Address data = temp;
- data.offset += QV4::Value::valueOffset();
- _as->load32(data, JITTargetPlatform::ReturnValueRegister);
- Jump testBoolean = _as->jump();
-
- booleanConversion.link(_as);
- reg = JITTargetPlatform::ReturnValueRegister;
- generateRuntimeCall(_as, reg, toBoolean, Reference(s->cond));
-
- testBoolean.link(_as);
- }
-
- _as->generateCJumpOnNonZero(reg, _block, s->iftrue, s->iffalse);
- return;
- } else if (IR::Const *c = s->cond->asConst()) {
- // TODO: SSA optimization for constant condition evaluation should remove this.
- // See also visitCJump() in RegAllocInfo.
- generateRuntimeCall(_as, JITTargetPlatform::ReturnValueRegister, toBoolean,
- PointerToValue(c));
- _as->generateCJumpOnNonZero(JITTargetPlatform::ReturnValueRegister, _block, s->iftrue, s->iffalse);
- return;
- } else if (IR::Binop *b = s->cond->asBinop()) {
- if (b->left->type == IR::DoubleType && b->right->type == IR::DoubleType
- && visitCJumpDouble(b->op, b->left, b->right, s->iftrue, s->iffalse))
- return;
-
- if (b->left->type == IR::SInt32Type && b->right->type == IR::SInt32Type
- && visitCJumpSInt32(b->op, b->left, b->right, s->iftrue, s->iffalse))
- return;
-
- if (b->op == IR::OpStrictEqual || b->op == IR::OpStrictNotEqual) {
- visitCJumpStrict(b, s->iftrue, s->iffalse);
- return;
- }
- if (b->op == IR::OpEqual || b->op == IR::OpNotEqual) {
- visitCJumpEqual(b, s->iftrue, s->iffalse);
- return;
- }
-
- typename JITAssembler::RuntimeCall op;
- typename JITAssembler::RuntimeCall opContext;
- const char *opName = 0;
- bool needsExceptionCheck;
- switch (b->op) {
- default: Q_UNREACHABLE(); Q_ASSERT(!"todo"); break;
- case IR::OpGt: setOp(op, opName, compareGreaterThan); break;
- case IR::OpLt: setOp(op, opName, compareLessThan); break;
- case IR::OpGe: setOp(op, opName, compareGreaterEqual); break;
- case IR::OpLe: setOp(op, opName, compareLessEqual); break;
- case IR::OpEqual: setOp(op, opName, compareEqual); break;
- case IR::OpNotEqual: setOp(op, opName, compareNotEqual); break;
- case IR::OpStrictEqual: setOp(op, opName, compareStrictEqual); break;
- case IR::OpStrictNotEqual: setOp(op, opName, compareStrictNotEqual); break;
- case IR::OpInstanceof: setOpContext(op, opName, compareInstanceof); break;
- case IR::OpIn: setOpContext(op, opName, compareIn); break;
- } // switch
-
- // TODO: in SSA optimization, do constant expression evaluation.
- // The case here is, for example:
- // if (true === true) .....
- // Of course, after folding the CJUMP to a JUMP, dead-code (dead-basic-block)
- // elimination (which isn't there either) would remove the whole else block.
- if (opContext.isValid())
- _as->generateFunctionCallImp(needsExceptionCheck,
- JITTargetPlatform::ReturnValueRegister, opName, opContext,
- JITTargetPlatform::EngineRegister,
- PointerToValue(b->left),
- PointerToValue(b->right));
- else
- _as->generateFunctionCallImp(needsExceptionCheck,
- JITTargetPlatform::ReturnValueRegister, opName, op,
- PointerToValue(b->left),
- PointerToValue(b->right));
-
- _as->generateCJumpOnNonZero(JITTargetPlatform::ReturnValueRegister, _block, s->iftrue, s->iffalse);
- return;
- }
- Q_UNREACHABLE();
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::visitRet(IR::Ret *s)
-{
- _as->returnFromFunction(s, regularRegistersToSave, fpRegistersToSave);
-}
-
-template <typename JITAssembler>
-int InstructionSelection<JITAssembler>::prepareVariableArguments(IR::ExprList* args)
-{
- int argc = 0;
- for (IR::ExprList *it = args; it; it = it->next) {
- ++argc;
- }
-
- int i = 0;
- for (IR::ExprList *it = args; it; it = it->next, ++i) {
- IR::Expr *arg = it->expr;
- Q_ASSERT(arg != 0);
- Pointer dst(_as->stackLayout().argumentAddressForCall(i));
- if (arg->asTemp() && arg->asTemp()->kind != IR::Temp::PhysicalRegister)
- _as->memcopyValue(dst, arg->asTemp(), JITTargetPlatform::ScratchRegister);
- else
- _as->copyValue(dst, arg);
- }
-
- return argc;
-}
-
-template <typename JITAssembler>
-int InstructionSelection<JITAssembler>::prepareCallData(IR::ExprList* args, IR::Expr *thisObject)
-{
- int argc = 0;
- for (IR::ExprList *it = args; it; it = it->next) {
- ++argc;
- }
-
- Pointer p = _as->stackLayout().callDataAddress(offsetof(CallData, tag));
- _as->store32(TrustedImm32(quint32(JITAssembler::ValueTypeInternal::Integer)), p);
- p = _as->stackLayout().callDataAddress(offsetof(CallData, argc));
- _as->store32(TrustedImm32(argc), p);
- p = _as->stackLayout().callDataAddress(offsetof(CallData, thisObject));
- if (!thisObject)
- _as->storeValue(JITAssembler::TargetPrimitive::undefinedValue(), p);
- else
- _as->copyValue(p, thisObject);
-
- int i = 0;
- for (IR::ExprList *it = args; it; it = it->next, ++i) {
- IR::Expr *arg = it->expr;
- Q_ASSERT(arg != 0);
- Pointer dst(_as->stackLayout().argumentAddressForCall(i));
- if (arg->asTemp() && arg->asTemp()->kind != IR::Temp::PhysicalRegister)
- _as->memcopyValue(dst, arg->asTemp(), JITTargetPlatform::ScratchRegister);
- else
- _as->copyValue(dst, arg);
- }
- return argc;
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::calculateRegistersToSave(const RegisterInformation &used)
-{
- regularRegistersToSave.clear();
- fpRegistersToSave.clear();
-
- for (const RegisterInfo &ri : JITTargetPlatform::getRegisterInfo()) {
- if (JITTargetPlatform::gotRegister != -1 && ri.isRegularRegister() && ri.reg<RegisterID>() == JITTargetPlatform::gotRegister) {
- regularRegistersToSave.append(ri);
- continue;
- }
- if (ri.isCallerSaved())
- continue;
- if (ri.isRegularRegister()) {
- if (ri.isPredefined() || used.contains(ri))
- regularRegistersToSave.append(ri);
- } else {
- Q_ASSERT(ri.isFloatingPoint());
- if (ri.isPredefined() || used.contains(ri))
- fpRegistersToSave.append(ri);
- }
- }
-}
-
-QT_BEGIN_NAMESPACE
-namespace QV4 {
-bool operator==(const Primitive &v1, const Primitive &v2)
-{
- return v1.rawValue() == v2.rawValue();
-}
-} // QV4 namespace
-QT_END_NAMESPACE
-
-template <typename JITAssembler>
-bool InstructionSelection<JITAssembler>::visitCJumpDouble(IR::AluOp op, IR::Expr *left, IR::Expr *right,
- IR::BasicBlock *iftrue, IR::BasicBlock *iffalse)
-{
- if (_as->nextBlock() == iftrue) {
- Jump target = _as->branchDouble(true, op, left, right);
- _as->addPatch(iffalse, target);
- } else {
- Jump target = _as->branchDouble(false, op, left, right);
- _as->addPatch(iftrue, target);
- _as->jumpToBlock(_block, iffalse);
- }
- return true;
-}
-
-template <typename JITAssembler>
-bool InstructionSelection<JITAssembler>::visitCJumpSInt32(IR::AluOp op, IR::Expr *left, IR::Expr *right,
- IR::BasicBlock *iftrue, IR::BasicBlock *iffalse)
-{
- if (_as->nextBlock() == iftrue) {
- Jump target = _as->branchInt32(true, op, left, right);
- _as->addPatch(iffalse, target);
- } else {
- Jump target = _as->branchInt32(false, op, left, right);
- _as->addPatch(iftrue, target);
- _as->jumpToBlock(_block, iffalse);
- }
- return true;
-}
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::visitCJumpStrict(IR::Binop *binop, IR::BasicBlock *trueBlock,
- IR::BasicBlock *falseBlock)
-{
- Q_ASSERT(binop->op == IR::OpStrictEqual || binop->op == IR::OpStrictNotEqual);
-
- if (visitCJumpStrictNull(binop, trueBlock, falseBlock))
- return;
- if (visitCJumpStrictUndefined(binop, trueBlock, falseBlock))
- return;
- if (visitCJumpStrictBool(binop, trueBlock, falseBlock))
- return;
-
- IR::Expr *left = binop->left;
- IR::Expr *right = binop->right;
-
- generateRuntimeCall(_as, JITTargetPlatform::ReturnValueRegister, compareStrictEqual,
- PointerToValue(left), PointerToValue(right));
- _as->generateCJumpOnCompare(binop->op == IR::OpStrictEqual ? RelationalCondition::NotEqual : RelationalCondition::Equal,
- JITTargetPlatform::ReturnValueRegister, TrustedImm32(0),
- _block, trueBlock, falseBlock);
-}
-
-// Only load the non-null temp.
-template <typename JITAssembler>
-bool InstructionSelection<JITAssembler>::visitCJumpStrictNull(IR::Binop *binop,
- IR::BasicBlock *trueBlock,
- IR::BasicBlock *falseBlock)
-{
- IR::Expr *varSrc = 0;
- if (binop->left->type == IR::VarType && binop->right->type == IR::NullType)
- varSrc = binop->left;
- else if (binop->left->type == IR::NullType && binop->right->type == IR::VarType)
- varSrc = binop->right;
- if (!varSrc)
- return false;
-
- if (varSrc->asTemp() && varSrc->asTemp()->kind == IR::Temp::PhysicalRegister) {
- _as->jumpToBlock(_block, falseBlock);
- return true;
- }
-
- if (IR::Const *c = varSrc->asConst()) {
- if (c->type == IR::NullType)
- _as->jumpToBlock(_block, trueBlock);
- else
- _as->jumpToBlock(_block, falseBlock);
- return true;
- }
-
- Pointer tagAddr = _as->loadAddress(JITTargetPlatform::ScratchRegister, varSrc);
- tagAddr.offset += 4;
- const RegisterID tagReg = JITTargetPlatform::ScratchRegister;
- _as->load32(tagAddr, tagReg);
-
- RelationalCondition cond = binop->op == IR::OpStrictEqual ? RelationalCondition::Equal
- : RelationalCondition::NotEqual;
- const TrustedImm32 tag{quint32(JITAssembler::ValueTypeInternal::Null)};
- _as->generateCJumpOnCompare(cond, tagReg, tag, _block, trueBlock, falseBlock);
- return true;
-}
-
-template <typename JITAssembler>
-bool InstructionSelection<JITAssembler>::visitCJumpStrictUndefined(IR::Binop *binop,
- IR::BasicBlock *trueBlock,
- IR::BasicBlock *falseBlock)
-{
- IR::Expr *varSrc = 0;
- if (binop->left->type == IR::VarType && binop->right->type == IR::UndefinedType)
- varSrc = binop->left;
- else if (binop->left->type == IR::UndefinedType && binop->right->type == IR::VarType)
- varSrc = binop->right;
- if (!varSrc)
- return false;
-
- if (varSrc->asTemp() && varSrc->asTemp()->kind == IR::Temp::PhysicalRegister) {
- _as->jumpToBlock(_block, falseBlock);
- return true;
- }
-
- if (IR::Const *c = varSrc->asConst()) {
- if (c->type == IR::UndefinedType)
- _as->jumpToBlock(_block, trueBlock);
- else
- _as->jumpToBlock(_block, falseBlock);
- return true;
- }
-
- RelationalCondition cond = binop->op == IR::OpStrictEqual ? RelationalCondition::Equal
- : RelationalCondition::NotEqual;
- const RegisterID tagReg = JITTargetPlatform::ReturnValueRegister;
- _as->generateCJumpOnUndefined(cond, varSrc, JITTargetPlatform::ScratchRegister, tagReg, _block, trueBlock, falseBlock);
- return true;
-}
-
-template <typename JITAssembler>
-bool InstructionSelection<JITAssembler>::visitCJumpStrictBool(IR::Binop *binop, IR::BasicBlock *trueBlock,
- IR::BasicBlock *falseBlock)
-{
- IR::Expr *boolSrc = 0, *otherSrc = 0;
- if (binop->left->type == IR::BoolType) {
- boolSrc = binop->left;
- otherSrc = binop->right;
- } else if (binop->right->type == IR::BoolType) {
- boolSrc = binop->right;
- otherSrc = binop->left;
- } else {
- // neither operands are statically typed as bool, so bail out.
- return false;
- }
- if (otherSrc->type == IR::UnknownType) {
- // Ok, we really need to call into the runtime.
- // (This case doesn't happen when the optimizer ran, because everything will be typed (yes,
- // possibly as "var" meaning anything), but it does happen for $0===true, which is generated
- // for things where the optimizer didn't run (like functions with a try block).)
- return false;
- }
-
- RelationalCondition cond = binop->op == IR::OpStrictEqual ? RelationalCondition::Equal
- : RelationalCondition::NotEqual;
-
- if (otherSrc->type == IR::BoolType) { // both are boolean
- RegisterID one = _as->toBoolRegister(boolSrc, JITTargetPlatform::ReturnValueRegister);
- RegisterID two = _as->toBoolRegister(otherSrc, JITTargetPlatform::ScratchRegister);
- _as->generateCJumpOnCompare(cond, one, two, _block, trueBlock, falseBlock);
- return true;
- }
-
- if (otherSrc->type != IR::VarType) {
- _as->jumpToBlock(_block, falseBlock);
- return true;
- }
-
- Pointer otherAddr = _as->loadAddress(JITTargetPlatform::ReturnValueRegister, otherSrc);
- otherAddr.offset += 4; // tag address
-
- // check if the tag of the var operand is indicates 'boolean'
- _as->load32(otherAddr, JITTargetPlatform::ScratchRegister);
- Jump noBool = _as->branch32(RelationalCondition::NotEqual, JITTargetPlatform::ScratchRegister,
- TrustedImm32(quint32(JITAssembler::ValueTypeInternal::Boolean)));
- if (binop->op == IR::OpStrictEqual)
- _as->addPatch(falseBlock, noBool);
- else
- _as->addPatch(trueBlock, noBool);
-
- // ok, both are boolean, so let's load them and compare them.
- otherAddr.offset -= 4; // int_32 address
- _as->load32(otherAddr, JITTargetPlatform::ReturnValueRegister);
- RegisterID boolReg = _as->toBoolRegister(boolSrc, JITTargetPlatform::ScratchRegister);
- _as->generateCJumpOnCompare(cond, boolReg, JITTargetPlatform::ReturnValueRegister, _block, trueBlock,
- falseBlock);
- return true;
-}
-
-template <typename JITAssembler>
-bool InstructionSelection<JITAssembler>::visitCJumpNullUndefined(IR::Type nullOrUndef, IR::Binop *binop,
- IR::BasicBlock *trueBlock,
- IR::BasicBlock *falseBlock)
-{
- Q_ASSERT(nullOrUndef == IR::NullType || nullOrUndef == IR::UndefinedType);
-
- IR::Expr *varSrc = 0;
- if (binop->left->type == IR::VarType && binop->right->type == nullOrUndef)
- varSrc = binop->left;
- else if (binop->left->type == nullOrUndef && binop->right->type == IR::VarType)
- varSrc = binop->right;
- if (!varSrc)
- return false;
-
- if (varSrc->asTemp() && varSrc->asTemp()->kind == IR::Temp::PhysicalRegister) {
- _as->jumpToBlock(_block, falseBlock);
- return true;
- }
-
- if (IR::Const *c = varSrc->asConst()) {
- if (c->type == nullOrUndef)
- _as->jumpToBlock(_block, trueBlock);
- else
- _as->jumpToBlock(_block, falseBlock);
- return true;
- }
-
- Pointer tagAddr = _as->loadAddress(JITTargetPlatform::ScratchRegister, varSrc);
- tagAddr.offset += 4;
- const RegisterID tagReg = JITTargetPlatform::ReturnValueRegister;
- _as->load32(tagAddr, tagReg);
-
- if (binop->op == IR::OpNotEqual)
- qSwap(trueBlock, falseBlock);
- Jump isNull = _as->branch32(RelationalCondition::Equal, tagReg, TrustedImm32(quint32(JITAssembler::ValueTypeInternal::Null)));
- Jump isNotUndefinedTag = _as->branch32(RelationalCondition::NotEqual, tagReg, TrustedImm32(int(QV4::Value::Managed_Type_Internal)));
- tagAddr.offset -= 4;
- _as->load32(tagAddr, tagReg);
- Jump isNotUndefinedValue = _as->branch32(RelationalCondition::NotEqual, tagReg, TrustedImm32(0));
- _as->addPatch(trueBlock, isNull);
- _as->addPatch(falseBlock, isNotUndefinedTag);
- _as->addPatch(falseBlock, isNotUndefinedValue);
- _as->jumpToBlock(_block, trueBlock);
-
- return true;
-}
-
-
-template <typename JITAssembler>
-void InstructionSelection<JITAssembler>::visitCJumpEqual(IR::Binop *binop, IR::BasicBlock *trueBlock,
- IR::BasicBlock *falseBlock)
-{
- Q_ASSERT(binop->op == IR::OpEqual || binop->op == IR::OpNotEqual);
-
- if (visitCJumpNullUndefined(IR::NullType, binop, trueBlock, falseBlock))
- return;
-
- IR::Expr *left = binop->left;
- IR::Expr *right = binop->right;
-
- generateRuntimeCall(_as, JITTargetPlatform::ReturnValueRegister, compareEqual,
- PointerToValue(left), PointerToValue(right));
- _as->generateCJumpOnCompare(binop->op == IR::OpEqual ? RelationalCondition::NotEqual : RelationalCondition::Equal,
- JITTargetPlatform::ReturnValueRegister, TrustedImm32(0),
- _block, trueBlock, falseBlock);
-}
-
-template <typename JITAssembler>
-QQmlRefPointer<CompiledData::CompilationUnit> ISelFactory<JITAssembler>::createUnitForLoading()
-{
- QQmlRefPointer<CompiledData::CompilationUnit> result;
- result.adopt(new JIT::CompilationUnit);
- return result;
-}
-
-#endif // ENABLE(ASSEMBLER)
-
-QT_BEGIN_NAMESPACE
-namespace QV4 { namespace JIT {
-#if ENABLE(ASSEMBLER)
-template class Q_QML_EXPORT InstructionSelection<>;
-template class Q_QML_EXPORT ISelFactory<>;
-#endif
-
-#if defined(V4_BOOTSTRAP)
-
-Q_QML_EXPORT QV4::EvalISelFactory *createISelForArchitecture(const QString &architecture)
-{
-#if ENABLE(ASSEMBLER)
- using ARMv7CrossAssembler = QV4::JIT::Assembler<AssemblerTargetConfiguration<JSC::MacroAssemblerARMv7, NoOperatingSystemSpecialization>>;
- using ARM64CrossAssembler = QV4::JIT::Assembler<AssemblerTargetConfiguration<JSC::MacroAssemblerARM64, NoOperatingSystemSpecialization>>;
-
- if (architecture == QLatin1String("arm"))
- return new ISelFactory<ARMv7CrossAssembler>;
- else if (architecture == QLatin1String("arm64"))
- return new ISelFactory<ARM64CrossAssembler>;
-
- QString hostArch;
-#if CPU(ARM_THUMB2)
- hostArch = QStringLiteral("arm");
-#elif CPU(MIPS)
- hostArch = QStringLiteral("mips");
-#elif CPU(X86)
- hostArch = QStringLiteral("i386");
-#elif CPU(X86_64)
- hostArch = QStringLiteral("x86_64");
-#endif
- if (!hostArch.isEmpty() && architecture == hostArch)
- return new ISelFactory<>;
-#endif // ENABLE(ASSEMBLER)
-
- return nullptr;
-}
-
-#endif
-} }
-QT_END_NAMESPACE
-
diff --git a/src/qml/jit/qv4isel_masm_p.h b/src/qml/jit/qv4isel_masm_p.h
deleted file mode 100644
index 0992e96e8b..0000000000
--- a/src/qml/jit/qv4isel_masm_p.h
+++ /dev/null
@@ -1,313 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#ifndef QV4ISEL_MASM_P_H
-#define QV4ISEL_MASM_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "private/qv4global_p.h"
-#include "private/qv4jsir_p.h"
-#include "private/qv4isel_p.h"
-#include "private/qv4isel_util_p.h"
-#include "private/qv4util_p.h"
-#include "private/qv4value_p.h"
-#include "private/qv4lookup_p.h"
-
-#include <QtCore/QHash>
-#include <QtCore/QStack>
-#include <config.h>
-#include <wtf/Vector.h>
-
-#include "qv4assembler_p.h"
-
-#if ENABLE(ASSEMBLER)
-
-QT_BEGIN_NAMESPACE
-
-namespace QV4 {
-namespace JIT {
-
-template <typename JITAssembler = Assembler<DefaultAssemblerTargetConfiguration>>
-class Q_QML_EXPORT InstructionSelection:
- protected IR::IRDecoder,
- public EvalInstructionSelection
-{
-public:
- InstructionSelection(QQmlEnginePrivate *qmlEngine, QV4::ExecutableAllocator *execAllocator, IR::Module *module, QV4::Compiler::JSUnitGenerator *jsGenerator, EvalISelFactory *iselFactory);
- ~InstructionSelection();
-
- void run(int functionIndex) override;
-
-protected:
- QQmlRefPointer<QV4::CompiledData::CompilationUnit> backendCompileStep() override;
-
- void callBuiltinInvalid(IR::Name *func, IR::ExprList *args, IR::Expr *result) override;
- void callBuiltinTypeofQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int propertyIndex, IR::Expr *result) override;
- void callBuiltinTypeofMember(IR::Expr *base, const QString &name, IR::Expr *result) override;
- void callBuiltinTypeofSubscript(IR::Expr *base, IR::Expr *index, IR::Expr *result) override;
- void callBuiltinTypeofName(const QString &name, IR::Expr *result) override;
- void callBuiltinTypeofValue(IR::Expr *value, IR::Expr *result) override;
- void callBuiltinDeleteMember(IR::Expr *base, const QString &name, IR::Expr *result) override;
- void callBuiltinDeleteSubscript(IR::Expr *base, IR::Expr *index, IR::Expr *result) override;
- void callBuiltinDeleteName(const QString &name, IR::Expr *result) override;
- void callBuiltinDeleteValue(IR::Expr *result) override;
- void callBuiltinThrow(IR::Expr *arg) override;
- void callBuiltinReThrow() override;
- void callBuiltinUnwindException(IR::Expr *) override;
- void callBuiltinPushCatchScope(const QString &exceptionName) override;
- void callBuiltinForeachIteratorObject(IR::Expr *arg, IR::Expr *result) override;
- void callBuiltinForeachNextPropertyname(IR::Expr *arg, IR::Expr *result) override;
- void callBuiltinPushWithScope(IR::Expr *arg) override;
- void callBuiltinPopScope() override;
- void callBuiltinDeclareVar(bool deletable, const QString &name) override;
- void callBuiltinDefineArray(IR::Expr *result, IR::ExprList *args) override;
- void callBuiltinDefineObjectLiteral(IR::Expr *result, int keyValuePairCount, IR::ExprList *keyValuePairs, IR::ExprList *arrayEntries, bool needSparseArray) override;
- void callBuiltinSetupArgumentObject(IR::Expr *result) override;
- void callBuiltinConvertThisToObject() override;
- void callValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result) override;
- void callQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int propertyIndex, IR::ExprList *args, IR::Expr *result) override;
- void callProperty(IR::Expr *base, const QString &name, IR::ExprList *args, IR::Expr *result) override;
- void callSubscript(IR::Expr *base, IR::Expr *index, IR::ExprList *args, IR::Expr *result) override;
- void convertType(IR::Expr *source, IR::Expr *target) override;
- void loadThisObject(IR::Expr *temp) override;
- void loadQmlContext(IR::Expr *target) override;
- void loadQmlImportedScripts(IR::Expr *target) override;
- void loadQmlSingleton(const QString &name, IR::Expr *target) override;
- void loadConst(IR::Const *sourceConst, IR::Expr *target) override;
- void loadString(const QString &str, IR::Expr *target) override;
- void loadRegexp(IR::RegExp *sourceRegexp, IR::Expr *target) override;
- void getActivationProperty(const IR::Name *name, IR::Expr *target) override;
- void setActivationProperty(IR::Expr *source, const QString &targetName) override;
- void initClosure(IR::Closure *closure, IR::Expr *target) override;
- void getProperty(IR::Expr *base, const QString &name, IR::Expr *target) override;
- void getQmlContextProperty(IR::Expr *source, IR::Member::MemberKind kind, int index, bool captureRequired, IR::Expr *target) override;
- void getQObjectProperty(IR::Expr *base, int propertyIndex, bool captureRequired, bool isSingleton, int attachedPropertiesId, IR::Expr *target) override;
- void setProperty(IR::Expr *source, IR::Expr *targetBase, const QString &targetName) override;
- void setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase, IR::Member::MemberKind kind, int propertyIndex) override;
- void setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int propertyIndex) override;
- void getElement(IR::Expr *base, IR::Expr *index, IR::Expr *target) override;
- void setElement(IR::Expr *source, IR::Expr *targetBase, IR::Expr *targetIndex) override;
- void copyValue(IR::Expr *source, IR::Expr *target) override;
- void swapValues(IR::Expr *source, IR::Expr *target) override;
- void unop(IR::AluOp oper, IR::Expr *sourceTemp, IR::Expr *target) override;
- void binop(IR::AluOp oper, IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target) override;
-
- using Address = typename JITAssembler::Address;
- using Pointer = typename JITAssembler::Pointer;
- using PointerToValue = typename JITAssembler::PointerToValue;
- using RegisterID = typename JITAssembler::RegisterID;
- using FPRegisterID = typename JITAssembler::FPRegisterID;
- using ResultCondition = typename JITAssembler::ResultCondition;
- using TrustedImm32 = typename JITAssembler::TrustedImm32;
- using TrustedImm64 = typename JITAssembler::TrustedImm64;
- using Label = typename JITAssembler::Label;
- using Jump = typename JITAssembler::Jump;
- using StringToIndex = typename JITAssembler::StringToIndex;
- using Reference = typename JITAssembler::Reference;
- using RelationalCondition = typename JITAssembler::RelationalCondition;
- using BranchTruncateType = typename JITAssembler::BranchTruncateType;
- using RuntimeCall = typename JITAssembler::RuntimeCall;
-
- using JITTargetPlatform = typename JITAssembler::JITTargetPlatform;
-
- Address addressForArgument(int index) const
- {
- // FramePointerRegister points to its old value on the stack, and above
- // it we have the return address, hence the need to step over two
- // values before reaching the first argument.
- return Address(JITTargetPlatform::FramePointerRegister, (index + 2) * JITTargetPlatform::RegisterSize);
- }
-
- Pointer baseAddressForCallArguments()
- {
- return _as->stackLayout().argumentAddressForCall(0);
- }
-
- Pointer baseAddressForCallData()
- {
- return _as->stackLayout().callDataAddress();
- }
-
- void constructActivationProperty(IR::Name *func, IR::ExprList *args, IR::Expr *result) override;
- void constructProperty(IR::Expr *base, const QString &name, IR::ExprList *args, IR::Expr*result) override;
- void constructValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result) override;
-
- void visitJump(IR::Jump *) override;
- void visitCJump(IR::CJump *) override;
- void visitRet(IR::Ret *) override;
-
- bool visitCJumpDouble(IR::AluOp op, IR::Expr *left, IR::Expr *right,
- IR::BasicBlock *iftrue, IR::BasicBlock *iffalse);
- bool visitCJumpSInt32(IR::AluOp op, IR::Expr *left, IR::Expr *right,
- IR::BasicBlock *iftrue, IR::BasicBlock *iffalse);
- void visitCJumpStrict(IR::Binop *binop, IR::BasicBlock *trueBlock, IR::BasicBlock *falseBlock);
- bool visitCJumpStrictNull(IR::Binop *binop, IR::BasicBlock *trueBlock, IR::BasicBlock *falseBlock);
- bool visitCJumpStrictUndefined(IR::Binop *binop, IR::BasicBlock *trueBlock, IR::BasicBlock *falseBlock);
- bool visitCJumpStrictBool(IR::Binop *binop, IR::BasicBlock *trueBlock, IR::BasicBlock *falseBlock);
- bool visitCJumpNullUndefined(IR::Type nullOrUndef, IR::Binop *binop,
- IR::BasicBlock *trueBlock, IR::BasicBlock *falseBlock);
- void visitCJumpEqual(IR::Binop *binop, IR::BasicBlock *trueBlock, IR::BasicBlock *falseBlock);
-
-private:
- void convertTypeSlowPath(IR::Expr *source, IR::Expr *target);
- void convertTypeToDouble(IR::Expr *source, IR::Expr *target);
- void convertTypeToBool(IR::Expr *source, IR::Expr *target);
- void convertTypeToSInt32(IR::Expr *source, IR::Expr *target);
- void convertTypeToUInt32(IR::Expr *source, IR::Expr *target);
-
- void convertIntToDouble(IR::Expr *source, IR::Expr *target)
- {
- if (IR::Temp *targetTemp = target->asTemp()) {
- if (targetTemp->kind == IR::Temp::PhysicalRegister) {
- if (IR::Temp *sourceTemp = source->asTemp()) {
- if (sourceTemp->kind == IR::Temp::PhysicalRegister) {
- _as->convertInt32ToDouble((RegisterID) sourceTemp->index,
- (FPRegisterID) targetTemp->index);
- } else {
- _as->convertInt32ToDouble(_as->loadAddress(JITTargetPlatform::ReturnValueRegister, sourceTemp),
- (FPRegisterID) targetTemp->index);
- }
- } else {
- _as->convertInt32ToDouble(_as->toInt32Register(source, JITTargetPlatform::ScratchRegister),
- (FPRegisterID) targetTemp->index);
- }
-
- return;
- }
- }
-
- _as->convertInt32ToDouble(_as->toInt32Register(source, JITTargetPlatform::ScratchRegister),
- JITTargetPlatform::FPGpr0);
- _as->storeDouble(JITTargetPlatform::FPGpr0, _as->loadAddress(JITTargetPlatform::ReturnValueRegister, target));
- }
-
- void convertUIntToDouble(IR::Expr *source, IR::Expr *target)
- {
- RegisterID tmpReg = JITTargetPlatform::ScratchRegister;
- RegisterID reg = _as->toInt32Register(source, tmpReg);
-
- if (IR::Temp *targetTemp = target->asTemp()) {
- if (targetTemp->kind == IR::Temp::PhysicalRegister) {
- _as->convertUInt32ToDouble(reg, (FPRegisterID) targetTemp->index, tmpReg);
- return;
- }
- }
-
- _as->convertUInt32ToDouble(_as->toUInt32Register(source, tmpReg),
- JITTargetPlatform::FPGpr0, tmpReg);
- _as->storeDouble(JITTargetPlatform::FPGpr0, _as->loadAddress(tmpReg, target));
- }
-
- void convertIntToBool(IR::Expr *source, IR::Expr *target)
- {
- RegisterID reg = JITTargetPlatform::ScratchRegister;
-
- if (IR::Temp *targetTemp = target->asTemp())
- if (targetTemp->kind == IR::Temp::PhysicalRegister)
- reg = (RegisterID) targetTemp->index;
- _as->move(_as->toInt32Register(source, reg), reg);
- _as->compare32(RelationalCondition::NotEqual, reg, TrustedImm32(0), reg);
- _as->storeBool(reg, target);
- }
-
- int prepareVariableArguments(IR::ExprList* args);
- int prepareCallData(IR::ExprList* args, IR::Expr *thisObject);
-
- void calculateRegistersToSave(const RegisterInformation &used);
-
- template <typename Retval, typename Arg1, typename Arg2, typename Arg3>
- void generateLookupCall(Retval retval, uint index, uint getterSetterOffset, Arg1 arg1, Arg2 arg2, Arg3 arg3)
- {
- // Note: using the return value register is intentional: for ABIs where the first parameter
- // goes into the same register as the return value (currently only ARM), the prepareCall
- // will combine loading the looupAddr into the register and calculating the indirect call
- // address.
- Pointer lookupAddr(JITTargetPlatform::ReturnValueRegister, index * sizeof(QV4::Lookup));
-
- _as->generateFunctionCallImp(true, retval, "lookup getter/setter",
- typename JITAssembler::LookupCall(lookupAddr, getterSetterOffset), lookupAddr,
- arg1, arg2, arg3);
- }
-
- template <typename Retval, typename Arg1, typename Arg2>
- void generateLookupCall(Retval retval, uint index, uint getterSetterOffset, Arg1 arg1, Arg2 arg2)
- {
- generateLookupCall(retval, index, getterSetterOffset, arg1, arg2, typename JITAssembler::VoidType());
- }
-
- IR::BasicBlock *_block;
- BitVector _removableJumps;
- JITAssembler* _as;
-
- QScopedPointer<CompilationUnit> compilationUnit;
- QQmlEnginePrivate *qmlEngine;
- RegisterInformation regularRegistersToSave;
- RegisterInformation fpRegistersToSave;
-};
-
-template <typename JITAssembler = Assembler<DefaultAssemblerTargetConfiguration>>
-class Q_QML_EXPORT ISelFactory: public EvalISelFactory
-{
-public:
- ISelFactory() : EvalISelFactory(QStringLiteral("jit")) {}
- virtual ~ISelFactory() {}
- EvalInstructionSelection *create(QQmlEnginePrivate *qmlEngine, QV4::ExecutableAllocator *execAllocator, IR::Module *module, QV4::Compiler::JSUnitGenerator *jsGenerator) Q_DECL_OVERRIDE Q_DECL_FINAL
- { return new InstructionSelection<JITAssembler>(qmlEngine, execAllocator, module, jsGenerator, this); }
- bool jitCompileRegexps() const Q_DECL_OVERRIDE Q_DECL_FINAL
- { return true; }
- QQmlRefPointer<CompiledData::CompilationUnit> createUnitForLoading() Q_DECL_OVERRIDE Q_DECL_FINAL;
-};
-
-} // end of namespace JIT
-} // end of namespace QV4
-
-QT_END_NAMESPACE
-
-#endif // ENABLE(ASSEMBLER)
-
-#endif // QV4ISEL_MASM_P_H
diff --git a/src/qml/jit/qv4jit.cpp b/src/qml/jit/qv4jit.cpp
new file mode 100644
index 0000000000..1ab45d6765
--- /dev/null
+++ b/src/qml/jit/qv4jit.cpp
@@ -0,0 +1,1309 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qv4jit_p.h"
+#include "qv4assembler_p.h"
+#include <private/qv4lookup_p.h>
+
+#ifdef V4_ENABLE_JIT
+
+QT_USE_NAMESPACE
+using namespace QV4;
+using namespace QV4::JIT;
+using namespace QV4::Moth;
+
+ByteCodeHandler::~ByteCodeHandler()
+{
+}
+
+#define DISPATCH_INSTRUCTION(name, nargs, ...) \
+ generate_##name( \
+ __VA_ARGS__ \
+ );
+
+#define DECODE_AND_DISPATCH(instr) \
+ { \
+ INSTR_##instr(MOTH_DECODE_WITH_BASE) \
+ Q_UNUSED(base_ptr); \
+ startInstruction(Instr::Type::instr); \
+ _offset = code - start; \
+ INSTR_##instr(DISPATCH) \
+ endInstruction(Instr::Type::instr); \
+ continue; \
+ }
+
+void ByteCodeHandler::decode(const char *code, uint len)
+{
+ MOTH_JUMP_TABLE;
+
+ const char *start = code;
+ const char *end = code + len;
+ while (code < end) {
+ MOTH_DISPATCH()
+
+ FOR_EACH_MOTH_INSTR(DECODE_AND_DISPATCH)
+ }
+}
+
+#undef DECODE_AND_DISPATCH
+#undef DISPATCH_INSTRUCTION
+
+BaselineJIT::BaselineJIT(Function *function)
+ : function(function)
+ , as(new Assembler(function->compilationUnit->constants))
+{}
+
+BaselineJIT::~BaselineJIT()
+{}
+
+void BaselineJIT::generate()
+{
+// qDebug()<<"jitting" << function->name()->toQString();
+ collectLabelsInBytecode();
+
+ as->generatePrologue();
+ decode(reinterpret_cast<const char *>(function->codeData), function->compiledFunction->codeSize);
+ as->generateEpilogue();
+
+ as->link(function);
+// qDebug()<<"done";
+}
+
+#define STORE_IP() as->storeInstructionPointer(instructionOffset())
+#define STORE_ACC() as->saveAccumulatorInFrame()
+
+void BaselineJIT::generate_Ret()
+{
+ as->ret();
+}
+
+void BaselineJIT::generate_Debug() { Q_UNREACHABLE(); }
+
+void BaselineJIT::generate_LoadConst(int index)
+{
+ as->loadConst(index);
+}
+
+void BaselineJIT::generate_LoadZero()
+{
+ as->loadValue(Encode(int(0)));
+}
+
+void BaselineJIT::generate_LoadTrue()
+{
+ as->loadValue(Encode(true));
+}
+
+void BaselineJIT::generate_LoadFalse()
+{
+ as->loadValue(Encode(false));
+}
+
+void BaselineJIT::generate_LoadNull()
+{
+ as->loadValue(Encode::null());
+}
+
+void BaselineJIT::generate_LoadUndefined()
+{
+ as->loadValue(Encode::undefined());
+}
+
+void BaselineJIT::generate_LoadInt(int value)
+{
+ //###
+ as->loadValue(Encode(value));
+}
+
+void BaselineJIT::generate_MoveConst(int constIndex, int destTemp)
+{
+ as->copyConst(constIndex, destTemp);
+}
+
+void BaselineJIT::generate_LoadReg(int reg)
+{
+ as->loadReg(reg);
+}
+
+void BaselineJIT::generate_StoreReg(int reg)
+{
+ as->storeReg(reg);
+}
+
+void BaselineJIT::generate_MoveReg(int srcReg, int destReg)
+{
+ as->loadReg(srcReg);
+ as->storeReg(destReg);
+}
+
+void BaselineJIT::generate_LoadLocal(int index)
+{
+ as->loadLocal(index);
+}
+
+void BaselineJIT::generate_StoreLocal(int index)
+{
+ as->checkException();
+ as->storeLocal(index);
+}
+
+void BaselineJIT::generate_LoadScopedLocal(int scope, int index)
+{
+ as->loadLocal(index, scope);
+}
+
+void BaselineJIT::generate_StoreScopedLocal(int scope, int index)
+{
+ as->checkException();
+ as->storeLocal(index, scope);
+}
+
+void BaselineJIT::generate_LoadRuntimeString(int stringId)
+{
+ as->loadString(stringId);
+}
+
+void BaselineJIT::generate_MoveRegExp(int regExpId, int destReg)
+{
+ as->prepareCallWithArgCount(2);
+ as->passInt32AsArg(regExpId, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_regexpLiteral, Assembler::ResultInAccumulator);
+ as->storeReg(destReg);
+}
+
+void BaselineJIT::generate_LoadClosure(int value)
+{
+ as->prepareCallWithArgCount(2);
+ as->passInt32AsArg(value, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_closure, Assembler::ResultInAccumulator);
+}
+
+void BaselineJIT::generate_LoadName(int name)
+{
+ STORE_IP();
+ as->prepareCallWithArgCount(2);
+ as->passInt32AsArg(name, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_loadName, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+static ReturnedValue loadGlobalLookupHelper(ExecutionEngine *engine, QV4::Function *f, int index)
+{
+ QV4::Lookup *l = f->compilationUnit->runtimeLookups + index;
+ return l->globalGetter(l, engine);
+}
+
+void BaselineJIT::generate_LoadGlobalLookup(int index)
+{
+ as->prepareCallWithArgCount(3);
+ as->passInt32AsArg(index, 2);
+ as->passFunctionAsArg(1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(loadGlobalLookupHelper, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+void BaselineJIT::generate_StoreNameSloppy(int name)
+{
+ STORE_IP();
+ STORE_ACC();
+ as->prepareCallWithArgCount(3);
+ as->passAccumulatorAsArg(2);
+ as->passInt32AsArg(name, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_storeNameSloppy, Assembler::IgnoreResult);
+ as->checkException();
+}
+
+void BaselineJIT::generate_StoreNameStrict(int name)
+{
+ STORE_IP();
+ STORE_ACC();
+ as->prepareCallWithArgCount(3);
+ as->passAccumulatorAsArg(2);
+ as->passInt32AsArg(name, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_storeNameStrict, Assembler::IgnoreResult);
+ as->checkException();
+}
+
+void BaselineJIT::generate_LoadElement(int base, int index)
+{
+ STORE_IP();
+ as->prepareCallWithArgCount(3);
+ as->passRegAsArg(index, 2);
+ as->passRegAsArg(base, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_loadElement, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+void BaselineJIT::generate_LoadElementA(int base)
+{
+ STORE_IP();
+ STORE_ACC();
+ as->prepareCallWithArgCount(3);
+ as->passAccumulatorAsArg(2);
+ as->passRegAsArg(base, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_loadElement, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+static void storeElementHelper(QV4::Function *f, const Value &base, const Value &index, const Value &value)
+{
+ auto engine = f->internalClass->engine;
+ if (!Runtime::method_storeElement(engine, base, index, value) && f->isStrict())
+ engine->throwTypeError();
+}
+
+void BaselineJIT::generate_StoreElement(int base, int index)
+{
+ STORE_IP();
+ STORE_ACC();
+ as->prepareCallWithArgCount(4);
+ as->passAccumulatorAsArg(3);
+ as->passRegAsArg(index, 2);
+ as->passRegAsArg(base, 1);
+ as->passFunctionAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(storeElementHelper, Assembler::IgnoreResult);
+ as->checkException();
+}
+
+void BaselineJIT::generate_LoadProperty(int name, int base)
+{
+ STORE_IP();
+ as->prepareCallWithArgCount(3);
+ as->passInt32AsArg(name, 2);
+ as->passRegAsArg(base, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_loadProperty, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+void BaselineJIT::generate_LoadPropertyA(int name)
+{
+ STORE_IP();
+ STORE_ACC();
+ as->prepareCallWithArgCount(3);
+ as->passInt32AsArg(name, 2);
+ as->passAccumulatorAsArg(1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_loadProperty, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+static ReturnedValue getLookupHelper(ExecutionEngine *engine, QV4::Function *f, int index, const QV4::Value &base)
+{
+ QV4::Lookup *l = f->compilationUnit->runtimeLookups + index;
+ return l->getter(l, engine, base);
+}
+
+void BaselineJIT::generate_GetLookup(int index, int base)
+{
+ STORE_IP();
+ as->prepareCallWithArgCount(4);
+ as->passRegAsArg(base, 3);
+ as->passInt32AsArg(index, 2);
+ as->passFunctionAsArg(1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(getLookupHelper, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+void BaselineJIT::generate_GetLookupA(int index)
+{
+ STORE_IP();
+ STORE_ACC();
+ as->prepareCallWithArgCount(4);
+ as->passAccumulatorAsArg(3);
+ as->passInt32AsArg(index, 2);
+ as->passFunctionAsArg(1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(getLookupHelper, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+static void storePropertyHelper(QV4::Function *f, const Value &base, int name, const Value &value)
+{
+ auto engine = f->internalClass->engine;
+ if (!Runtime::method_storeProperty(engine, base, name, value) && f->isStrict())
+ engine->throwTypeError();
+}
+
+void BaselineJIT::generate_StoreProperty(int name, int base)
+{
+ STORE_IP();
+ STORE_ACC();
+ as->prepareCallWithArgCount(4);
+ as->passAccumulatorAsArg(3);
+ as->passInt32AsArg(name, 2);
+ as->passRegAsArg(base, 1);
+ as->passFunctionAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(storePropertyHelper, Assembler::IgnoreResult);
+ as->checkException();
+}
+
+static void setLookupHelper(QV4::Function *f, int index, QV4::Value &base, const QV4::Value &value)
+{
+ ExecutionEngine *engine = f->internalClass->engine;
+ QV4::Lookup *l = f->compilationUnit->runtimeLookups + index;
+ if (!l->setter(l, engine, base, value) && f->isStrict())
+ engine->throwTypeError();
+}
+
+void BaselineJIT::generate_SetLookup(int index, int base)
+{
+ STORE_IP();
+ STORE_ACC();
+ as->prepareCallWithArgCount(4);
+ as->passAccumulatorAsArg(3);
+ as->passRegAsArg(base, 2);
+ as->passInt32AsArg(index, 1);
+ as->passFunctionAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(setLookupHelper, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+void BaselineJIT::generate_StoreScopeObjectProperty(int base, int propertyIndex)
+{
+ STORE_ACC();
+ as->prepareCallWithArgCount(4);
+ as->passAccumulatorAsArg(3);
+ as->passInt32AsArg(propertyIndex, 2);
+ as->passRegAsArg(base, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_storeQmlScopeObjectProperty, Assembler::IgnoreResult);
+ as->checkException();
+}
+
+void BaselineJIT::generate_StoreContextObjectProperty(int base, int propertyIndex)
+{
+ STORE_ACC();
+ as->prepareCallWithArgCount(4);
+ as->passAccumulatorAsArg(3);
+ as->passInt32AsArg(propertyIndex, 2);
+ as->passRegAsArg(base, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_storeQmlContextObjectProperty, Assembler::IgnoreResult);
+ as->checkException();
+}
+
+void BaselineJIT::generate_LoadScopeObjectProperty(int propertyIndex, int base, int captureRequired)
+{
+ STORE_IP();
+ as->prepareCallWithArgCount(4);
+ as->passInt32AsArg(captureRequired, 3);
+ as->passInt32AsArg(propertyIndex, 2);
+ as->passRegAsArg(base, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_loadQmlScopeObjectProperty, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+void BaselineJIT::generate_LoadContextObjectProperty(int propertyIndex, int base, int captureRequired)
+{
+ STORE_IP();
+ as->prepareCallWithArgCount(4);
+ as->passInt32AsArg(captureRequired, 3);
+ as->passInt32AsArg(propertyIndex, 2);
+ as->passRegAsArg(base, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_loadQmlContextObjectProperty, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+void BaselineJIT::generate_LoadIdObject(int index, int base)
+{
+ STORE_IP();
+ as->prepareCallWithArgCount(3);
+ as->passInt32AsArg(index, 2);
+ as->passRegAsArg(base, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_loadQmlIdObject, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+void BaselineJIT::generate_CallValue(int name, int argc, int argv)
+{
+ STORE_IP();
+ as->prepareCallWithArgCount(4);
+ as->passInt32AsArg(argc, 3);
+ as->passRegAsArg(argv, 2);
+ as->passRegAsArg(name, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_callValue, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+void BaselineJIT::generate_CallProperty(int name, int base, int argc, int argv)
+{
+ STORE_IP();
+ as->prepareCallWithArgCount(5);
+ as->passInt32AsArg(argc, 4);
+ as->passRegAsArg(argv, 3);
+ as->passInt32AsArg(name, 2);
+ as->passRegAsArg(base, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_callProperty, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+void BaselineJIT::generate_CallPropertyLookup(int lookupIndex, int base, int argc, int argv)
+{
+ STORE_IP();
+ as->prepareCallWithArgCount(5);
+ as->passInt32AsArg(argc, 4);
+ as->passRegAsArg(argv, 3);
+ as->passInt32AsArg(lookupIndex, 2);
+ as->passRegAsArg(base, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_callPropertyLookup, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+void BaselineJIT::generate_CallElement(int base, int index, int argc, int argv)
+{
+ STORE_IP();
+ as->prepareCallWithArgCount(5);
+ as->passInt32AsArg(argc, 4);
+ as->passRegAsArg(argv, 3);
+ as->passRegAsArg(index, 2);
+ as->passRegAsArg(base, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_callElement, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+void BaselineJIT::generate_CallName(int name, int argc, int argv)
+{
+ STORE_IP();
+ as->prepareCallWithArgCount(4);
+ as->passInt32AsArg(argc, 3);
+ as->passRegAsArg(argv, 2);
+ as->passInt32AsArg(name, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_callName, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+void BaselineJIT::generate_CallPossiblyDirectEval(int argc, int argv)
+{
+ STORE_IP();
+ as->prepareCallWithArgCount(3);
+ as->passInt32AsArg(argc, 2);
+ as->passRegAsArg(argv, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_callPossiblyDirectEval, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+void BaselineJIT::generate_CallGlobalLookup(int index, int argc, int argv)
+{
+ STORE_IP();
+ as->prepareCallWithArgCount(4);
+ as->passInt32AsArg(argc, 3);
+ as->passRegAsArg(argv, 2);
+ as->passInt32AsArg(index, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_callGlobalLookup, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+void BaselineJIT::generate_SetExceptionHandler(int offset)
+{
+ if (offset)
+ as->setExceptionHandler(instructionOffset() + offset);
+ else
+ as->clearExceptionHandler();
+}
+
+void BaselineJIT::generate_ThrowException()
+{
+ STORE_IP();
+ STORE_ACC();
+ as->prepareCallWithArgCount(2);
+ as->passAccumulatorAsArg(1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_throwException, Assembler::IgnoreResult);
+ as->gotoCatchException();
+}
+
+void BaselineJIT::generate_GetException() { as->getException(); }
+void BaselineJIT::generate_SetException() { as->setException(); }
+
+void BaselineJIT::generate_CreateCallContext()
+{
+ as->prepareCallWithArgCount(1);
+ as->passCppFrameAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(ExecutionContext::newCallContext, Assembler::IgnoreResult); // keeps result in return value register
+ as->storeHeapObject(CallData::Context);
+}
+
+void BaselineJIT::generate_PushCatchContext(int name, int reg) { as->pushCatchContext(name, reg); }
+
+static void pushWithContextHelper(ExecutionEngine *engine, QV4::Value *stack, int reg)
+{
+ QV4::Value &accumulator = stack[CallData::Accumulator];
+ accumulator = accumulator.toObject(engine);
+ if (engine->hasException)
+ return;
+ stack[reg] = stack[CallData::Context];
+ ExecutionContext *c = static_cast<ExecutionContext *>(stack + CallData::Context);
+ stack[CallData::Context] = Runtime::method_createWithContext(c, accumulator);
+}
+
+void BaselineJIT::generate_PushWithContext(int reg)
+{
+ STORE_IP();
+ as->saveAccumulatorInFrame();
+ as->prepareCallWithArgCount(3);
+ as->passInt32AsArg(reg, 2);
+ as->passRegAsArg(0, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(pushWithContextHelper, Assembler::IgnoreResult);
+ as->checkException();
+}
+
+void BaselineJIT::generate_PopContext(int reg) { as->popContext(reg); }
+
+void BaselineJIT::generate_ForeachIteratorObject()
+{
+ as->saveAccumulatorInFrame();
+ as->prepareCallWithArgCount(2);
+ as->passAccumulatorAsArg(1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_foreachIterator, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+void BaselineJIT::generate_ForeachNextPropertyName()
+{
+ as->saveAccumulatorInFrame();
+ as->prepareCallWithArgCount(1);
+ as->passAccumulatorAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_foreachNextPropertyName,
+ Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+static ReturnedValue deleteMemberHelper(QV4::Function *function, const QV4::Value &base, int member)
+{
+ auto engine = function->internalClass->engine;
+ if (!Runtime::method_deleteMember(engine, base, member)) {
+ if (function->isStrict())
+ engine->throwTypeError();
+ return Encode(false);
+ } else {
+ return Encode(true);
+ }
+}
+
+void BaselineJIT::generate_DeleteMember(int member, int base)
+{
+ STORE_IP();
+ as->prepareCallWithArgCount(3);
+ as->passInt32AsArg(member, 2);
+ as->passRegAsArg(base, 1);
+ as->passFunctionAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(deleteMemberHelper, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+static ReturnedValue deleteSubscriptHelper(QV4::Function *function, const QV4::Value &base, const QV4::Value &index)
+{
+ auto engine = function->internalClass->engine;
+ if (!Runtime::method_deleteElement(engine, base, index)) {
+ if (function->isStrict())
+ engine->throwTypeError();
+ return Encode(false);
+ } else {
+ return Encode(true);
+ }
+}
+
+void BaselineJIT::generate_DeleteSubscript(int base, int index)
+{
+ STORE_IP();
+ as->prepareCallWithArgCount(3);
+ as->passRegAsArg(index, 2);
+ as->passRegAsArg(base, 1);
+ as->passFunctionAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(deleteSubscriptHelper, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+static ReturnedValue deleteNameHelper(QV4::Function *function, int name)
+{
+ auto engine = function->internalClass->engine;
+ if (!Runtime::method_deleteName(engine, name)) {
+ if (function->isStrict())
+ engine->throwTypeError();
+ return Encode(false);
+ } else {
+ return Encode(true);
+ }
+}
+
+void BaselineJIT::generate_DeleteName(int name)
+{
+ STORE_IP();
+ as->prepareCallWithArgCount(2);
+ as->passInt32AsArg(name, 1);
+ as->passFunctionAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(deleteNameHelper, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+void BaselineJIT::generate_TypeofName(int name)
+{
+ as->prepareCallWithArgCount(2);
+ as->passInt32AsArg(name, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_typeofName, Assembler::ResultInAccumulator);
+}
+
+void BaselineJIT::generate_TypeofValue()
+{
+ STORE_ACC();
+ as->prepareCallWithArgCount(2);
+ as->passAccumulatorAsArg(1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_typeofValue, Assembler::ResultInAccumulator);
+}
+
+void BaselineJIT::generate_DeclareVar(int varName, int isDeletable)
+{
+ as->prepareCallWithArgCount(3);
+ as->passInt32AsArg(varName, 2);
+ as->passInt32AsArg(isDeletable, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_declareVar, Assembler::IgnoreResult);
+}
+
+void BaselineJIT::generate_DefineArray(int argc, int args)
+{
+ as->prepareCallWithArgCount(3);
+ as->passInt32AsArg(argc, 2);
+ as->passRegAsArg(args, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_arrayLiteral, Assembler::ResultInAccumulator);
+}
+
+void BaselineJIT::generate_DefineObjectLiteral(int internalClassId, int arrayValueCount,
+ int arrayGetterSetterCountAndFlags, int args)
+{
+ as->prepareCallWithArgCount(5);
+ as->passInt32AsArg(arrayGetterSetterCountAndFlags, 4);
+ as->passInt32AsArg(arrayValueCount, 3);
+ as->passInt32AsArg(internalClassId, 2);
+ as->passRegAsArg(args, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_objectLiteral, Assembler::ResultInAccumulator);
+}
+void BaselineJIT::generate_CreateMappedArgumentsObject()
+{
+ as->prepareCallWithArgCount(1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_createMappedArgumentsObject,
+ Assembler::ResultInAccumulator);
+}
+
+void BaselineJIT::generate_CreateUnmappedArgumentsObject()
+{
+ as->prepareCallWithArgCount(1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_createUnmappedArgumentsObject,
+ Assembler::ResultInAccumulator);
+}
+
+static void convertThisToObjectHelper(ExecutionEngine *engine, Value *t)
+{
+ if (!t->isObject()) {
+ if (t->isNullOrUndefined()) {
+ *t = engine->globalObject->asReturnedValue();
+ } else {
+ *t = t->toObject(engine)->asReturnedValue();
+ }
+ }
+}
+
+void BaselineJIT::generate_ConvertThisToObject()
+{
+ as->prepareCallWithArgCount(2);
+ as->passRegAsArg(CallData::This, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(convertThisToObjectHelper, Assembler::IgnoreResult);
+ as->checkException();
+}
+
+void BaselineJIT::generate_Construct(int func, int argc, int argv)
+{
+ STORE_IP();
+ as->prepareCallWithArgCount(4);
+ as->passInt32AsArg(argc, 3);
+ as->passRegAsArg(argv, 2);
+ as->passRegAsArg(func, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_construct, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+void BaselineJIT::generate_Jump(int offset) { as->jump(instructionOffset() + offset); }
+void BaselineJIT::generate_JumpTrue(int offset) { as->jumpTrue(instructionOffset() + offset); }
+void BaselineJIT::generate_JumpFalse(int offset) { as->jumpFalse(instructionOffset() + offset); }
+
+void BaselineJIT::generate_CmpEqNull() { as->cmpeqNull(); }
+void BaselineJIT::generate_CmpNeNull() { as->cmpneNull(); }
+void BaselineJIT::generate_CmpEqInt(int lhs) { as->cmpeqInt(lhs); }
+void BaselineJIT::generate_CmpNeInt(int lhs) { as->cmpneInt(lhs); }
+void BaselineJIT::generate_CmpEq(int lhs) { as->cmpeq(lhs); }
+void BaselineJIT::generate_CmpNe(int lhs) { as->cmpne(lhs); }
+void BaselineJIT::generate_CmpGt(int lhs) { as->cmpgt(lhs); }
+void BaselineJIT::generate_CmpGe(int lhs) { as->cmpge(lhs); }
+void BaselineJIT::generate_CmpLt(int lhs) { as->cmplt(lhs); }
+void BaselineJIT::generate_CmpLe(int lhs) { as->cmple(lhs); }
+void BaselineJIT::generate_CmpStrictEqual(int lhs) { as->cmpStrictEqual(lhs); }
+void BaselineJIT::generate_CmpStrictNotEqual(int lhs) { as->cmpStrictNotEqual(lhs); }
+
+void BaselineJIT::generate_CmpIn(int lhs)
+{
+ STORE_ACC();
+ as->prepareCallWithArgCount(3);
+ as->passAccumulatorAsArg(2);
+ as->passRegAsArg(lhs, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_in, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+void BaselineJIT::generate_CmpInstanceOf(int lhs)
+{
+ STORE_ACC();
+ as->prepareCallWithArgCount(3);
+ as->passAccumulatorAsArg(2);
+ as->passRegAsArg(lhs, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_instanceof, Assembler::ResultInAccumulator);
+ as->checkException();
+}
+
+void BaselineJIT::generate_JumpStrictEqualStackSlotInt(int lhs, int rhs, int offset)
+{
+ as->jumpStrictEqualStackSlotInt(lhs, rhs, instructionOffset() + offset);
+}
+
+void BaselineJIT::generate_JumpStrictNotEqualStackSlotInt(int lhs, int rhs, int offset)
+{
+ as->jumpStrictNotEqualStackSlotInt(lhs, rhs, instructionOffset() + offset);
+}
+
+void BaselineJIT::generate_UNot() { as->unot(); }
+void BaselineJIT::generate_UPlus() { as->toNumber(); }
+void BaselineJIT::generate_UMinus() { as->uminus(); }
+void BaselineJIT::generate_UCompl() { as->ucompl(); }
+void BaselineJIT::generate_Increment() { as->inc(); }
+void BaselineJIT::generate_Decrement() { as->dec(); }
+void BaselineJIT::generate_Add(int lhs) { as->add(lhs); }
+
+void BaselineJIT::generate_BitAnd(int lhs) { as->bitAnd(lhs); }
+void BaselineJIT::generate_BitOr(int lhs) { as->bitOr(lhs); }
+void BaselineJIT::generate_BitXor(int lhs) { as->bitXor(lhs); }
+void BaselineJIT::generate_UShr(int lhs) { as->ushr(lhs); }
+void BaselineJIT::generate_Shr(int lhs) { as->shr(lhs); }
+void BaselineJIT::generate_Shl(int lhs) { as->shl(lhs); }
+
+void BaselineJIT::generate_BitAndConst(int rhs) { as->bitAndConst(rhs); }
+void BaselineJIT::generate_BitOrConst(int rhs) { as->bitOrConst(rhs); }
+void BaselineJIT::generate_BitXorConst(int rhs) { as->bitXorConst(rhs); }
+void BaselineJIT::generate_UShrConst(int rhs) { as->ushrConst(rhs); }
+void BaselineJIT::generate_ShrConst(int rhs) { as->shrConst(rhs); }
+void BaselineJIT::generate_ShlConst(int rhs) { as->shlConst(rhs); }
+
+void BaselineJIT::generate_Mul(int lhs) { as->mul(lhs); }
+void BaselineJIT::generate_Div(int lhs) { as->div(lhs); }
+void BaselineJIT::generate_Mod(int lhs) { as->mod(lhs); }
+void BaselineJIT::generate_Sub(int lhs) { as->sub(lhs); }
+
+//void BaselineJIT::generate_BinopContext(int alu, int lhs)
+//{
+// auto engine = function->internalClass->engine;
+// void *op = engine->runtime.runtimeMethods[alu];
+// STORE_ACC();
+// as->passAccumulatorAsArg(2);
+// as->passRegAsArg(lhs, 1);
+// as->passEngineAsArg(0);
+// as->callRuntime("binopContext", op, Assembler::ResultInAccumulator);
+// as->checkException();
+//}
+
+void BaselineJIT::generate_LoadQmlContext(int result)
+{
+ as->prepareCallWithArgCount(1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_loadQmlContext, Assembler::ResultInAccumulator);
+ as->storeReg(result);
+}
+
+void BaselineJIT::generate_LoadQmlImportedScripts(int result)
+{
+ as->prepareCallWithArgCount(1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_loadQmlImportedScripts, Assembler::ResultInAccumulator);
+ as->storeReg(result);
+}
+
+void BaselineJIT::generate_LoadQmlSingleton(int name)
+{
+ as->prepareCallWithArgCount(2);
+ as->passInt32AsArg(name, 1);
+ as->passEngineAsArg(0);
+ JIT_GENERATE_RUNTIME_CALL(Runtime::method_loadQmlSingleton, Assembler::ResultInAccumulator);
+}
+
+void BaselineJIT::startInstruction(Instr::Type /*instr*/)
+{
+ if (hasLabel())
+ as->addLabel(instructionOffset());
+}
+
+void BaselineJIT::endInstruction(Instr::Type instr)
+{
+ Q_UNUSED(instr);
+}
+
+#define MOTH_UNUSED_ARGS0()
+#define MOTH_UNUSED_ARGS1(arg) \
+ Q_UNUSED(arg);
+#define MOTH_UNUSED_ARGS2(arg1, arg2) \
+ Q_UNUSED(arg1); \
+ Q_UNUSED(arg2);
+#define MOTH_UNUSED_ARGS3(arg1, arg2, arg3) \
+ Q_UNUSED(arg1); \
+ Q_UNUSED(arg2); \
+ Q_UNUSED(arg3);
+#define MOTH_UNUSED_ARGS4(arg1, arg2, arg3, arg4) \
+ Q_UNUSED(arg1); \
+ Q_UNUSED(arg2); \
+ Q_UNUSED(arg3); \
+ Q_UNUSED(arg4);
+
+#define MOTH_MARK_ARGS_UNUSED_PLEASE(nargs, ...) \
+ MOTH_EXPAND_FOR_MSVC(MOTH_UNUSED_ARGS##nargs(__VA_ARGS__))
+
+#define MOTH_MARK_ARGS_UNUSED_INSTRUCTION(name, nargs, ...) \
+ MOTH_MARK_ARGS_UNUSED_PLEASE(nargs, __VA_ARGS__)
+
+#define MOTH_BEGIN_INSTR(instr) \
+ { \
+ INSTR_##instr(MOTH_DECODE_WITH_BASE) \
+ INSTR_##instr(MOTH_MARK_ARGS_UNUSED) \
+ Q_UNUSED(base_ptr);
+
+#define MOTH_END_INSTR(instr) \
+ continue; \
+ }
+
+void BaselineJIT::collectLabelsInBytecode()
+{
+ MOTH_JUMP_TABLE;
+
+ const auto addLabel = [&](int offset) {
+ Q_ASSERT(offset >= 0 && offset < static_cast<int>(function->compiledFunction->codeSize));
+ labels.push_back(offset);
+ };
+
+ const char *code = reinterpret_cast<const char *>(function->codeData);
+ const char *start = code;
+ const char *end = code + function->compiledFunction->codeSize;
+ while (code < end) {
+ MOTH_DISPATCH()
+ Q_UNREACHABLE();
+
+ MOTH_BEGIN_INSTR(LoadReg)
+ MOTH_END_INSTR(LoadReg)
+
+ MOTH_BEGIN_INSTR(StoreReg)
+ MOTH_END_INSTR(StoreReg)
+
+ MOTH_BEGIN_INSTR(MoveReg)
+ MOTH_END_INSTR(MoveReg)
+
+ MOTH_BEGIN_INSTR(LoadConst)
+ MOTH_END_INSTR(LoadConst)
+
+ MOTH_BEGIN_INSTR(LoadNull)
+ MOTH_END_INSTR(LoadNull)
+
+ MOTH_BEGIN_INSTR(LoadZero)
+ MOTH_END_INSTR(LoadZero)
+
+ MOTH_BEGIN_INSTR(LoadTrue)
+ MOTH_END_INSTR(LoadTrue)
+
+ MOTH_BEGIN_INSTR(LoadFalse)
+ MOTH_END_INSTR(LoadFalse)
+
+ MOTH_BEGIN_INSTR(LoadUndefined)
+ MOTH_END_INSTR(LoadUndefined)
+
+ MOTH_BEGIN_INSTR(LoadInt)
+ MOTH_END_INSTR(LoadInt)
+
+ MOTH_BEGIN_INSTR(MoveConst)
+ MOTH_END_INSTR(MoveConst)
+
+ MOTH_BEGIN_INSTR(LoadLocal)
+ MOTH_END_INSTR(LoadLocal)
+
+ MOTH_BEGIN_INSTR(StoreLocal)
+ MOTH_END_INSTR(StoreLocal)
+
+ MOTH_BEGIN_INSTR(LoadScopedLocal)
+ MOTH_END_INSTR(LoadScopedLocal)
+
+ MOTH_BEGIN_INSTR(StoreScopedLocal)
+ MOTH_END_INSTR(StoreScopedLocal)
+
+ MOTH_BEGIN_INSTR(LoadRuntimeString)
+ MOTH_END_INSTR(LoadRuntimeString)
+
+ MOTH_BEGIN_INSTR(MoveRegExp)
+ MOTH_END_INSTR(MoveRegExp)
+
+ MOTH_BEGIN_INSTR(LoadClosure)
+ MOTH_END_INSTR(LoadClosure)
+
+ MOTH_BEGIN_INSTR(LoadName)
+ MOTH_END_INSTR(LoadName)
+
+ MOTH_BEGIN_INSTR(LoadGlobalLookup)
+ MOTH_END_INSTR(LoadGlobalLookup)
+
+ MOTH_BEGIN_INSTR(StoreNameSloppy)
+ MOTH_END_INSTR(StoreNameSloppy)
+
+ MOTH_BEGIN_INSTR(StoreNameStrict)
+ MOTH_END_INSTR(StoreNameStrict)
+
+ MOTH_BEGIN_INSTR(LoadElement)
+ MOTH_END_INSTR(LoadElement)
+
+ MOTH_BEGIN_INSTR(LoadElementA)
+ MOTH_END_INSTR(LoadElement)
+
+ MOTH_BEGIN_INSTR(StoreElement)
+ MOTH_END_INSTR(StoreElement)
+
+ MOTH_BEGIN_INSTR(LoadProperty)
+ MOTH_END_INSTR(LoadProperty)
+
+ MOTH_BEGIN_INSTR(LoadPropertyA)
+ MOTH_END_INSTR(LoadElementA)
+
+ MOTH_BEGIN_INSTR(GetLookup)
+ MOTH_END_INSTR(GetLookup)
+
+ MOTH_BEGIN_INSTR(GetLookupA)
+ MOTH_END_INSTR(GetLookupA)
+
+ MOTH_BEGIN_INSTR(StoreProperty)
+ MOTH_END_INSTR(StoreProperty)
+
+ MOTH_BEGIN_INSTR(SetLookup)
+ MOTH_END_INSTR(SetLookup)
+
+ MOTH_BEGIN_INSTR(StoreScopeObjectProperty)
+ MOTH_END_INSTR(StoreScopeObjectProperty)
+
+ MOTH_BEGIN_INSTR(LoadScopeObjectProperty)
+ MOTH_END_INSTR(LoadScopeObjectProperty)
+
+ MOTH_BEGIN_INSTR(StoreContextObjectProperty)
+ MOTH_END_INSTR(StoreContextObjectProperty)
+
+ MOTH_BEGIN_INSTR(LoadContextObjectProperty)
+ MOTH_END_INSTR(LoadContextObjectProperty)
+
+ MOTH_BEGIN_INSTR(LoadIdObject)
+ MOTH_END_INSTR(LoadIdObject)
+
+ MOTH_BEGIN_INSTR(CallValue)
+ MOTH_END_INSTR(CallValue)
+
+ MOTH_BEGIN_INSTR(CallProperty)
+ MOTH_END_INSTR(CallProperty)
+
+ MOTH_BEGIN_INSTR(CallPropertyLookup)
+ MOTH_END_INSTR(CallPropertyLookup)
+
+ MOTH_BEGIN_INSTR(CallElement)
+ MOTH_END_INSTR(CallElement)
+
+ MOTH_BEGIN_INSTR(CallName)
+ MOTH_END_INSTR(CallName)
+
+ MOTH_BEGIN_INSTR(CallPossiblyDirectEval)
+ MOTH_END_INSTR(CallPossiblyDirectEval)
+
+ MOTH_BEGIN_INSTR(CallGlobalLookup)
+ MOTH_END_INSTR(CallGlobalLookup)
+
+ MOTH_BEGIN_INSTR(SetExceptionHandler)
+ addLabel(code - start + offset);
+ MOTH_END_INSTR(SetExceptionHandler)
+
+ MOTH_BEGIN_INSTR(ThrowException)
+ MOTH_END_INSTR(ThrowException)
+
+ MOTH_BEGIN_INSTR(GetException)
+ MOTH_END_INSTR(HasException)
+
+ MOTH_BEGIN_INSTR(SetException)
+ MOTH_END_INSTR(SetExceptionFlag)
+
+ MOTH_BEGIN_INSTR(CreateCallContext)
+ MOTH_END_INSTR(CreateCallContext)
+
+ MOTH_BEGIN_INSTR(PushCatchContext)
+ MOTH_END_INSTR(PushCatchContext)
+
+ MOTH_BEGIN_INSTR(PushWithContext)
+ MOTH_END_INSTR(PushWithContext)
+
+ MOTH_BEGIN_INSTR(PopContext)
+ MOTH_END_INSTR(PopContext)
+
+ MOTH_BEGIN_INSTR(ForeachIteratorObject)
+ MOTH_END_INSTR(ForeachIteratorObject)
+
+ MOTH_BEGIN_INSTR(ForeachNextPropertyName)
+ MOTH_END_INSTR(ForeachNextPropertyName)
+
+ MOTH_BEGIN_INSTR(DeleteMember)
+ MOTH_END_INSTR(DeleteMember)
+
+ MOTH_BEGIN_INSTR(DeleteSubscript)
+ MOTH_END_INSTR(DeleteSubscript)
+
+ MOTH_BEGIN_INSTR(DeleteName)
+ MOTH_END_INSTR(DeleteName)
+
+ MOTH_BEGIN_INSTR(TypeofName)
+ MOTH_END_INSTR(TypeofName)
+
+ MOTH_BEGIN_INSTR(TypeofValue)
+ MOTH_END_INSTR(TypeofValue)
+
+ MOTH_BEGIN_INSTR(DeclareVar)
+ MOTH_END_INSTR(DeclareVar)
+
+ MOTH_BEGIN_INSTR(DefineArray)
+ MOTH_END_INSTR(DefineArray)
+
+ MOTH_BEGIN_INSTR(DefineObjectLiteral)
+ MOTH_END_INSTR(DefineObjectLiteral)
+
+ MOTH_BEGIN_INSTR(CreateMappedArgumentsObject)
+ MOTH_END_INSTR(CreateMappedArgumentsObject)
+
+ MOTH_BEGIN_INSTR(CreateUnmappedArgumentsObject)
+ MOTH_END_INSTR(CreateUnmappedArgumentsObject)
+
+ MOTH_BEGIN_INSTR(ConvertThisToObject)
+ MOTH_END_INSTR(ConvertThisToObject)
+
+ MOTH_BEGIN_INSTR(Construct)
+ MOTH_END_INSTR(Construct)
+
+ MOTH_BEGIN_INSTR(Jump)
+ addLabel(code - start + offset);
+ MOTH_END_INSTR(Jump)
+
+ MOTH_BEGIN_INSTR(JumpTrue)
+ addLabel(code - start + offset);
+ MOTH_END_INSTR(JumpTrue)
+
+ MOTH_BEGIN_INSTR(JumpFalse)
+ addLabel(code - start + offset);
+ MOTH_END_INSTR(JumpFalse)
+
+ MOTH_BEGIN_INSTR(CmpEqNull)
+ MOTH_END_INSTR(CmpEqNull)
+
+ MOTH_BEGIN_INSTR(CmpNeNull)
+ MOTH_END_INSTR(CmpNeNull)
+
+ MOTH_BEGIN_INSTR(CmpEqInt)
+ MOTH_END_INSTR(CmpEq)
+
+ MOTH_BEGIN_INSTR(CmpNeInt)
+ MOTH_END_INSTR(CmpNeInt)
+
+ MOTH_BEGIN_INSTR(CmpEq)
+ MOTH_END_INSTR(CmpEq)
+
+ MOTH_BEGIN_INSTR(CmpNe)
+ MOTH_END_INSTR(CmpNe)
+
+ MOTH_BEGIN_INSTR(CmpGt)
+ MOTH_END_INSTR(CmpGt)
+
+ MOTH_BEGIN_INSTR(CmpGe)
+ MOTH_END_INSTR(CmpGe)
+
+ MOTH_BEGIN_INSTR(CmpLt)
+ MOTH_END_INSTR(CmpLt)
+
+ MOTH_BEGIN_INSTR(CmpLe)
+ MOTH_END_INSTR(CmpLe)
+
+ MOTH_BEGIN_INSTR(CmpStrictEqual)
+ MOTH_END_INSTR(CmpStrictEqual)
+
+ MOTH_BEGIN_INSTR(CmpStrictNotEqual)
+ MOTH_END_INSTR(CmpStrictNotEqual)
+
+ MOTH_BEGIN_INSTR(CmpIn)
+ MOTH_END_INSTR(CmpIn)
+
+ MOTH_BEGIN_INSTR(CmpInstanceOf)
+ MOTH_END_INSTR(CmpInstanceOf)
+
+ MOTH_BEGIN_INSTR(JumpStrictEqualStackSlotInt)
+ addLabel(code - start + offset);
+ MOTH_END_INSTR(JumpStrictEqualStackSlotInt)
+
+ MOTH_BEGIN_INSTR(JumpStrictNotEqualStackSlotInt)
+ addLabel(code - start + offset);
+ MOTH_END_INSTR(JumpStrictNotEqualStackSlotInt)
+
+ MOTH_BEGIN_INSTR(UNot)
+ MOTH_END_INSTR(UNot)
+
+ MOTH_BEGIN_INSTR(UPlus)
+ MOTH_END_INSTR(UPlus)
+
+ MOTH_BEGIN_INSTR(UMinus)
+ MOTH_END_INSTR(UMinus)
+
+ MOTH_BEGIN_INSTR(UCompl)
+ MOTH_END_INSTR(UCompl)
+
+ MOTH_BEGIN_INSTR(Increment)
+ MOTH_END_INSTR(PreIncrement)
+
+ MOTH_BEGIN_INSTR(Decrement)
+ MOTH_END_INSTR(PreDecrement)
+
+ MOTH_BEGIN_INSTR(Add)
+ MOTH_END_INSTR(Add)
+
+ MOTH_BEGIN_INSTR(BitAnd)
+ MOTH_END_INSTR(BitAnd)
+
+ MOTH_BEGIN_INSTR(BitOr)
+ MOTH_END_INSTR(BitOr)
+
+ MOTH_BEGIN_INSTR(BitXor)
+ MOTH_END_INSTR(BitXor)
+
+ MOTH_BEGIN_INSTR(UShr)
+ MOTH_END_INSTR(UShr)
+
+ MOTH_BEGIN_INSTR(Shr)
+ MOTH_END_INSTR(Shr)
+
+ MOTH_BEGIN_INSTR(Shl)
+ MOTH_END_INSTR(Shl)
+
+ MOTH_BEGIN_INSTR(BitAndConst)
+ MOTH_END_INSTR(BitAndConst)
+
+ MOTH_BEGIN_INSTR(BitOrConst)
+ MOTH_END_INSTR(BitOr)
+
+ MOTH_BEGIN_INSTR(BitXorConst)
+ MOTH_END_INSTR(BitXor)
+
+ MOTH_BEGIN_INSTR(UShrConst)
+ MOTH_END_INSTR(UShrConst)
+
+ MOTH_BEGIN_INSTR(ShrConst)
+ MOTH_END_INSTR(ShrConst)
+
+ MOTH_BEGIN_INSTR(ShlConst)
+ MOTH_END_INSTR(ShlConst)
+
+ MOTH_BEGIN_INSTR(Mul)
+ MOTH_END_INSTR(Mul)
+
+ MOTH_BEGIN_INSTR(Div)
+ MOTH_END_INSTR(Div)
+
+ MOTH_BEGIN_INSTR(Mod)
+ MOTH_END_INSTR(Mod)
+
+ MOTH_BEGIN_INSTR(Sub)
+ MOTH_END_INSTR(Sub)
+
+ MOTH_BEGIN_INSTR(Ret)
+ MOTH_END_INSTR(Ret)
+
+#ifndef QT_NO_QML_DEBUGGER
+ MOTH_BEGIN_INSTR(Debug)
+ MOTH_END_INSTR(Debug)
+#endif // QT_NO_QML_DEBUGGER
+
+ MOTH_BEGIN_INSTR(LoadQmlContext)
+ MOTH_END_INSTR(LoadQmlContext)
+
+ MOTH_BEGIN_INSTR(LoadQmlImportedScripts)
+ MOTH_END_INSTR(LoadQmlImportedScripts)
+
+ MOTH_BEGIN_INSTR(LoadQmlSingleton)
+ MOTH_END_INSTR(LoadQmlSingleton)
+ }
+}
+#undef MOTH_BEGIN_INSTR
+#undef MOTH_END_INSTR
+
+#endif // V4_ENABLE_JIT
diff --git a/src/qml/jit/qv4jit_p.h b/src/qml/jit/qv4jit_p.h
new file mode 100644
index 0000000000..c7ec1700c3
--- /dev/null
+++ b/src/qml/jit/qv4jit_p.h
@@ -0,0 +1,265 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QV4JIT_P_H
+#define QV4JIT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qv4global_p.h>
+#include <private/qv4function_p.h>
+#include <private/qv4instr_moth_p.h>
+
+//QT_REQUIRE_CONFIG(qml_jit);
+
+#define JIT_DEFINE_ARGS(nargs, ...) \
+ MOTH_EXPAND_FOR_MSVC(JIT_DEFINE_ARGS##nargs(__VA_ARGS__))
+
+#define JIT_DEFINE_ARGS0()
+#define JIT_DEFINE_ARGS1(arg) \
+ int arg
+#define JIT_DEFINE_ARGS2(arg1, arg2) \
+ int arg1, \
+ int arg2
+#define JIT_DEFINE_ARGS3(arg1, arg2, arg3) \
+ int arg1, \
+ int arg2, \
+ int arg3
+#define JIT_DEFINE_ARGS4(arg1, arg2, arg3, arg4) \
+ int arg1, \
+ int arg2, \
+ int arg3, \
+ int arg4
+
+#define JIT_DEFINE_VIRTUAL_BYTECODE_HANDLER_INSTRUCTION(name, nargs, ...) \
+ virtual void generate_##name( \
+ JIT_DEFINE_ARGS(nargs, __VA_ARGS__) \
+ ) = 0;
+
+#define JIT_DEFINE_VIRTUAL_BYTECODE_HANDLER(instr) \
+ INSTR_##instr(JIT_DEFINE_VIRTUAL_BYTECODE_HANDLER)
+
+QT_BEGIN_NAMESPACE
+
+namespace QV4 {
+namespace JIT {
+
+class Assembler;
+
+class ByteCodeHandler
+{
+public:
+ virtual ~ByteCodeHandler();
+
+ void decode(const char *code, uint len);
+
+ int instructionOffset() const { return _offset; }
+
+protected:
+ FOR_EACH_MOTH_INSTR(JIT_DEFINE_VIRTUAL_BYTECODE_HANDLER)
+
+ virtual void startInstruction(Moth::Instr::Type instr) = 0;
+ virtual void endInstruction(Moth::Instr::Type instr) = 0;
+
+private:
+ int _offset = 0;
+};
+
+#ifdef V4_ENABLE_JIT
+class BaselineJIT final: public ByteCodeHandler
+{
+public:
+ BaselineJIT(QV4::Function *);
+ virtual ~BaselineJIT();
+
+ void generate();
+
+ void generate_Ret() Q_DECL_OVERRIDE;
+ void generate_Debug() Q_DECL_OVERRIDE;
+ void generate_LoadConst(int index) Q_DECL_OVERRIDE;
+ void generate_LoadZero() Q_DECL_OVERRIDE;
+ void generate_LoadTrue() Q_DECL_OVERRIDE;
+ void generate_LoadFalse() Q_DECL_OVERRIDE;
+ void generate_LoadNull() Q_DECL_OVERRIDE;
+ void generate_LoadUndefined() Q_DECL_OVERRIDE;
+ void generate_LoadInt(int value) Q_DECL_OVERRIDE;
+ void generate_MoveConst(int constIndex, int destTemp) Q_DECL_OVERRIDE;
+ void generate_LoadReg(int reg) Q_DECL_OVERRIDE;
+ void generate_StoreReg(int reg) Q_DECL_OVERRIDE;
+ void generate_MoveReg(int srcReg, int destReg) Q_DECL_OVERRIDE;
+ void generate_LoadLocal(int index) Q_DECL_OVERRIDE;
+ void generate_StoreLocal(int index) Q_DECL_OVERRIDE;
+ void generate_LoadScopedLocal(int scope, int index) Q_DECL_OVERRIDE;
+ void generate_StoreScopedLocal(int scope, int index) Q_DECL_OVERRIDE;
+ void generate_LoadRuntimeString(int stringId) Q_DECL_OVERRIDE;
+ void generate_MoveRegExp(int regExpId, int destReg) Q_DECL_OVERRIDE;
+ void generate_LoadClosure(int value) Q_DECL_OVERRIDE;
+ void generate_LoadName(int name) Q_DECL_OVERRIDE;
+ void generate_LoadGlobalLookup(int index) Q_DECL_OVERRIDE;
+ void generate_StoreNameSloppy(int name) Q_DECL_OVERRIDE;
+ void generate_StoreNameStrict(int name) Q_DECL_OVERRIDE;
+ void generate_LoadElement(int base, int index) Q_DECL_OVERRIDE;
+ void generate_LoadElementA(int base) Q_DECL_OVERRIDE;
+ void generate_StoreElement(int base, int index) Q_DECL_OVERRIDE;
+ void generate_LoadProperty(int name, int base) Q_DECL_OVERRIDE;
+ void generate_LoadPropertyA(int name) Q_DECL_OVERRIDE;
+ void generate_GetLookup(int index, int base) Q_DECL_OVERRIDE;
+ void generate_GetLookupA(int index) Q_DECL_OVERRIDE;
+ void generate_StoreProperty(int name, int base) Q_DECL_OVERRIDE;
+ void generate_SetLookup(int index, int base) Q_DECL_OVERRIDE;
+ void generate_StoreScopeObjectProperty(int base,
+ int propertyIndex) Q_DECL_OVERRIDE;
+ void generate_StoreContextObjectProperty(int base,
+ int propertyIndex) Q_DECL_OVERRIDE;
+ void generate_LoadScopeObjectProperty(int propertyIndex, int base,
+ int captureRequired) Q_DECL_OVERRIDE;
+ void generate_LoadContextObjectProperty(int propertyIndex, int base,
+ int captureRequired) Q_DECL_OVERRIDE;
+ void generate_LoadIdObject(int index, int base) Q_DECL_OVERRIDE;
+ void generate_CallValue(int name, int argc, int argv) Q_DECL_OVERRIDE;
+ void generate_CallProperty(int name, int base, int argc, int argv) Q_DECL_OVERRIDE;
+ void generate_CallPropertyLookup(int lookupIndex, int base, int argc, int argv) Q_DECL_OVERRIDE;
+ void generate_CallElement(int base, int index, int argc, int argv) Q_DECL_OVERRIDE;
+ void generate_CallName(int name, int argc, int argv) Q_DECL_OVERRIDE;
+ void generate_CallPossiblyDirectEval(int argc, int argv) Q_DECL_OVERRIDE;
+ void generate_CallGlobalLookup(int index, int argc, int argv) Q_DECL_OVERRIDE;
+ void generate_SetExceptionHandler(int offset) Q_DECL_OVERRIDE;
+ void generate_ThrowException() Q_DECL_OVERRIDE;
+ void generate_GetException() Q_DECL_OVERRIDE;
+ void generate_SetException() Q_DECL_OVERRIDE;
+ void generate_CreateCallContext() Q_DECL_OVERRIDE;
+ void generate_PushCatchContext(int name, int reg) Q_DECL_OVERRIDE;
+ void generate_PushWithContext(int reg) Q_DECL_OVERRIDE;
+ void generate_PopContext(int reg) Q_DECL_OVERRIDE;
+ void generate_ForeachIteratorObject() Q_DECL_OVERRIDE;
+ void generate_ForeachNextPropertyName() Q_DECL_OVERRIDE;
+ void generate_DeleteMember(int member, int base) Q_DECL_OVERRIDE;
+ void generate_DeleteSubscript(int base, int index) Q_DECL_OVERRIDE;
+ void generate_DeleteName(int name) Q_DECL_OVERRIDE;
+ void generate_TypeofName(int name) Q_DECL_OVERRIDE;
+ void generate_TypeofValue() Q_DECL_OVERRIDE;
+ void generate_DeclareVar(int varName, int isDeletable) Q_DECL_OVERRIDE;
+ void generate_DefineArray(int argc, int args) Q_DECL_OVERRIDE;
+ void generate_DefineObjectLiteral(int internalClassId, int arrayValueCount,
+ int arrayGetterSetterCountAndFlags,
+ int args) Q_DECL_OVERRIDE;
+ void generate_CreateMappedArgumentsObject() Q_DECL_OVERRIDE;
+ void generate_CreateUnmappedArgumentsObject() Q_DECL_OVERRIDE;
+ void generate_ConvertThisToObject() Q_DECL_OVERRIDE;
+ void generate_Construct(int func, int argc, int argv) Q_DECL_OVERRIDE;
+ void generate_Jump(int offset) Q_DECL_OVERRIDE;
+ void generate_JumpTrue(int offset) Q_DECL_OVERRIDE;
+ void generate_JumpFalse(int offset) Q_DECL_OVERRIDE;
+ void generate_CmpEqNull() Q_DECL_OVERRIDE;
+ void generate_CmpNeNull() Q_DECL_OVERRIDE;
+ void generate_CmpEqInt(int lhs) Q_DECL_OVERRIDE;
+ void generate_CmpNeInt(int lhs) Q_DECL_OVERRIDE;
+ void generate_CmpEq(int lhs) Q_DECL_OVERRIDE;
+ void generate_CmpNe(int lhs) Q_DECL_OVERRIDE;
+ void generate_CmpGt(int lhs) Q_DECL_OVERRIDE;
+ void generate_CmpGe(int lhs) Q_DECL_OVERRIDE;
+ void generate_CmpLt(int lhs) Q_DECL_OVERRIDE;
+ void generate_CmpLe(int lhs) Q_DECL_OVERRIDE;
+ void generate_CmpStrictEqual(int lhs) Q_DECL_OVERRIDE;
+ void generate_CmpStrictNotEqual(int lhs) Q_DECL_OVERRIDE;
+ void generate_CmpIn(int lhs) Q_DECL_OVERRIDE;
+ void generate_CmpInstanceOf(int lhs) Q_DECL_OVERRIDE;
+ void generate_JumpStrictEqualStackSlotInt(int lhs, int rhs,
+ int offset) Q_DECL_OVERRIDE;
+ void generate_JumpStrictNotEqualStackSlotInt(int lhs, int rhs,
+ int offset) Q_DECL_OVERRIDE;
+ void generate_UNot() Q_DECL_OVERRIDE;
+ void generate_UPlus() Q_DECL_OVERRIDE;
+ void generate_UMinus() Q_DECL_OVERRIDE;
+ void generate_UCompl() Q_DECL_OVERRIDE;
+ void generate_Increment() Q_DECL_OVERRIDE;
+ void generate_Decrement() Q_DECL_OVERRIDE;
+ void generate_Add(int lhs) Q_DECL_OVERRIDE;
+ void generate_BitAnd(int lhs) Q_DECL_OVERRIDE;
+ void generate_BitOr(int lhs) Q_DECL_OVERRIDE;
+ void generate_BitXor(int lhs) Q_DECL_OVERRIDE;
+ void generate_UShr(int lhs) Q_DECL_OVERRIDE;
+ void generate_Shr(int lhs) Q_DECL_OVERRIDE;
+ void generate_Shl(int lhs) Q_DECL_OVERRIDE;
+ void generate_BitAndConst(int rhs) Q_DECL_OVERRIDE;
+ void generate_BitOrConst(int rhs) Q_DECL_OVERRIDE;
+ void generate_BitXorConst(int rhs) Q_DECL_OVERRIDE;
+ void generate_UShrConst(int rhs) Q_DECL_OVERRIDE;
+ void generate_ShrConst(int rhs) Q_DECL_OVERRIDE;
+ void generate_ShlConst(int rhs) Q_DECL_OVERRIDE;
+ void generate_Mul(int lhs) Q_DECL_OVERRIDE;
+ void generate_Div(int lhs) Q_DECL_OVERRIDE;
+ void generate_Mod(int lhs) Q_DECL_OVERRIDE;
+ void generate_Sub(int lhs) Q_DECL_OVERRIDE;
+ void generate_LoadQmlContext(int result) Q_DECL_OVERRIDE;
+ void generate_LoadQmlImportedScripts(int result) Q_DECL_OVERRIDE;
+ void generate_LoadQmlSingleton(int name) Q_DECL_OVERRIDE;
+
+ void startInstruction(Moth::Instr::Type instr) Q_DECL_OVERRIDE;
+ void endInstruction(Moth::Instr::Type instr) Q_DECL_OVERRIDE;
+
+protected:
+ bool hasLabel() const
+ { return std::find(labels.cbegin(), labels.cend(), instructionOffset()) != labels.cend(); }
+
+private:
+ void collectLabelsInBytecode();
+
+private:
+ QV4::Function *function;
+ QScopedPointer<Assembler> as;
+ std::vector<int> labels;
+};
+#endif // V4_ENABLE_JIT
+
+} // namespace JIT
+} // namespace QV4
+
+QT_END_NAMESPACE
+
+#endif // QV4JIT_P_H
diff --git a/src/qml/jit/qv4regalloc.cpp b/src/qml/jit/qv4regalloc.cpp
deleted file mode 100644
index d418b050c4..0000000000
--- a/src/qml/jit/qv4regalloc.cpp
+++ /dev/null
@@ -1,1971 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the V4VM module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtCore/QBuffer>
-#include <QtCore/QDebug>
-#include "qv4regalloc_p.h"
-#include "qv4alloca_p.h"
-#include <private/qv4value_p.h>
-
-#include <algorithm>
-#if defined(Q_CC_MINGW)
-# include <malloc.h>
-#endif
-
-namespace {
-enum { DebugRegAlloc = 0 };
-
-struct Use {
- enum RegisterFlag { MustHaveRegister = 0, CouldHaveRegister = 1 };
- unsigned flag : 1;
- unsigned pos : 31;
-
- Use(): flag(MustHaveRegister), pos(0) {}
- Use(int position, RegisterFlag flag): flag(flag), pos(position)
- { Q_ASSERT(position >= 0); }
-
- bool mustHaveRegister() const { return flag == MustHaveRegister; }
-};
-}
-
-QT_BEGIN_NAMESPACE
-
-Q_DECLARE_TYPEINFO(Use, Q_MOVABLE_TYPE);
-
-using namespace QV4::IR;
-
-namespace QV4 {
-namespace JIT {
-
-namespace {
-class IRPrinterWithPositions: public IRPrinter
-{
- LifeTimeIntervals::Ptr intervals;
- const int positionSize;
-
-public:
- IRPrinterWithPositions(QTextStream *out, const LifeTimeIntervals::Ptr &intervals)
- : IRPrinter(out)
- , intervals(intervals)
- , positionSize(QString::number(intervals->lastPosition()).size())
- {}
-
-protected:
- void addStmtNr(Stmt *s) Q_DECL_OVERRIDE Q_DECL_FINAL
- {
- addJustifiedNr(intervals->positionForStatement(s));
- }
-};
-
-class IRPrinterWithRegisters: public IRPrinterWithPositions
-{
- const RegisterInformation &_registerInformation;
- QHash<int, const RegisterInfo *> _infoForRegularRegister;
- QHash<int, const RegisterInfo *> _infoForFPRegister;
-
-public:
- IRPrinterWithRegisters(QTextStream *out, const LifeTimeIntervals::Ptr &intervals,
- const RegisterInformation &registerInformation)
- : IRPrinterWithPositions(out, intervals)
- , _registerInformation(registerInformation)
- {
- for (int i = 0, ei = _registerInformation.size(); i != ei; ++i)
- if (_registerInformation.at(i).isRegularRegister())
- _infoForRegularRegister.insert(_registerInformation.at(i).reg<int>(),
- &_registerInformation.at(i));
- else
- _infoForFPRegister.insert(_registerInformation.at(i).reg<int>(),
- &_registerInformation.at(i));
- }
-
-protected:
- void visitTemp(Temp *e) Q_DECL_OVERRIDE Q_DECL_FINAL
- {
- switch (e->kind) {
- case Temp::PhysicalRegister: {
- const RegisterInfo *ri = e->type == DoubleType ? _infoForFPRegister.value(e->index, 0)
- : _infoForRegularRegister.value(e->index, 0);
- if (ri) {
- *out << ri->prettyName();
- break;
- }
- Q_FALLTHROUGH();
- }
- default:
- IRPrinterWithPositions::visitTemp(e);
- }
- }
-};
-}
-
-class RegAllocInfo: public IRDecoder
-{
-public:
- typedef QVarLengthArray<Temp, 4> Hints;
-
-private:
- struct Def {
- unsigned valid : 1;
- unsigned canHaveReg : 1;
- unsigned isPhiTarget : 1;
-
- Def(): valid(0), canHaveReg(0), isPhiTarget(0) {}
- Def(bool canHaveReg, bool isPhiTarget)
- : valid(1), canHaveReg(canHaveReg), isPhiTarget(isPhiTarget)
- {
- }
-
- bool isValid() const { return valid != 0; }
- };
-
- IR::LifeTimeIntervals::Ptr _lifeTimeIntervals;
- BasicBlock *_currentBB;
- Stmt *_currentStmt;
- std::vector<Def> _defs;
- std::vector<std::vector<Use> > _uses;
- std::vector<int> _calls;
- std::vector<Hints> _hints;
-
- int usePosition(Stmt *s) const
- {
- int usePos = _lifeTimeIntervals->positionForStatement(s);
- if (usePos == Stmt::InvalidId) // phi-node operand, so:
- usePos = _lifeTimeIntervals->startPosition(_currentBB);
- return usePos;
- }
-
-public:
- RegAllocInfo(): _currentBB(0), _currentStmt(0) {}
-
- void collect(IR::Function *function, const IR::LifeTimeIntervals::Ptr &lifeTimeIntervals)
- {
- _lifeTimeIntervals = lifeTimeIntervals;
- _defs.resize(function->tempCount);
- _uses.resize(function->tempCount);
- _calls.reserve(function->statementCount() / 3);
- _hints.resize(function->tempCount);
-
- for (BasicBlock *bb : function->basicBlocks()) {
- _currentBB = bb;
- for (Stmt *s : bb->statements()) {
- _currentStmt = s;
- visit(s);
- }
- }
- }
-
- const std::vector<Use> &uses(const Temp &t) const
- {
- return _uses.at(t.index);
- }
-
- bool canHaveRegister(const Temp &t) const {
- Q_ASSERT(_defs[t.index].isValid());
- return _defs[t.index].canHaveReg;
- }
- bool isPhiTarget(const Temp &t) const {
- Q_ASSERT(_defs[t.index].isValid());
- return _defs[t.index].isPhiTarget;
- }
-
- const std::vector<int> &calls() const { return _calls; }
- const Hints &hints(const Temp &t) const { return _hints[t.index]; }
- void addHint(const Temp &t, int physicalRegister)
- { addHint(t, Temp::PhysicalRegister, physicalRegister); }
-
- void addHint(const Temp &t, Temp::Kind kind, int hintedIndex)
- {
- Hints &hints = _hints[t.index];
- for (Hints::iterator i = hints.begin(), ei = hints.end(); i != ei; ++i)
- if (i->index == hintedIndex)
- return;
-
- Temp hint;
- hint.init(kind, hintedIndex);
- hints.append(hint);
- }
-
- void dump() const
- {
- if (!DebugRegAlloc)
- return;
-
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream qout(&buf);
- IRPrinterWithPositions printer(&qout, _lifeTimeIntervals);
-
- qout << "RegAllocInfo:" << endl << "Defs/uses:" << endl;
- for (unsigned t = 0; t < _defs.size(); ++t) {
- const std::vector<Use> &uses = _uses[t];
- if (uses.empty())
- continue;
- qout << "%" << t <<": "
- << " ("
- << (_defs[t].canHaveReg ? "can" : "can NOT")
- << " have a register, and "
- << (_defs[t].isPhiTarget ? "is" : "is NOT")
- << " defined by a phi node), uses at: ";
- for (unsigned i = 0; i < uses.size(); ++i) {
- if (i > 0) qout << ", ";
- qout << uses[i].pos;
- if (uses[i].mustHaveRegister()) qout << "(R)"; else qout << "(S)";
- }
- qout << endl;
- }
-
- qout << "Calls at: ";
- for (unsigned i = 0; i < _calls.size(); ++i) {
- if (i > 0) qout << ", ";
- qout << _calls[i];
- }
- qout << endl;
-
- qout << "Hints:" << endl;
- for (unsigned t = 0; t < _hints.size(); ++t) {
- if (_uses[t].empty())
- continue;
- qout << "\t%" << t << ": ";
- const Hints &hints = _hints[t];
- for (int i = 0; i < hints.size(); ++i) {
- if (i > 0) qout << ", ";
- printer.print(hints[i]);
- }
- qout << endl;
- }
- qDebug("%s", buf.data().constData());
- }
-
-protected: // IRDecoder
- void callBuiltinInvalid(IR::Name *, IR::ExprList *, IR::Expr *) override {}
- void callBuiltinTypeofQmlContextProperty(IR::Expr *, IR::Member::MemberKind, int, IR::Expr *) override {}
- void callBuiltinTypeofMember(IR::Expr *, const QString &, IR::Expr *) override {}
- void callBuiltinTypeofSubscript(IR::Expr *, IR::Expr *, IR::Expr *) override {}
- void callBuiltinTypeofName(const QString &, IR::Expr *) override {}
- void callBuiltinTypeofValue(IR::Expr *, IR::Expr *) override {}
- void callBuiltinDeleteMember(IR::Expr *, const QString &, IR::Expr *) override {}
- void callBuiltinDeleteSubscript(IR::Expr *, IR::Expr *, IR::Expr *) override {}
- void callBuiltinDeleteName(const QString &, IR::Expr *) override {}
- void callBuiltinDeleteValue(IR::Expr *) override {}
- void callBuiltinThrow(IR::Expr *) override {}
- void callBuiltinReThrow() override {}
- void callBuiltinUnwindException(IR::Expr *) override {}
- void callBuiltinPushCatchScope(const QString &) override {};
- void callBuiltinForeachIteratorObject(IR::Expr *, IR::Expr *) override {}
- virtual void callBuiltinForeachNextProperty(IR::Temp *, IR::Temp *) {}
- void callBuiltinForeachNextPropertyname(IR::Expr *, IR::Expr *) override {}
- void callBuiltinPushWithScope(IR::Expr *) override {}
- void callBuiltinPopScope() override {}
- void callBuiltinDeclareVar(bool , const QString &) override {}
- void callBuiltinDefineArray(IR::Expr *, IR::ExprList *) override {}
- void callBuiltinDefineObjectLiteral(IR::Expr *, int, IR::ExprList *, IR::ExprList *, bool) override {}
- void callBuiltinSetupArgumentObject(IR::Expr *) override {}
- void callBuiltinConvertThisToObject() override {}
-
- void callValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result) override
- {
- addDef(result);
- if (IR::Temp *tempValue = value->asTemp())
- addUses(tempValue, Use::CouldHaveRegister);
- addUses(args, Use::CouldHaveRegister);
- addCall();
- }
-
- void callQmlContextProperty(IR::Expr *base, IR::Member::MemberKind /*kind*/, int propertyIndex,
- IR::ExprList *args, IR::Expr *result) override
- {
- Q_UNUSED(propertyIndex)
-
- addDef(result);
- addUses(base->asTemp(), Use::CouldHaveRegister);
- addUses(args, Use::CouldHaveRegister);
- addCall();
- }
-
- void callProperty(IR::Expr *base, const QString &name, IR::ExprList *args,
- IR::Expr *result) override
- {
- Q_UNUSED(name)
-
- addDef(result);
- addUses(base->asTemp(), Use::CouldHaveRegister);
- addUses(args, Use::CouldHaveRegister);
- addCall();
- }
-
- void callSubscript(IR::Expr *base, IR::Expr *index, IR::ExprList *args,
- IR::Expr *result) override
- {
- addDef(result);
- addUses(base->asTemp(), Use::CouldHaveRegister);
- addUses(index->asTemp(), Use::CouldHaveRegister);
- addUses(args, Use::CouldHaveRegister);
- addCall();
- }
-
- void convertType(IR::Expr *source, IR::Expr *target) override
- {
- addDef(target);
-
- bool needsCall = true;
- Use::RegisterFlag sourceReg = Use::CouldHaveRegister;
-
- switch (target->type) {
- case DoubleType:
- switch (source->type) {
- case UInt32Type:
- case SInt32Type:
- case NullType:
- case UndefinedType:
- case BoolType:
- needsCall = false;
- break;
- default:
- break;
- }
- break;
- case BoolType:
- switch (source->type) {
- case UInt32Type:
- sourceReg = Use::MustHaveRegister;
- needsCall = false;
- break;
- case DoubleType:
- case UndefinedType:
- case NullType:
- case SInt32Type:
- needsCall = false;
- break;
- default:
- break;
- }
- break;
- case SInt32Type:
- switch (source->type) {
- case UInt32Type:
- case NullType:
- case UndefinedType:
- case BoolType:
- needsCall = false;
- default:
- break;
- }
- break;
- case UInt32Type:
- switch (source->type) {
- case SInt32Type:
- case NullType:
- case UndefinedType:
- case BoolType:
- needsCall = false;
- default:
- break;
- }
- break;
- default:
- break;
- }
-
- Temp *sourceTemp = source->asTemp();
- if (sourceTemp)
- addUses(sourceTemp, sourceReg);
-
- if (needsCall)
- addCall();
- else if (target->asTemp())
- addHint(target->asTemp(), sourceTemp);
- }
-
- void constructActivationProperty(IR::Name *, IR::ExprList *args, IR::Expr *result) override
- {
- addDef(result);
- addUses(args, Use::CouldHaveRegister);
- addCall();
- }
-
- void constructProperty(IR::Expr *base, const QString &, IR::ExprList *args, IR::Expr *result) override
- {
- addDef(result);
- addUses(base, Use::CouldHaveRegister);
- addUses(args, Use::CouldHaveRegister);
- addCall();
- }
-
- void constructValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result) override
- {
- addDef(result);
- addUses(value, Use::CouldHaveRegister);
- addUses(args, Use::CouldHaveRegister);
- addCall();
- }
-
- void loadThisObject(IR::Expr *temp) override
- {
- addDef(temp);
- }
-
- void loadQmlContext(IR::Expr *temp) override
- {
- addDef(temp);
- addCall();
- }
-
- void loadQmlImportedScripts(IR::Expr *temp) override
- {
- addDef(temp);
- addCall();
- }
-
- void loadQmlSingleton(const QString &/*name*/, Expr *temp) override
- {
- Q_UNUSED(temp);
-
- addDef(temp);
- addCall();
- }
-
- void loadConst(IR::Const *sourceConst, Expr *targetTemp) override
- {
- Q_UNUSED(sourceConst);
-
- addDef(targetTemp);
- }
-
- void loadString(const QString &str, Expr *targetTemp) override
- {
- Q_UNUSED(str);
-
- addDef(targetTemp);
- }
-
- void loadRegexp(IR::RegExp *sourceRegexp, Expr *targetTemp) override
- {
- Q_UNUSED(sourceRegexp);
-
- addDef(targetTemp);
- addCall();
- }
-
- void getActivationProperty(const IR::Name *, Expr *temp) override
- {
- addDef(temp);
- addCall();
- }
-
- void setActivationProperty(IR::Expr *source, const QString &) override
- {
- addUses(source->asTemp(), Use::CouldHaveRegister);
- addCall();
- }
-
- void initClosure(IR::Closure *closure, Expr *target) override
- {
- Q_UNUSED(closure);
-
- addDef(target);
- addCall();
- }
-
- void getProperty(IR::Expr *base, const QString &, Expr *target) override
- {
- addDef(target);
- addUses(base->asTemp(), Use::CouldHaveRegister);
- addCall();
- }
-
- void setProperty(IR::Expr *source, IR::Expr *targetBase, const QString &) override
- {
- addUses(source->asTemp(), Use::CouldHaveRegister);
- addUses(targetBase->asTemp(), Use::CouldHaveRegister);
- addCall();
- }
-
- void setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase,
- IR::Member::MemberKind /*kind*/, int /*propertyIndex*/) override
- {
- addUses(source->asTemp(), Use::CouldHaveRegister);
- addUses(targetBase->asTemp(), Use::CouldHaveRegister);
- addCall();
- }
-
- void setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int /*propertyIndex*/) override
- {
- addUses(source->asTemp(), Use::CouldHaveRegister);
- addUses(targetBase->asTemp(), Use::CouldHaveRegister);
- addCall();
- }
-
- void getQmlContextProperty(IR::Expr *base, IR::Member::MemberKind /*kind*/, int /*index*/,
- bool /*captureRequired*/, IR::Expr *target) override
- {
- addDef(target);
- addUses(base->asTemp(), Use::CouldHaveRegister);
- addCall();
- }
-
- void getQObjectProperty(IR::Expr *base, int /*propertyIndex*/, bool /*captureRequired*/,
- bool /*isSingleton*/, int /*attachedPropertiesId*/, IR::Expr *target) override
- {
- addDef(target);
- addUses(base->asTemp(), Use::CouldHaveRegister);
- addCall();
- }
-
- void getElement(IR::Expr *base, IR::Expr *index, Expr *target) override
- {
- addDef(target);
- addUses(base->asTemp(), Use::CouldHaveRegister);
- addUses(index->asTemp(), Use::CouldHaveRegister);
- addCall();
- }
-
- void setElement(IR::Expr *source, IR::Expr *targetBase, IR::Expr *targetIndex) override
- {
- addUses(source->asTemp(), Use::CouldHaveRegister);
- addUses(targetBase->asTemp(), Use::CouldHaveRegister);
- addUses(targetIndex->asTemp(), Use::CouldHaveRegister);
- addCall();
- }
-
- void copyValue(Expr *source, Expr *target) override
- {
- addDef(target);
- Temp *sourceTemp = source->asTemp();
- if (!sourceTemp)
- return;
- addUses(sourceTemp, Use::CouldHaveRegister);
- Temp *targetTemp = target->asTemp();
- if (targetTemp)
- addHint(targetTemp, sourceTemp);
- }
-
- void swapValues(Expr *, Expr *) override
- {
- // Inserted by the register allocator, so it cannot occur here.
- Q_UNREACHABLE();
- }
-
- void unop(AluOp oper, Expr *source, Expr *target) override
- {
- addDef(target);
-
- bool needsCall = true;
- if (oper == OpNot && source->type == IR::BoolType && target->type == IR::BoolType)
- needsCall = false;
-
-#if 0 // TODO: change masm to generate code
- switch (oper) {
- case OpIfTrue:
- case OpNot:
- case OpUMinus:
- case OpUPlus:
- case OpCompl:
- needsCall = sourceTemp->type & ~NumberType && sourceTemp->type != BoolType;
- break;
-
- case OpIncrement:
- case OpDecrement:
- default:
- Q_UNREACHABLE();
- }
-#endif
-
- IR::Temp *sourceTemp = source->asTemp();
- if (needsCall) {
- if (sourceTemp)
- addUses(sourceTemp, Use::CouldHaveRegister);
- addCall();
- } else {
- if (sourceTemp)
- addUses(sourceTemp, Use::MustHaveRegister);
- }
- }
-
- void binop(AluOp oper, Expr *leftSource, Expr *rightSource, Expr *target) override
- {
- bool needsCall = true;
-
- if (oper == OpStrictEqual || oper == OpStrictNotEqual) {
- bool noCall = leftSource->type == NullType || rightSource->type == NullType
- || leftSource->type == UndefinedType || rightSource->type == UndefinedType
- || leftSource->type == BoolType || rightSource->type == BoolType;
- needsCall = !noCall;
- } else if (leftSource->type == DoubleType && rightSource->type == DoubleType) {
- if (oper == OpMul || oper == OpAdd || oper == OpDiv || oper == OpSub
- || (oper >= OpGt && oper <= OpStrictNotEqual)) {
- needsCall = false;
- }
- } else if (oper == OpBitAnd || oper == OpBitOr || oper == OpBitXor || oper == OpLShift || oper == OpRShift || oper == OpURShift) {
- needsCall = false;
- } else if (oper == OpAdd || oper == OpMul || oper == OpSub
- || (oper >= OpGt && oper <= OpStrictNotEqual)) {
- if (leftSource->type == SInt32Type && rightSource->type == SInt32Type)
- needsCall = false;
- }
-
- addDef(target);
-
- if (needsCall) {
- addUses(leftSource->asTemp(), Use::CouldHaveRegister);
- addUses(rightSource->asTemp(), Use::CouldHaveRegister);
- addCall();
- } else {
- addUses(leftSource->asTemp(), Use::MustHaveRegister);
- addHint(target, leftSource->asTemp());
- addHint(target, rightSource->asTemp());
-
-#if CPU(X86) || CPU(X86_64)
- switch (oper) {
- // The rhs operand can be a memory address
- case OpAdd:
- case OpSub:
- case OpMul:
- case OpDiv:
-#if CPU(X86_64)
- if (leftSource->type == DoubleType || rightSource->type == DoubleType) {
- // well, on 64bit the doubles are mangled, so they must first be loaded in a register and demangled, so...:
- addUses(rightSource->asTemp(), Use::MustHaveRegister);
- break;
- }
- Q_FALLTHROUGH();
-#endif
- case OpBitAnd:
- case OpBitOr:
- case OpBitXor:
- addUses(rightSource->asTemp(), Use::CouldHaveRegister);
- break;
-
- default:
- addUses(rightSource->asTemp(), Use::MustHaveRegister);
- break;
- }
-#else
- addUses(rightSource->asTemp(), Use::MustHaveRegister);
-#endif
- }
- }
-
- void visitJump(IR::Jump *) override {}
- void visitCJump(IR::CJump *s) override
- {
- if (Temp *t = s->cond->asTemp()) {
-#if 0 // TODO: change masm to generate code
- addUses(t, Use::MustHaveRegister);
-#else
- addUses(t, Use::CouldHaveRegister);
- addCall();
-#endif
- } else if (Binop *b = s->cond->asBinop()) {
- binop(b->op, b->left, b->right, 0);
- } else if (s->cond->asConst()) {
- // TODO: SSA optimization for constant condition evaluation should remove this.
- // See also visitCJump() in masm.
- addCall();
- } else {
- Q_UNREACHABLE();
- }
- }
-
- void visitRet(IR::Ret *s) override
- { addUses(s->expr->asTemp(), Use::CouldHaveRegister); }
-
- void visitPhi(IR::Phi *s) override
- {
- addDef(s->targetTemp, true);
- for (int i = 0, ei = s->incoming.size(); i < ei; ++i) {
- Expr *e = s->incoming.at(i);
- if (Temp *t = e->asTemp()) {
- // The actual use of an incoming value in a phi node is right before the terminator
- // of the other side of the incoming edge.
- const int usePos = _lifeTimeIntervals->positionForStatement(_currentBB->in.at(i)->terminator()) - 1;
- addUses(t, Use::CouldHaveRegister, usePos);
- addHint(s->targetTemp, t);
- addHint(t, s->targetTemp);
- }
- }
- }
-
-protected:
- void callBuiltin(IR::Call *c, IR::Expr *result) override
- {
- addDef(result);
- addUses(c->base, Use::CouldHaveRegister);
- addUses(c->args, Use::CouldHaveRegister);
- addCall();
- }
-
-private:
- void addDef(Expr *e, bool isPhiTarget = false)
- {
- if (!e)
- return;
- Temp *t = e->asTemp();
- if (!t)
- return;
- if (!t || t->kind != Temp::VirtualRegister)
- return;
- Q_ASSERT(!_defs[t->index].isValid());
- bool canHaveReg = true;
- switch (t->type) {
- case QObjectType:
- case VarType:
- case StringType:
- case UndefinedType:
- case NullType:
- canHaveReg = false;
- break;
- default:
- break;
- }
-
- _defs[t->index] = Def(canHaveReg, isPhiTarget);
- }
-
- void addUses(Expr *e, Use::RegisterFlag flag)
- {
- const int usePos = usePosition(_currentStmt);
- addUses(e, flag, usePos);
- }
-
- void addUses(Expr *e, Use::RegisterFlag flag, int usePos)
- {
- Q_ASSERT(usePos > 0);
- if (!e)
- return;
- Temp *t = e->asTemp();
- if (!t)
- return;
- if (t && t->kind == Temp::VirtualRegister)
- _uses[t->index].push_back(Use(usePos, flag));
- }
-
- void addUses(ExprList *l, Use::RegisterFlag flag)
- {
- for (ExprList *it = l; it; it = it->next)
- addUses(it->expr, flag);
- }
-
- void addCall()
- {
- _calls.push_back(usePosition(_currentStmt));
- }
-
- void addHint(Expr *hinted, Temp *hint1, Temp *hint2 = 0)
- {
- if (hinted)
- if (Temp *hintedTemp = hinted->asTemp())
- addHint(hintedTemp, hint1, hint2);
- }
-
- void addHint(Temp *hinted, Temp *hint1, Temp *hint2 = 0)
- {
- if (!hinted || hinted->kind != Temp::VirtualRegister)
- return;
- if (hint1 && hint1->kind == Temp::VirtualRegister && hinted->type == hint1->type)
- addHint(*hinted, Temp::VirtualRegister, hint1->index);
- if (hint2 && hint2->kind == Temp::VirtualRegister && hinted->type == hint2->type)
- addHint(*hinted, Temp::VirtualRegister, hint2->index);
- }
-};
-
-} // JIT namespace
-} // QV4 namespace
-QT_END_NAMESPACE
-
-QT_USE_NAMESPACE
-
-using namespace QT_PREPEND_NAMESPACE(QV4::JIT);
-using namespace QT_PREPEND_NAMESPACE(QV4::IR);
-using namespace QT_PREPEND_NAMESPACE(QV4);
-
-namespace {
-class ResolutionPhase
-{
- Q_DISABLE_COPY(ResolutionPhase)
-
- LifeTimeIntervals::Ptr _intervals;
- QVector<LifeTimeInterval *> _unprocessedReverseOrder;
- IR::Function *_function;
- const std::vector<int> &_assignedSpillSlots;
- std::vector<const LifeTimeInterval *> _liveIntervals;
- const QVector<const RegisterInfo *> &_intRegs;
- const QVector<const RegisterInfo *> &_fpRegs;
-
- Stmt *_currentStmt;
- std::vector<Move *> _loads;
- std::vector<Move *> _stores;
-
- std::vector<std::vector<const LifeTimeInterval *> > _liveAtStart;
- std::vector<std::vector<const LifeTimeInterval *> > _liveAtEnd;
-
-public:
- ResolutionPhase(QVector<LifeTimeInterval *> &&unprocessedReversedOrder,
- const LifeTimeIntervals::Ptr &intervals,
- IR::Function *function,
- const std::vector<int> &assignedSpillSlots,
- const QVector<const RegisterInfo *> &intRegs,
- const QVector<const RegisterInfo *> &fpRegs)
- : _intervals(intervals)
- , _unprocessedReverseOrder(unprocessedReversedOrder)
- , _function(function)
- , _assignedSpillSlots(assignedSpillSlots)
- , _intRegs(intRegs)
- , _fpRegs(fpRegs)
- , _currentStmt(0)
- {
- _liveAtStart.resize(function->basicBlockCount());
- _liveAtEnd.resize(function->basicBlockCount());
- }
-
- void run() {
- renumber();
- if (DebugRegAlloc) {
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream qout(&buf);
- IRPrinterWithPositions(&qout, _intervals).print(_function);
- qDebug("%s", buf.data().constData());
- }
- resolve();
- }
-
-private:
- int defPosition(Stmt *s) const
- {
- return usePosition(s) + 1;
- }
-
- int usePosition(Stmt *s) const
- {
- return _intervals->positionForStatement(s);
- }
-
- void renumber()
- {
- QVector<Stmt *> newStatements;
-
- for (BasicBlock *bb : _function->basicBlocks()) {
- _currentStmt = 0;
-
- QVector<Stmt *> statements = bb->statements();
- newStatements.reserve(bb->statements().size() + 7);
- newStatements.erase(newStatements.begin(), newStatements.end());
-
- cleanOldIntervals(_intervals->startPosition(bb));
- addNewIntervals(_intervals->startPosition(bb));
- _liveAtStart[bb->index()] = _liveIntervals;
-
- for (int i = 0, ei = statements.size(); i != ei; ++i) {
- _currentStmt = statements.at(i);
- _loads.clear();
- _stores.clear();
- if (_currentStmt->asTerminator())
- addNewIntervals(usePosition(_currentStmt));
- else
- addNewIntervals(defPosition(_currentStmt));
- visit(_currentStmt);
- for (Move *load : _loads)
- newStatements.append(load);
- if (_currentStmt->asPhi())
- newStatements.prepend(_currentStmt);
- else
- newStatements.append(_currentStmt);
- for (Move *store : _stores)
- newStatements.append(store);
- }
-
- cleanOldIntervals(_intervals->endPosition(bb));
- _liveAtEnd[bb->index()] = _liveIntervals;
-
- if (DebugRegAlloc) {
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream os(&buf);
- os << "Intervals live at the start of L" << bb->index() << ":" << endl;
- if (_liveAtStart[bb->index()].empty())
- os << "\t(none)" << endl;
- for (const LifeTimeInterval *i : _liveAtStart.at(bb->index())) {
- os << "\t";
- i->dump(os);
- os << endl;
- }
- os << "Intervals live at the end of L" << bb->index() << ":" << endl;
- if (_liveAtEnd[bb->index()].empty())
- os << "\t(none)" << endl;
- for (const LifeTimeInterval *i : _liveAtEnd.at(bb->index())) {
- os << "\t";
- i->dump(os);
- os << endl;
- }
- qDebug("%s", buf.data().constData());
- }
-
- bb->setStatements(newStatements);
- }
-
- }
-
- const LifeTimeInterval *findLiveInterval(Temp *t) const
- {
- for (const LifeTimeInterval *lti : _liveIntervals) {
- if (lti->temp() == *t)
- return lti;
- }
-
- return nullptr;
- }
-
- void maybeGenerateSpill(Temp *t)
- {
- const LifeTimeInterval *i = findLiveInterval(t);
- if (i->reg() == LifeTimeInterval::InvalidRegister)
- return;
-
- const RegisterInfo *pReg = platformRegister(*i);
- Q_ASSERT(pReg);
- int spillSlot = _assignedSpillSlots[i->temp().index];
- if (spillSlot != RegisterAllocator::InvalidSpillSlot)
- _stores.push_back(generateSpill(spillSlot, i->temp().type, pReg->reg<int>()));
- }
-
- void addNewIntervals(int position)
- {
- if (position == Stmt::InvalidId)
- return;
-
- while (!_unprocessedReverseOrder.isEmpty()) {
- const LifeTimeInterval *i = _unprocessedReverseOrder.constLast();
- if (i->start() > position)
- break;
-
- Q_ASSERT(!i->isFixedInterval());
- auto it = _liveIntervals.begin();
- for (; it != _liveIntervals.end(); ++it) {
- if ((*it)->temp() == i->temp()) {
- *it = i;
- break;
- }
- }
- if (it == _liveIntervals.end())
- _liveIntervals.push_back(i);
-// qDebug() << "-- Activating interval for temp" << i->temp().index;
-
- _unprocessedReverseOrder.removeLast();
- }
- }
-
- void cleanOldIntervals(int position)
- {
- for (size_t it = 0; it != _liveIntervals.size(); ) {
- const LifeTimeInterval *lti = _liveIntervals.at(it);
- if (lti->end() < position || lti->isFixedInterval())
- _liveIntervals.erase(_liveIntervals.begin() + it);
- else
- ++it;
- }
- }
-
- void resolve()
- {
- for (BasicBlock *bb : _function->basicBlocks()) {
- for (BasicBlock *bbOut : bb->out)
- resolveEdge(bb, bbOut);
- }
- }
-
- Phi *findDefPhi(const Temp &t, BasicBlock *bb) const
- {
- for (Stmt *s : bb->statements()) {
- Phi *phi = s->asPhi();
- if (!phi)
- return 0;
-
- if (*phi->targetTemp == t)
- return phi;
- }
-
- Q_UNREACHABLE();
- }
-
- void resolveEdge(BasicBlock *predecessor, BasicBlock *successor)
- {
- if (DebugRegAlloc) {
- qDebug() << "Resolving edge" << predecessor->index() << "->" << successor->index();
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream qout(&buf);
- IRPrinterWithPositions printer(&qout, _intervals);
- printer.print(predecessor);
- printer.print(successor);
- qDebug("%s", buf.data().constData());
- }
-
- MoveMapping mapping;
-
- const int predecessorEnd = _intervals->endPosition(predecessor);
- Q_ASSERT(predecessorEnd > 0);
-
- int successorStart = _intervals->startPosition(successor);
- Q_ASSERT(successorStart > 0);
-
- for (const LifeTimeInterval *it : _liveAtStart.at(successor->index())) {
- bool isPhiTarget = false;
- Expr *moveFrom = 0;
-
- if (it->start() == successorStart) {
- if (Phi *phi = findDefPhi(it->temp(), successor)) {
- isPhiTarget = true;
- Expr *opd = phi->incoming[successor->in.indexOf(predecessor)];
- if (opd->asConst()) {
- moveFrom = opd;
- } else {
- Temp *t = opd->asTemp();
- Q_ASSERT(t);
-
- for (const LifeTimeInterval *it2 : _liveAtEnd.at(predecessor->index())) {
- if (it2->temp() == *t
- && it2->reg() != LifeTimeInterval::InvalidRegister
- && it2->covers(predecessorEnd)) {
- moveFrom = createPhysicalRegister(it2, t->type);
- break;
- }
- }
- if (!moveFrom)
- moveFrom = createTemp(Temp::StackSlot,
- _assignedSpillSlots[t->index],
- t->type);
- }
- }
- } else {
- for (const LifeTimeInterval *predIt : _liveAtEnd.at(predecessor->index())) {
- if (predIt->temp() == it->temp()) {
- if (predIt->reg() != LifeTimeInterval::InvalidRegister
- && predIt->covers(predecessorEnd)) {
- moveFrom = createPhysicalRegister(predIt, predIt->temp().type);
- } else {
- int spillSlot = _assignedSpillSlots[predIt->temp().index];
- if (spillSlot != -1)
- moveFrom = createTemp(Temp::StackSlot, spillSlot, predIt->temp().type);
- }
- break;
- }
- }
- }
- if (!moveFrom) {
-#if !defined(QT_NO_DEBUG) && 0
- bool lifeTimeHole = false;
- if (it->ranges().first().start <= successorStart && it->ranges().last().end >= successorStart)
- lifeTimeHole = !it->covers(successorStart);
-
- Q_ASSERT(!_info->isPhiTarget(it->temp()) || it->isSplitFromInterval() || lifeTimeHole);
- if (_info->def(it->temp()) != successorStart && !it->isSplitFromInterval()) {
- const int successorEnd = successor->terminator()->id();
- const int idx = successor->in.indexOf(predecessor);
- for (const Use &use : _info->uses(it->temp)) {
- if (use.pos == static_cast<unsigned>(successorStart)) {
- // only check the current edge, not all other possible ones. This is
- // important for phi nodes: they have uses that are only valid when
- // coming in over a specific edge.
- for (Stmt *s : successor->statements()) {
- if (Phi *phi = s->asPhi()) {
- Q_ASSERT(it->temp().index != phi->targetTemp->index);
- Q_ASSERT(phi->d->incoming[idx]->asTemp() == 0
- || it->temp().index != phi->d->incoming[idx]->asTemp()->index);
- } else {
- // TODO: check that the first non-phi statement does not use
- // the temp.
- break;
- }
- }
- } else {
- Q_ASSERT(use.pos < static_cast<unsigned>(successorStart) ||
- use.pos > static_cast<unsigned>(successorEnd));
- }
- }
- }
-#endif
-
- continue;
- }
-
- Temp *moveTo;
- if (it->reg() == LifeTimeInterval::InvalidRegister || !it->covers(successorStart)) {
- if (!isPhiTarget) // if it->temp() is a phi target, skip it.
- continue;
- const int spillSlot = _assignedSpillSlots[it->temp().index];
- if (spillSlot == RegisterAllocator::InvalidSpillSlot)
- continue; // it has a life-time hole here.
- moveTo = createTemp(Temp::StackSlot, spillSlot, it->temp().type);
- } else {
- moveTo = createPhysicalRegister(it, it->temp().type);
- }
-
- // add move to mapping
- mapping.add(moveFrom, moveTo);
- }
-
- if (DebugRegAlloc)
- mapping.dump();
- mapping.order();
- if (DebugRegAlloc)
- mapping.dump();
-
- bool insertIntoPredecessor = successor->in.size() > 1;
- mapping.insertMoves(insertIntoPredecessor ? predecessor : successor, _function,
- insertIntoPredecessor);
-
- if (DebugRegAlloc) {
- qDebug() << ".. done, result:";
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream qout(&buf);
- IRPrinterWithPositions printer(&qout, _intervals);
- printer.print(predecessor);
- printer.print(successor);
- qDebug("%s", buf.data().constData());
- }
- }
-
- Temp *createTemp(Temp::Kind kind, int index, Type type) const
- {
- Q_ASSERT(index >= 0);
- Temp *t = _function->New<Temp>();
- t->init(kind, index);
- t->type = type;
- return t;
- }
-
- Temp *createPhysicalRegister(const LifeTimeInterval *i, Type type) const
- {
- const RegisterInfo *ri = platformRegister(*i);
- Q_ASSERT(ri);
- return createTemp(Temp::PhysicalRegister, ri->reg<int>(), type);
- }
-
- const RegisterInfo *platformRegister(const LifeTimeInterval &i) const
- {
- if (i.isFP())
- return _fpRegs.value(i.reg(), 0);
- else
- return _intRegs.value(i.reg(), 0);
- }
-
- Move *generateSpill(int spillSlot, Type type, int pReg) const
- {
- Q_ASSERT(spillSlot >= 0);
-
- Move *store = _function->NewStmt<Move>();
- store->init(createTemp(Temp::StackSlot, spillSlot, type),
- createTemp(Temp::PhysicalRegister, pReg, type));
- return store;
- }
-
- Move *generateUnspill(const Temp &t, int pReg) const
- {
- Q_ASSERT(pReg >= 0);
- int spillSlot = _assignedSpillSlots[t.index];
- Q_ASSERT(spillSlot != -1);
- Move *load = _function->NewStmt<Move>();
- load->init(createTemp(Temp::PhysicalRegister, pReg, t.type),
- createTemp(Temp::StackSlot, spillSlot, t.type));
- return load;
- }
-
-private:
- void visit(Expr *e)
- {
- switch (e->exprKind) {
- case Expr::TempExpr:
- visitTemp(e->asTemp());
- break;
- default:
- EXPR_VISIT_ALL_KINDS(e);
- break;
- }
- }
-
- void visitTemp(Temp *t)
- {
- if (t->kind != Temp::VirtualRegister)
- return;
-
- const LifeTimeInterval *i = findLiveInterval(t);
- Q_ASSERT(i->isValid());
-
- if (_currentStmt != 0 && i->start() == usePosition(_currentStmt)) {
- Q_ASSERT(i->isSplitFromInterval());
- const RegisterInfo *pReg = platformRegister(*i);
- Q_ASSERT(pReg);
- _loads.push_back(generateUnspill(i->temp(), pReg->reg<int>()));
- }
-
- if (i->reg() != LifeTimeInterval::InvalidRegister &&
- (i->covers(defPosition(_currentStmt)) ||
- i->covers(usePosition(_currentStmt)))) {
- const RegisterInfo *pReg = platformRegister(*i);
- Q_ASSERT(pReg);
- t->kind = Temp::PhysicalRegister;
- t->index = pReg->reg<unsigned>();
- } else {
- int stackSlot = _assignedSpillSlots[t->index];
- Q_ASSERT(stackSlot >= 0);
- t->kind = Temp::StackSlot;
- t->index = stackSlot;
- }
- }
-
- void visit(Stmt *s)
- {
- switch (s->stmtKind) {
- case Stmt::MoveStmt: {
- auto m = s->asMove();
- if (Temp *t = m->target->asTemp())
- maybeGenerateSpill(t);
-
- visit(m->source);
- visit(m->target);
- } break;
- case Stmt::PhiStmt: {
- auto p = s->asPhi();
- maybeGenerateSpill(p->targetTemp);
- } break;
- default:
- STMT_VISIT_ALL_KINDS(s);
- break;
- }
- }
-};
-} // anonymous namespace
-
-RegisterAllocator::RegisterAllocator(const QV4::JIT::RegisterInformation &registerInformation)
- : _registerInformation(registerInformation)
-{
- for (int i = 0, ei = registerInformation.size(); i != ei; ++i) {
- const RegisterInfo &regInfo = registerInformation.at(i);
- if (regInfo.useForRegAlloc()) {
- if (regInfo.isRegularRegister())
- _normalRegisters.append(&regInfo);
- else
- _fpRegisters.append(&regInfo);
- }
- }
- Q_ASSERT(_normalRegisters.size() >= 2);
- Q_ASSERT(_fpRegisters.size() >= 2);
- _active.reserve((_normalRegisters.size() + _fpRegisters.size()) * 2);
- _inactive.reserve(_active.size());
-
- _regularRegsInUse.resize(_normalRegisters.size());
- _fpRegsInUse.resize(_fpRegisters.size());
-}
-
-RegisterAllocator::~RegisterAllocator()
-{
-}
-
-void RegisterAllocator::run(IR::Function *function, const Optimizer &opt)
-{
- _lastAssignedRegister.assign(function->tempCount, LifeTimeInterval::InvalidRegister);
- _assignedSpillSlots.assign(function->tempCount, InvalidSpillSlot);
- _activeSpillSlots.resize(function->tempCount);
-
- if (DebugRegAlloc)
- qDebug() << "*** Running regalloc for function" << (function->name ? qPrintable(*function->name) : "NO NAME") << "***";
-
- _lifeTimeIntervals = opt.lifeTimeIntervals();
-
- _unhandled = _lifeTimeIntervals->intervals();
- _handled.reserve(_unhandled.size());
-
- _info.reset(new RegAllocInfo);
- _info->collect(function, _lifeTimeIntervals);
-
- if (DebugRegAlloc) {
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream qout(&buf);
- qout << "Ranges:" << endl;
- QVector<LifeTimeInterval *> intervals = _unhandled;
- std::reverse(intervals.begin(), intervals.end());
- for (const LifeTimeInterval *r : qAsConst(intervals)) {
- r->dump(qout);
- qout << endl;
- }
- qDebug("%s", buf.data().constData());
- _info->dump();
-
- qDebug() << "*** Before register allocation:";
- buf.setData(QByteArray());
- IRPrinterWithPositions(&qout, _lifeTimeIntervals).print(function);
- qDebug("%s", buf.data().constData());
- }
- prepareRanges();
-
- linearScan();
-
- if (DebugRegAlloc)
- dump(function);
-
- // sort the ranges in reverse order, so the ResolutionPhase can take from the end (and thereby
- // prevent the copy overhead that taking from the beginning would give).
- std::sort(_handled.begin(), _handled.end(),
- [](const LifeTimeInterval *r1, const LifeTimeInterval *r2) -> bool {
- return LifeTimeInterval::lessThan(r2, r1);
- });
- ResolutionPhase(std::move(_handled), _lifeTimeIntervals, function, _assignedSpillSlots, _normalRegisters, _fpRegisters).run();
-
- function->tempCount = *std::max_element(_assignedSpillSlots.begin(), _assignedSpillSlots.end()) + 1;
-
- if (DebugRegAlloc)
- qDebug() << "*** Finished regalloc , result:";
-
- static const bool showCode = qEnvironmentVariableIsSet("QV4_SHOW_IR");
- if (showCode) {
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream qout(&buf);
- IRPrinterWithRegisters(&qout, _lifeTimeIntervals, _registerInformation).print(function);
- qDebug("%s", buf.data().constData());
- }
-}
-
-RegisterInformation RegisterAllocator::usedRegisters() const
-{
- RegisterInformation regInfo;
-
- for (int i = 0, ei = _normalRegisters.size(); i != ei; ++i) {
- if (_regularRegsInUse.testBit(i))
- regInfo.append(*_normalRegisters.at(i));
- }
-
- for (int i = 0, ei = _fpRegisters.size(); i != ei; ++i) {
- if (_fpRegsInUse.testBit(i))
- regInfo.append(*_fpRegisters.at(i));
- }
-
- return regInfo;
-}
-
-void RegisterAllocator::markInUse(int reg, bool isFPReg)
-{
- if (isFPReg)
- _fpRegsInUse.setBit(reg);
- else
- _regularRegsInUse.setBit(reg);
-}
-
-static inline LifeTimeInterval createFixedInterval(int rangeCount)
-{
- LifeTimeInterval i(rangeCount);
- i.setReg(0);
-
- Temp t;
- t.init(Temp::PhysicalRegister, 0);
- t.type = IR::SInt32Type;
- i.setTemp(t);
-
- return i;
-}
-
-LifeTimeInterval *RegisterAllocator::cloneFixedInterval(int reg, bool isFP, const LifeTimeInterval &original)
-{
- LifeTimeInterval *lti = new LifeTimeInterval(original);
- _lifeTimeIntervals->add(lti);
- lti->setReg(reg);
- lti->setFixedInterval(true);
-
- Temp t;
- t.init(Temp::PhysicalRegister, reg);
- t.type = isFP ? IR::DoubleType : IR::SInt32Type;
- lti->setTemp(t);
-
- return lti;
-}
-
-// Creates the intervals with fixed ranges. See [Wimmer2]. Note that this only applies to callee-
-// saved registers.
-void RegisterAllocator::prepareRanges()
-{
- LifeTimeInterval ltiWithCalls = createFixedInterval(int(_info->calls().size()));
- for (int callPosition : _info->calls())
- ltiWithCalls.addRange(callPosition, callPosition);
-
- const int regCount = _normalRegisters.size();
- _fixedRegisterRanges.resize(regCount);
- for (int reg = 0; reg < regCount; ++reg) {
- if (_normalRegisters.at(reg)->isCallerSaved()) {
- LifeTimeInterval *lti = cloneFixedInterval(reg, false, ltiWithCalls);
- if (lti->isValid()) {
- _fixedRegisterRanges[reg] = lti;
- _active.append(lti);
- }
- }
- }
-
- const int fpRegCount = _fpRegisters.size();
- _fixedFPRegisterRanges.resize(fpRegCount);
- for (int fpReg = 0; fpReg < fpRegCount; ++fpReg) {
- if (_fpRegisters.at(fpReg)->isCallerSaved()) {
- LifeTimeInterval *lti = cloneFixedInterval(fpReg, true, ltiWithCalls);
- if (lti->isValid()) {
- _fixedFPRegisterRanges[fpReg] = lti;
- _active.append(lti);
- }
- }
- }
-}
-
-void RegisterAllocator::linearScan()
-{
- while (!_unhandled.isEmpty()) {
- LifeTimeInterval *current = _unhandled.back();
- _unhandled.pop_back();
- const int position = current->start();
-
- // check for intervals in active that are handled or inactive
- for (int i = 0; i < _active.size(); ) {
- LifeTimeInterval *it = _active.at(i);
- if (it->end() < position) {
- if (!it->isFixedInterval())
- _handled += it;
- _active.remove(i);
- } else if (!it->covers(position)) {
- _inactive += it;
- _active.remove(i);
- } else {
- ++i;
- }
- }
-
- // check for intervals in inactive that are handled or active
- for (int i = 0; i < _inactive.size(); ) {
- LifeTimeInterval *it = _inactive.at(i);
- if (it->end() < position) {
- if (!it->isFixedInterval())
- _handled += it;
- _inactive.remove(i);
- } else if (it->covers(position)) {
- if (it->reg() != LifeTimeInterval::InvalidRegister) {
- _active += it;
- _inactive.remove(i);
- } else {
- // although this interval is now active, it has no register allocated (always
- // spilled), so leave it in inactive.
- ++i;
- }
- } else {
- ++i;
- }
- }
-
- Q_ASSERT(!current->isFixedInterval());
-
-#ifdef DEBUG_REGALLOC
- qDebug() << "** Position" << position;
-#endif // DEBUG_REGALLOC
-
- if (_info->canHaveRegister(current->temp())) {
- tryAllocateFreeReg(*current);
- if (current->reg() == LifeTimeInterval::InvalidRegister)
- allocateBlockedReg(*current);
- if (current->reg() != LifeTimeInterval::InvalidRegister)
- _active += current;
- } else {
- assignSpillSlot(current->temp(), current->start(), current->end());
- _inactive += current;
- if (DebugRegAlloc)
- qDebug() << "*** allocating stack slot" << _assignedSpillSlots[current->temp().index]
- << "for %" << current->temp().index << "as it cannot be loaded in a register";
- }
- }
-
- for (LifeTimeInterval *r : qAsConst(_active))
- if (!r->isFixedInterval())
- _handled.append(r);
- _active.clear();
- for (LifeTimeInterval *r : qAsConst(_inactive))
- if (!r->isFixedInterval())
- _handled.append(r);
- _inactive.clear();
-}
-
-static inline int indexOfRangeCoveringPosition(const LifeTimeInterval::Ranges &ranges, int position)
-{
- for (int i = 0, ei = ranges.size(); i != ei; ++i) {
- if (position <= ranges[i].end)
- return i;
- }
- return -1;
-}
-
-static inline int intersectionPosition(const LifeTimeIntervalRange &one, const LifeTimeIntervalRange &two)
-{
- if (one.covers(two.start))
- return two.start;
- if (two.covers(one.start))
- return one.start;
- return -1;
-}
-
-static inline bool isFP(const Temp &t)
-{ return t.type == DoubleType; }
-
-static inline bool candidateIsBetterFit(int bestSizeSoFar, int idealSize, int candidateSize)
-{
- // If the candidateSize is larger than the current we take it only if the current size does not
- // yet fit for the whole interval.
- if (bestSizeSoFar < candidateSize && bestSizeSoFar < idealSize)
- return true;
-
- // If the candidateSize is smaller we only take it if it still fits the whole interval.
- if (bestSizeSoFar > candidateSize && candidateSize >= idealSize)
- return true;
-
- // Other wise: no luck.
- return false;
-}
-
-// Out of all available registers (with their next-uses), choose the one that fits the requested
-// duration best. This can return a register that is not free for the whole interval, but that's
-// fine: we just have to split the current interval.
-static void longestAvailableReg(int *nextUses, int nextUseCount, int &reg, int &freeUntilPos_reg, int lastUse)
-{
- reg = LifeTimeInterval::InvalidRegister;
- freeUntilPos_reg = 0;
-
- for (int candidate = 0, candidateEnd = nextUseCount; candidate != candidateEnd; ++candidate) {
- int fp = nextUses[candidate];
- if (candidateIsBetterFit(freeUntilPos_reg, lastUse, fp)) {
- reg = candidate;
- freeUntilPos_reg = fp;
- }
- }
-}
-
-#define CALLOC_ON_STACK(ty, ptr, sz, val) \
- Q_ASSERT(sz > 0); \
- Q_ALLOCA_VAR(ty, ptr, sizeof(ty) * (sz)); \
- for (ty *it = ptr, *eit = ptr + (sz); it != eit; ++it) \
- *it = val;
-
-// Try to allocate a register that's currently free.
-void RegisterAllocator::tryAllocateFreeReg(LifeTimeInterval &current)
-{
- Q_ASSERT(!current.isFixedInterval());
- Q_ASSERT(current.reg() == LifeTimeInterval::InvalidRegister);
-
- const bool needsFPReg = isFP(current.temp());
- const int freeUntilPosCount = needsFPReg ? _fpRegisters.size() : _normalRegisters.size();
- CALLOC_ON_STACK(int, freeUntilPos, freeUntilPosCount, INT_MAX);
-
- for (Intervals::const_iterator i = _active.constBegin(), ei = _active.constEnd(); i != ei; ++i) {
- const LifeTimeInterval *it = *i;
- if (it->isFP() == needsFPReg)
- freeUntilPos[it->reg()] = 0; // mark register as unavailable
- }
-
- for (Intervals::const_iterator i = _inactive.constBegin(), ei = _inactive.constEnd(); i != ei; ++i) {
- const LifeTimeInterval *it = *i;
- if (it->isFP() != needsFPReg)
- continue; // different register type, so not applicable.
- if (it->reg() == LifeTimeInterval::InvalidRegister)
- continue; // this range does not block a register from being used, as it has no register assigned
-
- if (current.isSplitFromInterval() || it->isFixedInterval()) {
- const int intersectionPos = nextIntersection(current, *it);
- if (intersectionPos != -1)
- freeUntilPos[it->reg()] = qMin(freeUntilPos[it->reg()], intersectionPos);
- }
- }
-
- int reg = LifeTimeInterval::InvalidRegister;
- int freeUntilPos_reg = 0;
-
- const RegAllocInfo::Hints &hints = _info->hints(current.temp());
- for (RegAllocInfo::Hints::const_iterator i = hints.begin(), ei = hints.end(); i != ei; ++i) {
- const Temp &hint = *i;
- int candidate;
- if (hint.kind == Temp::PhysicalRegister)
- candidate = hint.index;
- else
- candidate = _lastAssignedRegister[hint.index];
-
- const int end = current.end();
- if (candidate == LifeTimeInterval::InvalidRegister)
- continue; // the candidate has no register assigned, so it cannot be (re-)used
- if (current.isFP() != isFP(hint))
- continue; // different register type, so not applicable.
-
- const int fp = freeUntilPos[candidate];
- if (candidateIsBetterFit(freeUntilPos_reg, end, fp)) {
- reg = candidate;
- freeUntilPos_reg = fp;
- }
- }
-
- // None of the hinted registers could fit the interval, so try all registers next.
- if (reg == LifeTimeInterval::InvalidRegister)
- longestAvailableReg(freeUntilPos, freeUntilPosCount, reg, freeUntilPos_reg, current.end());
-
- if (freeUntilPos_reg == 0) {
- // no register available without spilling
- if (DebugRegAlloc)
- qDebug("*** no register available for %u", current.temp().index);
- return;
- } else if (current.end() < freeUntilPos_reg) {
- // register available for the whole interval
- if (DebugRegAlloc)
- qDebug() << "*** allocating register" << reg << "for the whole interval of %" << current.temp().index;
- current.setReg(reg);
- _lastAssignedRegister[current.temp().index] = reg;
- markInUse(reg, needsFPReg);
- } else {
- // register available for the first part of the interval
-
- // TODO: this is slightly inefficient in the following case:
- // %1 = something
- // some_call(%1)
- // %2 = %1 + 1
- // Now %1 will get a register assigned, and will be spilled to the stack immediately. It
- // would be better to check if there are actually uses in the range before the split.
-
- current.setReg(reg);
- _lastAssignedRegister[current.temp().index] = reg;
- if (DebugRegAlloc)
- qDebug() << "*** allocating register" << reg << "for the first part of interval of %" << current.temp().index;
- split(current, freeUntilPos_reg, true);
- markInUse(reg, needsFPReg);
- }
-}
-
-// This gets called when all registers are currently in use.
-void RegisterAllocator::allocateBlockedReg(LifeTimeInterval &current)
-{
- Q_ASSERT(!current.isFixedInterval());
- Q_ASSERT(current.reg() == LifeTimeInterval::InvalidRegister);
- const int position = current.start();
-
- const bool isPhiTarget = _info->isPhiTarget(current.temp());
- if (isPhiTarget && !current.isSplitFromInterval()) {
- // Special case: storing to a phi-node's target will result in a single move. So, if we
- // would spill another interval to the stack (that's 1 store), and then do the move for the
- // phi target (at least 1 move or a load), that would result in 2 instructions. Instead, we
- // force the phi-node's target to go to the stack immediately, which is always a single
- // store.
- split(current, position + 1, true);
- _inactive.append(&current);
- return;
- }
-
- const bool needsFPReg = isFP(current.temp());
- const int nextUsePosCount = needsFPReg ? _fpRegisters.size() : _normalRegisters.size();
- CALLOC_ON_STACK(int, nextUsePos, nextUsePosCount, INT_MAX);
- QVector<LifeTimeInterval *> nextUseRangeForReg(nextUsePosCount, 0);
-
- for (Intervals::const_iterator i = _active.constBegin(), ei = _active.constEnd(); i != ei; ++i) {
- LifeTimeInterval &it = **i;
- if (it.isFP() != needsFPReg)
- continue; // different register type, so not applicable.
-
- const int nu = it.isFixedInterval() ? 0 : nextUse(it.temp(), current.start());
- if (nu == position) {
- nextUsePos[it.reg()] = 0;
- } else if (nu != -1 && nu < nextUsePos[it.reg()]) {
- nextUsePos[it.reg()] = nu;
- nextUseRangeForReg[it.reg()] = &it;
- } else if (nu == -1 && nextUsePos[it.reg()] == INT_MAX) {
- // in a loop, the range can be active, but the result might only be used before the
- // current position (e.g. the induction variable being used in the phi node in the loop
- // header). So, we can use this register, but we need to remember to split the interval
- // in order to have the edge-resolving generate a load at the edge going back to the
- // loop header.
- nextUseRangeForReg[it.reg()] = &it;
- }
- }
-
- for (Intervals::const_iterator i = _inactive.constBegin(), ei = _inactive.constEnd(); i != ei; ++i) {
- LifeTimeInterval &it = **i;
- if (it.isFP() != needsFPReg)
- continue; // different register type, so not applicable.
- if (it.reg() == LifeTimeInterval::InvalidRegister)
- continue; // this range does not block a register from being used, as it has no register assigned
-
- if (current.isSplitFromInterval() || it.isFixedInterval()) {
- if (nextIntersection(current, it) != -1) {
- const int nu = nextUse(it.temp(), current.start());
- if (nu != -1 && nu < nextUsePos[it.reg()]) {
- nextUsePos[it.reg()] = nu;
- nextUseRangeForReg[it.reg()] = &it;
- }
- }
- }
- }
-
- int reg, nextUsePos_reg;
- longestAvailableReg(nextUsePos, nextUsePosCount, reg, nextUsePos_reg, current.end());
-
- Q_ASSERT(current.start() <= nextUsePos_reg);
-
- // spill interval that currently block reg
- if (DebugRegAlloc) {
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream out(&buf);
- out << "*** spilling intervals that block reg " <<reg<< " for interval ";
- current.dump(out);
- qDebug("%s", buf.data().constData());
- }
- current.setReg(reg);
- _lastAssignedRegister[current.temp().index] = reg;
- LifeTimeInterval *nextUse = nextUseRangeForReg[reg];
- Q_ASSERT(nextUse);
- Q_ASSERT(!nextUse->isFixedInterval());
-
- split(*nextUse, position, /*skipOptionalRegisterUses =*/ true);
-
- // We might have chosen a register that is used by a range that has a hole in its life time.
- // If that's the case, check if the current interval completely fits in the hole. Or rephrased:
- // check if the current interval will use the register after that hole ends (so that range, and
- // if so, split that interval so that it gets a new register assigned when it needs one.
- splitInactiveAtEndOfLifetimeHole(reg, needsFPReg, position);
-
- // make sure that current does not intersect with the fixed interval for reg
- const LifeTimeInterval *fixedRegRange = needsFPReg ? _fixedFPRegisterRanges.at(reg)
- : _fixedRegisterRanges.at(reg);
- if (fixedRegRange) {
- int ni = nextIntersection(current, *fixedRegRange);
- if (ni != -1) {
- if (DebugRegAlloc) {
- qDebug("***-- current range intersects with a fixed reg use at %d, so splitting it.", ni);
- }
- // current does overlap with a fixed interval, so split current before that intersection.
- split(current, ni, true);
- }
- }
-}
-
-int RegisterAllocator::nextIntersection(const LifeTimeInterval &current,
- const LifeTimeInterval &another) const
-{
- const LifeTimeInterval::Ranges &currentRanges = current.ranges();
- int currentIt = 0;
-
- const LifeTimeInterval::Ranges &anotherRanges = another.ranges();
- const int anotherItStart = indexOfRangeCoveringPosition(anotherRanges, current.start());
- if (anotherItStart == -1)
- return -1;
-
- for (int currentEnd = currentRanges.size(); currentIt < currentEnd; ++currentIt) {
- const LifeTimeIntervalRange currentRange = currentRanges.at(currentIt);
- for (int anotherIt = anotherItStart, anotherEnd = anotherRanges.size(); anotherIt < anotherEnd; ++anotherIt) {
- const LifeTimeIntervalRange anotherRange = anotherRanges.at(anotherIt);
- if (anotherRange.start > currentRange.end)
- break;
- int intersectPos = intersectionPosition(currentRange, anotherRange);
- if (intersectPos != -1)
- return intersectPos;
- }
- }
-
- return -1;
-}
-
-/// Find the first use after the start position for the given temp.
-///
-/// This is only called when all registers are in use, and when one of them has to be spilled to the
-/// stack. So, uses where a register is optional can be ignored.
-int RegisterAllocator::nextUse(const Temp &t, int startPosition) const
-{
- typedef std::vector<Use>::const_iterator ConstIt;
-
- const std::vector<Use> &usePositions = _info->uses(t);
- const ConstIt cend = usePositions.end();
- for (ConstIt it = usePositions.begin(); it != cend; ++it) {
- if (it->mustHaveRegister()) {
- const int usePos = it->pos;
- if (usePos >= startPosition)
- return usePos;
- }
- }
-
- return -1;
-}
-
-static inline void insertReverseSorted(QVector<LifeTimeInterval *> &intervals, LifeTimeInterval *newInterval)
-{
- newInterval->validate();
- for (int i = intervals.size(); i > 0;) {
- if (LifeTimeInterval::lessThan(newInterval, intervals.at(--i))) {
- intervals.insert(i + 1, newInterval);
- return;
- }
- }
- intervals.insert(0, newInterval);
-}
-
-void RegisterAllocator::split(LifeTimeInterval &current, int beforePosition,
- bool skipOptionalRegisterUses)
-{ // TODO: check if we can always skip the optional register uses
- Q_ASSERT(!current.isFixedInterval());
-
- if (DebugRegAlloc) {
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream out(&buf);
- out << "***** split request for range ";
- current.dump(out);
- out << " before position " << beforePosition
- << " and skipOptionalRegisterUses = " << skipOptionalRegisterUses << endl;
- qDebug("%s", buf.data().constData());
- }
-
- assignSpillSlot(current.temp(), current.start(), current.end());
-
- const int firstPosition = current.start();
- Q_ASSERT(beforePosition > firstPosition && "split before start");
-
- int lastUse = firstPosition;
- int nextUse = -1;
- const std::vector<Use> &usePositions = _info->uses(current.temp());
- for (size_t i = 0, ei = usePositions.size(); i != ei; ++i) {
- const Use &usePosition = usePositions.at(i);
- const int usePos = usePosition.pos;
- if (lastUse < usePos && usePos < beforePosition) {
- lastUse = usePos;
- } else if (usePos >= beforePosition) {
- if (!skipOptionalRegisterUses || usePosition.mustHaveRegister()) {
- nextUse = usePos;
- break;
- }
- }
- }
- Q_ASSERT(lastUse != -1);
- Q_ASSERT(lastUse < beforePosition);
-
- LifeTimeInterval newInterval = current.split(lastUse, nextUse);
- if (DebugRegAlloc) {
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream out(&buf);
- out << "***** last use = " << lastUse << ", nextUse = " << nextUse << endl;
- out << "***** new interval: ";
- newInterval.dump(out);
- out << endl;
- out << "***** preceding interval: ";
- current.dump(out);
- out << endl;
- qDebug("%s", buf.data().constData());
- }
- if (newInterval.isValid()) {
- if (current.reg() != LifeTimeInterval::InvalidRegister)
- _info->addHint(current.temp(), current.reg());
- newInterval.setReg(LifeTimeInterval::InvalidRegister);
- LifeTimeInterval *newIntervalPtr = new LifeTimeInterval(newInterval);
- _lifeTimeIntervals->add(newIntervalPtr);
- insertReverseSorted(_unhandled, newIntervalPtr);
- }
-}
-
-void RegisterAllocator::splitInactiveAtEndOfLifetimeHole(int reg, bool isFPReg, int position)
-{
- for (int i = 0, ei = _inactive.size(); i != ei; ++i) {
- LifeTimeInterval &interval = *_inactive[i];
- if (interval.isFixedInterval())
- continue;
- if (isFPReg == interval.isFP() && interval.reg() == reg) {
- LifeTimeInterval::Ranges ranges = interval.ranges();
- int endOfLifetimeHole = -1;
- for (int j = 0, ej = ranges.size(); j != ej; ++j) {
- if (position < ranges[j].start)
- endOfLifetimeHole = ranges[j].start;
- }
- if (endOfLifetimeHole != -1)
- split(interval, endOfLifetimeHole);
- }
- }
-}
-
-void RegisterAllocator::assignSpillSlot(const Temp &t, int startPos, int endPos)
-{
- if (_assignedSpillSlots[t.index] != InvalidSpillSlot)
- return;
-
- for (int i = 0, ei = _activeSpillSlots.size(); i != ei; ++i) {
- if (_activeSpillSlots.at(i) < startPos) {
- _activeSpillSlots[i] = endPos;
- _assignedSpillSlots[t.index] = i;
- return;
- }
- }
-
- Q_UNREACHABLE();
-}
-
-void RegisterAllocator::dump(IR::Function *function) const
-{
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- QTextStream qout(&buf);
- IRPrinterWithPositions printer(&qout, _lifeTimeIntervals);
-
- qout << "Ranges:" << endl;
- QVector<LifeTimeInterval *> handled = _handled;
- std::sort(handled.begin(), handled.end(), LifeTimeInterval::lessThanForTemp);
- for (const LifeTimeInterval *r : qAsConst(handled)) {
- r->dump(qout);
- qout << endl;
- }
-
- qout << "Spill slots:" << endl;
- for (unsigned i = 0; i < _assignedSpillSlots.size(); ++i)
- if (_assignedSpillSlots[i] != InvalidSpillSlot)
- qout << "\t%" << i << " -> " << _assignedSpillSlots[i] << endl;
-
- printer.print(function);
- qDebug("%s", buf.data().constData());
-}
-
-// References:
-// [Wimmer1] C. Wimmer and M. Franz. Linear Scan Register Allocation on SSA Form. In Proceedings of
-// CGO'10, ACM Press, 2010
-// [Wimmer2] C. Wimmer and H. Mossenbock. Optimized Interval Splitting in a Linear Scan Register
-// Allocator. In Proceedings of the ACM/USENIX International Conference on Virtual
-// Execution Environments, pages 132-141. ACM Press, 2005.
-// [Traub] Omri Traub, Glenn Holloway, and Michael D. Smith. Quality and Speed in Linear-scan
-// Register Allocation. In Proceedings of the ACM SIGPLAN 1998 Conference on Programming
-// Language Design and Implementation, pages 142-151, June 1998.
diff --git a/src/qml/jit/qv4regalloc_p.h b/src/qml/jit/qv4regalloc_p.h
deleted file mode 100644
index 4ee440b73e..0000000000
--- a/src/qml/jit/qv4regalloc_p.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the V4VM module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#ifndef QV4REGALLOC_P_H
-#define QV4REGALLOC_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qv4global_p.h"
-#include "qv4isel_p.h"
-#include "qv4ssa_p.h"
-#include "qv4registerinfo_p.h"
-
-#include <config.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace QV4 {
-namespace JIT {
-
-class RegAllocInfo;
-
-// This class implements a linear-scan register allocator, with a couple of tweaks:
-// - Second-chance allocation is used when an interval becomes active after a spill, which results
-// in fewer differences between edges, and hence fewer moves before jumps.
-// - Use positions are flagged with either "must have" register or "could have" register. This is
-// used to decide whether a register is really needed when a temporary is used after a spill
-// occurred.
-// - Fixed intervals are used to denotate IR positions where certain registers are needed in order
-// to implement the operation, and cannot be used by a temporary on that position. An example is
-// caller saved registers, where the call will use/clobber those registers.
-// - Hints are used to indicate which registers could be used to generate more compact code. An
-// example is an addition, where one (or both) operands' life-time ends at that instruction. In
-// this case, re-using an operand register for the result will result in an in-place add.
-// - SSA form properties are used:
-// - to simplify life-times (two temporaries will never interfere as long as their intervals
-// are not split), resulting in a slightly faster algorithm;
-// - when a temporary needs to be spilled, it is done directly after calculating it, so that
-// 1 store is generated even if multiple spills/splits happen.
-// - phi-node elimination (SSA form deconstruction) is done when resolving differences between
-// CFG edges
-class RegisterAllocator
-{
- typedef IR::LifeTimeInterval LifeTimeInterval;
-
- const RegisterInformation &_registerInformation;
- QVector<const RegisterInfo *> _normalRegisters;
- QVector<const RegisterInfo *> _fpRegisters;
- QScopedPointer<RegAllocInfo> _info;
-
- QVector<LifeTimeInterval *> _fixedRegisterRanges, _fixedFPRegisterRanges;
-
- IR::LifeTimeIntervals::Ptr _lifeTimeIntervals;
- typedef QVector<LifeTimeInterval *> Intervals;
- Intervals _unhandled, _active, _inactive, _handled;
-
- std::vector<int> _lastAssignedRegister;
- std::vector<int> _assignedSpillSlots;
- QVector<int> _activeSpillSlots;
-
- QBitArray _regularRegsInUse, _fpRegsInUse;
-
- Q_DISABLE_COPY(RegisterAllocator)
-
-public:
- enum { InvalidSpillSlot = -1 };
-
- RegisterAllocator(const RegisterInformation &registerInformation);
- ~RegisterAllocator();
-
- void run(IR::Function *function, const IR::Optimizer &opt);
- RegisterInformation usedRegisters() const;
-
-private:
- void markInUse(int reg, bool isFPReg);
- LifeTimeInterval *cloneFixedInterval(int reg, bool isFP, const LifeTimeInterval &original);
- void prepareRanges();
- void linearScan();
- void tryAllocateFreeReg(LifeTimeInterval &current);
- void allocateBlockedReg(LifeTimeInterval &current);
- int nextIntersection(const LifeTimeInterval &current, const LifeTimeInterval &another) const;
- int nextUse(const IR::Temp &t, int startPosition) const;
- void split(LifeTimeInterval &current, int beforePosition, bool skipOptionalRegisterUses =false);
- void splitInactiveAtEndOfLifetimeHole(int reg, bool isFPReg, int position);
- void assignSpillSlot(const IR::Temp &t, int startPos, int endPos);
- void resolve(IR::Function *function, const IR::Optimizer &opt);
-
- void dump(IR::Function *function) const;
-};
-
-} // end of namespace JIT
-} // end of namespace QV4
-
-QT_END_NAMESPACE
-
-#endif // QV4REGALLOC_P_H
diff --git a/src/qml/jit/qv4targetplatform_p.h b/src/qml/jit/qv4targetplatform_p.h
deleted file mode 100644
index 6d788f4a93..0000000000
--- a/src/qml/jit/qv4targetplatform_p.h
+++ /dev/null
@@ -1,707 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QV4TARGETPLATFORM_P_H
-#define QV4TARGETPLATFORM_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <config.h>
-
-#if ENABLE(ASSEMBLER)
-
-#include <private/qv4value_p.h>
-#include "qv4registerinfo_p.h"
-#include <assembler/MacroAssembler.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace QV4 {
-namespace JIT {
-
-enum TargetOperatingSystemSpecialization {
- NoOperatingSystemSpecialization,
- WindowsSpecialization
-};
-
-// The TargetPlatform class describes how the stack and the registers work on a CPU+ABI combination.
-//
-// All combinations have a separate definition, guarded by #ifdefs. The exceptions are:
-// - Linux/x86 and win32, which are the same, except that linux non-PIC/PIE code does not need to
-// restore ebx (which holds the GOT ptr) before a call
-// - All (supported) ARM platforms, where the only variety is the platform specific usage of r9,
-// and the frame-pointer in Thumb/Thumb2 v.s. ARM mode.
-//
-// Specific handling of ebx when it holds the GOT:
-// In this case we can use it, but it needs to be restored when doing a call. So, the handling is as
-// follows: it is marked as caller saved, meaning the value in it won't survive a call. When
-// calculating the list of callee saved registers in getCalleeSavedRegisters (which is used to
-// generate push/pop instructions in the prelude/postlude), we add ebx too. Then when synthesizing
-// a call, we add a load it right before emitting the call instruction.
-//
-// NOTE: When adding new architecture, do not forget to whitelist it in qv4global_p.h!
-template <typename PlatformAssembler, TargetOperatingSystemSpecialization specialization = NoOperatingSystemSpecialization>
-class TargetPlatform
-{
-};
-
-#if CPU(X86) && (OS(LINUX) || OS(WINDOWS) || OS(QNX) || OS(FREEBSD) || defined(Q_OS_IOS))
-template <>
-class TargetPlatform<JSC::MacroAssemblerX86, NoOperatingSystemSpecialization>
-{
-public:
- using PlatformAssembler = JSC::MacroAssemblerX86;
- using RegisterID = PlatformAssembler::RegisterID;
- using FPRegisterID = PlatformAssembler::FPRegisterID;
- using TrustedImm32 = PlatformAssembler::TrustedImm32;
-
- enum { RegAllocIsSupported = 1 };
-
- static const RegisterID FramePointerRegister = JSC::X86Registers::ebp;
- static const RegisterID StackPointerRegister = JSC::X86Registers::esp;
- static const RegisterID LocalsRegister = JSC::X86Registers::edi;
- static const RegisterID EngineRegister = JSC::X86Registers::esi;
- static const RegisterID ReturnValueRegister = JSC::X86Registers::eax;
- static const RegisterID ScratchRegister = JSC::X86Registers::ecx;
- static const FPRegisterID FPGpr0 = JSC::X86Registers::xmm0;
- static const FPRegisterID FPGpr1 = JSC::X86Registers::xmm1;
- static const RegisterID LowReturnValueRegister = JSC::X86Registers::eax;
- static const RegisterID HighReturnValueRegister = JSC::X86Registers::edx;
-
- static RegisterInformation getRegisterInfo()
- {
- typedef RegisterInfo RI;
- static RegisterInformation info = RegisterInformation()
- << RI(JSC::X86Registers::edx, QStringLiteral("edx"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::ebx, QStringLiteral("ebx"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::edi, QStringLiteral("edi"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
- << RI(JSC::X86Registers::esi, QStringLiteral("esi"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
- << RI(JSC::X86Registers::xmm2, QStringLiteral("xmm2"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::xmm3, QStringLiteral("xmm3"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::xmm4, QStringLiteral("xmm4"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::xmm5, QStringLiteral("xmm5"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::xmm6, QStringLiteral("xmm6"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::xmm7, QStringLiteral("xmm7"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- ;
- return info;
- }
-
-# define HAVE_ALU_OPS_WITH_MEM_OPERAND 1
- static const int RegisterSize = 4;
-
- static const int RegisterArgumentCount = 0;
- static RegisterID registerForArgument(int) { Q_UNREACHABLE(); }
-
- static const int StackAlignment = 16;
- static const int StackShadowSpace = 0;
- static const int StackSpaceAllocatedUponFunctionEntry = RegisterSize; // Return address is pushed onto stack by the CPU.
- static void platformEnterStandardStackFrame(PlatformAssembler *as) { as->push(FramePointerRegister); }
- static void platformFinishEnteringStandardStackFrame(PlatformAssembler *) {}
- static void platformLeaveStandardStackFrame(PlatformAssembler *as, int frameSize)
- {
- if (frameSize > 0)
- as->add32(TrustedImm32(frameSize), StackPointerRegister);
- as->pop(FramePointerRegister);
- }
-
-#if OS(WINDOWS) || OS(QNX) || \
- ((OS(LINUX) || OS(FREEBSD)) && (defined(__PIC__) || defined(__PIE__)))
-
- static const int gotRegister = JSC::X86Registers::ebx;
- static int savedGOTRegisterSlotOnStack() {
- static int ebxIdx = -1;
- if (ebxIdx == -1) {
- int calleeSaves = 0;
- const auto infos = getRegisterInfo();
- for (const RegisterInfo &info : infos) {
- if (info.reg<JSC::X86Registers::RegisterID>() == JSC::X86Registers::ebx) {
- ebxIdx = calleeSaves;
- break;
- } else if (info.isCalleeSaved()) {
- ++calleeSaves;
- }
- }
- Q_ASSERT(ebxIdx >= 0);
- ebxIdx += 1;
- }
- return ebxIdx * -int(sizeof(void*));
- }
-#else
- static const int gotRegister = -1;
- static int savedGOTRegisterSlotOnStack() { return -1; }
-#endif
-};
-#endif // x86
-
-#if CPU(X86_64) && (OS(LINUX) || OS(MAC_OS_X) || OS(FREEBSD) || OS(QNX) || defined(Q_OS_IOS))
-template <>
-class TargetPlatform<JSC::MacroAssemblerX86_64, NoOperatingSystemSpecialization>
-{
-public:
- using PlatformAssembler = JSC::MacroAssemblerX86_64;
- using RegisterID = PlatformAssembler::RegisterID;
- using FPRegisterID = PlatformAssembler::FPRegisterID;
- using TrustedImm32 = PlatformAssembler::TrustedImm32;
-
- enum { RegAllocIsSupported = 1 };
-
- static const RegisterID FramePointerRegister = JSC::X86Registers::ebp;
- static const RegisterID StackPointerRegister = JSC::X86Registers::esp;
- static const RegisterID LocalsRegister = JSC::X86Registers::r12;
- static const RegisterID EngineRegister = JSC::X86Registers::r14;
- static const RegisterID ReturnValueRegister = JSC::X86Registers::eax;
- static const RegisterID ScratchRegister = JSC::X86Registers::r10;
- static const RegisterID DoubleMaskRegister = JSC::X86Registers::r13;
- static const FPRegisterID FPGpr0 = JSC::X86Registers::xmm0;
- static const FPRegisterID FPGpr1 = JSC::X86Registers::xmm1;
-
- static RegisterInformation getRegisterInfo()
- {
- typedef RegisterInfo RI;
- static RegisterInformation info = RegisterInformation()
- << RI(JSC::X86Registers::ebx, QStringLiteral("rbx"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::edi, QStringLiteral("rdi"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::esi, QStringLiteral("rsi"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::edx, QStringLiteral("rdx"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::r9, QStringLiteral("r9"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::r8, QStringLiteral("r8"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- // r11 is used as scratch register by the macro assembler
- << RI(JSC::X86Registers::r12, QStringLiteral("r12"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
- << RI(JSC::X86Registers::r13, QStringLiteral("r13"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
- << RI(JSC::X86Registers::r14, QStringLiteral("r14"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
- << RI(JSC::X86Registers::r15, QStringLiteral("r15"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::xmm2, QStringLiteral("xmm2"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::xmm3, QStringLiteral("xmm3"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::xmm4, QStringLiteral("xmm4"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::xmm5, QStringLiteral("xmm5"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::xmm6, QStringLiteral("xmm6"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::xmm7, QStringLiteral("xmm7"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- ;
- return info;
- }
-
-#define HAVE_ALU_OPS_WITH_MEM_OPERAND 1
- static const int RegisterSize = 8;
-
- static const int RegisterArgumentCount = 6;
- static RegisterID registerForArgument(int index)
- {
- static RegisterID regs[RegisterArgumentCount] = {
- JSC::X86Registers::edi,
- JSC::X86Registers::esi,
- JSC::X86Registers::edx,
- JSC::X86Registers::ecx,
- JSC::X86Registers::r8,
- JSC::X86Registers::r9
- };
- Q_ASSERT(index >= 0 && index < RegisterArgumentCount);
- return regs[index];
- };
-
- static const int StackAlignment = 16;
- static const int StackShadowSpace = 0;
- static const int StackSpaceAllocatedUponFunctionEntry = RegisterSize; // Return address is pushed onto stack by the CPU.
- static void platformEnterStandardStackFrame(PlatformAssembler *as) { as->push(FramePointerRegister); }
- static void platformFinishEnteringStandardStackFrame(PlatformAssembler *as)
- {
- as->move(PlatformAssembler::TrustedImm64(QV4::Value::NaNEncodeMask), DoubleMaskRegister);
- }
- static void platformLeaveStandardStackFrame(PlatformAssembler *as, int frameSize)
- {
- if (frameSize > 0)
- as->add64(TrustedImm32(frameSize), StackPointerRegister);
- as->pop(FramePointerRegister);
- }
-
- static const int gotRegister = -1;
- static int savedGOTRegisterSlotOnStack() { return -1; }
-};
-#endif // Linux/MacOS on x86_64
-
-#if CPU(X86_64) && OS(WINDOWS)
-template <>
-class TargetPlatform<JSC::MacroAssemblerX86_64, WindowsSpecialization>
-{
-public:
- using PlatformAssembler = JSC::MacroAssemblerX86_64;
- using RegisterID = PlatformAssembler::RegisterID;
- using FPRegisterID = PlatformAssembler::FPRegisterID;
- using TrustedImm32 = PlatformAssembler::TrustedImm32;
-
- enum { RegAllocIsSupported = 1 };
-
- static const RegisterID FramePointerRegister = JSC::X86Registers::ebp;
- static const RegisterID StackPointerRegister = JSC::X86Registers::esp;
- static const RegisterID LocalsRegister = JSC::X86Registers::r12;
- static const RegisterID EngineRegister = JSC::X86Registers::r14;
- static const RegisterID ReturnValueRegister = JSC::X86Registers::eax;
- static const RegisterID ScratchRegister = JSC::X86Registers::r10;
- static const RegisterID DoubleMaskRegister = JSC::X86Registers::r13;
- static const FPRegisterID FPGpr0 = JSC::X86Registers::xmm0;
- static const FPRegisterID FPGpr1 = JSC::X86Registers::xmm1;
-
- static RegisterInformation getRegisterInfo()
- {
- typedef RegisterInfo RI;
- static RegisterInformation info = RegisterInformation()
- << RI(JSC::X86Registers::ebx, QStringLiteral("rbx"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::edi, QStringLiteral("rdi"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::esi, QStringLiteral("rsi"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::edx, QStringLiteral("rdx"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::r8, QStringLiteral("r8"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::r9, QStringLiteral("r9"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- // r11 is used as scratch register by the macro assembler
- << RI(JSC::X86Registers::r12, QStringLiteral("r12"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
- << RI(JSC::X86Registers::r13, QStringLiteral("r13"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
- << RI(JSC::X86Registers::r14, QStringLiteral("r14"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
- << RI(JSC::X86Registers::r15, QStringLiteral("r15"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::xmm2, QStringLiteral("xmm2"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::xmm3, QStringLiteral("xmm3"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::xmm4, QStringLiteral("xmm4"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::xmm5, QStringLiteral("xmm5"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::xmm6, QStringLiteral("xmm6"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::X86Registers::xmm7, QStringLiteral("xmm7"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
- ;
- return info;
- }
-
-#define HAVE_ALU_OPS_WITH_MEM_OPERAND 1
- static const int RegisterSize = 8;
-
- static const int RegisterArgumentCount = 4;
- static RegisterID registerForArgument(int index)
- {
- static RegisterID regs[RegisterArgumentCount] = {
- JSC::X86Registers::ecx,
- JSC::X86Registers::edx,
- JSC::X86Registers::r8,
- JSC::X86Registers::r9
- };
- Q_ASSERT(index >= 0 && index < RegisterArgumentCount);
- return regs[index];
- }
-
- static const int StackAlignment = 16;
- static const int StackShadowSpace = 32;
- static const int StackSpaceAllocatedUponFunctionEntry = RegisterSize; // Return address is pushed onto stack by the CPU.
- static void platformEnterStandardStackFrame(PlatformAssembler *as) { as->push(FramePointerRegister); }
- static void platformFinishEnteringStandardStackFrame(PlatformAssembler *as)
- {
- as->move(PlatformAssembler::TrustedImm64(QV4::Value::NaNEncodeMask), DoubleMaskRegister);
- }
- static void platformLeaveStandardStackFrame(PlatformAssembler *as, int frameSize)
- {
- if (frameSize > 0)
- as->add64(TrustedImm32(frameSize), StackPointerRegister);
- as->pop(FramePointerRegister);
- }
-
- static const int gotRegister = -1;
- static int savedGOTRegisterSlotOnStack() { return -1; }
-};
-#endif // Windows on x86_64
-
-#if CPU(ARM) || defined(V4_BOOTSTRAP)
-template <>
-class TargetPlatform<JSC::MacroAssemblerARMv7, NoOperatingSystemSpecialization>
-{
-public:
- using PlatformAssembler = JSC::MacroAssemblerARMv7;
- using RegisterID = PlatformAssembler::RegisterID;
- using FPRegisterID = PlatformAssembler::FPRegisterID;
- using TrustedImm32 = PlatformAssembler::TrustedImm32;
-
- enum { RegAllocIsSupported = 1 };
-
- // The AAPCS specifies that the platform ABI has to define the usage of r9. Known are:
- // - The GNU/Linux ABI defines it as an additional callee-saved variable register (v6).
- // - iOS (for which we cannot JIT, but still...) defines it as having a special use, so we do
- // not touch it, nor use it.
- // - Any other platform has not been verified, so we conservatively assume we cannot use it.
-#if OS(LINUX)
-#define CAN_USE_R9
-#endif
-
- // There are two designated frame-pointer registers on ARM, depending on which instruction set
- // is used for the subroutine: r7 for Thumb or Thumb2, and r11 for ARM. We assign the constants
- // accordingly, and assign the locals-register to the "other" register.
-#if CPU(ARM_THUMB2) || defined(V4_BOOTSTRAP)
- static const RegisterID FramePointerRegister = JSC::ARMRegisters::r7;
- static const RegisterID LocalsRegister = JSC::ARMRegisters::r11;
-#else // Thumbs down
- static const RegisterID FramePointerRegister = JSC::ARMRegisters::r11;
- static const RegisterID LocalsRegister = JSC::ARMRegisters::r7;
-#endif
- static const RegisterID StackPointerRegister = JSC::ARMRegisters::r13;
- static const RegisterID ScratchRegister = JSC::ARMRegisters::r5;
- static const RegisterID EngineRegister = JSC::ARMRegisters::r10;
- static const RegisterID ReturnValueRegister = JSC::ARMRegisters::r0;
- static const FPRegisterID FPGpr0 = JSC::ARMRegisters::d0;
- static const FPRegisterID FPGpr1 = JSC::ARMRegisters::d1;
- static const RegisterID LowReturnValueRegister = JSC::ARMRegisters::r0;
- static const RegisterID HighReturnValueRegister = JSC::ARMRegisters::r1;
-
- static RegisterInformation getRegisterInfo()
- {
- typedef RegisterInfo RI;
- static RegisterInformation info = RegisterInformation()
- << RI(JSC::ARMRegisters::r0, QStringLiteral("r0"), RI::RegularRegister, RI::CallerSaved, RI::Predefined)
- << RI(JSC::ARMRegisters::r1, QStringLiteral("r1"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARMRegisters::r2, QStringLiteral("r2"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARMRegisters::r3, QStringLiteral("r3"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARMRegisters::r4, QStringLiteral("r4"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::ARMRegisters::r5, QStringLiteral("r5"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
- << RI(JSC::ARMRegisters::r6, QStringLiteral("r6"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
-#if !CPU(ARM_THUMB2) && !defined(V4_BOOTSTRAP)
- << RI(JSC::ARMRegisters::r7, QStringLiteral("r7"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
-#endif
- << RI(JSC::ARMRegisters::r8, QStringLiteral("r8"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
-#ifdef CAN_USE_R9
- << RI(JSC::ARMRegisters::r9, QStringLiteral("r9"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
-#endif
- << RI(JSC::ARMRegisters::r10, QStringLiteral("r10"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
-#if CPU(ARM_THUMB2) || defined(V4_BOOTSTRAP)
- << RI(JSC::ARMRegisters::r11, QStringLiteral("r11"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
-#endif
- << RI(JSC::ARMRegisters::d2, QStringLiteral("d2"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARMRegisters::d3, QStringLiteral("d3"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARMRegisters::d4, QStringLiteral("d4"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARMRegisters::d5, QStringLiteral("d5"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARMRegisters::d6, QStringLiteral("d6"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARMRegisters::d8, QStringLiteral("d8"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::ARMRegisters::d9, QStringLiteral("d9"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::ARMRegisters::d10, QStringLiteral("d10"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::ARMRegisters::d11, QStringLiteral("d11"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::ARMRegisters::d12, QStringLiteral("d12"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::ARMRegisters::d13, QStringLiteral("d13"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::ARMRegisters::d14, QStringLiteral("d14"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::ARMRegisters::d15, QStringLiteral("d15"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
- ;
- return info;
- }
-
-#undef HAVE_ALU_OPS_WITH_MEM_OPERAND
- static const int RegisterSize = 4;
-
- static const int RegisterArgumentCount = 4;
- static RegisterID registerForArgument(int index)
- {
- static RegisterID regs[RegisterArgumentCount] = {
- JSC::ARMRegisters::r0,
- JSC::ARMRegisters::r1,
- JSC::ARMRegisters::r2,
- JSC::ARMRegisters::r3
- };
-
- Q_ASSERT(index >= 0 && index < RegisterArgumentCount);
- return regs[index];
- };
-
- static const int StackAlignment = 8; // Per AAPCS
- static const int StackShadowSpace = 0;
- static const int StackSpaceAllocatedUponFunctionEntry = 1 * RegisterSize; // Registers saved in platformEnterStandardStackFrame below.
-
- static void platformEnterStandardStackFrame(PlatformAssembler *as)
- {
- as->push(JSC::ARMRegisters::lr);
- as->push(FramePointerRegister);
- }
-
- static void platformFinishEnteringStandardStackFrame(PlatformAssembler *) {}
-
- static void platformLeaveStandardStackFrame(PlatformAssembler *as, int frameSize)
- {
- if (frameSize > 0) {
- // Work around bug in ARMv7Assembler.h where add32(imm, sp, sp) doesn't
- // work well for large immediates.
- as->move(TrustedImm32(frameSize), JSC::ARMRegisters::r3);
- as->add32(JSC::ARMRegisters::r3, StackPointerRegister);
- }
- as->pop(FramePointerRegister);
- as->pop(JSC::ARMRegisters::lr);
- }
-
- static const int gotRegister = -1;
- static int savedGOTRegisterSlotOnStack() { return -1; }
-};
-#endif // ARM (32 bit)
-
-#if CPU(ARM64) || defined(V4_BOOTSTRAP)
-template <>
-class TargetPlatform<JSC::MacroAssemblerARM64, NoOperatingSystemSpecialization>
-{
-public:
- using PlatformAssembler = JSC::MacroAssemblerARM64;
- using RegisterID = PlatformAssembler::RegisterID;
- using FPRegisterID = PlatformAssembler::FPRegisterID;
- using TrustedImm32 = PlatformAssembler::TrustedImm32;
-
- enum { RegAllocIsSupported = 1 };
-
- static const RegisterID FramePointerRegister = JSC::ARM64Registers::fp;
- static const RegisterID LocalsRegister = JSC::ARM64Registers::x28;
- static const RegisterID StackPointerRegister = JSC::ARM64Registers::sp;
- static const RegisterID ScratchRegister = JSC::ARM64Registers::x9;
- static const RegisterID EngineRegister = JSC::ARM64Registers::x27;
- static const RegisterID ReturnValueRegister = JSC::ARM64Registers::x0;
- static const RegisterID DoubleMaskRegister = JSC::ARM64Registers::x26;
- static const FPRegisterID FPGpr0 = JSC::ARM64Registers::q0;
- static const FPRegisterID FPGpr1 = JSC::ARM64Registers::q1;
-
- static RegisterInformation getRegisterInfo()
- {
- typedef RegisterInfo RI;
- static RegisterInformation info = RegisterInformation()
- << RI(JSC::ARM64Registers::x0, QStringLiteral("x0"), RI::RegularRegister, RI::CallerSaved, RI::Predefined)
- << RI(JSC::ARM64Registers::x1, QStringLiteral("x1"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::x2, QStringLiteral("x2"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::x3, QStringLiteral("x3"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::x4, QStringLiteral("x4"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::x5, QStringLiteral("x5"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::x6, QStringLiteral("x6"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::x7, QStringLiteral("x7"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::x8, QStringLiteral("x8"), RI::RegularRegister, RI::CallerSaved, RI::Predefined)
- << RI(JSC::ARM64Registers::x9, QStringLiteral("x9"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
- << RI(JSC::ARM64Registers::x10, QStringLiteral("x10"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::x11, QStringLiteral("x11"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::x12, QStringLiteral("x12"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::x13, QStringLiteral("x13"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::x14, QStringLiteral("x14"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::x15, QStringLiteral("x15"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::x19, QStringLiteral("x19"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::x20, QStringLiteral("x20"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::x21, QStringLiteral("x21"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::x22, QStringLiteral("x22"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::x23, QStringLiteral("x23"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::x24, QStringLiteral("x24"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::x25, QStringLiteral("x25"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::x26, QStringLiteral("x26"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
- << RI(JSC::ARM64Registers::x27, QStringLiteral("x27"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
- << RI(JSC::ARM64Registers::x28, QStringLiteral("x28"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
-
- << RI(JSC::ARM64Registers::q2, QStringLiteral("q2"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q3, QStringLiteral("q3"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q4, QStringLiteral("q4"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q5, QStringLiteral("q5"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q6, QStringLiteral("q6"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q8, QStringLiteral("q8"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q9, QStringLiteral("q9"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q10, QStringLiteral("q10"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q11, QStringLiteral("q11"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q12, QStringLiteral("q12"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q13, QStringLiteral("q13"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q14, QStringLiteral("q14"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q15, QStringLiteral("q15"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q16, QStringLiteral("q16"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q17, QStringLiteral("q17"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q18, QStringLiteral("q18"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q19, QStringLiteral("q19"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q20, QStringLiteral("q20"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q21, QStringLiteral("q21"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q22, QStringLiteral("q22"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q23, QStringLiteral("q23"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q24, QStringLiteral("q24"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q25, QStringLiteral("q25"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q26, QStringLiteral("q26"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q27, QStringLiteral("q27"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q28, QStringLiteral("q28"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q29, QStringLiteral("q29"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q30, QStringLiteral("q30"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::ARM64Registers::q31, QStringLiteral("q31"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- ;
- return info;
- }
-
-#undef HAVE_ALU_OPS_WITH_MEM_OPERAND
- static const int RegisterSize = 8;
-
- static const int RegisterArgumentCount = 8;
- static RegisterID registerForArgument(int index)
- {
- static RegisterID regs[RegisterArgumentCount] = {
- JSC::ARM64Registers::x0,
- JSC::ARM64Registers::x1,
- JSC::ARM64Registers::x2,
- JSC::ARM64Registers::x3,
- JSC::ARM64Registers::x4,
- JSC::ARM64Registers::x5,
- JSC::ARM64Registers::x6,
- JSC::ARM64Registers::x7
- };
-
- Q_ASSERT(index >= 0 && index < RegisterArgumentCount);
- return regs[index];
- };
-
- static const int StackAlignment = 16;
- static const int StackShadowSpace = 0;
- static const int StackSpaceAllocatedUponFunctionEntry = 1 * RegisterSize; // Registers saved in platformEnterStandardStackFrame below.
-
- static void platformEnterStandardStackFrame(PlatformAssembler *as)
- {
- as->pushPair(FramePointerRegister, JSC::ARM64Registers::lr);
- }
-
- static void platformFinishEnteringStandardStackFrame(PlatformAssembler *as)
- {
- as->move(PlatformAssembler::TrustedImm64(QV4::Value::NaNEncodeMask), DoubleMaskRegister);
- }
-
- static void platformLeaveStandardStackFrame(PlatformAssembler *as, int frameSize)
- {
- if (frameSize > 0)
- as->add64(TrustedImm32(frameSize), StackPointerRegister);
- as->popPair(FramePointerRegister, JSC::ARM64Registers::lr);
- }
-
- static const int gotRegister = -1;
- static int savedGOTRegisterSlotOnStack() { return -1; }
-};
-#endif // ARM64
-
-#if defined(Q_PROCESSOR_MIPS_32) && defined(Q_OS_LINUX)
-template <>
-class TargetPlatform<JSC::MacroAssemblerMIPS, NoOperatingSystemSpecialization>
-{
-public:
- using PlatformAssembler = JSC::MacroAssemblerMIPS;
- using RegisterID = PlatformAssembler::RegisterID;
- using FPRegisterID = PlatformAssembler::FPRegisterID;
- using TrustedImm32 = PlatformAssembler::TrustedImm32;
- enum { RegAllocIsSupported = 1 };
-
- static const RegisterID FramePointerRegister = JSC::MIPSRegisters::fp;
- static const RegisterID StackPointerRegister = JSC::MIPSRegisters::sp;
- static const RegisterID LocalsRegister = JSC::MIPSRegisters::s0;
- static const RegisterID EngineRegister = JSC::MIPSRegisters::s1;
- static const RegisterID ReturnValueRegister = JSC::MIPSRegisters::v0;
- static const RegisterID ScratchRegister = JSC::MIPSRegisters::s2;
- static const FPRegisterID FPGpr0 = JSC::MIPSRegisters::f0;
- static const FPRegisterID FPGpr1 = JSC::MIPSRegisters::f2;
- static const RegisterID LowReturnValueRegister = JSC::MIPSRegisters::v0;
- static const RegisterID HighReturnValueRegister = JSC::MIPSRegisters::v1;
-
- static RegisterInformation getRegisterInfo()
- {
- typedef RegisterInfo RI;
- static RegisterInformation info = RegisterInformation()
- // Note: t0, t1, t2, t3 and f16 are already used by MacroAssemblerMIPS.
- << RI(JSC::MIPSRegisters::t4, QStringLiteral("t4"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::MIPSRegisters::t5, QStringLiteral("t5"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::MIPSRegisters::t6, QStringLiteral("t6"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::MIPSRegisters::t7, QStringLiteral("t7"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::MIPSRegisters::t8, QStringLiteral("t8"), RI::RegularRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::MIPSRegisters::s0, QStringLiteral("s0"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
- << RI(JSC::MIPSRegisters::s1, QStringLiteral("s1"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
- << RI(JSC::MIPSRegisters::s2, QStringLiteral("s2"), RI::RegularRegister, RI::CalleeSaved, RI::Predefined)
- << RI(JSC::MIPSRegisters::s3, QStringLiteral("s3"), RI::RegularRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::MIPSRegisters::f4, QStringLiteral("f4"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::MIPSRegisters::f6, QStringLiteral("f6"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::MIPSRegisters::f8, QStringLiteral("f8"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::MIPSRegisters::f10, QStringLiteral("f10"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::MIPSRegisters::f18, QStringLiteral("f18"), RI::FloatingPointRegister, RI::CallerSaved, RI::RegAlloc)
- << RI(JSC::MIPSRegisters::f20, QStringLiteral("f20"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::MIPSRegisters::f22, QStringLiteral("f22"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::MIPSRegisters::f24, QStringLiteral("f24"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::MIPSRegisters::f26, QStringLiteral("f26"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
- << RI(JSC::MIPSRegisters::f28, QStringLiteral("f28"), RI::FloatingPointRegister, RI::CalleeSaved, RI::RegAlloc)
- ;
- return info;
- }
-
-#undef HAVE_ALU_OPS_WITH_MEM_OPERAND
- static const int RegisterSize = 4;
-
- static const int RegisterArgumentCount = 4;
- static RegisterID registerForArgument(int index)
- {
- static RegisterID regs[RegisterArgumentCount] = {
- JSC::MIPSRegisters::a0,
- JSC::MIPSRegisters::a1,
- JSC::MIPSRegisters::a2,
- JSC::MIPSRegisters::a3
- };
-
- Q_ASSERT(index >= 0 && index < RegisterArgumentCount);
- return regs[index];
- };
-
- static const int StackAlignment = 8;
- static const int StackShadowSpace = 4 * RegisterSize; // Stack space for 4 argument registers.
- static const int StackSpaceAllocatedUponFunctionEntry = 1 * RegisterSize; // Registers saved in platformEnterStandardStackFrame below.
-
- static void platformEnterStandardStackFrame(PlatformAssembler *as)
- {
- as->push(JSC::MIPSRegisters::ra);
- as->push(FramePointerRegister);
- }
-
- static void platformFinishEnteringStandardStackFrame(PlatformAssembler *) {}
-
- static void platformLeaveStandardStackFrame(PlatformAssembler *as, int frameSize)
- {
- if (frameSize > 0)
- as->add32(TrustedImm32(frameSize), StackPointerRegister);
- as->pop(FramePointerRegister);
- as->pop(JSC::MIPSRegisters::ra);
- }
-
-
- static const int gotRegister = -1;
- static int savedGOTRegisterSlotOnStack() { return -1; }
-};
-#endif // Linux on MIPS (32 bit)
-
-} // JIT namespace
-} // QV4 namespace
-
-QT_END_NAMESPACE
-
-#endif // ENABLE(ASSEMBLER)
-
-#endif // QV4TARGETPLATFORM_P_H
diff --git a/src/qml/jit/qv4unop.cpp b/src/qml/jit/qv4unop.cpp
deleted file mode 100644
index 78546e1509..0000000000
--- a/src/qml/jit/qv4unop.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include <qv4unop_p.h>
-#include <qv4assembler_p.h>
-
-#if ENABLE(ASSEMBLER)
-
-using namespace QV4;
-using namespace JIT;
-
-#define stringIfyx(s) #s
-#define stringIfy(s) stringIfyx(s)
-#define setOp(operation) \
- do { \
- call = typename JITAssembler::RuntimeCall(QV4::Runtime::operation); name = "Runtime::" stringIfy(operation); \
- needsExceptionCheck = Runtime::Method_##operation##_NeedsExceptionCheck; \
- } while (0)
-
-template <typename JITAssembler>
-void Unop<JITAssembler>::generate(IR::Expr *source, IR::Expr *target)
-{
- bool needsExceptionCheck;
- typename JITAssembler::RuntimeCall call;
- const char *name = 0;
- switch (op) {
- case IR::OpNot:
- generateNot(source, target);
- return;
- case IR::OpUMinus:
- generateUMinus(source, target);
- return;
- case IR::OpUPlus: setOp(uPlus); break;
- case IR::OpCompl:
- generateCompl(source, target);
- return;
- case IR::OpIncrement: setOp(increment); break;
- case IR::OpDecrement: setOp(decrement); break;
- default:
- Q_UNREACHABLE();
- } // switch
-
- Q_ASSERT(call.isValid());
- _as->generateFunctionCallImp(needsExceptionCheck, target, name, call, PointerToValue(source));
-}
-
-template <typename JITAssembler>
-void Unop<JITAssembler>::generateUMinus(IR::Expr *source, IR::Expr *target)
-{
- IR::Temp *targetTemp = target->asTemp();
-
- if (IR::Const *c = source->asConst()) {
- if (c->value == 0 && source->type == IR::SInt32Type) {
- // special case: minus integer 0 is 0, which is not what JS expects it to be, so always
- // do a runtime call
- generateRuntimeCall(_as, target, uMinus, PointerToValue(source));
- return;
- }
- }
- if (source->type == IR::SInt32Type) {
- typename JITAssembler::RegisterID tReg = JITAssembler::ScratchRegister;
- if (targetTemp && targetTemp->kind == IR::Temp::PhysicalRegister)
- tReg = (typename JITAssembler::RegisterID) targetTemp->index;
- typename JITAssembler::RegisterID sReg = _as->toInt32Register(source, tReg);
- _as->move(sReg, tReg);
- _as->neg32(tReg);
- if (!targetTemp || targetTemp->kind != IR::Temp::PhysicalRegister)
- _as->storeInt32(tReg, target);
- return;
- }
-
- generateRuntimeCall(_as, target, uMinus, PointerToValue(source));
-}
-
-template <typename JITAssembler>
-void Unop<JITAssembler>::generateNot(IR::Expr *source, IR::Expr *target)
-{
- IR::Temp *targetTemp = target->asTemp();
- if (source->type == IR::BoolType) {
- typename JITAssembler::RegisterID tReg = JITAssembler::ScratchRegister;
- if (targetTemp && targetTemp->kind == IR::Temp::PhysicalRegister)
- tReg = (typename JITAssembler::RegisterID) targetTemp->index;
- _as->xor32(TrustedImm32(0x1), _as->toInt32Register(source, tReg), tReg);
- if (!targetTemp || targetTemp->kind != IR::Temp::PhysicalRegister)
- _as->storeBool(tReg, target);
- return;
- } else if (source->type == IR::SInt32Type) {
- typename JITAssembler::RegisterID tReg = JITAssembler::ScratchRegister;
- if (targetTemp && targetTemp->kind == IR::Temp::PhysicalRegister)
- tReg = (typename JITAssembler::RegisterID) targetTemp->index;
- _as->compare32(RelationalCondition::Equal,
- _as->toInt32Register(source, JITAssembler::ScratchRegister), TrustedImm32(0),
- tReg);
- if (!targetTemp || targetTemp->kind != IR::Temp::PhysicalRegister)
- _as->storeBool(tReg, target);
- return;
- } else if (source->type == IR::DoubleType) {
- // ###
- }
- // ## generic implementation testing for int/bool
-
- generateRuntimeCall(_as, target, uNot, PointerToValue(source));
-}
-
-template <typename JITAssembler>
-void Unop<JITAssembler>::generateCompl(IR::Expr *source, IR::Expr *target)
-{
- IR::Temp *targetTemp = target->asTemp();
- if (source->type == IR::SInt32Type) {
- typename JITAssembler::RegisterID tReg = JITAssembler::ScratchRegister;
- if (targetTemp && targetTemp->kind == IR::Temp::PhysicalRegister)
- tReg = (typename JITAssembler::RegisterID) targetTemp->index;
- _as->xor32(TrustedImm32(0xffffffff), _as->toInt32Register(source, tReg), tReg);
- if (!targetTemp || targetTemp->kind != IR::Temp::PhysicalRegister)
- _as->storeInt32(tReg, target);
- return;
- }
- generateRuntimeCall(_as, target, complement, PointerToValue(source));
-}
-
-template struct QV4::JIT::Unop<QV4::JIT::Assembler<DefaultAssemblerTargetConfiguration>>;
-#if defined(V4_BOOTSTRAP)
-#if !CPU(ARM_THUMB2)
-template struct QV4::JIT::Unop<QV4::JIT::Assembler<AssemblerTargetConfiguration<JSC::MacroAssemblerARMv7, NoOperatingSystemSpecialization>>>;
-#endif
-#if !CPU(ARM64)
-template struct QV4::JIT::Unop<QV4::JIT::Assembler<AssemblerTargetConfiguration<JSC::MacroAssemblerARM64, NoOperatingSystemSpecialization>>>;
-#endif
-#endif
-
-#endif
diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp
index 6cab8def4f..1c1314f05d 100644
--- a/src/qml/jsapi/qjsengine.cpp
+++ b/src/qml/jsapi/qjsengine.cpp
@@ -304,8 +304,9 @@ QJSEngine::QJSEngine()
QJSEngine::QJSEngine(QObject *parent)
: QObject(*new QJSEnginePrivate, parent)
- , d(new QV8Engine(this))
+ , m_v4Engine(new QV4::ExecutionEngine)
{
+ m_v4Engine->v8Engine = new QV8Engine(this, m_v4Engine);
checkForApplicationInstance();
QJSEnginePrivate::addToDebugServer(this);
@@ -316,8 +317,9 @@ QJSEngine::QJSEngine(QObject *parent)
*/
QJSEngine::QJSEngine(QJSEnginePrivate &dd, QObject *parent)
: QObject(dd, parent)
- , d(new QV8Engine(this))
+ , m_v4Engine(new QV4::ExecutionEngine)
{
+ m_v4Engine->v8Engine = new QV8Engine(this, m_v4Engine);
checkForApplicationInstance();
}
@@ -331,11 +333,12 @@ QJSEngine::QJSEngine(QJSEnginePrivate &dd, QObject *parent)
QJSEngine::~QJSEngine()
{
QJSEnginePrivate::removeFromDebugServer(this);
- delete d;
+ delete m_v4Engine->v8Engine;
+ delete m_v4Engine;
}
/*!
- \fn QV8Engine *QJSEngine::handle() const
+ \fn QV4::ExecutionEngine *QJSEngine::handle() const
\internal
*/
@@ -352,7 +355,7 @@ QJSEngine::~QJSEngine()
*/
void QJSEngine::collectGarbage()
{
- d->m_v4Engine->memoryManager->runGC();
+ m_v4Engine->memoryManager->runGC();
}
#if QT_DEPRECATED_SINCE(5, 6)
@@ -409,12 +412,12 @@ void QJSEngine::installTranslatorFunctions(const QJSValue &object)
void QJSEngine::installExtensions(QJSEngine::Extensions extensions, const QJSValue &object)
{
QV4::ExecutionEngine *otherEngine = QJSValuePrivate::engine(&object);
- if (otherEngine && otherEngine != d->m_v4Engine) {
+ if (otherEngine && otherEngine != m_v4Engine) {
qWarning("QJSEngine: Trying to install extensions from a different engine");
return;
}
- QV4::Scope scope(d->m_v4Engine);
+ QV4::Scope scope(m_v4Engine);
QV4::ScopedObject obj(scope);
QV4::Value *val = QJSValuePrivate::getValue(&object);
if (val)
@@ -455,17 +458,16 @@ void QJSEngine::installExtensions(QJSEngine::Extensions extensions, const QJSVal
*/
QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, int lineNumber)
{
- QV4::ExecutionEngine *v4 = d->m_v4Engine;
+ QV4::ExecutionEngine *v4 = m_v4Engine;
QV4::Scope scope(v4);
- QV4::ExecutionContextSaver saver(scope);
-
- QV4::ExecutionContext *ctx = v4->currentContext;
- if (ctx->d() != v4->rootContext()->d())
- ctx = v4->pushGlobalContext();
QV4::ScopedValue result(scope);
- QV4::Script script(ctx, program, fileName, lineNumber);
- script.strictMode = ctx->d()->strictMode;
+ QV4::Script script(v4->rootContext(), QV4::Compiler::GlobalCode, program, fileName, lineNumber);
+ script.strictMode = false;
+ if (v4->currentStackFrame)
+ script.strictMode = v4->currentStackFrame->v4Function->isStrict();
+ else if (v4->globalCode)
+ script.strictMode = v4->globalCode->isStrict();
script.inheritContext = true;
script.parse();
if (!scope.engine->hasException)
@@ -473,7 +475,9 @@ QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, in
if (scope.engine->hasException)
result = v4->catchException();
- return QJSValue(v4, result->asReturnedValue());
+ QJSValue retval(v4, result->asReturnedValue());
+
+ return retval;
}
/*!
@@ -486,9 +490,9 @@ QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, in
*/
QJSValue QJSEngine::newObject()
{
- QV4::Scope scope(d->m_v4Engine);
- QV4::ScopedValue v(scope, d->m_v4Engine->newObject());
- return QJSValue(d->m_v4Engine, v->asReturnedValue());
+ QV4::Scope scope(m_v4Engine);
+ QV4::ScopedValue v(scope, m_v4Engine->newObject());
+ return QJSValue(m_v4Engine, v->asReturnedValue());
}
/*!
@@ -498,12 +502,12 @@ QJSValue QJSEngine::newObject()
*/
QJSValue QJSEngine::newArray(uint length)
{
- QV4::Scope scope(d->m_v4Engine);
- QV4::ScopedArrayObject array(scope, d->m_v4Engine->newArrayObject());
+ QV4::Scope scope(m_v4Engine);
+ QV4::ScopedArrayObject array(scope, m_v4Engine->newArrayObject());
if (length < 0x1000)
array->arrayReserve(length);
array->setArrayLengthUnchecked(length);
- return QJSValue(d->m_v4Engine, array.asReturnedValue());
+ return QJSValue(m_v4Engine, array.asReturnedValue());
}
/*!
@@ -529,7 +533,7 @@ QJSValue QJSEngine::newArray(uint length)
QJSValue QJSEngine::newQObject(QObject *object)
{
Q_D(QJSEngine);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(d);
+ QV4::ExecutionEngine *v4 = m_v4Engine;
QV4::Scope scope(v4);
if (object) {
QQmlData *ddata = QQmlData::get(object, true);
@@ -556,13 +560,13 @@ QJSValue QJSEngine::newQObject(QObject *object)
QJSValue QJSEngine::newQMetaObject(const QMetaObject* metaObject) {
Q_D(QJSEngine);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(d);
+ QV4::ExecutionEngine *v4 = m_v4Engine;
QV4::Scope scope(v4);
QV4::ScopedValue v(scope, QV4::QMetaObjectWrapper::create(v4, metaObject));
return QJSValue(v4, v->asReturnedValue());
}
-/*! \fn QJSValue QJSEngine::newQMetaObject<T>()
+/*! \fn template <typename T> QJSValue QJSEngine::newQMetaObject()
\since 5.8
Creates a JavaScript object that wraps the static QMetaObject associated
@@ -584,10 +588,9 @@ QJSValue QJSEngine::newQMetaObject(const QMetaObject* metaObject) {
*/
QJSValue QJSEngine::globalObject() const
{
- Q_D(const QJSEngine);
- QV4::Scope scope(d->m_v4Engine);
- QV4::ScopedValue v(scope, d->m_v4Engine->globalObject);
- return QJSValue(d->m_v4Engine, v->asReturnedValue());
+ QV4::Scope scope(m_v4Engine);
+ QV4::ScopedValue v(scope, m_v4Engine->globalObject);
+ return QJSValue(m_v4Engine, v->asReturnedValue());
}
/*!
@@ -596,10 +599,9 @@ QJSValue QJSEngine::globalObject() const
*/
QJSValue QJSEngine::create(int type, const void *ptr)
{
- Q_D(QJSEngine);
- QV4::Scope scope(d->m_v4Engine);
+ QV4::Scope scope(m_v4Engine);
QV4::ScopedValue v(scope, scope.engine->metaTypeToJS(type, ptr));
- return QJSValue(d->m_v4Engine, v->asReturnedValue());
+ return QJSValue(m_v4Engine, v->asReturnedValue());
}
/*!
@@ -722,14 +724,14 @@ bool QJSEngine::convertV2(const QJSValue &value, int type, void *ptr)
}
}
-/*! \fn QJSValue QJSEngine::toScriptValue(const T &value)
+/*! \fn template <typename T> QJSValue QJSEngine::toScriptValue(const T &value)
Creates a QJSValue with the given \a value.
\sa fromScriptValue()
*/
-/*! \fn T QJSEngine::fromScriptValue(const QJSValue &value)
+/*! \fn template <typename T> T QJSEngine::fromScriptValue(const QJSValue &value)
Returns the given \a value converted to the template type \c{T}.
@@ -739,7 +741,7 @@ bool QJSEngine::convertV2(const QJSValue &value, int type, void *ptr)
QJSEnginePrivate *QJSEnginePrivate::get(QV4::ExecutionEngine *e)
{
- return e->v8Engine->publicEngine()->d_func();
+ return e->jsEngine()->d_func();
}
QJSEnginePrivate::~QJSEnginePrivate()
diff --git a/src/qml/jsapi/qjsengine.h b/src/qml/jsapi/qjsengine.h
index 41c4b81270..89642b6f20 100644
--- a/src/qml/jsapi/qjsengine.h
+++ b/src/qml/jsapi/qjsengine.h
@@ -47,10 +47,10 @@
#include <QtCore/qobject.h>
#include <QtQml/qjsvalue.h>
-QT_BEGIN_NAMESPACE
+#include <QtQml/qqmldebug.h>
+QT_BEGIN_NAMESPACE
-class QV8Engine;
template <typename T>
inline T qjsvalue_cast(const QJSValue &);
@@ -109,7 +109,7 @@ public:
void installExtensions(Extensions extensions, const QJSValue &object = QJSValue());
- QV8Engine *handle() const { return d; }
+ QV4::ExecutionEngine *handle() const { return m_v4Engine; }
private:
QJSValue create(int type, const void *ptr);
@@ -119,13 +119,12 @@ private:
friend inline bool qjsvalue_cast_helper(const QJSValue &, int, void *);
protected:
- QJSEngine(QJSEnginePrivate &dd, QObject *parent = Q_NULLPTR);
+ QJSEngine(QJSEnginePrivate &dd, QObject *parent = nullptr);
private:
- QV8Engine *d;
+ QV4::ExecutionEngine *m_v4Engine;
Q_DISABLE_COPY(QJSEngine)
Q_DECLARE_PRIVATE(QJSEngine)
- friend class QV8Engine;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QJSEngine::Extensions)
diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp
index 24aa4ac5f2..c4090ac482 100644
--- a/src/qml/jsapi/qjsvalue.cpp
+++ b/src/qml/jsapi/qjsvalue.cpp
@@ -53,7 +53,7 @@
#include "qv4errorobject_p.h"
#include "private/qv8engine_p.h"
#include <private/qv4mm_p.h>
-#include <private/qv4scopedvalue_p.h>
+#include <private/qv4jscall_p.h>
#include <private/qv4qobjectwrapper_p.h>
/*!
@@ -152,6 +152,13 @@
\value NullValue A null value.
*/
+/*!
+ \typedef QJSValueList
+ \relates QJSValue
+
+ This is a typedef for a QList<QJSValue>.
+*/
+
QT_BEGIN_NAMESPACE
using namespace QV4;
@@ -257,7 +264,7 @@ QJSValue::QJSValue(const QJSValue& other)
*/
/*!
- \fn QJSValue &operator=(QJSValue && other)
+ \fn QJSValue &QJSValue::operator=(QJSValue && other)
Move-assigns \a other to this QJSValue object.
*/
@@ -689,21 +696,21 @@ QJSValue QJSValue::call(const QJSValueList &args)
Q_ASSERT(engine);
Scope scope(engine);
- ScopedCallData callData(scope, args.length());
- callData->thisObject = engine->globalObject;
+ JSCallData jsCallData(scope, args.length());
+ *jsCallData->thisObject = engine->globalObject;
for (int i = 0; i < args.size(); ++i) {
if (!QJSValuePrivate::checkEngine(engine, args.at(i))) {
qWarning("QJSValue::call() failed: cannot call function with argument created in a different engine");
return QJSValue();
}
- callData->args[i] = QJSValuePrivate::convertedToValue(engine, args.at(i));
+ jsCallData->args[i] = QJSValuePrivate::convertedToValue(engine, args.at(i));
}
- f->call(scope, callData);
+ ScopedValue result(scope, f->call(jsCallData));
if (engine->hasException)
- scope.result = engine->catchException();
+ result = engine->catchException();
- return QJSValue(engine, scope.result.asReturnedValue());
+ return QJSValue(engine, result->asReturnedValue());
}
/*!
@@ -745,21 +752,21 @@ QJSValue QJSValue::callWithInstance(const QJSValue &instance, const QJSValueList
return QJSValue();
}
- ScopedCallData callData(scope, args.size());
- callData->thisObject = QJSValuePrivate::convertedToValue(engine, instance);
+ JSCallData jsCallData(scope, args.size());
+ *jsCallData->thisObject = QJSValuePrivate::convertedToValue(engine, instance);
for (int i = 0; i < args.size(); ++i) {
if (!QJSValuePrivate::checkEngine(engine, args.at(i))) {
qWarning("QJSValue::call() failed: cannot call function with argument created in a different engine");
return QJSValue();
}
- callData->args[i] = QJSValuePrivate::convertedToValue(engine, args.at(i));
+ jsCallData->args[i] = QJSValuePrivate::convertedToValue(engine, args.at(i));
}
- f->call(scope, callData);
+ ScopedValue result(scope, f->call(jsCallData));
if (engine->hasException)
- scope.result = engine->catchException();
+ result = engine->catchException();
- return QJSValue(engine, scope.result.asReturnedValue());
+ return QJSValue(engine, result->asReturnedValue());
}
/*!
@@ -794,20 +801,20 @@ QJSValue QJSValue::callAsConstructor(const QJSValueList &args)
Q_ASSERT(engine);
Scope scope(engine);
- ScopedCallData callData(scope, args.size());
+ JSCallData jsCallData(scope, args.size());
for (int i = 0; i < args.size(); ++i) {
if (!QJSValuePrivate::checkEngine(engine, args.at(i))) {
qWarning("QJSValue::callAsConstructor() failed: cannot construct function with argument created in a different engine");
return QJSValue();
}
- callData->args[i] = QJSValuePrivate::convertedToValue(engine, args.at(i));
+ jsCallData->args[i] = QJSValuePrivate::convertedToValue(engine, args.at(i));
}
- f->construct(scope, callData);
+ ScopedValue result(scope, f->callAsConstructor(jsCallData));
if (engine->hasException)
- scope.result = engine->catchException();
+ result = engine->catchException();
- return QJSValue(engine, scope.result.asReturnedValue());
+ return QJSValue(engine, result->asReturnedValue());
}
#ifdef QT_DEPRECATED
@@ -1242,10 +1249,7 @@ bool QJSValue::deleteProperty(const QString &name)
return false;
ScopedString s(scope, engine->newString(name));
- bool b = o->deleteProperty(s);
- if (engine->hasException)
- engine->catchException();
- return b;
+ return o->deleteProperty(s);
}
/*!
diff --git a/src/qml/jsapi/qjsvalue.h b/src/qml/jsapi/qjsvalue.h
index ab20a2607d..56bd64eec1 100644
--- a/src/qml/jsapi/qjsvalue.h
+++ b/src/qml/jsapi/qjsvalue.h
@@ -133,9 +133,9 @@ public:
bool deleteProperty(const QString &name);
bool isCallable() const;
- QJSValue call(const QJSValueList &args = QJSValueList());
- QJSValue callWithInstance(const QJSValue &instance, const QJSValueList &args = QJSValueList());
- QJSValue callAsConstructor(const QJSValueList &args = QJSValueList());
+ QJSValue call(const QJSValueList &args = QJSValueList()); // ### Qt6: Make const
+ QJSValue callWithInstance(const QJSValue &instance, const QJSValueList &args = QJSValueList()); // ### Qt6: Make const
+ QJSValue callAsConstructor(const QJSValueList &args = QJSValueList()); // ### Qt6: Make const
#ifdef QT_DEPRECATED
QT_DEPRECATED QJSEngine *engine() const;
diff --git a/src/qml/jsruntime/jsruntime.pri b/src/qml/jsruntime/jsruntime.pri
index 9938f60aea..4bc877bd9d 100644
--- a/src/qml/jsruntime/jsruntime.pri
+++ b/src/qml/jsruntime/jsruntime.pri
@@ -33,6 +33,7 @@ SOURCES += \
$$PWD/qv4variantobject.cpp \
$$PWD/qv4objectiterator.cpp \
$$PWD/qv4regexp.cpp \
+ $$PWD/qv4runtimecodegen.cpp \
$$PWD/qv4serialize.cpp \
$$PWD/qv4script.cpp \
$$PWD/qv4sequenceobject.cpp \
@@ -40,9 +41,10 @@ SOURCES += \
$$PWD/qv4qobjectwrapper.cpp \
$$PWD/qv4arraybuffer.cpp \
$$PWD/qv4typedarray.cpp \
- $$PWD/qv4dataview.cpp
+ $$PWD/qv4dataview.cpp \
+ $$PWD/qv4vme_moth.cpp
-!contains(QT_CONFIG, no-qml-debug): SOURCES += $$PWD/qv4profiling.cpp
+qtConfig(qml-debug): SOURCES += $$PWD/qv4profiling.cpp
HEADERS += \
$$PWD/qv4global_p.h \
@@ -58,6 +60,7 @@ HEADERS += \
$$PWD/qv4identifiertable_p.h \
$$PWD/qv4managed_p.h \
$$PWD/qv4internalclass_p.h \
+ $$PWD/qv4jscall_p.h \
$$PWD/qv4sparsearray_p.h \
$$PWD/qv4arraydata_p.h \
$$PWD/qv4arrayobject_p.h \
@@ -76,6 +79,7 @@ HEADERS += \
$$PWD/qv4objectproto_p.h \
$$PWD/qv4qmlcontext_p.h \
$$PWD/qv4regexpobject_p.h \
+ $$PWD/qv4runtimecodegen_p.h \
$$PWD/qv4stringobject_p.h \
$$PWD/qv4variantobject_p.h \
$$PWD/qv4property_p.h \
@@ -91,14 +95,8 @@ HEADERS += \
$$PWD/qv4profiling_p.h \
$$PWD/qv4arraybuffer_p.h \
$$PWD/qv4typedarray_p.h \
- $$PWD/qv4dataview_p.h
-
-qtConfig(qml-interpreter) {
- HEADERS += \
- $$PWD/qv4vme_moth_p.h
- SOURCES += \
- $$PWD/qv4vme_moth.cpp
-}
+ $$PWD/qv4dataview_p.h \
+ $$PWD/qv4vme_moth_p.h
}
diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp
index 6ab838c387..075e7afd8a 100644
--- a/src/qml/jsruntime/qv4argumentsobject.cpp
+++ b/src/qml/jsruntime/qv4argumentsobject.cpp
@@ -41,39 +41,53 @@
#include <qv4scopedvalue_p.h>
#include <qv4string_p.h>
#include <qv4function_p.h>
+#include <qv4jscall_p.h>
using namespace QV4;
DEFINE_OBJECT_VTABLE(ArgumentsObject);
+DEFINE_OBJECT_VTABLE(StrictArgumentsObject);
-void Heap::ArgumentsObject::init(QV4::CallContext *context)
+void Heap::ArgumentsObject::init(QV4::CppStackFrame *frame)
{
+ ExecutionEngine *v4 = internalClass->engine;
+
+ int nFormals = frame->v4Function->nFormals;
+ QV4::CallContext *context = static_cast<QV4::CallContext *>(frame->context());
+
Object::init();
fullyCreated = false;
- this->context = context->d();
+ this->nFormals = nFormals;
+ this->context.set(v4, context->d());
Q_ASSERT(vtable() == QV4::ArgumentsObject::staticVTable());
- ExecutionEngine *v4 = context->engine();
+ Q_ASSERT(CalleePropertyIndex == internalClass->find(v4->id_callee()));
+ setProperty(v4, CalleePropertyIndex, context->d()->function);
+ Q_ASSERT(LengthPropertyIndex == internalClass->find(v4->id_length()));
+ setProperty(v4, LengthPropertyIndex, Primitive::fromInt32(context->argc()));
+}
+
+void Heap::StrictArgumentsObject::init(QV4::CppStackFrame *frame)
+{
+ Q_ASSERT(vtable() == QV4::StrictArgumentsObject::staticVTable());
+ ExecutionEngine *v4 = internalClass->engine;
+
+ Object::init();
+
+ Q_ASSERT(CalleePropertyIndex == internalClass->find(v4->id_callee()));
+ Q_ASSERT(CallerPropertyIndex == internalClass->find(v4->id_caller()));
+ setProperty(v4, CalleePropertyIndex + QV4::Object::GetterOffset, *v4->thrower());
+ setProperty(v4, CalleePropertyIndex + QV4::Object::SetterOffset, *v4->thrower());
+ setProperty(v4, CallerPropertyIndex + QV4::Object::GetterOffset, *v4->thrower());
+ setProperty(v4, CallerPropertyIndex + QV4::Object::SetterOffset, *v4->thrower());
+
Scope scope(v4);
- Scoped<QV4::ArgumentsObject> args(scope, this);
-
- if (context->d()->strictMode) {
- Q_ASSERT(CalleePropertyIndex == args->internalClass()->find(v4->id_callee()));
- Q_ASSERT(CallerPropertyIndex == args->internalClass()->find(v4->id_caller()));
- *args->propertyData(CalleePropertyIndex + QV4::Object::GetterOffset) = v4->thrower();
- *args->propertyData(CalleePropertyIndex + QV4::Object::SetterOffset) = v4->thrower();
- *args->propertyData(CallerPropertyIndex + QV4::Object::GetterOffset) = v4->thrower();
- *args->propertyData(CallerPropertyIndex + QV4::Object::SetterOffset) = v4->thrower();
-
- args->arrayReserve(context->argc());
- args->arrayPut(0, context->args(), context->argc());
- args->d()->fullyCreated = true;
- } else {
- Q_ASSERT(CalleePropertyIndex == args->internalClass()->find(v4->id_callee()));
- *args->propertyData(CalleePropertyIndex) = context->d()->function->asReturnedValue();
- }
+ Scoped<QV4::StrictArgumentsObject> args(scope, this);
+ args->arrayReserve(frame->originalArgumentsCount);
+ args->arrayPut(0, frame->originalArguments, frame->originalArgumentsCount);
+
Q_ASSERT(LengthPropertyIndex == args->internalClass()->find(v4->id_length()));
- *args->propertyData(LengthPropertyIndex) = Primitive::fromInt32(context->d()->callData->argc);
+ setProperty(v4, LengthPropertyIndex, Primitive::fromInt32(frame->originalArgumentsCount));
}
void ArgumentsObject::fullyCreate()
@@ -83,21 +97,21 @@ void ArgumentsObject::fullyCreate()
Scope scope(engine());
- uint argCount = context()->callData->argc;
- uint numAccessors = qMin(context()->formalParameterCount(), argCount);
+ int argCount = context()->argc();
+ uint numAccessors = qMin(d()->nFormals, argCount);
ArrayData::realloc(this, Heap::ArrayData::Sparse, argCount, true);
scope.engine->requireArgumentsAccessors(numAccessors);
Scoped<MemberData> md(scope, d()->mappedArguments);
if (numAccessors) {
- d()->mappedArguments = md->allocate(scope.engine, numAccessors);
+ d()->mappedArguments.set(scope.engine, md->allocate(scope.engine, numAccessors));
for (uint i = 0; i < numAccessors; ++i) {
- d()->mappedArguments->data[i] = context()->callData->args[i];
+ d()->mappedArguments->values.set(scope.engine, i, context()->args()[i]);
arraySet(i, scope.engine->argumentsAccessors + i, Attr_Accessor);
}
}
- arrayPut(numAccessors, context()->callData->args + numAccessors, argCount - numAccessors);
- for (uint i = numAccessors; i < argCount; ++i)
+ arrayPut(numAccessors, context()->args() + numAccessors, argCount - numAccessors);
+ for (int i = int(numAccessors); i < argCount; ++i)
setArrayAttributes(i, Attr_Data);
d()->fullyCreated = true;
@@ -108,46 +122,43 @@ bool ArgumentsObject::defineOwnProperty(ExecutionEngine *engine, uint index, con
fullyCreate();
Scope scope(engine);
- Property *pd = arrayData() ? arrayData()->getProperty(index) : 0;
ScopedProperty map(scope);
PropertyAttributes mapAttrs;
+ uint numAccessors = qMin(d()->nFormals, context()->argc());
bool isMapped = false;
- uint numAccessors = qMin((int)context()->formalParameterCount(), context()->callData->argc);
- if (pd && index < (uint)numAccessors)
- isMapped = arrayData()->attributes(index).isAccessor() &&
- pd->getter() == scope.engine->argumentsAccessors[index].getter();
+ if (arrayData() && index < numAccessors &&
+ arrayData()->attributes(index).isAccessor() &&
+ arrayData()->get(index) == scope.engine->argumentsAccessors[index].getter()->asReturnedValue())
+ isMapped = true;
if (isMapped) {
Q_ASSERT(arrayData());
mapAttrs = arrayData()->attributes(index);
- map->copy(pd, mapAttrs);
+ arrayData()->getProperty(index, map, &mapAttrs);
setArrayAttributes(index, Attr_Data);
- pd = arrayData()->getProperty(index);
- pd->value = d()->mappedArguments->data[index];
+ ArrayData::Index arrayIndex{ arrayData(), arrayData()->mappedIndex(index) };
+ arrayIndex.set(scope.engine, d()->mappedArguments->values[index]);
}
- bool strict = engine->current->strictMode;
- engine->current->strictMode = false;
bool result = Object::defineOwnProperty2(scope.engine, index, desc, attrs);
- engine->current->strictMode = strict;
+ if (!result) {
+ return false;
+ }
if (isMapped && attrs.isData()) {
Q_ASSERT(arrayData());
ScopedFunctionObject setter(scope, map->setter());
- ScopedCallData callData(scope, 1);
- callData->thisObject = this->asReturnedValue();
- callData->args[0] = desc->value;
- setter->call(scope, callData);
+ JSCallData jsCallData(scope, 1);
+ *jsCallData->thisObject = this->asReturnedValue();
+ jsCallData->args[0] = desc->value;
+ setter->call(jsCallData);
if (attrs.isWritable()) {
setArrayAttributes(index, mapAttrs);
- pd = arrayData()->getProperty(index);
- pd->copy(map, mapAttrs);
+ arrayData()->setProperty(engine, index, map);
}
}
- if (engine->current->strictMode && !result)
- return engine->throwTypeError();
return result;
}
@@ -157,28 +168,27 @@ ReturnedValue ArgumentsObject::getIndexed(const Managed *m, uint index, bool *ha
if (args->fullyCreated())
return Object::getIndexed(m, index, hasProperty);
- if (index < static_cast<uint>(args->context()->callData->argc)) {
+ if (index < static_cast<uint>(args->context()->argc())) {
if (hasProperty)
*hasProperty = true;
- return args->context()->callData->args[index].asReturnedValue();
+ return args->context()->args()[index].asReturnedValue();
}
if (hasProperty)
*hasProperty = false;
return Encode::undefined();
}
-void ArgumentsObject::putIndexed(Managed *m, uint index, const Value &value)
+bool ArgumentsObject::putIndexed(Managed *m, uint index, const Value &value)
{
ArgumentsObject *args = static_cast<ArgumentsObject *>(m);
- if (!args->fullyCreated() && index >= static_cast<uint>(args->context()->callData->argc))
+ if (!args->fullyCreated() && index >= static_cast<uint>(args->context()->argc()))
args->fullyCreate();
- if (args->fullyCreated()) {
- Object::putIndexed(m, index, value);
- return;
- }
+ if (args->fullyCreated())
+ return Object::putIndexed(m, index, value);
- args->context()->callData->args[index] = value;
+ args->context()->setArg(index, value);
+ return true;
}
bool ArgumentsObject::deleteIndexedProperty(Managed *m, uint index)
@@ -195,8 +205,8 @@ PropertyAttributes ArgumentsObject::queryIndexed(const Managed *m, uint index)
if (args->fullyCreated())
return Object::queryIndexed(m, index);
- uint numAccessors = qMin((int)args->context()->formalParameterCount(), args->context()->callData->argc);
- uint argCount = args->context()->callData->argc;
+ uint numAccessors = qMin(args->d()->nFormals, args->context()->argc());
+ uint argCount = args->context()->argc();
if (index >= argCount)
return PropertyAttributes();
if (index >= numAccessors)
@@ -206,46 +216,33 @@ PropertyAttributes ArgumentsObject::queryIndexed(const Managed *m, uint index)
DEFINE_OBJECT_VTABLE(ArgumentsGetterFunction);
-void ArgumentsGetterFunction::call(const Managed *getter, Scope &scope, CallData *callData)
+ReturnedValue ArgumentsGetterFunction::call(const FunctionObject *getter, const Value *thisObject, const Value *, int)
{
- ExecutionEngine *v4 = static_cast<const ArgumentsGetterFunction *>(getter)->engine();
- Scoped<ArgumentsGetterFunction> g(scope, static_cast<const ArgumentsGetterFunction *>(getter));
- Scoped<ArgumentsObject> o(scope, callData->thisObject.as<ArgumentsObject>());
- if (!o) {
- scope.result = v4->throwTypeError();
- return;
- }
+ ExecutionEngine *v4 = getter->engine();
+ Scope scope(v4);
+ const ArgumentsGetterFunction *g = static_cast<const ArgumentsGetterFunction *>(getter);
+ Scoped<ArgumentsObject> o(scope, thisObject->as<ArgumentsObject>());
+ if (!o)
+ return v4->throwTypeError();
- Q_ASSERT(g->index() < static_cast<unsigned>(o->context()->callData->argc));
- scope.result = o->context()->callData->args[g->index()];
+ Q_ASSERT(g->index() < static_cast<unsigned>(o->context()->argc()));
+ return o->context()->args()[g->index()].asReturnedValue();
}
DEFINE_OBJECT_VTABLE(ArgumentsSetterFunction);
-void ArgumentsSetterFunction::call(const Managed *setter, Scope &scope, CallData *callData)
+ReturnedValue ArgumentsSetterFunction::call(const FunctionObject *setter, const Value *thisObject, const Value *argv, int argc)
{
- ExecutionEngine *v4 = static_cast<const ArgumentsSetterFunction *>(setter)->engine();
- Scoped<ArgumentsSetterFunction> s(scope, static_cast<const ArgumentsSetterFunction *>(setter));
- Scoped<ArgumentsObject> o(scope, callData->thisObject.as<ArgumentsObject>());
- if (!o) {
- scope.result = v4->throwTypeError();
- return;
- }
-
- Q_ASSERT(s->index() < static_cast<unsigned>(o->context()->callData->argc));
- o->context()->callData->args[s->index()] = callData->argc ? callData->args[0].asReturnedValue() : Encode::undefined();
- scope.result = Encode::undefined();
-}
-
-void ArgumentsObject::markObjects(Heap::Base *that, ExecutionEngine *e)
-{
- ArgumentsObject::Data *o = static_cast<ArgumentsObject::Data *>(that);
- if (o->context)
- o->context->mark(e);
- if (o->mappedArguments)
- o->mappedArguments->mark(e);
+ ExecutionEngine *v4 = setter->engine();
+ Scope scope(v4);
+ const ArgumentsSetterFunction *s = static_cast<const ArgumentsSetterFunction *>(setter);
+ Scoped<ArgumentsObject> o(scope, thisObject->as<ArgumentsObject>());
+ if (!o)
+ return v4->throwTypeError();
- Object::markObjects(that, e);
+ Q_ASSERT(s->index() < static_cast<unsigned>(o->context()->argc()));
+ o->context()->setArg(s->index(), argc ? argv[0] : Primitive::undefinedValue());
+ return Encode::undefined();
}
uint ArgumentsObject::getLength(const Managed *m)
diff --git a/src/qml/jsruntime/qv4argumentsobject_p.h b/src/qml/jsruntime/qv4argumentsobject_p.h
index 0a2ea3b42a..ac281f555a 100644
--- a/src/qml/jsruntime/qv4argumentsobject_p.h
+++ b/src/qml/jsruntime/qv4argumentsobject_p.h
@@ -59,26 +59,46 @@ namespace QV4 {
namespace Heap {
-struct ArgumentsGetterFunction : FunctionObject {
+#define ArgumentsGetterFunctionMembers(class, Member) \
+ Member(class, NoMark, uint, index)
+
+DECLARE_HEAP_OBJECT(ArgumentsGetterFunction, FunctionObject) {
+ DECLARE_MARKOBJECTS(ArgumentsGetterFunction);
inline void init(QV4::ExecutionContext *scope, uint index);
- uint index;
};
-struct ArgumentsSetterFunction : FunctionObject {
+#define ArgumentsSetterFunctionMembers(class, Member) \
+ Member(class, NoMark, uint, index)
+
+DECLARE_HEAP_OBJECT(ArgumentsSetterFunction, FunctionObject) {
+ DECLARE_MARKOBJECTS(ArgumentsSetterFunction);
inline void init(QV4::ExecutionContext *scope, uint index);
- uint index;
};
-struct ArgumentsObject : Object {
+#define ArgumentsObjectMembers(class, Member) \
+ Member(class, Pointer, CallContext *, context) \
+ Member(class, Pointer, MemberData *, mappedArguments) \
+ Member(class, NoMark, bool, fullyCreated) \
+ Member(class, NoMark, int, nFormals)
+
+DECLARE_HEAP_OBJECT(ArgumentsObject, Object) {
+ DECLARE_MARKOBJECTS(ArgumentsObject);
+ enum {
+ LengthPropertyIndex = 0,
+ CalleePropertyIndex = 1
+ };
+ void init(CppStackFrame *frame);
+};
+
+#define StrictArgumentsObjectMembers(class, Member)
+
+DECLARE_HEAP_OBJECT(StrictArgumentsObject, Object) {
enum {
LengthPropertyIndex = 0,
CalleePropertyIndex = 1,
CallerPropertyIndex = 3
};
- void init(QV4::CallContext *context);
- Pointer<CallContext> context;
- bool fullyCreated;
- Pointer<MemberData> mappedArguments;
+ void init(CppStackFrame *frame);
};
}
@@ -88,7 +108,7 @@ struct ArgumentsGetterFunction: FunctionObject
V4_OBJECT2(ArgumentsGetterFunction, FunctionObject)
uint index() const { return d()->index; }
- static void call(const Managed *that, Scope &scope, CallData *d);
+ static ReturnedValue call(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
};
inline void
@@ -103,7 +123,7 @@ struct ArgumentsSetterFunction: FunctionObject
V4_OBJECT2(ArgumentsSetterFunction, FunctionObject)
uint index() const { return d()->index; }
- static void call(const Managed *that, Scope &scope, CallData *callData);
+ static ReturnedValue call(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
};
inline void
@@ -122,22 +142,25 @@ struct ArgumentsObject: Object {
bool fullyCreated() const { return d()->fullyCreated; }
static bool isNonStrictArgumentsObject(Managed *m) {
- return m->d()->vtable()->type == Type_ArgumentsObject &&
- !static_cast<ArgumentsObject *>(m)->context()->strictMode;
+ return m->d()->vtable() == staticVTable();
}
bool defineOwnProperty(ExecutionEngine *engine, uint index, const Property *desc, PropertyAttributes attrs);
static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty);
- static void putIndexed(Managed *m, uint index, const Value &value);
+ static bool putIndexed(Managed *m, uint index, const Value &value);
static bool deleteIndexedProperty(Managed *m, uint index);
static PropertyAttributes queryIndexed(const Managed *m, uint index);
- static void markObjects(Heap::Base *that, ExecutionEngine *e);
static uint getLength(const Managed *m);
void fullyCreate();
};
+struct StrictArgumentsObject : Object {
+ V4_OBJECT2(StrictArgumentsObject, Object)
+ Q_MANAGED_TYPE(ArgumentsObject)
+};
+
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4arraybuffer.cpp b/src/qml/jsruntime/qv4arraybuffer.cpp
index ffe9aa846f..f7b9e8acef 100644
--- a/src/qml/jsruntime/qv4arraybuffer.cpp
+++ b/src/qml/jsruntime/qv4arraybuffer.cpp
@@ -40,6 +40,7 @@
#include "qv4typedarray_p.h"
#include "qv4dataview_p.h"
#include "qv4string_p.h"
+#include "qv4jscall_p.h"
using namespace QV4;
@@ -51,49 +52,42 @@ void Heap::ArrayBufferCtor::init(QV4::ExecutionContext *scope)
Heap::FunctionObject::init(scope, QStringLiteral("ArrayBuffer"));
}
-void ArrayBufferCtor::construct(const Managed *m, Scope &scope, CallData *callData)
+ReturnedValue ArrayBufferCtor::callAsConstructor(const FunctionObject *f, const Value *argv, int argc)
{
- ExecutionEngine *v4 = static_cast<const Object *>(m)->engine();
+ ExecutionEngine *v4 = f->engine();
+ Scope scope(v4);
- ScopedValue l(scope, callData->argument(0));
+ ScopedValue l(scope, argc ? argv[0] : Primitive::undefinedValue());
double dl = l->toInteger();
- if (v4->hasException) {
- scope.result = Encode::undefined();
- return;
- }
+ if (v4->hasException)
+ return Encode::undefined();
uint len = (uint)qBound(0., dl, (double)UINT_MAX);
- if (len != dl) {
- scope.result = v4->throwRangeError(QLatin1String("ArrayBuffer constructor: invalid length"));
- return;
- }
+ if (len != dl)
+ return v4->throwRangeError(QLatin1String("ArrayBuffer constructor: invalid length"));
Scoped<ArrayBuffer> a(scope, v4->newArrayBuffer(len));
- if (scope.engine->hasException) {
- scope.result = Encode::undefined();
- } else {
- scope.result = a->asReturnedValue();
- }
+ if (scope.engine->hasException)
+ return Encode::undefined();
+
+ return a->asReturnedValue();
}
-void ArrayBufferCtor::call(const Managed *that, Scope &scope, CallData *callData)
+ReturnedValue ArrayBufferCtor::call(const FunctionObject *f, const Value *, const Value *argv, int argc)
{
- construct(that, scope, callData);
+ return callAsConstructor(f, argv, argc);
}
-void ArrayBufferCtor::method_isView(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ArrayBufferCtor::method_isView(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- QV4::Scoped<TypedArray> a(scope, callData->argument(0));
- if (!!a) {
- scope.result = Encode(true);
- return;
- }
- QV4::Scoped<DataView> v(scope, callData->argument(0));
- if (!!v) {
- scope.result = Encode(true);
- return;
- }
- scope.result = Encode(false);
+ if (argc < 1)
+ return Encode(false);
+
+ if (argv[0].as<TypedArray>() ||
+ argv[0].as<DataView>())
+ return Encode(true);
+
+ return Encode(false);
}
@@ -163,48 +157,51 @@ void ArrayBufferPrototype::init(ExecutionEngine *engine, Object *ctor)
defineDefaultProperty(QStringLiteral("toString"), method_toString, 0);
}
-void ArrayBufferPrototype::method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ArrayBufferPrototype::method_get_byteLength(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<ArrayBuffer> v(scope, callData->thisObject);
- if (!v)
- THROW_TYPE_ERROR();
+ const ArrayBuffer *a = thisObject->as<ArrayBuffer>();
+ if (!a)
+ return b->engine()->throwTypeError();
- scope.result = Encode(v->d()->data->size);
+ return Encode(a->d()->data->size);
}
-void ArrayBufferPrototype::method_slice(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ArrayBufferPrototype::method_slice(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- Scoped<ArrayBuffer> a(scope, callData->thisObject);
+ ExecutionEngine *v4 = b->engine();
+ const ArrayBuffer *a = thisObject->as<ArrayBuffer>();
if (!a)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
- double start = callData->argc > 0 ? callData->args[0].toInteger() : 0;
- double end = (callData->argc < 2 || callData->args[1].isUndefined()) ?
- a->d()->data->size : callData->args[1].toInteger();
- CHECK_EXCEPTION();
+ double start = argc > 0 ? argv[0].toInteger() : 0;
+ double end = (argc < 2 || argv[1].isUndefined()) ?
+ a->d()->data->size : argv[1].toInteger();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
double first = (start < 0) ? qMax(a->d()->data->size + start, 0.) : qMin(start, (double)a->d()->data->size);
double final = (end < 0) ? qMax(a->d()->data->size + end, 0.) : qMin(end, (double)a->d()->data->size);
+ Scope scope(v4);
ScopedFunctionObject constructor(scope, a->get(scope.engine->id_constructor()));
if (!constructor)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
- ScopedCallData cData(scope, 1);
double newLen = qMax(final - first, 0.);
- cData->args[0] = QV4::Encode(newLen);
- constructor->construct(scope, cData);
- QV4::Scoped<ArrayBuffer> newBuffer(scope, scope.result);
+ ScopedValue argument(scope, QV4::Encode(newLen));
+ QV4::Scoped<ArrayBuffer> newBuffer(scope, constructor->callAsConstructor(argument, 1));
if (!newBuffer || newBuffer->d()->data->size < (int)newLen)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
memcpy(newBuffer->d()->data->data(), a->d()->data->data() + (uint)first, newLen);
+ return Encode::undefined();
}
-void ArrayBufferPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ArrayBufferPrototype::method_toString(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<ArrayBuffer> a(scope, callData->thisObject);
+ ExecutionEngine *v4 = b->engine();
+ const ArrayBuffer *a = thisObject->as<ArrayBuffer>();
if (!a)
RETURN_UNDEFINED();
- scope.result = scope.engine->newString(QString::fromUtf8(a->asByteArray()));
+ return Encode(v4->newString(QString::fromUtf8(a->asByteArray())));
}
diff --git a/src/qml/jsruntime/qv4arraybuffer_p.h b/src/qml/jsruntime/qv4arraybuffer_p.h
index 4f7926d3dc..e236a23d1f 100644
--- a/src/qml/jsruntime/qv4arraybuffer_p.h
+++ b/src/qml/jsruntime/qv4arraybuffer_p.h
@@ -78,10 +78,10 @@ struct ArrayBufferCtor: FunctionObject
{
V4_OBJECT2(ArrayBufferCtor, FunctionObject)
- static void construct(const Managed *m, Scope &scope, CallData *callData);
- static void call(const Managed *that, Scope &scope, CallData *callData);
+ static ReturnedValue callAsConstructor(const FunctionObject *f, const Value *argv, int argc);
+ static ReturnedValue call(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
- static void method_isView(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_isView(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
};
@@ -104,9 +104,9 @@ struct ArrayBufferPrototype: Object
{
void init(ExecutionEngine *engine, Object *ctor);
- static void method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_slice(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_get_byteLength(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_slice(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_toString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
};
diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp
index 6d1fb62e0a..5e971c8e9b 100644
--- a/src/qml/jsruntime/qv4arraydata.cpp
+++ b/src/qml/jsruntime/qv4arraydata.cpp
@@ -43,6 +43,7 @@
#include "qv4runtime_p.h"
#include "qv4argumentsobject_p.h"
#include "qv4string_p.h"
+#include "qv4jscall_p.h"
using namespace QV4;
@@ -62,7 +63,7 @@ const QV4::VTable QV4::ArrayData::static_vtbl = {
QV4::ArrayData::MyType,
"ArrayData",
Q_VTABLE_FUNCTION(QV4::ArrayData, destroy),
- 0,
+ ArrayData::Data::markObjects,
isEqualTo
};
@@ -110,6 +111,13 @@ static Q_ALWAYS_INLINE void storeValue(ReturnedValue *target, uint value)
*target = v.asReturnedValue();
}
+void Heap::ArrayData::markObjects(Heap::Base *base, MarkStack *stack)
+{
+ ArrayData *a = static_cast<ArrayData *>(base);
+ a->values.mark(stack);
+}
+
+
void ArrayData::realloc(Object *o, Type newType, uint requested, bool enforceAttributes)
{
Scope scope(o->engine());
@@ -130,7 +138,7 @@ void ArrayData::realloc(Object *o, Type newType, uint requested, bool enforceAtt
if (d->type() < Heap::ArrayData::Sparse) {
offset = d->d()->offset;
- toCopy = d->d()->len;
+ toCopy = d->d()->values.size;
} else {
toCopy = d->alloc();
}
@@ -151,7 +159,7 @@ void ArrayData::realloc(Object *o, Type newType, uint requested, bool enforceAtt
Heap::SimpleArrayData *n = scope.engine->memoryManager->allocManaged<SimpleArrayData>(size);
n->init();
n->offset = 0;
- n->len = d ? d->d()->len : 0;
+ n->values.size = d ? d->d()->values.size : 0;
newData = n;
} else {
Heap::SparseArrayData *n = scope.engine->memoryManager->allocManaged<SparseArrayData>(size);
@@ -160,7 +168,9 @@ void ArrayData::realloc(Object *o, Type newType, uint requested, bool enforceAtt
}
newData->setAlloc(alloc);
newData->setType(newType);
- newData->setAttrs(enforceAttributes ? reinterpret_cast<PropertyAttributes *>(newData->d()->arrayData + alloc) : 0);
+ if (d)
+ newData->d()->needsMark = d->d()->needsMark;
+ newData->setAttrs(enforceAttributes ? reinterpret_cast<PropertyAttributes *>(newData->d()->values.values + alloc) : 0);
o->setArrayData(newData);
if (d) {
@@ -172,14 +182,18 @@ void ArrayData::realloc(Object *o, Type newType, uint requested, bool enforceAtt
newData->attrs()[i] = Attr_Data;
}
- if (toCopy > d->d()->alloc - offset) {
- uint copyFromStart = toCopy - (d->d()->alloc - offset);
- memcpy(newData->d()->arrayData + toCopy - copyFromStart, d->d()->arrayData, sizeof(Value)*copyFromStart);
+ if (toCopy > d->d()->values.alloc - offset) {
+ uint copyFromStart = toCopy - (d->d()->values.alloc - offset);
+ // no write barrier required here
+ memcpy(newData->d()->values.values + toCopy - copyFromStart, d->d()->values.values, sizeof(Value)*copyFromStart);
toCopy -= copyFromStart;
}
- memcpy(newData->d()->arrayData, d->d()->arrayData + offset, sizeof(Value)*toCopy);
+ // no write barrier required here
+ memcpy(newData->d()->values.values, d->d()->values.values + offset, sizeof(Value)*toCopy);
}
+ if (newType != Heap::ArrayData::Simple)
+ newData->d()->needsMark = true;
if (newType != Heap::ArrayData::Sparse)
return;
@@ -190,34 +204,33 @@ void ArrayData::realloc(Object *o, Type newType, uint requested, bool enforceAtt
Heap::SparseArrayData *old = static_cast<Heap::SparseArrayData *>(d->d());
sparse->sparse = old->sparse;
old->sparse = 0;
- sparse->freeList = old->freeList;
- lastFree = &sparse->freeList;
+ lastFree = &sparse->sparse->freeList;
} else {
sparse->sparse = new SparseArray;
- lastFree = &sparse->freeList;
+ lastFree = &sparse->sparse->freeList;
storeValue(lastFree, 0);
for (uint i = 0; i < toCopy; ++i) {
- if (!sparse->arrayData[i].isEmpty()) {
+ if (!sparse->values[i].isEmpty()) {
SparseArrayNode *n = sparse->sparse->insert(i);
n->value = i;
} else {
storeValue(lastFree, i);
- sparse->arrayData[i].setEmpty();
- lastFree = &sparse->arrayData[i].rawValueRef();
+ sparse->values.values[i].setEmpty();
+ lastFree = &sparse->values.values[i].rawValueRef();
}
}
}
- if (toCopy < sparse->alloc) {
- for (uint i = toCopy; i < sparse->alloc; ++i) {
+ if (toCopy < sparse->values.alloc) {
+ for (uint i = toCopy; i < sparse->values.alloc; ++i) {
storeValue(lastFree, i);
- sparse->arrayData[i].setEmpty();
- lastFree = &sparse->arrayData[i].rawValueRef();
+ sparse->values.values[i].setEmpty();
+ lastFree = &sparse->values.values[i].rawValueRef();
}
- storeValue(lastFree, UINT_MAX);
}
+ storeValue(lastFree, UINT_MAX);
- Q_ASSERT(Value::fromReturnedValue(sparse->freeList).isEmpty());
+ Q_ASSERT(Value::fromReturnedValue(sparse->sparse->freeList).isEmpty());
// ### Could explicitly free the old data
}
@@ -235,24 +248,10 @@ void ArrayData::ensureAttributes(Object *o)
ArrayData::realloc(o, Heap::ArrayData::Simple, 0, true);
}
-
-void SimpleArrayData::markObjects(Heap::Base *d, ExecutionEngine *e)
-{
- Heap::SimpleArrayData *dd = static_cast<Heap::SimpleArrayData *>(d);
- uint end = dd->offset + dd->len;
- if (end > dd->alloc) {
- for (uint i = 0; i < end - dd->alloc; ++i)
- dd->arrayData[i].mark(e);
- end = dd->alloc;
- }
- for (uint i = dd->offset; i < end; ++i)
- dd->arrayData[i].mark(e);
-}
-
ReturnedValue SimpleArrayData::get(const Heap::ArrayData *d, uint index)
{
const Heap::SimpleArrayData *dd = static_cast<const Heap::SimpleArrayData *>(d);
- if (index >= dd->len)
+ if (index >= dd->values.size)
return Primitive::emptyValue().asReturnedValue();
return dd->data(index).asReturnedValue();
}
@@ -260,13 +259,13 @@ ReturnedValue SimpleArrayData::get(const Heap::ArrayData *d, uint index)
bool SimpleArrayData::put(Object *o, uint index, const Value &value)
{
Heap::SimpleArrayData *dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
- Q_ASSERT(index >= dd->len || !dd->attrs || !dd->attrs[index].isAccessor());
+ Q_ASSERT(index >= dd->values.size || !dd->attrs || !dd->attrs[index].isAccessor());
// ### honour attributes
- dd->data(index) = value;
- if (index >= dd->len) {
+ dd->setData(o->engine(), index, value);
+ if (index >= dd->values.size) {
if (dd->attrs)
dd->attrs[index] = Attr_Data;
- dd->len = index + 1;
+ dd->values.size = index + 1;
}
return true;
}
@@ -274,11 +273,11 @@ bool SimpleArrayData::put(Object *o, uint index, const Value &value)
bool SimpleArrayData::del(Object *o, uint index)
{
Heap::SimpleArrayData *dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
- if (index >= dd->len)
+ if (index >= dd->values.size)
return true;
if (!dd->attrs || dd->attrs[index].isConfigurable()) {
- dd->data(index) = Primitive::emptyValue();
+ dd->setData(o->engine(), index, Primitive::emptyValue());
if (dd->attrs)
dd->attrs[index] = Attr_Data;
return true;
@@ -297,8 +296,8 @@ void SimpleArrayData::push_front(Object *o, const Value *values, uint n)
{
Heap::SimpleArrayData *dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
Q_ASSERT(!dd->attrs);
- if (dd->len + n > dd->alloc) {
- realloc(o, Heap::ArrayData::Simple, dd->len + n, false);
+ if (dd->values.size + n > dd->values.alloc) {
+ realloc(o, Heap::ArrayData::Simple, dd->values.size + n, false);
Q_ASSERT(o->d()->arrayData->type == Heap::ArrayData::Simple);
dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
}
@@ -306,91 +305,83 @@ void SimpleArrayData::push_front(Object *o, const Value *values, uint n)
dd->offset -= n; // there is enough space left in front
} else {
// we need to wrap around, so:
- dd->offset = dd->alloc - // start at the back, but subtract:
+ dd->offset = dd->values.alloc - // start at the back, but subtract:
(n - dd->offset); // the number of items we can put in the free space at the start of the allocated array
}
- dd->len += n;
+ dd->values.size += n;
for (uint i = 0; i < n; ++i)
- dd->data(i) = values[i].asReturnedValue();
+ dd->setData(o->engine(), i, values[i]);
}
ReturnedValue SimpleArrayData::pop_front(Object *o)
{
Heap::SimpleArrayData *dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
Q_ASSERT(!dd->attrs);
- if (!dd->len)
+ if (!dd->values.size)
return Encode::undefined();
ReturnedValue v = dd->data(0).isEmpty() ? Encode::undefined() : dd->data(0).asReturnedValue();
- dd->offset = (dd->offset + 1) % dd->alloc;
- --dd->len;
+ dd->offset = (dd->offset + 1) % dd->values.alloc;
+ --dd->values.size;
return v;
}
uint SimpleArrayData::truncate(Object *o, uint newLen)
{
Heap::SimpleArrayData *dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
- if (dd->len < newLen)
+ if (dd->values.size < newLen)
return newLen;
if (!dd->attrs) {
- dd->len = newLen;
+ dd->values.size = newLen;
return newLen;
}
- while (dd->len > newLen) {
- if (!dd->data(dd->len - 1).isEmpty() && !dd->attrs[dd->len - 1].isConfigurable())
- return dd->len;
- --dd->len;
+ while (dd->values.size > newLen) {
+ if (!dd->data(dd->values.size - 1).isEmpty() && !dd->attrs[dd->values.size - 1].isConfigurable())
+ return dd->values.size;
+ --dd->values.size;
}
- return dd->len;
+ return dd->values.size;
}
uint SimpleArrayData::length(const Heap::ArrayData *d)
{
- return d->len;
+ return d->values.size;
}
bool SimpleArrayData::putArray(Object *o, uint index, const Value *values, uint n)
{
Heap::SimpleArrayData *dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
- if (index + n > dd->alloc) {
+ if (index + n > dd->values.alloc) {
reallocate(o, index + n + 1, false);
dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
}
- for (uint i = dd->len; i < index; ++i)
- dd->data(i) = Primitive::emptyValue();
+ QV4::ExecutionEngine *e = o->engine();
+ for (uint i = dd->values.size; i < index; ++i)
+ dd->setData(e, i, Primitive::emptyValue());
for (uint i = 0; i < n; ++i)
- dd->data(index + i) = values[i];
- dd->len = qMax(dd->len, index + n);
+ dd->setData(e, index + i, values[i]);
+ dd->values.size = qMax(dd->values.size, index + n);
return true;
}
void SparseArrayData::free(Heap::ArrayData *d, uint idx)
{
Q_ASSERT(d && d->type == Heap::ArrayData::Sparse);
- Value *v = d->arrayData + idx;
+ Value *v = d->values.values + idx;
if (d->attrs && d->attrs[idx].isAccessor()) {
// double slot, free both. Order is important, so we have a double slot for allocation again afterwards.
- v[1].setEmpty(Value::fromReturnedValue(d->freeList).emptyValue());
+ v[1].setEmpty(Value::fromReturnedValue(d->sparse->freeList).emptyValue());
v[0].setEmpty(idx + 1);
} else {
- v->setEmpty(Value::fromReturnedValue(d->freeList).emptyValue());
+ v->setEmpty(Value::fromReturnedValue(d->sparse->freeList).emptyValue());
}
- d->freeList = Primitive::emptyValue(idx).asReturnedValue();
+ d->sparse->freeList = Primitive::emptyValue(idx).asReturnedValue();
if (d->attrs)
d->attrs[idx].clear();
}
-
-void SparseArrayData::markObjects(Heap::Base *d, ExecutionEngine *e)
-{
- Heap::SparseArrayData *dd = static_cast<Heap::SparseArrayData *>(d);
- uint l = dd->alloc;
- for (uint i = 0; i < l; ++i)
- dd->arrayData[i].mark(e);
-}
-
Heap::ArrayData *SparseArrayData::reallocate(Object *o, uint n, bool enforceAttributes)
{
realloc(o, Heap::ArrayData::Sparse, n, enforceAttributes);
@@ -403,36 +394,36 @@ uint SparseArrayData::allocate(Object *o, bool doubleSlot)
Q_ASSERT(o->d()->arrayData->type == Heap::ArrayData::Sparse);
Heap::SimpleArrayData *dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
if (doubleSlot) {
- ReturnedValue *last = &dd->freeList;
+ ReturnedValue *last = &dd->sparse->freeList;
while (1) {
if (Value::fromReturnedValue(*last).value() == UINT_MAX) {
- reallocate(o, dd->alloc + 2, true);
+ reallocate(o, dd->values.alloc + 2, true);
dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
- last = &dd->freeList;
+ last = &dd->sparse->freeList;
Q_ASSERT(Value::fromReturnedValue(*last).value() != UINT_MAX);
}
- Q_ASSERT(dd->arrayData[Value::fromReturnedValue(*last).value()].value() != Value::fromReturnedValue(*last).value());
- if (dd->arrayData[Value::fromReturnedValue(*last).value()].value() == (Value::fromReturnedValue(*last).value() + 1)) {
+ Q_ASSERT(dd->values[Value::fromReturnedValue(*last).value()].value() != Value::fromReturnedValue(*last).value());
+ if (dd->values[Value::fromReturnedValue(*last).value()].value() == (Value::fromReturnedValue(*last).value() + 1)) {
// found two slots in a row
uint idx = Value::fromReturnedValue(*last).emptyValue();
Value lastV = Value::fromReturnedValue(*last);
- lastV.setEmpty(dd->arrayData[lastV.emptyValue() + 1].value());
+ lastV.setEmpty(dd->values[lastV.emptyValue() + 1].value());
*last = lastV.rawValue();
dd->attrs[idx] = Attr_Accessor;
return idx;
}
- last = &dd->arrayData[Value::fromReturnedValue(*last).value()].rawValueRef();
+ last = &dd->values.values[Value::fromReturnedValue(*last).value()].rawValueRef();
}
} else {
- if (Value::fromReturnedValue(dd->freeList).value() == UINT_MAX) {
- reallocate(o, dd->alloc + 1, false);
+ if (Value::fromReturnedValue(dd->sparse->freeList).value() == UINT_MAX) {
+ reallocate(o, dd->values.alloc + 1, false);
dd = o->d()->arrayData.cast<Heap::SimpleArrayData>();
}
- uint idx = Value::fromReturnedValue(dd->freeList).value();
+ uint idx = Value::fromReturnedValue(dd->sparse->freeList).value();
Q_ASSERT(idx != UINT_MAX);
- dd->freeList = dd->arrayData[idx].asReturnedValue();
- Q_ASSERT(Value::fromReturnedValue(dd->freeList).isEmpty());
+ dd->sparse->freeList = dd->values[idx].asReturnedValue();
+ Q_ASSERT(Value::fromReturnedValue(dd->sparse->freeList).isEmpty());
if (dd->attrs)
dd->attrs[idx] = Attr_Data;
return idx;
@@ -445,7 +436,7 @@ ReturnedValue SparseArrayData::get(const Heap::ArrayData *d, uint index)
index = s->mappedIndex(index);
if (index == UINT_MAX)
return Primitive::emptyValue().asReturnedValue();
- return s->arrayData[index].asReturnedValue();
+ return s->values[index].asReturnedValue();
}
bool SparseArrayData::put(Object *o, uint index, const Value &value)
@@ -459,7 +450,7 @@ bool SparseArrayData::put(Object *o, uint index, const Value &value)
if (n->value == UINT_MAX)
n->value = allocate(o);
s = o->d()->arrayData.cast<Heap::SparseArrayData>();
- s->arrayData[n->value] = value;
+ s->setArrayData(o->engine(), n->value, value);
if (s->attrs)
s->attrs[n->value] = Attr_Data;
return true;
@@ -474,7 +465,7 @@ bool SparseArrayData::del(Object *o, uint index)
return true;
uint pidx = n->value;
- Q_ASSERT(!dd->arrayData[pidx].isEmpty());
+ Q_ASSERT(!dd->values[pidx].isEmpty());
bool isAccessor = false;
if (dd->attrs) {
@@ -487,14 +478,14 @@ bool SparseArrayData::del(Object *o, uint index)
if (isAccessor) {
// free up both indices
- dd->arrayData[pidx + 1].setEmpty(Value::fromReturnedValue(dd->freeList).emptyValue());
- dd->arrayData[pidx].setEmpty(pidx + 1);
+ dd->values.values[pidx + 1].setEmpty(Value::fromReturnedValue(dd->sparse->freeList).emptyValue());
+ dd->values.values[pidx].setEmpty(pidx + 1);
} else {
Q_ASSERT(dd->type == Heap::ArrayData::Sparse);
- dd->arrayData[pidx].setEmpty(Value::fromReturnedValue(dd->freeList).emptyValue());
+ dd->values.values[pidx].setEmpty(Value::fromReturnedValue(dd->sparse->freeList).emptyValue());
}
- dd->freeList = Primitive::emptyValue(pidx).asReturnedValue();
+ dd->sparse->freeList = Primitive::emptyValue(pidx).asReturnedValue();
dd->sparse->erase(n);
return true;
}
@@ -520,10 +511,10 @@ void SparseArrayData::push_front(Object *o, const Value *values, uint n)
{
Heap::SparseArrayData *d = o->d()->arrayData.cast<Heap::SparseArrayData>();
Q_ASSERT(!d->attrs);
- for (int i = n - 1; i >= 0; --i) {
+ for (int i = static_cast<int>(n) - 1; i >= 0; --i) {
uint idx = allocate(o);
d = o->d()->arrayData.cast<Heap::SparseArrayData>();
- d->arrayData[idx] = values[i];
+ d->setArrayData(o->engine(), idx, values[i]);
d->sparse->push_front(idx);
}
}
@@ -535,7 +526,7 @@ ReturnedValue SparseArrayData::pop_front(Object *o)
uint idx = d->sparse->pop_front();
ReturnedValue v;
if (idx != UINT_MAX) {
- v = d->arrayData[idx].asReturnedValue();
+ v = d->values[idx].asReturnedValue();
free(o->arrayData(), idx);
} else {
v = Encode::undefined();
@@ -613,24 +604,24 @@ uint ArrayData::append(Object *obj, ArrayObject *otherObj, uint n)
ScopedValue v(scope);
for (const SparseArrayNode *it = os->sparse->begin();
it != os->sparse->end(); it = it->nextNode()) {
- v = otherObj->getValue(os->arrayData[it->value], other->d()->attrs[it->value]);
+ v = otherObj->getValue(os->values[it->value], other->d()->attrs[it->value]);
obj->arraySet(oldSize + it->key(), v);
}
} else {
for (const SparseArrayNode *it = other->d()->sparse->begin();
it != os->sparse->end(); it = it->nextNode())
- obj->arraySet(oldSize + it->key(), os->arrayData[it->value]);
+ obj->arraySet(oldSize + it->key(), os->values[it->value]);
}
} else {
Heap::SimpleArrayData *os = static_cast<Heap::SimpleArrayData *>(other->d());
uint toCopy = n;
uint chunk = toCopy;
- if (chunk > os->alloc - os->offset)
- chunk -= os->alloc - os->offset;
- obj->arrayPut(oldSize, os->arrayData + os->offset, chunk);
+ if (chunk > os->values.alloc - os->offset)
+ chunk -= os->values.alloc - os->offset;
+ obj->arrayPut(oldSize, os->values.data() + os->offset, chunk);
toCopy -= chunk;
if (toCopy)
- obj->arrayPut(oldSize + chunk, os->arrayData, toCopy);
+ obj->arrayPut(oldSize + chunk, os->values.data(), toCopy);
}
return oldSize + n;
@@ -640,18 +631,18 @@ void ArrayData::insert(Object *o, uint index, const Value *v, bool isAccessor)
{
if (!isAccessor && o->d()->arrayData->type != Heap::ArrayData::Sparse) {
Heap::SimpleArrayData *d = o->d()->arrayData.cast<Heap::SimpleArrayData>();
- if (index < 0x1000 || index < d->len + (d->len >> 2)) {
- if (index >= d->alloc) {
+ if (index < 0x1000 || index < d->values.size + (d->values.size >> 2)) {
+ if (index >= d->values.alloc) {
o->arrayReserve(index + 1);
d = o->d()->arrayData.cast<Heap::SimpleArrayData>();
}
- if (index >= d->len) {
+ if (index >= d->values.size) {
// mark possible hole in the array
- for (uint i = d->len; i < index; ++i)
- d->data(i) = Primitive::emptyValue();
- d->len = index + 1;
+ for (uint i = d->values.size; i < index; ++i)
+ d->setData(o->engine(), i, Primitive::emptyValue());
+ d->values.size = index + 1;
}
- d->arrayData[d->mappedIndex(index)] = *v;
+ d->setData(o->engine(), index, *v);
return;
}
}
@@ -662,9 +653,9 @@ void ArrayData::insert(Object *o, uint index, const Value *v, bool isAccessor)
if (n->value == UINT_MAX)
n->value = SparseArrayData::allocate(o, isAccessor);
s = o->d()->arrayData.cast<Heap::SparseArrayData>();
- s->arrayData[n->value] = *v;
+ s->setArrayData(o->engine(), n->value, *v);
if (isAccessor)
- s->arrayData[n->value + Object::SetterOffset] = v[Object::SetterOffset];
+ s->setArrayData(o->engine(), n->value + Object::SetterOffset, v[Object::SetterOffset]);
}
@@ -691,15 +682,14 @@ bool ArrayElementLessThan::operator()(Value v1, Value v2) const
return false;
if (v2.isUndefined() || v2.isEmpty())
return true;
- ScopedObject o(scope, m_comparefn);
+ ScopedFunctionObject o(scope, m_comparefn);
if (o) {
Scope scope(o->engine());
ScopedValue result(scope);
- ScopedCallData callData(scope, 2);
- callData->thisObject = Primitive::undefinedValue();
- callData->args[0] = v1;
- callData->args[1] = v2;
- result = QV4::Runtime::method_callValue(scope.engine, m_comparefn, callData);
+ JSCallData jsCallData(scope, 2);
+ jsCallData->args[0] = v1;
+ jsCallData->args[1] = v2;
+ result = o->call(jsCallData);
return result->toNumber() < 0;
}
@@ -773,7 +763,7 @@ void ArrayData::sort(ExecutionEngine *engine, Object *thisObject, const Value &c
if (!arrayData || !arrayData->length())
return;
- if (!(comparefn.isUndefined() || comparefn.as<Object>())) {
+ if (!comparefn.isUndefined() && !comparefn.isFunctionObject()) {
engine->throwTypeError();
return;
}
@@ -801,7 +791,7 @@ void ArrayData::sort(ExecutionEngine *engine, Object *thisObject, const Value &c
break;
PropertyAttributes a = sparse->attrs() ? sparse->attrs()[n->value] : Attr_Data;
- d->data(i) = thisObject->getValue(sparse->arrayData()[n->value], a);
+ d->setData(engine, i, Value::fromReturnedValue(thisObject->getValue(sparse->arrayData()[n->value], a)));
d->attrs[i] = a.isAccessor() ? Attr_Data : a;
n = n->nextNode();
@@ -811,12 +801,12 @@ void ArrayData::sort(ExecutionEngine *engine, Object *thisObject, const Value &c
while (n != sparse->sparse()->end()) {
if (n->value >= len)
break;
- d->data(i) = sparse->arrayData()[n->value];
+ d->setData(engine, i, sparse->arrayData()[n->value]);
n = n->nextNode();
++i;
}
}
- d->len = i;
+ d->values.size = i;
if (len > i)
len = i;
if (n != sparse->sparse()->end()) {
@@ -824,7 +814,7 @@ void ArrayData::sort(ExecutionEngine *engine, Object *thisObject, const Value &c
thisObject->initSparseArray();
while (n != sparse->sparse()->end()) {
PropertyAttributes a = sparse->attrs() ? sparse->attrs()[n->value] : Attr_Data;
- thisObject->arraySet(n->value, reinterpret_cast<Property *>(sparse->arrayData() + n->value), a);
+ thisObject->arraySet(n->value, reinterpret_cast<const Property *>(sparse->arrayData() + n->value), a);
n = n->nextNode();
}
@@ -832,8 +822,8 @@ void ArrayData::sort(ExecutionEngine *engine, Object *thisObject, const Value &c
}
} else {
Heap::SimpleArrayData *d = thisObject->d()->arrayData.cast<Heap::SimpleArrayData>();
- if (len > d->len)
- len = d->len;
+ if (len > d->values.size)
+ len = d->values.size;
// sort empty values to the end
for (uint i = 0; i < len; i++) {
@@ -842,8 +832,8 @@ void ArrayData::sort(ExecutionEngine *engine, Object *thisObject, const Value &c
if (!d->data(len).isEmpty())
break;
Q_ASSERT(!d->attrs || !d->attrs[len].isAccessor());
- d->data(i) = d->data(len);
- d->data(len) = Primitive::emptyValue();
+ d->setData(engine, i, d->data(len));
+ d->setData(engine, len, Primitive::emptyValue());
}
}
@@ -852,9 +842,9 @@ void ArrayData::sort(ExecutionEngine *engine, Object *thisObject, const Value &c
}
- ArrayElementLessThan lessThan(engine, thisObject, comparefn);
+ ArrayElementLessThan lessThan(engine, thisObject, static_cast<const FunctionObject &>(comparefn));
- Value *begin = thisObject->arrayData()->arrayData;
+ Value *begin = thisObject->arrayData()->values.values;
sortHelper(begin, begin + len, *begin, lessThan);
#ifdef CHECK_SPARSE_ARRAYS
diff --git a/src/qml/jsruntime/qv4arraydata_p.h b/src/qml/jsruntime/qv4arraydata_p.h
index daf8c36814..d6549e44ee 100644
--- a/src/qml/jsruntime/qv4arraydata_p.h
+++ b/src/qml/jsruntime/qv4arraydata_p.h
@@ -90,27 +90,31 @@ struct ArrayVTable
namespace Heap {
-struct ArrayData : public Base {
- enum Type {
- Simple = 0,
- Complex = 1,
- Sparse = 2,
- Custom = 3
+#define ArrayDataMembers(class, Member) \
+ Member(class, NoMark, ushort, type) \
+ Member(class, NoMark, ushort, needsMark) \
+ Member(class, NoMark, uint, offset) \
+ Member(class, NoMark, PropertyAttributes *, attrs) \
+ Member(class, NoMark, SparseArray *, sparse) \
+ Member(class, ValueArray, ValueArray, values)
+
+DECLARE_HEAP_OBJECT(ArrayData, Base) {
+ static void markObjects(Heap::Base *base, MarkStack *stack);
+
+ enum Type { Simple = 0, Complex = 1, Sparse = 2, Custom = 3 };
+
+ struct Index {
+ Heap::ArrayData *arrayData;
+ uint index;
+
+ void set(EngineBase *e, Value newVal) {
+ arrayData->values.set(e, index, newVal);
+ }
+ const Value *operator->() const { return &arrayData->values[index]; }
+ const Value &operator*() const { return arrayData->values[index]; }
+ bool isNull() const { return !arrayData; }
};
- uint alloc;
- Type type;
- PropertyAttributes *attrs;
- union {
- uint len;
- ReturnedValue freeList;
- };
- union {
- uint offset;
- SparseArray *sparse;
- };
- Value arrayData[1];
-
bool isSparse() const { return type == Sparse; }
const ArrayVTable *vtable() const { return reinterpret_cast<const ArrayVTable *>(Base::vtable()); }
@@ -118,42 +122,41 @@ struct ArrayData : public Base {
inline ReturnedValue get(uint i) const {
return vtable()->get(this, i);
}
- inline void getProperty(uint index, Property *p, PropertyAttributes *attrs);
- inline void setProperty(uint index, const Property *p);
- inline Property *getProperty(uint index);
- inline Value *getValueOrSetter(uint index, PropertyAttributes *attrs);
+ inline bool getProperty(uint index, Property *p, PropertyAttributes *attrs);
+ inline void setProperty(EngineBase *e, uint index, const Property *p);
+ inline Index getValueOrSetter(uint index, PropertyAttributes *attrs);
inline PropertyAttributes attributes(uint i) const;
bool isEmpty(uint i) const {
return get(i) == Primitive::emptyValue().asReturnedValue();
}
- inline ReturnedValue length() const {
+ inline uint length() const {
return vtable()->length(this);
}
+ void setArrayData(EngineBase *e, uint index, Value newVal) {
+ values.set(e, index, newVal);
+ }
+
+ uint mappedIndex(uint index) const;
};
-V4_ASSERT_IS_TRIVIAL(ArrayData)
+Q_STATIC_ASSERT(std::is_trivial< ArrayData >::value);
struct SimpleArrayData : public ArrayData {
- uint mappedIndex(uint index) const { return (index + offset) % alloc; }
- Value data(uint index) const { return arrayData[mappedIndex(index)]; }
- Value &data(uint index) { return arrayData[mappedIndex(index)]; }
-
- Property *getProperty(uint index) {
- if (index >= len)
- return 0;
- index = mappedIndex(index);
- if (arrayData[index].isEmpty())
- return 0;
- return reinterpret_cast<Property *>(arrayData + index);
+ uint mappedIndex(uint index) const { index += offset; if (index >= values.alloc) index -= values.alloc; return index; }
+ const Value &data(uint index) const { return values[mappedIndex(index)]; }
+ void setData(EngineBase *e, uint index, Value newVal) {
+ if (newVal.isManaged())
+ needsMark = true;
+ values.set(e, mappedIndex(index), newVal);
}
PropertyAttributes attributes(uint i) const {
return attrs ? attrs[i] : Attr_Data;
}
};
-V4_ASSERT_IS_TRIVIAL(SimpleArrayData)
+Q_STATIC_ASSERT(std::is_trivial< SimpleArrayData >::value);
struct SparseArrayData : public ArrayData {
void destroy() {
@@ -168,13 +171,6 @@ struct SparseArrayData : public ArrayData {
return n->value;
}
- Property *getProperty(uint index) {
- SparseArrayNode *n = sparse->findNode(index);
- if (!n)
- return 0;
- return reinterpret_cast<Property *>(arrayData + n->value);
- }
-
PropertyAttributes attributes(uint i) const {
if (!attrs)
return Attr_Data;
@@ -189,16 +185,23 @@ struct Q_QML_EXPORT ArrayData : public Managed
{
typedef Heap::ArrayData::Type Type;
V4_MANAGED(ArrayData, Managed)
+ enum {
+ IsArrayData = true
+ };
- uint alloc() const { return d()->alloc; }
- uint &alloc() { return d()->alloc; }
- void setAlloc(uint a) { d()->alloc = a; }
- Type type() const { return d()->type; }
+ typedef Heap::ArrayData::Index Index;
+
+ uint alloc() const { return d()->values.alloc; }
+ uint &alloc() { return d()->values.alloc; }
+ void setAlloc(uint a) { d()->values.alloc = a; }
+ Type type() const { return static_cast<Type>(d()->type); }
void setType(Type t) { d()->type = t; }
PropertyAttributes *attrs() const { return d()->attrs; }
void setAttrs(PropertyAttributes *a) { d()->attrs = a; }
- const Value *arrayData() const { return &d()->arrayData[0]; }
- Value *arrayData() { return &d()->arrayData[0]; }
+ const Value *arrayData() const { return d()->values.data(); }
+ void setArrayData(EngineBase *e, uint index, Value newVal) {
+ d()->setArrayData(e, index, newVal);
+ }
const ArrayVTable *vtable() const { return d()->vtable(); }
bool isSparse() const { return type() == Heap::ArrayData::Sparse; }
@@ -221,9 +224,6 @@ struct Q_QML_EXPORT ArrayData : public Managed
ReturnedValue get(uint i) const {
return d()->get(i);
}
- inline Property *getProperty(uint index) {
- return d()->getProperty(index);
- }
static void ensureAttributes(Object *o);
static void realloc(Object *o, Type newType, uint alloc, bool enforceAttributes);
@@ -240,15 +240,12 @@ struct Q_QML_EXPORT SimpleArrayData : public ArrayData
uint mappedIndex(uint index) const { return d()->mappedIndex(index); }
Value data(uint index) const { return d()->data(index); }
- Value &data(uint index) { return d()->data(index); }
- uint &len() { return d()->len; }
- uint len() const { return d()->len; }
+ uint &len() { return d()->values.size; }
+ uint len() const { return d()->values.size; }
static Heap::ArrayData *reallocate(Object *o, uint n, bool enforceAttributes);
- static void markObjects(Heap::Base *d, ExecutionEngine *e);
-
static ReturnedValue get(const Heap::ArrayData *d, uint index);
static bool put(Object *o, uint index, const Value &value);
static bool putArray(Object *o, uint index, const Value *values, uint n);
@@ -266,8 +263,6 @@ struct Q_QML_EXPORT SparseArrayData : public ArrayData
V4_INTERNALCLASS(SparseArrayData)
V4_NEEDS_DESTROY
- ReturnedValue &freeList() { return d()->freeList; }
- ReturnedValue freeList() const { return d()->freeList; }
SparseArray *sparse() const { return d()->sparse; }
void setSparse(SparseArray *s) { d()->sparse = s; }
@@ -276,8 +271,6 @@ struct Q_QML_EXPORT SparseArrayData : public ArrayData
uint mappedIndex(uint index) const { return d()->mappedIndex(index); }
- static void markObjects(Heap::Base *d, ExecutionEngine *e);
-
static Heap::ArrayData *reallocate(Object *o, uint n, bool enforceAttributes);
static ReturnedValue get(const Heap::ArrayData *d, uint index);
static bool put(Object *o, uint index, const Value &value);
@@ -292,30 +285,38 @@ struct Q_QML_EXPORT SparseArrayData : public ArrayData
namespace Heap {
-void ArrayData::getProperty(uint index, Property *p, PropertyAttributes *attrs)
+inline uint ArrayData::mappedIndex(uint index) const
{
- Property *pd = getProperty(index);
- Q_ASSERT(pd);
- *attrs = attributes(index);
- p->value = pd->value;
- if (attrs->isAccessor())
- p->set = pd->set;
+ if (isSparse())
+ return static_cast<const SparseArrayData *>(this)->mappedIndex(index);
+ if (index >= values.size)
+ return UINT_MAX;
+ uint idx = static_cast<const SimpleArrayData *>(this)->mappedIndex(index);
+ return values[idx].isEmpty() ? UINT_MAX : idx;
}
-void ArrayData::setProperty(uint index, const Property *p)
+bool ArrayData::getProperty(uint index, Property *p, PropertyAttributes *attrs)
{
- Property *pd = getProperty(index);
- Q_ASSERT(pd);
- pd->value = p->value;
- if (attributes(index).isAccessor())
- pd->set = p->set;
+ uint mapped = mappedIndex(index);
+ if (mapped == UINT_MAX) {
+ *attrs = Attr_Invalid;
+ return false;
+ }
+
+ *attrs = attributes(index);
+ p->value = *(Index{ this, mapped });
+ if (attrs->isAccessor())
+ p->set = *(Index{ this, mapped + 1 /*Object::SetterOffset*/ });
+ return true;
}
-inline Property *ArrayData::getProperty(uint index)
+void ArrayData::setProperty(QV4::EngineBase *e, uint index, const Property *p)
{
- if (isSparse())
- return static_cast<SparseArrayData *>(this)->getProperty(index);
- return static_cast<SimpleArrayData *>(this)->getProperty(index);
+ uint mapped = mappedIndex(index);
+ Q_ASSERT(mapped != UINT_MAX);
+ values.set(e, mapped, p->value);
+ if (attributes(index).isAccessor())
+ values.set(e, mapped + 1 /*QV4::Object::SetterOffset*/, p->set);
}
inline PropertyAttributes ArrayData::attributes(uint i) const
@@ -325,16 +326,16 @@ inline PropertyAttributes ArrayData::attributes(uint i) const
return static_cast<const SimpleArrayData *>(this)->attributes(i);
}
-Value *ArrayData::getValueOrSetter(uint index, PropertyAttributes *attrs)
+ArrayData::Index ArrayData::getValueOrSetter(uint index, PropertyAttributes *attrs)
{
- Property *p = getProperty(index);
- if (!p) {
+ uint idx = mappedIndex(index);
+ if (idx == UINT_MAX) {
*attrs = Attr_Invalid;
- return 0;
+ return { 0, 0 };
}
*attrs = attributes(index);
- return attrs->isAccessor() ? &p->set : &p->value;
+ return { this, attrs->isAccessor() ? idx + 1 /* QV4::Object::SetterOffset*/ : idx };
}
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index 759354f4e2..bd019d3bcb 100644
--- a/src/qml/jsruntime/qv4arrayobject.cpp
+++ b/src/qml/jsruntime/qv4arrayobject.cpp
@@ -40,7 +40,7 @@
#include "qv4arrayobject_p.h"
#include "qv4sparsearray_p.h"
#include "qv4objectproto_p.h"
-#include "qv4scopedvalue_p.h"
+#include "qv4jscall_p.h"
#include "qv4argumentsobject_p.h"
#include "qv4runtime_p.h"
#include "qv4string_p.h"
@@ -55,35 +55,34 @@ void Heap::ArrayCtor::init(QV4::ExecutionContext *scope)
Heap::FunctionObject::init(scope, QStringLiteral("Array"));
}
-void ArrayCtor::construct(const Managed *m, Scope &scope, CallData *callData)
+ReturnedValue ArrayCtor::callAsConstructor(const FunctionObject *f, const Value *argv, int argc)
{
- ExecutionEngine *v4 = static_cast<const ArrayCtor *>(m)->engine();
+ ExecutionEngine *v4 = static_cast<const ArrayCtor *>(f)->engine();
+ Scope scope(v4);
ScopedArrayObject a(scope, v4->newArrayObject());
uint len;
- if (callData->argc == 1 && callData->args[0].isNumber()) {
+ if (argc == 1 && argv[0].isNumber()) {
bool ok;
- len = callData->args[0].asArrayLength(&ok);
+ len = argv[0].asArrayLength(&ok);
- if (!ok) {
- scope.result = v4->throwRangeError(callData->args[0]);
- return;
- }
+ if (!ok)
+ return v4->throwRangeError(argv[0]);
if (len < 0x1000)
a->arrayReserve(len);
} else {
- len = callData->argc;
+ len = argc;
a->arrayReserve(len);
- a->arrayPut(0, callData->args, len);
+ a->arrayPut(0, argv, len);
}
a->setArrayLengthUnchecked(len);
- scope.result = a.asReturnedValue();
+ return a.asReturnedValue();
}
-void ArrayCtor::call(const Managed *that, Scope &scope, CallData *callData)
+ReturnedValue ArrayCtor::call(const FunctionObject *f, const Value *, const Value *argv, int argc)
{
- construct(that, scope, callData);
+ return callAsConstructor(f, argv, argc);
}
void ArrayPrototype::init(ExecutionEngine *engine, Object *ctor)
@@ -119,35 +118,35 @@ void ArrayPrototype::init(ExecutionEngine *engine, Object *ctor)
defineDefaultProperty(QStringLiteral("reduceRight"), method_reduceRight, 1);
}
-void ArrayPrototype::method_isArray(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ArrayPrototype::method_isArray(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- bool isArray = callData->argc && callData->args[0].as<ArrayObject>();
- scope.result = Encode(isArray);
+ bool isArray = argc && argv[0].as<ArrayObject>();
+ return Encode(isArray);
}
-void ArrayPrototype::method_toString(const BuiltinFunction *builtin, Scope &scope, CallData *callData)
+ReturnedValue ArrayPrototype::method_toString(const FunctionObject *builtin, const Value *thisObject, const Value *argv, int argc)
{
- ScopedObject o(scope, callData->thisObject, ScopedObject::Convert);
- CHECK_EXCEPTION();
- ScopedString s(scope, scope.engine->newString(QStringLiteral("join")));
- ScopedFunctionObject f(scope, o->get(s));
- if (!!f) {
- ScopedCallData d(scope, 0);
- d->thisObject = callData->thisObject;
- f->call(scope, d);
- return;
- }
- ObjectPrototype::method_toString(builtin, scope, callData);
+ Scope scope(builtin);
+ ScopedObject that(scope, thisObject->toObject(scope.engine));
+ if (scope.hasException())
+ return QV4::Encode::undefined();
+
+ ScopedString string(scope, scope.engine->newString(QStringLiteral("join")));
+ ScopedFunctionObject f(scope, that->get(string));
+ if (f)
+ return f->call(that, argv, argc);
+ return ObjectPrototype::method_toString(builtin, that, argv, argc);
}
-void ArrayPrototype::method_toLocaleString(const BuiltinFunction *builtin, Scope &scope, CallData *callData)
+ReturnedValue ArrayPrototype::method_toLocaleString(const FunctionObject *builtin, const Value *thisObject, const Value *argv, int argc)
{
- return method_toString(builtin, scope, callData);
+ return method_toString(builtin, thisObject, argv, argc);
}
-void ArrayPrototype::method_concat(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ArrayPrototype::method_concat(const FunctionObject *b, const Value *that, const Value *argv, int argc)
{
- ScopedObject thisObject(scope, callData->thisObject.toObject(scope.engine));
+ Scope scope(b);
+ ScopedObject thisObject(scope, that->toObject(scope.engine));
if (!thisObject)
RETURN_UNDEFINED();
@@ -162,9 +161,9 @@ void ArrayPrototype::method_concat(const BuiltinFunction *, Scope &scope, CallDa
ScopedArrayObject elt(scope);
ScopedObject eltAsObj(scope);
ScopedValue entry(scope);
- for (int i = 0; i < callData->argc; ++i) {
- eltAsObj = callData->args[i];
- elt = callData->args[i];
+ for (int i = 0, ei = argc; i < ei; ++i) {
+ eltAsObj = argv[i];
+ elt = argv[i];
if (elt) {
uint n = elt->getLength();
uint newLen = ArrayData::append(result, elt, n);
@@ -173,93 +172,94 @@ void ArrayPrototype::method_concat(const BuiltinFunction *, Scope &scope, CallDa
const uint startIndex = result->getLength();
for (int i = 0, len = eltAsObj->getLength(); i < len; ++i) {
entry = eltAsObj->getIndexed(i);
+ // spec says not to throw if this fails
result->putIndexed(startIndex + i, entry);
}
} else {
- result->arraySet(result->getLength(), callData->args[i]);
+ result->arraySet(result->getLength(), argv[i]);
}
}
- scope.result = result;
+ return result.asReturnedValue();
}
-void ArrayPrototype::method_find(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ArrayPrototype::method_find(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
+ Scope scope(b);
+ ScopedObject instance(scope, thisObject->toObject(scope.engine));
if (!instance)
RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, callData->argument(0));
- if (!callback)
+ if (!argc || !argv[0].isFunctionObject())
THROW_TYPE_ERROR();
+ const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
- ScopedCallData cData(scope, 3);
- cData->thisObject = callData->argument(1);
- cData->args[2] = instance;
+ ScopedValue result(scope);
+ Value *arguments = scope.alloc(3);
- ScopedValue v(scope);
+ ScopedValue that(scope, argc > 1 ? argv[1] : Primitive::undefinedValue());
for (uint k = 0; k < len; ++k) {
- v = instance->getIndexed(k);
+ arguments[0] = instance->getIndexed(k);
CHECK_EXCEPTION();
- cData->args[0] = v;
- cData->args[1] = Primitive::fromDouble(k);
- callback->call(scope, cData);
+ arguments[1] = Primitive::fromDouble(k);
+ arguments[2] = instance;
+ result = callback->call(that, arguments, 3);
CHECK_EXCEPTION();
- if (scope.result.toBoolean())
- RETURN_RESULT(v);
+ if (result->toBoolean())
+ return arguments[0].asReturnedValue();
}
RETURN_UNDEFINED();
}
-void ArrayPrototype::method_findIndex(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ArrayPrototype::method_findIndex(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
+ Scope scope(b);
+ ScopedObject instance(scope, thisObject->toObject(scope.engine));
if (!instance)
RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, callData->argument(0));
- if (!callback)
+ if (!argc || !argv[0].isFunctionObject())
THROW_TYPE_ERROR();
+ const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
- ScopedCallData cData(scope, 3);
- cData->thisObject = callData->argument(1);
- cData->args[2] = instance;
+ ScopedValue result(scope);
+ Value *arguments = scope.alloc(3);
- ScopedValue v(scope);
+ ScopedValue that(scope, argc > 1 ? argv[1] : Primitive::undefinedValue());
for (uint k = 0; k < len; ++k) {
- v = instance->getIndexed(k);
+ arguments[0] = instance->getIndexed(k);
CHECK_EXCEPTION();
- cData->args[0] = v;
- cData->args[1] = Primitive::fromDouble(k);
- callback->call(scope, cData);
+ arguments[1] = Primitive::fromDouble(k);
+ arguments[2] = instance;
+ result = callback->call(that, arguments, 3);
CHECK_EXCEPTION();
- if (scope.result.toBoolean())
- RETURN_RESULT(Encode(k));
+ if (result->toBoolean())
+ return Encode(k);
}
- RETURN_RESULT(Encode(-1));
+ return Encode(-1);
}
-void ArrayPrototype::method_join(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ArrayPrototype::method_join(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- ScopedValue arg(scope, callData->argument(0));
- ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
+ Scope scope(b);
+ ScopedObject instance(scope, thisObject->toObject(scope.engine));
- if (!instance) {
- scope.result = scope.engine->newString();
- return;
- }
+ if (!instance)
+ return Encode(scope.engine->newString());
+
+ ScopedValue arg(scope, argc ? argv[0] : Primitive::undefinedValue());
QString r4;
if (arg->isUndefined())
@@ -270,10 +270,8 @@ void ArrayPrototype::method_join(const BuiltinFunction *, Scope &scope, CallData
ScopedValue length(scope, instance->get(scope.engine->id_length()));
const quint32 r2 = length->isUndefined() ? 0 : length->toUInt32();
- if (!r2) {
- scope.result = scope.engine->newString();
- return;
- }
+ if (!r2)
+ return Encode(scope.engine->newString());
QString R;
@@ -311,12 +309,13 @@ void ArrayPrototype::method_join(const BuiltinFunction *, Scope &scope, CallData
}
}
- scope.result = scope.engine->newString(R);
+ return Encode(scope.engine->newString(R));
}
-void ArrayPrototype::method_pop(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ArrayPrototype::method_pop(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
+ Scope scope(b);
+ ScopedObject instance(scope, thisObject->toObject(scope.engine));
if (!instance)
RETURN_UNDEFINED();
@@ -331,19 +330,22 @@ void ArrayPrototype::method_pop(const BuiltinFunction *, Scope &scope, CallData
ScopedValue result(scope, instance->getIndexed(len - 1));
CHECK_EXCEPTION();
- instance->deleteIndexedProperty(len - 1);
- CHECK_EXCEPTION();
+ if (!instance->deleteIndexedProperty(len - 1))
+ return scope.engine->throwTypeError();
if (instance->isArrayObject())
instance->setArrayLength(len - 1);
- else
- instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len - 1)));
- scope.result = result;
+ else {
+ if (!instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len - 1))))
+ return scope.engine->throwTypeError();
+ }
+ return result->asReturnedValue();
}
-void ArrayPrototype::method_push(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ArrayPrototype::method_push(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
+ Scope scope(b);
+ ScopedObject instance(scope, thisObject->toObject(scope.engine));
if (!instance)
RETURN_UNDEFINED();
@@ -352,47 +354,52 @@ void ArrayPrototype::method_push(const BuiltinFunction *, Scope &scope, CallData
uint len = instance->getLength();
- if (len + callData->argc < len) {
- // ughh...
+ if (len + argc < len) {
+ // ughh... this goes beyond UINT_MAX
double l = len;
ScopedString s(scope);
- for (int i = 0; i < callData->argc; ++i) {
+ for (int i = 0, ei = argc; i < ei; ++i) {
s = Primitive::fromDouble(l + i).toString(scope.engine);
- instance->put(s, callData->args[i]);
+ if (!instance->put(s, argv[i]))
+ return scope.engine->throwTypeError();
}
- double newLen = l + callData->argc;
- if (!instance->isArrayObject())
- instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(newLen)));
- else {
+ double newLen = l + argc;
+ if (!instance->isArrayObject()) {
+ if (!instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(newLen))))
+ return scope.engine->throwTypeError();
+ } else {
ScopedString str(scope, scope.engine->newString(QStringLiteral("Array.prototype.push: Overflow")));
- scope.result = scope.engine->throwRangeError(str);
- return;
+ return scope.engine->throwRangeError(str);
}
- scope.result = Encode(newLen);
- return;
+ return Encode(newLen);
}
- if (!callData->argc)
+ if (!argc)
;
else if (!instance->protoHasArray() && instance->arrayData()->length() <= len && instance->arrayData()->type == Heap::ArrayData::Simple) {
- instance->arrayData()->vtable()->putArray(instance, len, callData->args, callData->argc);
+ instance->arrayData()->vtable()->putArray(instance, len, argv, argc);
len = instance->arrayData()->length();
} else {
- for (int i = 0; i < callData->argc; ++i)
- instance->putIndexed(len + i, callData->args[i]);
- len += callData->argc;
+ for (int i = 0, ei = argc; i < ei; ++i) {
+ if (!instance->putIndexed(len + i, argv[i]))
+ return scope.engine->throwTypeError();
+ }
+ len += argc;
}
if (instance->isArrayObject())
instance->setArrayLengthUnchecked(len);
- else
- instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len)));
+ else {
+ if (!instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len))))
+ return scope.engine->throwTypeError();
+ }
- scope.result = Encode(len);
+ return Encode(len);
}
-void ArrayPrototype::method_reverse(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ArrayPrototype::method_reverse(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
+ Scope scope(b);
+ ScopedObject instance(scope, thisObject->toObject(scope.engine));
if (!instance)
RETURN_UNDEFINED();
@@ -407,22 +414,27 @@ void ArrayPrototype::method_reverse(const BuiltinFunction *, Scope &scope, CallD
lval = instance->getIndexed(lo, &loExists);
hval = instance->getIndexed(hi, &hiExists);
CHECK_EXCEPTION();
+ bool ok;
if (hiExists)
- instance->putIndexed(lo, hval);
- else
- instance->deleteIndexedProperty(lo);
- CHECK_EXCEPTION();
- if (loExists)
- instance->putIndexed(hi, lval);
+ ok = instance->putIndexed(lo, hval);
else
- instance->deleteIndexedProperty(hi);
+ ok = instance->deleteIndexedProperty(lo);
+ if (ok) {
+ if (loExists)
+ ok = instance->putIndexed(hi, lval);
+ else
+ ok = instance->deleteIndexedProperty(hi);
+ }
+ if (!ok)
+ return scope.engine->throwTypeError();
}
- scope.result = instance;
+ return instance->asReturnedValue();
}
-void ArrayPrototype::method_shift(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ArrayPrototype::method_shift(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
+ Scope scope(b);
+ ScopedObject instance(scope, thisObject->toObject(scope.engine));
if (!instance)
RETURN_UNDEFINED();
@@ -433,14 +445,16 @@ void ArrayPrototype::method_shift(const BuiltinFunction *, Scope &scope, CallDat
if (!len) {
if (!instance->isArrayObject())
- instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromInt32(0)));
+ if (!instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromInt32(0))))
+ return scope.engine->throwTypeError();
RETURN_UNDEFINED();
}
+ ScopedValue result(scope);
if (!instance->protoHasArray() && !instance->arrayData()->attrs && instance->arrayData()->length() <= len && instance->arrayData()->type != Heap::ArrayData::Custom) {
- scope.result = instance->arrayData()->vtable()->pop_front(instance);
+ result = instance->arrayData()->vtable()->pop_front(instance);
} else {
- scope.result = instance->getIndexed(0);
+ result = instance->getIndexed(0);
CHECK_EXCEPTION();
ScopedValue v(scope);
// do it the slow way
@@ -448,31 +462,40 @@ void ArrayPrototype::method_shift(const BuiltinFunction *, Scope &scope, CallDat
bool exists;
v = instance->getIndexed(k, &exists);
CHECK_EXCEPTION();
+ bool ok;
if (exists)
- instance->putIndexed(k - 1, v);
+ ok = instance->putIndexed(k - 1, v);
else
- instance->deleteIndexedProperty(k - 1);
- CHECK_EXCEPTION();
+ ok = instance->deleteIndexedProperty(k - 1);
+ if (!ok)
+ return scope.engine->throwTypeError();
}
- instance->deleteIndexedProperty(len - 1);
- CHECK_EXCEPTION();
+ bool ok = instance->deleteIndexedProperty(len - 1);
+ if (!ok)
+ return scope.engine->throwTypeError();
}
if (instance->isArrayObject())
instance->setArrayLengthUnchecked(len - 1);
- else
- instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len - 1)));
+ else {
+ bool ok = instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len - 1)));
+ if (!ok)
+ return scope.engine->throwTypeError();
+ }
+
+ return result->asReturnedValue();
}
-void ArrayPrototype::method_slice(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ArrayPrototype::method_slice(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- ScopedObject o(scope, callData->thisObject.toObject(scope.engine));
+ Scope scope(b);
+ ScopedObject o(scope, thisObject->toObject(scope.engine));
if (!o)
RETURN_UNDEFINED();
ScopedArrayObject result(scope, scope.engine->newArrayObject());
uint len = o->getLength();
- double s = ScopedValue(scope, callData->argument(0))->toInteger();
+ double s = (argc ? argv[0] : Primitive::undefinedValue()).toInteger();
uint start;
if (s < 0)
start = (uint)qMax(len + s, 0.);
@@ -481,8 +504,8 @@ void ArrayPrototype::method_slice(const BuiltinFunction *, Scope &scope, CallDat
else
start = (uint) s;
uint end = len;
- if (callData->argc > 1 && !callData->args[1].isUndefined()) {
- double e = callData->args[1].toInteger();
+ if (argc > 1 && !argv[1].isUndefined()) {
+ double e = argv[1].toInteger();
if (e < 0)
end = (uint)qMax(len + e, 0.);
else if (e > len)
@@ -501,25 +524,27 @@ void ArrayPrototype::method_slice(const BuiltinFunction *, Scope &scope, CallDat
result->arraySet(n, v);
++n;
}
- scope.result = result;
+ return result->asReturnedValue();
}
-void ArrayPrototype::method_sort(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ArrayPrototype::method_sort(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
+ Scope scope(b);
+ ScopedObject instance(scope, thisObject->toObject(scope.engine));
if (!instance)
RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedValue comparefn(scope, callData->argument(0));
+ ScopedValue comparefn(scope, argc ? argv[0] : Primitive::undefinedValue());
ArrayData::sort(scope.engine, instance, comparefn, len);
- scope.result = callData->thisObject;
+ return thisObject->asReturnedValue();
}
-void ArrayPrototype::method_splice(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ArrayPrototype::method_splice(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
+ Scope scope(b);
+ ScopedObject instance(scope, thisObject->toObject(scope.engine));
if (!instance)
RETURN_UNDEFINED();
@@ -527,14 +552,14 @@ void ArrayPrototype::method_splice(const BuiltinFunction *, Scope &scope, CallDa
ScopedArrayObject newArray(scope, scope.engine->newArrayObject());
- double rs = ScopedValue(scope, callData->argument(0))->toInteger();
+ double rs = (argc ? argv[0] : Primitive::undefinedValue()).toInteger();
uint start;
if (rs < 0)
start = (uint) qMax(0., len + rs);
else
start = (uint) qMin(rs, (double)len);
- uint deleteCount = (uint)qMin(qMax(ScopedValue(scope, callData->argument(1))->toInteger(), 0.), (double)(len - start));
+ uint deleteCount = (uint)qMin(qMax((argc > 1 ? argv[1] : Primitive::undefinedValue()).toInteger(), 0.), (double)(len - start));
newArray->arrayReserve(deleteCount);
ScopedValue v(scope);
@@ -547,22 +572,24 @@ void ArrayPrototype::method_splice(const BuiltinFunction *, Scope &scope, CallDa
}
newArray->setArrayLengthUnchecked(deleteCount);
- uint itemCount = callData->argc < 2 ? 0 : callData->argc - 2;
+ uint itemCount = argc < 2 ? 0 : argc - 2;
if (itemCount < deleteCount) {
for (uint k = start; k < len - deleteCount; ++k) {
bool exists;
v = instance->getIndexed(k + deleteCount, &exists);
CHECK_EXCEPTION();
+ bool ok;
if (exists)
- instance->putIndexed(k + itemCount, v);
+ ok = instance->putIndexed(k + itemCount, v);
else
- instance->deleteIndexedProperty(k + itemCount);
- CHECK_EXCEPTION();
+ ok = instance->deleteIndexedProperty(k + itemCount);
+ if (!ok)
+ return scope.engine->throwTypeError();
}
for (uint k = len; k > len - deleteCount + itemCount; --k) {
- instance->deleteIndexedProperty(k - 1);
- CHECK_EXCEPTION();
+ if (!instance->deleteIndexedProperty(k - 1))
+ return scope.engine->throwTypeError();
}
} else if (itemCount > deleteCount) {
uint k = len - deleteCount;
@@ -570,31 +597,30 @@ void ArrayPrototype::method_splice(const BuiltinFunction *, Scope &scope, CallDa
bool exists;
v = instance->getIndexed(k + deleteCount - 1, &exists);
CHECK_EXCEPTION();
+ bool ok;
if (exists)
- instance->putIndexed(k + itemCount - 1, v);
+ ok = instance->putIndexed(k + itemCount - 1, v);
else
- instance->deleteIndexedProperty(k + itemCount - 1);
- CHECK_EXCEPTION();
+ ok = instance->deleteIndexedProperty(k + itemCount - 1);
+ if (!ok)
+ return scope.engine->throwTypeError();
--k;
}
}
- for (uint i = 0; i < itemCount; ++i) {
- instance->putIndexed(start + i, callData->args[i + 2]);
- CHECK_EXCEPTION();
- }
+ for (uint i = 0; i < itemCount; ++i)
+ instance->putIndexed(start + i, argv[i + 2]);
- bool wasStrict = scope.engine->current->strictMode;
- scope.engine->current->strictMode = true;
- instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len - deleteCount + itemCount)));
+ if (!instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len - deleteCount + itemCount))))
+ return scope.engine->throwTypeError();
- scope.result = newArray;
- scope.engine->current->strictMode = wasStrict;
+ return newArray->asReturnedValue();
}
-void ArrayPrototype::method_unshift(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ArrayPrototype::method_unshift(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
+ Scope scope(b);
+ ScopedObject instance(scope, thisObject->toObject(scope.engine));
if (!instance)
RETURN_UNDEFINED();
@@ -605,52 +631,57 @@ void ArrayPrototype::method_unshift(const BuiltinFunction *, Scope &scope, CallD
if (!instance->protoHasArray() && !instance->arrayData()->attrs && instance->arrayData()->length() <= len &&
instance->arrayData()->type != Heap::ArrayData::Custom) {
- instance->arrayData()->vtable()->push_front(instance, callData->args, callData->argc);
+ instance->arrayData()->vtable()->push_front(instance, argv, argc);
} else {
ScopedValue v(scope);
for (uint k = len; k > 0; --k) {
bool exists;
v = instance->getIndexed(k - 1, &exists);
+ bool ok;
if (exists)
- instance->putIndexed(k + callData->argc - 1, v);
+ ok = instance->putIndexed(k + argc - 1, v);
else
- instance->deleteIndexedProperty(k + callData->argc - 1);
+ ok = instance->deleteIndexedProperty(k + argc - 1);
+ if (!ok)
+ return scope.engine->throwTypeError();
+ }
+ for (int i = 0, ei = argc; i < ei; ++i) {
+ bool ok = instance->putIndexed(i, argv[i]);
+ if (!ok)
+ return scope.engine->throwTypeError();
}
- for (int i = 0; i < callData->argc; ++i)
- instance->putIndexed(i, callData->args[i]);
}
- uint newLen = len + callData->argc;
+ uint newLen = len + argc;
if (instance->isArrayObject())
instance->setArrayLengthUnchecked(newLen);
- else
- instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(newLen)));
+ else {
+ if (!instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(newLen))))
+ return scope.engine->throwTypeError();
+ }
- scope.result = Encode(newLen);
+ return Encode(newLen);
}
-void ArrayPrototype::method_indexOf(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ArrayPrototype::method_indexOf(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
+ Scope scope(b);
+ ScopedObject instance(scope, thisObject->toObject(scope.engine));
if (!instance)
RETURN_UNDEFINED();
uint len = instance->getLength();
- if (!len) {
- scope.result = Encode(-1);
- return;
- }
+ if (!len)
+ return Encode(-1);
- ScopedValue searchValue(scope, callData->argument(0));
+ ScopedValue searchValue(scope, argc ? argv[0] : Primitive::undefinedValue());
uint fromIndex = 0;
- if (callData->argc >= 2) {
- double f = callData->args[1].toInteger();
+ if (argc >= 2) {
+ double f = argv[1].toInteger();
CHECK_EXCEPTION();
- if (f >= len) {
- scope.result = Encode(-1);
- return;
- }
+ if (f >= len)
+ return Encode(-1);
if (f < 0)
f = qMax(len + f, 0.);
fromIndex = (uint) f;
@@ -661,13 +692,10 @@ void ArrayPrototype::method_indexOf(const BuiltinFunction *, Scope &scope, CallD
for (uint k = fromIndex; k < len; ++k) {
bool exists;
v = instance->getIndexed(k, &exists);
- if (exists && RuntimeHelpers::strictEqual(v, searchValue)) {
- scope.result = Encode(k);
- return;
- }
+ if (exists && RuntimeHelpers::strictEqual(v, searchValue))
+ return Encode(k);
}
- scope.result = Encode(-1);
- return;
+ return Encode(-1);
}
ScopedValue value(scope);
@@ -679,64 +707,56 @@ void ArrayPrototype::method_indexOf(const BuiltinFunction *, Scope &scope, CallD
bool exists;
value = instance->getIndexed(i, &exists);
CHECK_EXCEPTION();
- if (exists && RuntimeHelpers::strictEqual(value, searchValue)) {
- scope.result = Encode(i);
- return;
- }
+ if (exists && RuntimeHelpers::strictEqual(value, searchValue))
+ return Encode(i);
}
} else if (!instance->arrayData()) {
- scope.result = Encode(-1);
- return;
+ return Encode(-1);
} else {
Q_ASSERT(instance->arrayType() == Heap::ArrayData::Simple || instance->arrayType() == Heap::ArrayData::Complex);
Heap::SimpleArrayData *sa = instance->d()->arrayData.cast<Heap::SimpleArrayData>();
- if (len > sa->len)
- len = sa->len;
+ if (len > sa->values.size)
+ len = sa->values.size;
uint idx = fromIndex;
while (idx < len) {
value = sa->data(idx);
CHECK_EXCEPTION();
- if (RuntimeHelpers::strictEqual(value, searchValue)) {
- scope.result = Encode(idx);
- return;
- }
+ if (RuntimeHelpers::strictEqual(value, searchValue))
+ return Encode(idx);
++idx;
}
}
- scope.result = Encode(-1);
+ return Encode(-1);
}
-void ArrayPrototype::method_lastIndexOf(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ArrayPrototype::method_lastIndexOf(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
+ Scope scope(b);
+ ScopedObject instance(scope, thisObject->toObject(scope.engine));
if (!instance)
RETURN_UNDEFINED();
uint len = instance->getLength();
- if (!len) {
- scope.result = Encode(-1);
- return;
- }
+ if (!len)
+ return Encode(-1);
ScopedValue searchValue(scope);
uint fromIndex = len;
- if (callData->argc >= 1)
- searchValue = callData->argument(0);
+ if (argc >= 1)
+ searchValue = argv[0];
else
searchValue = Primitive::undefinedValue();
- if (callData->argc >= 2) {
- double f = callData->args[1].toInteger();
+ if (argc >= 2) {
+ double f = argv[1].toInteger();
CHECK_EXCEPTION();
if (f > 0)
f = qMin(f, (double)(len - 1));
else if (f < 0) {
f = len + f;
- if (f < 0) {
- scope.result = Encode(-1);
- return;
- }
+ if (f < 0)
+ return Encode(-1);
}
fromIndex = (uint) f + 1;
}
@@ -747,281 +767,277 @@ void ArrayPrototype::method_lastIndexOf(const BuiltinFunction *, Scope &scope, C
bool exists;
v = instance->getIndexed(k, &exists);
CHECK_EXCEPTION();
- if (exists && RuntimeHelpers::strictEqual(v, searchValue)) {
- scope.result = Encode(k);
- return;
- }
+ if (exists && RuntimeHelpers::strictEqual(v, searchValue))
+ return Encode(k);
}
- scope.result = Encode(-1);
+ return Encode(-1);
}
-void ArrayPrototype::method_every(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ArrayPrototype::method_every(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
+ Scope scope(b);
+ ScopedObject instance(scope, thisObject->toObject(scope.engine));
if (!instance)
RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, callData->argument(0));
- if (!callback)
+ if (!argc || !argv->isFunctionObject())
THROW_TYPE_ERROR();
+ const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
- ScopedCallData cData(scope, 3);
- cData->args[2] = instance;
- cData->thisObject = callData->argument(1);
- ScopedValue v(scope);
+ ScopedValue that(scope, argc > 1 ? argv[1] : Primitive::undefinedValue());
+ ScopedValue r(scope);
+ Value *arguments = scope.alloc(3);
bool ok = true;
for (uint k = 0; ok && k < len; ++k) {
bool exists;
- v = instance->getIndexed(k, &exists);
+ arguments[0] = instance->getIndexed(k, &exists);
if (!exists)
continue;
- cData->args[0] = v;
- cData->args[1] = Primitive::fromDouble(k);
- callback->call(scope, cData);
- ok = scope.result.toBoolean();
+ arguments[1] = Primitive::fromDouble(k);
+ arguments[2] = instance;
+ r = callback->call(that, arguments, 3);
+ ok = r->toBoolean();
}
- scope.result = Encode(ok);
+ return Encode(ok);
}
-void ArrayPrototype::method_some(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ArrayPrototype::method_some(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
+ Scope scope(b);
+ ScopedObject instance(scope, thisObject->toObject(scope.engine));
if (!instance)
RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, callData->argument(0));
- if (!callback)
+ if (!argc || !argv->isFunctionObject())
THROW_TYPE_ERROR();
+ const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
- ScopedCallData cData(scope, 3);
- cData->thisObject = callData->argument(1);
- cData->args[2] = instance;
- ScopedValue v(scope);
+ ScopedValue that(scope, argc > 1 ? argv[1] : Primitive::undefinedValue());
+ ScopedValue result(scope);
+ Value *arguments = scope.alloc(3);
for (uint k = 0; k < len; ++k) {
bool exists;
- v = instance->getIndexed(k, &exists);
+ arguments[0] = instance->getIndexed(k, &exists);
if (!exists)
continue;
- cData->args[0] = v;
- cData->args[1] = Primitive::fromDouble(k);
- callback->call(scope, cData);
- if (scope.result.toBoolean()) {
- scope.result = Encode(true);
- return;
- }
+ arguments[1] = Primitive::fromDouble(k);
+ arguments[2] = instance;
+ result = callback->call(that, arguments, 3);
+ if (result->toBoolean())
+ return Encode(true);
}
- scope.result = Encode(false);
+ return Encode(false);
}
-void ArrayPrototype::method_forEach(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ArrayPrototype::method_forEach(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
+ Scope scope(b);
+ ScopedObject instance(scope, thisObject->toObject(scope.engine));
if (!instance)
RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, callData->argument(0));
- if (!callback)
+ if (!argc || !argv->isFunctionObject())
THROW_TYPE_ERROR();
+ const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
- ScopedCallData cData(scope, 3);
- cData->thisObject = callData->argument(1);
- cData->args[2] = instance;
+ ScopedValue that(scope, argc > 1 ? argv[1] : Primitive::undefinedValue());
+ Value *arguments = scope.alloc(3);
- ScopedValue v(scope);
for (uint k = 0; k < len; ++k) {
bool exists;
- v = instance->getIndexed(k, &exists);
+ arguments[0] = instance->getIndexed(k, &exists);
if (!exists)
continue;
- cData->args[0] = v;
- cData->args[1] = Primitive::fromDouble(k);
- callback->call(scope, cData);
+ arguments[1] = Primitive::fromDouble(k);
+ arguments[2] = instance;
+ callback->call(that, arguments, 3);
}
RETURN_UNDEFINED();
}
-void ArrayPrototype::method_map(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ArrayPrototype::method_map(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
+ Scope scope(b);
+ ScopedObject instance(scope, thisObject->toObject(scope.engine));
if (!instance)
RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, callData->argument(0));
- if (!callback)
+ if (!argc || !argv->isFunctionObject())
THROW_TYPE_ERROR();
+ const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
ScopedArrayObject a(scope, scope.engine->newArrayObject());
a->arrayReserve(len);
a->setArrayLengthUnchecked(len);
- ScopedCallData cData(scope, 3);
- cData->thisObject = callData->argument(1);
- cData->args[2] = instance;
-
ScopedValue v(scope);
+ ScopedValue mapped(scope);
+ ScopedValue that(scope, argc > 1 ? argv[1] : Primitive::undefinedValue());
+ Value *arguments = scope.alloc(3);
+
for (uint k = 0; k < len; ++k) {
bool exists;
- v = instance->getIndexed(k, &exists);
+ arguments[0] = instance->getIndexed(k, &exists);
if (!exists)
continue;
- cData->args[0] = v;
- cData->args[1] = Primitive::fromDouble(k);
- callback->call(scope, cData);
- a->arraySet(k, scope.result);
+ arguments[1] = Primitive::fromDouble(k);
+ arguments[2] = instance;
+ mapped = callback->call(that, arguments, 3);
+ a->arraySet(k, mapped);
}
- scope.result = a.asReturnedValue();
+ return a.asReturnedValue();
}
-void ArrayPrototype::method_filter(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ArrayPrototype::method_filter(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
+ Scope scope(b);
+ ScopedObject instance(scope, thisObject->toObject(scope.engine));
if (!instance)
RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, callData->argument(0));
- if (!callback)
+ if (!argc || !argv->isFunctionObject())
THROW_TYPE_ERROR();
+ const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
ScopedArrayObject a(scope, scope.engine->newArrayObject());
a->arrayReserve(len);
- ScopedCallData cData(scope, 3);
- cData->thisObject = callData->argument(1);
- cData->args[2] = instance;
-
- ScopedValue v(scope);
+ ScopedValue selected(scope);
+ ScopedValue that(scope, argc > 1 ? argv[1] : Primitive::undefinedValue());
+ Value *arguments = scope.alloc(3);
uint to = 0;
for (uint k = 0; k < len; ++k) {
bool exists;
- v = instance->getIndexed(k, &exists);
+ arguments[0] = instance->getIndexed(k, &exists);
if (!exists)
continue;
- cData->args[0] = v;
- cData->args[1] = Primitive::fromDouble(k);
- callback->call(scope, cData);
- if (scope.result.toBoolean()) {
- a->arraySet(to, v);
+ arguments[1] = Primitive::fromDouble(k);
+ arguments[2] = instance;
+ selected = callback->call(that, arguments, 3);
+ if (selected->toBoolean()) {
+ a->arraySet(to, arguments[0]);
++to;
}
}
- scope.result = a.asReturnedValue();
+ return a.asReturnedValue();
}
-void ArrayPrototype::method_reduce(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ArrayPrototype::method_reduce(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
+ Scope scope(b);
+ ScopedObject instance(scope, thisObject->toObject(scope.engine));
if (!instance)
RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, callData->argument(0));
- if (!callback)
+ if (!argc || !argv->isFunctionObject())
THROW_TYPE_ERROR();
+ const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
uint k = 0;
+ ScopedValue acc(scope);
ScopedValue v(scope);
- if (callData->argc > 1) {
- scope.result = callData->argument(1);
+ if (argc > 1) {
+ acc = argv[1];
} else {
bool kPresent = false;
while (k < len && !kPresent) {
v = instance->getIndexed(k, &kPresent);
if (kPresent)
- scope.result = v;
+ acc = v;
++k;
}
if (!kPresent)
THROW_TYPE_ERROR();
}
- ScopedCallData cData(scope, 4);
- cData->thisObject = Primitive::undefinedValue();
- cData->args[0] = scope.result;
- cData->args[3] = instance;
+ Value *arguments = scope.alloc(4);
while (k < len) {
bool kPresent;
v = instance->getIndexed(k, &kPresent);
if (kPresent) {
- cData->args[0] = scope.result;
- cData->args[1] = v;
- cData->args[2] = Primitive::fromDouble(k);
- callback->call(scope, cData);
+ arguments[0] = acc;
+ arguments[1] = v;
+ arguments[2] = Primitive::fromDouble(k);
+ arguments[3] = instance;
+ acc = callback->call(nullptr, arguments, 4);
}
++k;
}
+ return acc->asReturnedValue();
}
-void ArrayPrototype::method_reduceRight(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ArrayPrototype::method_reduceRight(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
+ Scope scope(b);
+ ScopedObject instance(scope, thisObject->toObject(scope.engine));
if (!instance)
RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, callData->argument(0));
- if (!callback)
+ if (!argc || !argv->isFunctionObject())
THROW_TYPE_ERROR();
+ const FunctionObject *callback = static_cast<const FunctionObject *>(argv);
if (len == 0) {
- if (callData->argc == 1)
+ if (argc == 1)
THROW_TYPE_ERROR();
- scope.result = callData->argument(1);
- return;
+ return argv[1].asReturnedValue();
}
uint k = len;
+ ScopedValue acc(scope);
ScopedValue v(scope);
- if (callData->argc > 1) {
- scope.result = callData->argument(1);
+ if (argc > 1) {
+ acc = argv[1];
} else {
bool kPresent = false;
while (k > 0 && !kPresent) {
v = instance->getIndexed(k - 1, &kPresent);
if (kPresent)
- scope.result = v;
+ acc = v;
--k;
}
if (!kPresent)
THROW_TYPE_ERROR();
}
- ScopedCallData cData(scope, 4);
- cData->thisObject = Primitive::undefinedValue();
- cData->args[3] = instance;
+ Value *arguments = scope.alloc(4);
while (k > 0) {
bool kPresent;
v = instance->getIndexed(k - 1, &kPresent);
if (kPresent) {
- cData->args[0] = scope.result;
- cData->args[1] = v;
- cData->args[2] = Primitive::fromDouble(k - 1);
- callback->call(scope, cData);
+ arguments[0] = acc;
+ arguments[1] = v;
+ arguments[2] = Primitive::fromDouble(k - 1);
+ arguments[3] = instance;
+ acc = callback->call(nullptr, arguments, 4);
}
--k;
}
- scope.result = scope.result.asReturnedValue();
+ return acc->asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4arrayobject_p.h b/src/qml/jsruntime/qv4arrayobject_p.h
index 689752433b..3825a600a2 100644
--- a/src/qml/jsruntime/qv4arrayobject_p.h
+++ b/src/qml/jsruntime/qv4arrayobject_p.h
@@ -70,38 +70,38 @@ struct ArrayCtor: FunctionObject
{
V4_OBJECT2(ArrayCtor, FunctionObject)
- static void construct(const Managed *m, Scope &scope, CallData *callData);
- static void call(const Managed *that, Scope &scope, CallData *callData);
+ static ReturnedValue callAsConstructor(const FunctionObject *f, const Value *argv, int argc);
+ static ReturnedValue call(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
};
struct ArrayPrototype: ArrayObject
{
void init(ExecutionEngine *engine, Object *ctor);
- static void method_isArray(const BuiltinFunction *, Scope &, CallData *callData);
- static void method_toString(const BuiltinFunction *, Scope &, CallData *callData);
- static void method_toLocaleString(const BuiltinFunction *builtin, Scope &, CallData *callData);
- static void method_concat(const BuiltinFunction *, Scope &, CallData *callData);
- static void method_find(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_findIndex(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_join(const BuiltinFunction *, Scope &, CallData *callData);
- static void method_pop(const BuiltinFunction *, Scope &, CallData *callData);
- static void method_push(const BuiltinFunction *, Scope &, CallData *callData);
- static void method_reverse(const BuiltinFunction *, Scope &, CallData *callData);
- static void method_shift(const BuiltinFunction *, Scope &, CallData *callData);
- static void method_slice(const BuiltinFunction *, Scope &, CallData *callData);
- static void method_sort(const BuiltinFunction *, Scope &, CallData *callData);
- static void method_splice(const BuiltinFunction *, Scope &, CallData *callData);
- static void method_unshift(const BuiltinFunction *, Scope &, CallData *callData);
- static void method_indexOf(const BuiltinFunction *, Scope &, CallData *callData);
- static void method_lastIndexOf(const BuiltinFunction *, Scope &, CallData *callData);
- static void method_every(const BuiltinFunction *, Scope &, CallData *callData);
- static void method_some(const BuiltinFunction *, Scope &, CallData *callData);
- static void method_forEach(const BuiltinFunction *, Scope &, CallData *callData);
- static void method_map(const BuiltinFunction *, Scope &, CallData *callData);
- static void method_filter(const BuiltinFunction *, Scope &, CallData *callData);
- static void method_reduce(const BuiltinFunction *, Scope &, CallData *callData);
- static void method_reduceRight(const BuiltinFunction *, Scope &, CallData *callData);
+ static ReturnedValue method_isArray(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_toString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_toLocaleString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_concat(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_find(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_findIndex(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_join(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_pop(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_push(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_reverse(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_shift(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_slice(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_sort(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_splice(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_unshift(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_indexOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_lastIndexOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_every(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_some(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_forEach(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_map(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_filter(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_reduce(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_reduceRight(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
};
diff --git a/src/qml/jsruntime/qv4booleanobject.cpp b/src/qml/jsruntime/qv4booleanobject.cpp
index c8e9ebb2dd..eb83f902db 100644
--- a/src/qml/jsruntime/qv4booleanobject.cpp
+++ b/src/qml/jsruntime/qv4booleanobject.cpp
@@ -50,16 +50,16 @@ void Heap::BooleanCtor::init(QV4::ExecutionContext *scope)
Heap::FunctionObject::init(scope, QStringLiteral("Boolean"));
}
-void BooleanCtor::construct(const Managed *, Scope &scope, CallData *callData)
+ReturnedValue BooleanCtor::callAsConstructor(const FunctionObject *that, const Value *argv, int argc)
{
- bool n = callData->argc ? callData->args[0].toBoolean() : false;
- scope.result = Encode(scope.engine->newBooleanObject(n));
+ bool n = argc ? argv[0].toBoolean() : false;
+ return Encode(that->engine()->newBooleanObject(n));
}
-void BooleanCtor::call(const Managed *, Scope &scope, CallData *callData)
+ReturnedValue BooleanCtor::call(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- bool value = callData->argc ? callData->args[0].toBoolean() : 0;
- scope.result = Encode(value);
+ bool value = argc ? argv[0].toBoolean() : 0;
+ return Encode(value);
}
void BooleanPrototype::init(ExecutionEngine *engine, Object *ctor)
@@ -73,31 +73,39 @@ void BooleanPrototype::init(ExecutionEngine *engine, Object *ctor)
defineDefaultProperty(engine->id_valueOf(), method_valueOf);
}
-void BooleanPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
+static bool value(const Value *thisObject, bool *exception)
{
- bool result;
- if (callData->thisObject.isBoolean()) {
- result = callData->thisObject.booleanValue();
+ *exception = false;
+ if (thisObject->isBoolean()) {
+ return thisObject->booleanValue();
} else {
- const BooleanObject *thisObject = callData->thisObject.as<BooleanObject>();
- if (!thisObject)
- THROW_TYPE_ERROR();
- result = thisObject->value();
+ const BooleanObject *that = thisObject->as<BooleanObject>();
+ if (that)
+ return that->value();
}
+ *exception = true;
+ return false;
+}
+
+ReturnedValue BooleanPrototype::method_toString(const FunctionObject *b, const Value *thisObject, const Value *, int)
+{
+ bool exception;
+ bool result = ::value(thisObject, &exception);
+ ExecutionEngine *v4 = b->engine();
+ if (exception)
+ return v4->throwTypeError();
- scope.result = result ? scope.engine->id_true() : scope.engine->id_false();
+ return Encode(result ? v4->id_true() : v4->id_false());
}
-void BooleanPrototype::method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue BooleanPrototype::method_valueOf(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- if (callData->thisObject.isBoolean()) {
- scope.result = callData->thisObject.asReturnedValue();
- return;
+ bool exception;
+ bool result = ::value(thisObject, &exception);
+ if (exception) {
+ ExecutionEngine *v4 = b->engine();
+ return v4->throwTypeError();
}
- const BooleanObject *thisObject = callData->thisObject.as<BooleanObject>();
- if (!thisObject)
- THROW_TYPE_ERROR();
-
- scope.result = Encode(thisObject->value());
+ return Encode(result);
}
diff --git a/src/qml/jsruntime/qv4booleanobject_p.h b/src/qml/jsruntime/qv4booleanobject_p.h
index ca2cf7d17a..3cf09b2667 100644
--- a/src/qml/jsruntime/qv4booleanobject_p.h
+++ b/src/qml/jsruntime/qv4booleanobject_p.h
@@ -70,8 +70,8 @@ struct BooleanCtor: FunctionObject
{
V4_OBJECT2(BooleanCtor, FunctionObject)
- static void construct(const Managed *, Scope &scope, CallData *callData);
- static void call(const Managed *that, Scope &scope, CallData *callData);
+ static ReturnedValue callAsConstructor(const FunctionObject *, const Value *argv, int argc);
+ static ReturnedValue call(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
};
struct BooleanPrototype: BooleanObject
@@ -79,8 +79,8 @@ struct BooleanPrototype: BooleanObject
V4_PROTOTYPE(objectPrototype)
void init(ExecutionEngine *engine, Object *ctor);
- static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_toString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_valueOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
};
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index 3ff864d7b9..00d816fe91 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -48,56 +48,52 @@
#include "qv4errorobject_p.h"
#include "qv4string_p.h"
#include "qv4qmlcontext_p.h"
-#include "qv4profiling_p.h"
-#include <private/qqmljavascriptexpression_p.h>
using namespace QV4;
DEFINE_MANAGED_VTABLE(ExecutionContext);
DEFINE_MANAGED_VTABLE(CallContext);
-DEFINE_MANAGED_VTABLE(WithContext);
DEFINE_MANAGED_VTABLE(CatchContext);
-DEFINE_MANAGED_VTABLE(GlobalContext);
-/* Function *f, int argc */
-#define requiredMemoryForExecutionContect(f, argc) \
- ((sizeof(CallContext::Data) + 7) & ~7) + \
- sizeof(Value) * (f->compiledFunction->nLocals + qMax((uint)argc, f->nFormals)) + sizeof(CallData)
-
-Heap::CallContext *ExecutionContext::newCallContext(Function *function, CallData *callData)
+Heap::CallContext *ExecutionContext::newCallContext(CppStackFrame *frame)
{
- Heap::CallContext *c = engine()->memoryManager->allocManaged<CallContext>(
- requiredMemoryForExecutionContect(function, callData->argc));
- c->init(Heap::ExecutionContext::Type_CallContext);
-
- c->v4Function = function;
+ Function *function = frame->v4Function;
+ Heap::ExecutionContext *outer = static_cast<Heap::ExecutionContext *>(frame->context()->m());
- c->strictMode = function->isStrict();
- c->outer = this->d();
+ uint nFormals = qMax(static_cast<uint>(frame->originalArgumentsCount), function->nFormals);
+ uint localsAndFormals = function->compiledFunction->nLocals + nFormals;
+ size_t requiredMemory = sizeof(CallContext::Data) - sizeof(Value) + sizeof(Value) * (localsAndFormals);
- c->activation = 0;
+ ExecutionEngine *v4 = outer->internalClass->engine;
+ Heap::CallContext *c = v4->memoryManager->allocManaged<CallContext>(requiredMemory, function->internalClass);
+ c->init();
- c->compilationUnit = function->compilationUnit;
- c->lookups = function->compilationUnit->runtimeLookups;
- c->constantTable = function->compilationUnit->constants;
- c->locals = (Value *)((quintptr(c + 1) + 7) & ~7);
+ c->outer.set(v4, outer);
+ c->function.set(v4, static_cast<Heap::FunctionObject *>(frame->jsFrame->function.m()));
const CompiledData::Function *compiledFunction = function->compiledFunction;
- int nLocals = compiledFunction->nLocals;
- if (nLocals)
- std::fill(c->locals, c->locals + nLocals, Primitive::undefinedValue());
-
- c->callData = reinterpret_cast<CallData *>(c->locals + nLocals);
- ::memcpy(c->callData, callData, sizeof(CallData) + (callData->argc - 1) * sizeof(Value));
- if (callData->argc < static_cast<int>(compiledFunction->nFormals))
- std::fill(c->callData->args + c->callData->argc, c->callData->args + compiledFunction->nFormals, Primitive::undefinedValue());
+ uint nLocals = compiledFunction->nLocals;
+ c->locals.size = nLocals;
+ c->locals.alloc = localsAndFormals;
+ // memory allocated from the JS heap is 0 initialized, so check if undefined is 0
+ Q_ASSERT(Primitive::undefinedValue().asReturnedValue() == 0);
+
+ Value *args = c->locals.values + nLocals;
+ ::memcpy(args, frame->originalArguments, frame->originalArgumentsCount * sizeof(Value));
+ c->nArgs = frame->originalArgumentsCount;
+ for (uint i = frame->originalArgumentsCount; i < function->nFormals; ++i)
+ args[i] = Encode::undefined();
return c;
}
-Heap::WithContext *ExecutionContext::newWithContext(Heap::Object *with)
+Heap::ExecutionContext *ExecutionContext::newWithContext(Heap::Object *with)
{
- return engine()->memoryManager->alloc<WithContext>(d(), with);
+ Heap::ExecutionContext *c = engine()->memoryManager->alloc<ExecutionContext>(Heap::ExecutionContext::Type_WithContext);
+ c->outer.set(engine(), d());
+ c->activation.set(engine(), with);
+
+ return c;
}
Heap::CatchContext *ExecutionContext::newCatchContext(Heap::String *exceptionVarName, ReturnedValue exceptionValue)
@@ -117,25 +113,23 @@ void ExecutionContext::createMutableBinding(String *name, bool deletable)
while (ctx) {
switch (ctx->d()->type) {
case Heap::ExecutionContext::Type_CallContext:
- case Heap::ExecutionContext::Type_SimpleCallContext: {
- Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx->d());
if (!activation) {
+ Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx->d());
if (!c->activation)
- c->activation = scope.engine->newObject();
+ c->activation.set(scope.engine, scope.engine->newObject());
activation = c->activation;
}
break;
- }
case Heap::ExecutionContext::Type_QmlContext: {
// this is ugly, as it overrides the inner callcontext, but has to stay as long
// as bindings still get their own callcontext
- Heap::QmlContext *qml = static_cast<Heap::QmlContext *>(ctx->d());
- activation = qml->qml;
+ activation = ctx->d()->activation;
break;
}
case Heap::ExecutionContext::Type_GlobalContext: {
+ Q_ASSERT(scope.engine->globalObject->d() == ctx->d()->activation);
if (!activation)
- activation = scope.engine->globalObject;
+ activation = ctx->d()->activation;
break;
}
default:
@@ -144,7 +138,7 @@ void ExecutionContext::createMutableBinding(String *name, bool deletable)
ctx = ctx->d()->outer;
}
- if (activation->hasProperty(name))
+ if (activation->hasOwnProperty(name))
return;
ScopedProperty desc(scope);
PropertyAttributes attrs(Attr_Data);
@@ -152,91 +146,46 @@ void ExecutionContext::createMutableBinding(String *name, bool deletable)
activation->__defineOwnProperty__(scope.engine, name, desc, attrs);
}
-void Heap::GlobalContext::init(ExecutionEngine *eng)
-{
- Heap::ExecutionContext::init(Heap::ExecutionContext::Type_GlobalContext);
- global = eng->globalObject->d();
-}
-
void Heap::CatchContext::init(ExecutionContext *outerContext, String *exceptionVarName,
const Value &exceptionValue)
{
Heap::ExecutionContext::init(Heap::ExecutionContext::Type_CatchContext);
- outer = outerContext;
- strictMode = outer->strictMode;
- callData = outer->callData;
- lookups = outer->lookups;
- constantTable = outer->constantTable;
- compilationUnit = outer->compilationUnit;
-
- this->exceptionVarName = exceptionVarName;
- this->exceptionValue = exceptionValue;
-}
+ outer.set(internalClass->engine, outerContext);
-
-Identifier * const *CallContext::formals() const
-{
- return d()->v4Function ? d()->v4Function->internalClass->nameMap.constData() : 0;
-}
-
-unsigned int CallContext::formalCount() const
-{
- return d()->v4Function ? d()->v4Function->nFormals : 0;
+ this->exceptionVarName.set(internalClass->engine, exceptionVarName);
+ this->exceptionValue.set(internalClass->engine, exceptionValue);
}
-Identifier * const *CallContext::variables() const
-{
- return d()->v4Function ? d()->v4Function->internalClass->nameMap.constData() + d()->v4Function->nFormals : 0;
-}
-
-unsigned int CallContext::variableCount() const
-{
- return d()->v4Function ? d()->v4Function->compiledFunction->nLocals : 0;
-}
-
-
-
bool ExecutionContext::deleteProperty(String *name)
{
name->makeIdentifier();
Identifier *id = name->identifier();
- Scope scope(this);
- bool hasWith = false;
- ScopedContext ctx(scope, this);
- for (; ctx; ctx = ctx->d()->outer) {
- switch (ctx->d()->type) {
+ Heap::ExecutionContext *ctx = d();
+ for (; ctx; ctx = ctx->outer) {
+ switch (ctx->type) {
case Heap::ExecutionContext::Type_CatchContext: {
- Heap::CatchContext *c = static_cast<Heap::CatchContext *>(ctx->d());
+ Heap::CatchContext *c = static_cast<Heap::CatchContext *>(ctx);
if (c->exceptionVarName->isEqualTo(name->d()))
return false;
break;
}
- case Heap::ExecutionContext::Type_WithContext: {
- hasWith = true;
- ScopedObject withObject(scope, static_cast<Heap::WithContext *>(ctx->d())->withObject);
- if (withObject->hasProperty(name))
- return withObject->deleteProperty(name);
- break;
+ case Heap::ExecutionContext::Type_CallContext: {
+ Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx);
+ uint index = c->internalClass->find(id);
+ if (index < UINT_MAX)
+ // ### throw in strict mode?
+ return false;
+ Q_FALLTHROUGH();
}
+ case Heap::ExecutionContext::Type_WithContext:
case Heap::ExecutionContext::Type_GlobalContext: {
- ScopedObject global(scope, static_cast<Heap::GlobalContext *>(ctx->d())->global);
- if (global->hasProperty(name))
- return global->deleteProperty(name);
- break;
- }
- case Heap::ExecutionContext::Type_CallContext:
- case Heap::ExecutionContext::Type_SimpleCallContext: {
- Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx->d());
- if (c->v4Function && (c->v4Function->needsActivation() || hasWith)) {
- uint index = c->v4Function->internalClass->find(id);
- if (index < UINT_MAX)
- // ### throw in strict mode?
- return false;
+ if (ctx->activation) {
+ Scope scope(this);
+ ScopedObject object(scope, ctx->activation);
+ if (object && object->hasProperty(name))
+ return object->deleteProperty(name);
}
- ScopedObject qml(scope, c->activation);
- if (qml && qml->hasProperty(name))
- return qml->deleteProperty(name);
break;
}
case Heap::ExecutionContext::Type_QmlContext:
@@ -245,360 +194,165 @@ bool ExecutionContext::deleteProperty(String *name)
}
}
- if (d()->strictMode)
- engine()->throwSyntaxError(QStringLiteral("Can't delete property %1").arg(name->toQString()));
- return true;
-}
-
-bool CallContext::needsOwnArguments() const
-{
- QV4::Function *f = d()->v4Function;
- return (f && f->needsActivation()) || (argc() < (f ? static_cast<int>(f->nFormals) : 0));
-}
-
-void ExecutionContext::markObjects(Heap::Base *m, ExecutionEngine *engine)
-{
- ExecutionContext::Data *ctx = static_cast<ExecutionContext::Data *>(m);
-
- if (ctx->outer)
- ctx->outer->mark(engine);
-
- switch (ctx->type) {
- case Heap::ExecutionContext::Type_CatchContext: {
- CatchContext::Data *c = static_cast<CatchContext::Data *>(ctx);
- c->exceptionVarName->mark(engine);
- c->exceptionValue.mark(engine);
- break;
- }
- case Heap::ExecutionContext::Type_WithContext: {
- WithContext::Data *w = static_cast<WithContext::Data *>(ctx);
- if (w->withObject)
- w->withObject->mark(engine);
- break;
- }
- case Heap::ExecutionContext::Type_GlobalContext: {
- GlobalContext::Data *g = static_cast<GlobalContext::Data *>(ctx);
- g->global->mark(engine);
- break;
- }
- case Heap::ExecutionContext::Type_SimpleCallContext:
- break;
- case Heap::ExecutionContext::Type_CallContext: {
- QV4::Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx);
- Q_ASSERT(c->v4Function);
- ctx->callData->thisObject.mark(engine);
- for (int arg = 0; arg < qMax(ctx->callData->argc, (int)c->v4Function->nFormals); ++arg)
- ctx->callData->args[arg].mark(engine);
- for (unsigned local = 0, lastLocal = c->v4Function->compiledFunction->nLocals; local < lastLocal; ++local)
- c->locals[local].mark(engine);
- if (c->activation)
- c->activation->mark(engine);
- if (c->function)
- c->function->mark(engine);
- break;
- }
- case Heap::ExecutionContext::Type_QmlContext: {
- QmlContext::Data *g = static_cast<QmlContext::Data *>(ctx);
- g->qml->mark(engine);
- break;
- }
- }
-}
-
-// Do a standard call with this execution context as the outer scope
-void ExecutionContext::call(Scope &scope, CallData *callData, Function *function, const FunctionObject *f)
-{
- ExecutionContextSaver ctxSaver(scope);
-
- Scoped<CallContext> ctx(scope, newCallContext(function, callData));
- if (f)
- ctx->d()->function = f->d();
- scope.engine->pushContext(ctx);
-
- scope.result = Q_V4_PROFILE(scope.engine, function);
-
- if (function->hasQmlDependencies)
- QQmlPropertyCapture::registerQmlDependencies(function->compiledFunction, scope);
+ return !engine()->currentStackFrame->v4Function->isStrict();
}
-// Do a simple, fast call with this execution context as the outer scope
-void QV4::ExecutionContext::simpleCall(Scope &scope, CallData *callData, Function *function)
-{
- Q_ASSERT(function->canUseSimpleFunction());
-
- ExecutionContextSaver ctxSaver(scope);
-
- CallContext::Data *ctx = scope.engine->memoryManager->allocSimpleCallContext();
-
- ctx->strictMode = function->isStrict();
- ctx->callData = callData;
- ctx->v4Function = function;
- ctx->compilationUnit = function->compilationUnit;
- ctx->lookups = function->compilationUnit->runtimeLookups;
- ctx->constantTable = function->compilationUnit->constants;
- ctx->outer = this->d();
- ctx->locals = scope.alloc(function->compiledFunction->nLocals);
- for (int i = callData->argc; i < (int)function->nFormals; ++i)
- callData->args[i] = Encode::undefined();
-
- scope.engine->pushContext(ctx);
- Q_ASSERT(scope.engine->current == ctx);
-
- scope.result = Q_V4_PROFILE(scope.engine, function);
-
- if (function->hasQmlDependencies)
- QQmlPropertyCapture::registerQmlDependencies(function->compiledFunction, scope);
- scope.engine->memoryManager->freeSimpleCallContext();
-}
-
-void ExecutionContext::setProperty(String *name, const Value &value)
+ExecutionContext::Error ExecutionContext::setProperty(String *name, const Value &value)
{
name->makeIdentifier();
Identifier *id = name->identifier();
- Scope scope(this);
- ScopedContext ctx(scope, this);
- ScopedObject activation(scope);
+ QV4::ExecutionEngine *v4 = engine();
+ Heap::ExecutionContext *ctx = d();
- for (; ctx; ctx = ctx->d()->outer) {
- activation = (Object *)0;
- switch (ctx->d()->type) {
+ for (; ctx; ctx = ctx->outer) {
+ switch (ctx->type) {
case Heap::ExecutionContext::Type_CatchContext: {
- Heap::CatchContext *c = static_cast<Heap::CatchContext *>(ctx->d());
+ Heap::CatchContext *c = static_cast<Heap::CatchContext *>(ctx);
if (c->exceptionVarName->isEqualTo(name->d())) {
- c->exceptionValue = value;
- return;
+ c->exceptionValue.set(v4, value);
+ return NoError;
}
break;
}
case Heap::ExecutionContext::Type_WithContext: {
- ScopedObject w(scope, static_cast<Heap::WithContext *>(ctx->d())->withObject);
+ Scope scope(v4);
+ ScopedObject w(scope, ctx->activation);
if (w->hasProperty(name)) {
- w->put(name, value);
- return;
+ if (!w->put(name, value))
+ return TypeError;
+ return NoError;
}
break;
}
- case Heap::ExecutionContext::Type_GlobalContext: {
- activation = static_cast<Heap::GlobalContext *>(ctx->d())->global;
- break;
+ case Heap::ExecutionContext::Type_CallContext: {
+ Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx);
+ uint index = c->internalClass->find(id);
+ if (index < UINT_MAX) {
+ static_cast<Heap::CallContext *>(c)->locals.set(v4, index, value);
+ return NoError;
+ }
}
- case Heap::ExecutionContext::Type_CallContext:
- case Heap::ExecutionContext::Type_SimpleCallContext: {
- Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx->d());
- if (c->v4Function) {
- uint index = c->v4Function->internalClass->find(id);
- if (index < UINT_MAX) {
- if (index < c->v4Function->nFormals) {
- c->callData->args[c->v4Function->nFormals - index - 1] = value;
- } else {
- index -= c->v4Function->nFormals;
- c->locals[index] = value;
- }
- return;
+ Q_FALLTHROUGH();
+ case Heap::ExecutionContext::Type_GlobalContext:
+ if (ctx->activation) {
+ uint member = ctx->activation->internalClass->find(id);
+ if (member < UINT_MAX) {
+ Scope scope(v4);
+ ScopedObject a(scope, ctx->activation);
+ if (!a->putValue(member, value))
+ return TypeError;
+ return NoError;
}
}
- activation = c->activation;
break;
- }
case Heap::ExecutionContext::Type_QmlContext: {
- activation = static_cast<Heap::QmlContext *>(ctx->d())->qml;
- activation->put(name, value);
- return;
+ Scope scope(v4);
+ ScopedObject activation(scope, ctx->activation);
+ if (!activation->put(name, value))
+ return TypeError;
+ return NoError;
}
}
- if (activation) {
- uint member = activation->internalClass()->find(id);
- if (member < UINT_MAX) {
- activation->putValue(member, value);
- return;
- }
- }
}
- if (d()->strictMode || name->equals(engine()->id_this())) {
- ScopedValue n(scope, name->asReturnedValue());
- engine()->throwReferenceError(n);
- return;
- }
- engine()->globalObject->put(name, value);
+ return RangeError;
}
ReturnedValue ExecutionContext::getProperty(String *name)
{
- Scope scope(this);
- ScopedValue v(scope);
name->makeIdentifier();
- if (name->equals(engine()->id_this()))
- return thisObject().asReturnedValue();
-
- bool hasWith = false;
- bool hasCatchScope = false;
- ScopedContext ctx(scope, this);
- for (; ctx; ctx = ctx->d()->outer) {
- switch (ctx->d()->type) {
+ Heap::ExecutionContext *ctx = d();
+ for (; ctx; ctx = ctx->outer) {
+ switch (ctx->type) {
case Heap::ExecutionContext::Type_CatchContext: {
- hasCatchScope = true;
- Heap::CatchContext *c = static_cast<Heap::CatchContext *>(ctx->d());
+ Heap::CatchContext *c = static_cast<Heap::CatchContext *>(ctx);
if (c->exceptionVarName->isEqualTo(name->d()))
return c->exceptionValue.asReturnedValue();
break;
}
- case Heap::ExecutionContext::Type_WithContext: {
- ScopedObject w(scope, static_cast<Heap::WithContext *>(ctx->d())->withObject);
- hasWith = true;
- bool hasProperty = false;
- v = w->get(name, &hasProperty);
- if (hasProperty) {
- return v->asReturnedValue();
- }
- break;
- }
- case Heap::ExecutionContext::Type_GlobalContext: {
- ScopedObject global(scope, static_cast<Heap::GlobalContext *>(ctx->d())->global);
- bool hasProperty = false;
- v = global->get(name, &hasProperty);
- if (hasProperty)
- return v->asReturnedValue();
- break;
+ case Heap::ExecutionContext::Type_CallContext: {
+ Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx);
+ Identifier *id = name->identifier();
+
+ uint index = c->internalClass->find(id);
+ if (index < UINT_MAX)
+ return c->locals[index].asReturnedValue();
+ Q_FALLTHROUGH();
}
- case Heap::ExecutionContext::Type_CallContext:
- case Heap::ExecutionContext::Type_SimpleCallContext: {
- Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx->d());
- if (c->v4Function && (c->v4Function->needsActivation() || hasWith || hasCatchScope)) {
- name->makeIdentifier();
- Identifier *id = name->identifier();
-
- uint index = c->v4Function->internalClass->find(id);
- if (index < UINT_MAX) {
- if (index < c->v4Function->nFormals)
- return c->callData->args[c->v4Function->nFormals - index - 1].asReturnedValue();
- return c->locals[index - c->v4Function->nFormals].asReturnedValue();
- }
- }
- ScopedObject activation(scope, c->activation);
- if (activation) {
+ case Heap::ExecutionContext::Type_WithContext:
+ case Heap::ExecutionContext::Type_GlobalContext:
+ case Heap::ExecutionContext::Type_QmlContext: {
+ if (ctx->activation) {
+ Scope scope(this);
+ ScopedObject activation(scope, ctx->activation);
bool hasProperty = false;
- v = activation->get(name, &hasProperty);
+ ReturnedValue v = activation->get(name, &hasProperty);
if (hasProperty)
- return v->asReturnedValue();
+ return v;
}
- if (c->function && c->v4Function->isNamedExpression()
- && name->equals(ScopedString(scope, c->v4Function->name())))
- return c->function->asReturnedValue();
- break;
- }
- case Heap::ExecutionContext::Type_QmlContext: {
- ScopedObject qml(scope, static_cast<Heap::QmlContext *>(ctx->d())->qml);
- bool hasProperty = false;
- v = qml->get(name, &hasProperty);
- if (hasProperty)
- return v->asReturnedValue();
break;
}
}
}
- ScopedValue n(scope, name);
- return engine()->throwReferenceError(n);
+ return engine()->throwReferenceError(*name);
}
ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Value *base)
{
- Scope scope(this);
- ScopedValue v(scope);
base->setM(0);
name->makeIdentifier();
- if (name->equals(engine()->id_this()))
- return thisObject().asReturnedValue();
-
- bool hasWith = false;
- bool hasCatchScope = false;
- ScopedContext ctx(scope, this);
- for (; ctx; ctx = ctx->d()->outer) {
- switch (ctx->d()->type) {
+ Heap::ExecutionContext *ctx = d();
+ for (; ctx; ctx = ctx->outer) {
+ switch (ctx->type) {
case Heap::ExecutionContext::Type_CatchContext: {
- hasCatchScope = true;
- Heap::CatchContext *c = static_cast<Heap::CatchContext *>(ctx->d());
+ Heap::CatchContext *c = static_cast<Heap::CatchContext *>(ctx);
if (c->exceptionVarName->isEqualTo(name->d()))
return c->exceptionValue.asReturnedValue();
break;
}
- case Heap::ExecutionContext::Type_WithContext: {
- ScopedObject w(scope, static_cast<Heap::WithContext *>(ctx->d())->withObject);
- hasWith = true;
- bool hasProperty = false;
- v = w->get(name, &hasProperty);
- if (hasProperty) {
- base->setM(w->d());
- return v->asReturnedValue();
- }
- break;
+ case Heap::ExecutionContext::Type_CallContext: {
+ Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx);
+ name->makeIdentifier();
+ Identifier *id = name->identifier();
+
+ uint index = c->internalClass->find(id);
+ if (index < UINT_MAX)
+ return c->locals[index].asReturnedValue();
+ Q_FALLTHROUGH();
}
case Heap::ExecutionContext::Type_GlobalContext: {
- ScopedObject global(scope, static_cast<Heap::GlobalContext *>(ctx->d())->global);
- bool hasProperty = false;
- v = global->get(name, &hasProperty);
- if (hasProperty)
- return v->asReturnedValue();
- break;
- }
- case Heap::ExecutionContext::Type_CallContext:
- case Heap::ExecutionContext::Type_SimpleCallContext: {
- Heap::CallContext *c = static_cast<Heap::CallContext *>(ctx->d());
- if (c->v4Function && (c->v4Function->needsActivation() || hasWith || hasCatchScope)) {
- name->makeIdentifier();
- Identifier *id = name->identifier();
-
- uint index = c->v4Function->internalClass->find(id);
- if (index < UINT_MAX) {
- if (index < c->v4Function->nFormals)
- return c->callData->args[c->v4Function->nFormals - index - 1].asReturnedValue();
- return c->locals[index - c->v4Function->nFormals].asReturnedValue();
- }
- }
- ScopedObject activation(scope, c->activation);
- if (activation) {
+ if (ctx->activation) {
+ Scope scope(this);
+ ScopedObject activation(scope, ctx->activation);
bool hasProperty = false;
- v = activation->get(name, &hasProperty);
+ ReturnedValue v = activation->get(name, &hasProperty);
if (hasProperty)
- return v->asReturnedValue();
+ return v;
}
- if (c->function && c->v4Function->isNamedExpression()
- && name->equals(ScopedString(scope, c->v4Function->name())))
- return c->function->asReturnedValue();
break;
}
+ case Heap::ExecutionContext::Type_WithContext:
case Heap::ExecutionContext::Type_QmlContext: {
- ScopedObject qml(scope, static_cast<Heap::QmlContext *>(ctx->d())->qml);
+ Scope scope(this);
+ ScopedObject o(scope, ctx->activation);
bool hasProperty = false;
- v = qml->get(name, &hasProperty);
+ ReturnedValue v = o->get(name, &hasProperty);
if (hasProperty) {
- base->setM(qml->d());
- return v->asReturnedValue();
+ base->setM(o->d());
+ return v;
}
break;
}
}
}
- ScopedValue n(scope, name);
- return engine()->throwReferenceError(n);
+ return engine()->throwReferenceError(*name);
}
-Function *ExecutionContext::getFunction() const
+void Heap::CallContext::setArg(uint index, Value v)
{
- Scope scope(engine());
- ScopedContext it(scope, this->d());
- for (; it; it = it->d()->outer) {
- if (const CallContext *callCtx = it->asCallContext())
- return callCtx->d()->v4Function;
- else if (it->asCatchContext() || it->asWithContext())
- continue; // look in the parent context for a FunctionObject
- else
- break;
- }
-
- return 0;
+ locals.set(internalClass->engine, locals.size + index, v);
}
diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h
index 0b63922a4b..dfac5534be 100644
--- a/src/qml/jsruntime/qv4context_p.h
+++ b/src/qml/jsruntime/qv4context_p.h
@@ -69,74 +69,65 @@ struct Function;
struct Identifier;
struct CallContext;
struct CatchContext;
-struct WithContext;
struct QmlContext;
-struct QmlContextWrapper;
+struct QQmlContextWrapper;
-// Attention: Make sure that this structure is the same size on 32-bit and 64-bit
-// architecture or you'll have to change the JIT code.
struct CallData
{
- // below is to be compatible with Value. Initialize tag to 0
-#if Q_BYTE_ORDER != Q_LITTLE_ENDIAN
- uint tag;
-#endif
- int argc;
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- uint tag;
-#endif
+ enum Offsets {
+ Function = 0,
+ Context = 1,
+ Accumulator = 2,
+ This = 3,
+ Argc = 4
+ };
+
+ Value function;
+ Value context;
+ Value accumulator;
+ Value thisObject;
+ Value _argc;
+
+ int argc() const {
+ Q_ASSERT(_argc.isInteger());
+ return _argc.int_32();
+ }
+
+ void setArgc(int argc) {
+ Q_ASSERT(argc >= 0);
+ _argc.setInt_32(argc);
+ }
+
inline ReturnedValue argument(int i) const {
- return i < argc ? args[i].asReturnedValue() : Primitive::undefinedValue().asReturnedValue();
+ return i < argc() ? args[i].asReturnedValue() : Primitive::undefinedValue().asReturnedValue();
}
- Value thisObject;
Value args[1];
+
+ static Q_DECL_CONSTEXPR int HeaderSize() { return offsetof(CallData, args) / sizeof(QV4::Value); }
};
Q_STATIC_ASSERT(std::is_standard_layout<CallData>::value);
-Q_STATIC_ASSERT(offsetof(CallData, thisObject) == 8);
-Q_STATIC_ASSERT(offsetof(CallData, args) == 16);
+Q_STATIC_ASSERT(offsetof(CallData, thisObject) == CallData::This*sizeof(Value));
+Q_STATIC_ASSERT(offsetof(CallData, args) == 5*sizeof(Value));
namespace Heap {
struct QmlContext;
-// ### Temporary arrangment until this code hits the dev branch and
-// can use the Members macro
-struct ExecutionContextData {
- CallData *callData;
- ExecutionContext *outer;
- Lookup *lookups;
- const QV4::Value *constantTable;
- CompiledData::CompilationUnitBase *compilationUnit;
- // as member of non-pointer size this has to come last to preserve the ability to
- // translate offsetof of it between 64-bit and 32-bit.
- int lineNumber;
-#if QT_POINTER_SIZE == 8
- uint padding_;
-#endif
-};
-
-Q_STATIC_ASSERT(std::is_standard_layout<ExecutionContextData>::value);
-Q_STATIC_ASSERT(offsetof(ExecutionContextData, callData) == 0);
-Q_STATIC_ASSERT(offsetof(ExecutionContextData, outer) == offsetof(ExecutionContextData, callData) + QT_POINTER_SIZE);
-Q_STATIC_ASSERT(offsetof(ExecutionContextData, lookups) == offsetof(ExecutionContextData, outer) + QT_POINTER_SIZE);
-Q_STATIC_ASSERT(offsetof(ExecutionContextData, constantTable) == offsetof(ExecutionContextData, lookups) + QT_POINTER_SIZE);
-Q_STATIC_ASSERT(offsetof(ExecutionContextData, compilationUnit) == offsetof(ExecutionContextData, constantTable) + QT_POINTER_SIZE);
-Q_STATIC_ASSERT(offsetof(ExecutionContextData, lineNumber) == offsetof(ExecutionContextData, compilationUnit) + QT_POINTER_SIZE);
+#define ExecutionContextMembers(class, Member) \
+ Member(class, Pointer, ExecutionContext *, outer) \
+ Member(class, Pointer, Object *, activation)
-struct ExecutionContextSizeStruct : public Base, public ExecutionContextData {};
-
-struct ExecutionContext : Base, public ExecutionContextData {
- static Q_CONSTEXPR size_t baseOffset = sizeof(ExecutionContextSizeStruct) - sizeof(ExecutionContextData);
+DECLARE_HEAP_OBJECT(ExecutionContext, Base) {
+ DECLARE_MARKOBJECTS(ExecutionContext);
enum ContextType {
Type_GlobalContext = 0x1,
Type_CatchContext = 0x2,
Type_WithContext = 0x3,
Type_QmlContext = 0x4,
- Type_SimpleCallContext = 0x5,
- Type_CallContext = 0x6
+ Type_CallContext = 0x5
};
void init(ContextType t)
@@ -144,74 +135,62 @@ struct ExecutionContext : Base, public ExecutionContextData {
Base::init();
type = t;
- lineNumber = -1;
}
- quint8 type;
- bool strictMode : 8;
+ quint32 type : 8;
+ quint32 nArgs : 24;
#if QT_POINTER_SIZE == 8
- quint8 padding_[6];
-#else
- quint8 padding_[2];
+ quint8 padding_[4];
#endif
};
-V4_ASSERT_IS_TRIVIAL(ExecutionContext)
+Q_STATIC_ASSERT(std::is_trivial< ExecutionContext >::value);
Q_STATIC_ASSERT(sizeof(ExecutionContext) == sizeof(Base) + sizeof(ExecutionContextData) + QT_POINTER_SIZE);
-struct CallContextData {
- Value *locals;
-};
-
-Q_STATIC_ASSERT(std::is_standard_layout<CallContextData>::value);
-Q_STATIC_ASSERT(offsetof(CallContextData, locals) == 0);
+Q_STATIC_ASSERT(std::is_standard_layout<ExecutionContextData>::value);
+Q_STATIC_ASSERT(offsetof(ExecutionContextData, outer) == 0);
+Q_STATIC_ASSERT(offsetof(ExecutionContextData, activation) == offsetof(ExecutionContextData, outer) + QT_POINTER_SIZE);
-struct CallContextSizeStruct : public ExecutionContext, public CallContextData {};
+#define CallContextMembers(class, Member) \
+ Member(class, Pointer, FunctionObject *, function) \
+ Member(class, ValueArray, ValueArray, locals)
-struct CallContext : ExecutionContext, public CallContextData {
- static Q_CONSTEXPR size_t baseOffset = sizeof(CallContextSizeStruct) - sizeof(CallContextData);
+DECLARE_HEAP_OBJECT(CallContext, ExecutionContext) {
+ DECLARE_MARKOBJECTS(CallContext);
- void init(ContextType t = Type_SimpleCallContext)
+ void init()
{
- ExecutionContext::init(t);
+ ExecutionContext::init(Type_CallContext);
}
- inline unsigned int formalParameterCount() const;
-
- Pointer<FunctionObject> function;
- QV4::Function *v4Function;
- Pointer<Object> activation;
-};
-V4_ASSERT_IS_TRIVIAL(CallContext)
-
-struct GlobalContext : ExecutionContext {
- void init(ExecutionEngine *engine);
- Pointer<Object> global;
+ int argc() const {
+ return static_cast<int>(nArgs);
+ }
+ const Value *args() const {
+ return locals.data() + locals.size;
+ }
+ void setArg(uint index, Value v);
};
-V4_ASSERT_IS_TRIVIAL(GlobalContext)
+Q_STATIC_ASSERT(std::is_trivial< CallContext >::value);
+Q_STATIC_ASSERT(std::is_standard_layout<CallContextData>::value);
+Q_STATIC_ASSERT(offsetof(CallContextData, function) == 0);
+//### The following size check fails on Win8. With the ValueArray at the end of the
+// CallContextMembers, it doesn't look very useful.
+//#if defined(Q_PROCESSOR_ARM_32) && !defined(Q_OS_IOS)
+//Q_STATIC_ASSERT(sizeof(CallContext) == sizeof(ExecutionContext) + sizeof(CallContextData) + QT_POINTER_SIZE);
+//#else
+//Q_STATIC_ASSERT(sizeof(CallContext) == sizeof(ExecutionContext) + sizeof(CallContextData));
+//#endif
+
+#define CatchContextMembers(class, Member) \
+ Member(class, Pointer, String *, exceptionVarName) \
+ Member(class, HeapValue, HeapValue, exceptionValue)
+
+DECLARE_HEAP_OBJECT(CatchContext, ExecutionContext) {
+ DECLARE_MARKOBJECTS(CatchContext);
-struct CatchContext : ExecutionContext {
void init(ExecutionContext *outerContext, String *exceptionVarName, const Value &exceptionValue);
- Pointer<String> exceptionVarName;
- Value exceptionValue;
-};
-V4_ASSERT_IS_TRIVIAL(CatchContext)
-
-struct WithContext : ExecutionContext {
- void init(ExecutionContext *outerContext, Object *with)
- {
- Heap::ExecutionContext::init(Heap::ExecutionContext::Type_WithContext);
- outer = outerContext;
- callData = outer->callData;
- lookups = outer->lookups;
- constantTable = outer->constantTable;
- compilationUnit = outer->compilationUnit;
-
- withObject = with;
- }
-
- Pointer<Object> withObject;
};
-V4_ASSERT_IS_TRIVIAL(WithContext)
+Q_STATIC_ASSERT(std::is_trivial< CatchContext >::value);
}
@@ -225,41 +204,26 @@ struct Q_QML_EXPORT ExecutionContext : public Managed
Q_MANAGED_TYPE(ExecutionContext)
V4_INTERNALCLASS(ExecutionContext)
- Heap::CallContext *newCallContext(Function *f, CallData *callData);
- Heap::WithContext *newWithContext(Heap::Object *with);
+ static Heap::CallContext *newCallContext(QV4::CppStackFrame *frame);
+ Heap::ExecutionContext *newWithContext(Heap::Object *with);
Heap::CatchContext *newCatchContext(Heap::String *exceptionVarName, ReturnedValue exceptionValue);
void createMutableBinding(String *name, bool deletable);
- void setProperty(String *name, const Value &value);
+ enum Error {
+ NoError,
+ TypeError,
+ RangeError
+ };
+
+ Error setProperty(String *name, const Value &value);
+
ReturnedValue getProperty(String *name);
ReturnedValue getPropertyAndBase(String *name, Value *base);
bool deleteProperty(String *name);
inline CallContext *asCallContext();
inline const CallContext *asCallContext() const;
- inline const CatchContext *asCatchContext() const;
- inline const WithContext *asWithContext() const;
-
- Function *getFunction() const;
-
- static void markObjects(Heap::Base *m, ExecutionEngine *e);
-
- Value &thisObject() const {
- return d()->callData->thisObject;
- }
- int argc() const {
- return d()->callData->argc;
- }
- const Value *args() const {
- return d()->callData->args;
- }
- ReturnedValue argument(int i) const {
- return d()->callData->argument(i);
- }
-
- void call(Scope &scope, CallData *callData, QV4::Function *function, const QV4::FunctionObject *f = 0);
- void simpleCall(Scope &scope, CallData *callData, QV4::Function *function);
};
struct Q_QML_EXPORT CallContext : public ExecutionContext
@@ -267,25 +231,12 @@ struct Q_QML_EXPORT CallContext : public ExecutionContext
V4_MANAGED(CallContext, ExecutionContext)
V4_INTERNALCLASS(CallContext)
- // formals are in reverse order
- Identifier * const *formals() const;
- unsigned int formalCount() const;
- Identifier * const *variables() const;
- unsigned int variableCount() const;
-
- inline ReturnedValue argument(int i) const;
- bool needsOwnArguments() const;
-
-};
-
-inline ReturnedValue CallContext::argument(int i) const {
- return i < argc() ? args()[i].asReturnedValue() : Primitive::undefinedValue().asReturnedValue();
-}
-
-struct GlobalContext : public ExecutionContext
-{
- V4_MANAGED(GlobalContext, ExecutionContext)
-
+ int argc() const {
+ return d()->argc();
+ }
+ const Value *args() const {
+ return d()->args();
+ }
};
struct CatchContext : public ExecutionContext
@@ -293,29 +244,14 @@ struct CatchContext : public ExecutionContext
V4_MANAGED(CatchContext, ExecutionContext)
};
-struct WithContext : public ExecutionContext
-{
- V4_MANAGED(WithContext, ExecutionContext)
-};
-
inline CallContext *ExecutionContext::asCallContext()
{
- return d()->type >= Heap::ExecutionContext::Type_SimpleCallContext ? static_cast<CallContext *>(this) : 0;
+ return d()->type == Heap::ExecutionContext::Type_CallContext ? static_cast<CallContext *>(this) : 0;
}
inline const CallContext *ExecutionContext::asCallContext() const
{
- return d()->type >= Heap::ExecutionContext::Type_SimpleCallContext ? static_cast<const CallContext *>(this) : 0;
-}
-
-inline const CatchContext *ExecutionContext::asCatchContext() const
-{
- return d()->type == Heap::ExecutionContext::Type_CatchContext ? static_cast<const CatchContext *>(this) : 0;
-}
-
-inline const WithContext *ExecutionContext::asWithContext() const
-{
- return d()->type == Heap::ExecutionContext::Type_WithContext ? static_cast<const WithContext *>(this) : 0;
+ return d()->type == Heap::ExecutionContext::Type_CallContext ? static_cast<const CallContext *>(this) : 0;
}
} // namespace QV4
diff --git a/src/qml/jsruntime/qv4dataview.cpp b/src/qml/jsruntime/qv4dataview.cpp
index a810b38f24..397ef1cfec 100644
--- a/src/qml/jsruntime/qv4dataview.cpp
+++ b/src/qml/jsruntime/qv4dataview.cpp
@@ -54,41 +54,31 @@ void Heap::DataViewCtor::init(QV4::ExecutionContext *scope)
Heap::FunctionObject::init(scope, QStringLiteral("DataView"));
}
-void DataViewCtor::construct(const Managed *, Scope &scope, CallData *callData)
+ReturnedValue DataViewCtor::callAsConstructor(const FunctionObject *f, const Value *argv, int argc)
{
- Scoped<ArrayBuffer> buffer(scope, callData->argument(0));
- if (!buffer) {
- scope.result = scope.engine->throwTypeError();
- return;
- }
+ Scope scope(f->engine());
+ Scoped<ArrayBuffer> buffer(scope, argc ? argv[0] : Primitive::undefinedValue());
+ if (!buffer)
+ return scope.engine->throwTypeError();
- double bo = callData->argc > 1 ? callData->args[1].toNumber() : 0;
+ double bo = argc > 1 ? argv[1].toNumber() : 0;
uint byteOffset = (uint)bo;
uint bufferLength = buffer->d()->data->size;
- double bl = callData->argc < 3 || callData->args[2].isUndefined() ? (bufferLength - bo) : callData->args[2].toNumber();
+ double bl = argc < 3 || argv[2].isUndefined() ? (bufferLength - bo) : argv[2].toNumber();
uint byteLength = (uint)bl;
- if (bo != byteOffset || bl != byteLength || byteOffset + byteLength > bufferLength) {
- scope.result = scope.engine->throwRangeError(QStringLiteral("DataView: constructor arguments out of range"));
- return;
- }
+ if (bo != byteOffset || bl != byteLength || byteOffset + byteLength > bufferLength)
+ return scope.engine->throwRangeError(QStringLiteral("DataView: constructor arguments out of range"));
Scoped<DataView> a(scope, scope.engine->memoryManager->allocObject<DataView>());
- a->d()->buffer = buffer->d();
+ a->d()->buffer.set(scope.engine, buffer->d());
a->d()->byteLength = byteLength;
a->d()->byteOffset = byteOffset;
- scope.result = a.asReturnedValue();
-}
-
-void DataViewCtor::call(const Managed *that, Scope &scope, CallData *callData)
-{
- construct(that, scope, callData);
+ return a.asReturnedValue();
}
-
-void DataView::markObjects(Heap::Base *that, ExecutionEngine *e)
+ReturnedValue DataViewCtor::call(const FunctionObject *f, const Value *, const Value *argv, int argc)
{
- DataView::Data *v = static_cast<DataView::Data *>(that);
- v->buffer->mark(e);
+ return callAsConstructor(f, argv, argc);
}
void DataViewPrototype::init(ExecutionEngine *engine, Object *ctor)
@@ -129,84 +119,84 @@ void DataViewPrototype::init(ExecutionEngine *engine, Object *ctor)
defineDefaultProperty(QStringLiteral("setUInt32"), method_set<unsigned int>, 0);
}
-void DataViewPrototype::method_get_buffer(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DataViewPrototype::method_get_buffer(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<DataView> v(scope, callData->thisObject);
+ const DataView *v = thisObject->as<DataView>();
if (!v)
- THROW_TYPE_ERROR();
+ return b->engine()->throwTypeError();
- scope.result = v->d()->buffer;
+ return v->d()->buffer->asReturnedValue();
}
-void DataViewPrototype::method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DataViewPrototype::method_get_byteLength(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<DataView> v(scope, callData->thisObject);
+ const DataView *v = thisObject->as<DataView>();
if (!v)
- THROW_TYPE_ERROR();
+ return b->engine()->throwTypeError();
- scope.result = Encode(v->d()->byteLength);
+ return Encode(v->d()->byteLength);
}
-void DataViewPrototype::method_get_byteOffset(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DataViewPrototype::method_get_byteOffset(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<DataView> v(scope, callData->thisObject);
+ const DataView *v = thisObject->as<DataView>();
if (!v)
- THROW_TYPE_ERROR();
+ return b->engine()->throwTypeError();
- scope.result = Encode(v->d()->byteOffset);
+ return Encode(v->d()->byteOffset);
}
template <typename T>
-void DataViewPrototype::method_getChar(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DataViewPrototype::method_getChar(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- Scoped<DataView> v(scope, callData->thisObject);
- if (!v || callData->argc < 1)
- THROW_TYPE_ERROR();
- double l = callData->args[0].toNumber();
+ const DataView *v = thisObject->as<DataView>();
+ if (!v || argc < 1)
+ return b->engine()->throwTypeError();
+ double l = argv[0].toNumber();
uint idx = (uint)l;
if (l != idx || idx + sizeof(T) > v->d()->byteLength)
- THROW_TYPE_ERROR();
+ return b->engine()->throwTypeError();
idx += v->d()->byteOffset;
T t = T(v->d()->buffer->data->data()[idx]);
- scope.result = Encode((int)t);
+ return Encode((int)t);
}
template <typename T>
-void DataViewPrototype::method_get(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DataViewPrototype::method_get(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- Scoped<DataView> v(scope, callData->thisObject);
- if (!v || callData->argc < 1)
- THROW_TYPE_ERROR();
- double l = callData->args[0].toNumber();
+ const DataView *v = thisObject->as<DataView>();
+ if (!v || argc < 1)
+ return b->engine()->throwTypeError();
+ double l = argv[0].toNumber();
uint idx = (uint)l;
if (l != idx || idx + sizeof(T) > v->d()->byteLength)
- THROW_TYPE_ERROR();
+ return b->engine()->throwTypeError();
idx += v->d()->byteOffset;
- bool littleEndian = callData->argc < 2 ? false : callData->args[1].toBoolean();
+ bool littleEndian = argc < 2 ? false : argv[1].toBoolean();
T t = littleEndian
? qFromLittleEndian<T>((uchar *)v->d()->buffer->data->data() + idx)
: qFromBigEndian<T>((uchar *)v->d()->buffer->data->data() + idx);
- scope.result = Encode(t);
+ return Encode(t);
}
template <typename T>
-void DataViewPrototype::method_getFloat(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DataViewPrototype::method_getFloat(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- Scoped<DataView> v(scope, callData->thisObject);
- if (!v || callData->argc < 1)
- THROW_TYPE_ERROR();
- double l = callData->args[0].toNumber();
+ const DataView *v = thisObject->as<DataView>();
+ if (!v || argc < 1)
+ return b->engine()->throwTypeError();
+ double l = argv[0].toNumber();
uint idx = (uint)l;
if (l != idx || idx + sizeof(T) > v->d()->byteLength)
- THROW_TYPE_ERROR();
+ return b->engine()->throwTypeError();
idx += v->d()->byteOffset;
- bool littleEndian = callData->argc < 2 ? false : callData->args[1].toBoolean();
+ bool littleEndian = argc < 2 ? false : argv[1].toBoolean();
if (sizeof(T) == 4) {
// float
@@ -217,7 +207,7 @@ void DataViewPrototype::method_getFloat(const BuiltinFunction *, Scope &scope, C
u.i = littleEndian
? qFromLittleEndian<uint>((uchar *)v->d()->buffer->data->data() + idx)
: qFromBigEndian<uint>((uchar *)v->d()->buffer->data->data() + idx);
- scope.result = Encode(u.f);
+ return Encode(u.f);
} else {
Q_ASSERT(sizeof(T) == 8);
union {
@@ -227,43 +217,43 @@ void DataViewPrototype::method_getFloat(const BuiltinFunction *, Scope &scope, C
u.i = littleEndian
? qFromLittleEndian<quint64>((uchar *)v->d()->buffer->data->data() + idx)
: qFromBigEndian<quint64>((uchar *)v->d()->buffer->data->data() + idx);
- scope.result = Encode(u.d);
+ return Encode(u.d);
}
}
template <typename T>
-void DataViewPrototype::method_setChar(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DataViewPrototype::method_setChar(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- Scoped<DataView> v(scope, callData->thisObject);
- if (!v || callData->argc < 1)
- THROW_TYPE_ERROR();
- double l = callData->args[0].toNumber();
+ const DataView *v = thisObject->as<DataView>();
+ if (!v || argc < 1)
+ return b->engine()->throwTypeError();
+ double l = argv[0].toNumber();
uint idx = (uint)l;
if (l != idx || idx + sizeof(T) > v->d()->byteLength)
- THROW_TYPE_ERROR();
+ return b->engine()->throwTypeError();
idx += v->d()->byteOffset;
- int val = callData->argc >= 2 ? callData->args[1].toInt32() : 0;
+ int val = argc >= 2 ? argv[1].toInt32() : 0;
v->d()->buffer->data->data()[idx] = (char)val;
RETURN_UNDEFINED();
}
template <typename T>
-void DataViewPrototype::method_set(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DataViewPrototype::method_set(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- Scoped<DataView> v(scope, callData->thisObject);
- if (!v || callData->argc < 1)
- THROW_TYPE_ERROR();
- double l = callData->args[0].toNumber();
+ const DataView *v = thisObject->as<DataView>();
+ if (!v || argc < 1)
+ return b->engine()->throwTypeError();
+ double l = argv[0].toNumber();
uint idx = (uint)l;
if (l != idx || idx + sizeof(T) > v->d()->byteLength)
- THROW_TYPE_ERROR();
+ return b->engine()->throwTypeError();
idx += v->d()->byteOffset;
- int val = callData->argc >= 2 ? callData->args[1].toInt32() : 0;
+ int val = argc >= 2 ? argv[1].toInt32() : 0;
- bool littleEndian = callData->argc < 3 ? false : callData->args[2].toBoolean();
+ bool littleEndian = argc < 3 ? false : argv[2].toBoolean();
if (littleEndian)
qToLittleEndian<T>(val, (uchar *)v->d()->buffer->data->data() + idx);
@@ -274,19 +264,19 @@ void DataViewPrototype::method_set(const BuiltinFunction *, Scope &scope, CallDa
}
template <typename T>
-void DataViewPrototype::method_setFloat(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DataViewPrototype::method_setFloat(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- Scoped<DataView> v(scope, callData->thisObject);
- if (!v || callData->argc < 1)
- THROW_TYPE_ERROR();
- double l = callData->args[0].toNumber();
+ const DataView *v = thisObject->as<DataView>();
+ if (!v || argc < 1)
+ return b->engine()->throwTypeError();
+ double l = argv[0].toNumber();
uint idx = (uint)l;
if (l != idx || idx + sizeof(T) > v->d()->byteLength)
- THROW_TYPE_ERROR();
+ return b->engine()->throwTypeError();
idx += v->d()->byteOffset;
- double val = callData->argc >= 2 ? callData->args[1].toNumber() : qt_qnan();
- bool littleEndian = callData->argc < 3 ? false : callData->args[2].toBoolean();
+ double val = argc >= 2 ? argv[1].toNumber() : qt_qnan();
+ bool littleEndian = argc < 3 ? false : argv[2].toBoolean();
if (sizeof(T) == 4) {
// float
diff --git a/src/qml/jsruntime/qv4dataview_p.h b/src/qml/jsruntime/qv4dataview_p.h
index 11cc0a6bd9..1e07d85118 100644
--- a/src/qml/jsruntime/qv4dataview_p.h
+++ b/src/qml/jsruntime/qv4dataview_p.h
@@ -63,11 +63,14 @@ struct DataViewCtor : FunctionObject {
void init(QV4::ExecutionContext *scope);
};
-struct DataView : Object {
+#define DataViewMembers(class, Member) \
+ Member(class, Pointer, ArrayBuffer *, buffer) \
+ Member(class, NoMark, uint, byteLength) \
+ Member(class, NoMark, uint, byteOffset)
+
+DECLARE_HEAP_OBJECT(DataView, Object) {
+ DECLARE_MARKOBJECTS(DataView);
void init() { Object::init(); }
- Pointer<ArrayBuffer> buffer;
- uint byteLength;
- uint byteOffset;
};
}
@@ -76,37 +79,35 @@ struct DataViewCtor: FunctionObject
{
V4_OBJECT2(DataViewCtor, FunctionObject)
- static void construct(const Managed *m, Scope &scope, CallData *callData);
- static void call(const Managed *that, Scope &scope, CallData *callData);
+ static ReturnedValue callAsConstructor(const FunctionObject *f, const Value *argv, int argc);
+ static ReturnedValue call(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
};
struct DataView : Object
{
V4_OBJECT2(DataView, Object)
V4_PROTOTYPE(dataViewPrototype)
-
- static void markObjects(Heap::Base *that, ExecutionEngine *e);
};
struct DataViewPrototype: Object
{
void init(ExecutionEngine *engine, Object *ctor);
- static void method_get_buffer(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_get_byteOffset(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_get_buffer(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_byteLength(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_byteOffset(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
template <typename T>
- static void method_getChar(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_getChar(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
template <typename T>
- static void method_get(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_get(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
template <typename T>
- static void method_getFloat(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_getFloat(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
template <typename T>
- static void method_setChar(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_setChar(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
template <typename T>
- static void method_set(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_set(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
template <typename T>
- static void method_setFloat(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_setFloat(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
};
diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp
index b90c335b1c..bc9b3013d1 100644
--- a/src/qml/jsruntime/qv4dateobject.cpp
+++ b/src/qml/jsruntime/qv4dateobject.cpp
@@ -43,6 +43,7 @@
#include "qv4scopedvalue_p.h"
#include "qv4runtime_p.h"
#include "qv4string_p.h"
+#include "qv4jscall_p.h"
#include <QtCore/QDebug>
#include <QtCore/QDateTime>
@@ -54,16 +55,29 @@
#include <wtf/MathExtras.h>
-#ifdef Q_OS_WIN
-# include <windows.h>
+#ifdef Q_OS_LINUX
+/*
+ See QTBUG-56899. Although we don't (yet) have a proper way to reset the
+ system zone, the code below, that uses QTimeZone::systemTimeZone(), works
+ adequately on Linux, when the TZ environment variable is changed.
+ */
+#define USE_QTZ_SYSTEM_ZONE
+#endif
+
+#ifdef USE_QTZ_SYSTEM_ZONE
+#include <QtCore/QTimeZone>
#else
-# ifndef Q_OS_VXWORKS
-# include <sys/time.h>
+# ifdef Q_OS_WIN
+# include <windows.h>
# else
-# include "qplatformdefs.h"
+# ifndef Q_OS_VXWORKS
+# include <sys/time.h>
+# else
+# include "qplatformdefs.h"
+# endif
+# include <unistd.h> // for _POSIX_THREAD_SAFE_FUNCTIONS
# endif
-# include <unistd.h> // for _POSIX_THREAD_SAFE_FUNCTIONS
-#endif
+#endif // USE_QTZ_SYSTEM_ZONE
using namespace QV4;
@@ -75,6 +89,7 @@ static const double msPerMinute = 60000.0;
static const double msPerHour = 3600000.0;
static const double msPerDay = 86400000.0;
+// The current *standard* time offset, regardless of DST:
static double LocalTZA = 0.0; // initialized at startup
static inline double TimeWithinDay(double t)
@@ -285,10 +300,35 @@ static inline double MakeDate(double day, double time)
return day * msPerDay + time;
}
+#ifdef USE_QTZ_SYSTEM_ZONE
+/*
+ ECMAScript specifies use of a fixed (current, standard) time-zone offset,
+ LocalTZA; and LocalTZA + DaylightSavingTA(t) is taken to be (see LocalTime and
+ UTC, following) local time's offset from UTC at time t. For simple zones,
+ DaylightSavingTA(t) is thus the DST offset applicable at date/time t; however,
+ if a zone has changed its standard offset, the only way to make LocalTime and
+ UTC (if implemented in accord with the spec) perform correct transformations
+ is to have DaylightSavingTA(t) correct for the zone's standard offset change
+ as well as its actual DST offset.
+
+ This means we have to treat any historical changes in the zone's standard
+ offset as DST perturbations, regardless of historical reality. (This shall
+ mean a whole day of DST offset for some zones, that have crossed the
+ international date line. This shall confuse client code.) The bug report
+ against the ECMAScript spec is https://github.com/tc39/ecma262/issues/725
+*/
+
+static inline double DaylightSavingTA(double t) // t is a UTC time
+{
+ return QTimeZone::systemTimeZone().offsetFromUtc(
+ QDateTime::fromMSecsSinceEpoch(qint64(t), Qt::UTC)) * 1e3 - LocalTZA;
+}
+#else
+// This implementation fails to take account of past changes in standard offset.
static inline double DaylightSavingTA(double t)
{
struct tm tmtm;
-#if defined(_MSC_VER) && _MSC_VER >= 1400
+#if defined(Q_CC_MSVC)
__time64_t tt = (__time64_t)(t / msPerSecond);
// _localtime_64_s returns non-zero on failure
if (_localtime64_s(&tmtm, &tt) != 0)
@@ -306,52 +346,53 @@ static inline double DaylightSavingTA(double t)
return 0;
return (tmtm.tm_isdst > 0) ? msPerHour : 0;
}
+#endif // USE_QTZ_SYSTEM_ZONE
static inline double LocalTime(double t)
{
+ // Flawed, yet verbatim from the spec:
return t + LocalTZA + DaylightSavingTA(t);
}
+// The spec does note [*] that UTC and LocalTime are not quite mutually inverse.
+// [*] http://www.ecma-international.org/ecma-262/7.0/index.html#sec-utc-t
+
static inline double UTC(double t)
{
+ // Flawed, yet verbatim from the spec:
return t - LocalTZA - DaylightSavingTA(t - LocalTZA);
}
static inline double currentTime()
{
-#ifndef Q_OS_WIN
- struct timeval tv;
-
- gettimeofday(&tv, 0);
- return ::floor(tv.tv_sec * msPerSecond + (tv.tv_usec / 1000.0));
-#else
- SYSTEMTIME st;
- GetSystemTime(&st);
- FILETIME ft;
- SystemTimeToFileTime(&st, &ft);
- LARGE_INTEGER li;
- li.LowPart = ft.dwLowDateTime;
- li.HighPart = ft.dwHighDateTime;
- return double(li.QuadPart - Q_INT64_C(116444736000000000)) / 10000.0;
-#endif
+ return QDateTime::currentDateTimeUtc().toMSecsSinceEpoch();
}
static inline double TimeClip(double t)
{
if (! qt_is_finite(t) || fabs(t) > 8.64e15)
return qt_qnan();
- return Primitive::toInteger(t);
+
+ // +0 looks weird, but is correct. See ES6 20.3.1.15. We must not return -0.
+ return Primitive::toInteger(t) + 0;
}
static inline double ParseString(const QString &s)
{
- // first try the format defined in 15.9.1.15, only if that fails fall back to
- // QDateTime for parsing
+ /*
+ First, try the format defined in ECMA 262's "Date Time String Format";
+ only if that fails, fall back to QDateTime for parsing
+
+ The defined string format is YYYY-MM-DDTHH:mm:ss.sssZ; the time (T and all
+ after it) may be omitted; in each part, the second and later components
+ are optional; and there's an extended syntax for negative and large
+ positive years: +/-YYYYYY; the leading sign, even when +, isn't optional.
+ If month or day is omitted, it is 01; if minute or second is omitted, it's
+ 00; if milliseconds are omitted, they're 000.
- // the define string format is YYYY-MM-DDTHH:mm:ss.sssZ
- // It can be date or time only, and the second and later components
- // of both fields are optional
- // and extended syntax for negative and large positive years exists: +/-YYYYYY
+ When the time zone offset is absent, date-only forms are interpreted as
+ indicating a UTC time and date-time forms are interpreted in local time.
+ */
enum Format {
Year,
@@ -384,6 +425,8 @@ static inline double ParseString(const QString &s)
int msec = 0;
int offsetSign = 1;
int offset = 0;
+ bool seenT = false;
+ bool seenZ = false; // Have seen zone, i.e. +HH:mm or literal Z.
bool error = false;
if (*ch == '+' || *ch == '-') {
@@ -392,7 +435,7 @@ static inline double ParseString(const QString &s)
yearSign = -1;
++ch;
}
- while (ch <= end) {
+ for (; ch <= end && !error && format != Done; ++ch) {
if (*ch >= '0' && *ch <= '9') {
current *= 10;
current += ch->unicode() - '0';
@@ -420,7 +463,7 @@ static inline double ParseString(const QString &s)
break;
case Minute:
minute = current;
- error = (currentSize != 2) || minute > 60;
+ error = (currentSize != 2) || minute >= 60;
break;
case Second:
second = current;
@@ -431,8 +474,10 @@ static inline double ParseString(const QString &s)
error = (currentSize != 3);
break;
case TimezoneHour:
- offset = current*60;
- error = (currentSize != 2) || offset > 23*60;
+ Q_ASSERT(offset == 0 && !seenZ);
+ offset = current * 60;
+ error = (currentSize != 2) || current > 23;
+ seenZ = true;
break;
case TimezoneMinute:
offset += current;
@@ -443,6 +488,7 @@ static inline double ParseString(const QString &s)
if (format >= Hour)
error = true;
format = Hour;
+ seenT = true;
} else if (*ch == '-') {
if (format < Day)
++format;
@@ -451,6 +497,7 @@ static inline double ParseString(const QString &s)
else if (format >= TimezoneHour)
error = true;
else {
+ Q_ASSERT(offset == 0 && !seenZ);
offsetSign = -1;
format = TimezoneHour;
}
@@ -463,23 +510,31 @@ static inline double ParseString(const QString &s)
error = true;
++format;
} else if (*ch == '+') {
- if (format < Minute || format >= TimezoneHour)
+ if (seenZ || format < Minute || format >= TimezoneHour)
error = true;
format = TimezoneHour;
- } else if (*ch == 'Z' || ch->unicode() == 0) {
+ } else if (*ch == 'Z') {
+ if (seenZ || format < Minute || format >= TimezoneHour)
+ error = true;
+ else
+ Q_ASSERT(offset == 0);
+ format = Done;
+ seenZ = true;
+ } else if (ch->unicode() == 0) {
format = Done;
}
current = 0;
currentSize = 0;
}
- if (error || format == Done)
- break;
- ++ch;
}
if (!error) {
double t = MakeDate(MakeDay(year * yearSign, month, day), MakeTime(hour, minute, second, msec));
- t -= offset * offsetSign * 60 * 1000;
+ if (seenZ)
+ t -= offset * offsetSign * 60 * 1000;
+ else if (seenT) // No zone specified, treat date-time as local time
+ t = UTC(t);
+ // else: treat plain date as already in UTC
return t;
}
@@ -489,56 +544,61 @@ static inline double ParseString(const QString &s)
if (!dt.isValid())
dt = QDateTime::fromString(s, Qt::RFC2822Date);
if (!dt.isValid()) {
- QStringList formats;
- formats << QStringLiteral("M/d/yyyy")
- << QStringLiteral("M/d/yyyy hh:mm")
- << QStringLiteral("M/d/yyyy hh:mm A")
-
- << QStringLiteral("M/d/yyyy, hh:mm")
- << QStringLiteral("M/d/yyyy, hh:mm A")
-
- << QStringLiteral("MMM d yyyy")
- << QStringLiteral("MMM d yyyy hh:mm")
- << QStringLiteral("MMM d yyyy hh:mm:ss")
- << QStringLiteral("MMM d yyyy, hh:mm")
- << QStringLiteral("MMM d yyyy, hh:mm:ss")
-
- << QStringLiteral("MMMM d yyyy")
- << QStringLiteral("MMMM d yyyy hh:mm")
- << QStringLiteral("MMMM d yyyy hh:mm:ss")
- << QStringLiteral("MMMM d yyyy, hh:mm")
- << QStringLiteral("MMMM d yyyy, hh:mm:ss")
-
- << QStringLiteral("MMM d, yyyy")
- << QStringLiteral("MMM d, yyyy hh:mm")
- << QStringLiteral("MMM d, yyyy hh:mm:ss")
-
- << QStringLiteral("MMMM d, yyyy")
- << QStringLiteral("MMMM d, yyyy hh:mm")
- << QStringLiteral("MMMM d, yyyy hh:mm:ss")
-
- << QStringLiteral("d MMM yyyy")
- << QStringLiteral("d MMM yyyy hh:mm")
- << QStringLiteral("d MMM yyyy hh:mm:ss")
- << QStringLiteral("d MMM yyyy, hh:mm")
- << QStringLiteral("d MMM yyyy, hh:mm:ss")
-
- << QStringLiteral("d MMMM yyyy")
- << QStringLiteral("d MMMM yyyy hh:mm")
- << QStringLiteral("d MMMM yyyy hh:mm:ss")
- << QStringLiteral("d MMMM yyyy, hh:mm")
- << QStringLiteral("d MMMM yyyy, hh:mm:ss")
-
- << QStringLiteral("d MMM, yyyy")
- << QStringLiteral("d MMM, yyyy hh:mm")
- << QStringLiteral("d MMM, yyyy hh:mm:ss")
-
- << QStringLiteral("d MMMM, yyyy")
- << QStringLiteral("d MMMM, yyyy hh:mm")
- << QStringLiteral("d MMMM, yyyy hh:mm:ss");
-
- for (int i = 0; i < formats.size(); ++i) {
- dt = QDateTime::fromString(s, formats.at(i));
+ const QString formats[] = {
+ QStringLiteral("M/d/yyyy"),
+ QStringLiteral("M/d/yyyy hh:mm"),
+ QStringLiteral("M/d/yyyy hh:mm A"),
+
+ QStringLiteral("M/d/yyyy, hh:mm"),
+ QStringLiteral("M/d/yyyy, hh:mm A"),
+
+ QStringLiteral("MMM d yyyy"),
+ QStringLiteral("MMM d yyyy hh:mm"),
+ QStringLiteral("MMM d yyyy hh:mm:ss"),
+ QStringLiteral("MMM d yyyy, hh:mm"),
+ QStringLiteral("MMM d yyyy, hh:mm:ss"),
+
+ QStringLiteral("MMMM d yyyy"),
+ QStringLiteral("MMMM d yyyy hh:mm"),
+ QStringLiteral("MMMM d yyyy hh:mm:ss"),
+ QStringLiteral("MMMM d yyyy, hh:mm"),
+ QStringLiteral("MMMM d yyyy, hh:mm:ss"),
+
+ QStringLiteral("MMM d, yyyy"),
+ QStringLiteral("MMM d, yyyy hh:mm"),
+ QStringLiteral("MMM d, yyyy hh:mm:ss"),
+
+ QStringLiteral("MMMM d, yyyy"),
+ QStringLiteral("MMMM d, yyyy hh:mm"),
+ QStringLiteral("MMMM d, yyyy hh:mm:ss"),
+
+ QStringLiteral("d MMM yyyy"),
+ QStringLiteral("d MMM yyyy hh:mm"),
+ QStringLiteral("d MMM yyyy hh:mm:ss"),
+ QStringLiteral("d MMM yyyy, hh:mm"),
+ QStringLiteral("d MMM yyyy, hh:mm:ss"),
+
+ QStringLiteral("d MMMM yyyy"),
+ QStringLiteral("d MMMM yyyy hh:mm"),
+ QStringLiteral("d MMMM yyyy hh:mm:ss"),
+ QStringLiteral("d MMMM yyyy, hh:mm"),
+ QStringLiteral("d MMMM yyyy, hh:mm:ss"),
+
+ QStringLiteral("d MMM, yyyy"),
+ QStringLiteral("d MMM, yyyy hh:mm"),
+ QStringLiteral("d MMM, yyyy hh:mm:ss"),
+
+ QStringLiteral("d MMMM, yyyy"),
+ QStringLiteral("d MMMM, yyyy hh:mm"),
+ QStringLiteral("d MMMM, yyyy hh:mm:ss"),
+ };
+
+ for (uint i = 0; i < sizeof(formats) / sizeof(formats[0]); ++i) {
+ const QString &format(formats[i]);
+ dt = format.indexOf(QLatin1String("hh:mm")) < 0
+ ? QDateTime(QDate::fromString(s, format),
+ QTime(0, 0, 0), Qt::UTC)
+ : QDateTime::fromString(s, format); // as local time
if (dt.isValid())
break;
}
@@ -558,7 +618,7 @@ static inline QDateTime ToDateTime(double t, Qt::TimeSpec spec)
{
if (std::isnan(t))
return QDateTime();
- return QDateTime::fromMSecsSinceEpoch(t, spec);
+ return QDateTime::fromMSecsSinceEpoch(t, Qt::UTC).toTimeSpec(spec);
}
static inline QString ToString(double t)
@@ -616,20 +676,28 @@ static inline QString ToLocaleTimeString(double t)
static double getLocalTZA()
{
#ifndef Q_OS_WIN
+ tzset();
+#endif
+#ifdef USE_QTZ_SYSTEM_ZONE
+ // TODO: QTimeZone::resetSystemTimeZone(), see QTBUG-56899 and comment above.
+ // Standard offset, with no daylight-savings adjustment, in ms:
+ return QTimeZone::systemTimeZone().standardTimeOffset(QDateTime::currentDateTime()) * 1e3;
+#else
+# ifdef Q_OS_WIN
+ TIME_ZONE_INFORMATION tzInfo;
+ GetTimeZoneInformation(&tzInfo);
+ return -tzInfo.Bias * 60.0 * 1000.0;
+# else
struct tm t;
time_t curr;
- tzset();
time(&curr);
- localtime_r(&curr, &t);
+ localtime_r(&curr, &t); // Wrong: includes DST offset
time_t locl = mktime(&t);
gmtime_r(&curr, &t);
time_t globl = mktime(&t);
return (double(locl) - double(globl)) * 1000.0;
-#else
- TIME_ZONE_INFORMATION tzInfo;
- GetTimeZoneInformation(&tzInfo);
- return -tzInfo.Bias * 60.0 * 1000.0;
-#endif
+# endif
+#endif // USE_QTZ_SYSTEM_ZONE
}
DEFINE_OBJECT_VTABLE(DateObject);
@@ -648,17 +716,19 @@ void Heap::DateObject::init(const QTime &time)
return;
}
- /* All programmers know that stuff starts at 0. Whatever that may mean in this context (and
- * local timezone), it's before the epoch, so there is defenitely no DST problem. Specifically:
- * you can't start with a date before the epoch, add some[*] hours, and end up with a date
- * after. That's a problem for timezones where new year happens during DST, like
- * Australia/Hobart, because we have to ignore DST before the epoch (but honor it after the
- * epoch).
- *
- * [*] Well, when "some" is in the range 0-24. If you add something like 1M then this might
- * still happen.
+ /* We have to chose a date on which to instantiate this time. All we really
+ * care about is that it round-trips back to the same time if we extract the
+ * time from it, which shall (via toQDateTime(), below) discard the date
+ * part. We need a date for which time-zone data is likely to be sane (so
+ * MakeDay(0, 0, 0) was a bad choice; 2 BC, December 31st is before
+ * time-zones were standardized), with no transition nearby in date. We
+ * ignore DST transitions before 1970, but even then zone transitions did
+ * happen. Some do happen at new year, others on DST transitions in spring
+ * and autumn; so pick the three hundredth anniversary of the birth of
+ * Giovanni Domenico Cassini (1625-06-08), whose work first let us
+ * synchronize clocks tolerably accurately at distant locations.
*/
- static const double d = MakeDay(0, 0, 0);
+ static const double d = MakeDay(1925, 5, 8);
double t = MakeTime(time.hour(), time.minute(), time.second(), time.msec());
date = TimeClip(UTC(MakeDate(d, t)));
}
@@ -675,15 +745,16 @@ void Heap::DateCtor::init(QV4::ExecutionContext *scope)
Heap::FunctionObject::init(scope, QStringLiteral("Date"));
}
-void DateCtor::construct(const Managed *, Scope &scope, CallData *callData)
+ReturnedValue DateCtor::callAsConstructor(const FunctionObject *that, const Value *argv, int argc)
{
double t = 0;
- if (callData->argc == 0)
+ if (argc == 0)
t = currentTime();
- else if (callData->argc == 1) {
- ScopedValue arg(scope, callData->args[0]);
+ else if (argc == 1) {
+ Scope scope(that->engine());
+ ScopedValue arg(scope, argv[0]);
if (DateObject *d = arg->as<DateObject>()) {
t = d->date();
} else {
@@ -697,26 +768,26 @@ void DateCtor::construct(const Managed *, Scope &scope, CallData *callData)
}
else { // d.argc > 1
- double year = callData->args[0].toNumber();
- double month = callData->args[1].toNumber();
- double day = callData->argc >= 3 ? callData->args[2].toNumber() : 1;
- double hours = callData->argc >= 4 ? callData->args[3].toNumber() : 0;
- double mins = callData->argc >= 5 ? callData->args[4].toNumber() : 0;
- double secs = callData->argc >= 6 ? callData->args[5].toNumber() : 0;
- double ms = callData->argc >= 7 ? callData->args[6].toNumber() : 0;
+ double year = argv[0].toNumber();
+ double month = argv[1].toNumber();
+ double day = argc >= 3 ? argv[2].toNumber() : 1;
+ double hours = argc >= 4 ? argv[3].toNumber() : 0;
+ double mins = argc >= 5 ? argv[4].toNumber() : 0;
+ double secs = argc >= 6 ? argv[5].toNumber() : 0;
+ double ms = argc >= 7 ? argv[6].toNumber() : 0;
if (year >= 0 && year <= 99)
year += 1900;
t = MakeDate(MakeDay(year, month, day), MakeTime(hours, mins, secs, ms));
t = TimeClip(UTC(t));
}
- scope.result = Encode(scope.engine->newDateObject(Primitive::fromDouble(t)));
+ return Encode(that->engine()->newDateObject(Primitive::fromDouble(t)));
}
-void DateCtor::call(const Managed *m, Scope &scope, CallData *)
+ReturnedValue DateCtor::call(const FunctionObject *m, const Value *, const Value *, int)
{
double t = currentTime();
- scope.result = static_cast<const DateCtor *>(m)->engine()->newString(ToString(t));
+ return m->engine()->newString(ToString(t))->asReturnedValue();
}
void DatePrototype::init(ExecutionEngine *engine, Object *ctor)
@@ -724,7 +795,7 @@ void DatePrototype::init(ExecutionEngine *engine, Object *ctor)
Scope scope(engine);
ScopedObject o(scope);
ctor->defineReadonlyProperty(engine->id_prototype(), (o = this));
- ctor->defineReadonlyProperty(engine->id_length(), Primitive::fromInt32(7));
+ ctor->defineReadonlyConfigurableProperty(engine->id_length(), Primitive::fromInt32(7));
LocalTZA = getLocalTZA();
ctor->defineDefaultProperty(QStringLiteral("parse"), method_parse, 1);
@@ -774,441 +845,537 @@ void DatePrototype::init(ExecutionEngine *engine, Object *ctor)
defineDefaultProperty(QStringLiteral("setYear"), method_setYear, 1);
defineDefaultProperty(QStringLiteral("setFullYear"), method_setFullYear, 3);
defineDefaultProperty(QStringLiteral("setUTCFullYear"), method_setUTCFullYear, 3);
- defineDefaultProperty(QStringLiteral("toUTCString"), method_toUTCString, 0);
- defineDefaultProperty(QStringLiteral("toGMTString"), method_toUTCString, 0);
+
+ // ES6: B.2.4.3 & 20.3.4.43:
+ // We have to use the *same object* for toUTCString and toGMTString
+ {
+ QString toUtcString(QStringLiteral("toUTCString"));
+ QString toGmtString(QStringLiteral("toGMTString"));
+ ScopedString us(scope, engine->newIdentifier(toUtcString));
+ ScopedString gs(scope, engine->newIdentifier(toGmtString));
+ ExecutionContext *global = engine->rootContext();
+ ScopedFunctionObject toUtcGmtStringFn(scope, FunctionObject::createBuiltinFunction(global, us, method_toUTCString));
+ toUtcGmtStringFn->defineReadonlyConfigurableProperty(engine->id_length(), Primitive::fromInt32(0));
+ defineDefaultProperty(us, toUtcGmtStringFn);
+ defineDefaultProperty(gs, toUtcGmtStringFn);
+ }
+
defineDefaultProperty(QStringLiteral("toISOString"), method_toISOString, 0);
defineDefaultProperty(QStringLiteral("toJSON"), method_toJSON, 1);
}
-double DatePrototype::getThisDate(Scope &scope, CallData *callData)
+double DatePrototype::getThisDate(ExecutionEngine *v4, const Value *thisObject)
{
- if (DateObject *thisObject = callData->thisObject.as<DateObject>())
- return thisObject->date();
- else {
- scope.engine->throwTypeError();
- return 0;
- }
+ if (const DateObject *that = thisObject->as<DateObject>())
+ return that->date();
+ v4->throwTypeError();
+ return 0;
}
-void DatePrototype::method_parse(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_parse(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- if (!callData->argc)
- scope.result = Encode(qt_qnan());
+ if (!argc)
+ return Encode(qt_qnan());
else
- scope.result = Encode(ParseString(callData->args[0].toQString()));
+ return Encode(ParseString(argv[0].toQString()));
}
-void DatePrototype::method_UTC(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_UTC(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- const int numArgs = callData->argc;
+ const int numArgs = argc;
if (numArgs >= 2) {
- double year = callData->args[0].toNumber();
- double month = callData->args[1].toNumber();
- double day = numArgs >= 3 ? callData->args[2].toNumber() : 1;
- double hours = numArgs >= 4 ? callData->args[3].toNumber() : 0;
- double mins = numArgs >= 5 ? callData->args[4].toNumber() : 0;
- double secs = numArgs >= 6 ? callData->args[5].toNumber() : 0;
- double ms = numArgs >= 7 ? callData->args[6].toNumber() : 0;
+ double year = argv[0].toNumber();
+ double month = argv[1].toNumber();
+ double day = numArgs >= 3 ? argv[2].toNumber() : 1;
+ double hours = numArgs >= 4 ? argv[3].toNumber() : 0;
+ double mins = numArgs >= 5 ? argv[4].toNumber() : 0;
+ double secs = numArgs >= 6 ? argv[5].toNumber() : 0;
+ double ms = numArgs >= 7 ? argv[6].toNumber() : 0;
if (year >= 0 && year <= 99)
year += 1900;
double t = MakeDate(MakeDay(year, month, day),
MakeTime(hours, mins, secs, ms));
- scope.result = Encode(TimeClip(t));
- return;
+ return Encode(TimeClip(t));
}
RETURN_UNDEFINED();
}
-void DatePrototype::method_now(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_now(const FunctionObject *, const Value *, const Value *, int)
{
- Q_UNUSED(callData);
- double t = currentTime();
- scope.result = Encode(t);
+ return Encode(currentTime());
}
-void DatePrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_toString(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- double t = getThisDate(scope, callData);
- scope.result = scope.engine->newString(ToString(t));
+ ExecutionEngine *v4 = b->engine();
+ double t = getThisDate(v4, thisObject);
+ return Encode(v4->newString(ToString(t)));
}
-void DatePrototype::method_toDateString(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_toDateString(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- double t = getThisDate(scope, callData);
- scope.result = scope.engine->newString(ToDateString(t));
+ ExecutionEngine *v4 = b->engine();
+ double t = getThisDate(v4, thisObject);
+ return Encode(v4->newString(ToDateString(t)));
}
-void DatePrototype::method_toTimeString(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_toTimeString(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- double t = getThisDate(scope, callData);
- scope.result = scope.engine->newString(ToTimeString(t));
+ ExecutionEngine *v4 = b->engine();
+ double t = getThisDate(v4, thisObject);
+ return Encode(v4->newString(ToTimeString(t)));
}
-void DatePrototype::method_toLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_toLocaleString(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- double t = getThisDate(scope, callData);
- scope.result = scope.engine->newString(ToLocaleString(t));
+ ExecutionEngine *v4 = b->engine();
+ double t = getThisDate(v4, thisObject);
+ return Encode(v4->newString(ToLocaleString(t)));
}
-void DatePrototype::method_toLocaleDateString(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_toLocaleDateString(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- double t = getThisDate(scope, callData);
- scope.result = scope.engine->newString(ToLocaleDateString(t));
+ ExecutionEngine *v4 = b->engine();
+ double t = getThisDate(v4, thisObject);
+ return Encode(v4->newString(ToLocaleDateString(t)));
}
-void DatePrototype::method_toLocaleTimeString(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_toLocaleTimeString(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- double t = getThisDate(scope, callData);
- scope.result = scope.engine->newString(ToLocaleTimeString(t));
+ ExecutionEngine *v4 = b->engine();
+ double t = getThisDate(v4, thisObject);
+ return Encode(v4->newString(ToLocaleTimeString(t)));
}
-void DatePrototype::method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_valueOf(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- double t = getThisDate(scope, callData);
- scope.result = Encode(t);
+ ExecutionEngine *v4 = b->engine();
+ double t = getThisDate(v4, thisObject);
+ return Encode(t);
}
-void DatePrototype::method_getTime(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_getTime(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- double t = getThisDate(scope, callData);
- scope.result = Encode(t);
+ ExecutionEngine *v4 = b->engine();
+ double t = getThisDate(v4, thisObject);
+ return Encode(t);
}
-void DatePrototype::method_getYear(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_getYear(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- double t = getThisDate(scope, callData);
+ ExecutionEngine *v4 = b->engine();
+ double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
t = YearFromTime(LocalTime(t)) - 1900;
- scope.result = Encode(t);
+ return Encode(t);
}
-void DatePrototype::method_getFullYear(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_getFullYear(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- double t = getThisDate(scope, callData);
+ ExecutionEngine *v4 = b->engine();
+ double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
t = YearFromTime(LocalTime(t));
- scope.result = Encode(t);
+ return Encode(t);
}
-void DatePrototype::method_getUTCFullYear(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_getUTCFullYear(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- double t = getThisDate(scope, callData);
+ ExecutionEngine *v4 = b->engine();
+ double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
t = YearFromTime(t);
- scope.result = Encode(t);
+ return Encode(t);
}
-void DatePrototype::method_getMonth(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_getMonth(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- double t = getThisDate(scope, callData);
+ ExecutionEngine *v4 = b->engine();
+ double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
t = MonthFromTime(LocalTime(t));
- scope.result = Encode(t);
+ return Encode(t);
}
-void DatePrototype::method_getUTCMonth(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_getUTCMonth(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- double t = getThisDate(scope, callData);
+ ExecutionEngine *v4 = b->engine();
+ double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
t = MonthFromTime(t);
- scope.result = Encode(t);
+ return Encode(t);
}
-void DatePrototype::method_getDate(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_getDate(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- double t = getThisDate(scope, callData);
+ ExecutionEngine *v4 = b->engine();
+ double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
t = DateFromTime(LocalTime(t));
- scope.result = Encode(t);
+ return Encode(t);
}
-void DatePrototype::method_getUTCDate(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_getUTCDate(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- double t = getThisDate(scope, callData);
+ ExecutionEngine *v4 = b->engine();
+ double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
t = DateFromTime(t);
- scope.result = Encode(t);
+ return Encode(t);
}
-void DatePrototype::method_getDay(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_getDay(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- double t = getThisDate(scope, callData);
+ ExecutionEngine *v4 = b->engine();
+ double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
t = WeekDay(LocalTime(t));
- scope.result = Encode(t);
+ return Encode(t);
}
-void DatePrototype::method_getUTCDay(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_getUTCDay(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- double t = getThisDate(scope, callData);
+ ExecutionEngine *v4 = b->engine();
+ double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
t = WeekDay(t);
- scope.result = Encode(t);
+ return Encode(t);
}
-void DatePrototype::method_getHours(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_getHours(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- double t = getThisDate(scope, callData);
+ ExecutionEngine *v4 = b->engine();
+ double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
t = HourFromTime(LocalTime(t));
- scope.result = Encode(t);
+ return Encode(t);
}
-void DatePrototype::method_getUTCHours(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_getUTCHours(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- double t = getThisDate(scope, callData);
+ ExecutionEngine *v4 = b->engine();
+ double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
t = HourFromTime(t);
- scope.result = Encode(t);
+ return Encode(t);
}
-void DatePrototype::method_getMinutes(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_getMinutes(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- double t = getThisDate(scope, callData);
+ ExecutionEngine *v4 = b->engine();
+ double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
t = MinFromTime(LocalTime(t));
- scope.result = Encode(t);
+ return Encode(t);
}
-void DatePrototype::method_getUTCMinutes(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_getUTCMinutes(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- double t = getThisDate(scope, callData);
+ ExecutionEngine *v4 = b->engine();
+ double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
t = MinFromTime(t);
- scope.result = Encode(t);
+ return Encode(t);
}
-void DatePrototype::method_getSeconds(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_getSeconds(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- double t = getThisDate(scope, callData);
+ ExecutionEngine *v4 = b->engine();
+ double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
t = SecFromTime(LocalTime(t));
- scope.result = Encode(t);
+ return Encode(t);
}
-void DatePrototype::method_getUTCSeconds(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_getUTCSeconds(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- double t = getThisDate(scope, callData);
+ ExecutionEngine *v4 = b->engine();
+ double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
t = SecFromTime(t);
- scope.result = Encode(t);
+ return Encode(t);
}
-void DatePrototype::method_getMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_getMilliseconds(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- double t = getThisDate(scope, callData);
+ ExecutionEngine *v4 = b->engine();
+ double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
t = msFromTime(LocalTime(t));
- scope.result = Encode(t);
+ return Encode(t);
}
-void DatePrototype::method_getUTCMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_getUTCMilliseconds(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- double t = getThisDate(scope, callData);
+ ExecutionEngine *v4 = b->engine();
+ double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
t = msFromTime(t);
- scope.result = Encode(t);
+ return Encode(t);
}
-void DatePrototype::method_getTimezoneOffset(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_getTimezoneOffset(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- double t = getThisDate(scope, callData);
+ ExecutionEngine *v4 = b->engine();
+ double t = getThisDate(v4, thisObject);
if (!std::isnan(t))
t = (t - LocalTime(t)) / msPerMinute;
- scope.result = Encode(t);
+ return Encode(t);
}
-void DatePrototype::method_setTime(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_setTime(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- Scoped<DateObject> self(scope, callData->thisObject);
+ ExecutionEngine *v4 = b->engine();
+ DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
if (!self)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
- double t = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double t = argc ? argv[0].toNumber() : qt_qnan();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
self->setDate(TimeClip(t));
- scope.result = Encode(self->date());
+ return Encode(self->date());
}
-void DatePrototype::method_setMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_setMilliseconds(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- Scoped<DateObject> self(scope, callData->thisObject);
+ ExecutionEngine *v4 = b->engine();
+ DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
if (!self)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
double t = LocalTime(self->date());
- double ms = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
+ double ms = argc ? argv[0].toNumber() : qt_qnan();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
self->setDate(TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms)))));
- scope.result = Encode(self->date());
+ return Encode(self->date());
}
-void DatePrototype::method_setUTCMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_setUTCMilliseconds(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- DateObject *self = callData->thisObject.as<DateObject>();
+ ExecutionEngine *v4 = b->engine();
+ DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
if (!self)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
double t = self->date();
- double ms = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
+ double ms = argc ? argv[0].toNumber() : qt_qnan();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
self->setDate(TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms))));
- scope.result = Encode(self->date());
+ return Encode(self->date());
}
-void DatePrototype::method_setSeconds(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_setSeconds(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- DateObject *self = callData->thisObject.as<DateObject>();
+ ExecutionEngine *v4 = b->engine();
+ DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
if (!self)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
double t = LocalTime(self->date());
- double sec = callData->argc ? callData->args[0].toNumber() : qt_qnan();
- double ms = (callData->argc < 2) ? msFromTime(t) : callData->args[1].toNumber();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
+ double sec = argc ? argv[0].toNumber() : qt_qnan();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
+ double ms = (argc < 2) ? msFromTime(t) : argv[1].toNumber();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms))));
self->setDate(t);
- scope.result = Encode(self->date());
+ return Encode(self->date());
}
-void DatePrototype::method_setUTCSeconds(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_setUTCSeconds(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- DateObject *self = callData->thisObject.as<DateObject>();
+ ExecutionEngine *v4 = b->engine();
+ DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
if (!self)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
double t = self->date();
- double sec = callData->argc ? callData->args[0].toNumber() : qt_qnan();
- double ms = (callData->argc < 2) ? msFromTime(t) : callData->args[1].toNumber();
+ double sec = argc ? argv[0].toNumber() : qt_qnan();
+ double ms = (argc < 2) ? msFromTime(t) : argv[1].toNumber();
t = TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms)));
self->setDate(t);
- scope.result = Encode(self->date());
+ return Encode(self->date());
}
-void DatePrototype::method_setMinutes(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_setMinutes(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- DateObject *self = callData->thisObject.as<DateObject>();
+ ExecutionEngine *v4 = b->engine();
+ DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
if (!self)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
double t = LocalTime(self->date());
- double min = callData->argc ? callData->args[0].toNumber() : qt_qnan();
- double sec = (callData->argc < 2) ? SecFromTime(t) : callData->args[1].toNumber();
- double ms = (callData->argc < 3) ? msFromTime(t) : callData->args[2].toNumber();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
+ double min = argc ? argv[0].toNumber() : qt_qnan();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
+ double sec = (argc < 2) ? SecFromTime(t) : argv[1].toNumber();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
+ double ms = (argc < 3) ? msFromTime(t) : argv[2].toNumber();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms))));
self->setDate(t);
- scope.result = Encode(self->date());
+ return Encode(self->date());
}
-void DatePrototype::method_setUTCMinutes(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_setUTCMinutes(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- DateObject *self = callData->thisObject.as<DateObject>();
+ ExecutionEngine *v4 = b->engine();
+ DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
if (!self)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
double t = self->date();
- double min = callData->argc ? callData->args[0].toNumber() : qt_qnan();
- double sec = (callData->argc < 2) ? SecFromTime(t) : callData->args[1].toNumber();
- double ms = (callData->argc < 3) ? msFromTime(t) : callData->args[2].toNumber();
+ double min = argc ? argv[0].toNumber() : qt_qnan();
+ double sec = (argc < 2) ? SecFromTime(t) : argv[1].toNumber();
+ double ms = (argc < 3) ? msFromTime(t) : argv[2].toNumber();
t = TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms)));
self->setDate(t);
- scope.result = Encode(self->date());
+ return Encode(self->date());
}
-void DatePrototype::method_setHours(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_setHours(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- DateObject *self = callData->thisObject.as<DateObject>();
+ ExecutionEngine *v4 = b->engine();
+ DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
if (!self)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
double t = LocalTime(self->date());
- double hour = callData->argc ? callData->args[0].toNumber() : qt_qnan();
- double min = (callData->argc < 2) ? MinFromTime(t) : callData->args[1].toNumber();
- double sec = (callData->argc < 3) ? SecFromTime(t) : callData->args[2].toNumber();
- double ms = (callData->argc < 4) ? msFromTime(t) : callData->args[3].toNumber();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
+ double hour = argc ? argv[0].toNumber() : qt_qnan();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
+ double min = (argc < 2) ? MinFromTime(t) : argv[1].toNumber();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
+ double sec = (argc < 3) ? SecFromTime(t) : argv[2].toNumber();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
+ double ms = (argc < 4) ? msFromTime(t) : argv[3].toNumber();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(hour, min, sec, ms))));
self->setDate(t);
- scope.result = Encode(self->date());
+ return Encode(self->date());
}
-void DatePrototype::method_setUTCHours(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_setUTCHours(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- DateObject *self = callData->thisObject.as<DateObject>();
+ ExecutionEngine *v4 = b->engine();
+ DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
if (!self)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
double t = self->date();
- double hour = callData->argc ? callData->args[0].toNumber() : qt_qnan();
- double min = (callData->argc < 2) ? MinFromTime(t) : callData->args[1].toNumber();
- double sec = (callData->argc < 3) ? SecFromTime(t) : callData->args[2].toNumber();
- double ms = (callData->argc < 4) ? msFromTime(t) : callData->args[3].toNumber();
+ double hour = argc ? argv[0].toNumber() : qt_qnan();
+ double min = (argc < 2) ? MinFromTime(t) : argv[1].toNumber();
+ double sec = (argc < 3) ? SecFromTime(t) : argv[2].toNumber();
+ double ms = (argc < 4) ? msFromTime(t) : argv[3].toNumber();
t = TimeClip(MakeDate(Day(t), MakeTime(hour, min, sec, ms)));
self->setDate(t);
- scope.result = Encode(self->date());
+ return Encode(self->date());
}
-void DatePrototype::method_setDate(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_setDate(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- DateObject *self = callData->thisObject.as<DateObject>();
+ ExecutionEngine *v4 = b->engine();
+ DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
if (!self)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
double t = LocalTime(self->date());
- double date = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
+ double date = argc ? argv[0].toNumber() : qt_qnan();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t))));
self->setDate(t);
- scope.result = Encode(self->date());
+ return Encode(self->date());
}
-void DatePrototype::method_setUTCDate(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_setUTCDate(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- DateObject *self = callData->thisObject.as<DateObject>();
+ ExecutionEngine *v4 = b->engine();
+ DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
if (!self)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
double t = self->date();
- double date = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
+ double date = argc ? argv[0].toNumber() : qt_qnan();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
t = TimeClip(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t)));
self->setDate(t);
- scope.result = Encode(self->date());
+ return Encode(self->date());
}
-void DatePrototype::method_setMonth(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_setMonth(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- DateObject *self = callData->thisObject.as<DateObject>();
+ ExecutionEngine *v4 = b->engine();
+ DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
if (!self)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
double t = LocalTime(self->date());
- double month = callData->argc ? callData->args[0].toNumber() : qt_qnan();
- double date = (callData->argc < 2) ? DateFromTime(t) : callData->args[1].toNumber();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
+ double month = argc ? argv[0].toNumber() : qt_qnan();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
+ double date = (argc < 2) ? DateFromTime(t) : argv[1].toNumber();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t))));
self->setDate(t);
- scope.result = Encode(self->date());
+ return Encode(self->date());
}
-void DatePrototype::method_setUTCMonth(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_setUTCMonth(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- DateObject *self = callData->thisObject.as<DateObject>();
+ ExecutionEngine *v4 = b->engine();
+ DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
if (!self)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
double t = self->date();
- double month = callData->argc ? callData->args[0].toNumber() : qt_qnan();
- double date = (callData->argc < 2) ? DateFromTime(t) : callData->args[1].toNumber();
+ double month = argc ? argv[0].toNumber() : qt_qnan();
+ double date = (argc < 2) ? DateFromTime(t) : argv[1].toNumber();
t = TimeClip(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t)));
self->setDate(t);
- scope.result = Encode(self->date());
+ return Encode(self->date());
}
-void DatePrototype::method_setYear(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_setYear(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- DateObject *self = callData->thisObject.as<DateObject>();
+ ExecutionEngine *v4 = b->engine();
+ DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
if (!self)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
double t = self->date();
if (std::isnan(t))
t = 0;
else
t = LocalTime(t);
- double year = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double year = argc ? argv[0].toNumber() : qt_qnan();
double r;
if (std::isnan(year)) {
r = qt_qnan();
@@ -1220,49 +1387,60 @@ void DatePrototype::method_setYear(const BuiltinFunction *, Scope &scope, CallDa
r = TimeClip(r);
}
self->setDate(r);
- scope.result = Encode(self->date());
+ return Encode(self->date());
}
-void DatePrototype::method_setUTCFullYear(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_setUTCFullYear(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- DateObject *self = callData->thisObject.as<DateObject>();
+ ExecutionEngine *v4 = b->engine();
+ DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
if (!self)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
double t = self->date();
- double year = callData->argc ? callData->args[0].toNumber() : qt_qnan();
- double month = (callData->argc < 2) ? MonthFromTime(t) : callData->args[1].toNumber();
- double date = (callData->argc < 3) ? DateFromTime(t) : callData->args[2].toNumber();
+ double year = argc ? argv[0].toNumber() : qt_qnan();
+ double month = (argc < 2) ? MonthFromTime(t) : argv[1].toNumber();
+ double date = (argc < 3) ? DateFromTime(t) : argv[2].toNumber();
t = TimeClip(MakeDate(MakeDay(year, month, date), TimeWithinDay(t)));
self->setDate(t);
- scope.result = Encode(self->date());
+ return Encode(self->date());
}
-void DatePrototype::method_setFullYear(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_setFullYear(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- DateObject *self = callData->thisObject.as<DateObject>();
+ ExecutionEngine *v4 = b->engine();
+ DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
if (!self)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
double t = LocalTime(self->date());
+ if (v4->hasException)
+ return QV4::Encode::undefined();
if (std::isnan(t))
t = 0;
- double year = callData->argc ? callData->args[0].toNumber() : qt_qnan();
- double month = (callData->argc < 2) ? MonthFromTime(t) : callData->args[1].toNumber();
- double date = (callData->argc < 3) ? DateFromTime(t) : callData->args[2].toNumber();
+ double year = argc ? argv[0].toNumber() : qt_qnan();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
+ double month = (argc < 2) ? MonthFromTime(t) : argv[1].toNumber();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
+ double date = (argc < 3) ? DateFromTime(t) : argv[2].toNumber();
+ if (v4->hasException)
+ return QV4::Encode::undefined();
t = TimeClip(UTC(MakeDate(MakeDay(year, month, date), TimeWithinDay(t))));
self->setDate(t);
- scope.result = Encode(self->date());
+ return Encode(self->date());
}
-void DatePrototype::method_toUTCString(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_toUTCString(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- DateObject *self = callData->thisObject.as<DateObject>();
+ ExecutionEngine *v4 = b->engine();
+ DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
if (!self)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
double t = self->date();
- scope.result = scope.engine->newString(ToUTCString(t));
+ return Encode(v4->newString(ToUTCString(t)));
}
static void addZeroPrefixedInt(QString &str, int num, int nDigits)
@@ -1278,21 +1456,22 @@ static void addZeroPrefixedInt(QString &str, int num, int nDigits)
}
}
-void DatePrototype::method_toISOString(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_toISOString(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- DateObject *self = callData->thisObject.as<DateObject>();
+ ExecutionEngine *v4 = b->engine();
+ DateObject *self = const_cast<DateObject *>(thisObject->as<DateObject>());
if (!self)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
double t = self->date();
if (!std::isfinite(t))
- RETURN_RESULT(scope.engine->throwRangeError(callData->thisObject));
+ RETURN_RESULT(v4->throwRangeError(*thisObject));
QString result;
int year = (int)YearFromTime(t);
if (year < 0 || year > 9999) {
if (qAbs(year) >= 1000000)
- RETURN_RESULT(scope.engine->newString(QStringLiteral("Invalid Date")));
+ RETURN_RESULT(v4->newString(QStringLiteral("Invalid Date")));
result += year < 0 ? QLatin1Char('-') : QLatin1Char('+');
year = qAbs(year);
addZeroPrefixedInt(result, year, 6);
@@ -1313,29 +1492,30 @@ void DatePrototype::method_toISOString(const BuiltinFunction *, Scope &scope, Ca
addZeroPrefixedInt(result, msFromTime(t), 3);
result += QLatin1Char('Z');
- scope.result = scope.engine->newString(result);
+ return Encode(v4->newString(result));
}
-void DatePrototype::method_toJSON(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue DatePrototype::method_toJSON(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- ScopedObject O(scope, callData->thisObject.toObject(scope.engine));
- CHECK_EXCEPTION();
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+ ScopedObject O(scope, thisObject->toObject(v4));
+ if (v4->hasException)
+ return QV4::Encode::undefined();
ScopedValue tv(scope, RuntimeHelpers::toPrimitive(O, NUMBER_HINT));
if (tv->isNumber() && !std::isfinite(tv->toNumber()))
- RETURN_RESULT(Encode::null());
+ return Encode::null();
- ScopedString s(scope, scope.engine->newString(QStringLiteral("toISOString")));
+ ScopedString s(scope, v4->newString(QStringLiteral("toISOString")));
ScopedValue v(scope, O->get(s));
FunctionObject *toIso = v->as<FunctionObject>();
if (!toIso)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
- ScopedCallData cData(scope);
- cData->thisObject = callData->thisObject;
- toIso->call(scope, cData);
+ return toIso->call(O, nullptr, 0);
}
void DatePrototype::timezoneUpdated()
diff --git a/src/qml/jsruntime/qv4dateobject_p.h b/src/qml/jsruntime/qv4dateobject_p.h
index ecd57bcd8d..a4ab0a27ed 100644
--- a/src/qml/jsruntime/qv4dateobject_p.h
+++ b/src/qml/jsruntime/qv4dateobject_p.h
@@ -108,67 +108,67 @@ struct DateCtor: FunctionObject
{
V4_OBJECT2(DateCtor, FunctionObject)
- static void construct(const Managed *, Scope &scope, CallData *callData);
- static void call(const Managed *that, Scope &scope, CallData *);
+ static ReturnedValue callAsConstructor(const FunctionObject *, const Value *argv, int argc);
+ static ReturnedValue call(const FunctionObject *f, const Value *thisObject, const Value *argv, int);
};
-struct DatePrototype: DateObject
+struct DatePrototype: Object
{
V4_PROTOTYPE(objectPrototype)
void init(ExecutionEngine *engine, Object *ctor);
- static double getThisDate(Scope &scope, CallData *callData);
-
- static void method_parse(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_UTC(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_now(const BuiltinFunction *, Scope &scope, CallData *callData);
-
- static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_toDateString(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_toTimeString(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_toLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_toLocaleDateString(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_toLocaleTimeString(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_getTime(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_getYear(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_getFullYear(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_getUTCFullYear(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_getMonth(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_getUTCMonth(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_getDate(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_getUTCDate(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_getDay(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_getUTCDay(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_getHours(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_getUTCHours(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_getMinutes(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_getUTCMinutes(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_getSeconds(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_getUTCSeconds(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_getMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_getUTCMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_getTimezoneOffset(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_setTime(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_setMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_setUTCMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_setSeconds(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_setUTCSeconds(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_setMinutes(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_setUTCMinutes(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_setHours(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_setUTCHours(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_setDate(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_setUTCDate(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_setMonth(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_setUTCMonth(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_setYear(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_setFullYear(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_setUTCFullYear(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_toUTCString(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_toISOString(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_toJSON(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static double getThisDate(ExecutionEngine *v4, const Value *thisObject);
+
+ static ReturnedValue method_parse(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_UTC(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_now(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+
+ static ReturnedValue method_toString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_toDateString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_toTimeString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_toLocaleString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_toLocaleDateString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_toLocaleTimeString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_valueOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_getTime(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_getYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_getFullYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_getUTCFullYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_getMonth(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_getUTCMonth(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_getDate(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_getUTCDate(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_getDay(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_getUTCDay(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_getHours(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_getUTCHours(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_getMinutes(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_getUTCMinutes(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_getSeconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_getUTCSeconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_getMilliseconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_getUTCMilliseconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_getTimezoneOffset(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_setTime(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_setMilliseconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_setUTCMilliseconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_setSeconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_setUTCSeconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_setMinutes(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_setUTCMinutes(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_setHours(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_setUTCHours(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_setDate(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_setUTCDate(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_setMonth(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_setUTCMonth(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_setYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_setFullYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_setUTCFullYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_toUTCString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_toISOString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_toJSON(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
static void timezoneUpdated();
};
diff --git a/src/qml/jsruntime/qv4debugging_p.h b/src/qml/jsruntime/qv4debugging_p.h
index 8e2eec03d2..61a55964ab 100644
--- a/src/qml/jsruntime/qv4debugging_p.h
+++ b/src/qml/jsruntime/qv4debugging_p.h
@@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
namespace Debugging {
-#ifdef QT_NO_QML_DEBUGGER
+#if !QT_CONFIG(qml_debug)
class Debugger
{
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 0d3f29d089..ce29afdb6c 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -81,14 +81,6 @@
#include <QtCore/QTextStream>
#include <QDateTime>
-#ifdef V4_ENABLE_JIT
-#include "qv4isel_masm_p.h"
-#endif // V4_ENABLE_JIT
-
-#if QT_CONFIG(qml_interpreter)
-#include "qv4isel_moth_p.h"
-#endif
-
#if USE(PTHREADS)
# include <pthread.h>
#if !defined(Q_OS_INTEGRITY)
@@ -109,9 +101,9 @@ using namespace QV4;
static QBasicAtomicInt engineSerial = Q_BASIC_ATOMIC_INITIALIZER(1);
-void throwTypeError(const BuiltinFunction *, Scope &scope, CallData *)
+ReturnedValue throwTypeError(const FunctionObject *b, const QV4::Value *, const QV4::Value *, int)
{
- scope.result = scope.engine->throwTypeError();
+ return b->engine()->throwTypeError();
}
@@ -128,12 +120,16 @@ QQmlEngine *ExecutionEngine::qmlEngine() const
#endif // V4_BOOTSTRAP
qint32 ExecutionEngine::maxCallDepth = -1;
+#if defined(V4_ENABLE_JIT) && !defined(V4_BOOTSTRAP)
+const bool ExecutionEngine::canAllocateExecutableMemory = OSAllocator::canAllocateExecutableMemory();
+#endif
-ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
+ExecutionEngine::ExecutionEngine()
: executableAllocator(new QV4::ExecutableAllocator)
, regExpAllocator(new QV4::ExecutableAllocator)
, bumperPointerAllocator(new WTF::BumpPointerAllocator)
, jsStack(new WTF::PageAllocation)
+ , gcStack(new WTF::PageAllocation)
, globalCode(0)
, v8Engine(0)
, argumentsAccessors(0)
@@ -148,52 +144,42 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
bool ok = false;
maxCallDepth = qEnvironmentVariableIntValue("QV4_MAX_CALL_DEPTH", &ok);
if (!ok || maxCallDepth <= 0) {
+#ifdef QT_NO_DEBUG
maxCallDepth = 1234;
- }
- }
- Q_ASSERT(maxCallDepth > 0);
-
- if (!factory) {
-#if QT_CONFIG(qml_interpreter)
- bool jitDisabled = true;
-
-#ifdef V4_ENABLE_JIT
- static const bool forceMoth = !qEnvironmentVariableIsEmpty("QV4_FORCE_INTERPRETER") ||
- !OSAllocator::canAllocateExecutableMemory();
- if (forceMoth) {
- factory = new Moth::ISelFactory;
- } else {
- factory = new JIT::ISelFactory<>;
- jitDisabled = false;
- }
-#else // !V4_ENABLE_JIT
- factory = new Moth::ISelFactory;
-#endif // V4_ENABLE_JIT
-
- if (jitDisabled) {
- qWarning("JIT is disabled for QML. Property bindings and animations will be "
- "very slow. Visit https://wiki.qt.io/V4 to learn about possible "
- "solutions for your platform.");
- }
#else
- factory = new JIT::ISelFactory<>;
+ // no (tail call) optimization is done, so there'll be a lot mare stack frames active
+ maxCallDepth = 200;
#endif
+ }
}
- iselFactory.reset(factory);
+ Q_ASSERT(maxCallDepth > 0);
// reserve space for the JS stack
- // we allow it to grow to 2 times JSStackLimit, as we can overshoot due to garbage collection
- // and ScopedValues allocated outside of JIT'ed methods.
- *jsStack = WTF::PageAllocation::allocate(2 * JSStackLimit, WTF::OSAllocator::JSVMStackPages,
+ // we allow it to grow to a bit more than JSStackLimit, as we can overshoot due to ScopedValues
+ // allocated outside of JIT'ed methods.
+ *jsStack = WTF::PageAllocation::allocate(JSStackLimit + 256*1024, WTF::OSAllocator::JSVMStackPages,
/* writable */ true, /* executable */ false,
/* includesGuardPages */ true);
jsStackBase = (Value *)jsStack->base();
#ifdef V4_USE_VALGRIND
- VALGRIND_MAKE_MEM_UNDEFINED(jsStackBase, 2*JSStackLimit);
+ VALGRIND_MAKE_MEM_UNDEFINED(jsStackBase, JSStackLimit + 256*1024);
#endif
jsStackTop = jsStackBase;
+ *gcStack = WTF::PageAllocation::allocate(GCStackLimit, WTF::OSAllocator::JSVMStackPages,
+ /* writable */ true, /* executable */ false,
+ /* includesGuardPages */ true);
+
+ {
+ bool ok = false;
+ jitCallCountThreshold = qEnvironmentVariableIntValue("QV4_JIT_CALL_THRESHOLD", &ok);
+ if (!ok)
+ jitCallCountThreshold = 3;
+ if (qEnvironmentVariableIsSet("QV4_FORCE_INTERPRETER"))
+ jitCallCountThreshold = std::numeric_limits<int>::max();
+ }
+
exceptionValue = jsAlloca(1);
globalObject = static_cast<Object *>(jsAlloca(1));
jsObjects = jsAlloca(NJSObjects);
@@ -214,7 +200,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
internalClasses[Class_SimpleArrayData] = internalClasses[EngineBase::Class_Empty]->changeVTable(QV4::SimpleArrayData::staticVTable());
internalClasses[Class_SparseArrayData] = internalClasses[EngineBase::Class_Empty]->changeVTable(QV4::SparseArrayData::staticVTable());
internalClasses[Class_ExecutionContext] = internalClasses[EngineBase::Class_Empty]->changeVTable(QV4::ExecutionContext::staticVTable());
- internalClasses[EngineBase::Class_QmlContext] = internalClasses[EngineBase::Class_ExecutionContext]->changeVTable(QV4::QmlContext::staticVTable());
+ internalClasses[Class_QmlContext] = internalClasses[EngineBase::Class_ExecutionContext]->changeVTable(QV4::QmlContext::staticVTable());
internalClasses[Class_CallContext] = internalClasses[EngineBase::Class_Empty]->changeVTable(QV4::CallContext::staticVTable());
jsStrings[String_Empty] = newIdentifier(QString());
@@ -257,7 +243,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
InternalClass *ic = internalClasses[Class_Empty]->changeVTable(QV4::Object::staticVTable());
jsObjects[ObjectProto] = memoryManager->allocObject<ObjectPrototype>(ic);
internalClasses[Class_Object] = ic->changePrototype(objectPrototype()->d());
- internalClasses[EngineBase::Class_QmlContextWrapper] = internalClasses[Class_Object]->changeVTable(QV4::QmlContextWrapper::staticVTable());
+ internalClasses[EngineBase::Class_QmlContextWrapper] = internalClasses[Class_Object]->changeVTable(QV4::QQmlContextWrapper::staticVTable());
ic = newInternalClass(ArrayPrototype::staticVTable(), objectPrototype());
Q_ASSERT(ic->prototype);
@@ -270,6 +256,8 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
InternalClass *argsClass = newInternalClass(ArgumentsObject::staticVTable(), objectPrototype());
argsClass = argsClass->addMember(id_length(), Attr_NotEnumerable);
internalClasses[EngineBase::Class_ArgumentsObject] = argsClass->addMember(id_callee(), Attr_Data|Attr_NotEnumerable);
+ argsClass = newInternalClass(StrictArgumentsObject::staticVTable(), objectPrototype());
+ argsClass = argsClass->addMember(id_length(), Attr_NotEnumerable);
argsClass = argsClass->addMember(id_callee(), Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
internalClasses[EngineBase::Class_StrictArgumentsObject] = argsClass->addMember(id_caller(), Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
@@ -301,8 +289,6 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
ic = ic->changeVTable(ScriptFunction::staticVTable());
internalClasses[EngineBase::Class_ScriptFunction] = ic->addMember(id_length(), Attr_ReadOnly, &index);
Q_ASSERT(index == Heap::ScriptFunction::Index_Length);
- internalClasses[EngineBase::Class_BuiltinFunction] = ic->changeVTable(BuiltinFunction::staticVTable());
- Q_ASSERT(index == Heap::ScriptFunction::Index_Length);
internalClasses[EngineBase::Class_ObjectProto] = internalClasses[Class_Object]->addMember(id_constructor(), Attr_NotEnumerable, &index);
Q_ASSERT(index == Heap::FunctionObject::Index_ProtoConstructor);
@@ -346,7 +332,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
internalClasses[EngineBase::Class_ErrorProto] = ic->addMember(id_name(), Attr_Data|Attr_NotEnumerable, &index);
Q_ASSERT(index == ErrorPrototype::Index_Name);
- jsObjects[GetStack_Function] = BuiltinFunction::create(rootContext(), str = newIdentifier(QStringLiteral("stack")), ErrorObject::method_get_stack);
+ jsObjects[GetStack_Function] = FunctionObject::createBuiltinFunction(rootContext(), str = newIdentifier(QStringLiteral("stack")), ErrorObject::method_get_stack);
getStackFunction()->defineReadonlyProperty(id_length(), Primitive::fromInt32(0));
jsObjects[ErrorProto] = memoryManager->allocObject<ErrorPrototype>(internalClasses[EngineBase::Class_ErrorProto], objectPrototype());
@@ -422,13 +408,13 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
//
// set up the global object
//
- rootContext()->d()->global = globalObject->d();
- rootContext()->d()->callData->thisObject = globalObject;
+ rootContext()->d()->activation.set(scope.engine, globalObject->d());
Q_ASSERT(globalObject->d()->vtable());
globalObject->defineDefaultProperty(QStringLiteral("Object"), *objectCtor());
globalObject->defineDefaultProperty(QStringLiteral("String"), *stringCtor());
- globalObject->defineDefaultProperty(QStringLiteral("Number"), *numberCtor());
+ FunctionObject *numberObject = numberCtor();
+ globalObject->defineDefaultProperty(QStringLiteral("Number"), *numberObject);
globalObject->defineDefaultProperty(QStringLiteral("Boolean"), *booleanCtor());
globalObject->defineDefaultProperty(QStringLiteral("Array"), *arrayCtor());
globalObject->defineDefaultProperty(QStringLiteral("Function"), *functionCtor());
@@ -458,8 +444,26 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
jsObjects[Eval_Function] = memoryManager->allocObject<EvalFunction>(global);
globalObject->defineDefaultProperty(QStringLiteral("eval"), *evalFunction());
- globalObject->defineDefaultProperty(QStringLiteral("parseInt"), GlobalFunctions::method_parseInt, 2);
- globalObject->defineDefaultProperty(QStringLiteral("parseFloat"), GlobalFunctions::method_parseFloat, 1);
+ // ES6: 20.1.2.12 & 20.1.2.13:
+ // parseInt and parseFloat must be the same FunctionObject on the global &
+ // Number object.
+ {
+ QString piString(QStringLiteral("parseInt"));
+ QString pfString(QStringLiteral("parseFloat"));
+ Scope scope(this);
+ ScopedString pi(scope, newIdentifier(piString));
+ ScopedString pf(scope, newIdentifier(pfString));
+ ExecutionContext *global = rootContext();
+ ScopedFunctionObject parseIntFn(scope, FunctionObject::createBuiltinFunction(global, pi, GlobalFunctions::method_parseInt));
+ ScopedFunctionObject parseFloatFn(scope, FunctionObject::createBuiltinFunction(global, pf, GlobalFunctions::method_parseFloat));
+ parseIntFn->defineReadonlyConfigurableProperty(id_length(), Primitive::fromInt32(2));
+ parseFloatFn->defineReadonlyConfigurableProperty(id_length(), Primitive::fromInt32(1));
+ globalObject->defineDefaultProperty(piString, parseIntFn);
+ globalObject->defineDefaultProperty(pfString, parseFloatFn);
+ numberObject->defineDefaultProperty(piString, parseIntFn);
+ numberObject->defineDefaultProperty(pfString, parseFloatFn);
+ }
+
globalObject->defineDefaultProperty(QStringLiteral("isNaN"), GlobalFunctions::method_isNaN, 1);
globalObject->defineDefaultProperty(QStringLiteral("isFinite"), GlobalFunctions::method_isFinite, 1);
globalObject->defineDefaultProperty(QStringLiteral("decodeURI"), GlobalFunctions::method_decodeURI, 1);
@@ -470,7 +474,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
globalObject->defineDefaultProperty(QStringLiteral("unescape"), GlobalFunctions::method_unescape, 1);
ScopedString name(scope, newString(QStringLiteral("thrower")));
- jsObjects[ThrowerObject] = BuiltinFunction::create(global, name, ::throwTypeError);
+ jsObjects[ThrowerObject] = FunctionObject::createBuiltinFunction(global, name, ::throwTypeError);
}
ExecutionEngine::~ExecutionEngine()
@@ -491,10 +495,12 @@ ExecutionEngine::~ExecutionEngine()
delete executableAllocator;
jsStack->deallocate();
delete jsStack;
+ gcStack->deallocate();
+ delete gcStack;
delete [] argumentsAccessors;
}
-#ifndef QT_NO_QML_DEBUGGER
+#if QT_CONFIG(qml_debug)
void ExecutionEngine::setDebugger(Debugging::Debugger *debugger)
{
Q_ASSERT(!m_debugger);
@@ -506,24 +512,16 @@ void ExecutionEngine::setProfiler(Profiling::Profiler *profiler)
Q_ASSERT(!m_profiler);
m_profiler.reset(profiler);
}
-#endif // QT_NO_QML_DEBUGGER
+#endif // QT_CONFIG(qml_debug)
void ExecutionEngine::initRootContext()
{
Scope scope(this);
- Scoped<GlobalContext> r(scope, memoryManager->allocManaged<GlobalContext>(
- sizeof(GlobalContext::Data) + sizeof(CallData)));
- r->d_unchecked()->init(this);
- r->d()->callData = reinterpret_cast<CallData *>(r->d() + 1);
- r->d()->callData->tag = quint32(Value::ValueTypeInternal::Integer);
- r->d()->callData->argc = 0;
- r->d()->callData->thisObject = globalObject;
- r->d()->callData->args[0] = Encode::undefined();
+ Scoped<ExecutionContext> r(scope, memoryManager->allocManaged<ExecutionContext>(sizeof(ExecutionContext::Data)));
+ r->d_unchecked()->init(Heap::ExecutionContext::Type_GlobalContext);
+ r->d()->activation.set(this, globalObject->d());
jsObjects[RootContext] = r;
jsObjects[IntegerNull] = Encode((int)0);
-
- currentContext = static_cast<ExecutionContext *>(jsObjects + RootContext);
- current = currentContext->d();
}
InternalClass *ExecutionEngine::newClass(const InternalClass &other)
@@ -531,14 +529,6 @@ InternalClass *ExecutionEngine::newClass(const InternalClass &other)
return new (classPool) InternalClass(other);
}
-ExecutionContext *ExecutionEngine::pushGlobalContext()
-{
- pushContext(rootContext()->d());
-
- Q_ASSERT(current == rootContext()->d());
- return currentContext;
-}
-
InternalClass *ExecutionEngine::newInternalClass(const VTable *vtable, Object *prototype)
{
return internalClasses[EngineBase::Class_Empty]->changeVTable(vtable)->changePrototype(prototype ? prototype->d() : 0);
@@ -602,12 +592,20 @@ Heap::ArrayObject *ExecutionEngine::newArrayObject(const Value *values, int leng
size_t size = sizeof(Heap::ArrayData) + (length-1)*sizeof(Value);
Heap::SimpleArrayData *d = scope.engine->memoryManager->allocManaged<SimpleArrayData>(size);
d->init();
- d->alloc = length;
d->type = Heap::ArrayData::Simple;
d->offset = 0;
- d->len = length;
- memcpy(&d->arrayData, values, length*sizeof(Value));
- a->d()->arrayData = d;
+ d->values.alloc = length;
+ d->values.size = length;
+ // this doesn't require a write barrier, things will be ok, when the new array data gets inserted into
+ // the parent object
+ memcpy(&d->values.values, values, length*sizeof(Value));
+ for (int i = 0; i < length; ++i) {
+ if (values[i].isManaged()) {
+ d->needsMark = true;
+ break;
+ }
+ }
+ a->d()->arrayData.set(this, d);
a->setArrayLengthUnchecked(length);
}
return a->d();
@@ -659,9 +657,9 @@ Heap::DateObject *ExecutionEngine::newDateObjectFromTime(const QTime &t)
Heap::RegExpObject *ExecutionEngine::newRegExpObject(const QString &pattern, int flags)
{
- bool global = (flags & IR::RegExp::RegExp_Global);
- bool ignoreCase = (flags & IR::RegExp::RegExp_IgnoreCase);
- bool multiline = (flags & IR::RegExp::RegExp_Multiline);
+ bool global = (flags & QV4::CompiledData::RegExp::RegExp_Global);
+ bool ignoreCase = (flags & QV4::CompiledData::RegExp::RegExp_IgnoreCase);
+ bool multiline = (flags & QV4::CompiledData::RegExp::RegExp_Multiline);
Scope scope(this);
Scoped<RegExp> re(scope, RegExp::create(this, pattern, ignoreCase, multiline, global));
@@ -734,11 +732,9 @@ Heap::Object *ExecutionEngine::newForEachIteratorObject(Object *o)
Heap::QmlContext *ExecutionEngine::qmlContext() const
{
- Heap::ExecutionContext *ctx = current;
-
- // get the correct context when we're within a builtin function
- if (ctx->type == Heap::ExecutionContext::Type_SimpleCallContext && !ctx->outer)
- ctx = parentContext(currentContext)->d();
+ if (!currentStackFrame)
+ return 0;
+ Heap::ExecutionContext *ctx = currentContext()->d();
if (ctx->type != Heap::ExecutionContext::Type_QmlContext && !ctx->outer)
return 0;
@@ -759,7 +755,7 @@ QObject *ExecutionEngine::qmlScopeObject() const
if (!ctx)
return 0;
- return ctx->qml->scopeObject;
+ return ctx->qml()->scopeObject;
}
ReturnedValue ExecutionEngine::qmlSingletonWrapper(String *name)
@@ -789,57 +785,56 @@ QQmlContextData *ExecutionEngine::callingQmlContext() const
if (!ctx)
return 0;
- return ctx->qml->context->contextData();
+ return ctx->qml()->context->contextData();
}
-QVector<StackFrame> ExecutionEngine::stackTrace(int frameLimit) const
+QString CppStackFrame::source() const
{
- Scope scope(const_cast<ExecutionEngine *>(this));
- ScopedString name(scope);
- QVector<StackFrame> stack;
-
- ExecutionContext *c = currentContext;
- while (c && frameLimit) {
- QV4::Function *function = c->getFunction();
- if (function) {
- StackFrame frame;
- frame.source = function->sourceFile();
- name = function->name();
- frame.function = name->toQString();
-
- // line numbers can be negative for places where you can't set a real breakpoint
- frame.line = qAbs(c->d()->lineNumber);
- frame.column = -1;
-
- stack.append(frame);
- --frameLimit;
- }
- c = parentContext(c);
- }
-
- if (frameLimit && globalCode) {
- StackFrame frame;
- frame.source = globalCode->sourceFile();
- frame.function = globalCode->name()->toQString();
- frame.line = rootContext()->d()->lineNumber;
- frame.column = -1;
+ return v4Function->sourceFile();
+}
- stack.append(frame);
- }
- return stack;
+QString CppStackFrame::function() const
+{
+ return v4Function->name()->toQString();
}
-StackFrame ExecutionEngine::currentStackFrame() const
+int CppStackFrame::lineNumber() const
{
- StackFrame frame;
- frame.line = -1;
- frame.column = -1;
+ auto findLine = [](const CompiledData::CodeOffsetToLine &entry, uint offset) {
+ return entry.codeOffset < offset;
+ };
- QVector<StackFrame> trace = stackTrace(/*limit*/ 1);
- if (!trace.isEmpty())
- frame = trace.first();
+ const QV4::CompiledData::Function *cf = v4Function->compiledFunction;
+ uint offset = instructionPointer;
+ const CompiledData::CodeOffsetToLine *lineNumbers = cf->lineNumberTable();
+ uint nLineNumbers = cf->nLineNumbers;
+ const CompiledData::CodeOffsetToLine *line = std::lower_bound(lineNumbers, lineNumbers + nLineNumbers, offset, findLine) - 1;
+ return line->line;
+}
- return frame;
+ReturnedValue CppStackFrame::thisObject() const {
+ return jsFrame->thisObject.asReturnedValue();
+}
+
+StackTrace ExecutionEngine::stackTrace(int frameLimit) const
+{
+ Scope scope(const_cast<ExecutionEngine *>(this));
+ ScopedString name(scope);
+ StackTrace stack;
+
+ CppStackFrame *f = currentStackFrame;
+ while (f && frameLimit) {
+ QV4::StackFrame frame;
+ frame.source = f->source();
+ frame.function = f->function();
+ frame.line = qAbs(f->lineNumber());
+ frame.column = -1;
+ stack.append(frame);
+ --frameLimit;
+ f = f->parent;
+ }
+
+ return stack;
}
/* Helper and "C" linkage exported function to format a GDBMI stacktrace for
@@ -882,14 +877,13 @@ QUrl ExecutionEngine::resolvedUrl(const QString &file)
return src;
QUrl base;
- ExecutionContext *c = currentContext;
- while (c) {
- CallContext *callCtx = c->asCallContext();
- if (callCtx && callCtx->d()->v4Function) {
- base = callCtx->d()->v4Function->finalUrl();
+ CppStackFrame *f = currentStackFrame;
+ while (f) {
+ if (f->v4Function) {
+ base = f->v4Function->finalUrl();
break;
}
- c = parentContext(c);
+ f = f->parent;
}
if (base.isEmpty() && globalCode)
@@ -927,35 +921,24 @@ void ExecutionEngine::requireArgumentsAccessors(int n)
}
}
-static void drainMarkStack(ExecutionEngine *engine, QV4::Value *markBase)
+void ExecutionEngine::markObjects(MarkStack *markStack)
{
- while (engine->jsStackTop > markBase) {
- Heap::Base *h = engine->popForGC();
- Q_ASSERT (h->vtable()->markObjects);
- h->vtable()->markObjects(h, engine);
- }
-}
-
-void ExecutionEngine::markObjects()
-{
- Value *markBase = jsStackTop;
- identifierTable->mark(this);
+ identifierTable->mark(markStack);
for (int i = 0; i < nArgumentsAccessors; ++i) {
const Property &pd = argumentsAccessors[i];
if (Heap::FunctionObject *getter = pd.getter())
- getter->mark(this);
+ getter->mark(markStack);
if (Heap::FunctionObject *setter = pd.setter())
- setter->mark(this);
+ setter->mark(markStack);
}
- classPool->markObjects(this);
-
- drainMarkStack(this, markBase);
+ classPool->markObjects(markStack);
+ markStack->drain();
for (auto compilationUnit: compilationUnits) {
- compilationUnit->markObjects(this);
- drainMarkStack(this, markBase);
+ compilationUnit->markObjects(markStack);
+ markStack->drain();
}
}
@@ -1150,9 +1133,9 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int
return QVariant::fromValue(QV4::JsonObject::toJsonObject(object));
} else if (QV4::QObjectWrapper *wrapper = object->as<QV4::QObjectWrapper>()) {
return qVariantFromValue<QObject *>(wrapper->object());
- } else if (object->as<QV4::QmlContextWrapper>()) {
+ } else if (object->as<QV4::QQmlContextWrapper>()) {
return QVariant();
- } else if (QV4::QmlTypeWrapper *w = object->as<QV4::QmlTypeWrapper>()) {
+ } else if (QV4::QQmlTypeWrapper *w = object->as<QV4::QQmlTypeWrapper>()) {
return w->toVariant();
} else if (QV4::QQmlValueTypeWrapper *v = object->as<QV4::QQmlValueTypeWrapper>()) {
return v->toVariant();
@@ -1355,7 +1338,7 @@ QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant)
case QMetaType::QDateTime:
return QV4::Encode(newDateObject(*reinterpret_cast<const QDateTime *>(ptr)));
case QMetaType::QDate:
- return QV4::Encode(newDateObject(QDateTime(*reinterpret_cast<const QDate *>(ptr))));
+ return QV4::Encode(newDateObject(QDateTime(*reinterpret_cast<const QDate *>(ptr), QTime(0, 0, 0), Qt::UTC)));
case QMetaType::QTime:
return QV4::Encode(newDateObjectFromTime(*reinterpret_cast<const QTime *>(ptr)));
case QMetaType::QRegExp:
@@ -1574,15 +1557,9 @@ QV4::ReturnedValue ExecutionEngine::metaTypeToJS(int type, const void *data)
return 0;
}
-void ExecutionEngine::assertObjectBelongsToEngine(const Heap::Base &baseObject)
-{
- Q_ASSERT(!baseObject.vtable()->isObject || static_cast<const Heap::Object&>(baseObject).internalClass->engine == this);
- Q_UNUSED(baseObject);
-}
-
-void ExecutionEngine::failStackLimitCheck(Scope &scope)
+ReturnedValue ExecutionEngine::global()
{
- scope.result = throwRangeError(QStringLiteral("Maximum call stack size exceeded."));
+ return globalObject->asReturnedValue();
}
// Converts a JS value to a meta-type.
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index fee06ebc58..930ad8fed1 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -51,13 +51,14 @@
//
#include "qv4global_p.h"
-#include "private/qv4isel_p.h"
#include "qv4managed_p.h"
#include "qv4context_p.h"
#include <private/qintrusivelist_p.h>
#include "qv4enginebase_p.h"
+
#ifndef V4_BOOTSTRAP
+# include "qv4function_p.h"
# include <private/qv8engine_p.h>
# include <private/qv4compileddata_p.h>
#endif
@@ -86,9 +87,36 @@ namespace CompiledData {
struct CompilationUnit;
}
+struct Function;
struct InternalClass;
struct InternalClassPool;
+struct Q_QML_EXPORT CppStackFrame {
+ CppStackFrame *parent;
+ Function *v4Function;
+ CallData *jsFrame;
+ const Value *originalArguments;
+ int originalArgumentsCount;
+ int instructionPointer;
+
+ QString source() const;
+ QString function() const;
+ inline QV4::ExecutionContext *context() const {
+ return static_cast<ExecutionContext *>(&jsFrame->context);
+ }
+ int lineNumber() const;
+
+ inline QV4::Heap::CallContext *callContext() const {
+ Heap::ExecutionContext *ctx = static_cast<ExecutionContext &>(jsFrame->context).d();\
+ while (ctx->type != Heap::ExecutionContext::Type_CallContext)
+ ctx = ctx->outer;
+ return static_cast<Heap::CallContext *>(ctx);
+ }
+ ReturnedValue thisObject() const;
+};
+
+
+
struct Q_QML_EXPORT ExecutionEngine : public EngineBase
{
private:
@@ -100,21 +128,16 @@ private:
public:
ExecutableAllocator *executableAllocator;
ExecutableAllocator *regExpAllocator;
- QScopedPointer<EvalISelFactory> iselFactory;
WTF::BumpPointerAllocator *bumperPointerAllocator; // Used by Yarr Regex engine.
- enum { JSStackLimit = 4*1024*1024 };
+ enum {
+ JSStackLimit = 4*1024*1024,
+ GCStackLimit = 2*1024*1024
+ };
WTF::PageAllocation *jsStack;
- void pushForGC(Heap::Base *m) {
- *jsStackTop = m;
- ++jsStackTop;
- }
- Heap::Base *popForGC() {
- --jsStackTop;
- return jsStackTop->heapObject();
- }
+ WTF::PageAllocation *gcStack;
QML_NEARLY_ALWAYS_INLINE Value *jsAlloca(int nValues) {
Value *ptr = jsStackTop;
@@ -187,7 +210,7 @@ public:
Value *jsObjects;
enum { NTypedArrayTypes = 9 }; // == TypedArray::NValues, avoid header dependency
- GlobalContext *rootContext() const { return reinterpret_cast<GlobalContext *>(jsObjects + RootContext); }
+ ExecutionContext *rootContext() const { return reinterpret_cast<ExecutionContext *>(jsObjects + RootContext); }
FunctionObject *objectCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + Object_Ctor); }
FunctionObject *stringCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + String_Ctor); }
FunctionObject *numberCtor() const { return reinterpret_cast<FunctionObject *>(jsObjects + Number_Ctor); }
@@ -346,10 +369,12 @@ public:
// bookkeeping.
MultiplyWrappedQObjectMap *m_multiplyWrappedQObjects;
- ExecutionEngine(EvalISelFactory *iselFactory = 0);
+ int internalClassIdCount = 0;
+
+ ExecutionEngine();
~ExecutionEngine();
-#ifdef QT_NO_QML_DEBUGGER
+#if !QT_CONFIG(qml_debug)
QV4::Debugging::Debugger *debugger() const { return nullptr; }
QV4::Profiling::Profiler *profiler() const { return nullptr; }
@@ -361,13 +386,14 @@ public:
void setDebugger(Debugging::Debugger *debugger);
void setProfiler(Profiling::Profiler *profiler);
-#endif // QT_NO_QML_DEBUGGER
+#endif // QT_CONFIG(qml_debug)
- ExecutionContext *pushGlobalContext();
- void pushContext(Heap::ExecutionContext *context);
- void pushContext(ExecutionContext *context);
- void popContext();
- ExecutionContext *parentContext(ExecutionContext *context) const;
+ void setCurrentContext(Heap::ExecutionContext *context);
+ ExecutionContext *currentContext() const {
+ return static_cast<ExecutionContext *>(&currentStackFrame->jsFrame->context);
+ }
+
+ int newInternalClassId() { return ++internalClassIdCount; }
InternalClass *newInternalClass(const VTable *vtable, Object *prototype);
@@ -417,19 +443,16 @@ public:
StackTrace stackTrace(int frameLimit = -1) const;
- StackFrame currentStackFrame() const;
QUrl resolvedUrl(const QString &file);
void requireArgumentsAccessors(int n);
- void markObjects();
+ void markObjects(MarkStack *markStack);
void initRootContext();
InternalClass *newClass(const InternalClass &other);
- // Exception handling
- Value *exceptionValue;
StackTrace exceptionStackTrace;
ReturnedValue throwError(const Value &value);
@@ -459,17 +482,33 @@ public:
bool metaTypeFromJS(const Value *value, int type, void *data);
QV4::ReturnedValue metaTypeToJS(int type, const void *data);
- void assertObjectBelongsToEngine(const Heap::Base &baseObject);
+ bool checkStackLimits();
- bool checkStackLimits(Scope &scope);
+ bool canJIT(Function *f = nullptr)
+ {
+#if defined(V4_ENABLE_JIT) && !defined(V4_BOOTSTRAP)
+ if (!canAllocateExecutableMemory)
+ return false;
+ if (f)
+ return f->interpreterCallCount >= jitCallCountThreshold;
+ return true;
+#else
+ Q_UNUSED(f);
+ return false;
+#endif
+ }
-private:
- void failStackLimitCheck(Scope &scope);
+ QV4::ReturnedValue global();
-#ifndef QT_NO_QML_DEBUGGER
+private:
+#if QT_CONFIG(qml_debug)
QScopedPointer<QV4::Debugging::Debugger> m_debugger;
QScopedPointer<QV4::Profiling::Profiler> m_profiler;
#endif
+ int jitCallCountThreshold;
+#if defined(V4_ENABLE_JIT) && !defined(V4_BOOTSTRAP)
+ static const bool canAllocateExecutableMemory;
+#endif
};
// This is a trick to tell the code generators that functions taking a NoThrowContext won't
@@ -483,62 +522,12 @@ struct NoThrowEngine;
#endif
-inline void ExecutionEngine::pushContext(Heap::ExecutionContext *context)
-{
- Q_ASSERT(currentContext && context);
- Value *v = jsAlloca(2);
- v[0] = Encode(context);
- v[1] = Encode((int)(v - static_cast<Value *>(currentContext)));
- currentContext = static_cast<ExecutionContext *>(v);
- current = currentContext->d();
-}
-
-inline void ExecutionEngine::pushContext(ExecutionContext *context)
-{
- pushContext(context->d());
-}
-
-
-inline void ExecutionEngine::popContext()
-{
- Q_ASSERT(jsStackTop > currentContext);
- QV4::Value *offset = (currentContext + 1);
- Q_ASSERT(offset->isInteger());
- int o = offset->integerValue();
- Q_ASSERT(o);
- currentContext -= o;
- current = currentContext->d();
-}
-
-inline ExecutionContext *ExecutionEngine::parentContext(ExecutionContext *context) const
-{
- Value *offset = static_cast<Value *>(context) + 1;
- Q_ASSERT(offset->isInteger());
- int o = offset->integerValue();
- return o ? context - o : 0;
-}
-
-inline
-void Heap::Base::mark(QV4::ExecutionEngine *engine)
-{
- Q_ASSERT(inUse());
- if (isMarked())
- return;
-#ifndef QT_NO_DEBUG
- engine->assertObjectBelongsToEngine(*this);
-#endif
- setMarkBit();
- engine->pushForGC(this);
-}
-
-inline void Value::mark(ExecutionEngine *e)
+inline void ExecutionEngine::setCurrentContext(Heap::ExecutionContext *context)
{
- Heap::Base *o = heapObject();
- if (o)
- o->mark(e);
+ currentStackFrame->jsFrame->context = context;
}
-#define CHECK_STACK_LIMITS(v4, scope) if ((v4)->checkStackLimits(scope)) return; \
+#define CHECK_STACK_LIMITS(v4) if ((v4)->checkStackLimits()) return Encode::undefined(); \
ExecutionEngineCallDepthRecorder _executionEngineCallDepthRecorder(v4);
struct ExecutionEngineCallDepthRecorder
@@ -549,10 +538,10 @@ struct ExecutionEngineCallDepthRecorder
~ExecutionEngineCallDepthRecorder() { --ee->callDepth; }
};
-inline bool ExecutionEngine::checkStackLimits(Scope &scope)
+inline bool ExecutionEngine::checkStackLimits()
{
if (Q_UNLIKELY((jsStackTop > jsStackLimit) || (callDepth >= maxCallDepth))) {
- failStackLimitCheck(scope);
+ throwRangeError(QStringLiteral("Maximum call stack size exceeded."));
return true;
}
diff --git a/src/qml/jsruntime/qv4enginebase_p.h b/src/qml/jsruntime/qv4enginebase_p.h
index 38b5ed8909..59fb4a564a 100644
--- a/src/qml/jsruntime/qv4enginebase_p.h
+++ b/src/qml/jsruntime/qv4enginebase_p.h
@@ -57,29 +57,36 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
+struct CppStackFrame;
+
// Base class for the execution engine
#if defined(Q_CC_MSVC) || defined(Q_CC_GNU)
#pragma pack(push, 1)
#endif
-struct EngineBase {
- Heap::ExecutionContext *current = 0;
+struct Q_QML_EXPORT EngineBase {
+
+ CppStackFrame *currentStackFrame = nullptr;
- Value *jsStackTop = 0;
- quint32 hasException = false;
+ Value *jsStackTop = nullptr;
+ quint8 hasException = false;
+ quint8 writeBarrierActive = false;
+ quint16 unused = 0;
#if QT_POINTER_SIZE == 8
quint8 padding[4];
#endif
- MemoryManager *memoryManager = 0;
+ MemoryManager *memoryManager = nullptr;
Runtime runtime;
qint32 callDepth = 0;
- Value *jsStackLimit = 0;
- Value *jsStackBase = 0;
+ Value *jsStackLimit = nullptr;
+ Value *jsStackBase = nullptr;
+
+ IdentifierTable *identifierTable = nullptr;
+ Object *globalObject = nullptr;
- ExecutionContext *currentContext = 0;
- IdentifierTable *identifierTable = 0;
- Object *globalObject = 0;
+ // Exception handling
+ Value *exceptionValue = nullptr;
enum {
Class_Empty,
@@ -94,7 +101,6 @@ struct EngineBase {
Class_FunctionObject,
Class_StringObject,
Class_ScriptFunction,
- Class_BuiltinFunction,
Class_ObjectProto,
Class_RegExp,
Class_RegExpObject,
@@ -115,8 +121,8 @@ struct EngineBase {
#endif
Q_STATIC_ASSERT(std::is_standard_layout<EngineBase>::value);
-Q_STATIC_ASSERT(offsetof(EngineBase, current) == 0);
-Q_STATIC_ASSERT(offsetof(EngineBase, jsStackTop) == offsetof(EngineBase, current) + QT_POINTER_SIZE);
+Q_STATIC_ASSERT(offsetof(EngineBase, currentStackFrame) == 0);
+Q_STATIC_ASSERT(offsetof(EngineBase, jsStackTop) == offsetof(EngineBase, currentStackFrame) + QT_POINTER_SIZE);
Q_STATIC_ASSERT(offsetof(EngineBase, hasException) == offsetof(EngineBase, jsStackTop) + QT_POINTER_SIZE);
Q_STATIC_ASSERT(offsetof(EngineBase, memoryManager) == offsetof(EngineBase, hasException) + QT_POINTER_SIZE);
Q_STATIC_ASSERT(offsetof(EngineBase, runtime) == offsetof(EngineBase, memoryManager) + QT_POINTER_SIZE);
diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp
index 6811438915..90e158ba37 100644
--- a/src/qml/jsruntime/qv4errorobject.cpp
+++ b/src/qml/jsruntime/qv4errorobject.cpp
@@ -51,7 +51,6 @@
#include <private/qqmljslexer_p.h>
#include <private/qqmljsparser_p.h>
#include <private/qqmljsast_p.h>
-#include <qv4jsir_p.h>
#include <qv4codegen_p.h>
#ifndef Q_OS_WIN
@@ -78,10 +77,10 @@ void Heap::ErrorObject::init()
if (internalClass == scope.engine->internalClasses[EngineBase::Class_ErrorProto])
return;
- *propertyData(QV4::ErrorObject::Index_Stack) = scope.engine->getStackFunction();
- *propertyData(QV4::ErrorObject::Index_Stack + QV4::Object::SetterOffset) = Encode::undefined();
- *propertyData(QV4::ErrorObject::Index_FileName) = Encode::undefined();
- *propertyData(QV4::ErrorObject::Index_LineNumber) = Encode::undefined();
+ setProperty(scope.engine, QV4::ErrorObject::Index_Stack, scope.engine->getStackFunction()->d());
+ setProperty(scope.engine, QV4::ErrorObject::Index_Stack + QV4::Object::SetterOffset, Primitive::undefinedValue());
+ setProperty(scope.engine, QV4::ErrorObject::Index_FileName, Primitive::undefinedValue());
+ setProperty(scope.engine, QV4::ErrorObject::Index_LineNumber, Primitive::undefinedValue());
}
void Heap::ErrorObject::init(const Value &message, ErrorType t)
@@ -92,29 +91,30 @@ void Heap::ErrorObject::init(const Value &message, ErrorType t)
Scope scope(internalClass->engine);
Scoped<QV4::ErrorObject> e(scope, this);
- *propertyData(QV4::ErrorObject::Index_Stack) = scope.engine->getStackFunction();
- *propertyData(QV4::ErrorObject::Index_Stack + QV4::Object::SetterOffset) = Encode::undefined();
+ setProperty(scope.engine, QV4::ErrorObject::Index_Stack, scope.engine->getStackFunction()->d());
+ setProperty(scope.engine, QV4::ErrorObject::Index_Stack + QV4::Object::SetterOffset, Primitive::undefinedValue());
e->d()->stackTrace = new StackTrace(scope.engine->stackTrace());
if (!e->d()->stackTrace->isEmpty()) {
- *propertyData(QV4::ErrorObject::Index_FileName) = scope.engine->newString(e->d()->stackTrace->at(0).source);
- *propertyData(QV4::ErrorObject::Index_LineNumber) = Primitive::fromInt32(e->d()->stackTrace->at(0).line);
+ setProperty(scope.engine, QV4::ErrorObject::Index_FileName, scope.engine->newString(e->d()->stackTrace->at(0).source));
+ setProperty(scope.engine, QV4::ErrorObject::Index_LineNumber, Primitive::fromInt32(e->d()->stackTrace->at(0).line));
}
if (!message.isUndefined())
- *propertyData(QV4::ErrorObject::Index_Message) = message;
+ setProperty(scope.engine, QV4::ErrorObject::Index_Message, message);
}
void Heap::ErrorObject::init(const Value &message, const QString &fileName, int line, int column, ErrorObject::ErrorType t)
{
+ Q_UNUSED(fileName); // ####
Object::init();
errorType = t;
Scope scope(internalClass->engine);
Scoped<QV4::ErrorObject> e(scope, this);
- *propertyData(QV4::ErrorObject::Index_Stack) = scope.engine->getStackFunction();
- *propertyData(QV4::ErrorObject::Index_Stack + QV4::Object::SetterOffset) = Encode::undefined();
+ setProperty(scope.engine, QV4::ErrorObject::Index_Stack, scope.engine->getStackFunction()->d());
+ setProperty(scope.engine, QV4::ErrorObject::Index_Stack + QV4::Object::SetterOffset, Primitive::undefinedValue());
e->d()->stackTrace = new StackTrace(scope.engine->stackTrace());
StackFrame frame;
@@ -123,13 +123,12 @@ void Heap::ErrorObject::init(const Value &message, const QString &fileName, int
frame.column = column;
e->d()->stackTrace->prepend(frame);
- if (!e->d()->stackTrace->isEmpty()) {
- *propertyData(QV4::ErrorObject::Index_FileName) = scope.engine->newString(e->d()->stackTrace->at(0).source);
- *propertyData(QV4::ErrorObject::Index_LineNumber) = Primitive::fromInt32(e->d()->stackTrace->at(0).line);
- }
+ Q_ASSERT(!e->d()->stackTrace->isEmpty());
+ setProperty(scope.engine, QV4::ErrorObject::Index_FileName, scope.engine->newString(e->d()->stackTrace->at(0).source));
+ setProperty(scope.engine, QV4::ErrorObject::Index_LineNumber, Primitive::fromInt32(e->d()->stackTrace->at(0).line));
if (!message.isUndefined())
- *propertyData(QV4::ErrorObject::Index_Message) = message;
+ setProperty(scope.engine, QV4::ErrorObject::Index_Message, message);
}
const char *ErrorObject::className(Heap::ErrorObject::ErrorType t)
@@ -153,11 +152,12 @@ const char *ErrorObject::className(Heap::ErrorObject::ErrorType t)
Q_UNREACHABLE();
}
-void ErrorObject::method_get_stack(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ErrorObject::method_get_stack(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<ErrorObject> This(scope, callData->thisObject);
+ ExecutionEngine *v4 = b->engine();
+ const ErrorObject *This = thisObject->as<ErrorObject>();
if (!This)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
if (!This->d()->stack) {
QString trace;
for (int i = 0; i < This->d()->stackTrace->count(); ++i) {
@@ -168,17 +168,9 @@ void ErrorObject::method_get_stack(const BuiltinFunction *, Scope &scope, CallDa
if (frame.line >= 0)
trace += QLatin1Char(':') + QString::number(frame.line);
}
- This->d()->stack = scope.engine->newString(trace);
+ This->d()->stack.set(v4, v4->newString(trace));
}
- scope.result = This->d()->stack;
-}
-
-void ErrorObject::markObjects(Heap::Base *that, ExecutionEngine *e)
-{
- ErrorObject::Data *This = static_cast<ErrorObject::Data *>(that);
- if (This->stack)
- This->stack->mark(e);
- Object::markObjects(that, e);
+ return This->d()->stack->asReturnedValue();
}
DEFINE_OBJECT_VTABLE(ErrorObject);
@@ -241,15 +233,15 @@ void Heap::ErrorCtor::init(QV4::ExecutionContext *scope, const QString &name)
Heap::FunctionObject::init(scope, name);
}
-void ErrorCtor::construct(const Managed *, Scope &scope, CallData *callData)
+ReturnedValue ErrorCtor::callAsConstructor(const FunctionObject *f, const Value *argv, int argc)
{
- ScopedValue v(scope, callData->argument(0));
- scope.result = ErrorObject::create<ErrorObject>(scope.engine, v);
+ Value v = argc ? *argv : Primitive::undefinedValue();
+ return ErrorObject::create<ErrorObject>(f->engine(), v)->asReturnedValue();
}
-void ErrorCtor::call(const Managed *that, Scope &scope, CallData *callData)
+ReturnedValue ErrorCtor::call(const FunctionObject *f, const Value *, const Value *argv, int argc)
{
- static_cast<const Object *>(that)->construct(scope, callData);
+ return f->callAsConstructor(argv, argc);
}
void Heap::EvalErrorCtor::init(QV4::ExecutionContext *scope)
@@ -257,10 +249,10 @@ void Heap::EvalErrorCtor::init(QV4::ExecutionContext *scope)
Heap::ErrorCtor::init(scope, QStringLiteral("EvalError"));
}
-void EvalErrorCtor::construct(const Managed *, Scope &scope, CallData *callData)
+ReturnedValue EvalErrorCtor::callAsConstructor(const FunctionObject *f, const Value *argv, int argc)
{
- ScopedValue v(scope, callData->argument(0));
- scope.result = ErrorObject::create<EvalErrorObject>(scope.engine, v);
+ Value v = argc ? *argv : Primitive::undefinedValue();
+ return ErrorObject::create<EvalErrorObject>(f->engine(), v)->asReturnedValue();
}
void Heap::RangeErrorCtor::init(QV4::ExecutionContext *scope)
@@ -268,10 +260,10 @@ void Heap::RangeErrorCtor::init(QV4::ExecutionContext *scope)
Heap::ErrorCtor::init(scope, QStringLiteral("RangeError"));
}
-void RangeErrorCtor::construct(const Managed *, Scope &scope, CallData *callData)
+ReturnedValue RangeErrorCtor::callAsConstructor(const FunctionObject *f, const Value *argv, int argc)
{
- ScopedValue v(scope, callData->argument(0));
- scope.result = ErrorObject::create<RangeErrorObject>(scope.engine, v);
+ Value v = argc ? *argv : Primitive::undefinedValue();
+ return ErrorObject::create<RangeErrorObject>(f->engine(), v)->asReturnedValue();
}
void Heap::ReferenceErrorCtor::init(QV4::ExecutionContext *scope)
@@ -279,10 +271,10 @@ void Heap::ReferenceErrorCtor::init(QV4::ExecutionContext *scope)
Heap::ErrorCtor::init(scope, QStringLiteral("ReferenceError"));
}
-void ReferenceErrorCtor::construct(const Managed *, Scope &scope, CallData *callData)
+ReturnedValue ReferenceErrorCtor::callAsConstructor(const FunctionObject *f, const Value *argv, int argc)
{
- ScopedValue v(scope, callData->argument(0));
- scope.result = ErrorObject::create<ReferenceErrorObject>(scope.engine, v);
+ Value v = argc ? *argv : Primitive::undefinedValue();
+ return ErrorObject::create<ReferenceErrorObject>(f->engine(), v)->asReturnedValue();
}
void Heap::SyntaxErrorCtor::init(QV4::ExecutionContext *scope)
@@ -290,10 +282,10 @@ void Heap::SyntaxErrorCtor::init(QV4::ExecutionContext *scope)
Heap::ErrorCtor::init(scope, QStringLiteral("SyntaxError"));
}
-void SyntaxErrorCtor::construct(const Managed *, Scope &scope, CallData *callData)
+ReturnedValue SyntaxErrorCtor::callAsConstructor(const FunctionObject *f, const Value *argv, int argc)
{
- ScopedValue v(scope, callData->argument(0));
- scope.result = ErrorObject::create<SyntaxErrorObject>(scope.engine, v);
+ Value v = argc ? *argv : Primitive::undefinedValue();
+ return ErrorObject::create<SyntaxErrorObject>(f->engine(), v)->asReturnedValue();
}
void Heap::TypeErrorCtor::init(QV4::ExecutionContext *scope)
@@ -301,10 +293,10 @@ void Heap::TypeErrorCtor::init(QV4::ExecutionContext *scope)
Heap::ErrorCtor::init(scope, QStringLiteral("TypeError"));
}
-void TypeErrorCtor::construct(const Managed *, Scope &scope, CallData *callData)
+ReturnedValue TypeErrorCtor::callAsConstructor(const FunctionObject *f, const Value *argv, int argc)
{
- ScopedValue v(scope, callData->argument(0));
- scope.result = ErrorObject::create<TypeErrorObject>(scope.engine, v);
+ Value v = argc ? *argv : Primitive::undefinedValue();
+ return ErrorObject::create<TypeErrorObject>(f->engine(), v)->asReturnedValue();
}
void Heap::URIErrorCtor::init(QV4::ExecutionContext *scope)
@@ -312,10 +304,10 @@ void Heap::URIErrorCtor::init(QV4::ExecutionContext *scope)
Heap::ErrorCtor::init(scope, QStringLiteral("URIError"));
}
-void URIErrorCtor::construct(const Managed *, Scope &scope, CallData *callData)
+ReturnedValue URIErrorCtor::callAsConstructor(const FunctionObject *f, const Value *argv, int argc)
{
- ScopedValue v(scope, callData->argument(0));
- scope.result = ErrorObject::create<URIErrorObject>(scope.engine, v);
+ Value v = argc ? *argv : Primitive::undefinedValue();
+ return ErrorObject::create<URIErrorObject>(f->engine(), v)->asReturnedValue();
}
void ErrorPrototype::init(ExecutionEngine *engine, Object *ctor, Object *obj, Heap::ErrorObject::ErrorType t)
@@ -325,18 +317,20 @@ void ErrorPrototype::init(ExecutionEngine *engine, Object *ctor, Object *obj, He
ScopedObject o(scope);
ctor->defineReadonlyProperty(engine->id_prototype(), (o = obj));
ctor->defineReadonlyProperty(engine->id_length(), Primitive::fromInt32(1));
- *obj->propertyData(Index_Constructor) = ctor;
- *obj->propertyData(Index_Message) = engine->id_empty();
- *obj->propertyData(Index_Name) = engine->newString(QString::fromLatin1(ErrorObject::className(t)));
+ obj->setProperty(Index_Constructor, ctor->d());
+ obj->setProperty(Index_Message, engine->id_empty()->d());
+ obj->setProperty(Index_Name, engine->newString(QString::fromLatin1(ErrorObject::className(t))));
obj->defineDefaultProperty(engine->id_toString(), method_toString, 0);
}
-void ErrorPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ErrorPrototype::method_toString(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Object *o = callData->thisObject.as<Object>();
+ ExecutionEngine *v4 = b->engine();
+ const Object *o = thisObject->as<Object>();
if (!o)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
+ Scope scope(v4);
ScopedValue name(scope, o->get(scope.engine->id_name()));
QString qname;
if (name->isUndefined())
@@ -359,5 +353,5 @@ void ErrorPrototype::method_toString(const BuiltinFunction *, Scope &scope, Call
str = qname + QLatin1String(": ") + qmessage;
}
- scope.result = scope.engine->newString(str)->asReturnedValue();
+ return scope.engine->newString(str)->asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h
index 12531c9309..a5ee0eb886 100644
--- a/src/qml/jsruntime/qv4errorobject_p.h
+++ b/src/qml/jsruntime/qv4errorobject_p.h
@@ -62,7 +62,12 @@ struct SyntaxErrorObject;
namespace Heap {
-struct ErrorObject : Object {
+
+#define ErrorObjectMembers(class, Member) \
+ Member(class, Pointer, String *, stack)
+
+DECLARE_HEAP_OBJECT(ErrorObject, Object) {
+ DECLARE_MARKOBJECTS(ErrorObject);
enum ErrorType {
Error,
EvalError,
@@ -72,6 +77,8 @@ struct ErrorObject : Object {
TypeError,
URIError
};
+ StackTrace *stackTrace;
+ ErrorType errorType;
void init();
void init(const Value &message, ErrorType t = Error);
@@ -80,10 +87,6 @@ struct ErrorObject : Object {
delete stackTrace;
Object::destroy();
}
-
- ErrorType errorType;
- StackTrace *stackTrace;
- Pointer<String> stack;
};
struct EvalErrorObject : ErrorObject {
@@ -172,8 +175,7 @@ struct ErrorObject: Object {
static const char *className(Heap::ErrorObject::ErrorType t);
- static void method_get_stack(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void markObjects(Heap::Base *that, ExecutionEngine *e);
+ static ReturnedValue method_get_stack(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
};
template<>
@@ -227,50 +229,50 @@ struct ErrorCtor: FunctionObject
{
V4_OBJECT2(ErrorCtor, FunctionObject)
- static void construct(const Managed *, Scope &scope, CallData *callData);
- static void call(const Managed *that, Scope &scope, CallData *callData);
+ static ReturnedValue callAsConstructor(const FunctionObject *f, const Value *argv, int argc);
+ static ReturnedValue call(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
};
struct EvalErrorCtor: ErrorCtor
{
V4_OBJECT2(EvalErrorCtor, ErrorCtor)
- static void construct(const Managed *m, Scope &scope, CallData *callData);
+ static ReturnedValue callAsConstructor(const FunctionObject *f, const Value *argv, int argc);
};
struct RangeErrorCtor: ErrorCtor
{
V4_OBJECT2(RangeErrorCtor, ErrorCtor)
- static void construct(const Managed *, Scope &scope, CallData *callData);
+ static ReturnedValue callAsConstructor(const FunctionObject *f, const Value *argv, int argc);
};
struct ReferenceErrorCtor: ErrorCtor
{
V4_OBJECT2(ReferenceErrorCtor, ErrorCtor)
- static void construct(const Managed *m, Scope &scope, CallData *callData);
+ static ReturnedValue callAsConstructor(const FunctionObject *f, const Value *argv, int argc);
};
struct SyntaxErrorCtor: ErrorCtor
{
V4_OBJECT2(SyntaxErrorCtor, ErrorCtor)
- static void construct(const Managed *m, Scope &scope, CallData *callData);
+ static ReturnedValue callAsConstructor(const FunctionObject *f, const Value *argv, int argc);
};
struct TypeErrorCtor: ErrorCtor
{
V4_OBJECT2(TypeErrorCtor, ErrorCtor)
- static void construct(const Managed *m, Scope &scope, CallData *callData);
+ static ReturnedValue callAsConstructor(const FunctionObject *f, const Value *argv, int argc);
};
struct URIErrorCtor: ErrorCtor
{
V4_OBJECT2(URIErrorCtor, ErrorCtor)
- static void construct(const Managed *m, Scope &scope, CallData *callData);
+ static ReturnedValue callAsConstructor(const FunctionObject *f, const Value *argv, int argc);
};
@@ -284,7 +286,7 @@ struct ErrorPrototype : ErrorObject
void init(ExecutionEngine *engine, Object *ctor) { init(engine, ctor, this, Heap::ErrorObject::Error); }
static void init(ExecutionEngine *engine, Object *ctor, Object *obj, Heap::ErrorObject::ErrorType t);
- static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_toString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
};
struct EvalErrorPrototype : ErrorObject
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp
index f78555dbda..83e861138b 100644
--- a/src/qml/jsruntime/qv4function.cpp
+++ b/src/qml/jsruntime/qv4function.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "qv4function_p.h"
+#include "qv4functionobject_p.h"
#include "qv4managed_p.h"
#include "qv4string_p.h"
#include "qv4value_p.h"
@@ -45,79 +46,83 @@
#include "qv4lookup_p.h"
#include <private/qv4mm_p.h>
#include <private/qv4identifiertable_p.h>
+#include <assembler/MacroAssemblerCodeRef.h>
QT_BEGIN_NAMESPACE
using namespace QV4;
-Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit, const CompiledData::Function *function,
- ReturnedValue (*codePtr)(ExecutionEngine *, const uchar *))
+Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit, const CompiledData::Function *function, Code codePtr)
: compiledFunction(function)
, compilationUnit(unit)
, code(codePtr)
- , codeData(0)
+ , codeData(function->code())
+ , jittedCode(nullptr)
+ , codeRef(nullptr)
, hasQmlDependencies(function->hasQmlDependencies())
{
- internalClass = engine->internalClasses[EngineBase::Class_Empty];
- const CompiledData::LEUInt32 *formalsIndices = compiledFunction->formalsTable();
- // iterate backwards, so we get the right ordering for duplicate names
- Scope scope(engine);
- ScopedString arg(scope);
- for (int i = static_cast<int>(compiledFunction->nFormals - 1); i >= 0; --i) {
- arg = compilationUnit->runtimeStrings[formalsIndices[i]];
- while (1) {
- InternalClass *newClass = internalClass->addMember(arg, Attr_NotConfigurable);
- if (newClass != internalClass) {
- internalClass = newClass;
- break;
- }
- // duplicate arguments, need some trick to store them
- MemoryManager *mm = engine->memoryManager;
- arg = mm->alloc<String>(arg->d(), engine->newString(QString(0xfffe)));
- }
- }
- nFormals = compiledFunction->nFormals;
+ Q_UNUSED(engine);
+
+ internalClass = engine->internalClasses[EngineBase::Class_CallContext];
- const CompiledData::LEUInt32 *localsIndices = compiledFunction->localsTable();
+ // first locals
+ const quint32_le *localsIndices = compiledFunction->localsTable();
for (quint32 i = 0; i < compiledFunction->nLocals; ++i)
internalClass = internalClass->addMember(engine->identifierTable->identifier(compilationUnit->runtimeStrings[localsIndices[i]]), Attr_NotConfigurable);
- activationRequired = compiledFunction->nInnerFunctions > 0 || (compiledFunction->flags & (CompiledData::Function::HasDirectEval | CompiledData::Function::UsesArgumentsObject));
+ const quint32_le *formalsIndices = compiledFunction->formalsTable();
+ for (quint32 i = 0; i < compiledFunction->nFormals; ++i)
+ internalClass = internalClass->addMember(engine->identifierTable->identifier(compilationUnit->runtimeStrings[formalsIndices[i]]), Attr_NotConfigurable);
- canUseSimpleCall = !needsActivation() && !(compiledFunction->flags & CompiledData::Function::HasCatchOrWith) &&
- !(compiledFunction->nFormals > QV4::Global::ReservedArgumentCount) && !isNamedExpression();
+ nFormals = compiledFunction->nFormals;
}
Function::~Function()
{
+ delete codeRef;
}
void Function::updateInternalClass(ExecutionEngine *engine, const QList<QByteArray> &parameters)
{
- internalClass = engine->internalClasses[EngineBase::Class_Empty];
+ QStringList parameterNames;
- // iterate backwards, so we get the right ordering for duplicate names
- Scope scope(engine);
- ScopedString arg(scope);
- for (int i = parameters.size() - 1; i >= 0; --i) {
- arg = engine->newString(QString::fromUtf8(parameters.at(i)));
- while (1) {
- InternalClass *newClass = internalClass->addMember(arg, Attr_NotConfigurable);
- if (newClass != internalClass) {
- internalClass = newClass;
+ // Resolve duplicate parameter names:
+ for (int i = 0, ei = parameters.count(); i != ei; ++i) {
+ const QByteArray &param = parameters.at(i);
+ int duplicate = -1;
+
+ for (int j = i - 1; j >= 0; --j) {
+ const QByteArray &prevParam = parameters.at(j);
+ if (param == prevParam) {
+ duplicate = j;
break;
}
- // duplicate arguments, need some trick to store them
- arg = engine->memoryManager->alloc<String>(arg->d(), engine->newString(QString(0xfffe)));
}
+
+ if (duplicate == -1) {
+ parameterNames.append(QString::fromUtf8(param));
+ } else {
+ const QString &dup = parameterNames[duplicate];
+ parameterNames.append(dup);
+ parameterNames[duplicate] =
+ QString(0xfffe) + QString::number(duplicate) + dup;
+ }
+
+ }
+
+ internalClass = engine->internalClasses[EngineBase::Class_CallContext];
+
+ Scope scope(engine);
+ ScopedString arg(scope);
+ for (const QString &parameterName : parameterNames) {
+ arg = engine->newString(parameterName);
+ internalClass = internalClass->addMember(arg, Attr_NotConfigurable);
}
nFormals = parameters.size();
- const CompiledData::LEUInt32 *localsIndices = compiledFunction->localsTable();
+ const quint32_le *localsIndices = compiledFunction->localsTable();
for (quint32 i = 0; i < compiledFunction->nLocals; ++i)
internalClass = internalClass->addMember(engine->identifierTable->identifier(compilationUnit->runtimeStrings[localsIndices[i]]), Attr_NotConfigurable);
-
- activationRequired = true;
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h
index b212b3d027..4c8c790ca7 100644
--- a/src/qml/jsruntime/qv4function_p.h
+++ b/src/qml/jsruntime/qv4function_p.h
@@ -54,6 +54,11 @@
#include <private/qqmlglobal_p.h>
#include <private/qv4compileddata_p.h>
#include <private/qv4context_p.h>
+#include <private/qv4vme_moth_p.h>
+
+namespace JSC {
+class MacroAssemblerCodeRef;
+}
QT_BEGIN_NAMESPACE
@@ -63,18 +68,25 @@ struct Q_QML_EXPORT Function {
const CompiledData::Function *compiledFunction;
CompiledData::CompilationUnit *compilationUnit;
- ReturnedValue (*code)(ExecutionEngine *, const uchar *);
+ ReturnedValue call(const Value *thisObject, const Value *argv, int argc, const ExecutionContext *context) {
+ return Moth::VME::exec(this, thisObject, argv, argc, context);
+ }
+
+ typedef ReturnedValue (*Code)(const FunctionObject *fo, const Value *thisObject, const Value *argv, int argc);
+ Code code;
const uchar *codeData;
+ typedef ReturnedValue (*JittedCode)(CppStackFrame *, ExecutionEngine *);
+ JittedCode jittedCode;
+ JSC::MacroAssemblerCodeRef *codeRef;
+
// first nArguments names in internalClass are the actual arguments
InternalClass *internalClass;
uint nFormals;
- bool activationRequired;
+ int interpreterCallCount = 0;
bool hasQmlDependencies;
- bool canUseSimpleCall;
- Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit, const CompiledData::Function *function,
- ReturnedValue (*codePtr)(ExecutionEngine *, const uchar *));
+ Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit, const CompiledData::Function *function, Code codePtr);
~Function();
// used when dynamically assigning signal handlers (QQmlConnection)
@@ -88,27 +100,13 @@ struct Q_QML_EXPORT Function {
inline bool usesArgumentsObject() const { return compiledFunction->flags & CompiledData::Function::UsesArgumentsObject; }
inline bool isStrict() const { return compiledFunction->flags & CompiledData::Function::IsStrict; }
- inline bool isNamedExpression() const { return compiledFunction->flags & CompiledData::Function::IsNamedExpression; }
-
- inline bool needsActivation() const
- { return activationRequired; }
-
- inline bool canUseSimpleFunction() const { return canUseSimpleCall; }
QQmlSourceLocation sourceLocation() const
{
return QQmlSourceLocation(sourceFile(), compiledFunction->location.line, compiledFunction->location.column);
}
-
};
-
-inline unsigned int Heap::CallContext::formalParameterCount() const
-{
- return v4Function ? v4Function->nFormals : 0;
-}
-
-
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index 63396998fa..165f1801ea 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -38,8 +38,6 @@
****************************************************************************/
#include "qv4object_p.h"
-#include "qv4jsir_p.h"
-#include "qv4isel_p.h"
#include "qv4objectproto_p.h"
#include "qv4stringobject_p.h"
#include "qv4function_p.h"
@@ -55,9 +53,10 @@
#include <private/qqmljsast_p.h>
#include <private/qqmljavascriptexpression_p.h>
#include <private/qqmlengine_p.h>
-#include <qv4codegen_p.h>
+#include <qv4runtimecodegen_p.h>
#include "private/qlocale_tools_p.h"
#include "private/qqmlbuiltinfunctions_p.h"
+#include <private/qv4jscall_p.h>
#include <QtCore/QDebug>
#include <algorithm>
@@ -69,11 +68,28 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(FunctionObject);
+void Heap::FunctionObject::init(QV4::ExecutionContext *scope, QV4::String *name,
+ ReturnedValue (*code)(const QV4::FunctionObject *, const Value *thisObject, const Value *argv, int argc))
+{
+ jsCall = code;
+ jsConstruct = QV4::FunctionObject::callAsConstructor;
+
+ Object::init();
+ function = nullptr;
+ this->scope.set(scope->engine(), scope->d());
+ Scope s(scope->engine());
+ ScopedFunctionObject f(s, this);
+ f->init(name, false);
+}
+
void Heap::FunctionObject::init(QV4::ExecutionContext *scope, QV4::String *name, bool createProto)
{
+ jsCall = reinterpret_cast<const ObjectVTable *>(vtable())->call;
+ jsConstruct = reinterpret_cast<const ObjectVTable *>(vtable())->callAsConstructor;
+
Object::init();
function = nullptr;
- this->scope = scope->d();
+ this->scope.set(scope->engine(), scope->d());
Scope s(scope->engine());
ScopedFunctionObject f(s, this);
f->init(name, createProto);
@@ -81,10 +97,13 @@ void Heap::FunctionObject::init(QV4::ExecutionContext *scope, QV4::String *name,
void Heap::FunctionObject::init(QV4::ExecutionContext *scope, Function *function, bool createProto)
{
+ jsCall = reinterpret_cast<const ObjectVTable *>(vtable())->call;
+ jsConstruct = reinterpret_cast<const ObjectVTable *>(vtable())->callAsConstructor;
+
Object::init();
this->function = function;
function->compilationUnit->addref();
- this->scope = scope->d();
+ this->scope.set(scope->engine(), scope->d());
Scope s(scope->engine());
ScopedString name(s, function->name());
ScopedFunctionObject f(s, this);
@@ -100,11 +119,14 @@ void Heap::FunctionObject::init(QV4::ExecutionContext *scope, const QString &nam
void Heap::FunctionObject::init()
{
+ jsCall = reinterpret_cast<const ObjectVTable *>(vtable())->call;
+ jsConstruct = reinterpret_cast<const ObjectVTable *>(vtable())->callAsConstructor;
+
Object::init();
function = nullptr;
- this->scope = internalClass->engine->rootContext()->d();
+ this->scope.set(internalClass->engine, internalClass->engine->rootContext()->d());
Q_ASSERT(internalClass && internalClass->find(internalClass->engine->id_prototype()) == Index_Prototype);
- *propertyData(Index_Prototype) = Encode::undefined();
+ setProperty(internalClass->engine, Index_Prototype, Primitive::undefinedValue());
}
@@ -124,14 +146,14 @@ void FunctionObject::init(String *n, bool createProto)
if (createProto) {
ScopedObject proto(s, s.engine->newObject(s.engine->internalClasses[EngineBase::Class_ObjectProto], s.engine->objectPrototype()));
Q_ASSERT(s.engine->internalClasses[EngineBase::Class_ObjectProto]->find(s.engine->id_constructor()) == Heap::FunctionObject::Index_ProtoConstructor);
- *proto->propertyData(Heap::FunctionObject::Index_ProtoConstructor) = this->asReturnedValue();
- *propertyData(Heap::FunctionObject::Index_Prototype) = proto.asReturnedValue();
+ proto->setProperty(Heap::FunctionObject::Index_ProtoConstructor, d());
+ setProperty(Heap::FunctionObject::Index_Prototype, proto);
} else {
- *propertyData(Heap::FunctionObject::Index_Prototype) = Encode::undefined();
+ setProperty(Heap::FunctionObject::Index_Prototype, Primitive::undefinedValue());
}
if (n)
- defineReadonlyProperty(s.engine->id_name(), *n);
+ defineReadonlyConfigurableProperty(s.engine->id_name(), *n);
}
ReturnedValue FunctionObject::name() const
@@ -139,23 +161,14 @@ ReturnedValue FunctionObject::name() const
return get(scope()->internalClass->engine->id_name());
}
-void FunctionObject::construct(const Managed *that, Scope &scope, CallData *)
-{
- scope.result = static_cast<const FunctionObject *>(that)->engine()->throwTypeError();
-}
-
-void FunctionObject::call(const Managed *, Scope &scope, CallData *)
+ReturnedValue FunctionObject::callAsConstructor(const FunctionObject *f, const Value *, int)
{
- scope.result = Encode::undefined();
+ return f->engine()->throwTypeError();
}
-void FunctionObject::markObjects(Heap::Base *that, ExecutionEngine *e)
+ReturnedValue FunctionObject::call(const FunctionObject *, const Value *, const Value *, int)
{
- Heap::FunctionObject *o = static_cast<Heap::FunctionObject *>(that);
- if (o->scope)
- o->scope->mark(e);
-
- Object::markObjects(that, e);
+ return Encode::undefined();
}
Heap::FunctionObject *FunctionObject::createScriptFunction(ExecutionContext *scope, Function *function)
@@ -186,24 +199,22 @@ void Heap::FunctionCtor::init(QV4::ExecutionContext *scope)
}
// 15.3.2
-void FunctionCtor::construct(const Managed *that, Scope &scope, CallData *callData)
+ReturnedValue FunctionCtor::callAsConstructor(const FunctionObject *f, const Value *argv, int argc)
{
- Scoped<FunctionCtor> f(scope, static_cast<const FunctionCtor *>(that));
+ Scope scope(f->engine());
QString arguments;
QString body;
- if (callData->argc > 0) {
- for (int i = 0; i < callData->argc - 1; ++i) {
+ if (argc > 0) {
+ for (int i = 0, ei = argc - 1; i < ei; ++i) {
if (i)
arguments += QLatin1String(", ");
- arguments += callData->args[i].toQString();
+ arguments += argv[i].toQString();
}
- body = callData->args[callData->argc - 1].toQString();
- }
- if (scope.engine->hasException) {
- scope.result = Encode::undefined();
- return;
+ body = argv[argc - 1].toQString();
}
+ if (scope.engine->hasException)
+ return Encode::undefined();
QString function = QLatin1String("function(") + arguments + QLatin1String("){") + body + QLatin1Char('}');
@@ -214,36 +225,30 @@ void FunctionCtor::construct(const Managed *that, Scope &scope, CallData *callDa
const bool parsed = parser.parseExpression();
- if (!parsed) {
- scope.result = scope.engine->throwSyntaxError(QLatin1String("Parse error"));
- return;
- }
+ if (!parsed)
+ return scope.engine->throwSyntaxError(QLatin1String("Parse error"));
- using namespace QQmlJS::AST;
- FunctionExpression *fe = QQmlJS::AST::cast<FunctionExpression *>(parser.rootNode());
- if (!fe) {
- scope.result = scope.engine->throwSyntaxError(QLatin1String("Parse error"));
- return;
- }
-
- IR::Module module(scope.engine->debugger() != 0);
+ QQmlJS::AST::FunctionExpression *fe = QQmlJS::AST::cast<QQmlJS::AST::FunctionExpression *>(parser.rootNode());
+ if (!fe)
+ return scope.engine->throwSyntaxError(QLatin1String("Parse error"));
- QQmlJS::RuntimeCodegen cg(scope.engine, f->strictMode());
- cg.generateFromFunctionExpression(QString(), QString(), function, fe, &module);
+ Compiler::Module module(scope.engine->debugger() != 0);
Compiler::JSUnitGenerator jsGenerator(&module);
- QScopedPointer<EvalInstructionSelection> isel(scope.engine->iselFactory->create(QQmlEnginePrivate::get(scope.engine), scope.engine->executableAllocator, &module, &jsGenerator));
- QQmlRefPointer<CompiledData::CompilationUnit> compilationUnit = isel->compile();
+ RuntimeCodegen cg(scope.engine, &jsGenerator, false);
+ cg.generateFromFunctionExpression(QString(), function, fe, &module);
+
+ QQmlRefPointer<CompiledData::CompilationUnit> compilationUnit = cg.generateCompilationUnit();
Function *vmf = compilationUnit->linkToEngine(scope.engine);
ExecutionContext *global = scope.engine->rootContext();
- scope.result = FunctionObject::createScriptFunction(global, vmf);
+ return Encode(FunctionObject::createScriptFunction(global, vmf));
}
// 15.3.1: This is equivalent to new Function(...)
-void FunctionCtor::call(const Managed *that, Scope &scope, CallData *callData)
+ReturnedValue FunctionCtor::call(const FunctionObject *f, const Value *, const Value *argv, int argc)
{
- construct(that, scope, callData);
+ return callAsConstructor(f, argv, argc);
}
DEFINE_OBJECT_VTABLE(FunctionPrototype);
@@ -258,10 +263,10 @@ void FunctionPrototype::init(ExecutionEngine *engine, Object *ctor)
Scope scope(engine);
ScopedObject o(scope);
- ctor->defineReadonlyProperty(engine->id_length(), Primitive::fromInt32(1));
+ ctor->defineReadonlyConfigurableProperty(engine->id_length(), Primitive::fromInt32(1));
ctor->defineReadonlyProperty(engine->id_prototype(), (o = this));
- defineReadonlyProperty(engine->id_length(), Primitive::fromInt32(0));
+ defineReadonlyConfigurableProperty(engine->id_length(), Primitive::fromInt32(0));
defineDefaultProperty(QStringLiteral("constructor"), (o = ctor));
defineDefaultProperty(engine->id_toString(), method_toString, 0);
defineDefaultProperty(QStringLiteral("apply"), method_apply, 2);
@@ -270,157 +275,123 @@ void FunctionPrototype::init(ExecutionEngine *engine, Object *ctor)
}
-void FunctionPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue FunctionPrototype::method_toString(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- FunctionObject *fun = callData->thisObject.as<FunctionObject>();
+ ExecutionEngine *v4 = b->engine();
+ const FunctionObject *fun = thisObject->as<FunctionObject>();
if (!fun)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
- scope.result = scope.engine->newString(QStringLiteral("function() { [code] }"));
+ return Encode(v4->newString(QStringLiteral("function() { [code] }")));
}
-void FunctionPrototype::method_apply(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue FunctionPrototype::method_apply(const QV4::FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- FunctionObject *o = callData->thisObject.as<FunctionObject>();
- if (!o)
- THROW_TYPE_ERROR();
-
- ScopedValue arg(scope, callData->argument(1));
+ ExecutionEngine *v4 = b->engine();
+ const FunctionObject *f = thisObject->as<FunctionObject>();
+ if (!f)
+ return v4->throwTypeError();
+ thisObject = argc ? argv : nullptr;
+ if (argc < 2 || argv[1].isNullOrUndefined())
+ return f->call(thisObject, argv, 0);
- ScopedObject arr(scope, arg);
-
- quint32 len;
- if (!arr) {
- len = 0;
- if (!arg->isNullOrUndefined())
- THROW_TYPE_ERROR();
- } else {
- len = arr->getLength();
- }
+ Object *arr = argv[1].objectValue();
+ if (!arr)
+ return v4->throwTypeError();
- ScopedCallData cData(scope, len);
+ uint len = arr->getLength();
+ Scope scope(v4);
+ Value *arguments = v4->jsAlloca(len);
if (len) {
if (ArgumentsObject::isNonStrictArgumentsObject(arr) && !arr->cast<ArgumentsObject>()->fullyCreated()) {
QV4::ArgumentsObject *a = arr->cast<ArgumentsObject>();
- int l = qMin(len, (uint)a->d()->context->callData->argc);
- memcpy(cData->args, a->d()->context->callData->args, l*sizeof(Value));
+ int l = qMin(len, (uint)a->d()->context->argc());
+ memcpy(arguments, a->d()->context->args(), l*sizeof(Value));
for (quint32 i = l; i < len; ++i)
- cData->args[i] = Primitive::undefinedValue();
+ arguments[i] = Primitive::undefinedValue();
} else if (arr->arrayType() == Heap::ArrayData::Simple && !arr->protoHasArray()) {
auto sad = static_cast<Heap::SimpleArrayData *>(arr->arrayData());
- uint alen = sad ? sad->len : 0;
+ uint alen = sad ? sad->values.size : 0;
if (alen > len)
alen = len;
for (uint i = 0; i < alen; ++i)
- cData->args[i] = sad->data(i);
+ arguments[i] = sad->data(i);
for (quint32 i = alen; i < len; ++i)
- cData->args[i] = Primitive::undefinedValue();
+ arguments[i] = Primitive::undefinedValue();
} else {
for (quint32 i = 0; i < len; ++i)
- cData->args[i] = arr->getIndexed(i);
+ arguments[i] = arr->getIndexed(i);
}
}
- cData->thisObject = callData->argument(0);
- o->call(scope, cData);
+ return f->call(thisObject, arguments, len);
}
-void FunctionPrototype::method_call(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue FunctionPrototype::method_call(const QV4::FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- FunctionObject *o = callData->thisObject.as<FunctionObject>();
- if (!o)
- THROW_TYPE_ERROR();
-
- ScopedCallData cData(scope, callData->argc ? callData->argc - 1 : 0);
- if (callData->argc) {
- for (int i = 1; i < callData->argc; ++i)
- cData->args[i - 1] = callData->args[i];
- }
- cData->thisObject = callData->argument(0);
+ if (!thisObject->isFunctionObject())
+ return b->engine()->throwTypeError();
+
+ const FunctionObject *f = static_cast<const FunctionObject *>(thisObject);
- o->call(scope, cData);
+ thisObject = argc ? argv : nullptr;
+ if (argc) {
+ ++argv;
+ --argc;
+ }
+ return f->call(thisObject, argv, argc);
}
-void FunctionPrototype::method_bind(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue FunctionPrototype::method_bind(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- FunctionObject *target = callData->thisObject.as<FunctionObject>();
+ QV4::Scope scope(b);
+ ScopedFunctionObject target(scope, thisObject);
if (!target)
- THROW_TYPE_ERROR();
+ return scope.engine->throwTypeError();
- ScopedValue boundThis(scope, callData->argument(0));
+ ScopedValue boundThis(scope, argc ? argv[0] : Primitive::undefinedValue());
Scoped<MemberData> boundArgs(scope, (Heap::MemberData *)0);
- if (callData->argc > 1) {
- boundArgs = MemberData::allocate(scope.engine, callData->argc - 1);
- boundArgs->d()->size = callData->argc - 1;
- memcpy(boundArgs->data(), callData->args + 1, (callData->argc - 1)*sizeof(Value));
+ if (argc > 1) {
+ boundArgs = MemberData::allocate(scope.engine, argc - 1);
+ boundArgs->d()->values.size = argc - 1;
+ for (uint i = 0, ei = static_cast<uint>(argc - 1); i < ei; ++i)
+ boundArgs->set(scope.engine, i, argv[i + 1]);
}
ExecutionContext *global = scope.engine->rootContext();
- scope.result = BoundFunction::create(global, target, boundThis, boundArgs);
+ return BoundFunction::create(global, target, boundThis, boundArgs)->asReturnedValue();
}
DEFINE_OBJECT_VTABLE(ScriptFunction);
-void ScriptFunction::construct(const Managed *that, Scope &scope, CallData *callData)
+ReturnedValue ScriptFunction::callAsConstructor(const FunctionObject *fo, const Value *argv, int argc)
{
- ExecutionEngine *v4 = scope.engine;
- if (Q_UNLIKELY(v4->hasException)) {
- scope.result = Encode::undefined();
- return;
- }
- CHECK_STACK_LIMITS(v4, scope);
+ ExecutionEngine *v4 = fo->engine();
+ const ScriptFunction *f = static_cast<const ScriptFunction *>(fo);
- ExecutionContextSaver ctxSaver(scope);
+ Scope scope(v4);
+ InternalClass *ic = f->classForConstructor();
+ ScopedValue thisObject(scope, v4->memoryManager->allocObject<Object>(ic));
- Scoped<ScriptFunction> f(scope, static_cast<const ScriptFunction *>(that));
+ ReturnedValue result = Moth::VME::exec(fo, thisObject, argv, argc);
- InternalClass *ic = f->classForConstructor();
- ScopedObject proto(scope, ic->prototype);
- ScopedObject obj(scope, v4->newObject(ic, proto));
- callData->thisObject = obj.asReturnedValue();
-
- QV4::Function *v4Function = f->function();
- Q_ASSERT(v4Function);
-
- ScopedContext c(scope, f->scope());
- if (v4Function->canUseSimpleCall)
- c->simpleCall(scope, callData, v4Function);
- else
- c->call(scope, callData, v4Function, f);
-
- if (Q_UNLIKELY(v4->hasException)) {
- scope.result = Encode::undefined();
- } else if (!scope.result.isObject()) {
- scope.result = obj.asReturnedValue();
- }
+ if (Q_UNLIKELY(v4->hasException))
+ return Encode::undefined();
+ else if (!Value::fromReturnedValue(result).isObject())
+ return thisObject->asReturnedValue();
+ return result;
}
-void ScriptFunction::call(const Managed *that, Scope &scope, CallData *callData)
+ReturnedValue ScriptFunction::call(const FunctionObject *fo, const Value *thisObject, const Value *argv, int argc)
{
- ExecutionEngine *v4 = scope.engine;
- if (Q_UNLIKELY(v4->hasException)) {
- scope.result = Encode::undefined();
- return;
- }
- CHECK_STACK_LIMITS(v4, scope);
-
- Scoped<ScriptFunction> f(scope, static_cast<const ScriptFunction *>(that));
-
- QV4::Function *v4Function = f->function();
- Q_ASSERT(v4Function);
-
- ScopedContext c(scope, f->scope());
- if (v4Function->canUseSimpleCall)
- c->simpleCall(scope, callData, v4Function);
- else
- c->call(scope, callData, v4Function, f);
+ return Moth::VME::exec(fo, thisObject, argv, argc);
}
void Heap::ScriptFunction::init(QV4::ExecutionContext *scope, Function *function)
{
FunctionObject::init();
- this->scope = scope->d();
+ this->scope.set(scope->engine(), scope->d());
this->function = function;
function->compilationUnit->addref();
@@ -433,9 +404,9 @@ void Heap::ScriptFunction::init(QV4::ExecutionContext *scope, Function *function
ScopedString name(s, function->name());
f->init(name, true);
Q_ASSERT(internalClass && internalClass->find(s.engine->id_length()) == Index_Length);
- *propertyData(Index_Length) = Primitive::fromInt32(f->formalParameterCount());
+ setProperty(s.engine, Index_Length, Primitive::fromInt32(f->formalParameterCount()));
- if (scope->d()->strictMode) {
+ if (function->isStrict()) {
ScopedProperty pd(s);
pd->value = s.engine->thrower();
pd->set = s.engine->thrower();
@@ -459,54 +430,6 @@ InternalClass *ScriptFunction::classForConstructor() const
return ic;
}
-
-DEFINE_OBJECT_VTABLE(BuiltinFunction);
-
-void Heap::BuiltinFunction::init(QV4::ExecutionContext *scope, QV4::String *name, void (*code)(const QV4::BuiltinFunction *, Scope &, CallData *))
-{
- Heap::FunctionObject::init(scope, name);
- this->code = code;
-}
-
-void BuiltinFunction::construct(const Managed *f, Scope &scope, CallData *)
-{
- scope.result = static_cast<const BuiltinFunction *>(f)->internalClass()->engine->throwTypeError();
-}
-
-void BuiltinFunction::call(const Managed *that, Scope &scope, CallData *callData)
-{
- const BuiltinFunction *f = static_cast<const BuiltinFunction *>(that);
- ExecutionEngine *v4 = scope.engine;
- if (v4->hasException) {
- scope.result = Encode::undefined();
- return;
- }
- f->d()->code(f, scope, callData);
-}
-
-
-void IndexedBuiltinFunction::call(const Managed *that, Scope &scope, CallData *callData)
-{
- const IndexedBuiltinFunction *f = static_cast<const IndexedBuiltinFunction *>(that);
- ExecutionEngine *v4 = scope.engine;
- if (v4->hasException) {
- scope.result = Encode::undefined();
- return;
- }
- CHECK_STACK_LIMITS(v4, scope);
-
- ExecutionContextSaver ctxSaver(scope);
-
- CallContext::Data *ctx = v4->memoryManager->allocSimpleCallContext();
- ctx->strictMode = f->scope()->strictMode; // ### needed? scope or parent context?
- ctx->callData = callData;
- v4->pushContext(ctx);
- Q_ASSERT(v4->current == ctx);
-
- scope.result = f->d()->code(static_cast<QV4::CallContext *>(v4->currentContext), f->d()->index);
- v4->memoryManager->freeSimpleCallContext();
-}
-
DEFINE_OBJECT_VTABLE(IndexedBuiltinFunction);
DEFINE_OBJECT_VTABLE(BoundFunction);
@@ -514,12 +437,12 @@ DEFINE_OBJECT_VTABLE(BoundFunction);
void Heap::BoundFunction::init(QV4::ExecutionContext *scope, QV4::FunctionObject *target,
const Value &boundThis, QV4::MemberData *boundArgs)
{
+ Scope s(scope);
Heap::FunctionObject::init(scope, QStringLiteral("__bound function__"));
- this->target = target->d();
- this->boundArgs = boundArgs ? boundArgs->d() : 0;
- this->boundThis = boundThis;
+ this->target.set(s.engine, target->d());
+ this->boundArgs.set(s.engine, boundArgs ? boundArgs->d() : 0);
+ this->boundThis.set(scope->engine(), boundThis);
- Scope s(scope);
ScopedObject f(s, this);
ScopedValue l(s, target->get(s.engine->id_length()));
@@ -528,7 +451,7 @@ void Heap::BoundFunction::init(QV4::ExecutionContext *scope, QV4::FunctionObject
len -= boundArgs->size();
if (len < 0)
len = 0;
- f->defineReadonlyProperty(s.engine->id_length(), Primitive::fromInt32(len));
+ f->defineReadonlyConfigurableProperty(s.engine->id_length(), Primitive::fromInt32(len));
ScopedProperty pd(s);
pd->value = s.engine->thrower();
@@ -537,54 +460,43 @@ void Heap::BoundFunction::init(QV4::ExecutionContext *scope, QV4::FunctionObject
f->insertMember(s.engine->id_caller(), pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable);
}
-void BoundFunction::call(const Managed *that, Scope &scope, CallData *dd)
+ReturnedValue BoundFunction::call(const FunctionObject *fo, const Value *, const Value *argv, int argc)
{
- const BoundFunction *f = static_cast<const BoundFunction *>(that);
- if (scope.hasException()) {
- scope.result = Encode::undefined();
- return;
- }
+ const BoundFunction *f = static_cast<const BoundFunction *>(fo);
+ Scope scope(f->engine());
+
+ if (scope.hasException())
+ return Encode::undefined();
Scoped<MemberData> boundArgs(scope, f->boundArgs());
- ScopedCallData callData(scope, (boundArgs ? boundArgs->size() : 0) + dd->argc);
- callData->thisObject = f->boundThis();
- Value *argp = callData->args;
+ ScopedFunctionObject target(scope, f->target());
+ JSCallData jsCallData(scope, (boundArgs ? boundArgs->size() : 0) + argc);
+ *jsCallData->thisObject = f->boundThis();
+ Value *argp = jsCallData->args;
if (boundArgs) {
memcpy(argp, boundArgs->data(), boundArgs->size()*sizeof(Value));
argp += boundArgs->size();
}
- memcpy(argp, dd->args, dd->argc*sizeof(Value));
- ScopedFunctionObject t(scope, f->target());
- t->call(scope, callData);
+ memcpy(argp, argv, argc*sizeof(Value));
+ return target->call(jsCallData);
}
-void BoundFunction::construct(const Managed *that, Scope &scope, CallData *dd)
+ReturnedValue BoundFunction::callAsConstructor(const FunctionObject *fo, const Value *argv, int argc)
{
- const BoundFunction *f = static_cast<const BoundFunction *>(that);
- if (scope.hasException()) {
- scope.result = Encode::undefined();
- return;
- }
+ const BoundFunction *f = static_cast<const BoundFunction *>(fo);
+ Scope scope(f->engine());
+
+ if (scope.hasException())
+ return Encode::undefined();
Scoped<MemberData> boundArgs(scope, f->boundArgs());
- ScopedCallData callData(scope, (boundArgs ? boundArgs->size() : 0) + dd->argc);
- Value *argp = callData->args;
+ ScopedFunctionObject target(scope, f->target());
+ JSCallData jsCallData(scope, (boundArgs ? boundArgs->size() : 0) + argc);
+ Value *argp = jsCallData->args;
if (boundArgs) {
memcpy(argp, boundArgs->data(), boundArgs->size()*sizeof(Value));
argp += boundArgs->size();
}
- memcpy(argp, dd->args, dd->argc*sizeof(Value));
- ScopedFunctionObject t(scope, f->target());
- t->construct(scope, callData);
-}
-
-void BoundFunction::markObjects(Heap::Base *that, ExecutionEngine *e)
-{
- BoundFunction::Data *o = static_cast<BoundFunction::Data *>(that);
- if (o->target)
- o->target->mark(e);
- o->boundThis.mark(e);
- if (o->boundArgs)
- o->boundArgs->mark(e);
- FunctionObject::markObjects(that, e);
+ memcpy(argp, argv, argc*sizeof(Value));
+ return target->callAsConstructor(jsCallData);
}
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index d691b869fe..abd6f2dbcb 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -61,16 +61,29 @@ struct QQmlSourceLocation;
namespace QV4 {
-struct BuiltinFunction;
+struct IndexedBuiltinFunction;
+struct JSCallData;
+
+typedef ReturnedValue (*jsCallFunction)(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+typedef ReturnedValue (*jsConstructFunction)(const FunctionObject *, const Value *argv, int argc);
namespace Heap {
-struct Q_QML_PRIVATE_EXPORT FunctionObject : Object {
+
+#define FunctionObjectMembers(class, Member) \
+ Member(class, Pointer, ExecutionContext *, scope) \
+ Member(class, NoMark, Function *, function) \
+ Member(class, NoMark, jsCallFunction, jsCall) \
+ Member(class, NoMark, jsConstructFunction, jsConstruct)
+
+DECLARE_HEAP_OBJECT(FunctionObject, Object) {
+ DECLARE_MARKOBJECTS(FunctionObject);
enum {
Index_Prototype = 0,
Index_ProtoConstructor = 0
};
+ Q_QML_PRIVATE_EXPORT void init(QV4::ExecutionContext *scope, QV4::String *name, ReturnedValue (*code)(const QV4::FunctionObject *, const Value *thisObject, const Value *argv, int argc));
void init(QV4::ExecutionContext *scope, QV4::String *name = 0, bool createProto = false);
void init(QV4::ExecutionContext *scope, QV4::Function *function, bool createProto = false);
void init(QV4::ExecutionContext *scope, const QString &name, bool createProto = false);
@@ -79,12 +92,8 @@ struct Q_QML_PRIVATE_EXPORT FunctionObject : Object {
unsigned int formalParameterCount() { return function ? function->nFormals : 0; }
unsigned int varCount() { return function ? function->compiledFunction->nLocals : 0; }
- bool needsActivation() const { return function ? function->needsActivation() : false; }
const QV4::Object *protoProperty() const { return propertyData(Index_Prototype)->as<QV4::Object>(); }
-
- Pointer<ExecutionContext> scope;
- Function *function;
};
struct FunctionCtor : FunctionObject {
@@ -95,19 +104,8 @@ struct FunctionPrototype : FunctionObject {
void init();
};
-struct Q_QML_EXPORT OldBuiltinFunction : FunctionObject {
- void init(QV4::ExecutionContext *scope, QV4::String *name, ReturnedValue (*code)(QV4::CallContext *));
- ReturnedValue (*code)(QV4::CallContext *);
-};
-
-struct Q_QML_EXPORT BuiltinFunction : FunctionObject {
- void init(QV4::ExecutionContext *scope, QV4::String *name, void (*code)(const QV4::BuiltinFunction *, Scope &, CallData *));
- void (*code)(const QV4::BuiltinFunction *, Scope &, CallData *);
-};
-
struct IndexedBuiltinFunction : FunctionObject {
- inline void init(QV4::ExecutionContext *scope, uint index, ReturnedValue (*code)(QV4::CallContext *ctx, uint index));
- ReturnedValue (*code)(QV4::CallContext *, uint index);
+ inline void init(QV4::ExecutionContext *scope, uint index, ReturnedValue (*code)(const QV4::FunctionObject *, const Value *, const Value *, int));
uint index;
};
@@ -121,11 +119,15 @@ struct ScriptFunction : FunctionObject {
QV4::InternalClass *cachedClassForConstructor;
};
-struct BoundFunction : FunctionObject {
+#define BoundFunctionMembers(class, Member) \
+ Member(class, Pointer, FunctionObject *, target) \
+ Member(class, HeapValue, HeapValue, boundThis) \
+ Member(class, Pointer, MemberData *, boundArgs)
+
+DECLARE_HEAP_OBJECT(BoundFunction, FunctionObject) {
+ DECLARE_MARKOBJECTS(BoundFunction);
+
void init(QV4::ExecutionContext *scope, QV4::FunctionObject *target, const Value &boundThis, QV4::MemberData *boundArgs);
- Pointer<FunctionObject> target;
- Value boundThis;
- Pointer<MemberData> boundArgs;
};
}
@@ -139,6 +141,7 @@ struct Q_QML_EXPORT FunctionObject: Object {
V4_INTERNALCLASS(FunctionObject)
V4_PROTOTYPE(functionPrototype)
V4_NEEDS_DESTROY
+ enum { NInlineProperties = 1 };
Heap::ExecutionContext *scope() const { return d()->scope; }
Function *function() const { return d()->function; }
@@ -149,21 +152,29 @@ struct Q_QML_EXPORT FunctionObject: Object {
void init(String *name, bool createProto);
- using Object::construct;
- using Object::call;
- static void construct(const Managed *that, Scope &scope, CallData *);
- static void call(const Managed *that, Scope &scope, CallData *d);
+ inline ReturnedValue callAsConstructor(const JSCallData &data) const;
+ ReturnedValue callAsConstructor(const Value *argv, int argc) const {
+ return d()->jsConstruct(this, argv, argc);
+ }
+ inline ReturnedValue call(const JSCallData &data) const;
+ ReturnedValue call(const Value *thisObject, const Value *argv, int argc) const {
+ return d()->jsCall(this, thisObject, argv, argc);
+ }
+ static ReturnedValue callAsConstructor(const FunctionObject *f, const Value *argv, int argc);
+ static ReturnedValue call(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
static Heap::FunctionObject *createScriptFunction(ExecutionContext *scope, Function *function);
+ static Heap::FunctionObject *createBuiltinFunction(ExecutionContext *scope, String *name,
+ ReturnedValue (*code)(const FunctionObject *, const Value *thisObject, const Value *argv, int argc))
+ {
+ return scope->engine()->memoryManager->allocObject<FunctionObject>(scope, name, code);
+ }
- bool needsActivation() const { return d()->needsActivation(); }
bool strictMode() const { return d()->function ? d()->function->isStrict() : false; }
bool isBinding() const;
bool isBoundFunction() const;
QQmlSourceLocation sourceLocation() const;
-
- static void markObjects(Heap::Base *that, ExecutionEngine *e);
};
template<>
@@ -176,8 +187,8 @@ struct FunctionCtor: FunctionObject
{
V4_OBJECT2(FunctionCtor, FunctionObject)
- static void construct(const Managed *that, Scope &scope, CallData *callData);
- static void call(const Managed *that, Scope &scope, CallData *callData);
+ static ReturnedValue callAsConstructor(const FunctionObject *f, const Value *argv, int argc);
+ static ReturnedValue call(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
};
struct FunctionPrototype: FunctionObject
@@ -186,52 +197,33 @@ struct FunctionPrototype: FunctionObject
void init(ExecutionEngine *engine, Object *ctor);
- static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_apply(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_call(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_bind(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_toString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_apply(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_call(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_bind(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
};
-struct Q_QML_EXPORT BuiltinFunction : FunctionObject {
- V4_OBJECT2(BuiltinFunction, FunctionObject)
- V4_INTERNALCLASS(BuiltinFunction)
-
- static Heap::BuiltinFunction *create(ExecutionContext *scope, String *name, void (*code)(const BuiltinFunction *, Scope &, CallData *))
- {
- return scope->engine()->memoryManager->allocObject<BuiltinFunction>(scope, name, code);
- }
-
- static void construct(const Managed *, Scope &scope, CallData *);
- static void call(const Managed *that, Scope &scope, CallData *callData);
-};
-
-struct IndexedBuiltinFunction: FunctionObject
+struct IndexedBuiltinFunction : FunctionObject
{
V4_OBJECT2(IndexedBuiltinFunction, FunctionObject)
-
- static void construct(const Managed *m, Scope &scope, CallData *)
- {
- scope.result = static_cast<const IndexedBuiltinFunction *>(m)->engine()->throwTypeError();
- }
-
- static void call(const Managed *that, Scope &scope, CallData *callData);
};
void Heap::IndexedBuiltinFunction::init(QV4::ExecutionContext *scope, uint index,
- ReturnedValue (*code)(QV4::CallContext *ctx, uint index))
+ ReturnedValue (*code)(const QV4::FunctionObject *, const Value *thisObject, const Value *argv, int argc))
{
Heap::FunctionObject::init(scope);
+ this->jsCall = code;
this->index = index;
- this->code = code;
}
struct ScriptFunction : FunctionObject {
V4_OBJECT2(ScriptFunction, FunctionObject)
V4_INTERNALCLASS(ScriptFunction)
+ enum { NInlineProperties = 3 };
- static void construct(const Managed *, Scope &scope, CallData *callData);
- static void call(const Managed *that, Scope &scope, CallData *callData);
+ static ReturnedValue callAsConstructor(const FunctionObject *, const Value *argv, int argc);
+ static ReturnedValue call(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
InternalClass *classForConstructor() const;
};
@@ -249,10 +241,8 @@ struct BoundFunction: FunctionObject {
Value boundThis() const { return d()->boundThis; }
Heap::MemberData *boundArgs() const { return d()->boundArgs; }
- static void construct(const Managed *, Scope &scope, CallData *d);
- static void call(const Managed *that, Scope &scope, CallData *dd);
-
- static void markObjects(Heap::Base *that, ExecutionEngine *e);
+ static ReturnedValue callAsConstructor(const FunctionObject *, const Value *argv, int argc);
+ static ReturnedValue call(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
};
}
diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h
index a3ef395076..7f82a02ae0 100644
--- a/src/qml/jsruntime/qv4global_p.h
+++ b/src/qml/jsruntime/qv4global_p.h
@@ -76,9 +76,6 @@ namespace std {
inline bool isinf(double d) { return !_finite(d) && !_isnan(d); }
inline bool isnan(double d) { return !!_isnan(d); }
inline bool isfinite(double d) { return _finite(d); }
-#if _MSC_VER < 1800
-inline bool signbit(double d) { return _copysign(1.0, d) < 0; }
-#endif
} // namespace std
@@ -107,8 +104,8 @@ inline double trunc(double d) { return d > 0 ? floor(d) : ceil(d); }
# if defined(Q_OS_LINUX) || defined(Q_OS_QNX)
# define V4_ENABLE_JIT
# endif
-#elif defined(Q_PROCESSOR_MIPS_32) && defined(Q_OS_LINUX)
-# define V4_ENABLE_JIT
+//#elif defined(Q_PROCESSOR_MIPS_32) && defined(Q_OS_LINUX)
+//# define V4_ENABLE_JIT
#endif
// Black list some platforms
@@ -147,6 +144,12 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
+namespace Compiler {
+ struct Module;
+ struct Context;
+ struct JSUnitGenerator;
+}
+
namespace Heap {
struct Base;
struct MemberData;
@@ -157,7 +160,6 @@ namespace Heap {
struct ObjectPrototype;
struct ExecutionContext;
- struct GlobalContext;
struct CallContext;
struct ScriptFunction;
@@ -178,23 +180,27 @@ namespace Heap {
struct DataView;
struct TypedArray;
+ template <typename T, size_t> struct Pointer;
}
class MemoryManager;
+class ExecutableAllocator;
struct String;
struct Object;
struct ObjectPrototype;
struct ObjectIterator;
struct ExecutionContext;
-struct GlobalContext;
struct CallContext;
struct ScriptFunction;
struct InternalClass;
struct Property;
struct Value;
+template<size_t> struct HeapValue;
+template<size_t> struct ValueArray;
struct Lookup;
struct ArrayData;
struct VTable;
+struct Function;
struct BooleanObject;
struct NumberObject;
@@ -202,7 +208,6 @@ struct StringObject;
struct ArrayObject;
struct DateObject;
struct FunctionObject;
-struct BuiltinFunction;
struct ErrorObject;
struct ArgumentsObject;
struct Managed;
@@ -239,12 +244,6 @@ struct IdentifierTable;
class RegExpCache;
class MultiplyWrappedQObjectMap;
-namespace Global {
- enum {
- ReservedArgumentCount = 6
- };
-}
-
enum PropertyFlag {
Attr_Data = 0,
Attr_Accessor = 0x1,
@@ -252,6 +251,7 @@ enum PropertyFlag {
Attr_NotEnumerable = 0x4,
Attr_NotConfigurable = 0x8,
Attr_ReadOnly = Attr_NotWritable|Attr_NotEnumerable|Attr_NotConfigurable,
+ Attr_ReadOnly_ButConfigurable = Attr_NotWritable|Attr_NotEnumerable,
Attr_Invalid = 0xff
};
@@ -344,11 +344,11 @@ struct PropertyAttributes
}
};
-struct StackFrame {
+struct Q_QML_EXPORT StackFrame {
QString source;
QString function;
- int line;
- int column;
+ int line = -1;
+ int column = -1;
};
typedef QVector<StackFrame> StackTrace;
diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp
index 0916e8e110..3214a716e8 100644
--- a/src/qml/jsruntime/qv4globalobject.cpp
+++ b/src/qml/jsruntime/qv4globalobject.cpp
@@ -47,12 +47,12 @@
#include "qv4script_p.h"
#include "qv4scopedvalue_p.h"
#include "qv4string_p.h"
+#include "qv4jscall_p.h"
#include <private/qqmljsengine_p.h>
#include <private/qqmljslexer_p.h>
#include <private/qqmljsparser_p.h>
#include <private/qqmljsast_p.h>
-#include <qv4jsir_p.h>
#include <qv4codegen_p.h>
#include "private/qlocale_tools_p.h"
#include "private/qtools_p.h"
@@ -338,72 +338,56 @@ void Heap::EvalFunction::init(QV4::ExecutionContext *scope)
f->defineReadonlyProperty(s.engine->id_length(), Primitive::fromInt32(1));
}
-void EvalFunction::evalCall(Scope &scope, CallData *callData, bool directCall) const
+ReturnedValue EvalFunction::evalCall(const Value *, const Value *argv, int argc, bool directCall) const
{
- if (callData->argc < 1) {
- scope.result = Encode::undefined();
- return;
- }
+ if (argc < 1)
+ return Encode::undefined();
ExecutionEngine *v4 = engine();
- ExecutionContextSaver ctxSaver(scope);
+ bool isStrict = v4->currentStackFrame->v4Function->isStrict();
- ExecutionContext *currentContext = v4->currentContext;
- ExecutionContext *ctx = currentContext;
+ Scope scope(v4);
+ ScopedContext ctx(scope, v4->currentContext());
if (!directCall) {
- // the context for eval should be the global scope, so we fake a root
- // context
- ctx = v4->pushGlobalContext();
+ // the context for eval should be the global scope
+ ctx = v4->rootContext();
}
- String *scode = callData->args[0].stringValue();
- if (!scode) {
- scope.result = callData->args[0].asReturnedValue();
- return;
- }
+ String *scode = argv[0].stringValue();
+ if (!scode)
+ return argv[0].asReturnedValue();
const QString code = scode->toQString();
- bool inheritContext = !ctx->d()->strictMode;
+ bool inheritContext = !isStrict;
- Script script(ctx, code, QStringLiteral("eval code"));
- script.strictMode = (directCall && currentContext->d()->strictMode);
+ Script script(ctx, QV4::Compiler::EvalCode, code, QStringLiteral("eval code"));
+ script.strictMode = (directCall && isStrict);
script.inheritContext = inheritContext;
script.parse();
- if (v4->hasException) {
- scope.result = Encode::undefined();
- return;
- }
+ if (v4->hasException)
+ return Encode::undefined();
Function *function = script.function();
- if (!function) {
- scope.result = Encode::undefined();
- return;
- }
+ if (!function)
+ return Encode::undefined();
- if (function->isStrict() || (ctx->d()->strictMode)) {
+ if (function->isStrict() || isStrict) {
ScopedFunctionObject e(scope, FunctionObject::createScriptFunction(ctx, function));
- ScopedCallData callData(scope, 0);
- callData->thisObject = ctx->thisObject();
- e->call(scope, callData);
- return;
+ ScopedValue thisObject(scope, directCall ? scope.engine->currentStackFrame->thisObject() : scope.engine->globalObject->asReturnedValue());
+ return e->call(thisObject, 0, 0);
}
- ContextStateSaver stateSaver(scope, ctx);
-
- // set the correct strict mode flag on the context
- ctx->d()->strictMode = false;
- ctx->d()->compilationUnit = function->compilationUnit;
- ctx->d()->constantTable = function->compilationUnit->constants;
+ ScopedValue thisObject(scope, scope.engine->currentStackFrame->thisObject());
- scope.result = Q_V4_PROFILE(ctx->engine(), function);
+ return function->call(thisObject, 0, 0, ctx);
}
-void EvalFunction::call(const Managed *that, Scope &scope, CallData *callData)
+ReturnedValue EvalFunction::call(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
{
// indirect call
- static_cast<const EvalFunction *>(that)->evalCall(scope, callData, false);
+ return static_cast<const EvalFunction *>(f)->evalCall(thisObject, argv, argc, false);
}
@@ -424,10 +408,11 @@ static inline int toInt(const QChar &qc, int R)
}
// parseInt [15.1.2.2]
-void GlobalFunctions::method_parseInt(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue GlobalFunctions::method_parseInt(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- ScopedValue inputString(scope, callData->argument(0));
- ScopedValue radix(scope, callData->argument(1));
+ Scope scope(b);
+ ScopedValue inputString(scope, argc ? argv[0] : Primitive::undefinedValue());
+ ScopedValue radix(scope, argc > 1 ? argv[1] : Primitive::undefinedValue());
int R = radix->isUndefined() ? 0 : radix->toInt32();
// [15.1.2.2] step by step:
@@ -504,10 +489,11 @@ void GlobalFunctions::method_parseInt(const BuiltinFunction *, Scope &scope, Cal
}
// parseFloat [15.1.2.3]
-void GlobalFunctions::method_parseFloat(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue GlobalFunctions::method_parseFloat(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
+ Scope scope(b);
// [15.1.2.3] step by step:
- ScopedString inputString(scope, callData->argument(0), ScopedString::Convert);
+ ScopedString inputString(scope, argc ? argv[0] : Primitive::undefinedValue(), ScopedString::Convert);
CHECK_EXCEPTION();
QString trimmed = inputString->toQString().trimmed(); // 2
@@ -530,115 +516,125 @@ void GlobalFunctions::method_parseFloat(const BuiltinFunction *, Scope &scope, C
}
/// isNaN [15.1.2.4]
-void GlobalFunctions::method_isNaN(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue GlobalFunctions::method_isNaN(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- if (!callData->argc)
+ if (!argc)
// undefined gets converted to NaN
RETURN_RESULT(Encode(true));
- if (callData->args[0].integerCompatible())
+ if (argv[0].integerCompatible())
RETURN_RESULT(Encode(false));
- double d = callData->args[0].toNumber();
+ double d = argv[0].toNumber();
RETURN_RESULT(Encode((bool)std::isnan(d)));
}
/// isFinite [15.1.2.5]
-void GlobalFunctions::method_isFinite(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue GlobalFunctions::method_isFinite(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- if (!callData->argc)
+ if (!argc)
// undefined gets converted to NaN
RETURN_RESULT(Encode(false));
- if (callData->args[0].integerCompatible())
+ if (argv[0].integerCompatible())
RETURN_RESULT(Encode(true));
- double d = callData->args[0].toNumber();
+ double d = argv[0].toNumber();
RETURN_RESULT(Encode((bool)std::isfinite(d)));
}
/// decodeURI [15.1.3.1]
-void GlobalFunctions::method_decodeURI(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue GlobalFunctions::method_decodeURI(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc == 0)
+ if (argc == 0)
RETURN_UNDEFINED();
- QString uriString = callData->args[0].toQString();
+ ExecutionEngine *v4 = b->engine();
+ QString uriString = argv[0].toQString();
bool ok;
QString out = decode(uriString, DecodeNonReserved, &ok);
if (!ok) {
+ Scope scope(v4);
ScopedString s(scope, scope.engine->newString(QStringLiteral("malformed URI sequence")));
RETURN_RESULT(scope.engine->throwURIError(s));
}
- RETURN_RESULT(scope.engine->newString(out));
+ RETURN_RESULT(v4->newString(out));
}
/// decodeURIComponent [15.1.3.2]
-void GlobalFunctions::method_decodeURIComponent(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue GlobalFunctions::method_decodeURIComponent(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc == 0)
+ if (argc == 0)
RETURN_UNDEFINED();
- QString uriString = callData->args[0].toQString();
+ ExecutionEngine *v4 = b->engine();
+ QString uriString = argv[0].toQString();
bool ok;
QString out = decode(uriString, DecodeAll, &ok);
if (!ok) {
+ Scope scope(v4);
ScopedString s(scope, scope.engine->newString(QStringLiteral("malformed URI sequence")));
RETURN_RESULT(scope.engine->throwURIError(s));
}
- RETURN_RESULT(scope.engine->newString(out));
+ RETURN_RESULT(v4->newString(out));
}
/// encodeURI [15.1.3.3]
-void GlobalFunctions::method_encodeURI(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue GlobalFunctions::method_encodeURI(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc == 0)
+ if (argc == 0)
RETURN_UNDEFINED();
- QString uriString = callData->args[0].toQString();
+ ExecutionEngine *v4 = b->engine();
+ QString uriString = argv[0].toQString();
bool ok;
QString out = encode(uriString, uriUnescapedReserved, &ok);
if (!ok) {
+ Scope scope(v4);
ScopedString s(scope, scope.engine->newString(QStringLiteral("malformed URI sequence")));
RETURN_RESULT(scope.engine->throwURIError(s));
}
- RETURN_RESULT(scope.engine->newString(out));
+ RETURN_RESULT(v4->newString(out));
}
/// encodeURIComponent [15.1.3.4]
-void GlobalFunctions::method_encodeURIComponent(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue GlobalFunctions::method_encodeURIComponent(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc == 0)
+ if (argc == 0)
RETURN_UNDEFINED();
- QString uriString = callData->args[0].toQString();
+ ExecutionEngine *v4 = b->engine();
+ QString uriString = argv[0].toQString();
bool ok;
QString out = encode(uriString, uriUnescaped, &ok);
if (!ok) {
+ Scope scope(v4);
ScopedString s(scope, scope.engine->newString(QStringLiteral("malformed URI sequence")));
RETURN_RESULT(scope.engine->throwURIError(s));
}
- RETURN_RESULT(scope.engine->newString(out));
+ RETURN_RESULT(v4->newString(out));
}
-void GlobalFunctions::method_escape(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue GlobalFunctions::method_escape(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (!callData->argc)
- RETURN_RESULT(scope.engine->newString(QStringLiteral("undefined")));
+ ExecutionEngine *v4 = b->engine();
+ if (!argc)
+ RETURN_RESULT(v4->newString(QStringLiteral("undefined")));
- QString str = callData->args[0].toQString();
- RETURN_RESULT(scope.engine->newString(escape(str)));
+ QString str = argv[0].toQString();
+ RETURN_RESULT(v4->newString(escape(str)));
}
-void GlobalFunctions::method_unescape(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue GlobalFunctions::method_unescape(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (!callData->argc)
- RETURN_RESULT(scope.engine->newString(QStringLiteral("undefined")));
+ ExecutionEngine *v4 = b->engine();
+ if (!argc)
+ RETURN_RESULT(v4->newString(QStringLiteral("undefined")));
- QString str = callData->args[0].toQString();
- RETURN_RESULT(scope.engine->newString(unescape(str)));
+ QString str = argv[0].toQString();
+ RETURN_RESULT(v4->newString(unescape(str)));
}
diff --git a/src/qml/jsruntime/qv4globalobject_p.h b/src/qml/jsruntime/qv4globalobject_p.h
index 273f1ba7ea..fd1820c23c 100644
--- a/src/qml/jsruntime/qv4globalobject_p.h
+++ b/src/qml/jsruntime/qv4globalobject_p.h
@@ -69,23 +69,23 @@ struct Q_QML_EXPORT EvalFunction : FunctionObject
{
V4_OBJECT2(EvalFunction, FunctionObject)
- void evalCall(Scope &scope, CallData *callData, bool directCall) const;
+ ReturnedValue evalCall(const Value *thisObject, const Value *argv, int argc, bool directCall) const;
- static void call(const Managed *that, Scope &scope, CallData *callData);
+ static ReturnedValue call(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
};
struct GlobalFunctions
{
- static void method_parseInt(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_parseFloat(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_isNaN(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_isFinite(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_decodeURI(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_decodeURIComponent(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_encodeURI(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_encodeURIComponent(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_escape(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_unescape(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_parseInt(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_parseFloat(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_isNaN(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_isFinite(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_decodeURI(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_decodeURIComponent(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_encodeURI(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_encodeURIComponent(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_escape(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_unescape(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
};
}
diff --git a/src/qml/jsruntime/qv4identifier.cpp b/src/qml/jsruntime/qv4identifier.cpp
index 6260fd0cc8..116d4ec201 100644
--- a/src/qml/jsruntime/qv4identifier.cpp
+++ b/src/qml/jsruntime/qv4identifier.cpp
@@ -75,13 +75,13 @@ IdentifierHashData::IdentifierHashData(IdentifierHashData *other)
memcpy(entries, other->entries, alloc*sizeof(IdentifierHashEntry));
}
-IdentifierHashBase::IdentifierHashBase(ExecutionEngine *engine)
+IdentifierHash::IdentifierHash(ExecutionEngine *engine)
{
d = new IdentifierHashData(3);
d->identifierTable = engine->identifierTable;
}
-void IdentifierHashBase::detach()
+void IdentifierHash::detach()
{
if (!d || d->refCount == 1)
return;
@@ -92,7 +92,7 @@ void IdentifierHashBase::detach()
}
-IdentifierHashEntry *IdentifierHashBase::addEntry(const Identifier *identifier)
+IdentifierHashEntry *IdentifierHash::addEntry(const Identifier *identifier)
{
// fill up to max 50%
bool grow = (d->alloc <= d->size*2);
@@ -129,7 +129,7 @@ IdentifierHashEntry *IdentifierHashBase::addEntry(const Identifier *identifier)
return d->entries + idx;
}
-const IdentifierHashEntry *IdentifierHashBase::lookup(const Identifier *identifier) const
+const IdentifierHashEntry *IdentifierHash::lookup(const Identifier *identifier) const
{
if (!d)
return 0;
@@ -146,13 +146,13 @@ const IdentifierHashEntry *IdentifierHashBase::lookup(const Identifier *identifi
}
}
-const IdentifierHashEntry *IdentifierHashBase::lookup(const QString &str) const
+const IdentifierHashEntry *IdentifierHash::lookup(const QString &str) const
{
if (!d)
return 0;
Q_ASSERT(d->entries);
- uint hash = String::createHashValue(str.constData(), str.length(), Q_NULLPTR);
+ uint hash = String::createHashValue(str.constData(), str.length(), nullptr);
uint idx = hash % d->alloc;
while (1) {
if (!d->entries[idx].identifier)
@@ -164,7 +164,7 @@ const IdentifierHashEntry *IdentifierHashBase::lookup(const QString &str) const
}
}
-const IdentifierHashEntry *IdentifierHashBase::lookup(String *str) const
+const IdentifierHashEntry *IdentifierHash::lookup(String *str) const
{
if (!d)
return 0;
@@ -173,13 +173,13 @@ const IdentifierHashEntry *IdentifierHashBase::lookup(String *str) const
return lookup(str->toQString());
}
-const Identifier *IdentifierHashBase::toIdentifier(const QString &str) const
+const Identifier *IdentifierHash::toIdentifier(const QString &str) const
{
Q_ASSERT(d);
return d->identifierTable->identifier(str);
}
-const Identifier *IdentifierHashBase::toIdentifier(Heap::String *str) const
+const Identifier *IdentifierHash::toIdentifier(Heap::String *str) const
{
Q_ASSERT(d);
return d->identifierTable->identifier(str);
diff --git a/src/qml/jsruntime/qv4identifier_p.h b/src/qml/jsruntime/qv4identifier_p.h
index 2695bbc875..f0ff987608 100644
--- a/src/qml/jsruntime/qv4identifier_p.h
+++ b/src/qml/jsruntime/qv4identifier_p.h
@@ -73,13 +73,7 @@ struct Identifier
struct IdentifierHashEntry {
const Identifier *identifier;
- union {
- int value;
- void *pointer;
- };
- static int get(const IdentifierHashEntry *This, int *) { return This ? This->value : -1; }
- static bool get(const IdentifierHashEntry *This, bool *) { return This != 0; }
- static void *get(const IdentifierHashEntry *This, void **) { return This ? This->pointer : 0; }
+ int value;
};
struct IdentifierHashData
@@ -98,26 +92,30 @@ struct IdentifierHashData
IdentifierHashEntry *entries;
};
-struct IdentifierHashBase
+struct IdentifierHash
{
IdentifierHashData *d;
- IdentifierHashBase() : d(0) {}
- IdentifierHashBase(ExecutionEngine *engine);
- inline IdentifierHashBase(const IdentifierHashBase &other);
- inline ~IdentifierHashBase();
- inline IdentifierHashBase &operator=(const IdentifierHashBase &other);
+ IdentifierHash() : d(0) {}
+ IdentifierHash(ExecutionEngine *engine);
+ inline IdentifierHash(const IdentifierHash &other);
+ inline ~IdentifierHash();
+ inline IdentifierHash &operator=(const IdentifierHash &other);
bool isEmpty() const { return !d; }
inline int count() const;
- bool contains(const Identifier *i) const;
- bool contains(const QString &str) const;
- bool contains(String *str) const;
void detach();
+ void add(const QString &str, int value);
+ void add(Heap::String *str, int value);
+
+ inline int value(const QString &str) const;
+ inline int value(String *str) const;
+ QString findId(int value) const;
+
protected:
IdentifierHashEntry *addEntry(const Identifier *i);
const IdentifierHashEntry *lookup(const Identifier *identifier) const;
@@ -128,43 +126,20 @@ protected:
};
-template<typename T>
-struct IdentifierHash : public IdentifierHashBase
-{
- IdentifierHash()
- : IdentifierHashBase() {}
- IdentifierHash(ExecutionEngine *engine)
- : IdentifierHashBase(engine) {}
- inline IdentifierHash(const IdentifierHash<T> &other)
- : IdentifierHashBase(other) {}
- inline ~IdentifierHash() {}
- inline IdentifierHash &operator=(const IdentifierHash<T> &other) {
- IdentifierHashBase::operator =(other);
- return *this;
- }
-
- void add(const QString &str, const T &value);
- void add(Heap::String *str, const T &value);
-
- inline T value(const QString &str) const;
- inline T value(String *str) const;
- QString findId(T value) const;
-};
-
-inline IdentifierHashBase::IdentifierHashBase(const IdentifierHashBase &other)
+inline IdentifierHash::IdentifierHash(const IdentifierHash &other)
{
d = other.d;
if (d)
d->refCount.ref();
}
-inline IdentifierHashBase::~IdentifierHashBase()
+inline IdentifierHash::~IdentifierHash()
{
if (d && !d->refCount.deref())
delete d;
}
-IdentifierHashBase &IdentifierHashBase::operator=(const IdentifierHashBase &other)
+IdentifierHash &IdentifierHash::operator=(const IdentifierHash &other)
{
if (other.d)
other.d->refCount.ref();
@@ -174,60 +149,45 @@ IdentifierHashBase &IdentifierHashBase::operator=(const IdentifierHashBase &othe
return *this;
}
-inline int IdentifierHashBase::count() const
+inline int IdentifierHash::count() const
{
return d ? d->size : 0;
}
-inline bool IdentifierHashBase::contains(const Identifier *i) const
-{
- return lookup(i) != 0;
-}
-
-inline bool IdentifierHashBase::contains(const QString &str) const
-{
- return lookup(str) != 0;
-}
-
-inline bool IdentifierHashBase::contains(String *str) const
-{
- return lookup(str) != 0;
-}
-
-template<typename T>
-void IdentifierHash<T>::add(const QString &str, const T &value)
+inline
+void IdentifierHash::add(const QString &str, int value)
{
IdentifierHashEntry *e = addEntry(toIdentifier(str));
e->value = value;
}
-template<typename T>
-void IdentifierHash<T>::add(Heap::String *str, const T &value)
+inline
+void IdentifierHash::add(Heap::String *str, int value)
{
IdentifierHashEntry *e = addEntry(toIdentifier(str));
e->value = value;
}
-template<typename T>
-inline T IdentifierHash<T>::value(const QString &str) const
+inline int IdentifierHash::value(const QString &str) const
{
- return IdentifierHashEntry::get(lookup(str), (T*)0);
+ const IdentifierHashEntry *e = lookup(str);
+ return e ? e->value : -1;
}
-template<typename T>
-inline T IdentifierHash<T>::value(String *str) const
+inline int IdentifierHash::value(String *str) const
{
- return IdentifierHashEntry::get(lookup(str), (T*)0);
+ const IdentifierHashEntry *e = lookup(str);
+ return e ? e->value : -1;
}
-template<typename T>
-QString IdentifierHash<T>::findId(T value) const
+inline
+QString IdentifierHash::findId(int value) const
{
IdentifierHashEntry *e = d->entries;
IdentifierHashEntry *end = e + d->alloc;
while (e < end) {
- if (e->identifier && IdentifierHashEntry::get(e, (T*)0) == value)
+ if (e->identifier && e->value == value)
return e->identifier->string;
++e;
}
diff --git a/src/qml/jsruntime/qv4identifiertable_p.h b/src/qml/jsruntime/qv4identifiertable_p.h
index 89af5db731..b0b08f1e54 100644
--- a/src/qml/jsruntime/qv4identifiertable_p.h
+++ b/src/qml/jsruntime/qv4identifiertable_p.h
@@ -93,14 +93,14 @@ public:
Heap::String *stringFromIdentifier(Identifier *i);
- void mark(ExecutionEngine *e) {
+ void mark(MarkStack *markStack) {
for (int i = 0; i < alloc; ++i) {
Heap::String *entry = entries[i];
if (!entry || entry->isMarked())
continue;
entry->setMarkBit();
Q_ASSERT(entry->vtable()->markObjects);
- entry->vtable()->markObjects(entry, e);
+ entry->vtable()->markObjects(entry, markStack);
}
}
};
diff --git a/src/qml/jsruntime/qv4include.cpp b/src/qml/jsruntime/qv4include.cpp
index 1edb7d3914..d1ceb0a892 100644
--- a/src/qml/jsruntime/qv4include.cpp
+++ b/src/qml/jsruntime/qv4include.cpp
@@ -39,6 +39,7 @@
#include "qv4include_p.h"
#include "qv4scopedvalue_p.h"
+#include "qv4jscall_p.h"
#include <QtQml/qjsengine.h>
#if QT_CONFIG(qml_network)
@@ -118,10 +119,10 @@ void QV4Include::callback(const QV4::Value &callback, const QV4::Value &status)
if (!f)
return;
- QV4::ScopedCallData callData(scope, 1);
- callData->thisObject = v4->globalObject->asReturnedValue();
- callData->args[0] = status;
- f->call(scope, callData);
+ QV4::JSCallData jsCallData(scope, 1);
+ *jsCallData->thisObject = v4->globalObject->asReturnedValue();
+ jsCallData->args[0] = status;
+ f->call(jsCallData);
if (scope.hasException())
scope.engine->catchException();
}
@@ -195,9 +196,10 @@ void QV4Include::finished()
/*
Documented in qv8engine.cpp
*/
-void QV4Include::method_include(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QV4Include::method_include(const QV4::FunctionObject *b, const QV4::Value *, const QV4::Value *argv, int argc)
{
- if (!callData->argc)
+ QV4::Scope scope(b);
+ if (!argc)
RETURN_UNDEFINED();
QQmlContextData *context = scope.engine->callingQmlContext();
@@ -206,11 +208,11 @@ void QV4Include::method_include(const QV4::BuiltinFunction *, QV4::Scope &scope,
RETURN_RESULT(scope.engine->throwError(QString::fromUtf8("Qt.include(): Can only be called from JavaScript files")));
QV4::ScopedValue callbackFunction(scope, QV4::Primitive::undefinedValue());
- if (callData->argc >= 2 && callData->args[1].as<QV4::FunctionObject>())
- callbackFunction = callData->args[1];
+ if (argc >= 2 && argv[1].as<QV4::FunctionObject>())
+ callbackFunction = argv[1];
#if QT_CONFIG(qml_network)
- QUrl url(scope.engine->resolvedUrl(callData->args[0].toQStringNoThrow()));
+ QUrl url(scope.engine->resolvedUrl(argv[0].toQStringNoThrow()));
if (scope.engine->qmlEngine() && scope.engine->qmlEngine()->urlInterceptor())
url = scope.engine->qmlEngine()->urlInterceptor()->intercept(url, QQmlAbstractUrlInterceptor::JavaScriptFile);
@@ -225,21 +227,7 @@ void QV4Include::method_include(const QV4::BuiltinFunction *, QV4::Scope &scope,
} else {
QScopedPointer<QV4::Script> script;
-
- if (const QQmlPrivate::CachedQmlUnit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(url)) {
- QV4::CompiledData::CompilationUnit *jsUnit = cachedUnit->createCompilationUnit();
- script.reset(new QV4::Script(scope.engine, qmlcontext, jsUnit));
- } else {
- QFile f(localFile);
-
- if (f.open(QIODevice::ReadOnly)) {
- QByteArray data = f.readAll();
- QString code = QString::fromUtf8(data);
- QmlIR::Document::removeScriptPragmas(code);
-
- script.reset(new QV4::Script(scope.engine, qmlcontext, code, url.toString()));
- }
- }
+ script.reset(QV4::Script::createFromFileOrCache(scope.engine, qmlcontext, localFile, url));
if (!script.isNull()) {
script->parse();
@@ -260,13 +248,13 @@ void QV4Include::method_include(const QV4::BuiltinFunction *, QV4::Scope &scope,
callback(callbackFunction, result);
}
- scope.result = result;
#else
QV4::ScopedValue result(scope);
result = resultValue(scope.engine, NetworkError);
callback(callbackFunction, result);
- scope.result = result;
#endif
+
+ return result->asReturnedValue();
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4include_p.h b/src/qml/jsruntime/qv4include_p.h
index 5908d6bfde..8015722afc 100644
--- a/src/qml/jsruntime/qv4include_p.h
+++ b/src/qml/jsruntime/qv4include_p.h
@@ -77,7 +77,7 @@ public:
Exception = 3
};
- static void method_include(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static QV4::ReturnedValue method_include(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
private Q_SLOTS:
void finished();
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp
index 0bcd510541..4041052344 100644
--- a/src/qml/jsruntime/qv4internalclass.cpp
+++ b/src/qml/jsruntime/qv4internalclass.cpp
@@ -112,6 +112,7 @@ InternalClass::InternalClass(ExecutionEngine *engine)
, size(0)
, extensible(true)
{
+ id = engine->newInternalClassId();
}
@@ -127,54 +128,30 @@ InternalClass::InternalClass(const QV4::InternalClass &other)
, m_frozen(0)
, size(other.size)
, extensible(other.extensible)
+ , isUsedAsProto(other.isUsedAsProto)
{
- Q_ASSERT(extensible);
+ id = engine->newInternalClassId();
}
static void insertHoleIntoPropertyData(Object *object, int idx)
{
- int inlineSize = object->d()->vtable()->nInlineProperties;
- int icSize = object->internalClass()->size;
- int from = qMax(idx, inlineSize);
- int to = from + 1;
- if (from < icSize) {
- memmove(object->propertyData(to), object->propertyData(from),
- (icSize - from - 1) * sizeof(Value));
- }
- if (from == idx)
- return;
- if (inlineSize < icSize)
- *object->propertyData(inlineSize) = *object->propertyData(inlineSize - 1);
- from = idx;
- to = from + 1;
- if (from < inlineSize - 1) {
- memmove(object->propertyData(to), object->propertyData(from),
- (inlineSize - from - 1) * sizeof(Value));
- }
+ Heap::Object *o = object->d();
+ ExecutionEngine *v4 = o->internalClass->engine;
+ int size = o->internalClass->size;
+ for (int i = size - 1; i > idx; --i)
+ o->setProperty(v4, i, *o->propertyData(i - 1));
}
static void removeFromPropertyData(Object *object, int idx, bool accessor = false)
{
- int inlineSize = object->d()->vtable()->nInlineProperties;
- int delta = (accessor ? 2 : 1);
- int oldSize = object->internalClass()->size + delta;
- int to = idx;
- int from = to + delta;
- if (from < inlineSize) {
- memmove(object->propertyData(to), object->d()->propertyData(from), (inlineSize - from)*sizeof(Value));
- to = inlineSize - delta;
- from = inlineSize;
- }
- if (to < inlineSize && from < oldSize) {
- Q_ASSERT(from >= inlineSize);
- memcpy(object->propertyData(to), object->d()->propertyData(from), (inlineSize - to)*sizeof(Value));
- to = inlineSize;
- from = inlineSize + delta;
- }
- if (from < oldSize) {
- Q_ASSERT(to >= inlineSize && from > to);
- memmove(object->propertyData(to), object->d()->propertyData(from), (oldSize - to)*sizeof(Value));
- }
+ Heap::Object *o = object->d();
+ ExecutionEngine *v4 = o->internalClass->engine;
+ int size = o->internalClass->size;
+ for (int i = idx; i < size; ++i)
+ o->setProperty(v4, i, *o->propertyData(i + (accessor ? 2 : 1)));
+ o->setProperty(v4, size, Primitive::undefinedValue());
+ if (accessor)
+ o->setProperty(v4, size + 1, Primitive::undefinedValue());
}
void InternalClass::changeMember(Object *object, String *string, PropertyAttributes data, uint *index)
@@ -188,7 +165,7 @@ void InternalClass::changeMember(Object *object, String *string, PropertyAttribu
object->setInternalClass(newClass);
if (newClass->size > oldClass->size) {
Q_ASSERT(newClass->size == oldClass->size + 1);
- insertHoleIntoPropertyData(object, idx + 1);
+ insertHoleIntoPropertyData(object, idx);
} else if (newClass->size < oldClass->size) {
Q_ASSERT(newClass->size == oldClass->size - 1);
removeFromPropertyData(object, idx + 1);
@@ -241,7 +218,10 @@ InternalClass *InternalClass::changeMember(Identifier *identifier, PropertyAttri
InternalClass *InternalClass::changePrototypeImpl(Heap::Object *proto)
{
+ if (proto)
+ proto->setUsedAsProto();
Q_ASSERT(prototype != proto);
+ Q_ASSERT(!proto || proto->internalClass->isUsedAsProto);
Transition temp = { { nullptr }, 0, Transition::PrototypeChange };
temp.prototype = proto;
@@ -265,6 +245,7 @@ InternalClass *InternalClass::changePrototypeImpl(Heap::Object *proto)
}
t.lookup = newClass;
+
return newClass;
}
@@ -417,7 +398,7 @@ void InternalClass::removeMember(Object *object, Identifier *id)
Q_ASSERT(t.lookup);
}
-uint QV4::InternalClass::find(const String *string)
+uint InternalClass::find(const String *string)
{
engine->identifierTable->identifier(string);
const Identifier *id = string->d()->identifier;
@@ -477,6 +458,24 @@ InternalClass *InternalClass::propertiesFrozen() const
return frozen;
}
+InternalClass *InternalClass::asProtoClass()
+{
+ if (isUsedAsProto)
+ return this;
+
+ Transition temp = { { nullptr }, nullptr, Transition::ProtoClass };
+ Transition &t = lookupOrInsertTransition(temp);
+ if (t.lookup)
+ return t.lookup;
+
+ InternalClass *newClass = engine->newClass(*this);
+ newClass->isUsedAsProto = true;
+
+ t.lookup = newClass;
+ Q_ASSERT(t.lookup);
+ return newClass;
+}
+
void InternalClass::destroy()
{
std::vector<InternalClass *> destroyStack;
@@ -506,8 +505,9 @@ void InternalClass::destroy()
}
}
-void InternalClassPool::markObjects(ExecutionEngine *engine)
+void InternalClass::updateProtoUsage(Heap::Object *o)
{
+ Q_ASSERT(isUsedAsProto);
InternalClass *ic = engine->internalClasses[EngineBase::Class_Empty];
Q_ASSERT(!ic->prototype);
@@ -518,11 +518,44 @@ void InternalClassPool::markObjects(ExecutionEngine *engine)
if (t.flags == InternalClassTransition::VTableChange) {
InternalClass *ic2 = t.lookup;
for (auto &t2 : ic2->transitions) {
+ if (t2.flags == InternalClassTransition::PrototypeChange &&
+ t2.lookup->prototype == o)
+ ic2->updateInternalClassIdRecursive();
+ }
+ } else if (t.flags == InternalClassTransition::PrototypeChange && t.lookup->prototype == o) {
+ ic->updateInternalClassIdRecursive();
+ }
+ }
+}
+
+void InternalClass::updateInternalClassIdRecursive()
+{
+ id = engine->newInternalClassId();
+ for (auto &t : transitions) {
+ Q_ASSERT(t.lookup);
+ t.lookup->updateInternalClassIdRecursive();
+ }
+}
+
+
+
+void InternalClassPool::markObjects(MarkStack *markStack)
+{
+ InternalClass *ic = markStack->engine->internalClasses[EngineBase::Class_Empty];
+ Q_ASSERT(!ic->prototype);
+
+ // only need to go two levels into the IC hierarchy, as prototype changes
+ // can only happen there
+ for (auto &t : ic->transitions) {
+ Q_ASSERT(t.lookup);
+ if (t.flags == InternalClassTransition::VTableChange) {
+ InternalClass *ic2 = t.lookup;
+ for (auto &t2 : ic2->transitions) {
if (t2.flags == InternalClassTransition::PrototypeChange)
- t2.lookup->prototype->mark(engine);
+ t2.lookup->prototype->mark(markStack);
}
} else if (t.flags == InternalClassTransition::PrototypeChange) {
- t.lookup->prototype->mark(engine);
+ t.lookup->prototype->mark(markStack);
}
}
}
diff --git a/src/qml/jsruntime/qv4internalclass_p.h b/src/qml/jsruntime/qv4internalclass_p.h
index 9e8ab9e73e..546073dcf5 100644
--- a/src/qml/jsruntime/qv4internalclass_p.h
+++ b/src/qml/jsruntime/qv4internalclass_p.h
@@ -64,6 +64,7 @@ struct String;
struct Object;
struct Identifier;
struct VTable;
+struct MarkStack;
struct PropertyHashData;
struct PropertyHash
@@ -231,7 +232,8 @@ struct InternalClassTransition
// range 0-0xff is reserved for attribute changes
NotExtensible = 0x100,
VTableChange = 0x200,
- PrototypeChange = 0x201
+ PrototypeChange = 0x201,
+ ProtoClass = 0x202
};
bool operator==(const InternalClassTransition &other) const
@@ -242,6 +244,7 @@ struct InternalClassTransition
};
struct InternalClass : public QQmlJS::Managed {
+ int id = 0; // unique across the engine, gets changed also when proto chain changes
ExecutionEngine *engine;
const VTable *vtable;
Heap::Object *prototype;
@@ -259,6 +262,7 @@ struct InternalClass : public QQmlJS::Managed {
uint size;
bool extensible;
+ bool isUsedAsProto = false;
Q_REQUIRED_RESULT InternalClass *nonExtensible();
Q_REQUIRED_RESULT InternalClass *changeVTable(const VTable *vt) {
@@ -292,12 +296,17 @@ struct InternalClass : public QQmlJS::Managed {
Q_REQUIRED_RESULT InternalClass *frozen();
Q_REQUIRED_RESULT InternalClass *propertiesFrozen() const;
+ Q_REQUIRED_RESULT InternalClass *asProtoClass();
+
void destroy();
+ void updateProtoUsage(Heap::Object *o);
+
private:
Q_QML_EXPORT InternalClass *changeVTableImpl(const VTable *vt);
Q_QML_EXPORT InternalClass *changePrototypeImpl(Heap::Object *proto);
InternalClass *addMemberImpl(Identifier *identifier, PropertyAttributes data, uint *index);
+ void updateInternalClassIdRecursive();
friend struct ExecutionEngine;
InternalClass(ExecutionEngine *engine);
InternalClass(const InternalClass &other);
@@ -305,7 +314,7 @@ private:
struct InternalClassPool : public QQmlJS::MemoryPool
{
- void markObjects(ExecutionEngine *engine);
+ void markObjects(MarkStack *markStack);
};
}
diff --git a/src/qml/jsruntime/qv4jscall_p.h b/src/qml/jsruntime/qv4jscall_p.h
new file mode 100644
index 0000000000..6d641bf9c5
--- /dev/null
+++ b/src/qml/jsruntime/qv4jscall_p.h
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QV4JSCALL_H
+#define QV4JSCALL_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qv4object_p.h"
+#include "qv4function_p.h"
+#include "qv4functionobject_p.h"
+#include "qv4context_p.h"
+#include "qv4scopedvalue_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace QV4 {
+
+struct JSCallData {
+ JSCallData(const Scope &scope, int argc = 0, const Value *argv = 0, const Value *thisObject = 0)
+ : scope(scope), argc(argc)
+ {
+ if (thisObject)
+ this->thisObject = const_cast<Value *>(thisObject);
+ else
+ this->thisObject = scope.alloc(1);
+ if (argv)
+ this->args = const_cast<Value *>(argv);
+ else
+ this->args = scope.alloc(argc);
+ }
+
+ JSCallData *operator->() {
+ return this;
+ }
+
+ CallData *callData(const FunctionObject *f = nullptr) const {
+ int size = int(offsetof(QV4::CallData, args)/sizeof(QV4::Value)) + argc;
+ CallData *ptr = reinterpret_cast<CallData *>(scope.engine->jsStackTop);
+ scope.engine->jsStackTop += size;
+ ptr->function = Encode::undefined();
+ ptr->context = Encode::undefined();
+ ptr->accumulator = Encode::undefined();
+ ptr->thisObject = thisObject->asReturnedValue();
+ ptr->setArgc(argc);
+ if (argc)
+ memcpy(ptr->args, args, argc*sizeof(Value));
+ if (f)
+ ptr->function = f->asReturnedValue();
+ return ptr;
+ }
+ const Scope &scope;
+ int argc;
+ Value *args;
+ Value *thisObject;
+};
+
+inline
+ReturnedValue FunctionObject::callAsConstructor(const JSCallData &data) const
+{
+ return d()->jsConstruct(this, data.args, data.argc);
+}
+
+inline
+ReturnedValue FunctionObject::call(const JSCallData &data) const
+{
+ return d()->jsCall(this, data.thisObject, data.args, data.argc);
+}
+
+
+struct ScopedStackFrame {
+ Scope &scope;
+ CppStackFrame frame;
+
+ ScopedStackFrame(Scope &scope, Heap::ExecutionContext *context)
+ : scope(scope)
+ {
+ frame.parent = scope.engine->currentStackFrame;
+ if (!context)
+ return;
+ frame.jsFrame = reinterpret_cast<CallData *>(scope.alloc(sizeof(CallData)/sizeof(Value)));
+ frame.jsFrame->context = context;
+ frame.v4Function = frame.parent ? frame.parent->v4Function : 0;
+ scope.engine->currentStackFrame = &frame;
+ }
+ ~ScopedStackFrame() {
+ scope.engine->currentStackFrame = frame.parent;
+ }
+};
+
+}
+
+QT_END_NAMESPACE
+
+#endif // QV4JSCALL_H
diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp
index 1d571f53f3..51802d895b 100644
--- a/src/qml/jsruntime/qv4jsonobject.cpp
+++ b/src/qml/jsruntime/qv4jsonobject.cpp
@@ -46,6 +46,7 @@
#include <qv4runtime_p.h>
#include <qv4variantobject_p.h>
#include "qv4string_p.h"
+#include "qv4jscall_p.h"
#include <qstack.h>
#include <qstringlist.h>
@@ -689,57 +690,57 @@ static QString quote(const QString &str)
QString Stringify::Str(const QString &key, const Value &v)
{
Scope scope(v4);
- scope.result = v;
- ScopedObject o(scope, scope.result);
+ ScopedValue value(scope, v);
+ ScopedObject o(scope, value);
if (o) {
ScopedString s(scope, v4->newString(QStringLiteral("toJSON")));
ScopedFunctionObject toJSON(scope, o->get(s));
if (!!toJSON) {
- ScopedCallData callData(scope, 1);
- callData->thisObject = scope.result;
- callData->args[0] = v4->newString(key);
- toJSON->call(scope, callData);
+ JSCallData jsCallData(scope, 1);
+ *jsCallData->thisObject = value;
+ jsCallData->args[0] = v4->newString(key);
+ value = toJSON->call(jsCallData);
}
}
if (replacerFunction) {
ScopedObject holder(scope, v4->newObject());
- holder->put(scope.engine, QString(), scope.result);
- ScopedCallData callData(scope, 2);
- callData->args[0] = v4->newString(key);
- callData->args[1] = scope.result;
- callData->thisObject = holder;
- replacerFunction->call(scope, callData);
+ holder->put(scope.engine->id_empty(), value);
+ JSCallData jsCallData(scope, 2);
+ jsCallData->args[0] = v4->newString(key);
+ jsCallData->args[1] = value;
+ *jsCallData->thisObject = holder;
+ value = replacerFunction->call(jsCallData);
}
- o = scope.result.asReturnedValue();
+ o = value->asReturnedValue();
if (o) {
if (NumberObject *n = o->as<NumberObject>())
- scope.result = Encode(n->value());
+ value = Encode(n->value());
else if (StringObject *so = o->as<StringObject>())
- scope.result = so->d()->string;
+ value = so->d()->string;
else if (BooleanObject *b = o->as<BooleanObject>())
- scope.result = Encode(b->value());
+ value = Encode(b->value());
}
- if (scope.result.isNull())
+ if (value->isNull())
return QStringLiteral("null");
- if (scope.result.isBoolean())
- return scope.result.booleanValue() ? QStringLiteral("true") : QStringLiteral("false");
- if (String *s = scope.result.stringValue())
- return quote(s->toQString());
-
- if (scope.result.isNumber()) {
- double d = scope.result.toNumber();
- return std::isfinite(d) ? scope.result.toQString() : QStringLiteral("null");
+ if (value->isBoolean())
+ return value->booleanValue() ? QStringLiteral("true") : QStringLiteral("false");
+ if (value->isString())
+ return quote(value->stringValue()->toQString());
+
+ if (value->isNumber()) {
+ double d = value->toNumber();
+ return std::isfinite(d) ? value->toQString() : QStringLiteral("null");
}
- if (const QV4::VariantObject *v = scope.result.as<QV4::VariantObject>()) {
+ if (const QV4::VariantObject *v = value->as<QV4::VariantObject>()) {
return v->d()->data().toString();
}
- o = scope.result.asReturnedValue();
+ o = value->asReturnedValue();
if (o) {
if (!o->as<FunctionObject>()) {
if (o->as<ArrayObject>()) {
@@ -883,28 +884,31 @@ void Heap::JsonObject::init()
}
-void JsonObject::method_parse(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue JsonObject::method_parse(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- ScopedValue v(scope, callData->argument(0));
- QString jtext = v->toQString();
+ ExecutionEngine *v4 = b->engine();
+ QString jtext;
+ if (argc > 0)
+ jtext = argv[0].toQString();
DEBUG << "parsing source = " << jtext;
- JsonParser parser(scope.engine, jtext.constData(), jtext.length());
+ JsonParser parser(v4, jtext.constData(), jtext.length());
QJsonParseError error;
- ScopedValue result(scope, parser.parse(&error));
+ ReturnedValue result = parser.parse(&error);
if (error.error != QJsonParseError::NoError) {
DEBUG << "parse error" << error.errorString();
- RETURN_RESULT(scope.engine->throwSyntaxError(QStringLiteral("JSON.parse: Parse error")));
+ RETURN_RESULT(v4->throwSyntaxError(QStringLiteral("JSON.parse: Parse error")));
}
- scope.result = result;
+ return result;
}
-void JsonObject::method_stringify(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue JsonObject::method_stringify(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
+ Scope scope(b);
Stringify stringify(scope.engine);
- ScopedObject o(scope, callData->argument(1));
+ ScopedObject o(scope, argc > 1 ? argv[1] : Primitive::undefinedValue());
if (o) {
stringify.replacerFunction = o->as<FunctionObject>();
if (o->isArrayObject()) {
@@ -929,7 +933,7 @@ void JsonObject::method_stringify(const BuiltinFunction *, Scope &scope, CallDat
}
}
- ScopedValue s(scope, callData->argument(2));
+ ScopedValue s(scope, argc > 2 ? argv[2] : Primitive::undefinedValue());
if (NumberObject *n = s->as<NumberObject>())
s = Encode(n->value());
else if (StringObject *so = s->as<StringObject>())
@@ -942,11 +946,11 @@ void JsonObject::method_stringify(const BuiltinFunction *, Scope &scope, CallDat
}
- ScopedValue arg0(scope, callData->argument(0));
+ ScopedValue arg0(scope, argc ? argv[0] : Primitive::undefinedValue());
QString result = stringify.Str(QString(), arg0);
if (result.isEmpty() || scope.engine->hasException)
RETURN_UNDEFINED();
- scope.result = scope.engine->newString(result);
+ return Encode(scope.engine->newString(result));
}
diff --git a/src/qml/jsruntime/qv4jsonobject_p.h b/src/qml/jsruntime/qv4jsonobject_p.h
index a73ce1c74e..7d9f204910 100644
--- a/src/qml/jsruntime/qv4jsonobject_p.h
+++ b/src/qml/jsruntime/qv4jsonobject_p.h
@@ -88,8 +88,8 @@ private:
typedef QSet<ObjectItem> V4ObjectSet;
public:
- static void method_parse(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_stringify(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_parse(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_stringify(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue fromJsonValue(ExecutionEngine *engine, const QJsonValue &value);
static ReturnedValue fromJsonObject(ExecutionEngine *engine, const QJsonObject &object);
diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp
index 7a158ece35..52ab03cd94 100644
--- a/src/qml/jsruntime/qv4lookup.cpp
+++ b/src/qml/jsruntime/qv4lookup.cpp
@@ -38,7 +38,7 @@
****************************************************************************/
#include "qv4lookup_p.h"
#include "qv4functionobject_p.h"
-#include "qv4scopedvalue_p.h"
+#include "qv4jscall_p.h"
#include "qv4string_p.h"
#include <private/qv4identifiertable_p.h>
@@ -47,316 +47,163 @@ QT_BEGIN_NAMESPACE
using namespace QV4;
-ReturnedValue Lookup::lookup(const Value &thisObject, Object *o, PropertyAttributes *attrs)
+void Lookup::resolveProtoGetter(Identifier *name, const Heap::Object *proto)
{
- ExecutionEngine *engine = o->engine();
- Identifier *name = engine->identifierTable->identifier(engine->current->compilationUnit->runtimeStrings[nameIndex]);
- int i = 0;
- Heap::Object *obj = o->d();
- while (i < Size && obj) {
- classList[i] = obj->internalClass;
-
- index = obj->internalClass->find(name);
- if (index != UINT_MAX) {
- level = i;
- *attrs = obj->internalClass->propertyData.at(index);
- Value *v = obj->propertyData(index);
- return !attrs->isAccessor() ? v->asReturnedValue() : Object::getValue(thisObject, *v, *attrs);
- }
-
- obj = obj->prototype();
- ++i;
- }
- level = Size;
-
- while (obj) {
- index = obj->internalClass->find(name);
- if (index != UINT_MAX) {
- *attrs = obj->internalClass->propertyData.at(index);
- Value *v = obj->propertyData(index);
- return !attrs->isAccessor() ? v->asReturnedValue() : Object::getValue(thisObject, *v, *attrs);
- }
-
- obj = obj->prototype();
- }
- return Primitive::emptyValue().asReturnedValue();
-}
-
-ReturnedValue Lookup::lookup(const Object *thisObject, PropertyAttributes *attrs)
-{
- Heap::Object *obj = thisObject->d();
- ExecutionEngine *engine = thisObject->engine();
- Identifier *name = engine->identifierTable->identifier(engine->current->compilationUnit->runtimeStrings[nameIndex]);
- int i = 0;
- while (i < Size && obj) {
- classList[i] = obj->internalClass;
-
- index = obj->internalClass->find(name);
- if (index != UINT_MAX) {
- level = i;
- *attrs = obj->internalClass->propertyData.at(index);
- Value *v = obj->propertyData(index);
- return !attrs->isAccessor() ? v->asReturnedValue() : thisObject->getValue(*v, *attrs);
- }
-
- obj = obj->prototype();
- ++i;
- }
- level = Size;
-
- while (obj) {
- index = obj->internalClass->find(name);
+ while (proto) {
+ uint index = proto->internalClass->find(name);
if (index != UINT_MAX) {
- *attrs = obj->internalClass->propertyData.at(index);
- Value *v = obj->propertyData(index);
- return !attrs->isAccessor() ? v->asReturnedValue() : thisObject->getValue(*v, *attrs);
- }
-
- obj = obj->prototype();
- }
- return Primitive::emptyValue().asReturnedValue();
-}
-
-ReturnedValue Lookup::indexedGetterGeneric(Lookup *l, const Value &object, const Value &index)
-{
- uint idx;
- if (object.isObject() && index.asArrayIndex(idx)) {
- l->indexedGetter = indexedGetterObjectInt;
- return indexedGetterObjectInt(l, object, index);
- }
- return indexedGetterFallback(l, object, index);
-}
-
-ReturnedValue Lookup::indexedGetterFallback(Lookup *l, const Value &object, const Value &index)
-{
- Q_UNUSED(l);
- Scope scope(l->engine);
- uint idx = 0;
- bool isInt = index.asArrayIndex(idx);
-
- ScopedObject o(scope, object);
- if (!o) {
- if (isInt) {
- if (const String *str = object.as<String>()) {
- if (idx >= (uint)str->toQString().length()) {
- return Encode::undefined();
- }
- const QString s = str->toQString().mid(idx, 1);
- return scope.engine->newString(s)->asReturnedValue();
+ PropertyAttributes attrs = proto->internalClass->propertyData.at(index);
+ protoLookup.data = proto->propertyData(index);
+ if (attrs.isData()) {
+ getter = getterProto;
+ } else {
+ getter = getterProtoAccessor;
}
- }
-
- if (object.isNullOrUndefined()) {
- QString message = QStringLiteral("Cannot read property '%1' of %2").arg(index.toQStringNoThrow()).arg(object.toQStringNoThrow());
- return l->engine->throwTypeError(message);
- }
-
- o = RuntimeHelpers::convertToObject(scope.engine, object);
- if (!o) // type error
- return Encode::undefined();
- }
-
- if (isInt) {
- if (o->d()->arrayData && !o->d()->arrayData->attrs) {
- ScopedValue v(scope, Scoped<ArrayData>(scope, o->arrayData())->get(idx));
- if (!v->isEmpty())
- return v->asReturnedValue();
- }
-
- return o->getIndexed(idx);
- }
-
- ScopedString name(scope, index.toString(scope.engine));
- if (scope.hasException())
- return Encode::undefined();
- return o->get(name);
-
-}
-
-
-ReturnedValue Lookup::indexedGetterObjectInt(Lookup *l, const Value &object, const Value &index)
-{
- uint idx;
- if (index.asArrayIndex(idx)) {
- if (Heap::Base *b = object.heapObject()) {
- if (b->vtable()->isObject) {
- Heap::Object *o = static_cast<Heap::Object *>(b);
- if (o->arrayData && o->arrayData->type == Heap::ArrayData::Simple) {
- Heap::SimpleArrayData *s = o->arrayData.cast<Heap::SimpleArrayData>();
- if (idx < s->len)
- if (!s->data(idx).isEmpty())
- return s->data(idx).asReturnedValue();
- }
- }
- }
- }
-
- return indexedGetterFallback(l, object, index);
-}
-
-void Lookup::indexedSetterGeneric(Lookup *l, const Value &object, const Value &index, const Value &v)
-{
- if (Object *o = object.objectValue()) {
- uint idx;
- if (o->d()->arrayData && o->d()->arrayData->type == Heap::ArrayData::Simple && index.asArrayIndex(idx)) {
- l->indexedSetter = indexedSetterObjectInt;
- indexedSetterObjectInt(l, object, index, v);
return;
}
+ proto = proto->prototype();
}
- indexedSetterFallback(l, object, index, v);
+ // ### put in a getterNotFound!
+ getter = getterFallback;
}
-void Lookup::indexedSetterFallback(Lookup *l, const Value &object, const Value &index, const Value &value)
+ReturnedValue Lookup::resolveGetter(ExecutionEngine *engine, const Object *object)
{
- Scope scope(l->engine);
- ScopedObject o(scope, object.toObject(scope.engine));
- if (scope.engine->hasException)
- return;
+ Heap::Object *obj = object->d();
+ Identifier *name = engine->identifierTable->identifier(engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
- uint idx;
- if (index.asArrayIndex(idx)) {
- if (o->d()->arrayData && o->d()->arrayData->type == Heap::ArrayData::Simple) {
- Heap::SimpleArrayData *s = o->d()->arrayData.cast<Heap::SimpleArrayData>();
- if (idx < s->len) {
- s->data(idx) = value;
- return;
+ uint index = obj->internalClass->find(name);
+ if (index != UINT_MAX) {
+ PropertyAttributes attrs = obj->internalClass->propertyData.at(index);
+ uint nInline = obj->vtable()->nInlineProperties;
+ if (attrs.isData()) {
+ if (index < obj->vtable()->nInlineProperties) {
+ index += obj->vtable()->inlinePropertyOffset;
+ getter = getter0Inline;
+ } else {
+ index -= nInline;
+ getter = getter0MemberData;
}
+ } else {
+ getter = getterAccessor;
}
- o->putIndexed(idx, value);
- return;
+ objectLookup.ic = obj->internalClass;
+ objectLookup.offset = index;
+ return getter(this, engine, *object);
}
- ScopedString name(scope, index.toString(scope.engine));
- o->put(name, value);
-}
-
-void Lookup::indexedSetterObjectInt(Lookup *l, const Value &object, const Value &index, const Value &v)
-{
- uint idx;
- if (index.asArrayIndex(idx)) {
- if (Heap::Base *b = object.heapObject()) {
- if (b->vtable()->isObject) {
- Heap::Object *o = static_cast<Heap::Object *>(b);
- if (o->arrayData && o->arrayData->type == Heap::ArrayData::Simple) {
- Heap::SimpleArrayData *s = o->arrayData.cast<Heap::SimpleArrayData>();
- if (idx < s->len) {
- s->data(idx) = v;
- return;
- }
- }
- }
- }
- }
- indexedSetterFallback(l, object, index, v);
+ protoLookup.icIdentifier = obj->internalClass->id;
+ resolveProtoGetter(name, obj->prototype());
+ return getter(this, engine, *object);
}
-ReturnedValue Lookup::getterGeneric(Lookup *l, ExecutionEngine *engine, const Value &object)
+ReturnedValue Lookup::resolvePrimitiveGetter(ExecutionEngine *engine, const Value &object)
{
- if (const Object *o = object.as<Object>())
- return o->getLookup(l);
-
- Object *proto;
- switch (object.type()) {
+ primitiveLookup.type = object.type();
+ switch (primitiveLookup.type) {
case Value::Undefined_Type:
case Value::Null_Type:
return engine->throwTypeError();
case Value::Boolean_Type:
- proto = engine->booleanPrototype();
+ primitiveLookup.proto = engine->booleanPrototype()->d();
break;
case Value::Managed_Type: {
+ // ### Should move this over to the Object path, as strings also have an internalClass
Q_ASSERT(object.isString());
- proto = engine->stringPrototype();
+ primitiveLookup.proto = engine->stringPrototype()->d();
Scope scope(engine);
- ScopedString name(scope, engine->current->compilationUnit->runtimeStrings[l->nameIndex]);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
if (name->equals(engine->id_length())) {
// special case, as the property is on the object itself
- l->getter = stringLengthGetter;
- return stringLengthGetter(l, engine, object);
+ getter = stringLengthGetter;
+ return stringLengthGetter(this, engine, object);
}
break;
}
case Value::Integer_Type:
default: // Number
- proto = engine->numberPrototype();
+ primitiveLookup.proto = engine->numberPrototype()->d();
}
- PropertyAttributes attrs;
- ReturnedValue v = l->lookup(object, proto, &attrs);
- if (v != Primitive::emptyValue().asReturnedValue()) {
- l->type = object.type();
- l->proto = proto->d();
- if (attrs.isData()) {
- if (l->level == 0) {
- uint nInline = l->proto->vtable()->nInlineProperties;
- if (l->index < nInline)
- l->getter = Lookup::primitiveGetter0Inline;
- else {
- l->index -= nInline;
- l->getter = Lookup::primitiveGetter0MemberData;
- }
- } else if (l->level == 1)
- l->getter = Lookup::primitiveGetter1;
- return v;
- } else {
- if (l->level == 0)
- l->getter = Lookup::primitiveGetterAccessor0;
- else if (l->level == 1)
- l->getter = Lookup::primitiveGetterAccessor1;
- return v;
- }
+ Identifier *name = engine->identifierTable->identifier(engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
+ protoLookup.icIdentifier = primitiveLookup.proto->internalClass->id;
+ resolveProtoGetter(name, primitiveLookup.proto);
+
+ if (getter == getterProto)
+ getter = primitiveGetterProto;
+ else if (getter == getterProtoAccessor)
+ getter = primitiveGetterAccessor;
+ return getter(this, engine, object);
+}
+
+ReturnedValue Lookup::resolveGlobalGetter(ExecutionEngine *engine)
+{
+ Object *o = engine->globalObject;
+ Identifier *name = engine->identifierTable->identifier(engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
+ protoLookup.icIdentifier = o->internalClass()->id;
+ resolveProtoGetter(name, o->d());
+
+ if (getter == getterProto)
+ globalGetter = globalGetterProto;
+ else if (getter == getterProtoAccessor)
+ globalGetter = globalGetterProtoAccessor;
+ else {
+ globalGetter = globalGetterGeneric;
+ Scope scope(engine);
+ ScopedString n(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
+ return engine->throwReferenceError(n);
}
+ return globalGetter(this, engine);
+}
- return Encode::undefined();
+ReturnedValue Lookup::getterGeneric(Lookup *l, ExecutionEngine *engine, const Value &object)
+{
+ if (const Object *o = object.as<Object>())
+ return l->resolveGetter(engine, o);
+ return l->resolvePrimitiveGetter(engine, object);
}
ReturnedValue Lookup::getterTwoClasses(Lookup *l, ExecutionEngine *engine, const Value &object)
{
- Lookup l1 = *l;
-
- if (l1.getter == Lookup::getter0MemberData || l1.getter == Lookup::getter0Inline || l1.getter == Lookup::getter1) {
- if (const Object *o = object.as<Object>()) {
- ReturnedValue v = o->getLookup(l);
- Lookup l2 = *l;
-
- if (l2.index != UINT_MAX) {
- if (l1.getter != Lookup::getter0Inline) {
- if (l2.getter == Lookup::getter0Inline ||
- (l1.getter != Lookup::getter0MemberData && l2.getter == Lookup::getter0MemberData))
- // sort the better getter first
- qSwap(l1, l2);
- }
-
- l->classList[0] = l1.classList[0];
- l->classList[1] = l1.classList[1];
- l->classList[2] = l2.classList[0];
- l->classList[3] = l2.classList[1];
- l->index = l1.index;
- l->index2 = l2.index;
-
- if (l1.getter == Lookup::getter0Inline) {
- if (l2.getter == Lookup::getter0Inline)
- l->getter = Lookup::getter0Inlinegetter0Inline;
- else if (l2.getter == Lookup::getter0MemberData)
- l->getter = Lookup::getter0Inlinegetter0MemberData;
- else if (l2.getter == Lookup::getter1)
- l->getter = Lookup::getter0Inlinegetter1;
- else
- Q_UNREACHABLE();
- } else if (l1.getter == Lookup::getter0MemberData) {
- if (l2.getter == Lookup::getter0MemberData)
- l->getter = Lookup::getter0MemberDatagetter0MemberData;
- else if (l2.getter == Lookup::getter1)
- l->getter = Lookup::getter0MemberDatagetter1;
- else
- Q_UNREACHABLE();
- } else {
- Q_ASSERT(l1.getter == Lookup::getter1 && l2.getter == Lookup::getter1);
- l->getter = Lookup::getter1getter1;
- }
- return v;
- }
+ if (const Object *o = object.as<Object>()) {
+ Lookup first = *l;
+ Lookup second = *l;
+
+ ReturnedValue result = second.resolveGetter(engine, o);
+
+ if (first.getter == getter0Inline && (second.getter == getter0Inline || second.getter == getter0MemberData)) {
+ l->objectLookupTwoClasses.ic = first.objectLookup.ic;
+ l->objectLookupTwoClasses.ic2 = second.objectLookup.ic;
+ l->objectLookupTwoClasses.offset = first.objectLookup.offset;
+ l->objectLookupTwoClasses.offset2 = second.objectLookup.offset;
+ l->getter = second.getter == getter0Inline ? getter0Inlinegetter0Inline : getter0Inlinegetter0MemberData;
+ return result;
+ }
+ if (first.getter == getter0MemberData && (second.getter == getter0Inline || second.getter == getter0MemberData)) {
+ l->objectLookupTwoClasses.ic = second.objectLookup.ic;
+ l->objectLookupTwoClasses.ic2 = first.objectLookup.ic;
+ l->objectLookupTwoClasses.offset = second.objectLookup.offset;
+ l->objectLookupTwoClasses.offset2 = first.objectLookup.offset;
+ l->getter = second.getter == getter0Inline ? getter0Inlinegetter0MemberData : getter0MemberDatagetter0MemberData;
+ return result;
}
+ if (first.getter == getterProto && second.getter == getterProto) {
+ l->protoLookupTwoClasses.icIdentifier = first.protoLookup.icIdentifier;
+ l->protoLookupTwoClasses.icIdentifier2 = second.protoLookup.icIdentifier;
+ l->protoLookupTwoClasses.data = first.protoLookup.data;
+ l->protoLookupTwoClasses.data2 = second.protoLookup.data;
+ l->getter = getterProtoTwoClasses;
+ return result;
+ }
+ if (first.getter == getterProtoAccessor && second.getter == getterProtoAccessor) {
+ l->protoLookupTwoClasses.icIdentifier = first.protoLookup.icIdentifier;
+ l->protoLookupTwoClasses.icIdentifier2 = second.protoLookup.icIdentifier;
+ l->protoLookupTwoClasses.data = first.protoLookup.data;
+ l->protoLookupTwoClasses.data2 = second.protoLookup.data;
+ l->getter = getterProtoAccessorTwoClasses;
+ return result;
+ }
+
}
l->getter = getterFallback;
@@ -369,7 +216,7 @@ ReturnedValue Lookup::getterFallback(Lookup *l, ExecutionEngine *engine, const V
QV4::ScopedObject o(scope, object.toObject(scope.engine));
if (!o)
return Encode::undefined();
- ScopedString name(scope, engine->current->compilationUnit->runtimeStrings[l->nameIndex]);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
return o->get(name);
}
@@ -379,8 +226,8 @@ ReturnedValue Lookup::getter0MemberData(Lookup *l, ExecutionEngine *engine, cons
// the internal class won't match
Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
if (o) {
- if (l->classList[0] == o->internalClass)
- return o->memberData->data[l->index].asReturnedValue();
+ if (l->objectLookup.ic == o->internalClass)
+ return o->memberData->values.data()[l->objectLookup.offset].asReturnedValue();
}
return getterTwoClasses(l, engine, object);
}
@@ -391,53 +238,34 @@ ReturnedValue Lookup::getter0Inline(Lookup *l, ExecutionEngine *engine, const Va
// the internal class won't match
Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
if (o) {
- if (l->classList[0] == o->internalClass)
- return o->inlinePropertyData(l->index)->asReturnedValue();
+ if (l->objectLookup.ic == o->internalClass)
+ return o->inlinePropertyDataWithOffset(l->objectLookup.offset)->asReturnedValue();
}
return getterTwoClasses(l, engine, object);
}
-ReturnedValue Lookup::getter1(Lookup *l, ExecutionEngine *engine, const Value &object)
+ReturnedValue Lookup::getterProto(Lookup *l, ExecutionEngine *engine, const Value &object)
{
// we can safely cast to a QV4::Object here. If object is actually a string,
// the internal class won't match
Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
if (o) {
- if (l->classList[0] == o->internalClass && l->classList[1] == l->proto->internalClass)
- return l->proto->propertyData(l->index)->asReturnedValue();
+ if (l->protoLookup.icIdentifier == o->internalClass->id)
+ return l->protoLookup.data->asReturnedValue();
}
return getterTwoClasses(l, engine, object);
}
-ReturnedValue Lookup::getter2(Lookup *l, ExecutionEngine *engine, const Value &object)
-{
- // we can safely cast to a QV4::Object here. If object is actually a string,
- // the internal class won't match
- Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
- if (o) {
- if (l->classList[0] == o->internalClass) {
- Q_ASSERT(l->proto == o->prototype());
- if (l->classList[1] == l->proto->internalClass) {
- Heap::Object *p = l->proto->prototype();
- if (l->classList[2] == p->internalClass)
- return p->propertyData(l->index)->asReturnedValue();
- }
- }
- }
- l->getter = getterFallback;
- return getterFallback(l, engine, object);
-}
-
ReturnedValue Lookup::getter0Inlinegetter0Inline(Lookup *l, ExecutionEngine *engine, const Value &object)
{
// we can safely cast to a QV4::Object here. If object is actually a string,
// the internal class won't match
Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
if (o) {
- if (l->classList[0] == o->internalClass)
- return o->inlinePropertyData(l->index)->asReturnedValue();
- if (l->classList[2] == o->internalClass)
- return o->inlinePropertyData(l->index2)->asReturnedValue();
+ if (l->objectLookupTwoClasses.ic == o->internalClass)
+ return o->inlinePropertyDataWithOffset(l->objectLookupTwoClasses.offset)->asReturnedValue();
+ if (l->objectLookupTwoClasses.ic2 == o->internalClass)
+ return o->inlinePropertyDataWithOffset(l->objectLookupTwoClasses.offset2)->asReturnedValue();
}
l->getter = getterFallback;
return getterFallback(l, engine, object);
@@ -449,10 +277,10 @@ ReturnedValue Lookup::getter0Inlinegetter0MemberData(Lookup *l, ExecutionEngine
// the internal class won't match
Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
if (o) {
- if (l->classList[0] == o->internalClass)
- return o->inlinePropertyData(l->index)->asReturnedValue();
- if (l->classList[2] == o->internalClass)
- return o->memberData->data[l->index2].asReturnedValue();
+ if (l->objectLookupTwoClasses.ic == o->internalClass)
+ return o->inlinePropertyDataWithOffset(l->objectLookupTwoClasses.offset)->asReturnedValue();
+ if (l->objectLookupTwoClasses.ic2 == o->internalClass)
+ return o->memberData->values.data()[l->objectLookupTwoClasses.offset2].asReturnedValue();
}
l->getter = getterFallback;
return getterFallback(l, engine, object);
@@ -464,206 +292,108 @@ ReturnedValue Lookup::getter0MemberDatagetter0MemberData(Lookup *l, ExecutionEng
// the internal class won't match
Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
if (o) {
- if (l->classList[0] == o->internalClass)
- return o->memberData->data[l->index].asReturnedValue();
- if (l->classList[2] == o->internalClass)
- return o->memberData->data[l->index2].asReturnedValue();
- }
- l->getter = getterFallback;
- return getterFallback(l, engine, object);
-}
-
-ReturnedValue Lookup::getter0Inlinegetter1(Lookup *l, ExecutionEngine *engine, const Value &object)
-{
- // we can safely cast to a QV4::Object here. If object is actually a string,
- // the internal class won't match
- Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
- if (o) {
- if (l->classList[0] == o->internalClass)
- return o->inlinePropertyData(l->index)->asReturnedValue();
- if (l->classList[2] == o->internalClass && l->classList[3] == o->prototype()->internalClass)
- return o->prototype()->propertyData(l->index2)->asReturnedValue();
+ if (l->objectLookupTwoClasses.ic == o->internalClass)
+ return o->memberData->values.data()[l->objectLookupTwoClasses.offset].asReturnedValue();
+ if (l->objectLookupTwoClasses.ic2 == o->internalClass)
+ return o->memberData->values.data()[l->objectLookupTwoClasses.offset2].asReturnedValue();
}
l->getter = getterFallback;
return getterFallback(l, engine, object);
}
-ReturnedValue Lookup::getter0MemberDatagetter1(Lookup *l, ExecutionEngine *engine, const Value &object)
+ReturnedValue Lookup::getterProtoTwoClasses(Lookup *l, ExecutionEngine *engine, const Value &object)
{
// we can safely cast to a QV4::Object here. If object is actually a string,
// the internal class won't match
Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
if (o) {
- if (l->classList[0] == o->internalClass)
- return o->memberData->data[l->index].asReturnedValue();
- if (l->classList[2] == o->internalClass && l->classList[3] == o->prototype()->internalClass)
- return o->prototype()->propertyData(l->index2)->asReturnedValue();
- }
- l->getter = getterFallback;
- return getterFallback(l, engine, object);
-}
-
-ReturnedValue Lookup::getter1getter1(Lookup *l, ExecutionEngine *engine, const Value &object)
-{
- // we can safely cast to a QV4::Object here. If object is actually a string,
- // the internal class won't match
- Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
- if (o) {
- if (l->classList[0] == o->internalClass &&
- l->classList[1] == o->prototype()->internalClass)
- return o->prototype()->propertyData(l->index)->asReturnedValue();
- if (l->classList[2] == o->internalClass &&
- l->classList[3] == o->prototype()->internalClass)
- return o->prototype()->propertyData(l->index2)->asReturnedValue();
+ if (l->protoLookupTwoClasses.icIdentifier == o->internalClass->id)
+ return l->protoLookupTwoClasses.data->asReturnedValue();
+ if (l->protoLookupTwoClasses.icIdentifier2 == o->internalClass->id)
+ return l->protoLookupTwoClasses.data2->asReturnedValue();
return getterFallback(l, engine, object);
}
l->getter = getterFallback;
return getterFallback(l, engine, object);
}
-
-ReturnedValue Lookup::getterAccessor0(Lookup *l, ExecutionEngine *engine, const Value &object)
+ReturnedValue Lookup::getterAccessor(Lookup *l, ExecutionEngine *engine, const Value &object)
{
// we can safely cast to a QV4::Object here. If object is actually a string,
// the internal class won't match
Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
if (o) {
- if (l->classList[0] == o->internalClass) {
- Scope scope(o->internalClass->engine);
- ScopedFunctionObject getter(scope, o->propertyData(l->index + Object::GetterOffset));
- if (!getter)
+ if (l->objectLookup.ic == o->internalClass) {
+ const Value *getter = o->propertyData(l->objectLookup.offset);
+ if (!getter->isFunctionObject()) // ### catch at resolve time
return Encode::undefined();
- ScopedCallData callData(scope, 0);
- callData->thisObject = object;
- getter->call(scope, callData);
- return scope.result.asReturnedValue();
+ return static_cast<const FunctionObject *>(getter)->call(&object, nullptr, 0);
}
}
l->getter = getterFallback;
return getterFallback(l, engine, object);
}
-ReturnedValue Lookup::getterAccessor1(Lookup *l, ExecutionEngine *engine, const Value &object)
+ReturnedValue Lookup::getterProtoAccessor(Lookup *l, ExecutionEngine *engine, const Value &object)
{
// we can safely cast to a QV4::Object here. If object is actually a string,
// the internal class won't match
Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
- if (o) {
- if (l->classList[0] == o->internalClass &&
- l->classList[1] == l->proto->internalClass) {
- Scope scope(o->internalClass->engine);
- ScopedFunctionObject getter(scope, o->prototype()->propertyData(l->index + Object::GetterOffset));
- if (!getter)
- return Encode::undefined();
+ if (o && l->protoLookup.icIdentifier == o->internalClass->id) {
+ const Value *getter = l->protoLookup.data;
+ if (!getter->isFunctionObject()) // ### catch at resolve time
+ return Encode::undefined();
- ScopedCallData callData(scope, 0);
- callData->thisObject = object;
- getter->call(scope, callData);
- return scope.result.asReturnedValue();
- }
+ return static_cast<const FunctionObject *>(getter)->call(&object, nullptr, 0);
}
- l->getter = getterFallback;
- return getterFallback(l, engine, object);
+ l->getter = getterTwoClasses;
+ return getterTwoClasses(l, engine, object);
}
-ReturnedValue Lookup::getterAccessor2(Lookup *l, ExecutionEngine *engine, const Value &object)
+ReturnedValue Lookup::getterProtoAccessorTwoClasses(Lookup *l, ExecutionEngine *engine, const Value &object)
{
// we can safely cast to a QV4::Object here. If object is actually a string,
// the internal class won't match
Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
if (o) {
- if (l->classList[0] == o->internalClass) {
- Q_ASSERT(o->prototype() == l->proto);
- if (l->classList[1] == l->proto->internalClass) {
- o = l->proto->prototype();
- if (l->classList[2] == o->internalClass) {
- Scope scope(o->internalClass->engine);
- ScopedFunctionObject getter(scope, o->propertyData(l->index + Object::GetterOffset));
- if (!getter)
- return Encode::undefined();
-
- ScopedCallData callData(scope, 0);
- callData->thisObject = object;
- getter->call(scope, callData);
- return scope.result.asReturnedValue();
- }
- }
+ const Value *getter = nullptr;
+ if (l->protoLookupTwoClasses.icIdentifier == o->internalClass->id)
+ getter = l->protoLookupTwoClasses.data;
+ else if (l->protoLookupTwoClasses.icIdentifier2 == o->internalClass->id)
+ getter = l->protoLookupTwoClasses.data2;
+ if (getter) {
+ if (!getter->isFunctionObject()) // ### catch at resolve time
+ return Encode::undefined();
+
+ return static_cast<const FunctionObject *>(getter)->call(&object, nullptr, 0);
}
}
l->getter = getterFallback;
return getterFallback(l, engine, object);
}
-ReturnedValue Lookup::primitiveGetter0Inline(Lookup *l, ExecutionEngine *engine, const Value &object)
-{
- if (object.type() == l->type) {
- Heap::Object *o = l->proto;
- if (l->classList[0] == o->internalClass)
- return o->inlinePropertyData(l->index)->asReturnedValue();
- }
- l->getter = getterGeneric;
- return getterGeneric(l, engine, object);
-}
-
-ReturnedValue Lookup::primitiveGetter0MemberData(Lookup *l, ExecutionEngine *engine, const Value &object)
+ReturnedValue Lookup::primitiveGetterProto(Lookup *l, ExecutionEngine *engine, const Value &object)
{
- if (object.type() == l->type) {
- Heap::Object *o = l->proto;
- if (l->classList[0] == o->internalClass)
- return o->memberData->data[l->index].asReturnedValue();
- }
- l->getter = getterGeneric;
- return getterGeneric(l, engine, object);
-}
-
-ReturnedValue Lookup::primitiveGetter1(Lookup *l, ExecutionEngine *engine, const Value &object)
-{
- if (object.type() == l->type) {
- Heap::Object *o = l->proto;
- if (l->classList[0] == o->internalClass &&
- l->classList[1] == o->prototype()->internalClass)
- return o->prototype()->propertyData(l->index)->asReturnedValue();
- }
- l->getter = getterGeneric;
- return getterGeneric(l, engine, object);
-}
-
-ReturnedValue Lookup::primitiveGetterAccessor0(Lookup *l, ExecutionEngine *engine, const Value &object)
-{
- if (object.type() == l->type) {
- Heap::Object *o = l->proto;
- if (l->classList[0] == o->internalClass) {
- Scope scope(o->internalClass->engine);
- ScopedFunctionObject getter(scope, o->propertyData(l->index + Object::GetterOffset));
- if (!getter)
- return Encode::undefined();
-
- ScopedCallData callData(scope, 0);
- callData->thisObject = object;
- getter->call(scope, callData);
- return scope.result.asReturnedValue();
- }
+ if (object.type() == l->primitiveLookup.type) {
+ Heap::Object *o = l->primitiveLookup.proto;
+ if (l->primitiveLookup.icIdentifier == o->internalClass->id)
+ return l->primitiveLookup.data->asReturnedValue();
}
l->getter = getterGeneric;
return getterGeneric(l, engine, object);
}
-ReturnedValue Lookup::primitiveGetterAccessor1(Lookup *l, ExecutionEngine *engine, const Value &object)
+ReturnedValue Lookup::primitiveGetterAccessor(Lookup *l, ExecutionEngine *engine, const Value &object)
{
- if (object.type() == l->type) {
- Heap::Object *o = l->proto;
- if (l->classList[0] == o->internalClass &&
- l->classList[1] == o->prototype()->internalClass) {
- Scope scope(o->internalClass->engine);
- ScopedFunctionObject getter(scope, o->prototype()->propertyData(l->index + Object::GetterOffset));
- if (!getter)
+ if (object.type() == l->primitiveLookup.type) {
+ Heap::Object *o = l->primitiveLookup.proto;
+ if (l->primitiveLookup.icIdentifier == o->internalClass->id) {
+ const Value *getter = l->primitiveLookup.data;
+ if (!getter->isFunctionObject()) // ### catch at resolve time
return Encode::undefined();
- ScopedCallData callData(scope, 0);
- callData->thisObject = object;
- getter->call(scope, callData);
- return scope.result.asReturnedValue();
+ return static_cast<const FunctionObject *>(getter)->call(&object, nullptr, 0);
}
}
l->getter = getterGeneric;
@@ -679,296 +409,194 @@ ReturnedValue Lookup::stringLengthGetter(Lookup *l, ExecutionEngine *engine, con
return getterGeneric(l, engine, object);
}
-ReturnedValue Lookup::arrayLengthGetter(Lookup *l, ExecutionEngine *engine, const Value &object)
-{
- if (const ArrayObject *a = object.as<ArrayObject>())
- return a->propertyData(Heap::ArrayObject::LengthPropertyIndex)->asReturnedValue();
-
- l->getter = getterGeneric;
- return getterGeneric(l, engine, object);
-}
-
-
ReturnedValue Lookup::globalGetterGeneric(Lookup *l, ExecutionEngine *engine)
{
- Object *o = engine->globalObject;
- PropertyAttributes attrs;
- ReturnedValue v = l->lookup(o, &attrs);
- if (v != Primitive::emptyValue().asReturnedValue()) {
- if (attrs.isData()) {
- if (l->level == 0) {
- uint nInline = o->d()->vtable()->nInlineProperties;
- if (l->index < nInline)
- l->globalGetter = globalGetter0Inline;
- else {
- l->index -= nInline;
- l->globalGetter = globalGetter0MemberData;
- }
- } else if (l->level == 1)
- l->globalGetter = globalGetter1;
- else if (l->level == 2)
- l->globalGetter = globalGetter2;
- return v;
- } else {
- if (l->level == 0)
- l->globalGetter = globalGetterAccessor0;
- else if (l->level == 1)
- l->globalGetter = globalGetterAccessor1;
- else if (l->level == 2)
- l->globalGetter = globalGetterAccessor2;
- return v;
- }
- }
- Scope scope(engine);
- ScopedString n(scope, engine->current->compilationUnit->runtimeStrings[l->nameIndex]);
- return engine->throwReferenceError(n);
-}
-
-ReturnedValue Lookup::globalGetter0Inline(Lookup *l, ExecutionEngine *engine)
-{
- Object *o = engine->globalObject;
- if (l->classList[0] == o->internalClass())
- return o->d()->inlinePropertyData(l->index)->asReturnedValue();
-
- l->globalGetter = globalGetterGeneric;
- return globalGetterGeneric(l, engine);
+ return l->resolveGlobalGetter(engine);
}
-ReturnedValue Lookup::globalGetter0MemberData(Lookup *l, ExecutionEngine *engine)
-{
- Object *o = engine->globalObject;
- if (l->classList[0] == o->internalClass())
- return o->d()->memberData->data[l->index].asReturnedValue();
-
- l->globalGetter = globalGetterGeneric;
- return globalGetterGeneric(l, engine);
-}
-
-ReturnedValue Lookup::globalGetter1(Lookup *l, ExecutionEngine *engine)
-{
- Object *o = engine->globalObject;
- if (l->classList[0] == o->internalClass() &&
- l->classList[1] == o->prototype()->internalClass)
- return o->prototype()->propertyData(l->index)->asReturnedValue();
-
- l->globalGetter = globalGetterGeneric;
- return globalGetterGeneric(l, engine);
-}
-
-ReturnedValue Lookup::globalGetter2(Lookup *l, ExecutionEngine *engine)
+ReturnedValue Lookup::globalGetterProto(Lookup *l, ExecutionEngine *engine)
{
Heap::Object *o = engine->globalObject->d();
- if (l->classList[0] == o->internalClass) {
- o = o->prototype();
- if (l->classList[1] == o->internalClass) {
- o = o->prototype();
- if (l->classList[2] == o->internalClass) {
- return o->prototype()->propertyData(l->index)->asReturnedValue();
- }
- }
- }
+ if (l->protoLookup.icIdentifier == o->internalClass->id)
+ return l->protoLookup.data->asReturnedValue();
l->globalGetter = globalGetterGeneric;
return globalGetterGeneric(l, engine);
}
-ReturnedValue Lookup::globalGetterAccessor0(Lookup *l, ExecutionEngine *engine)
+ReturnedValue Lookup::globalGetterProtoAccessor(Lookup *l, ExecutionEngine *engine)
{
- Object *o = engine->globalObject;
- if (l->classList[0] == o->internalClass()) {
- Scope scope(o->engine());
- ScopedFunctionObject getter(scope, o->propertyData(l->index + Object::GetterOffset));
- if (!getter)
+ Heap::Object *o = engine->globalObject->d();
+ if (l->protoLookup.icIdentifier == o->internalClass->id) {
+ const Value *getter = l->protoLookup.data;
+ if (!getter->isFunctionObject()) // ### catch at resolve time
return Encode::undefined();
- ScopedCallData callData(scope, 0);
- callData->thisObject = Primitive::undefinedValue();
- getter->call(scope, callData);
- return scope.result.asReturnedValue();
+ return static_cast<const FunctionObject *>(getter)->call(engine->globalObject, nullptr, 0);
}
l->globalGetter = globalGetterGeneric;
return globalGetterGeneric(l, engine);
}
-ReturnedValue Lookup::globalGetterAccessor1(Lookup *l, ExecutionEngine *engine)
+bool Lookup::resolveSetter(ExecutionEngine *engine, Object *object, const Value &value)
{
- Object *o = engine->globalObject;
- if (l->classList[0] == o->internalClass() &&
- l->classList[1] == o->prototype()->internalClass) {
- Scope scope(o->engine());
- ScopedFunctionObject getter(scope, o->prototype()->propertyData(l->index + Object::GetterOffset));
- if (!getter)
- return Encode::undefined();
+ Scope scope(engine);
+ ScopedString name(scope, scope.engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
+
+ InternalClass *c = object->internalClass();
+ uint idx = c->find(name);
+ if (idx != UINT_MAX) {
+ if (object->isArrayObject() && idx == Heap::ArrayObject::LengthPropertyIndex) {
+ setter = arrayLengthSetter;
+ return setter(this, engine, *object, value);
+ } else if (object->internalClass()->propertyData[idx].isData() && object->internalClass()->propertyData[idx].isWritable()) {
+ objectLookup.ic = object->internalClass();
+ objectLookup.offset = idx;
+ setter = idx < object->d()->vtable()->nInlineProperties ? Lookup::setter0Inline : Lookup::setter0;
+ return setter(this, engine, *object, value);
+ } else {
+ // ### handle setter
+ setter = setterFallback;
+ }
+ return setter(this, engine, *object, value);
+ }
- ScopedCallData callData(scope, 0);
- callData->thisObject = Primitive::undefinedValue();
- getter->call(scope, callData);
- return scope.result.asReturnedValue();
+ insertionLookup.icIdentifier = c->id;
+ if (!object->put(name, value)) {
+ setter = Lookup::setterFallback;
+ return false;
}
- l->globalGetter = globalGetterGeneric;
- return globalGetterGeneric(l, engine);
-}
-ReturnedValue Lookup::globalGetterAccessor2(Lookup *l, ExecutionEngine *engine)
-{
- Heap::Object *o = engine->globalObject->d();
- if (l->classList[0] == o->internalClass) {
- o = o->prototype();
- if (l->classList[1] == o->internalClass) {
- o = o->prototype();
- if (l->classList[2] == o->internalClass) {
- Scope scope(o->internalClass->engine);
- ScopedFunctionObject getter(scope, o->propertyData(l->index + Object::GetterOffset));
- if (!getter)
- return Encode::undefined();
-
- ScopedCallData callData(scope, 0);
- callData->thisObject = Primitive::undefinedValue();
- getter->call(scope, callData);
- return scope.result.asReturnedValue();
- }
- }
+ if (object->internalClass() == c) {
+ // ### setter in the prototype, should handle this
+ setter = setterFallback;
+ return true;
}
- l->globalGetter = globalGetterGeneric;
- return globalGetterGeneric(l, engine);
+ idx = object->internalClass()->find(name);
+ if (idx == UINT_MAX) { // ### can this even happen?
+ setter = setterFallback;
+ return false;
+ }
+ insertionLookup.newClass = object->internalClass();
+ insertionLookup.offset = idx;
+ setter = setterInsert;
+ return true;
}
-void Lookup::setterGeneric(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
+bool Lookup::setterGeneric(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
{
+ if (object.isObject())
+ return l->resolveSetter(engine, static_cast<Object *>(&object), value);
+
Scope scope(engine);
- ScopedObject o(scope, object);
- if (!o) {
- o = RuntimeHelpers::convertToObject(scope.engine, object);
- if (!o) // type error
- return;
- ScopedString name(scope, engine->current->compilationUnit->runtimeStrings[l->nameIndex]);
- o->put(name, value);
- return;
- }
- o->setLookup(l, value);
+ ScopedObject o(scope, RuntimeHelpers::convertToObject(scope.engine, object));
+ if (!o) // type error
+ return false;
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
+ return o->put(name, value);
}
-void Lookup::setterTwoClasses(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
+bool Lookup::setterTwoClasses(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
{
- Lookup l1 = *l;
+ Lookup first = *l;
+ Lookup second = *l;
- if (Object *o = object.as<Object>()) {
- o->setLookup(l, value);
+ if (object.isObject()) {
+ if (!l->resolveSetter(engine, static_cast<Object *>(&object), value)) {
+ l->setter = setterFallback;
+ return false;
+ }
if (l->setter == Lookup::setter0 || l->setter == Lookup::setter0Inline) {
+ l->objectLookupTwoClasses.ic = first.objectLookup.ic;
+ l->objectLookupTwoClasses.ic2 = second.objectLookup.ic;
+ l->objectLookupTwoClasses.offset = first.objectLookup.offset;
+ l->objectLookupTwoClasses.offset2 = second.objectLookup.offset;
l->setter = setter0setter0;
- l->classList[1] = l1.classList[0];
- l->index2 = l1.index;
- return;
+ return true;
}
}
l->setter = setterFallback;
- setterFallback(l, engine, object, value);
+ return setterFallback(l, engine, object, value);
}
-void Lookup::setterFallback(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
+bool Lookup::setterFallback(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
{
QV4::Scope scope(engine);
QV4::ScopedObject o(scope, object.toObject(scope.engine));
- if (o) {
- ScopedString name(scope, engine->current->compilationUnit->runtimeStrings[l->nameIndex]);
- o->put(name, value);
- }
-}
-
-void Lookup::setter0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
-{
- Object *o = static_cast<Object *>(object.managed());
- if (o && o->internalClass() == l->classList[0]) {
- *o->propertyData(l->index) = value;
- return;
- }
+ if (!o)
+ return false;
- setterTwoClasses(l, engine, object, value);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[l->nameIndex]);
+ return o->put(name, value);
}
-void Lookup::setter0Inline(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
+bool Lookup::setter0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
{
- Object *o = static_cast<Object *>(object.managed());
- if (o && o->internalClass() == l->classList[0]) {
- *o->d()->inlinePropertyData(l->index) = value;
- return;
+ Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
+ if (o && o->internalClass == l->objectLookup.ic) {
+ o->setProperty(engine, l->objectLookup.offset, value);
+ return true;
}
- setterTwoClasses(l, engine, object, value);
+ return setterTwoClasses(l, engine, object, value);
}
-void Lookup::setterInsert0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
+bool Lookup::setter0Inline(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
{
- Object *o = static_cast<Object *>(object.managed());
- if (o && o->internalClass() == l->classList[0]) {
- Q_ASSERT(!o->prototype());
- o->setInternalClass(l->classList[3]);
- *o->propertyData(l->index) = value;
- return;
+ Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
+ if (o && o->internalClass == l->objectLookup.ic) {
+ o->setInlineProperty(engine, l->objectLookup.offset, value);
+ return true;
}
- l->setter = setterFallback;
- setterFallback(l, engine, object, value);
+ return setterTwoClasses(l, engine, object, value);
}
-void Lookup::setterInsert1(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
+bool Lookup::setter0setter0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
{
- Object *o = static_cast<Object *>(object.managed());
- if (o && o->internalClass() == l->classList[0]) {
- Heap::Object *p = o->prototype();
- Q_ASSERT(p);
- if (p->internalClass == l->classList[1]) {
- Q_ASSERT(!p->prototype());
- o->setInternalClass(l->classList[3]);
- *o->propertyData(l->index) = value;
- return;
+ Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
+ if (o) {
+ if (o->internalClass == l->objectLookupTwoClasses.ic) {
+ o->setProperty(engine, l->objectLookupTwoClasses.offset, value);
+ return true;
+ }
+ if (o->internalClass == l->objectLookupTwoClasses.ic2) {
+ o->setProperty(engine, l->objectLookupTwoClasses.offset2, value);
+ return true;
}
}
l->setter = setterFallback;
- setterFallback(l, engine, object, value);
+ return setterFallback(l, engine, object, value);
}
-void Lookup::setterInsert2(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
+bool Lookup::setterInsert(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
{
Object *o = static_cast<Object *>(object.managed());
- if (o && o->internalClass() == l->classList[0]) {
- Heap::Object *p = o->prototype();
- Q_ASSERT(p);
- if (p->internalClass == l->classList[1]) {
- p = p->prototype();
- Q_ASSERT(p);
- if (p->internalClass == l->classList[2]) {
- Q_ASSERT(!p->prototype());
- o->setInternalClass(l->classList[3]);
- *o->propertyData(l->index) = value;
- return;
- }
- }
+ if (o && o->internalClass()->id == l->insertionLookup.icIdentifier) {
+ o->setInternalClass(l->insertionLookup.newClass);
+ o->d()->setProperty(engine, l->insertionLookup.offset, value);
+ return true;
}
l->setter = setterFallback;
- setterFallback(l, engine, object, value);
+ return setterFallback(l, engine, object, value);
}
-void Lookup::setter0setter0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value)
+bool Lookup::arrayLengthSetter(Lookup *, ExecutionEngine *engine, Value &object, const Value &value)
{
- Object *o = static_cast<Object *>(object.managed());
- if (o) {
- if (o->internalClass() == l->classList[0]) {
- *o->propertyData(l->index) = value;
- return;
- }
- if (o->internalClass() == l->classList[1]) {
- *o->propertyData(l->index2) = value;
- return;
- }
+ Q_ASSERT(object.isObject() && static_cast<Object &>(object).isArrayObject());
+ bool ok;
+ uint len = value.asArrayLength(&ok);
+ if (!ok) {
+ engine->throwRangeError(value);
+ return false;
}
-
- l->setter = setterFallback;
- setterFallback(l, engine, object, value);
-
+ ok = static_cast<Object &>(object).setArrayLength(len);
+ if (!ok)
+ return false;
+ return true;
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4lookup_p.h b/src/qml/jsruntime/qv4lookup_p.h
index 151231991f..5f507733fd 100644
--- a/src/qml/jsruntime/qv4lookup_p.h
+++ b/src/qml/jsruntime/qv4lookup_p.h
@@ -67,37 +67,50 @@ namespace QV4 {
struct Lookup {
enum { Size = 4 };
union {
- ReturnedValue (*indexedGetter)(Lookup *l, const Value &object, const Value &index);
- void (*indexedSetter)(Lookup *l, const Value &object, const Value &index, const Value &v);
ReturnedValue (*getter)(Lookup *l, ExecutionEngine *engine, const Value &object);
ReturnedValue (*globalGetter)(Lookup *l, ExecutionEngine *engine);
- void (*setter)(Lookup *l, ExecutionEngine *engine, Value &object, const Value &v);
+ bool (*setter)(Lookup *l, ExecutionEngine *engine, Value &object, const Value &v);
};
union {
- ExecutionEngine *engine;
- InternalClass *classList[Size];
struct {
- void *dummy0;
- void *dummy1;
- void *dummy2;
+ InternalClass *ic;
+ int offset;
+ } objectLookup;
+ struct {
+ const Value *data;
+ int icIdentifier;
+ } protoLookup;
+ struct {
+ InternalClass *ic;
+ InternalClass *ic2;
+ int offset;
+ int offset2;
+ } objectLookupTwoClasses;
+ struct {
+ const Value *data;
+ const Value *data2;
+ int icIdentifier;
+ int icIdentifier2;
+ } protoLookupTwoClasses;
+ struct {
+ // Make sure the next two values are in sync with protoLookup
+ const Value *data;
+ int icIdentifier;
+ unsigned type;
Heap::Object *proto;
- };
- };
- union {
- int level;
- uint index2;
- unsigned type;
+ } primitiveLookup;
+ struct {
+ InternalClass *newClass;
+ int icIdentifier;
+ int offset;
+ } insertionLookup;
};
- uint index;
uint nameIndex;
- static ReturnedValue indexedGetterGeneric(Lookup *l, const Value &object, const Value &index);
- static ReturnedValue indexedGetterFallback(Lookup *l, const Value &object, const Value &index);
- static ReturnedValue indexedGetterObjectInt(Lookup *l, const Value &object, const Value &index);
-
- static void indexedSetterGeneric(Lookup *l, const Value &object, const Value &index, const Value &v);
- static void indexedSetterFallback(Lookup *l, const Value &object, const Value &index, const Value &value);
- static void indexedSetterObjectInt(Lookup *l, const Value &object, const Value &index, const Value &v);
+ ReturnedValue resolveGetter(ExecutionEngine *engine, const Object *object);
+ ReturnedValue resolvePrimitiveGetter(ExecutionEngine *engine, const Value &object);
+ ReturnedValue resolveGlobalGetter(ExecutionEngine *engine);
+ void resolveProtoGetter(Identifier *name, const Heap::Object *proto);
static ReturnedValue getterGeneric(Lookup *l, ExecutionEngine *engine, const Value &object);
static ReturnedValue getterTwoClasses(Lookup *l, ExecutionEngine *engine, const Value &object);
@@ -105,56 +118,38 @@ struct Lookup {
static ReturnedValue getter0MemberData(Lookup *l, ExecutionEngine *engine, const Value &object);
static ReturnedValue getter0Inline(Lookup *l, ExecutionEngine *engine, const Value &object);
- static ReturnedValue getter1(Lookup *l, ExecutionEngine *engine, const Value &object);
- static ReturnedValue getter2(Lookup *l, ExecutionEngine *engine, const Value &object);
+ static ReturnedValue getterProto(Lookup *l, ExecutionEngine *engine, const Value &object);
static ReturnedValue getter0Inlinegetter0Inline(Lookup *l, ExecutionEngine *engine, const Value &object);
static ReturnedValue getter0Inlinegetter0MemberData(Lookup *l, ExecutionEngine *engine, const Value &object);
static ReturnedValue getter0MemberDatagetter0MemberData(Lookup *l, ExecutionEngine *engine, const Value &object);
- static ReturnedValue getter0Inlinegetter1(Lookup *l, ExecutionEngine *engine, const Value &object);
- static ReturnedValue getter0MemberDatagetter1(Lookup *l, ExecutionEngine *engine, const Value &object);
- static ReturnedValue getter1getter1(Lookup *l, ExecutionEngine *engine, const Value &object);
- static ReturnedValue getterAccessor0(Lookup *l, ExecutionEngine *engine, const Value &object);
- static ReturnedValue getterAccessor1(Lookup *l, ExecutionEngine *engine, const Value &object);
- static ReturnedValue getterAccessor2(Lookup *l, ExecutionEngine *engine, const Value &object);
-
- static ReturnedValue primitiveGetter0Inline(Lookup *l, ExecutionEngine *engine, const Value &object);
- static ReturnedValue primitiveGetter0MemberData(Lookup *l, ExecutionEngine *engine, const Value &object);
- static ReturnedValue primitiveGetter1(Lookup *l, ExecutionEngine *engine, const Value &object);
- static ReturnedValue primitiveGetterAccessor0(Lookup *l, ExecutionEngine *engine, const Value &object);
- static ReturnedValue primitiveGetterAccessor1(Lookup *l, ExecutionEngine *engine, const Value &object);
+ static ReturnedValue getterProtoTwoClasses(Lookup *l, ExecutionEngine *engine, const Value &object);
+ static ReturnedValue getterAccessor(Lookup *l, ExecutionEngine *engine, const Value &object);
+ static ReturnedValue getterProtoAccessor(Lookup *l, ExecutionEngine *engine, const Value &object);
+ static ReturnedValue getterProtoAccessorTwoClasses(Lookup *l, ExecutionEngine *engine, const Value &object);
+
+ static ReturnedValue primitiveGetterProto(Lookup *l, ExecutionEngine *engine, const Value &object);
+ static ReturnedValue primitiveGetterAccessor(Lookup *l, ExecutionEngine *engine, const Value &object);
static ReturnedValue stringLengthGetter(Lookup *l, ExecutionEngine *engine, const Value &object);
- static ReturnedValue arrayLengthGetter(Lookup *l, ExecutionEngine *engine, const Value &object);
static ReturnedValue globalGetterGeneric(Lookup *l, ExecutionEngine *engine);
- static ReturnedValue globalGetter0Inline(Lookup *l, ExecutionEngine *engine);
- static ReturnedValue globalGetter0MemberData(Lookup *l, ExecutionEngine *engine);
- static ReturnedValue globalGetter1(Lookup *l, ExecutionEngine *engine);
- static ReturnedValue globalGetter2(Lookup *l, ExecutionEngine *engine);
- static ReturnedValue globalGetterAccessor0(Lookup *l, ExecutionEngine *engine);
- static ReturnedValue globalGetterAccessor1(Lookup *l, ExecutionEngine *engine);
- static ReturnedValue globalGetterAccessor2(Lookup *l, ExecutionEngine *engine);
-
- static void setterGeneric(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
- static void setterTwoClasses(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
- static void setterFallback(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
- static void setter0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
- static void setter0Inline(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
- static void setterInsert0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
- static void setterInsert1(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
- static void setterInsert2(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
- static void setter0setter0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
-
- ReturnedValue lookup(const Value &thisObject, Object *obj, PropertyAttributes *attrs);
- ReturnedValue lookup(const Object *obj, PropertyAttributes *attrs);
-
+ static ReturnedValue globalGetterProto(Lookup *l, ExecutionEngine *engine);
+ static ReturnedValue globalGetterProtoAccessor(Lookup *l, ExecutionEngine *engine);
+
+ bool resolveSetter(ExecutionEngine *engine, Object *object, const Value &value);
+ static bool setterGeneric(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
+ static bool setterTwoClasses(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
+ static bool setterFallback(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
+ static bool setter0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
+ static bool setter0Inline(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
+ static bool setter0setter0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
+ static bool setterInsert(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
+ static bool arrayLengthSetter(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
};
Q_STATIC_ASSERT(std::is_standard_layout<Lookup>::value);
// Ensure that these offsets are always at this point to keep generated code compatible
// across 32-bit and 64-bit (matters when cross-compiling).
-Q_STATIC_ASSERT(offsetof(Lookup, indexedGetter) == 0);
Q_STATIC_ASSERT(offsetof(Lookup, getter) == 0);
-Q_STATIC_ASSERT(offsetof(Lookup, engine) == offsetof(Lookup, getter) + QT_POINTER_SIZE);
}
diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h
index 6859334797..092c61b81c 100644
--- a/src/qml/jsruntime/qv4managed_p.h
+++ b/src/qml/jsruntime/qv4managed_p.h
@@ -54,6 +54,7 @@
#include "qv4value_p.h"
#include "qv4enginebase_p.h"
#include <private/qv4heap_p.h>
+#include <private/qv4writebarrier_p.h>
QT_BEGIN_NAMESPACE
@@ -92,7 +93,7 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
dptr->_checkIsInitialized(); \
return dptr; \
} \
- V4_ASSERT_IS_TRIVIAL(QV4::Heap::DataClass)
+ Q_STATIC_ASSERT(std::is_trivial< QV4::Heap::DataClass >::value);
#define V4_MANAGED(DataClass, superClass) \
private: \
@@ -131,7 +132,7 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
{ \
parentVTable, \
(sizeof(classname::Data) + sizeof(QV4::Value) - 1)/sizeof(QV4::Value), \
- (sizeof(classname::Data) + (std::is_same<classname, Object>::value ? 2*sizeof(QV4::Value) : 0) + QV4::Chunk::SlotSize - 1)/QV4::Chunk::SlotSize*QV4::Chunk::SlotSize/sizeof(QV4::Value) \
+ (sizeof(classname::Data) + (classname::NInlineProperties*sizeof(QV4::Value)) + QV4::Chunk::SlotSize - 1)/QV4::Chunk::SlotSize*QV4::Chunk::SlotSize/sizeof(QV4::Value) \
- (sizeof(classname::Data) + sizeof(QV4::Value) - 1)/sizeof(QV4::Value), \
classname::IsExecutionContext, \
classname::IsString, \
@@ -143,9 +144,9 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
classname::MyType, \
#classname, \
Q_VTABLE_FUNCTION(classname, destroy), \
- markObjects, \
+ classname::Data::markObjects, \
isEqualTo \
-}
+} \
#define DEFINE_MANAGED_VTABLE(classname) \
QT_WARNING_SUPPRESS_GCC_TAUTOLOGICAL_COMPARE_ON \
@@ -173,6 +174,7 @@ private:
Q_DISABLE_COPY(Managed)
public:
+ enum { NInlineProperties = 0 };
enum Type {
Type_Invalid,
@@ -215,6 +217,7 @@ public:
bool inUse() const { return d()->inUse(); }
bool markBit() const { return d()->isMarked(); }
+ inline void mark(MarkStack *markStack);
static void destroy(Heap::Base *) {}
@@ -235,6 +238,11 @@ private:
friend struct ObjectIterator;
};
+inline void Managed::mark(MarkStack *markStack)
+{
+ Q_ASSERT(m());
+ m()->mark(markStack);
+}
template<>
inline const Managed *Value::as() const {
diff --git a/src/qml/jsruntime/qv4mathobject.cpp b/src/qml/jsruntime/qv4mathobject.cpp
index 109d6c38b5..0c18d908de 100644
--- a/src/qml/jsruntime/qv4mathobject.cpp
+++ b/src/qml/jsruntime/qv4mathobject.cpp
@@ -42,6 +42,7 @@
#include <QtCore/qdatetime.h>
#include <QtCore/qmath.h>
+#include <QtCore/qrandom.h>
#include <QtCore/private/qnumeric_p.h>
#include <QtCore/qthreadstorage.h>
@@ -93,54 +94,54 @@ static Q_ALWAYS_INLINE double copySign(double x, double y)
return ::copysign(x, y);
}
-void MathObject::method_abs(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue MathObject::method_abs(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- if (!callData->argc)
+ if (!argc)
RETURN_RESULT(Encode(qt_qnan()));
- if (callData->args[0].isInteger()) {
- int i = callData->args[0].integerValue();
+ if (argv[0].isInteger()) {
+ int i = argv[0].integerValue();
RETURN_RESULT(Encode(i < 0 ? - i : i));
}
- double v = callData->args[0].toNumber();
+ double v = argv[0].toNumber();
if (v == 0) // 0 | -0
RETURN_RESULT(Encode(0));
RETURN_RESULT(Encode(v < 0 ? -v : v));
}
-void MathObject::method_acos(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue MathObject::method_acos(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- double v = callData->argc ? callData->args[0].toNumber() : 2;
+ double v = argc ? argv[0].toNumber() : 2;
if (v > 1)
RETURN_RESULT(Encode(qt_qnan()));
RETURN_RESULT(Encode(std::acos(v)));
}
-void MathObject::method_asin(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue MathObject::method_asin(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- double v = callData->argc ? callData->args[0].toNumber() : 2;
+ double v = argc ? argv[0].toNumber() : 2;
if (v > 1)
RETURN_RESULT(Encode(qt_qnan()));
else
RETURN_RESULT(Encode(std::asin(v)));
}
-void MathObject::method_atan(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue MathObject::method_atan(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double v = argc ? argv[0].toNumber() : qt_qnan();
if (v == 0.0)
RETURN_RESULT(Encode(v));
else
RETURN_RESULT(Encode(std::atan(v)));
}
-void MathObject::method_atan2(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue MathObject::method_atan2(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- double v1 = callData->argc ? callData->args[0].toNumber() : qt_qnan();
- double v2 = callData->argc > 1 ? callData->args[1].toNumber() : qt_qnan();
+ double v1 = argc ? argv[0].toNumber() : qt_qnan();
+ double v2 = argc > 1 ? argv[1].toNumber() : qt_qnan();
if ((v1 < 0) && qt_is_finite(v1) && qt_is_inf(v2) && (copySign(1.0, v2) == 1.0))
RETURN_RESULT(Encode(copySign(0, -1.0)));
@@ -155,24 +156,24 @@ void MathObject::method_atan2(const BuiltinFunction *, Scope &scope, CallData *c
RETURN_RESULT(Encode(std::atan2(v1, v2)));
}
-void MathObject::method_ceil(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue MathObject::method_ceil(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double v = argc ? argv[0].toNumber() : qt_qnan();
if (v < 0.0 && v > -1.0)
RETURN_RESULT(Encode(copySign(0, -1.0)));
else
RETURN_RESULT(Encode(std::ceil(v)));
}
-void MathObject::method_cos(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue MathObject::method_cos(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double v = argc ? argv[0].toNumber() : qt_qnan();
RETURN_RESULT(Encode(std::cos(v)));
}
-void MathObject::method_exp(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue MathObject::method_exp(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double v = argc ? argv[0].toNumber() : qt_qnan();
if (qt_is_inf(v)) {
if (copySign(1.0, v) == -1.0)
RETURN_RESULT(Encode(0));
@@ -183,37 +184,39 @@ void MathObject::method_exp(const BuiltinFunction *, Scope &scope, CallData *cal
}
}
-void MathObject::method_floor(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue MathObject::method_floor(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
- RETURN_RESULT(Encode(std::floor(v)));
+ double v = argc ? argv[0].toNumber() : qt_qnan();
+ Value result = Primitive::fromDouble(std::floor(v));
+ result.isInt32();
+ RETURN_RESULT(result);
}
-void MathObject::method_log(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue MathObject::method_log(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double v = argc ? argv[0].toNumber() : qt_qnan();
if (v < 0)
RETURN_RESULT(Encode(qt_qnan()));
else
RETURN_RESULT(Encode(std::log(v)));
}
-void MathObject::method_max(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue MathObject::method_max(const FunctionObject *, const Value *, const Value *argv, int argc)
{
double mx = -qt_inf();
- for (int i = 0; i < callData->argc; ++i) {
- double x = callData->args[i].toNumber();
+ for (int i = 0, ei = argc; i < ei; ++i) {
+ double x = argv[i].toNumber();
if (x > mx || std::isnan(x))
mx = x;
}
RETURN_RESULT(Encode(mx));
}
-void MathObject::method_min(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue MathObject::method_min(const FunctionObject *, const Value *, const Value *argv, int argc)
{
double mx = qt_inf();
- for (int i = 0; i < callData->argc; ++i) {
- double x = callData->args[i].toNumber();
+ for (int i = 0, ei = argc; i < ei; ++i) {
+ double x = argv[i].toNumber();
if ((x == 0 && mx == x && copySign(1.0, x) == -1.0)
|| (x < mx) || std::isnan(x)) {
mx = x;
@@ -222,10 +225,10 @@ void MathObject::method_min(const BuiltinFunction *, Scope &scope, CallData *cal
RETURN_RESULT(Encode(mx));
}
-void MathObject::method_pow(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue MathObject::method_pow(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- double x = callData->argc > 0 ? callData->args[0].toNumber() : qt_qnan();
- double y = callData->argc > 1 ? callData->args[1].toNumber() : qt_qnan();
+ double x = argc > 0 ? argv[0].toNumber() : qt_qnan();
+ double y = argc > 1 ? argv[1].toNumber() : qt_qnan();
if (std::isnan(y))
RETURN_RESULT(Encode(qt_qnan()));
@@ -272,32 +275,21 @@ void MathObject::method_pow(const BuiltinFunction *, Scope &scope, CallData *cal
RETURN_RESULT(Encode(qt_qnan()));
}
-Q_GLOBAL_STATIC(QThreadStorage<bool *>, seedCreatedStorage);
-
-void MathObject::method_random(const BuiltinFunction *, Scope &scope, CallData *)
+ReturnedValue MathObject::method_random(const FunctionObject *, const Value *, const Value *, int)
{
- if (!seedCreatedStorage()->hasLocalData()) {
- int msecs = QTime(0,0,0).msecsTo(QTime::currentTime());
- Q_ASSERT(msecs >= 0);
- qsrand(uint(uint(msecs) ^ reinterpret_cast<quintptr>(scope.engine)));
- seedCreatedStorage()->setLocalData(new bool(true));
- }
- // rand()/qrand() return a value where the upperbound is RAND_MAX inclusive. So, instead of
- // dividing by RAND_MAX (which would return 0..RAND_MAX inclusive), we divide by RAND_MAX + 1.
- qint64 upperLimit = qint64(RAND_MAX) + 1;
- RETURN_RESULT(Encode(qrand() / double(upperLimit)));
+ RETURN_RESULT(Encode(QRandomGenerator::global()->generateDouble()));
}
-void MathObject::method_round(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue MathObject::method_round(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double v = argc ? argv[0].toNumber() : qt_qnan();
v = copySign(std::floor(v + 0.5), v);
RETURN_RESULT(Encode(v));
}
-void MathObject::method_sign(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue MathObject::method_sign(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double v = argc ? argv[0].toNumber() : qt_qnan();
if (std::isnan(v))
RETURN_RESULT(Encode(qt_qnan()));
@@ -308,21 +300,21 @@ void MathObject::method_sign(const BuiltinFunction *, Scope &scope, CallData *ca
RETURN_RESULT(Encode(std::signbit(v) ? -1 : 1));
}
-void MathObject::method_sin(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue MathObject::method_sin(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double v = argc ? argv[0].toNumber() : qt_qnan();
RETURN_RESULT(Encode(std::sin(v)));
}
-void MathObject::method_sqrt(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue MathObject::method_sqrt(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double v = argc ? argv[0].toNumber() : qt_qnan();
RETURN_RESULT(Encode(std::sqrt(v)));
}
-void MathObject::method_tan(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue MathObject::method_tan(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double v = argc ? argv[0].toNumber() : qt_qnan();
if (v == 0.0)
RETURN_RESULT(Encode(v));
else
diff --git a/src/qml/jsruntime/qv4mathobject_p.h b/src/qml/jsruntime/qv4mathobject_p.h
index e617712905..0bf5da9404 100644
--- a/src/qml/jsruntime/qv4mathobject_p.h
+++ b/src/qml/jsruntime/qv4mathobject_p.h
@@ -69,25 +69,25 @@ struct MathObject: Object
V4_OBJECT2(MathObject, Object)
Q_MANAGED_TYPE(MathObject)
- static void method_abs(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_acos(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_asin(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_atan(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_atan2(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_ceil(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_cos(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_exp(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_floor(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_log(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_max(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_min(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_pow(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_random(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_round(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_sign(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_sin(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_sqrt(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_tan(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_abs(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_acos(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_asin(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_atan(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_atan2(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_ceil(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_cos(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_exp(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_floor(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_log(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_max(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_min(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_pow(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_random(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_round(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_sign(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_sin(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_sqrt(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_tan(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
};
}
diff --git a/src/qml/jsruntime/qv4memberdata.cpp b/src/qml/jsruntime/qv4memberdata.cpp
index db45c77472..8f862d63e9 100644
--- a/src/qml/jsruntime/qv4memberdata.cpp
+++ b/src/qml/jsruntime/qv4memberdata.cpp
@@ -45,24 +45,19 @@ using namespace QV4;
DEFINE_MANAGED_VTABLE(MemberData);
-void MemberData::markObjects(Heap::Base *that, ExecutionEngine *e)
-{
- Heap::MemberData *m = static_cast<Heap::MemberData *>(that);
- for (uint i = 0; i < m->size; ++i)
- m->data[i].mark(e);
-}
-
Heap::MemberData *MemberData::allocate(ExecutionEngine *e, uint n, Heap::MemberData *old)
{
- Q_ASSERT(!old || old->size < n);
+ Q_ASSERT(!old || old->values.size < n);
Q_ASSERT(n);
size_t alloc = MemoryManager::align(sizeof(Heap::MemberData) + (n - 1)*sizeof(Value));
Heap::MemberData *m = e->memoryManager->allocManaged<MemberData>(alloc);
if (old)
- memcpy(m, old, sizeof(Heap::MemberData) + (old->size - 1)* sizeof(Value));
+ // no write barrier required here
+ memcpy(m, old, sizeof(Heap::MemberData) + (old->values.size - 1) * sizeof(Value));
else
m->init();
- m->size = static_cast<uint>((alloc - sizeof(Heap::MemberData) + sizeof(Value))/sizeof(Value));
+ m->values.alloc = static_cast<uint>((alloc - sizeof(Heap::MemberData) + sizeof(Value))/sizeof(Value));
+ m->values.size = m->values.alloc;
return m;
}
diff --git a/src/qml/jsruntime/qv4memberdata_p.h b/src/qml/jsruntime/qv4memberdata_p.h
index e239458849..12eaf336b9 100644
--- a/src/qml/jsruntime/qv4memberdata_p.h
+++ b/src/qml/jsruntime/qv4memberdata_p.h
@@ -59,14 +59,13 @@ namespace QV4 {
namespace Heap {
-struct MemberData : Base {
- union {
- uint size;
- double _dummy;
- };
- Value data[1];
+#define MemberDataMembers(class, Member) \
+ Member(class, ValueArray, ValueArray, values)
+
+DECLARE_HEAP_OBJECT(MemberData, Base) {
+ DECLARE_MARKOBJECTS(MemberData);
};
-V4_ASSERT_IS_TRIVIAL(MemberData)
+Q_STATIC_ASSERT(std::is_trivial< MemberData >::value);
}
@@ -75,14 +74,26 @@ struct MemberData : Managed
V4_MANAGED(MemberData, Managed)
V4_INTERNALCLASS(MemberData)
- Value &operator[] (uint idx) { return d()->data[idx]; }
- const Value *data() const { return d()->data; }
- Value *data() { return d()->data; }
- inline uint size() const { return d()->size; }
+ struct Index {
+ Heap::Base *base;
+ Value *slot;
- static Heap::MemberData *allocate(QV4::ExecutionEngine *e, uint n, Heap::MemberData *old = 0);
+ void set(EngineBase *e, Value newVal) {
+ WriteBarrier::write(e, base, slot->data_ptr(), newVal.asReturnedValue());
+ }
+ const Value *operator->() const { return slot; }
+ const Value &operator*() const { return *slot; }
+ bool isNull() const { return !slot; }
+ };
- static void markObjects(Heap::Base *that, ExecutionEngine *e);
+ const Value &operator[] (uint idx) const { return d()->values[idx]; }
+ const Value *data() const { return d()->values.data(); }
+ void set(EngineBase *e, uint index, Value v) { d()->values.set(e, index, v); }
+ void set(EngineBase *e, uint index, Heap::Base *b) { d()->values.set(e, index, b); }
+
+ inline uint size() const { return d()->values.size; }
+
+ static Heap::MemberData *allocate(QV4::ExecutionEngine *e, uint n, Heap::MemberData *old = 0);
};
}
diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp
index 255d0212c1..f58ff45801 100644
--- a/src/qml/jsruntime/qv4numberobject.cpp
+++ b/src/qml/jsruntime/qv4numberobject.cpp
@@ -78,16 +78,16 @@ void Heap::NumberCtor::init(QV4::ExecutionContext *scope)
Heap::FunctionObject::init(scope, QStringLiteral("Number"));
}
-void NumberCtor::construct(const Managed *, Scope &scope, CallData *callData)
+ReturnedValue NumberCtor::callAsConstructor(const FunctionObject *f, const Value *argv, int argc)
{
- double dbl = callData->argc ? callData->args[0].toNumber() : 0.;
- scope.result = Encode(scope.engine->newNumberObject(dbl));
+ double dbl = argc ? argv[0].toNumber() : 0.;
+ return Encode(f->engine()->newNumberObject(dbl));
}
-void NumberCtor::call(const Managed *, Scope &scope, CallData *callData)
+ReturnedValue NumberCtor::call(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- double dbl = callData->argc ? callData->args[0].toNumber() : 0.;
- scope.result = Encode(dbl);
+ double dbl = argc ? argv[0].toNumber() : 0.;
+ return Encode(dbl);
}
void NumberPrototype::init(ExecutionEngine *engine, Object *ctor)
@@ -102,6 +102,8 @@ void NumberPrototype::init(ExecutionEngine *engine, Object *ctor)
ctor->defineReadonlyProperty(QStringLiteral("POSITIVE_INFINITY"), Primitive::fromDouble(qInf()));
ctor->defineReadonlyProperty(QStringLiteral("MAX_VALUE"), Primitive::fromDouble(1.7976931348623158e+308));
ctor->defineReadonlyProperty(QStringLiteral("EPSILON"), Primitive::fromDouble(std::numeric_limits<double>::epsilon()));
+ ctor->defineReadonlyProperty(QStringLiteral("MAX_SAFE_INTEGER"), Primitive::fromDouble(9007199254740991));
+ ctor->defineReadonlyProperty(QStringLiteral("MIN_SAFE_INTEGER"), Primitive::fromDouble(-9007199254740991));
QT_WARNING_PUSH
QT_WARNING_DISABLE_INTEL(239)
@@ -109,84 +111,114 @@ QT_WARNING_DISABLE_INTEL(239)
QT_WARNING_POP
ctor->defineDefaultProperty(QStringLiteral("isFinite"), method_isFinite, 1);
+ ctor->defineDefaultProperty(QStringLiteral("isInteger"), method_isInteger, 1);
+ ctor->defineDefaultProperty(QStringLiteral("isSafeInteger"), method_isSafeInteger, 1);
ctor->defineDefaultProperty(QStringLiteral("isNaN"), method_isNaN, 1);
defineDefaultProperty(QStringLiteral("constructor"), (o = ctor));
- defineDefaultProperty(engine->id_toString(), method_toString);
+ defineDefaultProperty(engine->id_toString(), method_toString, 1);
defineDefaultProperty(QStringLiteral("toLocaleString"), method_toLocaleString);
defineDefaultProperty(engine->id_valueOf(), method_valueOf);
defineDefaultProperty(QStringLiteral("toFixed"), method_toFixed, 1);
- defineDefaultProperty(QStringLiteral("toExponential"), method_toExponential);
- defineDefaultProperty(QStringLiteral("toPrecision"), method_toPrecision);
+ defineDefaultProperty(QStringLiteral("toExponential"), method_toExponential, 1);
+ defineDefaultProperty(QStringLiteral("toPrecision"), method_toPrecision, 1);
}
-inline ReturnedValue thisNumberValue(Scope &scope, CallData *callData)
+inline ReturnedValue thisNumberValue(ExecutionEngine *v4, const Value *thisObject)
{
- if (callData->thisObject.isNumber())
- return callData->thisObject.asReturnedValue();
- NumberObject *n = callData->thisObject.as<NumberObject>();
+ if (thisObject->isNumber())
+ return thisObject->asReturnedValue();
+ const NumberObject *n = thisObject->as<NumberObject>();
if (!n) {
- scope.engine->throwTypeError();
+ v4->throwTypeError();
return Encode::undefined();
}
return Encode(n->value());
}
-inline double thisNumber(Scope &scope, CallData *callData)
+inline double thisNumber(ExecutionEngine *engine, const Value *thisObject)
{
- if (callData->thisObject.isNumber())
- return callData->thisObject.asDouble();
- NumberObject *n = callData->thisObject.as<NumberObject>();
+ if (thisObject->isNumber())
+ return thisObject->asDouble();
+ const NumberObject *n = thisObject->as<NumberObject>();
if (!n) {
- scope.engine->throwTypeError();
+ engine->throwTypeError();
return 0;
}
return n->value();
}
-void NumberPrototype::method_isFinite(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue NumberPrototype::method_isFinite(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- if (!callData->argc) {
- scope.result = Encode(false);
- return;
- }
+ if (!argc)
+ return Encode(false);
- double v = callData->args[0].toNumber();
- scope.result = Encode(!std::isnan(v) && !qt_is_inf(v));
+ double v = argv[0].toNumber();
+ return Encode(!std::isnan(v) && !qt_is_inf(v));
}
-void NumberPrototype::method_isNaN(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue NumberPrototype::method_isInteger(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- if (!callData->argc) {
- scope.result = Encode(false);
- return;
- }
+ if (!argc)
+ return Encode(false);
+
+ const Value &v = argv[0];
+ if (!v.isNumber())
+ return Encode(false);
+
+ double dv = v.toNumber();
+ if (std::isnan(dv) || qt_is_inf(dv))
+ return Encode(false);
+
+ double iv = v.toInteger();
+ return Encode(dv == iv);
+}
+
+ReturnedValue NumberPrototype::method_isSafeInteger(const FunctionObject *, const Value *, const Value *argv, int argc)
+{
+ if (!argc)
+ return Encode(false);
+
+ const Value &v = argv[0];
+ if (!v.isNumber())
+ return Encode(false);
- double v = callData->args[0].toNumber();
+ double dv = v.toNumber();
+ if (std::isnan(dv) || qt_is_inf(dv))
+ return Encode(false);
+
+ double iv = v.toInteger();
+ return Encode(dv == iv && std::fabs(iv) <= (2^53)-1);
+}
+
+ReturnedValue NumberPrototype::method_isNaN(const FunctionObject *, const Value *, const Value *argv, int argc)
+{
+ if (!argc)
+ return Encode(false);
+
+ double v = argv[0].toNumber();
// cast to bool explicitly as std::isnan() may give us ::isnan(), which
// sometimes returns an int and we don't want the Encode(int) overload.
- scope.result = Encode(bool(std::isnan(v)));
+ return Encode(bool(std::isnan(v)));
}
-void NumberPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue NumberPrototype::method_toString(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- double num = thisNumber(scope, callData);
- CHECK_EXCEPTION();
+ ExecutionEngine *v4 = b->engine();
+ double num = thisNumber(v4, thisObject);
+ if (v4->hasException)
+ return QV4::Encode::undefined();
- if (callData->argc && !callData->args[0].isUndefined()) {
- int radix = callData->args[0].toInt32();
+ if (argc && !argv[0].isUndefined()) {
+ int radix = argv[0].toInt32();
if (radix < 2 || radix > 36) {
- scope.result = scope.engine->throwError(QStringLiteral("Number.prototype.toString: %0 is not a valid radix")
- .arg(radix));
- return;
+ return v4->throwError(QStringLiteral("Number.prototype.toString: %0 is not a valid radix").arg(radix));
}
if (std::isnan(num)) {
- scope.result = scope.engine->newString(QStringLiteral("NaN"));
- return;
+ return Encode(v4->newString(QStringLiteral("NaN")));
} else if (qt_is_inf(num)) {
- scope.result = scope.engine->newString(QLatin1String(num < 0 ? "-Infinity" : "Infinity"));
- return;
+ return Encode(v4->newString(QLatin1String(num < 0 ? "-Infinity" : "Infinity")));
}
if (radix != 10) {
@@ -216,43 +248,42 @@ void NumberPrototype::method_toString(const BuiltinFunction *, Scope &scope, Cal
}
if (negative)
str.prepend(QLatin1Char('-'));
- scope.result = scope.engine->newString(str);
- return;
+ return Encode(v4->newString(str));
}
}
- scope.result = Primitive::fromDouble(num).toString(scope.engine);
+ return Encode(Primitive::fromDouble(num).toString(v4));
}
-void NumberPrototype::method_toLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue NumberPrototype::method_toLocaleString(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- ScopedValue v(scope, thisNumberValue(scope, callData));
- scope.result = v->toString(scope.engine);
- CHECK_EXCEPTION();
+ Scope scope(b);
+ ScopedValue v(scope, thisNumberValue(b->engine(), thisObject));
+ return Encode(v->toString(scope.engine));
}
-void NumberPrototype::method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue NumberPrototype::method_valueOf(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- scope.result = thisNumberValue(scope, callData);
+ return thisNumberValue(b->engine(), thisObject);
}
-void NumberPrototype::method_toFixed(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue NumberPrototype::method_toFixed(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- double v = thisNumber(scope, callData);
- CHECK_EXCEPTION();
+ ExecutionEngine *v4 = b->engine();
+ double v = thisNumber(v4, thisObject);
+ if (v4->hasException)
+ return QV4::Encode::undefined();
double fdigits = 0;
- if (callData->argc > 0)
- fdigits = callData->args[0].toInteger();
+ if (argc > 0)
+ fdigits = argv[0].toInteger();
if (std::isnan(fdigits))
fdigits = 0;
- if (fdigits < 0 || fdigits > 20) {
- scope.result = scope.engine->throwRangeError(callData->thisObject);
- return;
- }
+ if (fdigits < 0 || fdigits > 20)
+ return v4->throwRangeError(*thisObject);
QString str;
if (std::isnan(v))
@@ -262,49 +293,51 @@ void NumberPrototype::method_toFixed(const BuiltinFunction *, Scope &scope, Call
else if (v < 1.e21)
str = NumberLocale::instance()->toString(v, 'f', int(fdigits));
else {
- scope.result = RuntimeHelpers::stringFromNumber(scope.engine, v);
- return;
+ return Encode(RuntimeHelpers::stringFromNumber(v4, v));
}
- scope.result = scope.engine->newString(str);
+ return Encode(v4->newString(str));
}
-void NumberPrototype::method_toExponential(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue NumberPrototype::method_toExponential(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- double d = thisNumber(scope, callData);
- CHECK_EXCEPTION();
+ ExecutionEngine *v4 = b->engine();
+ double d = thisNumber(v4, thisObject);
+ if (v4->hasException)
+ return QV4::Encode::undefined();
+
int fdigits = NumberLocale::instance()->defaultDoublePrecision;
- if (callData->argc && !callData->args[0].isUndefined()) {
- fdigits = callData->args[0].toInt32();
+ if (argc && !argv[0].isUndefined()) {
+ fdigits = argv[0].toInt32();
if (fdigits < 0 || fdigits > 20) {
- ScopedString error(scope, scope.engine->newString(QStringLiteral("Number.prototype.toExponential: fractionDigits out of range")));
- scope.result = scope.engine->throwRangeError(error);
- return;
+ Scope scope(v4);
+ ScopedString error(scope, v4->newString(QStringLiteral("Number.prototype.toExponential: fractionDigits out of range")));
+ return v4->throwRangeError(error);
}
}
QString result = NumberLocale::instance()->toString(d, 'e', fdigits);
- scope.result = scope.engine->newString(result);
+ return Encode(v4->newString(result));
}
-void NumberPrototype::method_toPrecision(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue NumberPrototype::method_toPrecision(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- ScopedValue v(scope, thisNumberValue(scope, callData));
- CHECK_EXCEPTION();
+ Scope scope(b);
+ ScopedValue v(scope, thisNumberValue(scope.engine, thisObject));
+ if (scope.engine->hasException)
+ return QV4::Encode::undefined();
- if (!callData->argc || callData->args[0].isUndefined()) {
- scope.result = v->toString(scope.engine);
- return;
- }
- int precision = callData->args[0].toInt32();
+ if (!argc || argv[0].isUndefined())
+ return Encode(v->toString(scope.engine));
+
+ int precision = argv[0].toInt32();
if (precision < 1 || precision > 21) {
ScopedString error(scope, scope.engine->newString(QStringLiteral("Number.prototype.toPrecision: precision out of range")));
- scope.result = scope.engine->throwRangeError(error);
- return;
+ return scope.engine->throwRangeError(error);
}
QString result = NumberLocale::instance()->toString(v->asDouble(), 'g', precision);
- scope.result = scope.engine->newString(result);
+ return Encode(scope.engine->newString(result));
}
diff --git a/src/qml/jsruntime/qv4numberobject_p.h b/src/qml/jsruntime/qv4numberobject_p.h
index 85d306020c..cfdcf9bc1d 100644
--- a/src/qml/jsruntime/qv4numberobject_p.h
+++ b/src/qml/jsruntime/qv4numberobject_p.h
@@ -79,8 +79,8 @@ struct NumberCtor: FunctionObject
{
V4_OBJECT2(NumberCtor, FunctionObject)
- static void construct(const Managed *that, Scope &scope, CallData *callData);
- static void call(const Managed *, Scope &scope, CallData *callData);
+ static ReturnedValue callAsConstructor(const FunctionObject *f, const Value *argv, int argc);
+ static ReturnedValue call(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
};
struct NumberPrototype: NumberObject
@@ -88,14 +88,16 @@ struct NumberPrototype: NumberObject
V4_PROTOTYPE(objectPrototype)
void init(ExecutionEngine *engine, Object *ctor);
- static void method_isFinite(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_isNaN(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_toLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_toFixed(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_toExponential(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_toPrecision(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_isFinite(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_isInteger(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_isSafeInteger(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_isNaN(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_toString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_toLocaleString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_valueOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_toFixed(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_toExponential(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_toPrecision(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
};
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index 98f5c7464f..aa8e850aed 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -38,8 +38,6 @@
****************************************************************************/
#include "qv4object_p.h"
-#include "qv4jsir_p.h"
-#include "qv4isel_p.h"
#include "qv4objectproto_p.h"
#include "qv4stringobject_p.h"
#include "qv4argumentsobject_p.h"
@@ -51,6 +49,7 @@
#include "qv4identifier_p.h"
#include "qv4string_p.h"
#include "qv4identifiertable_p.h"
+#include "qv4jscall_p.h"
#include <stdint.h>
@@ -61,14 +60,16 @@ DEFINE_OBJECT_VTABLE(Object);
void Object::setInternalClass(InternalClass *ic)
{
d()->internalClass = ic;
+ if (ic->isUsedAsProto)
+ ic->updateProtoUsage(d());
Q_ASSERT(ic && ic->vtable);
uint nInline = d()->vtable()->nInlineProperties;
if (ic->size <= nInline)
return;
bool hasMD = d()->memberData != nullptr;
uint requiredSize = ic->size - nInline;
- if (!hasMD || (hasMD && d()->memberData->size < requiredSize))
- d()->memberData = MemberData::allocate(ic->engine, requiredSize, d()->memberData);
+ if (!(hasMD && requiredSize) || (hasMD && d()->memberData->values.size < requiredSize))
+ d()->memberData.set(ic->engine, MemberData::allocate(ic->engine, requiredSize, d()->memberData));
}
void Object::getProperty(uint index, Property *p, PropertyAttributes *attrs) const
@@ -81,9 +82,14 @@ void Object::getProperty(uint index, Property *p, PropertyAttributes *attrs) con
void Object::setProperty(uint index, const Property *p)
{
- *propertyData(index) = p->value;
+ setProperty(index, p->value);
if (internalClass()->propertyData.at(index).isAccessor())
- *propertyData(index + SetterOffset) = p->set;
+ setProperty(index + SetterOffset, p->set);
+}
+
+void Heap::Object::setUsedAsProto()
+{
+ internalClass = internalClass->asProtoClass();
}
bool Object::setPrototype(Object *proto)
@@ -99,13 +105,6 @@ bool Object::setPrototype(Object *proto)
return true;
}
-void Object::put(ExecutionEngine *engine, const QString &name, const Value &value)
-{
- Scope scope(engine);
- ScopedString n(scope, engine->newString(name));
- put(n, value);
-}
-
ReturnedValue Object::getValue(const Value &thisObject, const Value &v, PropertyAttributes attrs)
{
if (!attrs.isAccessor())
@@ -115,43 +114,38 @@ ReturnedValue Object::getValue(const Value &thisObject, const Value &v, Property
return Encode::undefined();
Scope scope(f->engine());
- ScopedCallData callData(scope);
- callData->thisObject = thisObject;
- f->call(scope, callData);
- return scope.result.asReturnedValue();
+ JSCallData jsCallData(scope);
+ *jsCallData->thisObject = thisObject;
+ return f->call(jsCallData);
}
-void Object::putValue(uint memberIndex, const Value &value)
+bool Object::putValue(uint memberIndex, const Value &value)
{
QV4::InternalClass *ic = internalClass();
if (ic->engine->hasException)
- return;
+ return false;
PropertyAttributes attrs = ic->propertyData[memberIndex];
if (attrs.isAccessor()) {
- FunctionObject *set = propertyData(memberIndex + SetterOffset)->as<FunctionObject>();
+ const FunctionObject *set = propertyData(memberIndex + SetterOffset)->as<FunctionObject>();
if (set) {
Scope scope(ic->engine);
ScopedFunctionObject setter(scope, set);
- ScopedCallData callData(scope, 1);
- callData->args[0] = value;
- callData->thisObject = this;
- setter->call(scope, callData);
- return;
+ JSCallData jsCallData(scope, 1);
+ jsCallData->args[0] = value;
+ *jsCallData->thisObject = this;
+ setter->call(jsCallData);
+ return !ic->engine->hasException;
}
- goto reject;
+ return false;
}
if (!attrs.isWritable())
- goto reject;
-
- *propertyData(memberIndex) = value;
- return;
+ return false;
- reject:
- if (engine()->current->strictMode)
- engine()->throwTypeError();
+ setProperty(memberIndex, value);
+ return true;
}
void Object::defineDefaultProperty(const QString &name, const Value &value)
@@ -162,29 +156,29 @@ void Object::defineDefaultProperty(const QString &name, const Value &value)
defineDefaultProperty(s, value);
}
-void Object::defineDefaultProperty(const QString &name, void (*code)(const BuiltinFunction *, Scope &, CallData *), int argumentCount)
+void Object::defineDefaultProperty(const QString &name, ReturnedValue (*code)(const FunctionObject *, const Value *thisObject, const Value *argv, int argc), int argumentCount)
{
ExecutionEngine *e = engine();
Scope scope(e);
ScopedString s(scope, e->newIdentifier(name));
ExecutionContext *global = e->rootContext();
- ScopedFunctionObject function(scope, BuiltinFunction::create(global, s, code));
- function->defineReadonlyProperty(e->id_length(), Primitive::fromInt32(argumentCount));
+ ScopedFunctionObject function(scope, FunctionObject::createBuiltinFunction(global, s, code));
+ function->defineReadonlyConfigurableProperty(e->id_length(), Primitive::fromInt32(argumentCount));
defineDefaultProperty(s, function);
}
-void Object::defineDefaultProperty(String *name, void (*code)(const BuiltinFunction *, Scope &, CallData *), int argumentCount)
+void Object::defineDefaultProperty(String *name, ReturnedValue (*code)(const FunctionObject *, const Value *thisObject, const Value *argv, int argc), int argumentCount)
{
ExecutionEngine *e = engine();
Scope scope(e);
ExecutionContext *global = e->rootContext();
- ScopedFunctionObject function(scope, BuiltinFunction::create(global, name, code));
- function->defineReadonlyProperty(e->id_length(), Primitive::fromInt32(argumentCount));
+ ScopedFunctionObject function(scope, FunctionObject::createBuiltinFunction(global, name, code));
+ function->defineReadonlyConfigurableProperty(e->id_length(), Primitive::fromInt32(argumentCount));
defineDefaultProperty(name, function);
}
-void Object::defineAccessorProperty(const QString &name, void (*getter)(const BuiltinFunction *, Scope &, CallData *),
- void (*setter)(const BuiltinFunction *, Scope &, CallData *))
+void Object::defineAccessorProperty(const QString &name, ReturnedValue (*getter)(const FunctionObject *, const Value *, const Value *, int),
+ ReturnedValue (*setter)(const FunctionObject *, const Value *, const Value *, int))
{
ExecutionEngine *e = engine();
Scope scope(e);
@@ -192,18 +186,20 @@ void Object::defineAccessorProperty(const QString &name, void (*getter)(const Bu
defineAccessorProperty(s, getter, setter);
}
-void Object::defineAccessorProperty(String *name, void (*getter)(const BuiltinFunction *, Scope &, CallData *),
- void (*setter)(const BuiltinFunction *, Scope &, CallData *))
+void Object::defineAccessorProperty(String *name, ReturnedValue (*getter)(const FunctionObject *, const Value *, const Value *, int),
+ ReturnedValue (*setter)(const FunctionObject *, const Value *, const Value *, int))
{
ExecutionEngine *v4 = engine();
QV4::Scope scope(v4);
ScopedProperty p(scope);
ExecutionContext *global = v4->rootContext();
- p->setGetter(ScopedFunctionObject(scope, (getter ? BuiltinFunction::create(global, name, getter) : 0)));
- p->setSetter(ScopedFunctionObject(scope, (setter ? BuiltinFunction::create(global, name, setter) : 0)));
+ p->setGetter(ScopedFunctionObject(scope, (getter ? FunctionObject::createBuiltinFunction(global, name, getter) : 0)));
+ p->setSetter(ScopedFunctionObject(scope, (setter ? FunctionObject::createBuiltinFunction(global, name, setter) : 0)));
insertMember(name, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
}
+
+
void Object::defineReadonlyProperty(const QString &name, const Value &value)
{
QV4::ExecutionEngine *e = engine();
@@ -217,19 +213,34 @@ void Object::defineReadonlyProperty(String *name, const Value &value)
insertMember(name, value, Attr_ReadOnly);
}
-void Object::markObjects(Heap::Base *that, ExecutionEngine *e)
+void Object::defineReadonlyConfigurableProperty(const QString &name, const Value &value)
+{
+ QV4::ExecutionEngine *e = engine();
+ Scope scope(e);
+ ScopedString s(scope, e->newIdentifier(name));
+ defineReadonlyConfigurableProperty(s, value);
+}
+
+void Object::defineReadonlyConfigurableProperty(String *name, const Value &value)
{
- Heap::Object *o = static_cast<Heap::Object *>(that);
+ insertMember(name, value, Attr_ReadOnly_ButConfigurable);
+}
+void Heap::Object::markObjects(Heap::Base *b, MarkStack *stack)
+{
+ Object *o = static_cast<Object *>(b);
if (o->memberData)
- o->memberData->mark(e);
- if (o->arrayData)
- o->arrayData->mark(e);
+ o->memberData->mark(stack);
+ if (o->arrayData) {
+ o->arrayData->setMarkBit();
+ if (o->arrayData->needsMark)
+ ArrayData::markObjects(o->arrayData, stack);
+ }
uint nInline = o->vtable()->nInlineProperties;
Value *v = reinterpret_cast<Value *>(o) + o->vtable()->inlinePropertyOffset;
const Value *end = v + nInline;
while (v < end) {
- v->mark(e);
+ v->mark(stack);
++v;
}
}
@@ -240,10 +251,10 @@ void Object::insertMember(String *s, const Property *p, PropertyAttributes attri
InternalClass::addMember(this, s, attributes, &idx);
if (attributes.isAccessor()) {
- *propertyData(idx + GetterOffset) = p->value;
- *propertyData(idx + SetterOffset) = p->set;
+ setProperty(idx + GetterOffset, p->value);
+ setProperty(idx + SetterOffset, p->set);
} else {
- *propertyData(idx) = p->value;
+ setProperty(idx, p->value);
}
}
@@ -275,12 +286,9 @@ void Object::getOwnProperty(String *name, PropertyAttributes *attrs, Property *p
void Object::getOwnProperty(uint index, PropertyAttributes *attrs, Property *p)
{
- Property *pd = arrayData() ? arrayData()->getProperty(index) : 0;
- if (pd) {
- *attrs = arrayData()->attributes(index);
- if (p)
- p->copy(pd, *attrs);
- return;
+ if (arrayData()) {
+ if (arrayData()->getProperty(index, p, attrs))
+ return;
}
if (isStringObject()) {
*attrs = Attr_NotConfigurable|Attr_NotWritable;
@@ -295,7 +303,7 @@ void Object::getOwnProperty(uint index, PropertyAttributes *attrs, Property *p)
}
// Section 8.12.2
-Value *Object::getValueOrSetter(String *name, PropertyAttributes *attrs)
+MemberData::Index Object::getValueOrSetter(String *name, PropertyAttributes *attrs)
{
Q_ASSERT(name->asArrayIndex() == UINT_MAX);
@@ -307,36 +315,38 @@ Value *Object::getValueOrSetter(String *name, PropertyAttributes *attrs)
uint idx = o->internalClass->find(id);
if (idx < UINT_MAX) {
*attrs = o->internalClass->propertyData[idx];
- return o->propertyData(attrs->isAccessor() ? idx + SetterOffset : idx);
+ return o->writablePropertyData(attrs->isAccessor() ? idx + SetterOffset : idx );
}
o = o->prototype();
}
*attrs = Attr_Invalid;
- return 0;
+ return { 0, 0 };
}
-Value *Object::getValueOrSetter(uint index, PropertyAttributes *attrs)
+ArrayData::Index Object::getValueOrSetter(uint index, PropertyAttributes *attrs)
{
Heap::Object *o = d();
while (o) {
- Property *p = o->arrayData ? o->arrayData->getProperty(index) : 0;
- if (p) {
- *attrs = o->arrayData->attributes(index);
- return attrs->isAccessor() ? &p->set : &p->value;
+ if (o->arrayData) {
+ uint idx = o->arrayData->mappedIndex(index);
+ if (idx != UINT_MAX) {
+ *attrs = o->arrayData->attributes(index);
+ return { o->arrayData , attrs->isAccessor() ? idx + SetterOffset : idx };
+ }
}
if (o->vtable()->type == Type_StringObject) {
if (index < static_cast<const Heap::StringObject *>(o)->length()) {
// this is an evil hack, but it works, as the method is only ever called from putIndexed,
// where we don't use the returned pointer there for non writable attributes
*attrs = (Attr_NotWritable|Attr_NotConfigurable);
- return reinterpret_cast<Value *>(0x1);
+ return { reinterpret_cast<Heap::ArrayData *>(0x1), 0 };
}
}
o = o->prototype();
}
*attrs = Attr_Invalid;
- return 0;
+ return { 0, 0 };
}
bool Object::hasProperty(String *name) const
@@ -401,14 +411,14 @@ bool Object::hasOwnProperty(uint index) const
return false;
}
-void Object::construct(const Managed *m, Scope &scope, CallData *)
+ReturnedValue Object::callAsConstructor(const FunctionObject *f, const Value *, int)
{
- scope.result = static_cast<const Object *>(m)->engine()->throwTypeError();
+ return f->engine()->throwTypeError();
}
-void Object::call(const Managed *m, Scope &scope, CallData *)
+ReturnedValue Object::call(const FunctionObject *f, const Value *, const Value *, int)
{
- scope.result = static_cast<const Object *>(m)->engine()->throwTypeError();
+ return f->engine()->throwTypeError();
}
ReturnedValue Object::get(const Managed *m, String *name, bool *hasProperty)
@@ -421,14 +431,14 @@ ReturnedValue Object::getIndexed(const Managed *m, uint index, bool *hasProperty
return static_cast<const Object *>(m)->internalGetIndexed(index, hasProperty);
}
-void Object::put(Managed *m, String *name, const Value &value)
+bool Object::put(Managed *m, String *name, const Value &value)
{
- static_cast<Object *>(m)->internalPut(name, value);
+ return static_cast<Object *>(m)->internalPut(name, value);
}
-void Object::putIndexed(Managed *m, uint index, const Value &value)
+bool Object::putIndexed(Managed *m, uint index, const Value &value)
{
- static_cast<Object *>(m)->internalPutIndexed(index, value);
+ return static_cast<Object *>(m)->internalPutIndexed(index, value);
}
PropertyAttributes Object::query(const Managed *m, String *name)
@@ -471,98 +481,6 @@ bool Object::deleteIndexedProperty(Managed *m, uint index)
return static_cast<Object *>(m)->internalDeleteIndexedProperty(index);
}
-ReturnedValue Object::getLookup(const Managed *m, Lookup *l)
-{
- const Object *o = static_cast<const Object *>(m);
- PropertyAttributes attrs;
- ReturnedValue v = l->lookup(o, &attrs);
- if (v != Primitive::emptyValue().asReturnedValue()) {
- l->proto = l->classList[0]->prototype;
- if (attrs.isData()) {
- Q_ASSERT(l->classList[0] == o->internalClass());
- if (l->level == 0) {
- uint nInline = o->d()->vtable()->nInlineProperties;
- if (l->index < nInline)
- l->getter = Lookup::getter0Inline;
- else {
- l->index -= nInline;
- l->getter = Lookup::getter0MemberData;
- }
- }
- else if (l->level == 1)
- l->getter = Lookup::getter1;
- else if (l->level == 2)
- l->getter = Lookup::getter2;
- else
- l->getter = Lookup::getterFallback;
- return v;
- } else {
- if (l->level == 0)
- l->getter = Lookup::getterAccessor0;
- else if (l->level == 1)
- l->getter = Lookup::getterAccessor1;
- else if (l->level == 2)
- l->getter = Lookup::getterAccessor2;
- else
- l->getter = Lookup::getterFallback;
- return v;
- }
- }
- return Encode::undefined();
-}
-
-void Object::setLookup(Managed *m, Lookup *l, const Value &value)
-{
- Scope scope(static_cast<Object *>(m)->engine());
- ScopedObject o(scope, static_cast<Object *>(m));
- ScopedString name(scope, scope.engine->current->compilationUnit->runtimeStrings[l->nameIndex]);
-
- InternalClass *c = o->internalClass();
- uint idx = c->find(name);
- if (!o->isArrayObject() || idx != Heap::ArrayObject::LengthPropertyIndex) {
- if (idx != UINT_MAX && o->internalClass()->propertyData[idx].isData() && o->internalClass()->propertyData[idx].isWritable()) {
- l->classList[0] = o->internalClass();
- l->index = idx;
- l->setter = idx < o->d()->vtable()->nInlineProperties ? Lookup::setter0Inline : Lookup::setter0;
- *o->propertyData(idx) = value;
- return;
- }
-
- if (idx != UINT_MAX) {
- o->putValue(idx, value);
- return;
- }
- }
-
- o->put(name, value);
-
- if (o->internalClass() == c)
- return;
- idx = o->internalClass()->find(name);
- if (idx == UINT_MAX)
- return;
- l->classList[0] = c;
- l->classList[3] = o->internalClass();
- l->index = idx;
- if (!o->prototype()) {
- l->setter = Lookup::setterInsert0;
- return;
- }
- o = o->prototype();
- l->classList[1] = o->internalClass();
- if (!o->prototype()) {
- l->setter = Lookup::setterInsert1;
- return;
- }
- o = o->prototype();
- l->classList[2] = o->internalClass();
- if (!o->prototype()) {
- l->setter = Lookup::setterInsert2;
- return;
- }
- l->setter = Lookup::setterGeneric;
-}
-
void Object::advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *pd, PropertyAttributes *attrs)
{
Object *o = static_cast<Object *>(m);
@@ -579,7 +497,7 @@ void Object::advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *
int k = it->arrayNode->key();
uint pidx = it->arrayNode->value;
Heap::SparseArrayData *sa = o->d()->arrayData.cast<Heap::SparseArrayData>();
- Property *p = reinterpret_cast<Property *>(sa->arrayData + pidx);
+ const Property *p = reinterpret_cast<const Property *>(sa->values.data() + pidx);
it->arrayNode = it->arrayNode->nextNode();
PropertyAttributes a = sa->attrs ? sa->attrs[pidx] : Attr_Data;
if (!(it->flags & ObjectIterator::EnumerableOnly) || a.isEnumerable()) {
@@ -594,9 +512,9 @@ void Object::advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *
it->arrayIndex = UINT_MAX;
}
// dense arrays
- while (it->arrayIndex < o->d()->arrayData->len) {
+ while (it->arrayIndex < o->d()->arrayData->values.size) {
Heap::SimpleArrayData *sa = o->d()->arrayData.cast<Heap::SimpleArrayData>();
- Value &val = sa->data(it->arrayIndex);
+ const Value &val = sa->data(it->arrayIndex);
PropertyAttributes a = o->arrayData()->attributes(it->arrayIndex);
++it->arrayIndex;
if (!val.isEmpty()
@@ -643,14 +561,13 @@ ReturnedValue Object::internalGet(String *name, bool *hasProperty) const
name->makeIdentifier();
Identifier *id = name->identifier();
- Scope scope(engine());
- ScopedObject o(scope, this);
+ Heap::Object *o = d();
while (o) {
- uint idx = o->internalClass()->find(id);
+ uint idx = o->internalClass->find(id);
if (idx < UINT_MAX) {
if (hasProperty)
*hasProperty = true;
- return getValue(*o->propertyData(idx), o->internalClass()->propertyData.at(idx));
+ return getValue(*o->propertyData(idx), o->internalClass->propertyData.at(idx));
}
o = o->prototype();
@@ -663,15 +580,14 @@ ReturnedValue Object::internalGet(String *name, bool *hasProperty) const
ReturnedValue Object::internalGetIndexed(uint index, bool *hasProperty) const
{
- Property *pd = 0;
PropertyAttributes attrs;
Scope scope(engine());
ScopedObject o(scope, this);
+ ScopedProperty pd(scope);
+ bool exists = false;
while (o) {
- Property *p = o->arrayData() ? o->arrayData()->getProperty(index) : 0;
- if (p) {
- pd = p;
- attrs = o->arrayData()->attributes(index);
+ if (o->arrayData() && o->arrayData()->getProperty(index, pd, &attrs)) {
+ exists = true;
break;
}
if (o->isStringObject()) {
@@ -686,7 +602,7 @@ ReturnedValue Object::internalGetIndexed(uint index, bool *hasProperty) const
o = o->prototype();
}
- if (pd) {
+ if (exists) {
if (hasProperty)
*hasProperty = true;
return getValue(pd->value, attrs);
@@ -699,10 +615,11 @@ ReturnedValue Object::internalGetIndexed(uint index, bool *hasProperty) const
// Section 8.12.5
-void Object::internalPut(String *name, const Value &value)
+bool Object::internalPut(String *name, const Value &value)
{
- if (internalClass()->engine->hasException)
- return;
+ ExecutionEngine *engine = this->engine();
+ if (engine->hasException)
+ return false;
uint idx = name->asArrayIndex();
if (idx != UINT_MAX)
@@ -711,145 +628,137 @@ void Object::internalPut(String *name, const Value &value)
name->makeIdentifier();
Identifier *id = name->identifier();
+ MemberData::Index memberIndex{0, 0};
uint member = internalClass()->find(id);
- Value *v = 0;
PropertyAttributes attrs;
if (member < UINT_MAX) {
attrs = internalClass()->propertyData[member];
- v = propertyData(attrs.isAccessor() ? member + SetterOffset : member);
+ memberIndex = d()->writablePropertyData(attrs.isAccessor() ? member + SetterOffset : member);
}
// clause 1
- if (v) {
+ if (!memberIndex.isNull()) {
if (attrs.isAccessor()) {
- if (v->as<FunctionObject>())
+ if (memberIndex->as<FunctionObject>())
goto cont;
- goto reject;
+ return false;
} else if (!attrs.isWritable())
- goto reject;
- else if (isArrayObject() && name->equals(engine()->id_length())) {
+ return false;
+ else if (isArrayObject() && name->equals(engine->id_length())) {
bool ok;
uint l = value.asArrayLength(&ok);
if (!ok) {
- engine()->throwRangeError(value);
- return;
+ engine->throwRangeError(value);
+ return false;
}
ok = setArrayLength(l);
if (!ok)
- goto reject;
+ return false;
} else {
- *v = value;
+ memberIndex.set(engine, value);
}
- return;
+ return true;
} else if (!prototype()) {
if (!isExtensible())
- goto reject;
+ return false;
} else {
// clause 4
- Scope scope(engine());
- if ((v = ScopedObject(scope, prototype())->getValueOrSetter(name, &attrs))) {
+ Scope scope(engine);
+ memberIndex = ScopedObject(scope, prototype())->getValueOrSetter(name, &attrs);
+ if (!memberIndex.isNull()) {
if (attrs.isAccessor()) {
- if (!v->as<FunctionObject>())
- goto reject;
+ if (!memberIndex->as<FunctionObject>())
+ return false;
} else if (!isExtensible() || !attrs.isWritable()) {
- goto reject;
+ return false;
}
} else if (!isExtensible()) {
- goto reject;
+ return false;
}
}
cont:
// Clause 5
- if (v && attrs.isAccessor()) {
- Q_ASSERT(v->as<FunctionObject>());
-
- Scope scope(engine());
- ScopedFunctionObject setter(scope, *v);
- ScopedCallData callData(scope, 1);
- callData->args[0] = value;
- callData->thisObject = this;
- setter->call(scope, callData);
- return;
+ if (!memberIndex.isNull() && attrs.isAccessor()) {
+ Q_ASSERT(memberIndex->as<FunctionObject>());
+
+ Scope scope(engine);
+ ScopedFunctionObject setter(scope, *memberIndex);
+ JSCallData jsCallData(scope, 1);
+ jsCallData->args[0] = value;
+ *jsCallData->thisObject = this;
+ setter->call(jsCallData);
+ return !engine->hasException;
}
insertMember(name, value);
- return;
-
- reject:
- if (engine()->current->strictMode) {
- QString message = QLatin1String("Cannot assign to read-only property \"") +
- name->toQString() + QLatin1Char('\"');
- engine()->throwTypeError(message);
- }
+ return true;
}
-void Object::internalPutIndexed(uint index, const Value &value)
+bool Object::internalPutIndexed(uint index, const Value &value)
{
- if (internalClass()->engine->hasException)
- return;
+ ExecutionEngine *engine = this->engine();
+ if (engine->hasException)
+ return false;
PropertyAttributes attrs;
- Value *v = arrayData() ? arrayData()->getValueOrSetter(index, &attrs) : 0;
+ ArrayData::Index arrayIndex = arrayData() ? arrayData()->getValueOrSetter(index, &attrs) : ArrayData::Index{ 0, 0 };
- if (!v && isStringObject()) {
+ if (arrayIndex.isNull() && isStringObject()) {
if (index < static_cast<StringObject *>(this)->length())
// not writable
- goto reject;
+ return false;
}
// clause 1
- if (v) {
+ if (!arrayIndex.isNull()) {
if (attrs.isAccessor()) {
- if (v->as<FunctionObject>())
+ if (arrayIndex->as<FunctionObject>())
goto cont;
- goto reject;
+ return false;
} else if (!attrs.isWritable())
- goto reject;
- else
- *v = value;
- return;
+ return false;
+
+ arrayIndex.set(engine, value);
+ return true;
} else if (!prototype()) {
if (!isExtensible())
- goto reject;
+ return false;
} else {
// clause 4
- Scope scope(engine());
- if ((v = ScopedObject(scope, prototype())->getValueOrSetter(index, &attrs))) {
+ Scope scope(engine);
+ arrayIndex = ScopedObject(scope, prototype())->getValueOrSetter(index, &attrs);
+ if (!arrayIndex.isNull()) {
if (attrs.isAccessor()) {
- if (!v->as<FunctionObject>())
- goto reject;
+ if (!arrayIndex->as<FunctionObject>())
+ return false;
} else if (!isExtensible() || !attrs.isWritable()) {
- goto reject;
+ return false;
}
} else if (!isExtensible()) {
- goto reject;
+ return false;
}
}
cont:
// Clause 5
- if (v && attrs.isAccessor()) {
- Q_ASSERT(v->as<FunctionObject>());
-
- Scope scope(engine());
- ScopedFunctionObject setter(scope, *v);
- ScopedCallData callData(scope, 1);
- callData->args[0] = value;
- callData->thisObject = this;
- setter->call(scope, callData);
- return;
+ if (!arrayIndex.isNull() && attrs.isAccessor()) {
+ Q_ASSERT(arrayIndex->as<FunctionObject>());
+
+ Scope scope(engine);
+ ScopedFunctionObject setter(scope, *arrayIndex);
+ JSCallData jsCallData(scope, 1);
+ jsCallData->args[0] = value;
+ *jsCallData->thisObject = this;
+ setter->call(jsCallData);
+ return !engine->hasException;
}
arraySet(index, value);
- return;
-
- reject:
- if (engine()->current->strictMode)
- engine()->throwTypeError();
+ return true;
}
// Section 8.12.7
@@ -870,8 +779,6 @@ bool Object::internalDeleteProperty(String *name)
InternalClass::removeMember(this, name->identifier());
return true;
}
- if (engine()->current->strictMode)
- engine()->throwTypeError();
return false;
}
@@ -888,8 +795,6 @@ bool Object::internalDeleteIndexedProperty(uint index)
if (!ad || ad->vtable()->del(this, index))
return true;
- if (engine()->current->strictMode)
- engine()->throwTypeError();
return false;
}
@@ -913,7 +818,7 @@ bool Object::__defineOwnProperty__(ExecutionEngine *engine, String *name, const
if (attrs.isEmpty() || p->isSubset(attrs, lp, cattrs))
return true;
if (!cattrs.isWritable() || attrs.type() == PropertyAttributes::Accessor || attrs.isConfigurable() || attrs.isEnumerable())
- goto reject;
+ return false;
bool succeeded = true;
if (attrs.type() == PropertyAttributes::Data) {
bool ok;
@@ -930,7 +835,7 @@ bool Object::__defineOwnProperty__(ExecutionEngine *engine, String *name, const
InternalClass::changeMember(this, engine->id_length(), cattrs);
}
if (!succeeded)
- goto reject;
+ return false;
return true;
}
@@ -940,7 +845,7 @@ bool Object::__defineOwnProperty__(ExecutionEngine *engine, String *name, const
if (memberIndex == UINT_MAX) {
// clause 3
if (!isExtensible())
- goto reject;
+ return false;
// clause 4
ScopedProperty pd(scope);
pd->copy(p, attrs);
@@ -950,26 +855,18 @@ bool Object::__defineOwnProperty__(ExecutionEngine *engine, String *name, const
}
return __defineOwnProperty__(engine, memberIndex, name, p, attrs);
-reject:
- if (engine->current->strictMode)
- engine->throwTypeError();
- return false;
}
bool Object::__defineOwnProperty__(ExecutionEngine *engine, uint index, const Property *p, PropertyAttributes attrs)
{
// 15.4.5.1, 4b
if (isArrayObject() && index >= getLength() && !internalClass()->propertyData[Heap::ArrayObject::LengthPropertyIndex].isWritable())
- goto reject;
+ return false;
if (ArgumentsObject::isNonStrictArgumentsObject(this))
return static_cast<ArgumentsObject *>(this)->defineOwnProperty(engine, index, p, attrs);
return defineOwnProperty2(engine, index, p, attrs);
-reject:
- if (engine->current->strictMode)
- engine->throwTypeError();
- return false;
}
bool Object::defineOwnProperty2(ExecutionEngine *engine, uint index, const Property *p, PropertyAttributes attrs)
@@ -978,15 +875,15 @@ bool Object::defineOwnProperty2(ExecutionEngine *engine, uint index, const Prope
// Clause 1
if (arrayData()) {
- hasProperty = arrayData()->getProperty(index);
- if (!hasProperty && isStringObject())
+ hasProperty = arrayData()->mappedIndex(index) != UINT_MAX;
+ if (!hasProperty && isStringObject())
hasProperty = (index < static_cast<StringObject *>(this)->length());
}
if (!hasProperty) {
// clause 3
if (!isExtensible())
- goto reject;
+ return false;
// clause 4
Scope scope(engine);
ScopedProperty pp(scope);
@@ -1002,10 +899,6 @@ bool Object::defineOwnProperty2(ExecutionEngine *engine, uint index, const Prope
}
return __defineOwnProperty__(engine, index, 0, p, attrs);
-reject:
- if (engine->current->strictMode)
- engine->throwTypeError();
- return false;
}
bool Object::__defineOwnProperty__(ExecutionEngine *engine, uint index, String *member, const Property *p, PropertyAttributes attrs)
@@ -1032,9 +925,9 @@ bool Object::__defineOwnProperty__(ExecutionEngine *engine, uint index, String *
// clause 7
if (!cattrs.isConfigurable()) {
if (attrs.isConfigurable())
- goto reject;
+ return false;
if (attrs.hasEnumerable() && attrs.isEnumerable() != cattrs.isEnumerable())
- goto reject;
+ return false;
}
// clause 8
@@ -1045,7 +938,7 @@ bool Object::__defineOwnProperty__(ExecutionEngine *engine, uint index, String *
if (cattrs.isData() != attrs.isData()) {
// 9a
if (!cattrs.isConfigurable())
- goto reject;
+ return false;
if (cattrs.isData()) {
// 9b
cattrs.setType(PropertyAttributes::Accessor);
@@ -1071,15 +964,15 @@ bool Object::__defineOwnProperty__(ExecutionEngine *engine, uint index, String *
} else if (cattrs.isData() && attrs.isData()) { // clause 10
if (!cattrs.isConfigurable() && !cattrs.isWritable()) {
if (attrs.isWritable() || !current->value.sameValue(p->value))
- goto reject;
+ return false;
}
} else { // clause 10
Q_ASSERT(cattrs.isAccessor() && attrs.isAccessor());
if (!cattrs.isConfigurable()) {
if (!p->value.isEmpty() && current->value.rawValue() != p->value.rawValue())
- goto reject;
+ return false;
if (!p->set.isEmpty() && current->set.rawValue() != p->set.rawValue())
- goto reject;
+ return false;
}
}
@@ -1091,13 +984,9 @@ bool Object::__defineOwnProperty__(ExecutionEngine *engine, uint index, String *
setProperty(index, current);
} else {
setArrayAttributes(index, cattrs);
- arrayData()->setProperty(index, current);
+ arrayData()->setProperty(scope.engine, index, current);
}
return true;
- reject:
- if (engine->current->strictMode)
- engine->throwTypeError();
- return false;
}
@@ -1127,18 +1016,19 @@ void Object::copyArrayData(Object *other)
;
} else {
Q_ASSERT(!arrayData() && other->arrayData());
- ArrayData::realloc(this, other->d()->arrayData->type, other->d()->arrayData->alloc, false);
+ ArrayData::realloc(this, static_cast<ArrayData::Type>(other->d()->arrayData->type),
+ other->d()->arrayData->values.alloc, false);
if (other->arrayType() == Heap::ArrayData::Sparse) {
Heap::ArrayData *od = other->d()->arrayData;
Heap::ArrayData *dd = d()->arrayData;
dd->sparse = new SparseArray(*od->sparse);
- dd->freeList = od->freeList;
} else {
Heap::ArrayData *dd = d()->arrayData;
- dd->len = other->d()->arrayData->len;
+ dd->values.size = other->d()->arrayData->values.size;
dd->offset = other->d()->arrayData->offset;
}
- memcpy(d()->arrayData->arrayData, other->d()->arrayData->arrayData, other->d()->arrayData->alloc*sizeof(Value));
+ // ### need a write barrier
+ memcpy(d()->arrayData->values.values, other->d()->arrayData->values.values, other->d()->arrayData->values.alloc*sizeof(Value));
}
setArrayLengthUnchecked(other->getLength());
}
@@ -1247,19 +1137,6 @@ void Heap::ArrayObject::init(const QStringList &list)
a->setArrayLengthUnchecked(len);
}
-ReturnedValue ArrayObject::getLookup(const Managed *m, Lookup *l)
-{
- Scope scope(static_cast<const Object *>(m)->engine());
- ScopedString name(scope, scope.engine->current->compilationUnit->runtimeStrings[l->nameIndex]);
- if (name->equals(scope.engine->id_length())) {
- // special case, as the property is on the object itself
- l->getter = Lookup::arrayLengthGetter;
- const ArrayObject *a = static_cast<const ArrayObject *>(m);
- return a->propertyData(Heap::ArrayObject::LengthPropertyIndex)->asReturnedValue();
- }
- return Object::getLookup(m, l);
-}
-
uint ArrayObject::getLength(const Managed *m)
{
const ArrayObject *a = static_cast<const ArrayObject *>(m);
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 9592ff5d1b..db57d1cf3f 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -57,27 +57,48 @@
#include "qv4scopedvalue_p.h"
#include "qv4value_p.h"
#include "qv4internalclass_p.h"
+#include "qv4string_p.h"
QT_BEGIN_NAMESPACE
namespace QV4 {
-struct BuiltinFunction;
-
namespace Heap {
-struct Object : Base {
+#define ObjectMembers(class, Member) \
+ Member(class, Pointer, MemberData *, memberData) \
+ Member(class, Pointer, ArrayData *, arrayData)
+
+DECLARE_EXPORTED_HEAP_OBJECT(Object, Base) {
+ static void markObjects(Heap::Base *base, MarkStack *stack);
void init() { Base::init(); }
- void destroy() { Base::destroy(); }
+ const Value *inlinePropertyDataWithOffset(uint indexWithOffset) const {
+ Q_ASSERT(indexWithOffset >= vtable()->inlinePropertyOffset && indexWithOffset < vtable()->inlinePropertyOffset + vtable()->nInlineProperties);
+ return reinterpret_cast<const Value *>(this) + indexWithOffset;
+ }
const Value *inlinePropertyData(uint index) const {
Q_ASSERT(index < vtable()->nInlineProperties);
return reinterpret_cast<const Value *>(this) + vtable()->inlinePropertyOffset + index;
}
- Value *inlinePropertyData(uint index) {
+ void setInlineProperty(ExecutionEngine *e, uint index, Value v) {
+ Q_ASSERT(index < vtable()->nInlineProperties);
+ Value *prop = reinterpret_cast<Value *>(this) + vtable()->inlinePropertyOffset + index;
+ WriteBarrier::write(e, this, prop->data_ptr(), v.asReturnedValue());
+ }
+ void setInlineProperty(ExecutionEngine *e, uint index, Heap::Base *b) {
Q_ASSERT(index < vtable()->nInlineProperties);
- return reinterpret_cast<Value *>(this) + vtable()->inlinePropertyOffset + index;
+ Value *prop = reinterpret_cast<Value *>(this) + vtable()->inlinePropertyOffset + index;
+ WriteBarrier::write(e, this, prop->data_ptr(), b->asReturnedValue());
+ }
+
+ QV4::MemberData::Index writablePropertyData(uint index) {
+ uint nInline = vtable()->nInlineProperties;
+ if (index < nInline)
+ return { this, reinterpret_cast<Value *>(this) + vtable()->inlinePropertyOffset + index};
+ index -= nInline;
+ return { memberData, memberData->values.values + index };
}
const Value *propertyData(uint index) const {
@@ -85,38 +106,34 @@ struct Object : Base {
if (index < nInline)
return reinterpret_cast<const Value *>(this) + vtable()->inlinePropertyOffset + index;
index -= nInline;
- return memberData->data + index;
+ return memberData->values.data() + index;
}
- Value *propertyData(uint index) {
+ void setProperty(ExecutionEngine *e, uint index, Value v) {
uint nInline = vtable()->nInlineProperties;
- if (index < nInline)
- return reinterpret_cast<Value *>(this) + vtable()->inlinePropertyOffset + index;
+ if (index < nInline) {
+ setInlineProperty(e, index, v);
+ return;
+ }
index -= nInline;
- return memberData->data + index;
+ memberData->values.set(e, index, v);
}
+ void setProperty(ExecutionEngine *e, uint index, Heap::Base *b) {
+ uint nInline = vtable()->nInlineProperties;
+ if (index < nInline) {
+ setInlineProperty(e, index, b);
+ return;
+ }
+ index -= nInline;
+ memberData->values.set(e, index, b);
+ }
+
+ void setUsedAsProto();
Heap::Object *prototype() const { return internalClass->prototype; }
- Pointer<MemberData> memberData;
- Pointer<ArrayData> arrayData;
};
}
-#define V4_OBJECT(superClass) \
- public: \
- Q_MANAGED_CHECK \
- typedef superClass SuperClass; \
- static const QV4::ObjectVTable static_vtbl; \
- static inline const QV4::VTable *staticVTable() { return &static_vtbl.vTable; } \
- V4_MANAGED_SIZE_TEST \
- Data *d_unchecked() const { return static_cast<Data *>(m()); } \
- Data *d() const { \
- Data *dptr = d_unchecked(); \
- dptr->_checkIsInitialized(); \
- return dptr; \
- } \
- V4_ASSERT_IS_TRIVIAL(Data);
-
#define V4_OBJECT2(DataClass, superClass) \
private: \
DataClass() Q_DECL_EQ_DELETE; \
@@ -134,7 +151,7 @@ struct Object : Base {
dptr->_checkIsInitialized(); \
return dptr; \
} \
- V4_ASSERT_IS_TRIVIAL(QV4::Heap::DataClass);
+ Q_STATIC_ASSERT(std::is_trivial< QV4::Heap::DataClass >::value);
#define V4_PROTOTYPE(p) \
static QV4::Object *defaultPrototype(QV4::ExecutionEngine *e) \
@@ -143,18 +160,16 @@ struct Object : Base {
struct ObjectVTable
{
VTable vTable;
- void (*call)(const Managed *, Scope &scope, CallData *data);
- void (*construct)(const Managed *, Scope &scope, CallData *data);
+ ReturnedValue (*call)(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ ReturnedValue (*callAsConstructor)(const FunctionObject *, const Value *argv, int argc);
ReturnedValue (*get)(const Managed *, String *name, bool *hasProperty);
ReturnedValue (*getIndexed)(const Managed *, uint index, bool *hasProperty);
- void (*put)(Managed *, String *name, const Value &value);
- void (*putIndexed)(Managed *, uint index, const Value &value);
+ bool (*put)(Managed *, String *name, const Value &value);
+ bool (*putIndexed)(Managed *, uint index, const Value &value);
PropertyAttributes (*query)(const Managed *, String *name);
PropertyAttributes (*queryIndexed)(const Managed *, uint index);
bool (*deleteProperty)(Managed *m, String *name);
bool (*deleteIndexedProperty)(Managed *m, uint index);
- ReturnedValue (*getLookup)(const Managed *m, Lookup *l);
- void (*setLookup)(Managed *m, Lookup *l, const Value &v);
uint (*getLength)(const Managed *m);
void (*advanceIterator)(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
ReturnedValue (*instanceOf)(const Object *typeObject, const Value &var);
@@ -165,7 +180,7 @@ const QV4::ObjectVTable classname::static_vtbl = \
{ \
DEFINE_MANAGED_VTABLE_INT(classname, (std::is_same<classname::SuperClass, Object>::value) ? nullptr : &classname::SuperClass::static_vtbl.vTable), \
call, \
- construct, \
+ callAsConstructor, \
get, \
getIndexed, \
put, \
@@ -174,8 +189,6 @@ const QV4::ObjectVTable classname::static_vtbl = \
queryIndexed, \
deleteProperty, \
deleteIndexedProperty, \
- getLookup, \
- setLookup, \
getLength, \
advanceIterator, \
instanceOf \
@@ -197,6 +210,8 @@ struct Q_QML_EXPORT Object: Managed {
V4_INTERNALCLASS(Object)
V4_PROTOTYPE(objectPrototype)
+ enum { NInlineProperties = 2 };
+
enum {
IsObject = true,
GetterOffset = 0,
@@ -206,13 +221,16 @@ struct Q_QML_EXPORT Object: Managed {
void setInternalClass(InternalClass *ic);
const Value *propertyData(uint index) const { return d()->propertyData(index); }
- Value *propertyData(uint index) { return d()->propertyData(index); }
Heap::ArrayData *arrayData() const { return d()->arrayData; }
- void setArrayData(ArrayData *a) { d()->arrayData = a->d(); }
+ void setArrayData(ArrayData *a) { d()->arrayData.set(engine(), a->d()); }
void getProperty(uint index, Property *p, PropertyAttributes *attrs) const;
void setProperty(uint index, const Property *p);
+ void setProperty(uint index, Value v) const { d()->setProperty(engine(), index, v); }
+ void setProperty(uint index, Heap::Base *b) const { d()->setProperty(engine(), index, b); }
+ void setProperty(ExecutionEngine *engine, uint index, Value v) const { d()->setProperty(engine, index, v); }
+ void setProperty(ExecutionEngine *engine, uint index, Heap::Base *b) const { d()->setProperty(engine, index, b); }
const ObjectVTable *vtable() const { return reinterpret_cast<const ObjectVTable *>(d()->vtable()); }
Heap::Object *prototype() const { return d()->prototype(); }
@@ -221,8 +239,8 @@ struct Q_QML_EXPORT Object: Managed {
void getOwnProperty(String *name, PropertyAttributes *attrs, Property *p = 0);
void getOwnProperty(uint index, PropertyAttributes *attrs, Property *p = 0);
- Value *getValueOrSetter(String *name, PropertyAttributes *attrs);
- Value *getValueOrSetter(uint index, PropertyAttributes *attrs);
+ MemberData::Index getValueOrSetter(String *name, PropertyAttributes *attrs);
+ ArrayData::Index getValueOrSetter(uint index, PropertyAttributes *attrs);
bool hasProperty(String *name) const;
bool hasProperty(uint index) const;
@@ -239,8 +257,6 @@ struct Q_QML_EXPORT Object: Managed {
//
// helpers
//
- void put(ExecutionEngine *engine, const QString &name, const Value &value);
-
static ReturnedValue getValue(const Value &thisObject, const Value &v, PropertyAttributes attrs);
ReturnedValue getValue(const Value &v, PropertyAttributes attrs) const {
Scope scope(this->engine());
@@ -248,23 +264,27 @@ struct Q_QML_EXPORT Object: Managed {
return getValue(t, v, attrs);
}
- void putValue(uint memberIndex, const Value &value);
+ bool putValue(uint memberIndex, const Value &value);
/* The spec default: Writable: true, Enumerable: false, Configurable: true */
void defineDefaultProperty(String *name, const Value &value) {
insertMember(name, value, Attr_Data|Attr_NotEnumerable);
}
void defineDefaultProperty(const QString &name, const Value &value);
- void defineDefaultProperty(const QString &name, void (*code)(const BuiltinFunction *, Scope &, CallData *), int argumentCount = 0);
- void defineDefaultProperty(String *name, void (*code)(const BuiltinFunction *, Scope &, CallData *), int argumentCount = 0);
- void defineAccessorProperty(const QString &name, void (*getter)(const BuiltinFunction *, Scope &, CallData *),
- void (*setter)(const BuiltinFunction *, Scope &, CallData *));
- void defineAccessorProperty(String *name, void (*getter)(const BuiltinFunction *, Scope &, CallData *),
- void (*setter)(const BuiltinFunction *, Scope &, CallData *));
+ void defineDefaultProperty(const QString &name, ReturnedValue (*code)(const FunctionObject *, const Value *thisObject, const Value *argv, int argc), int argumentCount = 0);
+ void defineDefaultProperty(String *name, ReturnedValue (*code)(const FunctionObject *, const Value *thisObject, const Value *argv, int argc), int argumentCount = 0);
+ void defineAccessorProperty(const QString &name, ReturnedValue (*getter)(const FunctionObject *, const Value *, const Value *, int),
+ ReturnedValue (*setter)(const FunctionObject *, const Value *, const Value *, int));
+ void defineAccessorProperty(String *name, ReturnedValue (*getter)(const FunctionObject *, const Value *, const Value *, int),
+ ReturnedValue (*setter)(const FunctionObject *, const Value *, const Value *, int));
/* Fixed: Writable: false, Enumerable: false, Configurable: false */
void defineReadonlyProperty(const QString &name, const Value &value);
void defineReadonlyProperty(String *name, const Value &value);
+ /* Fixed: Writable: false, Enumerable: false, Configurable: true */
+ void defineReadonlyConfigurableProperty(const QString &name, const Value &value);
+ void defineReadonlyConfigurableProperty(String *name, const Value &value);
+
void insertMember(String *s, const Value &v, PropertyAttributes attributes = Attr_Data) {
Scope scope(engine());
ScopedProperty p(scope);
@@ -304,7 +324,7 @@ public:
void push_back(const Value &v);
ArrayData::Type arrayType() const {
- return arrayData() ? d()->arrayData->type : Heap::ArrayData::Simple;
+ return arrayData() ? static_cast<ArrayData::Type>(d()->arrayData->type) : Heap::ArrayData::Simple;
}
// ### remove me
void setArrayType(ArrayData::Type t) {
@@ -344,10 +364,34 @@ public:
{ return vtable()->get(this, name, hasProperty); }
inline ReturnedValue getIndexed(uint idx, bool *hasProperty = 0) const
{ return vtable()->getIndexed(this, idx, hasProperty); }
- inline void put(String *name, const Value &v)
- { vtable()->put(this, name, v); }
- inline void putIndexed(uint idx, const Value &v)
- { vtable()->putIndexed(this, idx, v); }
+
+ // use the set variants instead, to customize throw behavior
+ inline bool put(String *name, const Value &v)
+ { return vtable()->put(this, name, v); }
+ inline bool putIndexed(uint idx, const Value &v)
+ { return vtable()->putIndexed(this, idx, v); }
+
+ enum ThrowOnFailure {
+ DoThrowOnRejection,
+ DoNotThrow
+ };
+
+ // ES6: 7.3.3 Set (O, P, V, Throw)
+ inline bool set(String *name, const Value &v, ThrowOnFailure shouldThrow)
+ {
+ bool ret = vtable()->put(this, name, v);
+ // ES6: 7.3.3, 6: If success is false and Throw is true, throw a TypeError exception.
+ if (!ret && shouldThrow == ThrowOnFailure::DoThrowOnRejection) {
+ ExecutionEngine *e = engine();
+ if (!e->hasException) { // allow a custom set impl to throw itself
+ QString message = QLatin1String("Cannot assign to read-only property \"") +
+ name->toQString() + QLatin1Char('\"');
+ e->throwTypeError(message);
+ }
+ }
+ return ret;
+ }
+
PropertyAttributes query(String *name) const
{ return vtable()->query(this, name); }
PropertyAttributes queryIndexed(uint index) const
@@ -356,34 +400,23 @@ public:
{ return vtable()->deleteProperty(this, name); }
bool deleteIndexedProperty(uint index)
{ return vtable()->deleteIndexedProperty(this, index); }
- ReturnedValue getLookup(Lookup *l) const
- { return vtable()->getLookup(this, l); }
- void setLookup(Lookup *l, const Value &v)
- { vtable()->setLookup(this, l, v); }
void advanceIterator(ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes)
{ vtable()->advanceIterator(this, it, name, index, p, attributes); }
uint getLength() const { return vtable()->getLength(this); }
ReturnedValue instanceOf(const Value &var) const
{ return vtable()->instanceOf(this, var); }
- inline void construct(Scope &scope, CallData *d) const
- { return vtable()->construct(this, scope, d); }
- inline void call(Scope &scope, CallData *d) const
- { vtable()->call(this, scope, d); }
protected:
- static void markObjects(Heap::Base *that, ExecutionEngine *e);
- static void construct(const Managed *m, Scope &scope, CallData *);
- static void call(const Managed *m, Scope &scope, CallData *);
+ static ReturnedValue callAsConstructor(const FunctionObject *f, const Value *argv, int argc);
+ static ReturnedValue call(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty);
- static void put(Managed *m, String *name, const Value &value);
- static void putIndexed(Managed *m, uint index, const Value &value);
+ static bool put(Managed *m, String *name, const Value &value);
+ static bool putIndexed(Managed *m, uint index, const Value &value);
static PropertyAttributes query(const Managed *m, String *name);
static PropertyAttributes queryIndexed(const Managed *m, uint index);
static bool deleteProperty(Managed *m, String *name);
static bool deleteIndexedProperty(Managed *m, uint index);
- static ReturnedValue getLookup(const Managed *m, Lookup *l);
- static void setLookup(Managed *m, Lookup *l, const Value &v);
static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
static uint getLength(const Managed *m);
static ReturnedValue instanceOf(const Object *typeObject, const Value &var);
@@ -391,8 +424,8 @@ protected:
private:
ReturnedValue internalGet(String *name, bool *hasProperty) const;
ReturnedValue internalGetIndexed(uint index, bool *hasProperty) const;
- void internalPut(String *name, const Value &value);
- void internalPutIndexed(uint index, const Value &value);
+ bool internalPut(String *name, const Value &value);
+ bool internalPutIndexed(uint index, const Value &value);
bool internalDeleteProperty(String *name);
bool internalDeleteIndexedProperty(uint index);
@@ -436,7 +469,7 @@ struct ArrayObject : Object {
private:
void commonInit()
- { *propertyData(LengthPropertyIndex) = Primitive::fromInt32(0); }
+ { setProperty(internalClass->engine, LengthPropertyIndex, Primitive::fromInt32(0)); }
};
}
@@ -466,7 +499,6 @@ struct ArrayObject: Object {
void init(ExecutionEngine *engine);
- static ReturnedValue getLookup(const Managed *m, Lookup *l);
using Object::getLength;
static uint getLength(const Managed *m);
@@ -476,7 +508,7 @@ struct ArrayObject: Object {
inline void Object::setArrayLengthUnchecked(uint l)
{
if (isArrayObject())
- *propertyData(Heap::ArrayObject::LengthPropertyIndex) = Primitive::fromUInt32(l);
+ setProperty(Heap::ArrayObject::LengthPropertyIndex, Primitive::fromUInt32(l));
}
inline void Object::push_back(const Value &v)
@@ -493,7 +525,7 @@ inline void Object::arraySet(uint index, const Property *p, PropertyAttributes a
{
// ### Clean up
arrayCreate();
- if (attributes.isAccessor() || (index > 0x1000 && index > 2*d()->arrayData->alloc)) {
+ if (attributes.isAccessor() || (index > 0x1000 && index > 2*d()->arrayData->values.alloc)) {
initSparseArray();
} else {
arrayData()->vtable()->reallocate(this, index + 1, false);
@@ -508,7 +540,7 @@ inline void Object::arraySet(uint index, const Property *p, PropertyAttributes a
inline void Object::arraySet(uint index, const Value &value)
{
arrayCreate();
- if (index > 0x1000 && index > 2*d()->arrayData->alloc) {
+ if (index > 0x1000 && index > 2*d()->arrayData->values.alloc) {
initSparseArray();
}
ArrayData::insert(this, index, &value);
diff --git a/src/qml/jsruntime/qv4objectiterator.cpp b/src/qml/jsruntime/qv4objectiterator.cpp
index 59115dfe21..0394c704f9 100644
--- a/src/qml/jsruntime/qv4objectiterator.cpp
+++ b/src/qml/jsruntime/qv4objectiterator.cpp
@@ -177,10 +177,10 @@ ReturnedValue ObjectIterator::nextPropertyNameAsString()
DEFINE_OBJECT_VTABLE(ForEachIteratorObject);
-void ForEachIteratorObject::markObjects(Heap::Base *that, ExecutionEngine *e)
+void Heap::ForEachIteratorObject::markObjects(Heap::Base *that, MarkStack *markStack)
{
- ForEachIteratorObject::Data *o = static_cast<ForEachIteratorObject::Data *>(that);
- o->workArea[0].mark(e);
- o->workArea[1].mark(e);
- Object::markObjects(that, e);
+ ForEachIteratorObject *o = static_cast<ForEachIteratorObject *>(that);
+ o->workArea[0].mark(markStack);
+ o->workArea[1].mark(markStack);
+ Object::markObjects(that, markStack);
}
diff --git a/src/qml/jsruntime/qv4objectiterator_p.h b/src/qml/jsruntime/qv4objectiterator_p.h
index 98e94a95ea..3e501f23ce 100644
--- a/src/qml/jsruntime/qv4objectiterator_p.h
+++ b/src/qml/jsruntime/qv4objectiterator_p.h
@@ -73,7 +73,7 @@ struct Q_QML_EXPORT ObjectIteratorData
uint memberIndex;
uint flags;
};
-V4_ASSERT_IS_TRIVIAL(ObjectIteratorData)
+Q_STATIC_ASSERT(std::is_trivial< ObjectIteratorData >::value);
struct Q_QML_EXPORT ObjectIterator: ObjectIteratorData
{
@@ -116,6 +116,7 @@ struct ForEachIteratorObject : Object {
ObjectIterator &it() { return *reinterpret_cast<ObjectIterator*>(&itData); }
Value workArea[2];
+ static void markObjects(Heap::Base *that, MarkStack *markStack);
private:
ObjectIteratorData itData;
};
@@ -127,9 +128,6 @@ struct ForEachIteratorObject: Object {
Q_MANAGED_TYPE(ForeachIteratorObject)
ReturnedValue nextPropertyName() { return d()->it().nextPropertyNameAsString(); }
-
-protected:
- static void markObjects(Heap::Base *that, ExecutionEngine *e);
};
inline
diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp
index 97dbe24339..a86352be40 100644
--- a/src/qml/jsruntime/qv4objectproto.cpp
+++ b/src/qml/jsruntime/qv4objectproto.cpp
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2017 Crimson AS <info@crimson.no>
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
@@ -45,6 +46,7 @@
#include "qv4runtime_p.h"
#include "qv4objectiterator_p.h"
#include "qv4string_p.h"
+#include "qv4jscall_p.h"
#include <QtCore/QDateTime>
#include <QtCore/QStringList>
@@ -59,27 +61,29 @@ void Heap::ObjectCtor::init(QV4::ExecutionContext *scope)
Heap::FunctionObject::init(scope, QStringLiteral("Object"));
}
-void ObjectCtor::construct(const Managed *that, Scope &scope, CallData *callData)
+ReturnedValue ObjectCtor::callAsConstructor(const FunctionObject *f, const Value *argv, int argc)
{
- const ObjectCtor *ctor = static_cast<const ObjectCtor *>(that);
- if (!callData->argc || callData->args[0].isUndefined() || callData->args[0].isNull()) {
+ ExecutionEngine *v4 = f->engine();
+ const ObjectCtor *ctor = static_cast<const ObjectCtor *>(f);
+ if (!argc || argv[0].isUndefined() || argv[0].isNull()) {
+ Scope scope(v4);
ScopedObject obj(scope, scope.engine->newObject());
ScopedObject proto(scope, ctor->get(scope.engine->id_prototype()));
if (!!proto)
obj->setPrototype(proto);
- scope.result = obj.asReturnedValue();
+ return obj.asReturnedValue();
} else {
- scope.result = callData->args[0].toObject(scope.engine);
+ return argv[0].toObject(v4)->asReturnedValue();
}
}
-void ObjectCtor::call(const Managed *, Scope &scope, CallData *callData)
+ReturnedValue ObjectCtor::call(const FunctionObject *m, const Value *, const Value *argv, int argc)
{
- ExecutionEngine *v4 = scope.engine;
- if (!callData->argc || callData->args[0].isUndefined() || callData->args[0].isNull()) {
- scope.result = v4->newObject()->asReturnedValue();
+ ExecutionEngine *v4 = m->engine();
+ if (!argc || argv[0].isUndefined() || argv[0].isNull()) {
+ return v4->newObject()->asReturnedValue();
} else {
- scope.result = callData->args[0].toObject(v4);
+ return argv[0].toObject(v4)->asReturnedValue();
}
}
@@ -89,10 +93,11 @@ void ObjectPrototype::init(ExecutionEngine *v4, Object *ctor)
ScopedObject o(scope, this);
ctor->defineReadonlyProperty(v4->id_prototype(), o);
- ctor->defineReadonlyProperty(v4->id_length(), Primitive::fromInt32(1));
+ ctor->defineReadonlyConfigurableProperty(v4->id_length(), Primitive::fromInt32(1));
ctor->defineDefaultProperty(QStringLiteral("getPrototypeOf"), method_getPrototypeOf, 1);
ctor->defineDefaultProperty(QStringLiteral("getOwnPropertyDescriptor"), method_getOwnPropertyDescriptor, 2);
ctor->defineDefaultProperty(QStringLiteral("getOwnPropertyNames"), method_getOwnPropertyNames, 1);
+ ctor->defineDefaultProperty(QStringLiteral("assign"), method_assign, 2);
ctor->defineDefaultProperty(QStringLiteral("create"), method_create, 2);
ctor->defineDefaultProperty(QStringLiteral("defineProperty"), method_defineProperty, 3);
ctor->defineDefaultProperty(QStringLiteral("defineProperties"), method_defineProperties, 2);
@@ -116,104 +121,168 @@ void ObjectPrototype::init(ExecutionEngine *v4, Object *ctor)
ExecutionContext *global = v4->rootContext();
ScopedProperty p(scope);
- p->value = BuiltinFunction::create(global, v4->id___proto__(), method_get_proto);
- p->set = BuiltinFunction::create(global, v4->id___proto__(), method_set_proto);
+ p->value = FunctionObject::createBuiltinFunction(global, v4->id___proto__(), method_get_proto);
+ p->set = FunctionObject::createBuiltinFunction(global, v4->id___proto__(), method_set_proto);
insertMember(v4->id___proto__(), p, Attr_Accessor|Attr_NotEnumerable);
}
-void ObjectPrototype::method_getPrototypeOf(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ObjectPrototype::method_getPrototypeOf(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- ScopedObject o(scope, callData->argument(0));
- if (!o)
- THROW_TYPE_ERROR();
+ Scope scope(b);
+ if (argc < 1)
+ return scope.engine->throwTypeError();
+
+ ScopedObject o(scope, argv[0].toObject(scope.engine));
+ if (scope.engine->hasException)
+ return QV4::Encode::undefined();
ScopedObject p(scope, o->prototype());
- scope.result = !!p ? p->asReturnedValue() : Encode::null();
+ return (!!p ? p->asReturnedValue() : Encode::null());
}
-void ObjectPrototype::method_getOwnPropertyDescriptor(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ObjectPrototype::method_getOwnPropertyDescriptor(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- ScopedObject O(scope, callData->argument(0));
- if (!O) {
- scope.result = scope.engine->throwTypeError();
- return;
- }
+ Scope scope(b);
+ if (argc < 1)
+ return scope.engine->throwTypeError();
+
+ ScopedObject O(scope, argv[0].toObject(scope.engine));
+ if (scope.engine->hasException)
+ return QV4::Encode::undefined();
if (ArgumentsObject::isNonStrictArgumentsObject(O))
static_cast<ArgumentsObject *>(O.getPointer())->fullyCreate();
- ScopedValue v(scope, callData->argument(1));
+ ScopedValue v(scope, argc > 1 ? argv[1] : Primitive::undefinedValue());
ScopedString name(scope, v->toString(scope.engine));
- CHECK_EXCEPTION();
+ if (scope.engine->hasException)
+ return QV4::Encode::undefined();
PropertyAttributes attrs;
ScopedProperty desc(scope);
O->getOwnProperty(name, &attrs, desc);
- scope.result = fromPropertyDescriptor(scope.engine, desc, attrs);
+ return fromPropertyDescriptor(scope.engine, desc, attrs);
}
-void ObjectPrototype::method_getOwnPropertyNames(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ObjectPrototype::method_getOwnPropertyNames(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- ScopedObject O(scope, callData->argument(0));
- if (!O) {
- scope.result = scope.engine->throwTypeError();
- return;
- }
+ Scope scope(b);
+ if (argc < 1)
+ return scope.engine->throwTypeError();
+
+ ScopedObject O(scope, argv[0].toObject(scope.engine));
+ if (scope.engine->hasException)
+ return QV4::Encode::undefined();
- scope.result = getOwnPropertyNames(scope.engine, callData->args[0]);
+ return Encode(getOwnPropertyNames(scope.engine, argv[0]));
}
-void ObjectPrototype::method_create(const BuiltinFunction *builtin, Scope &scope, CallData *callData)
+// 19.1.2.1
+ReturnedValue ObjectPrototype::method_assign(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- ScopedValue O(scope, callData->argument(0));
- if (!O->isObject() && !O->isNull()) {
- scope.result = scope.engine->throwTypeError();
- return;
+ Scope scope(b);
+ if (argc < 1)
+ return scope.engine->throwTypeError();
+
+ ScopedObject to(scope, argv[0].toObject(scope.engine));
+ if (scope.engine->hasException)
+ return QV4::Encode::undefined();
+
+ if (argc == 1)
+ return to.asReturnedValue();
+
+ for (int i = 1, ei = argc; i < ei; ++i) {
+ if (argv[i].isUndefined() || argv[i].isNull())
+ continue;
+
+ ScopedObject from(scope, argv[i].toObject(scope.engine));
+ if (scope.engine->hasException)
+ return QV4::Encode::undefined();
+ QV4::ScopedArrayObject keys(scope, QV4::ObjectPrototype::getOwnPropertyNames(scope.engine, from));
+ quint32 length = keys->getLength();
+
+ ScopedString nextKey(scope);
+ ScopedValue propValue(scope);
+ for (quint32 i = 0; i < length; ++i) {
+ nextKey = Value::fromReturnedValue(keys->getIndexed(i)).toString(scope.engine);
+
+ PropertyAttributes attrs;
+ ScopedProperty prop(scope);
+ from->getOwnProperty(nextKey, &attrs, prop);
+
+ if (attrs == PropertyFlag::Attr_Invalid)
+ continue;
+
+ if (!attrs.isEnumerable())
+ continue;
+
+ propValue = from->get(nextKey);
+ to->set(nextKey, propValue, Object::DoThrowOnRejection);
+ if (scope.engine->hasException)
+ return QV4::Encode::undefined();
+ }
}
+ return to.asReturnedValue();
+}
+
+ReturnedValue ObjectPrototype::method_create(const FunctionObject *builtin, const Value *thisObject, const Value *argv, int argc)
+{
+ Scope scope(builtin);
+ if (!argc || (!argv[0].isObject() && !argv[0].isNull()))
+ return scope.engine->throwTypeError();
+
+ ScopedObject O(scope, argv[0]);
+
ScopedObject newObject(scope, scope.engine->newObject());
- newObject->setPrototype(O->as<Object>());
+ newObject->setPrototype(O);
- if (callData->argc > 1 && !callData->args[1].isUndefined()) {
- callData->args[0] = newObject;
- method_defineProperties(builtin, scope, callData);
- return;
+
+ if (argc > 1 && !argv[1].isUndefined()) {
+ Value *arguments = scope.alloc(argc);
+ arguments[0] = newObject;
+ memcpy(arguments + 1, argv + 1, (argc - 1)*sizeof(Value));
+ return method_defineProperties(builtin, thisObject, arguments, argc);
}
- scope.result = newObject;
+ return newObject.asReturnedValue();
}
-void ObjectPrototype::method_defineProperty(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ObjectPrototype::method_defineProperty(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- ScopedObject O(scope, callData->argument(0));
- if (!O) {
- scope.result = scope.engine->throwTypeError();
- return;
- }
+ Scope scope(b);
+ if (!argc || !argv[0].isObject())
+ return scope.engine->throwTypeError();
- ScopedString name(scope, callData->argument(1), ScopedString::Convert);
- CHECK_EXCEPTION();
+ ScopedObject O(scope, argv[0]);
+ ScopedString name(scope, argc > 1 ? argv[1] : Primitive::undefinedValue(), ScopedString::Convert);
+ if (scope.engine->hasException)
+ return QV4::Encode::undefined();
- ScopedValue attributes(scope, callData->argument(2));
+ ScopedValue attributes(scope, argc > 2 ? argv[2] : Primitive::undefinedValue());
ScopedProperty pd(scope);
PropertyAttributes attrs;
toPropertyDescriptor(scope.engine, attributes, pd, &attrs);
- CHECK_EXCEPTION();
+ if (scope.engine->hasException)
+ return QV4::Encode::undefined();
if (!O->__defineOwnProperty__(scope.engine, name, pd, attrs))
THROW_TYPE_ERROR();
- scope.result = O;
+ return O.asReturnedValue();
}
-void ObjectPrototype::method_defineProperties(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ObjectPrototype::method_defineProperties(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- ScopedObject O(scope, callData->argument(0));
- if (!O)
- THROW_TYPE_ERROR();
+ Scope scope(b);
+ if (argc < 2 || !argv[0].isObject())
+ return scope.engine->throwTypeError();
- ScopedObject o(scope, callData->argument(1), ScopedObject::Convert);
- CHECK_EXCEPTION();
+ ScopedObject O(scope, argv[0]);
+
+ ScopedObject o(scope, argv[1].toObject(scope.engine));
+ if (scope.engine->hasException)
+ return QV4::Encode::undefined();
ScopedValue val(scope);
@@ -230,7 +299,8 @@ void ObjectPrototype::method_defineProperties(const BuiltinFunction *, Scope &sc
PropertyAttributes nattrs;
val = o->getValue(pd->value, attrs);
toPropertyDescriptor(scope.engine, val, n, &nattrs);
- CHECK_EXCEPTION();
+ if (scope.engine->hasException)
+ return QV4::Encode::undefined();
bool ok;
if (name)
ok = O->__defineOwnProperty__(scope.engine, name, n, nattrs);
@@ -240,33 +310,40 @@ void ObjectPrototype::method_defineProperties(const BuiltinFunction *, Scope &sc
THROW_TYPE_ERROR();
}
- scope.result = O;
+ return O.asReturnedValue();
}
-void ObjectPrototype::method_seal(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ObjectPrototype::method_seal(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- ScopedObject o(scope, callData->argument(0));
- if (!o)
- THROW_TYPE_ERROR();
+ const Value a = argc ? argv[0] : Primitive::undefinedValue();
+ if (!a.isObject())
+ // 19.1.2.17, 1
+ return a.asReturnedValue();
+ Scope scope(b);
+ ScopedObject o(scope, a);
o->setInternalClass(o->internalClass()->sealed());
if (o->arrayData()) {
ArrayData::ensureAttributes(o);
- for (uint i = 0; i < o->d()->arrayData->alloc; ++i) {
+ for (uint i = 0; i < o->d()->arrayData->values.alloc; ++i) {
if (!o->arrayData()->isEmpty(i))
o->d()->arrayData->attrs[i].setConfigurable(false);
}
}
- scope.result = o;
+ return o.asReturnedValue();
}
-void ObjectPrototype::method_freeze(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ObjectPrototype::method_freeze(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- ScopedObject o(scope, callData->argument(0));
- if (!o)
- THROW_TYPE_ERROR();
+ const Value a = argc ? argv[0] : Primitive::undefinedValue();
+ if (!a.isObject())
+ // 19.1.2.5, 1
+ return a.asReturnedValue();
+
+ Scope scope(b);
+ ScopedObject o(scope, a);
if (ArgumentsObject::isNonStrictArgumentsObject(o))
static_cast<ArgumentsObject *>(o.getPointer())->fullyCreate();
@@ -275,116 +352,116 @@ void ObjectPrototype::method_freeze(const BuiltinFunction *, Scope &scope, CallD
if (o->arrayData()) {
ArrayData::ensureAttributes(o);
- for (uint i = 0; i < o->arrayData()->alloc; ++i) {
+ for (uint i = 0; i < o->arrayData()->values.alloc; ++i) {
if (!o->arrayData()->isEmpty(i))
o->arrayData()->attrs[i].setConfigurable(false);
if (o->arrayData()->attrs[i].isData())
o->arrayData()->attrs[i].setWritable(false);
}
}
- scope.result = o;
+ return o.asReturnedValue();
}
-void ObjectPrototype::method_preventExtensions(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ObjectPrototype::method_preventExtensions(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- ScopedObject o(scope, callData->argument(0));
+ Scope scope(b);
+ if (!argc)
+ return scope.engine->throwTypeError();
+
+ ScopedObject o(scope, argv[0].toObject(scope.engine));
if (!o)
- THROW_TYPE_ERROR();
+ return argv[0].asReturnedValue();
o->setInternalClass(o->internalClass()->nonExtensible());
- scope.result = o;
+ return o.asReturnedValue();
}
-void ObjectPrototype::method_isSealed(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ObjectPrototype::method_isSealed(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- ScopedObject o(scope, callData->argument(0));
+ Scope scope(b);
+ if (!argc)
+ return scope.engine->throwTypeError();
+
+ ScopedObject o(scope, argv[0].toObject(scope.engine));
if (!o)
- THROW_TYPE_ERROR();
+ return Encode(true);
- if (o->isExtensible()) {
- scope.result = Encode(false);
- return;
- }
+ if (o->isExtensible())
+ return Encode(false);
- if (o->internalClass() != o->internalClass()->sealed()) {
- scope.result = Encode(false);
- return;
- }
+ if (o->internalClass() != o->internalClass()->sealed())
+ return Encode(false);
- if (!o->arrayData() || !o->arrayData()->length()) {
- scope.result = Encode(true);
- return;
- }
+ if (!o->arrayData() || !o->arrayData()->length())
+ return Encode(true);
Q_ASSERT(o->arrayData() && o->arrayData()->length());
- if (!o->arrayData()->attrs) {
- scope.result = Encode(false);
- return;
- }
+ if (!o->arrayData()->attrs)
+ return Encode(false);
- for (uint i = 0; i < o->arrayData()->alloc; ++i) {
+ for (uint i = 0; i < o->arrayData()->values.alloc; ++i) {
if (!o->arrayData()->isEmpty(i))
- if (o->arrayData()->attributes(i).isConfigurable()) {
- scope.result = Encode(false);
- return;
- }
+ if (o->arrayData()->attributes(i).isConfigurable())
+ return Encode(false);
}
- scope.result = Encode(true);
+ return Encode(true);
}
-void ObjectPrototype::method_isFrozen(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ObjectPrototype::method_isFrozen(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- ScopedObject o(scope, callData->argument(0));
+ Scope scope(b);
+ if (!argc)
+ return scope.engine->throwTypeError();
+
+ ScopedObject o(scope, argv[0].toObject(scope.engine));
if (!o)
- THROW_TYPE_ERROR();
+ return Encode(true);
- if (o->isExtensible()) {
- scope.result = Encode(false);
- return;
- }
+ if (o->isExtensible())
+ return Encode(false);
- if (o->internalClass() != o->internalClass()->frozen()) {
- scope.result = Encode(false);
- return;
- }
+ if (o->internalClass() != o->internalClass()->frozen())
+ return Encode(false);
- if (!o->arrayData() || !o->arrayData()->length()) {
- scope.result = Encode(true);
- return;
- }
+ if (!o->arrayData() || !o->arrayData()->length())
+ return Encode(true);
Q_ASSERT(o->arrayData() && o->arrayData()->length());
- if (!o->arrayData()->attrs) {
- scope.result = Encode(false);
- return;
- }
+ if (!o->arrayData()->attrs)
+ return Encode(false);
- for (uint i = 0; i < o->arrayData()->alloc; ++i) {
+ for (uint i = 0; i < o->arrayData()->values.alloc; ++i) {
if (!o->arrayData()->isEmpty(i))
- if (o->arrayData()->attributes(i).isConfigurable() || o->arrayData()->attributes(i).isWritable()) {
- scope.result = Encode(false);
- return;
- }
+ if (o->arrayData()->attributes(i).isConfigurable() || o->arrayData()->attributes(i).isWritable())
+ return Encode(false);
}
- scope.result = Encode(true);
+ return Encode(true);
}
-void ObjectPrototype::method_isExtensible(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ObjectPrototype::method_isExtensible(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- ScopedObject o(scope, callData->argument(0));
+ Scope scope(b);
+ if (!argc)
+ return scope.engine->throwTypeError();
+
+ ScopedObject o(scope, argv[0].toObject(scope.engine));
if (!o)
- THROW_TYPE_ERROR();
+ return Encode(false);
- scope.result = Encode((bool)o->isExtensible());
+ return Encode((bool)o->isExtensible());
}
-void ObjectPrototype::method_keys(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ObjectPrototype::method_keys(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- ScopedObject o(scope, callData->argument(0));
- if (!o)
- THROW_TYPE_ERROR();
+ Scope scope(b);
+ if (!argc)
+ return scope.engine->throwTypeError();
+
+ ScopedObject o(scope, argv[0].toObject(scope.engine));
+ if (scope.engine->hasException)
+ return QV4::Encode::undefined();
ScopedArrayObject a(scope, scope.engine->newArrayObject());
@@ -397,101 +474,109 @@ void ObjectPrototype::method_keys(const BuiltinFunction *, Scope &scope, CallDat
a->push_back(name);
}
- scope.result = a;
+ return a.asReturnedValue();
}
-void ObjectPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ObjectPrototype::method_toString(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- if (callData->thisObject.isUndefined()) {
- scope.result = scope.engine->newString(QStringLiteral("[object Undefined]"));
- } else if (callData->thisObject.isNull()) {
- scope.result = scope.engine->newString(QStringLiteral("[object Null]"));
+ ExecutionEngine *v4 = b->engine();
+ if (thisObject->isUndefined()) {
+ return Encode(v4->newString(QStringLiteral("[object Undefined]")));
+ } else if (thisObject->isNull()) {
+ return Encode(v4->newString(QStringLiteral("[object Null]")));
} else {
- ScopedObject obj(scope, callData->thisObject.toObject(scope.engine));
+ Scope scope(v4);
+ ScopedObject obj(scope, thisObject->toObject(scope.engine));
QString className = obj->className();
- scope.result = scope.engine->newString(QStringLiteral("[object %1]").arg(className));
+ return Encode(v4->newString(QStringLiteral("[object %1]").arg(className)));
}
}
-void ObjectPrototype::method_toLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ObjectPrototype::method_toLocaleString(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- ScopedObject o(scope, callData->thisObject.toObject(scope.engine));
+ Scope scope(b);
+ ScopedObject o(scope, thisObject->toObject(scope.engine));
if (!o)
RETURN_UNDEFINED();
ScopedFunctionObject f(scope, o->get(scope.engine->id_toString()));
if (!f)
THROW_TYPE_ERROR();
- ScopedCallData cData(scope);
- cData->thisObject = o;
- f->call(scope, callData);
+
+ return f->call(thisObject, argv, argc);
}
-void ObjectPrototype::method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ObjectPrototype::method_valueOf(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- scope.result = callData->thisObject.toObject(scope.engine);
+ return Encode(thisObject->toObject(b->engine()));
}
-void ObjectPrototype::method_hasOwnProperty(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ObjectPrototype::method_hasOwnProperty(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- ScopedString P(scope, callData->argument(0), ScopedString::Convert);
- CHECK_EXCEPTION();
- ScopedObject O(scope, callData->thisObject, ScopedObject::Convert);
- CHECK_EXCEPTION();
+ Scope scope(b);
+ ScopedString P(scope, argc ? argv[0] : Primitive::undefinedValue(), ScopedString::Convert);
+ if (scope.engine->hasException)
+ return QV4::Encode::undefined();
+ ScopedObject O(scope, thisObject->toObject(scope.engine));
+ if (scope.engine->hasException)
+ return QV4::Encode::undefined();
bool r = O->hasOwnProperty(P);
if (!r)
r = !O->query(P).isEmpty();
- scope.result = Encode(r);
+ return Encode(r);
}
-void ObjectPrototype::method_isPrototypeOf(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ObjectPrototype::method_isPrototypeOf(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- ScopedObject V(scope, callData->argument(0));
- if (!V) {
- scope.result = Encode(false);
- return;
- }
-
- ScopedObject O(scope, callData->thisObject, ScopedObject::Convert);
- CHECK_EXCEPTION();
+ Scope scope(b);
+ if (!argc || !argv[0].isObject())
+ return Encode(false);
+
+ ScopedObject V(scope, argv[0]);
+ ScopedObject O(scope, thisObject->toObject(scope.engine));
+ if (scope.engine->hasException)
+ return QV4::Encode::undefined();
ScopedObject proto(scope, V->prototype());
while (proto) {
- if (O->d() == proto->d()) {
- scope.result = Encode(true);
- return;
- }
+ if (O->d() == proto->d())
+ return Encode(true);
proto = proto->prototype();
}
- scope.result = Encode(false);
+ return Encode(false);
}
-void ObjectPrototype::method_propertyIsEnumerable(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ObjectPrototype::method_propertyIsEnumerable(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- ScopedString p(scope, callData->argument(0), ScopedString::Convert);
- CHECK_EXCEPTION();
-
- ScopedObject o(scope, callData->thisObject, ScopedObject::Convert);
- CHECK_EXCEPTION();
+ Scope scope(b);
+ ScopedString p(scope, argc ? argv[0] : Primitive::undefinedValue(), ScopedString::Convert);
+ if (scope.engine->hasException)
+ return QV4::Encode::undefined();
+
+ ScopedObject o(scope, thisObject->toObject(scope.engine));
+ if (scope.engine->hasException)
+ return QV4::Encode::undefined();
PropertyAttributes attrs;
o->getOwnProperty(p, &attrs);
- scope.result = Encode(attrs.isEnumerable());
+ return Encode(attrs.isEnumerable());
}
-void ObjectPrototype::method_defineGetter(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ObjectPrototype::method_defineGetter(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- if (callData->argc < 2)
+ Scope scope(b);
+ if (argc < 2)
THROW_TYPE_ERROR();
- ScopedFunctionObject f(scope, callData->argument(1));
+ ScopedFunctionObject f(scope, argv[1]);
if (!f)
THROW_TYPE_ERROR();
- ScopedString prop(scope, callData->argument(0), ScopedString::Convert);
- CHECK_EXCEPTION();
+ ScopedString prop(scope, argv[0], ScopedString::Convert);
+ if (scope.engine->hasException)
+ return QV4::Encode::undefined();
- ScopedObject o(scope, callData->thisObject);
+ ScopedObject o(scope, thisObject);
if (!o) {
- if (!callData->thisObject.isUndefined())
+ if (!thisObject->isUndefined())
RETURN_UNDEFINED();
o = scope.engine->globalObject;
}
@@ -499,25 +584,29 @@ void ObjectPrototype::method_defineGetter(const BuiltinFunction *, Scope &scope,
ScopedProperty pd(scope);
pd->value = f;
pd->set = Primitive::emptyValue();
- o->__defineOwnProperty__(scope.engine, prop, pd, Attr_Accessor);
+ bool ok = o->__defineOwnProperty__(scope.engine, prop, pd, Attr_Accessor);
+ if (!ok)
+ THROW_TYPE_ERROR();
RETURN_UNDEFINED();
}
-void ObjectPrototype::method_defineSetter(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ObjectPrototype::method_defineSetter(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- if (callData->argc < 2)
+ Scope scope(b);
+ if (argc < 2)
THROW_TYPE_ERROR();
- ScopedFunctionObject f(scope, callData->argument(1));
+ ScopedFunctionObject f(scope, argv[1]);
if (!f)
THROW_TYPE_ERROR();
- ScopedString prop(scope, callData->argument(0), ScopedString::Convert);
- CHECK_EXCEPTION();
+ ScopedString prop(scope, argv[0], ScopedString::Convert);
+ if (scope.engine->hasException)
+ return QV4::Encode::undefined();
- ScopedObject o(scope, callData->thisObject);
+ ScopedObject o(scope, thisObject);
if (!o) {
- if (!callData->thisObject.isUndefined())
+ if (!thisObject->isUndefined())
RETURN_UNDEFINED();
o = scope.engine->globalObject;
}
@@ -525,31 +614,35 @@ void ObjectPrototype::method_defineSetter(const BuiltinFunction *, Scope &scope,
ScopedProperty pd(scope);
pd->value = Primitive::emptyValue();
pd->set = f;
- o->__defineOwnProperty__(scope.engine, prop, pd, Attr_Accessor);
+ bool ok = o->__defineOwnProperty__(scope.engine, prop, pd, Attr_Accessor);
+ if (!ok)
+ THROW_TYPE_ERROR();
RETURN_UNDEFINED();
}
-void ObjectPrototype::method_get_proto(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ObjectPrototype::method_get_proto(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- ScopedObject o(scope, callData->thisObject.as<Object>());
+ Scope scope(b);
+ ScopedObject o(scope, thisObject->as<Object>());
if (!o)
THROW_TYPE_ERROR();
- scope.result = o->prototype();
+ return Encode(o->prototype());
}
-void ObjectPrototype::method_set_proto(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ObjectPrototype::method_set_proto(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- ScopedObject o(scope, callData->thisObject);
- if (!o || !callData->argc)
+ Scope scope(b);
+ ScopedObject o(scope, thisObject);
+ if (!o || !argc)
THROW_TYPE_ERROR();
- if (callData->args[0].isNull()) {
+ if (argv[0].isNull()) {
o->setPrototype(0);
RETURN_UNDEFINED();
}
- ScopedObject p(scope, callData->args[0]);
+ ScopedObject p(scope, argv[0]);
bool ok = false;
if (!!p) {
if (o->prototype() == p->d()) {
@@ -558,10 +651,8 @@ void ObjectPrototype::method_set_proto(const BuiltinFunction *, Scope &scope, Ca
ok = o->setPrototype(p);
}
}
- if (!ok) {
- scope.result = scope.engine->throwTypeError(QStringLiteral("Cyclic __proto__ value"));
- return;
- }
+ if (!ok)
+ return scope.engine->throwTypeError(QStringLiteral("Cyclic __proto__ value"));
RETURN_UNDEFINED();
}
@@ -670,12 +761,12 @@ ReturnedValue ObjectPrototype::fromPropertyDescriptor(ExecutionEngine *engine, c
return o.asReturnedValue();
}
-
+// es6: GetOwnPropertyKeys
Heap::ArrayObject *ObjectPrototype::getOwnPropertyNames(ExecutionEngine *v4, const Value &o)
{
Scope scope(v4);
ScopedArrayObject array(scope, v4->newArrayObject());
- ScopedObject O(scope, o);
+ ScopedObject O(scope, o.toObject(v4));
if (O) {
ObjectIterator it(scope, O, ObjectIterator::NoFlags);
ScopedValue name(scope);
diff --git a/src/qml/jsruntime/qv4objectproto_p.h b/src/qml/jsruntime/qv4objectproto_p.h
index 1db8615511..2b231d46ad 100644
--- a/src/qml/jsruntime/qv4objectproto_p.h
+++ b/src/qml/jsruntime/qv4objectproto_p.h
@@ -70,40 +70,41 @@ struct ObjectCtor: FunctionObject
{
V4_OBJECT2(ObjectCtor, FunctionObject)
- static void construct(const Managed *that, Scope &scope, CallData *callData);
- static void call(const Managed *that, Scope &scope, CallData *callData);
+ static ReturnedValue callAsConstructor(const FunctionObject *f, const Value *argv, int argc);
+ static ReturnedValue call(const FunctionObject *m, const Value *thisObject, const Value *argv, int argc);
};
struct ObjectPrototype: Object
{
void init(ExecutionEngine *engine, Object *ctor);
- static void method_getPrototypeOf(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_getOwnPropertyDescriptor(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_getOwnPropertyNames(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_create(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_defineProperty(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_defineProperties(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_seal(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_freeze(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_preventExtensions(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_isSealed(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_isFrozen(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_isExtensible(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_keys(const BuiltinFunction *, Scope &scope, CallData *callData);
-
- static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_toLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_hasOwnProperty(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_isPrototypeOf(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_propertyIsEnumerable(const BuiltinFunction *, Scope &scope, CallData *callData);
-
- static void method_defineGetter(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_defineSetter(const BuiltinFunction *, Scope &scope, CallData *callData);
-
- static void method_get_proto(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_set_proto(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_getPrototypeOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_getOwnPropertyDescriptor(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_getOwnPropertyNames(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_assign(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_create(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_defineProperty(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_defineProperties(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_seal(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_freeze(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_preventExtensions(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_isSealed(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_isFrozen(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_isExtensible(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_keys(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+
+ static ReturnedValue method_toString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_toLocaleString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_valueOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_hasOwnProperty(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_isPrototypeOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_propertyIsEnumerable(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+
+ static ReturnedValue method_defineGetter(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_defineSetter(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+
+ static ReturnedValue method_get_proto(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_set_proto(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
static void toPropertyDescriptor(ExecutionEngine *engine, const Value &v, Property *desc, PropertyAttributes *attrs);
static ReturnedValue fromPropertyDescriptor(ExecutionEngine *engine, const Property *desc, PropertyAttributes attrs);
diff --git a/src/qml/jsruntime/qv4persistent.cpp b/src/qml/jsruntime/qv4persistent.cpp
index 75f7c95dde..973541553a 100644
--- a/src/qml/jsruntime/qv4persistent.cpp
+++ b/src/qml/jsruntime/qv4persistent.cpp
@@ -232,26 +232,15 @@ void PersistentValueStorage::free(Value *v)
freePage(p);
}
-static void drainMarkStack(QV4::ExecutionEngine *engine, Value *markBase)
+void PersistentValueStorage::mark(MarkStack *markStack)
{
- while (engine->jsStackTop > markBase) {
- Heap::Base *h = engine->popForGC();
- Q_ASSERT (h->vtable()->markObjects);
- h->vtable()->markObjects(h, engine);
- }
-}
-
-void PersistentValueStorage::mark(ExecutionEngine *e)
-{
- Value *markBase = e->jsStackTop;
-
Page *p = static_cast<Page *>(firstPage);
while (p) {
for (int i = 0; i < kEntriesPerPage; ++i) {
if (Managed *m = p->values[i].as<Managed>())
- m->mark(e);
+ m->mark(markStack);
}
- drainMarkStack(e, markBase);
+ markStack->drain();
p = p->header.next;
}
@@ -407,11 +396,11 @@ void WeakValue::allocVal(ExecutionEngine *engine)
val = engine->memoryManager->m_weakValues->allocate();
}
-void WeakValue::markOnce(ExecutionEngine *e)
+void WeakValue::markOnce(MarkStack *markStack)
{
if (!val)
return;
- val->mark(e);
+ val->mark(markStack);
}
void WeakValue::free()
diff --git a/src/qml/jsruntime/qv4persistent_p.h b/src/qml/jsruntime/qv4persistent_p.h
index c1cd1f34df..1f838f5531 100644
--- a/src/qml/jsruntime/qv4persistent_p.h
+++ b/src/qml/jsruntime/qv4persistent_p.h
@@ -65,7 +65,7 @@ struct Q_QML_EXPORT PersistentValueStorage
Value *allocate();
static void free(Value *e);
- void mark(ExecutionEngine *e);
+ void mark(MarkStack *markStack);
struct Iterator {
Iterator(void *p, int idx);
@@ -203,7 +203,7 @@ public:
bool isNullOrUndefined() const { return !val || val->isNullOrUndefined(); }
void clear() { free(); }
- void markOnce(ExecutionEngine *e);
+ void markOnce(MarkStack *markStack);
private:
Value *val;
diff --git a/src/qml/jsruntime/qv4profiling_p.h b/src/qml/jsruntime/qv4profiling_p.h
index 08b4ba6c76..c69d1e4cf6 100644
--- a/src/qml/jsruntime/qv4profiling_p.h
+++ b/src/qml/jsruntime/qv4profiling_p.h
@@ -57,17 +57,20 @@
#include <QElapsedTimer>
-#ifdef QT_NO_QML_DEBUGGER
+#if !QT_CONFIG(qml_debug)
#define Q_V4_PROFILE_ALLOC(engine, size, type) (!engine)
#define Q_V4_PROFILE_DEALLOC(engine, size, type) (!engine)
-#define Q_V4_PROFILE(engine, function) (function->code(engine, function->codeData))
QT_BEGIN_NAMESPACE
namespace QV4 {
namespace Profiling {
class Profiler {};
+class FunctionCallProfiler {
+public:
+ FunctionCallProfiler(ExecutionEngine *, Function *) {}
+};
}
}
@@ -85,12 +88,6 @@ QT_END_NAMESPACE
(engine->profiler()->featuresEnabled & (1 << Profiling::FeatureMemoryAllocation)) ?\
engine->profiler()->trackDealloc(size, type) : false)
-#define Q_V4_PROFILE(engine, function)\
- (Q_UNLIKELY(engine->profiler()) &&\
- (engine->profiler()->featuresEnabled & (1 << Profiling::FeatureFunctionCall)) ?\
- Profiling::FunctionCallProfiler::profileCall(engine->profiler(), engine, function) :\
- function->code(engine, function->codeData))
-
QT_BEGIN_NAMESPACE
namespace QV4 {
@@ -278,19 +275,21 @@ public:
// It's enough to ref() the function in the destructor as it will probably not disappear while
// it's executing ...
- FunctionCallProfiler(Profiler *profiler, Function *function) :
- profiler(profiler), function(function), startTime(profiler->m_timer.nsecsElapsed())
- {}
-
- ~FunctionCallProfiler()
+ FunctionCallProfiler(ExecutionEngine *engine, Function *f)
+ : profiler(0)
{
- profiler->m_data.append(FunctionCall(function, startTime, profiler->m_timer.nsecsElapsed()));
+ Profiler *p = engine->profiler();
+ if (Q_UNLIKELY(p) && (p->featuresEnabled & (1 << Profiling::FeatureFunctionCall))) {
+ profiler = p;
+ function = f;
+ startTime = profiler->m_timer.nsecsElapsed();
+ }
}
- static ReturnedValue profileCall(Profiler *profiler, ExecutionEngine *engine, Function *function)
+ ~FunctionCallProfiler()
{
- FunctionCallProfiler callProfiler(profiler, function);
- return function->code(engine, function->codeData);
+ if (profiler)
+ profiler->m_data.append(FunctionCall(function, startTime, profiler->m_timer.nsecsElapsed()));
}
Profiler *profiler;
@@ -313,6 +312,6 @@ Q_DECLARE_METATYPE(QV4::Profiling::FunctionLocationHash)
Q_DECLARE_METATYPE(QVector<QV4::Profiling::FunctionCallProperties>)
Q_DECLARE_METATYPE(QVector<QV4::Profiling::MemoryAllocationProperties>)
-#endif // QT_NO_QML_DEBUGGER
+#endif // QT_CONFIG(qml_debug)
#endif // QV4PROFILING_H
diff --git a/src/qml/jsruntime/qv4property_p.h b/src/qml/jsruntime/qv4property_p.h
index 5069d7690b..2a5b6f7f74 100644
--- a/src/qml/jsruntime/qv4property_p.h
+++ b/src/qml/jsruntime/qv4property_p.h
@@ -78,12 +78,6 @@ struct Property {
attrs->resolve();
}
- static Property genericDescriptor() {
- Property pd;
- pd.value = Primitive::emptyValue();
- return pd;
- }
-
inline bool isSubset(const PropertyAttributes &attrs, const Property *other, PropertyAttributes otherAttrs) const;
inline void merge(PropertyAttributes &attrs, const Property *other, PropertyAttributes otherAttrs);
@@ -99,19 +93,12 @@ struct Property {
}
explicit Property() { value = Encode::undefined(); set = Value::fromHeapObject(0); }
- explicit Property(Value v) : value(v) { set = Value::fromHeapObject(0); }
- Property(FunctionObject *getter, FunctionObject *setter) {
- value = reinterpret_cast<Managed *>(getter);
- set = reinterpret_cast<Managed *>(setter);
- }
Property(Heap::FunctionObject *getter, Heap::FunctionObject *setter) {
value.setM(reinterpret_cast<Heap::Base *>(getter));
set.setM(reinterpret_cast<Heap::Base *>(setter));
}
- Property &operator=(Value v) { value = v; return *this; }
private:
- Property(const Property &);
- Property &operator=(const Property &);
+ Q_DISABLE_COPY(Property)
};
inline bool Property::isSubset(const PropertyAttributes &attrs, const Property *other, PropertyAttributes otherAttrs) const
diff --git a/src/qml/jsruntime/qv4qmlcontext.cpp b/src/qml/jsruntime/qv4qmlcontext.cpp
index c7254e5989..cf4ef68bc0 100644
--- a/src/qml/jsruntime/qv4qmlcontext.cpp
+++ b/src/qml/jsruntime/qv4qmlcontext.cpp
@@ -59,10 +59,10 @@ QT_BEGIN_NAMESPACE
using namespace QV4;
-DEFINE_OBJECT_VTABLE(QmlContextWrapper);
+DEFINE_OBJECT_VTABLE(QQmlContextWrapper);
DEFINE_MANAGED_VTABLE(QmlContext);
-void Heap::QmlContextWrapper::init(QQmlContextData *context, QObject *scopeObject)
+void Heap::QQmlContextWrapper::init(QQmlContextData *context, QObject *scopeObject)
{
Object::init();
readOnly = true;
@@ -71,17 +71,17 @@ void Heap::QmlContextWrapper::init(QQmlContextData *context, QObject *scopeObjec
this->scopeObject.init(scopeObject);
}
-void Heap::QmlContextWrapper::destroy()
+void Heap::QQmlContextWrapper::destroy()
{
delete context;
scopeObject.destroy();
Object::destroy();
}
-ReturnedValue QmlContextWrapper::get(const Managed *m, String *name, bool *hasProperty)
+ReturnedValue QQmlContextWrapper::get(const Managed *m, String *name, bool *hasProperty)
{
- Q_ASSERT(m->as<QmlContextWrapper>());
- const QmlContextWrapper *resource = static_cast<const QmlContextWrapper *>(m);
+ Q_ASSERT(m->as<QQmlContextWrapper>());
+ const QQmlContextWrapper *resource = static_cast<const QQmlContextWrapper *>(m);
QV4::ExecutionEngine *v4 = resource->engine();
QV4::Scope scope(v4);
@@ -108,8 +108,8 @@ ReturnedValue QmlContextWrapper::get(const Managed *m, String *name, bool *hasPr
return result->asReturnedValue();
}
- // Its possible we could delay the calculation of the "actual" context (in the case
- // of sub contexts) until it is definately needed.
+ // It's possible we could delay the calculation of the "actual" context (in the case
+ // of sub contexts) until it is definitely needed.
QQmlContextData *context = resource->getContext();
QQmlContextData *expressionContext = context;
@@ -131,7 +131,7 @@ ReturnedValue QmlContextWrapper::get(const Managed *m, String *name, bool *hasPr
if (context->imports && name->startsWithUpper()) {
// Search for attached properties, enums and imported scripts
- QQmlTypeNameCache::Result r = context->imports->query(name);
+ QQmlTypeNameCache::Result r = context->imports->query(name, QQmlImport::AllowRecursion);
if (r.isValid()) {
if (hasProperty)
@@ -142,9 +142,9 @@ ReturnedValue QmlContextWrapper::get(const Managed *m, String *name, bool *hasPr
return scripts->getIndexed(r.scriptIndex);
return QV4::Encode::null();
} else if (r.type.isValid()) {
- return QmlTypeWrapper::create(v4, scopeObject, r.type);
+ return QQmlTypeWrapper::create(v4, scopeObject, r.type);
} else if (r.importNamespace) {
- return QmlTypeWrapper::create(v4, scopeObject, context->imports, r.importNamespace);
+ return QQmlTypeWrapper::create(v4, scopeObject, context->imports, r.importNamespace);
}
Q_ASSERT(!"Unreachable");
}
@@ -156,7 +156,7 @@ ReturnedValue QmlContextWrapper::get(const Managed *m, String *name, bool *hasPr
while (context) {
// Search context properties
- const QV4::IdentifierHash<int> &properties = context->propertyNames();
+ const QV4::IdentifierHash &properties = context->propertyNames();
if (properties.count()) {
int propertyIdx = properties.value(name);
@@ -224,21 +224,19 @@ ReturnedValue QmlContextWrapper::get(const Managed *m, String *name, bool *hasPr
return Encode::undefined();
}
-void QmlContextWrapper::put(Managed *m, String *name, const Value &value)
+bool QQmlContextWrapper::put(Managed *m, String *name, const Value &value)
{
- Q_ASSERT(m->as<QmlContextWrapper>());
- QmlContextWrapper *resource = static_cast<QmlContextWrapper *>(m);
+ Q_ASSERT(m->as<QQmlContextWrapper>());
+ QQmlContextWrapper *resource = static_cast<QQmlContextWrapper *>(m);
ExecutionEngine *v4 = resource->engine();
QV4::Scope scope(v4);
if (scope.hasException())
- return;
- QV4::Scoped<QmlContextWrapper> wrapper(scope, resource);
+ return false;
+ QV4::Scoped<QQmlContextWrapper> wrapper(scope, resource);
uint member = wrapper->internalClass()->find(name);
- if (member < UINT_MAX) {
- wrapper->putValue(member, value);
- return;
- }
+ if (member < UINT_MAX)
+ return wrapper->putValue(member, value);
if (wrapper->d()->isNullWrapper) {
if (wrapper && wrapper->d()->readOnly) {
@@ -246,41 +244,40 @@ void QmlContextWrapper::put(Managed *m, String *name, const Value &value)
QLatin1Char('"');
ScopedString e(scope, v4->newString(error));
v4->throwError(e);
- return;
+ return false;
}
- Object::put(m, name, value);
- return;
+ return Object::put(m, name, value);
}
- // Its possible we could delay the calculation of the "actual" context (in the case
- // of sub contexts) until it is definately needed.
+ // It's possible we could delay the calculation of the "actual" context (in the case
+ // of sub contexts) until it is definitely needed.
QQmlContextData *context = wrapper->getContext();
QQmlContextData *expressionContext = context;
if (!context)
- return;
+ return false;
// See QV8ContextWrapper::Getter for resolution order
QObject *scopeObject = wrapper->getScopeObject();
while (context) {
- const QV4::IdentifierHash<int> &properties = context->propertyNames();
+ const QV4::IdentifierHash &properties = context->propertyNames();
// Search context properties
if (properties.count() && properties.value(name) != -1)
- return;
+ return false;
// Search scope object
if (scopeObject &&
QV4::QObjectWrapper::setQmlProperty(v4, context, scopeObject, name, QV4::QObjectWrapper::CheckRevision, value))
- return;
+ return true;
scopeObject = 0;
// Search context object
if (context->contextObject &&
QV4::QObjectWrapper::setQmlProperty(v4, context, context->contextObject, name, QV4::QObjectWrapper::CheckRevision, value))
- return;
+ return true;
context = context->parent;
}
@@ -291,23 +288,18 @@ void QmlContextWrapper::put(Managed *m, String *name, const Value &value)
QString error = QLatin1String("Invalid write to global property \"") + name->toQString() +
QLatin1Char('"');
v4->throwError(error);
- return;
+ return false;
}
- Object::put(m, name, value);
+ return Object::put(m, name, value);
}
-void Heap::QmlContext::init(QV4::ExecutionContext *outerContext, QV4::QmlContextWrapper *qml)
+void Heap::QmlContext::init(QV4::ExecutionContext *outerContext, QV4::QQmlContextWrapper *qml)
{
Heap::ExecutionContext::init(Heap::ExecutionContext::Type_QmlContext);
- outer = outerContext->d();
- strictMode = false;
- callData = outer->callData;
- lookups = outer->lookups;
- constantTable = outer->constantTable;
- compilationUnit = outer->compilationUnit;
-
- this->qml = qml->d();
+ outer.set(internalClass->engine, outerContext->d());
+
+ this->activation.set(internalClass->engine, qml->d());
}
Heap::QmlContext *QmlContext::createWorkerContext(ExecutionContext *parent, const QUrl &source, Value *sendFunction)
@@ -320,7 +312,7 @@ Heap::QmlContext *QmlContext::createWorkerContext(ExecutionContext *parent, cons
context->isInternal = true;
context->isJSContext = true;
- Scoped<QmlContextWrapper> qml(scope, scope.engine->memoryManager->allocObject<QmlContextWrapper>(context, (QObject*)0));
+ Scoped<QQmlContextWrapper> qml(scope, scope.engine->memoryManager->allocObject<QQmlContextWrapper>(context, (QObject*)0));
qml->d()->isNullWrapper = true;
qml->setReadOnly(false);
@@ -338,7 +330,7 @@ Heap::QmlContext *QmlContext::create(ExecutionContext *parent, QQmlContextData *
{
Scope scope(parent);
- Scoped<QmlContextWrapper> qml(scope, scope.engine->memoryManager->allocObject<QmlContextWrapper>(context, scopeObject));
+ Scoped<QQmlContextWrapper> qml(scope, scope.engine->memoryManager->allocObject<QQmlContextWrapper>(context, scopeObject));
Heap::QmlContext *c = scope.engine->memoryManager->alloc<QmlContext>(parent, qml);
Q_ASSERT(c->vtable() == staticVTable());
return c;
diff --git a/src/qml/jsruntime/qv4qmlcontext_p.h b/src/qml/jsruntime/qv4qmlcontext_p.h
index 8ef7356f4c..647bef7fc1 100644
--- a/src/qml/jsruntime/qv4qmlcontext_p.h
+++ b/src/qml/jsruntime/qv4qmlcontext_p.h
@@ -62,11 +62,11 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
-struct QmlContextWrapper;
+struct QQmlContextWrapper;
namespace Heap {
-struct QmlContextWrapper : Object {
+struct QQmlContextWrapper : Object {
void init(QQmlContextData *context, QObject *scopeObject);
void destroy();
bool readOnly;
@@ -76,17 +76,20 @@ struct QmlContextWrapper : Object {
QQmlQPointer<QObject> scopeObject;
};
-struct QmlContext : ExecutionContext {
- void init(QV4::ExecutionContext *outerContext, QV4::QmlContextWrapper *qml);
+#define QmlContextMembers(class, Member)
- Pointer<QmlContextWrapper> qml;
+DECLARE_HEAP_OBJECT(QmlContext, ExecutionContext) {
+ DECLARE_MARKOBJECTS(QmlContext);
+
+ QQmlContextWrapper *qml() { return static_cast<QQmlContextWrapper *>(activation.get()); }
+ void init(QV4::ExecutionContext *outerContext, QV4::QQmlContextWrapper *qml);
};
}
-struct Q_QML_EXPORT QmlContextWrapper : Object
+struct Q_QML_EXPORT QQmlContextWrapper : Object
{
- V4_OBJECT2(QmlContextWrapper, Object)
+ V4_OBJECT2(QQmlContextWrapper, Object)
V4_NEEDS_DESTROY
V4_INTERNALCLASS(QmlContextWrapper)
@@ -96,7 +99,7 @@ struct Q_QML_EXPORT QmlContextWrapper : Object
void setReadOnly(bool b) { d()->readOnly = b; }
static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
- static void put(Managed *m, String *name, const Value &value);
+ static bool put(Managed *m, String *name, const Value &value);
};
struct Q_QML_EXPORT QmlContext : public ExecutionContext
@@ -108,10 +111,10 @@ struct Q_QML_EXPORT QmlContext : public ExecutionContext
static Heap::QmlContext *create(QV4::ExecutionContext *parent, QQmlContextData *context, QObject *scopeObject);
QObject *qmlScope() const {
- return d()->qml->scopeObject;
+ return d()->qml()->scopeObject;
}
QQmlContextData *qmlContext() const {
- return *d()->qml->context;
+ return *d()->qml()->context;
}
};
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 89c10e0995..9ee357eca5 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -62,6 +62,7 @@
#include <private/qv4regexpobject_p.h>
#include <private/qv4dateobject_p.h>
#include <private/qv4scopedvalue_p.h>
+#include <private/qv4jscall_p.h>
#include <private/qv4mm_p.h>
#include <private/qqmlscriptstring_p.h>
#include <private/qv4compileddata_p.h>
@@ -74,9 +75,14 @@
#include <QtCore/qtimer.h>
#include <QtCore/qatomic.h>
#include <QtCore/qmetaobject.h>
+#include <QtCore/qabstractitemmodel.h>
+#include <QtCore/qloggingcategory.h>
+#include <vector>
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcBindingRemoval, "qt.qml.binding.removal", QtWarningMsg)
+
// The code in this file does not violate strict aliasing, but GCC thinks it does
// so turn off the warnings for us to have a clean build
QT_WARNING_DISABLE_GCC("-Wstrict-aliasing")
@@ -202,19 +208,61 @@ void QObjectWrapper::initializeBindings(ExecutionEngine *engine)
QQmlPropertyData *QObjectWrapper::findProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local) const
{
+ QObject *o = d()->object();
+ return findProperty(engine, o, qmlContext, name, revisionMode, local);
+}
+
+QQmlPropertyData *QObjectWrapper::findProperty(ExecutionEngine *engine, QObject *o, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local)
+{
Q_UNUSED(revisionMode);
- QQmlData *ddata = QQmlData::get(d()->object(), false);
- if (!ddata)
- return 0;
+ QQmlData *ddata = QQmlData::get(o, false);
QQmlPropertyData *result = 0;
if (ddata && ddata->propertyCache)
- result = ddata->propertyCache->property(name, d()->object(), qmlContext);
+ result = ddata->propertyCache->property(name, o, qmlContext);
else
- result = QQmlPropertyCache::property(engine->jsEngine(), d()->object(), name, qmlContext, *local);
+ result = QQmlPropertyCache::property(engine->jsEngine(), o, name, qmlContext, *local);
return result;
}
+ReturnedValue QObjectWrapper::getProperty(ExecutionEngine *engine, QObject *object, QQmlPropertyData *property, bool captureRequired)
+{
+ QQmlData::flushPendingBinding(object, QQmlPropertyIndex(property->coreIndex()));
+
+ if (property->isFunction() && !property->isVarProperty()) {
+ if (property->isVMEFunction()) {
+ QQmlVMEMetaObject *vmemo = QQmlVMEMetaObject::get(object);
+ Q_ASSERT(vmemo);
+ return vmemo->vmeMethod(property->coreIndex());
+ } else if (property->isV4Function()) {
+ Scope scope(engine);
+ ScopedContext global(scope, engine->qmlContext());
+ if (!global)
+ global = engine->rootContext();
+ return QV4::QObjectMethod::create(global, object, property->coreIndex());
+ } else if (property->isSignalHandler()) {
+ QmlSignalHandler::initProto(engine);
+ return engine->memoryManager->allocObject<QV4::QmlSignalHandler>(object, property->coreIndex())->asReturnedValue();
+ } else {
+ ExecutionContext *global = engine->rootContext();
+ return QV4::QObjectMethod::create(global, object, property->coreIndex());
+ }
+ }
+
+ QQmlEnginePrivate *ep = engine->qmlEngine() ? QQmlEnginePrivate::get(engine->qmlEngine()) : 0;
+
+ if (captureRequired && ep && ep->propertyCapture && !property->isConstant())
+ ep->propertyCapture->captureProperty(object, property->coreIndex(), property->notifyIndex());
+
+ if (property->isVarProperty()) {
+ QQmlVMEMetaObject *vmemo = QQmlVMEMetaObject::get(object);
+ Q_ASSERT(vmemo);
+ return vmemo->vmeProperty(property->coreIndex());
+ } else {
+ return loadProperty(engine, object, *property);
+ }
+}
+
ReturnedValue QObjectWrapper::getQmlProperty(QQmlContextData *qmlContext, String *name, QObjectWrapper::RevisionMode revisionMode,
bool *hasProperty, bool includeImports) const
{
@@ -250,11 +298,11 @@ ReturnedValue QObjectWrapper::getQmlProperty(QQmlContextData *qmlContext, String
if (r.scriptIndex != -1) {
return QV4::Encode::undefined();
} else if (r.type.isValid()) {
- return QmlTypeWrapper::create(v4, d()->object(),
- r.type, Heap::QmlTypeWrapper::ExcludeEnums);
+ return QQmlTypeWrapper::create(v4, d()->object(),
+ r.type, Heap::QQmlTypeWrapper::ExcludeEnums);
} else if (r.importNamespace) {
- return QmlTypeWrapper::create(v4, d()->object(),
- qmlContext->imports, r.importNamespace, Heap::QmlTypeWrapper::ExcludeEnums);
+ return QQmlTypeWrapper::create(v4, d()->object(),
+ qmlContext->imports, r.importNamespace, Heap::QQmlTypeWrapper::ExcludeEnums);
}
Q_ASSERT(!"Unreachable");
}
@@ -279,42 +327,19 @@ ReturnedValue QObjectWrapper::getQmlProperty(QQmlContextData *qmlContext, String
return getProperty(v4, d()->object(), result);
}
-ReturnedValue QObjectWrapper::getProperty(ExecutionEngine *engine, QObject *object, QQmlPropertyData *property, bool captureRequired)
+ReturnedValue QObjectWrapper::getProperty(ExecutionEngine *engine, QObject *object, int propertyIndex, bool captureRequired)
{
- QQmlData::flushPendingBinding(object, QQmlPropertyIndex(property->coreIndex()));
-
- if (property->isFunction() && !property->isVarProperty()) {
- if (property->isVMEFunction()) {
- QQmlVMEMetaObject *vmemo = QQmlVMEMetaObject::get(object);
- Q_ASSERT(vmemo);
- return vmemo->vmeMethod(property->coreIndex());
- } else if (property->isV4Function()) {
- Scope scope(engine);
- ScopedContext global(scope, engine->qmlContext());
- if (!global)
- global = engine->rootContext();
- return QV4::QObjectMethod::create(global, object, property->coreIndex());
- } else if (property->isSignalHandler()) {
- QmlSignalHandler::initProto(engine);
- return engine->memoryManager->allocObject<QV4::QmlSignalHandler>(object, property->coreIndex())->asReturnedValue();
- } else {
- ExecutionContext *global = engine->rootContext();
- return QV4::QObjectMethod::create(global, object, property->coreIndex());
- }
- }
-
- QQmlEnginePrivate *ep = engine->qmlEngine() ? QQmlEnginePrivate::get(engine->qmlEngine()) : 0;
-
- if (captureRequired && ep && ep->propertyCapture && !property->isConstant())
- ep->propertyCapture->captureProperty(object, property->coreIndex(), property->notifyIndex());
+ if (QQmlData::wasDeleted(object))
+ return QV4::Encode::null();
+ QQmlData *ddata = QQmlData::get(object, /*create*/false);
+ if (!ddata)
+ return QV4::Encode::undefined();
- if (property->isVarProperty()) {
- QQmlVMEMetaObject *vmemo = QQmlVMEMetaObject::get(object);
- Q_ASSERT(vmemo);
- return vmemo->vmeProperty(property->coreIndex());
- } else {
- return loadProperty(engine, object, *property);
- }
+ QQmlPropertyCache *cache = ddata->propertyCache;
+ Q_ASSERT(cache);
+ QQmlPropertyData *property = cache->property(propertyIndex);
+ Q_ASSERT(property); // We resolved this property earlier, so it better exist!
+ return getProperty(engine, object, property, captureRequired);
}
ReturnedValue QObjectWrapper::getQmlProperty(QV4::ExecutionEngine *engine, QQmlContextData *qmlContext, QObject *object, String *name, QObjectWrapper::RevisionMode revisionMode, bool *hasProperty)
@@ -325,12 +350,49 @@ ReturnedValue QObjectWrapper::getQmlProperty(QV4::ExecutionEngine *engine, QQmlC
return QV4::Encode::null();
}
- if (!QQmlData::get(object, true)) {
+ if (name->equals(engine->id_destroy()) || name->equals(engine->id_toString())) {
+ int index = name->equals(engine->id_destroy()) ? QV4::QObjectMethod::DestroyMethod : QV4::QObjectMethod::ToStringMethod;
if (hasProperty)
- *hasProperty = false;
- return QV4::Encode::null();
+ *hasProperty = true;
+ ExecutionContext *global = engine->rootContext();
+ return QV4::QObjectMethod::create(global, object, index);
}
+ QQmlData *ddata = QQmlData::get(object, false);
+ QQmlPropertyData local;
+ QQmlPropertyData *result = findProperty(engine, object, qmlContext, name, revisionMode, &local);
+
+ if (result) {
+ if (revisionMode == QV4::QObjectWrapper::CheckRevision && result->hasRevision()) {
+ if (ddata && ddata->propertyCache && !ddata->propertyCache->isAllowedInRevision(result)) {
+ if (hasProperty)
+ *hasProperty = false;
+ return QV4::Encode::undefined();
+ }
+ }
+
+ if (hasProperty)
+ *hasProperty = true;
+
+ return getProperty(engine, object, result);
+ } else {
+ // Check if this object is already wrapped.
+ if (!ddata || (ddata->jsWrapper.isUndefined() &&
+ (ddata->jsEngineId == 0 || // Nobody owns the QObject
+ !ddata->hasTaintedV4Object))) { // Someone else has used the QObject, but it isn't tainted
+
+ // Not wrapped. Last chance: try query QObjectWrapper's prototype.
+ // If it can't handle this, then there is no point
+ // to wrap the QObject just to look at an empty set of JS props.
+ QV4::Object *proto = QObjectWrapper::defaultPrototype(engine);
+ return proto->get(name, hasProperty);
+ }
+ }
+
+ // If we get here, we must already be wrapped (which implies a ddata).
+ // There's no point wrapping again, as there wouldn't be any new props.
+ Q_ASSERT(ddata);
+
QV4::Scope scope(engine);
QV4::Scoped<QObjectWrapper> wrapper(scope, wrap(engine, object));
if (!wrapper) {
@@ -341,6 +403,7 @@ ReturnedValue QObjectWrapper::getQmlProperty(QV4::ExecutionEngine *engine, QQmlC
return wrapper->getQmlProperty(qmlContext, name, revisionMode, hasProperty);
}
+
bool QObjectWrapper::setQmlProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, QObject *object, String *name,
QObjectWrapper::RevisionMode revisionMode, const Value &value)
{
@@ -399,10 +462,23 @@ void QObjectWrapper::setProperty(ExecutionEngine *engine, QObject *object, QQmlP
}
}
- if (newBinding)
+ if (newBinding) {
QQmlPropertyPrivate::setBinding(newBinding);
- else
+ } else {
+ if (Q_UNLIKELY(lcBindingRemoval().isInfoEnabled())) {
+ if (auto binding = QQmlPropertyPrivate::binding(object, QQmlPropertyIndex(property->coreIndex()))) {
+ Q_ASSERT(!binding->isValueTypeProxy());
+ const auto qmlBinding = static_cast<const QQmlBinding*>(binding);
+ const auto stackFrame = engine->currentStackFrame;
+ qCInfo(lcBindingRemoval,
+ "Overwriting binding on %s::%s at %s:%d that was initially bound at %s",
+ object->metaObject()->className(), qPrintable(property->name(object)),
+ qPrintable(stackFrame->source()), stackFrame->lineNumber(),
+ qPrintable(qmlBinding->expressionIdentifier()));
+ }
+ }
QQmlPropertyPrivate::removeBinding(object, QQmlPropertyIndex(property->coreIndex()));
+ }
if (!newBinding && property->isVarProperty()) {
// allow assignment of "special" values (null, undefined, function) to var properties
@@ -539,7 +615,7 @@ ReturnedValue QObjectWrapper::wrap_slowPath(ExecutionEngine *engine, QObject *ob
}
}
-void QObjectWrapper::markWrapper(QObject *object, ExecutionEngine *engine)
+void QObjectWrapper::markWrapper(QObject *object, MarkStack *markStack)
{
if (QQmlData::wasDeleted(object))
return;
@@ -548,25 +624,10 @@ void QObjectWrapper::markWrapper(QObject *object, ExecutionEngine *engine)
if (!ddata)
return;
- if (ddata->jsEngineId == engine->m_engineId)
- ddata->jsWrapper.markOnce(engine);
- else if (engine->m_multiplyWrappedQObjects && ddata->hasTaintedV4Object)
- engine->m_multiplyWrappedQObjects->mark(object, engine);
-}
-
-ReturnedValue QObjectWrapper::getProperty(ExecutionEngine *engine, QObject *object, int propertyIndex, bool captureRequired)
-{
- if (QQmlData::wasDeleted(object))
- return QV4::Encode::null();
- QQmlData *ddata = QQmlData::get(object, /*create*/false);
- if (!ddata)
- return QV4::Encode::undefined();
-
- QQmlPropertyCache *cache = ddata->propertyCache;
- Q_ASSERT(cache);
- QQmlPropertyData *property = cache->property(propertyIndex);
- Q_ASSERT(property); // We resolved this property earlier, so it better exist!
- return getProperty(engine, object, property, captureRequired);
+ if (ddata->jsEngineId == markStack->engine->m_engineId)
+ ddata->jsWrapper.markOnce(markStack);
+ else if (markStack->engine->m_multiplyWrappedQObjects && ddata->hasTaintedV4Object)
+ markStack->engine->m_multiplyWrappedQObjects->mark(object, markStack);
}
void QObjectWrapper::setProperty(ExecutionEngine *engine, int propertyIndex, const Value &value)
@@ -598,7 +659,7 @@ bool QObjectWrapper::isEqualTo(Managed *a, Managed *b)
QV4::QObjectWrapper *qobjectWrapper = static_cast<QV4::QObjectWrapper *>(a);
QV4::Object *o = b->as<Object>();
if (o) {
- if (QV4::QmlTypeWrapper *qmlTypeWrapper = o->as<QV4::QmlTypeWrapper>())
+ if (QV4::QQmlTypeWrapper *qmlTypeWrapper = o->as<QV4::QQmlTypeWrapper>())
return qmlTypeWrapper->toVariant().value<QObject*>() == qobjectWrapper->object();
}
@@ -625,13 +686,13 @@ QV4::ReturnedValue QObjectWrapper::get(const Managed *m, String *name, bool *has
return that->getQmlProperty(qmlContext, name, IgnoreRevision, hasProperty, /*includeImports*/ true);
}
-void QObjectWrapper::put(Managed *m, String *name, const Value &value)
+bool QObjectWrapper::put(Managed *m, String *name, const Value &value)
{
QObjectWrapper *that = static_cast<QObjectWrapper*>(m);
ExecutionEngine *v4 = that->engine();
if (v4->hasException || QQmlData::wasDeleted(that->d()->object()))
- return;
+ return false;
QQmlContextData *qmlContext = v4->callingQmlContext();
if (!setQmlProperty(v4, qmlContext, that->d()->object(), name, QV4::QObjectWrapper::IgnoreRevision, value)) {
@@ -642,10 +703,13 @@ void QObjectWrapper::put(Managed *m, String *name, const Value &value)
QString error = QLatin1String("Cannot assign to non-existent property \"") +
name->toQString() + QLatin1Char('\"');
v4->throwError(error);
+ return false;
} else {
- QV4::Object::put(m, name, value);
+ return QV4::Object::put(m, name, value);
}
}
+
+ return true;
}
PropertyAttributes QObjectWrapper::query(const Managed *m, String *name)
@@ -756,18 +820,18 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase
QV4::Scope scope(v4);
QV4::ScopedFunctionObject f(scope, This->function.value());
- QV4::ScopedCallData callData(scope, argCount);
- callData->thisObject = This->thisObject.isUndefined() ? v4->globalObject->asReturnedValue() : This->thisObject.value();
+ QV4::JSCallData jsCallData(scope, argCount);
+ *jsCallData->thisObject = This->thisObject.isUndefined() ? v4->globalObject->asReturnedValue() : This->thisObject.value();
for (int ii = 0; ii < argCount; ++ii) {
int type = argsTypes[ii + 1];
if (type == qMetaTypeId<QVariant>()) {
- callData->args[ii] = v4->fromVariant(*((QVariant *)metaArgs[ii + 1]));
+ jsCallData->args[ii] = v4->fromVariant(*((QVariant *)metaArgs[ii + 1]));
} else {
- callData->args[ii] = v4->fromVariant(QVariant(type, metaArgs[ii + 1]));
+ jsCallData->args[ii] = v4->fromVariant(QVariant(type, metaArgs[ii + 1]));
}
}
- f->call(scope, callData);
+ f->call(jsCallData);
if (scope.hasException()) {
QQmlError error = v4->catchExceptionAsQmlError();
if (error.description().isEmpty()) {
@@ -840,12 +904,14 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase
} // namespace QV4
-void QObjectWrapper::method_connect(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QObjectWrapper::method_connect(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- if (callData->argc == 0)
+ QV4::Scope scope(b);
+
+ if (argc == 0)
THROW_GENERIC_ERROR("Function.prototype.connect: no arguments given");
- QPair<QObject *, int> signalInfo = extractQtSignal(callData->thisObject);
+ QPair<QObject *, int> signalInfo = extractQtSignal(*thisObject);
QObject *signalObject = signalInfo.first;
int signalIndex = signalInfo.second; // in method range, not signal range!
@@ -859,25 +925,25 @@ void QObjectWrapper::method_connect(const BuiltinFunction *, Scope &scope, CallD
THROW_GENERIC_ERROR("Function.prototype.connect: this object is not a signal");
QV4::ScopedFunctionObject f(scope);
- QV4::ScopedValue thisObject (scope, QV4::Encode::undefined());
+ QV4::ScopedValue object (scope, QV4::Encode::undefined());
- if (callData->argc == 1) {
- f = callData->args[0];
- } else if (callData->argc >= 2) {
- thisObject = callData->args[0];
- f = callData->args[1];
+ if (argc == 1) {
+ f = argv[0];
+ } else if (argc >= 2) {
+ object = argv[0];
+ f = argv[1];
}
if (!f)
THROW_GENERIC_ERROR("Function.prototype.connect: target is not a function");
- if (!thisObject->isUndefined() && !thisObject->isObject())
+ if (!object->isUndefined() && !object->isObject())
THROW_GENERIC_ERROR("Function.prototype.connect: target this is not an object");
QV4::QObjectSlotDispatcher *slot = new QV4::QObjectSlotDispatcher;
slot->signalIndex = signalIndex;
- slot->thisObject.set(scope.engine, thisObject);
+ slot->thisObject.set(scope.engine, object);
slot->function.set(scope.engine, f);
if (QQmlData *ddata = QQmlData::get(signalObject)) {
@@ -890,12 +956,14 @@ void QObjectWrapper::method_connect(const BuiltinFunction *, Scope &scope, CallD
RETURN_UNDEFINED();
}
-void QObjectWrapper::method_disconnect(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QObjectWrapper::method_disconnect(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- if (callData->argc == 0)
+ QV4::Scope scope(b);
+
+ if (argc == 0)
THROW_GENERIC_ERROR("Function.prototype.disconnect: no arguments given");
- QPair<QObject *, int> signalInfo = extractQtSignal(callData->thisObject);
+ QPair<QObject *, int> signalInfo = extractQtSignal(*thisObject);
QObject *signalObject = signalInfo.first;
int signalIndex = signalInfo.second;
@@ -911,11 +979,11 @@ void QObjectWrapper::method_disconnect(const BuiltinFunction *, Scope &scope, Ca
QV4::ScopedFunctionObject functionValue(scope);
QV4::ScopedValue functionThisValue(scope, QV4::Encode::undefined());
- if (callData->argc == 1) {
- functionValue = callData->args[0];
- } else if (callData->argc >= 2) {
- functionThisValue = callData->args[0];
- functionValue = callData->args[1];
+ if (argc == 1) {
+ functionValue = argv[0];
+ } else if (argc >= 2) {
+ functionThisValue = argv[0];
+ functionValue = argv[1];
}
if (!functionValue)
@@ -939,36 +1007,36 @@ void QObjectWrapper::method_disconnect(const BuiltinFunction *, Scope &scope, Ca
RETURN_UNDEFINED();
}
-static void markChildQObjectsRecursively(QObject *parent, QV4::ExecutionEngine *e)
+static void markChildQObjectsRecursively(QObject *parent, QV4::MarkStack *markStack)
{
const QObjectList &children = parent->children();
for (int i = 0; i < children.count(); ++i) {
QObject *child = children.at(i);
if (!child)
continue;
- QObjectWrapper::markWrapper(child, e);
- markChildQObjectsRecursively(child, e);
+ QObjectWrapper::markWrapper(child, markStack);
+ markChildQObjectsRecursively(child, markStack);
}
}
-void QObjectWrapper::markObjects(Heap::Base *that, QV4::ExecutionEngine *e)
+void Heap::QObjectWrapper::markObjects(Heap::Base *that, QV4::MarkStack *markStack)
{
- QObjectWrapper::Data *This = static_cast<QObjectWrapper::Data *>(that);
+ QObjectWrapper *This = static_cast<QObjectWrapper *>(that);
if (QObject *o = This->object()) {
QQmlVMEMetaObject *vme = QQmlVMEMetaObject::get(o);
if (vme)
- vme->mark(e);
+ vme->mark(markStack);
// Children usually don't need to be marked, the gc keeps them alive.
// But in the rare case of a "floating" QObject without a parent that
// _gets_ marked (we've been called here!) then we also need to
// propagate the marking down to the children recursively.
if (!o->parent())
- markChildQObjectsRecursively(o, e);
+ markChildQObjectsRecursively(o, markStack);
}
- QV4::Object::markObjects(that, e);
+ Object::markObjects(that, markStack);
}
void QObjectWrapper::destroyObject(bool lastCall)
@@ -1038,12 +1106,21 @@ private:
inline void cleanup();
+ template <class T, class M>
+ void fromContainerValue(const QV4::Object *object, int type, M CallArgument::*member, bool &queryEngine);
+
union {
float floatValue;
double doubleValue;
quint32 intValue;
bool boolValue;
QObject *qobjectPtr;
+ std::vector<int> *stdVectorIntPtr;
+ std::vector<qreal> *stdVectorRealPtr;
+ std::vector<bool> *stdVectorBoolPtr;
+ std::vector<QString> *stdVectorQStringPtr;
+ std::vector<QUrl> *stdVectorQUrlPtr;
+ std::vector<QModelIndex> *stdVectorQModelIndexPtr;
char allocData[MaxSizeOf8<QVariant,
QString,
@@ -1111,7 +1188,7 @@ static QV4::ReturnedValue CallMethod(const QQmlObjectOrGadget &object, int index
}
}
-/*!
+/*
Returns the match score for converting \a actual to be of type \a conversionType. A
zero score means "perfect match" whereas a higher score is worse.
@@ -1268,7 +1345,7 @@ static inline int QMetaObject_methods(const QMetaObject *metaObject)
return reinterpret_cast<const Private *>(metaObject->d.data)->methodCount;
}
-/*!
+/*
Returns the next related method, if one, or 0.
*/
static const QQmlPropertyData * RelatedMethod(const QQmlObjectOrGadget &object,
@@ -1344,7 +1421,7 @@ static QV4::ReturnedValue CallPrecise(const QQmlObjectOrGadget &object, const QQ
+ QLatin1String(unknownTypeError));
}
- if (args[0] > callArgs->argc) {
+ if (args[0] > callArgs->argc()) {
QString error = QLatin1String("Insufficient arguments");
return engine->throwError(error);
}
@@ -1358,7 +1435,7 @@ static QV4::ReturnedValue CallPrecise(const QQmlObjectOrGadget &object, const QQ
}
}
-/*!
+/*
Resolve the overloaded method to call. The algorithm works conceptually like this:
1. Resolve the set of overloads it is *possible* to call.
Impossible overloads include those that have too many parameters or have parameters
@@ -1375,7 +1452,7 @@ static QV4::ReturnedValue CallOverloaded(const QQmlObjectOrGadget &object, const
QV4::ExecutionEngine *engine, QV4::CallData *callArgs, const QQmlPropertyCache *propertyCache,
QMetaObject::Call callType = QMetaObject::InvokeMetaMethod)
{
- int argumentCount = callArgs->argc;
+ int argumentCount = callArgs->argc();
QQmlPropertyData best;
int bestParameterScore = INT_MAX;
@@ -1473,6 +1550,18 @@ void *CallArgument::dataPtr()
{
if (type == -1)
return qvariantPtr->data();
+ else if (type == qMetaTypeId<std::vector<int>>())
+ return stdVectorIntPtr;
+ else if (type == qMetaTypeId<std::vector<qreal>>())
+ return stdVectorRealPtr;
+ else if (type == qMetaTypeId<std::vector<bool>>())
+ return stdVectorBoolPtr;
+ else if (type == qMetaTypeId<std::vector<QString>>())
+ return stdVectorQStringPtr;
+ else if (type == qMetaTypeId<std::vector<QUrl>>())
+ return stdVectorQUrlPtr;
+ else if (type == qMetaTypeId<std::vector<QModelIndex>>())
+ return stdVectorQModelIndexPtr;
else if (type != 0)
return (void *)&allocData;
return 0;
@@ -1522,6 +1611,19 @@ void CallArgument::initAsType(int callType)
}
}
+template <class T, class M>
+void CallArgument::fromContainerValue(const QV4::Object *object, int callType, M CallArgument::*member, bool &queryEngine)
+{
+ if (object && object->isListType()) {
+ T* ptr = static_cast<T*>(QV4::SequencePrototype::getRawContainerPtr(object, callType));
+ if (ptr) {
+ (this->*member) = ptr;
+ type = callType;
+ queryEngine = false;
+ }
+ }
+}
+
void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const QV4::Value &value)
{
if (type != 0) {
@@ -1560,7 +1662,7 @@ void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q
qobjectPtr = 0;
if (const QV4::QObjectWrapper *qobjectWrapper = value.as<QV4::QObjectWrapper>())
qobjectPtr = qobjectWrapper->object();
- else if (const QV4::QmlTypeWrapper *qmlTypeWrapper = value.as<QV4::QmlTypeWrapper>())
+ else if (const QV4::QQmlTypeWrapper *qmlTypeWrapper = value.as<QV4::QQmlTypeWrapper>())
queryEngine = qmlTypeWrapper->isSingleton();
type = callType;
} else if (callType == qMetaTypeId<QVariant>()) {
@@ -1603,6 +1705,33 @@ void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q
type = callType;
} else if (callType == QMetaType::Void) {
*qvariantPtr = QVariant();
+ } else if (callType == qMetaTypeId<std::vector<int>>()
+ || callType == qMetaTypeId<std::vector<qreal>>()
+ || callType == qMetaTypeId<std::vector<bool>>()
+ || callType == qMetaTypeId<std::vector<QString>>()
+ || callType == qMetaTypeId<std::vector<QUrl>>()
+ || callType == qMetaTypeId<std::vector<QModelIndex>>()) {
+ queryEngine = true;
+ const QV4::Object* object = value.as<Object>();
+ if (callType == qMetaTypeId<std::vector<int>>()) {
+ stdVectorIntPtr = nullptr;
+ fromContainerValue<std::vector<int>>(object, callType, &CallArgument::stdVectorIntPtr, queryEngine);
+ } else if (callType == qMetaTypeId<std::vector<qreal>>()) {
+ stdVectorRealPtr = nullptr;
+ fromContainerValue<std::vector<qreal>>(object, callType, &CallArgument::stdVectorRealPtr, queryEngine);
+ } else if (callType == qMetaTypeId<std::vector<bool>>()) {
+ stdVectorBoolPtr = nullptr;
+ fromContainerValue<std::vector<bool>>(object, callType, &CallArgument::stdVectorBoolPtr, queryEngine);
+ } else if (callType == qMetaTypeId<std::vector<QString>>()) {
+ stdVectorQStringPtr = nullptr;
+ fromContainerValue<std::vector<QString>>(object, callType, &CallArgument::stdVectorQStringPtr, queryEngine);
+ } else if (callType == qMetaTypeId<std::vector<QUrl>>()) {
+ stdVectorQUrlPtr = nullptr;
+ fromContainerValue<std::vector<QUrl>>(object, callType, &CallArgument::stdVectorQUrlPtr, queryEngine);
+ } else if (callType == qMetaTypeId<std::vector<QModelIndex>>()) {
+ stdVectorQModelIndexPtr = nullptr;
+ fromContainerValue<std::vector<QModelIndex>>(object, callType, &CallArgument::stdVectorQModelIndexPtr, queryEngine);
+ }
} else {
queryEngine = true;
}
@@ -1712,7 +1841,7 @@ ReturnedValue QObjectMethod::create(ExecutionContext *scope, const QQmlValueType
Scoped<QObjectMethod> method(valueScope, valueScope.engine->memoryManager->allocObject<QObjectMethod>(scope));
method->d()->setPropertyCache(valueType->d()->propertyCache());
method->d()->index = index;
- method->d()->valueTypeWrapper = valueType->d();
+ method->d()->valueTypeWrapper.set(valueScope.engine, valueType->d());
return method.asReturnedValue();
}
@@ -1728,7 +1857,7 @@ const QMetaObject *Heap::QObjectMethod::metaObject()
return object()->metaObject();
}
-QV4::ReturnedValue QObjectMethod::method_toString(QV4::ExecutionContext *ctx) const
+QV4::ReturnedValue QObjectMethod::method_toString(QV4::ExecutionEngine *engine) const
{
QString result;
if (const QMetaObject *metaObject = d()->metaObject()) {
@@ -1747,15 +1876,15 @@ QV4::ReturnedValue QObjectMethod::method_toString(QV4::ExecutionContext *ctx) co
result = QLatin1String("null");
}
- return ctx->engine()->newString(result)->asReturnedValue();
+ return engine->newString(result)->asReturnedValue();
}
-QV4::ReturnedValue QObjectMethod::method_destroy(QV4::ExecutionContext *ctx, const Value *args, int argc) const
+QV4::ReturnedValue QObjectMethod::method_destroy(QV4::ExecutionEngine *engine, const Value *args, int argc) const
{
if (!d()->object())
return Encode::undefined();
if (QQmlData::keepAliveDuringGarbageCollection(d()->object()))
- return ctx->engine()->throwError(QStringLiteral("Invalid attempt to destroy() an indestructible object"));
+ return engine->throwError(QStringLiteral("Invalid attempt to destroy() an indestructible object"));
int delay = 0;
if (argc > 0)
@@ -1769,32 +1898,24 @@ QV4::ReturnedValue QObjectMethod::method_destroy(QV4::ExecutionContext *ctx, con
return Encode::undefined();
}
-void QObjectMethod::call(const Managed *m, Scope &scope, CallData *callData)
+ReturnedValue QObjectMethod::call(const FunctionObject *m, const Value *thisObject, const Value *argv, int argc)
{
const QObjectMethod *This = static_cast<const QObjectMethod*>(m);
- This->callInternal(callData, scope);
+ return This->callInternal(thisObject, argv, argc);
}
-void QObjectMethod::callInternal(CallData *callData, Scope &scope) const
+ReturnedValue QObjectMethod::callInternal(const Value *thisObject, const Value *argv, int argc) const
{
ExecutionEngine *v4 = engine();
- ExecutionContext *context = v4->currentContext;
- if (d()->index == DestroyMethod) {
- scope.result = method_destroy(context, callData->args, callData->argc);
- return;
- }
-
- else if (d()->index == ToStringMethod) {
- scope.result = method_toString(context);
- return;
- }
+ if (d()->index == DestroyMethod)
+ return method_destroy(v4, argv, argc);
+ else if (d()->index == ToStringMethod)
+ return method_toString(v4);
QQmlObjectOrGadget object(d()->object());
if (!d()->object()) {
- if (!d()->valueTypeWrapper) {
- scope.result = Encode::undefined();
- return;
- }
+ if (!d()->valueTypeWrapper)
+ return Encode::undefined();
object = QQmlObjectOrGadget(d()->propertyCache(), d()->valueTypeWrapper->gadgetPtr);
}
@@ -1803,20 +1924,16 @@ void QObjectMethod::callInternal(CallData *callData, Scope &scope) const
if (d()->propertyCache()) {
QQmlPropertyData *data = d()->propertyCache()->method(d()->index);
- if (!data) {
- scope.result = QV4::Encode::undefined();
- return;
- }
+ if (!data)
+ return QV4::Encode::undefined();
method = *data;
} else {
const QMetaObject *mo = d()->object()->metaObject();
const QMetaMethod moMethod = mo->method(d()->index);
method.load(moMethod);
- if (method.coreIndex() == -1) {
- scope.result = QV4::Encode::undefined();
- return;
- }
+ if (method.coreIndex() == -1)
+ return QV4::Encode::undefined();
// Look for overloaded methods
QByteArray methodName = moMethod.name();
@@ -1831,33 +1948,28 @@ void QObjectMethod::callInternal(CallData *callData, Scope &scope) const
}
}
+ Scope scope(v4);
+ JSCallData cData(scope, argc, argv, thisObject);
+ CallData *callData = cData.callData();
+
if (method.isV4Function()) {
- scope.result = QV4::Encode::undefined();
- QQmlV4Function func(callData, &scope.result, v4);
+ QV4::ScopedValue rv(scope, QV4::Primitive::undefinedValue());
+ QQmlV4Function func(callData, rv, v4);
QQmlV4Function *funcptr = &func;
void *args[] = { 0, &funcptr };
object.metacall(QMetaObject::InvokeMetaMethod, method.coreIndex(), args);
- return;
+ return rv->asReturnedValue();
}
if (!method.isOverload()) {
- scope.result = CallPrecise(object, method, v4, callData);
+ return CallPrecise(object, method, v4, callData);
} else {
- scope.result = CallOverloaded(object, method, v4, callData, d()->propertyCache());
+ return CallOverloaded(object, method, v4, callData, d()->propertyCache());
}
}
-void QObjectMethod::markObjects(Heap::Base *that, ExecutionEngine *e)
-{
- QObjectMethod::Data *This = static_cast<QObjectMethod::Data*>(that);
- if (This->valueTypeWrapper)
- This->valueTypeWrapper->mark(e);
-
- FunctionObject::markObjects(that, e);
-}
-
DEFINE_OBJECT_VTABLE(QObjectMethod);
@@ -1917,13 +2029,14 @@ void QMetaObjectWrapper::init(ExecutionEngine *) {
}
}
-void QMetaObjectWrapper::construct(const Managed *m, Scope &scope, CallData *callData)
+ReturnedValue QMetaObjectWrapper::callAsConstructor(const FunctionObject *f, const Value *argv, int argc)
{
- const QMetaObjectWrapper *This = static_cast<const QMetaObjectWrapper*>(m);
- scope.result = This->constructInternal(callData);
+ const QMetaObjectWrapper *This = static_cast<const QMetaObjectWrapper*>(f);
+ return This->constructInternal(argv, argc);
}
-ReturnedValue QMetaObjectWrapper::constructInternal(CallData * callData) const {
+ReturnedValue QMetaObjectWrapper::constructInternal(const Value *argv, int argc) const
+{
d()->ensureConstructorsCache();
@@ -1936,6 +2049,8 @@ ReturnedValue QMetaObjectWrapper::constructInternal(CallData * callData) const {
Scope scope(v4);
Scoped<QObjectWrapper> object(scope);
+ JSCallData cData(scope, argc, argv);
+ CallData *callData = cData.callData();
if (d()->constructorCount == 1) {
object = callConstructor(d()->constructors[0], v4, callData);
@@ -1960,7 +2075,7 @@ ReturnedValue QMetaObjectWrapper::callConstructor(const QQmlPropertyData &data,
ReturnedValue QMetaObjectWrapper::callOverloadedConstructor(QV4::ExecutionEngine *engine, QV4::CallData *callArgs) const {
const int numberOfConstructors = d()->constructorCount;
- const int argumentCount = callArgs->argc;
+ const int argumentCount = callArgs->argc();
const QQmlStaticMetaObject object(d()->metaObject);
QQmlPropertyData best;
@@ -2083,12 +2198,12 @@ void MultiplyWrappedQObjectMap::remove(QObject *key)
erase(it);
}
-void MultiplyWrappedQObjectMap::mark(QObject *key, ExecutionEngine *engine)
+void MultiplyWrappedQObjectMap::mark(QObject *key, MarkStack *markStack)
{
Iterator it = find(key);
if (it == end())
return;
- it->markOnce(engine);
+ it->markOnce(markStack);
}
void MultiplyWrappedQObjectMap::removeDestroyedObject(QObject *object)
diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h
index 6494c20bd2..28717b5d80 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper_p.h
+++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h
@@ -90,12 +90,21 @@ struct Q_QML_EXPORT QObjectWrapper : Object {
}
QObject *object() const { return qObj.data(); }
+ static void markObjects(Heap::Base *that, MarkStack *markStack);
private:
QQmlQPointer<QObject> qObj;
};
-struct QObjectMethod : FunctionObject {
+#define QObjectMethodMembers(class, Member) \
+ Member(class, Pointer, QQmlValueTypeWrapper *, valueTypeWrapper) \
+ Member(class, NoMark, QQmlQPointer<QObject>, qObj) \
+ Member(class, NoMark, QQmlPropertyCache *, _propertyCache) \
+ Member(class, NoMark, int, index)
+
+DECLARE_HEAP_OBJECT(QObjectMethod, FunctionObject) {
+ DECLARE_MARKOBJECTS(QObjectMethod);
+
void init(QV4::ExecutionContext *scope);
void destroy()
{
@@ -113,18 +122,10 @@ struct QObjectMethod : FunctionObject {
_propertyCache = c;
}
- Pointer<QQmlValueTypeWrapper> valueTypeWrapper;
-
const QMetaObject *metaObject();
QObject *object() const { return qObj.data(); }
void setObject(QObject *o) { qObj = o; }
-private:
- QQmlQPointer<QObject> qObj;
- QQmlPropertyCache *_propertyCache;
-
-public:
- int index;
};
struct QMetaObjectWrapper : FunctionObject {
@@ -171,7 +172,7 @@ struct Q_QML_EXPORT QObjectWrapper : public Object
static bool setQmlProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, QObject *object, String *name, RevisionMode revisionMode, const Value &value);
static ReturnedValue wrap(ExecutionEngine *engine, QObject *object);
- static void markWrapper(QObject *object, ExecutionEngine *engine);
+ static void markWrapper(QObject *object, MarkStack *markStack);
using Object::get;
@@ -189,16 +190,16 @@ protected:
static ReturnedValue create(ExecutionEngine *engine, QObject *object);
+ static QQmlPropertyData *findProperty(ExecutionEngine *engine, QObject *o, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local);
QQmlPropertyData *findProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local) const;
static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
- static void put(Managed *m, String *name, const Value &value);
+ static bool put(Managed *m, String *name, const Value &value);
static PropertyAttributes query(const Managed *, String *name);
static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
- static void markObjects(Heap::Base *that, QV4::ExecutionEngine *e);
- static void method_connect(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_disconnect(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_connect(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_disconnect(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
private:
Q_NEVER_INLINE static ReturnedValue wrap_slowPath(ExecutionEngine *engine, QObject *object);
@@ -233,14 +234,12 @@ struct Q_QML_EXPORT QObjectMethod : public QV4::FunctionObject
int methodIndex() const { return d()->index; }
QObject *object() const { return d()->object(); }
- QV4::ReturnedValue method_toString(QV4::ExecutionContext *ctx) const;
- QV4::ReturnedValue method_destroy(QV4::ExecutionContext *ctx, const Value *args, int argc) const;
-
- static void call(const Managed *, Scope &scope, CallData *callData);
+ QV4::ReturnedValue method_toString(QV4::ExecutionEngine *engine) const;
+ QV4::ReturnedValue method_destroy(QV4::ExecutionEngine *ctx, const Value *args, int argc) const;
- void callInternal(CallData *callData, Scope &scope) const;
+ static ReturnedValue call(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
- static void markObjects(Heap::Base *that, QV4::ExecutionEngine *e);
+ ReturnedValue callInternal(const Value *thisObject, const Value *argv, int argc) const;
static QPair<QObject *, int> extractQtMethod(const QV4::FunctionObject *function);
};
@@ -252,14 +251,14 @@ struct Q_QML_EXPORT QMetaObjectWrapper : public QV4::FunctionObject
V4_NEEDS_DESTROY
static ReturnedValue create(ExecutionEngine *engine, const QMetaObject* metaObject);
- static void construct(const Managed *, Scope &scope, CallData *callData);
+ static ReturnedValue callAsConstructor(const FunctionObject *, const Value *argv, int argc);
static bool isEqualTo(Managed *a, Managed *b);
const QMetaObject *metaObject() const { return d()->metaObject; }
private:
void init(ExecutionEngine *engine);
- ReturnedValue constructInternal(CallData *callData) const;
+ ReturnedValue constructInternal(const Value *argv, int argc) const;
ReturnedValue callConstructor(const QQmlPropertyData &data, QV4::ExecutionEngine *engine, QV4::CallData *callArgs) const;
ReturnedValue callOverloadedConstructor(QV4::ExecutionEngine *engine, QV4::CallData *callArgs) const;
@@ -294,7 +293,7 @@ public:
ReturnedValue value(QObject *key) const { return QHash<QObject*, QV4::WeakValue>::value(key).value(); }
Iterator erase(Iterator it);
void remove(QObject *key);
- void mark(QObject *key, ExecutionEngine *engine);
+ void mark(QObject *key, MarkStack *markStack);
private Q_SLOTS:
void removeDestroyedObject(QObject*);
diff --git a/src/qml/jsruntime/qv4regexp.cpp b/src/qml/jsruntime/qv4regexp.cpp
index 8cb15b9d7e..36616bc024 100644
--- a/src/qml/jsruntime/qv4regexp.cpp
+++ b/src/qml/jsruntime/qv4regexp.cpp
@@ -62,7 +62,7 @@ uint RegExp::match(const QString &string, int start, uint *matchOffsets)
WTF::String s(string);
#if ENABLE(YARR_JIT)
- if (!jitCode()->isFallBack() && jitCode()->has16BitCode())
+ if (d()->hasValidJITCode())
return uint(jitCode()->execute(s.characters16(), start, s.length(), (int*)matchOffsets).start);
#endif
@@ -90,7 +90,7 @@ Heap::RegExp *RegExp::create(ExecutionEngine* engine, const QString& pattern, bo
return result->d();
}
-void Heap::RegExp::init(ExecutionEngine* engine, const QString &pattern, bool ignoreCase, bool multiline, bool global)
+void Heap::RegExp::init(ExecutionEngine *engine, const QString &pattern, bool ignoreCase, bool multiline, bool global)
{
Base::init();
this->pattern = new QString(pattern);
@@ -98,20 +98,28 @@ void Heap::RegExp::init(ExecutionEngine* engine, const QString &pattern, bool ig
this->multiLine = multiline;
this->global = global;
+ valid = false;
+
const char* error = 0;
- JSC::Yarr::YarrPattern yarrPattern(WTF::String(pattern), ignoreCase, multiline, &error);
+ JSC::Yarr::YarrPattern yarrPattern(WTF::String(pattern), ignoreCase, multiLine, &error);
if (error)
return;
subPatternCount = yarrPattern.m_numSubpatterns;
- OwnPtr<JSC::Yarr::BytecodePattern> p = JSC::Yarr::byteCompile(yarrPattern, engine->bumperPointerAllocator);
- byteCode = p.take();
#if ENABLE(YARR_JIT)
- jitCode = new JSC::Yarr::YarrCodeBlock;
- if (!yarrPattern.m_containsBackreferences && engine->iselFactory->jitCompileRegexps()) {
- JSC::JSGlobalData dummy(engine->regExpAllocator);
+ if (!yarrPattern.m_containsBackreferences && engine->canJIT()) {
+ jitCode = new JSC::Yarr::YarrCodeBlock;
+ JSC::JSGlobalData dummy(internalClass->engine->regExpAllocator);
JSC::Yarr::jitCompile(yarrPattern, JSC::Yarr::Char16, &dummy, *jitCode);
}
#endif
+ if (hasValidJITCode()) {
+ valid = true;
+ return;
+ }
+ OwnPtr<JSC::Yarr::BytecodePattern> p = JSC::Yarr::byteCompile(yarrPattern, internalClass->engine->bumperPointerAllocator);
+ byteCode = p.take();
+ if (byteCode)
+ valid = true;
}
void Heap::RegExp::destroy()
@@ -127,9 +135,3 @@ void Heap::RegExp::destroy()
delete pattern;
Base::destroy();
}
-
-void RegExp::markObjects(Heap::Base *that, ExecutionEngine *e)
-{
- Q_UNUSED(that);
- Q_UNUSED(e);
-}
diff --git a/src/qml/jsruntime/qv4regexp_p.h b/src/qml/jsruntime/qv4regexp_p.h
index d9b536406c..56454f73d3 100644
--- a/src/qml/jsruntime/qv4regexp_p.h
+++ b/src/qml/jsruntime/qv4regexp_p.h
@@ -76,7 +76,7 @@ struct RegExpCacheKey;
namespace Heap {
struct RegExp : Base {
- void init(ExecutionEngine* engine, const QString& pattern, bool ignoreCase, bool multiline, bool global);
+ void init(ExecutionEngine *engine, const QString& pattern, bool ignoreCase, bool multiline, bool global);
void destroy();
QString *pattern;
@@ -84,15 +84,23 @@ struct RegExp : Base {
#if ENABLE(YARR_JIT)
JSC::Yarr::YarrCodeBlock *jitCode;
#endif
+ bool hasValidJITCode() const {
+#if ENABLE(YARR_JIT)
+ return jitCode && !jitCode->isFallBack() && jitCode->has16BitCode();
+#else
+ return false;
+#endif
+ }
RegExpCache *cache;
int subPatternCount;
bool ignoreCase;
bool multiLine;
bool global;
+ bool valid;
int captureCount() const { return subPatternCount + 1; }
};
-V4_ASSERT_IS_TRIVIAL(RegExp)
+Q_STATIC_ASSERT(std::is_trivial< RegExp >::value);
}
@@ -116,14 +124,12 @@ struct RegExp : public Managed
static Heap::RegExp *create(ExecutionEngine* engine, const QString& pattern, bool ignoreCase = false, bool multiline = false, bool global = false);
- bool isValid() const { return d()->byteCode; }
+ bool isValid() const { return d()->valid; }
uint match(const QString& string, int start, uint *matchOffsets);
int captureCount() const { return subPatternCount() + 1; }
- static void markObjects(Heap::Base *that, QV4::ExecutionEngine *e);
-
friend class RegExpCache;
};
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index 82b0f67075..9a5afdf308 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -38,20 +38,17 @@
****************************************************************************/
#include "qv4regexpobject_p.h"
-#include "qv4jsir_p.h"
-#include "qv4isel_p.h"
#include "qv4objectproto_p.h"
#include "qv4regexp_p.h"
#include "qv4stringobject_p.h"
#include <private/qv4mm_p.h>
#include "qv4scopedvalue_p.h"
+#include "qv4jscall_p.h"
#include <private/qqmljsengine_p.h>
#include <private/qqmljslexer_p.h>
#include <private/qqmljsparser_p.h>
#include <private/qqmljsast_p.h>
-#include <qv4jsir_p.h>
-#include <qv4codegen_p.h>
#include "private/qlocale_tools_p.h"
#include <QtCore/QDebug>
@@ -74,15 +71,15 @@ void Heap::RegExpObject::init()
Object::init();
Scope scope(internalClass->engine);
Scoped<QV4::RegExpObject> o(scope, this);
- o->d()->value = QV4::RegExp::create(scope.engine, QString(), false, false, false);
+ value.set(scope.engine, QV4::RegExp::create(scope.engine, QString(), false, false));
o->initProperties();
}
void Heap::RegExpObject::init(QV4::RegExp *value)
{
Object::init();
- this->value = value->d();
Scope scope(internalClass->engine);
+ this->value.set(scope.engine, value->d());
Scoped<QV4::RegExpObject> o(scope, this);
o->initProperties();
}
@@ -134,14 +131,15 @@ void Heap::RegExpObject::init(const QRegExp &re)
Scope scope(internalClass->engine);
Scoped<QV4::RegExpObject> o(scope, this);
- o->d()->value = QV4::RegExp::create(scope.engine, pattern, re.caseSensitivity() == Qt::CaseInsensitive, false);
+ o->d()->value.set(scope.engine,
+ QV4::RegExp::create(scope.engine, pattern, re.caseSensitivity() == Qt::CaseInsensitive, false));
o->initProperties();
}
void RegExpObject::initProperties()
{
- *propertyData(Index_LastIndex) = Primitive::fromInt32(0);
+ setProperty(Index_LastIndex, Primitive::fromInt32(0));
Q_ASSERT(value());
@@ -153,25 +151,10 @@ void RegExpObject::initProperties()
p.replace('/', QLatin1String("\\/"));
}
- *propertyData(Index_Source) = engine()->newString(p);
- *propertyData(Index_Global) = Primitive::fromBoolean(global());
- *propertyData(Index_IgnoreCase) = Primitive::fromBoolean(value()->ignoreCase);
- *propertyData(Index_Multiline) = Primitive::fromBoolean(value()->multiLine);
-}
-
-
-void RegExpObject::markObjects(Heap::Base *that, ExecutionEngine *e)
-{
- RegExpObject::Data *re = static_cast<RegExpObject::Data *>(that);
- if (re->value)
- re->value->mark(e);
- Object::markObjects(that, e);
-}
-
-Value *RegExpObject::lastIndexProperty()
-{
- Q_ASSERT(0 == internalClass()->find(engine()->id_lastIndex()));
- return propertyData(0);
+ setProperty(Index_Source, engine()->newString(p));
+ setProperty(Index_Global, Primitive::fromBoolean(global()));
+ setProperty(Index_IgnoreCase, Primitive::fromBoolean(value()->ignoreCase));
+ setProperty(Index_Multiline, Primitive::fromBoolean(value()->multiLine));
}
// Converts a JS RegExp to a QRegExp.
@@ -225,45 +208,39 @@ void Heap::RegExpCtor::init(QV4::ExecutionContext *scope)
void Heap::RegExpCtor::clearLastMatch()
{
- lastMatch = Primitive::nullValue();
- lastInput = internalClass->engine->id_empty()->d();
+ lastMatch.set(internalClass->engine, Primitive::nullValue());
+ lastInput.set(internalClass->engine, internalClass->engine->id_empty()->d());
lastMatchStart = 0;
lastMatchEnd = 0;
}
-void RegExpCtor::construct(const Managed *, Scope &scope, CallData *callData)
+ReturnedValue RegExpCtor::callAsConstructor(const FunctionObject *fo, const Value *argv, int argc)
{
- ScopedValue r(scope, callData->argument(0));
- ScopedValue f(scope, callData->argument(1));
+ Scope scope(fo->engine());
+ ScopedValue r(scope, argc ? argv[0] : Primitive::undefinedValue());
+ ScopedValue f(scope, argc > 1 ? argv[1] : Primitive::undefinedValue());
Scoped<RegExpObject> re(scope, r);
if (re) {
- if (!f->isUndefined()) {
- scope.result = scope.engine->throwTypeError();
- return;
- }
+ if (!f->isUndefined())
+ return scope.engine->throwTypeError();
Scoped<RegExp> regexp(scope, re->value());
- scope.result = Encode(scope.engine->newRegExpObject(regexp));
- return;
+ return Encode(scope.engine->newRegExpObject(regexp));
}
QString pattern;
if (!r->isUndefined())
pattern = r->toQString();
- if (scope.hasException()) {
- scope.result = Encode::undefined();
- return;
- }
+ if (scope.hasException())
+ return Encode::undefined();
bool global = false;
bool ignoreCase = false;
bool multiLine = false;
if (!f->isUndefined()) {
ScopedString s(scope, f->toString(scope.engine));
- if (scope.hasException()) {
- scope.result = Encode::undefined();
- return;
- }
+ if (scope.hasException())
+ return Encode::undefined();
QString str = s->toQString();
for (int i = 0; i < str.length(); ++i) {
if (str.at(i) == QLatin1Char('g') && !global) {
@@ -273,40 +250,27 @@ void RegExpCtor::construct(const Managed *, Scope &scope, CallData *callData)
} else if (str.at(i) == QLatin1Char('m') && !multiLine) {
multiLine = true;
} else {
- scope.result = scope.engine->throwSyntaxError(QStringLiteral("Invalid flags supplied to RegExp constructor"));
- return;
+ return scope.engine->throwSyntaxError(QStringLiteral("Invalid flags supplied to RegExp constructor"));
}
}
}
Scoped<RegExp> regexp(scope, RegExp::create(scope.engine, pattern, ignoreCase, multiLine, global));
if (!regexp->isValid()) {
- scope.result = scope.engine->throwSyntaxError(QStringLiteral("Invalid regular expression"));
- return;
+ return scope.engine->throwSyntaxError(QStringLiteral("Invalid regular expression"));
}
- scope.result = Encode(scope.engine->newRegExpObject(regexp));
+ return Encode(scope.engine->newRegExpObject(regexp));
}
-void RegExpCtor::call(const Managed *that, Scope &scope, CallData *callData)
+ReturnedValue RegExpCtor::call(const FunctionObject *f, const Value *, const Value *argv, int argc)
{
- if (callData->argc > 0 && callData->args[0].as<RegExpObject>()) {
- if (callData->argc == 1 || callData->args[1].isUndefined()) {
- scope.result = callData->args[0];
- return;
- }
+ if (argc > 0 && argv[0].as<RegExpObject>()) {
+ if (argc == 1 || argv[1].isUndefined())
+ return Encode(argv[0]);
}
- construct(that, scope, callData);
-}
-
-void RegExpCtor::markObjects(Heap::Base *that, ExecutionEngine *e)
-{
- RegExpCtor::Data *This = static_cast<RegExpCtor::Data *>(that);
- This->lastMatch.mark(e);
- if (This->lastInput)
- This->lastInput->mark(e);
- FunctionObject::markObjects(that, e);
+ return callAsConstructor(f, argv, argc);
}
void RegExpPrototype::init(ExecutionEngine *engine, Object *constructor)
@@ -346,32 +310,79 @@ void RegExpPrototype::init(ExecutionEngine *engine, Object *constructor)
defineDefaultProperty(QStringLiteral("compile"), method_compile, 2);
}
-void RegExpPrototype::method_exec(const BuiltinFunction *, Scope &scope, CallData *callData)
+/* used by String.match */
+ReturnedValue RegExpPrototype::execFirstMatch(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- Scoped<RegExpObject> r(scope, callData->thisObject.as<RegExpObject>());
+ Scope scope(b);
+ Scoped<RegExpObject> r(scope, thisObject->as<RegExpObject>());
+ Q_ASSERT(r && r->global());
+
+ ScopedString str(scope, argc ? argv[0] : Primitive::undefinedValue());
+ Q_ASSERT(str);
+ QString s = str->toQString();
+
+ int offset = r->lastIndex();
+ if (offset < 0 || offset > s.length()) {
+ r->setLastIndex(0);
+ RETURN_RESULT(Encode::null());
+ }
+
+ Q_ALLOCA_VAR(uint, matchOffsets, r->value()->captureCount() * 2 * sizeof(uint));
+ const int result = Scoped<RegExp>(scope, r->value())->match(s, offset, matchOffsets);
+
+ RegExpCtor *regExpCtor = static_cast<RegExpCtor *>(scope.engine->regExpCtor());
+ regExpCtor->d()->clearLastMatch();
+
+ if (result == -1) {
+ r->setLastIndex(0);
+ RETURN_RESULT(Encode::null());
+ }
+
+ ReturnedValue retVal = Encode::undefined();
+ // return first match
+ if (r->value()->captureCount()) {
+ int start = matchOffsets[0];
+ int end = matchOffsets[1];
+ retVal = (start != -1) ? scope.engine->memoryManager->alloc<ComplexString>(str->d(), start, end - start)->asReturnedValue() : Encode::undefined();
+ }
+
+ RegExpCtor::Data *dd = regExpCtor->d();
+ dd->lastInput.set(scope.engine, str->d());
+ dd->lastMatchStart = matchOffsets[0];
+ dd->lastMatchEnd = matchOffsets[1];
+
+ r->setLastIndex(matchOffsets[1]);
+
+ return retVal;
+}
+
+ReturnedValue RegExpPrototype::method_exec(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
+{
+ Scope scope(b);
+ Scoped<RegExpObject> r(scope, thisObject->as<RegExpObject>());
if (!r)
- THROW_TYPE_ERROR();
+ return scope.engine->throwTypeError();
- ScopedValue arg(scope, callData->argument(0));
+ ScopedValue arg(scope, argc ? argv[0]: Primitive::undefinedValue());
ScopedString str(scope, arg->toString(scope.engine));
if (scope.hasException())
RETURN_UNDEFINED();
QString s = str->toQString();
- int offset = r->global() ? r->lastIndexProperty()->toInt32() : 0;
+ int offset = r->global() ? r->lastIndex() : 0;
if (offset < 0 || offset > s.length()) {
- *r->lastIndexProperty() = Primitive::fromInt32(0);
+ r->setLastIndex(0);
RETURN_RESULT(Encode::null());
}
Q_ALLOCA_VAR(uint, matchOffsets, r->value()->captureCount() * 2 * sizeof(uint));
const int result = Scoped<RegExp>(scope, r->value())->match(s, offset, matchOffsets);
- Scoped<RegExpCtor> regExpCtor(scope, scope.engine->regExpCtor());
+ RegExpCtor *regExpCtor = static_cast<RegExpCtor *>(scope.engine->regExpCtor());
regExpCtor->d()->clearLastMatch();
if (result == -1) {
- *r->lastIndexProperty() = Primitive::fromInt32(0);
+ r->setLastIndex(0);
RETURN_RESULT(Encode::null());
}
@@ -383,90 +394,94 @@ void RegExpPrototype::method_exec(const BuiltinFunction *, Scope &scope, CallDat
for (int i = 0; i < len; ++i) {
int start = matchOffsets[i * 2];
int end = matchOffsets[i * 2 + 1];
- v = (start != -1) ? scope.engine->newString(s.mid(start, end - start))->asReturnedValue() : Encode::undefined();
+ v = (start != -1) ? scope.engine->memoryManager->alloc<ComplexString>(str->d(), start, end - start)->asReturnedValue() : Encode::undefined();
array->arrayPut(i, v);
}
array->setArrayLengthUnchecked(len);
- *array->propertyData(Index_ArrayIndex) = Primitive::fromInt32(result);
- *array->propertyData(Index_ArrayInput) = str;
+ array->setProperty(Index_ArrayIndex, Primitive::fromInt32(result));
+ array->setProperty(Index_ArrayInput, str);
RegExpCtor::Data *dd = regExpCtor->d();
- dd->lastMatch = array;
- dd->lastInput = str->d();
+ dd->lastMatch.set(scope.engine, array);
+ dd->lastInput.set(scope.engine, str->d());
dd->lastMatchStart = matchOffsets[0];
dd->lastMatchEnd = matchOffsets[1];
if (r->global())
- *r->lastIndexProperty() = Primitive::fromInt32(matchOffsets[1]);
+ r->setLastIndex(matchOffsets[1]);
- scope.result = array;
+ return array.asReturnedValue();
}
-void RegExpPrototype::method_test(const BuiltinFunction *b, Scope &scope, CallData *callData)
+ReturnedValue RegExpPrototype::method_test(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- method_exec(b, scope, callData);
- scope.result = Encode(!scope.result.isNull());
+ Value res = Value::fromReturnedValue(method_exec(b, thisObject, argv, argc));
+ return Encode(!res.isNull());
}
-void RegExpPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue RegExpPrototype::method_toString(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<RegExpObject> r(scope, callData->thisObject.as<RegExpObject>());
+ ExecutionEngine *v4 = b->engine();
+ const RegExpObject *r = thisObject->as<RegExpObject>();
if (!r)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
- scope.result = scope.engine->newString(r->toString());
+ return Encode(v4->newString(r->toString()));
}
-void RegExpPrototype::method_compile(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue RegExpPrototype::method_compile(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- Scoped<RegExpObject> r(scope, callData->thisObject.as<RegExpObject>());
+ Scope scope(b);
+ Scoped<RegExpObject> r(scope, thisObject->as<RegExpObject>());
if (!r)
- THROW_TYPE_ERROR();
-
- ScopedCallData cData(scope, callData->argc);
- memcpy(cData->args, callData->args, callData->argc*sizeof(Value));
+ return scope.engine->throwTypeError();
- scope.engine->regExpCtor()->as<FunctionObject>()->construct(scope, cData);
- Scoped<RegExpObject> re(scope, scope.result.asReturnedValue());
+ Scoped<RegExpObject> re(scope, scope.engine->regExpCtor()->callAsConstructor(argv, argc));
- r->d()->value = re->value();
- RETURN_UNDEFINED();
+ r->d()->value.set(scope.engine, re->value());
+ return Encode::undefined();
}
template <int index>
-void RegExpPrototype::method_get_lastMatch_n(const BuiltinFunction *, Scope &scope, CallData *)
+ReturnedValue RegExpPrototype::method_get_lastMatch_n(const FunctionObject *b, const Value *, const Value *, int)
{
+ Scope scope(b);
ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(scope.engine->regExpCtor())->lastMatch());
- scope.result = lastMatch ? lastMatch->getIndexed(index) : Encode::undefined();
- if (scope.result.isUndefined())
- scope.result = scope.engine->newString();
+ ScopedValue res(scope, lastMatch ? lastMatch->getIndexed(index) : Encode::undefined());
+ if (res->isUndefined())
+ res = scope.engine->newString();
+ return res->asReturnedValue();
}
-void RegExpPrototype::method_get_lastParen(const BuiltinFunction *, Scope &scope, CallData *)
+ReturnedValue RegExpPrototype::method_get_lastParen(const FunctionObject *b, const Value *, const Value *, int)
{
+ Scope scope(b);
ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(scope.engine->regExpCtor())->lastMatch());
- scope.result = lastMatch ? lastMatch->getIndexed(lastMatch->getLength() - 1) : Encode::undefined();
- if (scope.result.isUndefined())
- scope.result = scope.engine->newString();
+ ScopedValue res(scope, lastMatch ? lastMatch->getIndexed(lastMatch->getLength() - 1) : Encode::undefined());
+ if (res->isUndefined())
+ res = scope.engine->newString();
+ return res->asReturnedValue();
}
-void RegExpPrototype::method_get_input(const BuiltinFunction *, Scope &scope, CallData *)
+ReturnedValue RegExpPrototype::method_get_input(const FunctionObject *b, const Value *, const Value *, int)
{
- scope.result = static_cast<RegExpCtor*>(scope.engine->regExpCtor())->lastInput();
+ return static_cast<RegExpCtor*>(b->engine()->regExpCtor())->lastInput()->asReturnedValue();
}
-void RegExpPrototype::method_get_leftContext(const BuiltinFunction *, Scope &scope, CallData *)
+ReturnedValue RegExpPrototype::method_get_leftContext(const FunctionObject *b, const Value *, const Value *, int)
{
+ Scope scope(b);
Scoped<RegExpCtor> regExpCtor(scope, scope.engine->regExpCtor());
QString lastInput = regExpCtor->lastInput()->toQString();
- scope.result = scope.engine->newString(lastInput.left(regExpCtor->lastMatchStart()));
+ return Encode(scope.engine->newString(lastInput.left(regExpCtor->lastMatchStart())));
}
-void RegExpPrototype::method_get_rightContext(const BuiltinFunction *, Scope &scope, CallData *)
+ReturnedValue RegExpPrototype::method_get_rightContext(const FunctionObject *b, const Value *, const Value *, int)
{
+ Scope scope(b);
Scoped<RegExpCtor> regExpCtor(scope, scope.engine->regExpCtor());
QString lastInput = regExpCtor->lastInput()->toQString();
- scope.result = scope.engine->newString(lastInput.mid(regExpCtor->lastMatchEnd()));
+ return Encode(scope.engine->newString(lastInput.mid(regExpCtor->lastMatchEnd())));
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h
index af49a1bf5e..181628241b 100644
--- a/src/qml/jsruntime/qv4regexpobject_p.h
+++ b/src/qml/jsruntime/qv4regexpobject_p.h
@@ -55,8 +55,6 @@
#include "qv4context_p.h"
#include "qv4functionobject_p.h"
#include "qv4string_p.h"
-#include "qv4codegen_p.h"
-#include "qv4isel_p.h"
#include "qv4managed_p.h"
#include "qv4property_p.h"
#include "qv4objectiterator_p.h"
@@ -74,20 +72,27 @@ namespace QV4 {
namespace Heap {
-struct RegExpObject : Object {
+#define RegExpObjectMembers(class, Member) \
+ Member(class, Pointer, RegExp *, value)
+
+DECLARE_HEAP_OBJECT(RegExpObject, Object) {
+ DECLARE_MARKOBJECTS(RegExpObject);
+
void init();
void init(QV4::RegExp *value);
void init(const QRegExp &re);
-
- Pointer<RegExp> value;
};
-struct RegExpCtor : FunctionObject {
+#define RegExpCtorMembers(class, Member) \
+ Member(class, HeapValue, HeapValue, lastMatch) \
+ Member(class, Pointer, String *, lastInput) \
+ Member(class, NoMark, int, lastMatchStart) \
+ Member(class, NoMark, int, lastMatchEnd)
+
+DECLARE_HEAP_OBJECT(RegExpCtor, FunctionObject) {
+ DECLARE_MARKOBJECTS(RegExpCtor);
+
void init(QV4::ExecutionContext *scope);
- Value lastMatch;
- Pointer<String> lastInput;
- int lastMatchStart;
- int lastMatchEnd;
void clearLastMatch();
};
@@ -99,7 +104,7 @@ struct RegExpObject: Object {
V4_INTERNALCLASS(RegExpObject)
V4_PROTOTYPE(regExpPrototype)
- // needs to be compatible with the flags in qv4jsir_p.h
+ // needs to be compatible with the flags in qv4compileddata_p.h
enum Flags {
RegExp_Global = 0x01,
RegExp_IgnoreCase = 0x02,
@@ -116,19 +121,26 @@ struct RegExpObject: Object {
Index_ArrayInput = Index_ArrayIndex + 1
};
+ enum { NInlineProperties = 5 };
+
Heap::RegExp *value() const { return d()->value; }
bool global() const { return d()->value->global; }
void initProperties();
- Value *lastIndexProperty();
+ int lastIndex() const {
+ Q_ASSERT(Index_LastIndex == internalClass()->find(engine()->id_lastIndex()));
+ return propertyData(Index_LastIndex)->toInt32();
+ }
+ void setLastIndex(int index) {
+ Q_ASSERT(Index_LastIndex == internalClass()->find(engine()->id_lastIndex()));
+ return setProperty(Index_LastIndex, Primitive::fromInt32(index));
+ }
+
QRegExp toQRegExp() const;
QString toString() const;
QString source() const;
uint flags() const;
-
-protected:
- static void markObjects(Heap::Base *that, ExecutionEngine *e);
};
struct RegExpCtor: FunctionObject
@@ -140,26 +152,27 @@ struct RegExpCtor: FunctionObject
int lastMatchStart() { return d()->lastMatchStart; }
int lastMatchEnd() { return d()->lastMatchEnd; }
- static void construct(const Managed *m, Scope &scope, CallData *callData);
- static void call(const Managed *that, Scope &scope, CallData *callData);
- static void markObjects(Heap::Base *that, ExecutionEngine *e);
+ static ReturnedValue callAsConstructor(const FunctionObject *f, const Value *argv, int argc);
+ static ReturnedValue call(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
};
struct RegExpPrototype: RegExpObject
{
void init(ExecutionEngine *engine, Object *ctor);
- static void method_exec(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_test(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_compile(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_exec(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_test(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_toString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_compile(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
template <int index>
- static void method_get_lastMatch_n(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_get_lastParen(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_get_input(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_get_leftContext(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_get_rightContext(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_get_lastMatch_n(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_lastParen(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_input(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_leftContext(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_rightContext(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+
+ static ReturnedValue execFirstMatch(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
};
}
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 28b344d154..e7a104af66 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -55,6 +55,7 @@
#include "qv4regexpobject_p.h"
#include "private/qlocale_tools_p.h"
#include "qv4scopedvalue_p.h"
+#include "qv4jscall_p.h"
#include <private/qv4qmlcontext_p.h>
#include <private/qqmltypewrapper_p.h>
#include <private/qqmlengine_p.h>
@@ -310,47 +311,47 @@ void RuntimeHelpers::numberToString(QString *result, double num, int radix)
ReturnedValue Runtime::method_closure(ExecutionEngine *engine, int functionId)
{
- QV4::Function *clos = static_cast<CompiledData::CompilationUnit*>(engine->current->compilationUnit)->runtimeFunctions[functionId];
+ QV4::Function *clos = static_cast<CompiledData::CompilationUnit*>(engine->currentStackFrame->v4Function->compilationUnit)->runtimeFunctions[functionId];
Q_ASSERT(clos);
- return FunctionObject::createScriptFunction(engine->currentContext, clos)->asReturnedValue();
+ ExecutionContext *current = static_cast<ExecutionContext *>(&engine->currentStackFrame->jsFrame->context);
+ return FunctionObject::createScriptFunction(current, clos)->asReturnedValue();
}
-ReturnedValue Runtime::method_deleteElement(ExecutionEngine *engine, const Value &base, const Value &index)
+bool Runtime::method_deleteElement(ExecutionEngine *engine, const Value &base, const Value &index)
{
Scope scope(engine);
ScopedObject o(scope, base);
if (o) {
uint n = index.asArrayIndex();
- if (n < UINT_MAX) {
- return Encode((bool)o->deleteIndexedProperty(n));
- }
+ if (n < UINT_MAX)
+ return o->deleteIndexedProperty(n);
}
ScopedString name(scope, index.toString(engine));
return method_deleteMemberString(engine, base, name);
}
-ReturnedValue Runtime::method_deleteMember(ExecutionEngine *engine, const Value &base, int nameIndex)
+bool Runtime::method_deleteMember(ExecutionEngine *engine, const Value &base, int nameIndex)
{
Scope scope(engine);
- ScopedString name(scope, engine->current->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
return method_deleteMemberString(engine, base, name);
}
-ReturnedValue Runtime::method_deleteMemberString(ExecutionEngine *engine, const Value &base, String *name)
+bool Runtime::method_deleteMemberString(ExecutionEngine *engine, const Value &base, String *name)
{
Scope scope(engine);
ScopedObject obj(scope, base.toObject(engine));
if (scope.engine->hasException)
return Encode::undefined();
- return Encode(obj->deleteProperty(name));
+ return obj->deleteProperty(name);
}
-ReturnedValue Runtime::method_deleteName(ExecutionEngine *engine, int nameIndex)
+bool Runtime::method_deleteName(ExecutionEngine *engine, int nameIndex)
{
Scope scope(engine);
- ScopedString name(scope, engine->current->compilationUnit->runtimeStrings[nameIndex]);
- return Encode(engine->currentContext->deleteProperty(name));
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
+ return static_cast<ExecutionContext &>(engine->currentStackFrame->jsFrame->context).deleteProperty(name);
}
QV4::ReturnedValue Runtime::method_instanceof(ExecutionEngine *engine, const Value &lval, const Value &rval)
@@ -425,14 +426,13 @@ ReturnedValue RuntimeHelpers::objectDefaultValue(const Object *object, int typeH
qSwap(meth1, meth2);
Scope scope(engine);
- ScopedCallData callData(scope, 0);
- callData->thisObject = *object;
-
+ ScopedValue result(scope);
ScopedValue conv(scope, object->get(meth1));
+
if (FunctionObject *o = conv->as<FunctionObject>()) {
- o->call(scope, callData);
- if (scope.result.isPrimitive())
- return scope.result.asReturnedValue();
+ result = o->call(object, nullptr, 0);
+ if (result->isPrimitive())
+ return result->asReturnedValue();
}
if (engine->hasException)
@@ -440,9 +440,9 @@ ReturnedValue RuntimeHelpers::objectDefaultValue(const Object *object, int typeH
conv = object->get(meth2);
if (FunctionObject *o = conv->as<FunctionObject>()) {
- o->call(scope, callData);
- if (scope.result.isPrimitive())
- return scope.result.asReturnedValue();
+ result = o->call(object, nullptr, 0);
+ if (result->isPrimitive())
+ return result->asReturnedValue();
}
return engine->throwTypeError();
@@ -469,8 +469,9 @@ Heap::Object *RuntimeHelpers::convertToObject(ExecutionEngine *engine, const Val
}
}
-Heap::String *RuntimeHelpers::convertToString(ExecutionEngine *engine, const Value &value)
+Heap::String *RuntimeHelpers::convertToString(ExecutionEngine *engine, Value value, TypeHint hint)
{
+ redo:
switch (value.type()) {
case Value::Empty_Type:
Q_ASSERT(!"empty Value encountered");
@@ -484,15 +485,15 @@ Heap::String *RuntimeHelpers::convertToString(ExecutionEngine *engine, const Val
return engine->id_true()->d();
else
return engine->id_false()->d();
- case Value::Managed_Type:
- if (String *s = value.stringValue())
- return s->d();
- {
- Scope scope(engine);
- ScopedValue prim(scope, RuntimeHelpers::toPrimitive(value, STRING_HINT));
- Q_ASSERT(!prim->isManaged() || prim->isString());
- return RuntimeHelpers::convertToString(engine, prim);
- }
+ case Value::Managed_Type: {
+ if (value.isString())
+ return static_cast<const String &>(value).d();
+ value = Primitive::fromReturnedValue(RuntimeHelpers::toPrimitive(value, hint));
+ Q_ASSERT(value.isPrimitive());
+ if (value.isString())
+ return static_cast<const String &>(value).d();
+ goto redo;
+ }
case Value::Integer_Type:
return RuntimeHelpers::stringFromNumber(engine, value.int_32());
default: // double
@@ -502,34 +503,9 @@ Heap::String *RuntimeHelpers::convertToString(ExecutionEngine *engine, const Val
// This is slightly different from the method above, as
// the + operator requires a slightly different conversion
-static Heap::String *convert_to_string_add(ExecutionEngine *engine, const Value &value)
+static Heap::String *convert_to_string_add(ExecutionEngine *engine, Value value)
{
- switch (value.type()) {
- case Value::Empty_Type:
- Q_ASSERT(!"empty Value encountered");
- Q_UNREACHABLE();
- case Value::Undefined_Type:
- return engine->id_undefined()->d();
- case Value::Null_Type:
- return engine->id_null()->d();
- case Value::Boolean_Type:
- if (value.booleanValue())
- return engine->id_true()->d();
- else
- return engine->id_false()->d();
- case Value::Managed_Type:
- if (String *s = value.stringValue())
- return s->d();
- {
- Scope scope(engine);
- ScopedValue prim(scope, RuntimeHelpers::toPrimitive(value, PREFERREDTYPE_HINT));
- return RuntimeHelpers::convertToString(engine, prim);
- }
- case Value::Integer_Type:
- return RuntimeHelpers::stringFromNumber(engine, value.int_32());
- default: // double
- return RuntimeHelpers::stringFromNumber(engine, value.doubleValue());
- } // switch
+ return RuntimeHelpers::convertToString(engine, value, PREFERREDTYPE_HINT);
}
QV4::ReturnedValue RuntimeHelpers::addHelper(ExecutionEngine *engine, const Value &left, const Value &right)
@@ -549,56 +525,28 @@ QV4::ReturnedValue RuntimeHelpers::addHelper(ExecutionEngine *engine, const Valu
pright = convert_to_string_add(engine, pright);
sright = static_cast<String *>(pright.ptr);
}
- if (scope.engine->hasException)
+ if (engine->hasException)
return Encode::undefined();
if (!sleft->d()->length())
return sright->asReturnedValue();
if (!sright->d()->length())
return sleft->asReturnedValue();
MemoryManager *mm = engine->memoryManager;
- return (mm->alloc<String>(sleft->d(), sright->d()))->asReturnedValue();
+ return (mm->alloc<ComplexString>(sleft->d(), sright->d()))->asReturnedValue();
}
double x = RuntimeHelpers::toNumber(pleft);
double y = RuntimeHelpers::toNumber(pright);
return Encode(x + y);
}
-QV4::ReturnedValue Runtime::method_addString(ExecutionEngine *engine, const Value &left, const Value &right)
+bool Runtime::method_storeProperty(ExecutionEngine *engine, const Value &object, int nameIndex, const Value &value)
{
- Q_ASSERT(left.isString() || right.isString());
-
Scope scope(engine);
- ScopedValue pleft(scope, left);
- ScopedValue pright(scope, right);
- String *sleft = pleft->stringValue();
- String *sright = pright->stringValue();
-
- if (!sleft) {
- pleft = convert_to_string_add(engine, pleft);
- sleft = static_cast<String *>(pleft.ptr);
- }
- if (!sright) {
- pright = convert_to_string_add(engine, pright);
- sright = static_cast<String *>(pright.ptr);
- }
- if (scope.engine->hasException)
- return Encode::undefined();
- if (!sleft->d()->length())
- return pright->asReturnedValue();
- if (!sright->d()->length())
- return pleft->asReturnedValue();
- MemoryManager *mm = engine->memoryManager;
- return (mm->alloc<String>(sleft->d(), sright->d()))->asReturnedValue();
-}
-
-void Runtime::method_setProperty(ExecutionEngine *engine, const Value &object, int nameIndex, const Value &value)
-{
- Scope scope(engine);
- ScopedString name(scope, engine->current->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
ScopedObject o(scope, object.toObject(engine));
if (!o)
- return;
- o->put(name, value);
+ return false;
+ return o->put(name, value);
}
static Q_NEVER_INLINE ReturnedValue getElementIntFallback(ExecutionEngine *engine, const Value &object, uint idx)
@@ -656,16 +604,24 @@ static Q_NEVER_INLINE ReturnedValue getElementFallback(ExecutionEngine *engine,
return o->get(name);
}
-ReturnedValue Runtime::method_getElement(ExecutionEngine *engine, const Value &object, const Value &index)
+/* load element:
+
+ Managed *m = object.heapObject();
+ if (m)
+ return m->internalClass->getIndexed(m, index);
+ return getIndexedFallback(object, index);
+*/
+
+ReturnedValue Runtime::method_loadElement(ExecutionEngine *engine, const Value &object, const Value &index)
{
- uint idx;
+ uint idx = 0;
if (index.asArrayIndex(idx)) {
if (Heap::Base *b = object.heapObject()) {
if (b->vtable()->isObject) {
Heap::Object *o = static_cast<Heap::Object *>(b);
if (o->arrayData && o->arrayData->type == Heap::ArrayData::Simple) {
Heap::SimpleArrayData *s = o->arrayData.cast<Heap::SimpleArrayData>();
- if (idx < s->len)
+ if (idx < s->values.size)
if (!s->data(idx).isEmpty())
return s->data(idx).asReturnedValue();
}
@@ -677,42 +633,41 @@ ReturnedValue Runtime::method_getElement(ExecutionEngine *engine, const Value &o
return getElementFallback(engine, object, index);
}
-static Q_NEVER_INLINE void setElementFallback(ExecutionEngine *engine, const Value &object, const Value &index, const Value &value)
+static Q_NEVER_INLINE bool setElementFallback(ExecutionEngine *engine, const Value &object, const Value &index, const Value &value)
{
Scope scope(engine);
ScopedObject o(scope, object.toObject(engine));
if (engine->hasException)
- return;
+ return false;
- uint idx;
+ uint idx = 0;
if (index.asArrayIndex(idx)) {
if (o->d()->arrayData && o->d()->arrayData->type == Heap::ArrayData::Simple) {
Heap::SimpleArrayData *s = o->d()->arrayData.cast<Heap::SimpleArrayData>();
- if (idx < s->len) {
- s->data(idx) = value;
- return;
+ if (idx < s->values.size) {
+ s->setData(engine, idx, value);
+ return true;
}
}
- o->putIndexed(idx, value);
- return;
+ return o->putIndexed(idx, value);
}
ScopedString name(scope, index.toString(engine));
- o->put(name, value);
+ return o->put(name, value);
}
-void Runtime::method_setElement(ExecutionEngine *engine, const Value &object, const Value &index, const Value &value)
+bool Runtime::method_storeElement(ExecutionEngine *engine, const Value &object, const Value &index, const Value &value)
{
- uint idx;
+ uint idx = 0;
if (index.asArrayIndex(idx)) {
if (Heap::Base *b = object.heapObject()) {
if (b->vtable()->isObject) {
Heap::Object *o = static_cast<Heap::Object *>(b);
if (o->arrayData && o->arrayData->type == Heap::ArrayData::Simple) {
Heap::SimpleArrayData *s = o->arrayData.cast<Heap::SimpleArrayData>();
- if (idx < s->len) {
- s->data(idx) = value;
- return;
+ if (idx < s->values.size) {
+ s->setData(engine, idx, value);
+ return true;
}
}
}
@@ -742,17 +697,31 @@ ReturnedValue Runtime::method_foreachNextPropertyName(const Value &foreach_itera
}
-void Runtime::method_setActivationProperty(ExecutionEngine *engine, int nameIndex, const Value &value)
+void Runtime::method_storeNameSloppy(ExecutionEngine *engine, int nameIndex, const Value &value)
+{
+ Scope scope(engine);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
+ ExecutionContext::Error e = static_cast<ExecutionContext &>(engine->currentStackFrame->jsFrame->context).setProperty(name, value);
+
+ if (e == ExecutionContext::RangeError)
+ engine->globalObject->put(name, value);
+}
+
+void Runtime::method_storeNameStrict(ExecutionEngine *engine, int nameIndex, const Value &value)
{
Scope scope(engine);
- ScopedString name(scope, engine->current->compilationUnit->runtimeStrings[nameIndex]);
- engine->currentContext->setProperty(name, value);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
+ ExecutionContext::Error e = static_cast<ExecutionContext &>(engine->currentStackFrame->jsFrame->context).setProperty(name, value);
+ if (e == ExecutionContext::TypeError)
+ engine->throwTypeError();
+ else if (e == ExecutionContext::RangeError)
+ engine->throwReferenceError(name);
}
-ReturnedValue Runtime::method_getProperty(ExecutionEngine *engine, const Value &object, int nameIndex)
+ReturnedValue Runtime::method_loadProperty(ExecutionEngine *engine, const Value &object, int nameIndex)
{
Scope scope(engine);
- ScopedString name(scope, engine->current->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
ScopedObject o(scope, object);
if (o)
@@ -769,11 +738,11 @@ ReturnedValue Runtime::method_getProperty(ExecutionEngine *engine, const Value &
return o->get(name);
}
-ReturnedValue Runtime::method_getActivationProperty(ExecutionEngine *engine, int nameIndex)
+ReturnedValue Runtime::method_loadName(ExecutionEngine *engine, int nameIndex)
{
Scope scope(engine);
- ScopedString name(scope, engine->current->compilationUnit->runtimeStrings[nameIndex]);
- return engine->currentContext->getProperty(name);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
+ return static_cast<ExecutionContext &>(engine->currentStackFrame->jsFrame->context).getProperty(name);
}
#endif // V4_BOOTSTRAP
@@ -1002,233 +971,142 @@ uint Runtime::method_compareIn(ExecutionEngine *engine, const Value &left, const
}
-ReturnedValue Runtime::method_callGlobalLookup(ExecutionEngine *engine, uint index, CallData *callData)
+ReturnedValue Runtime::method_callGlobalLookup(ExecutionEngine *engine, uint index, Value *argv, int argc)
{
- Scope scope(engine);
- Q_ASSERT(callData->thisObject.isUndefined());
-
- Lookup *l = engine->current->lookups + index;
- ScopedFunctionObject o(scope, l->globalGetter(l, engine));
- if (!o)
+ Lookup *l = engine->currentStackFrame->v4Function->compilationUnit->runtimeLookups + index;
+ Value function = Value::fromReturnedValue(l->globalGetter(l, engine));
+ if (!function.isFunctionObject())
return engine->throwTypeError();
- ScopedString name(scope, engine->current->compilationUnit->runtimeStrings[l->nameIndex]);
- if (o->d() == scope.engine->evalFunction()->d() && name->equals(scope.engine->id_eval())) {
- static_cast<EvalFunction *>(o.getPointer())->evalCall(scope, callData, true);
- } else {
- o->call(scope, callData);
- }
-
- return scope.result.asReturnedValue();
+ Value thisObject = Primitive::undefinedValue();
+ return static_cast<FunctionObject &>(function).call(&thisObject, argv, argc);
}
-
-ReturnedValue Runtime::method_callActivationProperty(ExecutionEngine *engine, int nameIndex, CallData *callData)
+ReturnedValue Runtime::method_callPossiblyDirectEval(ExecutionEngine *engine, Value *argv, int argc)
{
- Q_ASSERT(callData->thisObject.isUndefined());
Scope scope(engine);
- ScopedString name(scope, engine->current->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedValue thisObject(scope);
- ScopedObject base(scope);
- ScopedValue func(scope, engine->currentContext->getPropertyAndBase(name, base.getRef()));
- if (scope.engine->hasException)
+ ExecutionContext &ctx = static_cast<ExecutionContext &>(engine->currentStackFrame->jsFrame->context);
+ ScopedFunctionObject function(scope, ctx.getPropertyAndBase(engine->id_eval(), thisObject));
+ if (engine->hasException)
return Encode::undefined();
- if (base)
- callData->thisObject = base;
-
- FunctionObject *o = func->as<FunctionObject>();
- if (!o) {
+ if (!function) {
QString objectAsString = QStringLiteral("[null]");
- if (base)
- objectAsString = ScopedValue(scope, base.asReturnedValue())->toQStringNoThrow();
- QString msg = QStringLiteral("Property '%1' of object %2 is not a function").arg(name->toQString()).arg(objectAsString);
+ if (!thisObject->isUndefined())
+ objectAsString = thisObject->toQStringNoThrow();
+ QString msg = QStringLiteral("Property 'eval' of object %2 is not a function").arg(objectAsString);
return engine->throwTypeError(msg);
}
- if (o->d() == scope.engine->evalFunction()->d() && name->equals(scope.engine->id_eval())) {
- static_cast<EvalFunction *>(o)->evalCall(scope, callData, true);
- } else {
- o->call(scope, callData);
- }
+ if (function->d() == engine->evalFunction()->d())
+ return static_cast<EvalFunction *>(function.getPointer())->evalCall(thisObject, argv, argc, true);
- return scope.result.asReturnedValue();
+ return function->call(thisObject, argv, argc);
}
-ReturnedValue Runtime::method_callQmlScopeObjectProperty(ExecutionEngine *engine, int propertyIndex, CallData *callData)
+ReturnedValue Runtime::method_callName(ExecutionEngine *engine, int nameIndex, Value *argv, int argc)
{
Scope scope(engine);
- ScopedFunctionObject o(scope, method_getQmlScopeObjectProperty(engine, callData->thisObject, propertyIndex, /*captureRequired*/true));
- if (!o) {
- QString error = QStringLiteral("Property '%1' of scope object is not a function").arg(propertyIndex);
- return engine->throwTypeError(error);
- }
+ ScopedValue thisObject(scope);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
- o->call(scope, callData);
- return scope.result.asReturnedValue();
-}
+ ExecutionContext &ctx = static_cast<ExecutionContext &>(engine->currentStackFrame->jsFrame->context);
+ ScopedFunctionObject f(scope, ctx.getPropertyAndBase(name, thisObject));
+ if (engine->hasException)
+ return Encode::undefined();
-ReturnedValue Runtime::method_callQmlContextObjectProperty(ExecutionEngine *engine, int propertyIndex, CallData *callData)
-{
- Scope scope(engine);
- ScopedFunctionObject o(scope, method_getQmlContextObjectProperty(engine, callData->thisObject, propertyIndex, /*captureRequired*/true));
- if (!o) {
- QString error = QStringLiteral("Property '%1' of context object is not a function").arg(propertyIndex);
- return engine->throwTypeError(error);
+ if (!f) {
+ QString objectAsString = QStringLiteral("[null]");
+ if (!thisObject->isUndefined())
+ objectAsString = thisObject->toQStringNoThrow();
+ QString msg = QStringLiteral("Property '%1' of object %2 is not a function")
+ .arg(engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]->toQString(),
+ objectAsString);
+ return engine->throwTypeError(msg);
}
- o->call(scope, callData);
- return scope.result.asReturnedValue();
+ return f->call(thisObject, argv, argc);
}
-ReturnedValue Runtime::method_callProperty(ExecutionEngine *engine, int nameIndex, CallData *callData)
+ReturnedValue Runtime::method_callProperty(ExecutionEngine *engine, Value *base, int nameIndex, Value *argv, int argc)
{
Scope scope(engine);
- ScopedString name(scope, engine->current->compilationUnit->runtimeStrings[nameIndex]);
- ScopedObject baseObject(scope, callData->thisObject);
- if (!baseObject) {
- Q_ASSERT(!callData->thisObject.isEmpty());
- if (callData->thisObject.isNullOrUndefined()) {
- QString message = QStringLiteral("Cannot call method '%1' of %2").arg(name->toQString()).arg(callData->thisObject.toQStringNoThrow());
+
+ if (!base->isObject()) {
+ Q_ASSERT(!base->isEmpty());
+ if (base->isNullOrUndefined()) {
+ QString message = QStringLiteral("Cannot call method '%1' of %2")
+ .arg(engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]->toQString(),
+ base->toQStringNoThrow());
return engine->throwTypeError(message);
}
- baseObject = RuntimeHelpers::convertToObject(scope.engine, callData->thisObject);
- if (!baseObject) // type error
+ ScopedValue thisObject(scope, RuntimeHelpers::convertToObject(engine, *base));
+ if (engine->hasException) // type error
return Encode::undefined();
- callData->thisObject = baseObject.asReturnedValue();
+ base = thisObject;
}
- ScopedFunctionObject o(scope, baseObject->get(name));
- if (o) {
- o->call(scope, callData);
- return scope.result.asReturnedValue();
- } else {
- QString error = QStringLiteral("Property '%1' of object %2 is not a function").arg(name->toQString(), callData->thisObject.toQStringNoThrow());
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedFunctionObject f(scope, static_cast<Object *>(base)->get(name));
+
+ if (!f) {
+ QString error = QStringLiteral("Property '%1' of object %2 is not a function")
+ .arg(engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]->toQString(),
+ base->toQStringNoThrow());
return engine->throwTypeError(error);
}
+ return f->call(base, argv, argc);
}
-ReturnedValue Runtime::method_callPropertyLookup(ExecutionEngine *engine, uint index, CallData *callData)
+ReturnedValue Runtime::method_callPropertyLookup(ExecutionEngine *engine, Value *base, uint index, Value *argv, int argc)
{
- Lookup *l = engine->current->lookups + index;
- Value v;
- v = l->getter(l, engine, callData->thisObject);
- Object *o = v.objectValue();
- if (Q_LIKELY(o)) {
- Scope scope(engine);
- o->call(scope, callData);
- return scope.result.asReturnedValue();
- }
- return engine->throwTypeError();
-}
-
-ReturnedValue Runtime::method_callElement(ExecutionEngine *engine, const Value &index, CallData *callData)
-{
- Scope scope(engine);
- ScopedObject baseObject(scope, callData->thisObject.toObject(engine));
- ScopedString s(scope, index.toString(engine));
-
- if (scope.engine->hasException)
- return Encode::undefined();
- callData->thisObject = baseObject;
+ Lookup *l = engine->currentStackFrame->v4Function->compilationUnit->runtimeLookups + index;
+ // ok to have the value on the stack here
+ Value f = Value::fromReturnedValue(l->getter(l, engine, *base));
- ScopedObject o(scope, baseObject->get(s));
- if (!o)
+ if (!f.isFunctionObject())
return engine->throwTypeError();
- o->call(scope, callData);
- return scope.result.asReturnedValue();
-}
-
-ReturnedValue Runtime::method_callValue(ExecutionEngine *engine, const Value &func, CallData *callData)
-{
- if (Object *o = func.objectValue()) {
- Scope scope(engine);
- o->call(scope, callData);
- return scope.result.asReturnedValue();
- }
- return engine->throwTypeError(QStringLiteral("%1 is not a function").arg(func.toQStringNoThrow()));
+ return static_cast<FunctionObject &>(f).call(base, argv, argc);
}
-
-ReturnedValue Runtime::method_constructGlobalLookup(ExecutionEngine *engine, uint index, CallData *callData)
+ReturnedValue Runtime::method_callElement(ExecutionEngine *engine, Value *base, const Value &index, Value *argv, int argc)
{
Scope scope(engine);
- Q_ASSERT(callData->thisObject.isUndefined());
+ ScopedValue thisObject(scope, base->toObject(engine));
+ base = thisObject;
- Lookup *l = engine->current->lookups + index;
- ScopedObject f(scope, l->globalGetter(l, engine));
- if (f) {
- f->construct(scope, callData);
- return scope.result.asReturnedValue();
- } else {
- return engine->throwTypeError();
- }
-}
-
-
-ReturnedValue Runtime::method_constructActivationProperty(ExecutionEngine *engine, int nameIndex, CallData *callData)
-{
- Scope scope(engine);
- ScopedString name(scope, engine->current->compilationUnit->runtimeStrings[nameIndex]);
- ScopedValue func(scope, engine->currentContext->getProperty(name));
- if (scope.engine->hasException)
+ ScopedString str(scope, index.toString(engine));
+ if (engine->hasException)
return Encode::undefined();
- Object *f = func->as<Object>();
+ ScopedFunctionObject f(scope, static_cast<Object *>(base)->get(str));
if (!f)
return engine->throwTypeError();
- f->construct(scope, callData);
- return scope.result.asReturnedValue();
+ return f->call(base, argv, argc);
}
-ReturnedValue Runtime::method_constructValue(ExecutionEngine *engine, const Value &func, CallData *callData)
+ReturnedValue Runtime::method_callValue(ExecutionEngine *engine, const Value &func, Value *argv, int argc)
{
- const Object *f = func.as<Object>();
- if (!f)
- return engine->throwTypeError();
-
- Scope scope(engine);
- f->construct(scope, callData);
- return scope.result.asReturnedValue();
+ if (!func.isFunctionObject())
+ return engine->throwTypeError(QStringLiteral("%1 is not a function").arg(func.toQStringNoThrow()));
+ return static_cast<const FunctionObject &>(func).call(nullptr, argv, argc);
}
-ReturnedValue Runtime::method_constructProperty(ExecutionEngine *engine, int nameIndex, CallData *callData)
-{
- Scope scope(engine);
- ScopedObject thisObject(scope, callData->thisObject.toObject(engine));
- ScopedString name(scope, engine->current->compilationUnit->runtimeStrings[nameIndex]);
- if (scope.engine->hasException)
- return Encode::undefined();
- ScopedObject f(scope, thisObject->get(name));
- if (f) {
- Scope scope(engine);
- f->construct(scope, callData);
- return scope.result.asReturnedValue();
- } else {
+ReturnedValue Runtime::method_construct(ExecutionEngine *engine, const Value &function, Value *argv, int argc)
+{
+ if (!function.isFunctionObject())
return engine->throwTypeError();
- }
-}
-ReturnedValue Runtime::method_constructPropertyLookup(ExecutionEngine *engine, uint index, CallData *callData)
-{
- Lookup *l = engine->current->lookups + index;
- Value v;
- v = l->getter(l, engine, callData->thisObject);
- Object *o = v.objectValue();
- if (Q_LIKELY(o)) {
- Scope scope(engine);
- o->construct(scope, callData);
- return scope.result.asReturnedValue();
- }
- return engine->throwTypeError();
+ return static_cast<const FunctionObject &>(function).callAsConstructor(argv, argc);
}
-
void Runtime::method_throwException(ExecutionEngine *engine, const Value &value)
{
if (!value.isEmpty())
@@ -1267,96 +1145,37 @@ ReturnedValue Runtime::method_typeofValue(ExecutionEngine *engine, const Value &
QV4::ReturnedValue Runtime::method_typeofName(ExecutionEngine *engine, int nameIndex)
{
Scope scope(engine);
- ScopedString name(scope, engine->current->compilationUnit->runtimeStrings[nameIndex]);
- ScopedValue prop(scope, engine->currentContext->getProperty(name));
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedValue prop(scope, static_cast<ExecutionContext &>(engine->currentStackFrame->jsFrame->context).getProperty(name));
// typeof doesn't throw. clear any possible exception
scope.engine->hasException = false;
return method_typeofValue(engine, prop);
}
-#ifndef V4_BOOTSTRAP
-ReturnedValue Runtime::method_typeofScopeObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex)
-{
- Scope scope(engine);
- ScopedValue prop(scope, method_getQmlScopeObjectProperty(engine, context, propertyIndex, /*captureRequired*/true));
- if (scope.engine->hasException)
- return Encode::undefined();
- return method_typeofValue(engine, prop);
-}
-
-ReturnedValue Runtime::method_typeofContextObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex)
-{
- Scope scope(engine);
- ScopedValue prop(scope, method_getQmlContextObjectProperty(engine, context, propertyIndex, /*captureRequired*/true));
- if (scope.engine->hasException)
- return Encode::undefined();
- return method_typeofValue(engine, prop);
-}
-#endif // V4_BOOTSTRAP
-
-QV4::ReturnedValue Runtime::method_typeofMember(ExecutionEngine *engine, const Value &base, int nameIndex)
-{
- Scope scope(engine);
- ScopedString name(scope, engine->current->compilationUnit->runtimeStrings[nameIndex]);
- ScopedObject obj(scope, base.toObject(engine));
- if (scope.engine->hasException)
- return Encode::undefined();
- ScopedValue prop(scope, obj->get(name));
- return method_typeofValue(engine, prop);
-}
-
-QV4::ReturnedValue Runtime::method_typeofElement(ExecutionEngine *engine, const Value &base, const Value &index)
-{
- Scope scope(engine);
- ScopedString name(scope, index.toString(engine));
- ScopedObject obj(scope, base.toObject(engine));
- if (scope.engine->hasException)
- return Encode::undefined();
- ScopedValue prop(scope, obj->get(name));
- return method_typeofValue(engine, prop);
-}
-
-ReturnedValue Runtime::method_unwindException(ExecutionEngine *engine)
-{
- if (!engine->hasException)
- return Primitive::emptyValue().asReturnedValue();
- return engine->catchException(0);
-}
-
/* The next three methods are a bit tricky. They can't open up a Scope, as that
* would mess up the pushing of the context.
*
* Instead the push/pop pair acts as a non local scope.
*/
-void Runtime::method_pushWithScope(const Value &o, NoThrowEngine *engine)
+ReturnedValue Runtime::method_createWithContext(ExecutionContext *parent, const Value &o)
{
- QV4::Value *v = engine->jsAlloca(1);
- Heap::Object *withObject = o.toObject(engine);
- *v = withObject;
- engine->pushContext(engine->currentContext->newWithContext(withObject));
- Q_ASSERT(engine->jsStackTop == engine->currentContext + 2);
+ Q_ASSERT(o.isObject());
+ const Object &obj = static_cast<const Object &>(o);
+ return parent->newWithContext(obj.d())->asReturnedValue();
}
-void Runtime::method_pushCatchScope(NoThrowEngine *engine, int exceptionVarNameIndex)
+ReturnedValue Runtime::method_createCatchContext(ExecutionContext *parent, int exceptionVarNameIndex)
{
- engine->jsAlloca(1); // keep this symmetric with pushWithScope
- ExecutionContext *c = engine->currentContext;
- engine->pushContext(c->newCatchContext(c->d()->compilationUnit->runtimeStrings[exceptionVarNameIndex], engine->catchException(0)));
- Q_ASSERT(engine->jsStackTop == engine->currentContext + 2);
-}
-
-void Runtime::method_popScope(NoThrowEngine *engine)
-{
- Q_ASSERT(engine->jsStackTop == engine->currentContext + 2);
- engine->popContext();
- engine->jsStackTop -= 3;
+ ExecutionEngine *e = parent->engine();
+ return parent->newCatchContext(e->currentStackFrame->v4Function->compilationUnit->runtimeStrings[exceptionVarNameIndex],
+ e->catchException(0))->asReturnedValue();
}
void Runtime::method_declareVar(ExecutionEngine *engine, bool deletable, int nameIndex)
{
Scope scope(engine);
- ScopedString name(scope, engine->current->compilationUnit->runtimeStrings[nameIndex]);
- engine->currentContext->createMutableBinding(name, deletable);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
+ static_cast<ExecutionContext &>(engine->currentStackFrame->jsFrame->context).createMutableBinding(name, deletable);
}
ReturnedValue Runtime::method_arrayLiteral(ExecutionEngine *engine, Value *values, uint length)
@@ -1367,7 +1186,7 @@ ReturnedValue Runtime::method_arrayLiteral(ExecutionEngine *engine, Value *value
ReturnedValue Runtime::method_objectLiteral(ExecutionEngine *engine, const QV4::Value *args, int classId, int arrayValueCount, int arrayGetterSetterCountAndFlags)
{
Scope scope(engine);
- QV4::InternalClass *klass = static_cast<CompiledData::CompilationUnit*>(engine->current->compilationUnit)->runtimeClasses[classId];
+ QV4::InternalClass *klass = static_cast<CompiledData::CompilationUnit*>(engine->currentStackFrame->v4Function->compilationUnit)->runtimeClasses[classId];
ScopedObject o(scope, engine->newObject(klass, engine->objectPrototype()));
{
@@ -1377,7 +1196,7 @@ ReturnedValue Runtime::method_objectLiteral(ExecutionEngine *engine, const QV4::
}
for (uint i = 0; i < klass->size; ++i)
- *o->propertyData(i) = *args++;
+ o->setProperty(i, *args++);
if (arrayValueCount > 0) {
ScopedValue entry(scope);
@@ -1406,134 +1225,46 @@ ReturnedValue Runtime::method_objectLiteral(ExecutionEngine *engine, const QV4::
return o.asReturnedValue();
}
-QV4::ReturnedValue Runtime::method_setupArgumentsObject(ExecutionEngine *engine)
+QV4::ReturnedValue Runtime::method_createMappedArgumentsObject(ExecutionEngine *engine)
{
- Q_ASSERT(engine->current->type == Heap::ExecutionContext::Type_CallContext);
- QV4::CallContext *c = static_cast<QV4::CallContext *>(engine->currentContext);
- QV4::InternalClass *ic = engine->internalClasses[c->d()->strictMode ? EngineBase::Class_StrictArgumentsObject : EngineBase::Class_ArgumentsObject];
- return engine->memoryManager->allocObject<ArgumentsObject>(ic, engine->objectPrototype(), c)->asReturnedValue();
+ Q_ASSERT(engine->currentContext()->d()->type == Heap::ExecutionContext::Type_CallContext);
+ QV4::InternalClass *ic = engine->internalClasses[EngineBase::Class_ArgumentsObject];
+ return engine->memoryManager->allocObject<ArgumentsObject>(ic, engine->objectPrototype(), engine->currentStackFrame)->asReturnedValue();
}
-#endif // V4_BOOTSTRAP
-
-QV4::ReturnedValue Runtime::method_increment(const Value &value)
-{
- TRACE1(value);
-
- if (value.isInteger() && value.integerValue() < INT_MAX)
- return Encode(value.integerValue() + 1);
- else {
- double d = value.toNumber();
- return Encode(d + 1.);
- }
-}
-
-QV4::ReturnedValue Runtime::method_decrement(const Value &value)
-{
- TRACE1(value);
-
- if (value.isInteger() && value.integerValue() > INT_MIN)
- return Encode(value.integerValue() - 1);
- else {
- double d = value.toNumber();
- return Encode(d - 1.);
- }
-}
-
-ReturnedValue Runtime::method_toDouble(const Value &value)
-{
- TRACE1(value);
- return Encode(value.toNumber());
-}
-
-int Runtime::method_toInt(const Value &value)
-{
- TRACE1(value);
- return value.toInt32();
-}
-
-int Runtime::method_doubleToInt(const double &d)
-{
- TRACE0();
- return Primitive::toInt32(d);
-}
-
-unsigned Runtime::method_toUInt(const Value &value)
-{
- TRACE1(value);
- return value.toUInt32();
-}
-
-unsigned Runtime::method_doubleToUInt(const double &d)
+QV4::ReturnedValue Runtime::method_createUnmappedArgumentsObject(ExecutionEngine *engine)
{
- TRACE0();
- return Primitive::toUInt32(d);
+ QV4::InternalClass *ic = engine->internalClasses[EngineBase::Class_StrictArgumentsObject];
+ return engine->memoryManager->allocObject<StrictArgumentsObject>(ic, engine->objectPrototype(), engine->currentStackFrame)->asReturnedValue();
}
-#ifndef V4_BOOTSTRAP
-
-ReturnedValue Runtime::method_getQmlContext(NoThrowEngine *engine)
+ReturnedValue Runtime::method_loadQmlContext(NoThrowEngine *engine)
{
return engine->qmlContext()->asReturnedValue();
}
ReturnedValue Runtime::method_regexpLiteral(ExecutionEngine *engine, int id)
{
- Heap::RegExpObject *ro = engine->newRegExpObject(
- static_cast<CompiledData::CompilationUnit*>(engine->current->compilationUnit)
- ->runtimeRegularExpressions[id].as<RegExp>());
+ Heap::RegExpObject *ro = engine->newRegExpObject(engine->currentStackFrame->v4Function->compilationUnit->runtimeRegularExpressions[id].as<RegExp>());
return ro->asReturnedValue();
}
-ReturnedValue Runtime::method_getQmlQObjectProperty(ExecutionEngine *engine, const Value &object, int propertyIndex, bool captureRequired)
-{
- Scope scope(engine);
- QV4::Scoped<QObjectWrapper> wrapper(scope, object);
- if (!wrapper) {
- engine->throwTypeError(QStringLiteral("Cannot read property of null"));
- return Encode::undefined();
- }
- return QV4::QObjectWrapper::getProperty(scope.engine, wrapper->object(), propertyIndex, captureRequired);
-}
-
-QV4::ReturnedValue Runtime::method_getQmlAttachedProperty(ExecutionEngine *engine, int attachedPropertiesId, int propertyIndex)
-{
- QObject *scopeObject = engine->qmlScopeObject();
- QObject *attachedObject = qmlAttachedPropertiesObjectById(attachedPropertiesId, scopeObject);
-
- QJSEngine *jsEngine = engine->jsEngine();
- QQmlData::ensurePropertyCache(jsEngine, attachedObject);
- return QV4::QObjectWrapper::getProperty(engine, attachedObject, propertyIndex, /*captureRequired*/true);
-}
-
-ReturnedValue Runtime::method_getQmlScopeObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired)
+ReturnedValue Runtime::method_loadQmlScopeObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired)
{
const QmlContext &c = static_cast<const QmlContext &>(context);
- return QV4::QObjectWrapper::getProperty(engine, c.d()->qml->scopeObject, propertyIndex, captureRequired);
+ return QV4::QObjectWrapper::getProperty(engine, c.d()->qml()->scopeObject, propertyIndex, captureRequired);
}
-ReturnedValue Runtime::method_getQmlContextObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired)
+ReturnedValue Runtime::method_loadQmlContextObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired)
{
const QmlContext &c = static_cast<const QmlContext &>(context);
- return QV4::QObjectWrapper::getProperty(engine, (*c.d()->qml->context)->contextObject, propertyIndex, captureRequired);
-}
-
-ReturnedValue Runtime::method_getQmlSingletonQObjectProperty(ExecutionEngine *engine, const Value &object, int propertyIndex, bool captureRequired)
-{
- Scope scope(engine);
- QV4::Scoped<QmlTypeWrapper> wrapper(scope, object);
- if (!wrapper) {
- scope.engine->throwTypeError(QStringLiteral("Cannot read property of null"));
- return Encode::undefined();
- }
- return QV4::QObjectWrapper::getProperty(scope.engine, wrapper->singletonObject(), propertyIndex, captureRequired);
+ return QV4::QObjectWrapper::getProperty(engine, (*c.d()->qml()->context)->contextObject, propertyIndex, captureRequired);
}
-ReturnedValue Runtime::method_getQmlIdObject(ExecutionEngine *engine, const Value &c, uint index)
+ReturnedValue Runtime::method_loadQmlIdObject(ExecutionEngine *engine, const Value &c, uint index)
{
- Scope scope(engine);
const QmlContext &qmlContext = static_cast<const QmlContext &>(c);
- QQmlContextData *context = *qmlContext.d()->qml->context;
+ QQmlContextData *context = *qmlContext.d()->qml()->context;
if (!context || index >= (uint)context->idValueCount)
return Encode::undefined();
@@ -1544,30 +1275,19 @@ ReturnedValue Runtime::method_getQmlIdObject(ExecutionEngine *engine, const Valu
return QObjectWrapper::wrap(engine, context->idValues[index].data());
}
-void Runtime::method_setQmlScopeObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value)
+void Runtime::method_storeQmlScopeObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value)
{
const QmlContext &c = static_cast<const QmlContext &>(context);
- return QV4::QObjectWrapper::setProperty(engine, c.d()->qml->scopeObject, propertyIndex, value);
+ return QV4::QObjectWrapper::setProperty(engine, c.d()->qml()->scopeObject, propertyIndex, value);
}
-void Runtime::method_setQmlContextObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value)
+void Runtime::method_storeQmlContextObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value)
{
const QmlContext &c = static_cast<const QmlContext &>(context);
- return QV4::QObjectWrapper::setProperty(engine, (*c.d()->qml->context)->contextObject, propertyIndex, value);
+ return QV4::QObjectWrapper::setProperty(engine, (*c.d()->qml()->context)->contextObject, propertyIndex, value);
}
-void Runtime::method_setQmlQObjectProperty(ExecutionEngine *engine, const Value &object, int propertyIndex, const Value &value)
-{
- Scope scope(engine);
- QV4::Scoped<QObjectWrapper> wrapper(scope, object);
- if (!wrapper) {
- engine->throwTypeError(QStringLiteral("Cannot write property of null"));
- return;
- }
- wrapper->setProperty(engine, propertyIndex, value);
-}
-
-ReturnedValue Runtime::method_getQmlImportedScripts(NoThrowEngine *engine)
+ReturnedValue Runtime::method_loadQmlImportedScripts(NoThrowEngine *engine)
{
QQmlContextData *context = engine->callingQmlContext();
if (!context)
@@ -1575,44 +1295,20 @@ ReturnedValue Runtime::method_getQmlImportedScripts(NoThrowEngine *engine)
return context->importedScripts.value();
}
-QV4::ReturnedValue Runtime::method_getQmlSingleton(QV4::NoThrowEngine *engine, int nameIndex)
+QV4::ReturnedValue Runtime::method_loadQmlSingleton(QV4::NoThrowEngine *engine, int nameIndex)
{
Scope scope(engine);
- ScopedString name(scope, engine->current->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedString name(scope, engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[nameIndex]);
return engine->qmlSingletonWrapper(name);
}
-void Runtime::method_convertThisToObject(ExecutionEngine *engine)
-{
- Value *t = &engine->current->callData->thisObject;
- if (t->isObject())
- return;
- if (t->isNullOrUndefined()) {
- *t = engine->globalObject->asReturnedValue();
- } else {
- *t = t->toObject(engine)->asReturnedValue();
- }
-}
-
-ReturnedValue Runtime::method_uPlus(const Value &value)
-{
- TRACE1(value);
-
- if (value.isNumber())
- return value.asReturnedValue();
- if (value.integerCompatible())
- return Encode(value.int_32());
-
- double n = value.toNumberImpl();
- return Encode(n);
-}
-
ReturnedValue Runtime::method_uMinus(const Value &value)
{
TRACE1(value);
// +0 != -0, so we need to convert to double when negating 0
- if (value.isInteger() && value.integerValue())
+ if (value.isInteger() && value.integerValue() &&
+ value.integerValue() != std::numeric_limits<int>::min())
return Encode(-value.integerValue());
else {
double n = RuntimeHelpers::toNumber(value);
@@ -1620,56 +1316,14 @@ ReturnedValue Runtime::method_uMinus(const Value &value)
}
}
-ReturnedValue Runtime::method_complement(const Value &value)
-{
- TRACE1(value);
-
- int n = value.toInt32();
- return Encode((int)~n);
-}
-
-ReturnedValue Runtime::method_uNot(const Value &value)
-{
- TRACE1(value);
-
- bool b = value.toBoolean();
- return Encode(!b);
-}
-
// binary operators
-ReturnedValue Runtime::method_bitOr(const Value &left, const Value &right)
-{
- TRACE2(left, right);
-
- int lval = left.toInt32();
- int rval = right.toInt32();
- return Encode(lval | rval);
-}
-
-ReturnedValue Runtime::method_bitXor(const Value &left, const Value &right)
-{
- TRACE2(left, right);
-
- int lval = left.toInt32();
- int rval = right.toInt32();
- return Encode(lval ^ rval);
-}
-
-ReturnedValue Runtime::method_bitAnd(const Value &left, const Value &right)
-{
- TRACE2(left, right);
-
- int lval = left.toInt32();
- int rval = right.toInt32();
- return Encode(lval & rval);
-}
#ifndef V4_BOOTSTRAP
ReturnedValue Runtime::method_add(ExecutionEngine *engine, const Value &left, const Value &right)
{
TRACE2(left, right);
- if (Q_LIKELY(left.isInteger() && right.isInteger()))
+ if (Q_LIKELY(left.integerCompatible() && right.integerCompatible()))
return add_int32(left.integerValue(), right.integerValue());
if (left.isNumber() && right.isNumber())
return Primitive::fromDouble(left.asDouble() + right.asDouble()).asReturnedValue();
@@ -1682,7 +1336,7 @@ ReturnedValue Runtime::method_sub(const Value &left, const Value &right)
{
TRACE2(left, right);
- if (Q_LIKELY(left.isInteger() && right.isInteger()))
+ if (Q_LIKELY(left.integerCompatible() && right.integerCompatible()))
return sub_int32(left.integerValue(), right.integerValue());
double lval = left.isNumber() ? left.asDouble() : left.toNumberImpl();
@@ -1695,7 +1349,7 @@ ReturnedValue Runtime::method_mul(const Value &left, const Value &right)
{
TRACE2(left, right);
- if (Q_LIKELY(left.isInteger() && right.isInteger()))
+ if (Q_LIKELY(left.integerCompatible() && right.integerCompatible()))
return mul_int32(left.integerValue(), right.integerValue());
double lval = left.isNumber() ? left.asDouble() : left.toNumberImpl();
@@ -1878,11 +1532,6 @@ Bool Runtime::method_compareStrictNotEqual(const Value &left, const Value &right
return ! RuntimeHelpers::strictEqual(left, right);
}
-Bool Runtime::method_toBoolean(const Value &value)
-{
- return value.toBoolean();
-}
-
} // namespace QV4
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4runtime_p.h b/src/qml/jsruntime/qv4runtime_p.h
index 0d787714cf..3a26c23990 100644
--- a/src/qml/jsruntime/qv4runtime_p.h
+++ b/src/qml/jsruntime/qv4runtime_p.h
@@ -83,8 +83,8 @@ private:
};
# define TRACE0() RuntimeCounters::instance->count(Q_FUNC_INFO);
-# define TRACE1(x) RuntimeCounters::instance->count(Q_FUNC_INFO, x->type());
-# define TRACE2(x, y) RuntimeCounters::instance->count(Q_FUNC_INFO, x->type(), y->type());
+# define TRACE1(x) RuntimeCounters::instance->count(Q_FUNC_INFO, x.type());
+# define TRACE2(x, y) RuntimeCounters::instance->count(Q_FUNC_INFO, x.type(), y.type());
#else
# define TRACE0()
# define TRACE1(x)
@@ -99,14 +99,14 @@ enum TypeHint {
struct Q_QML_PRIVATE_EXPORT RuntimeHelpers {
static ReturnedValue objectDefaultValue(const Object *object, int typeHint);
- static ReturnedValue toPrimitive(const Value &value, int typeHint);
+ static ReturnedValue toPrimitive(const Value &value, TypeHint typeHint);
static double stringToNumber(const QString &s);
static Heap::String *stringFromNumber(ExecutionEngine *engine, double number);
static double toNumber(const Value &value);
static void numberToString(QString *result, double num, int radix = 10);
- static Heap::String *convertToString(ExecutionEngine *engine, const Value &value);
+ static Heap::String *convertToString(ExecutionEngine *engine, Value value, TypeHint = STRING_HINT);
static Heap::Object *convertToObject(ExecutionEngine *engine, const Value &value);
static Bool equalHelper(const Value &x, const Value &y);
@@ -118,12 +118,11 @@ struct Q_QML_PRIVATE_EXPORT RuntimeHelpers {
// type conversion and testing
#ifndef V4_BOOTSTRAP
-inline ReturnedValue RuntimeHelpers::toPrimitive(const Value &value, int typeHint)
+inline ReturnedValue RuntimeHelpers::toPrimitive(const Value &value, TypeHint typeHint)
{
- const Object *o = value.as<Object>();
- if (!o)
+ if (!value.isObject())
return value.asReturnedValue();
- return RuntimeHelpers::objectDefaultValue(o, typeHint);
+ return RuntimeHelpers::objectDefaultValue(&reinterpret_cast<const Object &>(value), typeHint);
}
#endif
diff --git a/src/qml/jsruntime/qv4runtimeapi_p.h b/src/qml/jsruntime/qv4runtimeapi_p.h
index 302facba06..ea31dfd08b 100644
--- a/src/qml/jsruntime/qv4runtimeapi_p.h
+++ b/src/qml/jsruntime/qv4runtimeapi_p.h
@@ -58,7 +58,6 @@ namespace QV4 {
typedef uint Bool;
struct NoThrowEngine;
-
namespace {
template <typename T>
struct ExceptionCheck {
@@ -93,84 +92,64 @@ struct ExceptionCheck<void (*)(QV4::NoThrowEngine *, A, B, C)> {
#define FOR_EACH_RUNTIME_METHOD(F) \
/* call */ \
- F(ReturnedValue, callGlobalLookup, (ExecutionEngine *engine, uint index, CallData *callData)) \
- F(ReturnedValue, callActivationProperty, (ExecutionEngine *engine, int nameIndex, CallData *callData)) \
- F(ReturnedValue, callQmlScopeObjectProperty, (ExecutionEngine *engine, int propertyIndex, CallData *callData)) \
- F(ReturnedValue, callQmlContextObjectProperty, (ExecutionEngine *engine, int propertyIndex, CallData *callData)) \
- F(ReturnedValue, callProperty, (ExecutionEngine *engine, int nameIndex, CallData *callData)) \
- F(ReturnedValue, callPropertyLookup, (ExecutionEngine *engine, uint index, CallData *callData)) \
- F(ReturnedValue, callElement, (ExecutionEngine *engine, const Value &index, CallData *callData)) \
- F(ReturnedValue, callValue, (ExecutionEngine *engine, const Value &func, CallData *callData)) \
+ F(ReturnedValue, callGlobalLookup, (ExecutionEngine *engine, uint index, Value *argv, int argc)) \
+ F(ReturnedValue, callName, (ExecutionEngine *engine, int nameIndex, Value *argv, int argc)) \
+ F(ReturnedValue, callProperty, (ExecutionEngine *engine, Value *base, int nameIndex, Value *argv, int argc)) \
+ F(ReturnedValue, callPropertyLookup, (ExecutionEngine *engine, Value *base, uint index, Value *argv, int argc)) \
+ F(ReturnedValue, callElement, (ExecutionEngine *engine, Value *base, const Value &index, Value *argv, int argc)) \
+ F(ReturnedValue, callValue, (ExecutionEngine *engine, const Value &func, Value *argv, int argc)) \
+ F(ReturnedValue, callPossiblyDirectEval, (ExecutionEngine *engine, Value *argv, int argc)) \
\
/* construct */ \
- F(ReturnedValue, constructGlobalLookup, (ExecutionEngine *engine, uint index, CallData *callData)) \
- F(ReturnedValue, constructActivationProperty, (ExecutionEngine *engine, int nameIndex, CallData *callData)) \
- F(ReturnedValue, constructProperty, (ExecutionEngine *engine, int nameIndex, CallData *callData)) \
- F(ReturnedValue, constructPropertyLookup, (ExecutionEngine *engine, uint index, CallData *callData)) \
- F(ReturnedValue, constructValue, (ExecutionEngine *engine, const Value &func, CallData *callData)) \
+ F(ReturnedValue, construct, (ExecutionEngine *engine, const Value &func, Value *argv, int argc)) \
\
- /* set & get */ \
- F(void, setActivationProperty, (ExecutionEngine *engine, int nameIndex, const Value &value)) \
- F(void, setProperty, (ExecutionEngine *engine, const Value &object, int nameIndex, const Value &value)) \
- F(void, setElement, (ExecutionEngine *engine, const Value &object, const Value &index, const Value &value)) \
- F(ReturnedValue, getProperty, (ExecutionEngine *engine, const Value &object, int nameIndex)) \
- F(ReturnedValue, getActivationProperty, (ExecutionEngine *engine, int nameIndex)) \
- F(ReturnedValue, getElement, (ExecutionEngine *engine, const Value &object, const Value &index)) \
+ /* load & store */ \
+ F(void, storeNameStrict, (ExecutionEngine *engine, int nameIndex, const Value &value)) \
+ F(void, storeNameSloppy, (ExecutionEngine *engine, int nameIndex, const Value &value)) \
+ F(bool, storeProperty, (ExecutionEngine *engine, const Value &object, int nameIndex, const Value &value)) \
+ F(bool, storeElement, (ExecutionEngine *engine, const Value &object, const Value &index, const Value &value)) \
+ F(ReturnedValue, loadProperty, (ExecutionEngine *engine, const Value &object, int nameIndex)) \
+ F(ReturnedValue, loadName, (ExecutionEngine *engine, int nameIndex)) \
+ F(ReturnedValue, loadElement, (ExecutionEngine *engine, const Value &object, const Value &index)) \
\
/* typeof */ \
F(ReturnedValue, typeofValue, (ExecutionEngine *engine, const Value &val)) \
F(ReturnedValue, typeofName, (ExecutionEngine *engine, int nameIndex)) \
- F(ReturnedValue, typeofScopeObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex)) \
- F(ReturnedValue, typeofContextObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex)) \
- F(ReturnedValue, typeofMember, (ExecutionEngine *engine, const Value &base, int nameIndex)) \
- F(ReturnedValue, typeofElement, (ExecutionEngine *engine, const Value &base, const Value &index)) \
\
/* delete */ \
- F(ReturnedValue, deleteElement, (ExecutionEngine *engine, const Value &base, const Value &index)) \
- F(ReturnedValue, deleteMember, (ExecutionEngine *engine, const Value &base, int nameIndex)) \
- F(ReturnedValue, deleteMemberString, (ExecutionEngine *engine, const Value &base, String *name)) \
- F(ReturnedValue, deleteName, (ExecutionEngine *engine, int nameIndex)) \
+ F(bool, deleteElement, (ExecutionEngine *engine, const Value &base, const Value &index)) \
+ F(bool, deleteMember, (ExecutionEngine *engine, const Value &base, int nameIndex)) \
+ F(bool, deleteMemberString, (ExecutionEngine *engine, const Value &base, String *name)) \
+ F(bool, deleteName, (ExecutionEngine *engine, int nameIndex)) \
\
/* exceptions & scopes */ \
F(void, throwException, (ExecutionEngine *engine, const Value &value)) \
- F(ReturnedValue, unwindException, (ExecutionEngine *engine)) \
- F(void, pushWithScope, (const Value &o, NoThrowEngine *engine)) \
- F(void, pushCatchScope, (NoThrowEngine *engine, int exceptionVarNameIndex)) \
- F(void, popScope, (NoThrowEngine *engine)) \
+ F(ReturnedValue, createWithContext, (ExecutionContext *parent, const Value &o)) \
+ F(ReturnedValue, createCatchContext, (ExecutionContext *parent, int exceptionVarNameIndex)) \
\
/* closures */ \
F(ReturnedValue, closure, (ExecutionEngine *engine, int functionId)) \
\
/* function header */ \
F(void, declareVar, (ExecutionEngine *engine, bool deletable, int nameIndex)) \
- F(ReturnedValue, setupArgumentsObject, (ExecutionEngine *engine)) \
- F(void, convertThisToObject, (ExecutionEngine *engine)) \
+ F(ReturnedValue, createMappedArgumentsObject, (ExecutionEngine *engine)) \
+ F(ReturnedValue, createUnmappedArgumentsObject, (ExecutionEngine *engine)) \
\
/* literals */ \
F(ReturnedValue, arrayLiteral, (ExecutionEngine *engine, Value *values, uint length)) \
F(ReturnedValue, objectLiteral, (ExecutionEngine *engine, const Value *args, int classId, int arrayValueCount, int arrayGetterSetterCountAndFlags)) \
- F(ReturnedValue, regexpLiteral, (ExecutionEngine *engine, int id)) \
\
/* foreach */ \
F(ReturnedValue, foreachIterator, (ExecutionEngine *engine, const Value &in)) \
F(ReturnedValue, foreachNextPropertyName, (const Value &foreach_iterator)) \
\
/* unary operators */ \
- F(ReturnedValue, uPlus, (const Value &value)) \
F(ReturnedValue, uMinus, (const Value &value)) \
- F(ReturnedValue, uNot, (const Value &value)) \
- F(ReturnedValue, complement, (const Value &value)) \
- F(ReturnedValue, increment, (const Value &value)) \
- F(ReturnedValue, decrement, (const Value &value)) \
\
/* binary operators */ \
F(ReturnedValue, instanceof, (ExecutionEngine *engine, const Value &left, const Value &right)) \
F(ReturnedValue, in, (ExecutionEngine *engine, const Value &left, const Value &right)) \
F(ReturnedValue, add, (ExecutionEngine *engine, const Value &left, const Value &right)) \
- F(ReturnedValue, addString, (ExecutionEngine *engine, const Value &left, const Value &right)) \
- F(ReturnedValue, bitOr, (const Value &left, const Value &right)) \
- F(ReturnedValue, bitXor, (const Value &left, const Value &right)) \
- F(ReturnedValue, bitAnd, (const Value &left, const Value &right)) \
F(ReturnedValue, sub, (const Value &left, const Value &right)) \
F(ReturnedValue, mul, (const Value &left, const Value &right)) \
F(ReturnedValue, div, (const Value &left, const Value &right)) \
@@ -200,28 +179,18 @@ struct ExceptionCheck<void (*)(QV4::NoThrowEngine *, A, B, C)> {
F(Bool, compareInstanceof, (ExecutionEngine *engine, const Value &left, const Value &right)) \
F(Bool, compareIn, (ExecutionEngine *engine, const Value &left, const Value &right)) \
\
- /* conversions */ \
- F(Bool, toBoolean, (const Value &value)) \
- F(ReturnedValue, toDouble, (const Value &value)) \
- F(int, toInt, (const Value &value)) \
- F(int, doubleToInt, (const double &d)) \
- F(unsigned, toUInt, (const Value &value)) \
- F(unsigned, doubleToUInt, (const double &d)) \
+ F(ReturnedValue, regexpLiteral, (ExecutionEngine *engine, int id)) \
\
/* qml */ \
- F(ReturnedValue, getQmlContext, (NoThrowEngine *engine)) \
- F(ReturnedValue, getQmlImportedScripts, (NoThrowEngine *engine)) \
- F(ReturnedValue, getQmlSingleton, (NoThrowEngine *engine, int nameIndex)) \
- F(ReturnedValue, getQmlAttachedProperty, (ExecutionEngine *engine, int attachedPropertiesId, int propertyIndex)) \
- F(ReturnedValue, getQmlScopeObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired)) \
- F(ReturnedValue, getQmlContextObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired)) \
- F(ReturnedValue, getQmlQObjectProperty, (ExecutionEngine *engine, const Value &object, int propertyIndex, bool captureRequired)) \
- F(ReturnedValue, getQmlSingletonQObjectProperty, (ExecutionEngine *engine, const Value &object, int propertyIndex, bool captureRequired)) \
- F(ReturnedValue, getQmlIdObject, (ExecutionEngine *engine, const Value &context, uint index)) \
- \
- F(void, setQmlScopeObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value)) \
- F(void, setQmlContextObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value)) \
- F(void, setQmlQObjectProperty, (ExecutionEngine *engine, const Value &object, int propertyIndex, const Value &value))
+ F(ReturnedValue, loadQmlContext, (NoThrowEngine *engine)) \
+ F(ReturnedValue, loadQmlImportedScripts, (NoThrowEngine *engine)) \
+ F(ReturnedValue, loadQmlSingleton, (NoThrowEngine *engine, int nameIndex)) \
+ F(ReturnedValue, loadQmlScopeObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired)) \
+ F(ReturnedValue, loadQmlContextObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired)) \
+ F(ReturnedValue, loadQmlIdObject, (ExecutionEngine *engine, const Value &context, uint index)) \
+ \
+ F(void, storeQmlScopeObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value)) \
+ F(void, storeQmlContextObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value)) \
struct Q_QML_PRIVATE_EXPORT Runtime {
Runtime();
diff --git a/src/qml/jsruntime/qv4runtimecodegen.cpp b/src/qml/jsruntime/qv4runtimecodegen.cpp
new file mode 100644
index 0000000000..662a780e71
--- /dev/null
+++ b/src/qml/jsruntime/qv4runtimecodegen.cpp
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qv4runtimecodegen_p.h"
+#include "qv4compilerscanfunctions_p.h"
+
+using namespace QV4;
+
+void RuntimeCodegen::generateFromFunctionExpression(const QString &fileName,
+ const QString &sourceCode,
+ AST::FunctionExpression *ast,
+ Compiler::Module *module)
+{
+ _module = module;
+ _module->fileName = fileName;
+ _module->finalUrl = fileName;
+ _context = 0;
+
+ Compiler::ScanFunctions scan(this, sourceCode, Compiler::GlobalCode);
+ // fake a global environment
+ scan.enterEnvironment(0, Compiler::FunctionCode);
+ scan(ast);
+ scan.leaveEnvironment();
+
+ int index = defineFunction(ast->name.toString(), ast, ast->formals, ast->body ? ast->body->elements : 0);
+ _module->rootContext = _module->functions.at(index);
+}
+
+void RuntimeCodegen::throwSyntaxError(const AST::SourceLocation &loc, const QString &detail)
+{
+ if (hasError)
+ return;
+ hasError = true;
+ engine->throwSyntaxError(detail, _module->fileName, loc.startLine, loc.startColumn);
+}
+
+void RuntimeCodegen::throwReferenceError(const AST::SourceLocation &loc, const QString &detail)
+{
+ if (hasError)
+ return;
+ hasError = true;
+ engine->throwReferenceError(detail, _module->fileName, loc.startLine, loc.startColumn);
+}
+
diff --git a/src/qml/jsruntime/qv4runtimecodegen_p.h b/src/qml/jsruntime/qv4runtimecodegen_p.h
new file mode 100644
index 0000000000..be66dc57ca
--- /dev/null
+++ b/src/qml/jsruntime/qv4runtimecodegen_p.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QV4RUNTIMECODEGEN_P_H
+#define QV4RUNTIMECODEGEN_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qv4codegen_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QV4 {
+
+class RuntimeCodegen : public Compiler::Codegen
+{
+public:
+ RuntimeCodegen(ExecutionEngine *engine, Compiler::JSUnitGenerator *jsUnitGenerator, bool strict)
+ : Codegen(jsUnitGenerator, strict)
+ , engine(engine)
+ {}
+
+ void generateFromFunctionExpression(const QString &fileName,
+ const QString &sourceCode,
+ AST::FunctionExpression *ast,
+ Compiler::Module *module);
+
+ void throwSyntaxError(const AST::SourceLocation &loc, const QString &detail) override;
+ void throwReferenceError(const AST::SourceLocation &loc, const QString &detail) override;
+private:
+ ExecutionEngine *engine;
+};
+
+}
+
+QT_END_NAMESPACE
+
+#endif // QV4CODEGEN_P_H
diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h
index 04a0c74133..afb5c21d36 100644
--- a/src/qml/jsruntime/qv4scopedvalue_p.h
+++ b/src/qml/jsruntime/qv4scopedvalue_p.h
@@ -52,7 +52,6 @@
#include "qv4engine_p.h"
#include "qv4value_p.h"
-#include "qv4persistent_p.h"
#include "qv4property_p.h"
#ifdef V4_USE_VALGRIND
@@ -71,56 +70,45 @@ struct ScopedValue;
#define CHECK_EXCEPTION() \
do { \
if (scope.hasException()) { \
- scope.result = QV4::Encode::undefined(); \
- return; \
+ return QV4::Encode::undefined(); \
} \
} while (false)
#define RETURN_UNDEFINED() \
- do { \
- scope.result = QV4::Encode::undefined(); \
- return; \
- } while (false)
+ return QV4::Encode::undefined()
#define RETURN_RESULT(r) \
- do { \
- scope.result = r; \
- return; \
- } while (false)
+ return QV4::Encode(r)
#define THROW_TYPE_ERROR() \
- do { \
- scope.result = scope.engine->throwTypeError(); \
- return; \
- } while (false)
+ return scope.engine->throwTypeError()
#define THROW_GENERIC_ERROR(str) \
- do { \
- scope.result = scope.engine->throwError(QString::fromUtf8(str)); \
- return; \
- } while (false)
+ return scope.engine->throwError(QString::fromUtf8(str))
struct Scope {
- inline Scope(ExecutionContext *ctx)
+ explicit Scope(ExecutionContext *ctx)
: engine(ctx->engine())
, mark(engine->jsStackTop)
- , result(*engine->jsAlloca(1))
{
- result = Encode::undefined();
}
explicit Scope(ExecutionEngine *e)
: engine(e)
, mark(engine->jsStackTop)
- , result(*engine->jsAlloca(1))
{
- result = Encode::undefined();
+ }
+
+ explicit Scope(const Managed *m)
+ : engine(m->engine())
+ , mark(engine->jsStackTop)
+ {
}
~Scope() {
#ifndef QT_NO_DEBUG
Q_ASSERT(engine->jsStackTop >= mark);
- Q_ASSERT(engine->currentContext < mark);
+// Q_ASSERT(engine->currentContext < mark);
memset(mark, 0, (engine->jsStackTop - mark)*sizeof(Value));
#endif
#ifdef V4_USE_VALGRIND
@@ -139,7 +127,6 @@ struct Scope {
ExecutionEngine *engine;
Value *mark;
- Value &result;
private:
Q_DISABLE_COPY(Scope)
@@ -363,27 +350,6 @@ struct Scoped
Value *ptr;
};
-struct ScopedCallData {
- ScopedCallData(const Scope &scope, int argc = 0)
- {
- int size = int(offsetof(QV4::CallData, args)/sizeof(QV4::Value)) + qMax(argc , int(QV4::Global::ReservedArgumentCount));
- ptr = reinterpret_cast<CallData *>(scope.alloc(size));
- ptr->tag = quint32(QV4::Value::ValueTypeInternal::Integer);
- ptr->argc = argc;
- }
-
- CallData *operator->() {
- return ptr;
- }
-
- operator CallData *() const {
- return ptr;
- }
-
- CallData *ptr;
-};
-
-
inline Value &Value::operator =(const ScopedValue &v)
{
_val = v.ptr->rawValue();
@@ -411,25 +377,6 @@ struct ScopedProperty
Property *property;
};
-struct ExecutionContextSaver
-{
- Scope scope; // this makes sure that a reference to context on the JS stack goes out of scope as soon as the context is not used anymore.
- ExecutionContext *savedContext;
-
- ExecutionContextSaver(const Scope &scope)
- : scope(scope.engine)
- {
- savedContext = scope.engine->currentContext;
- }
- ~ExecutionContextSaver()
- {
- Q_ASSERT(scope.engine->jsStackTop > scope.engine->currentContext);
- scope.engine->currentContext = savedContext;
- scope.engine->current = savedContext->d();
- }
-};
-
-
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp
index 9d1d5e2589..0c5f02bcfc 100644
--- a/src/qml/jsruntime/qv4script.cpp
+++ b/src/qml/jsruntime/qv4script.cpp
@@ -45,6 +45,7 @@
#include "qv4debugging_p.h"
#include "qv4profiling_p.h"
#include "qv4scopedvalue_p.h"
+#include "qv4jscall_p.h"
#include <private/qqmljsengine_p.h>
#include <private/qqmljslexer_p.h>
@@ -52,8 +53,7 @@
#include <private/qqmljsast_p.h>
#include <private/qqmlengine_p.h>
#include <private/qv4profiling_p.h>
-#include <qv4jsir_p.h>
-#include <qv4codegen_p.h>
+#include <qv4runtimecodegen_p.h>
#include <QtCore/QDebug>
#include <QtCore/QString>
@@ -61,7 +61,7 @@
using namespace QV4;
Script::Script(ExecutionEngine *v4, QmlContext *qml, CompiledData::CompilationUnit *compilationUnit)
- : line(0), column(0), scope(v4->rootContext()), strictMode(false), inheritContext(true), parsed(false)
+ : line(1), column(0), context(v4->rootContext()), strictMode(false), inheritContext(true), parsed(false)
, compilationUnit(compilationUnit), vmFunction(0), parseAsBinding(true)
{
if (qml)
@@ -81,16 +81,16 @@ void Script::parse()
if (parsed)
return;
- using namespace QQmlJS;
+ using namespace QV4::Compiler;
parsed = true;
- ExecutionEngine *v4 = scope->engine();
+ ExecutionEngine *v4 = context->engine();
Scope valueScope(v4);
- IR::Module module(v4->debugger() != 0);
+ Module module(v4->debugger() != 0);
- QQmlJS::Engine ee, *engine = &ee;
+ Engine ee, *engine = &ee;
Lexer lexer(engine);
lexer.setCode(sourceCode, line, parseAsBinding);
Parser parser(engine);
@@ -98,7 +98,7 @@ void Script::parse()
const bool parsed = parser.parseProgram();
const auto diagnosticMessages = parser.diagnosticMessages();
- for (const QQmlJS::DiagnosticMessage &m : diagnosticMessages) {
+ for (const DiagnosticMessage &m : diagnosticMessages) {
if (m.isError()) {
valueScope.engine->throwSyntaxError(m.message, sourceFile, m.loc.startLine, m.loc.startColumn);
return;
@@ -117,26 +117,15 @@ void Script::parse()
return;
}
- QStringList inheritedLocals;
- if (inheritContext) {
- Scoped<CallContext> ctx(valueScope, scope);
- if (ctx) {
- for (Identifier * const *i = ctx->variables(), * const *ei = i + ctx->variableCount(); i < ei; ++i)
- inheritedLocals.append(*i ? (*i)->string : QString());
- }
- }
-
- RuntimeCodegen cg(v4, strictMode);
- cg.generateFromProgram(sourceFile, sourceFile, sourceCode, program, &module,
- QQmlJS::Codegen::EvalCode, inheritedLocals);
+ QV4::Compiler::JSUnitGenerator jsGenerator(&module);
+ RuntimeCodegen cg(v4, &jsGenerator, strictMode);
+ if (inheritContext)
+ cg.setUseFastLookups(false);
+ cg.generateFromProgram(sourceFile, sourceFile, sourceCode, program, &module, compilationMode);
if (v4->hasException)
return;
- QV4::Compiler::JSUnitGenerator jsGenerator(&module);
- QScopedPointer<EvalInstructionSelection> isel(v4->iselFactory->create(QQmlEnginePrivate::get(v4), v4->executableAllocator, &module, &jsGenerator));
- if (inheritContext)
- isel->setUseFastLookups(false);
- compilationUnit = isel->compile();
+ compilationUnit = cg.generateCompilationUnit();
vmFunction = compilationUnit->linkToEngine(v4);
}
@@ -154,29 +143,16 @@ ReturnedValue Script::run()
if (!vmFunction)
return Encode::undefined();
- QV4::ExecutionEngine *engine = scope->engine();
+ QV4::ExecutionEngine *engine = context->engine();
QV4::Scope valueScope(engine);
if (qmlContext.isUndefined()) {
TemporaryAssignment<Function*> savedGlobalCode(engine->globalCode, vmFunction);
- ExecutionContextSaver ctxSaver(valueScope);
- ContextStateSaver stateSaver(valueScope, scope);
- scope->d()->strictMode = vmFunction->isStrict();
- scope->d()->lookups = vmFunction->compilationUnit->runtimeLookups;
- scope->d()->constantTable = vmFunction->compilationUnit->constants;
- scope->d()->compilationUnit = vmFunction->compilationUnit;
-
- return Q_V4_PROFILE(engine, vmFunction);
+ return vmFunction->call(engine->globalObject, 0, 0, context);
} else {
Scoped<QmlContext> qml(valueScope, qmlContext.value());
- ScopedCallData callData(valueScope);
- callData->thisObject = Primitive::undefinedValue();
- if (vmFunction->canUseSimpleFunction())
- qml->simpleCall(valueScope, callData, vmFunction);
- else
- qml->call(valueScope, callData, vmFunction);
- return valueScope.result.asReturnedValue();
+ return vmFunction->call(0, 0, 0, qml);
}
}
@@ -187,27 +163,26 @@ Function *Script::function()
return vmFunction;
}
-QQmlRefPointer<QV4::CompiledData::CompilationUnit> Script::precompile(
- IR::Module *module, Compiler::JSUnitGenerator *unitGenerator, ExecutionEngine *engine,
- const QString &fileName, const QString &finalUrl, const QString &source,
- QList<QQmlError> *reportedErrors, QQmlJS::Directives *directivesCollector)
+QQmlRefPointer<QV4::CompiledData::CompilationUnit> Script::precompile(QV4::Compiler::Module *module, Compiler::JSUnitGenerator *unitGenerator,
+ const QString &fileName, const QString &finalUrl, const QString &source,
+ QList<QQmlError> *reportedErrors, Directives *directivesCollector)
{
- using namespace QQmlJS;
+ using namespace QV4::Compiler;
using namespace QQmlJS::AST;
- QQmlJS::Engine ee;
+ Engine ee;
if (directivesCollector)
ee.setDirectives(directivesCollector);
- QQmlJS::Lexer lexer(&ee);
+ Lexer lexer(&ee);
lexer.setCode(source, /*line*/1, /*qml mode*/false);
- QQmlJS::Parser parser(&ee);
+ Parser parser(&ee);
parser.parseProgram();
QList<QQmlError> errors;
const auto diagnosticMessages = parser.diagnosticMessages();
- for (const QQmlJS::DiagnosticMessage &m : diagnosticMessages) {
+ for (const DiagnosticMessage &m : diagnosticMessages) {
if (m.isWarning()) {
qWarning("%s:%d : %s", qPrintable(fileName), m.loc.startLine, qPrintable(m.message));
continue;
@@ -234,8 +209,9 @@ QQmlRefPointer<QV4::CompiledData::CompilationUnit> Script::precompile(
return 0;
}
- QQmlJS::Codegen cg(/*strict mode*/false);
- cg.generateFromProgram(fileName, finalUrl, source, program, module, QQmlJS::Codegen::EvalCode);
+ Codegen cg(unitGenerator, /*strict mode*/false);
+ cg.setUseFastLookups(false);
+ cg.generateFromProgram(fileName, finalUrl, source, program, module, GlobalCode);
errors = cg.qmlErrors();
if (!errors.isEmpty()) {
if (reportedErrors)
@@ -243,9 +219,28 @@ QQmlRefPointer<QV4::CompiledData::CompilationUnit> Script::precompile(
return 0;
}
- QScopedPointer<EvalInstructionSelection> isel(engine->iselFactory->create(QQmlEnginePrivate::get(engine), engine->executableAllocator, module, unitGenerator));
- isel->setUseFastLookups(false);
- return isel->compile(/*generate unit data*/false);
+ return cg.generateCompilationUnit(/*generate unit data*/false);
+}
+
+Script *Script::createFromFileOrCache(ExecutionEngine *engine, QmlContext *qmlContext, const QString &fileName, const QUrl &originalUrl)
+{
+ if (const QV4::CompiledData::Unit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(originalUrl)) {
+ QQmlRefPointer<QV4::CompiledData::CompilationUnit> jsUnit;
+ jsUnit.adopt(new QV4::CompiledData::CompilationUnit(cachedUnit));
+ return new QV4::Script(engine, qmlContext, jsUnit);
+ }
+
+ QFile f(fileName);
+ if (!f.open(QIODevice::ReadOnly))
+ return nullptr;
+
+ QByteArray data = f.readAll();
+ QString sourceCode = QString::fromUtf8(data);
+ QmlIR::Document::removeScriptPragmas(sourceCode);
+
+ auto result = new QV4::Script(engine, qmlContext, sourceCode, originalUrl.toString());
+ result->parse();
+ return result;
}
QV4::ReturnedValue Script::evaluate(ExecutionEngine *engine, const QString &script, QmlContext *qmlContext)
diff --git a/src/qml/jsruntime/qv4script_p.h b/src/qml/jsruntime/qv4script_p.h
index 55a349b5fc..6ba405f828 100644
--- a/src/qml/jsruntime/qv4script_p.h
+++ b/src/qml/jsruntime/qv4script_p.h
@@ -54,6 +54,7 @@
#include "qv4engine_p.h"
#include "qv4functionobject_p.h"
#include "qv4qmlcontext_p.h"
+#include "private/qv4compilercontext_p.h"
#include <QQmlError>
@@ -61,60 +62,16 @@ QT_BEGIN_NAMESPACE
class QQmlContextData;
-namespace QQmlJS {
-class Directives;
-}
-
namespace QV4 {
-struct ContextStateSaver {
- Value *savedContext;
- bool strictMode;
- Lookup *lookups;
- const QV4::Value *constantTable;
- CompiledData::CompilationUnitBase *compilationUnit;
- int lineNumber;
-
- ContextStateSaver(const Scope &scope, ExecutionContext *context)
- : savedContext(scope.alloc(1))
- , strictMode(context->d()->strictMode)
- , lookups(context->d()->lookups)
- , constantTable(context->d()->constantTable)
- , compilationUnit(context->d()->compilationUnit)
- , lineNumber(context->d()->lineNumber)
- {
- savedContext->setM(context->d());
- }
- ContextStateSaver(const Scope &scope, Heap::ExecutionContext *context)
- : savedContext(scope.alloc(1))
- , strictMode(context->strictMode)
- , lookups(context->lookups)
- , constantTable(context->constantTable)
- , compilationUnit(context->compilationUnit)
- , lineNumber(context->lineNumber)
- {
- savedContext->setM(context);
- }
-
- ~ContextStateSaver()
- {
- Heap::ExecutionContext *ctx = static_cast<Heap::ExecutionContext *>(savedContext->m());
- ctx->strictMode = strictMode;
- ctx->lookups = lookups;
- ctx->constantTable = constantTable;
- ctx->compilationUnit = compilationUnit;
- ctx->lineNumber = lineNumber;
- }
-};
-
struct Q_QML_EXPORT Script {
- Script(ExecutionContext *scope, const QString &sourceCode, const QString &source = QString(), int line = 1, int column = 0)
+ Script(ExecutionContext *scope, QV4::Compiler::CompilationMode mode, const QString &sourceCode, const QString &source = QString(), int line = 1, int column = 0)
: sourceFile(source), line(line), column(column), sourceCode(sourceCode)
- , scope(scope), strictMode(false), inheritContext(false), parsed(false)
+ , context(scope), strictMode(false), inheritContext(false), parsed(false), compilationMode(mode)
, vmFunction(0), parseAsBinding(false) {}
Script(ExecutionEngine *engine, QmlContext *qml, const QString &sourceCode, const QString &source = QString(), int line = 1, int column = 0)
: sourceFile(source), line(line), column(column), sourceCode(sourceCode)
- , scope(engine->rootContext()), strictMode(false), inheritContext(true), parsed(false)
+ , context(engine->rootContext()), strictMode(false), inheritContext(true), parsed(false)
, vmFunction(0), parseAsBinding(true) {
if (qml)
qmlContext.set(engine, *qml);
@@ -125,10 +82,11 @@ struct Q_QML_EXPORT Script {
int line;
int column;
QString sourceCode;
- ExecutionContext *scope;
+ ExecutionContext *context;
bool strictMode;
bool inheritContext;
bool parsed;
+ QV4::Compiler::CompilationMode compilationMode = QV4::Compiler::EvalCode;
QV4::PersistentValue qmlContext;
QQmlRefPointer<CompiledData::CompilationUnit> compilationUnit;
Function *vmFunction;
@@ -140,9 +98,10 @@ struct Q_QML_EXPORT Script {
Function *function();
static QQmlRefPointer<CompiledData::CompilationUnit> precompile(
- IR::Module *module, Compiler::JSUnitGenerator *unitGenerator, ExecutionEngine *engine,
+ QV4::Compiler::Module *module, Compiler::JSUnitGenerator *unitGenerator,
const QString &fileName, const QString &finalUrl, const QString &source,
QList<QQmlError> *reportedErrors = 0, QQmlJS::Directives *directivesCollector = 0);
+ static Script *createFromFileOrCache(ExecutionEngine *engine, QmlContext *qmlContext, const QString &fileName, const QUrl &originalUrl);
static ReturnedValue evaluate(ExecutionEngine *engine, const QString &script, QmlContext *qmlContext);
};
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp
index 8ce10e326d..78413f1b0e 100644
--- a/src/qml/jsruntime/qv4sequenceobject.cpp
+++ b/src/qml/jsruntime/qv4sequenceobject.cpp
@@ -45,6 +45,7 @@
#include <private/qv4arrayobject_p.h>
#include <private/qqmlengine_p.h>
#include <private/qv4scopedvalue_p.h>
+#include <private/qv4jscall_p.h>
#include "qv4runtime_p.h"
#include "qv4objectiterator_p.h"
#include <private/qqmlvaluetypewrapper_p.h>
@@ -66,10 +67,10 @@ static void generateWarning(QV4::ExecutionEngine *v4, const QString& description
QQmlError retn;
retn.setDescription(description);
- QV4::StackFrame frame = v4->currentStackFrame();
+ QV4::CppStackFrame *stackFrame = v4->currentStackFrame;
- retn.setLine(frame.line);
- retn.setUrl(QUrl(frame.source));
+ retn.setLine(stackFrame->lineNumber());
+ retn.setUrl(QUrl(stackFrame->source()));
QQmlEnginePrivate::warning(engine, retn);
}
@@ -78,13 +79,22 @@ static void generateWarning(QV4::ExecutionEngine *v4, const QString& description
F(int, IntVector, QVector<int>, 0) \
F(qreal, RealVector, QVector<qreal>, 0.0) \
F(bool, BoolVector, QVector<bool>, false) \
+ F(int, IntStdVector, std::vector<int>, 0) \
+ F(qreal, RealStdVector, std::vector<qreal>, 0.0) \
+ F(bool, BoolStdVector, std::vector<bool>, false) \
F(int, Int, QList<int>, 0) \
F(qreal, Real, QList<qreal>, 0.0) \
F(bool, Bool, QList<bool>, false) \
F(QString, String, QList<QString>, QString()) \
F(QString, QString, QStringList, QString()) \
+ F(QString, StringVector, QVector<QString>, QString()) \
+ F(QString, StringStdVector, std::vector<QString>, QString()) \
F(QUrl, Url, QList<QUrl>, QUrl()) \
+ F(QUrl, UrlVector, QVector<QUrl>, QUrl()) \
+ F(QUrl, UrlStdVector, std::vector<QUrl>, QUrl()) \
F(QModelIndex, QModelIndex, QModelIndexList, QModelIndex()) \
+ F(QModelIndex, QModelIndexVector, QVector<QModelIndex>, QModelIndex()) \
+ F(QModelIndex, QModelIndexStdVector, std::vector<QModelIndex>, QModelIndex()) \
F(QItemSelectionRange, QItemSelectionRange, QItemSelection, QItemSelectionRange())
static QV4::ReturnedValue convertElementToValue(QV4::ExecutionEngine *engine, const QString &element)
@@ -263,56 +273,54 @@ public:
}
loadReference();
}
- qint32 signedIdx = static_cast<qint32>(index);
- if (signedIdx < d()->container->count()) {
+ if (index < size_t(d()->container->size())) {
if (hasProperty)
*hasProperty = true;
- return convertElementToValue(engine(), d()->container->at(signedIdx));
+ return convertElementToValue(engine(), qAsConst(*(d()->container))[index]);
}
if (hasProperty)
*hasProperty = false;
return Encode::undefined();
}
- void containerPutIndexed(uint index, const QV4::Value &value)
+ bool containerPutIndexed(uint index, const QV4::Value &value)
{
if (internalClass()->engine->hasException)
- return;
+ return false;
/* Qt containers have int (rather than uint) allowable indexes. */
if (index > INT_MAX) {
generateWarning(engine(), QLatin1String("Index out of range during indexed set"));
- return;
+ return false;
}
if (d()->isReference) {
if (!d()->object)
- return;
+ return false;
loadReference();
}
- qint32 signedIdx = static_cast<qint32>(index);
-
- int count = d()->container->count();
+ size_t count = size_t(d()->container->size());
typename Container::value_type element = convertValueToElement<typename Container::value_type>(value);
- if (signedIdx == count) {
- d()->container->append(element);
- } else if (signedIdx < count) {
- (*d()->container)[signedIdx] = element;
+ if (index == count) {
+ d()->container->push_back(element);
+ } else if (index < count) {
+ (*d()->container)[index] = element;
} else {
/* according to ECMA262r3 we need to insert */
/* the value at the given index, increasing length to index+1. */
- d()->container->reserve(signedIdx + 1);
- while (signedIdx > count++) {
- d()->container->append(typename Container::value_type());
+ d()->container->reserve(index + 1);
+ while (index > count++) {
+ d()->container->push_back(typename Container::value_type());
}
- d()->container->append(element);
+ d()->container->push_back(element);
}
if (d()->isReference)
storeReference();
+ return true;
}
QV4::PropertyAttributes containerQueryIndexed(uint index) const
@@ -327,8 +335,7 @@ public:
return QV4::Attr_Invalid;
loadReference();
}
- qint32 signedIdx = static_cast<qint32>(index);
- return (signedIdx < d()->container->count()) ? QV4::Attr_Data : QV4::Attr_Invalid;
+ return (index < size_t(d()->container->size())) ? QV4::Attr_Data : QV4::Attr_Invalid;
}
void containerAdvanceIterator(ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attrs)
@@ -344,7 +351,7 @@ public:
loadReference();
}
- if (it->arrayIndex < static_cast<uint>(d()->container->count())) {
+ if (it->arrayIndex < static_cast<uint>(d()->container->size())) {
*index = it->arrayIndex;
++it->arrayIndex;
*attrs = QV4::Attr_Data;
@@ -364,14 +371,13 @@ public:
return false;
loadReference();
}
- qint32 signedIdx = static_cast<qint32>(index);
- if (signedIdx >= d()->container->count())
+ if (index >= size_t(d()->container->size()))
return false;
/* according to ECMA262r3 it should be Undefined, */
/* but we cannot, so we insert a default-value instead. */
- d()->container->replace(signedIdx, typename Container::value_type());
+ (*d()->container)[index] = typename Container::value_type();
if (d()->isReference)
storeReference();
@@ -411,13 +417,14 @@ public:
bool operator()(typename Container::value_type lhs, typename Container::value_type rhs)
{
QV4::Scope scope(m_v4);
- ScopedObject compare(scope, m_compareFn);
- ScopedCallData callData(scope, 2);
- callData->args[0] = convertElementToValue(m_v4, lhs);
- callData->args[1] = convertElementToValue(m_v4, rhs);
- callData->thisObject = m_v4->globalObject;
- compare->call(scope, callData);
- return scope.result.toNumber() < 0;
+ ScopedFunctionObject compare(scope, m_compareFn);
+ if (!compare)
+ return m_v4->throwTypeError();
+ Value *argv = scope.alloc(2);
+ argv[0] = convertElementToValue(m_v4, lhs);
+ argv[1] = convertElementToValue(m_v4, rhs);
+ QV4::ScopedValue result(scope, compare->call(m_v4->globalObject, argv, 2));
+ return result->toNumber() < 0;
}
private:
@@ -425,7 +432,7 @@ public:
const QV4::Value *m_compareFn;
};
- void sort(const BuiltinFunction *, Scope &scope, CallData *callData)
+ void sort(const FunctionObject *f, const Value *, const Value *argv, int argc)
{
if (d()->isReference) {
if (!d()->object)
@@ -433,8 +440,8 @@ public:
loadReference();
}
- if (callData->argc == 1 && callData->args[0].as<FunctionObject>()) {
- CompareFunctor cf(scope.engine, callData->args[0]);
+ if (argc == 1 && argv[0].as<FunctionObject>()) {
+ CompareFunctor cf(f->engine(), argv[0]);
std::sort(d()->container->begin(), d()->container->end(), cf);
} else {
DefaultCompareFunctor cf;
@@ -445,9 +452,10 @@ public:
storeReference();
}
- static void method_get_length(const BuiltinFunction *, Scope &scope, CallData *callData)
+ static QV4::ReturnedValue method_get_length(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- QV4::Scoped<QQmlSequence<Container> > This(scope, callData->thisObject.as<QQmlSequence<Container> >());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQmlSequence<Container>> This(scope, thisObject->as<QQmlSequence<Container> >());
if (!This)
THROW_TYPE_ERROR();
@@ -456,16 +464,17 @@ public:
RETURN_RESULT(Encode(0));
This->loadReference();
}
- RETURN_RESULT(Encode(This->d()->container->count()));
+ RETURN_RESULT(Encode(qint32(This->d()->container->size())));
}
- static void method_set_length(const BuiltinFunction *, Scope &scope, CallData *callData)
+ static QV4::ReturnedValue method_set_length(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
{
- QV4::Scoped<QQmlSequence<Container> > This(scope, callData->thisObject.as<QQmlSequence<Container> >());
+ QV4::Scope scope(f);
+ QV4::Scoped<QQmlSequence<Container>> This(scope, thisObject->as<QQmlSequence<Container> >());
if (!This)
THROW_TYPE_ERROR();
- quint32 newLength = callData->args[0].toUInt32();
+ quint32 newLength = argc ? argv[0].toUInt32() : 0;
/* Qt containers have int (rather than uint) allowable indexes. */
if (newLength > INT_MAX) {
generateWarning(scope.engine, QLatin1String("Index out of range during length set"));
@@ -478,8 +487,8 @@ public:
This->loadReference();
}
/* Determine whether we need to modify the sequence */
- qint32 newCount = static_cast<qint32>(newLength);
- qint32 count = This->d()->container->count();
+ quint32 newCount = static_cast<quint32>(newLength);
+ quint32 count = static_cast<quint32>(This->d()->container->size());
if (newCount == count) {
RETURN_UNDEFINED();
} else if (newCount > count) {
@@ -488,14 +497,13 @@ public:
/* We cannot, so we insert default-values instead. */
This->d()->container->reserve(newCount);
while (newCount > count++) {
- This->d()->container->append(typename Container::value_type());
+ This->d()->container->push_back(typename Container::value_type());
}
} else {
/* according to ECMA262r3 we need to remove */
/* elements until the sequence is the required length. */
- while (newCount < count) {
- count--;
- This->d()->container->removeAt(count);
+ if (newCount < count) {
+ This->d()->container->erase(This->d()->container->begin() + newCount, This->d()->container->end());
}
}
/* write back if required. */
@@ -516,10 +524,13 @@ public:
quint32 length = array->getLength();
QV4::ScopedValue v(scope);
for (quint32 i = 0; i < length; ++i)
- result << convertValueToElement<typename Container::value_type>((v = array->getIndexed(i)));
+ result.push_back(convertValueToElement<typename Container::value_type>((v = array->getIndexed(i))));
return QVariant::fromValue(result);
}
+ void* getRawContainerPtr() const
+ { return d()->container; }
+
void loadReference() const
{
Q_ASSERT(d()->object);
@@ -540,8 +551,8 @@ public:
static QV4::ReturnedValue getIndexed(const QV4::Managed *that, uint index, bool *hasProperty)
{ return static_cast<const QQmlSequence<Container> *>(that)->containerGetIndexed(index, hasProperty); }
- static void putIndexed(Managed *that, uint index, const QV4::Value &value)
- { static_cast<QQmlSequence<Container> *>(that)->containerPutIndexed(index, value); }
+ static bool putIndexed(Managed *that, uint index, const QV4::Value &value)
+ { return static_cast<QQmlSequence<Container> *>(that)->containerPutIndexed(index, value); }
static QV4::PropertyAttributes queryIndexed(const QV4::Managed *that, uint index)
{ return static_cast<const QQmlSequence<Container> *>(that)->containerQueryIndexed(index); }
static bool deleteIndexedProperty(QV4::Managed *that, uint index)
@@ -594,16 +605,34 @@ typedef QQmlSequence<QVector<qreal> > QQmlRealVectorList;
DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlRealVectorList);
typedef QQmlSequence<QVector<bool> > QQmlBoolVectorList;
DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlBoolVectorList);
+typedef QQmlSequence<std::vector<int> > QQmlIntStdVectorList;
+DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlIntStdVectorList);
+typedef QQmlSequence<std::vector<qreal> > QQmlRealStdVectorList;
+DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlRealStdVectorList);
+typedef QQmlSequence<std::vector<bool> > QQmlBoolStdVectorList;
+DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlBoolStdVectorList);
typedef QQmlSequence<QStringList> QQmlQStringList;
DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlQStringList);
typedef QQmlSequence<QList<QString> > QQmlStringList;
DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlStringList);
+typedef QQmlSequence<QVector<QString> > QQmlStringVectorList;
+DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlStringVectorList);
+typedef QQmlSequence<std::vector<QString> > QQmlStringStdVectorList;
+DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlStringStdVectorList);
typedef QQmlSequence<QList<int> > QQmlIntList;
DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlIntList);
typedef QQmlSequence<QList<QUrl> > QQmlUrlList;
DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlUrlList);
+typedef QQmlSequence<QVector<QUrl> > QQmlUrlVectorList;
+DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlUrlVectorList);
+typedef QQmlSequence<std::vector<QUrl> > QQmlUrlStdVectorList;
+DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlUrlStdVectorList);
typedef QQmlSequence<QModelIndexList> QQmlQModelIndexList;
DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlQModelIndexList);
+typedef QQmlSequence<QVector<QModelIndex> > QQmlQModelIndexVectorList;
+DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlQModelIndexVectorList);
+typedef QQmlSequence<std::vector<QModelIndex> > QQmlQModelIndexStdVectorList;
+DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlQModelIndexStdVectorList);
typedef QQmlSequence<QItemSelection> QQmlQItemSelectionRangeList;
DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlQItemSelectionRangeList);
typedef QQmlSequence<QList<bool> > QQmlBoolList;
@@ -622,25 +651,31 @@ void SequencePrototype::init()
}
#undef REGISTER_QML_SEQUENCE_METATYPE
-void SequencePrototype::method_sort(const BuiltinFunction *b, Scope &scope, CallData *callData)
+ReturnedValue SequencePrototype::method_valueOf(const FunctionObject *f, const Value *thisObject, const Value *, int)
{
- QV4::ScopedObject o(scope, callData->thisObject);
+ return Encode(thisObject->toString(f->engine()));
+}
+
+ReturnedValue SequencePrototype::method_sort(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
+{
+ Scope scope(b);
+ QV4::ScopedObject o(scope, thisObject);
if (!o || !o->isListType())
THROW_TYPE_ERROR();
- if (callData->argc >= 2)
- RETURN_RESULT(o);
+ if (argc >= 2)
+ return o.asReturnedValue();
#define CALL_SORT(SequenceElementType, SequenceElementTypeName, SequenceType, DefaultValue) \
if (QQml##SequenceElementTypeName##List *s = o->as<QQml##SequenceElementTypeName##List>()) { \
- s->sort(b, scope, callData); \
+ s->sort(b, thisObject, argv, argc); \
} else
FOREACH_QML_SEQUENCE_TYPE(CALL_SORT)
#undef CALL_SORT
{}
- RETURN_RESULT(o);
+ return o.asReturnedValue();
}
#define IS_SEQUENCE(unused1, unused2, SequenceType, unused3) \
@@ -724,6 +759,19 @@ QVariant SequencePrototype::toVariant(const QV4::Value &array, int typeHint, boo
#undef SEQUENCE_TO_VARIANT
+#define SEQUENCE_GET_RAWCONTAINERPTR(ElementType, ElementTypeName, SequenceType, unused) \
+ if (const QQml##ElementTypeName##List *list = [&]() -> const QQml##ElementTypeName##List* \
+ { if (typeHint == qMetaTypeId<SequenceType>()) return object->as<QQml##ElementTypeName##List>(); return nullptr;}()) \
+ return list->getRawContainerPtr(); \
+ else
+
+void* SequencePrototype::getRawContainerPtr(const Object *object, int typeHint)
+{
+ FOREACH_QML_SEQUENCE_TYPE(SEQUENCE_GET_RAWCONTAINERPTR) { /* else */ return nullptr; }
+}
+
+#undef SEQUENCE_GET_RAWCONTAINERPTR
+
#define MAP_META_TYPE(ElementType, ElementTypeName, SequenceType, unused) \
if (object->as<QQml##ElementTypeName##List>()) { \
return qMetaTypeId<SequenceType>(); \
diff --git a/src/qml/jsruntime/qv4sequenceobject_p.h b/src/qml/jsruntime/qv4sequenceobject_p.h
index 0879f149fa..e9bef2f604 100644
--- a/src/qml/jsruntime/qv4sequenceobject_p.h
+++ b/src/qml/jsruntime/qv4sequenceobject_p.h
@@ -68,12 +68,8 @@ struct SequencePrototype : public QV4::Object
V4_PROTOTYPE(arrayPrototype)
void init();
- static void method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData)
- {
- scope.result = callData->thisObject.toString(scope.engine);
- }
-
- static void method_sort(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_valueOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_sort(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
static bool isSequenceType(int sequenceTypeId);
static ReturnedValue newSequence(QV4::ExecutionEngine *engine, int sequenceTypeId, QObject *object, int propertyIndex, bool *succeeded);
@@ -81,6 +77,7 @@ struct SequencePrototype : public QV4::Object
static int metaTypeForSequence(const Object *object);
static QVariant toVariant(Object *object);
static QVariant toVariant(const Value &array, int typeHint, bool *succeeded);
+ static void* getRawContainerPtr(const Object *object, int typeHint);
};
}
diff --git a/src/qml/jsruntime/qv4sparsearray.cpp b/src/qml/jsruntime/qv4sparsearray.cpp
index 8f6aa6723c..f295e74adc 100644
--- a/src/qml/jsruntime/qv4sparsearray.cpp
+++ b/src/qml/jsruntime/qv4sparsearray.cpp
@@ -395,6 +395,7 @@ void SparseArray::freeTree(SparseArrayNode *root, int alignment)
SparseArray::SparseArray()
: numEntries(0)
{
+ freeList = Primitive::emptyValue(UINT_MAX).asReturnedValue();
header.p = 0;
header.left = 0;
header.right = 0;
@@ -410,6 +411,7 @@ SparseArray::SparseArray(const SparseArray &other)
header.left->setParent(&header);
recalcMostLeftNode();
}
+ freeList = other.freeList;
}
SparseArrayNode *SparseArray::insert(uint akey)
diff --git a/src/qml/jsruntime/qv4sparsearray_p.h b/src/qml/jsruntime/qv4sparsearray_p.h
index 2e4ac883f2..ca6abcda89 100644
--- a/src/qml/jsruntime/qv4sparsearray_p.h
+++ b/src/qml/jsruntime/qv4sparsearray_p.h
@@ -150,6 +150,8 @@ struct Q_QML_EXPORT SparseArray
}
SparseArray(const SparseArray &other);
+
+ ReturnedValue freeList;
private:
SparseArray &operator=(const SparseArray &other);
diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp
index 515d61c8e4..40280534c4 100644
--- a/src/qml/jsruntime/qv4string.cpp
+++ b/src/qml/jsruntime/qv4string.cpp
@@ -52,17 +52,25 @@ using namespace QV4;
#ifndef V4_BOOTSTRAP
-DEFINE_MANAGED_VTABLE(String);
-
-void String::markObjects(Heap::Base *that, ExecutionEngine *e)
+void Heap::String::markObjects(Heap::Base *that, MarkStack *markStack)
{
- String::Data *s = static_cast<String::Data *>(that);
- if (s->largestSubLength) {
- s->left->mark(e);
- s->right->mark(e);
+ String *s = static_cast<String *>(that);
+ if (s->subtype < StringType_Complex)
+ return;
+
+ ComplexString *cs = static_cast<ComplexString *>(s);
+ if (cs->subtype == StringType_AddedString) {
+ cs->left->mark(markStack);
+ cs->right->mark(markStack);
+ } else {
+ Q_ASSERT(cs->subtype == StringType_SubString);
+ cs->left->mark(markStack);
}
}
+DEFINE_MANAGED_VTABLE(String);
+
+
bool String::isEqualTo(Managed *t, Managed *o)
{
if (t == o)
@@ -83,37 +91,45 @@ void Heap::String::init(const QString &t)
text = const_cast<QString &>(t).data_ptr();
text->ref.ref();
- identifier = 0;
- stringHash = UINT_MAX;
- largestSubLength = 0;
- len = text->size;
}
-void Heap::String::init(String *l, String *r)
+void Heap::ComplexString::init(String *l, String *r)
{
Base::init();
- subtype = String::StringType_Unknown;
+ subtype = String::StringType_AddedString;
left = l;
right = r;
- stringHash = UINT_MAX;
- largestSubLength = qMax(l->largestSubLength, r->largestSubLength);
- len = l->len + r->len;
- Q_ASSERT(largestSubLength <= len);
-
- if (!l->largestSubLength && l->len > largestSubLength)
- largestSubLength = l->len;
- if (!r->largestSubLength && r->len > largestSubLength)
- largestSubLength = r->len;
+ len = left->length() + right->length();
+ if (left->subtype >= StringType_Complex)
+ largestSubLength = static_cast<ComplexString *>(left)->largestSubLength;
+ else
+ largestSubLength = left->length();
+ if (right->subtype >= StringType_Complex)
+ largestSubLength = qMax(largestSubLength, static_cast<ComplexString *>(right)->largestSubLength);
+ else
+ largestSubLength = qMax(largestSubLength, right->length());
// make sure we don't get excessive depth in our strings
if (len > 256 && len >= 2*largestSubLength)
simplifyString();
}
+void Heap::ComplexString::init(Heap::String *ref, int from, int len)
+{
+ Q_ASSERT(ref->length() >= from + len);
+ Base::init();
+
+ subtype = String::StringType_SubString;
+
+ left = ref;
+ this->from = from;
+ this->len = len;
+}
+
void Heap::String::destroy() {
- if (!largestSubLength) {
+ if (text) {
internalClass->engine->memoryManager->changeUnmanagedHeapSizeUsage(qptrdiff(-text->size) * (int)sizeof(QChar));
if (!text->ref.deref())
QStringData::deallocate(text);
@@ -125,7 +141,7 @@ uint String::toUInt(bool *ok) const
{
*ok = true;
- if (subtype() == Heap::String::StringType_Unknown)
+ if (subtype() >= Heap::String::StringType_Unknown)
d()->createHashValue();
if (subtype() == Heap::String::StringType_ArrayIndex)
return d()->stringHash;
@@ -141,15 +157,15 @@ uint String::toUInt(bool *ok) const
void String::makeIdentifierImpl() const
{
- if (d()->largestSubLength)
+ if (!d()->text)
d()->simplifyString();
- Q_ASSERT(!d()->largestSubLength);
+ Q_ASSERT(d()->text);
engine()->identifierTable->identifier(this);
}
void Heap::String::simplifyString() const
{
- Q_ASSERT(largestSubLength);
+ Q_ASSERT(!text);
int l = length();
QString result(l, Qt::Uninitialized);
@@ -157,9 +173,33 @@ void Heap::String::simplifyString() const
append(this, ch);
text = result.data_ptr();
text->ref.ref();
+ const ComplexString *cs = static_cast<const ComplexString *>(this);
identifier = 0;
- largestSubLength = 0;
+ cs->left = cs->right = nullptr;
+
internalClass->engine->memoryManager->changeUnmanagedHeapSizeUsage(qptrdiff(text->size) * (qptrdiff)sizeof(QChar));
+ subtype = StringType_Unknown;
+}
+
+bool Heap::String::startsWithUpper() const
+{
+ if (subtype == StringType_AddedString)
+ return static_cast<const Heap::ComplexString *>(this)->left->startsWithUpper();
+
+ const Heap::String *str = this;
+ int offset = 0;
+ if (subtype == StringType_SubString) {
+ const ComplexString *cs = static_cast<const Heap::ComplexString *>(this);
+ if (!cs->len)
+ return false;
+ // simplification here is not ideal, but hopefully not a common case.
+ if (cs->left->subtype >= Heap::String::StringType_Complex)
+ cs->left->simplifyString();
+ str = cs->left;
+ offset = cs->from;
+ }
+ Q_ASSERT(str->subtype < Heap::String::StringType_Complex);
+ return str->text->size > offset && QChar::isUpper(str->text->data()[offset]);
}
void Heap::String::append(const String *data, QChar *ch)
@@ -172,9 +212,14 @@ void Heap::String::append(const String *data, QChar *ch)
const String *item = worklist.back();
worklist.pop_back();
- if (item->largestSubLength) {
- worklist.push_back(item->right);
- worklist.push_back(item->left);
+ if (item->subtype == StringType_AddedString) {
+ const ComplexString *cs = static_cast<const ComplexString *>(item);
+ worklist.push_back(cs->right);
+ worklist.push_back(cs->left);
+ } else if (item->subtype == StringType_SubString) {
+ const ComplexString *cs = static_cast<const ComplexString *>(item);
+ memcpy(ch, cs->left->toQString().constData() + cs->from, cs->len*sizeof(QChar));
+ ch += cs->len;
} else {
memcpy(ch, item->text->data(), item->text->size * sizeof(QChar));
ch += item->text->size;
@@ -184,9 +229,9 @@ void Heap::String::append(const String *data, QChar *ch)
void Heap::String::createHashValue() const
{
- if (largestSubLength)
+ if (!text)
simplifyString();
- Q_ASSERT(!largestSubLength);
+ Q_ASSERT(text);
const QChar *ch = reinterpret_cast<const QChar *>(text->data());
const QChar *end = ch + text->size;
stringHash = QV4::String::calculateHashValue(ch, end, &subtype);
diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h
index f5311ae5d4..679cb7329c 100644
--- a/src/qml/jsruntime/qv4string_p.h
+++ b/src/qml/jsruntime/qv4string_p.h
@@ -65,36 +65,34 @@ struct Identifier;
namespace Heap {
struct Q_QML_PRIVATE_EXPORT String : Base {
+ static void markObjects(Heap::Base *that, MarkStack *markStack);
enum StringType {
- StringType_Unknown,
StringType_Regular,
- StringType_ArrayIndex
+ StringType_ArrayIndex,
+ StringType_Unknown,
+ StringType_AddedString,
+ StringType_SubString,
+ StringType_Complex = StringType_AddedString
};
#ifndef V4_BOOTSTRAP
void init(const QString &text);
- void init(String *l, String *n);
void destroy();
void simplifyString() const;
- int length() const {
- Q_ASSERT((largestSubLength &&
- (len == left->len + right->len)) ||
- len == (uint)text->size);
- return len;
- }
+ int length() const;
std::size_t retainedTextSize() const {
- return largestSubLength ? 0 : (std::size_t(text->size) * sizeof(QChar));
+ return subtype >= StringType_Complex ? 0 : (std::size_t(text->size) * sizeof(QChar));
}
void createHashValue() const;
inline unsigned hashValue() const {
- if (subtype == StringType_Unknown)
+ if (subtype >= StringType_Unknown)
createHashValue();
- Q_ASSERT(!largestSubLength);
+ Q_ASSERT(subtype < StringType_Complex);
return stringHash;
}
inline QString toQString() const {
- if (largestSubLength)
+ if (subtype >= StringType_Complex)
simplifyString();
QStringDataPtr ptr = { text };
text->ref.ref();
@@ -105,7 +103,7 @@ struct Q_QML_PRIVATE_EXPORT String : Base {
return true;
if (hashValue() != other->hashValue())
return false;
- Q_ASSERT(!largestSubLength);
+ Q_ASSERT(subtype < StringType_Complex);
if (identifier && identifier == other->identifier)
return true;
if (subtype == Heap::String::StringType_ArrayIndex && other->subtype == Heap::String::StringType_ArrayIndex)
@@ -114,23 +112,37 @@ struct Q_QML_PRIVATE_EXPORT String : Base {
return toQString() == other->toQString();
}
- union {
- mutable QStringData *text;
- mutable String *left;
- };
- union {
- mutable Identifier *identifier;
- mutable String *right;
- };
+ bool startsWithUpper() const;
+
+ mutable QStringData *text;
+ mutable Identifier *identifier;
mutable uint subtype;
mutable uint stringHash;
- mutable uint largestSubLength;
- uint len;
private:
static void append(const String *data, QChar *ch);
#endif
};
-V4_ASSERT_IS_TRIVIAL(String)
+Q_STATIC_ASSERT(std::is_trivial< String >::value);
+
+#ifndef V4_BOOTSTRAP
+struct ComplexString : String {
+ void init(String *l, String *n);
+ void init(String *ref, int from, int len);
+ mutable String *left;
+ mutable String *right;
+ union {
+ mutable int largestSubLength;
+ int from;
+ };
+ int len;
+};
+Q_STATIC_ASSERT(std::is_trivial< ComplexString >::value);
+
+inline
+int String::length() const {
+ return text ? text->size : static_cast<const ComplexString *>(this)->len;
+}
+#endif
}
@@ -166,9 +178,9 @@ struct Q_QML_PRIVATE_EXPORT String : public Managed {
return d()->hashValue();
}
uint asArrayIndex() const {
- if (subtype() == Heap::String::StringType_Unknown)
+ if (subtype() >= Heap::String::StringType_Unknown)
d()->createHashValue();
- Q_ASSERT(!d()->largestSubLength);
+ Q_ASSERT(d()->subtype < Heap::String::StringType_Complex);
if (subtype() == Heap::String::StringType_ArrayIndex)
return d()->stringHash;
return UINT_MAX;
@@ -181,7 +193,8 @@ struct Q_QML_PRIVATE_EXPORT String : public Managed {
makeIdentifierImpl();
}
- void makeIdentifierImpl() const;
+ // slow path
+ Q_NEVER_INLINE void makeIdentifierImpl() const;
static uint createHashValue(const QChar *ch, int length, uint *subtype)
{
@@ -195,17 +208,11 @@ struct Q_QML_PRIVATE_EXPORT String : public Managed {
return calculateHashValue(ch, end, subtype);
}
- bool startsWithUpper() const {
- const String::Data *l = d();
- while (l->largestSubLength)
- l = l->left;
- return l->text->size && QChar::isUpper(l->text->data()[0]);
- }
+ bool startsWithUpper() const { return d()->startsWithUpper(); }
Identifier *identifier() const { return d()->identifier; }
protected:
- static void markObjects(Heap::Base *that, ExecutionEngine *e);
static bool isEqualTo(Managed *that, Managed *o);
static uint getLength(const Managed *m);
#endif
@@ -215,7 +222,7 @@ public:
private:
static inline uint toUInt(const QChar *ch) { return ch->unicode(); }
- static inline uint toUInt(const char *ch) { return *ch; }
+ static inline uint toUInt(const char *ch) { return static_cast<unsigned char>(*ch); }
template <typename T>
static inline uint toArrayIndex(const T *ch, const T *end)
@@ -262,12 +269,22 @@ public:
}
};
+#ifndef V4_BOOTSTRAP
+struct ComplexString : String {
+ typedef QV4::Heap::ComplexString Data;
+ QV4::Heap::ComplexString *d_unchecked() const { return static_cast<QV4::Heap::ComplexString *>(m()); }
+ QV4::Heap::ComplexString *d() const {
+ QV4::Heap::ComplexString *dptr = d_unchecked();
+ dptr->_checkIsInitialized();
+ return dptr;
+ }
+};
+
template<>
inline const String *Value::as() const {
return isManaged() && m()->vtable()->isString ? static_cast<const String *>(this) : 0;
}
-#ifndef V4_BOOTSTRAP
template<>
inline ReturnedValue value_convert<String>(ExecutionEngine *e, const Value &v)
{
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index 7ccb7a762f..8125aa53b2 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -45,17 +45,11 @@
#include <private/qv4mm_p.h>
#include "qv4scopedvalue_p.h"
#include "qv4alloca_p.h"
+#include "qv4jscall_p.h"
#include <QtCore/QDateTime>
#include <QtCore/QDebug>
#include <QtCore/QStringList>
-#include <private/qqmljsengine_p.h>
-#include <private/qqmljslexer_p.h>
-#include <private/qqmljsparser_p.h>
-#include <private/qqmljsast_p.h>
-#include <qv4jsir_p.h>
-#include <qv4codegen_p.h>
-
#include <cassert>
#ifndef Q_OS_WIN
@@ -77,15 +71,15 @@ void Heap::StringObject::init()
{
Object::init();
Q_ASSERT(vtable() == QV4::StringObject::staticVTable());
- string = internalClass->engine->id_empty()->d();
- *propertyData(LengthPropertyIndex) = Primitive::fromInt32(0);
+ string.set(internalClass->engine, internalClass->engine->id_empty()->d());
+ setProperty(internalClass->engine, LengthPropertyIndex, Primitive::fromInt32(0));
}
void Heap::StringObject::init(const QV4::String *str)
{
Object::init();
- string = str->d();
- *propertyData(LengthPropertyIndex) = Primitive::fromInt32(length());
+ string.set(internalClass->engine, str->d());
+ setProperty(internalClass->engine, LengthPropertyIndex, Primitive::fromInt32(length()));
}
Heap::String *Heap::StringObject::getIndex(uint index) const
@@ -98,7 +92,7 @@ Heap::String *Heap::StringObject::getIndex(uint index) const
uint Heap::StringObject::length() const
{
- return string->len;
+ return string->length();
}
bool StringObject::deleteIndexedProperty(Managed *m, uint index)
@@ -108,11 +102,8 @@ bool StringObject::deleteIndexedProperty(Managed *m, uint index)
Scoped<StringObject> o(scope, m->as<StringObject>());
Q_ASSERT(!!o);
- if (index < static_cast<uint>(o->d()->string->toQString().length())) {
- if (v4->current->strictMode)
- v4->throwTypeError();
+ if (index < static_cast<uint>(o->d()->string->toQString().length()))
return false;
- }
return true;
}
@@ -145,13 +136,6 @@ void StringObject::advanceIterator(Managed *m, ObjectIterator *it, Value *name,
return Object::advanceIterator(m, it, name, index, p, attrs);
}
-void StringObject::markObjects(Heap::Base *that, ExecutionEngine *e)
-{
- StringObject::Data *o = static_cast<StringObject::Data *>(that);
- o->string->mark(e);
- Object::markObjects(that, e);
-}
-
DEFINE_OBJECT_VTABLE(StringCtor);
void Heap::StringCtor::init(QV4::ExecutionContext *scope)
@@ -159,24 +143,25 @@ void Heap::StringCtor::init(QV4::ExecutionContext *scope)
Heap::FunctionObject::init(scope, QStringLiteral("String"));
}
-void StringCtor::construct(const Managed *m, Scope &scope, CallData *callData)
+ReturnedValue StringCtor::callAsConstructor(const FunctionObject *f, const Value *argv, int argc)
{
- ExecutionEngine *v4 = static_cast<const Object *>(m)->engine();
+ ExecutionEngine *v4 = static_cast<const Object *>(f)->engine();
+ Scope scope(v4);
ScopedString value(scope);
- if (callData->argc)
- value = callData->args[0].toString(v4);
+ if (argc)
+ value = argv[0].toString(v4);
else
value = v4->newString();
- scope.result = Encode(v4->newStringObject(value));
+ return Encode(v4->newStringObject(value));
}
-void StringCtor::call(const Managed *, Scope &scope, CallData *callData)
+ReturnedValue StringCtor::call(const FunctionObject *m, const Value *, const Value *argv, int argc)
{
- ExecutionEngine *v4 = scope.engine;
- if (callData->argc)
- scope.result = callData->args[0].toString(v4);
+ ExecutionEngine *v4 = m->engine();
+ if (argc)
+ return argv[0].toString(v4)->asReturnedValue();
else
- scope.result = v4->newString();
+ return v4->newString()->asReturnedValue();
}
void StringPrototype::init(ExecutionEngine *engine, Object *ctor)
@@ -200,6 +185,7 @@ void StringPrototype::init(ExecutionEngine *engine, Object *ctor)
defineDefaultProperty(QStringLiteral("lastIndexOf"), method_lastIndexOf, 1);
defineDefaultProperty(QStringLiteral("localeCompare"), method_localeCompare, 1);
defineDefaultProperty(QStringLiteral("match"), method_match, 1);
+ defineDefaultProperty(QStringLiteral("repeat"), method_repeat, 1);
defineDefaultProperty(QStringLiteral("replace"), method_replace, 2);
defineDefaultProperty(QStringLiteral("search"), method_search, 1);
defineDefaultProperty(QStringLiteral("slice"), method_slice, 2);
@@ -214,140 +200,163 @@ void StringPrototype::init(ExecutionEngine *engine, Object *ctor)
defineDefaultProperty(QStringLiteral("trim"), method_trim);
}
-static QString getThisString(Scope &scope, CallData *callData)
+static Heap::String *thisAsString(ExecutionEngine *v4, const Value *thisObject)
{
- ScopedValue t(scope, callData->thisObject);
- if (String *s = t->stringValue())
+ if (String *s = thisObject->stringValue())
+ return s->d();
+ if (const StringObject *thisString = thisObject->as<StringObject>())
+ return thisString->d()->string;
+ return thisObject->toString(v4);
+}
+
+static QString getThisString(ExecutionEngine *v4, const Value *thisObject)
+{
+ if (String *s = thisObject->stringValue())
return s->toQString();
- if (StringObject *thisString = t->as<StringObject>())
+ if (const StringObject *thisString = thisObject->as<StringObject>())
return thisString->d()->string->toQString();
- if (t->isUndefined() || t->isNull()) {
- scope.engine->throwTypeError();
+ if (thisObject->isUndefined() || thisObject->isNull()) {
+ v4->throwTypeError();
return QString();
}
- return t->toQString();
+ return thisObject->toQString();
}
-void StringPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue StringPrototype::method_toString(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- if (callData->thisObject.isString())
- RETURN_RESULT(callData->thisObject);
+ if (thisObject->isString())
+ return thisObject->asReturnedValue();
- StringObject *o = callData->thisObject.as<StringObject>();
+ ExecutionEngine *v4 = b->engine();
+ const StringObject *o = thisObject->as<StringObject>();
if (!o)
- THROW_TYPE_ERROR();
- scope.result = o->d()->string;
+ return v4->throwTypeError();
+ return o->d()->string->asReturnedValue();
}
-void StringPrototype::method_charAt(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue StringPrototype::method_charAt(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- const QString str = getThisString(scope, callData);
- CHECK_EXCEPTION();
+ ExecutionEngine *v4 = b->engine();
+ const QString str = getThisString(v4, thisObject);
+ if (v4->hasException)
+ return QV4::Encode::undefined();
int pos = 0;
- if (callData->argc > 0)
- pos = (int) callData->args[0].toInteger();
+ if (argc > 0)
+ pos = (int) argv[0].toInteger();
QString result;
if (pos >= 0 && pos < str.length())
result += str.at(pos);
- scope.result = scope.engine->newString(result);
+ return Encode(v4->newString(result));
}
-void StringPrototype::method_charCodeAt(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue StringPrototype::method_charCodeAt(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- const QString str = getThisString(scope, callData);
- CHECK_EXCEPTION();
+ ExecutionEngine *v4 = b->engine();
+ const QString str = getThisString(v4, thisObject);
+ if (v4->hasException)
+ return QV4::Encode::undefined();
int pos = 0;
- if (callData->argc > 0)
- pos = (int) callData->args[0].toInteger();
+ if (argc > 0)
+ pos = (int) argv[0].toInteger();
if (pos >= 0 && pos < str.length())
RETURN_RESULT(Encode(str.at(pos).unicode()));
- scope.result = Encode(qt_qnan());
+ return Encode(qt_qnan());
}
-void StringPrototype::method_concat(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue StringPrototype::method_concat(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- QString value = getThisString(scope, callData);
- CHECK_EXCEPTION();
+ ExecutionEngine *v4 = b->engine();
+ QString value = getThisString(v4, thisObject);
+ if (v4->hasException)
+ return QV4::Encode::undefined();
+ Scope scope(v4);
ScopedString s(scope);
- for (int i = 0; i < callData->argc; ++i) {
- s = callData->args[i].toString(scope.engine);
- CHECK_EXCEPTION();
+ for (int i = 0; i < argc; ++i) {
+ s = argv[i].toString(scope.engine);
+ if (v4->hasException)
+ return QV4::Encode::undefined();
Q_ASSERT(s->isString());
value += s->toQString();
}
- scope.result = scope.engine->newString(value);
+ return Encode(v4->newString(value));
}
-void StringPrototype::method_endsWith(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue StringPrototype::method_endsWith(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- QString value = getThisString(scope, callData);
- CHECK_EXCEPTION();
+ ExecutionEngine *v4 = b->engine();
+ const QString value = getThisString(v4, thisObject);
+ if (v4->hasException)
+ return QV4::Encode::undefined();
QString searchString;
- if (callData->argc) {
- if (callData->args[0].as<RegExpObject>())
- THROW_TYPE_ERROR();
- searchString = callData->args[0].toQString();
+ if (argc) {
+ if (argv[0].as<RegExpObject>())
+ return v4->throwTypeError();
+ searchString = argv[0].toQString();
}
int pos = value.length();
- if (callData->argc > 1)
- pos = (int) callData->args[1].toInteger();
+ if (argc > 1)
+ pos = (int) argv[1].toInteger();
if (pos == value.length())
RETURN_RESULT(Encode(value.endsWith(searchString)));
QStringRef stringToSearch = value.leftRef(pos);
- scope.result = Encode(stringToSearch.endsWith(searchString));
+ return Encode(stringToSearch.endsWith(searchString));
}
-void StringPrototype::method_indexOf(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue StringPrototype::method_indexOf(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- QString value = getThisString(scope, callData);
- CHECK_EXCEPTION();
+ ExecutionEngine *v4 = b->engine();
+ const QString value = getThisString(v4, thisObject);
+ if (v4->hasException)
+ return QV4::Encode::undefined();
QString searchString;
- if (callData->argc)
- searchString = callData->args[0].toQString();
+ if (argc)
+ searchString = argv[0].toQString();
int pos = 0;
- if (callData->argc > 1)
- pos = (int) callData->args[1].toInteger();
+ if (argc > 1)
+ pos = (int) argv[1].toInteger();
int index = -1;
if (! value.isEmpty())
index = value.indexOf(searchString, qMin(qMax(pos, 0), value.length()));
- scope.result = Encode(index);
+ return Encode(index);
}
-void StringPrototype::method_includes(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue StringPrototype::method_includes(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- QString value = getThisString(scope, callData);
- CHECK_EXCEPTION();
+ ExecutionEngine *v4 = b->engine();
+ const QString value = getThisString(v4, thisObject);
+ if (v4->hasException)
+ return QV4::Encode::undefined();
QString searchString;
- if (callData->argc) {
- if (callData->args[0].as<RegExpObject>())
- THROW_TYPE_ERROR();
- searchString = callData->args[0].toQString();
+ if (argc) {
+ if (argv[0].as<RegExpObject>())
+ return v4->throwTypeError();
+ searchString = argv[0].toQString();
}
int pos = 0;
- if (callData->argc > 1) {
- ScopedValue posArg(scope, callData->argument(1));
- pos = (int) posArg->toInteger();
- if (!posArg->isInteger() && posArg->isNumber() && qIsInf(posArg->toNumber()))
+ if (argc > 1) {
+ const Value &posArg = argv[1];
+ pos = (int) posArg.toInteger();
+ if (!posArg.isInteger() && posArg.isNumber() && qIsInf(posArg.toNumber()))
pos = value.length();
}
@@ -355,20 +364,21 @@ void StringPrototype::method_includes(const BuiltinFunction *, Scope &scope, Cal
RETURN_RESULT(Encode(value.contains(searchString)));
QStringRef stringToSearch = value.midRef(pos);
- scope.result = Encode(stringToSearch.contains(searchString));
+ return Encode(stringToSearch.contains(searchString));
}
-void StringPrototype::method_lastIndexOf(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue StringPrototype::method_lastIndexOf(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- const QString value = getThisString(scope, callData);
- CHECK_EXCEPTION();
+ ExecutionEngine *v4 = b->engine();
+ const QString value = getThisString(v4, thisObject);
+ if (v4->hasException)
+ return QV4::Encode::undefined();
QString searchString;
- if (callData->argc)
- searchString = callData->args[0].toQString();
+ if (argc)
+ searchString = argv[0].toQString();
- ScopedValue posArg(scope, callData->argument(1));
- double position = RuntimeHelpers::toNumber(posArg);
+ double position = argc > 1 ? RuntimeHelpers::toNumber(argv[1]) : +qInf();
if (std::isnan(position))
position = +qInf();
else
@@ -380,82 +390,84 @@ void StringPrototype::method_lastIndexOf(const BuiltinFunction *, Scope &scope,
if (searchString.isNull() && pos == 0)
RETURN_RESULT(Encode(-1));
int index = value.lastIndexOf(searchString, pos);
- scope.result = Encode(index);
+ return Encode(index);
}
-void StringPrototype::method_localeCompare(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue StringPrototype::method_localeCompare(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- const QString value = getThisString(scope, callData);
- CHECK_EXCEPTION();
+ ExecutionEngine *v4 = b->engine();
+ const QString value = getThisString(v4, thisObject);
+ if (v4->hasException)
+ return QV4::Encode::undefined();
- ScopedValue v(scope, callData->argument(0));
- const QString that = v->toQString();
- scope.result = Encode(QString::localeAwareCompare(value, that));
+ const QString that = (argc ? argv[0] : Primitive::undefinedValue()).toQString();
+ return Encode(QString::localeAwareCompare(value, that));
}
-void StringPrototype::method_match(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue StringPrototype::method_match(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- if (callData->thisObject.isUndefined() || callData->thisObject.isNull())
- THROW_TYPE_ERROR();
+ ExecutionEngine *v4 = b->engine();
+ if (thisObject->isNullOrUndefined())
+ return v4->throwTypeError();
- ScopedString s(scope, callData->thisObject.toString(scope.engine));
-
- ScopedValue regexp(scope, callData->argument(0));
- Scoped<RegExpObject> rx(scope, regexp);
- if (!rx) {
- ScopedCallData callData(scope, 1);
- callData->args[0] = regexp;
- scope.engine->regExpCtor()->construct(scope, callData);
- rx = scope.result.asReturnedValue();
+ Scope scope(v4);
+ ScopedString s(scope, thisObject->toString(v4));
+ if (v4->hasException)
+ return Encode::undefined();
+
+ Scoped<RegExpObject> that(scope, argc ? argv[0] : Primitive::undefinedValue());
+ if (!that) {
+ // convert args[0] to a regexp
+ that = RegExpCtor::callAsConstructor(b, argv, argc);
+ if (v4->hasException)
+ return Encode::undefined();
}
+ Q_ASSERT(!!that);
- if (!rx)
- // ### CHECK
- THROW_TYPE_ERROR();
-
- bool global = rx->global();
+ bool global = that->global();
- // ### use the standard builtin function, not the one that might be redefined in the proto
- ScopedString execString(scope, scope.engine->newString(QStringLiteral("exec")));
- ScopedFunctionObject exec(scope, scope.engine->regExpPrototype()->get(execString));
+ if (!global)
+ return RegExpPrototype::method_exec(b, that, s, 1);
- ScopedCallData cData(scope, 1);
- cData->thisObject = rx;
- cData->args[0] = s;
- if (!global) {
- exec->call(scope, cData);
- return;
- }
-
- ScopedString lastIndex(scope, scope.engine->newString(QStringLiteral("lastIndex")));
- rx->put(lastIndex, ScopedValue(scope, Primitive::fromInt32(0)));
+ // rx is now in thisObject
+ that->setLastIndex(0);
ScopedArrayObject a(scope, scope.engine->newArrayObject());
- double previousLastIndex = 0;
+ int previousLastIndex = 0;
uint n = 0;
- ScopedValue matchStr(scope);
- ScopedValue index(scope);
while (1) {
- exec->call(scope, cData);
- if (scope.result.isNull())
+ Value result = Primitive::fromReturnedValue(RegExpPrototype::execFirstMatch(b, that, s, 1));
+ if (result.isNull())
break;
- assert(scope.result.isObject());
- index = rx->get(lastIndex, 0);
- double thisIndex = index->toInteger();
- if (previousLastIndex == thisIndex) {
- previousLastIndex = thisIndex + 1;
- rx->put(lastIndex, ScopedValue(scope, Primitive::fromDouble(previousLastIndex)));
+ int index = that->lastIndex();
+ if (previousLastIndex == index) {
+ previousLastIndex = index + 1;
+ that->setLastIndex(previousLastIndex);
} else {
- previousLastIndex = thisIndex;
+ previousLastIndex = index;
}
- matchStr = scope.result.objectValue()->getIndexed(0);
- a->arraySet(n, matchStr);
+ a->arraySet(n, result);
++n;
}
if (!n)
- scope.result = Encode::null();
+ return Encode::null();
else
- scope.result = a;
+ return a.asReturnedValue();
+}
+
+ReturnedValue StringPrototype::method_repeat(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
+{
+ ExecutionEngine *v4 = b->engine();
+ const QString value = getThisString(v4, thisObject);
+ if (v4->hasException)
+ return QV4::Encode::undefined();
+
+ double repeats = (argc ? argv[0] : Primitive::undefinedValue()).toInteger();
+
+ if (repeats < 0 || qIsInf(repeats))
+ return v4->throwRangeError(QLatin1String("Invalid count value"));
+
+ return Encode(v4->newString(value.repeated(int(repeats))));
}
static void appendReplacementString(QString *result, const QString &input, const QString& replaceValue, uint* matchOffsets, int captureCount)
@@ -504,13 +516,13 @@ static void appendReplacementString(QString *result, const QString &input, const
}
}
-void StringPrototype::method_replace(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue StringPrototype::method_replace(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
QString string;
- if (StringObject *thisString = callData->thisObject.as<StringObject>())
+ if (const StringObject *thisString = thisObject->as<StringObject>())
string = thisString->d()->string->toQString();
else
- string = callData->thisObject.toQString();
+ string = thisObject->toQString();
int numCaptures = 0;
int numStringMatches = 0;
@@ -519,7 +531,8 @@ void StringPrototype::method_replace(const BuiltinFunction *, Scope &scope, Call
uint _matchOffsets[64];
uint *matchOffsets = _matchOffsets;
- ScopedValue searchValue(scope, callData->argument(0));
+ Scope scope(b);
+ ScopedValue searchValue(scope, argc ? argv[0] : Primitive::undefinedValue());
Scoped<RegExpObject> regExp(scope, searchValue);
if (regExp) {
uint offset = 0;
@@ -547,7 +560,7 @@ void StringPrototype::method_replace(const BuiltinFunction *, Scope &scope, Call
offset = qMax(offset + 1, matchOffsets[oldSize + 1]);
}
if (regExp->global())
- *regExp->lastIndexProperty() = Primitive::fromUInt32(0);
+ regExp->setLastIndex(0);
numStringMatches = nMatchOffsets / (regExp->value()->captureCount() * 2);
numCaptures = regExp->value()->captureCount();
} else {
@@ -562,14 +575,14 @@ void StringPrototype::method_replace(const BuiltinFunction *, Scope &scope, Call
}
QString result;
- ScopedValue replaceValue(scope, callData->argument(1));
+ ScopedValue replacement(scope);
+ ScopedValue replaceValue(scope, argc > 1 ? argv[1] : Primitive::undefinedValue());
ScopedFunctionObject searchCallback(scope, replaceValue);
if (!!searchCallback) {
result.reserve(string.length() + 10*numStringMatches);
- ScopedCallData callData(scope, numCaptures + 2);
- callData->thisObject = Primitive::undefinedValue();
- int lastEnd = 0;
ScopedValue entry(scope);
+ Value *arguments = scope.alloc(numCaptures + 2);
+ int lastEnd = 0;
for (int i = 0; i < numStringMatches; ++i) {
for (int k = 0; k < numCaptures; ++k) {
int idx = (i * numCaptures + k) * 2;
@@ -578,17 +591,18 @@ void StringPrototype::method_replace(const BuiltinFunction *, Scope &scope, Call
entry = Primitive::undefinedValue();
if (start != JSC::Yarr::offsetNoMatch && end != JSC::Yarr::offsetNoMatch)
entry = scope.engine->newString(string.mid(start, end - start));
- callData->args[k] = entry;
+ arguments[k] = entry;
}
uint matchStart = matchOffsets[i * numCaptures * 2];
Q_ASSERT(matchStart >= static_cast<uint>(lastEnd));
uint matchEnd = matchOffsets[i * numCaptures * 2 + 1];
- callData->args[numCaptures] = Primitive::fromUInt32(matchStart);
- callData->args[numCaptures + 1] = scope.engine->newString(string);
+ arguments[numCaptures] = Primitive::fromUInt32(matchStart);
+ arguments[numCaptures + 1] = scope.engine->newString(string);
- searchCallback->call(scope, callData);
+ Value that = Primitive::undefinedValue();
+ replacement = searchCallback->call(&that, arguments, numCaptures + 2);
result += string.midRef(lastEnd, matchStart - lastEnd);
- result += scope.result.toQString();
+ result += replacement->toQString();
lastEnd = matchEnd;
}
result += string.midRef(lastEnd);
@@ -614,44 +628,47 @@ void StringPrototype::method_replace(const BuiltinFunction *, Scope &scope, Call
if (matchOffsets != _matchOffsets)
free(matchOffsets);
- scope.result = scope.engine->newString(result);
+ return Encode(scope.engine->newString(result));
}
-void StringPrototype::method_search(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue StringPrototype::method_search(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- QString string = getThisString(scope, callData);
- scope.result = callData->argument(0);
- CHECK_EXCEPTION();
+ Scope scope(b);
+ QString string = getThisString(scope.engine, thisObject);
+ if (scope.engine->hasException)
+ return QV4::Encode::undefined();
- Scoped<RegExpObject> regExp(scope, scope.result.as<RegExpObject>());
+ Scoped<RegExpObject> regExp(scope, argc ? argv[0] : Primitive::undefinedValue());
if (!regExp) {
- ScopedCallData callData(scope, 1);
- callData->args[0] = scope.result;
- scope.engine->regExpCtor()->construct(scope, callData);
- CHECK_EXCEPTION();
+ regExp = scope.engine->regExpCtor()->callAsConstructor(argv, 1);
+ if (scope.engine->hasException)
+ return QV4::Encode::undefined();
- regExp = scope.result.as<RegExpObject>();
Q_ASSERT(regExp);
}
Scoped<RegExp> re(scope, regExp->value());
Q_ALLOCA_VAR(uint, matchOffsets, regExp->value()->captureCount() * 2 * sizeof(uint));
uint result = re->match(string, /*offset*/0, matchOffsets);
if (result == JSC::Yarr::offsetNoMatch)
- scope.result = Encode(-1);
+ return Encode(-1);
else
- scope.result = Encode(result);
+ return Encode(result);
}
-void StringPrototype::method_slice(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue StringPrototype::method_slice(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- const QString text = getThisString(scope, callData);
- CHECK_EXCEPTION();
+ ExecutionEngine *v4 = b->engine();
+ Scope scope(v4);
+ ScopedString s(scope, thisAsString(v4, thisObject));
+ if (v4->hasException)
+ return QV4::Encode::undefined();
+ Q_ASSERT(s);
- const double length = text.length();
+ const double length = s->d()->length();
- double start = callData->argc ? callData->args[0].toInteger() : 0;
- double end = (callData->argc < 2 || callData->args[1].isUndefined())
- ? length : callData->args[1].toInteger();
+ double start = argc ? argv[0].toInteger() : 0;
+ double end = (argc < 2 || argv[1].isUndefined())
+ ? length : argv[1].toInteger();
if (start < 0)
start = qMax(length + start, 0.);
@@ -667,16 +684,19 @@ void StringPrototype::method_slice(const BuiltinFunction *, Scope &scope, CallDa
const int intEnd = int(end);
int count = qMax(0, intEnd - intStart);
- scope.result = scope.engine->newString(text.mid(intStart, count));
+ return Encode(v4->memoryManager->alloc<ComplexString>(s->d(), intStart, count));
}
-void StringPrototype::method_split(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue StringPrototype::method_split(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- QString text = getThisString(scope, callData);
- CHECK_EXCEPTION();
+ ExecutionEngine *v4 = b->engine();
+ QString text = getThisString(v4, thisObject);
+ if (v4->hasException)
+ return QV4::Encode::undefined();
- ScopedValue separatorValue(scope, callData->argument(0));
- ScopedValue limitValue(scope, callData->argument(1));
+ Scope scope(v4);
+ ScopedValue separatorValue(scope, argc ? argv[0] : Primitive::undefinedValue());
+ ScopedValue limitValue(scope, argc > 1 ? argv[1] : Primitive::undefinedValue());
ScopedArrayObject array(scope, scope.engine->newArrayObject());
@@ -684,7 +704,7 @@ void StringPrototype::method_split(const BuiltinFunction *, Scope &scope, CallDa
if (limitValue->isUndefined()) {
ScopedString s(scope, scope.engine->newString(text));
array->push_back(s);
- RETURN_RESULT(array);
+ return array.asReturnedValue();
}
RETURN_RESULT(scope.engine->newString(text.left(limitValue->toInteger())));
}
@@ -692,7 +712,7 @@ void StringPrototype::method_split(const BuiltinFunction *, Scope &scope, CallDa
uint limit = limitValue->isUndefined() ? UINT_MAX : limitValue->toUInt32();
if (limit == 0)
- RETURN_RESULT(array);
+ return array.asReturnedValue();
Scoped<RegExpObject> re(scope, separatorValue);
if (re) {
@@ -733,7 +753,7 @@ void StringPrototype::method_split(const BuiltinFunction *, Scope &scope, CallDa
if (separator.isEmpty()) {
for (uint i = 0; i < qMin(limit, uint(text.length())); ++i)
array->push_back((s = scope.engine->newString(text.mid(i, 1))));
- RETURN_RESULT(array);
+ return array.asReturnedValue();
}
int start = 0;
@@ -747,44 +767,48 @@ void StringPrototype::method_split(const BuiltinFunction *, Scope &scope, CallDa
if (array->getLength() < limit && start != -1)
array->push_back((s = scope.engine->newString(text.mid(start))));
}
- RETURN_RESULT(array);
+ return array.asReturnedValue();
}
-void StringPrototype::method_startsWith(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue StringPrototype::method_startsWith(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- QString value = getThisString(scope, callData);
- CHECK_EXCEPTION();
+ ExecutionEngine *v4 = b->engine();
+ const QString value = getThisString(v4, thisObject);
+ if (v4->hasException)
+ return QV4::Encode::undefined();
QString searchString;
- if (callData->argc) {
- if (callData->args[0].as<RegExpObject>())
- THROW_TYPE_ERROR();
- searchString = callData->args[0].toQString();
+ if (argc) {
+ if (argv[0].as<RegExpObject>())
+ return v4->throwTypeError();
+ searchString = argv[0].toQString();
}
int pos = 0;
- if (callData->argc > 1)
- pos = (int) callData->args[1].toInteger();
+ if (argc > 1)
+ pos = (int) argv[1].toInteger();
if (pos == 0)
- RETURN_RESULT(Encode(value.startsWith(searchString)));
+ return Encode(value.startsWith(searchString));
QStringRef stringToSearch = value.midRef(pos);
RETURN_RESULT(Encode(stringToSearch.startsWith(searchString)));
}
-void StringPrototype::method_substr(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue StringPrototype::method_substr(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- const QString value = getThisString(scope, callData);
- CHECK_EXCEPTION();
+ ExecutionEngine *v4 = b->engine();
+ const QString value = getThisString(v4, thisObject);
+ if (v4->hasException)
+ return QV4::Encode::undefined();
double start = 0;
- if (callData->argc > 0)
- start = callData->args[0].toInteger();
+ if (argc > 0)
+ start = argv[0].toInteger();
double length = +qInf();
- if (callData->argc > 1)
- length = callData->args[1].toInteger();
+ if (argc > 1)
+ length = argv[1].toInteger();
double count = value.length();
if (start < 0)
@@ -794,25 +818,26 @@ void StringPrototype::method_substr(const BuiltinFunction *, Scope &scope, CallD
qint32 x = Primitive::toInt32(start);
qint32 y = Primitive::toInt32(length);
- scope.result = scope.engine->newString(value.mid(x, y));
+ return Encode(v4->newString(value.mid(x, y)));
}
-void StringPrototype::method_substring(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue StringPrototype::method_substring(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- QString value = getThisString(scope, callData);
- CHECK_EXCEPTION();
+ ExecutionEngine *v4 = b->engine();
+ const QString value = getThisString(v4, thisObject);
+ if (v4->hasException)
+ return QV4::Encode::undefined();
int length = value.length();
double start = 0;
double end = length;
- if (callData->argc > 0)
- start = callData->args[0].toInteger();
+ if (argc > 0)
+ start = argv[0].toInteger();
- ScopedValue endValue(scope, callData->argument(1));
- if (!endValue->isUndefined())
- end = endValue->toInteger();
+ if (argc > 1 && !argv[1].isUndefined())
+ end = argv[1].toInteger();
if (std::isnan(start) || start < 0)
start = 0;
@@ -834,50 +859,56 @@ void StringPrototype::method_substring(const BuiltinFunction *, Scope &scope, Ca
qint32 x = (int)start;
qint32 y = (int)(end - start);
- scope.result = scope.engine->newString(value.mid(x, y));
+ return Encode(v4->newString(value.mid(x, y)));
}
-void StringPrototype::method_toLowerCase(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue StringPrototype::method_toLowerCase(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- QString value = getThisString(scope, callData);
- CHECK_EXCEPTION();
+ ExecutionEngine *v4 = b->engine();
+ const QString value = getThisString(v4, thisObject);
+ if (v4->hasException)
+ return QV4::Encode::undefined();
- scope.result = scope.engine->newString(value.toLower());
+ return Encode(v4->newString(value.toLower()));
}
-void StringPrototype::method_toLocaleLowerCase(const BuiltinFunction *b, Scope &scope, CallData *callData)
+ReturnedValue StringPrototype::method_toLocaleLowerCase(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- method_toLowerCase(b, scope, callData);
+ return method_toLowerCase(b, thisObject, argv, argc);
}
-void StringPrototype::method_toUpperCase(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue StringPrototype::method_toUpperCase(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- QString value = getThisString(scope, callData);
- CHECK_EXCEPTION();
+ ExecutionEngine *v4 = b->engine();
+ const QString value = getThisString(v4, thisObject);
+ if (v4->hasException)
+ return QV4::Encode::undefined();
- scope.result = scope.engine->newString(value.toUpper());
+ return Encode(v4->newString(value.toUpper()));
}
-void StringPrototype::method_toLocaleUpperCase(const BuiltinFunction *b, Scope &scope, CallData *callData)
+ReturnedValue StringPrototype::method_toLocaleUpperCase(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- return method_toUpperCase(b, scope, callData);
+ return method_toUpperCase(b, thisObject, argv, argc);
}
-void StringPrototype::method_fromCharCode(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue StringPrototype::method_fromCharCode(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- QString str(callData->argc, Qt::Uninitialized);
+ QString str(argc, Qt::Uninitialized);
QChar *ch = str.data();
- for (int i = 0; i < callData->argc; ++i) {
- *ch = QChar(callData->args[i].toUInt16());
+ for (int i = 0, ei = argc; i < ei; ++i) {
+ *ch = QChar(argv[i].toUInt16());
++ch;
}
- scope.result = scope.engine->newString(str);
+ return Encode(b->engine()->newString(str));
}
-void StringPrototype::method_trim(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue StringPrototype::method_trim(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- QString s = getThisString(scope, callData);
- CHECK_EXCEPTION();
+ ExecutionEngine *v4 = b->engine();
+ QString s = getThisString(v4, thisObject);
+ if (v4->hasException)
+ return QV4::Encode::undefined();
const QChar *chars = s.constData();
int start, end;
@@ -890,5 +921,5 @@ void StringPrototype::method_trim(const BuiltinFunction *, Scope &scope, CallDat
break;
}
- scope.result = scope.engine->newString(QString(chars + start, end - start + 1));
+ return Encode(v4->newString(QString(chars + start, end - start + 1)));
}
diff --git a/src/qml/jsruntime/qv4stringobject_p.h b/src/qml/jsruntime/qv4stringobject_p.h
index 2e64364f9f..7d25678b61 100644
--- a/src/qml/jsruntime/qv4stringobject_p.h
+++ b/src/qml/jsruntime/qv4stringobject_p.h
@@ -60,14 +60,18 @@ namespace QV4 {
namespace Heap {
-struct StringObject : Object {
+#define StringObjectMembers(class, Member) \
+ Member(class, Pointer, String *, string)
+
+DECLARE_HEAP_OBJECT(StringObject, Object) {
+ DECLARE_MARKOBJECTS(StringObject);
+
enum {
LengthPropertyIndex = 0
};
void init();
void init(const QV4::String *string);
- String *string;
Heap::String *getIndex(uint index) const;
uint length() const;
@@ -96,15 +100,14 @@ struct StringObject: Object {
protected:
static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attrs);
- static void markObjects(Heap::Base *that, ExecutionEngine *e);
};
struct StringCtor: FunctionObject
{
V4_OBJECT2(StringCtor, FunctionObject)
- static void construct(const Managed *m, Scope &scope, CallData *callData);
- static void call(const Managed *, Scope &scope, CallData *callData);
+ static ReturnedValue callAsConstructor(const FunctionObject *f, const Value *argv, int argc);
+ static ReturnedValue call(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
};
struct StringPrototype: StringObject
@@ -112,29 +115,30 @@ struct StringPrototype: StringObject
V4_PROTOTYPE(objectPrototype)
void init(ExecutionEngine *engine, Object *ctor);
- static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_charAt(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_charCodeAt(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_concat(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_endsWith(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_indexOf(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_includes(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_lastIndexOf(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_localeCompare(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_match(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_replace(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_search(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_slice(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_split(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_startsWith(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_substr(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_substring(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_toLowerCase(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_toLocaleLowerCase(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_toUpperCase(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_toLocaleUpperCase(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_fromCharCode(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_trim(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_toString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_charAt(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_charCodeAt(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_concat(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_endsWith(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_indexOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_includes(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_lastIndexOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_localeCompare(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_match(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_repeat(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_replace(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_search(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_slice(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_split(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_startsWith(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_substr(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_substring(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_toLowerCase(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_toLocaleLowerCase(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_toUpperCase(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_toLocaleUpperCase(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_fromCharCode(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_trim(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
};
}
diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp
index 80655aded6..4ba31f9b6e 100644
--- a/src/qml/jsruntime/qv4typedarray.cpp
+++ b/src/qml/jsruntime/qv4typedarray.cpp
@@ -39,6 +39,7 @@
#include "qv4typedarray_p.h"
#include "qv4arraybuffer_p.h"
#include "qv4string_p.h"
+#include "qv4jscall_p.h"
#include <cmath>
@@ -208,36 +209,32 @@ void Heap::TypedArrayCtor::init(QV4::ExecutionContext *scope, TypedArray::Type t
type = t;
}
-void TypedArrayCtor::construct(const Managed *m, Scope &scope, CallData *callData)
+ReturnedValue TypedArrayCtor::callAsConstructor(const FunctionObject *f, const Value *argv, int argc)
{
- Scoped<TypedArrayCtor> that(scope, static_cast<const TypedArrayCtor *>(m));
+ Scope scope(f->engine());
+ const TypedArrayCtor *that = static_cast<const TypedArrayCtor *>(f);
- if (!callData->argc || !callData->args[0].isObject()) {
+ if (!argc || !argv[0].isObject()) {
// ECMA 6 22.2.1.1
- double l = callData->argc ? callData->args[0].toNumber() : 0;
- if (scope.engine->hasException) {
- scope.result = Encode::undefined();
- return;
- }
+ double l = argc ? argv[0].toNumber() : 0;
+ if (scope.engine->hasException)
+ return Encode::undefined();
uint len = (uint)l;
if (l != len)
scope.engine->throwRangeError(QStringLiteral("Non integer length for typed array."));
uint byteLength = len * operations[that->d()->type].bytesPerElement;
Scoped<ArrayBuffer> buffer(scope, scope.engine->newArrayBuffer(byteLength));
- if (scope.engine->hasException) {
- scope.result = Encode::undefined();
- return;
- }
+ if (scope.engine->hasException)
+ return Encode::undefined();
- Scoped<TypedArray > array(scope, TypedArray::create(scope.engine, that->d()->type));
- array->d()->buffer = buffer->d();
+ Scoped<TypedArray> array(scope, TypedArray::create(scope.engine, that->d()->type));
+ array->d()->buffer.set(scope.engine, buffer->d());
array->d()->byteLength = byteLength;
array->d()->byteOffset = 0;
- scope.result = array.asReturnedValue();
- return;
+ return array.asReturnedValue();
}
- Scoped<TypedArray> typedArray(scope, callData->argument(0));
+ Scoped<TypedArray> typedArray(scope, argc ? argv[0] : Primitive::undefinedValue());
if (!!typedArray) {
// ECMA 6 22.2.1.2
Scoped<ArrayBuffer> buffer(scope, typedArray->d()->buffer);
@@ -247,13 +244,11 @@ void TypedArrayCtor::construct(const Managed *m, Scope &scope, CallData *callDat
uint destByteLength = byteLength*destElementSize/srcElementSize;
Scoped<ArrayBuffer> newBuffer(scope, scope.engine->newArrayBuffer(destByteLength));
- if (scope.engine->hasException) {
- scope.result = Encode::undefined();
- return;
- }
+ if (scope.engine->hasException)
+ return Encode::undefined();
- Scoped<TypedArray > array(scope, TypedArray::create(scope.engine, that->d()->type));
- array->d()->buffer = newBuffer->d();
+ Scoped<TypedArray> array(scope, TypedArray::create(scope.engine, that->d()->type));
+ array->d()->buffer.set(scope.engine, newBuffer->d());
array->d()->byteLength = destByteLength;
array->d()->byteOffset = 0;
@@ -275,68 +270,54 @@ void TypedArrayCtor::construct(const Managed *m, Scope &scope, CallData *callDat
}
}
- scope.result = array.asReturnedValue();
- return;
+ return array.asReturnedValue();
}
- Scoped<ArrayBuffer> buffer(scope, callData->argument(0));
+ Scoped<ArrayBuffer> buffer(scope, argc ? argv[0] : Primitive::undefinedValue());
if (!!buffer) {
// ECMA 6 22.2.1.4
- double dbyteOffset = callData->argc > 1 ? callData->args[1].toInteger() : 0;
+ double dbyteOffset = argc > 1 ? argv[1].toInteger() : 0;
uint byteOffset = (uint)dbyteOffset;
uint elementSize = operations[that->d()->type].bytesPerElement;
- if (dbyteOffset < 0 || (byteOffset % elementSize) || dbyteOffset > buffer->byteLength()) {
- scope.result = scope.engine->throwRangeError(QStringLiteral("new TypedArray: invalid byteOffset"));
- return;
- }
+ if (dbyteOffset < 0 || (byteOffset % elementSize) || dbyteOffset > buffer->byteLength())
+ return scope.engine->throwRangeError(QStringLiteral("new TypedArray: invalid byteOffset"));
uint byteLength;
- if (callData->argc < 3 || callData->args[2].isUndefined()) {
+ if (argc < 3 || argv[2].isUndefined()) {
byteLength = buffer->byteLength() - byteOffset;
- if (buffer->byteLength() < byteOffset || byteLength % elementSize) {
- scope.result = scope.engine->throwRangeError(QStringLiteral("new TypedArray: invalid length"));
- return;
- }
+ if (buffer->byteLength() < byteOffset || byteLength % elementSize)
+ return scope.engine->throwRangeError(QStringLiteral("new TypedArray: invalid length"));
} else {
- double l = qBound(0., callData->args[2].toInteger(), (double)UINT_MAX);
- if (scope.engine->hasException) {
- scope.result = Encode::undefined();
- return;
- }
+ double l = qBound(0., argv[2].toInteger(), (double)UINT_MAX);
+ if (scope.engine->hasException)
+ return Encode::undefined();
l *= elementSize;
- if (buffer->byteLength() - byteOffset < l) {
- scope.result = scope.engine->throwRangeError(QStringLiteral("new TypedArray: invalid length"));
- return;
- }
+ if (buffer->byteLength() - byteOffset < l)
+ return scope.engine->throwRangeError(QStringLiteral("new TypedArray: invalid length"));
byteLength = (uint)l;
}
- Scoped<TypedArray > array(scope, TypedArray::create(scope.engine, that->d()->type));
- array->d()->buffer = buffer->d();
+ Scoped<TypedArray> array(scope, TypedArray::create(scope.engine, that->d()->type));
+ array->d()->buffer.set(scope.engine, buffer->d());
array->d()->byteLength = byteLength;
array->d()->byteOffset = byteOffset;
- scope.result = array.asReturnedValue();
- return;
+ return array.asReturnedValue();
}
// ECMA 6 22.2.1.3
- ScopedObject o(scope, callData->argument(0));
+ ScopedObject o(scope, argc ? argv[0] : Primitive::undefinedValue());
uint l = (uint) qBound(0., ScopedValue(scope, o->get(scope.engine->id_length()))->toInteger(), (double)UINT_MAX);
- if (scope.engine->hasException) {
- scope.result = scope.engine->throwTypeError();
- return;
- }
+ if (scope.engine->hasException)
+ return scope.engine->throwTypeError();
uint elementSize = operations[that->d()->type].bytesPerElement;
Scoped<ArrayBuffer> newBuffer(scope, scope.engine->newArrayBuffer(l * elementSize));
- if (scope.engine->hasException) {
- scope.result = Encode::undefined();
- return;
- }
+ if (scope.engine->hasException)
+ return Encode::undefined();
- Scoped<TypedArray > array(scope, TypedArray::create(scope.engine, that->d()->type));
- array->d()->buffer = newBuffer->d();
+ Scoped<TypedArray> array(scope, TypedArray::create(scope.engine, that->d()->type));
+ array->d()->buffer.set(scope.engine, newBuffer->d());
array->d()->byteLength = l * elementSize;
array->d()->byteOffset = 0;
@@ -346,21 +327,19 @@ void TypedArrayCtor::construct(const Managed *m, Scope &scope, CallData *callDat
while (idx < l) {
val = o->getIndexed(idx);
array->d()->type->write(scope.engine, b, 0, val);
- if (scope.engine->hasException) {
- scope.result = Encode::undefined();
- return;
- }
+ if (scope.engine->hasException)
+ return Encode::undefined();
++idx;
b += elementSize;
}
- scope.result = array.asReturnedValue();
+ return array.asReturnedValue();
}
-void TypedArrayCtor::call(const Managed *that, Scope &scope, CallData *callData)
+ReturnedValue TypedArrayCtor::call(const FunctionObject *f, const Value *, const Value *argv, int argc)
{
- construct(that, scope, callData);
+ return callAsConstructor(f, argv, argc);
}
void Heap::TypedArray::init(Type t)
@@ -377,12 +356,6 @@ Heap::TypedArray *TypedArray::create(ExecutionEngine *e, Heap::TypedArray::Type
return e->memoryManager->allocObject<TypedArray>(ic, e->typedArrayPrototype + t, t);
}
-void TypedArray::markObjects(Heap::Base *that, ExecutionEngine *e)
-{
- static_cast<TypedArray::Data *>(that)->buffer->mark(e);
- Object::markObjects(that, e);
-}
-
ReturnedValue TypedArray::getIndexed(const Managed *m, uint index, bool *hasProperty)
{
Scope scope(static_cast<const Object *>(m)->engine());
@@ -400,11 +373,11 @@ ReturnedValue TypedArray::getIndexed(const Managed *m, uint index, bool *hasProp
return a->d()->type->read(a->d()->buffer->data->data(), byteOffset);
}
-void TypedArray::putIndexed(Managed *m, uint index, const Value &value)
+bool TypedArray::putIndexed(Managed *m, uint index, const Value &value)
{
ExecutionEngine *v4 = static_cast<Object *>(m)->engine();
if (v4->hasException)
- return;
+ return false;
Scope scope(v4);
Scoped<TypedArray> a(scope, static_cast<TypedArray *>(m));
@@ -412,14 +385,10 @@ void TypedArray::putIndexed(Managed *m, uint index, const Value &value)
uint bytesPerElement = a->d()->type->bytesPerElement;
uint byteOffset = a->d()->byteOffset + index * bytesPerElement;
if (byteOffset + bytesPerElement > (uint)a->d()->buffer->byteLength())
- goto reject;
+ return false;
a->d()->type->write(scope.engine, a->d()->buffer->data->data(), byteOffset, value);
- return;
-
-reject:
- if (scope.engine->current->strictMode)
- scope.engine->throwTypeError();
+ return true;
}
void TypedArrayPrototype::init(ExecutionEngine *engine, TypedArrayCtor *ctor)
@@ -440,52 +409,57 @@ void TypedArrayPrototype::init(ExecutionEngine *engine, TypedArrayCtor *ctor)
defineDefaultProperty(QStringLiteral("subarray"), method_subarray, 0);
}
-void TypedArrayPrototype::method_get_buffer(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue TypedArrayPrototype::method_get_buffer(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<TypedArray> v(scope, callData->thisObject);
+ ExecutionEngine *v4 = b->engine();
+ const TypedArray *v = thisObject->as<TypedArray>();
if (!v)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
- scope.result = v->d()->buffer;
+ return v->d()->buffer->asReturnedValue();
}
-void TypedArrayPrototype::method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue TypedArrayPrototype::method_get_byteLength(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<TypedArray> v(scope, callData->thisObject);
+ ExecutionEngine *v4 = b->engine();
+ const TypedArray *v = thisObject->as<TypedArray>();
if (!v)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
- scope.result = Encode(v->d()->byteLength);
+ return Encode(v->d()->byteLength);
}
-void TypedArrayPrototype::method_get_byteOffset(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue TypedArrayPrototype::method_get_byteOffset(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<TypedArray> v(scope, callData->thisObject);
+ ExecutionEngine *v4 = b->engine();
+ const TypedArray *v = thisObject->as<TypedArray>();
if (!v)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
- scope.result = Encode(v->d()->byteOffset);
+ return Encode(v->d()->byteOffset);
}
-void TypedArrayPrototype::method_get_length(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue TypedArrayPrototype::method_get_length(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<TypedArray> v(scope, callData->thisObject);
+ ExecutionEngine *v4 = b->engine();
+ const TypedArray *v = thisObject->as<TypedArray>();
if (!v)
- THROW_TYPE_ERROR();
+ return v4->throwTypeError();
- scope.result = Encode(v->d()->byteLength/v->d()->type->bytesPerElement);
+ return Encode(v->d()->byteLength/v->d()->type->bytesPerElement);
}
-void TypedArrayPrototype::method_set(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue TypedArrayPrototype::method_set(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- Scoped<TypedArray> a(scope, callData->thisObject);
+ Scope scope(b);
+ Scoped<TypedArray> a(scope, *thisObject);
if (!a)
- THROW_TYPE_ERROR();
+ return scope.engine->throwTypeError();
Scoped<ArrayBuffer> buffer(scope, a->d()->buffer);
if (!buffer)
scope.engine->throwTypeError();
- double doffset = callData->argc >= 2 ? callData->args[1].toInteger() : 0;
+ double doffset = argc >= 2 ? argv[1].toInteger() : 0;
if (scope.engine->hasException)
RETURN_UNDEFINED();
@@ -494,17 +468,17 @@ void TypedArrayPrototype::method_set(const BuiltinFunction *, Scope &scope, Call
uint offset = (uint)doffset;
uint elementSize = a->d()->type->bytesPerElement;
- Scoped<TypedArray> srcTypedArray(scope, callData->args[0]);
+ Scoped<TypedArray> srcTypedArray(scope, argv[0]);
if (!srcTypedArray) {
// src is a regular object
- ScopedObject o(scope, callData->args[0].toObject(scope.engine));
+ ScopedObject o(scope, argv[0].toObject(scope.engine));
if (scope.engine->hasException || !o)
- THROW_TYPE_ERROR();
+ return scope.engine->throwTypeError();
double len = ScopedValue(scope, o->get(scope.engine->id_length()))->toNumber();
uint l = (uint)len;
if (scope.engine->hasException || l != len)
- THROW_TYPE_ERROR();
+ return scope.engine->throwTypeError();
if (offset + l > a->length())
RETURN_RESULT(scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range")));
@@ -526,7 +500,7 @@ void TypedArrayPrototype::method_set(const BuiltinFunction *, Scope &scope, Call
// src is a typed array
Scoped<ArrayBuffer> srcBuffer(scope, srcTypedArray->d()->buffer);
if (!srcBuffer)
- THROW_TYPE_ERROR();
+ return scope.engine->throwTypeError();
uint l = srcTypedArray->length();
if (offset + l > a->length())
@@ -564,24 +538,25 @@ void TypedArrayPrototype::method_set(const BuiltinFunction *, Scope &scope, Call
RETURN_UNDEFINED();
}
-void TypedArrayPrototype::method_subarray(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue TypedArrayPrototype::method_subarray(const FunctionObject *builtin, const Value *thisObject, const Value *argv, int argc)
{
- Scoped<TypedArray> a(scope, callData->thisObject);
+ Scope scope(builtin);
+ Scoped<TypedArray> a(scope, *thisObject);
if (!a)
- THROW_TYPE_ERROR();
+ return scope.engine->throwTypeError();
Scoped<ArrayBuffer> buffer(scope, a->d()->buffer);
if (!buffer)
- THROW_TYPE_ERROR();
+ return scope.engine->throwTypeError();
int len = a->length();
- double b = callData->argc > 0 ? callData->args[0].toInteger() : 0;
+ double b = argc > 0 ? argv[0].toInteger() : 0;
if (b < 0)
b = len + b;
uint begin = (uint)qBound(0., b, (double)len);
- double e = callData->argc < 2 || callData->args[1].isUndefined() ? len : callData->args[1].toInteger();
+ double e = argc < 2 || argv[1].isUndefined() ? len : argv[1].toInteger();
if (e < 0)
e = len + e;
uint end = (uint)qBound(0., e, (double)len);
@@ -595,11 +570,11 @@ void TypedArrayPrototype::method_subarray(const BuiltinFunction *, Scope &scope,
ScopedFunctionObject constructor(scope, a->get(scope.engine->id_constructor()));
if (!constructor)
- THROW_TYPE_ERROR();
+ return scope.engine->throwTypeError();
- ScopedCallData cData(scope, 3);
- cData->args[0] = buffer;
- cData->args[1] = Encode(a->d()->byteOffset + begin*a->d()->type->bytesPerElement);
- cData->args[2] = Encode(newLen);
- constructor->construct(scope, cData);
+ Value *arguments = scope.alloc(3);
+ arguments[0] = buffer;
+ arguments[1] = Encode(a->d()->byteOffset + begin*a->d()->type->bytesPerElement);
+ arguments[2] = Encode(newLen);
+ return constructor->callAsConstructor(arguments, 3);
}
diff --git a/src/qml/jsruntime/qv4typedarray_p.h b/src/qml/jsruntime/qv4typedarray_p.h
index a6a74e4b9b..129c662c97 100644
--- a/src/qml/jsruntime/qv4typedarray_p.h
+++ b/src/qml/jsruntime/qv4typedarray_p.h
@@ -72,7 +72,15 @@ struct TypedArrayOperations {
namespace Heap {
-struct TypedArray : Object {
+#define TypedArrayMembers(class, Member) \
+ Member(class, Pointer, ArrayBuffer *, buffer) \
+ Member(class, NoMark, const TypedArrayOperations *, type) \
+ Member(class, NoMark, uint, byteLength) \
+ Member(class, NoMark, uint, byteOffset) \
+ Member(class, NoMark, uint, arrayType)
+
+DECLARE_HEAP_OBJECT(TypedArray, Object) {
+ DECLARE_MARKOBJECTS(TypedArray);
enum Type {
Int8Array,
UInt8Array,
@@ -87,12 +95,6 @@ struct TypedArray : Object {
};
void init(Type t);
-
- const TypedArrayOperations *type;
- Pointer<ArrayBuffer> buffer;
- uint byteLength;
- uint byteOffset;
- Type arrayType;
};
struct TypedArrayCtor : FunctionObject {
@@ -128,20 +130,19 @@ struct Q_QML_PRIVATE_EXPORT TypedArray : Object
}
Heap::TypedArray::Type arrayType() const {
- return d()->arrayType;
+ return static_cast<Heap::TypedArray::Type>(d()->arrayType);
}
- static void markObjects(Heap::Base *that, ExecutionEngine *e);
static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty);
- static void putIndexed(Managed *m, uint index, const Value &value);
+ static bool putIndexed(Managed *m, uint index, const Value &value);
};
struct TypedArrayCtor: FunctionObject
{
V4_OBJECT2(TypedArrayCtor, FunctionObject)
- static void construct(const Managed *m, Scope &scope, CallData *callData);
- static void call(const Managed *that, Scope &scope, CallData *callData);
+ static ReturnedValue callAsConstructor(const FunctionObject *f, const Value *argv, int argc);
+ static ReturnedValue call(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
};
@@ -152,13 +153,13 @@ struct TypedArrayPrototype : Object
void init(ExecutionEngine *engine, TypedArrayCtor *ctor);
- static void method_get_buffer(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_get_byteOffset(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_get_length(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_get_buffer(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_byteLength(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_byteOffset(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_length(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
- static void method_set(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_subarray(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_set(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_subarray(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
};
inline void
diff --git a/src/qml/jsruntime/qv4value.cpp b/src/qml/jsruntime/qv4value.cpp
index f41442df7a..0d4711df3c 100644
--- a/src/qml/jsruntime/qv4value.cpp
+++ b/src/qml/jsruntime/qv4value.cpp
@@ -75,39 +75,29 @@ int Value::toUInt16() const
return (unsigned short)number;
}
-bool Value::toBoolean() const
+bool Value::toBooleanImpl(Value val)
{
- if (isInteger() || isBoolean())
- return static_cast<bool>(int_32());
-
- if (isUndefined() || isNull())
- return false;
-
- if (isManaged()) {
+ if (val.isManagedOrUndefined()) {
+ Heap::Base *b = val.m();
+ if (!b)
+ return false;
#ifdef V4_BOOTSTRAP
Q_UNIMPLEMENTED();
#else
- if (String *s = stringValue())
- return s->toQString().length() > 0;
+ if (b->vtable()->isString)
+ return static_cast<Heap::String *>(b)->length() > 0;
#endif
return true;
}
// double
- return doubleValue() && !std::isnan(doubleValue());
+ double d = val.doubleValue();
+ return d && !std::isnan(d);
}
-double Value::toInteger() const
+double Value::toNumberImpl(Value val)
{
- if (integerCompatible())
- return int_32();
-
- return Primitive::toInteger(toNumber());
-}
-
-double Value::toNumberImpl() const
-{
- switch (type()) {
+ switch (val.type()) {
case QV4::Value::Undefined_Type:
return std::numeric_limits<double>::quiet_NaN();
case QV4::Value::Managed_Type:
@@ -115,12 +105,13 @@ double Value::toNumberImpl() const
Q_UNIMPLEMENTED();
Q_FALLTHROUGH();
#else
- if (String *s = stringValue())
+ if (String *s = val.stringValue())
return RuntimeHelpers::stringToNumber(s->toQString());
{
- Q_ASSERT(isObject());
- Scope scope(objectValue()->engine());
- ScopedValue prim(scope, RuntimeHelpers::toPrimitive(*this, NUMBER_HINT));
+ Q_ASSERT(val.isObject());
+ Scope scope(val.objectValue()->engine());
+ ScopedValue protectThis(scope, val);
+ ScopedValue prim(scope, RuntimeHelpers::toPrimitive(val, NUMBER_HINT));
if (scope.engine->hasException)
return 0;
return prim->toNumber();
@@ -129,7 +120,7 @@ double Value::toNumberImpl() const
case QV4::Value::Null_Type:
case QV4::Value::Boolean_Type:
case QV4::Value::Integer_Type:
- return int_32();
+ return val.int_32();
default: // double
Q_UNREACHABLE();
}
@@ -236,83 +227,23 @@ bool Value::sameValue(Value other) const {
if (s && os)
return s->isEqualTo(os);
if (isInteger() && other.isDouble())
- return int_32() ? (double(int_32()) == other.doubleValue()) : (other._val == 0);
+ return int_32() ? (double(int_32()) == other.doubleValue())
+ : (other.doubleValue() == 0 && !std::signbit(other.doubleValue()));
if (isDouble() && other.isInteger())
- return other.int_32() ? (doubleValue() == double(other.int_32())) : (_val == 0);
+ return other.int_32() ? (doubleValue() == double(other.int_32()))
+ : (doubleValue() == 0 && !std::signbit(doubleValue()));
return false;
}
-
-int Primitive::toInt32(double number)
-{
- const double D32 = 4294967296.0;
- const double D31 = D32 / 2.0;
-
- if ((number >= -D31 && number < D31))
- return static_cast<int>(number);
-
-
- if (!std::isfinite(number))
- return 0;
-
- double d = ::floor(::fabs(number));
- if (std::signbit(number))
- d = -d;
-
- number = ::fmod(d , D32);
-
- if (number < -D31)
- number += D32;
- else if (number >= D31)
- number -= D32;
-
- return int(number);
-}
-
-unsigned int Primitive::toUInt32(double number)
-{
- const double D32 = 4294967296.0;
- if ((number >= 0 && number < D32))
- return static_cast<uint>(number);
-
- if (!std::isfinite(number))
- return +0;
-
- double d = ::floor(::fabs(number));
- if (std::signbit(number))
- d = -d;
-
- number = ::fmod(d , D32);
-
- if (number < 0)
- number += D32;
-
- return unsigned(number);
-}
-
-double Primitive::toInteger(double number)
-{
- if (std::isnan(number))
- return +0;
- else if (! number || std::isinf(number))
- return number;
- const double v = floor(fabs(number));
- return std::signbit(number) ? -v : v;
-}
-
#ifndef V4_BOOTSTRAP
-Heap::String *Value::toString(ExecutionEngine *e) const
+Heap::String *Value::toString(ExecutionEngine *e, Value val)
{
- if (String *s = stringValue())
- return s->d();
- return RuntimeHelpers::convertToString(e, *this);
+ return RuntimeHelpers::convertToString(e, val);
}
-Heap::Object *Value::toObject(ExecutionEngine *e) const
+Heap::Object *Value::toObject(ExecutionEngine *e, Value val)
{
- if (Object *o = objectValue())
- return o->d();
- return RuntimeHelpers::convertToObject(e, *this);
+ return RuntimeHelpers::convertToObject(e, val);
}
uint Value::asArrayLength(bool *ok) const
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index 94233d4ddb..b3f04d69be 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -51,6 +51,7 @@
//
#include <limits.h>
+#include <cmath>
#include <QtCore/QString>
#include "qv4global_p.h"
@@ -58,10 +59,6 @@
#include <private/qnumeric_p.h>
-#if QT_POINTER_SIZE == 8
-#define QV4_USE_64_BIT_VALUE_ENCODING
-#endif
-
QT_BEGIN_NAMESPACE
namespace QV4 {
@@ -74,9 +71,7 @@ struct Q_QML_PRIVATE_EXPORT Value
{
private:
/*
- We use two different ways of encoding JS values. One for 32bit and one for 64bit systems.
-
- In both cases, we use 8 bytes for a value and a different variant of NaN boxing. A Double
+ We use 8 bytes for a value and a different variant of NaN boxing. A Double
NaN (actually -qNaN) is indicated by a number that has the top 13 bits set, and for a
signalling NaN it is the top 14 bits. The other values are usually set to 0 by the
processor, and are thus free for us to store other data. We keep pointers in there for
@@ -85,18 +80,14 @@ private:
only have 48 bits of addressable memory. (Note: we do leave the lower 49 bits available for
pointers.)
- On 32bit, we store doubles as doubles. All other values, have the high 32bits set to a value
- that will make the number a NaN. The Masks below are used for encoding the other types.
-
- On 64 bit, we xor Doubles with (0xffff8000 << 32). That has the effect that no doubles will
+ We xor Doubles with (0xffff8000 << 32). That has the effect that no doubles will
get encoded with bits 63-49 all set to 0. We then use bit 48 to distinguish between
managed/undefined (0), or Null/Int/Bool/Empty (1). So, storing a 49 bit pointer will leave
the top 15 bits 0, which is exactly the 'natural' representation of pointers. If bit 49 is
set, bit 48 indicates Empty (0) or integer-convertible (1). Then the 3 bit below that are
used to encode Null/Int/Bool.
- On both 32bit and 64bit, Undefined is encoded as a managed pointer with value 0. This is
- the same as a nullptr.
+ Undefined is encoded as a managed pointer with value 0. This is the same as a nullptr.
Specific bit-sequences:
0 = always 0
@@ -104,8 +95,6 @@ private:
x = stored value
a,b,c,d = specific bit values, see notes
- 64bit:
-
32109876 54321098 76543210 98765432 10987654 32109876 54321098 76543210 |
66665555 55555544 44444444 33333333 33222222 22221111 11111100 00000000 | JS Value
------------------------------------------------------------------------+--------------
@@ -114,9 +103,9 @@ private:
a0000000 0000bc00 00000000 00000000 00000000 00000000 00000000 00000000 | NaN/Inf
dddddddd ddddddxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx | double
00000000 00000010 00000000 00000000 00000000 00000000 00000000 00000000 | empty (non-sparse array hole)
- 00000000 00000011 10000000 00000000 00000000 00000000 00000000 00000000 | Null
- 00000000 00000011 01000000 00000000 00000000 00000000 00000000 0000000x | Bool
- 00000000 00000011 00100000 00000000 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx | Int
+ 00000000 00000010 10000000 00000000 00000000 00000000 00000000 00000000 | Null
+ 00000000 00000011 00000000 00000000 00000000 00000000 00000000 0000000x | Bool
+ 00000000 00000011 10000000 00000000 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx | Int
Notes:
- a: xor-ed signbit, always 1 for NaN
@@ -130,31 +119,8 @@ private:
- Null, Bool, and Int have bit 48 set, indicating integer-convertible
- xoring _val with NaNEncodeMask will convert to a double in "natural" representation, where
any non double results in a NaN
-
- 32bit:
-
- 32109876 54321098 76543210 98765432 10987654 32109876 54321098 76543210 |
- 66665555 55555544 44444444 33333333 33222222 22221111 11111100 00000000 | JS Value
- ------------------------------------------------------------------------+--------------
- 01111111 11111100 00000000 00000000 00000000 00000000 00000000 00000000 | Undefined
- 01111111 11111100 00000000 00000000 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx | Managed (heap pointer)
- a1111111 1111bc00 00000000 00000000 00000000 00000000 00000000 00000000 | NaN/Inf
- xddddddd ddddddxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx | double
- 01111111 11111110 00000000 00000000 00000000 00000000 00000000 00000000 | empty (non-sparse array hole)
- 01111111 11111111 10000000 00000000 00000000 00000000 00000000 00000000 | Null
- 01111111 11111111 01000000 00000000 00000000 00000000 00000000 0000000x | Bool
- 01111111 11111111 00100000 00000000 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx | Int
-
- Notes:
- - the upper 32 bits are the tag, the lower 32 bits the value
- - Undefined has a nullptr in the value, Managed has a non-nullptr stored in the value
- - a: sign bit, always 0 for NaN
- - b,c: 00=inf, 01 = sNaN, 10 = qNaN, 11 = boxed value
- - d: stored double value, as long as not *all* of them are 1, because that's a boxed value
- (see above)
- - empty, Null, Bool, and Int have bit 63 set to 0, bits 62-50 set to 1 (same as undefined
- and managed), and bit 49 set to 1 (where undefined and managed have it set to 0)
- - Null, Bool, and Int have bit 48 set, indicating integer-convertible
+ - on 32bit we can use the fact that addresses are 32bits wide, so the tag part (bits 32 to
+ 63) are zero. No need to shift.
*/
quint64 _val;
@@ -174,8 +140,9 @@ public:
QML_NEARLY_ALWAYS_INLINE void setTagValue(quint32 tag, quint32 value) { _val = quint64(tag) << 32 | value; }
QML_NEARLY_ALWAYS_INLINE quint32 value() const { return _val & quint64(~quint32(0)); }
QML_NEARLY_ALWAYS_INLINE quint32 tag() const { return _val >> 32; }
+ QML_NEARLY_ALWAYS_INLINE void setTag(quint32 tag) { setTagValue(tag, value()); }
-#if defined(QV4_USE_64_BIT_VALUE_ENCODING)
+#if QT_POINTER_SIZE == 8
QML_NEARLY_ALWAYS_INLINE Heap::Base *m() const
{
Heap::Base *b;
@@ -186,7 +153,7 @@ public:
{
memcpy(&_val, &b, 8);
}
-#else // !QV4_USE_64_BIT_VALUE_ENCODING
+#elif QT_POINTER_SIZE == 4
QML_NEARLY_ALWAYS_INLINE Heap::Base *m() const
{
Q_STATIC_ASSERT(sizeof(Heap::Base*) == sizeof(quint32));
@@ -201,6 +168,8 @@ public:
memcpy(&v, &b, 4);
setTagValue(Managed_Type_Internal, v);
}
+#else
+# error "unsupported pointer size"
#endif
QML_NEARLY_ALWAYS_INLINE int int_32() const
@@ -234,24 +203,37 @@ public:
return quint32(value());
}
+ // ### Fix for 32 bit (easiest solution is to set highest bit to 1 for mananged/undefined/integercompatible
+ // and use negative numbers here
+ enum QuickType {
+ QT_ManagedOrUndefined = 0,
+ QT_ManagedOrUndefined1 = 1,
+ QT_ManagedOrUndefined2 = 2,
+ QT_ManagedOrUndefined3 = 3,
+ QT_Empty = 4,
+ QT_Null = 5,
+ QT_Bool = 6,
+ QT_Int = 7
+ // all other values are doubles
+ };
+
enum Type {
- Undefined_Type,
- Managed_Type,
- Empty_Type,
- Integer_Type,
- Boolean_Type,
- Null_Type,
- Double_Type
+ Undefined_Type = 0,
+ Managed_Type = 1,
+ Empty_Type = 4,
+ Null_Type = 5,
+ Boolean_Type = 6,
+ Integer_Type = 7,
+ Double_Type = 8
};
inline Type type() const {
- if (isUndefined()) return Undefined_Type;
- if (isManaged()) return Managed_Type;
- if (isEmpty()) return Empty_Type;
- if (isInteger()) return Integer_Type;
- if (isBoolean()) return Boolean_Type;
- if (isNull()) return Null_Type;
- Q_ASSERT(isDouble()); return Double_Type;
+ int t = quickType();
+ if (t < QT_Empty)
+ return _val ? Managed_Type : Undefined_Type;
+ if (t > QT_Int)
+ return Double_Type;
+ return static_cast<Type>(t);
}
// Shared between 32-bit and 64-bit encoding
@@ -264,19 +246,18 @@ public:
enum {
IsDouble_Shift = 64-14,
IsManagedOrUndefined_Shift = 64-15,
- IsIntegerConvertible_Shift = 64-16,
- IsDoubleTag_Shift = IsDouble_Shift - Tag_Shift,
- Managed_Type_Internal_64 = 0
+ IsIntegerConvertible_Shift = 64-15,
+ IsIntegerOrBool_Shift = 64-16,
+ QuickType_Shift = 64 - 17
};
static const quint64 Immediate_Mask_64 = 0x00020000u; // bit 49
enum class ValueTypeInternal_64 {
- Empty = Immediate_Mask_64| 0,
- ConvertibleToInt = Immediate_Mask_64| 0x10000u, // bit 48
- Null = ConvertibleToInt | 0x08000u,
- Boolean = ConvertibleToInt | 0x04000u,
- Integer = ConvertibleToInt | 0x02000u
+ Empty = Immediate_Mask_64 | 0,
+ Null = Immediate_Mask_64 | 0x08000u,
+ Boolean = Immediate_Mask_64 | 0x10000u,
+ Integer = Immediate_Mask_64 | 0x18000u
};
// Used only by 32-bit encoding
@@ -287,50 +268,44 @@ public:
static const quint64 Immediate_Mask_32 = NotDouble_Mask | 0x00020000u | SilentNaNBit;
enum class ValueTypeInternal_32 {
- Empty = Immediate_Mask_32| 0,
- ConvertibleToInt = Immediate_Mask_32| 0x10000u, // bit 48
- Null = ConvertibleToInt | 0x08000u,
- Boolean = ConvertibleToInt | 0x04000u,
- Integer = ConvertibleToInt | 0x02000u
+ Empty = Immediate_Mask_32 | 0,
+ Null = Immediate_Mask_32 | 0x08000u,
+ Boolean = Immediate_Mask_32 | 0x10000u,
+ Integer = Immediate_Mask_32 | 0x18000u
};
enum {
- Managed_Type_Internal_32 = NotDouble_Mask
+ Managed_Type_Internal = 0
};
-#ifdef QV4_USE_64_BIT_VALUE_ENCODING
- enum {
- Managed_Type_Internal = Managed_Type_Internal_64
- };
- static const quint64 Immediate_Mask = Immediate_Mask_64;
using ValueTypeInternal = ValueTypeInternal_64;
-#else
- enum {
- Managed_Type_Internal = Managed_Type_Internal_32
- };
- static const quint64 Immediate_Mask = Immediate_Mask_32;
- using ValueTypeInternal = ValueTypeInternal_32;
-#endif
+
enum {
NaN_Mask = 0x7ff80000,
};
+ inline quint64 quickType() const { return (_val >> QuickType_Shift); }
+
// used internally in property
inline bool isEmpty() const { return tag() == quint32(ValueTypeInternal::Empty); }
inline bool isNull() const { return tag() == quint32(ValueTypeInternal::Null); }
inline bool isBoolean() const { return tag() == quint32(ValueTypeInternal::Boolean); }
inline bool isInteger() const { return tag() == quint32(ValueTypeInternal::Integer); }
inline bool isNullOrUndefined() const { return isNull() || isUndefined(); }
- inline bool isNumber() const { return isDouble() || isInteger(); }
+ inline bool isNumber() const { return quickType() >= QT_Int; }
-#ifdef QV4_USE_64_BIT_VALUE_ENCODING
inline bool isUndefined() const { return _val == 0; }
inline bool isDouble() const { return (_val >> IsDouble_Shift); }
- inline bool isManaged() const { return !isUndefined() && ((_val >> IsManagedOrUndefined_Shift) == 0); }
+ inline bool isManaged() const { return _val && ((_val >> IsManagedOrUndefined_Shift) == 0); }
inline bool isManagedOrUndefined() const { return ((_val >> IsManagedOrUndefined_Shift) == 0); }
+ inline bool isIntOrBool() const {
+ return (_val >> IsIntegerOrBool_Shift) == 3;
+ }
+
inline bool integerCompatible() const {
- return (_val >> IsIntegerConvertible_Shift) == 3;
+ Q_ASSERT(!isEmpty());
+ return (_val >> IsIntegerConvertible_Shift) == 1;
}
static inline bool integerCompatible(Value a, Value b) {
return a.integerCompatible() && b.integerCompatible();
@@ -339,41 +314,25 @@ public:
return a.isDouble() && b.isDouble();
}
inline bool isNaN() const { return (tag() & 0x7ffc0000 ) == 0x00040000; }
-#else
- inline bool isUndefined() const { return tag() == Managed_Type_Internal && value() == 0; }
- inline bool isDouble() const { return (tag() & NotDouble_Mask) != NotDouble_Mask; }
- inline bool isManaged() const { return tag() == Managed_Type_Internal && !isUndefined(); }
- inline bool isManagedOrUndefined() const { return tag() == Managed_Type_Internal; }
- inline bool integerCompatible() const { return (tag() & quint32(ValueTypeInternal::ConvertibleToInt)) == quint32(ValueTypeInternal::ConvertibleToInt); }
- static inline bool integerCompatible(Value a, Value b) {
- return ((a.tag() & b.tag()) & quint32(ValueTypeInternal::ConvertibleToInt)) == quint32(ValueTypeInternal::ConvertibleToInt);
- }
- static inline bool bothDouble(Value a, Value b) {
- return ((a.tag() | b.tag()) & NotDouble_Mask) != NotDouble_Mask;
- }
- inline bool isNaN() const { return (tag() & QV4::Value::NotDouble_Mask) == QV4::Value::NaN_Mask; }
-#endif
+
QML_NEARLY_ALWAYS_INLINE double doubleValue() const {
Q_ASSERT(isDouble());
double d;
- quint64 v = _val;
-#ifdef QV4_USE_64_BIT_VALUE_ENCODING
- v ^= NaNEncodeMask;
-#endif
- memcpy(&d, &v, 8);
+ Value v = *this;
+ v._val ^= NaNEncodeMask;
+ memcpy(&d, &v._val, 8);
return d;
}
QML_NEARLY_ALWAYS_INLINE void setDouble(double d) {
if (qt_is_nan(d))
d = qt_qnan();
memcpy(&_val, &d, 8);
-#ifdef QV4_USE_64_BIT_VALUE_ENCODING
_val ^= NaNEncodeMask;
-#endif
Q_ASSERT(isDouble());
}
inline bool isString() const;
inline bool isObject() const;
+ inline bool isFunctionObject() const;
inline bool isInt32() {
if (tag() == quint32(ValueTypeInternal::Integer))
return true;
@@ -430,14 +389,31 @@ public:
inline int toInt32() const;
inline unsigned int toUInt32() const;
- bool toBoolean() const;
+ bool toBoolean() const {
+ if (integerCompatible())
+ return static_cast<bool>(int_32());
+
+ return toBooleanImpl(*this);
+ }
+ static bool toBooleanImpl(Value val);
double toInteger() const;
inline double toNumber() const;
- double toNumberImpl() const;
+ static double toNumberImpl(Value v);
+ double toNumberImpl() const { return toNumberImpl(*this); }
QString toQStringNoThrow() const;
QString toQString() const;
- Heap::String *toString(ExecutionEngine *e) const;
- Heap::Object *toObject(ExecutionEngine *e) const;
+ Heap::String *toString(ExecutionEngine *e) const {
+ if (isString())
+ return reinterpret_cast<Heap::String *>(m());
+ return toString(e, *this);
+ }
+ static Heap::String *toString(ExecutionEngine *e, Value val);
+ Heap::Object *toObject(ExecutionEngine *e) const {
+ if (isObject())
+ return reinterpret_cast<Heap::Object *>(m());
+ return toObject(e, *this);
+ }
+ static Heap::Object *toObject(ExecutionEngine *e, Value val);
inline bool isPrimitive() const;
inline bool tryIntegerConversion() {
@@ -485,13 +461,14 @@ public:
uint asArrayLength(bool *ok) const;
#endif
+ ReturnedValue *data_ptr() { return &_val; }
ReturnedValue asReturnedValue() const { return _val; }
static Value fromReturnedValue(ReturnedValue val) { Value v; v._val = val; return v; }
// Section 9.12
bool sameValue(Value other) const;
- inline void mark(ExecutionEngine *e);
+ inline void mark(MarkStack *markStack);
Value &operator =(const ScopedValue &v);
Value &operator=(ReturnedValue v) { _val = v; return *this; }
@@ -511,7 +488,14 @@ public:
template<typename T>
Value &operator=(const Scoped<T> &t);
};
-V4_ASSERT_IS_TRIVIAL(Value)
+Q_STATIC_ASSERT(std::is_trivial< Value >::value);
+
+inline void Value::mark(MarkStack *markStack)
+{
+ Heap::Base *o = heapObject();
+ if (o)
+ o->mark(markStack);
+}
inline bool Value::isString() const
{
@@ -524,6 +508,12 @@ inline bool Value::isObject() const
return b && b->vtable()->isObject;
}
+inline bool Value::isFunctionObject() const
+{
+ Heap::Base *b = heapObject();
+ return b && b->vtable()->isFunctionObject;
+}
+
inline bool Value::isPrimitive() const
{
return !isObject();
@@ -542,7 +532,7 @@ inline double Value::toNumber() const
#ifndef V4_BOOTSTRAP
inline uint Value::asArrayIndex() const
{
-#ifdef QV4_USE_64_BIT_VALUE_ENCODING
+#if QT_POINTER_SIZE == 8
if (!isNumber())
return UINT_MAX;
if (isInteger())
@@ -562,8 +552,8 @@ inline uint Value::asArrayIndex() const
inline bool Value::asArrayIndex(uint &idx) const
{
- if (!isDouble()) {
- if (isInteger() && int_32() >= 0) {
+ if (Q_LIKELY(!isDouble())) {
+ if (Q_LIKELY(isInteger() && int_32() >= 0)) {
idx = (uint)int_32();
return true;
}
@@ -597,15 +587,15 @@ struct Q_QML_PRIVATE_EXPORT Primitive : public Value
using Value::toInt32;
using Value::toUInt32;
- static double toInteger(double fromNumber);
- static int toInt32(double value);
- static unsigned int toUInt32(double value);
+ static double toInteger(double d);
+ static int toInt32(double d);
+ static unsigned int toUInt32(double d);
};
inline Primitive Primitive::undefinedValue()
{
Primitive v;
- v.setM(Q_NULLPTR);
+ v.setM(nullptr);
return v;
}
@@ -662,6 +652,72 @@ inline Primitive Primitive::fromUInt32(uint i)
return v;
}
+struct Double {
+ quint64 d;
+
+ Double(double dbl) {
+ memcpy(&d, &dbl, sizeof(double));
+ }
+
+ int sign() const {
+ return (d >> 63) ? -1 : 1;
+ }
+
+ bool isDenormal() const {
+ return static_cast<int>((d << 1) >> 53) == 0;
+ }
+
+ int exponent() const {
+ return static_cast<int>((d << 1) >> 53) - 1023;
+ }
+
+ quint64 significant() const {
+ quint64 m = (d << 12) >> 12;
+ if (!isDenormal())
+ m |= (static_cast<quint64>(1) << 52);
+ return m;
+ }
+
+ static int toInt32(double d) {
+ int i = static_cast<int>(d);
+ if (i == d)
+ return i;
+ return Double(d).toInt32();
+ }
+
+ int toInt32() {
+ int e = exponent() - 52;
+ if (e < 0) {
+ if (e <= -53)
+ return 0;
+ return sign() * static_cast<int>(significant() >> -e);
+ } else {
+ if (e > 31)
+ return 0;
+ return sign() * (static_cast<int>(significant()) << e);
+ }
+ }
+};
+
+inline double Primitive::toInteger(double d)
+{
+ if (std::isnan(d))
+ return +0;
+ else if (!d || std::isinf(d))
+ return d;
+ return d >= 0 ? std::floor(d) : std::ceil(d);
+}
+
+inline int Primitive::toInt32(double value)
+{
+ return Double::toInt32(value);
+}
+
+inline unsigned int Primitive::toUInt32(double d)
+{
+ return static_cast<uint>(toInt32(d));
+}
+
struct Encode {
static ReturnedValue undefined() {
return Primitive::undefinedValue().rawValue();
@@ -670,33 +726,47 @@ struct Encode {
return Primitive::nullValue().rawValue();
}
- Encode(bool b) {
+ explicit Encode(bool b) {
val = Primitive::fromBoolean(b).rawValue();
}
- Encode(double d) {
+ explicit Encode(double d) {
val = Primitive::fromDouble(d).rawValue();
}
- Encode(int i) {
+ explicit Encode(int i) {
val = Primitive::fromInt32(i).rawValue();
}
- Encode(uint i) {
+ explicit Encode(uint i) {
val = Primitive::fromUInt32(i).rawValue();
}
- Encode(ReturnedValue v) {
+ explicit Encode(ReturnedValue v) {
val = v;
}
+ Encode(Value v) {
+ val = v.rawValue();
+ }
- Encode(Heap::Base *o) {
- Q_ASSERT(o);
+ explicit Encode(Heap::Base *o) {
val = Value::fromHeapObject(o).asReturnedValue();
}
+ explicit Encode(Value *o) {
+ Q_ASSERT(o);
+ val = o->asReturnedValue();
+ }
+
+ static ReturnedValue smallestNumber(double d) {
+ if (static_cast<int>(d) == d && !(d == 0. && std::signbit(d)))
+ return Encode(static_cast<int>(d));
+ else
+ return Encode(d);
+ }
+
operator ReturnedValue() const {
return val;
}
quint64 val;
private:
- Encode(void *);
+ explicit Encode(void *);
};
template<typename T>
@@ -704,25 +774,117 @@ ReturnedValue value_convert(ExecutionEngine *e, const Value &v);
inline int Value::toInt32() const
{
- if (isInteger())
+ if (Q_LIKELY(integerCompatible()))
return int_32();
- double d = isNumber() ? doubleValue() : toNumberImpl();
-
- const double D32 = 4294967296.0;
- const double D31 = D32 / 2.0;
- if ((d >= -D31 && d < D31))
- return static_cast<int>(d);
+ if (Q_LIKELY(isDouble()))
+ return Double::toInt32(doubleValue());
- return Primitive::toInt32(d);
+ return Double::toInt32(toNumberImpl());
}
inline unsigned int Value::toUInt32() const
{
- return (unsigned int)toInt32();
+ return static_cast<unsigned int>(toInt32());
+}
+
+inline double Value::toInteger() const
+{
+ if (integerCompatible())
+ return int_32();
+
+ return Primitive::toInteger(isDouble() ? doubleValue() : toNumberImpl());
}
+template <size_t o>
+struct HeapValue : Value {
+ static Q_CONSTEXPR size_t offset = o;
+ Heap::Base *base() {
+ Heap::Base *base = reinterpret_cast<Heap::Base *>(this) - (offset/sizeof(Heap::Base));
+ Q_ASSERT(base->inUse());
+ return base;
+ }
+
+ void set(EngineBase *e, const Value &newVal) {
+ WriteBarrier::write(e, base(), data_ptr(), newVal.asReturnedValue());
+ }
+ void set(EngineBase *e, Heap::Base *b) {
+ WriteBarrier::write(e, base(), data_ptr(), b->asReturnedValue());
+ }
+};
+
+template <size_t o>
+struct ValueArray {
+ static Q_CONSTEXPR size_t offset = o;
+ uint size;
+ uint alloc;
+ Value values[1];
+
+ Heap::Base *base() {
+ Heap::Base *base = reinterpret_cast<Heap::Base *>(this) - (offset/sizeof(Heap::Base));
+ Q_ASSERT(base->inUse());
+ return base;
+ }
+
+ void set(EngineBase *e, uint index, Value v) {
+ WriteBarrier::write(e, base(), values[index].data_ptr(), v.asReturnedValue());
+ }
+ void set(EngineBase *e, uint index, Heap::Base *b) {
+ WriteBarrier::write(e, base(), values[index].data_ptr(), b->asReturnedValue());
+ }
+ inline const Value &operator[] (uint index) const {
+ Q_ASSERT(index < alloc);
+ return values[index];
+ }
+ inline const Value *data() const {
+ return values;
+ }
+
+ void insertData(EngineBase *e, uint index, Value v) {
+ for (uint i = size - 1; i > index; --i) {
+ values[i] = values[i - 1];
+ }
+ set(e, index, v);
+ }
+ void removeData(EngineBase *e, uint index, int n = 1) {
+ Q_UNUSED(e);
+ for (uint i = index; i < size - n; ++i) {
+ values[i] = values[i + n];
+ }
+ }
+
+ void mark(MarkStack *markStack) {
+ Value *v = values;
+ const Value *end = v + alloc;
+ if (alloc > 32*1024) {
+ // drain from time to time to avoid overflows in the js stack
+ Heap::Base **currentBase = markStack->top;
+ while (v < end) {
+ v->mark(markStack);
+ ++v;
+ if (markStack->top >= currentBase + 32*1024) {
+ Heap::Base **oldBase = markStack->base;
+ markStack->base = currentBase;
+ markStack->drain();
+ markStack->base = oldBase;
+ }
+ }
+ } else {
+ while (v < end) {
+ v->mark(markStack);
+ ++v;
+ }
+ }
+ }
+};
+
+// It's really important that the offset of values in this structure is
+// constant across all architecture, otherwise JIT cross-compiled code will
+// have wrong offsets between host and target.
+Q_STATIC_ASSERT(offsetof(ValueArray<0>, values) == 8);
+
+
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4variantobject.cpp b/src/qml/jsruntime/qv4variantobject.cpp
index 5cab4c5386..bee17e0390 100644
--- a/src/qml/jsruntime/qv4variantobject.cpp
+++ b/src/qml/jsruntime/qv4variantobject.cpp
@@ -84,7 +84,7 @@ bool VariantObject::isEqualTo(Managed *m, Managed *other)
return false;
}
-void VariantObject::addVmePropertyReference()
+void VariantObject::addVmePropertyReference() const
{
if (d()->isScarce() && ++d()->vmePropertyReferenceCount == 1) {
// remove from the ep->scarceResources list
@@ -94,7 +94,7 @@ void VariantObject::addVmePropertyReference()
}
}
-void VariantObject::removeVmePropertyReference()
+void VariantObject::removeVmePropertyReference() const
{
if (d()->isScarce() && --d()->vmePropertyReferenceCount == 0) {
// and add to the ep->scarceResources list
@@ -113,17 +113,17 @@ void VariantPrototype::init()
defineDefaultProperty(engine()->id_toString(), method_toString, 0);
}
-void VariantPrototype::method_preserve(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue VariantPrototype::method_preserve(const FunctionObject *, const Value *thisObject, const Value *, int)
{
- Scoped<VariantObject> o(scope, callData->thisObject.as<QV4::VariantObject>());
+ const VariantObject *o = thisObject->as<QV4::VariantObject>();
if (o && o->d()->isScarce())
o->d()->addVmePropertyReference();
RETURN_UNDEFINED();
}
-void VariantPrototype::method_destroy(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue VariantPrototype::method_destroy(const FunctionObject *, const Value *thisObject, const Value *, int)
{
- Scoped<VariantObject> o(scope, callData->thisObject.as<QV4::VariantObject>());
+ const VariantObject *o = thisObject->as<QV4::VariantObject>();
if (o) {
if (o->d()->isScarce())
o->d()->addVmePropertyReference();
@@ -132,9 +132,10 @@ void VariantPrototype::method_destroy(const BuiltinFunction *, Scope &scope, Cal
RETURN_UNDEFINED();
}
-void VariantPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue VariantPrototype::method_toString(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<VariantObject> o(scope, callData->thisObject.as<QV4::VariantObject>());
+ ExecutionEngine *v4 = b->engine();
+ const VariantObject *o = thisObject->as<QV4::VariantObject>();
if (!o)
RETURN_UNDEFINED();
QString result = o->d()->data().toString();
@@ -143,38 +144,33 @@ void VariantPrototype::method_toString(const BuiltinFunction *, Scope &scope, Ca
+ QLatin1String(o->d()->data().typeName())
+ QLatin1Char(')');
}
- scope.result = scope.engine->newString(result);
+ return Encode(v4->newString(result));
}
-void VariantPrototype::method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue VariantPrototype::method_valueOf(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<VariantObject> o(scope, callData->thisObject.as<QV4::VariantObject>());
+ const VariantObject *o = thisObject->as<QV4::VariantObject>();
if (o) {
QVariant v = o->d()->data();
switch (v.type()) {
case QVariant::Invalid:
- scope.result = Encode::undefined();
- return;
+ return Encode::undefined();
case QVariant::String:
- scope.result = scope.engine->newString(v.toString());
- return;
+ return Encode(b->engine()->newString(v.toString()));
case QVariant::Int:
- scope.result = Encode(v.toInt());
- return;
+ return Encode(v.toInt());
case QVariant::Double:
case QVariant::UInt:
- scope.result = Encode(v.toDouble());
- return;
+ return Encode(v.toDouble());
case QVariant::Bool:
- scope.result = Encode(v.toBool());
- return;
+ return Encode(v.toBool());
default:
if (QMetaType::typeFlags(v.userType()) & QMetaType::IsEnumeration)
RETURN_RESULT(Encode(v.toInt()));
break;
}
}
- scope.result = callData->thisObject;
+ return thisObject->asReturnedValue();
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4variantobject_p.h b/src/qml/jsruntime/qv4variantobject_p.h
index dba14b13fb..62fa7ff9a8 100644
--- a/src/qml/jsruntime/qv4variantobject_p.h
+++ b/src/qml/jsruntime/qv4variantobject_p.h
@@ -96,8 +96,8 @@ struct VariantObject : Object
V4_PROTOTYPE(variantPrototype)
V4_NEEDS_DESTROY
- void addVmePropertyReference();
- void removeVmePropertyReference();
+ void addVmePropertyReference() const;
+ void removeVmePropertyReference() const;
static bool isEqualTo(Managed *m, Managed *other);
};
@@ -108,10 +108,10 @@ public:
V4_PROTOTYPE(objectPrototype)
void init();
- static void method_preserve(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_destroy(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_preserve(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_destroy(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_toString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_valueOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
};
}
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 3d95353fc0..e248d590f7 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -53,19 +53,16 @@
#include <private/qv4regexp_p.h>
#include <private/qv4regexpobject_p.h>
#include <private/qv4string_p.h>
+#include <private/qv4profiling_p.h>
+#include <private/qv4jscall_p.h>
+#include <private/qqmljavascriptexpression_p.h>
#include <iostream>
#include "qv4alloca_p.h"
-#undef DO_TRACE_INSTR // define to enable instruction tracing
+#include <private/qv4jit_p.h>
-#ifdef DO_TRACE_INSTR
-# define TRACE_INSTR(I) qDebug("executing a %s\n", #I);
-# define TRACE(n, str, ...) { char buf[4096]; snprintf(buf, 4096, str, __VA_ARGS__); qDebug(" %s : %s", #n, buf); }
-#else
-# define TRACE_INSTR(I)
-# define TRACE(n, str, ...)
-#endif // DO_TRACE_INSTR
+#undef COUNT_INSTRUCTIONS
extern "C" {
@@ -144,9 +141,9 @@ Q_QML_EXPORT int qt_v4DebuggerHook(const char *json);
} // extern "C"
-#ifndef QT_NO_QML_DEBUGGER
+#if QT_CONFIG(qml_debug)
static int qt_v4BreakpointCount = 0;
-static bool qt_v4IsDebugging = true;
+static bool qt_v4IsDebugging = false;
static bool qt_v4IsStepping = false;
class Breakpoint
@@ -169,14 +166,6 @@ public:
static QVector<Breakpoint> qt_v4Breakpoints;
static Breakpoint qt_v4LastStop;
-static QV4::Function *qt_v4ExtractFunction(QV4::ExecutionContext *context)
-{
- if (QV4::Function *function = context->getFunction())
- return function;
- else
- return context->engine()->globalCode;
-}
-
static void qt_v4TriggerBreakpoint(const Breakpoint &bp, QV4::Function *function)
{
qt_v4LastStop = bp;
@@ -223,6 +212,7 @@ int qt_v4DebuggerHook(const char *json)
bp.fullName = ob.value(QLatin1String("fullName")).toString();
bp.condition = ob.value(QLatin1String("condition")).toString();
qt_v4Breakpoints.append(bp);
+ qt_v4IsDebugging = true;
return bp.bpNumber;
}
@@ -231,6 +221,7 @@ int qt_v4DebuggerHook(const char *json)
QString fullName = ob.value(QLatin1String("fullName")).toString();
if (qt_v4Breakpoints.last().matches(fullName, lineNumber)) {
qt_v4Breakpoints.removeLast();
+ qt_v4IsDebugging = !qt_v4Breakpoints.isEmpty();
return Success;
}
for (int i = 0; i + 1 < qt_v4Breakpoints.size(); ++i) {
@@ -251,13 +242,13 @@ int qt_v4DebuggerHook(const char *json)
return -NoSuchCommand; // Failure.
}
-static void qt_v4CheckForBreak(QV4::ExecutionContext *context)
+Q_NEVER_INLINE static void qt_v4CheckForBreak(QV4::CppStackFrame *frame)
{
if (!qt_v4IsStepping && !qt_v4Breakpoints.size())
return;
- const int lineNumber = context->d()->lineNumber;
- QV4::Function *function = qt_v4ExtractFunction(context);
+ const int lineNumber = frame->lineNumber();
+ QV4::Function *function = frame->v4Function;
QString engineName = function->sourceFile();
if (engineName.isEmpty())
@@ -287,69 +278,65 @@ static void qt_v4CheckForBreak(QV4::ExecutionContext *context)
}
}
-#endif // QT_NO_QML_DEBUGGER
+Q_NEVER_INLINE static void debug_slowPath(QV4::ExecutionEngine *engine)
+{
+ QV4::Debugging::Debugger *debugger = engine->debugger();
+ if (debugger && debugger->pauseAtNextOpportunity())
+ debugger->maybeBreakAtInstruction();
+ if (qt_v4IsDebugging)
+ qt_v4CheckForBreak(engine->currentStackFrame);
+}
+
+#endif // QT_CONFIG(qml_debug)
// End of debugger interface
using namespace QV4;
using namespace QV4::Moth;
-#define MOTH_BEGIN_INSTR_COMMON(I) { \
- const InstrMeta<(int)Instr::I>::DataType &instr = InstrMeta<(int)Instr::I>::data(*genericInstr); \
- code += InstrMeta<(int)Instr::I>::Size; \
- Q_UNUSED(instr); \
- TRACE_INSTR(I)
-
-#ifdef MOTH_THREADED_INTERPRETER
-
-# define MOTH_BEGIN_INSTR(I) op_##I: \
- MOTH_BEGIN_INSTR_COMMON(I)
-
-# define MOTH_END_INSTR(I) } \
- genericInstr = reinterpret_cast<const Instr *>(code); \
- goto *jumpTable[genericInstr->common.instructionType]; \
-
-#else
-
-# define MOTH_BEGIN_INSTR(I) \
- case Instr::I: \
- MOTH_BEGIN_INSTR_COMMON(I)
-
-# define MOTH_END_INSTR(I) } \
- continue;
-
-#endif
-
-#ifdef DO_TRACE_INSTR
-Param traceParam(const Param &param)
-{
- if (param.isConstant()) {
- qDebug(" constant\n");
- } else if (param.isArgument()) {
- qDebug(" argument %d@%d\n", param.index, param.scope);
- } else if (param.isLocal()) {
- qDebug(" local %d\n", param.index);
- } else if (param.isTemp()) {
- qDebug(" temp %d\n", param.index);
- } else if (param.isScopedLocal()) {
- qDebug(" temp %d@%d\n", param.index, param.scope);
- } else {
- Q_ASSERT(!"INVALID");
+#ifdef COUNT_INSTRUCTIONS
+static struct InstrCount {
+ InstrCount() {
+ fprintf(stderr, "Counting instructions...\n");
+ for (int i = 0; i < MOTH_NUM_INSTRUCTIONS(); ++i)
+ hits[i] = 0;
+ }
+ ~InstrCount() {
+ fprintf(stderr, "Instruction count:\n");
+#define BLAH(I) \
+ fprintf(stderr, "%llu : %s\n", hits[int(Instr::Type::I)], #I);
+ FOR_EACH_MOTH_INSTR(BLAH)
+ #undef BLAH
+ }
+ quint64 hits[MOTH_NUM_INSTRUCTIONS()];
+ void hit(Instr::Type i) { hits[int(i)]++; }
+} instrCount;
+#endif // COUNT_INSTRUCTIONS
+
+#define MOTH_BEGIN_INSTR_COMMON(instr) \
+ { \
+ INSTR_##instr(MOTH_DECODE)
+
+#ifdef COUNT_INSTRUCTIONS
+# define MOTH_BEGIN_INSTR(instr) \
+ MOTH_BEGIN_INSTR_COMMON(instr) \
+ instrCount.hit(Instr::Type::instr);
+#else // !COUNT_INSTRUCTIONS
+# define MOTH_BEGIN_INSTR(instr) \
+ MOTH_BEGIN_INSTR_COMMON(instr)
+#endif // COUNT_INSTRUCTIONS
+
+#ifdef MOTH_COMPUTED_GOTO
+#define MOTH_END_INSTR(instr) \
+ MOTH_DISPATCH() \
+ }
+#else // !MOTH_COMPUTED_GOTO
+#define MOTH_END_INSTR(instr) \
+ continue; \
}
- return param;
-}
-# define VALUE(param) (*VALUEPTR(param))
-# define VALUEPTR(param) (scopes[traceParam(param).scope] + param.index)
-#else
-# define VALUE(param) (*VALUEPTR(param))
-# define VALUEPTR(param) (scopes[param.scope] + param.index)
#endif
-#define STOREVALUE(param, value) { \
- QV4::ReturnedValue tmp = (value); \
- if (engine->hasException) \
- goto catchException; \
- VALUE(param) = tmp; \
- }
+#define STACK_VALUE(temp) stack[temp]
+
// qv4scopedvalue_p.h also defines a CHECK_EXCEPTION macro
#ifdef CHECK_EXCEPTION
#undef CHECK_EXCEPTION
@@ -358,609 +345,1037 @@ Param traceParam(const Param &param)
if (engine->hasException) \
goto catchException
-QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code)
+static inline Heap::CallContext *getScope(Value *stack, int level)
{
-#ifdef DO_TRACE_INSTR
- qDebug("Starting VME with context=%p and code=%p", context, code);
-#endif // DO_TRACE_INSTR
+ Heap::ExecutionContext *scope = static_cast<ExecutionContext &>(stack[CallData::Context]).d();
+ while (level > 0) {
+ --level;
+ scope = scope->outer;
+ }
+ Q_ASSERT(scope);
+ return static_cast<Heap::CallContext *>(scope);
+}
- qt_v4ResolvePendingBreakpointsHook();
+static inline const QV4::Value &constant(Function *function, int index)
+{
+ return function->compilationUnit->constants[index];
+}
-#ifdef MOTH_THREADED_INTERPRETER
-#define MOTH_INSTR_ADDR(I, FMT) &&op_##I,
- static void *jumpTable[] = {
- FOR_EACH_MOTH_INSTR(MOTH_INSTR_ADDR)
- };
-#undef MOTH_INSTR_ADDR
-#endif
- QV4::Value *stack = 0;
- unsigned stackSize = 0;
+static bool compareEqual(Value lhs, Value rhs)
+{
+ redo:
+ if (lhs.asReturnedValue() == rhs.asReturnedValue())
+ return !lhs.isNaN();
+
+ int lt = lhs.quickType();
+ int rt = rhs.quickType();
+ if (rt < lt) {
+ qSwap(lhs, rhs);
+ qSwap(lt, rt);
+ }
- const uchar *exceptionHandler = 0;
+ switch (lt) {
+ case Value::QT_ManagedOrUndefined:
+ if (lhs.isUndefined())
+ return rhs.isNullOrUndefined();
+ Q_FALLTHROUGH();
+ case Value::QT_ManagedOrUndefined1:
+ case Value::QT_ManagedOrUndefined2:
+ case Value::QT_ManagedOrUndefined3:
+ // LHS: Managed
+ switch (rt) {
+ case Value::QT_ManagedOrUndefined:
+ if (rhs.isUndefined())
+ return false;
+ Q_FALLTHROUGH();
+ case Value::QT_ManagedOrUndefined1:
+ case Value::QT_ManagedOrUndefined2:
+ case Value::QT_ManagedOrUndefined3: {
+ // RHS: Managed
+ Heap::Base *l = lhs.m();
+ Heap::Base *r = rhs.m();
+ Q_ASSERT(l);
+ Q_ASSERT(r);
+ if (l->vtable()->isString == r->vtable()->isString)
+ return static_cast<QV4::Managed &>(lhs).isEqualTo(&static_cast<QV4::Managed &>(rhs));
+ if (l->vtable()->isString) {
+ rhs = Primitive::fromReturnedValue(RuntimeHelpers::objectDefaultValue(&static_cast<QV4::Object &>(rhs), PREFERREDTYPE_HINT));
+ break;
+ } else {
+ Q_ASSERT(r->vtable()->isString);
+ lhs = Primitive::fromReturnedValue(RuntimeHelpers::objectDefaultValue(&static_cast<QV4::Object &>(lhs), PREFERREDTYPE_HINT));
+ break;
+ }
+ return false;
+ }
+ case Value::QT_Empty:
+ Q_UNREACHABLE();
+ case Value::QT_Null:
+ return false;
+ case Value::QT_Bool:
+ case Value::QT_Int:
+ rhs = Primitive::fromDouble(rhs.int_32());
+ // fall through
+ default: // double
+ if (lhs.m()->vtable()->isString)
+ return RuntimeHelpers::toNumber(lhs) == rhs.doubleValue();
+ else
+ lhs = Primitive::fromReturnedValue(RuntimeHelpers::objectDefaultValue(&static_cast<QV4::Object &>(lhs), PREFERREDTYPE_HINT));
+ }
+ goto redo;
+ case Value::QT_Empty:
+ Q_UNREACHABLE();
+ case Value::QT_Null:
+ return rhs.isNull();
+ case Value::QT_Bool:
+ case Value::QT_Int:
+ switch (rt) {
+ case Value::QT_ManagedOrUndefined:
+ case Value::QT_ManagedOrUndefined1:
+ case Value::QT_ManagedOrUndefined2:
+ case Value::QT_ManagedOrUndefined3:
+ case Value::QT_Empty:
+ case Value::QT_Null:
+ Q_UNREACHABLE();
+ case Value::QT_Bool:
+ case Value::QT_Int:
+ return lhs.int_32() == rhs.int_32();
+ default: // double
+ return lhs.int_32() == rhs.doubleValue();
+ }
+ default: // double
+ Q_ASSERT(rhs.isDouble());
+ return lhs.doubleValue() == rhs.doubleValue();
+ }
+}
- QV4::Scope scope(engine);
- engine->current->lineNumber = -1;
+static bool compareEqualInt(Value &accumulator, Value lhs, int rhs)
+{
+ redo:
+ switch (lhs.quickType()) {
+ case Value::QT_ManagedOrUndefined:
+ if (lhs.isUndefined())
+ return false;
+ Q_FALLTHROUGH();
+ case Value::QT_ManagedOrUndefined1:
+ case Value::QT_ManagedOrUndefined2:
+ case Value::QT_ManagedOrUndefined3:
+ // LHS: Managed
+ if (lhs.m()->vtable()->isString)
+ return RuntimeHelpers::stringToNumber(static_cast<String &>(lhs).toQString()) == rhs;
+ accumulator = lhs;
+ lhs = Primitive::fromReturnedValue(RuntimeHelpers::objectDefaultValue(&static_cast<QV4::Object &>(accumulator), PREFERREDTYPE_HINT));
+ goto redo;
+ case Value::QT_Empty:
+ Q_UNREACHABLE();
+ case Value::QT_Null:
+ return false;
+ case Value::QT_Bool:
+ case Value::QT_Int:
+ return lhs.int_32() == rhs;
+ default: // double
+ return lhs.doubleValue() == rhs;
+ }
+}
-#ifdef DO_TRACE_INSTR
- qDebug("Starting VME with context=%p and code=%p", context, code);
-#endif // DO_TRACE_INSTR
+#define STORE_IP() frame.instructionPointer = int(code - codeStart);
+#define STORE_ACC() accumulator = acc;
+#define ACC Primitive::fromReturnedValue(acc)
+#define VALUE_TO_INT(i, val) \
+ int i; \
+ do { \
+ if (Q_LIKELY(val.integerCompatible())) { \
+ i = val.int_32(); \
+ } else { \
+ double d; \
+ if (val.isDouble()) \
+ d = val.doubleValue(); \
+ else { \
+ STORE_ACC(); \
+ d = val.toNumberImpl(); \
+ CHECK_EXCEPTION; \
+ } \
+ i = Double::toInt32(d); \
+ } \
+ } while (false)
+
+QV4::ReturnedValue VME::exec(const FunctionObject *fo, const Value *thisObject, const Value *argv, int argc)
+{
+ qt_v4ResolvePendingBreakpointsHook();
+ ExecutionEngine *engine;
+ Value *stack;
+ CppStackFrame frame;
+ frame.originalArguments = argv;
+ frame.originalArgumentsCount = argc;
+ Function *function;
- // setup lookup scopes
- int scopeDepth = 0;
{
- QV4::Heap::ExecutionContext *scope = engine->current;
- while (scope) {
- ++scopeDepth;
- scope = scope->outer;
+ Heap::ExecutionContext *scope;
+
+ quintptr d = reinterpret_cast<quintptr>(fo);
+ if (d & 0x1) {
+ // we don't have a FunctionObject, but a ExecData
+ ExecData *data = reinterpret_cast<ExecData *>(d - 1);
+ function = data->function;
+ scope = data->scope->d();
+ fo = nullptr;
+ } else {
+ function = fo->function();
+ scope = fo->scope();
}
+
+ engine = function->internalClass->engine;
+
+ stack = engine->jsStackTop;
+ CallData *callData = reinterpret_cast<CallData *>(stack);
+ callData->function = fo ? fo->asReturnedValue() : Encode::undefined();
+ callData->context = scope;
+ callData->accumulator = Encode::undefined();
+ callData->thisObject = thisObject ? *thisObject : Primitive::undefinedValue();
+ if (argc > int(function->nFormals))
+ argc = int(function->nFormals);
+ callData->setArgc(argc);
+
+ int jsStackFrameSize = offsetof(CallData, args)/sizeof(Value) + function->compiledFunction->nRegisters;
+ engine->jsStackTop += jsStackFrameSize;
+ memcpy(callData->args, argv, argc*sizeof(Value));
+ for (Value *v = callData->args + argc; v < engine->jsStackTop; ++v)
+ *v = Encode::undefined();
+
+ frame.parent = engine->currentStackFrame;
+ frame.v4Function = function;
+ frame.instructionPointer = 0;
+ frame.jsFrame = callData;
+ engine->currentStackFrame = &frame;
}
+ CHECK_STACK_LIMITS(engine);
- Q_ALLOCA_VAR(QV4::Value*, scopes, sizeof(QV4::Value *)*(2 + 2*scopeDepth));
- {
- scopes[0] = const_cast<QV4::Value *>(static_cast<CompiledData::CompilationUnit*>(engine->current->compilationUnit)->constants);
- // stack gets setup in push instruction
- scopes[1] = 0;
- QV4::Heap::ExecutionContext *scope = engine->current;
- int i = 0;
- while (scope) {
- if (scope->type >= QV4::Heap::ExecutionContext::Type_SimpleCallContext) {
- QV4::Heap::CallContext *cc = static_cast<QV4::Heap::CallContext *>(scope);
- scopes[2*i + 2] = cc->callData->args;
- scopes[2*i + 3] = cc->locals;
- } else {
- scopes[2*i + 2] = 0;
- scopes[2*i + 3] = 0;
- }
- ++i;
- scope = scope->outer;
- }
+ Profiling::FunctionCallProfiler profiler(engine, function); // start execution profiling
+ QV4::Debugging::Debugger *debugger = engine->debugger();
+ const uchar *exceptionHandler = 0;
+
+ QV4::Value &accumulator = frame.jsFrame->accumulator;
+ QV4::ReturnedValue acc = Encode::undefined();
+
+#ifdef V4_ENABLE_JIT
+ if (function->jittedCode == nullptr && debugger == nullptr) {
+ if (engine->canJIT(function))
+ QV4::JIT::BaselineJIT(function).generate();
+ else
+ ++function->interpreterCallCount;
}
+#endif // V4_ENABLE_JIT
+
+ if (debugger)
+ debugger->enteringFunction();
+
+ if (function->jittedCode != nullptr && debugger == nullptr) {
+ acc = function->jittedCode(&frame, engine);
+ } else {
+ // interpreter
+ const uchar *code = function->codeData;
+ const uchar *codeStart = code;
+ MOTH_JUMP_TABLE;
for (;;) {
- const Instr *genericInstr = reinterpret_cast<const Instr *>(code);
-#ifdef MOTH_THREADED_INTERPRETER
- goto *jumpTable[genericInstr->common.instructionType];
-#else
- switch (genericInstr->common.instructionType) {
-#endif
+ MOTH_DISPATCH()
+ Q_UNREACHABLE(); // only reached when the dispatch doesn't jump somewhere
+
+ MOTH_BEGIN_INSTR(LoadConst)
+ acc = constant(function, index).asReturnedValue();
+ MOTH_END_INSTR(LoadConst)
+
+ MOTH_BEGIN_INSTR(LoadNull)
+ acc = Encode::null();
+ MOTH_END_INSTR(LoadNull)
+
+ MOTH_BEGIN_INSTR(LoadZero)
+ acc = Encode(static_cast<int>(0));
+ MOTH_END_INSTR(LoadZero)
+
+ MOTH_BEGIN_INSTR(LoadTrue)
+ acc = Encode(true);
+ MOTH_END_INSTR(LoadTrue)
- MOTH_BEGIN_INSTR(Move)
- VALUE(instr.result) = VALUE(instr.source);
- MOTH_END_INSTR(Move)
+ MOTH_BEGIN_INSTR(LoadFalse)
+ acc = Encode(false);
+ MOTH_END_INSTR(LoadFalse)
+
+ MOTH_BEGIN_INSTR(LoadUndefined)
+ acc = Encode::undefined();
+ MOTH_END_INSTR(LoadUndefined)
+
+ MOTH_BEGIN_INSTR(LoadInt)
+ acc = Encode(value);
+ MOTH_END_INSTR(LoadInt)
MOTH_BEGIN_INSTR(MoveConst)
- VALUE(instr.result) = instr.source;
+ STACK_VALUE(destTemp) = constant(function, constIndex);
MOTH_END_INSTR(MoveConst)
- MOTH_BEGIN_INSTR(SwapTemps)
- qSwap(VALUE(instr.left), VALUE(instr.right));
- MOTH_END_INSTR(MoveTemp)
+ MOTH_BEGIN_INSTR(LoadReg)
+ acc = STACK_VALUE(reg).asReturnedValue();
+ MOTH_END_INSTR(LoadReg)
+
+ MOTH_BEGIN_INSTR(StoreReg)
+ STACK_VALUE(reg) = acc;
+ MOTH_END_INSTR(StoreReg)
+
+ MOTH_BEGIN_INSTR(MoveReg)
+ STACK_VALUE(destReg) = STACK_VALUE(srcReg);
+ MOTH_END_INSTR(MoveReg)
+
+ MOTH_BEGIN_INSTR(LoadLocal)
+ auto cc = static_cast<Heap::CallContext *>(stack[CallData::Context].m());
+ acc = cc->locals[index].asReturnedValue();
+ MOTH_END_INSTR(LoadLocal)
+
+ MOTH_BEGIN_INSTR(StoreLocal)
+ CHECK_EXCEPTION;
+ auto cc = static_cast<Heap::CallContext *>(stack[CallData::Context].m());
+ QV4::WriteBarrier::write(engine, cc, cc->locals.values[index].data_ptr(), acc);
+ MOTH_END_INSTR(StoreLocal)
+
+ MOTH_BEGIN_INSTR(LoadScopedLocal)
+ auto cc = getScope(stack, scope);
+ acc = cc->locals[index].asReturnedValue();
+ MOTH_END_INSTR(LoadScopedLocal)
+
+ MOTH_BEGIN_INSTR(StoreScopedLocal)
+ CHECK_EXCEPTION;
+ auto cc = getScope(stack, scope);
+ QV4::WriteBarrier::write(engine, cc, cc->locals.values[index].data_ptr(), acc);
+ MOTH_END_INSTR(StoreScopedLocal)
MOTH_BEGIN_INSTR(LoadRuntimeString)
-// TRACE(value, "%s", instr.value.toString(context)->toQString().toUtf8().constData());
- VALUE(instr.result) = engine->current->compilationUnit->runtimeStrings[instr.stringId];
+ acc = function->compilationUnit->runtimeStrings[stringId]->asReturnedValue();
MOTH_END_INSTR(LoadRuntimeString)
- MOTH_BEGIN_INSTR(LoadRegExp)
-// TRACE(value, "%s", instr.value.toString(context)->toQString().toUtf8().constData());
- Heap::RegExpObject *ro = engine->newRegExpObject(
- static_cast<CompiledData::CompilationUnit*>(engine->current->compilationUnit)
- ->runtimeRegularExpressions[instr.regExpId].as<RegExp>());
- VALUE(instr.result) = ro;
- MOTH_END_INSTR(LoadRegExp)
+ MOTH_BEGIN_INSTR(MoveRegExp)
+ STACK_VALUE(destReg) = Runtime::method_regexpLiteral(engine, regExpId);
+ MOTH_END_INSTR(MoveRegExp)
MOTH_BEGIN_INSTR(LoadClosure)
- STOREVALUE(instr.result, Runtime::method_closure(engine, instr.value));
+ acc = Runtime::method_closure(engine, value);
MOTH_END_INSTR(LoadClosure)
MOTH_BEGIN_INSTR(LoadName)
- TRACE(inline, "property name = %s", runtimeStrings[instr.name]->toQString().toUtf8().constData());
- STOREVALUE(instr.result, Runtime::method_getActivationProperty(engine, instr.name));
+ STORE_IP();
+ acc = Runtime::method_loadName(engine, name);
+ CHECK_EXCEPTION;
MOTH_END_INSTR(LoadName)
- MOTH_BEGIN_INSTR(GetGlobalLookup)
- QV4::Lookup *l = engine->current->lookups + instr.index;
- STOREVALUE(instr.result, l->globalGetter(l, engine));
- MOTH_END_INSTR(GetGlobalLookup)
+ MOTH_BEGIN_INSTR(LoadGlobalLookup)
+ QV4::Lookup *l = function->compilationUnit->runtimeLookups + index;
+ acc = l->globalGetter(l, engine);
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(LoadGlobalLookup)
+
+ MOTH_BEGIN_INSTR(StoreNameStrict)
+ STORE_IP();
+ STORE_ACC();
+ Runtime::method_storeNameStrict(engine, name, accumulator);
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(StoreNameStrict)
- MOTH_BEGIN_INSTR(StoreName)
- TRACE(inline, "property name = %s", runtimeStrings[instr.name]->toQString().toUtf8().constData());
- Runtime::method_setActivationProperty(engine, instr.name, VALUE(instr.source));
+ MOTH_BEGIN_INSTR(StoreNameSloppy)
+ STORE_IP();
+ STORE_ACC();
+ Runtime::method_storeNameSloppy(engine, name, accumulator);
CHECK_EXCEPTION;
- MOTH_END_INSTR(StoreName)
+ MOTH_END_INSTR(StoreNameSloppy)
MOTH_BEGIN_INSTR(LoadElement)
- STOREVALUE(instr.result, Runtime::method_getElement(engine, VALUE(instr.base), VALUE(instr.index)));
+ STORE_IP();
+ acc = Runtime::method_loadElement(engine, STACK_VALUE(base), STACK_VALUE(index));
+ CHECK_EXCEPTION;
MOTH_END_INSTR(LoadElement)
- MOTH_BEGIN_INSTR(LoadElementLookup)
- QV4::Lookup *l = engine->current->lookups + instr.lookup;
- STOREVALUE(instr.result, l->indexedGetter(l, VALUE(instr.base), VALUE(instr.index)));
- MOTH_END_INSTR(LoadElementLookup)
+ MOTH_BEGIN_INSTR(LoadElementA)
+ STORE_IP();
+ STORE_ACC();
+ acc = Runtime::method_loadElement(engine, STACK_VALUE(base), accumulator);
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(LoadElementA)
MOTH_BEGIN_INSTR(StoreElement)
- Runtime::method_setElement(engine, VALUE(instr.base), VALUE(instr.index), VALUE(instr.source));
+ STORE_IP();
+ STORE_ACC();
+ if (!Runtime::method_storeElement(engine, STACK_VALUE(base), STACK_VALUE(index), accumulator) && function->isStrict())
+ engine->throwTypeError();
CHECK_EXCEPTION;
MOTH_END_INSTR(StoreElement)
- MOTH_BEGIN_INSTR(StoreElementLookup)
- QV4::Lookup *l = engine->current->lookups + instr.lookup;
- l->indexedSetter(l, VALUE(instr.base), VALUE(instr.index), VALUE(instr.source));
- CHECK_EXCEPTION;
- MOTH_END_INSTR(StoreElementLookup)
-
MOTH_BEGIN_INSTR(LoadProperty)
- STOREVALUE(instr.result, Runtime::method_getProperty(engine, VALUE(instr.base), instr.name));
+ STORE_IP();
+ acc = Runtime::method_loadProperty(engine, STACK_VALUE(base), name);
+ CHECK_EXCEPTION;
MOTH_END_INSTR(LoadProperty)
+ MOTH_BEGIN_INSTR(LoadPropertyA)
+ STORE_IP();
+ STORE_ACC();
+ acc = Runtime::method_loadProperty(engine, accumulator, name);
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(LoadPropertyA)
+
MOTH_BEGIN_INSTR(GetLookup)
- QV4::Lookup *l = engine->current->lookups + instr.index;
- STOREVALUE(instr.result, l->getter(l, engine, VALUE(instr.base)));
+ STORE_IP();
+ QV4::Lookup *l = function->compilationUnit->runtimeLookups + index;
+ acc = l->getter(l, engine, STACK_VALUE(base));
+ CHECK_EXCEPTION;
MOTH_END_INSTR(GetLookup)
+ MOTH_BEGIN_INSTR(GetLookupA)
+ STORE_IP();
+ STORE_ACC();
+ QV4::Lookup *l = function->compilationUnit->runtimeLookups + index;
+ acc = l->getter(l, engine, accumulator);
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(GetLookupA)
+
MOTH_BEGIN_INSTR(StoreProperty)
- Runtime::method_setProperty(engine, VALUE(instr.base), instr.name, VALUE(instr.source));
+ STORE_IP();
+ STORE_ACC();
+ if (!Runtime::method_storeProperty(engine, STACK_VALUE(base), name, accumulator) && function->isStrict())
+ engine->throwTypeError();
CHECK_EXCEPTION;
MOTH_END_INSTR(StoreProperty)
MOTH_BEGIN_INSTR(SetLookup)
- QV4::Lookup *l = engine->current->lookups + instr.index;
- l->setter(l, engine, VALUE(instr.base), VALUE(instr.source));
+ STORE_IP();
+ STORE_ACC();
+ QV4::Lookup *l = function->compilationUnit->runtimeLookups + index;
+ if (!l->setter(l, engine, STACK_VALUE(base), accumulator) && function->isStrict())
+ engine->throwTypeError();
CHECK_EXCEPTION;
MOTH_END_INSTR(SetLookup)
- MOTH_BEGIN_INSTR(StoreQObjectProperty)
- Runtime::method_setQmlQObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, VALUE(instr.source));
- CHECK_EXCEPTION;
- MOTH_END_INSTR(StoreQObjectProperty)
-
- MOTH_BEGIN_INSTR(LoadQObjectProperty)
- STOREVALUE(instr.result, Runtime::method_getQmlQObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, instr.captureRequired));
- MOTH_END_INSTR(LoadQObjectProperty)
-
MOTH_BEGIN_INSTR(StoreScopeObjectProperty)
- Runtime::method_setQmlScopeObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, VALUE(instr.source));
+ STORE_ACC();
+ Runtime::method_storeQmlScopeObjectProperty(engine, STACK_VALUE(base), propertyIndex, accumulator);
CHECK_EXCEPTION;
MOTH_END_INSTR(StoreScopeObjectProperty)
MOTH_BEGIN_INSTR(LoadScopeObjectProperty)
- STOREVALUE(instr.result, Runtime::method_getQmlScopeObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, instr.captureRequired));
+ STORE_IP();
+ acc = Runtime::method_loadQmlScopeObjectProperty(engine, STACK_VALUE(base), propertyIndex, captureRequired);
+ CHECK_EXCEPTION;
MOTH_END_INSTR(LoadScopeObjectProperty)
MOTH_BEGIN_INSTR(StoreContextObjectProperty)
- Runtime::method_setQmlContextObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, VALUE(instr.source));
+ STORE_IP();
+ STORE_ACC();
+ Runtime::method_storeQmlContextObjectProperty(engine, STACK_VALUE(base), propertyIndex, accumulator);
CHECK_EXCEPTION;
MOTH_END_INSTR(StoreContextObjectProperty)
MOTH_BEGIN_INSTR(LoadContextObjectProperty)
- STOREVALUE(instr.result, Runtime::method_getQmlContextObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, instr.captureRequired));
+ STORE_IP();
+ acc = Runtime::method_loadQmlContextObjectProperty(engine, STACK_VALUE(base), propertyIndex, captureRequired);
+ CHECK_EXCEPTION;
MOTH_END_INSTR(LoadContextObjectProperty)
MOTH_BEGIN_INSTR(LoadIdObject)
- STOREVALUE(instr.result, Runtime::method_getQmlIdObject(engine, VALUE(instr.base), instr.index));
+ STORE_IP();
+ acc = Runtime::method_loadQmlIdObject(engine, STACK_VALUE(base), index);
+ CHECK_EXCEPTION;
MOTH_END_INSTR(LoadIdObject)
- MOTH_BEGIN_INSTR(LoadAttachedQObjectProperty)
- STOREVALUE(instr.result, Runtime::method_getQmlAttachedProperty(engine, instr.attachedPropertiesId, instr.propertyIndex));
- MOTH_END_INSTR(LoadAttachedQObjectProperty)
-
- MOTH_BEGIN_INSTR(LoadSingletonQObjectProperty)
- STOREVALUE(instr.result, Runtime::method_getQmlSingletonQObjectProperty(engine, VALUE(instr.base), instr.propertyIndex, instr.captureRequired));
- MOTH_END_INSTR(LoadSingletonQObjectProperty)
-
- MOTH_BEGIN_INSTR(Push)
- TRACE(inline, "stack size: %u", instr.value);
- stackSize = instr.value;
- stack = scope.alloc(stackSize);
- scopes[1] = stack;
- MOTH_END_INSTR(Push)
-
MOTH_BEGIN_INSTR(CallValue)
-#if 0 //def DO_TRACE_INSTR
- if (Debugging::Debugger *debugger = context->engine()->debugger) {
- if (QV4::FunctionObject *o = (VALUE(instr.dest)).asFunctionObject()) {
- if (Debugging::FunctionDebugInfo *info = debugger->debugInfo(o)) {
- QString n = debugger->name(o);
- std::cerr << "*** Call to \"" << (n.isNull() ? "<no name>" : qPrintable(n)) << "\" defined @" << info->startLine << ":" << info->startColumn << std::endl;
- }
- }
+ STORE_IP();
+ Value func = STACK_VALUE(name);
+ if (Q_UNLIKELY(!func.isFunctionObject())) {
+ acc = engine->throwTypeError(QStringLiteral("%1 is not a function").arg(func.toQStringNoThrow()));
+ goto catchException;
}
-#endif // DO_TRACE_INSTR
- Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
- QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
- callData->tag = quint32(Value::ValueTypeInternal::Integer);
- callData->argc = instr.argc;
- callData->thisObject = QV4::Primitive::undefinedValue();
- STOREVALUE(instr.result, Runtime::method_callValue(engine, VALUE(instr.dest), callData));
+ acc = static_cast<const FunctionObject &>(func).call(nullptr, stack + argv, argc);
+ CHECK_EXCEPTION;
MOTH_END_INSTR(CallValue)
MOTH_BEGIN_INSTR(CallProperty)
- TRACE(property name, "%s, args=%u, argc=%u, this=%s", qPrintable(runtimeStrings[instr.name]->toQString()), instr.callData, instr.argc, (VALUE(instr.base)).toString(engine)->toQString().toUtf8().constData());
- Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
- QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
- callData->tag = quint32(Value::ValueTypeInternal::Integer);
- callData->argc = instr.argc;
- callData->thisObject = VALUE(instr.base);
- STOREVALUE(instr.result, Runtime::method_callProperty(engine, instr.name, callData));
+ STORE_IP();
+ acc = Runtime::method_callProperty(engine, stack + base, name, stack + argv, argc);
+ CHECK_EXCEPTION;
MOTH_END_INSTR(CallProperty)
MOTH_BEGIN_INSTR(CallPropertyLookup)
- Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
- QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
- callData->tag = quint32(Value::ValueTypeInternal::Integer);
- callData->argc = instr.argc;
- callData->thisObject = VALUE(instr.base);
- STOREVALUE(instr.result, Runtime::method_callPropertyLookup(engine, instr.lookupIndex, callData));
- MOTH_END_INSTR(CallPropertyLookup)
+ STORE_IP();
+ Lookup *l = function->compilationUnit->runtimeLookups + lookupIndex;
+ // ok to have the value on the stack here
+ Value f = Value::fromReturnedValue(l->getter(l, engine, stack[base]));
+
+ if (Q_UNLIKELY(!f.isFunctionObject())) {
+ acc = engine->throwTypeError();
+ goto catchException;
+ }
- MOTH_BEGIN_INSTR(CallScopeObjectProperty)
- TRACE(property name, "%s, args=%u, argc=%u, this=%s", qPrintable(runtimeStrings[instr.name]->toQString()), instr.callData, instr.argc, (VALUE(instr.base)).toString(engine)->toQString().toUtf8().constData());
- Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
- QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
- callData->tag = quint32(Value::ValueTypeInternal::Integer);
- callData->argc = instr.argc;
- callData->thisObject = VALUE(instr.base);
- STOREVALUE(instr.result, Runtime::method_callQmlScopeObjectProperty(engine, instr.index, callData));
- MOTH_END_INSTR(CallScopeObjectProperty)
-
- MOTH_BEGIN_INSTR(CallContextObjectProperty)
- TRACE(property name, "%s, args=%u, argc=%u, this=%s", qPrintable(runtimeStrings[instr.name]->toQString()), instr.callData, instr.argc, (VALUE(instr.base)).toString(engine)->toQString().toUtf8().constData());
- Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
- QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
- callData->tag = quint32(Value::ValueTypeInternal::Integer);
- callData->argc = instr.argc;
- callData->thisObject = VALUE(instr.base);
- STOREVALUE(instr.result, Runtime::method_callQmlContextObjectProperty(engine, instr.index, callData));
- MOTH_END_INSTR(CallContextObjectProperty)
+ acc = static_cast<FunctionObject &>(f).call(stack + base, stack + argv, argc);
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(CallPropertyLookup)
MOTH_BEGIN_INSTR(CallElement)
- Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
- QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
- callData->tag = quint32(Value::ValueTypeInternal::Integer);
- callData->argc = instr.argc;
- callData->thisObject = VALUE(instr.base);
- STOREVALUE(instr.result, Runtime::method_callElement(engine, VALUE(instr.index), callData));
+ STORE_IP();
+ acc = Runtime::method_callElement(engine, stack + base, STACK_VALUE(index), stack + argv, argc);
+ CHECK_EXCEPTION;
MOTH_END_INSTR(CallElement)
- MOTH_BEGIN_INSTR(CallActivationProperty)
- Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
- QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
- callData->tag = quint32(Value::ValueTypeInternal::Integer);
- callData->argc = instr.argc;
- callData->thisObject = QV4::Primitive::undefinedValue();
- STOREVALUE(instr.result, Runtime::method_callActivationProperty(engine, instr.name, callData));
- MOTH_END_INSTR(CallActivationProperty)
+ MOTH_BEGIN_INSTR(CallName)
+ STORE_IP();
+ acc = Runtime::method_callName(engine, name, stack + argv, argc);
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(CallName)
+
+ MOTH_BEGIN_INSTR(CallPossiblyDirectEval)
+ STORE_IP();
+ acc = Runtime::method_callPossiblyDirectEval(engine, stack + argv, argc);
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(CallPossiblyDirectEval)
MOTH_BEGIN_INSTR(CallGlobalLookup)
- Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
- QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
- callData->tag = quint32(Value::ValueTypeInternal::Integer);
- callData->argc = instr.argc;
- callData->thisObject = QV4::Primitive::undefinedValue();
- STOREVALUE(instr.result, Runtime::method_callGlobalLookup(engine, instr.index, callData));
+ STORE_IP();
+ acc = Runtime::method_callGlobalLookup(engine, index, stack + argv, argc);
+ CHECK_EXCEPTION;
MOTH_END_INSTR(CallGlobalLookup)
MOTH_BEGIN_INSTR(SetExceptionHandler)
- exceptionHandler = instr.offset ? ((const uchar *)&instr.offset) + instr.offset : 0;
+ exceptionHandler = offset ? code + offset : nullptr;
MOTH_END_INSTR(SetExceptionHandler)
- MOTH_BEGIN_INSTR(CallBuiltinThrow)
- Runtime::method_throwException(engine, VALUE(instr.arg));
+ MOTH_BEGIN_INSTR(ThrowException)
+ STORE_IP();
+ STORE_ACC();
+ Runtime::method_throwException(engine, accumulator);
+ goto catchException;
+ MOTH_END_INSTR(ThrowException)
+
+ MOTH_BEGIN_INSTR(GetException)
+ acc = engine->hasException ? engine->exceptionValue->asReturnedValue()
+ : Primitive::emptyValue().asReturnedValue();
+ engine->hasException = false;
+ MOTH_END_INSTR(HasException)
+
+ MOTH_BEGIN_INSTR(SetException)
+ *engine->exceptionValue = acc;
+ engine->hasException = true;
+ MOTH_END_INSTR(SetException)
+
+ MOTH_BEGIN_INSTR(PushCatchContext)
+ STACK_VALUE(reg) = STACK_VALUE(CallData::Context);
+ ExecutionContext *c = static_cast<ExecutionContext *>(stack + CallData::Context);
+ STACK_VALUE(CallData::Context) = Runtime::method_createCatchContext(c, name);
+ MOTH_END_INSTR(PushCatchContext)
+
+ MOTH_BEGIN_INSTR(CreateCallContext)
+ stack[CallData::Context] = ExecutionContext::newCallContext(&frame);
+ MOTH_END_INSTR(CreateCallContext)
+
+ MOTH_BEGIN_INSTR(PushWithContext)
+ STORE_IP();
+ STORE_ACC();
+ accumulator = accumulator.toObject(engine);
CHECK_EXCEPTION;
- MOTH_END_INSTR(CallBuiltinThrow)
+ STACK_VALUE(reg) = STACK_VALUE(CallData::Context);
+ ExecutionContext *c = static_cast<ExecutionContext *>(stack + CallData::Context);
+ STACK_VALUE(CallData::Context) = Runtime::method_createWithContext(c, accumulator);
+ MOTH_END_INSTR(PushWithContext)
+
+ MOTH_BEGIN_INSTR(PopContext)
+ STACK_VALUE(CallData::Context) = STACK_VALUE(reg);
+ MOTH_END_INSTR(PopContext)
+
+ MOTH_BEGIN_INSTR(ForeachIteratorObject)
+ STORE_ACC();
+ acc = Runtime::method_foreachIterator(engine, accumulator);
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(ForeachIteratorObject)
- MOTH_BEGIN_INSTR(CallBuiltinUnwindException)
- STOREVALUE(instr.result, Runtime::method_unwindException(engine));
- MOTH_END_INSTR(CallBuiltinUnwindException)
+ MOTH_BEGIN_INSTR(ForeachNextPropertyName)
+ STORE_ACC();
+ acc = Runtime::method_foreachNextPropertyName(accumulator);
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(ForeachNextPropertyName)
+
+ MOTH_BEGIN_INSTR(DeleteMember)
+ if (!Runtime::method_deleteMember(engine, STACK_VALUE(base), member)) {
+ if (function->isStrict()) {
+ STORE_IP();
+ engine->throwTypeError();
+ goto catchException;
+ }
+ acc = Encode(false);
+ } else {
+ acc = Encode(true);
+ }
+ MOTH_END_INSTR(DeleteMember)
+
+ MOTH_BEGIN_INSTR(DeleteSubscript)
+ if (!Runtime::method_deleteElement(engine, STACK_VALUE(base), STACK_VALUE(index))) {
+ if (function->isStrict()) {
+ STORE_IP();
+ engine->throwTypeError();
+ goto catchException;
+ }
+ acc = Encode(false);
+ } else {
+ acc = Encode(true);
+ }
+ MOTH_END_INSTR(DeleteSubscript)
+
+ MOTH_BEGIN_INSTR(DeleteName)
+ if (!Runtime::method_deleteName(engine, name)) {
+ if (function->isStrict()) {
+ STORE_IP();
+ QString n = function->compilationUnit->runtimeStrings[name]->toQString();
+ engine->throwSyntaxError(QStringLiteral("Can't delete property %1").arg(n));
+ goto catchException;
+ }
+ acc = Encode(false);
+ } else {
+ acc = Encode(true);
+ }
+ MOTH_END_INSTR(DeleteName)
+
+ MOTH_BEGIN_INSTR(TypeofName)
+ acc = Runtime::method_typeofName(engine, name);
+ MOTH_END_INSTR(TypeofName)
+
+ MOTH_BEGIN_INSTR(TypeofValue)
+ STORE_ACC();
+ acc = Runtime::method_typeofValue(engine, accumulator);
+ MOTH_END_INSTR(TypeofValue)
+
+ MOTH_BEGIN_INSTR(DeclareVar)
+ Runtime::method_declareVar(engine, isDeletable, varName);
+ MOTH_END_INSTR(DeclareVar)
+
+ MOTH_BEGIN_INSTR(DefineArray)
+ QV4::Value *arguments = stack + args;
+ acc = Runtime::method_arrayLiteral(engine, arguments, argc);
+ MOTH_END_INSTR(DefineArray)
+
+ MOTH_BEGIN_INSTR(DefineObjectLiteral)
+ QV4::Value *arguments = stack + args;
+ acc = Runtime::method_objectLiteral(engine, arguments, internalClassId, arrayValueCount, arrayGetterSetterCountAndFlags);
+ MOTH_END_INSTR(DefineObjectLiteral)
+
+ MOTH_BEGIN_INSTR(CreateMappedArgumentsObject)
+ acc = Runtime::method_createMappedArgumentsObject(engine);
+ MOTH_END_INSTR(CreateMappedArgumentsObject)
+
+ MOTH_BEGIN_INSTR(CreateUnmappedArgumentsObject)
+ acc = Runtime::method_createUnmappedArgumentsObject(engine);
+ MOTH_END_INSTR(CreateUnmappedArgumentsObject)
+
+ MOTH_BEGIN_INSTR(ConvertThisToObject)
+ Value *t = &stack[CallData::This];
+ if (!t->isObject()) {
+ if (t->isNullOrUndefined()) {
+ *t = engine->globalObject->asReturnedValue();
+ } else {
+ *t = t->toObject(engine)->asReturnedValue();
+ CHECK_EXCEPTION;
+ }
+ }
+ MOTH_END_INSTR(ConvertThisToObject)
- MOTH_BEGIN_INSTR(CallBuiltinPushCatchScope)
- Runtime::method_pushCatchScope(static_cast<QV4::NoThrowEngine*>(engine), instr.name);
- MOTH_END_INSTR(CallBuiltinPushCatchScope)
-
- MOTH_BEGIN_INSTR(CallBuiltinPushScope)
- Runtime::method_pushWithScope(VALUE(instr.arg), static_cast<QV4::NoThrowEngine*>(engine));
- CHECK_EXCEPTION;
- MOTH_END_INSTR(CallBuiltinPushScope)
-
- MOTH_BEGIN_INSTR(CallBuiltinPopScope)
- Runtime::method_popScope(static_cast<QV4::NoThrowEngine*>(engine));
- MOTH_END_INSTR(CallBuiltinPopScope)
-
- MOTH_BEGIN_INSTR(CallBuiltinForeachIteratorObject)
- STOREVALUE(instr.result, Runtime::method_foreachIterator(engine, VALUE(instr.arg)));
- MOTH_END_INSTR(CallBuiltinForeachIteratorObject)
-
- MOTH_BEGIN_INSTR(CallBuiltinForeachNextPropertyName)
- STOREVALUE(instr.result, Runtime::method_foreachNextPropertyName(VALUE(instr.arg)));
- MOTH_END_INSTR(CallBuiltinForeachNextPropertyName)
-
- MOTH_BEGIN_INSTR(CallBuiltinDeleteMember)
- STOREVALUE(instr.result, Runtime::method_deleteMember(engine, VALUE(instr.base), instr.member));
- MOTH_END_INSTR(CallBuiltinDeleteMember)
-
- MOTH_BEGIN_INSTR(CallBuiltinDeleteSubscript)
- STOREVALUE(instr.result, Runtime::method_deleteElement(engine, VALUE(instr.base), VALUE(instr.index)));
- MOTH_END_INSTR(CallBuiltinDeleteSubscript)
-
- MOTH_BEGIN_INSTR(CallBuiltinDeleteName)
- STOREVALUE(instr.result, Runtime::method_deleteName(engine, instr.name));
- MOTH_END_INSTR(CallBuiltinDeleteName)
-
- MOTH_BEGIN_INSTR(CallBuiltinTypeofScopeObjectProperty)
- STOREVALUE(instr.result, Runtime::method_typeofScopeObjectProperty(engine, VALUE(instr.base), instr.index));
- MOTH_END_INSTR(CallBuiltinTypeofMember)
-
- MOTH_BEGIN_INSTR(CallBuiltinTypeofContextObjectProperty)
- STOREVALUE(instr.result, Runtime::method_typeofContextObjectProperty(engine, VALUE(instr.base), instr.index));
- MOTH_END_INSTR(CallBuiltinTypeofMember)
-
- MOTH_BEGIN_INSTR(CallBuiltinTypeofMember)
- STOREVALUE(instr.result, Runtime::method_typeofMember(engine, VALUE(instr.base), instr.member));
- MOTH_END_INSTR(CallBuiltinTypeofMember)
-
- MOTH_BEGIN_INSTR(CallBuiltinTypeofSubscript)
- STOREVALUE(instr.result, Runtime::method_typeofElement(engine, VALUE(instr.base), VALUE(instr.index)));
- MOTH_END_INSTR(CallBuiltinTypeofSubscript)
-
- MOTH_BEGIN_INSTR(CallBuiltinTypeofName)
- STOREVALUE(instr.result, Runtime::method_typeofName(engine, instr.name));
- MOTH_END_INSTR(CallBuiltinTypeofName)
-
- MOTH_BEGIN_INSTR(CallBuiltinTypeofValue)
- STOREVALUE(instr.result, Runtime::method_typeofValue(engine, VALUE(instr.value)));
- MOTH_END_INSTR(CallBuiltinTypeofValue)
-
- MOTH_BEGIN_INSTR(CallBuiltinDeclareVar)
- Runtime::method_declareVar(engine, instr.isDeletable, instr.varName);
- MOTH_END_INSTR(CallBuiltinDeclareVar)
-
- MOTH_BEGIN_INSTR(CallBuiltinDefineArray)
- Q_ASSERT(instr.args + instr.argc <= stackSize);
- QV4::Value *args = stack + instr.args;
- STOREVALUE(instr.result, Runtime::method_arrayLiteral(engine, args, instr.argc));
- MOTH_END_INSTR(CallBuiltinDefineArray)
-
- MOTH_BEGIN_INSTR(CallBuiltinDefineObjectLiteral)
- QV4::Value *args = stack + instr.args;
- STOREVALUE(instr.result, Runtime::method_objectLiteral(engine, args, instr.internalClassId, instr.arrayValueCount, instr.arrayGetterSetterCountAndFlags));
- MOTH_END_INSTR(CallBuiltinDefineObjectLiteral)
-
- MOTH_BEGIN_INSTR(CallBuiltinSetupArgumentsObject)
- STOREVALUE(instr.result, Runtime::method_setupArgumentsObject(engine));
- MOTH_END_INSTR(CallBuiltinSetupArgumentsObject)
-
- MOTH_BEGIN_INSTR(CallBuiltinConvertThisToObject)
- Runtime::method_convertThisToObject(engine);
- CHECK_EXCEPTION;
- MOTH_END_INSTR(CallBuiltinConvertThisToObject)
-
- MOTH_BEGIN_INSTR(CreateValue)
- Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
- QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
- callData->tag = quint32(Value::ValueTypeInternal::Integer);
- callData->argc = instr.argc;
- callData->thisObject = QV4::Primitive::undefinedValue();
- STOREVALUE(instr.result, Runtime::method_constructValue(engine, VALUE(instr.func), callData));
- MOTH_END_INSTR(CreateValue)
-
- MOTH_BEGIN_INSTR(CreateProperty)
- Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
- QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
- callData->tag = quint32(Value::ValueTypeInternal::Integer);
- callData->argc = instr.argc;
- callData->thisObject = VALUE(instr.base);
- STOREVALUE(instr.result, Runtime::method_constructProperty(engine, instr.name, callData));
- MOTH_END_INSTR(CreateProperty)
-
- MOTH_BEGIN_INSTR(ConstructPropertyLookup)
- Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
- QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
- callData->tag = quint32(Value::ValueTypeInternal::Integer);
- callData->argc = instr.argc;
- callData->thisObject = VALUE(instr.base);
- STOREVALUE(instr.result, Runtime::method_constructPropertyLookup(engine, instr.index, callData));
- MOTH_END_INSTR(ConstructPropertyLookup)
-
- MOTH_BEGIN_INSTR(CreateActivationProperty)
- Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
- QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
- callData->tag = quint32(Value::ValueTypeInternal::Integer);
- callData->argc = instr.argc;
- callData->thisObject = QV4::Primitive::undefinedValue();
- STOREVALUE(instr.result, Runtime::method_constructActivationProperty(engine, instr.name, callData));
- MOTH_END_INSTR(CreateActivationProperty)
-
- MOTH_BEGIN_INSTR(ConstructGlobalLookup)
- Q_ASSERT(instr.callData + instr.argc + offsetof(QV4::CallData, args)/sizeof(QV4::Value) <= stackSize);
- QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData);
- callData->tag = quint32(Value::ValueTypeInternal::Integer);
- callData->argc = instr.argc;
- callData->thisObject = QV4::Primitive::undefinedValue();
- STOREVALUE(instr.result, Runtime::method_constructGlobalLookup(engine, instr.index, callData));
- MOTH_END_INSTR(ConstructGlobalLookup)
+ MOTH_BEGIN_INSTR(Construct)
+ STORE_IP();
+ acc = Runtime::method_construct(engine, STACK_VALUE(func), stack + argv, argc);
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(Construct)
MOTH_BEGIN_INSTR(Jump)
- code = ((const uchar *)&instr.offset) + instr.offset;
+ code += offset;
MOTH_END_INSTR(Jump)
- MOTH_BEGIN_INSTR(JumpEq)
- bool cond = VALUEPTR(instr.condition)->toBoolean();
- TRACE(condition, "%s", cond ? "TRUE" : "FALSE");
- if (cond)
- code = ((const uchar *)&instr.offset) + instr.offset;
- MOTH_END_INSTR(JumpEq)
+ MOTH_BEGIN_INSTR(JumpTrue)
+ if (Q_LIKELY(ACC.integerCompatible())) {
+ if (ACC.int_32())
+ code += offset;
+ } else {
+ if (ACC.toBoolean())
+ code += offset;
+ }
+ MOTH_END_INSTR(JumpTrue)
+
+ MOTH_BEGIN_INSTR(JumpFalse)
+ if (Q_LIKELY(ACC.integerCompatible())) {
+ if (!ACC.int_32())
+ code += offset;
+ } else {
+ if (!ACC.toBoolean())
+ code += offset;
+ }
+ MOTH_END_INSTR(JumpFalse)
+
+ MOTH_BEGIN_INSTR(CmpEqNull)
+ acc = Encode(ACC.isNullOrUndefined());
+ MOTH_END_INSTR(CmpEqNull)
+
+ MOTH_BEGIN_INSTR(CmpNeNull)
+ acc = Encode(!ACC.isNullOrUndefined());
+ MOTH_END_INSTR(CmpNeNull)
+
+ MOTH_BEGIN_INSTR(CmpEqInt)
+ if (ACC.isIntOrBool()) {
+ acc = Encode(ACC.int_32() == lhs);
+ } else {
+ STORE_ACC();
+ acc = Encode(compareEqualInt(accumulator, ACC, lhs));
+ CHECK_EXCEPTION;
+ }
+ MOTH_END_INSTR(CmpEqInt)
+
+ MOTH_BEGIN_INSTR(CmpNeInt)
+ if (ACC.isIntOrBool()) {
+ acc = Encode(bool(ACC.int_32() != lhs));
+ } else {
+ STORE_ACC();
+ acc = Encode(!compareEqualInt(accumulator, ACC, lhs));
+ CHECK_EXCEPTION;
+ }
+ MOTH_END_INSTR(CmpNeInt)
+
+ MOTH_BEGIN_INSTR(CmpEq)
+ const Value left = STACK_VALUE(lhs);
+ if (Q_LIKELY(left.asReturnedValue() == ACC.asReturnedValue())) {
+ acc = Encode(!ACC.isNaN());
+ } else if (Q_LIKELY(left.isInteger() && ACC.isInteger())) {
+ acc = Encode(left.int_32() == ACC.int_32());
+ } else {
+ STORE_ACC();
+ acc = Encode(compareEqual(left, accumulator));
+ CHECK_EXCEPTION;
+ }
+ MOTH_END_INSTR(CmpEq)
+
+ MOTH_BEGIN_INSTR(CmpNe)
+ const Value left = STACK_VALUE(lhs);
+ if (Q_LIKELY(left.isInteger() && ACC.isInteger())) {
+ acc = Encode(bool(left.int_32() != ACC.int_32()));
+ } else {
+ STORE_ACC();
+ acc = Encode(!compareEqual(left, accumulator));
+ CHECK_EXCEPTION;
+ }
+ MOTH_END_INSTR(CmpNe)
+
+ MOTH_BEGIN_INSTR(CmpGt)
+ const Value left = STACK_VALUE(lhs);
+ if (Q_LIKELY(left.isInteger() && ACC.isInteger())) {
+ acc = Encode(left.int_32() > ACC.int_32());
+ } else if (left.isNumber() && ACC.isNumber()) {
+ acc = Encode(left.asDouble() > ACC.asDouble());
+ } else {
+ STORE_ACC();
+ acc = Encode(bool(Runtime::method_compareGreaterThan(left, accumulator)));
+ CHECK_EXCEPTION;
+ }
+ MOTH_END_INSTR(CmpGt)
+
+ MOTH_BEGIN_INSTR(CmpGe)
+ const Value left = STACK_VALUE(lhs);
+ if (Q_LIKELY(left.isInteger() && ACC.isInteger())) {
+ acc = Encode(left.int_32() >= ACC.int_32());
+ } else if (left.isNumber() && ACC.isNumber()) {
+ acc = Encode(left.asDouble() >= ACC.asDouble());
+ } else {
+ STORE_ACC();
+ acc = Encode(bool(Runtime::method_compareGreaterEqual(left, accumulator)));
+ CHECK_EXCEPTION;
+ }
+ MOTH_END_INSTR(CmpGe)
+
+ MOTH_BEGIN_INSTR(CmpLt)
+ const Value left = STACK_VALUE(lhs);
+ if (Q_LIKELY(left.isInteger() && ACC.isInteger())) {
+ acc = Encode(left.int_32() < ACC.int_32());
+ } else if (left.isNumber() && ACC.isNumber()) {
+ acc = Encode(left.asDouble() < ACC.asDouble());
+ } else {
+ STORE_ACC();
+ acc = Encode(bool(Runtime::method_compareLessThan(left, accumulator)));
+ CHECK_EXCEPTION;
+ }
+ MOTH_END_INSTR(CmpLt)
+
+ MOTH_BEGIN_INSTR(CmpLe)
+ const Value left = STACK_VALUE(lhs);
+ if (Q_LIKELY(left.isInteger() && ACC.isInteger())) {
+ acc = Encode(left.int_32() <= ACC.int_32());
+ } else if (left.isNumber() && ACC.isNumber()) {
+ acc = Encode(left.asDouble() <= ACC.asDouble());
+ } else {
+ STORE_ACC();
+ acc = Encode(bool(Runtime::method_compareLessEqual(left, accumulator)));
+ CHECK_EXCEPTION;
+ }
+ MOTH_END_INSTR(CmpLe)
+
+ MOTH_BEGIN_INSTR(CmpStrictEqual)
+ if (STACK_VALUE(lhs).rawValue() == ACC.rawValue() && !ACC.isNaN()) {
+ acc = Encode(true);
+ } else {
+ STORE_ACC();
+ acc = Encode(bool(RuntimeHelpers::strictEqual(STACK_VALUE(lhs), accumulator)));
+ CHECK_EXCEPTION;
+ }
+ MOTH_END_INSTR(CmpStrictEqual)
+
+ MOTH_BEGIN_INSTR(CmpStrictNotEqual)
+ if (STACK_VALUE(lhs).rawValue() != ACC.rawValue() || ACC.isNaN()) {
+ STORE_ACC();
+ acc = Encode(!RuntimeHelpers::strictEqual(STACK_VALUE(lhs), accumulator));
+ CHECK_EXCEPTION;
+ } else {
+ acc = Encode(false);
+ }
+ MOTH_END_INSTR(CmpStrictNotEqual)
+
+ MOTH_BEGIN_INSTR(CmpIn)
+ STORE_ACC();
+ acc = Runtime::method_in(engine, STACK_VALUE(lhs), accumulator);
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(CmpIn)
+
+ MOTH_BEGIN_INSTR(CmpInstanceOf)
+ // 11.8.6, 5: rval must be an Object
+ if (Q_UNLIKELY(!Primitive::fromReturnedValue(acc).isObject())) {
+ acc = engine->throwTypeError();
+ goto catchException;
+ }
+
+ // 11.8.6, 7: call "HasInstance", which we term instanceOf, and return the result.
+ acc = Primitive::fromReturnedValue(acc).objectValue()->instanceOf(STACK_VALUE(lhs));
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(CmpInstanceOf)
- MOTH_BEGIN_INSTR(JumpNe)
- bool cond = VALUEPTR(instr.condition)->toBoolean();
- TRACE(condition, "%s", cond ? "TRUE" : "FALSE");
- if (!cond)
- code = ((const uchar *)&instr.offset) + instr.offset;
- MOTH_END_INSTR(JumpNe)
+ MOTH_BEGIN_INSTR(JumpStrictNotEqualStackSlotInt)
+ if (STACK_VALUE(lhs).int_32() != rhs || STACK_VALUE(lhs).isUndefined())
+ code += offset;
+ MOTH_END_INSTR(JumpStrictNotEqualStackSlotInt)
+
+ MOTH_BEGIN_INSTR(JumpStrictEqualStackSlotInt)
+ if (STACK_VALUE(lhs).int_32() == rhs && !STACK_VALUE(lhs).isUndefined())
+ code += offset;
+ MOTH_END_INSTR(JumpStrictNotEqualStackSlotInt)
MOTH_BEGIN_INSTR(UNot)
- STOREVALUE(instr.result, Runtime::method_uNot(VALUE(instr.source)));
+ if (ACC.integerCompatible()) {
+ acc = Encode(!static_cast<bool>(ACC.int_32()));
+ } else {
+ acc = Encode(!Value::toBooleanImpl(ACC));
+ }
MOTH_END_INSTR(UNot)
- MOTH_BEGIN_INSTR(UNotBool)
- bool b = VALUE(instr.source).booleanValue();
- VALUE(instr.result) = QV4::Encode(!b);
- MOTH_END_INSTR(UNotBool)
-
MOTH_BEGIN_INSTR(UPlus)
- STOREVALUE(instr.result, Runtime::method_uPlus(VALUE(instr.source)));
+ if (Q_UNLIKELY(!ACC.isNumber())) {
+ acc = Encode(ACC.toNumberImpl());
+ CHECK_EXCEPTION;
+ }
MOTH_END_INSTR(UPlus)
MOTH_BEGIN_INSTR(UMinus)
- STOREVALUE(instr.result, Runtime::method_uMinus(VALUE(instr.source)));
+ if (Q_LIKELY(ACC.integerCompatible())) {
+ int a = ACC.int_32();
+ if (a == 0 || a == std::numeric_limits<int>::min()) {
+ acc = Encode(-static_cast<double>(a));
+ } else {
+ acc = sub_int32(0, ACC.int_32());
+ }
+ } else if (ACC.isDouble()) {
+ acc ^= (1ull << 63); // simply flip sign bit
+ } else {
+ acc = Encode(-ACC.toNumberImpl());
+ CHECK_EXCEPTION;
+ }
MOTH_END_INSTR(UMinus)
MOTH_BEGIN_INSTR(UCompl)
- STOREVALUE(instr.result, Runtime::method_complement(VALUE(instr.source)));
+ VALUE_TO_INT(a, ACC);
+ acc = Encode(~a);
MOTH_END_INSTR(UCompl)
- MOTH_BEGIN_INSTR(UComplInt)
- VALUE(instr.result) = QV4::Encode((int)~VALUE(instr.source).integerValue());
- MOTH_END_INSTR(UComplInt)
-
MOTH_BEGIN_INSTR(Increment)
- STOREVALUE(instr.result, Runtime::method_increment(VALUE(instr.source)));
+ if (Q_LIKELY(ACC.integerCompatible())) {
+ acc = add_int32(ACC.int_32(), 1);
+ } else if (ACC.isDouble()) {
+ acc = QV4::Encode(ACC.doubleValue() + 1.);
+ } else {
+ acc = Encode(ACC.toNumberImpl() + 1.);
+ CHECK_EXCEPTION;
+ }
MOTH_END_INSTR(Increment)
MOTH_BEGIN_INSTR(Decrement)
- STOREVALUE(instr.result, Runtime::method_decrement(VALUE(instr.source)));
+ if (Q_LIKELY(ACC.integerCompatible())) {
+ acc = sub_int32(ACC.int_32(), 1);
+ } else if (ACC.isDouble()) {
+ acc = QV4::Encode(ACC.doubleValue() - 1.);
+ } else {
+ acc = Encode(ACC.toNumberImpl() - 1.);
+ CHECK_EXCEPTION;
+ }
MOTH_END_INSTR(Decrement)
- MOTH_BEGIN_INSTR(Binop)
- QV4::Runtime::BinaryOperation op = *reinterpret_cast<QV4::Runtime::BinaryOperation *>(reinterpret_cast<char *>(&engine->runtime.runtimeMethods[instr.alu]));
- STOREVALUE(instr.result, op(VALUE(instr.lhs), VALUE(instr.rhs)));
- MOTH_END_INSTR(Binop)
-
MOTH_BEGIN_INSTR(Add)
- STOREVALUE(instr.result, Runtime::method_add(engine, VALUE(instr.lhs), VALUE(instr.rhs)));
+ const Value left = STACK_VALUE(lhs);
+ if (Q_LIKELY(Value::integerCompatible(left, ACC))) {
+ acc = add_int32(left.int_32(), ACC.int_32());
+ } else if (left.isNumber() && ACC.isNumber()) {
+ acc = Encode(left.asDouble() + ACC.asDouble());
+ } else {
+ STORE_ACC();
+ acc = Runtime::method_add(engine, left, accumulator);
+ CHECK_EXCEPTION;
+ }
MOTH_END_INSTR(Add)
+ MOTH_BEGIN_INSTR(Sub)
+ const Value left = STACK_VALUE(lhs);
+ if (Q_LIKELY(Value::integerCompatible(left, ACC))) {
+ acc = sub_int32(left.int_32(), ACC.int_32());
+ } else if (left.isNumber() && ACC.isNumber()) {
+ acc = Encode(left.asDouble() - ACC.asDouble());
+ } else {
+ STORE_ACC();
+ acc = Runtime::method_sub(left, accumulator);
+ CHECK_EXCEPTION;
+ }
+ MOTH_END_INSTR(Sub)
+
+ MOTH_BEGIN_INSTR(Mul)
+ const Value left = STACK_VALUE(lhs);
+ if (Q_LIKELY(Value::integerCompatible(left, ACC))) {
+ acc = mul_int32(left.int_32(), ACC.int_32());
+ } else if (left.isNumber() && ACC.isNumber()) {
+ acc = Encode(left.asDouble() * ACC.asDouble());
+ } else {
+ STORE_ACC();
+ acc = Runtime::method_mul(left, accumulator);
+ CHECK_EXCEPTION;
+ }
+ MOTH_END_INSTR(Mul)
+
+ MOTH_BEGIN_INSTR(Div)
+ STORE_ACC();
+ acc = Runtime::method_div(STACK_VALUE(lhs), accumulator);
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(Div)
+
+ MOTH_BEGIN_INSTR(Mod)
+ STORE_ACC();
+ acc = Runtime::method_mod(STACK_VALUE(lhs), accumulator);
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(Mod)
+
MOTH_BEGIN_INSTR(BitAnd)
- STOREVALUE(instr.result, Runtime::method_bitAnd(VALUE(instr.lhs), VALUE(instr.rhs)));
+ VALUE_TO_INT(l, STACK_VALUE(lhs));
+ VALUE_TO_INT(a, ACC);
+ acc = Encode(l & a);
MOTH_END_INSTR(BitAnd)
MOTH_BEGIN_INSTR(BitOr)
- STOREVALUE(instr.result, Runtime::method_bitOr(VALUE(instr.lhs), VALUE(instr.rhs)));
+ VALUE_TO_INT(l, STACK_VALUE(lhs));
+ VALUE_TO_INT(a, ACC);
+ acc = Encode(l | a);
MOTH_END_INSTR(BitOr)
MOTH_BEGIN_INSTR(BitXor)
- STOREVALUE(instr.result, Runtime::method_bitXor(VALUE(instr.lhs), VALUE(instr.rhs)));
+ VALUE_TO_INT(l, STACK_VALUE(lhs));
+ VALUE_TO_INT(a, ACC);
+ acc = Encode(l ^ a);
MOTH_END_INSTR(BitXor)
+ MOTH_BEGIN_INSTR(UShr)
+ VALUE_TO_INT(l, STACK_VALUE(lhs));
+ VALUE_TO_INT(a, ACC);
+ acc = Encode(static_cast<uint>(l) >> uint(a & 0x1f));
+ MOTH_END_INSTR(UShr)
+
MOTH_BEGIN_INSTR(Shr)
- STOREVALUE(instr.result, QV4::Encode((int)(VALUEPTR(instr.lhs)->toInt32() >> (VALUEPTR(instr.rhs)->toInt32() & 0x1f))));
+ VALUE_TO_INT(l, STACK_VALUE(lhs));
+ VALUE_TO_INT(a, ACC);
+ acc = Encode(l >> (a & 0x1f));
MOTH_END_INSTR(Shr)
MOTH_BEGIN_INSTR(Shl)
- STOREVALUE(instr.result, QV4::Encode((int)(VALUEPTR(instr.lhs)->toInt32() << (VALUEPTR(instr.rhs)->toInt32() & 0x1f))));
+ VALUE_TO_INT(l, STACK_VALUE(lhs));
+ VALUE_TO_INT(a, ACC);
+ acc = Encode(l << (a & 0x1f));
MOTH_END_INSTR(Shl)
MOTH_BEGIN_INSTR(BitAndConst)
- int lhs = VALUEPTR(instr.lhs)->toInt32();
- STOREVALUE(instr.result, QV4::Encode((int)(lhs & instr.rhs)));
- MOTH_END_INSTR(BitAnd)
+ VALUE_TO_INT(a, ACC);
+ acc = Encode(a & rhs);
+ CHECK_EXCEPTION;
+ MOTH_END_INSTR(BitAndConst)
MOTH_BEGIN_INSTR(BitOrConst)
- int lhs = VALUEPTR(instr.lhs)->toInt32();
- STOREVALUE(instr.result, QV4::Encode((int)(lhs | instr.rhs)));
- MOTH_END_INSTR(BitOr)
+ VALUE_TO_INT(a, ACC);
+ acc = Encode(a | rhs);
+ MOTH_END_INSTR(BitOrConst)
MOTH_BEGIN_INSTR(BitXorConst)
- int lhs = VALUEPTR(instr.lhs)->toInt32();
- STOREVALUE(instr.result, QV4::Encode((int)(lhs ^ instr.rhs)));
- MOTH_END_INSTR(BitXor)
+ VALUE_TO_INT(a, ACC);
+ acc = Encode(a ^ rhs);
+ MOTH_END_INSTR(BitXorConst)
+
+ MOTH_BEGIN_INSTR(UShrConst)
+ acc = Encode(ACC.toUInt32() >> uint(rhs));
+ MOTH_END_INSTR(UShrConst)
MOTH_BEGIN_INSTR(ShrConst)
- STOREVALUE(instr.result, QV4::Encode((int)(VALUEPTR(instr.lhs)->toInt32() >> instr.rhs)));
+ VALUE_TO_INT(a, ACC);
+ acc = Encode(a >> rhs);
MOTH_END_INSTR(ShrConst)
MOTH_BEGIN_INSTR(ShlConst)
- STOREVALUE(instr.result, QV4::Encode((int)(VALUEPTR(instr.lhs)->toInt32() << instr.rhs)));
+ VALUE_TO_INT(a, ACC);
+ acc = Encode(a << rhs);
MOTH_END_INSTR(ShlConst)
- MOTH_BEGIN_INSTR(Mul)
- STOREVALUE(instr.result, Runtime::method_mul(VALUE(instr.lhs), VALUE(instr.rhs)));
- MOTH_END_INSTR(Mul)
-
- MOTH_BEGIN_INSTR(Sub)
- STOREVALUE(instr.result, Runtime::method_sub(VALUE(instr.lhs), VALUE(instr.rhs)));
- MOTH_END_INSTR(Sub)
-
- MOTH_BEGIN_INSTR(BinopContext)
- QV4::Runtime::BinaryOperationContext op = *reinterpret_cast<QV4::Runtime::BinaryOperationContext *>(reinterpret_cast<char *>(&engine->runtime.runtimeMethods[instr.alu]));
- STOREVALUE(instr.result, op(engine, VALUE(instr.lhs), VALUE(instr.rhs)));
- MOTH_END_INSTR(BinopContext)
-
MOTH_BEGIN_INSTR(Ret)
-// TRACE(Ret, "returning value %s", result.toString(context)->toQString().toUtf8().constData());
- return VALUE(instr.result).asReturnedValue();
+ goto functionExit;
MOTH_END_INSTR(Ret)
-#ifndef QT_NO_QML_DEBUGGER
MOTH_BEGIN_INSTR(Debug)
- engine->current->lineNumber = instr.lineNumber;
- QV4::Debugging::Debugger *debugger = engine->debugger();
- if (debugger && debugger->pauseAtNextOpportunity())
- debugger->maybeBreakAtInstruction();
- if (qt_v4IsDebugging)
- qt_v4CheckForBreak(engine->currentContext);
+#if QT_CONFIG(qml_debug)
+ STORE_IP();
+ debug_slowPath(engine);
+#endif // QT_CONFIG(qml_debug)
MOTH_END_INSTR(Debug)
- MOTH_BEGIN_INSTR(Line)
- engine->current->lineNumber = instr.lineNumber;
- if (qt_v4IsDebugging)
- qt_v4CheckForBreak(engine->currentContext);
- MOTH_END_INSTR(Line)
-#endif // QT_NO_QML_DEBUGGER
-
- MOTH_BEGIN_INSTR(LoadThis)
- VALUE(instr.result) = engine->currentContext->thisObject();
- MOTH_END_INSTR(LoadThis)
-
MOTH_BEGIN_INSTR(LoadQmlContext)
- VALUE(instr.result) = Runtime::method_getQmlContext(static_cast<QV4::NoThrowEngine*>(engine));
+ STACK_VALUE(result) = Runtime::method_loadQmlContext(static_cast<QV4::NoThrowEngine*>(engine));
MOTH_END_INSTR(LoadQmlContext)
MOTH_BEGIN_INSTR(LoadQmlImportedScripts)
- VALUE(instr.result) = Runtime::method_getQmlImportedScripts(static_cast<QV4::NoThrowEngine*>(engine));
+ STACK_VALUE(result) = Runtime::method_loadQmlImportedScripts(static_cast<QV4::NoThrowEngine*>(engine));
MOTH_END_INSTR(LoadQmlImportedScripts)
MOTH_BEGIN_INSTR(LoadQmlSingleton)
- VALUE(instr.result) = Runtime::method_getQmlSingleton(static_cast<QV4::NoThrowEngine*>(engine), instr.name);
+ acc = Runtime::method_loadQmlSingleton(static_cast<QV4::NoThrowEngine*>(engine), name);
MOTH_END_INSTR(LoadQmlSingleton)
-#ifdef MOTH_THREADED_INTERPRETER
- // nothing to do
-#else
- default:
- qFatal("QQmlJS::Moth::VME: Internal error - unknown instruction %d", genericInstr->common.instructionType);
- break;
- }
-#endif
-
- Q_ASSERT(false);
catchException:
Q_ASSERT(engine->hasException);
- if (!exceptionHandler)
- return QV4::Encode::undefined();
+ if (!exceptionHandler) {
+ acc = Encode::undefined();
+ goto functionExit;
+ }
code = exceptionHandler;
}
-}
+ }
-QV4::ReturnedValue VME::exec(ExecutionEngine *engine, const uchar *code)
-{
- VME vme;
- QV4::Debugging::Debugger *debugger = engine->debugger();
- if (debugger)
- debugger->enteringFunction();
- QV4::ReturnedValue retVal = vme.run(engine, code);
- if (debugger)
- debugger->leavingFunction(retVal);
- return retVal;
+functionExit:
+ if (QV4::Debugging::Debugger *debugger = engine->debugger())
+ debugger->leavingFunction(ACC.asReturnedValue());
+ engine->currentStackFrame = frame.parent;
+ engine->jsStackTop = stack;
+
+ return acc;
}
diff --git a/src/qml/jsruntime/qv4vme_moth_p.h b/src/qml/jsruntime/qv4vme_moth_p.h
index 8d46207f2b..3b7723ca7e 100644
--- a/src/qml/jsruntime/qv4vme_moth_p.h
+++ b/src/qml/jsruntime/qv4vme_moth_p.h
@@ -52,10 +52,6 @@
//
#include <private/qv4global_p.h>
-#include <private/qv4runtime_p.h>
-#include <private/qv4instr_moth_p.h>
-
-QT_REQUIRE_CONFIG(qml_interpreter);
QT_BEGIN_NAMESPACE
@@ -65,10 +61,17 @@ namespace Moth {
class VME
{
public:
- static QV4::ReturnedValue exec(QV4::ExecutionEngine *, const uchar *);
-
-private:
- QV4::ReturnedValue run(QV4::ExecutionEngine *, const uchar *code);
+ struct ExecData {
+ QV4::Function *function;
+ const QV4::ExecutionContext *scope;
+ };
+ static inline
+ QV4::ReturnedValue exec(Function *v4Function, const Value *thisObject, const Value *argv, int argc, const ExecutionContext *context) {
+ ExecData data{v4Function, context};
+ quintptr d = reinterpret_cast<quintptr>(&data) | 0x1;
+ return exec(reinterpret_cast<const FunctionObject *>(d), thisObject, argv, argc);
+ }
+ static QV4::ReturnedValue exec(const FunctionObject *fo, const Value *thisObject, const Value *argv, int argc);
};
} // namespace Moth
diff --git a/src/qml/memory/memory.pri b/src/qml/memory/memory.pri
index 38fadbf23f..7956e4a9a1 100644
--- a/src/qml/memory/memory.pri
+++ b/src/qml/memory/memory.pri
@@ -7,7 +7,8 @@ SOURCES += \
HEADERS += \
$$PWD/qv4mm_p.h \
- $$PWD/qv4mmdefs_p.h
+ $$PWD/qv4mmdefs_p.h \
+ $$PWD/qv4writebarrier_p.h
}
HEADERS += \
diff --git a/src/qml/memory/qv4heap_p.h b/src/qml/memory/qv4heap_p.h
index a4e96b4c84..53933cd090 100644
--- a/src/qml/memory/qv4heap_p.h
+++ b/src/qml/memory/qv4heap_p.h
@@ -53,6 +53,7 @@
#include <QtCore/QString>
#include <private/qv4global_p.h>
#include <private/qv4mmdefs_p.h>
+#include <private/qv4writebarrier_p.h>
#include <private/qv4internalclass_p.h>
#include <QSharedPointer>
@@ -60,12 +61,6 @@
// parent's init all up the inheritance chain), define QML_CHECK_INIT_DESTROY_CALLS below.
#undef QML_CHECK_INIT_DESTROY_CALLS
-#if defined(_MSC_VER) && (_MSC_VER < 1900) // broken compilers:
-# define V4_ASSERT_IS_TRIVIAL(x)
-#else // working compilers:
-# define V4_ASSERT_IS_TRIVIAL(x) Q_STATIC_ASSERT(std::is_trivial< x >::value);
-#endif
-
QT_BEGIN_NAMESPACE
namespace QV4 {
@@ -87,7 +82,7 @@ struct VTable
uint type : 8;
const char *className;
void (*destroy)(Heap::Base *);
- void (*markObjects)(Heap::Base *, ExecutionEngine *e);
+ void (*markObjects)(Heap::Base *, MarkStack *markStack);
bool (*isEqualTo)(Managed *m, Managed *other);
};
@@ -96,10 +91,12 @@ namespace Heap {
struct Q_QML_EXPORT Base {
void *operator new(size_t) = delete;
+ static void markObjects(Heap::Base *, MarkStack *) {}
+
InternalClass *internalClass;
inline ReturnedValue asReturnedValue() const;
- inline void mark(QV4::ExecutionEngine *engine);
+ inline void mark(QV4::MarkStack *markStack);
const VTable *vtable() const { return internalClass->vtable; }
inline bool isMarked() const {
@@ -114,6 +111,12 @@ struct Q_QML_EXPORT Base {
Q_ASSERT(!Chunk::testBit(c->extendsBitmap, h - c->realBase()));
return Chunk::setBit(c->blackBitmap, h - c->realBase());
}
+ inline void setGrayBit() {
+ const HeapItem *h = reinterpret_cast<const HeapItem *>(this);
+ Chunk *c = h->chunk();
+ Q_ASSERT(!Chunk::testBit(c->extendsBitmap, h - c->realBase()));
+ return Chunk::setBit(c->grayBitmap, h - c->realBase());
+ }
inline bool inUse() const {
const HeapItem *h = reinterpret_cast<const HeapItem *>(this);
@@ -122,6 +125,10 @@ struct Q_QML_EXPORT Base {
return Chunk::testBit(c->objectBitmap, h - c->realBase());
}
+ inline void markChildren(MarkStack *markStack) {
+ vtable()->markObjects(this, markStack);
+ }
+
void *operator new(size_t, Managed *m) { return m; }
void *operator new(size_t, Heap::Base *m) { return m; }
void operator delete(void *, Heap::Base *) {}
@@ -163,7 +170,7 @@ struct Q_QML_EXPORT Base {
Q_ALWAYS_INLINE void _setDestroyed() {}
#endif
};
-V4_ASSERT_IS_TRIVIAL(Base)
+Q_STATIC_ASSERT(std::is_trivial< Base >::value);
// This class needs to consist only of pointer sized members to allow
// for a size/offset translation when cross-compiling between 32- and
// 64-bit.
@@ -171,19 +178,54 @@ Q_STATIC_ASSERT(std::is_standard_layout<Base>::value);
Q_STATIC_ASSERT(offsetof(Base, internalClass) == 0);
Q_STATIC_ASSERT(sizeof(Base) == QT_POINTER_SIZE);
-template <typename T>
+}
+
+inline
+void Heap::Base::mark(QV4::MarkStack *markStack)
+{
+ Q_ASSERT(inUse());
+ const HeapItem *h = reinterpret_cast<const HeapItem *>(this);
+ Chunk *c = h->chunk();
+ size_t index = h - c->realBase();
+ Q_ASSERT(!Chunk::testBit(c->extendsBitmap, index));
+ quintptr *bitmap = c->blackBitmap + Chunk::bitmapIndex(index);
+ quintptr bit = Chunk::bitForIndex(index);
+ if (!(*bitmap & bit)) {
+ *bitmap |= bit;
+ markStack->push(this);
+ }
+}
+
+namespace Heap {
+
+template <typename T, size_t o>
struct Pointer {
- T *operator->() const { return ptr; }
- operator T *() const { return ptr; }
+ static Q_CONSTEXPR size_t offset = o;
+ T operator->() const { return get(); }
+ operator T () const { return get(); }
- Pointer &operator =(T *t) { ptr = t; return *this; }
+ Heap::Base *base() {
+ Heap::Base *base = reinterpret_cast<Heap::Base *>(this) - (offset/sizeof(Heap::Base));
+ Q_ASSERT(base->inUse());
+ return base;
+ }
+
+ void set(EngineBase *e, T newVal) {
+ WriteBarrier::write(e, base(), &ptr, reinterpret_cast<Heap::Base *>(newVal));
+ }
+
+ T get() const { return reinterpret_cast<T>(ptr); }
template <typename Type>
Type *cast() { return static_cast<Type *>(ptr); }
- T *ptr;
+ Heap::Base *heapObject() const { return ptr; }
+
+private:
+ Heap::Base *ptr;
};
-V4_ASSERT_IS_TRIVIAL(Pointer<void>)
+typedef Pointer<char *, 0> V4PointerCheck;
+Q_STATIC_ASSERT(std::is_trivial< V4PointerCheck >::value);
}
@@ -239,7 +281,7 @@ private:
QtSharedPointer::ExternalRefCountData *d;
QObject *qObject;
};
-V4_ASSERT_IS_TRIVIAL(QQmlQPointer<QObject>)
+Q_STATIC_ASSERT(std::is_trivial< QQmlQPointer<QObject> >::value);
#endif
}
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index 418c3444a4..9c51013317 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -61,7 +61,11 @@
#include "qv4alloca_p.h"
#include "qv4profiling_p.h"
-#define MM_DEBUG 0
+//#define MM_STATS
+
+#if !defined(MM_STATS) && !defined(QT_NO_DEBUG)
+#define MM_STATS
+#endif
#if MM_DEBUG
#define DEBUG qDebug() << "MM:"
@@ -281,6 +285,18 @@ QString binary(quintptr) { return QString(); }
#define SDUMP if (1) ; else qDebug
#endif
+// Stores a classname -> freed count mapping.
+typedef QHash<const char*, int> MMStatsHash;
+Q_GLOBAL_STATIC(MMStatsHash, freedObjectStatsGlobal)
+
+// This indirection avoids sticking QHash code in each of the call sites, which
+// shaves off some instructions in the case that it's unused.
+static void increaseFreedCountForClass(const char *className)
+{
+ (*freedObjectStatsGlobal())[className]++;
+}
+
+//bool Chunk::sweep(ClassDestroyStatsCallback classCountPtr)
bool Chunk::sweep(ExecutionEngine *engine)
{
bool hasUsedSlots = false;
@@ -288,7 +304,9 @@ bool Chunk::sweep(ExecutionEngine *engine)
HeapItem *o = realBase();
bool lastSlotFree = false;
for (uint i = 0; i < Chunk::EntriesInBitmap; ++i) {
+#if WRITEBARRIER(none)
Q_ASSERT((grayBitmap[i] | blackBitmap[i]) == blackBitmap[i]); // check that we don't have gray only objects
+#endif
quintptr toFree = objectBitmap[i] ^ blackBitmap[i];
Q_ASSERT((toFree & objectBitmap[i]) == toFree); // check all black objects are marked as being used
quintptr e = extendsBitmap[i];
@@ -317,8 +335,11 @@ bool Chunk::sweep(ExecutionEngine *engine)
HeapItem *itemToFree = o + index;
Heap::Base *b = *itemToFree;
- if (b->vtable()->destroy) {
- b->vtable()->destroy(b);
+ const VTable *v = b->vtable();
+// if (Q_UNLIKELY(classCountPtr))
+// classCountPtr(v->className);
+ if (v->destroy) {
+ v->destroy(b);
b->_checkIsDestroyed();
}
#ifdef V4_USE_HEAPTRACK
@@ -329,8 +350,8 @@ bool Chunk::sweep(ExecutionEngine *engine)
- (blackBitmap[i] | e)) * Chunk::SlotSize,
Profiling::SmallItem);
objectBitmap[i] = blackBitmap[i];
+ grayBitmap[i] = 0;
hasUsedSlots |= (blackBitmap[i] != 0);
- blackBitmap[i] = 0;
extendsBitmap[i] = e;
lastSlotFree = !((objectBitmap[i]|extendsBitmap[i]) >> (sizeof(quintptr)*8 - 1));
SDUMP() << " new extends =" << binary(e);
@@ -379,13 +400,56 @@ void Chunk::freeAll(ExecutionEngine *engine)
Q_V4_PROFILE_DEALLOC(engine, (qPopulationCount(objectBitmap[i]|extendsBitmap[i])
- qPopulationCount(e)) * Chunk::SlotSize, Profiling::SmallItem);
objectBitmap[i] = 0;
- blackBitmap[i] = 0;
+ grayBitmap[i] = 0;
extendsBitmap[i] = e;
o += Chunk::Bits;
}
// DEBUG << "swept chunk" << this << "freed" << slotsFreed << "slots.";
}
+void Chunk::resetBlackBits()
+{
+ memset(blackBitmap, 0, sizeof(blackBitmap));
+}
+
+#ifdef MM_STATS
+static uint nGrayItems = 0;
+#endif
+
+void Chunk::collectGrayItems(MarkStack *markStack)
+{
+ // DEBUG << "sweeping chunk" << this << (*freeList);
+ HeapItem *o = realBase();
+ for (uint i = 0; i < Chunk::EntriesInBitmap; ++i) {
+#if WRITEBARRIER(none)
+ Q_ASSERT((grayBitmap[i] | blackBitmap[i]) == blackBitmap[i]); // check that we don't have gray only objects
+#endif
+ quintptr toMark = blackBitmap[i] & grayBitmap[i]; // correct for a Steele type barrier
+ Q_ASSERT((toMark & objectBitmap[i]) == toMark); // check all black objects are marked as being used
+ // DEBUG << hex << " index=" << i << toFree;
+ while (toMark) {
+ uint index = qCountTrailingZeroBits(toMark);
+ quintptr bit = (static_cast<quintptr>(1) << index);
+
+ toMark ^= bit; // mask out marked slot
+ // DEBUG << " index" << hex << index << toFree;
+
+ HeapItem *itemToFree = o + index;
+ Heap::Base *b = *itemToFree;
+ Q_ASSERT(b->inUse());
+ markStack->push(b);
+#ifdef MM_STATS
+ ++nGrayItems;
+// qDebug() << "adding gray item" << b << "to mark stack";
+#endif
+ }
+ grayBitmap[i] = 0;
+ o += Chunk::Bits;
+ }
+ // DEBUG << "swept chunk" << this << "freed" << slotsFreed << "slots.";
+
+}
+
void Chunk::sortIntoBins(HeapItem **bins, uint nBins)
{
// qDebug() << "sortIntoBins:";
@@ -395,7 +459,7 @@ void Chunk::sortIntoBins(HeapItem **bins, uint nBins)
#else
const int start = 1;
#endif
-#ifndef QT_NO_DEBUG
+#ifdef MM_STATS
uint freeSlots = 0;
uint allocatedSlots = 0;
#endif
@@ -405,7 +469,7 @@ void Chunk::sortIntoBins(HeapItem **bins, uint nBins)
if (!i)
usedSlots |= (static_cast<quintptr>(1) << (HeaderSize/SlotSize)) - 1;
#endif
-#ifndef QT_NO_DEBUG
+#ifdef MM_STATS
allocatedSlots += qPopulationCount(usedSlots);
// qDebug() << hex << " i=" << i << "used=" << usedSlots;
#endif
@@ -422,7 +486,7 @@ void Chunk::sortIntoBins(HeapItem **bins, uint nBins)
break;
}
usedSlots = (objectBitmap[i]|extendsBitmap[i]);
-#ifndef QT_NO_DEBUG
+#ifdef MM_STATS
allocatedSlots += qPopulationCount(usedSlots);
// qDebug() << hex << " i=" << i << "used=" << usedSlots;
#endif
@@ -433,7 +497,7 @@ void Chunk::sortIntoBins(HeapItem **bins, uint nBins)
usedSlots |= (quintptr(1) << index) - 1;
uint freeEnd = i*Bits + index;
uint nSlots = freeEnd - freeStart;
-#ifndef QT_NO_DEBUG
+#ifdef MM_STATS
// qDebug() << hex << " got free slots from" << freeStart << "to" << freeEnd << "n=" << nSlots << "usedSlots=" << usedSlots;
freeSlots += nSlots;
#endif
@@ -444,56 +508,11 @@ void Chunk::sortIntoBins(HeapItem **bins, uint nBins)
bins[bin] = freeItem;
}
}
-#ifndef QT_NO_DEBUG
+#ifdef MM_STATS
Q_ASSERT(freeSlots + allocatedSlots == (EntriesInBitmap - start) * 8 * sizeof(quintptr));
#endif
}
-
-template<typename T>
-StackAllocator<T>::StackAllocator(ChunkAllocator *chunkAlloc)
- : chunkAllocator(chunkAlloc)
-{
- chunks.push_back(chunkAllocator->allocate());
- firstInChunk = chunks.back()->first();
- nextFree = firstInChunk;
- lastInChunk = firstInChunk + (Chunk::AvailableSlots - 1)/requiredSlots*requiredSlots;
-}
-
-template<typename T>
-void StackAllocator<T>::freeAll()
-{
- for (auto c : chunks)
- chunkAllocator->free(c);
-}
-
-template<typename T>
-void StackAllocator<T>::nextChunk() {
- Q_ASSERT(nextFree == lastInChunk);
- ++currentChunk;
- if (currentChunk >= chunks.size()) {
- Chunk *newChunk = chunkAllocator->allocate();
- chunks.push_back(newChunk);
- }
- firstInChunk = chunks.at(currentChunk)->first();
- nextFree = firstInChunk;
- lastInChunk = firstInChunk + (Chunk::AvailableSlots - 1)/requiredSlots*requiredSlots;
-}
-
-template<typename T>
-void QV4::StackAllocator<T>::prevChunk() {
- Q_ASSERT(nextFree == firstInChunk);
- Q_ASSERT(chunks.at(currentChunk) == nextFree->chunk());
- Q_ASSERT(currentChunk > 0);
- --currentChunk;
- firstInChunk = chunks.at(currentChunk)->first();
- lastInChunk = firstInChunk + (Chunk::AvailableSlots - 1)/requiredSlots*requiredSlots;
- nextFree = lastInChunk;
-}
-
-template struct StackAllocator<Heap::CallContext>;
-
-
HeapItem *BlockAllocator::allocate(size_t size, bool forceAllocation) {
Q_ASSERT((size % Chunk::SlotSize) == 0);
size_t slotsRequired = size >> Chunk::SlotSizeShift;
@@ -631,6 +650,18 @@ void BlockAllocator::freeAll()
}
}
+void BlockAllocator::resetBlackBits()
+{
+ for (auto c : chunks)
+ c->resetBlackBits();
+}
+
+void BlockAllocator::collectGrayItems(MarkStack *markStack)
+{
+ for (auto c : chunks)
+ c->collectGrayItems(markStack);
+
+}
HeapItem *HugeItemAllocator::allocate(size_t size) {
Chunk *c = chunkAllocator->allocate(size);
@@ -643,12 +674,16 @@ HeapItem *HugeItemAllocator::allocate(size_t size) {
return c->first();
}
-static void freeHugeChunk(ChunkAllocator *chunkAllocator, const HugeItemAllocator::HugeChunk &c)
+static void freeHugeChunk(ChunkAllocator *chunkAllocator, const HugeItemAllocator::HugeChunk &c, ClassDestroyStatsCallback classCountPtr)
{
HeapItem *itemToFree = c.chunk->first();
Heap::Base *b = *itemToFree;
- if (b->vtable()->destroy) {
- b->vtable()->destroy(b);
+ const VTable *v = b->vtable();
+ if (Q_UNLIKELY(classCountPtr))
+ classCountPtr(v->className);
+
+ if (v->destroy) {
+ v->destroy(b);
b->_checkIsDestroyed();
}
chunkAllocator->free(c.chunk, c.size);
@@ -657,13 +692,14 @@ static void freeHugeChunk(ChunkAllocator *chunkAllocator, const HugeItemAllocato
#endif
}
-void HugeItemAllocator::sweep() {
- auto isBlack = [this] (const HugeChunk &c) {
+void HugeItemAllocator::sweep(ClassDestroyStatsCallback classCountPtr)
+{
+ auto isBlack = [this, classCountPtr] (const HugeChunk &c) {
bool b = c.chunk->first()->isBlack();
Chunk::clearBit(c.chunk->blackBitmap, c.chunk->first() - c.chunk->realBase());
if (!b) {
Q_V4_PROFILE_DEALLOC(engine, c.size, Profiling::LargeItem);
- freeHugeChunk(chunkAllocator, c);
+ freeHugeChunk(chunkAllocator, c, classCountPtr);
}
return !b;
};
@@ -672,11 +708,29 @@ void HugeItemAllocator::sweep() {
chunks.erase(newEnd, chunks.end());
}
+void HugeItemAllocator::resetBlackBits()
+{
+ for (auto c : chunks)
+ Chunk::clearBit(c.chunk->blackBitmap, c.chunk->first() - c.chunk->realBase());
+}
+
+void HugeItemAllocator::collectGrayItems(MarkStack *markStack)
+{
+ for (auto c : chunks)
+ // Correct for a Steele type barrier
+ if (Chunk::testBit(c.chunk->blackBitmap, c.chunk->first() - c.chunk->realBase()) &&
+ Chunk::testBit(c.chunk->grayBitmap, c.chunk->first() - c.chunk->realBase())) {
+ HeapItem *i = c.chunk->first();
+ Heap::Base *b = *i;
+ b->mark(markStack);
+ }
+}
+
void HugeItemAllocator::freeAll()
{
for (auto &c : chunks) {
Q_V4_PROFILE_DEALLOC(engine, c.size, Profiling::LargeItem);
- freeHugeChunk(chunkAllocator, c);
+ freeHugeChunk(chunkAllocator, c, nullptr);
}
}
@@ -684,7 +738,6 @@ void HugeItemAllocator::freeAll()
MemoryManager::MemoryManager(ExecutionEngine *engine)
: engine(engine)
, chunkAllocator(new ChunkAllocator)
- , stackAllocator(chunkAllocator)
, blockAllocator(chunkAllocator, engine)
, hugeItemAllocator(chunkAllocator, engine)
, m_persistentValues(new PersistentValueStorage(engine))
@@ -702,15 +755,17 @@ MemoryManager::MemoryManager(ExecutionEngine *engine)
blockAllocator.allocationStats = statistics.allocations;
}
-#ifndef QT_NO_DEBUG
+#ifdef MM_STATS
+static int allocationCount = 0;
static size_t lastAllocRequestedSlots = 0;
#endif
Heap::Base *MemoryManager::allocString(std::size_t unmanagedSize)
{
const size_t stringSize = align(sizeof(Heap::String));
-#ifndef QT_NO_DEBUG
+#ifdef MM_STATS
lastAllocRequestedSlots = stringSize >> Chunk::SlotSizeShift;
+ ++allocationCount;
#endif
bool didGCRun = false;
@@ -721,7 +776,8 @@ Heap::Base *MemoryManager::allocString(std::size_t unmanagedSize)
unmanagedHeapSize += unmanagedSize;
if (unmanagedHeapSize > unmanagedHeapSizeGCLimit) {
- runGC();
+ if (!didGCRun)
+ runGC();
if (3*unmanagedHeapSizeGCLimit <= 4*unmanagedHeapSize)
// more than 75% full, raise limit
@@ -739,14 +795,16 @@ Heap::Base *MemoryManager::allocString(std::size_t unmanagedSize)
m = blockAllocator.allocate(stringSize, true);
}
+// qDebug() << "allocated string" << m;
memset(m, 0, stringSize);
return *m;
}
Heap::Base *MemoryManager::allocData(std::size_t size)
{
-#ifndef QT_NO_DEBUG
+#ifdef MM_STATS
lastAllocRequestedSlots = size >> Chunk::SlotSizeShift;
+ ++allocationCount;
#endif
bool didRunGC = false;
@@ -760,8 +818,11 @@ Heap::Base *MemoryManager::allocData(std::size_t size)
// qDebug() << "unmanagedHeapSize:" << unmanagedHeapSize << "limit:" << unmanagedHeapSizeGCLimit << "unmanagedSize:" << unmanagedSize;
- if (size > Chunk::DataSize)
- return *hugeItemAllocator.allocate(size);
+ if (size > Chunk::DataSize) {
+ HeapItem *h = hugeItemAllocator.allocate(size);
+// qDebug() << "allocating huge item" << h;
+ return *h;
+ }
HeapItem *m = blockAllocator.allocate(size);
if (!m) {
@@ -771,6 +832,7 @@ Heap::Base *MemoryManager::allocData(std::size_t size)
}
memset(m, 0, size);
+// qDebug() << "allocating data" << m;
return *m;
}
@@ -778,48 +840,74 @@ Heap::Object *MemoryManager::allocObjectWithMemberData(const QV4::VTable *vtable
{
uint size = (vtable->nInlineProperties + vtable->inlinePropertyOffset)*sizeof(Value);
Q_ASSERT(!(size % sizeof(HeapItem)));
- Heap::Object *o = static_cast<Heap::Object *>(allocData(size));
- // ### Could optimize this and allocate both in one go through the block allocator
- if (nMembers > vtable->nInlineProperties) {
+ Heap::Object *o;
+ if (nMembers <= vtable->nInlineProperties) {
+ o = static_cast<Heap::Object *>(allocData(size));
+ } else {
+ // Allocate both in one go through the block allocator
nMembers -= vtable->nInlineProperties;
std::size_t memberSize = align(sizeof(Heap::MemberData) + (nMembers - 1)*sizeof(Value));
-// qDebug() << "allocating member data for" << o << nMembers << memberSize;
- Heap::Base *m;
- if (memberSize > Chunk::DataSize)
- m = *hugeItemAllocator.allocate(memberSize);
- else
- m = *blockAllocator.allocate(memberSize, true);
- memset(m, 0, memberSize);
- o->memberData = static_cast<Heap::MemberData *>(m);
- o->memberData->internalClass = engine->internalClasses[EngineBase::Class_MemberData];
+ size_t totalSize = size + memberSize;
+ Heap::MemberData *m;
+ if (totalSize > Chunk::DataSize) {
+ o = static_cast<Heap::Object *>(allocData(size));
+ m = hugeItemAllocator.allocate(memberSize)->as<Heap::MemberData>();
+ } else {
+ HeapItem *mh = reinterpret_cast<HeapItem *>(allocData(totalSize));
+ Heap::Base *b = *mh;
+ o = static_cast<Heap::Object *>(b);
+ mh += (size >> Chunk::SlotSizeShift);
+ m = mh->as<Heap::MemberData>();
+ Chunk *c = mh->chunk();
+ size_t index = mh - c->realBase();
+ Chunk::setBit(c->objectBitmap, index);
+ Chunk::clearBit(c->extendsBitmap, index);
+ }
+ o->memberData.set(engine, m);
+ m->internalClass = engine->internalClasses[EngineBase::Class_MemberData];
Q_ASSERT(o->memberData->internalClass);
- o->memberData->size = static_cast<uint>((memberSize - sizeof(Heap::MemberData) + sizeof(Value))/sizeof(Value));
- o->memberData->init();
+ m->values.alloc = static_cast<uint>((memberSize - sizeof(Heap::MemberData) + sizeof(Value))/sizeof(Value));
+ m->values.size = o->memberData->values.alloc;
+ m->init();
// qDebug() << " got" << o->memberData << o->memberData->size;
}
+// qDebug() << "allocating object with memberData" << o << o->memberData.operator->();
return o;
}
-static void drainMarkStack(QV4::ExecutionEngine *engine, Value *markBase)
+static uint markStackSize = 0;
+
+MarkStack::MarkStack(ExecutionEngine *engine)
+ : engine(engine)
{
- while (engine->jsStackTop > markBase) {
- Heap::Base *h = engine->popForGC();
+ base = (Heap::Base **)engine->gcStack->base();
+ top = base;
+ limit = base + ExecutionEngine::GCStackLimit/sizeof(Heap::Base)*3/4;
+}
+
+void MarkStack::drain()
+{
+ while (top > base) {
+ Heap::Base *h = pop();
+ ++markStackSize;
Q_ASSERT(h); // at this point we should only have Heap::Base objects in this area on the stack. If not, weird things might happen.
- Q_ASSERT (h->vtable()->markObjects);
- h->vtable()->markObjects(h, engine);
+ h->markChildren(this);
}
}
-void MemoryManager::mark()
+void MemoryManager::collectRoots(MarkStack *markStack)
{
- Value *markBase = engine->jsStackTop;
+ engine->markObjects(markStack);
- engine->markObjects();
+// qDebug() << " mark stack after engine->mark" << (engine->jsStackTop - markBase);
- collectFromJSStack();
+ collectFromJSStack(markStack);
- m_persistentValues->mark(engine);
+// qDebug() << " mark stack after js stack collect" << (engine->jsStackTop - markBase);
+ m_persistentValues->mark(markStack);
+
+// qDebug() << " mark stack after persistants" << (engine->jsStackTop - markBase);
// Preserve QObject ownership rules within JavaScript: A parent with c++ ownership
// keeps all of its children alive in JavaScript.
@@ -846,16 +934,24 @@ void MemoryManager::mark()
}
if (keepAlive)
- qobjectWrapper->mark(engine);
+ qobjectWrapper->mark(markStack);
- if (engine->jsStackTop >= engine->jsStackLimit)
- drainMarkStack(engine, markBase);
+ if (markStack->top >= markStack->limit)
+ markStack->drain();
}
+}
+
+void MemoryManager::mark()
+{
+ markStackSize = 0;
+
+ MarkStack markStack(engine);
+ collectRoots(&markStack);
- drainMarkStack(engine, markBase);
+ markStack.drain();
}
-void MemoryManager::sweep(bool lastSweep)
+void MemoryManager::sweep(bool lastSweep, ClassDestroyStatsCallback classCountPtr)
{
for (PersistentValueStorage::Iterator it = m_weakValues->begin(); it != m_weakValues->end(); ++it) {
Managed *m = (*it).managed();
@@ -903,14 +999,13 @@ void MemoryManager::sweep(bool lastSweep)
}
blockAllocator.sweep();
- hugeItemAllocator.sweep();
+ hugeItemAllocator.sweep(classCountPtr);
}
bool MemoryManager::shouldRunGC() const
{
size_t total = blockAllocator.totalSlots();
- size_t usedSlots = blockAllocator.usedSlotsAfterLastSweep;
- if (total > MinSlotsGCLimit && usedSlots * GCOverallocation < total * 100)
+ if (total > MinSlotsGCLimit && usedSlotsAfterLastFullSweep * GCOverallocation < total * 100)
return true;
return false;
}
@@ -918,15 +1013,15 @@ bool MemoryManager::shouldRunGC() const
size_t dumpBins(BlockAllocator *b, bool printOutput = true)
{
const QLoggingCategory &stats = lcGcAllocatorStats();
- size_t totalFragmentedSlots = 0;
+ size_t totalSlotMem = 0;
if (printOutput)
- qDebug(stats) << "Fragmentation map:";
+ qDebug(stats) << "Slot map:";
for (uint i = 0; i < BlockAllocator::NumBins; ++i) {
uint nEntries = 0;
HeapItem *h = b->freeBins[i];
while (h) {
++nEntries;
- totalFragmentedSlots += h->freeData.availableSlots;
+ totalSlotMem += h->freeData.availableSlots;
h = h->freeData.next;
}
if (printOutput)
@@ -940,8 +1035,8 @@ size_t dumpBins(BlockAllocator *b, bool printOutput = true)
}
if (printOutput)
- qDebug(stats) << " total mem in bins" << totalFragmentedSlots*Chunk::SlotSize;
- return totalFragmentedSlots*Chunk::SlotSize;
+ qDebug(stats) << " total mem in bins" << totalSlotMem*Chunk::SlotSize;
+ return totalSlotMem*Chunk::SlotSize;
}
void MemoryManager::runGC()
@@ -952,6 +1047,7 @@ void MemoryManager::runGC()
}
QScopedValueRollback<bool> gcBlocker(gcBlocked, true);
+// qDebug() << "runGC";
if (gcStats) {
statistics.maxReservedMem = qMax(statistics.maxReservedMem, getAllocatedMem());
@@ -971,22 +1067,29 @@ void MemoryManager::runGC()
const QLoggingCategory &stats = lcGcAllocatorStats();
qDebug(stats) << "========== GC ==========";
-#ifndef QT_NO_DEBUG
+#ifdef MM_STATS
qDebug(stats) << " Triggered by alloc request of" << lastAllocRequestedSlots << "slots.";
+ qDebug(stats) << " Allocations since last GC" << allocationCount;
+ allocationCount = 0;
#endif
size_t oldChunks = blockAllocator.chunks.size();
qDebug(stats) << "Allocated" << totalMem << "bytes in" << oldChunks << "chunks";
qDebug(stats) << "Fragmented memory before GC" << (totalMem - usedBefore);
dumpBins(&blockAllocator);
+#ifdef MM_STATS
+ nGrayItems = 0;
+#endif
+
QElapsedTimer t;
t.start();
mark();
- qint64 markTime = t.restart();
- sweep();
+ qint64 markTime = t.nsecsElapsed()/1000;
+ t.restart();
+ sweep(false, increaseFreedCountForClass);
const size_t usedAfter = getUsedMem();
const size_t largeItemsAfter = getLargeItemsMem();
- qint64 sweepTime = t.elapsed();
+ qint64 sweepTime = t.nsecsElapsed()/1000;
if (triggeredByUnmanagedHeap) {
qDebug(stats) << "triggered by unmanaged heap:";
@@ -995,12 +1098,27 @@ void MemoryManager::runGC()
qDebug(stats) << " unmanaged heap limit:" << unmanagedHeapSizeGCLimit;
}
size_t memInBins = dumpBins(&blockAllocator);
- qDebug(stats) << "Marked object in" << markTime << "ms.";
- qDebug(stats) << "Sweeped object in" << sweepTime << "ms.";
+ qDebug(stats) << "Marked object in" << markTime << "us.";
+ qDebug(stats) << " " << markStackSize << "objects marked";
+ qDebug(stats) << "Sweeped object in" << sweepTime << "us.";
+
+ // sort our object types by number of freed instances
+ MMStatsHash freedObjectStats;
+ std::swap(freedObjectStats, *freedObjectStatsGlobal());
+ typedef std::pair<const char*, int> ObjectStatInfo;
+ std::vector<ObjectStatInfo> freedObjectsSorted;
+ freedObjectsSorted.reserve(freedObjectStats.count());
+ for (auto it = freedObjectStats.constBegin(); it != freedObjectStats.constEnd(); ++it) {
+ freedObjectsSorted.push_back(std::make_pair(it.key(), it.value()));
+ }
+ std::sort(freedObjectsSorted.begin(), freedObjectsSorted.end(), [](const ObjectStatInfo &a, const ObjectStatInfo &b) {
+ return a.second > b.second && strcmp(a.first, b.first) < 0;
+ });
+
qDebug(stats) << "Used memory before GC:" << usedBefore;
qDebug(stats) << "Used memory after GC:" << usedAfter;
- qDebug(stats) << "Freed up bytes:" << (usedBefore - usedAfter);
- qDebug(stats) << "Freed up chunks:" << (oldChunks - blockAllocator.chunks.size());
+ qDebug(stats) << "Freed up bytes :" << (usedBefore - usedAfter);
+ qDebug(stats) << "Freed up chunks :" << (oldChunks - blockAllocator.chunks.size());
size_t lost = blockAllocator.allocatedMem() - memInBins - usedAfter;
if (lost)
qDebug(stats) << "!!!!!!!!!!!!!!!!!!!!! LOST MEM:" << lost << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
@@ -1009,6 +1127,11 @@ void MemoryManager::runGC()
qDebug(stats) << "Large item memory after GC:" << largeItemsAfter;
qDebug(stats) << "Large item memory freed up:" << (largeItemsBefore - largeItemsAfter);
}
+
+ for (auto it = freedObjectsSorted.cbegin(); it != freedObjectsSorted.cend(); ++it) {
+ qDebug(stats).noquote() << QString::fromLatin1("Freed JS type: %1 (%2 instances)").arg(QString::fromLatin1(it->first), QString::number(it->second));
+ }
+
qDebug(stats) << "======== End GC ========";
}
@@ -1019,6 +1142,12 @@ void MemoryManager::runGC()
// ensure we don't 'loose' any memory
Q_ASSERT(blockAllocator.allocatedMem() == getUsedMem() + dumpBins(&blockAllocator, false));
}
+
+ usedSlotsAfterLastFullSweep = blockAllocator.usedSlotsAfterLastSweep;
+
+ // reset all black bits
+ blockAllocator.resetBlackBits();
+ hugeItemAllocator.resetBlackBits();
}
size_t MemoryManager::getUsedMem() const
@@ -1045,7 +1174,6 @@ MemoryManager::~MemoryManager()
sweep(/*lastSweep*/true);
blockAllocator.freeAll();
hugeItemAllocator.freeAll();
- stackAllocator.freeAll();
delete m_weakValues;
#ifdef V4_USE_VALGRIND
@@ -1071,15 +1199,17 @@ void MemoryManager::dumpStats() const
qDebug(stats) << " >=" << ((BlockAllocator::NumBins - 1) << Chunk::SlotSizeShift) << " bytes: " << statistics.allocations[BlockAllocator::NumBins - 1];
}
-void MemoryManager::collectFromJSStack() const
+void MemoryManager::collectFromJSStack(MarkStack *markStack) const
{
Value *v = engine->jsStackBase;
Value *top = engine->jsStackTop;
while (v < top) {
Managed *m = v->managed();
- if (m && m->inUse())
+ if (m) {
+ Q_ASSERT(m->inUse());
// Skip pointers to already freed objects, they are bogus as well
- m->mark(engine);
+ m->mark(markStack);
+ }
++v;
}
}
diff --git a/src/qml/memory/qv4mm_p.h b/src/qml/memory/qv4mm_p.h
index aa8d13de8c..7dc73bdacc 100644
--- a/src/qml/memory/qv4mm_p.h
+++ b/src/qml/memory/qv4mm_p.h
@@ -70,50 +70,6 @@ namespace QV4 {
struct ChunkAllocator;
-template<typename T>
-struct StackAllocator {
- Q_STATIC_ASSERT(sizeof(T) < Chunk::DataSize);
- static const uint requiredSlots = (sizeof(T) + sizeof(HeapItem) - 1)/sizeof(HeapItem);
-
- StackAllocator(ChunkAllocator *chunkAlloc);
-
- T *allocate() {
- T *m = nextFree->as<T>();
- if (Q_UNLIKELY(nextFree == lastInChunk)) {
- nextChunk();
- } else {
- nextFree += requiredSlots;
- }
-#if MM_DEBUG
- Chunk *c = m->chunk();
- Chunk::setBit(c->objectBitmap, m - c->realBase());
-#endif
- return m;
- }
- void free() {
-#if MM_DEBUG
- Chunk::clearBit(item->chunk()->objectBitmap, item - item->chunk()->realBase());
-#endif
- if (Q_UNLIKELY(nextFree == firstInChunk)) {
- prevChunk();
- } else {
- nextFree -= requiredSlots;
- }
- }
-
- void nextChunk();
- void prevChunk();
-
- void freeAll();
-
- ChunkAllocator *chunkAllocator;
- HeapItem *nextFree = 0;
- HeapItem *firstInChunk = 0;
- HeapItem *lastInChunk = 0;
- std::vector<Chunk *> chunks;
- uint currentChunk = 0;
-};
-
struct BlockAllocator {
BlockAllocator(ChunkAllocator *chunkAllocator, ExecutionEngine *engine)
: chunkAllocator(chunkAllocator), engine(engine)
@@ -145,6 +101,8 @@ struct BlockAllocator {
void sweep();
void freeAll();
+ void resetBlackBits();
+ void collectGrayItems(MarkStack *markStack);
// bump allocations
HeapItem *nextFree = 0;
@@ -163,8 +121,10 @@ struct HugeItemAllocator {
{}
HeapItem *allocate(size_t size);
- void sweep();
+ void sweep(ClassDestroyStatsCallback classCountPtr);
void freeAll();
+ void resetBlackBits();
+ void collectGrayItems(MarkStack *markStack);
size_t usedMem() const {
size_t used = 0;
@@ -197,23 +157,10 @@ public:
Q_DECL_CONSTEXPR static inline std::size_t align(std::size_t size)
{ return (size + Chunk::SlotSize - 1) & ~(Chunk::SlotSize - 1); }
- QV4::Heap::CallContext *allocSimpleCallContext()
- {
- Heap::CallContext *ctxt = stackAllocator.allocate();
- memset(ctxt, 0, sizeof(Heap::CallContext));
- ctxt->internalClass = CallContext::defaultInternalClass(engine);
- Q_ASSERT(ctxt->internalClass && ctxt->internalClass->vtable);
- ctxt->init();
- return ctxt;
-
- }
- void freeSimpleCallContext()
- { stackAllocator.free(); }
-
template<typename ManagedType>
inline typename ManagedType::Data *allocManaged(std::size_t size)
{
- V4_ASSERT_IS_TRIVIAL(typename ManagedType::Data)
+ Q_STATIC_ASSERT(std::is_trivial< typename ManagedType::Data >::value);
size = align(size);
Heap::Base *o = allocData(size);
InternalClass *ic = ManagedType::defaultInternalClass(engine);
@@ -223,6 +170,18 @@ public:
return static_cast<typename ManagedType::Data *>(o);
}
+ template<typename ManagedType>
+ inline typename ManagedType::Data *allocManaged(std::size_t size, InternalClass *ic)
+ {
+ Q_STATIC_ASSERT(std::is_trivial< typename ManagedType::Data >::value);
+ size = align(size);
+ Heap::Base *o = allocData(size);
+ o->internalClass = ic;
+ Q_ASSERT(o->internalClass && o->internalClass->vtable);
+ Q_ASSERT(ic->vtable == ManagedType::staticVTable());
+ return static_cast<typename ManagedType::Data *>(o);
+ }
+
template <typename ObjectType>
typename ObjectType::Data *allocateObject(InternalClass *ic)
{
@@ -431,7 +390,6 @@ public:
// called when a JS object grows itself. Specifically: Heap::String::append
void changeUnmanagedHeapSizeUsage(qptrdiff delta) { unmanagedHeapSize += delta; }
-
protected:
/// expects size to be aligned
Heap::Base *allocString(std::size_t unmanagedSize);
@@ -439,15 +397,15 @@ protected:
Heap::Object *allocObjectWithMemberData(const QV4::VTable *vtable, uint nMembers);
private:
- void collectFromJSStack() const;
+ void collectFromJSStack(MarkStack *markStack) const;
void mark();
- void sweep(bool lastSweep = false);
+ void sweep(bool lastSweep = false, ClassDestroyStatsCallback classCountPtr = nullptr);
bool shouldRunGC() const;
+ void collectRoots(MarkStack *markStack);
public:
QV4::ExecutionEngine *engine;
ChunkAllocator *chunkAllocator;
- StackAllocator<Heap::CallContext> stackAllocator;
BlockAllocator blockAllocator;
HugeItemAllocator hugeItemAllocator;
PersistentValueStorage *m_persistentValues;
@@ -456,6 +414,7 @@ public:
std::size_t unmanagedHeapSize = 0; // the amount of bytes of heap that is not managed by the memory manager, but which is held onto by managed items.
std::size_t unmanagedHeapSizeGCLimit;
+ std::size_t usedSlotsAfterLastFullSweep = 0;
bool gcBlocked = false;
bool aggressiveGC = false;
diff --git a/src/qml/memory/qv4mmdefs_p.h b/src/qml/memory/qv4mmdefs_p.h
index 7c82fef056..4e64ba8118 100644
--- a/src/qml/memory/qv4mmdefs_p.h
+++ b/src/qml/memory/qv4mmdefs_p.h
@@ -116,22 +116,29 @@ struct Chunk {
HeapItem *realBase();
HeapItem *first();
+ static Q_ALWAYS_INLINE size_t bitmapIndex(size_t index) {
+ return index >> BitShift;
+ }
+ static Q_ALWAYS_INLINE quintptr bitForIndex(size_t index) {
+ return static_cast<quintptr>(1) << (index & (Bits - 1));
+ }
+
static void setBit(quintptr *bitmap, size_t index) {
// Q_ASSERT(index >= HeaderSize/SlotSize && index < ChunkSize/SlotSize);
- bitmap += index >> BitShift;
- quintptr bit = static_cast<quintptr>(1) << (index & (Bits - 1));
+ bitmap += bitmapIndex(index);
+ quintptr bit = bitForIndex(index);
*bitmap |= bit;
}
static void clearBit(quintptr *bitmap, size_t index) {
// Q_ASSERT(index >= HeaderSize/SlotSize && index < ChunkSize/SlotSize);
- bitmap += index >> BitShift;
- quintptr bit = static_cast<quintptr>(1) << (index & (Bits - 1));
+ bitmap += bitmapIndex(index);
+ quintptr bit = bitForIndex(index);
*bitmap &= ~bit;
}
static bool testBit(quintptr *bitmap, size_t index) {
// Q_ASSERT(index >= HeaderSize/SlotSize && index < ChunkSize/SlotSize);
- bitmap += index >> BitShift;
- quintptr bit = static_cast<quintptr>(1) << (index & (Bits - 1));
+ bitmap += bitmapIndex(index);
+ quintptr bit = bitForIndex(index);
return (*bitmap & bit);
}
static void setBits(quintptr *bitmap, size_t index, size_t nBits) {
@@ -179,6 +186,9 @@ struct Chunk {
return usedSlots;
}
+ bool sweep(ClassDestroyStatsCallback classCountPtr);
+ void resetBlackBits();
+ void collectGrayItems(QV4::MarkStack *markStack);
bool sweep(ExecutionEngine *engine);
void freeAll(ExecutionEngine *engine);
@@ -260,6 +270,84 @@ Q_STATIC_ASSERT(sizeof(HeapItem) == Chunk::SlotSize);
Q_STATIC_ASSERT(QT_POINTER_SIZE*8 == Chunk::Bits);
Q_STATIC_ASSERT((1 << Chunk::BitShift) == Chunk::Bits);
+struct MarkStack {
+ MarkStack(ExecutionEngine *engine);
+ Heap::Base **top = 0;
+ Heap::Base **base = 0;
+ Heap::Base **limit = 0;
+ ExecutionEngine *engine;
+ void push(Heap::Base *m) {
+ *top = m;
+ ++top;
+ }
+ Heap::Base *pop() {
+ --top;
+ return *top;
+ }
+ void drain();
+
+};
+
+// Some helper to automate the generation of our
+// functions used for marking objects
+
+#define HEAP_OBJECT_OFFSET_MEMBER_EXPANSION(c, gcType, type, name) \
+ HEAP_OBJECT_OFFSET_MEMBER_EXPANSION_##gcType(c, type, name)
+
+#define HEAP_OBJECT_OFFSET_MEMBER_EXPANSION_Pointer(c, type, name) Pointer<type, 0> name;
+#define HEAP_OBJECT_OFFSET_MEMBER_EXPANSION_NoMark(c, type, name) type name;
+#define HEAP_OBJECT_OFFSET_MEMBER_EXPANSION_HeapValue(c, type, name) HeapValue<0> name;
+#define HEAP_OBJECT_OFFSET_MEMBER_EXPANSION_ValueArray(c, type, name) type<0> name;
+
+#define HEAP_OBJECT_MEMBER_EXPANSION(c, gcType, type, name) \
+ HEAP_OBJECT_MEMBER_EXPANSION_##gcType(c, type, name)
+
+#define HEAP_OBJECT_MEMBER_EXPANSION_Pointer(c, type, name) \
+ Pointer<type, offsetof(c##OffsetStruct, name) + baseOffset> name;
+#define HEAP_OBJECT_MEMBER_EXPANSION_NoMark(c, type, name) \
+ type name;
+#define HEAP_OBJECT_MEMBER_EXPANSION_HeapValue(c, type, name) \
+ HeapValue<offsetof(c##OffsetStruct, name) + baseOffset> name;
+#define HEAP_OBJECT_MEMBER_EXPANSION_ValueArray(c, type, name) \
+ type<offsetof(c##OffsetStruct, name) + baseOffset> name;
+
+#define HEAP_OBJECT_MARKOBJECTS_EXPANSION(c, gcType, type, name) \
+ HEAP_OBJECT_MARKOBJECTS_EXPANSION_##gcType(c, type, name)
+#define HEAP_OBJECT_MARKOBJECTS_EXPANSION_Pointer(c, type, name) \
+ if (o->name) o->name.heapObject()->mark(stack);
+#define HEAP_OBJECT_MARKOBJECTS_EXPANSION_NoMark(c, type, name)
+#define HEAP_OBJECT_MARKOBJECTS_EXPANSION_HeapValue(c, type, name) \
+ o->name.mark(stack);
+#define HEAP_OBJECT_MARKOBJECTS_EXPANSION_ValueArray(c, type, name) \
+ o->name.mark(stack);
+
+
+#define DECLARE_HEAP_OBJECT_BASE(name, base) \
+struct name##OffsetStruct { \
+ name##Members(name, HEAP_OBJECT_OFFSET_MEMBER_EXPANSION) \
+}; \
+struct name##SizeStruct : base, name##OffsetStruct {}; \
+struct name##Data { \
+ typedef base SuperClass; \
+ static Q_CONSTEXPR size_t baseOffset = sizeof(name##SizeStruct) - sizeof(name##OffsetStruct); \
+ name##Members(name, HEAP_OBJECT_MEMBER_EXPANSION) \
+}; \
+Q_STATIC_ASSERT(sizeof(name##SizeStruct) == sizeof(name##Data) + name##Data::baseOffset); \
+
+#define DECLARE_HEAP_OBJECT(name, base) \
+DECLARE_HEAP_OBJECT_BASE(name, base) \
+struct name : base, name##Data
+#define DECLARE_EXPORTED_HEAP_OBJECT(name, base) \
+DECLARE_HEAP_OBJECT_BASE(name, base) \
+struct Q_QML_EXPORT name : base, name##Data
+
+#define DECLARE_MARKOBJECTS(class) \
+ static void markObjects(Heap::Base *b, MarkStack *stack) { \
+ class *o = static_cast<class *>(b); \
+ class##Data::SuperClass::markObjects(o, stack); \
+ class##Members(class, HEAP_OBJECT_MARKOBJECTS_EXPANSION) \
+ }
+
}
QT_END_NAMESPACE
diff --git a/src/qml/jit/qv4unop_p.h b/src/qml/memory/qv4writebarrier_p.h
index fb68f80eec..8b04aa6cb1 100644
--- a/src/qml/jit/qv4unop_p.h
+++ b/src/qml/memory/qv4writebarrier_p.h
@@ -36,8 +36,8 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#ifndef QV4UNOP_P_H
-#define QV4UNOP_P_H
+#ifndef QV4WRITEBARRIER_P_H
+#define QV4WRITEBARRIER_P_H
//
// W A R N I N G
@@ -50,43 +50,60 @@
// We mean it.
//
-#include <qv4jsir_p.h>
-#include <qv4isel_masm_p.h>
+#include <private/qv4global_p.h>
+#include <private/qv4enginebase_p.h>
QT_BEGIN_NAMESPACE
-#if ENABLE(ASSEMBLER)
+#define WRITEBARRIER_none 1
+
+#define WRITEBARRIER(x) (1/WRITEBARRIER_##x == 1)
namespace QV4 {
-namespace JIT {
-template <typename JITAssembler>
-struct Unop {
- Unop(JITAssembler *assembler, IR::AluOp operation)
- : _as(assembler)
- , op(operation)
- {}
+namespace WriteBarrier {
- using RelationalCondition = typename JITAssembler::RelationalCondition;
- using PointerToValue = typename JITAssembler::PointerToValue;
- using RuntimeCall = typename JITAssembler::RuntimeCall;
- using TrustedImm32 = typename JITAssembler::TrustedImm32;
+enum Type {
+ NoBarrier,
+ Barrier
+};
- void generate(IR::Expr *source, IR::Expr *target);
+enum NewValueType {
+ Primitive,
+ Object,
+ Unknown
+};
- void generateUMinus(IR::Expr *source, IR::Expr *target);
- void generateNot(IR::Expr *source, IR::Expr *target);
- void generateCompl(IR::Expr *source, IR::Expr *target);
+// ### this needs to be filled with a real memory fence once marking is concurrent
+Q_ALWAYS_INLINE void fence() {}
- JITAssembler *_as;
- IR::AluOp op;
-};
+#if WRITEBARRIER(none)
+template <NewValueType type>
+static Q_CONSTEXPR inline bool isRequired() {
+ return false;
}
+
+inline void write(EngineBase *engine, Heap::Base *base, ReturnedValue *slot, ReturnedValue value)
+{
+ Q_UNUSED(engine);
+ Q_UNUSED(base);
+ *slot = value;
+}
+
+inline void write(EngineBase *engine, Heap::Base *base, Heap::Base **slot, Heap::Base *value)
+{
+ Q_UNUSED(engine);
+ Q_UNUSED(base);
+ *slot = value;
}
#endif
+}
+
+}
+
QT_END_NAMESPACE
#endif
diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g
index 9cd212015e..d2d947e55c 100644
--- a/src/qml/parser/qqmljs.g
+++ b/src/qml/parser/qqmljs.g
@@ -71,12 +71,13 @@
%token T_VAR "var" T_VOID "void" T_WHILE "while"
%token T_WITH "with" T_XOR "^" T_XOR_EQ "^="
%token T_NULL "null" T_TRUE "true" T_FALSE "false"
-%token T_CONST "const"
+%token T_CONST "const" T_LET "let"
%token T_DEBUGGER "debugger"
%token T_RESERVED_WORD "reserved word"
%token T_MULTILINE_STRING_LITERAL "multiline string literal"
%token T_COMMENT "comment"
%token T_COMPATIBILITY_SEMICOLON
+%token T_ENUM "enum"
--- context keywords.
%token T_PUBLIC "public"
@@ -281,6 +282,7 @@ public:
AST::UiArrayMemberList *UiArrayMemberList;
AST::UiQualifiedId *UiQualifiedId;
AST::UiQualifiedPragmaId *UiQualifiedPragmaId;
+ AST::UiEnumMemberList *UiEnumMemberList;
};
public:
@@ -449,6 +451,7 @@ Parser::Parser(Engine *engine):
location_stack(0),
string_stack(0),
program(0),
+ yylval(0),
first_token(0),
last_token(0)
{
@@ -1207,6 +1210,59 @@ case $rule_number: {
} break;
./
+UiObjectMember: T_ENUM T_IDENTIFIER T_LBRACE EnumMemberList T_RBRACE;
+/.
+case $rule_number: {
+ AST::UiEnumDeclaration *enumDeclaration = new (pool) AST::UiEnumDeclaration(stringRef(2), sym(4).UiEnumMemberList->finish());
+ enumDeclaration->enumToken = loc(1);
+ enumDeclaration->rbraceToken = loc(5);
+ sym(1).Node = enumDeclaration;
+ break;
+}
+./
+
+EnumMemberList: T_IDENTIFIER;
+/.
+case $rule_number: {
+ AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(stringRef(1));
+ node->memberToken = loc(1);
+ sym(1).Node = node;
+ break;
+}
+./
+
+EnumMemberList: T_IDENTIFIER T_EQ T_NUMERIC_LITERAL;
+/.
+case $rule_number: {
+ AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(stringRef(1), sym(3).dval);
+ node->memberToken = loc(1);
+ node->valueToken = loc(3);
+ sym(1).Node = node;
+ break;
+}
+./
+
+EnumMemberList: EnumMemberList T_COMMA T_IDENTIFIER;
+/.
+case $rule_number: {
+ AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(sym(1).UiEnumMemberList, stringRef(3));
+ node->memberToken = loc(3);
+ sym(1).Node = node;
+ break;
+}
+./
+
+EnumMemberList: EnumMemberList T_COMMA T_IDENTIFIER T_EQ T_NUMERIC_LITERAL;
+/.
+case $rule_number: {
+ AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(sym(1).UiEnumMemberList, stringRef(3), sym(5).dval);
+ node->memberToken = loc(3);
+ node->valueToken = loc(5);
+ sym(1).Node = node;
+ break;
+}
+./
+
JsIdentifier: T_IDENTIFIER;
JsIdentifier: T_PROPERTY ;
@@ -1602,6 +1658,7 @@ ReservedIdentifier: T_DEFAULT ;
ReservedIdentifier: T_DELETE ;
ReservedIdentifier: T_DO ;
ReservedIdentifier: T_ELSE ;
+ReservedIdentifier: T_ENUM ;
ReservedIdentifier: T_FALSE ;
ReservedIdentifier: T_FINALLY ;
ReservedIdentifier: T_FOR ;
@@ -1622,6 +1679,7 @@ ReservedIdentifier: T_VAR ;
ReservedIdentifier: T_VOID ;
ReservedIdentifier: T_WHILE ;
ReservedIdentifier: T_CONST ;
+ReservedIdentifier: T_LET ;
ReservedIdentifier: T_DEBUGGER ;
ReservedIdentifier: T_RESERVED_WORD ;
ReservedIdentifier: T_WITH ;
@@ -2486,14 +2544,26 @@ VariableStatement: VariableDeclarationKind VariableDeclarationList T_AUTOMATIC_S
VariableStatement: VariableDeclarationKind VariableDeclarationList T_SEMICOLON ;
/.
case $rule_number: {
- AST::VariableStatement *node = new (pool) AST::VariableStatement(
- sym(2).VariableDeclarationList->finish (/*readOnly=*/sym(1).ival == T_CONST));
+ AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope;
+ if (sym(1).ival == T_LET)
+ s = AST::VariableDeclaration::BlockScope;
+ else if (sym(1).ival == T_CONST)
+ s = AST::VariableDeclaration::ReadOnlyBlockScope;
+
+ AST::VariableStatement *node = new (pool) AST::VariableStatement(sym(2).VariableDeclarationList->finish(s));
node->declarationKindToken = loc(1);
node->semicolonToken = loc(3);
sym(1).Node = node;
} break;
./
+VariableDeclarationKind: T_LET ;
+/.
+case $rule_number: {
+ sym(1).ival = T_LET;
+} break;
+./
+
VariableDeclarationKind: T_CONST ;
/.
case $rule_number: {
@@ -2542,7 +2612,8 @@ case $rule_number: {
VariableDeclaration: JsIdentifier InitialiserOpt ;
/.
case $rule_number: {
- AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression);
+ AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope;
+ AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression, s);
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
@@ -2551,7 +2622,8 @@ case $rule_number: {
VariableDeclarationNotIn: JsIdentifier InitialiserNotInOpt ;
/.
case $rule_number: {
- AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression);
+ AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope;
+ AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression, s);
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
@@ -2677,8 +2749,9 @@ case $rule_number: {
IterationStatement: T_FOR T_LPAREN T_VAR VariableDeclarationListNotIn T_SEMICOLON ExpressionOpt T_SEMICOLON ExpressionOpt T_RPAREN Statement ;
/.
case $rule_number: {
+ AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope;
AST::LocalForStatement *node = new (pool) AST::LocalForStatement(
- sym(4).VariableDeclarationList->finish (/*readOnly=*/false), sym(6).Expression,
+ sym(4).VariableDeclarationList->finish(s), sym(6).Expression,
sym(8).Expression, sym(10).Statement);
node->forToken = loc(1);
node->lparenToken = loc(2);
diff --git a/src/qml/parser/qqmljsast.cpp b/src/qml/parser/qqmljsast.cpp
index 7f8cecca8f..2433522f42 100644
--- a/src/qml/parser/qqmljsast.cpp
+++ b/src/qml/parser/qqmljsast.cpp
@@ -967,6 +967,23 @@ void UiSourceElement::accept0(Visitor *visitor)
visitor->endVisit(this);
}
+void UiEnumDeclaration::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ accept(members, visitor);
+ }
+
+ visitor->endVisit(this);
+}
+
+void UiEnumMemberList::accept0(Visitor *visitor)
+{
+ if (visitor->visit(this)) {
+ }
+
+ visitor->endVisit(this);
+}
+
} } // namespace QQmlJS::AST
QT_QML_END_NAMESPACE
diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h
index 9b06bf3d31..7291cf0d3d 100644
--- a/src/qml/parser/qqmljsast_p.h
+++ b/src/qml/parser/qqmljsast_p.h
@@ -100,7 +100,8 @@ enum Op {
Sub,
URShift,
InplaceURightShift,
- InplaceXor
+ InplaceXor,
+ Invalid
};
} // namespace QSOperator
@@ -218,7 +219,9 @@ public:
Kind_UiQualifiedPragmaId,
Kind_UiScriptBinding,
Kind_UiSourceElement,
- Kind_UiHeaderItemList
+ Kind_UiHeaderItemList,
+ Kind_UiEnumDeclaration,
+ Kind_UiEnumMemberList
};
inline Node()
@@ -1315,10 +1318,18 @@ class QML_PARSER_EXPORT VariableDeclaration: public Node
public:
QQMLJS_DECLARE_AST_NODE(VariableDeclaration)
- VariableDeclaration(const QStringRef &n, ExpressionNode *e):
- name (n), expression (e), readOnly(false)
+ enum VariableScope {
+ FunctionScope,
+ BlockScope, // let
+ ReadOnlyBlockScope // const
+ };
+
+ VariableDeclaration(const QStringRef &n, ExpressionNode *e, VariableScope s):
+ name (n), expression (e), scope(s)
{ kind = K; }
+ bool isLexicallyScoped() const { return scope != FunctionScope; }
+
void accept0(Visitor *visitor) override;
SourceLocation firstSourceLocation() const override
@@ -1330,8 +1341,8 @@ public:
// attributes
QStringRef name;
ExpressionNode *expression;
- bool readOnly;
SourceLocation identifierToken;
+ VariableScope scope;
};
class QML_PARSER_EXPORT VariableDeclarationList: public Node
@@ -1363,14 +1374,13 @@ public:
return declaration->lastSourceLocation();
}
- inline VariableDeclarationList *finish (bool readOnly)
+ inline VariableDeclarationList *finish(VariableDeclaration::VariableScope s)
{
VariableDeclarationList *front = next;
next = 0;
- if (readOnly) {
- VariableDeclarationList *vdl;
- for (vdl = front; vdl != 0; vdl = vdl->next)
- vdl->declaration->readOnly = true;
+ VariableDeclarationList *vdl;
+ for (vdl = front; vdl != 0; vdl = vdl->next) {
+ vdl->declaration->scope = s;
}
return front;
}
@@ -2778,6 +2788,81 @@ public:
SourceLocation rbracketToken;
};
+class QML_PARSER_EXPORT UiEnumMemberList: public Node
+{
+ QQMLJS_DECLARE_AST_NODE(UiEnumMemberList)
+public:
+ UiEnumMemberList(const QStringRef &member, double v = 0.0)
+ : next(this), member(member), value(v)
+ { kind = K; }
+
+ UiEnumMemberList(UiEnumMemberList *previous, const QStringRef &member)
+ : member(member)
+ {
+ kind = K;
+ next = previous->next;
+ previous->next = this;
+ value = previous->value + 1;
+ }
+
+ UiEnumMemberList(UiEnumMemberList *previous, const QStringRef &member, double v)
+ : member(member), value(v)
+ {
+ kind = K;
+ next = previous->next;
+ previous->next = this;
+ }
+
+ SourceLocation firstSourceLocation() const override
+ { return memberToken; }
+
+ SourceLocation lastSourceLocation() const override
+ { return next ? next->lastSourceLocation() :
+ valueToken.isValid() ? valueToken : memberToken; }
+
+ void accept0(Visitor *visitor) override;
+
+ UiEnumMemberList *finish()
+ {
+ UiEnumMemberList *head = next;
+ next = 0;
+ return head;
+ }
+
+// attributes
+ UiEnumMemberList *next;
+ QStringRef member;
+ double value;
+ SourceLocation memberToken;
+ SourceLocation valueToken;
+};
+
+class QML_PARSER_EXPORT UiEnumDeclaration: public UiObjectMember
+{
+public:
+ QQMLJS_DECLARE_AST_NODE(UiEnumDeclaration)
+
+ UiEnumDeclaration(const QStringRef &name,
+ UiEnumMemberList *members)
+ : name(name)
+ , members(members)
+ { kind = K; }
+
+ SourceLocation firstSourceLocation() const override
+ { return enumToken; }
+
+ SourceLocation lastSourceLocation() const override
+ { return rbraceToken; }
+
+ void accept0(Visitor *visitor) override;
+
+// attributes
+ SourceLocation enumToken;
+ SourceLocation rbraceToken;
+ QStringRef name;
+ UiEnumMemberList *members;
+};
+
} } // namespace AST
diff --git a/src/qml/parser/qqmljsastfwd_p.h b/src/qml/parser/qqmljsastfwd_p.h
index 189eb72a57..140a757e51 100644
--- a/src/qml/parser/qqmljsastfwd_p.h
+++ b/src/qml/parser/qqmljsastfwd_p.h
@@ -181,6 +181,8 @@ class UiArrayMemberList;
class UiQualifiedId;
class UiQualifiedPragmaId;
class UiHeaderItemList;
+class UiEnumDeclaration;
+class UiEnumMemberList;
} } // namespace AST
diff --git a/src/qml/parser/qqmljsastvisitor_p.h b/src/qml/parser/qqmljsastvisitor_p.h
index e582a8f6a7..13218f0e98 100644
--- a/src/qml/parser/qqmljsastvisitor_p.h
+++ b/src/qml/parser/qqmljsastvisitor_p.h
@@ -84,6 +84,8 @@ public:
virtual bool visit(UiArrayMemberList *) { return true; }
virtual bool visit(UiQualifiedId *) { return true; }
virtual bool visit(UiQualifiedPragmaId *) { return true; }
+ virtual bool visit(UiEnumDeclaration *) { return true; }
+ virtual bool visit(UiEnumMemberList *) { return true; }
virtual void endVisit(UiProgram *) {}
virtual void endVisit(UiImport *) {}
@@ -101,6 +103,8 @@ public:
virtual void endVisit(UiArrayMemberList *) {}
virtual void endVisit(UiQualifiedId *) {}
virtual void endVisit(UiQualifiedPragmaId *) {}
+ virtual void endVisit(UiEnumDeclaration *) {}
+ virtual void endVisit(UiEnumMemberList *) { }
// QQmlJS
virtual bool visit(ThisExpression *) { return true; }
diff --git a/src/qml/parser/qqmljsgrammar.cpp b/src/qml/parser/qqmljsgrammar.cpp
index b27f4af080..f345990ff9 100644
--- a/src/qml/parser/qqmljsgrammar.cpp
+++ b/src/qml/parser/qqmljsgrammar.cpp
@@ -43,1049 +43,1125 @@
QT_BEGIN_NAMESPACE
const char *const QQmlJSGrammar::spell [] = {
- "end of file", "&", "&&", "&=", "break", "case", "catch", ":", ",", "continue",
- "default", "delete", "/", "/=", "do", ".", "else", "=", "==", "===",
- "finally", "for", "function", ">=", ">", ">>", ">>=", ">>>", ">>>=", "identifier",
- "if", "in", "instanceof", "{", "[", "<=", "(", "<", "<<", "<<=",
- "-", "-=", "--", "new", "!", "!=", "!==", "numeric literal", "|", "|=",
- "||", "+", "+=", "++", "?", "}", "]", "%", "%=", "return",
- ")", ";", 0, "*", "*=", "string literal", "property", "signal", "readonly", "switch",
- "this", "throw", "~", "try", "typeof", "var", "void", "while", "with", "^",
- "^=", "null", "true", "false", "const", "debugger", "reserved word", "multiline string literal", "comment", 0,
- "public", "import", "pragma", "as", "on", "get", "set", 0, 0, 0,
- 0, 0, 0, 0, 0, 0};
+ "end of file", "&", "&&", "&=", "break", "case", "catch", ":", ",", "continue",
+ "default", "delete", "/", "/=", "do", ".", "else", "=", "==", "===",
+ "finally", "for", "function", ">=", ">", ">>", ">>=", ">>>", ">>>=", "identifier",
+ "if", "in", "instanceof", "{", "[", "<=", "(", "<", "<<", "<<=",
+ "-", "-=", "--", "new", "!", "!=", "!==", "numeric literal", "|", "|=",
+ "||", "+", "+=", "++", "?", "}", "]", "%", "%=", "return",
+ ")", ";", 0, "*", "*=", "string literal", "property", "signal", "readonly", "switch",
+ "this", "throw", "~", "try", "typeof", "var", "void", "while", "with", "^",
+ "^=", "null", "true", "false", "const", "let", "debugger", "reserved word", "multiline string literal", "comment",
+ 0, "enum", "public", "import", "pragma", "as", "on", "get", "set", 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
const short QQmlJSGrammar::lhs [] = {
- 106, 106, 106, 106, 106, 106, 107, 113, 113, 116,
- 116, 116, 116, 119, 121, 117, 117, 118, 118, 118,
- 118, 118, 118, 118, 118, 122, 123, 115, 114, 126,
- 126, 127, 127, 128, 128, 125, 111, 111, 111, 111,
- 130, 130, 130, 130, 130, 130, 130, 111, 138, 138,
- 138, 138, 139, 139, 140, 140, 111, 111, 111, 111,
- 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,
- 111, 111, 111, 111, 111, 111, 124, 124, 124, 124,
- 124, 124, 124, 143, 143, 143, 143, 143, 143, 143,
- 143, 143, 143, 143, 143, 143, 143, 143, 143, 143,
- 143, 129, 145, 145, 145, 145, 144, 144, 149, 149,
- 149, 147, 147, 150, 150, 150, 150, 153, 153, 153,
- 153, 153, 153, 153, 153, 153, 153, 153, 153, 153,
- 153, 153, 153, 153, 153, 153, 153, 153, 153, 153,
- 153, 153, 153, 153, 153, 153, 153, 153, 154, 154,
- 120, 120, 120, 120, 120, 157, 157, 158, 158, 158,
- 158, 156, 156, 159, 159, 160, 160, 161, 161, 161,
- 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
- 163, 163, 163, 163, 164, 164, 164, 165, 165, 165,
- 165, 166, 166, 166, 166, 166, 166, 166, 167, 167,
- 167, 167, 167, 167, 168, 168, 168, 168, 168, 169,
- 169, 169, 169, 169, 170, 170, 171, 171, 172, 172,
- 173, 173, 174, 174, 175, 175, 176, 176, 177, 177,
- 178, 178, 179, 179, 180, 180, 181, 181, 148, 148,
- 182, 182, 183, 183, 183, 183, 183, 183, 183, 183,
- 183, 183, 183, 183, 109, 109, 184, 184, 185, 185,
- 186, 186, 108, 108, 108, 108, 108, 108, 108, 108,
- 108, 108, 108, 108, 108, 108, 108, 131, 195, 195,
- 194, 194, 142, 142, 196, 196, 197, 197, 199, 199,
- 198, 200, 203, 201, 201, 204, 202, 202, 132, 133,
- 133, 134, 134, 187, 187, 187, 187, 187, 187, 187,
- 187, 188, 188, 188, 188, 189, 189, 189, 189, 190,
- 190, 135, 136, 205, 205, 208, 208, 206, 206, 209,
- 207, 191, 192, 192, 137, 137, 137, 210, 211, 193,
- 193, 212, 141, 155, 155, 213, 213, 152, 152, 151,
- 151, 214, 112, 112, 215, 215, 110, 110, 146, 146,
- 216};
+ 108, 108, 108, 108, 108, 108, 109, 115, 115, 118,
+ 118, 118, 118, 121, 123, 119, 119, 120, 120, 120,
+ 120, 120, 120, 120, 120, 124, 125, 117, 116, 128,
+ 128, 129, 129, 130, 130, 127, 113, 113, 113, 113,
+ 132, 132, 132, 132, 132, 132, 132, 113, 140, 140,
+ 140, 140, 141, 141, 142, 142, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
+ 113, 113, 113, 113, 113, 113, 113, 145, 145, 145,
+ 145, 126, 126, 126, 126, 126, 126, 126, 146, 146,
+ 146, 146, 146, 146, 146, 146, 146, 146, 146, 146,
+ 146, 146, 146, 146, 146, 146, 131, 148, 148, 148,
+ 148, 147, 147, 152, 152, 152, 150, 150, 153, 153,
+ 153, 153, 156, 156, 156, 156, 156, 156, 156, 156,
+ 156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
+ 156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
+ 156, 156, 156, 156, 156, 157, 157, 122, 122, 122,
+ 122, 122, 160, 160, 161, 161, 161, 161, 159, 159,
+ 162, 162, 163, 163, 164, 164, 164, 165, 165, 165,
+ 165, 165, 165, 165, 165, 165, 165, 166, 166, 166,
+ 166, 167, 167, 167, 168, 168, 168, 168, 169, 169,
+ 169, 169, 169, 169, 169, 170, 170, 170, 170, 170,
+ 170, 171, 171, 171, 171, 171, 172, 172, 172, 172,
+ 172, 173, 173, 174, 174, 175, 175, 176, 176, 177,
+ 177, 178, 178, 179, 179, 180, 180, 181, 181, 182,
+ 182, 183, 183, 184, 184, 151, 151, 185, 185, 186,
+ 186, 186, 186, 186, 186, 186, 186, 186, 186, 186,
+ 186, 111, 111, 187, 187, 188, 188, 189, 189, 110,
+ 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
+ 110, 110, 110, 110, 133, 198, 198, 197, 197, 144,
+ 144, 199, 199, 199, 200, 200, 202, 202, 201, 203,
+ 206, 204, 204, 207, 205, 205, 134, 135, 135, 136,
+ 136, 190, 190, 190, 190, 190, 190, 190, 190, 191,
+ 191, 191, 191, 192, 192, 192, 192, 193, 193, 137,
+ 138, 208, 208, 211, 211, 209, 209, 212, 210, 194,
+ 195, 195, 139, 139, 139, 213, 214, 196, 196, 215,
+ 143, 158, 158, 216, 216, 155, 155, 154, 154, 217,
+ 114, 114, 218, 218, 112, 112, 149, 149, 219
+};
const short QQmlJSGrammar::rhs [] = {
- 2, 2, 2, 2, 2, 2, 2, 1, 1, 1,
- 1, 2, 2, 1, 1, 2, 2, 2, 2, 3,
- 3, 5, 5, 4, 4, 2, 2, 0, 1, 1,
- 2, 1, 3, 2, 3, 2, 1, 5, 4, 4,
- 1, 1, 1, 1, 1, 1, 1, 3, 1, 1,
- 1, 3, 0, 1, 2, 4, 6, 6, 3, 3,
- 7, 7, 4, 4, 5, 5, 8, 8, 5, 6,
- 6, 10, 6, 7, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 2, 3, 3, 4, 5, 3, 4,
- 3, 1, 1, 2, 3, 4, 1, 2, 3, 7,
- 8, 1, 3, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 4, 3, 5, 1, 2, 4, 4, 4,
- 3, 0, 1, 1, 3, 1, 1, 1, 2, 2,
- 1, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 1, 3, 3, 3, 1, 3, 3, 1, 3, 3,
- 3, 1, 3, 3, 3, 3, 3, 3, 1, 3,
- 3, 3, 3, 3, 1, 3, 3, 3, 3, 1,
- 3, 3, 3, 3, 1, 3, 1, 3, 1, 3,
- 1, 3, 1, 3, 1, 3, 1, 3, 1, 3,
- 1, 3, 1, 3, 1, 5, 1, 5, 1, 3,
- 1, 3, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 3, 0, 1, 1, 3,
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 3, 1, 2,
- 0, 1, 3, 3, 1, 1, 1, 3, 1, 3,
- 2, 2, 2, 0, 1, 2, 0, 1, 1, 2,
- 2, 7, 5, 7, 7, 7, 5, 9, 10, 7,
- 8, 2, 2, 3, 3, 2, 2, 3, 3, 3,
- 3, 5, 5, 3, 5, 1, 2, 0, 1, 4,
- 3, 3, 3, 3, 3, 3, 4, 5, 2, 2,
- 2, 1, 8, 8, 7, 1, 3, 0, 1, 0,
- 1, 1, 1, 1, 1, 2, 1, 1, 0, 1,
- 2};
+ 2, 2, 2, 2, 2, 2, 2, 1, 1, 1,
+ 1, 2, 2, 1, 1, 2, 2, 2, 2, 3,
+ 3, 5, 5, 4, 4, 2, 2, 0, 1, 1,
+ 2, 1, 3, 2, 3, 2, 1, 5, 4, 4,
+ 1, 1, 1, 1, 1, 1, 1, 3, 1, 1,
+ 1, 3, 0, 1, 2, 4, 6, 6, 3, 3,
+ 7, 7, 4, 4, 5, 5, 8, 8, 5, 6,
+ 6, 10, 6, 7, 1, 1, 5, 1, 3, 3,
+ 5, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 3, 4, 5, 3, 4, 3, 1, 1, 2, 3,
+ 4, 1, 2, 3, 7, 8, 1, 3, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 4,
+ 3, 5, 1, 2, 4, 4, 4, 3, 0, 1,
+ 1, 3, 1, 1, 1, 2, 2, 1, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 1, 3, 3,
+ 3, 1, 3, 3, 1, 3, 3, 3, 1, 3,
+ 3, 3, 3, 3, 3, 1, 3, 3, 3, 3,
+ 3, 1, 3, 3, 3, 3, 1, 3, 3, 3,
+ 3, 1, 3, 1, 3, 1, 3, 1, 3, 1,
+ 3, 1, 3, 1, 3, 1, 3, 1, 3, 1,
+ 3, 1, 5, 1, 5, 1, 3, 1, 3, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 3, 0, 1, 1, 3, 0, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 3, 1, 2, 0, 1, 3,
+ 3, 1, 1, 1, 1, 3, 1, 3, 2, 2,
+ 2, 0, 1, 2, 0, 1, 1, 2, 2, 7,
+ 5, 7, 7, 7, 5, 9, 10, 7, 8, 2,
+ 2, 3, 3, 2, 2, 3, 3, 3, 3, 5,
+ 5, 3, 5, 1, 2, 0, 1, 4, 3, 3,
+ 3, 3, 3, 3, 4, 5, 2, 2, 2, 1,
+ 8, 8, 7, 1, 3, 0, 1, 0, 1, 1,
+ 1, 1, 1, 2, 1, 1, 0, 1, 2
+};
const short QQmlJSGrammar::action_default [] = {
- 0, 0, 28, 0, 0, 0, 28, 0, 188, 255,
- 219, 227, 223, 167, 239, 215, 3, 152, 85, 168,
- 231, 235, 156, 185, 166, 171, 151, 205, 192, 0,
- 92, 93, 88, 0, 82, 77, 359, 0, 0, 0,
- 0, 90, 0, 0, 86, 89, 81, 0, 0, 78,
- 80, 83, 79, 91, 84, 0, 87, 0, 0, 181,
- 0, 0, 168, 187, 170, 169, 0, 0, 0, 183,
- 184, 182, 186, 0, 216, 0, 0, 0, 0, 206,
- 0, 0, 0, 0, 0, 0, 196, 0, 0, 0,
- 190, 191, 189, 194, 198, 197, 195, 193, 208, 207,
- 209, 0, 224, 0, 220, 0, 0, 162, 149, 161,
- 150, 118, 119, 120, 145, 121, 146, 122, 123, 124,
- 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
- 147, 135, 136, 137, 138, 139, 140, 141, 142, 143,
- 144, 148, 0, 0, 160, 256, 163, 0, 164, 0,
- 165, 159, 0, 252, 245, 243, 250, 251, 249, 248,
- 254, 247, 246, 244, 253, 240, 0, 228, 0, 0,
- 232, 0, 0, 236, 0, 0, 162, 154, 0, 153,
- 0, 158, 172, 0, 348, 348, 349, 0, 346, 0,
- 347, 0, 350, 263, 270, 269, 277, 265, 0, 266,
- 0, 351, 0, 358, 267, 268, 85, 273, 271, 355,
- 352, 357, 274, 0, 285, 0, 0, 0, 0, 342,
- 0, 359, 257, 299, 0, 0, 0, 286, 0, 0,
- 275, 276, 0, 264, 272, 300, 301, 0, 348, 0,
- 0, 350, 0, 343, 344, 0, 332, 356, 0, 316,
- 317, 318, 319, 0, 312, 313, 314, 315, 340, 341,
- 0, 0, 0, 0, 0, 304, 305, 306, 261, 259,
- 221, 229, 225, 241, 217, 262, 0, 168, 233, 237,
- 210, 199, 0, 0, 218, 0, 0, 0, 0, 211,
- 0, 0, 0, 0, 0, 203, 201, 204, 202, 200,
- 213, 212, 214, 0, 226, 0, 222, 0, 260, 168,
- 0, 242, 257, 258, 0, 257, 0, 0, 308, 0,
- 0, 0, 310, 0, 230, 0, 0, 234, 0, 0,
- 238, 297, 0, 289, 298, 292, 0, 296, 0, 257,
- 290, 0, 257, 0, 0, 309, 0, 0, 0, 311,
- 0, 0, 0, 303, 0, 302, 85, 112, 360, 0,
- 0, 117, 279, 282, 0, 118, 285, 121, 146, 123,
- 124, 88, 128, 129, 82, 130, 133, 86, 89, 257,
- 83, 91, 136, 84, 138, 87, 140, 141, 286, 143,
- 144, 148, 0, 114, 113, 116, 100, 115, 99, 0,
- 109, 280, 278, 0, 0, 0, 350, 0, 110, 156,
- 157, 162, 0, 155, 0, 320, 321, 0, 348, 0,
- 0, 350, 0, 111, 0, 0, 0, 323, 328, 326,
- 329, 0, 0, 327, 328, 0, 324, 0, 325, 281,
- 331, 0, 281, 330, 0, 333, 334, 0, 281, 335,
- 336, 0, 0, 337, 0, 0, 0, 338, 339, 174,
- 173, 0, 0, 0, 307, 0, 0, 0, 322, 294,
- 287, 0, 295, 291, 0, 293, 283, 0, 284, 288,
- 0, 0, 350, 0, 345, 103, 0, 0, 107, 94,
- 0, 96, 105, 0, 97, 106, 108, 98, 104, 95,
- 0, 101, 178, 176, 180, 177, 175, 179, 353, 6,
- 354, 4, 2, 75, 102, 0, 0, 78, 80, 79,
- 37, 5, 0, 76, 0, 51, 50, 49, 0, 0,
- 51, 0, 0, 0, 52, 0, 67, 68, 0, 65,
- 0, 66, 41, 42, 43, 44, 46, 47, 71, 45,
- 0, 51, 0, 0, 0, 0, 0, 61, 0, 62,
- 0, 0, 32, 0, 0, 72, 33, 0, 36, 34,
- 30, 0, 35, 31, 0, 63, 0, 64, 156, 0,
- 69, 73, 0, 0, 0, 0, 156, 281, 0, 70,
- 85, 118, 285, 121, 146, 123, 124, 88, 128, 129,
- 130, 133, 86, 89, 257, 91, 136, 84, 138, 87,
- 140, 141, 286, 143, 144, 148, 74, 0, 59, 53,
- 60, 54, 0, 0, 0, 0, 56, 0, 57, 58,
- 55, 0, 0, 0, 0, 48, 0, 38, 39, 0,
- 40, 8, 0, 0, 9, 0, 11, 0, 10, 0,
- 1, 27, 15, 14, 26, 13, 12, 29, 7, 0,
- 18, 0, 19, 0, 24, 25, 0, 20, 21, 0,
- 22, 23, 16, 17, 361};
+ 0, 0, 28, 0, 0, 0, 28, 0, 195, 262,
+ 226, 234, 230, 174, 246, 222, 3, 159, 90, 175,
+ 238, 242, 163, 192, 173, 178, 158, 212, 199, 0,
+ 97, 98, 93, 0, 87, 82, 367, 0, 0, 0,
+ 0, 95, 0, 0, 91, 94, 86, 0, 0, 83,
+ 85, 88, 84, 96, 89, 0, 92, 0, 0, 188,
+ 0, 0, 175, 194, 177, 176, 0, 0, 0, 190,
+ 191, 189, 193, 0, 223, 0, 0, 0, 0, 213,
+ 0, 0, 0, 0, 0, 0, 203, 0, 0, 0,
+ 197, 198, 196, 201, 205, 204, 202, 200, 215, 214,
+ 216, 0, 231, 0, 227, 0, 0, 169, 156, 168,
+ 157, 123, 124, 125, 151, 126, 153, 127, 128, 129,
+ 130, 131, 132, 133, 134, 135, 136, 137, 138, 152,
+ 139, 140, 154, 141, 142, 143, 144, 145, 146, 147,
+ 148, 149, 150, 155, 0, 0, 167, 263, 170, 0,
+ 171, 0, 172, 166, 0, 259, 252, 250, 257, 258,
+ 256, 255, 261, 254, 253, 251, 260, 247, 0, 235,
+ 0, 0, 239, 0, 0, 243, 0, 0, 169, 161,
+ 0, 160, 0, 165, 179, 0, 356, 356, 357, 0,
+ 354, 0, 355, 0, 358, 270, 277, 276, 284, 272,
+ 0, 273, 0, 359, 0, 366, 274, 275, 90, 280,
+ 278, 363, 360, 365, 281, 0, 293, 0, 0, 0,
+ 0, 350, 0, 367, 292, 264, 307, 0, 0, 0,
+ 294, 0, 0, 282, 283, 0, 271, 279, 308, 309,
+ 0, 356, 0, 0, 358, 0, 351, 352, 0, 340,
+ 364, 0, 324, 325, 326, 327, 0, 320, 321, 322,
+ 323, 348, 349, 0, 0, 0, 0, 0, 312, 313,
+ 314, 268, 266, 228, 236, 232, 248, 224, 269, 0,
+ 175, 240, 244, 217, 206, 0, 0, 225, 0, 0,
+ 0, 0, 218, 0, 0, 0, 0, 0, 210, 208,
+ 211, 209, 207, 220, 219, 221, 0, 233, 0, 229,
+ 0, 267, 175, 0, 249, 264, 265, 0, 264, 0,
+ 0, 316, 0, 0, 0, 318, 0, 237, 0, 0,
+ 241, 0, 0, 245, 305, 0, 297, 306, 300, 0,
+ 304, 0, 264, 298, 0, 264, 0, 0, 317, 0,
+ 0, 0, 319, 0, 0, 0, 311, 0, 310, 90,
+ 117, 368, 0, 0, 122, 286, 289, 0, 123, 293,
+ 126, 153, 128, 129, 93, 134, 135, 87, 136, 292,
+ 139, 91, 94, 264, 88, 96, 142, 89, 144, 92,
+ 146, 147, 294, 149, 150, 155, 0, 119, 118, 121,
+ 105, 120, 104, 0, 114, 287, 285, 0, 0, 0,
+ 358, 0, 115, 163, 164, 169, 0, 162, 0, 328,
+ 329, 0, 356, 0, 0, 358, 0, 116, 0, 0,
+ 0, 331, 336, 334, 337, 0, 0, 335, 336, 0,
+ 332, 0, 333, 288, 339, 0, 288, 338, 0, 341,
+ 342, 0, 288, 343, 344, 0, 0, 345, 0, 0,
+ 0, 346, 347, 181, 180, 0, 0, 0, 315, 0,
+ 0, 0, 330, 302, 295, 0, 303, 299, 0, 301,
+ 290, 0, 291, 296, 0, 0, 358, 0, 353, 108,
+ 0, 0, 112, 99, 0, 101, 110, 0, 102, 111,
+ 113, 103, 109, 100, 0, 106, 185, 183, 187, 184,
+ 182, 186, 361, 6, 362, 4, 2, 75, 107, 0,
+ 0, 0, 83, 85, 84, 37, 5, 0, 76, 0,
+ 51, 50, 49, 0, 0, 51, 0, 0, 0, 52,
+ 0, 67, 68, 0, 65, 0, 66, 41, 42, 43,
+ 44, 46, 47, 71, 45, 0, 0, 0, 78, 0,
+ 77, 80, 0, 81, 0, 79, 0, 51, 0, 0,
+ 0, 0, 0, 61, 0, 62, 0, 0, 32, 0,
+ 0, 72, 33, 0, 36, 34, 30, 0, 35, 31,
+ 0, 63, 0, 64, 163, 0, 69, 73, 0, 0,
+ 0, 0, 163, 288, 0, 70, 90, 123, 293, 126,
+ 153, 128, 129, 93, 134, 135, 136, 292, 139, 91,
+ 94, 264, 96, 142, 89, 144, 92, 146, 147, 294,
+ 149, 150, 155, 74, 0, 59, 53, 60, 54, 0,
+ 0, 0, 0, 56, 0, 57, 58, 55, 0, 0,
+ 0, 0, 48, 0, 38, 39, 0, 40, 8, 0,
+ 0, 9, 0, 11, 0, 10, 0, 1, 27, 15,
+ 14, 26, 13, 12, 29, 7, 0, 18, 0, 19,
+ 0, 24, 25, 0, 20, 21, 0, 22, 23, 16,
+ 17, 369
+};
const short QQmlJSGrammar::goto_default [] = {
- 7, 650, 211, 198, 209, 521, 509, 645, 658, 508,
- 644, 648, 646, 654, 22, 651, 649, 647, 18, 520,
- 571, 561, 568, 563, 548, 193, 197, 199, 204, 234,
- 212, 231, 552, 622, 621, 203, 233, 26, 487, 486,
- 359, 358, 9, 357, 360, 202, 480, 361, 109, 17,
- 147, 24, 13, 146, 19, 25, 59, 23, 8, 28,
- 27, 280, 15, 274, 10, 270, 12, 272, 11, 271,
- 20, 278, 21, 279, 14, 273, 269, 310, 414, 275,
- 276, 205, 195, 194, 208, 207, 230, 196, 364, 363,
- 232, 471, 470, 332, 333, 473, 335, 472, 334, 427,
- 431, 434, 430, 429, 449, 450, 200, 186, 201, 210,
- 0};
+ 7, 667, 213, 200, 211, 526, 513, 662, 675, 512,
+ 661, 665, 663, 671, 22, 668, 666, 664, 18, 525,
+ 587, 577, 584, 579, 553, 195, 199, 201, 206, 237,
+ 214, 234, 568, 639, 638, 205, 236, 557, 26, 491,
+ 490, 362, 361, 9, 360, 363, 204, 484, 364, 109,
+ 17, 149, 24, 13, 148, 19, 25, 59, 23, 8,
+ 28, 27, 283, 15, 277, 10, 273, 12, 275, 11,
+ 274, 20, 281, 21, 282, 14, 276, 272, 313, 418,
+ 278, 279, 207, 197, 196, 210, 209, 233, 198, 367,
+ 366, 235, 475, 474, 335, 336, 477, 338, 476, 337,
+ 431, 435, 438, 434, 433, 453, 454, 202, 188, 203,
+ 212, 0
+};
const short QQmlJSGrammar::action_index [] = {
- 246, 1285, 2768, 2768, 2666, 998, 98, 198, 86, -106,
- 26, -15, -39, 234, -106, 314, 54, -106, -106, 714,
- 89, 151, 212, 219, -106, -106, -106, 412, 279, 1285,
- -106, -106, -106, 525, -106, -106, 2360, 1675, 1285, 1285,
- 1285, -106, 902, 1285, -106, -106, -106, 1285, 1285, -106,
- -106, -106, -106, -106, -106, 1285, -106, 1285, 1285, -106,
- 1285, 1285, 103, 197, -106, -106, 1285, 1285, 1285, -106,
- -106, -106, 214, 1285, 297, 1285, 1285, 1285, 1285, 392,
- 1285, 1285, 1285, 1285, 1285, 1285, 213, 1285, 1285, 1285,
- 96, 100, 101, 279, 279, 195, 190, 181, 402, 372,
- 382, 1285, -10, 1285, 106, 2258, 1285, 1285, -106, -106,
- -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
- -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
- -106, -106, -106, -106, -106, -106, -106, -106, -106, -106,
- -106, -106, 136, 1285, -106, -106, 65, 29, -106, 1285,
- -106, -106, 1285, -106, -106, -106, -106, -106, -106, -106,
- -106, -106, -106, -106, -106, -106, 1285, -46, 1285, 1285,
- 30, 27, 1285, -106, 2258, 1285, 1285, -106, 130, -106,
- -31, -106, -106, -16, 520, 520, 71, 21, -106, 421,
- -106, 38, 2768, -106, -106, -106, -106, -106, 237, -106,
- 520, -106, -52, -106, -106, -106, 23, -106, -106, -106,
- 2768, -106, -106, 596, -106, 588, 141, 2666, 2, 1,
- -1, 2972, 1285, -106, 13, 1285, 28, -106, -28, -30,
- -106, -106, 435, -106, -106, -106, -106, 60, 520, 52,
- 67, 2768, 64, -106, -106, 2666, -106, -106, 126, -106,
- -106, -106, -106, 73, -106, -106, -106, -106, -106, -106,
- -18, 34, 1285, 156, 168, -106, -106, -106, 1479, -106,
- 79, 40, 48, -106, 312, 75, 42, 672, 80, 143,
- 331, 279, 442, 1285, 316, 1285, 1285, 1285, 1285, 341,
- 1285, 1285, 1285, 1285, 1285, 279, 360, 360, 196, 225,
- 443, 357, 351, 1285, -4, 1285, 63, 1285, -106, 714,
- 1285, -106, 1285, 102, 68, 1285, 62, 2666, -106, 1285,
- 147, 2666, -106, 1285, 56, 1285, 1285, 91, 87, 1285,
- -106, 81, 149, 74, -106, -106, 1285, -106, 439, 1285,
- -106, -44, 1285, -42, 2666, -106, 1285, 153, 2666, -106,
- 1285, 154, 2666, 10, 2666, -106, 0, -106, 15, -54,
- 92, -106, -106, 2666, -50, 539, -7, 536, 121, 1285,
- 2666, 5, -8, 445, 2462, 24, 902, 51, 50, 1384,
- 2462, 47, 20, 46, 1285, 44, 19, 1285, 41, 1285,
- 3, -5, 2564, -106, -106, -106, -106, -106, -106, 1285,
- -106, -106, -106, 6, -17, 11, 2768, -9, -106, 249,
- -106, 1285, -13, -106, 105, -106, -106, -12, 520, -41,
- -20, 2768, -45, -106, 1285, 115, 12, -106, 36, -106,
- 31, 122, 1285, -106, 58, 4, -106, -51, -106, 2666,
- -106, 146, 2666, -106, 235, -106, -106, 140, 2666, 93,
- -106, 84, 76, -106, 520, 17, 33, -106, -106, -106,
- -106, 1285, 134, 2666, -106, 1285, 125, 2666, -106, 55,
- -106, 163, -106, -106, 1285, -106, -106, 520, -106, -106,
- 7, 45, 2768, 32, -106, -106, 120, 1773, -106, -106,
- 1577, -106, -106, 1871, -106, -106, -106, -106, -106, -106,
- 113, -106, -106, -106, -106, -106, -106, -106, -106, -106,
- 2768, -106, -106, -106, 109, 35, 808, 206, 49, 61,
- -106, -106, 229, -106, 203, 37, -106, -106, 611, 183,
- -106, 124, 39, 389, -106, 97, -106, -106, 252, -106,
- 2061, -106, -106, -106, -106, -106, -106, -106, -106, -106,
- 269, -23, 611, 243, 180, 424, 232, -106, 16, -106,
- 808, 162, -106, 22, 808, -106, -106, 1190, -106, -106,
- -106, 1094, -106, -106, 248, -106, 2061, -106, 305, -24,
- -106, -106, 215, 457, 18, 2156, 292, 2870, -11, -106,
- 14, 599, 9, 528, 119, 1285, 2666, 8, 70, 514,
- 72, 902, 95, 90, 1384, 85, 59, 77, 1285, 110,
- 83, 1285, 104, 1285, 82, 78, -106, 205, -106, 236,
- -106, 57, 25, 611, 167, 517, -106, 107, -106, -106,
- -106, 1966, 808, 1675, 43, -106, 155, -106, -106, 53,
- -106, -106, 808, 808, 108, 808, -106, 289, -106, 117,
- -106, -106, 150, 157, -106, -106, -106, -106, -106, 364,
- -106, 226, -106, 69, -106, -106, 432, -106, -106, 88,
- -106, -106, -106, -106, -106,
+ 350, 1528, 3041, 3041, 2937, 1235, 115, 105, 239, -108,
+ 102, 93, 95, 205, -108, 422, 110, -108, -108, 727,
+ 92, 118, 265, 256, -108, -108, -108, 507, 247, 1528,
+ -108, -108, -108, 665, -108, -108, 2729, 1826, 1528, 1528,
+ 1528, -108, 1041, 1528, -108, -108, -108, 1528, 1528, -108,
+ -108, -108, -108, -108, -108, 1528, -108, 1528, 1528, -108,
+ 1528, 1528, 174, 221, -108, -108, 1528, 1528, 1528, -108,
+ -108, -108, 177, 1528, 422, 1528, 1528, 1528, 1528, 411,
+ 1528, 1528, 1528, 1528, 1528, 1528, 211, 1528, 1528, 1528,
+ 142, 148, 154, 217, 223, 226, 227, 231, 507, 385,
+ 395, 1528, 57, 1528, 83, 2521, 1528, 1528, -108, -108,
+ -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
+ -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
+ -108, -108, -108, -108, -108, -108, -108, -108, -108, -108,
+ -108, -108, -108, -108, 179, 1528, -108, -108, 77, 36,
+ -108, 1528, -108, -108, 1528, -108, -108, -108, -108, -108,
+ -108, -108, -108, -108, -108, -108, -108, -108, 1528, 56,
+ 1528, 1528, 80, 74, 1528, -108, 2521, 1528, 1528, -108,
+ 125, -108, 55, -108, -108, 53, 410, 418, 72, 52,
+ -108, 392, -108, 46, 3041, -108, -108, -108, -108, -108,
+ 273, -108, 396, -108, 44, -108, -108, -108, 76, -108,
+ -108, -108, 3041, -108, -108, 744, -108, 589, 98, 2937,
+ 91, 90, 88, 3249, -108, 1528, -108, 86, 1528, 81,
+ -108, 75, 73, -108, -108, 586, -108, -108, -108, -108,
+ 71, 491, 69, 65, 3041, 64, -108, -108, 2937, -108,
+ -108, 139, -108, -108, -108, -108, 134, -108, -108, -108,
+ -108, -108, -108, 63, 66, 1528, 147, 264, -108, -108,
+ -108, 1726, -108, 87, 68, 70, -108, 334, 82, 78,
+ 796, 89, 121, 349, 318, 469, 1528, 330, 1528, 1528,
+ 1528, 1528, 359, 1528, 1528, 1528, 1528, 1528, 284, 289,
+ 303, 306, 313, 365, 369, 375, 1528, 58, 1528, 85,
+ 1528, -108, 849, 1528, -108, 1528, 79, 59, 1528, 61,
+ 2937, -108, 1528, 146, 2937, -108, 1528, 62, 1528, 1528,
+ 106, 99, 1528, -108, 96, 176, 171, -108, -108, 1528,
+ -108, 407, 1528, -108, 97, 1528, -52, 2937, -108, 1528,
+ 120, 2937, -108, 1528, 123, 2937, 101, 2937, -108, 116,
+ -108, 84, 45, 0, -108, -108, 2937, -39, 641, -3,
+ 652, 156, 1528, 2937, -7, -11, 567, 2625, -21, 5,
+ 945, 2, 94, 1629, 2625, -1, -26, 6, 1528, 10,
+ -15, 1528, 14, 1528, -25, -12, 2833, -108, -108, -108,
+ -108, -108, -108, 1528, -108, -108, -108, -14, -58, -13,
+ 3041, -36, -108, 287, -108, 1528, -46, -108, 153, -108,
+ -108, -31, 586, -57, -32, 3041, 11, -108, 1528, 168,
+ 29, -108, 47, -108, 48, 169, 1528, -108, 49, 50,
+ -108, 9, -108, 2937, -108, 136, 2937, -108, 275, -108,
+ -108, 126, 2937, 35, -108, 33, 37, -108, 466, -4,
+ 38, -108, -108, -108, -108, 1528, 130, 2937, -108, 1528,
+ 117, 2937, -108, 34, -108, 296, -108, -108, 1528, -108,
+ -108, 404, -108, -108, 12, 40, 3041, 13, -108, -108,
+ 155, 1926, -108, -108, 2026, -108, -108, 2126, -108, -108,
+ -108, -108, -108, -108, 144, -108, -108, -108, -108, -108,
+ -108, -108, -108, -108, 3041, -108, -108, -108, 132, -27,
+ 15, 1137, 218, -23, 17, -108, -108, 196, -108, 242,
+ 8, -108, -108, 579, 237, -108, 127, 18, 415, -108,
+ 103, -108, -108, 236, -108, 2223, -108, -108, -108, -108,
+ -108, -108, -108, -108, -108, 27, 21, 137, 31, 20,
+ -108, 23, -5, -108, -9, -108, 332, -10, 571, 201,
+ 195, 586, 225, -108, 7, -108, 1137, 165, -108, 4,
+ 1137, -108, -108, 1333, -108, -108, -108, 1431, -108, -108,
+ 184, -108, 2223, -108, 331, 3, -108, -108, 202, 531,
+ 26, 2417, 327, 3145, 1, -108, 25, 629, 24, 649,
+ 124, 1528, 2937, 22, -6, 514, -8, 19, 1041, 16,
+ 94, 1629, 28, 42, 67, 1528, 60, 43, 1528, 54,
+ 1528, 41, 39, -108, 234, -108, 228, -108, 51, -2,
+ 564, 233, 575, -108, 100, -108, -108, -108, 2320, 1137,
+ 1826, 32, -108, 122, -108, -108, 30, -108, -108, 1137,
+ 1137, 104, 903, -108, 308, -108, 108, -108, -108, 133,
+ 119, -108, -108, -108, -108, -108, 451, -108, 164, -108,
+ 161, -108, -108, 458, -108, -108, 151, -108, -108, -108,
+ -108, -108,
- -111, 8, 65, 83, 84, 317, 1, -111, -111, -111,
- -111, -111, -111, -111, -111, -111, -111, -111, -111, -77,
- -111, -111, -111, -111, -111, -111, -111, -111, -111, 96,
- -111, -111, -111, 2, -111, -111, -5, -28, 12, 106,
- 95, -111, 61, 55, -111, -111, -111, 63, 70, -111,
- -111, -111, -111, -111, -111, 54, -111, 172, 177, -111,
- 180, 191, -111, -111, -111, -111, 197, 202, 203, -111,
- -111, -111, -111, 210, -111, 209, 195, 109, 116, -111,
- 146, 125, 126, 127, 135, 138, -111, 141, 144, 110,
- -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
- -111, 150, -111, 155, -111, 192, 4, -33, -111, -111,
- -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
- -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
- -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
- -111, -111, -111, -9, -111, -111, -111, -111, -111, 7,
- -111, -111, 40, -111, -111, -111, -111, -111, -111, -111,
- -111, -111, -111, -111, -111, -111, 99, -111, 52, 31,
- -111, -111, 30, -111, 253, 44, 87, -111, -111, -111,
- -111, -111, -111, -111, 45, 86, -111, -111, -111, 41,
- -111, -111, 5, -111, -111, -111, -111, -111, -111, -111,
- 50, -111, -111, -111, -111, -111, -111, -111, -111, -111,
- 154, -111, -111, 26, -111, 49, -111, 330, -111, 28,
- -111, 248, 27, -111, -111, 124, 51, -111, -111, -111,
- -111, -111, 46, -111, -111, -111, -111, -111, 196, -111,
- -111, 185, -111, -111, -111, 194, -111, -111, -111, -111,
- -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
- -111, -111, 15, -111, -111, -111, -111, -111, 74, -111,
- -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
- -111, -111, -16, 230, -111, 233, 269, 251, 265, -111,
- 80, 81, 82, 88, 89, -111, -111, -111, -111, -111,
- -111, -111, -111, 216, -111, 255, -111, 259, -111, -111,
- 223, -111, 68, -111, -111, 217, -111, 236, -111, 24,
- -111, 244, -111, 227, -111, 226, 257, -111, -111, 263,
- -111, -111, -111, -111, -111, -111, 249, -111, 113, 163,
- -111, -111, 212, -111, 173, -111, 48, -111, 211, -111,
- 53, -111, 206, -111, 204, -111, -111, -111, -111, -111,
- -111, -111, -111, 199, -111, 23, -111, 25, -111, 134,
- 175, -111, -111, 37, 200, -111, 222, -111, -111, 57,
- 56, -111, -111, -111, 124, -111, 32, 43, -111, 105,
- -111, -111, 139, -111, -111, -111, -111, -111, -111, 38,
- -111, -111, -111, -111, -111, -111, 75, -111, -111, -111,
- -111, 71, -111, -111, -111, -111, -111, -111, 72, -111,
- -111, 85, -111, -111, 59, -111, -111, -111, -111, -111,
- -37, -111, 62, -111, -58, -111, -111, -111, -111, 286,
- -111, -111, 250, -111, -111, -111, -111, -111, 153, -57,
- -111, -111, 33, -111, 34, -111, 36, -111, -111, -111,
- -111, 47, -111, 77, -111, 29, -111, 67, -111, -111,
- -111, -111, -111, -111, 42, -111, -111, 214, -111, -111,
- -111, -111, 229, -111, -111, -111, -111, 35, -111, -111,
- 145, -111, -111, 3, -111, -111, -111, -111, -111, -111,
- -111, -111, -111, -111, -111, -111, -111, -111, -111, -111,
- 207, -111, -111, -111, -111, -111, 39, -111, -111, -111,
- -111, -111, -111, -111, -24, -111, -111, -111, -12, -27,
- -111, -111, -111, -14, -111, -111, -111, -111, -111, -111,
- 333, -111, -111, -111, -111, -111, -111, -111, -111, -111,
- -111, -111, 6, 22, -111, 20, -111, -111, -111, -111,
- 159, -111, -111, -111, 246, -111, -111, 332, -111, -111,
- -111, 436, -111, -111, -111, -111, 388, -111, -111, 18,
- -111, -111, -6, 19, -111, 352, -111, 225, 14, -111,
- -111, 13, -111, 11, -111, 167, 136, -111, -111, 10,
- -111, 64, -111, -111, 9, -111, -111, -111, 124, -111,
- 0, 69, -111, 60, -111, -111, -111, -111, -111, -10,
- -111, -111, -111, -1, -11, -2, -111, -111, -111, -111,
- -111, 370, 142, 315, -3, -111, -111, -111, -111, 17,
- -111, -111, -13, 21, 133, 221, -111, -111, -111, -111,
- -111, -111, -111, -111, -111, -111, -111, -111, -111, 16,
- -111, -111, -111, -111, -111, -111, -15, -111, -111, -111,
- -111, -111, -111, -111, -111};
+ -112, 18, 86, 97, 69, 316, 7, -112, -112, -112,
+ -112, -112, -112, -112, -112, -112, -112, -112, -112, -64,
+ -112, -112, -112, -112, -112, -112, -112, -112, -112, 66,
+ -112, -112, -112, -17, -112, -112, -10, -36, 3, 90,
+ 95, -112, 149, 74, -112, -112, -112, 67, 13, -112,
+ -112, -112, -112, -112, -112, 178, -112, 181, 185, -112,
+ 189, 190, -112, -112, -112, -112, 198, 208, 212, -112,
+ -112, -112, -112, 209, -112, 201, 164, 111, 113, -112,
+ 116, 130, 131, 132, 134, 142, -112, 118, 124, 144,
+ -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
+ -112, 154, -112, 155, -112, 268, 28, -8, -112, -112,
+ -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
+ -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
+ -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
+ -112, -112, -112, -112, -112, 42, -112, -112, -112, -112,
+ -112, 47, -112, -112, 50, -112, -112, -112, -112, -112,
+ -112, -112, -112, -112, -112, -112, -112, -112, 159, -112,
+ 158, 56, -112, -112, 57, -112, 362, 60, 157, -112,
+ -112, -112, -112, -112, -112, -112, 20, 151, -112, -112,
+ -112, 25, -112, -112, 30, -112, -112, -112, -112, -112,
+ -112, -112, 31, -112, -112, -112, -112, -112, -112, -112,
+ -112, -112, 233, -112, -112, 34, -112, 35, -112, 225,
+ -112, 36, -112, 216, -112, 55, -112, -112, 53, 39,
+ -112, -112, -112, -112, -112, 19, -112, -112, -112, -112,
+ -112, 94, -112, -112, 92, -112, -112, -112, 117, -112,
+ -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
+ -112, -112, -112, -112, -112, 33, -112, -112, -112, -112,
+ -112, 88, -112, -112, -112, -112, -112, -112, -112, -112,
+ -112, -112, -112, -112, -112, 51, 220, -112, 227, 235,
+ 236, 244, -112, 21, 17, 102, 91, 89, -112, -112,
+ -112, -112, -112, -112, -112, -112, 211, -112, 247, -112,
+ 257, -112, -112, 264, -112, 75, -112, -112, 103, -112,
+ 112, -112, 29, -112, 73, -112, 263, -112, 255, 254,
+ -112, -112, 245, -112, -112, -112, -112, -112, -112, 248,
+ -112, 65, 105, -112, -112, 99, -112, 162, -112, 37,
+ -112, 115, -112, 44, -112, 135, -112, 137, -112, -112,
+ -112, -112, -112, -112, -112, -112, 138, -112, 24, -112,
+ 26, -112, 104, 140, -112, -112, 32, 64, -112, -112,
+ 174, -112, -112, 48, 87, -112, -112, -112, 54, -112,
+ 40, 71, -112, 150, -112, -112, 197, -112, -112, -112,
+ -112, -112, -112, 12, -112, -112, -112, -112, -112, -112,
+ 206, -112, -112, -112, -112, 207, -112, -112, -112, -112,
+ -112, -112, 231, -112, -112, 239, -112, -112, 43, -112,
+ -112, -112, -112, -112, -59, -112, 38, -112, -62, -112,
+ -112, -112, -112, 258, -112, -112, 259, -112, -112, -112,
+ -112, -112, 163, -72, -112, -112, 41, -112, 62, -112,
+ 61, -112, -112, -112, -112, 59, -112, 193, -112, 58,
+ -112, 204, -112, -112, -112, -112, -112, -112, 52, -112,
+ -112, 175, -112, -112, -112, -112, 186, -112, -112, -112,
+ -112, 49, -112, -112, 173, -112, -112, 45, -112, -112,
+ -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
+ -112, -112, -112, -112, 213, -112, -112, -112, -112, -112,
+ -112, 46, -112, -112, -112, -112, -112, -112, -112, 27,
+ -112, -112, -112, -18, -9, -112, -112, -112, 15, -112,
+ -112, -112, -112, -112, -112, 331, -112, -112, -112, -112,
+ -112, -112, -112, -112, -112, -112, -112, -112, -112, -112,
+ -112, -112, -112, -112, -112, -112, -112, -112, 11, -6,
+ -112, 10, -112, -112, -112, -112, 156, -112, -112, -112,
+ 240, -112, -112, 330, -112, -112, -112, 332, -112, -112,
+ -112, -112, 376, -112, -112, 8, -112, -112, -7, 76,
+ -112, 358, -112, 228, 5, -112, -112, 6, -112, 4,
+ -112, 79, 221, -112, -112, 2, -112, -112, 174, -112,
+ -112, 16, -112, -112, -112, 14, -112, -16, 70, -112,
+ 63, -112, -112, -112, -112, -112, -30, -112, -112, -112,
+ -15, -28, -13, -112, -112, -112, -112, -112, 460, 93,
+ 307, -12, -112, -112, -112, -112, -11, -112, -112, -2,
+ -1, 85, 84, -112, -112, -112, -112, -112, -112, -112,
+ -112, -112, -112, -112, -112, -112, -3, -112, -112, -112,
+ -112, -112, -112, 0, -112, -112, -112, -112, -112, -112,
+ -112, -112
+};
const short QQmlJSGrammar::action_info [] = {
- -145, 398, 101, 244, 438, 402, 465, 245, 461, 567,
- 423, 439, -126, 421, 553, -126, -145, 342, 344, 420,
- 185, 245, 567, 392, 418, 585, 354, 73, 268, 181,
- 245, 465, 166, 101, 172, 350, 432, 184, 268, 461,
- 103, 432, 404, 405, 406, 428, 408, 413, -142, 424,
- 560, -139, 448, -137, -115, 567, 424, -116, -134, 261,
- 350, 448, 143, 432, 283, 624, 448, 481, 534, 103,
- 262, 192, 474, 149, 529, 305, 567, 456, 482, 189,
- 283, 191, 323, 307, -137, 627, 567, 484, 303, 151,
- 617, 166, -115, 323, 329, 424, 238, -116, 336, 399,
- 241, 524, -134, 312, 303, 346, 268, 73, 350, 448,
- 143, -142, 240, 452, 465, 582, 448, -139, 461, 243,
- 454, 143, 317, 143, 174, 0, 60, 305, 490, 315,
- 665, 664, 435, 143, 257, 256, 60, 61, 143, 532,
- 60, 60, 143, 175, 143, 64, 451, 61, 533, 671,
- 670, 61, 61, 442, 143, 143, 65, 338, 537, 536,
- 452, 143, 143, 564, 143, 174, 416, 415, 629, 628,
- 564, 477, 174, 501, 0, 426, 491, 436, 673, 672,
- 259, 258, 259, 258, 175, 467, 179, 252, 251, 642,
- 643, 175, 144, 325, 463, 532, 530, 326, 674, 642,
- 643, 168, 259, 258, 555, 169, 87, 321, 88, 66,
- 339, 637, 530, 348, 352, 87, 264, 88, 565, 89,
- 87, 87, 88, 88, 478, 476, 66, 174, 89, 267,
- 265, 66, 525, 89, 89, 551, 631, 0, 87, 558,
- 88, 619, 527, 143, 530, 143, 175, 0, 176, 105,
- 87, 89, 88, 526, 67, 576, 0, 266, 527, 540,
- 68, 0, 567, 89, 174, 530, 620, 618, 106, 526,
- 107, 67, 530, 0, 0, 0, 67, 68, 527, 0,
- 0, 527, 68, 175, 174, 411, 0, 668, 667, 526,
- 527, 0, 526, 559, 557, 0, 446, 445, 236, 235,
- 0, 526, 0, 175, 87, 411, 88, 174, 0, 577,
- 575, 527, 0, 541, 539, 75, 76, 89, 527, 666,
- 174, 0, 526, 632, 0, -102, 175, 0, 176, 526,
- 285, 286, 75, 76, 285, 286, 661, 0, -102, 175,
- 0, 176, 77, 78, 6, 5, 4, 1, 3, 2,
- 662, 660, 0, 0, 290, 291, 0, 287, 288, 77,
- 78, 287, 288, 292, 290, 291, 293, 0, 294, 0,
- 0, 0, 0, 292, 290, 291, 293, 0, 294, 0,
- 290, 291, 659, 292, 0, 87, 293, 88, 294, 292,
- 0, 0, 293, 35, 294, 80, 81, 0, 89, 0,
- 0, 0, 0, 82, 83, 80, 81, 84, 0, 85,
- 0, 0, 0, 82, 83, 80, 81, 84, 35, 85,
- 0, 0, 0, 82, 83, 80, 81, 84, 0, 85,
- 49, 52, 50, 82, 83, 80, 81, 84, 0, 85,
- 0, 0, 0, 82, 83, 0, 0, 84, 0, 85,
- 35, 0, 0, 35, 0, 49, 52, 50, 46, 34,
- 51, 35, 0, 0, 35, 0, 290, 291, 35, 0,
- 0, 35, 532, 0, 35, 292, 0, 0, 293, 0,
- 294, 184, 0, 46, 34, 51, 35, 49, 52, 50,
- 49, 52, 50, 0, 0, 0, 0, 0, 49, 52,
- 50, 49, 52, 50, 0, 49, 52, 50, 49, 52,
- 50, 49, 52, 50, 0, 46, 34, 51, 46, 34,
- 51, 0, 0, 49, 52, 50, 46, 34, 51, 46,
- 34, 51, 532, 46, 34, 51, 46, 34, 51, 46,
- 34, 51, 0, 35, 0, 0, 35, 0, 0, 35,
- 184, 46, 34, 51, 35, 0, 0, 35, 0, 0,
- 0, 184, 0, 0, 0, 35, 0, 0, 35, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 49, 52, 50, 49, 52, 50, 49, 52, 50, 255,
- 254, 49, 52, 50, 49, 52, 50, 255, 254, 0,
- 250, 249, 49, 52, 50, 49, 52, 50, 46, 34,
- 51, 46, 34, 51, 46, 34, 51, 35, 0, 46,
- 34, 51, 46, 34, 51, 35, 532, 0, 35, 0,
- 46, 34, 51, 46, 34, 51, 0, 0, 0, 0,
- 35, 0, 0, 0, 0, 0, 0, 0, 0, 255,
- 254, 0, 0, 0, 49, 52, 50, 250, 249, 0,
- 250, 249, 49, 52, 50, 49, 52, 50, 0, 0,
- 0, 0, 0, 0, 0, 153, 0, 49, 52, 50,
- 0, 0, 46, 34, 51, 154, 0, 0, 0, 155,
- 46, 34, 51, 46, 34, 51, 0, 0, 156, 0,
- 157, 0, 0, 319, 0, 46, 34, 51, 0, 0,
- 0, 158, 0, 159, 64, 0, 0, 153, 0, 0,
- 0, 160, 0, 0, 161, 65, 0, 154, 0, 0,
- 162, 155, 0, 0, 0, 0, 163, 0, 0, 0,
- 156, 0, 157, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 164, 158, 0, 159, 64, 0, 0, 0,
- 0, 0, 0, 160, 0, 0, 161, 65, 0, 0,
- 0, 0, 162, 0, 0, 0, 0, 0, 163, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 164, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 30, 31, 0, 0, 0, 0, 0, 0, 0, 0,
- 33, 0, 0, 0, 0, 0, 0, 35, 0, 0,
- 0, 36, 37, 0, 38, 0, 0, 0, 0, 0,
- 0, 516, 0, 0, 0, 45, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 53, 49, 52, 50, 0, 54, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 44,
- 56, 32, 0, 0, 0, 41, 0, 0, 0, 0,
- 0, 0, 46, 34, 51, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 30, 31, 0, 0, 0, 0,
- 0, 0, 0, 0, 33, 0, 0, 0, 0, 0,
- 0, 35, 0, 0, 0, 36, 37, 0, 38, 0,
- 0, 0, 0, 0, 0, 42, 0, 0, 0, 45,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 53, 49, 52,
- 50, 0, 54, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 44, 56, 32, 0, 0, 0, 41,
- 0, 0, 0, 0, 0, 0, 46, 34, 51, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 515, 0,
- 30, 31, 0, 0, 0, 0, 0, 0, 0, 0,
- 219, 0, 0, 0, 0, 0, 0, 35, 0, 0,
- 0, 36, 37, 0, 38, 0, 0, 0, 0, 0,
- 0, 516, 0, 0, 0, 45, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 53, 517, 519, 518, 0, 54, 0,
- 0, 0, 0, 227, 0, 0, 0, 0, 0, 44,
- 56, 32, 214, 0, 0, 41, 0, 0, 0, 0,
- 0, 0, 46, 34, 51, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 515, 0, 30, 31, 0, 0,
- 0, 0, 0, 0, 0, 0, 219, 0, 0, 0,
- 0, 0, 0, 35, 0, 0, 0, 36, 37, 0,
- 38, 0, 0, 0, 0, 0, 0, 516, 0, 0,
- 0, 45, 0, 0, 0, 0, 0, 0, 0, 572,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 53,
- 517, 519, 518, 0, 54, 0, 0, 0, 0, 227,
- 0, 0, 0, 0, 0, 44, 56, 32, 214, 0,
- 0, 41, 0, 0, 0, 0, 0, 0, 46, 34,
- 51, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 515, 0, 30, 31, 0, 0, 0, 0, 0, 0,
- 0, 0, 219, 0, 0, 0, 0, 0, 0, 35,
- 0, 0, 0, 36, 37, 0, 38, 0, 0, 0,
- 0, 0, 0, 516, 0, 0, 0, 45, 0, 0,
- 0, 0, 0, 0, 0, 569, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 53, 517, 519, 518, 0,
- 54, 0, 0, 0, 0, 227, 0, 0, 0, 0,
- 0, 44, 56, 32, 214, 0, 0, 41, 0, 0,
- 0, 0, 0, 0, 46, 34, 51, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 29, 30, 31, 0,
- 0, 0, 0, 0, 0, 0, 0, 33, 0, 0,
- 0, 0, 0, 0, 35, 0, 0, 0, 36, 37,
- 0, 38, 0, 0, 0, 39, 0, 40, 42, 43,
- 0, 0, 45, 0, 0, 0, 47, 0, 48, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 53, 49, 52, 50, 0, 54, 0, 55, 0, 57,
- 0, 58, 0, 0, 0, 0, 44, 56, 32, 0,
- 0, 0, 41, 0, 0, 0, 0, 0, 0, 46,
- 34, 51, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, -135, 0, 0, 0, 29, 30, 31, 0, 0,
- 0, 0, 0, 0, 0, 0, 33, 0, 0, 0,
- 0, 0, 0, 35, 0, 0, 0, 36, 37, 0,
- 38, 0, 0, 0, 39, 0, 40, 42, 43, 0,
- 0, 45, 0, 0, 0, 47, 0, 48, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 53,
- 49, 52, 50, 0, 54, 0, 55, 0, 57, 0,
- 58, 0, 0, 0, 0, 44, 56, 32, 0, 0,
- 0, 41, 0, 0, 0, 0, 0, 0, 46, 34,
- 51, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 29, 30, 31, 0, 0, 0, 0, 0, 0, 0,
- 0, 33, 0, 0, 0, 0, 0, 0, 35, 0,
- 0, 0, 36, 37, 0, 38, 0, 0, 0, 39,
- 0, 40, 42, 43, 0, 0, 45, 0, 0, 0,
- 47, 0, 48, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 53, 49, 52, 50, 0, 54,
- 0, 55, 0, 57, 282, 58, 0, 0, 0, 0,
- 44, 56, 32, 0, 0, 0, 41, 0, 0, 0,
- 0, 0, 0, 46, 34, 51, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 488, 0, 0, 29, 30,
- 31, 0, 0, 0, 0, 0, 0, 0, 0, 33,
- 0, 0, 0, 0, 0, 0, 35, 0, 0, 0,
- 36, 37, 0, 38, 0, 0, 0, 39, 0, 40,
- 42, 43, 0, 0, 45, 0, 0, 0, 47, 0,
- 48, 0, 0, 494, 0, 0, 0, 0, 0, 0,
- 0, 0, 53, 49, 52, 50, 0, 54, 0, 55,
- 0, 57, 0, 58, 0, 0, 0, 0, 44, 56,
- 32, 0, 0, 0, 41, 0, 0, 0, 0, 0,
- 0, 46, 34, 51, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 488, 0, 0, 29, 30, 31, 0,
- 0, 0, 0, 0, 0, 0, 0, 33, 0, 0,
- 0, 0, 0, 0, 35, 0, 0, 0, 36, 37,
- 0, 38, 0, 0, 0, 39, 0, 40, 42, 43,
- 0, 0, 45, 0, 0, 0, 47, 0, 48, 0,
- 0, 489, 0, 0, 0, 0, 0, 0, 0, 0,
- 53, 49, 52, 50, 0, 54, 0, 55, 0, 57,
- 0, 58, 0, 0, 0, 0, 44, 56, 32, 0,
- 0, 0, 41, 0, 0, 0, 0, 0, 0, 46,
- 34, 51, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 496, 0, 0, 29, 30, 31, 0, 0, 0,
- 0, 0, 0, 0, 0, 33, 0, 0, 0, 0,
- 0, 0, 35, 0, 0, 0, 36, 37, 0, 38,
- 0, 0, 0, 39, 0, 40, 42, 43, 0, 0,
- 45, 0, 0, 0, 47, 0, 48, 0, 0, 499,
- 0, 0, 0, 0, 0, 0, 0, 0, 53, 49,
- 52, 50, 0, 54, 0, 55, 0, 57, 0, 58,
- 0, 0, 0, 0, 44, 56, 32, 0, 0, 0,
- 41, 0, 0, 0, 0, 0, 0, 46, 34, 51,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 496,
- 0, 0, 29, 30, 31, 0, 0, 0, 0, 0,
- 0, 0, 0, 33, 0, 0, 0, 0, 0, 0,
- 35, 0, 0, 0, 36, 37, 0, 38, 0, 0,
- 0, 39, 0, 40, 42, 43, 0, 0, 45, 0,
- 0, 0, 47, 0, 48, 0, 0, 497, 0, 0,
- 0, 0, 0, 0, 0, 0, 53, 49, 52, 50,
- 0, 54, 0, 55, 0, 57, 0, 58, 0, 0,
- 0, 0, 44, 56, 32, 0, 0, 0, 41, 0,
- 0, 0, 0, 0, 0, 46, 34, 51, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 29, 30, 31,
- 0, 0, 0, 0, 0, 0, 0, 0, 33, 0,
- 0, 0, 0, 0, 0, 35, 220, 0, 0, 587,
- 633, 0, 38, 0, 0, 0, 39, 0, 40, 42,
- 43, 0, 0, 45, 0, 0, 0, 47, 0, 48,
- 0, 0, 0, 0, 0, 0, 0, 223, 0, 0,
- 0, 53, 49, 52, 50, 224, 54, 0, 55, 226,
- 57, 0, 58, 0, 229, 0, 0, 44, 56, 32,
- 0, 0, 0, 41, 0, 0, 0, 0, 0, 0,
- 46, 34, 51, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 29, 30, 31, 0, 0, 0, 0, 0,
- 0, 0, 0, 33, 0, 0, 0, 0, 0, 0,
- 35, 220, 0, 0, 221, 37, 0, 38, 0, 0,
- 0, 39, 0, 40, 42, 43, 0, 0, 45, 0,
- 0, 0, 47, 0, 48, 0, 0, 0, 0, 0,
- 0, 0, 223, 0, 0, 0, 53, 49, 52, 50,
- 224, 54, 0, 55, 226, 57, 0, 58, 0, 229,
- 0, 0, 44, 56, 32, 0, 0, 0, 41, 0,
- 0, 0, 0, 0, 0, 46, 34, 51, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 29, 30, 31,
- 0, 0, 0, 0, 0, 0, 0, 0, 33, 0,
- 0, 0, 0, 0, 0, 35, 220, 0, 0, 587,
- 37, 0, 38, 0, 0, 0, 39, 0, 40, 42,
- 43, 0, 0, 45, 0, 0, 0, 47, 0, 48,
- 0, 0, 0, 0, 0, 0, 0, 223, 0, 0,
- 0, 53, 49, 52, 50, 224, 54, 0, 55, 226,
- 57, 0, 58, 0, 229, 0, 0, 44, 56, 32,
- 0, 0, 0, 41, 0, 0, 0, 0, 0, 0,
- 46, 34, 51, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 111, 112, 113, 0, 0, 115, 117, 118,
- 0, 0, 119, 0, 120, 0, 0, 0, 122, 123,
- 124, 0, 0, 0, 0, 0, 0, 35, 125, 126,
- 127, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 128, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 131, 0, 0,
- 0, 0, 0, 0, 49, 52, 50, 132, 133, 134,
- 0, 136, 137, 138, 139, 140, 141, 0, 0, 129,
- 135, 121, 114, 116, 130, 0, 0, 0, 0, 0,
- 0, 0, 46, 34, 51, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 111, 112, 113, 0, 0, 115,
- 117, 118, 0, 0, 119, 0, 120, 0, 0, 0,
- 122, 123, 124, 0, 0, 0, 0, 0, 0, 35,
- 125, 126, 127, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 128, 0, 0, 0, 395, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 131,
- 0, 0, 0, 0, 0, 397, 49, 52, 50, 132,
- 133, 134, 0, 136, 137, 138, 139, 140, 141, 0,
- 0, 129, 135, 121, 114, 116, 130, 0, 0, 0,
- 0, 0, 0, 0, 46, 374, 380, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 111, 112, 113, 0,
- 0, 115, 117, 118, 0, 0, 119, 0, 120, 0,
- 0, 0, 122, 123, 124, 0, 0, 0, 0, 0,
- 0, 35, 125, 126, 127, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 128, 0, 0, 0, 395,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 131, 0, 0, 0, 0, 0, 397, 49, 52,
- 50, 132, 133, 134, 0, 136, 137, 138, 139, 140,
- 141, 0, 0, 129, 135, 121, 114, 116, 130, 0,
- 0, 0, 0, 0, 0, 0, 46, 34, 51, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 111, 112,
- 113, 0, 0, 115, 117, 118, 0, 0, 119, 0,
- 120, 0, 0, 0, 122, 123, 124, 0, 0, 0,
- 0, 0, 0, 35, 125, 126, 127, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 128, 0, 0,
- 0, 395, 0, 0, 0, 0, 0, 0, 0, 396,
- 0, 0, 0, 131, 0, 0, 0, 0, 0, 397,
- 49, 52, 50, 132, 133, 134, 0, 136, 137, 138,
- 139, 140, 141, 0, 0, 129, 135, 121, 114, 116,
- 130, 0, 0, 0, 0, 0, 0, 0, 46, 374,
- 380, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 213, 0, 0, 0, 0, 215, 0, 29, 30, 31,
- 217, 0, 0, 0, 0, 0, 0, 218, 33, 0,
- 0, 0, 0, 0, 0, 35, 220, 0, 0, 221,
- 37, 0, 38, 0, 0, 0, 39, 0, 40, 42,
- 43, 0, 0, 45, 0, 0, 0, 47, 0, 48,
- 0, 0, 0, 0, 0, 222, 0, 223, 0, 0,
- 0, 53, 49, 52, 50, 224, 54, 225, 55, 226,
- 57, 227, 58, 228, 229, 0, 0, 44, 56, 32,
- 214, 216, 0, 41, 0, 0, 0, 0, 0, 0,
- 46, 34, 51, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 213, 0, 0, 0, 0, 215, 0, 29,
- 30, 31, 217, 0, 0, 0, 0, 0, 0, 218,
- 219, 0, 0, 0, 0, 0, 0, 35, 220, 0,
- 0, 221, 37, 0, 38, 0, 0, 0, 39, 0,
- 40, 42, 43, 0, 0, 45, 0, 0, 0, 47,
- 0, 48, 0, 0, 0, 0, 0, 222, 0, 223,
- 0, 0, 0, 53, 49, 52, 50, 224, 54, 225,
- 55, 226, 57, 227, 58, 228, 229, 0, 0, 44,
- 56, 32, 214, 216, 0, 41, 0, 0, 0, 0,
- 0, 0, 46, 34, 51, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 591, 112, 113, 0, 0, 593,
- 117, 595, 30, 31, 596, 0, 120, 0, 0, 0,
- 122, 598, 599, 0, 0, 0, 0, 0, 0, 35,
- 600, 126, 127, 221, 37, 0, 38, 0, 0, 0,
- 39, 0, 40, 601, 43, 0, 0, 603, 0, 0,
- 0, 47, 0, 48, 0, 0, 0, 0, 0, 604,
- 0, 223, 0, 0, 0, 605, 49, 52, 50, 606,
- 607, 608, 55, 610, 611, 612, 613, 614, 615, 0,
- 0, 602, 609, 597, 592, 594, 130, 41, 0, 0,
- 0, 0, 0, 0, 46, 374, 380, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 365, 112, 113, 0,
- 0, 367, 117, 369, 30, 31, 370, 0, 120, 0,
- 0, 0, 122, 372, 373, 0, 0, 0, 0, 0,
- 0, 35, 375, 126, 127, 221, 37, 0, 38, 0,
- 0, 0, 39, 0, 40, 376, 43, 0, 0, 378,
- 0, 0, 0, 47, 0, 48, 0, -281, 0, 0,
- 0, 379, 0, 223, 0, 0, 0, 381, 49, 52,
- 50, 382, 383, 384, 55, 386, 387, 388, 389, 390,
- 391, 0, 0, 377, 385, 371, 366, 368, 130, 41,
- 0, 0, 0, 0, 0, 0, 46, 374, 380, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
+ -132, 425, 409, 424, -151, 422, -120, 403, 347, -140,
+ 428, 465, -152, -143, 417, 353, 406, -145, 452, 412,
+ 410, -148, 408, -140, 469, 271, -152, 569, 353, -132,
+ 271, -151, 248, 601, 583, -120, 583, 583, 565, 529,
+ 562, 576, 563, 598, 555, 534, 634, 539, 564, 561,
+ 558, 478, 436, 436, 436, 456, 460, 443, 644, 641,
+ 556, -148, 432, 583, 442, 583, 427, -145, 488, 458,
+ 452, 452, 485, 486, -143, 469, 452, 465, 428, 194,
+ 191, 174, 168, 248, 73, 151, 286, 145, 286, 187,
+ 310, 326, 396, 0, 168, 0, 153, 0, 244, 247,
+ 402, -121, 265, 73, 101, 691, 332, 241, 326, 469,
+ 306, 465, 193, 339, 452, 183, 306, 357, 145, 246,
+ 318, 320, 428, 248, 353, 145, 186, 271, 145, 243,
+ 580, 145, 455, 145, 176, 0, 103, 308, 145, 315,
+ 264, 101, 537, 446, 145, 559, 456, 176, 176, 308,
+ 0, 538, 145, 177, 145, 145, 0, 0, 345, 262,
+ 261, 646, 645, 494, 542, 541, 177, 177, 170, 690,
+ 689, 328, 171, 580, 103, 329, 145, 471, 654, 439,
+ 351, 181, 60, 355, 341, 262, 261, 145, 60, 66,
+ 467, 592, 560, 61, 60, 260, 259, 659, 660, 61,
+ 255, 254, 349, 648, 505, 61, 324, 267, 659, 660,
+ 537, 495, 688, 687, 420, 419, 64, 262, 261, 571,
+ 105, 581, 682, 681, 440, 685, 684, 65, 430, 583,
+ 535, 535, 574, 66, 67, 146, 87, 342, 88, 106,
+ 68, 107, 87, 545, 88, 593, 591, 567, 87, 89,
+ 88, 87, 87, 88, 88, 89, 87, 535, 88, 683,
+ 0, 89, 535, 0, 89, 89, 535, 0, 66, 89,
+ 636, 530, 87, 0, 88, 0, 532, 532, 67, 60,
+ 176, 145, 0, 145, 68, 89, 575, 573, 531, 531,
+ 61, 0, 649, 532, 0, 637, 635, 546, 544, 177,
+ 0, 178, 176, 532, 481, 531, 0, 0, 532, 87,
+ 0, 88, 532, 67, 87, 531, 88, 532, 0, 68,
+ 531, 177, 89, 415, 531, 270, 268, 89, 87, 531,
+ 88, 87, 0, 88, 239, 238, 450, 449, 87, 0,
+ 88, 89, 176, 87, 89, 88, 176, 176, 288, 289,
+ 0, 89, 288, 289, 269, 678, 89, 482, 480, 0,
+ -107, 177, 0, 178, -107, 177, 177, 178, 415, 679,
+ 677, 0, 293, 294, 0, 290, 291, 0, 0, 290,
+ 291, 295, 293, 294, 296, 0, 297, 0, 293, 294,
+ 0, 295, 293, 294, 296, 0, 297, 295, 293, 294,
+ 296, 295, 297, 676, 296, 0, 297, 295, 80, 81,
+ 296, 0, 297, 0, 0, 0, 82, 83, 80, 81,
+ 84, 35, 85, 0, 0, 35, 82, 83, 0, 0,
+ 84, 0, 85, 35, 80, 81, 35, 0, 0, 35,
+ 75, 76, 82, 83, 35, 0, 84, 35, 85, 0,
+ 6, 5, 4, 1, 3, 2, 0, 0, 49, 52,
+ 50, 0, 49, 52, 50, 0, 0, 77, 78, 0,
+ 49, 52, 50, 49, 52, 50, 49, 52, 50, 0,
+ 35, 49, 52, 50, 49, 52, 50, 35, 46, 34,
+ 51, 0, 46, 34, 51, 35, 0, 0, 35, 0,
+ 46, 34, 51, 46, 34, 51, 46, 34, 51, 0,
+ 0, 46, 34, 51, 46, 34, 51, 49, 52, 50,
+ 35, 0, 0, 0, 49, 52, 50, 0, 0, 0,
+ 80, 81, 49, 52, 50, 49, 52, 50, 82, 83,
+ 0, 0, 84, 35, 85, 0, 537, 46, 34, 51,
+ 186, 0, 0, 0, 46, 34, 51, 49, 52, 50,
+ 35, 0, 46, 34, 51, 46, 34, 51, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 537,
+ 49, 52, 50, 0, 0, 0, 537, 46, 34, 51,
+ 537, 0, 0, 35, 537, 0, 35, 49, 52, 50,
+ 35, 0, 0, 186, 35, 0, 0, 0, 35, 0,
+ 46, 34, 51, 0, 0, 35, 0, 0, 35, 0,
+ 0, 0, 0, 0, 0, 0, 0, 46, 34, 51,
+ 49, 52, 50, 49, 52, 50, 0, 49, 52, 50,
+ 0, 49, 52, 50, 0, 49, 52, 50, 0, 0,
+ 258, 257, 49, 52, 50, 49, 52, 50, 35, 0,
+ 46, 34, 51, 46, 34, 51, 0, 46, 34, 51,
+ 35, 46, 34, 51, 0, 46, 34, 51, 35, 0,
+ 0, 35, 46, 34, 51, 46, 34, 51, 0, 0,
+ 253, 252, 0, 0, 35, 49, 52, 50, 0, 0,
+ 0, 186, 253, 252, 0, 0, 0, 49, 52, 50,
+ 258, 257, 0, 258, 257, 49, 52, 50, 49, 52,
+ 50, 0, 0, 0, 0, 46, 34, 51, 0, 0,
+ 155, 49, 52, 50, 0, 0, 0, 46, 34, 51,
+ 156, 0, 0, 0, 157, 46, 34, 51, 46, 34,
+ 51, 0, 0, 158, 0, 159, 0, 0, 0, 0,
+ 0, 46, 34, 51, 0, 0, 160, 0, 161, 64,
+ 0, 0, 0, 35, 0, 0, 162, 0, 0, 163,
+ 65, 0, 0, 0, 0, 164, 0, 0, 0, 0,
+ 0, 165, 0, 0, 0, 0, 0, 0, 0, 155,
+ 0, 0, 0, 0, 0, 253, 252, 166, 0, 156,
+ 49, 52, 50, 157, 0, 0, 0, 0, 0, 0,
+ 0, 0, 158, 0, 159, 0, 0, 322, 0, 0,
+ 0, 0, 0, 0, 0, 160, 0, 161, 64, 0,
+ 46, 34, 51, 0, 0, 162, 0, 0, 163, 65,
+ 0, 0, 155, 0, 164, 0, 0, 0, 0, 0,
+ 165, 0, 156, 0, 0, 0, 157, 0, 0, 0,
+ 0, 0, 0, 0, 0, 158, 166, 159, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 160, 0,
+ 161, 64, 0, 0, 0, 0, 0, 0, 162, 0,
+ 0, 163, 65, 0, 0, 0, 0, 164, 0, 0,
+ 0, 0, 0, 165, 0, 30, 31, 0, 0, 0,
+ 0, 0, 0, 0, 0, 33, 0, 0, 0, 166,
+ 0, 0, 35, 0, 0, 0, 36, 37, 0, 38,
+ 0, 0, 0, 0, 0, 0, 521, 0, 0, 0,
+ 45, 0, 0, 0, 0, 0, 0, 30, 31, 0,
+ 0, 0, 0, 0, 0, 0, 0, 33, 53, 49,
+ 52, 50, 0, 54, 35, 0, 0, 0, 36, 37,
+ 0, 38, 0, 0, 44, 56, 32, 0, 42, 0,
+ 0, 41, 45, 0, 0, 0, 0, 0, 0, 46,
+ 34, 51, 0, 0, 0, 0, 0, 0, 0, 0,
+ 53, 49, 52, 50, 0, 54, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 44, 56, 32, 0,
+ 0, 0, 0, 41, 0, 0, 0, 0, 0, 0,
+ 0, 46, 34, 51, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 30, 31, 0, 0, 0, 0, 0,
+ 0, 0, 0, 33, 0, 0, 0, 0, 0, 0,
+ 35, 0, 0, 0, 36, 37, 0, 38, 0, 0,
+ 0, 0, 0, 0, 42, 0, 0, 0, 45, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 53, 49, 52, 50,
+ 0, 54, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 44, 56, 32, 0, 0, 0, 0, 41,
+ 0, 0, 0, 0, 0, 0, 0, 46, 34, 51,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 30,
+ 31, 0, 0, 0, 0, 0, 0, 0, 0, 33,
+ 0, 0, 0, 0, 0, 0, 35, 0, 0, 0,
+ 36, 37, 0, 38, 0, 0, 0, 0, 0, 0,
+ 521, 0, 0, 0, 45, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 53, 49, 52, 50, 0, 54, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 44, 56,
+ 32, 0, 0, 0, 0, 41, 0, 0, 0, 0,
+ 0, 0, 0, 46, 34, 51, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 519, 0, 30, 31, 0,
+ 0, 0, 0, 0, 0, 0, 0, 221, 0, 0,
+ 0, 0, 0, 0, 35, 0, 0, 0, 36, 37,
+ 0, 38, 0, 0, 0, 0, 0, 0, 521, 0,
+ 0, 0, 45, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 53, 522, 524, 523, 0, 54, 0, 0, 0, 0,
+ 230, 0, 0, 0, 0, 0, 44, 56, 32, 216,
+ 224, 0, 0, 41, 0, 0, 520, 0, 0, 0,
+ 0, 46, 34, 51, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 519, 0, 30, 31, 0, 0, 0,
+ 0, 0, 0, 0, 0, 221, 0, 0, 0, 0,
+ 0, 0, 35, 0, 0, 0, 36, 37, 0, 38,
+ 0, 0, 0, 0, 0, 0, 521, 0, 0, 0,
+ 45, 0, 0, 0, 0, 0, 0, 0, 585, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 53, 522,
+ 524, 523, 0, 54, 0, 0, 0, 0, 230, 0,
+ 0, 0, 0, 0, 44, 56, 32, 216, 224, 0,
+ 0, 41, 0, 0, 520, 0, 0, 0, 0, 46,
+ 34, 51, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 519, 0, 30, 31, 0, 0, 0, 0, 0,
+ 0, 0, 0, 221, 0, 0, 0, 0, 0, 0,
+ 35, 0, 0, 0, 36, 37, 0, 38, 0, 0,
+ 0, 0, 0, 0, 521, 0, 0, 0, 45, 0,
+ 0, 0, 0, 0, 0, 0, 588, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 53, 522, 524, 523,
+ 0, 54, 0, 0, 0, 0, 230, 0, 0, 0,
+ 0, 0, 44, 56, 32, 216, 224, 0, 0, 41,
+ 0, 0, 520, 0, 0, 0, 0, 46, 34, 51,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 29,
+ 30, 31, 0, 0, 0, 0, 0, 0, 0, 0,
+ 33, 0, 0, 0, 0, 0, 0, 35, 0, 0,
+ 0, 36, 37, 0, 38, 0, 0, 0, 39, 0,
+ 40, 42, 43, 0, 0, 45, 0, 0, 0, 47,
+ 0, 48, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 53, 49, 52, 50, 0, 54, 0,
+ 55, 0, 57, 0, 58, 0, 0, 0, 0, 44,
+ 56, 32, 0, 0, 0, 0, 41, 0, 0, 0,
+ 0, 0, 0, 0, 46, 34, 51, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, -141, 0, 0, 0,
+ 29, 30, 31, 0, 0, 0, 0, 0, 0, 0,
+ 0, 33, 0, 0, 0, 0, 0, 0, 35, 0,
+ 0, 0, 36, 37, 0, 38, 0, 0, 0, 39,
+ 0, 40, 42, 43, 0, 0, 45, 0, 0, 0,
+ 47, 0, 48, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 53, 49, 52, 50, 0, 54,
+ 0, 55, 0, 57, 0, 58, 0, 0, 0, 0,
+ 44, 56, 32, 0, 0, 0, 0, 41, 0, 0,
+ 0, 0, 0, 0, 0, 46, 34, 51, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 29, 30, 31,
+ 0, 0, 0, 0, 0, 0, 0, 0, 33, 0,
+ 0, 0, 0, 0, 0, 35, 0, 0, 0, 36,
+ 37, 0, 38, 0, 0, 0, 39, 0, 40, 42,
+ 43, 0, 0, 45, 0, 0, 0, 47, 0, 48,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 53, 49, 52, 50, 0, 54, 0, 55, 0,
+ 57, 285, 58, 0, 0, 0, 0, 44, 56, 32,
+ 0, 0, 0, 0, 41, 0, 0, 0, 0, 0,
+ 0, 0, 46, 34, 51, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 492, 0, 0, 29, 30, 31,
+ 0, 0, 0, 0, 0, 0, 0, 0, 33, 0,
+ 0, 0, 0, 0, 0, 35, 0, 0, 0, 36,
+ 37, 0, 38, 0, 0, 0, 39, 0, 40, 42,
+ 43, 0, 0, 45, 0, 0, 0, 47, 0, 48,
+ 0, 0, 493, 0, 0, 0, 0, 0, 0, 0,
+ 0, 53, 49, 52, 50, 0, 54, 0, 55, 0,
+ 57, 0, 58, 0, 0, 0, 0, 44, 56, 32,
+ 0, 0, 0, 0, 41, 0, 0, 0, 0, 0,
+ 0, 0, 46, 34, 51, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 500, 0, 0, 29, 30, 31,
+ 0, 0, 0, 0, 0, 0, 0, 0, 33, 0,
+ 0, 0, 0, 0, 0, 35, 0, 0, 0, 36,
+ 37, 0, 38, 0, 0, 0, 39, 0, 40, 42,
+ 43, 0, 0, 45, 0, 0, 0, 47, 0, 48,
+ 0, 0, 503, 0, 0, 0, 0, 0, 0, 0,
+ 0, 53, 49, 52, 50, 0, 54, 0, 55, 0,
+ 57, 0, 58, 0, 0, 0, 0, 44, 56, 32,
+ 0, 0, 0, 0, 41, 0, 0, 0, 0, 0,
+ 0, 0, 46, 34, 51, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 492, 0, 0, 29, 30, 31,
+ 0, 0, 0, 0, 0, 0, 0, 0, 33, 0,
+ 0, 0, 0, 0, 0, 35, 0, 0, 0, 36,
+ 37, 0, 38, 0, 0, 0, 39, 0, 40, 42,
+ 43, 0, 0, 45, 0, 0, 0, 47, 0, 48,
+ 0, 0, 498, 0, 0, 0, 0, 0, 0, 0,
+ 0, 53, 49, 52, 50, 0, 54, 0, 55, 0,
+ 57, 0, 58, 0, 0, 0, 0, 44, 56, 32,
+ 0, 0, 0, 0, 41, 0, 0, 0, 0, 0,
+ 0, 0, 46, 34, 51, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 500, 0, 0, 29, 30, 31,
+ 0, 0, 0, 0, 0, 0, 0, 0, 33, 0,
+ 0, 0, 0, 0, 0, 35, 0, 0, 0, 36,
+ 37, 0, 38, 0, 0, 0, 39, 0, 40, 42,
+ 43, 0, 0, 45, 0, 0, 0, 47, 0, 48,
+ 0, 0, 501, 0, 0, 0, 0, 0, 0, 0,
+ 0, 53, 49, 52, 50, 0, 54, 0, 55, 0,
+ 57, 0, 58, 0, 0, 0, 0, 44, 56, 32,
+ 0, 0, 0, 0, 41, 0, 0, 0, 0, 0,
+ 0, 0, 46, 34, 51, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 29, 30, 31, 0, 0, 0,
+ 0, 0, 0, 0, 0, 33, 0, 0, 0, 0,
+ 0, 0, 35, 222, 0, 0, 223, 37, 0, 38,
+ 0, 0, 0, 39, 0, 40, 42, 43, 0, 0,
+ 45, 0, 0, 0, 47, 0, 48, 0, 0, 0,
+ 0, 0, 0, 0, 226, 0, 0, 0, 53, 49,
+ 52, 50, 227, 54, 0, 55, 229, 57, 0, 58,
+ 0, 232, 0, 0, 44, 56, 32, 0, 0, 0,
+ 0, 41, 0, 0, 0, 0, 0, 0, 0, 46,
+ 34, 51, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 29, 30, 31, 0, 0, 0, 0, 0, 0,
+ 0, 0, 33, 0, 0, 0, 0, 0, 0, 35,
+ 222, 0, 0, 603, 650, 0, 38, 0, 0, 0,
+ 39, 0, 40, 42, 43, 0, 0, 45, 0, 0,
+ 0, 47, 0, 48, 0, 0, 0, 0, 0, 0,
+ 0, 226, 0, 0, 0, 53, 49, 52, 50, 227,
+ 54, 0, 55, 229, 57, 0, 58, 0, 232, 0,
+ 0, 44, 56, 32, 0, 0, 0, 0, 41, 0,
+ 0, 0, 0, 0, 0, 0, 46, 34, 51, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 29, 30,
+ 31, 0, 0, 0, 0, 0, 0, 0, 0, 33,
+ 0, 0, 0, 0, 0, 0, 35, 222, 0, 0,
+ 603, 37, 0, 38, 0, 0, 0, 39, 0, 40,
+ 42, 43, 0, 0, 45, 0, 0, 0, 47, 0,
+ 48, 0, 0, 0, 0, 0, 0, 0, 226, 0,
+ 0, 0, 53, 49, 52, 50, 227, 54, 0, 55,
+ 229, 57, 0, 58, 0, 232, 0, 0, 44, 56,
+ 32, 0, 0, 0, 0, 41, 0, 0, 0, 0,
+ 0, 0, 0, 46, 34, 51, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 111, 112, 113, 0, 0,
+ 115, 117, 118, 0, 0, 119, 0, 120, 0, 0,
+ 0, 123, 124, 125, 0, 0, 0, 0, 0, 0,
+ 35, 126, 127, 128, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 130, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 133, 0, 0, 0, 0, 0, 0, 49, 52, 50,
+ 134, 135, 136, 0, 138, 139, 140, 141, 142, 143,
+ 0, 0, 131, 137, 122, 114, 129, 116, 132, 0,
+ 0, 0, 121, 0, 0, 0, 0, 46, 34, 51,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 111,
+ 112, 113, 0, 0, 115, 117, 118, 0, 0, 119,
+ 0, 120, 0, 0, 0, 123, 124, 125, 0, 0,
+ 0, 0, 0, 0, 35, 126, 127, 128, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 130, 0,
+ 0, 0, 399, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 133, 0, 0, 0, 0, 0,
+ 401, 49, 52, 50, 134, 135, 136, 0, 138, 139,
+ 140, 141, 142, 143, 0, 0, 131, 137, 122, 114,
+ 129, 116, 132, 0, 0, 0, 121, 0, 0, 0,
+ 0, 46, 34, 51, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 111, 112, 113, 0, 0, 115, 117,
+ 118, 0, 0, 119, 0, 120, 0, 0, 0, 123,
+ 124, 125, 0, 0, 0, 0, 0, 0, 35, 126,
+ 127, 128, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 130, 0, 0, 0, 399, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 133, 0,
+ 0, 0, 0, 0, 401, 49, 52, 50, 134, 135,
+ 136, 0, 138, 139, 140, 141, 142, 143, 0, 0,
+ 131, 137, 122, 114, 129, 116, 132, 0, 0, 0,
+ 121, 0, 0, 0, 0, 46, 377, 384, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 111, 112, 113,
+ 0, 0, 115, 117, 118, 0, 0, 119, 0, 120,
+ 0, 0, 0, 123, 124, 125, 0, 0, 0, 0,
+ 0, 0, 35, 126, 127, 128, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 130, 0, 0, 0,
+ 399, 0, 0, 0, 0, 0, 0, 0, 400, 0,
+ 0, 0, 133, 0, 0, 0, 0, 0, 401, 49,
+ 52, 50, 134, 135, 136, 0, 138, 139, 140, 141,
+ 142, 143, 0, 0, 131, 137, 122, 114, 129, 116,
+ 132, 0, 0, 0, 121, 0, 0, 0, 0, 46,
+ 377, 384, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 215, 0, 0, 0, 0, 217, 0, 29, 30,
+ 31, 219, 0, 0, 0, 0, 0, 0, 220, 33,
+ 0, 0, 0, 0, 0, 0, 35, 222, 0, 0,
+ 223, 37, 0, 38, 0, 0, 0, 39, 0, 40,
+ 42, 43, 0, 0, 45, 0, 0, 0, 47, 0,
+ 48, 0, 0, 0, 0, 0, 225, 0, 226, 0,
+ 0, 0, 53, 49, 52, 50, 227, 54, 228, 55,
+ 229, 57, 230, 58, 231, 232, 0, 0, 44, 56,
+ 32, 216, 224, 218, 0, 41, 0, 0, 0, 0,
+ 0, 0, 0, 46, 34, 51, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 215, 0, 0, 0, 0,
+ 217, 0, 29, 30, 31, 219, 0, 0, 0, 0,
+ 0, 0, 220, 221, 0, 0, 0, 0, 0, 0,
+ 35, 222, 0, 0, 223, 37, 0, 38, 0, 0,
+ 0, 39, 0, 40, 42, 43, 0, 0, 45, 0,
+ 0, 0, 47, 0, 48, 0, 0, 0, 0, 0,
+ 225, 0, 226, 0, 0, 0, 53, 49, 52, 50,
+ 227, 54, 228, 55, 229, 57, 230, 58, 231, 232,
+ 0, 0, 44, 56, 32, 216, 224, 218, 0, 41,
+ 0, 0, 0, 0, 0, 0, 0, 46, 34, 51,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 607,
+ 112, 113, 0, 0, 609, 117, 611, 30, 31, 612,
+ 0, 120, 0, 0, 0, 123, 614, 615, 0, 0,
+ 0, 0, 0, 0, 35, 616, 127, 128, 223, 37,
+ 0, 38, 0, 0, 0, 39, 0, 40, 618, 43,
+ 0, 0, 620, 0, 0, 0, 47, 0, 48, 0,
+ 0, 0, 0, 0, 621, 0, 226, 0, 0, 0,
+ 622, 49, 52, 50, 623, 624, 625, 55, 627, 628,
+ 629, 630, 631, 632, 0, 0, 619, 626, 613, 608,
+ 617, 610, 132, 41, 0, 0, 121, 0, 0, 0,
+ 0, 46, 377, 384, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 368, 112, 113, 0, 0, 370, 117,
+ 372, 30, 31, 373, 0, 120, 0, 0, 0, 123,
+ 375, 376, 0, 0, 0, 0, 0, 0, 35, 378,
+ 127, 128, 223, 37, 0, 38, 0, 0, 0, 39,
+ 0, 40, 380, 43, 0, 0, 382, 0, 0, 0,
+ 47, 0, 48, 0, -288, 0, 0, 0, 383, 0,
+ 226, 0, 0, 0, 385, 49, 52, 50, 386, 387,
+ 388, 55, 390, 391, 392, 393, 394, 395, 0, 0,
+ 381, 389, 374, 369, 379, 371, 132, 41, 0, 0,
+ 121, 0, 0, 0, 0, 46, 377, 384, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
- 152, 652, 331, 669, 535, 531, 538, 142, 528, 148,
- 641, 16, 313, 393, 485, 500, 626, 630, 263, 638,
- 183, 625, 623, 206, 574, 447, 583, 320, 183, 253,
- 313, 248, 466, 145, 663, 653, 616, 584, 556, 640,
- 581, 248, 437, 253, 248, 495, 183, 178, 453, 150,
- 462, 347, 455, 550, 554, 183, 351, 447, 458, 190,
- 313, 457, 425, 188, 469, 441, 433, 253, 237, 468,
- 0, 313, 173, 171, 393, 409, 447, 498, 409, 464,
- 400, 0, 165, 206, 475, 206, 512, 511, 0, 0,
- 188, 0, 0, 206, 0, 206, 0, 62, 0, 459,
- 417, 206, 206, 206, 188, 0, 62, 0, 62, 62,
- 507, 504, 410, 148, 62, 410, 460, 62, 419, 505,
- 407, 412, 170, 62, 62, 459, 506, 444, 277, 148,
- 422, 331, 187, 281, 62, 62, 62, 180, 260, 295,
- 296, 297, 62, 62, 656, 655, 314, 298, 299, 62,
- 62, 503, 182, 62, 206, 362, 514, 393, 247, 62,
- 62, 460, 502, 62, 62, 639, 313, 167, 92, 99,
- 62, 206, 206, 514, 510, 345, 100, 260, 562, 62,
- 62, 62, 394, 493, 93, 94, 95, 492, 62, 62,
- 182, 206, 62, 206, 96, 62, 246, 97, 62, 90,
- 62, 401, 91, 206, 62, 86, 355, 340, 353, 62,
- 108, 247, 206, 349, 188, 313, 102, 206, 393, 104,
- 313, 62, 206, 182, 206, 206, 62, 362, 459, 206,
- 242, 62, 469, 460, 62, 514, 409, 63, 318, 110,
- 657, 341, 239, 590, 403, 62, 322, 206, 72, 62,
- 362, 62, 362, 69, 206, 98, 62, 62, 70, 71,
- 514, 0, 206, 62, 62, 566, 356, 0, 206, 79,
- 62, 108, 74, 410, 483, 281, 0, 309, 0, 0,
- 62, 62, 281, 304, 62, 281, 281, 62, 362, 281,
- 343, 0, 281, 284, 289, 316, 324, 327, 0, 311,
- 110, 177, 0, 309, 206, 62, 479, 0, 281, 62,
- 281, 309, 301, 309, 281, 0, 281, 309, 281, 62,
- 306, 0, 281, 62, 281, 337, 302, 0, 281, 578,
- 300, 514, 260, 328, 562, 308, 636, 570, 443, 330,
- 522, 0, 0, 0, 0, 0, 514, 0, 206, 0,
- 0, 0, 513, 523, 0, 522, 0, 485, 542, 543,
- 544, 545, 549, 546, 547, 0, 586, 513, 523, 0,
- 0, 0, 0, 0, 440, 588, 589, 542, 543, 544,
- 545, 549, 546, 547, 586, 0, 0, 0, 0, 0,
- 0, 0, 0, 634, 635, 542, 543, 544, 545, 549,
- 546, 547, 578, 0, 0, 0, 0, 0, 0, 0,
- 0, 579, 580, 542, 543, 544, 545, 549, 546, 547,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 573, 0, 0, 0, 0, 0, 0, 0, 0,
- 514, 0, 0, 0, 0, 0, 0, 0, 0, 522,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 513, 523, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0};
+ 543, 185, 640, 647, 642, 643, 504, 489, 397, 451,
+ 655, 657, 669, 670, 154, 680, 658, 448, 686, 316,
+ 185, 16, 256, 536, 251, 599, 570, 633, 572, 590,
+ 597, 144, 323, 540, 457, 150, 266, 473, 190, 441,
+ 350, 445, 251, 192, 256, 437, 429, 354, 208, 240,
+ 185, 316, 251, 256, 185, 404, 448, 448, 316, 533,
+ 566, 470, 466, 180, 451, 451, 462, 0, 62, 334,
+ 510, 516, 62, 0, 0, 325, 62, 299, 316, 0,
+ 459, 298, 397, 334, 0, 147, 461, 208, 499, 0,
+ 152, 208, 502, 167, 600, 479, 673, 672, 518, 173,
+ 175, 515, 316, 674, 208, 397, 316, 518, 316, 407,
+ 208, 0, 190, 0, 321, 208, 656, 352, 62, 249,
+ 464, 62, 62, 184, 509, 62, 62, 463, 463, 62,
+ 208, 508, 421, 208, 62, 208, 184, 356, 245, 358,
+ 405, 242, 263, 280, 62, 62, 62, 506, 284, 302,
+ 62, 301, 507, 208, 317, 208, 208, 62, 208, 62,
+ 343, 184, 300, 413, 348, 365, 62, 0, 62, 190,
+ 518, 62, 99, 62, 100, 578, 86, 90, 346, 62,
+ 208, 208, 319, 91, 344, 62, 62, 62, 413, 62,
+ 93, 94, 95, 473, 96, 468, 514, 62, 189, 62,
+ 150, 414, 97, 92, 208, 62, 472, 464, 182, 62,
+ 62, 208, 497, 62, 62, 397, 496, 250, 365, 62,
+ 104, 102, 208, 263, 208, 98, 414, 263, 169, 172,
+ 365, 208, 487, 62, 359, 511, 62, 250, 463, 208,
+ 62, 398, 464, 208, 62, 62, 606, 63, 72, 190,
+ 150, 208, 411, 62, 518, 69, 62, 208, 416, 582,
+ 365, 365, 79, 62, 62, 70, 62, 62, 483, 71,
+ 0, 284, 74, 0, 0, 62, 208, 208, 423, 307,
+ 284, 0, 62, 0, 287, 426, 108, 284, 0, 292,
+ 62, 62, 0, 0, 0, 284, 284, 303, 304, 62,
+ 312, 0, 62, 312, 284, 284, 305, 284, 284, 312,
+ 62, 0, 312, 309, 284, 284, 110, 284, 62, 312,
+ 0, 594, 333, 284, 284, 340, 578, 330, 653, 0,
+ 518, 331, 0, 327, 311, 586, 0, 589, 0, 527,
+ 0, 314, 0, 0, 518, 0, 518, 444, 447, 0,
+ 489, 517, 528, 527, 0, 527, 547, 548, 549, 550,
+ 554, 551, 552, 0, 0, 517, 528, 517, 528, 0,
+ 0, 0, 602, 0, 0, 0, 0, 0, 0, 0,
+ 108, 604, 605, 547, 548, 549, 550, 554, 551, 552,
+ 594, 0, 0, 0, 0, 0, 0, 0, 0, 595,
+ 596, 547, 548, 549, 550, 554, 551, 552, 0, 0,
+ 110, 179, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 602, 0, 0, 0, 0, 0,
+ 0, 0, 0, 651, 652, 547, 548, 549, 550, 554,
+ 551, 552, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0
+};
const short QQmlJSGrammar::action_check [] = {
- 7, 55, 48, 55, 55, 55, 36, 7, 36, 33,
- 55, 7, 7, 33, 37, 7, 7, 61, 60, 60,
- 36, 7, 33, 8, 36, 7, 16, 1, 36, 60,
- 7, 36, 2, 48, 7, 36, 5, 36, 36, 36,
- 79, 5, 36, 60, 33, 33, 55, 60, 7, 36,
- 34, 7, 33, 7, 7, 33, 36, 7, 7, 77,
- 36, 33, 8, 5, 1, 8, 33, 60, 29, 79,
- 36, 33, 17, 8, 37, 79, 33, 60, 33, 8,
- 1, 60, 2, 8, 7, 60, 33, 55, 48, 60,
- 29, 2, 7, 2, 7, 36, 36, 7, 17, 7,
- 33, 66, 7, 61, 48, 31, 36, 1, 36, 33,
- 8, 7, 60, 20, 36, 66, 33, 7, 36, 55,
- 36, 8, 60, 8, 15, -1, 40, 79, 8, 61,
- 61, 62, 10, 8, 61, 62, 40, 51, 8, 15,
- 40, 40, 8, 34, 8, 42, 6, 51, 24, 61,
- 62, 51, 51, 7, 8, 8, 53, 8, 61, 62,
- 20, 8, 8, 8, 8, 15, 61, 62, 61, 62,
- 8, 8, 15, 60, -1, 60, 56, 55, 61, 62,
- 61, 62, 61, 62, 34, 60, 56, 61, 62, 91,
- 92, 34, 56, 50, 60, 15, 29, 54, 0, 91,
- 92, 50, 61, 62, 24, 54, 25, 60, 27, 12,
- 61, 56, 29, 60, 60, 25, 60, 27, 56, 38,
- 25, 25, 27, 27, 61, 62, 12, 15, 38, 61,
- 62, 12, 29, 38, 38, 29, 7, -1, 25, 7,
- 27, 36, 75, 8, 29, 8, 34, -1, 36, 15,
- 25, 38, 27, 86, 57, 7, -1, 89, 75, 7,
- 63, -1, 33, 38, 15, 29, 61, 62, 34, 86,
- 36, 57, 29, -1, -1, -1, 57, 63, 75, -1,
- -1, 75, 63, 34, 15, 36, -1, 61, 62, 86,
- 75, -1, 86, 61, 62, -1, 61, 62, 61, 62,
- -1, 86, -1, 34, 25, 36, 27, 15, -1, 61,
- 62, 75, -1, 61, 62, 18, 19, 38, 75, 93,
- 15, -1, 86, 94, -1, 33, 34, -1, 36, 86,
- 18, 19, 18, 19, 18, 19, 47, -1, 33, 34,
- -1, 36, 45, 46, 98, 99, 100, 101, 102, 103,
- 61, 62, -1, -1, 23, 24, -1, 45, 46, 45,
- 46, 45, 46, 32, 23, 24, 35, -1, 37, -1,
- -1, -1, -1, 32, 23, 24, 35, -1, 37, -1,
- 23, 24, 93, 32, -1, 25, 35, 27, 37, 32,
- -1, -1, 35, 29, 37, 23, 24, -1, 38, -1,
- -1, -1, -1, 31, 32, 23, 24, 35, -1, 37,
- -1, -1, -1, 31, 32, 23, 24, 35, 29, 37,
- -1, -1, -1, 31, 32, 23, 24, 35, -1, 37,
- 66, 67, 68, 31, 32, 23, 24, 35, -1, 37,
- -1, -1, -1, 31, 32, -1, -1, 35, -1, 37,
- 29, -1, -1, 29, -1, 66, 67, 68, 94, 95,
- 96, 29, -1, -1, 29, -1, 23, 24, 29, -1,
- -1, 29, 15, -1, 29, 32, -1, -1, 35, -1,
- 37, 36, -1, 94, 95, 96, 29, 66, 67, 68,
- 66, 67, 68, -1, -1, -1, -1, -1, 66, 67,
- 68, 66, 67, 68, -1, 66, 67, 68, 66, 67,
- 68, 66, 67, 68, -1, 94, 95, 96, 94, 95,
- 96, -1, -1, 66, 67, 68, 94, 95, 96, 94,
- 95, 96, 15, 94, 95, 96, 94, 95, 96, 94,
- 95, 96, -1, 29, -1, -1, 29, -1, -1, 29,
- 36, 94, 95, 96, 29, -1, -1, 29, -1, -1,
- -1, 36, -1, -1, -1, 29, -1, -1, 29, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 66, 67, 68, 66, 67, 68, 66, 67, 68, 61,
- 62, 66, 67, 68, 66, 67, 68, 61, 62, -1,
- 61, 62, 66, 67, 68, 66, 67, 68, 94, 95,
- 96, 94, 95, 96, 94, 95, 96, 29, -1, 94,
- 95, 96, 94, 95, 96, 29, 15, -1, 29, -1,
- 94, 95, 96, 94, 95, 96, -1, -1, -1, -1,
- 29, -1, -1, -1, -1, -1, -1, -1, -1, 61,
- 62, -1, -1, -1, 66, 67, 68, 61, 62, -1,
- 61, 62, 66, 67, 68, 66, 67, 68, -1, -1,
- -1, -1, -1, -1, -1, 3, -1, 66, 67, 68,
- -1, -1, 94, 95, 96, 13, -1, -1, -1, 17,
- 94, 95, 96, 94, 95, 96, -1, -1, 26, -1,
- 28, -1, -1, 31, -1, 94, 95, 96, -1, -1,
- -1, 39, -1, 41, 42, -1, -1, 3, -1, -1,
- -1, 49, -1, -1, 52, 53, -1, 13, -1, -1,
- 58, 17, -1, -1, -1, -1, 64, -1, -1, -1,
- 26, -1, 28, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 80, 39, -1, 41, 42, -1, -1, -1,
- -1, -1, -1, 49, -1, -1, 52, 53, -1, -1,
- -1, -1, 58, -1, -1, -1, -1, -1, 64, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 80, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 12, 13, -1, -1, -1, -1, -1, -1, -1, -1,
- 22, -1, -1, -1, -1, -1, -1, 29, -1, -1,
- -1, 33, 34, -1, 36, -1, -1, -1, -1, -1,
- -1, 43, -1, -1, -1, 47, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 65, 66, 67, 68, -1, 70, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 81,
- 82, 83, -1, -1, -1, 87, -1, -1, -1, -1,
- -1, -1, 94, 95, 96, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 12, 13, -1, -1, -1, -1,
- -1, -1, -1, -1, 22, -1, -1, -1, -1, -1,
- -1, 29, -1, -1, -1, 33, 34, -1, 36, -1,
- -1, -1, -1, -1, -1, 43, -1, -1, -1, 47,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 65, 66, 67,
- 68, -1, 70, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 81, 82, 83, -1, -1, -1, 87,
- -1, -1, -1, -1, -1, -1, 94, 95, 96, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 10, -1,
- 12, 13, -1, -1, -1, -1, -1, -1, -1, -1,
- 22, -1, -1, -1, -1, -1, -1, 29, -1, -1,
- -1, 33, 34, -1, 36, -1, -1, -1, -1, -1,
- -1, 43, -1, -1, -1, 47, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 65, 66, 67, 68, -1, 70, -1,
- -1, -1, -1, 75, -1, -1, -1, -1, -1, 81,
- 82, 83, 84, -1, -1, 87, -1, -1, -1, -1,
- -1, -1, 94, 95, 96, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 10, -1, 12, 13, -1, -1,
- -1, -1, -1, -1, -1, -1, 22, -1, -1, -1,
- -1, -1, -1, 29, -1, -1, -1, 33, 34, -1,
- 36, -1, -1, -1, -1, -1, -1, 43, -1, -1,
- -1, 47, -1, -1, -1, -1, -1, -1, -1, 55,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 65,
- 66, 67, 68, -1, 70, -1, -1, -1, -1, 75,
- -1, -1, -1, -1, -1, 81, 82, 83, 84, -1,
- -1, 87, -1, -1, -1, -1, -1, -1, 94, 95,
- 96, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 10, -1, 12, 13, -1, -1, -1, -1, -1, -1,
- -1, -1, 22, -1, -1, -1, -1, -1, -1, 29,
- -1, -1, -1, 33, 34, -1, 36, -1, -1, -1,
- -1, -1, -1, 43, -1, -1, -1, 47, -1, -1,
- -1, -1, -1, -1, -1, 55, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 65, 66, 67, 68, -1,
- 70, -1, -1, -1, -1, 75, -1, -1, -1, -1,
- -1, 81, 82, 83, 84, -1, -1, 87, -1, -1,
- -1, -1, -1, -1, 94, 95, 96, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 11, 12, 13, -1,
- -1, -1, -1, -1, -1, -1, -1, 22, -1, -1,
- -1, -1, -1, -1, 29, -1, -1, -1, 33, 34,
- -1, 36, -1, -1, -1, 40, -1, 42, 43, 44,
- -1, -1, 47, -1, -1, -1, 51, -1, 53, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 65, 66, 67, 68, -1, 70, -1, 72, -1, 74,
- -1, 76, -1, -1, -1, -1, 81, 82, 83, -1,
- -1, -1, 87, -1, -1, -1, -1, -1, -1, 94,
- 95, 96, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 7, -1, -1, -1, 11, 12, 13, -1, -1,
- -1, -1, -1, -1, -1, -1, 22, -1, -1, -1,
- -1, -1, -1, 29, -1, -1, -1, 33, 34, -1,
- 36, -1, -1, -1, 40, -1, 42, 43, 44, -1,
- -1, 47, -1, -1, -1, 51, -1, 53, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 65,
- 66, 67, 68, -1, 70, -1, 72, -1, 74, -1,
- 76, -1, -1, -1, -1, 81, 82, 83, -1, -1,
- -1, 87, -1, -1, -1, -1, -1, -1, 94, 95,
- 96, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 11, 12, 13, -1, -1, -1, -1, -1, -1, -1,
- -1, 22, -1, -1, -1, -1, -1, -1, 29, -1,
- -1, -1, 33, 34, -1, 36, -1, -1, -1, 40,
- -1, 42, 43, 44, -1, -1, 47, -1, -1, -1,
- 51, -1, 53, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 65, 66, 67, 68, -1, 70,
- -1, 72, -1, 74, 75, 76, -1, -1, -1, -1,
- 81, 82, 83, -1, -1, -1, 87, -1, -1, -1,
- -1, -1, -1, 94, 95, 96, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 8, -1, -1, 11, 12,
- 13, -1, -1, -1, -1, -1, -1, -1, -1, 22,
- -1, -1, -1, -1, -1, -1, 29, -1, -1, -1,
- 33, 34, -1, 36, -1, -1, -1, 40, -1, 42,
- 43, 44, -1, -1, 47, -1, -1, -1, 51, -1,
- 53, -1, -1, 56, -1, -1, -1, -1, -1, -1,
- -1, -1, 65, 66, 67, 68, -1, 70, -1, 72,
- -1, 74, -1, 76, -1, -1, -1, -1, 81, 82,
- 83, -1, -1, -1, 87, -1, -1, -1, -1, -1,
- -1, 94, 95, 96, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 8, -1, -1, 11, 12, 13, -1,
- -1, -1, -1, -1, -1, -1, -1, 22, -1, -1,
- -1, -1, -1, -1, 29, -1, -1, -1, 33, 34,
- -1, 36, -1, -1, -1, 40, -1, 42, 43, 44,
- -1, -1, 47, -1, -1, -1, 51, -1, 53, -1,
- -1, 56, -1, -1, -1, -1, -1, -1, -1, -1,
- 65, 66, 67, 68, -1, 70, -1, 72, -1, 74,
- -1, 76, -1, -1, -1, -1, 81, 82, 83, -1,
- -1, -1, 87, -1, -1, -1, -1, -1, -1, 94,
- 95, 96, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 8, -1, -1, 11, 12, 13, -1, -1, -1,
- -1, -1, -1, -1, -1, 22, -1, -1, -1, -1,
- -1, -1, 29, -1, -1, -1, 33, 34, -1, 36,
- -1, -1, -1, 40, -1, 42, 43, 44, -1, -1,
- 47, -1, -1, -1, 51, -1, 53, -1, -1, 56,
- -1, -1, -1, -1, -1, -1, -1, -1, 65, 66,
- 67, 68, -1, 70, -1, 72, -1, 74, -1, 76,
- -1, -1, -1, -1, 81, 82, 83, -1, -1, -1,
- 87, -1, -1, -1, -1, -1, -1, 94, 95, 96,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 8,
- -1, -1, 11, 12, 13, -1, -1, -1, -1, -1,
- -1, -1, -1, 22, -1, -1, -1, -1, -1, -1,
- 29, -1, -1, -1, 33, 34, -1, 36, -1, -1,
- -1, 40, -1, 42, 43, 44, -1, -1, 47, -1,
- -1, -1, 51, -1, 53, -1, -1, 56, -1, -1,
- -1, -1, -1, -1, -1, -1, 65, 66, 67, 68,
- -1, 70, -1, 72, -1, 74, -1, 76, -1, -1,
- -1, -1, 81, 82, 83, -1, -1, -1, 87, -1,
- -1, -1, -1, -1, -1, 94, 95, 96, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 11, 12, 13,
- -1, -1, -1, -1, -1, -1, -1, -1, 22, -1,
- -1, -1, -1, -1, -1, 29, 30, -1, -1, 33,
- 34, -1, 36, -1, -1, -1, 40, -1, 42, 43,
- 44, -1, -1, 47, -1, -1, -1, 51, -1, 53,
- -1, -1, -1, -1, -1, -1, -1, 61, -1, -1,
- -1, 65, 66, 67, 68, 69, 70, -1, 72, 73,
- 74, -1, 76, -1, 78, -1, -1, 81, 82, 83,
- -1, -1, -1, 87, -1, -1, -1, -1, -1, -1,
- 94, 95, 96, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 11, 12, 13, -1, -1, -1, -1, -1,
- -1, -1, -1, 22, -1, -1, -1, -1, -1, -1,
- 29, 30, -1, -1, 33, 34, -1, 36, -1, -1,
- -1, 40, -1, 42, 43, 44, -1, -1, 47, -1,
- -1, -1, 51, -1, 53, -1, -1, -1, -1, -1,
- -1, -1, 61, -1, -1, -1, 65, 66, 67, 68,
- 69, 70, -1, 72, 73, 74, -1, 76, -1, 78,
- -1, -1, 81, 82, 83, -1, -1, -1, 87, -1,
- -1, -1, -1, -1, -1, 94, 95, 96, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 11, 12, 13,
- -1, -1, -1, -1, -1, -1, -1, -1, 22, -1,
- -1, -1, -1, -1, -1, 29, 30, -1, -1, 33,
- 34, -1, 36, -1, -1, -1, 40, -1, 42, 43,
- 44, -1, -1, 47, -1, -1, -1, 51, -1, 53,
- -1, -1, -1, -1, -1, -1, -1, 61, -1, -1,
- -1, 65, 66, 67, 68, 69, 70, -1, 72, 73,
- 74, -1, 76, -1, 78, -1, -1, 81, 82, 83,
- -1, -1, -1, 87, -1, -1, -1, -1, -1, -1,
- 94, 95, 96, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 4, 5, 6, -1, -1, 9, 10, 11,
- -1, -1, 14, -1, 16, -1, -1, -1, 20, 21,
- 22, -1, -1, -1, -1, -1, -1, 29, 30, 31,
- 32, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 43, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 59, -1, -1,
- -1, -1, -1, -1, 66, 67, 68, 69, 70, 71,
- -1, 73, 74, 75, 76, 77, 78, -1, -1, 81,
- 82, 83, 84, 85, 86, -1, -1, -1, -1, -1,
- -1, -1, 94, 95, 96, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 4, 5, 6, -1, -1, 9,
- 10, 11, -1, -1, 14, -1, 16, -1, -1, -1,
- 20, 21, 22, -1, -1, -1, -1, -1, -1, 29,
- 30, 31, 32, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 43, -1, -1, -1, 47, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 59,
- -1, -1, -1, -1, -1, 65, 66, 67, 68, 69,
- 70, 71, -1, 73, 74, 75, 76, 77, 78, -1,
- -1, 81, 82, 83, 84, 85, 86, -1, -1, -1,
- -1, -1, -1, -1, 94, 95, 96, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 4, 5, 6, -1,
- -1, 9, 10, 11, -1, -1, 14, -1, 16, -1,
- -1, -1, 20, 21, 22, -1, -1, -1, -1, -1,
- -1, 29, 30, 31, 32, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 43, -1, -1, -1, 47,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 59, -1, -1, -1, -1, -1, 65, 66, 67,
- 68, 69, 70, 71, -1, 73, 74, 75, 76, 77,
- 78, -1, -1, 81, 82, 83, 84, 85, 86, -1,
- -1, -1, -1, -1, -1, -1, 94, 95, 96, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 4, 5,
- 6, -1, -1, 9, 10, 11, -1, -1, 14, -1,
- 16, -1, -1, -1, 20, 21, 22, -1, -1, -1,
- -1, -1, -1, 29, 30, 31, 32, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 43, -1, -1,
- -1, 47, -1, -1, -1, -1, -1, -1, -1, 55,
- -1, -1, -1, 59, -1, -1, -1, -1, -1, 65,
- 66, 67, 68, 69, 70, 71, -1, 73, 74, 75,
- 76, 77, 78, -1, -1, 81, 82, 83, 84, 85,
- 86, -1, -1, -1, -1, -1, -1, -1, 94, 95,
- 96, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 4, -1, -1, -1, -1, 9, -1, 11, 12, 13,
- 14, -1, -1, -1, -1, -1, -1, 21, 22, -1,
- -1, -1, -1, -1, -1, 29, 30, -1, -1, 33,
- 34, -1, 36, -1, -1, -1, 40, -1, 42, 43,
- 44, -1, -1, 47, -1, -1, -1, 51, -1, 53,
- -1, -1, -1, -1, -1, 59, -1, 61, -1, -1,
- -1, 65, 66, 67, 68, 69, 70, 71, 72, 73,
- 74, 75, 76, 77, 78, -1, -1, 81, 82, 83,
- 84, 85, -1, 87, -1, -1, -1, -1, -1, -1,
- 94, 95, 96, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 4, -1, -1, -1, -1, 9, -1, 11,
- 12, 13, 14, -1, -1, -1, -1, -1, -1, 21,
- 22, -1, -1, -1, -1, -1, -1, 29, 30, -1,
- -1, 33, 34, -1, 36, -1, -1, -1, 40, -1,
- 42, 43, 44, -1, -1, 47, -1, -1, -1, 51,
- -1, 53, -1, -1, -1, -1, -1, 59, -1, 61,
- -1, -1, -1, 65, 66, 67, 68, 69, 70, 71,
- 72, 73, 74, 75, 76, 77, 78, -1, -1, 81,
- 82, 83, 84, 85, -1, 87, -1, -1, -1, -1,
- -1, -1, 94, 95, 96, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 4, 5, 6, -1, -1, 9,
- 10, 11, 12, 13, 14, -1, 16, -1, -1, -1,
- 20, 21, 22, -1, -1, -1, -1, -1, -1, 29,
- 30, 31, 32, 33, 34, -1, 36, -1, -1, -1,
- 40, -1, 42, 43, 44, -1, -1, 47, -1, -1,
- -1, 51, -1, 53, -1, -1, -1, -1, -1, 59,
- -1, 61, -1, -1, -1, 65, 66, 67, 68, 69,
- 70, 71, 72, 73, 74, 75, 76, 77, 78, -1,
- -1, 81, 82, 83, 84, 85, 86, 87, -1, -1,
- -1, -1, -1, -1, 94, 95, 96, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 4, 5, 6, -1,
- -1, 9, 10, 11, 12, 13, 14, -1, 16, -1,
- -1, -1, 20, 21, 22, -1, -1, -1, -1, -1,
- -1, 29, 30, 31, 32, 33, 34, -1, 36, -1,
- -1, -1, 40, -1, 42, 43, 44, -1, -1, 47,
- -1, -1, -1, 51, -1, 53, -1, 55, -1, -1,
- -1, 59, -1, 61, -1, -1, -1, 65, 66, 67,
- 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
- 78, -1, -1, 81, 82, 83, 84, 85, 86, 87,
- -1, -1, -1, -1, -1, -1, 94, 95, 96, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
+ 7, 33, 60, 60, 7, 36, 7, 7, 60, 7,
+ 36, 36, 7, 7, 60, 36, 55, 7, 33, 55,
+ 33, 7, 36, 7, 36, 36, 7, 37, 36, 7,
+ 36, 7, 7, 7, 33, 7, 33, 33, 47, 66,
+ 17, 34, 47, 66, 29, 37, 29, 29, 17, 29,
+ 29, 17, 5, 5, 5, 20, 60, 7, 60, 8,
+ 33, 7, 33, 33, 55, 33, 55, 7, 55, 36,
+ 33, 33, 60, 33, 7, 36, 33, 36, 36, 33,
+ 8, 7, 2, 7, 1, 8, 1, 8, 1, 36,
+ 8, 2, 8, -1, 2, -1, 60, -1, 33, 55,
+ 55, 7, 36, 1, 48, 0, 7, 36, 2, 36,
+ 48, 36, 60, 17, 33, 60, 48, 16, 8, 55,
+ 61, 60, 36, 7, 36, 8, 36, 36, 8, 60,
+ 8, 8, 6, 8, 15, -1, 79, 79, 8, 61,
+ 77, 48, 15, 7, 8, 8, 20, 15, 15, 79,
+ -1, 24, 8, 34, 8, 8, -1, -1, 61, 61,
+ 62, 61, 62, 8, 61, 62, 34, 34, 50, 61,
+ 62, 50, 54, 8, 79, 54, 8, 60, 56, 10,
+ 60, 56, 40, 60, 8, 61, 62, 8, 40, 12,
+ 60, 7, 55, 51, 40, 61, 62, 93, 94, 51,
+ 61, 62, 31, 7, 60, 51, 60, 60, 93, 94,
+ 15, 56, 61, 62, 61, 62, 42, 61, 62, 24,
+ 15, 56, 61, 62, 55, 61, 62, 53, 60, 33,
+ 29, 29, 7, 12, 57, 56, 25, 61, 27, 34,
+ 63, 36, 25, 7, 27, 61, 62, 29, 25, 38,
+ 27, 25, 25, 27, 27, 38, 25, 29, 27, 95,
+ -1, 38, 29, -1, 38, 38, 29, -1, 12, 38,
+ 36, 29, 25, -1, 27, -1, 75, 75, 57, 40,
+ 15, 8, -1, 8, 63, 38, 61, 62, 87, 87,
+ 51, -1, 96, 75, -1, 61, 62, 61, 62, 34,
+ -1, 36, 15, 75, 8, 87, -1, -1, 75, 25,
+ -1, 27, 75, 57, 25, 87, 27, 75, -1, 63,
+ 87, 34, 38, 36, 87, 61, 62, 38, 25, 87,
+ 27, 25, -1, 27, 61, 62, 61, 62, 25, -1,
+ 27, 38, 15, 25, 38, 27, 15, 15, 18, 19,
+ -1, 38, 18, 19, 90, 47, 38, 61, 62, -1,
+ 33, 34, -1, 36, 33, 34, 34, 36, 36, 61,
+ 62, -1, 23, 24, -1, 45, 46, -1, -1, 45,
+ 46, 32, 23, 24, 35, -1, 37, -1, 23, 24,
+ -1, 32, 23, 24, 35, -1, 37, 32, 23, 24,
+ 35, 32, 37, 95, 35, -1, 37, 32, 23, 24,
+ 35, -1, 37, -1, -1, -1, 31, 32, 23, 24,
+ 35, 29, 37, -1, -1, 29, 31, 32, -1, -1,
+ 35, -1, 37, 29, 23, 24, 29, -1, -1, 29,
+ 18, 19, 31, 32, 29, -1, 35, 29, 37, -1,
+ 100, 101, 102, 103, 104, 105, -1, -1, 66, 67,
+ 68, -1, 66, 67, 68, -1, -1, 45, 46, -1,
+ 66, 67, 68, 66, 67, 68, 66, 67, 68, -1,
+ 29, 66, 67, 68, 66, 67, 68, 29, 96, 97,
+ 98, -1, 96, 97, 98, 29, -1, -1, 29, -1,
+ 96, 97, 98, 96, 97, 98, 96, 97, 98, -1,
+ -1, 96, 97, 98, 96, 97, 98, 66, 67, 68,
+ 29, -1, -1, -1, 66, 67, 68, -1, -1, -1,
+ 23, 24, 66, 67, 68, 66, 67, 68, 31, 32,
+ -1, -1, 35, 29, 37, -1, 15, 96, 97, 98,
+ 36, -1, -1, -1, 96, 97, 98, 66, 67, 68,
+ 29, -1, 96, 97, 98, 96, 97, 98, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 15,
+ 66, 67, 68, -1, -1, -1, 15, 96, 97, 98,
+ 15, -1, -1, 29, 15, -1, 29, 66, 67, 68,
+ 29, -1, -1, 36, 29, -1, -1, -1, 29, -1,
+ 96, 97, 98, -1, -1, 29, -1, -1, 29, -1,
+ -1, -1, -1, -1, -1, -1, -1, 96, 97, 98,
+ 66, 67, 68, 66, 67, 68, -1, 66, 67, 68,
+ -1, 66, 67, 68, -1, 66, 67, 68, -1, -1,
+ 61, 62, 66, 67, 68, 66, 67, 68, 29, -1,
+ 96, 97, 98, 96, 97, 98, -1, 96, 97, 98,
+ 29, 96, 97, 98, -1, 96, 97, 98, 29, -1,
+ -1, 29, 96, 97, 98, 96, 97, 98, -1, -1,
+ 61, 62, -1, -1, 29, 66, 67, 68, -1, -1,
+ -1, 36, 61, 62, -1, -1, -1, 66, 67, 68,
+ 61, 62, -1, 61, 62, 66, 67, 68, 66, 67,
+ 68, -1, -1, -1, -1, 96, 97, 98, -1, -1,
+ 3, 66, 67, 68, -1, -1, -1, 96, 97, 98,
+ 13, -1, -1, -1, 17, 96, 97, 98, 96, 97,
+ 98, -1, -1, 26, -1, 28, -1, -1, -1, -1,
+ -1, 96, 97, 98, -1, -1, 39, -1, 41, 42,
+ -1, -1, -1, 29, -1, -1, 49, -1, -1, 52,
+ 53, -1, -1, -1, -1, 58, -1, -1, -1, -1,
+ -1, 64, -1, -1, -1, -1, -1, -1, -1, 3,
+ -1, -1, -1, -1, -1, 61, 62, 80, -1, 13,
+ 66, 67, 68, 17, -1, -1, -1, -1, -1, -1,
+ -1, -1, 26, -1, 28, -1, -1, 31, -1, -1,
+ -1, -1, -1, -1, -1, 39, -1, 41, 42, -1,
+ 96, 97, 98, -1, -1, 49, -1, -1, 52, 53,
+ -1, -1, 3, -1, 58, -1, -1, -1, -1, -1,
+ 64, -1, 13, -1, -1, -1, 17, -1, -1, -1,
+ -1, -1, -1, -1, -1, 26, 80, 28, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 39, -1,
+ 41, 42, -1, -1, -1, -1, -1, -1, 49, -1,
+ -1, 52, 53, -1, -1, -1, -1, 58, -1, -1,
+ -1, -1, -1, 64, -1, 12, 13, -1, -1, -1,
+ -1, -1, -1, -1, -1, 22, -1, -1, -1, 80,
+ -1, -1, 29, -1, -1, -1, 33, 34, -1, 36,
+ -1, -1, -1, -1, -1, -1, 43, -1, -1, -1,
+ 47, -1, -1, -1, -1, -1, -1, 12, 13, -1,
+ -1, -1, -1, -1, -1, -1, -1, 22, 65, 66,
+ 67, 68, -1, 70, 29, -1, -1, -1, 33, 34,
+ -1, 36, -1, -1, 81, 82, 83, -1, 43, -1,
+ -1, 88, 47, -1, -1, -1, -1, -1, -1, 96,
+ 97, 98, -1, -1, -1, -1, -1, -1, -1, -1,
+ 65, 66, 67, 68, -1, 70, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 81, 82, 83, -1,
+ -1, -1, -1, 88, -1, -1, -1, -1, -1, -1,
+ -1, 96, 97, 98, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 12, 13, -1, -1, -1, -1, -1,
+ -1, -1, -1, 22, -1, -1, -1, -1, -1, -1,
+ 29, -1, -1, -1, 33, 34, -1, 36, -1, -1,
+ -1, -1, -1, -1, 43, -1, -1, -1, 47, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 65, 66, 67, 68,
+ -1, 70, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 81, 82, 83, -1, -1, -1, -1, 88,
+ -1, -1, -1, -1, -1, -1, -1, 96, 97, 98,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 12,
+ 13, -1, -1, -1, -1, -1, -1, -1, -1, 22,
+ -1, -1, -1, -1, -1, -1, 29, -1, -1, -1,
+ 33, 34, -1, 36, -1, -1, -1, -1, -1, -1,
+ 43, -1, -1, -1, 47, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 65, 66, 67, 68, -1, 70, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 81, 82,
+ 83, -1, -1, -1, -1, 88, -1, -1, -1, -1,
+ -1, -1, -1, 96, 97, 98, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 10, -1, 12, 13, -1,
+ -1, -1, -1, -1, -1, -1, -1, 22, -1, -1,
+ -1, -1, -1, -1, 29, -1, -1, -1, 33, 34,
+ -1, 36, -1, -1, -1, -1, -1, -1, 43, -1,
+ -1, -1, 47, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 65, 66, 67, 68, -1, 70, -1, -1, -1, -1,
+ 75, -1, -1, -1, -1, -1, 81, 82, 83, 84,
+ 85, -1, -1, 88, -1, -1, 91, -1, -1, -1,
+ -1, 96, 97, 98, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 10, -1, 12, 13, -1, -1, -1,
+ -1, -1, -1, -1, -1, 22, -1, -1, -1, -1,
+ -1, -1, 29, -1, -1, -1, 33, 34, -1, 36,
+ -1, -1, -1, -1, -1, -1, 43, -1, -1, -1,
+ 47, -1, -1, -1, -1, -1, -1, -1, 55, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 65, 66,
+ 67, 68, -1, 70, -1, -1, -1, -1, 75, -1,
+ -1, -1, -1, -1, 81, 82, 83, 84, 85, -1,
+ -1, 88, -1, -1, 91, -1, -1, -1, -1, 96,
+ 97, 98, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 10, -1, 12, 13, -1, -1, -1, -1, -1,
+ -1, -1, -1, 22, -1, -1, -1, -1, -1, -1,
+ 29, -1, -1, -1, 33, 34, -1, 36, -1, -1,
+ -1, -1, -1, -1, 43, -1, -1, -1, 47, -1,
+ -1, -1, -1, -1, -1, -1, 55, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 65, 66, 67, 68,
+ -1, 70, -1, -1, -1, -1, 75, -1, -1, -1,
+ -1, -1, 81, 82, 83, 84, 85, -1, -1, 88,
+ -1, -1, 91, -1, -1, -1, -1, 96, 97, 98,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 11,
+ 12, 13, -1, -1, -1, -1, -1, -1, -1, -1,
+ 22, -1, -1, -1, -1, -1, -1, 29, -1, -1,
+ -1, 33, 34, -1, 36, -1, -1, -1, 40, -1,
+ 42, 43, 44, -1, -1, 47, -1, -1, -1, 51,
+ -1, 53, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 65, 66, 67, 68, -1, 70, -1,
+ 72, -1, 74, -1, 76, -1, -1, -1, -1, 81,
+ 82, 83, -1, -1, -1, -1, 88, -1, -1, -1,
+ -1, -1, -1, -1, 96, 97, 98, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 7, -1, -1, -1,
+ 11, 12, 13, -1, -1, -1, -1, -1, -1, -1,
+ -1, 22, -1, -1, -1, -1, -1, -1, 29, -1,
+ -1, -1, 33, 34, -1, 36, -1, -1, -1, 40,
+ -1, 42, 43, 44, -1, -1, 47, -1, -1, -1,
+ 51, -1, 53, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 65, 66, 67, 68, -1, 70,
+ -1, 72, -1, 74, -1, 76, -1, -1, -1, -1,
+ 81, 82, 83, -1, -1, -1, -1, 88, -1, -1,
+ -1, -1, -1, -1, -1, 96, 97, 98, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 11, 12, 13,
+ -1, -1, -1, -1, -1, -1, -1, -1, 22, -1,
+ -1, -1, -1, -1, -1, 29, -1, -1, -1, 33,
+ 34, -1, 36, -1, -1, -1, 40, -1, 42, 43,
+ 44, -1, -1, 47, -1, -1, -1, 51, -1, 53,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 65, 66, 67, 68, -1, 70, -1, 72, -1,
+ 74, 75, 76, -1, -1, -1, -1, 81, 82, 83,
+ -1, -1, -1, -1, 88, -1, -1, -1, -1, -1,
+ -1, -1, 96, 97, 98, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8, -1, -1, 11, 12, 13,
+ -1, -1, -1, -1, -1, -1, -1, -1, 22, -1,
+ -1, -1, -1, -1, -1, 29, -1, -1, -1, 33,
+ 34, -1, 36, -1, -1, -1, 40, -1, 42, 43,
+ 44, -1, -1, 47, -1, -1, -1, 51, -1, 53,
+ -1, -1, 56, -1, -1, -1, -1, -1, -1, -1,
+ -1, 65, 66, 67, 68, -1, 70, -1, 72, -1,
+ 74, -1, 76, -1, -1, -1, -1, 81, 82, 83,
+ -1, -1, -1, -1, 88, -1, -1, -1, -1, -1,
+ -1, -1, 96, 97, 98, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8, -1, -1, 11, 12, 13,
+ -1, -1, -1, -1, -1, -1, -1, -1, 22, -1,
+ -1, -1, -1, -1, -1, 29, -1, -1, -1, 33,
+ 34, -1, 36, -1, -1, -1, 40, -1, 42, 43,
+ 44, -1, -1, 47, -1, -1, -1, 51, -1, 53,
+ -1, -1, 56, -1, -1, -1, -1, -1, -1, -1,
+ -1, 65, 66, 67, 68, -1, 70, -1, 72, -1,
+ 74, -1, 76, -1, -1, -1, -1, 81, 82, 83,
+ -1, -1, -1, -1, 88, -1, -1, -1, -1, -1,
+ -1, -1, 96, 97, 98, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8, -1, -1, 11, 12, 13,
+ -1, -1, -1, -1, -1, -1, -1, -1, 22, -1,
+ -1, -1, -1, -1, -1, 29, -1, -1, -1, 33,
+ 34, -1, 36, -1, -1, -1, 40, -1, 42, 43,
+ 44, -1, -1, 47, -1, -1, -1, 51, -1, 53,
+ -1, -1, 56, -1, -1, -1, -1, -1, -1, -1,
+ -1, 65, 66, 67, 68, -1, 70, -1, 72, -1,
+ 74, -1, 76, -1, -1, -1, -1, 81, 82, 83,
+ -1, -1, -1, -1, 88, -1, -1, -1, -1, -1,
+ -1, -1, 96, 97, 98, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 8, -1, -1, 11, 12, 13,
+ -1, -1, -1, -1, -1, -1, -1, -1, 22, -1,
+ -1, -1, -1, -1, -1, 29, -1, -1, -1, 33,
+ 34, -1, 36, -1, -1, -1, 40, -1, 42, 43,
+ 44, -1, -1, 47, -1, -1, -1, 51, -1, 53,
+ -1, -1, 56, -1, -1, -1, -1, -1, -1, -1,
+ -1, 65, 66, 67, 68, -1, 70, -1, 72, -1,
+ 74, -1, 76, -1, -1, -1, -1, 81, 82, 83,
+ -1, -1, -1, -1, 88, -1, -1, -1, -1, -1,
+ -1, -1, 96, 97, 98, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 11, 12, 13, -1, -1, -1,
+ -1, -1, -1, -1, -1, 22, -1, -1, -1, -1,
+ -1, -1, 29, 30, -1, -1, 33, 34, -1, 36,
+ -1, -1, -1, 40, -1, 42, 43, 44, -1, -1,
+ 47, -1, -1, -1, 51, -1, 53, -1, -1, -1,
+ -1, -1, -1, -1, 61, -1, -1, -1, 65, 66,
+ 67, 68, 69, 70, -1, 72, 73, 74, -1, 76,
+ -1, 78, -1, -1, 81, 82, 83, -1, -1, -1,
+ -1, 88, -1, -1, -1, -1, -1, -1, -1, 96,
+ 97, 98, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 11, 12, 13, -1, -1, -1, -1, -1, -1,
+ -1, -1, 22, -1, -1, -1, -1, -1, -1, 29,
+ 30, -1, -1, 33, 34, -1, 36, -1, -1, -1,
+ 40, -1, 42, 43, 44, -1, -1, 47, -1, -1,
+ -1, 51, -1, 53, -1, -1, -1, -1, -1, -1,
+ -1, 61, -1, -1, -1, 65, 66, 67, 68, 69,
+ 70, -1, 72, 73, 74, -1, 76, -1, 78, -1,
+ -1, 81, 82, 83, -1, -1, -1, -1, 88, -1,
+ -1, -1, -1, -1, -1, -1, 96, 97, 98, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 11, 12,
+ 13, -1, -1, -1, -1, -1, -1, -1, -1, 22,
+ -1, -1, -1, -1, -1, -1, 29, 30, -1, -1,
+ 33, 34, -1, 36, -1, -1, -1, 40, -1, 42,
+ 43, 44, -1, -1, 47, -1, -1, -1, 51, -1,
+ 53, -1, -1, -1, -1, -1, -1, -1, 61, -1,
+ -1, -1, 65, 66, 67, 68, 69, 70, -1, 72,
+ 73, 74, -1, 76, -1, 78, -1, -1, 81, 82,
+ 83, -1, -1, -1, -1, 88, -1, -1, -1, -1,
+ -1, -1, -1, 96, 97, 98, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 4, 5, 6, -1, -1,
+ 9, 10, 11, -1, -1, 14, -1, 16, -1, -1,
+ -1, 20, 21, 22, -1, -1, -1, -1, -1, -1,
+ 29, 30, 31, 32, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 43, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 59, -1, -1, -1, -1, -1, -1, 66, 67, 68,
+ 69, 70, 71, -1, 73, 74, 75, 76, 77, 78,
+ -1, -1, 81, 82, 83, 84, 85, 86, 87, -1,
+ -1, -1, 91, -1, -1, -1, -1, 96, 97, 98,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 4,
+ 5, 6, -1, -1, 9, 10, 11, -1, -1, 14,
+ -1, 16, -1, -1, -1, 20, 21, 22, -1, -1,
+ -1, -1, -1, -1, 29, 30, 31, 32, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 43, -1,
+ -1, -1, 47, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 59, -1, -1, -1, -1, -1,
+ 65, 66, 67, 68, 69, 70, 71, -1, 73, 74,
+ 75, 76, 77, 78, -1, -1, 81, 82, 83, 84,
+ 85, 86, 87, -1, -1, -1, 91, -1, -1, -1,
+ -1, 96, 97, 98, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 4, 5, 6, -1, -1, 9, 10,
+ 11, -1, -1, 14, -1, 16, -1, -1, -1, 20,
+ 21, 22, -1, -1, -1, -1, -1, -1, 29, 30,
+ 31, 32, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 43, -1, -1, -1, 47, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 59, -1,
+ -1, -1, -1, -1, 65, 66, 67, 68, 69, 70,
+ 71, -1, 73, 74, 75, 76, 77, 78, -1, -1,
+ 81, 82, 83, 84, 85, 86, 87, -1, -1, -1,
+ 91, -1, -1, -1, -1, 96, 97, 98, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 4, 5, 6,
+ -1, -1, 9, 10, 11, -1, -1, 14, -1, 16,
+ -1, -1, -1, 20, 21, 22, -1, -1, -1, -1,
+ -1, -1, 29, 30, 31, 32, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 43, -1, -1, -1,
+ 47, -1, -1, -1, -1, -1, -1, -1, 55, -1,
+ -1, -1, 59, -1, -1, -1, -1, -1, 65, 66,
+ 67, 68, 69, 70, 71, -1, 73, 74, 75, 76,
+ 77, 78, -1, -1, 81, 82, 83, 84, 85, 86,
+ 87, -1, -1, -1, 91, -1, -1, -1, -1, 96,
+ 97, 98, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 4, -1, -1, -1, -1, 9, -1, 11, 12,
+ 13, 14, -1, -1, -1, -1, -1, -1, 21, 22,
+ -1, -1, -1, -1, -1, -1, 29, 30, -1, -1,
+ 33, 34, -1, 36, -1, -1, -1, 40, -1, 42,
+ 43, 44, -1, -1, 47, -1, -1, -1, 51, -1,
+ 53, -1, -1, -1, -1, -1, 59, -1, 61, -1,
+ -1, -1, 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 74, 75, 76, 77, 78, -1, -1, 81, 82,
+ 83, 84, 85, 86, -1, 88, -1, -1, -1, -1,
+ -1, -1, -1, 96, 97, 98, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 4, -1, -1, -1, -1,
+ 9, -1, 11, 12, 13, 14, -1, -1, -1, -1,
+ -1, -1, 21, 22, -1, -1, -1, -1, -1, -1,
+ 29, 30, -1, -1, 33, 34, -1, 36, -1, -1,
+ -1, 40, -1, 42, 43, 44, -1, -1, 47, -1,
+ -1, -1, 51, -1, 53, -1, -1, -1, -1, -1,
+ 59, -1, 61, -1, -1, -1, 65, 66, 67, 68,
+ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ -1, -1, 81, 82, 83, 84, 85, 86, -1, 88,
+ -1, -1, -1, -1, -1, -1, -1, 96, 97, 98,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 4,
+ 5, 6, -1, -1, 9, 10, 11, 12, 13, 14,
+ -1, 16, -1, -1, -1, 20, 21, 22, -1, -1,
+ -1, -1, -1, -1, 29, 30, 31, 32, 33, 34,
+ -1, 36, -1, -1, -1, 40, -1, 42, 43, 44,
+ -1, -1, 47, -1, -1, -1, 51, -1, 53, -1,
+ -1, -1, -1, -1, 59, -1, 61, -1, -1, -1,
+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, -1, -1, 81, 82, 83, 84,
+ 85, 86, 87, 88, -1, -1, 91, -1, -1, -1,
+ -1, 96, 97, 98, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 4, 5, 6, -1, -1, 9, 10,
+ 11, 12, 13, 14, -1, 16, -1, -1, -1, 20,
+ 21, 22, -1, -1, -1, -1, -1, -1, 29, 30,
+ 31, 32, 33, 34, -1, 36, -1, -1, -1, 40,
+ -1, 42, 43, 44, -1, -1, 47, -1, -1, -1,
+ 51, -1, 53, -1, 55, -1, -1, -1, 59, -1,
+ 61, -1, -1, -1, 65, 66, 67, 68, 69, 70,
+ 71, 72, 73, 74, 75, 76, 77, 78, -1, -1,
+ 81, 82, 83, 84, 85, 86, 87, 88, -1, -1,
+ 91, -1, -1, -1, -1, 96, 97, 98, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1,
- 77, 14, 18, 18, 18, 32, 18, 3, 32, 42,
- 9, 3, 3, 18, 42, 3, 18, 18, 3, 22,
- 18, 32, 32, 18, 18, 25, 32, 3, 18, 18,
- 3, 18, 3, 42, 18, 14, 22, 18, 18, 22,
- 22, 18, 100, 18, 18, 42, 18, 3, 105, 42,
- 3, 3, 18, 14, 32, 18, 3, 25, 25, 18,
- 3, 25, 3, 18, 18, 3, 103, 18, 18, 2,
- -1, 3, 42, 42, 18, 14, 25, 42, 14, 2,
- 42, -1, 42, 18, 42, 18, 2, 4, -1, -1,
- 18, -1, -1, 18, -1, 18, -1, 54, -1, 56,
- 44, 18, 18, 18, 18, -1, 54, -1, 54, 54,
- 56, 56, 51, 42, 54, 51, 56, 54, 46, 56,
- 45, 50, 70, 54, 54, 56, 56, 3, 54, 42,
- 45, 18, 46, 59, 54, 54, 54, 50, 2, 59,
- 59, 59, 54, 54, 11, 12, 78, 59, 59, 54,
- 54, 56, 56, 54, 18, 2, 14, 18, 4, 54,
- 54, 56, 56, 54, 54, 23, 3, 68, 58, 60,
- 54, 18, 18, 14, 109, 2, 60, 2, 19, 54,
- 54, 54, 43, 38, 59, 59, 59, 42, 54, 54,
- 56, 18, 54, 18, 59, 54, 2, 59, 54, 58,
- 54, 2, 58, 18, 54, 59, 2, 94, 2, 54,
- 18, 4, 18, 2, 18, 3, 66, 18, 18, 64,
- 3, 54, 18, 56, 18, 18, 54, 2, 56, 18,
- 45, 54, 18, 56, 54, 14, 14, 57, 2, 47,
- 19, 78, 46, 18, 44, 54, 2, 18, 57, 54,
- 2, 54, 2, 56, 18, 60, 54, 54, 56, 56,
- 14, -1, 18, 54, 54, 19, 18, -1, 18, 60,
- 54, 18, 62, 51, 45, 59, -1, 54, -1, -1,
- 54, 54, 59, 67, 54, 59, 59, 54, 2, 59,
- 78, -1, 59, 63, 61, 78, 69, 71, -1, 76,
- 47, 48, -1, 54, 18, 54, 92, -1, 59, 54,
- 59, 54, 61, 54, 59, -1, 59, 54, 59, 54,
- 65, -1, 59, 54, 59, 76, 61, -1, 59, 14,
- 61, 14, 2, 76, 19, 76, 21, 5, 88, 76,
- 23, -1, -1, -1, -1, -1, 14, -1, 18, -1,
- -1, -1, 35, 36, -1, 23, -1, 42, 25, 26,
- 27, 28, 29, 30, 31, -1, 14, 35, 36, -1,
- -1, -1, -1, -1, 88, 23, 24, 25, 26, 27,
- 28, 29, 30, 31, 14, -1, -1, -1, -1, -1,
- -1, -1, -1, 23, 24, 25, 26, 27, 28, 29,
- 30, 31, 14, -1, -1, -1, -1, -1, -1, -1,
- -1, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 5, -1, -1, -1, -1, -1, -1, -1, -1,
- 14, -1, -1, -1, -1, -1, -1, -1, -1, 23,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 35, 36, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1};
+ 18, 18, 32, 18, 32, 18, 3, 43, 18, 25,
+ 22, 22, 14, 14, 78, 18, 9, 3, 18, 3,
+ 18, 3, 18, 32, 18, 32, 32, 22, 18, 18,
+ 22, 3, 3, 18, 106, 43, 3, 18, 18, 101,
+ 3, 3, 18, 18, 18, 104, 3, 3, 18, 18,
+ 18, 3, 18, 18, 18, 43, 3, 3, 3, 32,
+ 14, 3, 3, 3, 25, 25, 25, -1, 55, 18,
+ 57, 2, 55, -1, -1, 2, 55, 60, 3, -1,
+ 18, 60, 18, 18, -1, 43, 25, 18, 43, -1,
+ 43, 18, 43, 43, 18, 43, 11, 12, 14, 43,
+ 43, 4, 3, 19, 18, 18, 3, 14, 3, 45,
+ 18, -1, 18, -1, 2, 18, 23, 2, 55, 2,
+ 57, 55, 55, 57, 57, 55, 55, 57, 57, 55,
+ 18, 57, 45, 18, 55, 18, 57, 2, 46, 2,
+ 2, 47, 2, 55, 55, 55, 55, 57, 60, 60,
+ 55, 60, 57, 18, 79, 18, 18, 55, 18, 55,
+ 95, 57, 60, 14, 2, 2, 55, -1, 55, 18,
+ 14, 55, 61, 55, 61, 19, 60, 59, 79, 55,
+ 18, 18, 79, 59, 79, 55, 55, 55, 14, 55,
+ 60, 60, 60, 18, 60, 2, 110, 55, 47, 55,
+ 43, 52, 60, 59, 18, 55, 2, 57, 51, 55,
+ 55, 18, 39, 55, 55, 18, 43, 4, 2, 55,
+ 65, 67, 18, 2, 18, 61, 52, 2, 69, 71,
+ 2, 18, 46, 55, 18, 57, 55, 4, 57, 18,
+ 55, 44, 57, 18, 55, 55, 18, 58, 58, 18,
+ 43, 18, 46, 55, 14, 57, 55, 18, 51, 19,
+ 2, 2, 61, 55, 55, 57, 55, 55, 93, 57,
+ -1, 60, 63, -1, -1, 55, 18, 18, 47, 68,
+ 60, -1, 55, -1, 64, 46, 18, 60, -1, 62,
+ 55, 55, -1, -1, -1, 60, 60, 62, 62, 55,
+ 55, -1, 55, 55, 60, 60, 62, 60, 60, 55,
+ 55, -1, 55, 66, 60, 60, 48, 60, 55, 55,
+ -1, 14, 77, 60, 60, 77, 19, 72, 21, -1,
+ 14, 77, -1, 70, 77, 5, -1, 5, -1, 23,
+ -1, 77, -1, -1, 14, -1, 14, 89, 89, -1,
+ 43, 35, 36, 23, -1, 23, 25, 26, 27, 28,
+ 29, 30, 31, -1, -1, 35, 36, 35, 36, -1,
+ -1, -1, 14, -1, -1, -1, -1, -1, -1, -1,
+ 18, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 14, -1, -1, -1, -1, -1, -1, -1, -1, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, -1, -1,
+ 48, 49, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 14, -1, -1, -1, -1, -1,
+ -1, -1, -1, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1
+};
QT_END_NAMESPACE
diff --git a/src/qml/parser/qqmljsgrammar_p.h b/src/qml/parser/qqmljsgrammar_p.h
index 050ef6c288..9d028f2191 100644
--- a/src/qml/parser/qqmljsgrammar_p.h
+++ b/src/qml/parser/qqmljsgrammar_p.h
@@ -59,152 +59,154 @@ QT_BEGIN_NAMESPACE
class QQmlJSGrammar
{
public:
- enum VariousConstants {
- EOF_SYMBOL = 0,
- REDUCE_HERE = 105,
- SHIFT_THERE = 104,
- T_AND = 1,
- T_AND_AND = 2,
- T_AND_EQ = 3,
- T_AS = 93,
- T_AUTOMATIC_SEMICOLON = 62,
- T_BREAK = 4,
- T_CASE = 5,
- T_CATCH = 6,
- T_COLON = 7,
- T_COMMA = 8,
- T_COMMENT = 88,
- T_COMPATIBILITY_SEMICOLON = 89,
- T_CONST = 84,
- T_CONTINUE = 9,
- T_DEBUGGER = 85,
- T_DEFAULT = 10,
- T_DELETE = 11,
- T_DIVIDE_ = 12,
- T_DIVIDE_EQ = 13,
- T_DO = 14,
- T_DOT = 15,
- T_ELSE = 16,
- T_EQ = 17,
- T_EQ_EQ = 18,
- T_EQ_EQ_EQ = 19,
- T_ERROR = 97,
- T_FALSE = 83,
- T_FEED_JS_EXPRESSION = 101,
- T_FEED_JS_PROGRAM = 103,
- T_FEED_JS_SOURCE_ELEMENT = 102,
- T_FEED_JS_STATEMENT = 100,
- T_FEED_UI_OBJECT_MEMBER = 99,
- T_FEED_UI_PROGRAM = 98,
- T_FINALLY = 20,
- T_FOR = 21,
- T_FUNCTION = 22,
- T_GE = 23,
- T_GET = 95,
- T_GT = 24,
- T_GT_GT = 25,
- T_GT_GT_EQ = 26,
- T_GT_GT_GT = 27,
- T_GT_GT_GT_EQ = 28,
- T_IDENTIFIER = 29,
- T_IF = 30,
- T_IMPORT = 91,
- T_IN = 31,
- T_INSTANCEOF = 32,
- T_LBRACE = 33,
- T_LBRACKET = 34,
- T_LE = 35,
- T_LPAREN = 36,
- T_LT = 37,
- T_LT_LT = 38,
- T_LT_LT_EQ = 39,
- T_MINUS = 40,
- T_MINUS_EQ = 41,
- T_MINUS_MINUS = 42,
- T_MULTILINE_STRING_LITERAL = 87,
- T_NEW = 43,
- T_NOT = 44,
- T_NOT_EQ = 45,
- T_NOT_EQ_EQ = 46,
- T_NULL = 81,
- T_NUMERIC_LITERAL = 47,
- T_ON = 94,
- T_OR = 48,
- T_OR_EQ = 49,
- T_OR_OR = 50,
- T_PLUS = 51,
- T_PLUS_EQ = 52,
- T_PLUS_PLUS = 53,
- T_PRAGMA = 92,
- T_PROPERTY = 66,
- T_PUBLIC = 90,
- T_QUESTION = 54,
- T_RBRACE = 55,
- T_RBRACKET = 56,
- T_READONLY = 68,
- T_REMAINDER = 57,
- T_REMAINDER_EQ = 58,
- T_RESERVED_WORD = 86,
- T_RETURN = 59,
- T_RPAREN = 60,
- T_SEMICOLON = 61,
- T_SET = 96,
- T_SIGNAL = 67,
- T_STAR = 63,
- T_STAR_EQ = 64,
- T_STRING_LITERAL = 65,
- T_SWITCH = 69,
- T_THIS = 70,
- T_THROW = 71,
- T_TILDE = 72,
- T_TRUE = 82,
- T_TRY = 73,
- T_TYPEOF = 74,
- T_VAR = 75,
- T_VOID = 76,
- T_WHILE = 77,
- T_WITH = 78,
- T_XOR = 79,
- T_XOR_EQ = 80,
-
- ACCEPT_STATE = 674,
- RULE_COUNT = 361,
- STATE_COUNT = 675,
- TERMINAL_COUNT = 106,
- NON_TERMINAL_COUNT = 111,
-
- GOTO_INDEX_OFFSET = 675,
- GOTO_INFO_OFFSET = 3078,
- GOTO_CHECK_OFFSET = 3078
- };
-
- static const char *const spell [];
- static const short lhs [];
- static const short rhs [];
- static const short goto_default [];
- static const short action_default [];
- static const short action_index [];
- static const short action_info [];
- static const short action_check [];
-
- static inline int nt_action (int state, int nt)
- {
- const int yyn = action_index [GOTO_INDEX_OFFSET + state] + nt;
- if (yyn < 0 || action_check [GOTO_CHECK_OFFSET + yyn] != nt)
- return goto_default [nt];
-
- return action_info [GOTO_INFO_OFFSET + yyn];
- }
-
- static inline int t_action (int state, int token)
- {
- const int yyn = action_index [state] + token;
-
- if (yyn < 0 || action_check [yyn] != token)
- return - action_default [state];
-
- return action_info [yyn];
- }
+ enum VariousConstants {
+ EOF_SYMBOL = 0,
+ REDUCE_HERE = 107,
+ SHIFT_THERE = 106,
+ T_AND = 1,
+ T_AND_AND = 2,
+ T_AND_EQ = 3,
+ T_AS = 95,
+ T_AUTOMATIC_SEMICOLON = 62,
+ T_BREAK = 4,
+ T_CASE = 5,
+ T_CATCH = 6,
+ T_COLON = 7,
+ T_COMMA = 8,
+ T_COMMENT = 89,
+ T_COMPATIBILITY_SEMICOLON = 90,
+ T_CONST = 84,
+ T_CONTINUE = 9,
+ T_DEBUGGER = 86,
+ T_DEFAULT = 10,
+ T_DELETE = 11,
+ T_DIVIDE_ = 12,
+ T_DIVIDE_EQ = 13,
+ T_DO = 14,
+ T_DOT = 15,
+ T_ELSE = 16,
+ T_ENUM = 91,
+ T_EQ = 17,
+ T_EQ_EQ = 18,
+ T_EQ_EQ_EQ = 19,
+ T_ERROR = 99,
+ T_FALSE = 83,
+ T_FEED_JS_EXPRESSION = 103,
+ T_FEED_JS_PROGRAM = 105,
+ T_FEED_JS_SOURCE_ELEMENT = 104,
+ T_FEED_JS_STATEMENT = 102,
+ T_FEED_UI_OBJECT_MEMBER = 101,
+ T_FEED_UI_PROGRAM = 100,
+ T_FINALLY = 20,
+ T_FOR = 21,
+ T_FUNCTION = 22,
+ T_GE = 23,
+ T_GET = 97,
+ T_GT = 24,
+ T_GT_GT = 25,
+ T_GT_GT_EQ = 26,
+ T_GT_GT_GT = 27,
+ T_GT_GT_GT_EQ = 28,
+ T_IDENTIFIER = 29,
+ T_IF = 30,
+ T_IMPORT = 93,
+ T_IN = 31,
+ T_INSTANCEOF = 32,
+ T_LBRACE = 33,
+ T_LBRACKET = 34,
+ T_LE = 35,
+ T_LET = 85,
+ T_LPAREN = 36,
+ T_LT = 37,
+ T_LT_LT = 38,
+ T_LT_LT_EQ = 39,
+ T_MINUS = 40,
+ T_MINUS_EQ = 41,
+ T_MINUS_MINUS = 42,
+ T_MULTILINE_STRING_LITERAL = 88,
+ T_NEW = 43,
+ T_NOT = 44,
+ T_NOT_EQ = 45,
+ T_NOT_EQ_EQ = 46,
+ T_NULL = 81,
+ T_NUMERIC_LITERAL = 47,
+ T_ON = 96,
+ T_OR = 48,
+ T_OR_EQ = 49,
+ T_OR_OR = 50,
+ T_PLUS = 51,
+ T_PLUS_EQ = 52,
+ T_PLUS_PLUS = 53,
+ T_PRAGMA = 94,
+ T_PROPERTY = 66,
+ T_PUBLIC = 92,
+ T_QUESTION = 54,
+ T_RBRACE = 55,
+ T_RBRACKET = 56,
+ T_READONLY = 68,
+ T_REMAINDER = 57,
+ T_REMAINDER_EQ = 58,
+ T_RESERVED_WORD = 87,
+ T_RETURN = 59,
+ T_RPAREN = 60,
+ T_SEMICOLON = 61,
+ T_SET = 98,
+ T_SIGNAL = 67,
+ T_STAR = 63,
+ T_STAR_EQ = 64,
+ T_STRING_LITERAL = 65,
+ T_SWITCH = 69,
+ T_THIS = 70,
+ T_THROW = 71,
+ T_TILDE = 72,
+ T_TRUE = 82,
+ T_TRY = 73,
+ T_TYPEOF = 74,
+ T_VAR = 75,
+ T_VOID = 76,
+ T_WHILE = 77,
+ T_WITH = 78,
+ T_XOR = 79,
+ T_XOR_EQ = 80,
+
+ ACCEPT_STATE = 691,
+ RULE_COUNT = 369,
+ STATE_COUNT = 692,
+ TERMINAL_COUNT = 108,
+ NON_TERMINAL_COUNT = 112,
+
+ GOTO_INDEX_OFFSET = 692,
+ GOTO_INFO_OFFSET = 3357,
+ GOTO_CHECK_OFFSET = 3357
+ };
+
+ static const char *const spell[];
+ static const short lhs[];
+ static const short rhs[];
+ static const short goto_default[];
+ static const short action_default[];
+ static const short action_index[];
+ static const short action_info[];
+ static const short action_check[];
+
+ static inline int nt_action (int state, int nt)
+ {
+ const int yyn = action_index [GOTO_INDEX_OFFSET + state] + nt;
+ if (yyn < 0 || action_check [GOTO_CHECK_OFFSET + yyn] != nt)
+ return goto_default [nt];
+
+ return action_info [GOTO_INFO_OFFSET + yyn];
+ }
+
+ static inline int t_action (int state, int token)
+ {
+ const int yyn = action_index [state] + token;
+
+ if (yyn < 0 || action_check [yyn] != token)
+ return - action_default [state];
+
+ return action_info [yyn];
+ }
};
diff --git a/src/qml/parser/qqmljskeywords_p.h b/src/qml/parser/qqmljskeywords_p.h
index 84ebe5f210..20daf545a9 100644
--- a/src/qml/parser/qqmljskeywords_p.h
+++ b/src/qml/parser/qqmljskeywords_p.h
@@ -106,6 +106,13 @@ static inline int classify3(const QChar *s, bool qmlMode) {
}
}
}
+ else if (s[0].unicode() == 'l') {
+ if (s[1].unicode() == 'e') {
+ if (s[2].unicode() == 't') {
+ return int(Lexer::T_LET);
+ }
+ }
+ }
else if (s[0].unicode() == 'n') {
if (s[1].unicode() == 'e') {
if (s[2].unicode() == 'w') {
@@ -174,7 +181,7 @@ static inline int classify4(const QChar *s, bool qmlMode) {
else if (s[1].unicode() == 'n') {
if (s[2].unicode() == 'u') {
if (s[3].unicode() == 'm') {
- return Lexer::T_ENUM;
+ return qmlMode ? int(Lexer::T_ENUM) : int(Lexer::T_RESERVED_WORD);
}
}
}
@@ -278,7 +285,7 @@ static inline int classify5(const QChar *s, bool qmlMode) {
if (s[2].unicode() == 'n') {
if (s[3].unicode() == 's') {
if (s[4].unicode() == 't') {
- return qmlMode ? int(Lexer::T_CONST) : int(Lexer::T_RESERVED_WORD);
+ return int(Lexer::T_CONST);
}
}
}
diff --git a/src/qml/parser/qqmljslexer.cpp b/src/qml/parser/qqmljslexer.cpp
index 53e67fde03..bf56307e39 100644
--- a/src/qml/parser/qqmljslexer.cpp
+++ b/src/qml/parser/qqmljslexer.cpp
@@ -86,6 +86,7 @@ static inline QChar convertUnicode(QChar c1, QChar c2, QChar c3, QChar c4)
Lexer::Lexer(Engine *engine)
: _engine(engine)
, _codePtr(0)
+ , _endPtr(0)
, _lastLinePtr(0)
, _tokenLinePtr(0)
, _tokenStartPtr(0)
@@ -772,7 +773,7 @@ again:
u = QLatin1Char('\0');
break;
}
- // fall through
+ Q_FALLTHROUGH();
case '1':
case '2':
case '3':
diff --git a/src/qml/parser/qqmljslexer_p.h b/src/qml/parser/qqmljslexer_p.h
index af5597b625..11d8081713 100644
--- a/src/qml/parser/qqmljslexer_p.h
+++ b/src/qml/parser/qqmljslexer_p.h
@@ -99,7 +99,6 @@ public:
T_CHAR = T_RESERVED_WORD,
T_CLASS = T_RESERVED_WORD,
T_DOUBLE = T_RESERVED_WORD,
- T_ENUM = T_RESERVED_WORD,
T_EXPORT = T_RESERVED_WORD,
T_EXTENDS = T_RESERVED_WORD,
T_FINAL = T_RESERVED_WORD,
diff --git a/src/qml/parser/qqmljsparser.cpp b/src/qml/parser/qqmljsparser.cpp
index 50518a92ee..df16a24bcc 100644
--- a/src/qml/parser/qqmljsparser.cpp
+++ b/src/qml/parser/qqmljsparser.cpp
@@ -92,6 +92,7 @@ Parser::Parser(Engine *engine):
location_stack(0),
string_stack(0),
program(0),
+ yylval(0),
first_token(0),
last_token(0)
{
@@ -656,49 +657,87 @@ case 75: {
sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node);
} break;
-case 83: {
+case 76: {
+ AST::UiEnumDeclaration *enumDeclaration = new (pool) AST::UiEnumDeclaration(stringRef(2), sym(4).UiEnumMemberList->finish());
+ enumDeclaration->enumToken = loc(1);
+ enumDeclaration->rbraceToken = loc(5);
+ sym(1).Node = enumDeclaration;
+ break;
+}
+
+case 77: {
+ AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(stringRef(1));
+ node->memberToken = loc(1);
+ sym(1).Node = node;
+ break;
+}
+
+case 78: {
+ AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(stringRef(1), sym(3).dval);
+ node->memberToken = loc(1);
+ node->valueToken = loc(3);
+ sym(1).Node = node;
+ break;
+}
+
+case 79: {
+ AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(sym(1).UiEnumMemberList, stringRef(3));
+ node->memberToken = loc(3);
+ sym(1).Node = node;
+ break;
+}
+
+case 80: {
+ AST::UiEnumMemberList *node = new (pool) AST::UiEnumMemberList(sym(1).UiEnumMemberList, stringRef(3), sym(5).dval);
+ node->memberToken = loc(3);
+ node->valueToken = loc(5);
+ sym(1).Node = node;
+ break;
+}
+
+case 88: {
AST::ThisExpression *node = new (pool) AST::ThisExpression();
node->thisToken = loc(1);
sym(1).Node = node;
} break;
-case 84: {
+case 89: {
AST::IdentifierExpression *node = new (pool) AST::IdentifierExpression(stringRef(1));
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
-case 85: {
+case 90: {
AST::NullExpression *node = new (pool) AST::NullExpression();
node->nullToken = loc(1);
sym(1).Node = node;
} break;
-case 86: {
+case 91: {
AST::TrueLiteral *node = new (pool) AST::TrueLiteral();
node->trueToken = loc(1);
sym(1).Node = node;
} break;
-case 87: {
+case 92: {
AST::FalseLiteral *node = new (pool) AST::FalseLiteral();
node->falseToken = loc(1);
sym(1).Node = node;
} break;
-case 88: {
+case 93: {
AST::NumericLiteral *node = new (pool) AST::NumericLiteral(sym(1).dval);
node->literalToken = loc(1);
sym(1).Node = node;
} break;
-case 89:
-case 90: {
+case 94:
+case 95: {
AST::StringLiteral *node = new (pool) AST::StringLiteral(stringRef(1));
node->literalToken = loc(1);
sym(1).Node = node;
} break;
-case 91: {
+case 96: {
bool rx = lexer->scanRegExp(Lexer::NoPrefix);
if (!rx) {
diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage()));
@@ -714,7 +753,7 @@ case 91: {
sym(1).Node = node;
} break;
-case 92: {
+case 97: {
bool rx = lexer->scanRegExp(Lexer::EqualPrefix);
if (!rx) {
diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage()));
@@ -730,28 +769,28 @@ case 92: {
sym(1).Node = node;
} break;
-case 93: {
+case 98: {
AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral((AST::Elision *) 0);
node->lbracketToken = loc(1);
node->rbracketToken = loc(2);
sym(1).Node = node;
} break;
-case 94: {
+case 99: {
AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).Elision->finish());
node->lbracketToken = loc(1);
node->rbracketToken = loc(3);
sym(1).Node = node;
} break;
-case 95: {
+case 100: {
AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish ());
node->lbracketToken = loc(1);
node->rbracketToken = loc(3);
sym(1).Node = node;
} break;
-case 96: {
+case 101: {
AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (),
(AST::Elision *) 0);
node->lbracketToken = loc(1);
@@ -760,7 +799,7 @@ case 96: {
sym(1).Node = node;
} break;
-case 97: {
+case 102: {
AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (),
sym(4).Elision->finish());
node->lbracketToken = loc(1);
@@ -769,7 +808,7 @@ case 97: {
sym(1).Node = node;
} break;
-case 98: {
+case 103: {
AST::ObjectLiteral *node = 0;
if (sym(2).Node)
node = new (pool) AST::ObjectLiteral(
@@ -781,7 +820,7 @@ case 98: {
sym(1).Node = node;
} break;
-case 99: {
+case 104: {
AST::ObjectLiteral *node = new (pool) AST::ObjectLiteral(
sym(2).PropertyAssignmentList->finish ());
node->lbraceToken = loc(1);
@@ -789,14 +828,14 @@ case 99: {
sym(1).Node = node;
} break;
-case 100: {
+case 105: {
AST::NestedExpression *node = new (pool) AST::NestedExpression(sym(2).Expression);
node->lparenToken = loc(1);
node->rparenToken = loc(3);
sym(1).Node = node;
} break;
-case 101: {
+case 106: {
if (AST::ArrayMemberExpression *mem = AST::cast<AST::ArrayMemberExpression *>(sym(1).Expression)) {
diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Warning, mem->lbracketToken,
QLatin1String("Ignored annotation")));
@@ -816,48 +855,48 @@ case 101: {
}
} break;
-case 102: {
+case 107: {
sym(1).Node = new (pool) AST::ElementList((AST::Elision *) 0, sym(1).Expression);
} break;
-case 103: {
+case 108: {
sym(1).Node = new (pool) AST::ElementList(sym(1).Elision->finish(), sym(2).Expression);
} break;
-case 104: {
+case 109: {
AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList,
(AST::Elision *) 0, sym(3).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 105: {
+case 110: {
AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList, sym(3).Elision->finish(),
sym(4).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 106: {
+case 111: {
AST::Elision *node = new (pool) AST::Elision();
node->commaToken = loc(1);
sym(1).Node = node;
} break;
-case 107: {
+case 112: {
AST::Elision *node = new (pool) AST::Elision(sym(1).Elision);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 108: {
+case 113: {
AST::PropertyNameAndValue *node = new (pool) AST::PropertyNameAndValue(
sym(1).PropertyName, sym(3).Expression);
node->colonToken = loc(2);
sym(1).Node = node;
} break;
-case 109: {
+case 114: {
AST::PropertyGetterSetter *node = new (pool) AST::PropertyGetterSetter(
sym(2).PropertyName, sym(6).FunctionBody);
node->getSetToken = loc(1);
@@ -868,7 +907,7 @@ case 109: {
sym(1).Node = node;
} break;
-case 110: {
+case 115: {
AST::PropertyGetterSetter *node = new (pool) AST::PropertyGetterSetter(
sym(2).PropertyName, sym(4).FormalParameterList, sym(7).FunctionBody);
node->getSetToken = loc(1);
@@ -879,56 +918,56 @@ case 110: {
sym(1).Node = node;
} break;
-case 111: {
+case 116: {
sym(1).Node = new (pool) AST::PropertyAssignmentList(sym(1).PropertyAssignment);
} break;
-case 112: {
+case 117: {
AST::PropertyAssignmentList *node = new (pool) AST::PropertyAssignmentList(
sym(1).PropertyAssignmentList, sym(3).PropertyAssignment);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 113: {
+case 118: {
AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
-case 114: {
+case 119: {
AST::StringLiteralPropertyName *node = new (pool) AST::StringLiteralPropertyName(stringRef(1));
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
-case 115: {
+case 120: {
AST::NumericLiteralPropertyName *node = new (pool) AST::NumericLiteralPropertyName(sym(1).dval);
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
-case 116: {
+case 121: {
AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1));
node->propertyNameToken = loc(1);
sym(1).Node = node;
} break;
-case 152: {
+case 159: {
AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression);
node->lbracketToken = loc(2);
node->rbracketToken = loc(4);
sym(1).Node = node;
} break;
-case 153: {
+case 160: {
AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3));
node->dotToken = loc(2);
node->identifierToken = loc(3);
sym(1).Node = node;
} break;
-case 154: {
+case 161: {
AST::NewMemberExpression *node = new (pool) AST::NewMemberExpression(sym(2).Expression, sym(4).ArgumentList);
node->newToken = loc(1);
node->lparenToken = loc(3);
@@ -936,384 +975,384 @@ case 154: {
sym(1).Node = node;
} break;
-case 156: {
+case 163: {
AST::NewExpression *node = new (pool) AST::NewExpression(sym(2).Expression);
node->newToken = loc(1);
sym(1).Node = node;
} break;
-case 157: {
+case 164: {
AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList);
node->lparenToken = loc(2);
node->rparenToken = loc(4);
sym(1).Node = node;
} break;
-case 158: {
+case 165: {
AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList);
node->lparenToken = loc(2);
node->rparenToken = loc(4);
sym(1).Node = node;
} break;
-case 159: {
+case 166: {
AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression);
node->lbracketToken = loc(2);
node->rbracketToken = loc(4);
sym(1).Node = node;
} break;
-case 160: {
+case 167: {
AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3));
node->dotToken = loc(2);
node->identifierToken = loc(3);
sym(1).Node = node;
} break;
-case 161: {
+case 168: {
sym(1).Node = 0;
} break;
-case 162: {
+case 169: {
sym(1).Node = sym(1).ArgumentList->finish();
} break;
-case 163: {
+case 170: {
sym(1).Node = new (pool) AST::ArgumentList(sym(1).Expression);
} break;
-case 164: {
+case 171: {
AST::ArgumentList *node = new (pool) AST::ArgumentList(sym(1).ArgumentList, sym(3).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 168: {
+case 175: {
AST::PostIncrementExpression *node = new (pool) AST::PostIncrementExpression(sym(1).Expression);
node->incrementToken = loc(2);
sym(1).Node = node;
} break;
-case 169: {
+case 176: {
AST::PostDecrementExpression *node = new (pool) AST::PostDecrementExpression(sym(1).Expression);
node->decrementToken = loc(2);
sym(1).Node = node;
} break;
-case 171: {
+case 178: {
AST::DeleteExpression *node = new (pool) AST::DeleteExpression(sym(2).Expression);
node->deleteToken = loc(1);
sym(1).Node = node;
} break;
-case 172: {
+case 179: {
AST::VoidExpression *node = new (pool) AST::VoidExpression(sym(2).Expression);
node->voidToken = loc(1);
sym(1).Node = node;
} break;
-case 173: {
+case 180: {
AST::TypeOfExpression *node = new (pool) AST::TypeOfExpression(sym(2).Expression);
node->typeofToken = loc(1);
sym(1).Node = node;
} break;
-case 174: {
+case 181: {
AST::PreIncrementExpression *node = new (pool) AST::PreIncrementExpression(sym(2).Expression);
node->incrementToken = loc(1);
sym(1).Node = node;
} break;
-case 175: {
+case 182: {
AST::PreDecrementExpression *node = new (pool) AST::PreDecrementExpression(sym(2).Expression);
node->decrementToken = loc(1);
sym(1).Node = node;
} break;
-case 176: {
+case 183: {
AST::UnaryPlusExpression *node = new (pool) AST::UnaryPlusExpression(sym(2).Expression);
node->plusToken = loc(1);
sym(1).Node = node;
} break;
-case 177: {
+case 184: {
AST::UnaryMinusExpression *node = new (pool) AST::UnaryMinusExpression(sym(2).Expression);
node->minusToken = loc(1);
sym(1).Node = node;
} break;
-case 178: {
+case 185: {
AST::TildeExpression *node = new (pool) AST::TildeExpression(sym(2).Expression);
node->tildeToken = loc(1);
sym(1).Node = node;
} break;
-case 179: {
+case 186: {
AST::NotExpression *node = new (pool) AST::NotExpression(sym(2).Expression);
node->notToken = loc(1);
sym(1).Node = node;
} break;
-case 181: {
+case 188: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Mul, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 182: {
+case 189: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Div, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 183: {
+case 190: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Mod, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 185: {
+case 192: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Add, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 186: {
+case 193: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Sub, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 188: {
+case 195: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::LShift, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 189: {
+case 196: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::RShift, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 190: {
+case 197: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::URShift, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 192: {
+case 199: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Lt, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 193: {
+case 200: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Gt, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 194: {
+case 201: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Le, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 195: {
+case 202: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Ge, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 196: {
+case 203: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::InstanceOf, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 197: {
+case 204: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::In, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 199: {
+case 206: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Lt, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 200: {
+case 207: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Gt, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 201: {
+case 208: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Le, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 202: {
+case 209: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Ge, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 203: {
+case 210: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::InstanceOf, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 205: {
+case 212: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Equal, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 206: {
+case 213: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::NotEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 207: {
+case 214: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::StrictEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 208: {
+case 215: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::StrictNotEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 210: {
+case 217: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Equal, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 211: {
+case 218: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::NotEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 212: {
+case 219: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::StrictEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 213: {
+case 220: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::StrictNotEqual, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 215: {
+case 222: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitAnd, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 217: {
+case 224: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitAnd, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 219: {
+case 226: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitXor, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 221: {
+case 228: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitXor, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 223: {
+case 230: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitOr, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 225: {
+case 232: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::BitOr, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 227: {
+case 234: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::And, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 229: {
+case 236: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::And, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 231: {
+case 238: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Or, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 233: {
+case 240: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
QSOperator::Or, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 235: {
+case 242: {
AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression,
sym(3).Expression, sym(5).Expression);
node->questionToken = loc(2);
@@ -1321,7 +1360,7 @@ case 235: {
sym(1).Node = node;
} break;
-case 237: {
+case 244: {
AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression,
sym(3).Expression, sym(5).Expression);
node->questionToken = loc(2);
@@ -1329,189 +1368,200 @@ case 237: {
sym(1).Node = node;
} break;
-case 239: {
+case 246: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
sym(2).ival, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 241: {
+case 248: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression,
sym(2).ival, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
-case 242: {
+case 249: {
sym(1).ival = QSOperator::Assign;
} break;
-case 243: {
+case 250: {
sym(1).ival = QSOperator::InplaceMul;
} break;
-case 244: {
+case 251: {
sym(1).ival = QSOperator::InplaceDiv;
} break;
-case 245: {
+case 252: {
sym(1).ival = QSOperator::InplaceMod;
} break;
-case 246: {
+case 253: {
sym(1).ival = QSOperator::InplaceAdd;
} break;
-case 247: {
+case 254: {
sym(1).ival = QSOperator::InplaceSub;
} break;
-case 248: {
+case 255: {
sym(1).ival = QSOperator::InplaceLeftShift;
} break;
-case 249: {
+case 256: {
sym(1).ival = QSOperator::InplaceRightShift;
} break;
-case 250: {
+case 257: {
sym(1).ival = QSOperator::InplaceURightShift;
} break;
-case 251: {
+case 258: {
sym(1).ival = QSOperator::InplaceAnd;
} break;
-case 252: {
+case 259: {
sym(1).ival = QSOperator::InplaceXor;
} break;
-case 253: {
+case 260: {
sym(1).ival = QSOperator::InplaceOr;
} break;
-case 255: {
+case 262: {
AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 256: {
+case 263: {
sym(1).Node = 0;
} break;
-case 259: {
+case 266: {
AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 260: {
+case 267: {
sym(1).Node = 0;
} break;
-case 277: {
+case 284: {
AST::Block *node = new (pool) AST::Block(sym(2).StatementList);
node->lbraceToken = loc(1);
node->rbraceToken = loc(3);
sym(1).Node = node;
} break;
-case 278: {
+case 285: {
sym(1).Node = new (pool) AST::StatementList(sym(1).Statement);
} break;
-case 279: {
+case 286: {
sym(1).Node = new (pool) AST::StatementList(sym(1).StatementList, sym(2).Statement);
} break;
-case 280: {
+case 287: {
sym(1).Node = 0;
} break;
-case 281: {
+case 288: {
sym(1).Node = sym(1).StatementList->finish ();
} break;
-case 283: {
- AST::VariableStatement *node = new (pool) AST::VariableStatement(
- sym(2).VariableDeclarationList->finish (/*readOnly=*/sym(1).ival == T_CONST));
+case 290: {
+ AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope;
+ if (sym(1).ival == T_LET)
+ s = AST::VariableDeclaration::BlockScope;
+ else if (sym(1).ival == T_CONST)
+ s = AST::VariableDeclaration::ReadOnlyBlockScope;
+
+ AST::VariableStatement *node = new (pool) AST::VariableStatement(sym(2).VariableDeclarationList->finish(s));
node->declarationKindToken = loc(1);
node->semicolonToken = loc(3);
sym(1).Node = node;
} break;
-case 284: {
+case 291: {
+ sym(1).ival = T_LET;
+} break;
+
+case 292: {
sym(1).ival = T_CONST;
} break;
-case 285: {
+case 293: {
sym(1).ival = T_VAR;
} break;
-case 286: {
+case 294: {
sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclaration);
} break;
-case 287: {
+case 295: {
AST::VariableDeclarationList *node = new (pool) AST::VariableDeclarationList(
sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
node->commaToken = loc(2);
sym(1).Node = node;
} break;
-case 288: {
+case 296: {
sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclaration);
} break;
-case 289: {
+case 297: {
sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclarationList, sym(3).VariableDeclaration);
} break;
-case 290: {
- AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression);
+case 298: {
+ AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope;
+ AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression, s);
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
-case 291: {
- AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression);
+case 299: {
+ AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope;
+ AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression, s);
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
-case 292: {
+case 300: {
// ### TODO: AST for initializer
sym(1) = sym(2);
} break;
-case 293: {
+case 301: {
sym(1).Node = 0;
} break;
-case 295: {
+case 303: {
// ### TODO: AST for initializer
sym(1) = sym(2);
} break;
-case 296: {
+case 304: {
sym(1).Node = 0;
} break;
-case 298: {
+case 306: {
AST::EmptyStatement *node = new (pool) AST::EmptyStatement();
node->semicolonToken = loc(1);
sym(1).Node = node;
} break;
-case 300: {
+case 308: {
AST::ExpressionStatement *node = new (pool) AST::ExpressionStatement(sym(1).Expression);
node->semicolonToken = loc(2);
sym(1).Node = node;
} break;
-case 301: {
+case 309: {
AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement, sym(7).Statement);
node->ifToken = loc(1);
node->lparenToken = loc(2);
@@ -1520,7 +1570,7 @@ case 301: {
sym(1).Node = node;
} break;
-case 302: {
+case 310: {
AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement);
node->ifToken = loc(1);
node->lparenToken = loc(2);
@@ -1528,7 +1578,7 @@ case 302: {
sym(1).Node = node;
} break;
-case 305: {
+case 313: {
AST::DoWhileStatement *node = new (pool) AST::DoWhileStatement(sym(2).Statement, sym(5).Expression);
node->doToken = loc(1);
node->whileToken = loc(3);
@@ -1538,7 +1588,7 @@ case 305: {
sym(1).Node = node;
} break;
-case 306: {
+case 314: {
AST::WhileStatement *node = new (pool) AST::WhileStatement(sym(3).Expression, sym(5).Statement);
node->whileToken = loc(1);
node->lparenToken = loc(2);
@@ -1546,7 +1596,7 @@ case 306: {
sym(1).Node = node;
} break;
-case 307: {
+case 315: {
AST::ForStatement *node = new (pool) AST::ForStatement(sym(3).Expression,
sym(5).Expression, sym(7).Expression, sym(9).Statement);
node->forToken = loc(1);
@@ -1557,9 +1607,10 @@ case 307: {
sym(1).Node = node;
} break;
-case 308: {
+case 316: {
+ AST::VariableDeclaration::VariableScope s = AST::VariableDeclaration::FunctionScope;
AST::LocalForStatement *node = new (pool) AST::LocalForStatement(
- sym(4).VariableDeclarationList->finish (/*readOnly=*/false), sym(6).Expression,
+ sym(4).VariableDeclarationList->finish(s), sym(6).Expression,
sym(8).Expression, sym(10).Statement);
node->forToken = loc(1);
node->lparenToken = loc(2);
@@ -1570,7 +1621,7 @@ case 308: {
sym(1).Node = node;
} break;
-case 309: {
+case 317: {
AST:: ForEachStatement *node = new (pool) AST::ForEachStatement(sym(3).Expression,
sym(5).Expression, sym(7).Statement);
node->forToken = loc(1);
@@ -1580,7 +1631,7 @@ case 309: {
sym(1).Node = node;
} break;
-case 310: {
+case 318: {
AST::LocalForEachStatement *node = new (pool) AST::LocalForEachStatement(
sym(4).VariableDeclaration, sym(6).Expression, sym(8).Statement);
node->forToken = loc(1);
@@ -1591,14 +1642,14 @@ case 310: {
sym(1).Node = node;
} break;
-case 312: {
+case 320: {
AST::ContinueStatement *node = new (pool) AST::ContinueStatement();
node->continueToken = loc(1);
node->semicolonToken = loc(2);
sym(1).Node = node;
} break;
-case 314: {
+case 322: {
AST::ContinueStatement *node = new (pool) AST::ContinueStatement(stringRef(2));
node->continueToken = loc(1);
node->identifierToken = loc(2);
@@ -1606,14 +1657,14 @@ case 314: {
sym(1).Node = node;
} break;
-case 316: {
+case 324: {
AST::BreakStatement *node = new (pool) AST::BreakStatement(QStringRef());
node->breakToken = loc(1);
node->semicolonToken = loc(2);
sym(1).Node = node;
} break;
-case 318: {
+case 326: {
AST::BreakStatement *node = new (pool) AST::BreakStatement(stringRef(2));
node->breakToken = loc(1);
node->identifierToken = loc(2);
@@ -1621,14 +1672,14 @@ case 318: {
sym(1).Node = node;
} break;
-case 320: {
+case 328: {
AST::ReturnStatement *node = new (pool) AST::ReturnStatement(sym(2).Expression);
node->returnToken = loc(1);
node->semicolonToken = loc(3);
sym(1).Node = node;
} break;
-case 321: {
+case 329: {
AST::WithStatement *node = new (pool) AST::WithStatement(sym(3).Expression, sym(5).Statement);
node->withToken = loc(1);
node->lparenToken = loc(2);
@@ -1636,7 +1687,7 @@ case 321: {
sym(1).Node = node;
} break;
-case 322: {
+case 330: {
AST::SwitchStatement *node = new (pool) AST::SwitchStatement(sym(3).Expression, sym(5).CaseBlock);
node->switchToken = loc(1);
node->lparenToken = loc(2);
@@ -1644,83 +1695,83 @@ case 322: {
sym(1).Node = node;
} break;
-case 323: {
+case 331: {
AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses);
node->lbraceToken = loc(1);
node->rbraceToken = loc(3);
sym(1).Node = node;
} break;
-case 324: {
+case 332: {
AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses, sym(3).DefaultClause, sym(4).CaseClauses);
node->lbraceToken = loc(1);
node->rbraceToken = loc(5);
sym(1).Node = node;
} break;
-case 325: {
+case 333: {
sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClause);
} break;
-case 326: {
+case 334: {
sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClauses, sym(2).CaseClause);
} break;
-case 327: {
+case 335: {
sym(1).Node = 0;
} break;
-case 328: {
+case 336: {
sym(1).Node = sym(1).CaseClauses->finish ();
} break;
-case 329: {
+case 337: {
AST::CaseClause *node = new (pool) AST::CaseClause(sym(2).Expression, sym(4).StatementList);
node->caseToken = loc(1);
node->colonToken = loc(3);
sym(1).Node = node;
} break;
-case 330: {
+case 338: {
AST::DefaultClause *node = new (pool) AST::DefaultClause(sym(3).StatementList);
node->defaultToken = loc(1);
node->colonToken = loc(2);
sym(1).Node = node;
} break;
-case 331: {
+case 339: {
AST::LabelledStatement *node = new (pool) AST::LabelledStatement(stringRef(1), sym(3).Statement);
node->identifierToken = loc(1);
node->colonToken = loc(2);
sym(1).Node = node;
} break;
-case 333: {
+case 341: {
AST::ThrowStatement *node = new (pool) AST::ThrowStatement(sym(2).Expression);
node->throwToken = loc(1);
node->semicolonToken = loc(3);
sym(1).Node = node;
} break;
-case 334: {
+case 342: {
AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch);
node->tryToken = loc(1);
sym(1).Node = node;
} break;
-case 335: {
+case 343: {
AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Finally);
node->tryToken = loc(1);
sym(1).Node = node;
} break;
-case 336: {
+case 344: {
AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch, sym(4).Finally);
node->tryToken = loc(1);
sym(1).Node = node;
} break;
-case 337: {
+case 345: {
AST::Catch *node = new (pool) AST::Catch(stringRef(3), sym(5).Block);
node->catchToken = loc(1);
node->lparenToken = loc(2);
@@ -1729,20 +1780,20 @@ case 337: {
sym(1).Node = node;
} break;
-case 338: {
+case 346: {
AST::Finally *node = new (pool) AST::Finally(sym(2).Block);
node->finallyToken = loc(1);
sym(1).Node = node;
} break;
-case 340: {
+case 348: {
AST::DebuggerStatement *node = new (pool) AST::DebuggerStatement();
node->debuggerToken = loc(1);
node->semicolonToken = loc(2);
sym(1).Node = node;
} break;
-case 342: {
+case 350: {
AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody);
node->functionToken = loc(1);
node->identifierToken = loc(2);
@@ -1753,7 +1804,7 @@ case 342: {
sym(1).Node = node;
} break;
-case 343: {
+case 351: {
AST::FunctionExpression *node = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody);
node->functionToken = loc(1);
if (! stringRef(2).isNull())
@@ -1765,7 +1816,7 @@ case 343: {
sym(1).Node = node;
} break;
-case 344: {
+case 352: {
AST::FunctionExpression *node = new (pool) AST::FunctionExpression(QStringRef(), sym(3).FormalParameterList, sym(6).FunctionBody);
node->functionToken = loc(1);
node->lparenToken = loc(2);
@@ -1775,56 +1826,56 @@ case 344: {
sym(1).Node = node;
} break;
-case 345: {
+case 353: {
AST::FormalParameterList *node = new (pool) AST::FormalParameterList(stringRef(1));
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
-case 346: {
+case 354: {
AST::FormalParameterList *node = new (pool) AST::FormalParameterList(sym(1).FormalParameterList, stringRef(3));
node->commaToken = loc(2);
node->identifierToken = loc(3);
sym(1).Node = node;
} break;
-case 347: {
+case 355: {
sym(1).Node = 0;
} break;
-case 348: {
+case 356: {
sym(1).Node = sym(1).FormalParameterList->finish ();
} break;
-case 349: {
+case 357: {
sym(1).Node = 0;
} break;
-case 351: {
+case 359: {
sym(1).Node = new (pool) AST::FunctionBody(sym(1).SourceElements->finish ());
} break;
-case 353: {
+case 361: {
sym(1).Node = new (pool) AST::Program(sym(1).SourceElements->finish ());
} break;
-case 354: {
+case 362: {
sym(1).Node = new (pool) AST::SourceElements(sym(1).SourceElement);
} break;
-case 355: {
+case 363: {
sym(1).Node = new (pool) AST::SourceElements(sym(1).SourceElements, sym(2).SourceElement);
} break;
-case 356: {
+case 364: {
sym(1).Node = new (pool) AST::StatementSourceElement(sym(1).Statement);
} break;
-case 357: {
+case 365: {
sym(1).Node = new (pool) AST::FunctionSourceElement(sym(1).FunctionDeclaration);
} break;
-case 358: {
+case 366: {
sym(1).Node = 0;
} break;
diff --git a/src/qml/parser/qqmljsparser_p.h b/src/qml/parser/qqmljsparser_p.h
index f382cd7563..9dfee70f3a 100644
--- a/src/qml/parser/qqmljsparser_p.h
+++ b/src/qml/parser/qqmljsparser_p.h
@@ -125,6 +125,7 @@ public:
AST::UiArrayMemberList *UiArrayMemberList;
AST::UiQualifiedId *UiQualifiedId;
AST::UiQualifiedPragmaId *UiQualifiedPragmaId;
+ AST::UiEnumMemberList *UiEnumMemberList;
};
public:
@@ -246,9 +247,9 @@ protected:
-#define J_SCRIPT_REGEXPLITERAL_RULE1 91
+#define J_SCRIPT_REGEXPLITERAL_RULE1 96
-#define J_SCRIPT_REGEXPLITERAL_RULE2 92
+#define J_SCRIPT_REGEXPLITERAL_RULE2 97
QT_QML_END_NAMESPACE
diff --git a/src/qml/qml.pro b/src/qml/qml.pro
index e9d7dcbd2d..acaff08a29 100644
--- a/src/qml/qml.pro
+++ b/src/qml/qml.pro
@@ -6,7 +6,7 @@ qtConfig(qml-network): \
DEFINES += QT_NO_URL_CAST_FROM_STRING QT_NO_INTEGER_EVENT_COORDINATES
-win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x66000000
+msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x66000000
win32-msvc*:DEFINES *= _CRT_SECURE_NO_WARNINGS
win32:!winrt:LIBS += -lshell32
solaris-cc*:QMAKE_CXXFLAGS_RELEASE -= -O2
@@ -57,14 +57,16 @@ include(memory/memory.pri)
include(parser/parser.pri)
include(compiler/compiler.pri)
include(jsapi/jsapi.pri)
-include(jit/jit.pri)
include(jsruntime/jsruntime.pri)
+include(jit/jit.pri)
include(qml/qml.pri)
include(debugger/debugger.pri)
qtConfig(animation) {
include(animations/animations.pri)
}
include(types/types.pri)
+include(../3rdparty/masm/masm-defs.pri)
+include(../3rdparty/masm/masm.pri)
MODULE_PLUGIN_TYPES = \
qmltooling
diff --git a/src/qml/qml/ftw/qhashedstring_p.h b/src/qml/qml/ftw/qhashedstring_p.h
index 9ee50ec931..956805d696 100644
--- a/src/qml/qml/ftw/qhashedstring_p.h
+++ b/src/qml/qml/ftw/qhashedstring_p.h
@@ -1311,12 +1311,12 @@ bool QHashedString::compare(const char *lhs, const char *rhs, int length)
quint32 QHashedString::stringHash(const QChar *data, int length)
{
- return QV4::String::createHashValue(data, length, Q_NULLPTR);
+ return QV4::String::createHashValue(data, length, nullptr);
}
quint32 QHashedString::stringHash(const char *data, int length)
{
- return QV4::String::createHashValue(data, length, Q_NULLPTR);
+ return QV4::String::createHashValue(data, length, nullptr);
}
void QHashedString::computeHash() const
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h
index ddb4af0b81..219df264be 100644
--- a/src/qml/qml/qqml.h
+++ b/src/qml/qml/qqml.h
@@ -112,10 +112,10 @@ int qmlRegisterType()
qRegisterNormalizedMetaType<T *>(pointerName.constData()),
qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
0,
- Q_NULLPTR,
+ nullptr,
QString(),
- Q_NULLPTR, 0, 0, Q_NULLPTR, &T::staticMetaObject,
+ nullptr, 0, 0, nullptr, &T::staticMetaObject,
QQmlPrivate::attachedPropertiesFunc<T>(),
QQmlPrivate::attachedPropertiesMetaObject<T>(),
@@ -124,9 +124,9 @@ int qmlRegisterType()
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
- Q_NULLPTR, Q_NULLPTR,
+ nullptr, nullptr,
- Q_NULLPTR,
+ nullptr,
0
};
@@ -146,7 +146,7 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin
qRegisterNormalizedMetaType<T *>(pointerName.constData()),
qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
0,
- Q_NULLPTR,
+ nullptr,
reason,
uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
@@ -158,9 +158,9 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
- Q_NULLPTR, Q_NULLPTR,
+ nullptr, nullptr,
- Q_NULLPTR,
+ nullptr,
0
};
@@ -178,7 +178,7 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin
qRegisterNormalizedMetaType<T *>(pointerName.constData()),
qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
0,
- Q_NULLPTR,
+ nullptr,
reason,
uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
@@ -190,9 +190,9 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
- Q_NULLPTR, Q_NULLPTR,
+ nullptr, nullptr,
- Q_NULLPTR,
+ nullptr,
metaObjectRevision
};
@@ -217,7 +217,7 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve
qRegisterNormalizedMetaType<T *>(pointerName.constData()),
qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
0,
- Q_NULLPTR,
+ nullptr,
reason,
uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
@@ -231,7 +231,7 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve
QQmlPrivate::createParent<E>, &E::staticMetaObject,
- Q_NULLPTR,
+ nullptr,
0
};
@@ -256,7 +256,7 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve
qRegisterNormalizedMetaType<T *>(pointerName.constData()),
qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
0,
- Q_NULLPTR,
+ nullptr,
reason,
uri, versionMajor, versionMinor, qmlName, &T::staticMetaObject,
@@ -270,7 +270,7 @@ int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int ve
QQmlPrivate::createParent<E>, &E::staticMetaObject,
- Q_NULLPTR,
+ nullptr,
metaObjectRevision
};
@@ -301,9 +301,9 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
- Q_NULLPTR, Q_NULLPTR,
+ nullptr, nullptr,
- Q_NULLPTR,
+ nullptr,
0
};
@@ -332,9 +332,9 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
- Q_NULLPTR, Q_NULLPTR,
+ nullptr, nullptr,
- Q_NULLPTR,
+ nullptr,
metaObjectRevision
};
@@ -363,9 +363,9 @@ int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor)
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
- Q_NULLPTR, Q_NULLPTR,
+ nullptr, nullptr,
- Q_NULLPTR,
+ nullptr,
metaObjectRevision
};
@@ -384,10 +384,10 @@ int qmlRegisterExtendedType()
qRegisterNormalizedMetaType<T *>(pointerName.constData()),
qRegisterNormalizedMetaType<QQmlListProperty<T> >(listName.constData()),
0,
- Q_NULLPTR,
+ nullptr,
QString(),
- Q_NULLPTR, 0, 0, Q_NULLPTR, &T::staticMetaObject,
+ nullptr, 0, 0, nullptr, &T::staticMetaObject,
QQmlPrivate::attachedPropertiesFunc<T>(),
QQmlPrivate::attachedPropertiesMetaObject<T>(),
@@ -398,7 +398,7 @@ int qmlRegisterExtendedType()
QQmlPrivate::createParent<E>, &E::staticMetaObject,
- Q_NULLPTR,
+ nullptr,
0
};
@@ -437,7 +437,7 @@ int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor,
QQmlPrivate::createParent<E>, &E::staticMetaObject,
- Q_NULLPTR,
+ nullptr,
0
};
@@ -487,7 +487,7 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor,
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueSource>::cast(),
QQmlPrivate::StaticCastSelector<T,QQmlPropertyValueInterceptor>::cast(),
- Q_NULLPTR, Q_NULLPTR,
+ nullptr, nullptr,
parser,
0
@@ -583,7 +583,7 @@ inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versi
uri, versionMajor, versionMinor, typeName,
- callback, Q_NULLPTR, Q_NULLPTR, 0, 0
+ callback, nullptr, nullptr, 0, 0
};
return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api);
@@ -601,7 +601,7 @@ inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versi
uri, versionMajor, versionMinor, typeName,
- Q_NULLPTR, callback, &T::staticMetaObject, qRegisterNormalizedMetaType<T *>(pointerName.constData()), 0
+ nullptr, callback, &T::staticMetaObject, qRegisterNormalizedMetaType<T *>(pointerName.constData()), 0
};
return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api);
diff --git a/src/qml/qml/qqmlapplicationengine.h b/src/qml/qml/qqmlapplicationengine.h
index 6c57f46c72..d0f9e6d319 100644
--- a/src/qml/qml/qqmlapplicationengine.h
+++ b/src/qml/qml/qqmlapplicationengine.h
@@ -53,9 +53,9 @@ class Q_QML_EXPORT QQmlApplicationEngine : public QQmlEngine
{
Q_OBJECT
public:
- QQmlApplicationEngine(QObject *parent = Q_NULLPTR);
- QQmlApplicationEngine(const QUrl &url, QObject *parent = Q_NULLPTR);
- QQmlApplicationEngine(const QString &filePath, QObject *parent = Q_NULLPTR);
+ QQmlApplicationEngine(QObject *parent = nullptr);
+ QQmlApplicationEngine(const QUrl &url, QObject *parent = nullptr);
+ QQmlApplicationEngine(const QString &filePath, QObject *parent = nullptr);
~QQmlApplicationEngine();
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp
index 325f752cd5..a968aa908d 100644
--- a/src/qml/qml/qqmlbinding.cpp
+++ b/src/qml/qml/qqmlbinding.cpp
@@ -54,6 +54,7 @@
#include <QVariant>
#include <QtCore/qdebug.h>
+#include <QVector>
QT_BEGIN_NAMESPACE
@@ -83,7 +84,7 @@ QQmlBinding *QQmlBinding::create(const QQmlPropertyData *property, const QQmlScr
b->QQmlJavaScriptExpression::setContext(QQmlContextData::get(ctxt ? ctxt : scriptPrivate->context));
b->setScopeObject(obj ? obj : scriptPrivate->scope);
- QV4::ExecutionEngine *v4 = QQmlEnginePrivate::get(b->context()->engine)->v4engine();
+ QV4::ExecutionEngine *v4 = b->context()->engine->handle();
if (runtimeFunction) {
QV4::Scope scope(v4);
QV4::Scoped<QV4::QmlContext> qmlContext(scope, QV4::QmlContext::create(v4->rootContext(), ctxtdata, b->scopeObject()));
@@ -157,13 +158,13 @@ void QQmlBinding::update(QQmlPropertyData::WriteFlags flags)
DeleteWatcher watcher(this);
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context()->engine);
- QV4::Scope scope(ep->v4engine());
+ QQmlEngine *engine = context()->engine;
+ QV4::Scope scope(engine->handle());
if (canUseAccessor())
flags.setFlag(QQmlPropertyData::BypassInterceptor);
- QQmlBindingProfiler prof(ep->profiler, function());
+ QQmlBindingProfiler prof(QQmlEnginePrivate::get(engine)->profiler, function());
doUpdate(watcher, flags, scope);
if (!watcher.wasDeleted())
@@ -179,7 +180,7 @@ class QQmlBindingBinding: public QQmlBinding
{
protected:
void doUpdate(const DeleteWatcher &,
- QQmlPropertyData::WriteFlags flags, QV4::Scope &) Q_DECL_OVERRIDE Q_DECL_FINAL
+ QQmlPropertyData::WriteFlags flags, QV4::Scope &) override final
{
Q_ASSERT(!m_targetIndex.hasValueTypeIndex());
QQmlPropertyData *pd = nullptr;
@@ -195,19 +196,18 @@ class QQmlNonbindingBinding: public QQmlBinding
{
protected:
void doUpdate(const DeleteWatcher &watcher,
- QQmlPropertyData::WriteFlags flags, QV4::Scope &scope) Q_DECL_OVERRIDE Q_DECL_FINAL
+ QQmlPropertyData::WriteFlags flags, QV4::Scope &scope) override
{
auto ep = QQmlEnginePrivate::get(scope.engine);
ep->referenceScarceResources();
bool isUndefined = false;
- QV4::ScopedCallData callData(scope);
- QQmlJavaScriptExpression::evaluate(callData, &isUndefined, scope);
+ QV4::ScopedValue result(scope, QQmlJavaScriptExpression::evaluate(&isUndefined));
bool error = false;
if (!watcher.wasDeleted() && isAddedToObject() && !hasError())
- error = !write(scope.result, isUndefined, flags);
+ error = !write(result, isUndefined, flags);
if (!watcher.wasDeleted()) {
@@ -237,7 +237,7 @@ class GenericBinding: public QQmlNonbindingBinding
protected:
// Returns true if successful, false if an error description was set on expression
Q_ALWAYS_INLINE bool write(const QV4::Value &result, bool isUndefined,
- QQmlPropertyData::WriteFlags flags) Q_DECL_OVERRIDE Q_DECL_FINAL
+ QQmlPropertyData::WriteFlags flags) override final
{
Q_ASSERT(targetObject());
@@ -296,13 +296,62 @@ protected:
}
};
+class QQmlTranslationBinding : public GenericBinding<QMetaType::QString> {
+public:
+ QQmlTranslationBinding(QV4::CompiledData::CompilationUnit *compilationUnit, const QV4::CompiledData::Binding *binding)
+ {
+ setCompilationUnit(compilationUnit);
+ m_binding = binding;
+ setSourceLocation(QQmlSourceLocation(compilationUnit->fileName(), binding->valueLocation.line, binding->valueLocation.column));
+ }
+
+ void doUpdate(const DeleteWatcher &watcher,
+ QQmlPropertyData::WriteFlags flags, QV4::Scope &scope) override final
+ {
+ if (watcher.wasDeleted())
+ return;
+
+ if (!isAddedToObject() || hasError())
+ return;
+
+ const QString result = m_binding->valueAsString(m_compilationUnit->data);
+
+ Q_ASSERT(targetObject());
+
+ QQmlPropertyData *pd;
+ QQmlPropertyData vpd;
+ getPropertyData(&pd, &vpd);
+ Q_ASSERT(pd);
+ if (pd->propType() == QMetaType::QString) {
+ doStore(result, pd, flags);
+ } else {
+ QV4::ScopedString value(scope, scope.engine->newString(result));
+ slowWrite(*pd, vpd, value, /*isUndefined*/false, flags);
+ }
+ }
+
+private:
+ const QV4::CompiledData::Binding *m_binding;
+};
+
+QQmlBinding *QQmlBinding::createTranslationBinding(QV4::CompiledData::CompilationUnit *unit, const QV4::CompiledData::Binding *binding, QObject *obj, QQmlContextData *ctxt)
+{
+ QQmlTranslationBinding *b = new QQmlTranslationBinding(unit, binding);
+
+ b->setNotifyOnValueChanged(true);
+ b->QQmlJavaScriptExpression::setContext(ctxt);
+ b->setScopeObject(obj);
+
+ return b;
+}
+
Q_NEVER_INLINE bool QQmlBinding::slowWrite(const QQmlPropertyData &core,
const QQmlPropertyData &valueTypeData,
const QV4::Value &result,
bool isUndefined, QQmlPropertyData::WriteFlags flags)
{
QQmlEngine *engine = context()->engine;
- QV8Engine *v8engine = QQmlEnginePrivate::getV8Engine(engine);
+ QV4::ExecutionEngine *v4engine = engine->handle();
int type = valueTypeData.isValid() ? valueTypeData.propType() : core.propType();
@@ -313,13 +362,13 @@ Q_NEVER_INLINE bool QQmlBinding::slowWrite(const QQmlPropertyData &core,
if (isUndefined) {
} else if (core.isQList()) {
- value = QV8Engine::getV4(v8engine)->toVariant(result, qMetaTypeId<QList<QObject *> >());
+ value = v4engine->toVariant(result, qMetaTypeId<QList<QObject *> >());
} else if (result.isNull() && core.isQObject()) {
value = QVariant::fromValue((QObject *)0);
} else if (core.propType() == qMetaTypeId<QList<QUrl> >()) {
- value = QQmlPropertyPrivate::resolvedUrlSequence(QV8Engine::getV4(v8engine)->toVariant(result, qMetaTypeId<QList<QUrl> >()), context());
+ value = QQmlPropertyPrivate::resolvedUrlSequence(v4engine->toVariant(result, qMetaTypeId<QList<QUrl> >()), context());
} else if (!isVarProperty && type != qMetaTypeId<QJSValue>()) {
- value = QV8Engine::getV4(v8engine)->toVariant(result, type);
+ value = v4engine->toVariant(result, type);
}
if (hasError()) {
@@ -348,7 +397,7 @@ Q_NEVER_INLINE bool QQmlBinding::slowWrite(const QQmlPropertyData &core,
return false;
}
QQmlPropertyPrivate::writeValueProperty(m_target.data(), core, valueTypeData, QVariant::fromValue(
- QJSValue(QV8Engine::getV4(v8engine), result.asReturnedValue())),
+ QJSValue(v4engine, result.asReturnedValue())),
context(), flags);
} else if (isUndefined) {
const QLatin1String typeName(QMetaType::typeName(type)
@@ -406,18 +455,18 @@ Q_NEVER_INLINE bool QQmlBinding::slowWrite(const QQmlPropertyData &core,
QVariant QQmlBinding::evaluate()
{
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(context()->engine);
+ QQmlEngine *engine = context()->engine;
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
ep->referenceScarceResources();
bool isUndefined = false;
- QV4::Scope scope(ep->v4engine());
- QV4::ScopedCallData callData(scope);
- QQmlJavaScriptExpression::evaluate(callData, &isUndefined, scope);
+ QV4::Scope scope(engine->handle());
+ QV4::ScopedValue result(scope, QQmlJavaScriptExpression::evaluate(&isUndefined));
ep->dereferenceScarceResources();
- return scope.engine->toVariant(scope.result, qMetaTypeId<QList<QObject*> >());
+ return scope.engine->toVariant(result, qMetaTypeId<QList<QObject*> >());
}
QString QQmlBinding::expressionIdentifier() const
@@ -535,6 +584,37 @@ void QQmlBinding::getPropertyData(QQmlPropertyData **propertyData, QQmlPropertyD
}
}
+QVector<QQmlProperty> QQmlBinding::dependencies() const
+{
+ QVector<QQmlProperty> dependencies;
+ if (!m_target.data())
+ return dependencies;
+
+ for (const auto &guardList : { permanentGuards, activeGuards }) {
+ for (QQmlJavaScriptExpressionGuard *guard = guardList.first(); guard; guard = guardList.next(guard)) {
+ if (guard->signalIndex() == -1) // guard's sender is a QQmlNotifier, not a QObject*.
+ continue;
+
+ QObject *senderObject = guard->senderAsObject();
+ if (!senderObject)
+ continue;
+
+ const QMetaObject *senderMeta = senderObject->metaObject();
+ if (!senderMeta)
+ continue;
+
+ for (int i = 0; i < senderMeta->propertyCount(); i++) {
+ QMetaProperty property = senderMeta->property(i);
+ if (property.notifySignalIndex() == QMetaObjectPrivate::signal(senderMeta, guard->signalIndex()).methodIndex()) {
+ dependencies.push_back(QQmlProperty(senderObject, QString::fromUtf8(senderObject->metaObject()->property(i).name())));
+ }
+ }
+ }
+ }
+
+ return dependencies;
+}
+
class QObjectPointerBinding: public QQmlNonbindingBinding
{
QQmlMetaObject targetMetaObject;
@@ -546,7 +626,7 @@ public:
protected:
Q_ALWAYS_INLINE bool write(const QV4::Value &result, bool isUndefined,
- QQmlPropertyData::WriteFlags flags) Q_DECL_OVERRIDE Q_DECL_FINAL
+ QQmlPropertyData::WriteFlags flags) override final
{
QQmlPropertyData *pd;
QQmlPropertyData vtpd;
diff --git a/src/qml/qml/qqmlbinding_p.h b/src/qml/qml/qqmlbinding_p.h
index 0f2fb329f5..8bc9554a42 100644
--- a/src/qml/qml/qqmlbinding_p.h
+++ b/src/qml/qml/qqmlbinding_p.h
@@ -77,6 +77,8 @@ public:
const QString &url = QString(), quint16 lineNumber = 0);
static QQmlBinding *create(const QQmlPropertyData *property, QV4::Function *function,
QObject *obj, QQmlContextData *ctxt, QV4::ExecutionContext *scope);
+ static QQmlBinding *createTranslationBinding(QV4::CompiledData::CompilationUnit *unit, const QV4::CompiledData::Binding *binding,
+ QObject *obj, QQmlContextData *ctxt);
~QQmlBinding();
void setTarget(const QQmlProperty &);
@@ -84,10 +86,10 @@ public:
void setNotifyOnValueChanged(bool);
- void refresh() Q_DECL_OVERRIDE;
+ void refresh() override;
- void setEnabled(bool, QQmlPropertyData::WriteFlags flags = QQmlPropertyData::DontRemoveBinding) Q_DECL_OVERRIDE;
- QString expression() const Q_DECL_OVERRIDE;
+ void setEnabled(bool, QQmlPropertyData::WriteFlags flags = QQmlPropertyData::DontRemoveBinding) override;
+ QString expression() const override;
void update(QQmlPropertyData::WriteFlags flags = QQmlPropertyData::DontRemoveBinding);
typedef int Identifier;
@@ -100,6 +102,15 @@ public:
QString expressionIdentifier() const override;
void expressionChanged() override;
+ /**
+ * This method returns a snapshot of the currently tracked dependencies of
+ * this binding. The dependencies can change upon reevaluation. This method is
+ * used in GammaRay to visualize binding hierarchies.
+ *
+ * Call this method from the UI thread.
+ */
+ QVector<QQmlProperty> dependencies() const;
+
protected:
virtual void doUpdate(const DeleteWatcher &watcher,
QQmlPropertyData::WriteFlags flags, QV4::Scope &scope) = 0;
diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp
index 19ece44beb..501184b630 100644
--- a/src/qml/qml/qqmlboundsignal.cpp
+++ b/src/qml/qml/qqmlboundsignal.cpp
@@ -55,6 +55,7 @@
#include <private/qjsvalue_p.h>
#include <private/qv4value_p.h>
+#include <private/qv4jscall_p.h>
#include <private/qv4qobjectwrapper_p.h>
#include <QtCore/qdebug.h>
@@ -73,8 +74,7 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index,
{
init(ctxt, scope);
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine());
- QV4::ExecutionEngine *v4 = ep->v4engine();
+ QV4::ExecutionEngine *v4 = engine()->handle();
QString function;
@@ -122,7 +122,7 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index,
// It's important to call init first, because m_index gets remapped in case of cloned signals.
init(ctxt, scope);
- QV4::ExecutionEngine *engine = QQmlEnginePrivate::getV4Engine(ctxt->engine);
+ QV4::ExecutionEngine *engine = ctxt->engine->handle();
QList<QByteArray> signalParameters = QMetaObjectPrivate::signal(m_target->metaObject(), m_index).parameterNames();
if (!signalParameters.isEmpty()) {
@@ -181,8 +181,10 @@ void QQmlBoundSignalExpression::evaluate(void **a)
if (!expressionFunctionValid())
return;
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine());
- QV4::Scope scope(ep->v4engine());
+ QQmlEngine *qmlengine = engine();
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(qmlengine);
+ QV4::ExecutionEngine *v4 = qmlengine->handle();
+ QV4::Scope scope(v4);
ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
@@ -192,35 +194,35 @@ void QQmlBoundSignalExpression::evaluate(void **a)
int *argsTypes = QQmlMetaObject(m_target).methodParameterTypes(methodIndex, &storage, 0);
int argCount = argsTypes ? *argsTypes : 0;
- QV4::ScopedCallData callData(scope, argCount);
+ QV4::JSCallData jsCall(scope, argCount);
for (int ii = 0; ii < argCount; ++ii) {
int type = argsTypes[ii + 1];
//### ideally we would use metaTypeToJS, however it currently gives different results
// for several cases (such as QVariant type and QObject-derived types)
//args[ii] = engine->metaTypeToJS(type, a[ii + 1]);
if (type == qMetaTypeId<QJSValue>()) {
- if (QV4::Value *v4Value = QJSValuePrivate::valueForData(reinterpret_cast<QJSValue *>(a[ii + 1]), &callData->args[ii]))
- callData->args[ii] = *v4Value;
+ if (QV4::Value *v4Value = QJSValuePrivate::valueForData(reinterpret_cast<QJSValue *>(a[ii + 1]), &jsCall->args[ii]))
+ jsCall->args[ii] = *v4Value;
else
- callData->args[ii] = QV4::Encode::undefined();
+ jsCall->args[ii] = QV4::Encode::undefined();
} else if (type == QMetaType::QVariant) {
- callData->args[ii] = scope.engine->fromVariant(*((QVariant *)a[ii + 1]));
+ jsCall->args[ii] = scope.engine->fromVariant(*((QVariant *)a[ii + 1]));
} else if (type == QMetaType::Int) {
//### optimization. Can go away if we switch to metaTypeToJS, or be expanded otherwise
- callData->args[ii] = QV4::Primitive::fromInt32(*reinterpret_cast<const int*>(a[ii + 1]));
+ jsCall->args[ii] = QV4::Primitive::fromInt32(*reinterpret_cast<const int*>(a[ii + 1]));
} else if (type == qMetaTypeId<QQmlV4Handle>()) {
- callData->args[ii] = *reinterpret_cast<QQmlV4Handle *>(a[ii + 1]);
+ jsCall->args[ii] = *reinterpret_cast<QQmlV4Handle *>(a[ii + 1]);
} else if (ep->isQObject(type)) {
if (!*reinterpret_cast<void* const *>(a[ii + 1]))
- callData->args[ii] = QV4::Primitive::nullValue();
+ jsCall->args[ii] = QV4::Primitive::nullValue();
else
- callData->args[ii] = QV4::QObjectWrapper::wrap(ep->v4engine(), *reinterpret_cast<QObject* const *>(a[ii + 1]));
+ jsCall->args[ii] = QV4::QObjectWrapper::wrap(v4, *reinterpret_cast<QObject* const *>(a[ii + 1]));
} else {
- callData->args[ii] = scope.engine->fromVariant(QVariant(type, a[ii + 1]));
+ jsCall->args[ii] = scope.engine->fromVariant(QVariant(type, a[ii + 1]));
}
}
- QQmlJavaScriptExpression::evaluate(callData, 0, scope);
+ QQmlJavaScriptExpression::evaluate(jsCall.callData(), 0);
ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
}
@@ -232,17 +234,18 @@ void QQmlBoundSignalExpression::evaluate(const QList<QVariant> &args)
if (!expressionFunctionValid())
return;
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine());
- QV4::Scope scope(ep->v4engine());
+ QQmlEngine *qmlengine = engine();
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(qmlengine);
+ QV4::Scope scope(qmlengine->handle());
ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
- QV4::ScopedCallData callData(scope, args.count());
+ QV4::JSCallData jsCall(scope, args.count());
for (int ii = 0; ii < args.count(); ++ii) {
- callData->args[ii] = scope.engine->fromVariant(args[ii]);
+ jsCall->args[ii] = scope.engine->fromVariant(args[ii]);
}
- QQmlJavaScriptExpression::evaluate(callData, 0, scope);
+ QQmlJavaScriptExpression::evaluate(jsCall.callData(), 0);
ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
}
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 4da6b7958c..481507946d 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -58,6 +58,7 @@
#include <private/qv4scopedvalue_p.h>
#include <private/qv4objectiterator_p.h>
#include <private/qv4qobjectwrapper_p.h>
+#include <private/qv4jscall_p.h>
#include <QDir>
#include <QStack>
@@ -1060,20 +1061,52 @@ void QQmlComponent::create(QQmlIncubator &incubator, QQmlContext *context,
enginePriv->incubate(incubator, forContextData);
}
+/*
+ This is essentially a copy of QQmlComponent::create(); except it takes the QQmlContextData
+ arguments instead of QQmlContext which means we don't have to construct the rather weighty
+ wrapper class for every delegate item.
+
+ This is used by QQmlDelegateModel.
+*/
+void QQmlComponentPrivate::incubateObject(
+ QQmlIncubator *incubationTask,
+ QQmlComponent *component,
+ QQmlEngine *engine,
+ QQmlContextData *context,
+ QQmlContextData *forContext)
+{
+ QQmlIncubatorPrivate *incubatorPriv = QQmlIncubatorPrivate::get(incubationTask);
+ QQmlEnginePrivate *enginePriv = QQmlEnginePrivate::get(engine);
+ QQmlComponentPrivate *componentPriv = QQmlComponentPrivate::get(component);
+
+ incubatorPriv->compilationUnit = componentPriv->compilationUnit;
+ incubatorPriv->enginePriv = enginePriv;
+ incubatorPriv->creator.reset(new QQmlObjectCreator(context, componentPriv->compilationUnit, componentPriv->creationContext));
+ incubatorPriv->subComponentToCreate = componentPriv->start;
+
+ enginePriv->incubate(*incubationTask, forContext);
+}
+
+
+
class QQmlComponentIncubator;
namespace QV4 {
namespace Heap {
-struct QmlIncubatorObject : Object {
+#define QmlIncubatorObjectMembers(class, Member) \
+ Member(class, HeapValue, HeapValue, valuemap) \
+ Member(class, HeapValue, HeapValue, statusChanged) \
+ Member(class, Pointer, QmlContext *, qmlContext) \
+ Member(class, NoMark, QQmlComponentIncubator *, incubator) \
+ Member(class, NoMark, QQmlQPointer<QObject>, parent)
+
+DECLARE_HEAP_OBJECT(QmlIncubatorObject, Object) {
+ DECLARE_MARKOBJECTS(QmlIncubatorObject);
+
void init(QQmlIncubator::IncubationMode = QQmlIncubator::Asynchronous);
inline void destroy();
- QQmlComponentIncubator *incubator;
- QQmlQPointer<QObject> parent;
- QV4::Value valuemap;
- QV4::Value statusChanged;
- Pointer<Heap::QmlContext> qmlContext;
};
}
@@ -1083,13 +1116,11 @@ struct QmlIncubatorObject : public QV4::Object
V4_OBJECT2(QmlIncubatorObject, Object)
V4_NEEDS_DESTROY
- static void method_get_statusChanged(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_set_statusChanged(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_get_status(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_get_object(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_forceCompletion(const BuiltinFunction *, Scope &scope, CallData *callData);
-
- static void markObjects(QV4::Heap::Base *that, QV4::ExecutionEngine *e);
+ static ReturnedValue method_get_statusChanged(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_set_statusChanged(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_status(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_object(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_forceCompletion(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
void statusChanged(QQmlIncubator::Status);
void setInitialState(QObject *);
@@ -1199,8 +1230,7 @@ void QQmlComponentPrivate::setInitialProperties(QV4::ExecutionEngine *engine, QV
if (engine->hasException)
return;
- QV4::ExecutionContextSaver saver(scope);
- engine->pushContext(qmlContext);
+ QV4::ScopedStackFrame frame(scope, qmlContext->d());
while (1) {
name = it.nextPropertyNameAsString(val);
@@ -1394,8 +1424,8 @@ void QQmlComponent::incubateObject(QQmlV4Function *args)
r->setPrototype(p);
if (!valuemap->isUndefined())
- r->d()->valuemap = valuemap;
- r->d()->qmlContext = v4->qmlContext();
+ r->d()->valuemap.set(scope.engine, valuemap);
+ r->d()->qmlContext.set(scope.engine, v4->qmlContext());
r->d()->parent = parent;
QQmlIncubator *incubator = r->d()->incubator;
@@ -1411,8 +1441,7 @@ void QQmlComponent::incubateObject(QQmlV4Function *args)
// XXX used by QSGLoader
void QQmlComponentPrivate::initializeObjectWithInitialProperties(QV4::QmlContext *qmlContext, const QV4::Value &valuemap, QObject *toCreate)
{
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
- QV4::ExecutionEngine *v4engine = QV8Engine::getV4(ep->v8engine());
+ QV4::ExecutionEngine *v4engine = engine->handle();
QV4::Scope scope(v4engine);
QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(v4engine, toCreate));
@@ -1435,18 +1464,20 @@ QQmlComponentExtension::QQmlComponentExtension(QV4::ExecutionEngine *v4)
incubationProto.set(v4, proto);
}
-void QV4::QmlIncubatorObject::method_get_object(const BuiltinFunction *, Scope &scope, CallData *callData)
+QV4::ReturnedValue QV4::QmlIncubatorObject::method_get_object(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QmlIncubatorObject> o(scope, thisObject->as<QmlIncubatorObject>());
if (!o)
THROW_TYPE_ERROR();
- scope.result = QV4::QObjectWrapper::wrap(scope.engine, o->d()->incubator->object());
+ return QV4::QObjectWrapper::wrap(scope.engine, o->d()->incubator->object());
}
-void QV4::QmlIncubatorObject::method_forceCompletion(const BuiltinFunction *, Scope &scope, CallData *callData)
+QV4::ReturnedValue QV4::QmlIncubatorObject::method_forceCompletion(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QmlIncubatorObject> o(scope, thisObject->as<QmlIncubatorObject>());
if (!o)
THROW_TYPE_ERROR();
@@ -1455,31 +1486,34 @@ void QV4::QmlIncubatorObject::method_forceCompletion(const BuiltinFunction *, Sc
RETURN_UNDEFINED();
}
-void QV4::QmlIncubatorObject::method_get_status(const BuiltinFunction *, Scope &scope, CallData *callData)
+QV4::ReturnedValue QV4::QmlIncubatorObject::method_get_status(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QmlIncubatorObject> o(scope, thisObject->as<QmlIncubatorObject>());
if (!o)
THROW_TYPE_ERROR();
- scope.result = QV4::Encode(o->d()->incubator->status());
+ return QV4::Encode(o->d()->incubator->status());
}
-void QV4::QmlIncubatorObject::method_get_statusChanged(const BuiltinFunction *, Scope &scope, CallData *callData)
+QV4::ReturnedValue QV4::QmlIncubatorObject::method_get_statusChanged(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QmlIncubatorObject> o(scope, thisObject->as<QmlIncubatorObject>());
if (!o)
THROW_TYPE_ERROR();
- scope.result = o->d()->statusChanged;
+ return QV4::Encode(o->d()->statusChanged);
}
-void QV4::QmlIncubatorObject::method_set_statusChanged(const BuiltinFunction *, Scope &scope, CallData *callData)
+QV4::ReturnedValue QV4::QmlIncubatorObject::method_set_statusChanged(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>());
- if (!o || callData->argc < 1)
+ QV4::Scope scope(b);
+ QV4::Scoped<QmlIncubatorObject> o(scope, thisObject->as<QmlIncubatorObject>());
+ if (!o || argc < 1)
THROW_TYPE_ERROR();
- o->d()->statusChanged = callData->args[0];
+ o->d()->statusChanged.set(scope.engine, argv[0]);
RETURN_UNDEFINED();
}
@@ -1491,10 +1525,10 @@ QQmlComponentExtension::~QQmlComponentExtension()
void QV4::Heap::QmlIncubatorObject::init(QQmlIncubator::IncubationMode m)
{
Object::init();
- valuemap = QV4::Primitive::undefinedValue();
- statusChanged = QV4::Primitive::undefinedValue();
+ valuemap.set(internalClass->engine, QV4::Primitive::undefinedValue());
+ statusChanged.set(internalClass->engine, QV4::Primitive::undefinedValue());
parent.init();
- qmlContext = nullptr;
+ qmlContext.set(internalClass->engine, nullptr);
incubator = new QQmlComponentIncubator(this, m);
}
@@ -1517,16 +1551,6 @@ void QV4::QmlIncubatorObject::setInitialState(QObject *o)
}
}
-void QV4::QmlIncubatorObject::markObjects(QV4::Heap::Base *that, QV4::ExecutionEngine *e)
-{
- QmlIncubatorObject::Data *o = static_cast<QmlIncubatorObject::Data *>(that);
- o->valuemap.mark(e);
- o->statusChanged.mark(e);
- if (o->qmlContext)
- o->qmlContext->mark(e);
- Object::markObjects(that, e);
-}
-
void QV4::QmlIncubatorObject::statusChanged(QQmlIncubator::Status s)
{
QV4::Scope scope(engine());
@@ -1541,10 +1565,10 @@ void QV4::QmlIncubatorObject::statusChanged(QQmlIncubator::Status s)
QV4::ScopedFunctionObject f(scope, d()->statusChanged);
if (f) {
- QV4::ScopedCallData callData(scope, 1);
- callData->thisObject = this;
- callData->args[0] = QV4::Primitive::fromUInt32(s);
- f->call(scope, callData);
+ QV4::JSCallData jsCallData(scope, 1);
+ *jsCallData->thisObject = this;
+ jsCallData->args[0] = QV4::Primitive::fromUInt32(s);
+ f->call(jsCallData);
if (scope.hasException()) {
QQmlError error = scope.engine->catchExceptionAsQmlError();
QQmlEnginePrivate::warning(QQmlEnginePrivate::get(scope.engine->qmlEngine()), error);
diff --git a/src/qml/qml/qqmlcomponent.h b/src/qml/qml/qqmlcomponent.h
index ca60f01eb5..b8cc556e4a 100644
--- a/src/qml/qml/qqmlcomponent.h
+++ b/src/qml/qml/qqmlcomponent.h
@@ -77,12 +77,12 @@ public:
enum CompilationMode { PreferSynchronous, Asynchronous };
Q_ENUM(CompilationMode)
- QQmlComponent(QObject *parent = Q_NULLPTR);
- QQmlComponent(QQmlEngine *, QObject *parent = Q_NULLPTR);
- QQmlComponent(QQmlEngine *, const QString &fileName, QObject *parent = Q_NULLPTR);
- QQmlComponent(QQmlEngine *, const QString &fileName, CompilationMode mode, QObject *parent = Q_NULLPTR);
- QQmlComponent(QQmlEngine *, const QUrl &url, QObject *parent = Q_NULLPTR);
- QQmlComponent(QQmlEngine *, const QUrl &url, CompilationMode mode, QObject *parent = Q_NULLPTR);
+ QQmlComponent(QObject *parent = nullptr);
+ QQmlComponent(QQmlEngine *, QObject *parent = nullptr);
+ QQmlComponent(QQmlEngine *, const QString &fileName, QObject *parent = nullptr);
+ QQmlComponent(QQmlEngine *, const QString &fileName, CompilationMode mode, QObject *parent = nullptr);
+ QQmlComponent(QQmlEngine *, const QUrl &url, QObject *parent = nullptr);
+ QQmlComponent(QQmlEngine *, const QUrl &url, CompilationMode mode, QObject *parent = nullptr);
virtual ~QQmlComponent();
enum Status { Null, Ready, Loading, Error };
@@ -101,12 +101,12 @@ public:
QUrl url() const;
- virtual QObject *create(QQmlContext *context = Q_NULLPTR);
+ virtual QObject *create(QQmlContext *context = nullptr);
virtual QObject *beginCreate(QQmlContext *);
virtual void completeCreate();
- void create(QQmlIncubator &, QQmlContext *context = Q_NULLPTR,
- QQmlContext *forContext = Q_NULLPTR);
+ void create(QQmlIncubator &, QQmlContext *context = nullptr,
+ QQmlContext *forContext = nullptr);
QQmlContext *creationContext() const;
diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h
index 2a57f7b247..8a58a1ada0 100644
--- a/src/qml/qml/qqmlcomponent_p.h
+++ b/src/qml/qml/qqmlcomponent_p.h
@@ -88,6 +88,13 @@ public:
void initializeObjectWithInitialProperties(QV4::QmlContext *qmlContext, const QV4::Value &valuemap, QObject *toCreate);
static void setInitialProperties(QV4::ExecutionEngine *engine, QV4::QmlContext *qmlContext, const QV4::Value &o, const QV4::Value &v);
+ void incubateObject(
+ QQmlIncubator *incubationTask,
+ QQmlComponent *component,
+ QQmlEngine *engine,
+ QQmlContextData *context,
+ QQmlContextData *forContext);
+
QQmlTypeData *typeData;
void typeDataReady(QQmlTypeData *) override;
void typeDataProgress(QQmlTypeData *, qreal) override;
diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp
index 0c431b1260..0b0132fab7 100644
--- a/src/qml/qml/qqmlcontext.cpp
+++ b/src/qml/qml/qqmlcontext.cpp
@@ -306,16 +306,7 @@ void QQmlContext::setContextProperty(const QString &name, const QVariant &value)
return;
}
- if (data->engine) {
- bool ok;
- QObject *o = QQmlEnginePrivate::get(data->engine)->toQObject(value, &ok);
- if (ok) {
- setContextProperty(name, o);
- return;
- }
- }
-
- QV4::IdentifierHash<int> &properties = data->detachedPropertyNames();
+ QV4::IdentifierHash &properties = data->detachedPropertyNames();
int idx = properties.value(name);
if (idx == -1) {
properties.add(name, data->idValueCount + d->propertyValues.count());
@@ -335,37 +326,54 @@ void QQmlContext::setContextProperty(const QString &name, const QVariant &value)
*/
void QQmlContext::setContextProperty(const QString &name, QObject *value)
{
- Q_D(QQmlContext);
- if (d->notifyIndex == -1)
- d->notifyIndex = QMetaObjectPrivate::absoluteSignalCount(&QQmlContext::staticMetaObject);
+ setContextProperty(name, QVariant::fromValue(value));
+}
+
+/*!
+ \since 5.11
+
+ Set a batch of \a properties on this context.
+
+ Setting all properties in one batch avoids unnecessary
+ refreshing expressions, and is therefore recommended
+ instead of calling \l setContextProperty() for each individual property.
+
+ \sa QQmlContext::setContextProperty()
+*/
+void QQmlContext::setContextProperties(const QVector<PropertyPair> &properties)
+{
+ Q_D(const QQmlContext);
QQmlContextData *data = d->data;
- if (data->isInternal) {
- qWarning("QQmlContext: Cannot set property on internal context.");
- return;
- }
+ QQmlJavaScriptExpression *expressions = data->expressions;
+ QQmlContextData *childContexts = data->childContexts;
- if (!isValid()) {
- qWarning("QQmlContext: Cannot set property on invalid context.");
- return;
- }
+ data->expressions = 0;
+ data->childContexts = 0;
- QV4::IdentifierHash<int> &properties = data->detachedPropertyNames();
- int idx = properties.value(name);
+ for (auto property : properties)
+ setContextProperty(property.name, property.value);
- if (idx == -1) {
- properties.add(name, data->idValueCount + d->propertyValues.count());
- d->propertyValues.append(QVariant::fromValue(value));
+ data->expressions = expressions;
+ data->childContexts = childContexts;
- data->refreshExpressions();
- } else {
- d->propertyValues[idx] = QVariant::fromValue(value);
- QMetaObject::activate(this, d->notifyIndex, idx, 0);
- }
+ data->refreshExpressions();
}
/*!
+ \since 5.11
+
+ \class QQmlContext::PropertyPair
+ \inmodule QtQml
+
+ This struct contains a property name and a property value.
+ It is used as a parameter for the \c setContextProperties function.
+
+ \sa QQQmlContext::setContextProperties()
+*/
+
+/*!
Returns the value of the \a name property for this context
as a QVariant.
*/
@@ -377,7 +385,7 @@ QVariant QQmlContext::contextProperty(const QString &name) const
QQmlContextData *data = d->data;
- const QV4::IdentifierHash<int> &properties = data->propertyNames();
+ const QV4::IdentifierHash &properties = data->propertyNames();
if (properties.count())
idx = properties.value(name);
@@ -784,7 +792,7 @@ void QQmlContextData::setIdProperty(int idx, QObject *obj)
QString QQmlContextData::findObjectId(const QObject *obj) const
{
- const QV4::IdentifierHash<int> &properties = propertyNames();
+ const QV4::IdentifierHash &properties = propertyNames();
if (propertyNameCache.isEmpty())
return QString();
@@ -826,18 +834,18 @@ void QQmlContextData::initFromTypeCompilationUnit(const QQmlRefPointer<QV4::Comp
idValues = new ContextGuard[idValueCount];
}
-const QV4::IdentifierHash<int> &QQmlContextData::propertyNames() const
+const QV4::IdentifierHash &QQmlContextData::propertyNames() const
{
if (propertyNameCache.isEmpty()) {
if (typeCompilationUnit)
propertyNameCache = typeCompilationUnit->namedObjectsPerComponent(componentObjectIndex);
else
- propertyNameCache = QV4::IdentifierHash<int>(QV8Engine::getV4(engine));
+ propertyNameCache = QV4::IdentifierHash(engine->handle());
}
return propertyNameCache;
}
-QV4::IdentifierHash<int> &QQmlContextData::detachedPropertyNames()
+QV4::IdentifierHash &QQmlContextData::detachedPropertyNames()
{
propertyNames();
propertyNameCache.detach();
diff --git a/src/qml/qml/qqmlcontext.h b/src/qml/qml/qqmlcontext.h
index 781eac44fc..506ae216b2 100644
--- a/src/qml/qml/qqmlcontext.h
+++ b/src/qml/qml/qqmlcontext.h
@@ -42,6 +42,8 @@
#include <QtCore/qurl.h>
#include <QtCore/qobject.h>
+#include <QtCore/qlist.h>
+#include <QtCore/qpair.h>
#include <QtQml/qjsvalue.h>
#include <QtCore/qmetatype.h>
#include <QtCore/qvariant.h>
@@ -62,8 +64,10 @@ class Q_QML_EXPORT QQmlContext : public QObject
Q_DECLARE_PRIVATE(QQmlContext)
public:
- QQmlContext(QQmlEngine *parent, QObject *objParent = Q_NULLPTR);
- QQmlContext(QQmlContext *parent, QObject *objParent = Q_NULLPTR);
+ struct PropertyPair { QString name; QVariant value; };
+
+ QQmlContext(QQmlEngine *parent, QObject *objParent = nullptr);
+ QQmlContext(QQmlContext *parent, QObject *objParent = nullptr);
virtual ~QQmlContext();
bool isValid() const;
@@ -77,6 +81,7 @@ public:
QVariant contextProperty(const QString &) const;
void setContextProperty(const QString &, QObject *);
void setContextProperty(const QString &, const QVariant &);
+ void setContextProperties(const QVector<PropertyPair> &properties);
// ### Qt 6: no need for a mutable object, this should become a const QObject pointer
QString nameForObject(QObject *) const;
diff --git a/src/qml/qml/qqmlcontext_p.h b/src/qml/qml/qqmlcontext_p.h
index d01820a430..8939c810fe 100644
--- a/src/qml/qml/qqmlcontext_p.h
+++ b/src/qml/qml/qqmlcontext_p.h
@@ -158,9 +158,9 @@ public:
void initFromTypeCompilationUnit(const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &unit, int subComponentIndex);
// flag indicates whether the context owns the cache (after mutation) or not.
- mutable QV4::IdentifierHash<int> propertyNameCache;
- const QV4::IdentifierHash<int> &propertyNames() const;
- QV4::IdentifierHash<int> &detachedPropertyNames();
+ mutable QV4::IdentifierHash propertyNameCache;
+ const QV4::IdentifierHash &propertyNames() const;
+ QV4::IdentifierHash &detachedPropertyNames();
// Context object
QObject *contextObject;
diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp
index ecdaf41523..cc6e75a39c 100644
--- a/src/qml/qml/qqmlcustomparser.cpp
+++ b/src/qml/qml/qqmlcustomparser.cpp
@@ -121,13 +121,16 @@ int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const
{
Q_ASSERT_X(ok, "QQmlCustomParser::evaluateEnum", "ok must not be a null pointer");
*ok = false;
+
+ // we support one or two '.' in the enum phrase:
+ // * <TypeName>.<EnumValue>
+ // * <TypeName>.<ScopedEnumName>.<EnumValue>
+
int dot = script.indexOf('.');
- if (dot == -1)
+ if (dot == -1 || dot == script.length()-1)
return -1;
-
QString scope = QString::fromUtf8(script.left(dot));
- QByteArray enumValue = script.mid(dot+1);
if (scope != QLatin1String("Qt")) {
if (imports.isNull())
@@ -142,9 +145,20 @@ int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const
type = result.type;
}
- return type.enumValue(engine, QHashedCStringRef(enumValue.constData(), enumValue.length()), ok);
+ if (!type.isValid())
+ return -1;
+
+ int dot2 = script.indexOf('.', dot+1);
+ const bool dot2Valid = dot2 != -1 && dot2 != script.length()-1;
+ QByteArray enumValue = script.mid(dot2Valid ? dot2 + 1 : dot + 1);
+ QByteArray scopedEnumName = (dot2Valid ? script.mid(dot + 1, dot2 - dot - 1) : QByteArray());
+ if (!scopedEnumName.isEmpty())
+ return type.scopedEnumValue(engine, scopedEnumName, enumValue, ok);
+ else
+ return type.enumValue(engine, QHashedCStringRef(enumValue.constData(), enumValue.length()), ok);
}
+ QByteArray enumValue = script.mid(dot + 1);
const QMetaObject *mo = StaticQtMetaObject::get();
int i = mo->enumeratorCount();
while (i--) {
diff --git a/src/qml/qml/qqmldelayedcallqueue.cpp b/src/qml/qml/qqmldelayedcallqueue.cpp
index 13e62ec696..268f91c8ba 100644
--- a/src/qml/qml/qqmldelayedcallqueue.cpp
+++ b/src/qml/qml/qqmldelayedcallqueue.cpp
@@ -42,6 +42,7 @@
#include <private/qqmlengine_p.h>
#include <private/qqmljavascriptexpression_p.h>
#include <private/qv4value_p.h>
+#include <private/qv4jscall_p.h>
#include <private/qv4qobjectwrapper_p.h>
#include <QQmlError>
@@ -63,17 +64,17 @@ void QQmlDelayedCallQueue::DelayedFunctionCall::execute(QV4::ExecutionEngine *en
QV4::Scope scope(engine);
QV4::ArrayObject *array = m_args.as<QV4::ArrayObject>();
+ const QV4::FunctionObject *callback = m_function.as<QV4::FunctionObject>();
+ Q_ASSERT(callback);
const int argCount = array ? array->getLength() : 0;
- QV4::ScopedCallData callData(scope, argCount);
- callData->thisObject = QV4::Encode::undefined();
+ QV4::JSCallData jsCallData(scope, argCount);
+ *jsCallData->thisObject = QV4::Encode::undefined();
for (int i = 0; i < argCount; i++) {
- callData->args[i] = array->getIndexed(i);
+ jsCallData->args[i] = array->getIndexed(i);
}
- const QV4::FunctionObject *callback = m_function.as<QV4::FunctionObject>();
- Q_ASSERT(callback);
- callback->call(scope, callData);
+ callback->call(jsCallData);
if (scope.engine->hasException) {
QQmlError error = scope.engine->catchExceptionAsQmlError();
@@ -105,17 +106,19 @@ void QQmlDelayedCallQueue::init(QV4::ExecutionEngine* engine)
m_tickedMethod = metaObject.method(methodIndex);
}
-void QQmlDelayedCallQueue::addUniquelyAndExecuteLater(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQmlDelayedCallQueue::addUniquelyAndExecuteLater(const QV4::FunctionObject *b, const QV4::Value *, const QV4::Value *argv, int argc)
{
- if (callData->argc == 0)
+ QV4::Scope scope(b);
+ if (argc == 0)
THROW_GENERIC_ERROR("Qt.callLater: no arguments given");
- const QV4::FunctionObject *func = callData->args[0].as<QV4::FunctionObject>();
+ const QV4::FunctionObject *func = argv[0].as<QV4::FunctionObject>();
if (!func)
THROW_GENERIC_ERROR("Qt.callLater: first argument not a function or signal");
QPair<QObject *, int> functionData = QV4::QObjectMethod::extractQtMethod(func);
+ QV4::ReturnedValue arg0 = argc ? argv[0].asReturnedValue() : QV4::Encode::undefined();
QVector<DelayedFunctionCall>::Iterator iter;
if (functionData.second != -1) {
@@ -134,7 +137,7 @@ void QQmlDelayedCallQueue::addUniquelyAndExecuteLater(const QV4::BuiltinFunction
iter = m_delayedFunctionCalls.begin();
while (iter != m_delayedFunctionCalls.end()) {
DelayedFunctionCall& dfc = *iter;
- if (callData->argument(0) == dfc.m_function.value()) {
+ if (arg0 == dfc.m_function.value()) {
break; // Already stored!
}
++iter;
@@ -147,7 +150,7 @@ void QQmlDelayedCallQueue::addUniquelyAndExecuteLater(const QV4::BuiltinFunction
m_delayedFunctionCalls.erase(iter);
m_delayedFunctionCalls.append(dfc);
} else {
- m_delayedFunctionCalls.append(QV4::PersistentValue(m_engine, callData->argument(0)));
+ m_delayedFunctionCalls.append(QV4::PersistentValue(m_engine, arg0));
}
DelayedFunctionCall& dfc = m_delayedFunctionCalls.last();
@@ -158,33 +161,32 @@ void QQmlDelayedCallQueue::addUniquelyAndExecuteLater(const QV4::BuiltinFunction
dfc.m_guarded = true;
} else if (func->scope()->type == QV4::Heap::ExecutionContext::Type_QmlContext) {
QV4::QmlContext::Data *g = static_cast<QV4::QmlContext::Data *>(func->scope());
- Q_ASSERT(g->qml->scopeObject);
- dfc.m_objectGuard = QQmlGuard<QObject>(g->qml->scopeObject);
+ Q_ASSERT(g->qml()->scopeObject);
+ dfc.m_objectGuard = QQmlGuard<QObject>(g->qml()->scopeObject);
dfc.m_guarded = true;
}
}
- storeAnyArguments(dfc, callData, 1, m_engine);
+ storeAnyArguments(dfc, argv, argc, 1, m_engine);
if (!m_callbackOutstanding) {
m_tickedMethod.invoke(this, Qt::QueuedConnection);
m_callbackOutstanding = true;
}
- scope.result = QV4::Encode::undefined();
+ return QV4::Encode::undefined();
}
-void QQmlDelayedCallQueue::storeAnyArguments(DelayedFunctionCall &dfc, const QV4::CallData *callData, int offset, QV4::ExecutionEngine *engine)
+void QQmlDelayedCallQueue::storeAnyArguments(DelayedFunctionCall &dfc, const QV4::Value *argv, int argc, int offset, QV4::ExecutionEngine *engine)
{
- const int length = callData->argc - offset;
+ const int length = argc - offset;
if (length == 0) {
dfc.m_args.clear();
return;
}
QV4::Scope scope(engine);
QV4::ScopedArrayObject array(scope, engine->newArrayObject(length));
- int i = 0;
- for (int j = offset; j < callData->argc; ++i, ++j) {
- array->putIndexed(i, callData->args[j]);
- }
+ uint i = 0;
+ for (int j = offset, ej = argc; j < ej; ++i, ++j)
+ array->putIndexed(i, argv[j]);
dfc.m_args.set(engine, array);
}
diff --git a/src/qml/qml/qqmldelayedcallqueue_p.h b/src/qml/qml/qqmldelayedcallqueue_p.h
index cffde4f0c0..47e211829c 100644
--- a/src/qml/qml/qqmldelayedcallqueue_p.h
+++ b/src/qml/qml/qqmldelayedcallqueue_p.h
@@ -60,7 +60,6 @@
QT_BEGIN_NAMESPACE
-class QV8Engine;
class QQmlDelayedCallQueue : public QObject
{
Q_OBJECT
@@ -70,7 +69,7 @@ public:
void init(QV4::ExecutionEngine *);
- void addUniquelyAndExecuteLater(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ QV4::ReturnedValue addUniquelyAndExecuteLater(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
public Q_SLOTS:
void ticked();
@@ -90,7 +89,7 @@ private:
bool m_guarded;
};
- void storeAnyArguments(DelayedFunctionCall& dfc, const QV4::CallData *callData, int offset, QV4::ExecutionEngine *engine);
+ void storeAnyArguments(DelayedFunctionCall& dfc, const QV4::Value *argv, int argc, int offset, QV4::ExecutionEngine *engine);
void executeAllExpired_Later();
QV4::ExecutionEngine *m_engine;
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index f4656bafd2..02e206284b 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -134,21 +134,21 @@ int qmlRegisterUncreatableMetaObject(const QMetaObject &staticMetaObject,
0,
0,
0,
- Q_NULLPTR,
+ nullptr,
reason,
uri, versionMajor, versionMinor, qmlName, &staticMetaObject,
QQmlAttachedPropertiesFunc(),
- Q_NULLPTR,
+ nullptr,
0,
0,
0,
- Q_NULLPTR, Q_NULLPTR,
+ nullptr, nullptr,
- Q_NULLPTR,
+ nullptr,
0
};
@@ -453,6 +453,12 @@ The following functions are also on the Qt object.
\li \c "windows" - Windows
\li \c "winrt" - WinRT / UWP
\endlist
+
+ \row
+ \li \c platform.pluginName
+ \li This is the name of the platform set on the QGuiApplication instance
+ as returned by \l QGuiApplication::platformName()
+
\endtable
*/
@@ -664,7 +670,7 @@ the same object as is returned from the Qt.include() call.
QQmlEnginePrivate::QQmlEnginePrivate(QQmlEngine *e)
: propertyCapture(0), rootContext(0),
-#ifndef QT_NO_QML_DEBUGGER
+#if QT_CONFIG(qml_debug)
profiler(0),
#endif
outputWarningsToMsgLog(true),
@@ -708,7 +714,7 @@ QQmlEnginePrivate::~QQmlEnginePrivate()
QMetaType::unregisterType(iter.value()->metaTypeId);
QMetaType::unregisterType(iter.value()->listMetaTypeId);
}
-#ifndef QT_NO_QML_DEBUGGER
+#if QT_CONFIG(qml_debug)
delete profiler;
#endif
}
@@ -778,7 +784,7 @@ class QQmlThreadNotifierProxyObject : public QObject
public:
QPointer<QObject> target;
- virtual int qt_metacall(QMetaObject::Call, int methodIndex, void **a) {
+ int qt_metacall(QMetaObject::Call, int methodIndex, void **a) override {
if (!target)
return -1;
@@ -1351,6 +1357,30 @@ void QQmlEngine::setOutputWarningsToStandardError(bool enabled)
}
/*!
+ Refreshes all binding expressions that use strings marked for translation.
+
+ Call this function after you have installed a new translator with
+ QCoreApplication::installTranslator, to ensure that your user-interface
+ shows up-to-date translations.
+
+ \note Due to a limitation in the implementation, this function
+ refreshes all the engine's bindings, not only those that use strings
+ marked for translation.
+ This may be optimized in a future release.
+
+ \since 5.10
+*/
+void QQmlEngine::retranslate()
+{
+ Q_D(QQmlEngine);
+ QQmlContextData *context = QQmlContextData::get(d->rootContext)->childContexts;
+ while (context) {
+ context->refreshExpressions();
+ context = context->nextChild;
+ }
+}
+
+/*!
Returns the QQmlContext for the \a object, or 0 if no
context has been set.
@@ -1470,6 +1500,9 @@ bool QQmlEngine::event(QEvent *e)
Q_D(QQmlEngine);
if (e->type() == QEvent::User)
d->doDeleteInEngineThread();
+ else if (e->type() == QEvent::LanguageChange) {
+ retranslate();
+ }
return QJSEngine::event(e);
}
@@ -1519,9 +1552,9 @@ QQmlEngine *qmlEngine(const QObject *obj)
QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool create)
{
- QQmlData *data = QQmlData::get(object);
+ QQmlData *data = QQmlData::get(object, create);
if (!data)
- return 0; // Attached properties are only on objects created by QML
+ return 0; // Attached properties are only on objects created by QML, unless explicitly requested (create==true)
QObject *rv = data->hasExtendedData()?data->attachedProperties()->value(id):0;
if (rv || !create)
@@ -2047,7 +2080,7 @@ void QQmlEnginePrivate::cleanupScarceResources()
// note that the actual SRD is owned by the JS engine,
// so we cannot delete the SRD; but we can free the
// memory used by the variant in the SRD.
- QV4::ExecutionEngine *engine = QV8Engine::getV4(v8engine());
+ QV4::ExecutionEngine *engine = v4engine();
while (QV4::ExecutionEngine::ScarceResourceData *sr = engine->scarceResources.first()) {
sr->data = QVariant();
engine->scarceResources.remove(sr);
@@ -2309,7 +2342,7 @@ QQmlPropertyCache *QQmlEnginePrivate::propertyCacheForType(int t)
}
}
-QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t)
+QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t, int minorVersion)
{
Locker locker(this);
auto iter = m_compositeTypes.constFind(t);
@@ -2318,7 +2351,11 @@ QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t)
} else {
QQmlType type = QQmlMetaType::qmlType(t);
locker.unlock();
- return type.isValid() ? cache(type.baseMetaObject()) : 0;
+
+ if (minorVersion >= 0)
+ return type.isValid() ? cache(type, minorVersion) : 0;
+ else
+ return type.isValid() ? cache(type.baseMetaObject()) : 0;
}
}
diff --git a/src/qml/qml/qqmlengine.h b/src/qml/qml/qqmlengine.h
index 8cada954fe..937920e191 100644
--- a/src/qml/qml/qqmlengine.h
+++ b/src/qml/qml/qqmlengine.h
@@ -46,7 +46,6 @@
#include <QtQml/qjsengine.h>
#include <QtQml/qqml.h>
#include <QtQml/qqmlerror.h>
-#include <QtQml/qqmldebug.h>
QT_BEGIN_NAMESPACE
@@ -97,7 +96,7 @@ class Q_QML_EXPORT QQmlEngine : public QJSEngine
Q_PROPERTY(QString offlineStoragePath READ offlineStoragePath WRITE setOfflineStoragePath)
Q_OBJECT
public:
- explicit QQmlEngine(QObject *p = Q_NULLPTR);
+ explicit QQmlEngine(QObject *p = nullptr);
virtual ~QQmlEngine();
QQmlContext *rootContext() const;
@@ -144,6 +143,10 @@ public:
bool outputWarningsToStandardError() const;
void setOutputWarningsToStandardError(bool);
+public Q_SLOTS:
+ void retranslate();
+
+public:
static QQmlContext *contextForObject(const QObject *);
static void setContextForObject(QObject *, QQmlContext *);
diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h
index fd74a233a4..f12409ed9a 100644
--- a/src/qml/qml/qqmlengine_p.h
+++ b/src/qml/qml/qqmlengine_p.h
@@ -135,7 +135,7 @@ public:
QQmlContext *rootContext;
-#ifdef QT_NO_QML_DEBUGGER
+#if !QT_CONFIG(qml_debug)
static const quintptr profiler = 0;
#else
QQmlProfiler *profiler;
@@ -150,8 +150,8 @@ public:
QQmlDelayedError *erroredBindings;
int inProgressCreations;
- QV8Engine *v8engine() const { return q_func()->handle(); }
- QV4::ExecutionEngine *v4engine() const { return QV8Engine::getV4(q_func()->handle()); }
+ QV8Engine *v8engine() const { return q_func()->handle()->v8Engine; }
+ QV4::ExecutionEngine *v4engine() const { return q_func()->handle(); }
QQuickWorkerScriptEngine *getWorkerScriptEngine();
QQuickWorkerScriptEngine *workerScriptEngine;
@@ -220,7 +220,7 @@ public:
QQmlMetaObject rawMetaObjectForType(int) const;
QQmlMetaObject metaObjectForType(int) const;
QQmlPropertyCache *propertyCacheForType(int);
- QQmlPropertyCache *rawPropertyCacheForType(int);
+ QQmlPropertyCache *rawPropertyCacheForType(int, int minorVersion = -1);
void registerInternalCompositeType(QV4::CompiledData::CompilationUnit *compilationUnit);
void unregisterInternalCompositeType(QV4::CompiledData::CompilationUnit *compilationUnit);
@@ -295,7 +295,7 @@ inline void QQmlEnginePrivate::dereferenceScarceResources()
// expression must have completed. We can safely release the
// scarce resources.
if (Q_LIKELY(scarceResourcesRefCount == 0)) {
- QV4::ExecutionEngine *engine = QV8Engine::getV4(v8engine());
+ QV4::ExecutionEngine *engine = v4engine();
if (Q_UNLIKELY(!engine->scarceResources.isEmpty())) {
cleanupScarceResources();
}
@@ -385,14 +385,14 @@ QV8Engine *QQmlEnginePrivate::getV8Engine(QQmlEngine *e)
{
Q_ASSERT(e);
- return e->d_func()->v8engine();
+ return e->handle()->v8Engine;
}
QV4::ExecutionEngine *QQmlEnginePrivate::getV4Engine(QQmlEngine *e)
{
Q_ASSERT(e);
- return e->d_func()->v4engine();
+ return e->handle();
}
QQmlEnginePrivate *QQmlEnginePrivate::get(QQmlEngine *e)
@@ -428,9 +428,7 @@ QQmlEngine *QQmlEnginePrivate::get(QQmlEnginePrivate *p)
QQmlEnginePrivate *QQmlEnginePrivate::get(QV4::ExecutionEngine *e)
{
- if (!e->v8Engine)
- return 0;
- QQmlEngine *qmlEngine = e->v8Engine->engine();
+ QQmlEngine *qmlEngine = e->qmlEngine();
if (!qmlEngine)
return 0;
return get(qmlEngine);
diff --git a/src/qml/qml/qqmlerror.cpp b/src/qml/qml/qqmlerror.cpp
index 64f008cd32..1b264b025c 100644
--- a/src/qml/qml/qqmlerror.cpp
+++ b/src/qml/qml/qqmlerror.cpp
@@ -268,7 +268,7 @@ QtMsgType QQmlError::messageType() const
\since 5.9
Sets the \a messageType for this message. The message type determines which
- QDebug handlers are responsible for recieving the message.
+ QDebug handlers are responsible for receiving the message.
*/
void QQmlError::setMessageType(QtMsgType messageType)
{
diff --git a/src/qml/qml/qqmlexpression.cpp b/src/qml/qml/qqmlexpression.cpp
index 1e1fbcf448..3ba0afc7bd 100644
--- a/src/qml/qml/qqmlexpression.cpp
+++ b/src/qml/qml/qqmlexpression.cpp
@@ -74,7 +74,7 @@ void QQmlExpressionPrivate::init(QQmlContextData *ctxt, const QString &expr, QOb
void QQmlExpressionPrivate::init(QQmlContextData *ctxt, QV4::Function *runtimeFunction, QObject *me)
{
expressionFunctionValid = true;
- QV4::ExecutionEngine *engine = QQmlEnginePrivate::getV4Engine(ctxt->engine);
+ QV4::ExecutionEngine *engine = ctxt->engine->handle();
QV4::Scope scope(engine);
QV4::Scoped<QV4::QmlContext> qmlContext(scope, QV4::QmlContext::create(engine->rootContext(), ctxt, me));
setupFunction(qmlContext, runtimeFunction);
@@ -247,15 +247,14 @@ void QQmlExpression::setExpression(const QString &expression)
}
// Must be called with a valid handle scope
-void QQmlExpressionPrivate::v4value(bool *isUndefined, QV4::Scope &scope)
+QV4::ReturnedValue QQmlExpressionPrivate::v4value(bool *isUndefined)
{
if (!expressionFunctionValid) {
createQmlBinding(context(), scopeObject(), expression, url, line);
expressionFunctionValid = true;
}
- QV4::ScopedCallData callData(scope);
- evaluate(callData, isUndefined, scope);
+ return evaluate(isUndefined);
}
QVariant QQmlExpressionPrivate::value(bool *isUndefined)
@@ -267,16 +266,17 @@ QVariant QQmlExpressionPrivate::value(bool *isUndefined)
return QVariant();
}
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(q->engine());
+ QQmlEngine *engine = q->engine();
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
QVariant rv;
ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
{
- QV4::Scope scope(QV8Engine::getV4(ep->v8engine()));
- v4value(isUndefined, scope);
+ QV4::Scope scope(engine->handle());
+ QV4::ScopedValue result(scope, v4value(isUndefined));
if (!hasError())
- rv = scope.engine->toVariant(scope.result, -1);
+ rv = scope.engine->toVariant(result, -1);
}
ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
diff --git a/src/qml/qml/qqmlexpression.h b/src/qml/qml/qqmlexpression.h
index 5239d59c8a..e9c8770e92 100644
--- a/src/qml/qml/qqmlexpression.h
+++ b/src/qml/qml/qqmlexpression.h
@@ -60,8 +60,8 @@ class Q_QML_EXPORT QQmlExpression : public QObject
Q_OBJECT
public:
QQmlExpression();
- QQmlExpression(QQmlContext *, QObject *, const QString &, QObject * = Q_NULLPTR);
- explicit QQmlExpression(const QQmlScriptString &, QQmlContext * = Q_NULLPTR, QObject * = Q_NULLPTR, QObject * = Q_NULLPTR);
+ QQmlExpression(QQmlContext *, QObject *, const QString &, QObject * = nullptr);
+ explicit QQmlExpression(const QQmlScriptString &, QQmlContext * = nullptr, QObject * = nullptr, QObject * = nullptr);
virtual ~QQmlExpression();
QQmlEngine *engine() const;
@@ -84,7 +84,7 @@ public:
void clearError();
QQmlError error() const;
- QVariant evaluate(bool *valueIsUndefined = Q_NULLPTR);
+ QVariant evaluate(bool *valueIsUndefined = nullptr);
Q_SIGNALS:
void valueChanged();
diff --git a/src/qml/qml/qqmlexpression_p.h b/src/qml/qml/qqmlexpression_p.h
index 44342a957b..a94ca0fc2d 100644
--- a/src/qml/qml/qqmlexpression_p.h
+++ b/src/qml/qml/qqmlexpression_p.h
@@ -75,7 +75,7 @@ public:
QVariant value(bool *isUndefined = 0);
- void v4value(bool *isUndefined, QV4::Scope &scope);
+ QV4::ReturnedValue v4value(bool *isUndefined = 0);
static inline QQmlExpressionPrivate *get(QQmlExpression *expr);
static inline QQmlExpression *get(QQmlExpressionPrivate *expr);
diff --git a/src/qml/qml/qqmlextensionplugin.h b/src/qml/qml/qqmlextensionplugin.h
index c0915c0abe..84a46fb93e 100644
--- a/src/qml/qml/qqmlextensionplugin.h
+++ b/src/qml/qml/qqmlextensionplugin.h
@@ -58,7 +58,7 @@ class Q_QML_EXPORT QQmlExtensionPlugin
Q_INTERFACES(QQmlExtensionInterface)
Q_INTERFACES(QQmlTypesExtensionInterface)
public:
- explicit QQmlExtensionPlugin(QObject *parent = Q_NULLPTR);
+ explicit QQmlExtensionPlugin(QObject *parent = nullptr);
~QQmlExtensionPlugin();
QUrl baseUrl() const;
diff --git a/src/qml/qml/qqmlfileselector.h b/src/qml/qml/qqmlfileselector.h
index 03b951420e..4eaf92c918 100644
--- a/src/qml/qml/qqmlfileselector.h
+++ b/src/qml/qml/qqmlfileselector.h
@@ -54,7 +54,7 @@ class Q_QML_EXPORT QQmlFileSelector : public QObject
Q_OBJECT
Q_DECLARE_PRIVATE(QQmlFileSelector)
public:
- explicit QQmlFileSelector(QQmlEngine *engine, QObject *parent = Q_NULLPTR);
+ explicit QQmlFileSelector(QQmlEngine *engine, QObject *parent = nullptr);
~QQmlFileSelector();
QFileSelector *selector() const Q_DECL_NOTHROW;
void setSelector(QFileSelector *selector);
diff --git a/src/qml/qml/qqmlglobal.cpp b/src/qml/qml/qqmlglobal.cpp
index 7939656107..6418812bae 100644
--- a/src/qml/qml/qqmlglobal.cpp
+++ b/src/qml/qml/qqmlglobal.cpp
@@ -343,6 +343,8 @@ QObject *QQmlGuiProvider::styleHints()
return o;
}
+QString QQmlGuiProvider::pluginName() const { return QString(); }
+
static QQmlGuiProvider *guiProvider = 0;
Q_QML_PRIVATE_EXPORT QQmlGuiProvider *QQml_setGuiProvider(QQmlGuiProvider *newProvider)
diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h
index 707814e781..5c46da0ea4 100644
--- a/src/qml/qml/qqmlglobal_p.h
+++ b/src/qml/qml/qqmlglobal_p.h
@@ -193,16 +193,6 @@ do { \
return QObjectPrivate::get(sender)->isSignalConnected(signalIdx); \
} while (0)
-struct QQmlGraphics_DerivedObject : public QObject
-{
- void setParent_noEvent(QObject *parent) {
- bool sce = d_ptr->sendChildEvents;
- d_ptr->sendChildEvents = false;
- setParent(parent);
- d_ptr->sendChildEvents = sce;
- }
-};
-
/*!
Returns true if the case of \a fileName is equivalent to the file case of
\a fileName on disk, and false otherwise.
@@ -230,7 +220,11 @@ bool QQml_isFileCaseCorrect(const QString &fileName, int length = -1);
*/
inline void QQml_setParent_noEvent(QObject *object, QObject *parent)
{
- static_cast<QQmlGraphics_DerivedObject *>(object)->setParent_noEvent(parent);
+ QObjectPrivate *d_ptr = QObjectPrivate::get(object);
+ bool sce = d_ptr->sendChildEvents;
+ d_ptr->sendChildEvents = false;
+ object->setParent(parent);
+ d_ptr->sendChildEvents = sce;
}
class Q_QML_PRIVATE_EXPORT QQmlValueTypeProvider
@@ -311,6 +305,7 @@ public:
virtual QObject *styleHints();
virtual QStringList fontFamilies();
virtual bool openUrlExternally(QUrl &);
+ virtual QString pluginName() const;
};
Q_QML_PRIVATE_EXPORT QQmlGuiProvider *QQml_setGuiProvider(QQmlGuiProvider *);
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index f43ffb4c3c..a9113603b8 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -296,7 +296,9 @@ public:
bool resolveType(const QHashedStringRef &type, int *vmajor, int *vminor,
QQmlType *type_return, QList<QQmlError> *errors,
- QQmlType::RegistrationType registrationType);
+ QQmlType::RegistrationType registrationType,
+ QQmlImport::RecursionRestriction recursionRestriction
+ = QQmlImport::PreventRecursion);
QUrl baseUrl;
QString base;
@@ -634,7 +636,8 @@ QString QQmlImports::versionString(int vmaj, int vmin, ImportVersion version)
bool QQmlImports::resolveType(const QHashedStringRef &type,
QQmlType *type_return, int *vmaj, int *vmin,
QQmlImportNamespace** ns_return, QList<QQmlError> *errors,
- QQmlType::RegistrationType registrationType) const
+ QQmlType::RegistrationType registrationType,
+ QQmlImport::RecursionRestriction recursionRestriction) const
{
QQmlImportNamespace* ns = d->findQualifiedNamespace(type);
if (ns) {
@@ -643,7 +646,8 @@ bool QQmlImports::resolveType(const QHashedStringRef &type,
return true;
}
if (type_return) {
- if (d->resolveType(type, vmaj, vmin, type_return, errors, registrationType)) {
+ if (d->resolveType(type, vmaj, vmin, type_return, errors, registrationType,
+ recursionRestriction)) {
if (qmlImportTrace()) {
#define RESOLVE_TYPE_DEBUG qDebug().nospace() << "QQmlImports(" << qPrintable(baseUrl().toString()) \
<< ')' << "::resolveType: " << type.toString() << " => "
@@ -728,9 +732,10 @@ bool QQmlImports::resolveType(QQmlImportNamespace *ns, const QHashedStringRef &t
}
bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef& type,
- int *vmajor, int *vminor, QQmlType* type_return, QString *base,
+ int *vmajor, int *vminor, QQmlType *type_return, QString *base,
bool *typeRecursionDetected,
- QQmlType::RegistrationType registrationType) const
+ QQmlType::RegistrationType registrationType,
+ QQmlImport::RecursionRestriction recursionRestriction) const
{
if (majversion >= 0 && minversion >= 0) {
QQmlType t = QQmlMetaType::qmlType(type, uri, majversion, minversion);
@@ -766,6 +771,7 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt
// importing version -1 means import ALL versions
if ((majversion == -1) ||
+ (implicitlyImported && c.internal) || // allow the implicit import of internal types
(c.majorVersion == majversion && c.minorVersion <= minversion)) {
// Is this better than the previous candidate?
if ((candidate == end) ||
@@ -777,7 +783,7 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt
if (resolveLocalUrl(*base, c.fileName) != componentUrl)
continue; // failed attempt to access an internal type
}
- if (*base == componentUrl) {
+ if (recursionRestriction == QQmlImport::PreventRecursion && *base == componentUrl) {
if (typeRecursionDetected)
*typeRecursionDetected = true;
continue; // no recursion
@@ -820,7 +826,7 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt
}
if (exists) {
- if (base && (*base == qmlUrl)) { // no recursion
+ if (recursionRestriction == QQmlImport::PreventRecursion && base && (*base == qmlUrl)) { // no recursion
if (typeRecursionDetected)
*typeRecursionDetected = true;
} else {
@@ -838,7 +844,8 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, const QHashedSt
bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, int *vmajor, int *vminor,
QQmlType *type_return, QList<QQmlError> *errors,
- QQmlType::RegistrationType registrationType)
+ QQmlType::RegistrationType registrationType,
+ QQmlImport::RecursionRestriction recursionRestriction)
{
QQmlImportNamespace *s = 0;
int dot = type.indexOf(Dot);
@@ -868,7 +875,7 @@ bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, int *vmajor,
QHashedStringRef unqualifiedtype = dot < 0 ? type : QHashedStringRef(type.constData()+dot+1, type.length()-dot-1);
if (s) {
if (s->resolveType(typeLoader, unqualifiedtype, vmajor, vminor, type_return, &base, errors,
- registrationType))
+ registrationType, recursionRestriction))
return true;
if (s->imports.count() == 1 && !s->imports.at(0)->isLibrary && type_return && s != &unqualifiedset) {
// qualified, and only 1 url
@@ -892,13 +899,14 @@ QQmlImportInstance *QQmlImportNamespace::findImport(const QString &uri) const
bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type,
int *vmajor, int *vminor, QQmlType *type_return,
QString *base, QList<QQmlError> *errors,
- QQmlType::RegistrationType registrationType)
+ QQmlType::RegistrationType registrationType,
+ QQmlImport::RecursionRestriction recursionRestriction)
{
bool typeRecursionDetected = false;
for (int i=0; i<imports.count(); ++i) {
const QQmlImportInstance *import = imports.at(i);
- if (import->resolveType(typeLoader, type, vmajor, vminor, type_return,
- base, &typeRecursionDetected, registrationType)) {
+ if (import->resolveType(typeLoader, type, vmajor, vminor, type_return, base,
+ &typeRecursionDetected, registrationType, recursionRestriction)) {
if (qmlCheckTypes()) {
// check for type clashes
for (int j = i+1; j<imports.count(); ++j) {
@@ -973,7 +981,7 @@ QQmlImportNamespace *QQmlImportsPrivate::findQualifiedNamespace(const QHashedStr
return 0;
}
-/*!
+/*
Returns the list of possible versioned URI combinations. For example, if \a uri is
QtQml.Models, \a vmaj is 2, and \a vmin is 0, this method returns the following:
[QtQml.Models.2.0, QtQml.2.0.Models, QtQml.Models.2, QtQml.2.Models, QtQml.Models]
@@ -1009,7 +1017,7 @@ static QVector<QStaticPlugin> makePlugins()
return plugins;
}
-/*!
+/*
Get all static plugins that are QML plugins and has a meta data URI that matches with one of
\a versionUris, which is a list of all possible versioned URI combinations - see versionUriList()
above.
@@ -1051,7 +1059,7 @@ static inline QString msgCannotLoadPlugin(const QString &uri, const QString &why
}
#endif
-/*!
+/*
Import an extension defined by a qmldir file.
\a qmldirFilePath is a raw file path.
@@ -1223,10 +1231,12 @@ QString QQmlImportsPrivate::resolvedUri(const QString &dir_arg, QQmlImportDataba
stableRelativePath.replace(Backslash, Slash);
// remove optional versioning in dot notation from uri
- int lastSlash = stableRelativePath.lastIndexOf(Slash);
- if (lastSlash >= 0) {
- int versionDot = stableRelativePath.indexOf(Dot, lastSlash);
- if (versionDot >= 0)
+ int versionDot = stableRelativePath.lastIndexOf(Dot);
+ if (versionDot >= 0) {
+ int nextSlash = stableRelativePath.indexOf(Slash, versionDot);
+ if (nextSlash >= 0)
+ stableRelativePath.remove(versionDot, nextSlash - versionDot);
+ else
stableRelativePath = stableRelativePath.left(versionDot);
}
@@ -1537,6 +1547,20 @@ bool QQmlImportsPrivate::addFileImport(const QString& uri, const QString &prefix
if (!url.endsWith(Slash) && !url.endsWith(Backslash))
url += Slash;
+ // ### For enum support, we are now adding the implicit import always (and earlier). Bail early
+ // if the implicit import has already been explicitly added, otherwise we can run into issues
+ // with duplicate imports. However remember that we attempted to add this as implicit import, to
+ // allow for the loading of internal types.
+ if (isImplicitImport) {
+ for (QList<QQmlImportInstance *>::const_iterator it = nameSpace->imports.constBegin();
+ it != nameSpace->imports.constEnd(); ++it) {
+ if ((*it)->url == url) {
+ (*it)->implicitlyImported = true;
+ return true;
+ }
+ }
+ }
+
QQmlImportInstance *inserted = addImportToNamespace(nameSpace, importUri, url, vmaj, vmin, QV4::CompiledData::Import::ImportFile, errors, isImplicitImport);
Q_ASSERT(inserted);
@@ -1738,13 +1762,13 @@ QQmlImportDatabase::QQmlImportDatabase(QQmlEngine *e)
// env import paths
if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty("QML2_IMPORT_PATH"))) {
- const QByteArray envImportPath = qgetenv("QML2_IMPORT_PATH");
+ const QString envImportPath = qEnvironmentVariable("QML2_IMPORT_PATH");
#if defined(Q_OS_WIN)
QLatin1Char pathSep(';');
#else
QLatin1Char pathSep(':');
#endif
- QStringList paths = QString::fromLatin1(envImportPath).split(pathSep, QString::SkipEmptyParts);
+ QStringList paths = envImportPath.split(pathSep, QString::SkipEmptyParts);
for (int ii = paths.count() - 1; ii >= 0; --ii)
addImportPath(paths.at(ii));
}
diff --git a/src/qml/qml/qqmlimport_p.h b/src/qml/qml/qqmlimport_p.h
index 9cb5340c68..6298dd9c22 100644
--- a/src/qml/qml/qqmlimport_p.h
+++ b/src/qml/qml/qqmlimport_p.h
@@ -70,6 +70,10 @@ class QQmlImportDatabase;
class QQmlTypeLoader;
class QQmlTypeLoaderQmldirContent;
+namespace QQmlImport {
+ enum RecursionRestriction { PreventRecursion, AllowRecursion };
+}
+
struct QQmlImportInstance
{
QString uri; // e.g. QtQuick
@@ -77,6 +81,7 @@ struct QQmlImportInstance
int majversion; // the major version imported
int minversion; // the minor version imported
bool isLibrary; // true means that this is not a file import
+ bool implicitlyImported = false;
QQmlDirComponents qmlDirComponents; // a copy of the components listed in the qmldir
QQmlDirScripts qmlDirScripts; // a copy of the scripts in the qmldir
@@ -88,7 +93,8 @@ struct QQmlImportInstance
bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type,
int *vmajor, int *vminor, QQmlType* type_return,
QString *base = 0, bool *typeRecursionDetected = 0,
- QQmlType::RegistrationType = QQmlType::AnyRegistrationType) const;
+ QQmlType::RegistrationType = QQmlType::AnyRegistrationType,
+ QQmlImport::RecursionRestriction recursionRestriction = QQmlImport::PreventRecursion) const;
};
class QQmlImportNamespace
@@ -104,8 +110,8 @@ public:
bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef& type,
int *vmajor, int *vminor, QQmlType* type_return,
QString *base = 0, QList<QQmlError> *errors = 0,
- QQmlType::RegistrationType registrationType
- = QQmlType::AnyRegistrationType);
+ QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType,
+ QQmlImport::RecursionRestriction recursionRestriction = QQmlImport::PreventRecursion);
// Prefix when used as a qualified import. Otherwise empty.
QHashedString prefix;
@@ -132,8 +138,9 @@ public:
int *version_major, int *version_minor,
QQmlImportNamespace **ns_return,
QList<QQmlError> *errors = 0,
- QQmlType::RegistrationType registrationType
- = QQmlType::AnyRegistrationType) const;
+ QQmlType::RegistrationType registrationType = QQmlType::AnyRegistrationType,
+ QQmlImport::RecursionRestriction recursionRestriction
+ = QQmlImport::PreventRecursion) const;
bool resolveType(QQmlImportNamespace *,
const QHashedStringRef& type,
QQmlType *type_return, int *version_major, int *version_minor,
diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp
index eec5d1ae57..cd35ab93c6 100644
--- a/src/qml/qml/qqmljavascriptexpression.cpp
+++ b/src/qml/qml/qqmljavascriptexpression.cpp
@@ -46,6 +46,7 @@
#include <private/qv4script_p.h>
#include <private/qv4errorobject_p.h>
#include <private/qv4scopedvalue_p.h>
+#include <private/qv4jscall_p.h>
#include <private/qqmlglobal_p.h>
#include <private/qv4qobjectwrapper_p.h>
#include <private/qqmlbuiltinfunctions_p.h>
@@ -180,9 +181,16 @@ void QQmlJavaScriptExpression::refresh()
{
}
+QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(bool *isUndefined)
+{
+ QV4::ExecutionEngine *v4 = m_context->engine->handle();
+ QV4::Scope scope(v4);
+ QV4::JSCallData jsCall(scope);
+ return evaluate(jsCall.callData(), isUndefined);
+}
-void QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, bool *isUndefined, QV4::Scope &scope)
+QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, bool *isUndefined)
{
Q_ASSERT(m_context && m_context->engine);
@@ -190,7 +198,7 @@ void QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, bool *isUndefin
if (!v4Function) {
if (isUndefined)
*isUndefined = true;
- return;
+ return QV4::Encode::undefined();
}
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(m_context->engine);
@@ -209,20 +217,21 @@ void QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, bool *isUndefin
if (notifyOnValueChanged())
capture.guards.copyAndClearPrepend(activeGuards);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(ep->v8engine());
- scope.result = QV4::Primitive::undefinedValue();
+ QV4::ExecutionEngine *v4 = m_context->engine->handle();
callData->thisObject = v4->globalObject;
if (scopeObject()) {
- QV4::ScopedValue value(scope, QV4::QObjectWrapper::wrap(v4, scopeObject()));
- if (value->isObject())
- callData->thisObject = value;
+ QV4::ReturnedValue scope = QV4::QObjectWrapper::wrap(v4, scopeObject());
+ if (QV4::Value::fromReturnedValue(scope).isObject())
+ callData->thisObject = scope;
}
- QV4::ExecutionContext *outer = static_cast<QV4::ExecutionContext *>(m_qmlScope.valueRef());
- if (v4Function->canUseSimpleFunction()) {
- outer->simpleCall(scope, callData, v4Function);
- } else {
- outer->call(scope, callData, v4Function);
+ Q_ASSERT(m_qmlScope.valueRef());
+ QV4::ReturnedValue res = v4Function->call(&callData->thisObject, callData->args, callData->argc(), static_cast<QV4::ExecutionContext *>(m_qmlScope.valueRef()));
+ QV4::Scope scope(v4);
+ QV4::ScopedValue result(scope, res);
+ if (v4Function->hasQmlDependencies) {
+ QV4::Heap::QmlContext *qc = m_qmlScope.as<QV4::QmlContext>()->d();
+ QQmlPropertyCapture::registerQmlDependencies(qc, v4, v4Function->compiledFunction);
}
if (scope.hasException()) {
@@ -234,7 +243,7 @@ void QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, bool *isUndefin
*isUndefined = true;
} else {
if (isUndefined)
- *isUndefined = scope.result.isUndefined();
+ *isUndefined = result->isUndefined();
if (!watcher.wasDeleted() && hasDelayedError())
delayedError()->clearError();
@@ -251,6 +260,8 @@ void QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, bool *isUndefin
g->Delete();
ep->propertyCapture = lastPropertyCapture;
+
+ return result->asReturnedValue();
}
void QQmlPropertyCapture::captureProperty(QQmlNotifier *n, Duration duration)
@@ -329,12 +340,11 @@ void QQmlPropertyCapture::captureProperty(QObject *o, int c, int n, Duration dur
}
}
-void QQmlPropertyCapture::registerQmlDependencies(const QV4::CompiledData::Function *compiledFunction, const QV4::Scope &scope)
+void QQmlPropertyCapture::registerQmlDependencies(QV4::Heap::QmlContext *context, const QV4::ExecutionEngine *engine, const QV4::CompiledData::Function *compiledFunction)
{
// Let the caller check and avoid the function call :)
Q_ASSERT(compiledFunction->hasQmlDependencies());
- QV4::ExecutionEngine *engine = scope.engine;
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine->qmlEngine());
if (!ep)
return;
@@ -347,10 +357,10 @@ void QQmlPropertyCapture::registerQmlDependencies(const QV4::CompiledData::Funct
capture->expression->m_permanentDependenciesRegistered = true;
- QV4::Scoped<QV4::QmlContext> context(scope, engine->qmlContext());
- QQmlContextData *qmlContext = context->qmlContext();
+ QV4::Heap::QQmlContextWrapper *wrapper = context->qml();
+ QQmlContextData *qmlContext = wrapper->context->contextData();
- const QV4::CompiledData::LEUInt32 *idObjectDependency = compiledFunction->qmlIdObjectDependencyTable();
+ const quint32_le *idObjectDependency = compiledFunction->qmlIdObjectDependencyTable();
const int idObjectDependencyCount = compiledFunction->nDependingIdObjects;
for (int i = 0; i < idObjectDependencyCount; ++i, ++idObjectDependency) {
Q_ASSERT(int(*idObjectDependency) < qmlContext->idValueCount);
@@ -359,7 +369,7 @@ void QQmlPropertyCapture::registerQmlDependencies(const QV4::CompiledData::Funct
}
Q_ASSERT(qmlContext->contextObject);
- const QV4::CompiledData::LEUInt32 *contextPropertyDependency = compiledFunction->qmlContextPropertiesDependencyTable();
+ const quint32_le *contextPropertyDependency = compiledFunction->qmlContextPropertiesDependencyTable();
const int contextPropertyDependencyCount = compiledFunction->nDependingContextProperties;
for (int i = 0; i < contextPropertyDependencyCount; ++i) {
const int propertyIndex = *contextPropertyDependency++;
@@ -368,8 +378,8 @@ void QQmlPropertyCapture::registerQmlDependencies(const QV4::CompiledData::Funct
QQmlPropertyCapture::Permanently);
}
- QObject *scopeObject = context->qmlScope();
- const QV4::CompiledData::LEUInt32 *scopePropertyDependency = compiledFunction->qmlScopePropertiesDependencyTable();
+ QObject *scopeObject = wrapper->scopeObject;
+ const quint32_le *scopePropertyDependency = compiledFunction->qmlScopePropertiesDependencyTable();
const int scopePropertyDependencyCount = compiledFunction->nDependingScopeProperties;
for (int i = 0; i < scopePropertyDependencyCount; ++i) {
const int propertyIndex = *scopePropertyDependency++;
@@ -404,7 +414,7 @@ QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scopeObje
QQmlEngine *engine = ctxt->engine;
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(ep->v8engine());
+ QV4::ExecutionEngine *v4 = engine->handle();
QV4::Scope scope(v4);
QV4::Scoped<QV4::QmlContext> qmlContext(scope, QV4::QmlContext::create(v4->rootContext(), ctxt, scopeObject));
@@ -434,7 +444,7 @@ void QQmlJavaScriptExpression::createQmlBinding(QQmlContextData *ctxt, QObject *
QQmlEngine *engine = ctxt->engine;
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(ep->v8engine());
+ QV4::ExecutionEngine *v4 = engine->handle();
QV4::Scope scope(v4);
QV4::Scoped<QV4::QmlContext> qmlContext(scope, QV4::QmlContext::create(v4->rootContext(), ctxt, qmlScope));
@@ -461,7 +471,12 @@ void QQmlJavaScriptExpression::setupFunction(QV4::ExecutionContext *qmlContext,
return;
m_qmlScope.set(qmlContext->engine(), *qmlContext);
m_v4Function = f;
- m_compilationUnit = m_v4Function->compilationUnit;
+ setCompilationUnit(m_v4Function->compilationUnit);
+}
+
+void QQmlJavaScriptExpression::setCompilationUnit(QV4::CompiledData::CompilationUnit *compilationUnit)
+{
+ m_compilationUnit = compilationUnit;
}
void QQmlJavaScriptExpression::clearActiveGuards()
diff --git a/src/qml/qml/qqmljavascriptexpression_p.h b/src/qml/qml/qqmljavascriptexpression_p.h
index eeed272793..1cb6d7bfd1 100644
--- a/src/qml/qml/qqmljavascriptexpression_p.h
+++ b/src/qml/qml/qqmljavascriptexpression_p.h
@@ -103,7 +103,8 @@ public:
virtual QString expressionIdentifier() const = 0;
virtual void expressionChanged() = 0;
- void evaluate(QV4::CallData *callData, bool *isUndefined, QV4::Scope &scope);
+ QV4::ReturnedValue evaluate(bool *isUndefined);
+ QV4::ReturnedValue evaluate(QV4::CallData *callData, bool *isUndefined);
inline bool notifyOnValueChanged() const;
@@ -160,13 +161,7 @@ protected:
}
void setupFunction(QV4::ExecutionContext *qmlContext, QV4::Function *f);
-
-private:
- friend class QQmlContextData;
- friend class QQmlPropertyCapture;
- friend void QQmlJavaScriptExpressionGuard_callback(QQmlNotifierEndpoint *, void **);
-
- QQmlDelayedError *m_error;
+ void setCompilationUnit(QV4::CompiledData::CompilationUnit *compilationUnit);
// We store some flag bits in the following flag pointers.
// activeGuards:flag1 - notifyOnValueChanged
@@ -175,6 +170,14 @@ private:
QForwardFieldList<QQmlJavaScriptExpressionGuard, &QQmlJavaScriptExpressionGuard::next> activeGuards;
QForwardFieldList<QQmlJavaScriptExpressionGuard, &QQmlJavaScriptExpressionGuard::next> permanentGuards;
+private:
+ friend class QQmlContextData;
+ friend class QQmlPropertyCapture;
+ friend void QQmlJavaScriptExpressionGuard_callback(QQmlNotifierEndpoint *, void **);
+ friend class QQmlTranslationBinding;
+
+ QQmlDelayedError *m_error;
+
QQmlContextData *m_context;
QQmlJavaScriptExpression **m_prevExpression;
QQmlJavaScriptExpression *m_nextExpression;
@@ -202,7 +205,7 @@ public:
Permanently
};
- static void registerQmlDependencies(const QV4::CompiledData::Function *compiledFunction, const QV4::Scope &scope);
+ static void registerQmlDependencies(QV4::Heap::QmlContext *context, const QV4::ExecutionEngine *engine, const QV4::CompiledData::Function *compiledFunction);
void captureProperty(QQmlNotifier *, Duration duration = OnlyOnce);
void captureProperty(QObject *, int, int, Duration duration = OnlyOnce, bool doNotify = true);
diff --git a/src/qml/qml/qqmllist.cpp b/src/qml/qml/qqmllist.cpp
index 71be2e82a3..9bfdd3da35 100644
--- a/src/qml/qml/qqmllist.cpp
+++ b/src/qml/qml/qqmllist.cpp
@@ -374,12 +374,12 @@ The \l {Qt Quick 1} version of this class is named QDeclarativeListProperty.
*/
/*!
-\fn QQmlListProperty::QQmlListProperty()
+\fn template<typename T> QQmlListProperty<T>::QQmlListProperty()
\internal
*/
/*!
-\fn QQmlListProperty::QQmlListProperty(QObject *object, QList<T *> &list)
+\fn template<typename T> QQmlListProperty<T>::QQmlListProperty(QObject *object, QList<T *> &list)
Convenience constructor for making a QQmlListProperty value from an existing
QList \a list. The \a list reference must remain valid for as long as \a object
@@ -391,7 +391,7 @@ can be very useful while prototyping.
*/
/*!
-\fn QQmlListProperty::QQmlListProperty(QObject *object, void *data,
+\fn template<typename T> QQmlListProperty<T>::QQmlListProperty(QObject *object, void *data,
CountFunction count, AtFunction at)
Construct a readonly QQmlListProperty from a set of operation functions
@@ -401,7 +401,7 @@ remains valid while \a object exists.
*/
/*!
-\fn QQmlListProperty::QQmlListProperty(QObject *object, void *data, AppendFunction append,
+\fn template<typename T> QQmlListProperty<T>::QQmlListProperty(QObject *object, void *data, AppendFunction append,
CountFunction count, AtFunction at,
ClearFunction clear)
@@ -432,7 +432,7 @@ Return the number of elements in the list \a property.
*/
/*!
-\fn bool QQmlListProperty::operator==(const QQmlListProperty &other) const
+\fn template<typename T> bool QQmlListProperty<T>::operator==(const QQmlListProperty &other) const
Returns true if this QQmlListProperty is equal to \a other, otherwise false.
*/
diff --git a/src/qml/qml/qqmllist.h b/src/qml/qml/qqmllist.h
index e3955deee5..4c6ae0cb8f 100644
--- a/src/qml/qml/qqmllist.h
+++ b/src/qml/qml/qqmllist.h
@@ -61,20 +61,20 @@ public:
typedef void (*ClearFunction)(QQmlListProperty<T> *);
QQmlListProperty()
- : object(Q_NULLPTR),
- data(Q_NULLPTR),
- append(Q_NULLPTR),
- count(Q_NULLPTR),
- at(Q_NULLPTR),
- clear(Q_NULLPTR),
- dummy1(Q_NULLPTR),
- dummy2(Q_NULLPTR)
+ : object(nullptr),
+ data(nullptr),
+ append(nullptr),
+ count(nullptr),
+ at(nullptr),
+ clear(nullptr),
+ dummy1(nullptr),
+ dummy2(nullptr)
{}
QQmlListProperty(QObject *o, QList<T *> &list)
: object(o), data(&list), append(qlist_append), count(qlist_count), at(qlist_at),
clear(qlist_clear),
- dummy1(Q_NULLPTR),
- dummy2(Q_NULLPTR)
+ dummy1(nullptr),
+ dummy2(nullptr)
{}
QQmlListProperty(QObject *o, void *d, AppendFunction a, CountFunction c, AtFunction t,
ClearFunction r )
@@ -84,17 +84,17 @@ public:
count(c),
at(t),
clear(r),
- dummy1(Q_NULLPTR),
- dummy2(Q_NULLPTR)
+ dummy1(nullptr),
+ dummy2(nullptr)
{}
QQmlListProperty(QObject *o, void *d, CountFunction c, AtFunction t)
: object(o),
data(d),
- append(Q_NULLPTR),
+ append(nullptr),
count(c), at(t),
- clear(Q_NULLPTR),
- dummy1(Q_NULLPTR),
- dummy2(Q_NULLPTR)
+ clear(nullptr),
+ dummy1(nullptr),
+ dummy2(nullptr)
{}
bool operator==(const QQmlListProperty &o) const {
return object == o.object &&
@@ -140,7 +140,7 @@ class Q_QML_EXPORT QQmlListReference
{
public:
QQmlListReference();
- QQmlListReference(QObject *, const char *property, QQmlEngine * = Q_NULLPTR);
+ QQmlListReference(QObject *, const char *property, QQmlEngine * = nullptr);
QQmlListReference(const QQmlListReference &);
QQmlListReference &operator=(const QQmlListReference &);
~QQmlListReference();
diff --git a/src/qml/qml/qqmllistwrapper.cpp b/src/qml/qml/qqmllistwrapper.cpp
index d94f7c56e4..cdeb991e11 100644
--- a/src/qml/qml/qqmllistwrapper.cpp
+++ b/src/qml/qml/qqmllistwrapper.cpp
@@ -140,12 +140,13 @@ ReturnedValue QmlListWrapper::getIndexed(const Managed *m, uint index, bool *has
return Primitive::undefinedValue().asReturnedValue();
}
-void QmlListWrapper::put(Managed *m, String *name, const Value &value)
+bool QmlListWrapper::put(Managed *m, String *name, const Value &value)
{
// doesn't do anything. Should we throw?
Q_UNUSED(m);
Q_UNUSED(name);
Q_UNUSED(value);
+ return false;
}
void QmlListWrapper::advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attrs)
@@ -170,9 +171,10 @@ void PropertyListPrototype::init(ExecutionEngine *)
defineDefaultProperty(QStringLiteral("push"), method_push, 1);
}
-void PropertyListPrototype::method_push(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue PropertyListPrototype::method_push(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
+ Scope scope(b);
+ ScopedObject instance(scope, thisObject->toObject(scope.engine));
if (!instance)
RETURN_UNDEFINED();
QmlListWrapper *w = instance->as<QmlListWrapper>();
@@ -182,12 +184,13 @@ void PropertyListPrototype::method_push(const BuiltinFunction *, Scope &scope, C
THROW_GENERIC_ERROR("List doesn't define an Append function");
QV4::ScopedObject so(scope);
- for (int i = 0; i < callData->argc; ++i)
+ for (int i = 0, ei = argc; i < ei; ++i)
{
- so = callData->args[i].toObject(scope.engine);
+ so = argv[i].toObject(scope.engine);
if (QV4::QObjectWrapper *wrapper = so->as<QV4::QObjectWrapper>())
w->d()->property().append(&w->d()->property(), wrapper->object() );
}
+ return Encode::undefined();
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmllistwrapper_p.h b/src/qml/qml/qqmllistwrapper_p.h
index b914c681f2..e02831c8d1 100644
--- a/src/qml/qml/qqmllistwrapper_p.h
+++ b/src/qml/qml/qqmllistwrapper_p.h
@@ -95,7 +95,7 @@ struct Q_QML_EXPORT QmlListWrapper : Object
static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty);
- static void put(Managed *m, String *name, const Value &value);
+ static bool put(Managed *m, String *name, const Value &value);
static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
};
@@ -103,7 +103,7 @@ struct PropertyListPrototype : Object
{
void init(ExecutionEngine *engine);
- static void method_push(const BuiltinFunction *, Scope &, CallData *callData);
+ static ReturnedValue method_push(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
};
}
diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp
index 326b36c5cd..eafe2792c1 100644
--- a/src/qml/qml/qqmllocale.cpp
+++ b/src/qml/qml/qqmllocale.cpp
@@ -58,8 +58,7 @@ DEFINE_OBJECT_VTABLE(QQmlLocaleData);
#define THROW_ERROR(string) \
do { \
- scope.result = scope.engine->throwError(QString::fromUtf8(string)); \
- return; \
+ return scope.engine->throwError(QString::fromUtf8(string)); \
} while (false)
@@ -87,42 +86,37 @@ void QQmlDateExtension::registerExtension(QV4::ExecutionEngine *engine)
engine->dateCtor()->defineDefaultProperty(QStringLiteral("timeZoneUpdated"), method_timeZoneUpdated);
}
-void QQmlDateExtension::method_toLocaleString(const BuiltinFunction *b, Scope &scope, CallData *callData)
+ReturnedValue QQmlDateExtension::method_toLocaleString(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- if (callData->argc > 2) {
- QV4::DatePrototype::method_toLocaleString(b, scope, callData);
- return;
- }
+ Scope scope(b);
+ if (argc > 2)
+ return QV4::DatePrototype::method_toLocaleString(b, thisObject, argv, argc);
- QV4::DateObject *date = callData->thisObject.as<DateObject>();
- if (!date) {
- QV4::DatePrototype::method_toLocaleString(b, scope, callData);
- return;
- }
+ const QV4::DateObject *date = thisObject->as<DateObject>();
+ if (!date)
+ return QV4::DatePrototype::method_toLocaleString(b, thisObject, argv, argc);
QDateTime dt = date->toQDateTime();
- if (callData->argc == 0) {
+ if (argc == 0) {
// Use QLocale for standard toLocaleString() function
QLocale locale;
RETURN_RESULT(scope.engine->newString(locale.toString(dt)));
}
- if (!isLocaleObject(callData->args[0])) {
- QV4::DatePrototype::method_toLocaleString(b, scope, callData); // Use the default Date toLocaleString()
- return;
- }
+ if (!isLocaleObject(argv[0]))
+ return QV4::DatePrototype::method_toLocaleString(b, thisObject, argv, argc); // Use the default Date toLocaleString()
- GET_LOCALE_DATA_RESOURCE(callData->args[0]);
+ GET_LOCALE_DATA_RESOURCE(argv[0]);
QLocale::FormatType enumFormat = QLocale::LongFormat;
QString formattedDt;
- if (callData->argc == 2) {
- if (String *s = callData->args[1].stringValue()) {
+ if (argc == 2) {
+ if (String *s = argv[1].stringValue()) {
QString format = s->toQString();
formattedDt = r->d()->locale->toString(dt, format);
- } else if (callData->args[1].isNumber()) {
- quint32 intFormat = callData->args[1].toNumber();
+ } else if (argv[1].isNumber()) {
+ quint32 intFormat = argv[1].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
formattedDt = r->d()->locale->toString(dt, format);
} else {
@@ -132,44 +126,41 @@ void QQmlDateExtension::method_toLocaleString(const BuiltinFunction *b, Scope &s
formattedDt = r->d()->locale->toString(dt, enumFormat);
}
- scope.result = scope.engine->newString(formattedDt);
+ RETURN_RESULT(scope.engine->newString(formattedDt));
}
-void QQmlDateExtension::method_toLocaleTimeString(const BuiltinFunction *b, Scope &scope, CallData *callData)
+ReturnedValue QQmlDateExtension::method_toLocaleTimeString(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- if (callData->argc > 2) {
- QV4::DatePrototype::method_toLocaleTimeString(b, scope, callData);
- return;
- }
+ Scope scope(b);
+ if (argc > 2)
+ return QV4::DatePrototype::method_toLocaleTimeString(b, thisObject, argv, argc);
- QV4::DateObject *date = callData->thisObject.as<DateObject>();
- if (!date) {
- QV4::DatePrototype::method_toLocaleTimeString(b, scope, callData);
- return;
- }
+ const QV4::DateObject *date = thisObject->as<DateObject>();
+ if (!date)
+ return QV4::DatePrototype::method_toLocaleTimeString(b, thisObject, argv, argc);
QDateTime dt = date->toQDateTime();
QTime time = dt.time();
- if (callData->argc == 0) {
+ if (argc == 0) {
// Use QLocale for standard toLocaleString() function
QLocale locale;
RETURN_RESULT(scope.engine->newString(locale.toString(time)));
}
- if (!isLocaleObject(callData->args[0]))
- return QV4::DatePrototype::method_toLocaleTimeString(b, scope, callData); // Use the default Date toLocaleTimeString()
+ if (!isLocaleObject(argv[0]))
+ return QV4::DatePrototype::method_toLocaleTimeString(b, thisObject, argv, argc); // Use the default Date toLocaleTimeString()
- GET_LOCALE_DATA_RESOURCE(callData->args[0]);
+ GET_LOCALE_DATA_RESOURCE(argv[0]);
QLocale::FormatType enumFormat = QLocale::LongFormat;
QString formattedTime;
- if (callData->argc == 2) {
- if (String *s = callData->args[1].stringValue()) {
+ if (argc == 2) {
+ if (String *s = argv[1].stringValue()) {
QString format = s->toQString();
formattedTime = r->d()->locale->toString(time, format);
- } else if (callData->args[1].isNumber()) {
- quint32 intFormat = callData->args[1].toNumber();
+ } else if (argv[1].isNumber()) {
+ quint32 intFormat = argv[1].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
formattedTime = r->d()->locale->toString(time, format);
} else {
@@ -179,44 +170,41 @@ void QQmlDateExtension::method_toLocaleTimeString(const BuiltinFunction *b, Scop
formattedTime = r->d()->locale->toString(time, enumFormat);
}
- scope.result = scope.engine->newString(formattedTime);
+ RETURN_RESULT(scope.engine->newString(formattedTime));
}
-void QQmlDateExtension::method_toLocaleDateString(const BuiltinFunction *b, Scope &scope, CallData *callData)
+ReturnedValue QQmlDateExtension::method_toLocaleDateString(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- if (callData->argc > 2) {
- QV4::DatePrototype::method_toLocaleDateString(b, scope, callData);
- return;
- }
+ Scope scope(b);
+ if (argc > 2)
+ return QV4::DatePrototype::method_toLocaleDateString(b, thisObject, argv, argc);
- QV4::DateObject *dateObj = callData->thisObject.as<DateObject>();
- if (!dateObj) {
- QV4::DatePrototype::method_toLocaleDateString(b, scope, callData);
- return;
- }
+ const QV4::DateObject *dateObj = thisObject->as<DateObject>();
+ if (!dateObj)
+ return QV4::DatePrototype::method_toLocaleDateString(b, thisObject, argv, argc);
QDateTime dt = dateObj->toQDateTime();
QDate date = dt.date();
- if (callData->argc == 0) {
+ if (argc == 0) {
// Use QLocale for standard toLocaleString() function
QLocale locale;
RETURN_RESULT(scope.engine->newString(locale.toString(date)));
}
- if (!isLocaleObject(callData->args[0]))
- return QV4::DatePrototype::method_toLocaleDateString(b, scope, callData); // Use the default Date toLocaleDateString()
+ if (!isLocaleObject(argv[0]))
+ return QV4::DatePrototype::method_toLocaleDateString(b, thisObject, argv, argc); // Use the default Date toLocaleDateString()
- GET_LOCALE_DATA_RESOURCE(callData->args[0]);
+ GET_LOCALE_DATA_RESOURCE(argv[0]);
QLocale::FormatType enumFormat = QLocale::LongFormat;
QString formattedDate;
- if (callData->argc == 2) {
- if (String *s = callData->args[1].stringValue()) {
+ if (argc == 2) {
+ if (String *s = argv[1].stringValue()) {
QString format = s->toQString();
formattedDate = r->d()->locale->toString(date, format);
- } else if (callData->args[1].isNumber()) {
- quint32 intFormat = callData->args[1].toNumber();
+ } else if (argv[1].isNumber()) {
+ quint32 intFormat = argv[1].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
formattedDate = r->d()->locale->toString(date, format);
} else {
@@ -226,14 +214,15 @@ void QQmlDateExtension::method_toLocaleDateString(const BuiltinFunction *b, Scop
formattedDate = r->d()->locale->toString(date, enumFormat);
}
- scope.result = scope.engine->newString(formattedDate);
+ RETURN_RESULT(scope.engine->newString(formattedDate));
}
-void QQmlDateExtension::method_fromLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QQmlDateExtension::method_fromLocaleString(const QV4::FunctionObject *b, const QV4::Value *, const QV4::Value *argv, int argc)
{
+ QV4::Scope scope(b);
QV4::ExecutionEngine * const engine = scope.engine;
- if (callData->argc == 1) {
- if (String *s = callData->args[0].stringValue()) {
+ if (argc == 1) {
+ if (String *s = argv[0].stringValue()) {
QLocale locale;
QString dateString = s->toQString();
QDateTime dt = locale.toDateTime(dateString);
@@ -241,20 +230,20 @@ void QQmlDateExtension::method_fromLocaleString(const BuiltinFunction *, Scope &
}
}
- if (callData->argc < 1 || callData->argc > 3 || !isLocaleObject(callData->args[0]))
+ if (argc < 1 || argc > 3 || !isLocaleObject(argv[0]))
THROW_ERROR("Locale: Date.fromLocaleString(): Invalid arguments");
- GET_LOCALE_DATA_RESOURCE(callData->args[0]);
+ GET_LOCALE_DATA_RESOURCE(argv[0]);
QLocale::FormatType enumFormat = QLocale::LongFormat;
QDateTime dt;
- QString dateString = callData->args[1].toQStringNoThrow();
- if (callData->argc == 3) {
- if (String *s = callData->args[2].stringValue()) {
+ QString dateString = argv[1].toQStringNoThrow();
+ if (argc == 3) {
+ if (String *s = argv[2].stringValue()) {
QString format = s->toQString();
dt = r->d()->locale->toDateTime(dateString, format);
- } else if (callData->args[2].isNumber()) {
- quint32 intFormat = callData->args[2].toNumber();
+ } else if (argv[2].isNumber()) {
+ quint32 intFormat = argv[2].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
dt = r->d()->locale->toDateTime(dateString, format);
} else {
@@ -264,15 +253,16 @@ void QQmlDateExtension::method_fromLocaleString(const BuiltinFunction *, Scope &
dt = r->d()->locale->toDateTime(dateString, enumFormat);
}
- scope.result = engine->newDateObject(dt);
+ RETURN_RESULT(engine->newDateObject(dt));
}
-void QQmlDateExtension::method_fromLocaleTimeString(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QQmlDateExtension::method_fromLocaleTimeString(const QV4::FunctionObject *b, const QV4::Value *, const QV4::Value *argv, int argc)
{
+ QV4::Scope scope(b);
QV4::ExecutionEngine * const engine = scope.engine;
- if (callData->argc == 1) {
- if (String *s = callData->args[0].stringValue()) {
+ if (argc == 1) {
+ if (String *s = argv[0].stringValue()) {
QLocale locale;
QString timeString = s->toQString();
QTime time = locale.toTime(timeString);
@@ -282,20 +272,20 @@ void QQmlDateExtension::method_fromLocaleTimeString(const BuiltinFunction *, Sco
}
}
- if (callData->argc < 1 || callData->argc > 3 || !isLocaleObject(callData->args[0]))
+ if (argc < 1 || argc > 3 || !isLocaleObject(argv[0]))
THROW_ERROR("Locale: Date.fromLocaleTimeString(): Invalid arguments");
- GET_LOCALE_DATA_RESOURCE(callData->args[0]);
+ GET_LOCALE_DATA_RESOURCE(argv[0]);
QLocale::FormatType enumFormat = QLocale::LongFormat;
QTime tm;
- QString dateString = callData->args[1].toQStringNoThrow();
- if (callData->argc == 3) {
- if (String *s = callData->args[2].stringValue()) {
+ QString dateString = argv[1].toQStringNoThrow();
+ if (argc == 3) {
+ if (String *s = argv[2].stringValue()) {
QString format = s->toQString();
tm = r->d()->locale->toTime(dateString, format);
- } else if (callData->args[2].isNumber()) {
- quint32 intFormat = callData->args[2].toNumber();
+ } else if (argv[2].isNumber()) {
+ quint32 intFormat = argv[2].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
tm = r->d()->locale->toTime(dateString, format);
} else {
@@ -314,12 +304,13 @@ void QQmlDateExtension::method_fromLocaleTimeString(const BuiltinFunction *, Sco
RETURN_RESULT(engine->newDateObject(dt));
}
-void QQmlDateExtension::method_fromLocaleDateString(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QQmlDateExtension::method_fromLocaleDateString(const QV4::FunctionObject *b, const QV4::Value *, const QV4::Value *argv, int argc)
{
+ QV4::Scope scope(b);
QV4::ExecutionEngine * const engine = scope.engine;
- if (callData->argc == 1) {
- if (String *s = callData->args[0].stringValue()) {
+ if (argc == 1) {
+ if (String *s = argv[0].stringValue()) {
QLocale locale;
QString dateString = s->toQString();
QDate date = locale.toDate(dateString);
@@ -327,20 +318,20 @@ void QQmlDateExtension::method_fromLocaleDateString(const BuiltinFunction *, Sco
}
}
- if (callData->argc < 1 || callData->argc > 3 || !isLocaleObject(callData->args[0]))
+ if (argc < 1 || argc > 3 || !isLocaleObject(argv[0]))
THROW_ERROR("Locale: Date.fromLocaleDateString(): Invalid arguments");
- GET_LOCALE_DATA_RESOURCE(callData->args[0]);
+ GET_LOCALE_DATA_RESOURCE(argv[0]);
QLocale::FormatType enumFormat = QLocale::LongFormat;
QDate dt;
- QString dateString = callData->args[1].toQStringNoThrow();
- if (callData->argc == 3) {
- if (String *s = callData->args[2].stringValue()) {
+ QString dateString = argv[1].toQStringNoThrow();
+ if (argc == 3) {
+ if (String *s = argv[2].stringValue()) {
QString format = s->toQString();
dt = r->d()->locale->toDate(dateString, format);
- } else if (callData->args[2].isNumber()) {
- quint32 intFormat = callData->args[2].toNumber();
+ } else if (argv[2].isNumber()) {
+ quint32 intFormat = argv[2].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
dt = r->d()->locale->toDate(dateString, format);
} else {
@@ -353,9 +344,10 @@ void QQmlDateExtension::method_fromLocaleDateString(const BuiltinFunction *, Sco
RETURN_RESULT(engine->newDateObject(QDateTime(dt)));
}
-void QQmlDateExtension::method_timeZoneUpdated(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QQmlDateExtension::method_timeZoneUpdated(const QV4::FunctionObject *b, const QV4::Value *, const QV4::Value *, int argc)
{
- if (callData->argc != 0)
+ QV4::Scope scope(b);
+ if (argc != 0)
THROW_ERROR("Locale: Date.timeZoneUpdated(): Invalid arguments");
QV4::DatePrototype::timezoneUpdated();
@@ -373,91 +365,92 @@ void QQmlNumberExtension::registerExtension(QV4::ExecutionEngine *engine)
engine->numberCtor()->defineDefaultProperty(QStringLiteral("fromLocaleString"), method_fromLocaleString);
}
-void QQmlNumberExtension::method_toLocaleString(const BuiltinFunction *b, Scope &scope, CallData *callData)
+QV4::ReturnedValue QQmlNumberExtension::method_toLocaleString(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- if (callData->argc > 3)
+ QV4::Scope scope(b);
+ if (argc > 3)
THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
- double number = callData->thisObject.toNumber();
+ double number = thisObject->toNumber();
- if (callData->argc == 0) {
+ if (argc == 0) {
// Use QLocale for standard toLocaleString() function
QLocale locale;
RETURN_RESULT(scope.engine->newString(locale.toString(number)));
}
- if (!isLocaleObject(callData->args[0])) {
- QV4::NumberPrototype::method_toLocaleString(b, scope, callData); // Use the default Number toLocaleString()
- return;
- }
+ if (!isLocaleObject(argv[0]))
+ return QV4::NumberPrototype::method_toLocaleString(b, thisObject, argv, argc); // Use the default Number toLocaleString()
- GET_LOCALE_DATA_RESOURCE(callData->args[0]);
+ GET_LOCALE_DATA_RESOURCE(argv[0]);
quint16 format = 'f';
- if (callData->argc > 1) {
- if (!callData->args[1].isString())
+ if (argc > 1) {
+ if (!argv[1].isString())
THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
- QString fs = callData->args[1].toQString();
+ QString fs = argv[1].toQString();
if (fs.length())
format = fs.at(0).unicode();
}
int prec = 2;
- if (callData->argc > 2) {
- if (!callData->args[2].isNumber())
+ if (argc > 2) {
+ if (!argv[2].isNumber())
THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
- prec = callData->args[2].toInt32();
+ prec = argv[2].toInt32();
}
- scope.result = scope.engine->newString(r->d()->locale->toString(number, (char)format, prec));
+ RETURN_RESULT(scope.engine->newString(r->d()->locale->toString(number, (char)format, prec)));
}
-void QQmlNumberExtension::method_toLocaleCurrencyString(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QQmlNumberExtension::method_toLocaleCurrencyString(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- if (callData->argc > 2)
+ QV4::Scope scope(b);
+ if (argc > 2)
THROW_ERROR("Locale: Number.toLocaleCurrencyString(): Invalid arguments");
- double number = callData->thisObject.toNumber();
+ double number = thisObject->toNumber();
- if (callData->argc == 0) {
+ if (argc == 0) {
// Use QLocale for standard toLocaleString() function
QLocale locale;
RETURN_RESULT(scope.engine->newString(locale.toString(number)));
}
- if (!isLocaleObject(callData->args[0]))
+ if (!isLocaleObject(argv[0]))
THROW_ERROR("Locale: Number.toLocaleCurrencyString(): Invalid arguments");
- GET_LOCALE_DATA_RESOURCE(callData->args[0]);
+ GET_LOCALE_DATA_RESOURCE(argv[0]);
QString symbol;
- if (callData->argc > 1) {
- if (!callData->args[1].isString())
+ if (argc > 1) {
+ if (!argv[1].isString())
THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
- symbol = callData->args[1].toQStringNoThrow();
+ symbol = argv[1].toQStringNoThrow();
}
RETURN_RESULT(scope.engine->newString(r->d()->locale->toCurrencyString(number, symbol)));
}
-void QQmlNumberExtension::method_fromLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QQmlNumberExtension::method_fromLocaleString(const QV4::FunctionObject *b, const QV4::Value *, const QV4::Value *argv, int argc)
{
- if (callData->argc < 1 || callData->argc > 2)
+ QV4::Scope scope(b);
+ if (argc < 1 || argc > 2)
THROW_ERROR("Locale: Number.fromLocaleString(): Invalid arguments");
int numberIdx = 0;
QLocale locale;
- if (callData->argc == 2) {
- if (!isLocaleObject(callData->args[0]))
+ if (argc == 2) {
+ if (!isLocaleObject(argv[0]))
THROW_ERROR("Locale: Number.fromLocaleString(): Invalid arguments");
- GET_LOCALE_DATA_RESOURCE(callData->args[0]);
+ GET_LOCALE_DATA_RESOURCE(argv[0]);
locale = *r->d()->locale;
numberIdx = 1;
}
- QString ns = callData->args[numberIdx].toQString();
+ QString ns = argv[numberIdx].toQString();
if (!ns.length())
RETURN_RESULT(QV4::Encode(Q_QNAN));
@@ -467,45 +460,49 @@ void QQmlNumberExtension::method_fromLocaleString(const BuiltinFunction *, Scope
if (!ok)
THROW_ERROR("Locale: Number.fromLocaleString(): Invalid format");
- scope.result = QV4::Encode(val);
+ RETURN_RESULT(QV4::Encode(val));
}
//--------------
// Locale object
-void QQmlLocaleData::method_get_firstDayOfWeek(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QQmlLocaleData::method_get_firstDayOfWeek(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QLocale *locale = getThisLocale(scope, callData);
+ QV4::Scope scope(b);
+ const QLocale *locale = getThisLocale(scope, thisObject);
if (!locale)
- return;
+ return Encode::undefined();
int fdow = int(locale->firstDayOfWeek());
if (fdow == 7)
fdow = 0; // Qt::Sunday = 7, but Sunday is 0 in JS Date
- scope.result = QV4::Encode(fdow);
+ RETURN_RESULT(fdow);
}
-void QQmlLocaleData::method_get_measurementSystem(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QQmlLocaleData::method_get_measurementSystem(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QLocale *locale = getThisLocale(scope, callData);
+ QV4::Scope scope(b);
+ const QLocale *locale = getThisLocale(scope, thisObject);
if (!locale)
- return;
- scope.result = QV4::Encode(locale->measurementSystem());
+ return Encode::undefined();
+ return QV4::Encode(locale->measurementSystem());
}
-void QQmlLocaleData::method_get_textDirection(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QQmlLocaleData::method_get_textDirection(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QLocale *locale = getThisLocale(scope, callData);
+ QV4::Scope scope(b);
+ const QLocale *locale = getThisLocale(scope, thisObject);
if (!locale)
- return;
+ return Encode::undefined();
- scope.result = QV4::Encode(locale->textDirection());
+ return QV4::Encode(locale->textDirection());
}
-void QQmlLocaleData::method_get_weekDays(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QQmlLocaleData::method_get_weekDays(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QLocale *locale = getThisLocale(scope, callData);
+ QV4::Scope scope(b);
+ const QLocale *locale = getThisLocale(scope, thisObject);
if (!locale)
- return;
+ return Encode::undefined();
QList<Qt::DayOfWeek> days = locale->weekdays();
@@ -519,14 +516,15 @@ void QQmlLocaleData::method_get_weekDays(const BuiltinFunction *, Scope &scope,
}
result->setArrayLengthUnchecked(days.size());
- scope.result = result.asReturnedValue();
+ return result.asReturnedValue();
}
-void QQmlLocaleData::method_get_uiLanguages(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QQmlLocaleData::method_get_uiLanguages(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QLocale *locale = getThisLocale(scope, callData);
+ QV4::Scope scope(b);
+ const QLocale *locale = getThisLocale(scope, thisObject);
if (!locale)
- return;
+ return Encode::undefined();
QStringList langs = locale->uiLanguages();
QV4::ScopedArrayObject result(scope, scope.engine->newArrayObject());
@@ -537,40 +535,42 @@ void QQmlLocaleData::method_get_uiLanguages(const BuiltinFunction *, Scope &scop
result->setArrayLengthUnchecked(langs.size());
- scope.result = result.asReturnedValue();
+ return result.asReturnedValue();
}
-void QQmlLocaleData::method_currencySymbol(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QQmlLocaleData::method_currencySymbol(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QLocale *locale = getThisLocale(scope, callData);
+ QV4::Scope scope(b);
+ const QLocale *locale = getThisLocale(scope, thisObject);
if (!locale)
- return;
+ return Encode::undefined();
- if (callData->argc > 1)
+ if (argc > 1)
THROW_ERROR("Locale: currencySymbol(): Invalid arguments");
QLocale::CurrencySymbolFormat format = QLocale::CurrencySymbol;
- if (callData->argc == 1) {
- quint32 intFormat = callData->args[0].toNumber();
+ if (argc == 1) {
+ quint32 intFormat = argv[0].toNumber();
format = QLocale::CurrencySymbolFormat(intFormat);
}
- scope.result = scope.engine->newString(locale->currencySymbol(format));
+ RETURN_RESULT(scope.engine->newString(locale->currencySymbol(format)));
}
#define LOCALE_FORMAT(FUNC) \
-void QQmlLocaleData::method_ ##FUNC (const BuiltinFunction *, Scope &scope, CallData *callData) { \
- QLocale *locale = getThisLocale(scope, callData); \
+ReturnedValue QQmlLocaleData::method_ ##FUNC (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) { \
+ QV4::Scope scope(b); \
+ const QLocale *locale = getThisLocale(scope, thisObject); \
if (!locale) \
- return; \
- if (callData->argc > 1) \
+ return Encode::undefined(); \
+ if (argc > 1) \
THROW_ERROR("Locale: " #FUNC "(): Invalid arguments"); \
QLocale::FormatType format = QLocale::LongFormat;\
- if (callData->argc == 1) { \
- quint32 intFormat = callData->args[0].toUInt32(); \
+ if (argc == 1) { \
+ quint32 intFormat = argv[0].toUInt32(); \
format = QLocale::FormatType(intFormat); \
} \
- scope.result = scope.engine->newString(locale-> FUNC (format)); \
+ RETURN_RESULT(scope.engine->newString(locale-> FUNC (format))); \
}
LOCALE_FORMAT(dateTimeFormat)
@@ -579,20 +579,21 @@ LOCALE_FORMAT(dateFormat)
// +1 added to idx because JS is 0-based, whereas QLocale months begin at 1.
#define LOCALE_FORMATTED_MONTHNAME(VARIABLE) \
-void QQmlLocaleData::method_ ## VARIABLE (const BuiltinFunction *, Scope &scope, CallData *callData) {\
- QLocale *locale = getThisLocale(scope, callData); \
+ReturnedValue QQmlLocaleData::method_ ## VARIABLE (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) {\
+ Scope scope(b); \
+ const QLocale *locale = getThisLocale(scope, thisObject); \
if (!locale) \
- return; \
- if (callData->argc < 1 || callData->argc > 2) \
+ return Encode::undefined(); \
+ if (argc < 1 || argc > 2) \
THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \
QLocale::FormatType enumFormat = QLocale::LongFormat; \
- int idx = callData->args[0].toInt32() + 1; \
+ int idx = argv[0].toInt32() + 1; \
if (idx < 1 || idx > 12) \
THROW_ERROR("Locale: Invalid month"); \
QString name; \
- if (callData->argc == 2) { \
- if (callData->args[1].isNumber()) { \
- quint32 intFormat = callData->args[1].toUInt32(); \
+ if (argc == 2) { \
+ if (argv[1].isNumber()) { \
+ quint32 intFormat = argv[1].toUInt32(); \
QLocale::FormatType format = QLocale::FormatType(intFormat); \
name = locale-> VARIABLE(idx, format); \
} else { \
@@ -601,26 +602,27 @@ void QQmlLocaleData::method_ ## VARIABLE (const BuiltinFunction *, Scope &scope,
} else { \
name = locale-> VARIABLE(idx, enumFormat); \
} \
- scope.result = scope.engine->newString(name); \
+ RETURN_RESULT(scope.engine->newString(name)); \
}
// 0 -> 7 as Qt::Sunday is 7, but Sunday is 0 in JS Date
#define LOCALE_FORMATTED_DAYNAME(VARIABLE) \
-void QQmlLocaleData::method_ ## VARIABLE (const BuiltinFunction *, Scope &scope, CallData *callData) {\
- QLocale *locale = getThisLocale(scope, callData); \
+ReturnedValue QQmlLocaleData::method_ ## VARIABLE (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc) {\
+ Scope scope(b); \
+ const QLocale *locale = getThisLocale(scope, thisObject); \
if (!locale) \
- return; \
- if (callData->argc < 1 || callData->argc > 2) \
+ return Encode::undefined(); \
+ if (argc < 1 || argc > 2) \
THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \
QLocale::FormatType enumFormat = QLocale::LongFormat; \
- int idx = callData->args[0].toInt32(); \
+ int idx = argv[0].toInt32(); \
if (idx < 0 || idx > 7) \
THROW_ERROR("Locale: Invalid day"); \
if (idx == 0) idx = 7; \
QString name; \
- if (callData->argc == 2) { \
- if (callData->args[1].isNumber()) { \
- quint32 intFormat = callData->args[1].toUInt32(); \
+ if (argc == 2) { \
+ if (argv[1].isNumber()) { \
+ quint32 intFormat = argv[1].toUInt32(); \
QLocale::FormatType format = QLocale::FormatType(intFormat); \
name = locale-> VARIABLE(idx, format); \
} else { \
@@ -629,7 +631,7 @@ void QQmlLocaleData::method_ ## VARIABLE (const BuiltinFunction *, Scope &scope,
} else { \
name = locale-> VARIABLE(idx, enumFormat); \
} \
- scope.result = scope.engine->newString(name); \
+ RETURN_RESULT(scope.engine->newString(name)); \
}
LOCALE_FORMATTED_MONTHNAME(monthName)
@@ -637,12 +639,14 @@ LOCALE_FORMATTED_MONTHNAME(standaloneMonthName)
LOCALE_FORMATTED_DAYNAME(dayName)
LOCALE_FORMATTED_DAYNAME(standaloneDayName)
-#define LOCALE_STRING_PROPERTY(VARIABLE) void QQmlLocaleData::method_get_ ## VARIABLE (const BuiltinFunction *, Scope &scope, CallData *callData) \
+#define LOCALE_STRING_PROPERTY(VARIABLE) \
+ReturnedValue QQmlLocaleData::method_get_ ## VARIABLE (const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) \
{ \
- QLocale *locale = getThisLocale(scope, callData); \
+ Scope scope(b); \
+ const QLocale *locale = getThisLocale(scope, thisObject); \
if (!locale) \
- return; \
- scope.result = scope.engine->newString(locale-> VARIABLE());\
+ return Encode::undefined(); \
+ RETURN_RESULT(scope.engine->newString(locale-> VARIABLE()));\
}
LOCALE_STRING_PROPERTY(name)
@@ -833,22 +837,18 @@ void QQmlLocale::registerStringLocaleCompare(QV4::ExecutionEngine *engine)
engine->stringPrototype()->defineDefaultProperty(QStringLiteral("localeCompare"), method_localeCompare);
}
-void QQmlLocale::method_localeCompare(const BuiltinFunction *b, Scope &scope, CallData *callData)
+ReturnedValue QQmlLocale::method_localeCompare(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- if (callData->argc != 1 || (!callData->args[0].isString() && !callData->args[0].as<StringObject>())) {
- QV4::StringPrototype::method_localeCompare(b, scope, callData);
- return;
- }
+ if (argc != 1 || (!argv[0].isString() && !argv[0].as<StringObject>()))
+ return QV4::StringPrototype::method_localeCompare(b, thisObject, argv, argc);
- if (!callData->thisObject.isString() && !callData->thisObject.as<StringObject>()) {
- QV4::StringPrototype::method_localeCompare(b, scope, callData);
- return;
- }
+ if (!thisObject->isString() && !thisObject->as<StringObject>())
+ return QV4::StringPrototype::method_localeCompare(b, thisObject, argv, argc);
- QString thisString = callData->thisObject.toQStringNoThrow();
- QString thatString = callData->args[0].toQStringNoThrow();
+ QString thisString = thisObject->toQStringNoThrow();
+ QString thatString = argv[0].toQStringNoThrow();
- scope.result = QV4::Encode(QString::localeAwareCompare(thisString, thatString));
+ return QV4::Encode(QString::localeAwareCompare(thisString, thatString));
}
/*!
diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h
index 1a2ffc72b0..57666c64f1 100644
--- a/src/qml/qml/qqmllocale_p.h
+++ b/src/qml/qml/qqmllocale_p.h
@@ -67,13 +67,13 @@ public:
static void registerExtension(QV4::ExecutionEngine *engine);
private:
- static void method_toLocaleString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_toLocaleTimeString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_toLocaleDateString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_fromLocaleString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_fromLocaleTimeString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_fromLocaleDateString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_timeZoneUpdated(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static QV4::ReturnedValue method_toLocaleString(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_toLocaleTimeString(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_toLocaleDateString(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_fromLocaleString(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_fromLocaleTimeString(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_fromLocaleDateString(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_timeZoneUpdated(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
};
@@ -83,9 +83,9 @@ public:
static void registerExtension(QV4::ExecutionEngine *engine);
private:
- static void method_toLocaleString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_fromLocaleString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_toLocaleCurrencyString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static QV4::ReturnedValue method_toLocaleString(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_fromLocaleString(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_toLocaleCurrencyString(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
};
@@ -135,7 +135,7 @@ public:
private:
QQmlLocale();
- static void method_localeCompare(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static QV4::ReturnedValue method_localeCompare(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
};
namespace QV4 {
@@ -158,43 +158,43 @@ struct QQmlLocaleData : public QV4::Object
V4_OBJECT2(QQmlLocaleData, Object)
V4_NEEDS_DESTROY
- static QLocale *getThisLocale(QV4::Scope &scope, QV4::CallData *callData) {
- QV4::Object *o = callData->thisObject.as<Object>();
- QQmlLocaleData *thisObject = o ? o->as<QQmlLocaleData>() : 0;
- if (!thisObject) {
+ static QLocale *getThisLocale(QV4::Scope &scope, const QV4::Value *thisObject) {
+ const QV4::Object *o = thisObject->as<Object>();
+ const QQmlLocaleData *data = o ? o->as<QQmlLocaleData>() : nullptr;
+ if (!data) {
scope.engine->throwTypeError();
return 0;
}
- return thisObject->d()->locale;
+ return data->d()->locale;
}
- static void method_currencySymbol(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_dateTimeFormat(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_timeFormat(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_dateFormat(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_monthName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_standaloneMonthName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_dayName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_standaloneDayName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
-
- static void method_get_firstDayOfWeek(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_measurementSystem(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_textDirection(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_weekDays(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_uiLanguages(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
-
- static void method_get_name(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_nativeLanguageName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_nativeCountryName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_decimalPoint(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_groupSeparator(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_percent(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_zeroDigit(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_negativeSign(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_positiveSign(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_exponential(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_amText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_pmText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static QV4::ReturnedValue method_currencySymbol(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_dateTimeFormat(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_timeFormat(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_dateFormat(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_monthName(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_standaloneMonthName(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_dayName(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_standaloneDayName(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+
+ static QV4::ReturnedValue method_get_firstDayOfWeek(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_measurementSystem(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_textDirection(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_weekDays(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_uiLanguages(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+
+ static QV4::ReturnedValue method_get_name(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_nativeLanguageName(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_nativeCountryName(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_decimalPoint(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_groupSeparator(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_percent(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_zeroDigit(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_negativeSign(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_positiveSign(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_exponential(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_amText(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_pmText(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
};
}
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 89f3ced2d6..76d40bf442 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -170,8 +170,9 @@ public:
~QQmlTypePrivate();
void init() const;
- void initEnums() const;
+ void initEnums(const QQmlPropertyCache *cache = 0) const;
void insertEnums(const QMetaObject *metaObject) const;
+ void insertEnumsFromPropertyCache(const QQmlPropertyCache *cache) const;
QAtomicInt refCount;
QQmlType::RegistrationType regType;
@@ -227,12 +228,14 @@ public:
mutable bool haveSuperType:1;
mutable QList<QQmlProxyMetaObject::ProxyData> metaObjects;
mutable QStringHash<int> enums;
+ mutable QStringHash<int> scopedEnumIndex; // maps from enum name to index in scopedEnums
+ mutable QList<QStringHash<int>*> scopedEnums;
static QHash<const QMetaObject *, int> attachedPropertyIds;
struct PropertyCacheByMinorVersion
{
- PropertyCacheByMinorVersion() : cache(Q_NULLPTR), minorVersion(-1) {}
+ PropertyCacheByMinorVersion() : cache(nullptr), minorVersion(-1) {}
explicit PropertyCacheByMinorVersion(QQmlPropertyCache *pc, int ver) : cache(pc), minorVersion(ver) {}
QQmlPropertyCachePtr cache;
int minorVersion;
@@ -257,8 +260,6 @@ void QQmlMetaTypeData::registerType(QQmlTypePrivate *priv)
void QQmlType::SingletonInstanceInfo::init(QQmlEngine *e)
{
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(e->handle());
- v4->pushGlobalContext();
if (scriptCallback && scriptApi(e).isUndefined()) {
setScriptApi(e, scriptCallback(e, e));
} else if (qobjectCallback && !qobjectApi(e)) {
@@ -271,10 +272,11 @@ void QQmlType::SingletonInstanceInfo::init(QQmlEngine *e)
QQmlData::ensurePropertyCache(e, o);
} else if (!url.isEmpty() && !qobjectApi(e)) {
QQmlComponent component(e, url, QQmlComponent::PreferSynchronous);
- QObject *o = component.create();
+ QObject *o = component.beginCreate(e->rootContext());
setQObjectApi(e, o);
+ if (o)
+ component.completeCreate();
}
- v4->popContext();
}
void QQmlType::SingletonInstanceInfo::destroy(QQmlEngine *e)
@@ -348,6 +350,7 @@ QQmlTypePrivate::QQmlTypePrivate(QQmlType::RegistrationType type)
QQmlTypePrivate::~QQmlTypePrivate()
{
+ qDeleteAll(scopedEnums);
switch (regType) {
case QQmlType::CppType:
delete extraData.cd->customParser;
@@ -578,14 +581,17 @@ QQmlType QQmlType::resolveCompositeBaseType(QQmlEnginePrivate *engine) const
return QQmlMetaType::qmlType(mo);
}
-int QQmlType::resolveCompositeEnumValue(QQmlEnginePrivate *engine, const QString &name, bool *ok) const
+QQmlPropertyCache *QQmlType::compositePropertyCache(QQmlEnginePrivate *engine) const
{
+ // similar logic to resolveCompositeBaseType
Q_ASSERT(isComposite());
- if (!d)
- return -1;
- *ok = false;
- QQmlType type = resolveCompositeBaseType(engine);
- return type.enumValue(engine, name, ok);
+ if (!engine)
+ return 0;
+ QQmlRefPointer<QQmlTypeData> td(engine->typeLoader.getType(sourceUrl()), QQmlRefPointer<QQmlTypeData>::Adopt);
+ if (td.isNull() || !td->isComplete())
+ return 0;
+ QV4::CompiledData::CompilationUnit *compilationUnit = td->compilationUnit();
+ return compilationUnit->rootPropertyCache();
}
static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo,
@@ -754,7 +760,7 @@ void QQmlTypePrivate::init() const
lock.unlock();
}
-void QQmlTypePrivate::initEnums() const
+void QQmlTypePrivate::initEnums(const QQmlPropertyCache *cache) const
{
if (isEnumSetup) return;
@@ -763,6 +769,8 @@ void QQmlTypePrivate::initEnums() const
QMutexLocker lock(metaTypeDataLock());
if (isEnumSetup) return;
+ if (cache)
+ insertEnumsFromPropertyCache(cache);
if (baseMetaObject) // could be singleton type without metaobject
insertEnums(baseMetaObject);
@@ -783,17 +791,55 @@ void QQmlTypePrivate::insertEnums(const QMetaObject *metaObject) const
// Add any enum values defined by this class, overwriting any inherited values
for (int ii = 0; ii < metaObject->enumeratorCount(); ++ii) {
QMetaEnum e = metaObject->enumerator(ii);
- for (int jj = 0; jj < e.keyCount(); ++jj)
- enums.insert(QString::fromUtf8(e.key(jj)), e.value(jj));
+ const bool isScoped = e.isScoped();
+ QStringHash<int> *scoped = isScoped ? new QStringHash<int>() : 0;
+
+ for (int jj = 0; jj < e.keyCount(); ++jj) {
+ const QString key = QString::fromUtf8(e.key(jj));
+ const int value = e.value(jj);
+ enums.insert(key, value);
+ if (isScoped)
+ scoped->insert(key, value);
+ }
+
+ if (isScoped) {
+ scopedEnums << scoped;
+ scopedEnumIndex.insert(QString::fromUtf8(e.name()), scopedEnums.count()-1);
+ }
}
}
+void QQmlTypePrivate::insertEnumsFromPropertyCache(const QQmlPropertyCache *cache) const
+{
+ const QMetaObject *cppMetaObject = cache->firstCppMetaObject();
+
+ while (cache && cache->metaObject() != cppMetaObject) {
+
+ int count = cache->qmlEnumCount();
+ for (int ii = 0; ii < count; ++ii) {
+ QStringHash<int> *scoped = new QStringHash<int>();
+ QQmlEnumData *enumData = cache->qmlEnum(ii);
+
+ for (int jj = 0; jj < enumData->values.count(); ++jj) {
+ const QQmlEnumValue &value = enumData->values.at(jj);
+ enums.insert(value.namedValue, value.value);
+ scoped->insert(value.namedValue, value.value);
+ }
+ scopedEnums << scoped;
+ scopedEnumIndex.insert(enumData->name, scopedEnums.count()-1);
+ }
+ cache = cache->parent();
+ }
+ insertEnums(cppMetaObject);
+}
+
+
QQmlPropertyCache *QQmlTypePrivate::propertyCacheForMinorVersion(int minorVersion) const
{
for (int i = 0; i < propertyCaches.count(); ++i)
if (propertyCaches.at(i).minorVersion == minorVersion)
return propertyCaches.at(i).cache;
- return Q_NULLPTR;
+ return nullptr;
}
void QQmlTypePrivate::setPropertyCacheForMinorVersion(int minorVersion, QQmlPropertyCache *cache)
@@ -1079,11 +1125,11 @@ int QQmlType::enumValue(QQmlEnginePrivate *engine, const QHashedStringRef &name,
{
Q_ASSERT(ok);
if (d) {
- if (isComposite())
- return resolveCompositeEnumValue(engine, name.toString(), ok);
+ const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
+
*ok = true;
- d->initEnums();
+ d->initEnums(cache);
int *rv = d->enums.value(name);
if (rv)
@@ -1098,11 +1144,11 @@ int QQmlType::enumValue(QQmlEnginePrivate *engine, const QHashedCStringRef &name
{
Q_ASSERT(ok);
if (d) {
- if (isComposite())
- return resolveCompositeEnumValue(engine, name.toUtf16(), ok);
+ const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
+
*ok = true;
- d->initEnums();
+ d->initEnums(cache);
int *rv = d->enums.value(name);
if (rv)
@@ -1117,11 +1163,10 @@ int QQmlType::enumValue(QQmlEnginePrivate *engine, const QV4::String *name, bool
{
Q_ASSERT(ok);
if (d) {
- if (isComposite())
- return resolveCompositeEnumValue(engine, name->toQString(), ok);
+ const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
*ok = true;
- d->initEnums();
+ d->initEnums(cache);
int *rv = d->enums.value(name);
if (rv)
@@ -1132,6 +1177,122 @@ int QQmlType::enumValue(QQmlEnginePrivate *engine, const QV4::String *name, bool
return -1;
}
+int QQmlType::scopedEnumIndex(QQmlEnginePrivate *engine, const QV4::String *name, bool *ok) const
+{
+ Q_ASSERT(ok);
+ if (d) {
+ const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
+ *ok = true;
+
+ d->initEnums(cache);
+
+ int *rv = d->scopedEnumIndex.value(name);
+ if (rv)
+ return *rv;
+ }
+
+ *ok = false;
+ return -1;
+}
+
+int QQmlType::scopedEnumIndex(QQmlEnginePrivate *engine, const QString &name, bool *ok) const
+{
+ Q_ASSERT(ok);
+ if (d) {
+ const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
+ *ok = true;
+
+ d->initEnums(cache);
+
+ int *rv = d->scopedEnumIndex.value(name);
+ if (rv)
+ return *rv;
+ }
+
+ *ok = false;
+ return -1;
+}
+
+int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, int index, const QV4::String *name, bool *ok) const
+{
+ Q_UNUSED(engine)
+ Q_ASSERT(ok);
+ *ok = true;
+
+ if (d) {
+ Q_ASSERT(index > -1 && index < d->scopedEnums.count());
+ int *rv = d->scopedEnums.at(index)->value(name);
+ if (rv)
+ return *rv;
+ }
+
+ *ok = false;
+ return -1;
+}
+
+int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, int index, const QString &name, bool *ok) const
+{
+ Q_UNUSED(engine)
+ Q_ASSERT(ok);
+ *ok = true;
+
+ if (d) {
+ Q_ASSERT(index > -1 && index < d->scopedEnums.count());
+ int *rv = d->scopedEnums.at(index)->value(name);
+ if (rv)
+ return *rv;
+ }
+
+ *ok = false;
+ return -1;
+}
+
+int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, const QByteArray &scopedEnumName, const QByteArray &name, bool *ok) const
+{
+ Q_ASSERT(ok);
+ if (d) {
+ const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
+ *ok = true;
+
+ d->initEnums(cache);
+
+ int *rv = d->scopedEnumIndex.value(QHashedCStringRef(scopedEnumName.constData(), scopedEnumName.length()));
+ if (rv) {
+ int index = *rv;
+ Q_ASSERT(index > -1 && index < d->scopedEnums.count());
+ rv = d->scopedEnums.at(index)->value(QHashedCStringRef(name.constData(), name.length()));
+ if (rv)
+ return *rv;
+ }
+ }
+
+ *ok = false;
+ return -1;
+}
+
+int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, const QStringRef &scopedEnumName, const QStringRef &name, bool *ok) const
+{
+ Q_ASSERT(ok);
+ if (d) {
+ const QQmlPropertyCache *cache = isComposite() ? compositePropertyCache(engine) : 0;
+ *ok = true;
+
+ d->initEnums(cache);
+
+ int *rv = d->scopedEnumIndex.value(QHashedStringRef(scopedEnumName));
+ if (rv) {
+ int index = *rv;
+ Q_ASSERT(index > -1 && index < d->scopedEnums.count());
+ rv = d->scopedEnums.at(index)->value(QHashedStringRef(name));
+ if (rv)
+ return *rv;
+ }
+ }
+
+ *ok = false;
+ return -1;
+}
+
void QQmlType::refHandle(QQmlTypePrivate *priv)
{
if (priv)
@@ -1424,15 +1585,7 @@ bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *da
if (uri && !typeName.isEmpty()) {
QString nameSpace = QString::fromUtf8(uri);
- if (!data->typeRegistrationNamespace.isEmpty()) {
- // We can only install types into the registered namespace
- if (nameSpace != data->typeRegistrationNamespace) {
- QString failure(QCoreApplication::translate("qmlRegisterType",
- "Cannot install %1 '%2' into unregistered namespace '%3'"));
- data->typeRegistrationFailures.append(failure.arg(registrationTypeString(typeType)).arg(typeName).arg(nameSpace));
- return false;
- }
- } else if (data->typeRegistrationNamespace != nameSpace) {
+ if (data->typeRegistrationNamespace.isEmpty() && !nameSpace.isEmpty()) {
// Is the target namespace protected against further registrations?
if (data->protectedNamespaces.contains(nameSpace)) {
QString failure(QCoreApplication::translate("qmlRegisterType",
@@ -2310,7 +2463,7 @@ void QQmlMetaType::freeUnusedTypesAndCaches()
while (it != data->propertyCaches.end()) {
if ((*it)->count() == 1) {
- QQmlPropertyCache *pc = Q_NULLPTR;
+ QQmlPropertyCache *pc = nullptr;
qSwap(pc, *it);
it = data->propertyCaches.erase(it);
pc->release();
@@ -2386,16 +2539,16 @@ QList<QQmlType> QQmlMetaType::qmlSingletonTypes()
return retn;
}
-const QQmlPrivate::CachedQmlUnit *QQmlMetaType::findCachedCompilationUnit(const QUrl &uri)
+const QV4::CompiledData::Unit *QQmlMetaType::findCachedCompilationUnit(const QUrl &uri)
{
QMutexLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
for (const auto lookup : qAsConst(data->lookupCachedQmlUnit)) {
if (const QQmlPrivate::CachedQmlUnit *unit = lookup(uri))
- return unit;
+ return unit->qmlData;
}
- return 0;
+ return nullptr;
}
/*!
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index f5b9beb905..cee1070a09 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -133,7 +133,7 @@ public:
static QList<QQmlPrivate::AutoParentFunction> parentFunctions();
- static const QQmlPrivate::CachedQmlUnit *findCachedCompilationUnit(const QUrl &uri);
+ static const QV4::CompiledData::Unit *findCachedCompilationUnit(const QUrl &uri);
static bool namespaceContainsRegistrations(const QString &, int majorVersion);
@@ -149,6 +149,7 @@ public:
struct QQmlMetaTypeData;
class QHashedCStringRef;
+class QQmlPropertyCache;
class Q_QML_PRIVATE_EXPORT QQmlType
{
public:
@@ -244,6 +245,13 @@ public:
int enumValue(QQmlEnginePrivate *engine, const QHashedCStringRef &, bool *ok) const;
int enumValue(QQmlEnginePrivate *engine, const QV4::String *, bool *ok) const;
+ int scopedEnumIndex(QQmlEnginePrivate *engine, const QV4::String *, bool *ok) const;
+ int scopedEnumIndex(QQmlEnginePrivate *engine, const QString &, bool *ok) const;
+ int scopedEnumValue(QQmlEnginePrivate *engine, int index, const QV4::String *, bool *ok) const;
+ int scopedEnumValue(QQmlEnginePrivate *engine, int index, const QString &, bool *ok) const;
+ int scopedEnumValue(QQmlEnginePrivate *engine, const QByteArray &, const QByteArray &, bool *ok) const;
+ int scopedEnumValue(QQmlEnginePrivate *engine, const QStringRef &, const QStringRef &, bool *ok) const;
+
QQmlTypePrivate *priv() const { return d; }
static void refHandle(QQmlTypePrivate *priv);
static void derefHandle(QQmlTypePrivate *priv);
@@ -262,6 +270,7 @@ private:
QQmlType superType() const;
QQmlType resolveCompositeBaseType(QQmlEnginePrivate *engine) const;
int resolveCompositeEnumValue(QQmlEnginePrivate *engine, const QString &name, bool *ok) const;
+ QQmlPropertyCache *compositePropertyCache(QQmlEnginePrivate *engine) const;
friend class QQmlTypePrivate;
friend QString registrationTypeString(RegistrationType);
diff --git a/src/qml/qml/qqmlnotifier.cpp b/src/qml/qml/qqmlnotifier.cpp
index 938e2b77e2..e068ad174a 100644
--- a/src/qml/qml/qqmlnotifier.cpp
+++ b/src/qml/qml/qqmlnotifier.cpp
@@ -74,7 +74,7 @@ namespace {
void QQmlNotifier::notify(QQmlData *ddata, int notifierIndex)
{
if (QQmlNotifierEndpoint *ep = ddata->notify(notifierIndex))
- emitNotify(ep, Q_NULLPTR);
+ emitNotify(ep, nullptr);
}
void QQmlNotifier::emitNotify(QQmlNotifierEndpoint *endpoint, void **a)
diff --git a/src/qml/qml/qqmlnotifier_p.h b/src/qml/qml/qqmlnotifier_p.h
index 6e91369793..a99b13f155 100644
--- a/src/qml/qml/qqmlnotifier_p.h
+++ b/src/qml/qml/qqmlnotifier_p.h
@@ -109,6 +109,9 @@ public:
inline int signalIndex() const { return sourceSignal; }
+ inline QObject *senderAsObject() const;
+ inline QQmlNotifier *senderAsNotifier() const;
+
private:
friend class QQmlData;
friend class QQmlNotifier;
@@ -117,8 +120,6 @@ private:
// endpoint is connected to. While the endpoint is notifying, the
// senderPtr points to another qintptr that contains this value.
qintptr senderPtr;
- inline QObject *senderAsObject() const;
- inline QQmlNotifier *senderAsNotifier() const;
Callback callback:4;
int needsConnectNotify:1;
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 78d732d02c..caf063c79f 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -114,7 +114,7 @@ void QQmlObjectCreator::init(QQmlContextData *providedParentContext)
{
parentContext = providedParentContext;
engine = parentContext->engine;
- v4 = QV8Engine::getV4(engine);
+ v4 = engine->handle();
if (compilationUnit && !compilationUnit->engine)
compilationUnit->linkToEngine(v4);
@@ -875,17 +875,13 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
&& !_valueTypeProperty)
QQmlPropertyPrivate::removeBinding(_bindingTarget, QQmlPropertyIndex(property->coreIndex()));
- if (binding->type == QV4::CompiledData::Binding::Type_Script) {
- QV4::Function *runtimeFunction = compilationUnit->runtimeFunctions.at(binding->value.compiledScriptIndex);
-
- QV4::Scope scope(v4);
- QV4::Scoped<QV4::QmlContext> qmlContext(scope, currentQmlContext());
-
+ if (binding->type == QV4::CompiledData::Binding::Type_Script || binding->containsTranslations()) {
if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression) {
+ QV4::Function *runtimeFunction = compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex];
int signalIndex = _propertyCache->methodIndexToSignalIndex(property->coreIndex());
QQmlBoundSignal *bs = new QQmlBoundSignal(_bindingTarget, signalIndex, _scopeObject, engine);
QQmlBoundSignalExpression *expr = new QQmlBoundSignalExpression(_bindingTarget, signalIndex,
- context, _scopeObject, runtimeFunction, qmlContext);
+ context, _scopeObject, runtimeFunction, currentQmlContext());
bs->takeExpression(expr);
} else {
@@ -901,7 +897,12 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
prop = _valueTypeProperty;
subprop = property;
}
- qmlBinding = QQmlBinding::create(prop, runtimeFunction, _scopeObject, context, qmlContext);
+ if (binding->containsTranslations()) {
+ qmlBinding = QQmlBinding::createTranslationBinding(compilationUnit, binding, _scopeObject, context);
+ } else {
+ QV4::Function *runtimeFunction = compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex];
+ qmlBinding = QQmlBinding::create(prop, runtimeFunction, _scopeObject, context, currentQmlContext());
+ }
qmlBinding->setTarget(_bindingTarget, *prop, subprop);
sharedState->allCreatedBindings.push(QQmlAbstractBinding::Ptr(qmlBinding));
@@ -1021,7 +1022,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con
} else if (property->propType() == QMetaType::QVariant) {
if (property->isVarProperty()) {
QV4::Scope scope(v4);
- QV4::ScopedValue wrappedObject(scope, QV4::QObjectWrapper::wrap(QV8Engine::getV4(engine), createdSubObject));
+ QV4::ScopedValue wrappedObject(scope, QV4::QObjectWrapper::wrap(engine->handle(), createdSubObject));
_vmeMetaObject->setVMEProperty(property->coreIndex(), wrappedObject);
} else {
QVariant value = QVariant::fromValue(createdSubObject);
@@ -1070,7 +1071,7 @@ void QQmlObjectCreator::setupFunctions()
QV4::ScopedValue function(scope);
QV4::ScopedContext qmlContext(scope, currentQmlContext());
- const QV4::CompiledData::LEUInt32 *functionIdx = _compiledObject->functionOffsetTable();
+ const quint32_le *functionIdx = _compiledObject->functionOffsetTable();
for (quint32 i = 0; i < _compiledObject->nFunctions; ++i, ++functionIdx) {
QV4::Function *runtimeFunction = compilationUnit->runtimeFunctions[*functionIdx];
const QString name = runtimeFunction->name()->toQString();
@@ -1182,8 +1183,16 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
return 0;
}
}
- if (parent)
+ if (instance->isWidgetType()) {
+ if (parent && parent->isWidgetType()) {
+ QAbstractDeclarativeData::setWidgetParent(instance, parent);
+ } else {
+ // No parent! Layouts need to handle this through a default property that
+ // reparents accordingly. Otherwise the garbage collector will collect.
+ }
+ } else if (parent) {
QQml_setParent_noEvent(instance, parent);
+ }
ddata = QQmlData::get(instance, /*create*/true);
ddata->lineNumber = obj->location.line;
diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
index 21ee30acd0..bef58b8c9a 100644
--- a/src/qml/qml/qqmlobjectcreator_p.h
+++ b/src/qml/qml/qqmlobjectcreator_p.h
@@ -123,7 +123,7 @@ private:
void registerObjectWithContextById(const QV4::CompiledData::Object *object, QObject *instance) const;
- inline QV4::Heap::QmlContext *currentQmlContext();
+ inline QV4::QmlContext *currentQmlContext();
Q_NEVER_INLINE void createQmlContext();
enum Phase {
@@ -174,12 +174,12 @@ private:
QRecursionWatcher<QQmlObjectCreatorSharedState, &QQmlObjectCreatorSharedState::recursionNode> watcher;
};
-QV4::Heap::QmlContext *QQmlObjectCreator::currentQmlContext()
+QV4::QmlContext *QQmlObjectCreator::currentQmlContext()
{
- if (Q_UNLIKELY(!_qmlContext->isManaged()))
- createQmlContext(); // less common slow path
+ if (!_qmlContext->isManaged())
+ _qmlContext->setM(QV4::QmlContext::create(v4->rootContext(), context, _scopeObject));
- return _qmlContext->d();
+ return _qmlContext;
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlplatform.cpp b/src/qml/qml/qqmlplatform.cpp
index 0d6ab36066..0acf20bbb4 100644
--- a/src/qml/qml/qqmlplatform.cpp
+++ b/src/qml/qml/qqmlplatform.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "qqmlplatform_p.h"
+#include "qqmlglobal_p.h"
QT_BEGIN_NAMESPACE
@@ -80,6 +81,11 @@ QString QQmlPlatform::os()
#endif
}
+QString QQmlPlatform::pluginName() const
+{
+ return QQml_guiProvider()->pluginName();
+}
+
QT_END_NAMESPACE
#include "moc_qqmlplatform_p.cpp"
diff --git a/src/qml/qml/qqmlplatform_p.h b/src/qml/qml/qqmlplatform_p.h
index 6887720adb..6246ca7105 100644
--- a/src/qml/qml/qqmlplatform_p.h
+++ b/src/qml/qml/qqmlplatform_p.h
@@ -61,12 +61,14 @@ class Q_QML_PRIVATE_EXPORT QQmlPlatform : public QObject
{
Q_OBJECT
Q_PROPERTY(QString os READ os CONSTANT)
+ Q_PROPERTY(QString pluginName READ pluginName CONSTANT)
public:
explicit QQmlPlatform(QObject *parent = 0);
virtual ~QQmlPlatform();
static QString os();
+ QString pluginName() const;
private:
Q_DISABLE_COPY(QQmlPlatform)
diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h
index eeb5b4c302..b9e9d5e59e 100644
--- a/src/qml/qml/qqmlprivate.h
+++ b/src/qml/qml/qqmlprivate.h
@@ -69,7 +69,6 @@ namespace CompiledData {
struct Unit;
struct CompilationUnit;
}
-typedef CompiledData::CompilationUnit *(*CompilationUnitFactoryFunction)();
}
namespace QmlIR {
struct Document;
@@ -284,8 +283,8 @@ namespace QQmlPrivate
struct CachedQmlUnit {
const QV4::CompiledData::Unit *qmlData;
- QV4::CompilationUnitFactoryFunction createCompilationUnit;
- QmlIR::IRLoaderFunction loadIR;
+ void *unused1;
+ void *unused2;
};
typedef const CachedQmlUnit *(*QmlUnitCacheLookupFunction)(const QUrl &url);
diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp
index 019fa654d1..bce81c1504 100644
--- a/src/qml/qml/qqmlpropertycache.cpp
+++ b/src/qml/qml/qqmlpropertycache.cpp
@@ -303,12 +303,13 @@ QQmlPropertyCache *QQmlPropertyCache::copy()
}
QQmlPropertyCache *QQmlPropertyCache::copyAndReserve(int propertyCount, int methodCount,
- int signalCount)
+ int signalCount, int enumCount)
{
QQmlPropertyCache *rv = copy(propertyCount + methodCount + signalCount);
rv->propertyIndexCache.reserve(propertyCount);
rv->methodIndexCache.reserve(methodCount);
rv->signalHandlerIndexCache.reserve(signalCount);
+ rv->enumCache.reserve(enumCount);
rv->_metaObject = 0;
return rv;
@@ -320,13 +321,14 @@ QQmlPropertyCache *QQmlPropertyCache::copyAndReserve(int propertyCount, int meth
This is different from QMetaMethod::methodIndex().
*/
void QQmlPropertyCache::appendProperty(const QString &name, QQmlPropertyData::Flags flags,
- int coreIndex, int propType, int notifyIndex)
+ int coreIndex, int propType, int minorVersion, int notifyIndex)
{
QQmlPropertyData data;
data.setPropType(propType);
data.setCoreIndex(coreIndex);
data.setNotifyIndex(notifyIndex);
data.setFlags(flags);
+ data.setTypeMinorVersion(minorVersion);
QQmlPropertyData *old = findNamedProperty(name);
if (old)
@@ -403,6 +405,14 @@ void QQmlPropertyCache::appendMethod(const QString &name, QQmlPropertyData::Flag
setNamedProperty(name, methodIndex + methodOffset(), methodIndexCache.data() + methodIndex, (old != 0));
}
+void QQmlPropertyCache::appendEnum(const QString &name, const QVector<QQmlEnumValue> &values)
+{
+ QQmlEnumData data;
+ data.name = name;
+ data.values = values;
+ enumCache.append(data);
+}
+
// Returns this property cache's metaObject, creating it if necessary.
const QMetaObject *QQmlPropertyCache::createMetaObject()
{
@@ -1231,6 +1241,16 @@ void QQmlPropertyCache::toMetaObjectBuilder(QMetaObjectBuilder &builder)
method.setReturnType(returnType);
}
+ for (int ii = 0; ii < enumCache.count(); ++ii) {
+ const QQmlEnumData &enumData = enumCache.at(ii);
+ QMetaEnumBuilder enumeration = builder.addEnumerator(enumData.name.toUtf8());
+ enumeration.setIsScoped(true);
+ for (int jj = 0; jj < enumData.values.count(); ++jj) {
+ const QQmlEnumValue &value = enumData.values.at(jj);
+ enumeration.addKey(value.namedValue.toUtf8(), value.value);
+ }
+ }
+
if (!_defaultPropertyName.isEmpty()) {
QQmlPropertyData *dp = property(_defaultPropertyName, 0, 0);
if (dp && dp->coreIndex() >= propertyIndexCacheStart) {
diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h
index a841570f1d..11b7c04c52 100644
--- a/src/qml/qml/qqmlpropertycache_p.h
+++ b/src/qml/qml/qqmlpropertycache_p.h
@@ -218,12 +218,36 @@ public:
_coreIndex = qint16(idx);
}
- int revision() const { return _revision; }
- void setRevision(int rev)
+ quint8 revision() const { return _revision; }
+ void setRevision(quint8 rev)
{
- Q_ASSERT(rev >= std::numeric_limits<qint16>::min());
- Q_ASSERT(rev <= std::numeric_limits<qint16>::max());
- _revision = qint16(rev);
+ Q_ASSERT(rev <= std::numeric_limits<quint8>::max());
+ _revision = quint8(rev);
+ }
+
+ /* If a property is a C++ type, then we store the minor
+ * version of this type.
+ * This is required to resolve property or signal revisions
+ * if this property is used as a grouped property.
+ *
+ * Test.qml
+ * property TextEdit someTextEdit: TextEdit {}
+ *
+ * Test {
+ * someTextEdit.preeditText: "test" //revision 7
+ * someTextEdit.onEditingFinished: console.log("test") //revision 6
+ * }
+ *
+ * To determine if these properties with revisions are available we need
+ * the minor version of TextEdit as imported in Test.qml.
+ *
+ */
+
+ quint8 typeMinorVersion() const { return _typeMinorVersion; }
+ void setTypeMinorVersion(quint8 rev)
+ {
+ Q_ASSERT(rev <= std::numeric_limits<quint8>::max());
+ _typeMinorVersion = quint8(rev);
}
QQmlPropertyCacheMethodArguments *arguments() const { return _arguments; }
@@ -257,7 +281,8 @@ private:
qint16 _notifyIndex;
qint16 _overrideIndex;
- qint16 _revision;
+ quint8 _revision;
+ quint8 _typeMinorVersion;
qint16 _metaObjectOffset;
QQmlPropertyCacheMethodArguments *_arguments;
@@ -349,6 +374,20 @@ private:
bool notFullyResolved() const { return _flags.notFullyResolved; }
};
+struct QQmlEnumValue
+{
+ QQmlEnumValue() : value(-1) {}
+ QQmlEnumValue(const QString &n, int v) : namedValue(n), value(v) {}
+ QString namedValue;
+ int value;
+};
+
+struct QQmlEnumData
+{
+ QString name;
+ QVector<QQmlEnumValue> values;
+};
+
class QQmlPropertyCacheMethodArguments;
class Q_QML_PRIVATE_EXPORT QQmlPropertyCache : public QQmlRefCount
{
@@ -374,13 +413,14 @@ public:
QQmlPropertyRawData::Flags signalFlags = QQmlPropertyData::Flags());
QQmlPropertyCache *copyAndReserve(int propertyCount,
- int methodCount, int signalCount);
+ int methodCount, int signalCount, int enumCount);
void appendProperty(const QString &, QQmlPropertyRawData::Flags flags, int coreIndex,
- int propType, int notifyIndex);
+ int propType, int revision, int notifyIndex);
void appendSignal(const QString &, QQmlPropertyRawData::Flags, int coreIndex,
const int *types = 0, const QList<QByteArray> &names = QList<QByteArray>());
void appendMethod(const QString &, QQmlPropertyData::Flags flags, int coreIndex,
const QList<QByteArray> &names = QList<QByteArray>());
+ void appendEnum(const QString &, const QVector<QQmlEnumValue> &);
const QMetaObject *metaObject() const;
const QMetaObject *createMetaObject();
@@ -395,6 +435,7 @@ public:
QQmlPropertyData *property(int) const;
QQmlPropertyData *method(int) const;
QQmlPropertyData *signal(int index) const;
+ QQmlEnumData *qmlEnum(int) const;
int methodIndexToSignalIndex(int) const;
QString defaultPropertyName() const;
@@ -434,6 +475,7 @@ public:
inline int methodOffset() const;
inline int signalCount() const;
inline int signalOffset() const;
+ inline int qmlEnumCount() const;
static bool isDynamicMetaObject(const QMetaObject *);
@@ -500,6 +542,7 @@ private:
IndexCache signalHandlerIndexCache;
StringCache stringCache;
AllowedRevisionCache allowedRevisionCache;
+ QVector<QQmlEnumData> enumCache;
bool _hasPropertyOverrides : 1;
bool _ownMetaObject : 1;
@@ -742,6 +785,14 @@ inline QQmlPropertyData *QQmlPropertyCache::signal(int index) const
return ensureResolved(rv);
}
+inline QQmlEnumData *QQmlPropertyCache::qmlEnum(int index) const
+{
+ if (index < 0 || index >= enumCache.count())
+ return 0;
+
+ return const_cast<QQmlEnumData *>(&enumCache.at(index));
+}
+
inline int QQmlPropertyCache::methodIndexToSignalIndex(int index) const
{
if (index < 0 || index >= (methodIndexCacheStart + methodIndexCache.count()))
@@ -812,6 +863,11 @@ int QQmlPropertyCache::signalOffset() const
return signalHandlerIndexCacheStart;
}
+int QQmlPropertyCache::qmlEnumCount() const
+{
+ return enumCache.count();
+}
+
bool QQmlPropertyCache::callJSFactoryMethod(QObject *object, void **args) const
{
if (_jsFactoryMethodIndex != -1) {
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 5318375af7..e5682df761 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -44,6 +44,7 @@
#include <private/qqmlengine_p.h>
#include <private/qqmlglobal_p.h>
#include <private/qqmlthread_p.h>
+#include <private/qv4codegen_p.h>
#include <private/qqmlcomponent_p.h>
#include <private/qqmlprofiler_p.h>
#include <private/qqmlmemoryprofiler_p.h>
@@ -155,8 +156,8 @@ public:
void loadAsync(QQmlDataBlob *b);
void loadWithStaticData(QQmlDataBlob *b, const QByteArray &);
void loadWithStaticDataAsync(QQmlDataBlob *b, const QByteArray &);
- void loadWithCachedUnit(QQmlDataBlob *b, const QQmlPrivate::CachedQmlUnit *unit);
- void loadWithCachedUnitAsync(QQmlDataBlob *b, const QQmlPrivate::CachedQmlUnit *unit);
+ void loadWithCachedUnit(QQmlDataBlob *b, const QV4::CompiledData::Unit *unit);
+ void loadWithCachedUnitAsync(QQmlDataBlob *b, const QV4::CompiledData::Unit *unit);
void callCompleted(QQmlDataBlob *b);
void callDownloadProgressChanged(QQmlDataBlob *b, qreal p);
void initializeEngine(QQmlExtensionInterface *, const char *);
@@ -167,7 +168,7 @@ protected:
private:
void loadThread(QQmlDataBlob *b);
void loadWithStaticDataThread(QQmlDataBlob *b, const QByteArray &);
- void loadWithCachedUnitThread(QQmlDataBlob *b, const QQmlPrivate::CachedQmlUnit *unit);
+ void loadWithCachedUnitThread(QQmlDataBlob *b, const QV4::CompiledData::Unit *unit);
void callCompletedMain(QQmlDataBlob *b);
void callDownloadProgressChangedMain(QQmlDataBlob *b, qreal p);
void initializeEngineMain(QQmlExtensionInterface *iface, const char *uri);
@@ -841,13 +842,13 @@ void QQmlTypeLoaderThread::loadWithStaticDataAsync(QQmlDataBlob *b, const QByteA
postMethodToThread(&This::loadWithStaticDataThread, b, d);
}
-void QQmlTypeLoaderThread::loadWithCachedUnit(QQmlDataBlob *b, const QQmlPrivate::CachedQmlUnit *unit)
+void QQmlTypeLoaderThread::loadWithCachedUnit(QQmlDataBlob *b, const QV4::CompiledData::Unit *unit)
{
b->addref();
callMethodInThread(&This::loadWithCachedUnitThread, b, unit);
}
-void QQmlTypeLoaderThread::loadWithCachedUnitAsync(QQmlDataBlob *b, const QQmlPrivate::CachedQmlUnit *unit)
+void QQmlTypeLoaderThread::loadWithCachedUnitAsync(QQmlDataBlob *b, const QV4::CompiledData::Unit *unit)
{
b->addref();
postMethodToThread(&This::loadWithCachedUnitThread, b, unit);
@@ -893,7 +894,7 @@ void QQmlTypeLoaderThread::loadWithStaticDataThread(QQmlDataBlob *b, const QByte
b->release();
}
-void QQmlTypeLoaderThread::loadWithCachedUnitThread(QQmlDataBlob *b, const QQmlPrivate::CachedQmlUnit *unit)
+void QQmlTypeLoaderThread::loadWithCachedUnitThread(QQmlDataBlob *b, const QV4::CompiledData::Unit *unit)
{
m_loader->loadWithCachedUnitThread(b, unit);
b->release();
@@ -974,7 +975,7 @@ void QQmlTypeLoader::invalidate()
#endif // qml_network
}
-#ifndef QT_NO_QML_DEBUGGER
+#if QT_CONFIG(qml_debug)
void QQmlTypeLoader::setProfiler(QQmlProfiler *profiler)
{
Q_ASSERT(!m_profiler);
@@ -1026,8 +1027,8 @@ struct StaticLoader {
};
struct CachedLoader {
- const QQmlPrivate::CachedQmlUnit *unit;
- CachedLoader(const QQmlPrivate::CachedQmlUnit *unit) : unit(unit) {}
+ const QV4::CompiledData::Unit *unit;
+ CachedLoader(const QV4::CompiledData::Unit *unit) : unit(unit) {}
void loadThread(QQmlTypeLoader *loader, QQmlDataBlob *blob) const
{
@@ -1099,7 +1100,7 @@ void QQmlTypeLoader::loadWithStaticData(QQmlDataBlob *blob, const QByteArray &da
doLoad(StaticLoader(data), blob, mode);
}
-void QQmlTypeLoader::loadWithCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit, Mode mode)
+void QQmlTypeLoader::loadWithCachedUnit(QQmlDataBlob *blob, const QV4::CompiledData::Unit *unit, Mode mode)
{
doLoad(CachedLoader(unit), blob, mode);
}
@@ -1111,7 +1112,7 @@ void QQmlTypeLoader::loadWithStaticDataThread(QQmlDataBlob *blob, const QByteArr
setData(blob, data);
}
-void QQmlTypeLoader::loadWithCachedUnitThread(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit)
+void QQmlTypeLoader::loadWithCachedUnitThread(QQmlDataBlob *blob, const QV4::CompiledData::Unit *unit)
{
ASSERT_LOADTHREAD();
@@ -1299,7 +1300,7 @@ void QQmlTypeLoader::setData(QQmlDataBlob *blob, const QQmlDataBlob::SourceCodeD
blob->tryDone();
}
-void QQmlTypeLoader::setCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit)
+void QQmlTypeLoader::setCachedUnit(QQmlDataBlob *blob, const QV4::CompiledData::Unit *unit)
{
QML_MEMORY_SCOPE_URL(blob->url());
QQmlCompilingProfiler prof(profiler(), blob);
@@ -1534,7 +1535,7 @@ void QQmlTypeLoader::Blob::dependencyComplete(QQmlDataBlob *blob)
bool QQmlTypeLoader::Blob::isDebugging() const
{
- return QV8Engine::getV4(typeLoader()->engine())->debugger() != 0;
+ return typeLoader()->engine()->handle()->debugger() != 0;
}
bool QQmlTypeLoader::Blob::qmldirDataAvailable(QQmlQmldirData *data, QList<QQmlError> *errors)
@@ -1676,7 +1677,7 @@ QQmlTypeData *QQmlTypeLoader::getType(const QUrl &url, Mode mode)
typeData = new QQmlTypeData(url, this);
// TODO: if (compiledData == 0), is it safe to omit this insertion?
m_typeCache.insert(url, typeData);
- if (const QQmlPrivate::CachedQmlUnit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(typeData->url())) {
+ if (const QV4::CompiledData::Unit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(typeData->url())) {
QQmlTypeLoader::loadWithCachedUnit(typeData, cachedUnit, mode);
} else {
QQmlTypeLoader::load(typeData, mode);
@@ -1733,7 +1734,7 @@ QQmlScriptBlob *QQmlTypeLoader::getScript(const QUrl &url)
scriptBlob = new QQmlScriptBlob(url, this);
m_scriptCache.insert(url, scriptBlob);
- if (const QQmlPrivate::CachedQmlUnit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(scriptBlob->url())) {
+ if (const QV4::CompiledData::Unit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(scriptBlob->url())) {
QQmlTypeLoader::loadWithCachedUnit(scriptBlob, cachedUnit);
} else {
QQmlTypeLoader::load(scriptBlob);
@@ -2107,14 +2108,14 @@ bool QQmlTypeData::tryLoadFromDiskCache()
if (isDebugging())
return false;
- QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(typeLoader()->engine());
+ QV4::ExecutionEngine *v4 = typeLoader()->engine()->handle();
if (!v4)
return false;
- QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = v4->iselFactory->createUnitForLoading();
+ QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = QV4::Compiler::Codegen::createUnitForLoading();
{
QString error;
- if (!unit->loadFromDisk(url(), m_backupSourceCode.sourceTimeStamp(), v4->iselFactory.data(), &error)) {
+ if (!unit->loadFromDisk(url(), m_backupSourceCode.sourceTimeStamp(), &error)) {
qCDebug(DBG_DISK_CACHE) << "Error loading" << urlString() << "from disk cache:" << error;
return false;
}
@@ -2435,18 +2436,14 @@ void QQmlTypeData::dataReceived(const SourceCodeData &data)
continueLoadFromIR();
}
-void QQmlTypeData::initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit)
+void QQmlTypeData::initializeFromCachedUnit(const QV4::CompiledData::Unit *unit)
{
m_document.reset(new QmlIR::Document(isDebugging()));
- if (unit->loadIR) {
- // old code path for older generated code
- unit->loadIR(m_document.data(), unit);
- } else {
- // new code path
- QmlIR::IRLoader loader(unit->qmlData, m_document.data());
- loader.load();
- m_document->javaScriptCompilationUnit.adopt(unit->createCompilationUnit());
- }
+ QmlIR::IRLoader loader(unit, m_document.data());
+ loader.load();
+ m_document->jsModule.fileName = urlString();
+ m_document->jsModule.finalUrl = finalUrlString();
+ m_document->javaScriptCompilationUnit.adopt(new QV4::CompiledData::CompilationUnit(unit));
continueLoadFromIR();
}
@@ -2455,7 +2452,7 @@ bool QQmlTypeData::loadFromSource()
m_document.reset(new QmlIR::Document(isDebugging()));
m_document->jsModule.sourceTimeStamp = m_backupSourceCode.sourceTimeStamp();
QQmlEngine *qmlEngine = typeLoader()->engine();
- QmlIR::IRBuilder compiler(QV8Engine::get(qmlEngine)->illegalNames());
+ QmlIR::IRBuilder compiler(qmlEngine->handle()->v8Engine->illegalNames());
QString sourceError;
const QString source = m_backupSourceCode.readAll(&sourceError);
@@ -2486,8 +2483,8 @@ void QQmlTypeData::restoreIR(QQmlRefPointer<QV4::CompiledData::CompilationUnit>
m_document.reset(new QmlIR::Document(isDebugging()));
QmlIR::IRLoader loader(unit->data, m_document.data());
loader.load();
- m_document->jsModule.setFileName(urlString());
- m_document->jsModule.setFinalUrl(finalUrlString());
+ m_document->jsModule.fileName = urlString();
+ m_document->jsModule.finalUrl = finalUrlString();
m_document->javaScriptCompilationUnit = unit;
continueLoadFromIR();
}
@@ -2606,7 +2603,7 @@ void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCach
QString errorString;
if (m_compiledData->saveToDisk(url(), &errorString)) {
QString error;
- if (!m_compiledData->loadFromDisk(url(), m_backupSourceCode.sourceTimeStamp(), enginePrivate->v4engine()->iselFactory.data(), &error)) {
+ if (!m_compiledData->loadFromDisk(url(), m_backupSourceCode.sourceTimeStamp(), &error)) {
// ignore error, keep using the in-memory compilation unit.
}
} else {
@@ -2706,6 +2703,10 @@ void QQmlTypeData::resolveTypes()
m_resolvedTypes.insert(unresolvedRef.key(), ref);
}
+
+ // ### this allows enums to work without explicit import or instantiation of the type
+ if (!m_implicitImportLoaded)
+ loadImplicitImport();
}
QQmlCompileError QQmlTypeData::buildTypeResolutionCaches(
@@ -2840,9 +2841,7 @@ void QQmlScriptData::initialize(QQmlEngine *engine)
Q_ASSERT(engine);
Q_ASSERT(!hasEngine());
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
- QV8Engine *v8engine = ep->v8engine();
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(v8engine);
+ QV4::ExecutionEngine *v4 = engine->handle();
m_program = new QV4::Script(v4, 0, m_precompiledScript);
@@ -2858,7 +2857,7 @@ QV4::ReturnedValue QQmlScriptData::scriptValueForContext(QQmlContextData *parent
Q_ASSERT(parentCtxt && parentCtxt->engine);
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(parentCtxt->engine);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(parentCtxt->engine);
+ QV4::ExecutionEngine *v4 = parentCtxt->engine->handle();
QV4::Scope scope(v4);
bool shared = m_precompiledScript->data->flags & QV4::CompiledData::Unit::IsSharedLibrary;
@@ -2924,7 +2923,7 @@ QV4::ReturnedValue QQmlScriptData::scriptValueForContext(QQmlContextData *parent
ep->warning(error);
}
- QV4::ScopedValue retval(scope, qmlContext->d()->qml);
+ QV4::ScopedValue retval(scope, qmlContext->d()->qml());
if (shared) {
m_value.set(scope.engine, retval);
m_loaded = true;
@@ -2966,19 +2965,12 @@ QQmlScriptData *QQmlScriptBlob::scriptData() const
return m_scriptData;
}
-struct EmptyCompilationUnit : public QV4::CompiledData::CompilationUnit
-{
- void linkBackendToEngine(QV4::ExecutionEngine *) override {}
-};
-
void QQmlScriptBlob::dataReceived(const SourceCodeData &data)
{
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(m_typeLoader->engine());
-
if (!disableDiskCache() || forceDiskCache()) {
- QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = v4->iselFactory->createUnitForLoading();
+ QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = QV4::Compiler::Codegen::createUnitForLoading();
QString error;
- if (unit->loadFromDisk(url(), data.sourceTimeStamp(), v4->iselFactory.data(), &error)) {
+ if (unit->loadFromDisk(url(), data.sourceTimeStamp(), &error)) {
initializeFromCompilationUnit(unit);
return;
} else {
@@ -3001,7 +2993,7 @@ void QQmlScriptBlob::dataReceived(const SourceCodeData &data)
QList<QQmlError> errors;
QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = QV4::Script::precompile(
- &irUnit.jsModule, &irUnit.jsGenerator, v4, urlString(), finalUrlString(),
+ &irUnit.jsModule, &irUnit.jsGenerator, urlString(), finalUrlString(),
source, &errors, &collector);
// No need to addref on unit, it's initial refcount is 1
source.clear();
@@ -3010,7 +3002,7 @@ void QQmlScriptBlob::dataReceived(const SourceCodeData &data)
return;
}
if (!unit) {
- unit.adopt(new EmptyCompilationUnit);
+ unit.adopt(new QV4::CompiledData::CompilationUnit);
}
irUnit.javaScriptCompilationUnit = unit;
irUnit.imports = collector.imports;
@@ -3033,9 +3025,11 @@ void QQmlScriptBlob::dataReceived(const SourceCodeData &data)
initializeFromCompilationUnit(unit);
}
-void QQmlScriptBlob::initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit)
+void QQmlScriptBlob::initializeFromCachedUnit(const QV4::CompiledData::Unit *unit)
{
- initializeFromCompilationUnit(unit->createCompilationUnit());
+ QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit;
+ compilationUnit.adopt(new QV4::CompiledData::CompilationUnit(unit));
+ initializeFromCompilationUnit(compilationUnit);
}
void QQmlScriptBlob::done()
@@ -3097,7 +3091,7 @@ void QQmlScriptBlob::scriptImported(QQmlScriptBlob *blob, const QV4::CompiledDat
m_scripts << ref;
}
-void QQmlScriptBlob::initializeFromCompilationUnit(QV4::CompiledData::CompilationUnit *unit)
+void QQmlScriptBlob::initializeFromCompilationUnit(const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &unit)
{
Q_ASSERT(!m_scriptData);
m_scriptData = new QQmlScriptData();
@@ -3173,7 +3167,7 @@ void QQmlQmldirData::dataReceived(const SourceCodeData &data)
}
}
-void QQmlQmldirData::initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *)
+void QQmlQmldirData::initializeFromCachedUnit(const QV4::CompiledData::Unit *)
{
Q_UNIMPLEMENTED();
}
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index ab32bac7b2..875c335c9a 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -158,7 +158,7 @@ protected:
// Callbacks made in load thread
virtual void dataReceived(const SourceCodeData &) = 0;
- virtual void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit*) = 0;
+ virtual void initializeFromCachedUnit(const QV4::CompiledData::Unit*) = 0;
virtual void done();
#if QT_CONFIG(qml_network)
virtual void networkError(QNetworkReply::NetworkError);
@@ -318,19 +318,19 @@ public:
void load(QQmlDataBlob *, Mode = PreferSynchronous);
void loadWithStaticData(QQmlDataBlob *, const QByteArray &, Mode = PreferSynchronous);
- void loadWithCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit, Mode mode = PreferSynchronous);
+ void loadWithCachedUnit(QQmlDataBlob *blob, const QV4::CompiledData::Unit *unit, Mode mode = PreferSynchronous);
QQmlEngine *engine() const;
void initializeEngine(QQmlExtensionInterface *, const char *);
void invalidate();
-#ifdef QT_NO_QML_DEBUGGER
+#if !QT_CONFIG(qml_debug)
quintptr profiler() const { return 0; }
void setProfiler(quintptr) {}
#else
QQmlProfiler *profiler() const { return m_profiler.data(); }
void setProfiler(QQmlProfiler *profiler);
-#endif // QT_NO_QML_DEBUGGER
+#endif // QT_CONFIG(qml_debug)
private:
@@ -344,7 +344,7 @@ private:
void loadThread(QQmlDataBlob *);
void loadWithStaticDataThread(QQmlDataBlob *, const QByteArray &);
- void loadWithCachedUnitThread(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit);
+ void loadWithCachedUnitThread(QQmlDataBlob *blob, const QV4::CompiledData::Unit *unit);
#if QT_CONFIG(qml_network)
void networkReplyFinished(QNetworkReply *);
void networkReplyProgress(QNetworkReply *, qint64, qint64);
@@ -355,7 +355,7 @@ private:
void setData(QQmlDataBlob *, const QByteArray &);
void setData(QQmlDataBlob *, const QString &fileName);
void setData(QQmlDataBlob *, const QQmlDataBlob::SourceCodeData &);
- void setCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit);
+ void setCachedUnit(QQmlDataBlob *blob, const QV4::CompiledData::Unit *unit);
template<typename T>
struct TypedCallback
@@ -382,7 +382,7 @@ private:
QQmlEngine *m_engine;
QQmlTypeLoaderThread *m_thread;
-#ifndef QT_NO_QML_DEBUGGER
+#if QT_CONFIG(qml_debug)
QScopedPointer<QQmlProfiler> m_profiler;
#endif
@@ -457,7 +457,7 @@ protected:
void done() override;
void completed() override;
void dataReceived(const SourceCodeData &) override;
- void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit) override;
+ void initializeFromCachedUnit(const QV4::CompiledData::Unit *unit) override;
void allDependenciesDone() override;
void downloadProgressChanged(qreal) override;
@@ -570,14 +570,14 @@ public:
protected:
void dataReceived(const SourceCodeData &) override;
- void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit) override;
+ void initializeFromCachedUnit(const QV4::CompiledData::Unit *unit) override;
void done() override;
QString stringAt(int index) const override;
private:
void scriptImported(QQmlScriptBlob *blob, const QV4::CompiledData::Location &location, const QString &qualifier, const QString &nameSpace) override;
- void initializeFromCompilationUnit(QV4::CompiledData::CompilationUnit *unit);
+ void initializeFromCompilationUnit(const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &unit);
QList<ScriptReference> m_scripts;
QQmlScriptData *m_scriptData;
@@ -601,7 +601,7 @@ public:
protected:
void dataReceived(const SourceCodeData &) override;
- void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit*) override;
+ void initializeFromCachedUnit(const QV4::CompiledData::Unit *) override;
private:
QString m_content;
diff --git a/src/qml/qml/qqmltypenamecache.cpp b/src/qml/qml/qqmltypenamecache.cpp
index 72307c2800..32b0fa16c4 100644
--- a/src/qml/qml/qqmltypenamecache.cpp
+++ b/src/qml/qml/qqmltypenamecache.cpp
@@ -138,7 +138,7 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QHashedStringRef &name,
return result;
}
-QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QV4::String *name) const
+QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QV4::String *name, QQmlImport::RecursionRestriction recursionRestriction) const
{
Result result = query(m_namedImports, name);
@@ -154,7 +154,8 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QV4::String *name) cons
QQmlImportNamespace *typeNamespace = 0;
QList<QQmlError> errors;
QQmlType t;
- bool typeFound = m_imports.resolveType(typeName, &t, 0, 0, &typeNamespace, &errors);
+ bool typeFound = m_imports.resolveType(typeName, &t, 0, 0, &typeNamespace, &errors,
+ QQmlType::AnyRegistrationType, recursionRestriction);
if (typeFound) {
return Result(t);
}
diff --git a/src/qml/qml/qqmltypenamecache_p.h b/src/qml/qml/qqmltypenamecache_p.h
index 7e2cbec4b5..8ac25c4fbe 100644
--- a/src/qml/qml/qqmltypenamecache_p.h
+++ b/src/qml/qml/qqmltypenamecache_p.h
@@ -81,7 +81,7 @@ struct QQmlImportRef {
class QQmlType;
class QQmlEngine;
-class QQmlTypeNameCache : public QQmlRefCount
+class Q_QML_PRIVATE_EXPORT QQmlTypeNameCache : public QQmlRefCount
{
public:
QQmlTypeNameCache(const QQmlImports &imports);
@@ -107,7 +107,7 @@ public:
};
Result query(const QHashedStringRef &) const;
Result query(const QHashedStringRef &, const QQmlImportRef *importNamespace) const;
- Result query(const QV4::String *) const;
+ Result query(const QV4::String *, QQmlImport::RecursionRestriction recursionRestriction = QQmlImport::PreventRecursion) const;
Result query(const QV4::String *, const QQmlImportRef *importNamespace) const;
private:
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp
index 0fae76066d..8e067932bb 100644
--- a/src/qml/qml/qqmltypewrapper.cpp
+++ b/src/qml/qml/qqmltypewrapper.cpp
@@ -52,16 +52,17 @@ QT_BEGIN_NAMESPACE
using namespace QV4;
-DEFINE_OBJECT_VTABLE(QmlTypeWrapper);
+DEFINE_OBJECT_VTABLE(QQmlTypeWrapper);
+DEFINE_OBJECT_VTABLE(QQmlScopedEnumWrapper);
-void Heap::QmlTypeWrapper::init()
+void Heap::QQmlTypeWrapper::init()
{
Object::init();
mode = IncludeEnums;
object.init();
}
-void Heap::QmlTypeWrapper::destroy()
+void Heap::QQmlTypeWrapper::destroy()
{
QQmlType::derefHandle(typePrivate);
typePrivate = nullptr;
@@ -71,17 +72,17 @@ void Heap::QmlTypeWrapper::destroy()
Object::destroy();
}
-QQmlType Heap::QmlTypeWrapper::type() const
+QQmlType Heap::QQmlTypeWrapper::type() const
{
return QQmlType(typePrivate);
}
-bool QmlTypeWrapper::isSingleton() const
+bool QQmlTypeWrapper::isSingleton() const
{
return d()->type().isSingleton();
}
-QObject* QmlTypeWrapper::singletonObject() const
+QObject* QQmlTypeWrapper::singletonObject() const
{
if (!isSingleton())
return 0;
@@ -92,7 +93,7 @@ QObject* QmlTypeWrapper::singletonObject() const
return siinfo->qobjectApi(e);
}
-QVariant QmlTypeWrapper::toVariant() const
+QVariant QQmlTypeWrapper::toVariant() const
{
QObject *qobjectSingleton = singletonObject();
if (qobjectSingleton)
@@ -104,13 +105,13 @@ QVariant QmlTypeWrapper::toVariant() const
// Returns a type wrapper for type t on o. This allows access of enums, and attached properties.
-ReturnedValue QmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o, const QQmlType &t,
- Heap::QmlTypeWrapper::TypeNameMode mode)
+ReturnedValue QQmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o, const QQmlType &t,
+ Heap::QQmlTypeWrapper::TypeNameMode mode)
{
Q_ASSERT(t.isValid());
Scope scope(engine);
- Scoped<QmlTypeWrapper> w(scope, engine->memoryManager->allocObject<QmlTypeWrapper>());
+ Scoped<QQmlTypeWrapper> w(scope, engine->memoryManager->allocObject<QQmlTypeWrapper>());
w->d()->mode = mode; w->d()->object = o;
w->d()->typePrivate = t.priv();
QQmlType::refHandle(w->d()->typePrivate);
@@ -119,14 +120,14 @@ ReturnedValue QmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o, c
// Returns a type wrapper for importNamespace (of t) on o. This allows nested resolution of a type in a
// namespace.
-ReturnedValue QmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o, QQmlTypeNameCache *t, const QQmlImportRef *importNamespace,
- Heap::QmlTypeWrapper::TypeNameMode mode)
+ReturnedValue QQmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o, QQmlTypeNameCache *t, const QQmlImportRef *importNamespace,
+ Heap::QQmlTypeWrapper::TypeNameMode mode)
{
Q_ASSERT(t);
Q_ASSERT(importNamespace);
Scope scope(engine);
- Scoped<QmlTypeWrapper> w(scope, engine->memoryManager->allocObject<QmlTypeWrapper>());
+ Scoped<QQmlTypeWrapper> w(scope, engine->memoryManager->allocObject<QQmlTypeWrapper>());
w->d()->mode = mode; w->d()->object = o; w->d()->typeNamespace = t; w->d()->importNamespace = importNamespace;
t->addref();
return w.asReturnedValue();
@@ -161,14 +162,14 @@ static ReturnedValue throwLowercaseEnumError(QV4::ExecutionEngine *v4, String *n
return v4->throwTypeError(message);
}
-ReturnedValue QmlTypeWrapper::get(const Managed *m, String *name, bool *hasProperty)
+ReturnedValue QQmlTypeWrapper::get(const Managed *m, String *name, bool *hasProperty)
{
- Q_ASSERT(m->as<QmlTypeWrapper>());
+ Q_ASSERT(m->as<QQmlTypeWrapper>());
- QV4::ExecutionEngine *v4 = static_cast<const QmlTypeWrapper *>(m)->engine();
+ QV4::ExecutionEngine *v4 = static_cast<const QQmlTypeWrapper *>(m)->engine();
QV4::Scope scope(v4);
- Scoped<QmlTypeWrapper> w(scope, static_cast<const QmlTypeWrapper *>(m));
+ Scoped<QQmlTypeWrapper> w(scope, static_cast<const QQmlTypeWrapper *>(m));
if (hasProperty)
*hasProperty = true;
@@ -190,7 +191,7 @@ ReturnedValue QmlTypeWrapper::get(const Managed *m, String *name, bool *hasPrope
if (qobjectSingleton) {
// check for enum value
- const bool includeEnums = w->d()->mode == Heap::QmlTypeWrapper::IncludeEnums;
+ const bool includeEnums = w->d()->mode == Heap::QQmlTypeWrapper::IncludeEnums;
if (includeEnums && name->startsWithUpper()) {
bool ok = false;
const int value = enumForSingleton(v4, name, qobjectSingleton, type, &ok);
@@ -229,6 +230,15 @@ ReturnedValue QmlTypeWrapper::get(const Managed *m, String *name, bool *hasPrope
if (ok)
return QV4::Primitive::fromInt32(value).asReturnedValue();
+ value = type.scopedEnumIndex(QQmlEnginePrivate::get(v4->qmlEngine()), name, &ok);
+ if (ok) {
+ Scoped<QQmlScopedEnumWrapper> enumWrapper(scope, v4->memoryManager->allocObject<QQmlScopedEnumWrapper>());
+ enumWrapper->d()->typePrivate = type.priv();
+ QQmlType::refHandle(enumWrapper->d()->typePrivate);
+ enumWrapper->d()->scopeEnumIndex = value;
+ return enumWrapper.asReturnedValue();
+ }
+
// Fall through to base implementation
} else if (w->d()->object) {
@@ -285,13 +295,13 @@ ReturnedValue QmlTypeWrapper::get(const Managed *m, String *name, bool *hasPrope
}
-void QmlTypeWrapper::put(Managed *m, String *name, const Value &value)
+bool QQmlTypeWrapper::put(Managed *m, String *name, const Value &value)
{
- Q_ASSERT(m->as<QmlTypeWrapper>());
- QmlTypeWrapper *w = static_cast<QmlTypeWrapper *>(m);
+ Q_ASSERT(m->as<QQmlTypeWrapper>());
+ QQmlTypeWrapper *w = static_cast<QQmlTypeWrapper *>(m);
QV4::ExecutionEngine *v4 = w->engine();
if (v4->hasException)
- return;
+ return false;
QV4::Scope scope(v4);
QQmlContextData *context = v4->callingQmlContext();
@@ -302,7 +312,8 @@ void QmlTypeWrapper::put(Managed *m, String *name, const Value &value)
QQmlEngine *e = scope.engine->qmlEngine();
QObject *ao = qmlAttachedPropertiesObjectById(type.attachedPropertiesId(QQmlEnginePrivate::get(e)), object);
if (ao)
- QV4::QObjectWrapper::setQmlProperty(v4, context, ao, name, QV4::QObjectWrapper::IgnoreRevision, value);
+ return QV4::QObjectWrapper::setQmlProperty(v4, context, ao, name, QV4::QObjectWrapper::IgnoreRevision, value);
+ return false;
} else if (type.isSingleton()) {
QQmlEngine *e = scope.engine->qmlEngine();
QQmlType::SingletonInstanceInfo *siinfo = type.singletonInstanceInfo();
@@ -310,21 +321,23 @@ void QmlTypeWrapper::put(Managed *m, String *name, const Value &value)
QObject *qobjectSingleton = siinfo->qobjectApi(e);
if (qobjectSingleton) {
- QV4::QObjectWrapper::setQmlProperty(v4, context, qobjectSingleton, name, QV4::QObjectWrapper::IgnoreRevision, value);
+ return QV4::QObjectWrapper::setQmlProperty(v4, context, qobjectSingleton, name, QV4::QObjectWrapper::IgnoreRevision, value);
} else if (!siinfo->scriptApi(e).isUndefined()) {
QV4::ScopedObject apiprivate(scope, QJSValuePrivate::convertedToValue(v4, siinfo->scriptApi(e)));
if (!apiprivate) {
QString error = QLatin1String("Cannot assign to read-only property \"") + name->toQString() + QLatin1Char('\"');
v4->throwError(error);
- return;
+ return false;
} else {
- apiprivate->put(name, value);
+ return apiprivate->put(name, value);
}
}
}
+
+ return false;
}
-PropertyAttributes QmlTypeWrapper::query(const Managed *m, String *name)
+PropertyAttributes QQmlTypeWrapper::query(const Managed *m, String *name)
{
// ### Implement more efficiently.
bool hasProperty = false;
@@ -332,11 +345,11 @@ PropertyAttributes QmlTypeWrapper::query(const Managed *m, String *name)
return hasProperty ? Attr_Data : Attr_Invalid;
}
-bool QmlTypeWrapper::isEqualTo(Managed *a, Managed *b)
+bool QQmlTypeWrapper::isEqualTo(Managed *a, Managed *b)
{
- Q_ASSERT(a->as<QV4::QmlTypeWrapper>());
- QV4::QmlTypeWrapper *qmlTypeWrapperA = static_cast<QV4::QmlTypeWrapper *>(a);
- if (QV4::QmlTypeWrapper *qmlTypeWrapperB = b->as<QV4::QmlTypeWrapper>())
+ Q_ASSERT(a->as<QV4::QQmlTypeWrapper>());
+ QV4::QQmlTypeWrapper *qmlTypeWrapperA = static_cast<QV4::QQmlTypeWrapper *>(a);
+ if (QV4::QQmlTypeWrapper *qmlTypeWrapperB = b->as<QV4::QQmlTypeWrapper>())
return qmlTypeWrapperA->toVariant() == qmlTypeWrapperB->toVariant();
else if (QV4::QObjectWrapper *qobjectWrapper = b->as<QV4::QObjectWrapper>())
return qmlTypeWrapperA->toVariant().value<QObject*>() == qobjectWrapper->object();
@@ -344,4 +357,76 @@ bool QmlTypeWrapper::isEqualTo(Managed *a, Managed *b)
return false;
}
+ReturnedValue QQmlTypeWrapper::instanceOf(const Object *typeObject, const Value &var)
+{
+ Q_ASSERT(typeObject->as<QV4::QQmlTypeWrapper>());
+ const QV4::QQmlTypeWrapper *typeWrapper = static_cast<const QV4::QQmlTypeWrapper *>(typeObject);
+ QV4::ExecutionEngine *engine = typeObject->internalClass()->engine;
+ QQmlEnginePrivate *qenginepriv = QQmlEnginePrivate::get(engine->qmlEngine());
+
+ // can only compare a QObject* against a QML type
+ const QObjectWrapper *wrapper = var.as<QObjectWrapper>();
+ if (!wrapper)
+ return engine->throwTypeError();
+
+ // in case the wrapper outlived the QObject*
+ const QObject *wrapperObject = wrapper->object();
+ if (!wrapperObject)
+ return engine->throwTypeError();
+
+ const int myTypeId = typeWrapper->d()->type().typeId();
+ QQmlMetaObject myQmlType;
+ if (myTypeId == 0) {
+ // we're a composite type; a composite type cannot be equal to a
+ // non-composite object instance (Rectangle{} is never an instance of
+ // CustomRectangle)
+ QQmlData *theirDData = QQmlData::get(wrapperObject, /*create=*/false);
+ Q_ASSERT(theirDData); // must exist, otherwise how do we have a QObjectWrapper for it?!
+ if (!theirDData->compilationUnit)
+ return Encode(false);
+
+ QQmlTypeData *td = qenginepriv->typeLoader.getType(typeWrapper->d()->type().sourceUrl());
+ CompiledData::CompilationUnit *cu = td->compilationUnit();
+ myQmlType = qenginepriv->metaObjectForType(cu->metaTypeId);
+ } else {
+ myQmlType = qenginepriv->metaObjectForType(myTypeId);
+ }
+
+ const QMetaObject *theirType = wrapperObject->metaObject();
+
+ return QV4::Encode(QQmlMetaObject::canConvert(theirType, myQmlType));
+}
+
+void Heap::QQmlScopedEnumWrapper::destroy()
+{
+ QQmlType::derefHandle(typePrivate);
+ typePrivate = nullptr;
+ Object::destroy();
+}
+
+QQmlType Heap::QQmlScopedEnumWrapper::type() const
+{
+ return QQmlType(typePrivate);
+}
+
+ReturnedValue QQmlScopedEnumWrapper::get(const Managed *m, String *name, bool *hasProperty)
+{
+ Q_ASSERT(m->as<QQmlScopedEnumWrapper>());
+ const QQmlScopedEnumWrapper *resource = static_cast<const QQmlScopedEnumWrapper *>(m);
+ QV4::ExecutionEngine *v4 = resource->engine();
+ QV4::Scope scope(v4);
+
+ QQmlType type = resource->d()->type();
+ int index = resource->d()->scopeEnumIndex;
+
+ bool ok = false;
+ int value = type.scopedEnumValue(QQmlEnginePrivate::get(v4->qmlEngine()), index, name, &ok);
+ if (hasProperty)
+ *hasProperty = ok;
+ if (ok)
+ return QV4::Primitive::fromInt32(value).asReturnedValue();
+
+ return Encode::undefined();
+}
+
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmltypewrapper_p.h b/src/qml/qml/qqmltypewrapper_p.h
index c06c485fb8..25ff7ba7c8 100644
--- a/src/qml/qml/qqmltypewrapper_p.h
+++ b/src/qml/qml/qqmltypewrapper_p.h
@@ -60,12 +60,15 @@
QT_BEGIN_NAMESPACE
class QQmlTypeNameCache;
+class QQmlType;
+class QQmlTypePrivate;
+struct QQmlImportRef;
namespace QV4 {
namespace Heap {
-struct QmlTypeWrapper : Object {
+struct QQmlTypeWrapper : Object {
enum TypeNameMode {
IncludeEnums,
ExcludeEnums
@@ -83,11 +86,19 @@ struct QmlTypeWrapper : Object {
const QQmlImportRef *importNamespace;
};
+struct QQmlScopedEnumWrapper : Object {
+ void init() { Object::init(); }
+ void destroy();
+ int scopeEnumIndex;
+ QQmlTypePrivate *typePrivate;
+ QQmlType type() const;
+};
+
}
-struct Q_QML_EXPORT QmlTypeWrapper : Object
+struct Q_QML_EXPORT QQmlTypeWrapper : Object
{
- V4_OBJECT2(QmlTypeWrapper, Object)
+ V4_OBJECT2(QQmlTypeWrapper, Object)
V4_NEEDS_DESTROY
bool isSingleton() const;
@@ -96,16 +107,24 @@ struct Q_QML_EXPORT QmlTypeWrapper : Object
QVariant toVariant() const;
static ReturnedValue create(ExecutionEngine *, QObject *, const QQmlType &,
- Heap::QmlTypeWrapper::TypeNameMode = Heap::QmlTypeWrapper::IncludeEnums);
+ Heap::QQmlTypeWrapper::TypeNameMode = Heap::QQmlTypeWrapper::IncludeEnums);
static ReturnedValue create(ExecutionEngine *, QObject *, QQmlTypeNameCache *, const QQmlImportRef *,
- Heap::QmlTypeWrapper::TypeNameMode = Heap::QmlTypeWrapper::IncludeEnums);
+ Heap::QQmlTypeWrapper::TypeNameMode = Heap::QQmlTypeWrapper::IncludeEnums);
static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
- static void put(Managed *m, String *name, const Value &value);
+ static bool put(Managed *m, String *name, const Value &value);
static PropertyAttributes query(const Managed *, String *name);
static bool isEqualTo(Managed *that, Managed *o);
+ static ReturnedValue instanceOf(const Object *typeObject, const Value &var);
+};
+struct Q_QML_EXPORT QQmlScopedEnumWrapper : Object
+{
+ V4_OBJECT2(QQmlScopedEnumWrapper, Object)
+ V4_NEEDS_DESTROY
+
+ static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
};
}
diff --git a/src/qml/qml/qqmlvaluetypeproxybinding.cpp b/src/qml/qml/qqmlvaluetypeproxybinding.cpp
index 4e2e7b06c7..7a3e4b2df4 100644
--- a/src/qml/qml/qqmlvaluetypeproxybinding.cpp
+++ b/src/qml/qml/qqmlvaluetypeproxybinding.cpp
@@ -72,6 +72,11 @@ bool QQmlValueTypeProxyBinding::isValueTypeProxy() const
return true;
}
+QQmlAbstractBinding *QQmlValueTypeProxyBinding::subBindings() const
+{
+ return m_bindings.data();
+}
+
QQmlAbstractBinding *QQmlValueTypeProxyBinding::binding(QQmlPropertyIndex propertyIndex) const
{
QQmlAbstractBinding *binding = m_bindings.data();
diff --git a/src/qml/qml/qqmlvaluetypeproxybinding_p.h b/src/qml/qml/qqmlvaluetypeproxybinding_p.h
index 92b5470f39..ba0d305bd9 100644
--- a/src/qml/qml/qqmlvaluetypeproxybinding_p.h
+++ b/src/qml/qml/qqmlvaluetypeproxybinding_p.h
@@ -60,6 +60,7 @@ class QQmlValueTypeProxyBinding : public QQmlAbstractBinding
public:
QQmlValueTypeProxyBinding(QObject *o, QQmlPropertyIndex coreIndex);
+ QQmlAbstractBinding *subBindings() const;
QQmlAbstractBinding *binding(QQmlPropertyIndex targetPropertyIndex) const;
void removeBindings(quint32 mask);
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index b2b49f7909..c643beeadc 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -51,9 +51,11 @@
#include <private/qv4alloca_p.h>
#include <private/qv4objectiterator_p.h>
#include <private/qv4qobjectwrapper_p.h>
+#include <QtCore/qloggingcategory.h>
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(lcBindingRemoval)
DEFINE_OBJECT_VTABLE(QV4::QQmlValueTypeWrapper);
@@ -316,16 +318,16 @@ bool QQmlValueTypeWrapper::write(QObject *target, int propertyIndex) const
return true;
}
-void QQmlValueTypeWrapper::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QQmlValueTypeWrapper::method_toString(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Object *o = callData->thisObject.as<Object>();
+ const Object *o = thisObject->as<Object>();
if (!o)
- THROW_TYPE_ERROR();
- QQmlValueTypeWrapper *w = o->as<QQmlValueTypeWrapper>();
+ return b->engine()->throwTypeError();
+ const QQmlValueTypeWrapper *w = o->as<QQmlValueTypeWrapper>();
if (!w)
- THROW_TYPE_ERROR();
+ return b->engine()->throwTypeError();
- if (QQmlValueTypeReference *ref = w->as<QQmlValueTypeReference>())
+ if (const QQmlValueTypeReference *ref = w->as<QQmlValueTypeReference>())
if (!ref->readReferenceValue())
RETURN_UNDEFINED();
@@ -350,7 +352,7 @@ void QQmlValueTypeWrapper::method_toString(const BuiltinFunction *, Scope &scope
}
result += QLatin1Char(')');
}
- scope.result = scope.engine->newString(result);
+ return Encode(b->engine()->newString(result));
}
ReturnedValue QQmlValueTypeWrapper::get(const Managed *m, String *name, bool *hasProperty)
@@ -399,11 +401,11 @@ ReturnedValue QQmlValueTypeWrapper::get(const Managed *m, String *name, bool *ha
VALUE_TYPE_LOAD(QMetaType::Bool, bool, bool);
QVariant v;
- void *args[] = { Q_NULLPTR, Q_NULLPTR };
+ void *args[] = { nullptr, nullptr };
if (result->propType() == QMetaType::QVariant) {
args[0] = &v;
} else {
- v = QVariant(result->propType(), static_cast<void *>(Q_NULLPTR));
+ v = QVariant(result->propType(), static_cast<void *>(nullptr));
args[0] = v.data();
}
metaObject->d.static_metacall(reinterpret_cast<QObject*>(gadget), QMetaObject::ReadProperty, index, args);
@@ -411,13 +413,13 @@ ReturnedValue QQmlValueTypeWrapper::get(const Managed *m, String *name, bool *ha
#undef VALUE_TYPE_ACCESSOR
}
-void QQmlValueTypeWrapper::put(Managed *m, String *name, const Value &value)
+bool QQmlValueTypeWrapper::put(Managed *m, String *name, const Value &value)
{
Q_ASSERT(m->as<QQmlValueTypeWrapper>());
ExecutionEngine *v4 = static_cast<QQmlValueTypeWrapper *>(m)->engine();
Scope scope(v4);
if (scope.hasException())
- return;
+ return false;
Scoped<QQmlValueTypeWrapper> r(scope, static_cast<QQmlValueTypeWrapper *>(m));
Scoped<QQmlValueTypeReference> reference(scope, m->d());
@@ -428,7 +430,7 @@ void QQmlValueTypeWrapper::put(Managed *m, String *name, const Value &value)
QMetaProperty writebackProperty = reference->d()->object->metaObject()->property(reference->d()->property);
if (!writebackProperty.isWritable() || !reference->readReferenceValue())
- return;
+ return false;
writeBackPropertyType = writebackProperty.userType();
}
@@ -436,17 +438,20 @@ void QQmlValueTypeWrapper::put(Managed *m, String *name, const Value &value)
const QMetaObject *metaObject = r->d()->propertyCache()->metaObject();
const QQmlPropertyData *pd = r->d()->propertyCache()->property(name, 0, 0);
if (!pd)
- return;
+ return false;
if (reference) {
QV4::ScopedFunctionObject f(scope, value);
+ const QQmlQPointer<QObject> &referenceObject = reference->d()->object;
+ const int referencePropertyIndex = reference->d()->property;
+
if (f) {
if (!f->isBinding()) {
// assigning a JS function to a non-var-property is not allowed.
QString error = QStringLiteral("Cannot assign JavaScript function to value-type property");
ScopedString e(scope, v4->newString(error));
v4->throwError(e);
- return;
+ return false;
}
QQmlContextData *context = v4->callingQmlContext();
@@ -454,18 +459,31 @@ void QQmlValueTypeWrapper::put(Managed *m, String *name, const Value &value)
QQmlPropertyData cacheData;
cacheData.setWritable(true);
cacheData.setPropType(writeBackPropertyType);
- cacheData.setCoreIndex(reference->d()->property);
+ cacheData.setCoreIndex(referencePropertyIndex);
QV4::Scoped<QQmlBindingFunction> bindingFunction(scope, (const Value &)f);
QV4::ScopedContext ctx(scope, bindingFunction->scope());
- QQmlBinding *newBinding = QQmlBinding::create(&cacheData, bindingFunction->function(), reference->d()->object, context, ctx);
+ QQmlBinding *newBinding = QQmlBinding::create(&cacheData, bindingFunction->function(), referenceObject, context, ctx);
newBinding->setSourceLocation(bindingFunction->currentLocation());
- newBinding->setTarget(reference->d()->object, cacheData, pd);
+ newBinding->setTarget(referenceObject, cacheData, pd);
QQmlPropertyPrivate::setBinding(newBinding);
- return;
+ return true;
} else {
- QQmlPropertyPrivate::removeBinding(reference->d()->object, QQmlPropertyIndex(reference->d()->property, pd->coreIndex()));
+ if (Q_UNLIKELY(lcBindingRemoval().isInfoEnabled())) {
+ if (auto binding = QQmlPropertyPrivate::binding(referenceObject, QQmlPropertyIndex(referencePropertyIndex, pd->coreIndex()))) {
+ Q_ASSERT(!binding->isValueTypeProxy());
+ const auto qmlBinding = static_cast<const QQmlBinding*>(binding);
+ const auto stackFrame = v4->currentStackFrame;
+ qCInfo(lcBindingRemoval,
+ "Overwriting binding on %s::%s which was initially bound at %s by setting \"%s\" at %s:%d",
+ referenceObject->metaObject()->className(), referenceObject->metaObject()->property(referencePropertyIndex).name(),
+ qPrintable(qmlBinding->expressionIdentifier()),
+ metaObject->property(pd->coreIndex()).name(),
+ qPrintable(stackFrame->source()), stackFrame->lineNumber());
+ }
+ }
+ QQmlPropertyPrivate::removeBinding(referenceObject, QQmlPropertyIndex(referencePropertyIndex, pd->coreIndex()));
}
}
@@ -497,6 +515,8 @@ void QQmlValueTypeWrapper::put(Managed *m, String *name, const Value &value)
QMetaObject::metacall(reference->d()->object, QMetaObject::WriteProperty, reference->d()->property, a);
}
}
+
+ return true;
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h
index 87f9116056..f99d207d68 100644
--- a/src/qml/qml/qqmlvaluetypewrapper_p.h
+++ b/src/qml/qml/qqmlvaluetypewrapper_p.h
@@ -56,6 +56,7 @@
#include <private/qv4value_p.h>
#include <private/qv4object_p.h>
+#include <private/qqmlpropertycache_p.h>
QT_BEGIN_NAMESPACE
@@ -106,12 +107,12 @@ public:
bool write(QObject *target, int propertyIndex) const;
static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
- static void put(Managed *m, String *name, const Value &value);
+ static bool put(Managed *m, String *name, const Value &value);
static bool isEqualTo(Managed *m, Managed *other);
static PropertyAttributes query(const Managed *, String *name);
static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
- static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_toString(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
static void initProto(ExecutionEngine *v4);
};
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index 965b1fd3f2..73cb20dc7f 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -55,6 +55,7 @@
#include <private/qv4variantobject_p.h>
#include <private/qv4functionobject_p.h>
#include <private/qv4scopedvalue_p.h>
+#include <private/qv4jscall_p.h>
#include <private/qv4qobjectwrapper_p.h>
QT_BEGIN_NAMESPACE
@@ -104,8 +105,10 @@ void QQmlVMEVariantQObjectPtr::objectDestroyed(QObject *)
if (v4) {
QV4::Scope scope(v4);
QV4::Scoped<QV4::MemberData> sp(scope, m_target->propertyAndMethodStorage.value());
- if (sp)
- *(sp->data() + m_index) = QV4::Primitive::nullValue();
+ if (sp) {
+ QV4::MemberData::Index index{ sp->d(), sp->d()->values.values + m_index };
+ index.set(v4, QV4::Primitive::nullValue());
+ }
}
m_target->activate(m_target->object, m_target->methodOffset() + m_index, 0);
@@ -330,7 +333,7 @@ QQmlVMEMetaObject::QQmlVMEMetaObject(QV4::ExecutionEngine *engine,
if (size) {
QV4::Heap::MemberData *data = QV4::MemberData::allocate(engine, size);
propertyAndMethodStorage.set(engine, data);
- std::fill(data->data, data->data + data->size, QV4::Encode::undefined());
+ std::fill(data->values.values, data->values.values + data->values.size, QV4::Encode::undefined());
}
// Need JS wrapper to ensure properties/methods are marked.
@@ -365,77 +368,77 @@ void QQmlVMEMetaObject::writeProperty(int id, int v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
- *(md->data() + id) = QV4::Primitive::fromInt32(v);
+ md->set(engine, id, QV4::Primitive::fromInt32(v));
}
void QQmlVMEMetaObject::writeProperty(int id, bool v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
- *(md->data() + id) = QV4::Primitive::fromBoolean(v);
+ md->set(engine, id, QV4::Primitive::fromBoolean(v));
}
void QQmlVMEMetaObject::writeProperty(int id, double v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
- *(md->data() + id) = QV4::Primitive::fromDouble(v);
+ md->set(engine, id, QV4::Primitive::fromDouble(v));
}
void QQmlVMEMetaObject::writeProperty(int id, const QString& v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
- *(md->data() + id) = engine->newString(v);
+ md->set(engine, id, engine->newString(v));
}
void QQmlVMEMetaObject::writeProperty(int id, const QUrl& v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
- *(md->data() + id) = engine->newVariantObject(QVariant::fromValue(v));
+ md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
}
void QQmlVMEMetaObject::writeProperty(int id, const QDate& v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
- *(md->data() + id) = engine->newVariantObject(QVariant::fromValue(v));
+ md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
}
void QQmlVMEMetaObject::writeProperty(int id, const QDateTime& v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
- *(md->data() + id) = engine->newVariantObject(QVariant::fromValue(v));
+ md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
}
void QQmlVMEMetaObject::writeProperty(int id, const QPointF& v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
- *(md->data() + id) = engine->newVariantObject(QVariant::fromValue(v));
+ md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
}
void QQmlVMEMetaObject::writeProperty(int id, const QSizeF& v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
- *(md->data() + id) = engine->newVariantObject(QVariant::fromValue(v));
+ md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
}
void QQmlVMEMetaObject::writeProperty(int id, const QRectF& v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
- *(md->data() + id) = engine->newVariantObject(QVariant::fromValue(v));
+ md->set(engine, id, engine->newVariantObject(QVariant::fromValue(v)));
}
void QQmlVMEMetaObject::writeProperty(int id, QObject* v)
{
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md)
- *(md->data() + id) = QV4::QObjectWrapper::wrap(engine, v);
+ md->set(engine, id, QV4::Value::fromReturnedValue(QV4::QObjectWrapper::wrap(engine, v)));
QQmlVMEVariantQObjectPtr *guard = getQObjectGuardForProperty(id);
if (v && !guard) {
@@ -593,7 +596,7 @@ QList<QObject *> *QQmlVMEMetaObject::readPropertyAsList(int id) const
if (!v || (int)v->d()->data().userType() != qMetaTypeId<QList<QObject *> >()) {
QVariant variant(qVariantFromValue(QList<QObject*>()));
v = engine->newVariantObject(variant);
- *(md->data() + id) = v;
+ md->set(engine, id, v);
}
return static_cast<QList<QObject *> *>(v->d()->data().data());
}
@@ -742,7 +745,7 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
Q_ASSERT(fallbackMetaType != QMetaType::UnknownType);
if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
QVariant propertyAsVariant;
- if (QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>())
+ if (const QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>())
propertyAsVariant = v->d()->data();
QQml_valueTypeProvider()->readValueType(propertyAsVariant, a[0], fallbackMetaType);
}
@@ -815,9 +818,9 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
case QV4::CompiledData::Property::Quaternion:
Q_ASSERT(fallbackMetaType != QMetaType::UnknownType);
if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) {
- QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>();
+ const QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>();
if (!v) {
- *(md->data() + id) = engine->newVariantObject(QVariant());
+ md->set(engine, id, engine->newVariantObject(QVariant()));
v = (md->data() + id)->as<QV4::VariantObject>();
QQml_valueTypeProvider()->initValueType(fallbackMetaType, v->d()->data());
}
@@ -923,12 +926,14 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
id -= plainSignals;
if (id < methodCount) {
- if (!ctxt->engine)
+ QQmlEngine *engine = ctxt->engine;
+ if (!engine)
return -1; // We can't run the method
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(ctxt->engine);
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
+ QV4::ExecutionEngine *v4 = engine->handle();
ep->referenceScarceResources(); // "hold" scarce resources in memory during evaluation.
- QV4::Scope scope(ep->v4engine());
+ QV4::Scope scope(v4);
QV4::ScopedFunctionObject function(scope, method(id));
@@ -947,20 +952,20 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void *
}
const unsigned int parameterCount = function->formalParameterCount();
- QV4::ScopedCallData callData(scope, parameterCount);
- callData->thisObject = ep->v8engine()->global();
+ QV4::JSCallData jsCallData(scope, parameterCount);
+ *jsCallData->thisObject = v4->global();
for (uint ii = 0; ii < parameterCount; ++ii)
- callData->args[ii] = scope.engine->fromVariant(*(QVariant *)a[ii + 1]);
+ jsCallData->args[ii] = scope.engine->fromVariant(*(QVariant *)a[ii + 1]);
- function->call(scope, callData);
+ QV4::ScopedValue result(scope, function->call(jsCallData));
if (scope.hasException()) {
QQmlError error = scope.engine->catchExceptionAsQmlError();
if (error.isValid())
ep->warning(error);
if (a[0]) *(QVariant *)a[0] = QVariant();
} else {
- if (a[0]) *(QVariant *)a[0] = scope.engine->toVariant(scope.result, 0);
+ if (a[0]) *(QVariant *)a[0] = scope.engine->toVariant(result, 0);
}
ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete.
@@ -1028,7 +1033,7 @@ void QQmlVMEMetaObject::writeVarProperty(int id, const QV4::Value &value)
// Importantly, if the current value is a scarce resource, we need to ensure that it
// gets automatically released by the engine if no other references to it exist.
- QV4::VariantObject *oldVariant = (md->data() + id)->as<QV4::VariantObject>();
+ const QV4::VariantObject *oldVariant = (md->data() + id)->as<QV4::VariantObject>();
if (oldVariant)
oldVariant->removeVmePropertyReference();
@@ -1054,7 +1059,7 @@ void QQmlVMEMetaObject::writeVarProperty(int id, const QV4::Value &value)
guard->setGuardedValue(valueObject, this, id);
// Write the value and emit change signal as appropriate.
- *(md->data() + id) = value;
+ md->set(engine, id, value);
activate(object, methodOffset() + id, 0);
}
@@ -1067,7 +1072,7 @@ void QQmlVMEMetaObject::writeProperty(int id, const QVariant &value)
// Importantly, if the current value is a scarce resource, we need to ensure that it
// gets automatically released by the engine if no other references to it exist.
- QV4::VariantObject *oldv = (md->data() + id)->as<QV4::VariantObject>();
+ const QV4::VariantObject *oldv = (md->data() + id)->as<QV4::VariantObject>();
if (oldv)
oldv->removeVmePropertyReference();
@@ -1081,7 +1086,7 @@ void QQmlVMEMetaObject::writeProperty(int id, const QVariant &value)
// Write the value and emit change signal as appropriate.
QVariant currentValue = readPropertyAsVariant(id);
- *(md->data() + id) = newv;
+ md->set(engine, id, newv);
if ((currentValue.userType() != value.userType() || currentValue != value))
activate(object, methodOffset() + id, 0);
} else {
@@ -1093,14 +1098,14 @@ void QQmlVMEMetaObject::writeProperty(int id, const QVariant &value)
} else {
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (md) {
- QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>();
+ const QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>();
needActivate = (!v ||
v->d()->data().userType() != value.userType() ||
v->d()->data() != value);
if (v)
v->removeVmePropertyReference();
- *(md->data() + id) = engine->newVariantObject(value);
- v = static_cast<QV4::VariantObject *>(md->data() + id);
+ md->set(engine, id, engine->newVariantObject(value));
+ v = static_cast<const QV4::VariantObject *>(md->data() + id);
v->addVmePropertyReference();
}
}
@@ -1139,7 +1144,7 @@ void QQmlVMEMetaObject::setVmeMethod(int index, const QV4::Value &function)
QV4::MemberData *md = propertyAndMethodStorageAsMemberData();
if (!md)
return;
- *(md->data() + methodIndex + compiledObject->nProperties) = function;
+ md->set(engine, methodIndex + compiledObject->nProperties, function);
}
QV4::ReturnedValue QQmlVMEMetaObject::vmeProperty(int index) const
@@ -1167,15 +1172,15 @@ void QQmlVMEMetaObject::ensureQObjectWrapper()
QV4::QObjectWrapper::wrap(engine, object);
}
-void QQmlVMEMetaObject::mark(QV4::ExecutionEngine *e)
+void QQmlVMEMetaObject::mark(QV4::MarkStack *markStack)
{
- if (engine != e)
+ if (engine != markStack->engine)
return;
- propertyAndMethodStorage.markOnce(e);
+ propertyAndMethodStorage.markOnce(markStack);
if (QQmlVMEMetaObject *parent = parentVMEMetaObject())
- parent->mark(e);
+ parent->mark(markStack);
}
bool QQmlVMEMetaObject::aliasTarget(int index, QObject **target, int *coreIndex, int *valueTypeIndex) const
diff --git a/src/qml/qml/qqmlvmemetaobject_p.h b/src/qml/qml/qqmlvmemetaobject_p.h
index 2dff2b7a01..27e638ceb4 100644
--- a/src/qml/qml/qqmlvmemetaobject_p.h
+++ b/src/qml/qml/qqmlvmemetaobject_p.h
@@ -101,7 +101,7 @@ public:
static QQmlInterceptorMetaObject *get(QObject *obj);
- QAbstractDynamicMetaObject *toDynamicMetaObject(QObject *o) Q_DECL_OVERRIDE;
+ QAbstractDynamicMetaObject *toDynamicMetaObject(QObject *o) override;
// Used by auto-tests for inspection
QQmlPropertyCache *propertyCache() const { return cache; }
@@ -118,7 +118,7 @@ public:
}
protected:
- int metaCall(QObject *o, QMetaObject::Call c, int id, void **a) Q_DECL_OVERRIDE;
+ int metaCall(QObject *o, QMetaObject::Call c, int id, void **a) override;
bool intercept(QMetaObject::Call c, int id, void **a);
public:
@@ -163,7 +163,7 @@ public:
static QQmlVMEMetaObject *getForSignal(QObject *o, int coreIndex);
protected:
- int metaCall(QObject *o, QMetaObject::Call _c, int _id, void **_a) Q_DECL_OVERRIDE;
+ int metaCall(QObject *o, QMetaObject::Call _c, int _id, void **_a) override;
public:
QV4::ExecutionEngine *engine;
@@ -206,7 +206,7 @@ public:
void ensureQObjectWrapper();
- void mark(QV4::ExecutionEngine *e);
+ void mark(QV4::MarkStack *markStack);
void connectAlias(int aliasId);
diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp
index 58d8322675..9c9e199a5b 100644
--- a/src/qml/qml/qqmlxmlhttprequest.cpp
+++ b/src/qml/qml/qqmlxmlhttprequest.cpp
@@ -51,6 +51,7 @@
#include <private/qv4engine_p.h>
#include <private/qv4functionobject_p.h>
#include <private/qv4scopedvalue_p.h>
+#include <private/qv4jscall_p.h>
#include <QtCore/qobject.h>
#include <QtQml/qjsvalue.h>
@@ -74,8 +75,7 @@ using namespace QV4;
#define V4THROW_REFERENCE(string) \
do { \
ScopedObject error(scope, scope.engine->newReferenceErrorObject(QStringLiteral(string))); \
- scope.result = scope.engine->throwError(error); \
- return; \
+ return scope.engine->throwError(error); \
} while (false)
QT_BEGIN_NAMESPACE
@@ -276,25 +276,25 @@ public:
static void initClass(ExecutionEngine *engine);
// JS API
- static void method_get_nodeName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_nodeValue(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_nodeType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_namespaceUri(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
-
- static void method_get_parentNode(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_childNodes(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_firstChild(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_lastChild(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_previousSibling(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_nextSibling(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_attributes(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
-
- //static void ownerDocument(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- //static void namespaceURI(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- //static void prefix(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- //static void localName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- //static void baseURI(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- //static void textContent(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static ReturnedValue method_get_nodeName(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_nodeValue(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_nodeType(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_namespaceUri(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+
+ static ReturnedValue method_get_parentNode(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_childNodes(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_firstChild(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_lastChild(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_previousSibling(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_nextSibling(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_attributes(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+
+ //static ReturnedValue ownerDocument(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ //static ReturnedValue namespaceURI(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ //static ReturnedValue prefix(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ //static ReturnedValue localName(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ //static ReturnedValue baseURI(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ //static ReturnedValue textContent(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
static ReturnedValue getProto(ExecutionEngine *v4);
@@ -355,10 +355,10 @@ class Attr : public Node
{
public:
// JS API
- static void method_name(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static ReturnedValue method_name(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
// static void specified(CallContext *);
- static void method_value(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_ownerElement(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static ReturnedValue method_value(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_ownerElement(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
// static void schemaTypeInfo(CallContext *);
// static void isId(CallContext *c);
@@ -370,7 +370,7 @@ class CharacterData : public Node
{
public:
// JS API
- static void method_length(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static ReturnedValue method_length(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
// C++ API
static ReturnedValue prototype(ExecutionEngine *v4);
@@ -380,8 +380,8 @@ class Text : public CharacterData
{
public:
// JS API
- static void method_isElementContentWhitespace(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_wholeText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static ReturnedValue method_isElementContentWhitespace(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_wholeText(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
// C++ API
static ReturnedValue prototype(ExecutionEngine *);
@@ -398,10 +398,10 @@ class Document : public Node
{
public:
// JS API
- static void method_xmlVersion(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_xmlEncoding(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_xmlStandalone(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_documentElement(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static ReturnedValue method_xmlVersion(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_xmlEncoding(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_xmlStandalone(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_documentElement(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
// C++ API
static ReturnedValue prototype(ExecutionEngine *);
@@ -420,9 +420,10 @@ void NodeImpl::release()
document->release();
}
-void NodePrototype::method_get_nodeName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue NodePrototype::method_get_nodeName(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ Scope scope(b);
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
THROW_TYPE_ERROR();
@@ -441,12 +442,13 @@ void NodePrototype::method_get_nodeName(const QV4::BuiltinFunction *, QV4::Scope
name = r->d()->d->name;
break;
}
- scope.result = Encode(scope.engine->newString(name));
+ return Encode(scope.engine->newString(name));
}
-void NodePrototype::method_get_nodeValue(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue NodePrototype::method_get_nodeValue(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ QV4::Scope scope(b);
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
THROW_TYPE_ERROR();
@@ -459,75 +461,82 @@ void NodePrototype::method_get_nodeValue(const QV4::BuiltinFunction *, QV4::Scop
r->d()->d->type == NodeImpl::Notation)
RETURN_RESULT(Encode::null());
- scope.result = Encode(scope.engine->newString(r->d()->d->data));
+ return Encode(scope.engine->newString(r->d()->d->data));
}
-void NodePrototype::method_get_nodeType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue NodePrototype::method_get_nodeType(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ QV4::Scope scope(b);
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
THROW_TYPE_ERROR();
- scope.result = Encode(r->d()->d->type);
+ return Encode(r->d()->d->type);
}
-void NodePrototype::method_get_namespaceUri(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue NodePrototype::method_get_namespaceUri(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ QV4::Scope scope(b);
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
THROW_TYPE_ERROR();
- scope.result = Encode(scope.engine->newString(r->d()->d->namespaceUri));
+ return Encode(scope.engine->newString(r->d()->d->namespaceUri));
}
-void NodePrototype::method_get_parentNode(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue NodePrototype::method_get_parentNode(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ QV4::Scope scope(b);
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
THROW_TYPE_ERROR();
if (r->d()->d->parent)
- scope.result = Node::create(scope.engine, r->d()->d->parent);
+ return Node::create(scope.engine, r->d()->d->parent);
else
- scope.result = Encode::null();
+ return Encode::null();
}
-void NodePrototype::method_get_childNodes(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue NodePrototype::method_get_childNodes(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ QV4::Scope scope(b);
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
THROW_TYPE_ERROR();
- scope.result = NodeList::create(scope.engine, r->d()->d);
+ return NodeList::create(scope.engine, r->d()->d);
}
-void NodePrototype::method_get_firstChild(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue NodePrototype::method_get_firstChild(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ QV4::Scope scope(b);
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
THROW_TYPE_ERROR();
if (r->d()->d->children.isEmpty())
- scope.result = Encode::null();
+ return Encode::null();
else
- scope.result = Node::create(scope.engine, r->d()->d->children.constFirst());
+ return Node::create(scope.engine, r->d()->d->children.constFirst());
}
-void NodePrototype::method_get_lastChild(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue NodePrototype::method_get_lastChild(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ QV4::Scope scope(b);
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
THROW_TYPE_ERROR();
if (r->d()->d->children.isEmpty())
- scope.result = Encode::null();
+ return Encode::null();
else
- scope.result = Node::create(scope.engine, r->d()->d->children.constLast());
+ return Node::create(scope.engine, r->d()->d->children.constLast());
}
-void NodePrototype::method_get_previousSibling(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue NodePrototype::method_get_previousSibling(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ QV4::Scope scope(b);
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
THROW_TYPE_ERROR();
@@ -537,19 +546,19 @@ void NodePrototype::method_get_previousSibling(const QV4::BuiltinFunction *, QV4
for (int ii = 0; ii < r->d()->d->parent->children.count(); ++ii) {
if (r->d()->d->parent->children.at(ii) == r->d()->d) {
if (ii == 0)
- scope.result = Encode::null();
+ return Encode::null();
else
- scope.result = Node::create(scope.engine, r->d()->d->parent->children.at(ii - 1));
- return;
+ return Node::create(scope.engine, r->d()->d->parent->children.at(ii - 1));
}
}
- scope.result = Encode::null();
+ return Encode::null();
}
-void NodePrototype::method_get_nextSibling(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue NodePrototype::method_get_nextSibling(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ QV4::Scope scope(b);
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
THROW_TYPE_ERROR();
@@ -559,26 +568,26 @@ void NodePrototype::method_get_nextSibling(const QV4::BuiltinFunction *, QV4::Sc
for (int ii = 0; ii < r->d()->d->parent->children.count(); ++ii) {
if (r->d()->d->parent->children.at(ii) == r->d()->d) {
if ((ii + 1) == r->d()->d->parent->children.count())
- scope.result = Encode::null();
+ return Encode::null();
else
- scope.result = Node::create(scope.engine, r->d()->d->parent->children.at(ii + 1));
- return;
+ return Node::create(scope.engine, r->d()->d->parent->children.at(ii + 1));
}
}
- scope.result = Encode::null();
+ return Encode::null();
}
-void NodePrototype::method_get_attributes(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue NodePrototype::method_get_attributes(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ QV4::Scope scope(b);
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
THROW_TYPE_ERROR();
if (r->d()->d->type != NodeImpl::Element)
- scope.result = Encode::null();
+ return Encode::null();
else
- scope.result = NamedNodeMap::create(scope.engine, r->d()->d, r->d()->d->attributes);
+ return NamedNodeMap::create(scope.engine, r->d()->d, r->d()->d->attributes);
}
ReturnedValue NodePrototype::getProto(ExecutionEngine *v4)
@@ -659,40 +668,44 @@ ReturnedValue Attr::prototype(ExecutionEngine *engine)
return d->attrPrototype.value();
}
-void Attr::method_name(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue Attr::method_name(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ QV4::Scope scope(b);
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
RETURN_UNDEFINED();
- scope.result = scope.engine->newString(r->d()->d->name);
+ return Encode(scope.engine->newString(r->d()->d->name));
}
-void Attr::method_value(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue Attr::method_value(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ QV4::Scope scope(b);
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
RETURN_UNDEFINED();
- scope.result = scope.engine->newString(r->d()->d->data);
+ return Encode(scope.engine->newString(r->d()->d->data));
}
-void Attr::method_ownerElement(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue Attr::method_ownerElement(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ QV4::Scope scope(b);
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
RETURN_UNDEFINED();
- scope.result = Node::create(scope.engine, r->d()->d->parent);
+ return Node::create(scope.engine, r->d()->d->parent);
}
-void CharacterData::method_length(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue CharacterData::method_length(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ QV4::Scope scope(b);
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
RETURN_UNDEFINED();
- scope.result = Encode(r->d()->d->data.length());
+ return Encode(r->d()->d->data.length());
}
ReturnedValue CharacterData::prototype(ExecutionEngine *v4)
@@ -711,22 +724,24 @@ ReturnedValue CharacterData::prototype(ExecutionEngine *v4)
return d->characterDataPrototype.value();
}
-void Text::method_isElementContentWhitespace(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue Text::method_isElementContentWhitespace(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ QV4::Scope scope(b);
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
RETURN_UNDEFINED();
- scope.result = Encode(QStringRef(&r->d()->d->data).trimmed().isEmpty());
+ return Encode(QStringRef(&r->d()->d->data).trimmed().isEmpty());
}
-void Text::method_wholeText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue Text::method_wholeText(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ QV4::Scope scope(b);
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r)
RETURN_UNDEFINED();
- scope.result = scope.engine->newString(r->d()->d->data);
+ return Encode(scope.engine->newString(r->d()->d->data));
}
ReturnedValue Text::prototype(ExecutionEngine *v4)
@@ -952,40 +967,44 @@ ReturnedValue NodeList::create(ExecutionEngine *v4, NodeImpl *data)
return (v4->memoryManager->allocObject<NodeList>(data))->asReturnedValue();
}
-void Document::method_documentElement(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue Document::method_documentElement(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ Scope scope(b);
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r || r->d()->d->type != NodeImpl::Document)
RETURN_UNDEFINED();
- scope.result = Node::create(scope.engine, static_cast<DocumentImpl *>(r->d()->d)->root);
+ return Node::create(scope.engine, static_cast<DocumentImpl *>(r->d()->d)->root);
}
-void Document::method_xmlStandalone(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue Document::method_xmlStandalone(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ Scope scope(b);
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r || r->d()->d->type != NodeImpl::Document)
RETURN_UNDEFINED();
- scope.result = Encode(static_cast<DocumentImpl *>(r->d()->d)->isStandalone);
+ return Encode(static_cast<DocumentImpl *>(r->d()->d)->isStandalone);
}
-void Document::method_xmlVersion(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue Document::method_xmlVersion(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ Scope scope(b);
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r || r->d()->d->type != NodeImpl::Document)
RETURN_UNDEFINED();
- scope.result = scope.engine->newString(static_cast<DocumentImpl *>(r->d()->d)->version);
+ return Encode(scope.engine->newString(static_cast<DocumentImpl *>(r->d()->d)->version));
}
-void Document::method_xmlEncoding(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue Document::method_xmlEncoding(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ Scope scope(b);
+ Scoped<Node> r(scope, thisObject->as<Node>());
if (!r || r->d()->d->type != NodeImpl::Document)
RETURN_UNDEFINED();
- scope.result = scope.engine->newString(static_cast<DocumentImpl *>(r->d()->d)->encoding);
+ return Encode(scope.engine->newString(static_cast<DocumentImpl *>(r->d()->d)->encoding));
}
class QQmlXMLHttpRequest : public QObject
@@ -1557,9 +1576,8 @@ void QQmlXMLHttpRequest::dispatchCallback(Object *thisObj, QQmlContextData *cont
return;
}
- QV4::ScopedCallData callData(scope);
- callData->thisObject = Encode::undefined();
- callback->call(scope, callData);
+ QV4::JSCallData jsCallData(scope);
+ callback->call(jsCallData);
if (scope.engine->hasException) {
QQmlError error = scope.engine->catchExceptionAsQmlError();
@@ -1597,10 +1615,12 @@ struct QQmlXMLHttpRequestWrapper : Object {
QQmlXMLHttpRequest *request;
};
-struct QQmlXMLHttpRequestCtor : FunctionObject {
- void init(ExecutionEngine *engine);
+#define QQmlXMLHttpRequestCtorMembers(class, Member) \
+ Member(class, Pointer, Object *, proto)
- Pointer<Object> proto;
+DECLARE_HEAP_OBJECT(QQmlXMLHttpRequestCtor, FunctionObject) {
+ DECLARE_MARKOBJECTS(QQmlXMLHttpRequestCtor);
+ void init(ExecutionEngine *engine);
};
}
@@ -1614,48 +1634,40 @@ struct QQmlXMLHttpRequestWrapper : public Object
struct QQmlXMLHttpRequestCtor : public FunctionObject
{
V4_OBJECT2(QQmlXMLHttpRequestCtor, FunctionObject)
- static void markObjects(Heap::Base *that, ExecutionEngine *e) {
- QQmlXMLHttpRequestCtor::Data *c = static_cast<QQmlXMLHttpRequestCtor::Data *>(that);
- if (c->proto)
- c->proto->mark(e);
- FunctionObject::markObjects(that, e);
- }
- static void construct(const Managed *that, Scope &scope, QV4::CallData *)
+
+ static ReturnedValue callAsConstructor(const FunctionObject *f, const Value *, int)
{
- Scoped<QQmlXMLHttpRequestCtor> ctor(scope, that->as<QQmlXMLHttpRequestCtor>());
- if (!ctor) {
- scope.result = scope.engine->throwTypeError();
- return;
- }
+ Scope scope(f->engine());
+ const QQmlXMLHttpRequestCtor *ctor = static_cast<const QQmlXMLHttpRequestCtor *>(f);
QQmlXMLHttpRequest *r = new QQmlXMLHttpRequest(scope.engine->v8Engine->networkAccessManager());
Scoped<QQmlXMLHttpRequestWrapper> w(scope, scope.engine->memoryManager->allocObject<QQmlXMLHttpRequestWrapper>(r));
ScopedObject proto(scope, ctor->d()->proto);
w->setPrototype(proto);
- scope.result = w.asReturnedValue();
+ return w.asReturnedValue();
}
- static void call(const Managed *, Scope &scope, QV4::CallData *) {
- scope.result = Primitive::undefinedValue();
+ static ReturnedValue call(const FunctionObject *, const Value *, const Value *, int) {
+ return Encode::undefined();
}
void setupProto();
- static void method_open(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_setRequestHeader(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_send(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_abort(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_getResponseHeader(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_getAllResponseHeaders(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
-
- static void method_get_readyState(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_status(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_statusText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_responseText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_responseXML(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_response(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_responseType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_responseType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static ReturnedValue method_open(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_setRequestHeader(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_send(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_abort(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_getResponseHeader(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_getAllResponseHeaders(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+
+ static ReturnedValue method_get_readyState(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_status(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_statusText(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_responseText(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_responseXML(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_response(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_responseType(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_set_responseType(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
};
}
@@ -1686,7 +1698,7 @@ void QQmlXMLHttpRequestCtor::setupProto()
ExecutionEngine *v4 = engine();
Scope scope(v4);
ScopedObject p(scope, v4->newObject());
- d()->proto = p->d();
+ d()->proto.set(scope.engine, p->d());
// Methods
p->defineDefaultProperty(QStringLiteral("open"), method_open);
@@ -1717,18 +1729,19 @@ void QQmlXMLHttpRequestCtor::setupProto()
// XMLHttpRequest methods
-void QQmlXMLHttpRequestCtor::method_open(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_open(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scope scope(b);
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- if (callData->argc < 2 || callData->argc > 5)
+ if (argc < 2 || argc > 5)
THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
// Argument 0 - Method
- QString method = callData->args[0].toQStringNoThrow().toUpper();
+ QString method = argv[0].toQStringNoThrow().toUpper();
if (method != QLatin1String("GET") &&
method != QLatin1String("PUT") &&
method != QLatin1String("HEAD") &&
@@ -1740,23 +1753,23 @@ void QQmlXMLHttpRequestCtor::method_open(const QV4::BuiltinFunction *, QV4::Scop
THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Unsupported HTTP method type");
// Argument 1 - URL
- QUrl url = QUrl(callData->args[1].toQStringNoThrow());
+ QUrl url = QUrl(argv[1].toQStringNoThrow());
if (url.isRelative())
url = scope.engine->callingQmlContext()->resolvedUrl(url);
bool async = true;
// Argument 2 - async (optional)
- if (callData->argc > 2) {
- async = callData->args[2].booleanValue();
+ if (argc > 2) {
+ async = argv[2].booleanValue();
}
// Argument 3/4 - user/pass (optional)
QString username, password;
- if (callData->argc > 3)
- username = callData->args[3].toQStringNoThrow();
- if (callData->argc > 4)
- password = callData->args[4].toQStringNoThrow();
+ if (argc > 3)
+ username = argv[3].toQStringNoThrow();
+ if (argc > 4)
+ password = argv[4].toQStringNoThrow();
// Clear the fragment (if any)
url.setFragment(QString());
@@ -1765,24 +1778,25 @@ void QQmlXMLHttpRequestCtor::method_open(const QV4::BuiltinFunction *, QV4::Scop
if (!username.isNull()) url.setUserName(username);
if (!password.isNull()) url.setPassword(password);
- scope.result = r->open(w, scope.engine->callingQmlContext(), method, url, async ? QQmlXMLHttpRequest::AsynchronousLoad : QQmlXMLHttpRequest::SynchronousLoad);
+ return r->open(w, scope.engine->callingQmlContext(), method, url, async ? QQmlXMLHttpRequest::AsynchronousLoad : QQmlXMLHttpRequest::SynchronousLoad);
}
-void QQmlXMLHttpRequestCtor::method_setRequestHeader(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_setRequestHeader(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scope scope(b);
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- if (callData->argc != 2)
+ if (argc != 2)
THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
if (r->readyState() != QQmlXMLHttpRequest::Opened || r->sendFlag())
THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
- QString name = callData->args[0].toQStringNoThrow();
- QString value = callData->args[1].toQStringNoThrow();
+ QString name = argv[0].toQStringNoThrow();
+ QString value = argv[1].toQStringNoThrow();
// ### Check that name and value are well formed
@@ -1814,9 +1828,10 @@ void QQmlXMLHttpRequestCtor::method_setRequestHeader(const QV4::BuiltinFunction
RETURN_UNDEFINED();
}
-void QQmlXMLHttpRequestCtor::method_send(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_send(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scope scope(b);
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
@@ -1826,30 +1841,37 @@ void QQmlXMLHttpRequestCtor::method_send(const QV4::BuiltinFunction *, QV4::Scop
THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
QByteArray data;
- if (callData->argc > 0)
- data = callData->args[0].toQStringNoThrow().toUtf8();
+ if (argc > 0) {
+ if (const ArrayBuffer *buffer = argv[0].as<ArrayBuffer>()) {
+ data = buffer->asByteArray();
+ } else {
+ data = argv[0].toQStringNoThrow().toUtf8();
+ }
+ }
- scope.result = r->send(w, scope.engine->callingQmlContext(), data);
+ return r->send(w, scope.engine->callingQmlContext(), data);
}
-void QQmlXMLHttpRequestCtor::method_abort(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_abort(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scope scope(b);
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- scope.result = r->abort(w, scope.engine->callingQmlContext());
+ return r->abort(w, scope.engine->callingQmlContext());
}
-void QQmlXMLHttpRequestCtor::method_getResponseHeader(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_getResponseHeader(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scope scope(b);
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- if (callData->argc != 1)
+ if (argc != 1)
THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
if (r->readyState() != QQmlXMLHttpRequest::Loading &&
@@ -1857,17 +1879,18 @@ void QQmlXMLHttpRequestCtor::method_getResponseHeader(const QV4::BuiltinFunction
r->readyState() != QQmlXMLHttpRequest::HeadersReceived)
THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
- scope.result = scope.engine->newString(r->header(callData->args[0].toQStringNoThrow()));
+ return Encode(scope.engine->newString(r->header(argv[0].toQStringNoThrow())));
}
-void QQmlXMLHttpRequestCtor::method_getAllResponseHeaders(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_getAllResponseHeaders(const FunctionObject *b, const Value *thisObject, const Value *, int argc)
{
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scope scope(b);
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- if (callData->argc != 0)
+ if (argc != 0)
THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
if (r->readyState() != QQmlXMLHttpRequest::Loading &&
@@ -1875,23 +1898,25 @@ void QQmlXMLHttpRequestCtor::method_getAllResponseHeaders(const QV4::BuiltinFunc
r->readyState() != QQmlXMLHttpRequest::HeadersReceived)
THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
- scope.result = scope.engine->newString(r->headers());
+ return Encode(scope.engine->newString(r->headers()));
}
// XMLHttpRequest properties
-void QQmlXMLHttpRequestCtor::method_get_readyState(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_get_readyState(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scope scope(b);
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- scope.result = Encode(r->readyState());
+ return Encode(r->readyState());
}
-void QQmlXMLHttpRequestCtor::method_get_status(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_get_status(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scope scope(b);
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
@@ -1901,14 +1926,15 @@ void QQmlXMLHttpRequestCtor::method_get_status(const QV4::BuiltinFunction *, QV4
THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
if (r->errorFlag())
- scope.result = Encode(0);
+ return Encode(0);
else
- scope.result = Encode(r->replyStatus());
+ return Encode(r->replyStatus());
}
-void QQmlXMLHttpRequestCtor::method_get_statusText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_get_statusText(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scope scope(b);
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
@@ -1918,28 +1944,30 @@ void QQmlXMLHttpRequestCtor::method_get_statusText(const QV4::BuiltinFunction *,
THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
if (r->errorFlag())
- scope.result = scope.engine->newString(QString());
+ return Encode(scope.engine->newString(QString()));
else
- scope.result = scope.engine->newString(r->replyStatusText());
+ return Encode(scope.engine->newString(r->replyStatusText()));
}
-void QQmlXMLHttpRequestCtor::method_get_responseText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseText(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scope scope(b);
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
if (r->readyState() != QQmlXMLHttpRequest::Loading &&
r->readyState() != QQmlXMLHttpRequest::Done)
- scope.result = scope.engine->newString(QString());
+ return Encode(scope.engine->newString(QString()));
else
- scope.result = scope.engine->newString(r->responseBody());
+ return Encode(scope.engine->newString(r->responseBody()));
}
-void QQmlXMLHttpRequestCtor::method_get_responseXML(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseXML(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scope scope(b);
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
@@ -1947,17 +1975,18 @@ void QQmlXMLHttpRequestCtor::method_get_responseXML(const QV4::BuiltinFunction *
if (!r->receivedXml() ||
(r->readyState() != QQmlXMLHttpRequest::Loading &&
r->readyState() != QQmlXMLHttpRequest::Done)) {
- scope.result = Encode::null();
+ return Encode::null();
} else {
if (r->responseType().isEmpty())
r->setResponseType(QLatin1String("document"));
- scope.result = r->xmlResponseBody(scope.engine);
+ return r->xmlResponseBody(scope.engine);
}
}
-void QQmlXMLHttpRequestCtor::method_get_response(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_get_response(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scope scope(b);
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
@@ -1981,29 +2010,31 @@ void QQmlXMLHttpRequestCtor::method_get_response(const QV4::BuiltinFunction *, Q
}
-void QQmlXMLHttpRequestCtor::method_get_responseType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseType(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scope scope(b);
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- scope.result = scope.engine->newString(r->responseType());
+ return Encode(scope.engine->newString(r->responseType()));
}
-void QQmlXMLHttpRequestCtor::method_set_responseType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ReturnedValue QQmlXMLHttpRequestCtor::method_set_responseType(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
+ Scope scope(b);
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, thisObject->as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- if (callData->argc < 1)
+ if (argc < 1)
THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
// Argument 0 - response type
- r->setResponseType(callData->args[0].toQStringNoThrow());
+ r->setResponseType(argv[0].toQStringNoThrow());
- scope.result = Encode::undefined();
+ return Encode::undefined();
}
void qt_rem_qmlxmlhttprequest(ExecutionEngine * /* engine */, void *d)
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index 96d83b9870..44ad174f37 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -87,8 +87,7 @@ DEFINE_OBJECT_VTABLE(QtObject);
#define THROW_TYPE_ERROR_WITH_MESSAGE(msg) \
do { \
- scope.result = scope.engine->throwTypeError(QString::fromUtf8(msg)); \
- return; \
+ return scope.engine->throwTypeError(QString::fromUtf8(msg)); \
} while (false)
struct StaticQtMetaObject : public QObject
@@ -229,12 +228,12 @@ void QtObject::advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint
\qmlmethod bool Qt::isQtObject(object)
Returns true if \c object is a valid reference to a Qt or QML object, otherwise false.
*/
-void QtObject::method_isQtObject(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_isQtObject(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- if (callData->argc == 0)
+ if (argc == 0)
RETURN_RESULT(QV4::Encode(false));
- scope.result = QV4::Encode(callData->args[0].as<QV4::QObjectWrapper>() != 0);
+ return QV4::Encode(argv[0].as<QV4::QObjectWrapper>() != 0);
}
/*!
@@ -243,16 +242,16 @@ void QtObject::method_isQtObject(const BuiltinFunction *, Scope &scope, CallData
Returns a color with the specified \c red, \c green, \c blue and \c alpha components.
All components should be in the range 0-1 inclusive.
*/
-void QtObject::method_rgba(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_rgba(const FunctionObject *f, const Value *, const Value *argv, int argc)
{
- int argCount = callData->argc;
- if (argCount < 3 || argCount > 4)
+ QV4::Scope scope(f);
+ if (argc < 3 || argc > 4)
THROW_GENERIC_ERROR("Qt.rgba(): Invalid arguments");
- double r = callData->args[0].toNumber();
- double g = callData->args[1].toNumber();
- double b = callData->args[2].toNumber();
- double a = (argCount == 4) ? callData->args[3].toNumber() : 1;
+ double r = argv[0].toNumber();
+ double g = argv[1].toNumber();
+ double b = argv[2].toNumber();
+ double a = (argc == 4) ? argv[3].toNumber() : 1;
if (r < 0.0) r=0.0;
if (r > 1.0) r=1.0;
@@ -263,7 +262,7 @@ void QtObject::method_rgba(const BuiltinFunction *, Scope &scope, CallData *call
if (a < 0.0) a=0.0;
if (a > 1.0) a=1.0;
- scope.result = scope.engine->fromVariant(QQml_colorProvider()->fromRgbF(r, g, b, a));
+ return scope.engine->fromVariant(QQml_colorProvider()->fromRgbF(r, g, b, a));
}
/*!
@@ -272,16 +271,17 @@ void QtObject::method_rgba(const BuiltinFunction *, Scope &scope, CallData *call
Returns a color with the specified \c hue, \c saturation, \c lightness and \c alpha components.
All components should be in the range 0-1 inclusive.
*/
-void QtObject::method_hsla(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_hsla(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- int argCount = callData->argc;
+ QV4::Scope scope(b);
+ int argCount = argc;
if (argCount < 3 || argCount > 4)
THROW_GENERIC_ERROR("Qt.hsla(): Invalid arguments");
- double h = callData->args[0].toNumber();
- double s = callData->args[1].toNumber();
- double l = callData->args[2].toNumber();
- double a = (argCount == 4) ? callData->args[3].toNumber() : 1;
+ double h = argv[0].toNumber();
+ double s = argv[1].toNumber();
+ double l = argv[2].toNumber();
+ double a = (argCount == 4) ? argv[3].toNumber() : 1;
if (h < 0.0) h=0.0;
if (h > 1.0) h=1.0;
@@ -292,7 +292,7 @@ void QtObject::method_hsla(const BuiltinFunction *, Scope &scope, CallData *call
if (a < 0.0) a=0.0;
if (a > 1.0) a=1.0;
- scope.result = scope.engine->fromVariant(QQml_colorProvider()->fromHslF(h, s, l, a));
+ return scope.engine->fromVariant(QQml_colorProvider()->fromHslF(h, s, l, a));
}
/*!
@@ -303,23 +303,24 @@ All components should be in the range 0-1 inclusive.
\since 5.5
*/
-void QtObject::method_hsva(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_hsva(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- int argCount = callData->argc;
+ QV4::Scope scope(b);
+ int argCount = argc;
if (argCount < 3 || argCount > 4)
THROW_GENERIC_ERROR("Qt.hsva(): Invalid arguments");
- double h = callData->args[0].toNumber();
- double s = callData->args[1].toNumber();
- double v = callData->args[2].toNumber();
- double a = (argCount == 4) ? callData->args[3].toNumber() : 1;
+ double h = argv[0].toNumber();
+ double s = argv[1].toNumber();
+ double v = argv[2].toNumber();
+ double a = (argCount == 4) ? argv[3].toNumber() : 1;
h = qBound(0.0, h, 1.0);
s = qBound(0.0, s, 1.0);
v = qBound(0.0, v, 1.0);
a = qBound(0.0, a, 1.0);
- scope.result = scope.engine->fromVariant(QQml_colorProvider()->fromHsvF(h, s, v, a));
+ return scope.engine->fromVariant(QQml_colorProvider()->fromHsvF(h, s, v, a));
}
/*!
@@ -330,14 +331,15 @@ may be either color values or string values. If a string value is supplied it
must be convertible to a color, as described for the \l{colorbasictypedocs}{color}
basic type.
*/
-void QtObject::method_colorEqual(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_colorEqual(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc != 2)
+ QV4::Scope scope(b);
+ if (argc != 2)
THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid arguments");
bool ok = false;
- QVariant lhs = scope.engine->toVariant(callData->args[0], -1);
+ QVariant lhs = scope.engine->toVariant(argv[0], -1);
if (lhs.userType() == QVariant::String) {
lhs = QQmlStringConverters::colorFromString(lhs.toString(), &ok);
if (!ok) {
@@ -347,7 +349,7 @@ void QtObject::method_colorEqual(const BuiltinFunction *, Scope &scope, CallData
THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid arguments");
}
- QVariant rhs = scope.engine->toVariant(callData->args[1], -1);
+ QVariant rhs = scope.engine->toVariant(argv[1], -1);
if (rhs.userType() == QVariant::String) {
rhs = QQmlStringConverters::colorFromString(rhs.toString(), &ok);
if (!ok) {
@@ -358,7 +360,7 @@ void QtObject::method_colorEqual(const BuiltinFunction *, Scope &scope, CallData
}
bool equal = (lhs == rhs);
- scope.result = QV4::Encode(equal);
+ return QV4::Encode(equal);
}
/*!
@@ -368,47 +370,50 @@ Returns a \c rect with the top-left corner at \c x, \c y and the specified \c wi
The returned object has \c x, \c y, \c width and \c height attributes with the given values.
*/
-void QtObject::method_rect(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_rect(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc != 4)
+ QV4::Scope scope(b);
+ if (argc != 4)
THROW_GENERIC_ERROR("Qt.rect(): Invalid arguments");
- double x = callData->args[0].toNumber();
- double y = callData->args[1].toNumber();
- double w = callData->args[2].toNumber();
- double h = callData->args[3].toNumber();
+ double x = argv[0].toNumber();
+ double y = argv[1].toNumber();
+ double w = argv[2].toNumber();
+ double h = argv[3].toNumber();
- scope.result = scope.engine->fromVariant(QVariant::fromValue(QRectF(x, y, w, h)));
+ return scope.engine->fromVariant(QVariant::fromValue(QRectF(x, y, w, h)));
}
/*!
\qmlmethod point Qt::point(int x, int y)
Returns a Point with the specified \c x and \c y coordinates.
*/
-void QtObject::method_point(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_point(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc != 2)
+ QV4::Scope scope(b);
+ if (argc != 2)
THROW_GENERIC_ERROR("Qt.point(): Invalid arguments");
- double x = callData->args[0].toNumber();
- double y = callData->args[1].toNumber();
+ double x = argv[0].toNumber();
+ double y = argv[1].toNumber();
- scope.result = scope.engine->fromVariant(QVariant::fromValue(QPointF(x, y)));
+ return scope.engine->fromVariant(QVariant::fromValue(QPointF(x, y)));
}
/*!
\qmlmethod Qt::size(int width, int height)
Returns a Size with the specified \c width and \c height.
*/
-void QtObject::method_size(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_size(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc != 2)
+ QV4::Scope scope(b);
+ if (argc != 2)
THROW_GENERIC_ERROR("Qt.size(): Invalid arguments");
- double w = callData->args[0].toNumber();
- double h = callData->args[1].toNumber();
+ double w = argv[0].toNumber();
+ double h = argv[1].toNumber();
- scope.result = scope.engine->fromVariant(QVariant::fromValue(QSizeF(w, h)));
+ return scope.engine->fromVariant(QVariant::fromValue(QSizeF(w, h)));
}
/*!
@@ -419,17 +424,18 @@ key-value pairs where valid keys are the \l{fontbasictypedocs}{font} type's
subproperty names, and the values are valid values for each subproperty.
Invalid keys will be ignored.
*/
-void QtObject::method_font(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_font(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc != 1 || !callData->args[0].isObject())
+ QV4::Scope scope(b);
+ if (argc != 1 || !argv[0].isObject())
THROW_GENERIC_ERROR("Qt.font(): Invalid arguments");
QV4::ExecutionEngine *v4 = scope.engine;
bool ok = false;
- QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QFont, QQmlV4Handle(callData->args[0]), v4, &ok);
+ QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QFont, QQmlV4Handle(argv[0]), v4, &ok);
if (!ok)
THROW_GENERIC_ERROR("Qt.font(): Invalid argument: no valid font subproperties specified");
- scope.result = scope.engine->fromVariant(v);
+ return scope.engine->fromVariant(v);
}
@@ -438,73 +444,77 @@ void QtObject::method_font(const BuiltinFunction *, Scope &scope, CallData *call
\qmlmethod Qt::vector2d(real x, real y)
Returns a Vector2D with the specified \c x and \c y.
*/
-void QtObject::method_vector2d(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_vector2d(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc != 2)
+ QV4::Scope scope(b);
+ if (argc != 2)
THROW_GENERIC_ERROR("Qt.vector2d(): Invalid arguments");
float xy[3]; // qvector2d uses float internally
- xy[0] = callData->args[0].toNumber();
- xy[1] = callData->args[1].toNumber();
+ xy[0] = argv[0].toNumber();
+ xy[1] = argv[1].toNumber();
const void *params[] = { xy };
- scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector2D, 1, params));
+ return scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector2D, 1, params));
}
/*!
\qmlmethod Qt::vector3d(real x, real y, real z)
Returns a Vector3D with the specified \c x, \c y and \c z.
*/
-void QtObject::method_vector3d(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_vector3d(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc != 3)
+ QV4::Scope scope(b);
+ if (argc != 3)
THROW_GENERIC_ERROR("Qt.vector3d(): Invalid arguments");
float xyz[3]; // qvector3d uses float internally
- xyz[0] = callData->args[0].toNumber();
- xyz[1] = callData->args[1].toNumber();
- xyz[2] = callData->args[2].toNumber();
+ xyz[0] = argv[0].toNumber();
+ xyz[1] = argv[1].toNumber();
+ xyz[2] = argv[2].toNumber();
const void *params[] = { xyz };
- scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector3D, 1, params));
+ return scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector3D, 1, params));
}
/*!
\qmlmethod Qt::vector4d(real x, real y, real z, real w)
Returns a Vector4D with the specified \c x, \c y, \c z and \c w.
*/
-void QtObject::method_vector4d(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_vector4d(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc != 4)
+ QV4::Scope scope(b);
+ if (argc != 4)
THROW_GENERIC_ERROR("Qt.vector4d(): Invalid arguments");
float xyzw[4]; // qvector4d uses float internally
- xyzw[0] = callData->args[0].toNumber();
- xyzw[1] = callData->args[1].toNumber();
- xyzw[2] = callData->args[2].toNumber();
- xyzw[3] = callData->args[3].toNumber();
+ xyzw[0] = argv[0].toNumber();
+ xyzw[1] = argv[1].toNumber();
+ xyzw[2] = argv[2].toNumber();
+ xyzw[3] = argv[3].toNumber();
const void *params[] = { xyzw };
- scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector4D, 1, params));
+ return scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector4D, 1, params));
}
/*!
\qmlmethod Qt::quaternion(real scalar, real x, real y, real z)
Returns a Quaternion with the specified \c scalar, \c x, \c y, and \c z.
*/
-void QtObject::method_quaternion(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_quaternion(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc != 4)
+ QV4::Scope scope(b);
+ if (argc != 4)
THROW_GENERIC_ERROR("Qt.quaternion(): Invalid arguments");
qreal sxyz[4]; // qquaternion uses qreal internally
- sxyz[0] = callData->args[0].toNumber();
- sxyz[1] = callData->args[1].toNumber();
- sxyz[2] = callData->args[2].toNumber();
- sxyz[3] = callData->args[3].toNumber();
+ sxyz[0] = argv[0].toNumber();
+ sxyz[1] = argv[1].toNumber();
+ sxyz[2] = argv[2].toNumber();
+ sxyz[3] = argv[3].toNumber();
const void *params[] = { sxyz };
- scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QQuaternion, 1, params));
+ return scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QQuaternion, 1, params));
}
/*!
@@ -516,47 +526,45 @@ matrix values.
Finally, the function may be called with no arguments and the resulting
matrix will be the identity matrix.
*/
-void QtObject::method_matrix4x4(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_matrix4x4(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- QV4::ExecutionEngine *v4 = scope.engine;
+ QV4::Scope scope(b);
- if (callData->argc == 0) {
- scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 0, Q_NULLPTR));
- return;
+ if (argc == 0) {
+ return scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 0, nullptr));
}
- if (callData->argc == 1 && callData->args[0].isObject()) {
+ if (argc == 1 && argv[0].isObject()) {
bool ok = false;
- QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QMatrix4x4, QQmlV4Handle(callData->args[0]), v4, &ok);
+ QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QMatrix4x4, QQmlV4Handle(argv[0]), scope.engine, &ok);
if (!ok)
THROW_GENERIC_ERROR("Qt.matrix4x4(): Invalid argument: not a valid matrix4x4 values array");
- scope.result = scope.engine->fromVariant(v);
- return;
+ return scope.engine->fromVariant(v);
}
- if (callData->argc != 16)
+ if (argc != 16)
THROW_GENERIC_ERROR("Qt.matrix4x4(): Invalid arguments");
qreal vals[16]; // qmatrix4x4 uses qreal internally
- vals[0] = callData->args[0].toNumber();
- vals[1] = callData->args[1].toNumber();
- vals[2] = callData->args[2].toNumber();
- vals[3] = callData->args[3].toNumber();
- vals[4] = callData->args[4].toNumber();
- vals[5] = callData->args[5].toNumber();
- vals[6] = callData->args[6].toNumber();
- vals[7] = callData->args[7].toNumber();
- vals[8] = callData->args[8].toNumber();
- vals[9] = callData->args[9].toNumber();
- vals[10] = callData->args[10].toNumber();
- vals[11] = callData->args[11].toNumber();
- vals[12] = callData->args[12].toNumber();
- vals[13] = callData->args[13].toNumber();
- vals[14] = callData->args[14].toNumber();
- vals[15] = callData->args[15].toNumber();
+ vals[0] = argv[0].toNumber();
+ vals[1] = argv[1].toNumber();
+ vals[2] = argv[2].toNumber();
+ vals[3] = argv[3].toNumber();
+ vals[4] = argv[4].toNumber();
+ vals[5] = argv[5].toNumber();
+ vals[6] = argv[6].toNumber();
+ vals[7] = argv[7].toNumber();
+ vals[8] = argv[8].toNumber();
+ vals[9] = argv[9].toNumber();
+ vals[10] = argv[10].toNumber();
+ vals[11] = argv[11].toNumber();
+ vals[12] = argv[12].toNumber();
+ vals[13] = argv[13].toNumber();
+ vals[14] = argv[14].toNumber();
+ vals[15] = argv[15].toNumber();
const void *params[] = { vals };
- scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 1, params));
+ return scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 1, params));
}
/*!
@@ -573,29 +581,28 @@ by factor and converts the color back to RGB.
If \c factor is not supplied, returns a color 50% lighter than \c baseColor (factor 1.5).
*/
-void QtObject::method_lighter(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_lighter(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc != 1 && callData->argc != 2)
+ QV4::Scope scope(b);
+ if (argc != 1 && argc != 2)
THROW_GENERIC_ERROR("Qt.lighter(): Invalid arguments");
- QVariant v = scope.engine->toVariant(callData->args[0], -1);
+ QVariant v = scope.engine->toVariant(argv[0], -1);
if (v.userType() == QVariant::String) {
bool ok = false;
v = QQmlStringConverters::colorFromString(v.toString(), &ok);
if (!ok) {
- scope.result = QV4::Encode::null();
- return;
+ return QV4::Encode::null();
}
} else if (v.userType() != QVariant::Color) {
- scope.result = QV4::Encode::null();
- return;
+ return QV4::Encode::null();
}
qreal factor = 1.5;
- if (callData->argc == 2)
- factor = callData->args[1].toNumber();
+ if (argc == 2)
+ factor = argv[1].toNumber();
- scope.result = scope.engine->fromVariant(QQml_colorProvider()->lighter(v, factor));
+ return scope.engine->fromVariant(QQml_colorProvider()->lighter(v, factor));
}
/*!
@@ -613,29 +620,28 @@ by factor and converts the color back to RGB.
If \c factor is not supplied, returns a color 50% darker than \c baseColor (factor 2.0).
*/
-void QtObject::method_darker(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_darker(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc != 1 && callData->argc != 2)
+ QV4::Scope scope(b);
+ if (argc != 1 && argc != 2)
THROW_GENERIC_ERROR("Qt.darker(): Invalid arguments");
- QVariant v = scope.engine->toVariant(callData->args[0], -1);
+ QVariant v = scope.engine->toVariant(argv[0], -1);
if (v.userType() == QVariant::String) {
bool ok = false;
v = QQmlStringConverters::colorFromString(v.toString(), &ok);
if (!ok) {
- scope.result = QV4::Encode::null();
- return;
+ return QV4::Encode::null();
}
} else if (v.userType() != QVariant::Color) {
- scope.result = QV4::Encode::null();
- return;
+ return QV4::Encode::null();
}
qreal factor = 2.0;
- if (callData->argc == 2)
- factor = callData->args[1].toNumber();
+ if (argc == 2)
+ factor = argv[1].toNumber();
- scope.result = scope.engine->fromVariant(QQml_colorProvider()->darker(v, factor));
+ return scope.engine->fromVariant(QQml_colorProvider()->darker(v, factor));
}
/*!
@@ -662,40 +668,37 @@ void QtObject::method_darker(const BuiltinFunction *, Scope &scope, CallData *ca
Tint is most useful when a subtle change is intended to be conveyed due to some event; you can then use tinting to more effectively tune the visible color.
*/
-void QtObject::method_tint(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_tint(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc != 2)
+ QV4::Scope scope(b);
+ if (argc != 2)
THROW_GENERIC_ERROR("Qt.tint(): Invalid arguments");
// base color
- QVariant v1 = scope.engine->toVariant(callData->args[0], -1);
+ QVariant v1 = scope.engine->toVariant(argv[0], -1);
if (v1.userType() == QVariant::String) {
bool ok = false;
v1 = QQmlStringConverters::colorFromString(v1.toString(), &ok);
if (!ok) {
- scope.result = QV4::Encode::null();
- return;
+ return QV4::Encode::null();
}
} else if (v1.userType() != QVariant::Color) {
- scope.result = QV4::Encode::null();
- return;
+ return QV4::Encode::null();
}
// tint color
- QVariant v2 = scope.engine->toVariant(callData->args[1], -1);
+ QVariant v2 = scope.engine->toVariant(argv[1], -1);
if (v2.userType() == QVariant::String) {
bool ok = false;
v2 = QQmlStringConverters::colorFromString(v2.toString(), &ok);
if (!ok) {
- scope.result = QV4::Encode::null();
- return;
+ return QV4::Encode::null();
}
} else if (v2.userType() != QVariant::Color) {
- scope.result = QV4::Encode::null();
- return;
+ return QV4::Encode::null();
}
- scope.result = scope.engine->fromVariant(QQml_colorProvider()->tint(v1, v2));
+ return scope.engine->fromVariant(QQml_colorProvider()->tint(v1, v2));
}
/*!
@@ -714,21 +717,22 @@ If \a format is not specified, \a date is formatted using
\sa Locale
*/
-void QtObject::method_formatDate(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_formatDate(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc < 1 || callData->argc > 2)
+ QV4::Scope scope(b);
+ if (argc < 1 || argc > 2)
THROW_GENERIC_ERROR("Qt.formatDate(): Invalid arguments");
Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
- QDate date = scope.engine->toVariant(callData->args[0], -1).toDateTime().date();
+ QDate date = scope.engine->toVariant(argv[0], -1).toDateTime().date();
QString formattedDate;
- if (callData->argc == 2) {
- QV4::ScopedString s(scope, callData->args[1]);
+ if (argc == 2) {
+ QV4::ScopedString s(scope, argv[1]);
if (s) {
QString format = s->toQString();
formattedDate = date.toString(format);
- } else if (callData->args[1].isNumber()) {
- quint32 intFormat = callData->args[1].asDouble();
+ } else if (argv[1].isNumber()) {
+ quint32 intFormat = argv[1].asDouble();
Qt::DateFormat format = Qt::DateFormat(intFormat);
formattedDate = date.toString(format);
} else {
@@ -738,7 +742,7 @@ void QtObject::method_formatDate(const BuiltinFunction *, Scope &scope, CallData
formattedDate = date.toString(enumFormat);
}
- scope.result = scope.engine->newString(formattedDate);
+ return Encode(scope.engine->newString(formattedDate));
}
/*!
@@ -756,27 +760,28 @@ If \a format is not specified, \a time is formatted using
\sa Locale
*/
-void QtObject::method_formatTime(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_formatTime(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc < 1 || callData->argc > 2)
+ QV4::Scope scope(b);
+ if (argc < 1 || argc > 2)
THROW_GENERIC_ERROR("Qt.formatTime(): Invalid arguments");
- QVariant argVariant = scope.engine->toVariant(callData->args[0], -1);
+ QVariant argVariant = scope.engine->toVariant(argv[0], -1);
QTime time;
- if (callData->args[0].as<DateObject>() || (argVariant.type() == QVariant::String))
+ if (argv[0].as<DateObject>() || (argVariant.type() == QVariant::String))
time = argVariant.toDateTime().time();
else // if (argVariant.type() == QVariant::Time), or invalid.
time = argVariant.toTime();
Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
QString formattedTime;
- if (callData->argc == 2) {
- QV4::ScopedString s(scope, callData->args[1]);
+ if (argc == 2) {
+ QV4::ScopedString s(scope, argv[1]);
if (s) {
QString format = s->toQString();
formattedTime = time.toString(format);
- } else if (callData->args[1].isNumber()) {
- quint32 intFormat = callData->args[1].asDouble();
+ } else if (argv[1].isNumber()) {
+ quint32 intFormat = argv[1].asDouble();
Qt::DateFormat format = Qt::DateFormat(intFormat);
formattedTime = time.toString(format);
} else {
@@ -786,7 +791,7 @@ void QtObject::method_formatTime(const BuiltinFunction *, Scope &scope, CallData
formattedTime = time.toString(enumFormat);
}
- scope.result = scope.engine->newString(formattedTime);
+ return Encode(scope.engine->newString(formattedTime));
}
/*!
@@ -851,6 +856,8 @@ In addition the following expressions can be used to specify the time:
\li use AM/PM display. \e AP will be replaced by either "AM" or "PM".
\row \li ap
\li use am/pm display. \e ap will be replaced by either "am" or "pm".
+ \row \li t
+ \li include a time-zone indicator.
\endtable
All other input characters will be ignored. Any sequence of characters that
@@ -879,21 +886,22 @@ with the \a format values below to produce the following results:
\sa Locale
*/
-void QtObject::method_formatDateTime(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_formatDateTime(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc < 1 || callData->argc > 2)
+ QV4::Scope scope(b);
+ if (argc < 1 || argc > 2)
THROW_GENERIC_ERROR("Qt.formatDateTime(): Invalid arguments");
Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
- QDateTime dt = scope.engine->toVariant(callData->args[0], -1).toDateTime();
+ QDateTime dt = scope.engine->toVariant(argv[0], -1).toDateTime();
QString formattedDt;
- if (callData->argc == 2) {
- QV4::ScopedString s(scope, callData->args[1]);
+ if (argc == 2) {
+ QV4::ScopedString s(scope, argv[1]);
if (s) {
QString format = s->toQString();
formattedDt = dt.toString(format);
- } else if (callData->args[1].isNumber()) {
- quint32 intFormat = callData->args[1].asDouble();
+ } else if (argv[1].isNumber()) {
+ quint32 intFormat = argv[1].asDouble();
Qt::DateFormat format = Qt::DateFormat(intFormat);
formattedDt = dt.toString(format);
} else {
@@ -903,7 +911,7 @@ void QtObject::method_formatDateTime(const BuiltinFunction *, Scope &scope, Call
formattedDt = dt.toString(enumFormat);
}
- scope.result = scope.engine->newString(formattedDt);
+ return Encode(scope.engine->newString(formattedDt));
}
/*!
@@ -917,94 +925,98 @@ void QtObject::method_formatDateTime(const BuiltinFunction *, Scope &scope, Call
still fail to launch or fail to open the requested URL. This result will not be reported back
to the application.
*/
-void QtObject::method_openUrlExternally(const BuiltinFunction *b, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_openUrlExternally(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- if (callData->argc != 1) {
- scope.result = QV4::Encode(false);
- return;
- }
+ QV4::Scope scope(b);
+ if (argc != 1)
+ return QV4::Encode(false);
- method_resolvedUrl(b, scope, callData);
- QUrl url(scope.result.toQStringNoThrow());
- scope.result = scope.engine->fromVariant(QQml_guiProvider()->openUrlExternally(url));
+ ScopedValue result(scope, method_resolvedUrl(b, thisObject, argv, argc));
+ QUrl url(result->toQStringNoThrow());
+ return scope.engine->fromVariant(QQml_guiProvider()->openUrlExternally(url));
}
/*!
\qmlmethod url Qt::resolvedUrl(url url)
Returns \a url resolved relative to the URL of the caller.
*/
-void QtObject::method_resolvedUrl(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_resolvedUrl(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- ExecutionEngine *v4 = scope.engine;
+ QV4::Scope scope(b);
+ if (argc != 1)
+ return Encode::undefined();
- QUrl url = v4->toVariant(callData->args[0], -1).toUrl();
- QQmlEngine *e = v4->qmlEngine();
+ QUrl url = scope.engine->toVariant(argv[0], -1).toUrl();
+ QQmlEngine *e = scope.engine->qmlEngine();
QQmlEnginePrivate *p = 0;
if (e) p = QQmlEnginePrivate::get(e);
if (p) {
- QQmlContextData *ctxt = v4->callingQmlContext();
+ QQmlContextData *ctxt = scope.engine->callingQmlContext();
if (ctxt)
- scope.result = v4->newString(ctxt->resolvedUrl(url).toString());
+ return Encode(scope.engine->newString(ctxt->resolvedUrl(url).toString()));
else
- scope.result = v4->newString(url.toString());
- return;
+ return Encode(scope.engine->newString(url.toString()));
}
- scope.result = v4->newString(e->baseUrl().resolved(url).toString());
+ return Encode(scope.engine->newString(e->baseUrl().resolved(url).toString()));
}
/*!
\qmlmethod list<string> Qt::fontFamilies()
Returns a list of the font families available to the application.
*/
-void QtObject::method_fontFamilies(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_fontFamilies(const FunctionObject *b, const Value *, const Value *, int argc)
{
- if (callData->argc != 0)
+ QV4::Scope scope(b);
+ if (argc != 0)
THROW_GENERIC_ERROR("Qt.fontFamilies(): Invalid arguments");
- scope.result = scope.engine->fromVariant(QVariant(QQml_guiProvider()->fontFamilies()));
+ return scope.engine->fromVariant(QVariant(QQml_guiProvider()->fontFamilies()));
}
/*!
\qmlmethod string Qt::md5(data)
Returns a hex string of the md5 hash of \c data.
*/
-void QtObject::method_md5(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_md5(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc != 1)
+ QV4::Scope scope(b);
+ if (argc != 1)
THROW_GENERIC_ERROR("Qt.md5(): Invalid arguments");
- QByteArray data = callData->args[0].toQStringNoThrow().toUtf8();
+ QByteArray data = argv[0].toQStringNoThrow().toUtf8();
QByteArray result = QCryptographicHash::hash(data, QCryptographicHash::Md5);
- scope.result = scope.engine->newString(QLatin1String(result.toHex()));
+ return Encode(scope.engine->newString(QLatin1String(result.toHex())));
}
/*!
\qmlmethod string Qt::btoa(data)
Binary to ASCII - this function returns a base64 encoding of \c data.
*/
-void QtObject::method_btoa(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_btoa(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc != 1)
+ QV4::Scope scope(b);
+ if (argc != 1)
THROW_GENERIC_ERROR("Qt.btoa(): Invalid arguments");
- QByteArray data = callData->args[0].toQStringNoThrow().toUtf8();
+ QByteArray data = argv[0].toQStringNoThrow().toUtf8();
- scope.result = scope.engine->newString(QLatin1String(data.toBase64()));
+ return Encode(scope.engine->newString(QLatin1String(data.toBase64())));
}
/*!
\qmlmethod string Qt::atob(data)
ASCII to binary - this function decodes the base64 encoded \a data string and returns it.
*/
-void QtObject::method_atob(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_atob(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc != 1)
+ QV4::Scope scope(b);
+ if (argc != 1)
THROW_GENERIC_ERROR("Qt.atob(): Invalid arguments");
- QByteArray data = callData->args[0].toQStringNoThrow().toLatin1();
+ QByteArray data = argv[0].toQStringNoThrow().toLatin1();
- scope.result = scope.engine->newString(QString::fromUtf8(QByteArray::fromBase64(data)));
+ return Encode(scope.engine->newString(QString::fromUtf8(QByteArray::fromBase64(data))));
}
/*!
@@ -1016,10 +1028,10 @@ QQmlEngine::quit() signal to the QCoreApplication::quit() slot.
\sa exit()
*/
-void QtObject::method_quit(const BuiltinFunction *, Scope &scope, CallData *)
+ReturnedValue QtObject::method_quit(const FunctionObject *b, const Value *, const Value *, int)
{
- QQmlEnginePrivate::get(scope.engine->qmlEngine())->sendQuit();
- scope.result = Encode::undefined();
+ QQmlEnginePrivate::get(b->engine()->qmlEngine())->sendQuit();
+ return Encode::undefined();
}
/*!
@@ -1033,15 +1045,16 @@ void QtObject::method_quit(const BuiltinFunction *, Scope &scope, CallData *)
\sa quit()
*/
-void QtObject::method_exit(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_exit(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc != 1)
+ QV4::Scope scope(b);
+ if (argc != 1)
THROW_GENERIC_ERROR("Qt.exit(): Invalid arguments");
- int retCode = callData->args[0].toNumber();
+ int retCode = argv[0].toNumber();
QQmlEnginePrivate::get(scope.engine->qmlEngine())->sendExit(retCode);
- scope.result = QV4::Encode::undefined();
+ return QV4::Encode::undefined();
}
/*!
@@ -1068,9 +1081,10 @@ If this is the case, consider using \l{QtQml::Qt::createComponent()}{Qt.createCo
See \l {Dynamic QML Object Creation from JavaScript} for more information on using this function.
*/
-void QtObject::method_createQmlObject(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_createQmlObject(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc < 2 || callData->argc > 3)
+ QV4::Scope scope(b);
+ if (argc < 2 || argc > 3)
THROW_GENERIC_ERROR("Qt.createQmlObject(): Invalid arguments");
struct Error {
@@ -1102,8 +1116,7 @@ void QtObject::method_createQmlObject(const BuiltinFunction *, Scope &scope, Cal
}
};
- QV8Engine *v8engine = scope.engine->v8Engine;
- QQmlEngine *engine = v8engine->engine();
+ QQmlEngine *engine = scope.engine->qmlEngine();
QQmlContextData *context = scope.engine->callingQmlContext();
Q_ASSERT(context);
@@ -1114,13 +1127,13 @@ void QtObject::method_createQmlObject(const BuiltinFunction *, Scope &scope, Cal
effectiveContext = context->asQQmlContext();
Q_ASSERT(effectiveContext);
- QString qml = callData->args[0].toQStringNoThrow();
+ QString qml = argv[0].toQStringNoThrow();
if (qml.isEmpty())
RETURN_RESULT(Encode::null());
QUrl url;
- if (callData->argc > 2)
- url = QUrl(callData->args[2].toQStringNoThrow());
+ if (argc > 2)
+ url = QUrl(argv[2].toQStringNoThrow());
else
url = QUrl(QLatin1String("inline"));
@@ -1128,7 +1141,7 @@ void QtObject::method_createQmlObject(const BuiltinFunction *, Scope &scope, Cal
url = context->resolvedUrl(url);
QObject *parentArg = 0;
- QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, callData->args[1]);
+ QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, argv[1]);
if (!!qobjectWrapper)
parentArg = qobjectWrapper->object();
if (!parentArg)
@@ -1172,13 +1185,12 @@ void QtObject::method_createQmlObject(const BuiltinFunction *, Scope &scope, Cal
if (component.isError()) {
ScopedValue v(scope, Error::create(scope.engine, component.errors()));
- scope.result = scope.engine->throwError(v);
- return;
+ return scope.engine->throwError(v);
}
Q_ASSERT(obj);
- scope.result = QV4::QObjectWrapper::wrap(scope.engine, obj);
+ return QV4::QObjectWrapper::wrap(scope.engine, obj);
}
/*!
@@ -1225,13 +1237,13 @@ See \l {Dynamic QML Object Creation from JavaScript} for more information on usi
To create a QML object from an arbitrary string of QML (instead of a file),
use \l{QtQml::Qt::createQmlObject()}{Qt.createQmlObject()}.
*/
-void QtObject::method_createComponent(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_createComponent(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc < 1 || callData->argc > 3)
+ QV4::Scope scope(b);
+ if (argc < 1 || argc > 3)
THROW_GENERIC_ERROR("Qt.createComponent(): Invalid arguments");
- QV8Engine *v8engine = scope.engine->v8Engine;
- QQmlEngine *engine = v8engine->engine();
+ QQmlEngine *engine = scope.engine->qmlEngine();
QQmlContextData *context = scope.engine->callingQmlContext();
Q_ASSERT(context);
@@ -1239,7 +1251,7 @@ void QtObject::method_createComponent(const BuiltinFunction *, Scope &scope, Cal
if (context->isPragmaLibraryContext)
effectiveContext = 0;
- QString arg = callData->args[0].toQStringNoThrow();
+ QString arg = argv[0].toQStringNoThrow();
if (arg.isEmpty())
RETURN_RESULT(QV4::Encode::null());
@@ -1247,23 +1259,23 @@ void QtObject::method_createComponent(const BuiltinFunction *, Scope &scope, Cal
QObject *parentArg = 0;
int consumedCount = 1;
- if (callData->argc > 1) {
- ScopedValue lastArg(scope, callData->args[callData->argc-1]);
+ if (argc > 1) {
+ ScopedValue lastArg(scope, argv[argc-1]);
// The second argument could be the mode enum
- if (callData->args[1].isInteger()) {
- int mode = callData->args[1].integerValue();
+ if (argv[1].isInteger()) {
+ int mode = argv[1].integerValue();
if (mode != int(QQmlComponent::PreferSynchronous) && mode != int(QQmlComponent::Asynchronous))
THROW_GENERIC_ERROR("Qt.createComponent(): Invalid arguments");
compileMode = QQmlComponent::CompilationMode(mode);
consumedCount += 1;
} else {
// The second argument could be the parent only if there are exactly two args
- if ((callData->argc != 2) || !(lastArg->isObject() || lastArg->isNull()))
+ if ((argc != 2) || !(lastArg->isObject() || lastArg->isNull()))
THROW_GENERIC_ERROR("Qt.createComponent(): Invalid arguments");
}
- if (consumedCount < callData->argc) {
+ if (consumedCount < argc) {
if (lastArg->isObject()) {
Scoped<QObjectWrapper> qobjectWrapper(scope, lastArg);
if (qobjectWrapper)
@@ -1284,7 +1296,7 @@ void QtObject::method_createComponent(const BuiltinFunction *, Scope &scope, Cal
QQmlData::get(c, true)->explicitIndestructibleSet = false;
QQmlData::get(c)->indestructible = false;
- scope.result = QV4::QObjectWrapper::wrap(scope.engine, c);
+ return QV4::QObjectWrapper::wrap(scope.engine, c);
}
/*!
@@ -1307,18 +1319,19 @@ void QtObject::method_createComponent(const BuiltinFunction *, Scope &scope, Cal
\sa Locale
*/
-void QtObject::method_locale(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_locale(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
+ QV4::Scope scope(b);
QString code;
- if (callData->argc > 1)
+ if (argc > 1)
THROW_GENERIC_ERROR("locale() requires 0 or 1 argument");
- if (callData->argc == 1 && !callData->args[0].isString())
+ if (argc == 1 && !argv[0].isString())
THROW_TYPE_ERROR_WITH_MESSAGE("locale(): argument (locale code) must be a string");
- if (callData->argc == 1)
- code = callData->args[0].toQStringNoThrow();
+ if (argc == 1)
+ code = argv[0].toQStringNoThrow();
- scope.result = QQmlLocale::locale(scope.engine, code);
+ return QQmlLocale::locale(scope.engine, code);
}
void Heap::QQmlBindingFunction::init(const QV4::FunctionObject *originalFunction)
@@ -1330,8 +1343,8 @@ void Heap::QQmlBindingFunction::init(const QV4::FunctionObject *originalFunction
QQmlSourceLocation QQmlBindingFunction::currentLocation() const
{
- QV4::StackFrame frame = engine()->currentStackFrame();
- return QQmlSourceLocation(frame.source, frame.line, 0);
+ QV4::CppStackFrame *frame = engine()->currentStackFrame;
+ return QQmlSourceLocation(frame->source(), frame->lineNumber(), 0);
}
DEFINE_OBJECT_VTABLE(QQmlBindingFunction);
@@ -1380,25 +1393,27 @@ DEFINE_OBJECT_VTABLE(QQmlBindingFunction);
\since 5.0
*/
-void QtObject::method_binding(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_binding(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc != 1)
+ QV4::Scope scope(b);
+ if (argc != 1)
THROW_GENERIC_ERROR("binding() requires 1 argument");
- const QV4::FunctionObject *f = callData->args[0].as<FunctionObject>();
+ const QV4::FunctionObject *f = argv[0].as<FunctionObject>();
if (!f)
THROW_TYPE_ERROR_WITH_MESSAGE("binding(): argument (binding expression) must be a function");
- scope.result = scope.engine->memoryManager->allocObject<QQmlBindingFunction>(f);
+ return Encode(scope.engine->memoryManager->allocObject<QQmlBindingFunction>(f));
}
-void QtObject::method_get_platform(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_get_platform(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
+ QV4::Scope scope(b);
// ### inefficient. Should be just a value based getter
- Object *o = callData->thisObject.as<Object>();
+ const Object *o = thisObject->as<Object>();
if (!o)
THROW_TYPE_ERROR();
- QtObject *qt = o->as<QtObject>();
+ const QtObject *qt = o->as<QtObject>();
if (!qt)
THROW_TYPE_ERROR();
@@ -1406,16 +1421,17 @@ void QtObject::method_get_platform(const BuiltinFunction *, Scope &scope, CallDa
// Only allocate a platform object once
qt->d()->platform = new QQmlPlatform(scope.engine->jsEngine());
- scope.result = QV4::QObjectWrapper::wrap(scope.engine, qt->d()->platform);
+ return QV4::QObjectWrapper::wrap(scope.engine, qt->d()->platform);
}
-void QtObject::method_get_application(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_get_application(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
+ QV4::Scope scope(b);
// ### inefficient. Should be just a value based getter
- Object *o = callData->thisObject.as<Object>();
+ const Object *o = thisObject->as<Object>();
if (!o)
THROW_TYPE_ERROR();
- QtObject *qt = o->as<QtObject>();
+ const QtObject *qt = o->as<QtObject>();
if (!qt)
THROW_TYPE_ERROR();
@@ -1423,19 +1439,19 @@ void QtObject::method_get_application(const BuiltinFunction *, Scope &scope, Cal
// Only allocate an application object once
qt->d()->application = QQml_guiProvider()->application(scope.engine->jsEngine());
- scope.result = QV4::QObjectWrapper::wrap(scope.engine, qt->d()->application);
+ return QV4::QObjectWrapper::wrap(scope.engine, qt->d()->application);
}
-void QtObject::method_get_inputMethod(const BuiltinFunction *, Scope &scope, CallData *)
+ReturnedValue QtObject::method_get_inputMethod(const FunctionObject *b, const Value *, const Value *, int)
{
QObject *o = QQml_guiProvider()->inputMethod();
- scope.result = QV4::QObjectWrapper::wrap(scope.engine, o);
+ return QV4::QObjectWrapper::wrap(b->engine(), o);
}
-void QtObject::method_get_styleHints(const BuiltinFunction *, Scope &scope, CallData *)
+ReturnedValue QtObject::method_get_styleHints(const FunctionObject *b, const Value *, const Value *, int)
{
QObject *o = QQml_guiProvider()->styleHints();
- scope.result = QV4::QObjectWrapper::wrap(scope.engine, o);
+ return QV4::QObjectWrapper::wrap(b->engine(), o);
}
@@ -1495,16 +1511,17 @@ static QString jsStack(QV4::ExecutionEngine *engine) {
return stack;
}
-static void writeToConsole(const BuiltinFunction *, Scope &scope, CallData *callData,
- ConsoleLogTypes logType, bool printStack = false)
+static ReturnedValue writeToConsole(const FunctionObject *b, const Value *, const Value *argv, int argc,
+ ConsoleLogTypes logType, bool printStack = false)
{
QLoggingCategory *loggingCategory = 0;
QString result;
+ QV4::Scope scope(b);
QV4::ExecutionEngine *v4 = scope.engine;
int start = 0;
- if (callData->argc > 0) {
- if (const QObjectWrapper* wrapper = callData->args[0].as<QObjectWrapper>()) {
+ if (argc > 0) {
+ if (const QObjectWrapper* wrapper = argv[0].as<QObjectWrapper>()) {
if (QQmlLoggingCategory* category = qobject_cast<QQmlLoggingCategory*>(wrapper->object())) {
if (category->category())
loggingCategory = category->category();
@@ -1516,14 +1533,14 @@ static void writeToConsole(const BuiltinFunction *, Scope &scope, CallData *call
}
- for (int i = start; i < callData->argc; ++i) {
+ for (int i = start, ei = argc; i < ei; ++i) {
if (i != start)
result.append(QLatin1Char(' '));
- if (callData->args[i].as<ArrayObject>())
- result += QLatin1Char('[') + callData->args[i].toQStringNoThrow() + QLatin1Char(']');
+ if (argv[i].as<ArrayObject>())
+ result += QLatin1Char('[') + argv[i].toQStringNoThrow() + QLatin1Char(']');
else
- result.append(callData->args[i].toQStringNoThrow());
+ result.append(argv[i].toQStringNoThrow());
}
if (printStack)
@@ -1534,10 +1551,10 @@ static void writeToConsole(const BuiltinFunction *, Scope &scope, CallData *call
if (!loggingCategory)
loggingCategory = v4->qmlEngine() ? &qmlLoggingCategory : &jsLoggingCategory;
- QV4::StackFrame frame = v4->currentStackFrame();
- const QByteArray baSource = frame.source.toUtf8();
- const QByteArray baFunction = frame.function.toUtf8();
- QMessageLogger logger(baSource.constData(), frame.line, baFunction.constData(), loggingCategory->categoryName());
+ QV4::CppStackFrame *frame = v4->currentStackFrame;
+ const QByteArray baSource = frame->source().toUtf8();
+ const QByteArray baFunction = frame->function().toUtf8();
+ QMessageLogger logger(baSource.constData(), frame->lineNumber(), baFunction.constData(), loggingCategory->categoryName());
switch (logType) {
case Log:
@@ -1560,37 +1577,38 @@ static void writeToConsole(const BuiltinFunction *, Scope &scope, CallData *call
break;
}
- scope.result = QV4::Encode::undefined();
+ return Encode::undefined();
}
DEFINE_OBJECT_VTABLE(ConsoleObject);
-void ConsoleObject::method_error(const BuiltinFunction *b, Scope &scope, CallData *callData)
+ReturnedValue ConsoleObject::method_error(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- writeToConsole(b, scope, callData, Error);
+ return writeToConsole(b, thisObject, argv, argc, Error);
}
-void ConsoleObject::method_log(const BuiltinFunction *b, Scope &scope, CallData *callData)
+ReturnedValue ConsoleObject::method_log(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
//console.log
//console.debug
//print
- writeToConsole(b, scope, callData, Log);
+ return writeToConsole(b, thisObject, argv, argc, Log);
}
-void ConsoleObject::method_info(const BuiltinFunction *b, Scope &scope, CallData *callData)
+ReturnedValue ConsoleObject::method_info(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- writeToConsole(b, scope, callData, Info);
+ return writeToConsole(b, thisObject, argv, argc, Info);
}
-void ConsoleObject::method_profile(const BuiltinFunction *, Scope &scope, CallData *)
+ReturnedValue ConsoleObject::method_profile(const FunctionObject *b, const Value *, const Value *, int)
{
+ QV4::Scope scope(b);
QV4::ExecutionEngine *v4 = scope.engine;
- QV4::StackFrame frame = v4->currentStackFrame();
- const QByteArray baSource = frame.source.toUtf8();
- const QByteArray baFunction = frame.function.toUtf8();
- QMessageLogger logger(baSource.constData(), frame.line, baFunction.constData());
+ QV4::CppStackFrame *frame = v4->currentStackFrame;
+ const QByteArray baSource = frame->source().toUtf8();
+ const QByteArray baFunction = frame->function().toUtf8();
+ QMessageLogger logger(baSource.constData(), frame->lineNumber(), baFunction.constData());
QQmlProfilerService *service = QQmlDebugConnector::service<QQmlProfilerService>();
if (!service) {
logger.warning("Cannot start profiling because debug service is disabled. Start with -qmljsdebugger=port:XXXXX.");
@@ -1599,17 +1617,18 @@ void ConsoleObject::method_profile(const BuiltinFunction *, Scope &scope, CallDa
logger.debug("Profiling started.");
}
- scope.result = QV4::Encode::undefined();
+ return QV4::Encode::undefined();
}
-void ConsoleObject::method_profileEnd(const BuiltinFunction *, Scope &scope, CallData *)
+ReturnedValue ConsoleObject::method_profileEnd(const FunctionObject *b, const Value *, const Value *, int)
{
+ QV4::Scope scope(b);
QV4::ExecutionEngine *v4 = scope.engine;
- QV4::StackFrame frame = v4->currentStackFrame();
- const QByteArray baSource = frame.source.toUtf8();
- const QByteArray baFunction = frame.function.toUtf8();
- QMessageLogger logger(baSource.constData(), frame.line, baFunction.constData());
+ QV4::CppStackFrame *frame = v4->currentStackFrame;
+ const QByteArray baSource = frame->source().toUtf8();
+ const QByteArray baFunction = frame->function().toUtf8();
+ QMessageLogger logger(baSource.constData(), frame->lineNumber(), baFunction.constData());
QQmlProfilerService *service = QQmlDebugConnector::service<QQmlProfilerService>();
if (!service) {
@@ -1619,118 +1638,122 @@ void ConsoleObject::method_profileEnd(const BuiltinFunction *, Scope &scope, Cal
logger.debug("Profiling ended.");
}
- scope.result = QV4::Encode::undefined();
+ return QV4::Encode::undefined();
}
-void ConsoleObject::method_time(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ConsoleObject::method_time(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc != 1)
+ QV4::Scope scope(b);
+ if (argc != 1)
THROW_GENERIC_ERROR("console.time(): Invalid arguments");
QV8Engine *v8engine = scope.engine->v8Engine;
- QString name = callData->args[0].toQStringNoThrow();
+ QString name = argv[0].toQStringNoThrow();
v8engine->startTimer(name);
- scope.result = QV4::Encode::undefined();
+ return QV4::Encode::undefined();
}
-void ConsoleObject::method_timeEnd(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ConsoleObject::method_timeEnd(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc != 1)
+ QV4::Scope scope(b);
+ if (argc != 1)
THROW_GENERIC_ERROR("console.timeEnd(): Invalid arguments");
QV8Engine *v8engine = scope.engine->v8Engine;
- QString name = callData->args[0].toQStringNoThrow();
+ QString name = argv[0].toQStringNoThrow();
bool wasRunning;
qint64 elapsed = v8engine->stopTimer(name, &wasRunning);
if (wasRunning) {
qDebug("%s: %llims", qPrintable(name), elapsed);
}
- scope.result = QV4::Encode::undefined();
+ return QV4::Encode::undefined();
}
-void ConsoleObject::method_count(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ConsoleObject::method_count(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
// first argument: name to print. Ignore any additional arguments
QString name;
- if (callData->argc > 0)
- name = callData->args[0].toQStringNoThrow();
+ if (argc > 0)
+ name = argv[0].toQStringNoThrow();
+ Scope scope(b);
QV4::ExecutionEngine *v4 = scope.engine;
QV8Engine *v8engine = scope.engine->v8Engine;
- QV4::StackFrame frame = v4->currentStackFrame();
+ QV4::CppStackFrame *frame = v4->currentStackFrame;
- QString scriptName = frame.source;
+ QString scriptName = frame->source();
- int value = v8engine->consoleCountHelper(scriptName, frame.line, frame.column);
+ int value = v8engine->consoleCountHelper(scriptName, frame->lineNumber(), -1);
QString message = name + QLatin1String(": ") + QString::number(value);
- QMessageLogger(qPrintable(scriptName), frame.line,
- qPrintable(frame.function))
+ QMessageLogger(qPrintable(scriptName), frame->lineNumber(),
+ qPrintable(frame->function()))
.debug("%s", qPrintable(message));
- scope.result = QV4::Encode::undefined();
+ return QV4::Encode::undefined();
}
-void ConsoleObject::method_trace(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ConsoleObject::method_trace(const FunctionObject *b, const Value *, const Value *, int argc)
{
- if (callData->argc != 0)
+ QV4::Scope scope(b);
+ if (argc != 0)
THROW_GENERIC_ERROR("console.trace(): Invalid arguments");
QV4::ExecutionEngine *v4 = scope.engine;
QString stack = jsStack(v4);
- QV4::StackFrame frame = v4->currentStackFrame();
- QMessageLogger(frame.source.toUtf8().constData(), frame.line,
- frame.function.toUtf8().constData())
+ QV4::CppStackFrame *frame = v4->currentStackFrame;
+ QMessageLogger(frame->source().toUtf8().constData(), frame->lineNumber(),
+ frame->function().toUtf8().constData())
.debug("%s", qPrintable(stack));
- scope.result = QV4::Encode::undefined();
+ return QV4::Encode::undefined();
}
-void ConsoleObject::method_warn(const BuiltinFunction *b, Scope &scope, CallData *callData)
+ReturnedValue ConsoleObject::method_warn(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- return writeToConsole(b, scope, callData, Warn);
+ return writeToConsole(b, thisObject, argv, argc, Warn);
}
-void ConsoleObject::method_assert(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue ConsoleObject::method_assert(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc == 0)
+ QV4::Scope scope(b);
+ if (argc == 0)
THROW_GENERIC_ERROR("console.assert(): Missing argument");
QV4::ExecutionEngine *v4 = scope.engine;
- if (!callData->args[0].toBoolean()) {
+ if (!argv[0].toBoolean()) {
QString message;
- for (int i = 1; i < callData->argc; ++i) {
+ for (int i = 1, ei = argc; i < ei; ++i) {
if (i != 1)
message.append(QLatin1Char(' '));
- message.append(callData->args[i].toQStringNoThrow());
+ message.append(argv[i].toQStringNoThrow());
}
QString stack = jsStack(v4);
- QV4::StackFrame frame = v4->currentStackFrame();
- QMessageLogger(frame.source.toUtf8().constData(), frame.line,
- frame.function.toUtf8().constData())
+ QV4::CppStackFrame *frame = v4->currentStackFrame;
+ QMessageLogger(frame->source().toUtf8().constData(), frame->lineNumber(),
+ frame->function().toUtf8().constData())
.critical("%s\n%s",qPrintable(message), qPrintable(stack));
}
- scope.result = QV4::Encode::undefined();
+ return QV4::Encode::undefined();
}
-void ConsoleObject::method_exception(const BuiltinFunction *b, Scope &scope, CallData *callData)
+ReturnedValue ConsoleObject::method_exception(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- if (callData->argc == 0)
+ QV4::Scope scope(b);
+ if (argc == 0)
THROW_GENERIC_ERROR("console.exception(): Missing argument");
- writeToConsole(b, scope, callData, Error, true);
-
- scope.result = QV4::Encode::undefined();
+ return writeToConsole(b, thisObject, argv, argc, Error, true);
}
@@ -1786,38 +1809,39 @@ void QV4::GlobalExtensions::init(Object *globalObject, QJSEngine::Extensions ext
\sa {Internationalization and Localization with Qt Quick}
*/
-void GlobalExtensions::method_qsTranslate(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue GlobalExtensions::method_qsTranslate(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc < 2)
+ QV4::Scope scope(b);
+ if (argc < 2)
THROW_GENERIC_ERROR("qsTranslate() requires at least two arguments");
- if (!callData->args[0].isString())
+ if (!argv[0].isString())
THROW_GENERIC_ERROR("qsTranslate(): first argument (context) must be a string");
- if (!callData->args[1].isString())
+ if (!argv[1].isString())
THROW_GENERIC_ERROR("qsTranslate(): second argument (sourceText) must be a string");
- if ((callData->argc > 2) && !callData->args[2].isString())
+ if ((argc > 2) && !argv[2].isString())
THROW_GENERIC_ERROR("qsTranslate(): third argument (disambiguation) must be a string");
- QString context = callData->args[0].toQStringNoThrow();
- QString text = callData->args[1].toQStringNoThrow();
+ QString context = argv[0].toQStringNoThrow();
+ QString text = argv[1].toQStringNoThrow();
QString comment;
- if (callData->argc > 2) comment = callData->args[2].toQStringNoThrow();
+ if (argc > 2) comment = argv[2].toQStringNoThrow();
int i = 3;
- if (callData->argc > i && callData->args[i].isString()) {
+ if (argc > i && argv[i].isString()) {
qWarning("qsTranslate(): specifying the encoding as fourth argument is deprecated");
++i;
}
int n = -1;
- if (callData->argc > i)
- n = callData->args[i].toInt32();
+ if (argc > i)
+ n = argv[i].toInt32();
QString result = QCoreApplication::translate(context.toUtf8().constData(),
text.toUtf8().constData(),
comment.toUtf8().constData(),
n);
- scope.result = scope.engine->newString(result);
+ return Encode(scope.engine->newString(result));
}
/*!
@@ -1842,12 +1866,13 @@ void GlobalExtensions::method_qsTranslate(const BuiltinFunction *, Scope &scope,
\sa {Internationalization and Localization with Qt Quick}
*/
-void GlobalExtensions::method_qsTranslateNoOp(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue GlobalExtensions::method_qsTranslateNoOp(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc < 2)
- scope.result = QV4::Encode::undefined();
+ QV4::Scope scope(b);
+ if (argc < 2)
+ return QV4::Encode::undefined();
else
- scope.result = callData->args[1];
+ return argv[1].asReturnedValue();
}
/*!
@@ -1867,15 +1892,16 @@ void GlobalExtensions::method_qsTranslateNoOp(const BuiltinFunction *, Scope &sc
\sa {Internationalization and Localization with Qt Quick}
*/
-void GlobalExtensions::method_qsTr(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue GlobalExtensions::method_qsTr(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc < 1)
+ QV4::Scope scope(b);
+ if (argc < 1)
THROW_GENERIC_ERROR("qsTr() requires at least one argument");
- if (!callData->args[0].isString())
+ if (!argv[0].isString())
THROW_GENERIC_ERROR("qsTr(): first argument (sourceText) must be a string");
- if ((callData->argc > 1) && !callData->args[1].isString())
+ if ((argc > 1) && !argv[1].isString())
THROW_GENERIC_ERROR("qsTr(): second argument (disambiguation) must be a string");
- if ((callData->argc > 2) && !callData->args[2].isNumber())
+ if ((argc > 2) && !argv[2].isNumber())
THROW_GENERIC_ERROR("qsTr(): third argument (n) must be a number");
QString context;
@@ -1886,10 +1912,10 @@ void GlobalExtensions::method_qsTr(const BuiltinFunction *, Scope &scope, CallDa
int length = lastDot - (lastSlash + 1);
context = (lastSlash > -1) ? path.mid(lastSlash + 1, (length > -1) ? length : -1) : QString();
} else {
- ExecutionContext *parentCtx = scope.engine->currentContext;
+ CppStackFrame *frame = scope.engine->currentStackFrame;
// The first non-empty source URL in the call stack determines the translation context.
- while (!!parentCtx && context.isEmpty()) {
- if (CompiledData::CompilationUnit *unit = static_cast<CompiledData::CompilationUnit*>(parentCtx->d()->compilationUnit)) {
+ while (frame && context.isEmpty()) {
+ if (CompiledData::CompilationUnit *unit = frame->v4Function->compilationUnit) {
QString fileName = unit->fileName();
QUrl url(unit->fileName());
if (url.isValid() && url.isRelative()) {
@@ -1901,22 +1927,22 @@ void GlobalExtensions::method_qsTr(const BuiltinFunction *, Scope &scope, CallDa
}
context = QFileInfo(context).baseName();
}
- parentCtx = scope.engine->parentContext(parentCtx);
+ frame = frame->parent;
}
}
- QString text = callData->args[0].toQStringNoThrow();
+ QString text = argv[0].toQStringNoThrow();
QString comment;
- if (callData->argc > 1)
- comment = callData->args[1].toQStringNoThrow();
+ if (argc > 1)
+ comment = argv[1].toQStringNoThrow();
int n = -1;
- if (callData->argc > 2)
- n = callData->args[2].toInt32();
+ if (argc > 2)
+ n = argv[2].toInt32();
QString result = QCoreApplication::translate(context.toUtf8().constData(), text.toUtf8().constData(),
comment.toUtf8().constData(), n);
- scope.result = scope.engine->newString(result);
+ return Encode(scope.engine->newString(result));
}
/*!
@@ -1941,12 +1967,12 @@ void GlobalExtensions::method_qsTr(const BuiltinFunction *, Scope &scope, CallDa
\sa {Internationalization and Localization with Qt Quick}
*/
-void GlobalExtensions::method_qsTrNoOp(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue GlobalExtensions::method_qsTrNoOp(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- if (callData->argc < 1)
- scope.result = QV4::Encode::undefined();
+ if (argc < 1)
+ return QV4::Encode::undefined();
else
- scope.result = callData->args[0];
+ return argv[0].asReturnedValue();
}
/*!
@@ -1979,20 +2005,21 @@ void GlobalExtensions::method_qsTrNoOp(const BuiltinFunction *, Scope &scope, Ca
\sa QT_TRID_NOOP(), {Internationalization and Localization with Qt Quick}
*/
-void GlobalExtensions::method_qsTrId(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue GlobalExtensions::method_qsTrId(const FunctionObject *b, const Value *, const Value *argv, int argc)
{
- if (callData->argc < 1)
+ QV4::Scope scope(b);
+ if (argc < 1)
THROW_GENERIC_ERROR("qsTrId() requires at least one argument");
- if (!callData->args[0].isString())
+ if (!argv[0].isString())
THROW_TYPE_ERROR_WITH_MESSAGE("qsTrId(): first argument (id) must be a string");
- if (callData->argc > 1 && !callData->args[1].isNumber())
+ if (argc > 1 && !argv[1].isNumber())
THROW_TYPE_ERROR_WITH_MESSAGE("qsTrId(): second argument (n) must be a number");
int n = -1;
- if (callData->argc > 1)
- n = callData->args[1].toInt32();
+ if (argc > 1)
+ n = argv[1].toInt32();
- scope.result = scope.engine->newString(qtTrId(callData->args[0].toQStringNoThrow().toUtf8().constData(), n));
+ return Encode(scope.engine->newString(qtTrId(argv[0].toQStringNoThrow().toUtf8().constData(), n)));
}
/*!
@@ -2011,33 +2038,34 @@ void GlobalExtensions::method_qsTrId(const BuiltinFunction *, Scope &scope, Call
\sa qsTrId(), {Internationalization and Localization with Qt Quick}
*/
-void GlobalExtensions::method_qsTrIdNoOp(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue GlobalExtensions::method_qsTrIdNoOp(const FunctionObject *, const Value *, const Value *argv, int argc)
{
- if (callData->argc < 1)
- scope.result = QV4::Encode::undefined();
+ if (argc < 1)
+ return QV4::Encode::undefined();
else
- scope.result = callData->args[0];
+ return argv[0].asReturnedValue();
}
#endif // translation
-void GlobalExtensions::method_gc(const BuiltinFunction *, Scope &scope, CallData *)
+ReturnedValue GlobalExtensions::method_gc(const FunctionObject *b, const Value *, const Value *, int)
{
- scope.engine->memoryManager->runGC();
+ b->engine()->memoryManager->runGC();
- scope.result = QV4::Encode::undefined();
+ return QV4::Encode::undefined();
}
-void GlobalExtensions::method_string_arg(const BuiltinFunction *, Scope &scope, CallData *callData)
+ReturnedValue GlobalExtensions::method_string_arg(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- if (callData->argc != 1)
+ QV4::Scope scope(b);
+ if (argc != 1)
THROW_GENERIC_ERROR("String.arg(): Invalid arguments");
- QString value = callData->thisObject.toQString();
+ QString value = thisObject->toQString();
- QV4::ScopedValue arg(scope, callData->args[0]);
+ QV4::ScopedValue arg(scope, argv[0]);
if (arg->isInteger())
RETURN_RESULT(scope.engine->newString(value.arg(arg->integerValue())));
else if (arg->isDouble())
@@ -2068,10 +2096,10 @@ be passed on to the function invoked. Note that if redundant calls
are eliminated, then only the last set of arguments will be passed to the
function.
*/
-void QtObject::method_callLater(const BuiltinFunction *b, Scope &scope, CallData *callData)
+ReturnedValue QtObject::method_callLater(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc)
{
- QV8Engine *v8engine = scope.engine->v8Engine;
- v8engine->delayedCallQueue()->addUniquelyAndExecuteLater(b, scope, callData);
+ QV8Engine *v8engine = b->engine()->v8Engine;
+ return v8engine->delayedCallQueue()->addUniquelyAndExecuteLater(b, thisObject, argv, argc);
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
index 21613b7c10..104dae5d79 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
@@ -93,45 +93,45 @@ struct QtObject : Object
static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
- static void method_isQtObject(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_rgba(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_hsla(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_hsva(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_colorEqual(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_font(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_rect(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_point(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_size(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_vector2d(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_vector3d(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_vector4d(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_quaternion(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_matrix4x4(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_lighter(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_darker(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_tint(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_formatDate(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_formatTime(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_formatDateTime(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_openUrlExternally(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_fontFamilies(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_md5(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_btoa(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_atob(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_quit(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_exit(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_resolvedUrl(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_createQmlObject(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_createComponent(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_locale(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_binding(const BuiltinFunction *, Scope &scope, CallData *callData);
-
- static void method_get_platform(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_get_application(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_get_inputMethod(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_get_styleHints(const BuiltinFunction *, Scope &scope, CallData *callData);
-
- static void method_callLater(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_isQtObject(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_rgba(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_hsla(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_hsva(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_colorEqual(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_font(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_rect(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_point(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_size(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_vector2d(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_vector3d(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_vector4d(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_quaternion(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_matrix4x4(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_lighter(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_darker(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_tint(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_formatDate(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_formatTime(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_formatDateTime(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_openUrlExternally(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_fontFamilies(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_md5(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_btoa(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_atob(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_quit(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_exit(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_resolvedUrl(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_createQmlObject(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_createComponent(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_locale(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_binding(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+
+ static ReturnedValue method_get_platform(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_application(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_inputMethod(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_get_styleHints(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+
+ static ReturnedValue method_callLater(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
private:
void addAll();
@@ -142,18 +142,18 @@ struct ConsoleObject : Object
{
V4_OBJECT2(ConsoleObject, Object)
- static void method_error(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_log(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_info(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_profile(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_profileEnd(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_time(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_timeEnd(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_count(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_trace(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_warn(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_assert(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_exception(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_error(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_log(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_info(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_profile(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_profileEnd(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_time(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_timeEnd(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_count(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_trace(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_warn(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_assert(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_exception(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
};
@@ -161,17 +161,17 @@ struct Q_QML_PRIVATE_EXPORT GlobalExtensions {
static void init(Object *globalObject, QJSEngine::Extensions extensions);
#if QT_CONFIG(translation)
- static void method_qsTranslate(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_qsTranslateNoOp(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_qsTr(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_qsTrNoOp(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_qsTrId(const BuiltinFunction *, Scope &scope, CallData *callData);
- static void method_qsTrIdNoOp(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_qsTranslate(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_qsTranslateNoOp(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_qsTr(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_qsTrNoOp(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_qsTrId(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
+ static ReturnedValue method_qsTrIdNoOp(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
#endif
- static void method_gc(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_gc(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
// on String:prototype
- static void method_string_arg(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static ReturnedValue method_string_arg(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
};
diff --git a/src/qml/qml/v8/qv4domerrors_p.h b/src/qml/qml/v8/qv4domerrors_p.h
index a9bdbe01ae..06a70a13e9 100644
--- a/src/qml/qml/v8/qv4domerrors_p.h
+++ b/src/qml/qml/v8/qv4domerrors_p.h
@@ -78,8 +78,7 @@ QT_BEGIN_NAMESPACE
QV4::ScopedValue v(scope, scope.engine->newString(QStringLiteral(string))); \
QV4::ScopedObject ex(scope, scope.engine->newErrorObject(v)); \
ex->put(QV4::ScopedString(scope, scope.engine->newIdentifier(QStringLiteral("code"))), QV4::ScopedValue(scope, QV4::Primitive::fromInt32(error))); \
- scope.result = scope.engine->throwError(ex); \
- return; \
+ return scope.engine->throwError(ex); \
}
namespace QV4 {
diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp
index dadff819cf..2bf623f144 100644
--- a/src/qml/qml/v8/qv8engine.cpp
+++ b/src/qml/qml/v8/qv8engine.cpp
@@ -123,11 +123,11 @@ static void restoreJSValue(QDataStream &stream, void *data)
}
}
-QV8Engine::QV8Engine(QJSEngine* qq)
+QV8Engine::QV8Engine(QJSEngine *qq, QV4::ExecutionEngine *v4)
: q(qq)
, m_engine(0)
+ , m_v4Engine(v4)
, m_xmlHttpRequestData(0)
- , m_listModelData(0)
{
#ifdef Q_PROCESSOR_X86_32
if (!qCpuHasFeature(SSE2)) {
@@ -147,8 +147,6 @@ QV8Engine::QV8Engine(QJSEngine* qq)
QMetaType::registerConverter<QJSValue, QStringList>(convertJSValueToVariantType<QStringList>);
QMetaType::registerStreamOperators(qMetaTypeId<QJSValue>(), saveJSValue, restoreJSValue);
- m_v4Engine = new QV4::ExecutionEngine;
- m_v4Engine->v8Engine = this;
m_delayedCallQueue.init(m_v4Engine);
QV4::QObjectWrapper::initializeBindings(m_v4Engine);
@@ -163,11 +161,6 @@ QV8Engine::~QV8Engine()
qt_rem_qmlxmlhttprequest(m_v4Engine, m_xmlHttpRequestData);
m_xmlHttpRequestData = 0;
#endif
-
- delete m_listModelData;
- m_listModelData = 0;
-
- delete m_v4Engine;
}
#if QT_CONFIG(qml_network)
@@ -292,11 +285,6 @@ void QV8Engine::setEngine(QQmlEngine *engine)
initQmlGlobalObject();
}
-QV4::ReturnedValue QV8Engine::global()
-{
- return m_v4Engine->globalObject->asReturnedValue();
-}
-
void QV8Engine::startTimer(const QString &timerName)
{
if (!m_time.isValid())
diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h
index 3bd3517968..eb2b8b474c 100644
--- a/src/qml/qml/v8/qv8engine_p.h
+++ b/src/qml/qml/v8/qv8engine_p.h
@@ -77,12 +77,6 @@ namespace QV4 {
struct QObjectMethod;
}
-#define V4THROW_ERROR(string) \
- return ctx->engine()->throwError(QString::fromUtf8(string));
-
-#define V4THROW_TYPE(string) \
- return ctx->engine()->throwTypeError(QStringLiteral(string));
-
#define V4_DEFINE_EXTENSION(dataclass, datafunction) \
static inline dataclass *datafunction(QV4::ExecutionEngine *engine) \
{ \
@@ -116,8 +110,8 @@ namespace QV4 {
class QQmlV4Function
{
public:
- int length() const { return callData->argc; }
- QV4::ReturnedValue operator[](int idx) const { return (idx < callData->argc ? callData->args[idx].asReturnedValue() : QV4::Encode::undefined()); }
+ int length() const { return callData->argc(); }
+ QV4::ReturnedValue operator[](int idx) const { return (idx < callData->argc() ? callData->args[idx].asReturnedValue() : QV4::Encode::undefined()); }
void setReturnValue(QV4::ReturnedValue rv) { *retVal = rv; }
QV4::ExecutionEngine *v4engine() const { return e; }
private:
@@ -159,12 +153,11 @@ class Q_QML_PRIVATE_EXPORT QV8Engine
{
friend class QJSEngine;
public:
- static QV8Engine* get(QJSEngine* q) { Q_ASSERT(q); return q->handle(); }
// static QJSEngine* get(QV8Engine* d) { Q_ASSERT(d); return d->q; }
- static QV4::ExecutionEngine *getV4(QJSEngine *q) { return q->handle()->m_v4Engine; }
+ static QV4::ExecutionEngine *getV4(QJSEngine *q) { return q->handle(); }
static QV4::ExecutionEngine *getV4(QV8Engine *d) { return d->m_v4Engine; }
- QV8Engine(QJSEngine* qq);
+ QV8Engine(QJSEngine* qq, QV4::ExecutionEngine *v4);
virtual ~QV8Engine();
// This enum should be in sync with QQmlEngine::ObjectOwnership
@@ -178,14 +171,10 @@ public:
void setEngine(QQmlEngine *engine);
QQmlEngine *engine() { return m_engine; }
QJSEngine *publicEngine() { return q; }
- QV4::ReturnedValue global();
QQmlDelayedCallQueue *delayedCallQueue() { return &m_delayedCallQueue; }
void *xmlHttpRequestData() const { return m_xmlHttpRequestData; }
- Deletable *listModelData() const { return m_listModelData; }
- void setListModelData(Deletable *d) { if (m_listModelData) delete m_listModelData; m_listModelData = d; }
-
void freezeObject(const QV4::Value &value);
#if QT_CONFIG(qml_network)
@@ -222,7 +211,6 @@ protected:
void *m_xmlHttpRequestData;
QVector<Deletable *> m_extensionData;
- Deletable *m_listModelData;
QSet<QString> m_illegalNames;
diff --git a/src/qml/qtqmlglobal.h b/src/qml/qtqmlglobal.h
index 387c28a945..6e92867cf5 100644
--- a/src/qml/qtqmlglobal.h
+++ b/src/qml/qtqmlglobal.h
@@ -50,6 +50,8 @@
# if QT_CONFIG(qml_network)
# include <QtNetwork/qtnetworkglobal.h>
# endif
+#else
+# define QT_FEATURE_qml_debug -1
#endif
QT_BEGIN_NAMESPACE
diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp
index 7607c19374..e218cdcfe4 100644
--- a/src/qml/types/qqmlconnections.cpp
+++ b/src/qml/types/qqmlconnections.cpp
@@ -235,14 +235,13 @@ void QQmlConnectionsParser::verifyBindings(const QV4::CompiledData::Unit *qmlUni
{
for (int ii = 0; ii < props.count(); ++ii) {
const QV4::CompiledData::Binding *binding = props.at(ii);
- QString propName = qmlUnit->stringAt(binding->propertyNameIndex);
+ const QString &propName = qmlUnit->stringAt(binding->propertyNameIndex);
- if (!propName.startsWith(QLatin1String("on")) || !propName.at(2).isUpper()) {
+ if (!propName.startsWith(QLatin1String("on")) || (propName.length() < 3 || !propName.at(2).isUpper())) {
error(props.at(ii), QQmlConnections::tr("Cannot assign to non-existent property \"%1\"").arg(propName));
return;
}
-
if (binding->type >= QV4::CompiledData::Binding::Type_Object) {
const QV4::CompiledData::Object *target = qmlUnit->objectAt(binding->value.objectIndex);
if (!qmlUnit->stringAt(target->inheritedTypeNameIndex).isEmpty())
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
index 2badef4268..ca19d68948 100644
--- a/src/qml/types/qqmldelegatemodel.cpp
+++ b/src/qml/types/qqmldelegatemodel.cpp
@@ -96,17 +96,16 @@ struct DelegateModelGroupFunction : QV4::FunctionObject
return scope->engine()->memoryManager->allocObject<DelegateModelGroupFunction>(scope, flag, code);
}
- static void call(const QV4::Managed *that, QV4::Scope &scope, QV4::CallData *callData)
+ static ReturnedValue call(const QV4::FunctionObject *that, const Value *thisObject, const Value *argv, int argc)
{
+ QV4::Scope scope(that->engine());
QV4::Scoped<DelegateModelGroupFunction> f(scope, static_cast<const DelegateModelGroupFunction *>(that));
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject);
- if (!o) {
- scope.result = scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object"));
- return;
- }
+ QV4::Scoped<QQmlDelegateModelItemObject> o(scope, thisObject);
+ if (!o)
+ return scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object"));
- QV4::ScopedValue v(scope, callData->argument(0));
- scope.result = f->d()->code(o->d()->item, f->d()->flag, v);
+ QV4::ScopedValue v(scope, argc ? argv[0] : Primitive::undefinedValue());
+ return f->d()->code(o->d()->item, f->d()->flag, v);
}
};
@@ -129,7 +128,8 @@ public:
QQmlDelegateModelEngineData(QV4::ExecutionEngine *v4);
~QQmlDelegateModelEngineData();
- QV4::ReturnedValue array(QV8Engine *engine, const QVector<QQmlChangeSet::Change> &changes);
+ QV4::ReturnedValue array(QV4::ExecutionEngine *engine,
+ const QVector<QQmlChangeSet::Change> &changes);
QV4::PersistentValue changeProto;
};
@@ -326,7 +326,7 @@ void QQmlDelegateModel::componentComplete()
}
d->m_cacheMetaType = new QQmlDelegateModelItemMetaType(
- QQmlEnginePrivate::getV8Engine(d->m_context->engine()), this, groupNames);
+ d->m_context->engine()->handle(), this, groupNames);
d->m_compositor.setGroupCount(d->m_groupCount);
d->m_compositor.setDefaultGroups(defaultGroups);
@@ -993,7 +993,9 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, QQ
}
}
- cacheItem->incubateObject(
+ QQmlComponentPrivate *cp = QQmlComponentPrivate::get(m_delegate);
+ cp->incubateObject(
+ cacheItem->incubationTask,
m_delegate,
m_context->engine(),
ctxt,
@@ -1480,7 +1482,7 @@ void QQmlDelegateModelPrivate::emitChanges()
return;
m_transaction = true;
- QV8Engine *engine = QQmlEnginePrivate::getV8Engine(m_context->engine());
+ QV4::ExecutionEngine *engine = m_context->engine()->handle();
for (int i = 1; i < m_groupCount; ++i)
QQmlDelegateModelGroupPrivate::get(m_groups[i])->emitChanges(engine);
m_transaction = false;
@@ -1675,10 +1677,10 @@ bool QQmlDelegateModelPrivate::insert(Compositor::insert_iterator &before, const
//============================================================================
QQmlDelegateModelItemMetaType::QQmlDelegateModelItemMetaType(
- QV8Engine *engine, QQmlDelegateModel *model, const QStringList &groupNames)
+ QV4::ExecutionEngine *engine, QQmlDelegateModel *model, const QStringList &groupNames)
: model(model)
, groupCount(groupNames.count() + 1)
- , v8Engine(engine)
+ , v4Engine(engine)
, metaObject(0)
, groupNames(groupNames)
{
@@ -1719,37 +1721,36 @@ void QQmlDelegateModelItemMetaType::initializeMetaObject()
void QQmlDelegateModelItemMetaType::initializePrototype()
{
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(v8Engine);
- QV4::Scope scope(v4);
+ QV4::Scope scope(v4Engine);
- QV4::ScopedObject proto(scope, v4->newObject());
+ QV4::ScopedObject proto(scope, v4Engine->newObject());
proto->defineAccessorProperty(QStringLiteral("model"), QQmlDelegateModelItem::get_model, 0);
proto->defineAccessorProperty(QStringLiteral("groups"), QQmlDelegateModelItem::get_groups, QQmlDelegateModelItem::set_groups);
QV4::ScopedString s(scope);
QV4::ScopedProperty p(scope);
- s = v4->newString(QStringLiteral("isUnresolved"));
+ s = v4Engine->newString(QStringLiteral("isUnresolved"));
QV4::ScopedFunctionObject f(scope);
QV4::ExecutionContext *global = scope.engine->rootContext();
p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, 30, QQmlDelegateModelItem::get_member)));
p->setSetter(0);
proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
- s = v4->newString(QStringLiteral("inItems"));
+ s = v4Engine->newString(QStringLiteral("inItems"));
p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, QQmlListCompositor::Default, QQmlDelegateModelItem::get_member)));
p->setSetter((f = QV4::DelegateModelGroupFunction::create(global, QQmlListCompositor::Default, QQmlDelegateModelItem::set_member)));
proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
- s = v4->newString(QStringLiteral("inPersistedItems"));
+ s = v4Engine->newString(QStringLiteral("inPersistedItems"));
p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, QQmlListCompositor::Persisted, QQmlDelegateModelItem::get_member)));
p->setSetter((f = QV4::DelegateModelGroupFunction::create(global, QQmlListCompositor::Persisted, QQmlDelegateModelItem::set_member)));
proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
- s = v4->newString(QStringLiteral("itemsIndex"));
+ s = v4Engine->newString(QStringLiteral("itemsIndex"));
p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, QQmlListCompositor::Default, QQmlDelegateModelItem::get_index)));
proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
- s = v4->newString(QStringLiteral("persistedItemsIndex"));
+ s = v4Engine->newString(QStringLiteral("persistedItemsIndex"));
p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, QQmlListCompositor::Persisted, QQmlDelegateModelItem::get_index)));
p->setSetter(0);
proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
@@ -1757,19 +1758,19 @@ void QQmlDelegateModelItemMetaType::initializePrototype()
for (int i = 2; i < groupNames.count(); ++i) {
QString propertyName = QLatin1String("in") + groupNames.at(i);
propertyName.replace(2, 1, propertyName.at(2).toUpper());
- s = v4->newString(propertyName);
+ s = v4Engine->newString(propertyName);
p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, i + 1, QQmlDelegateModelItem::get_member)));
p->setSetter((f = QV4::DelegateModelGroupFunction::create(global, i + 1, QQmlDelegateModelItem::set_member)));
proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
}
for (int i = 2; i < groupNames.count(); ++i) {
const QString propertyName = groupNames.at(i) + QLatin1String("Index");
- s = v4->newString(propertyName);
+ s = v4Engine->newString(propertyName);
p->setGetter((f = QV4::DelegateModelGroupFunction::create(global, i + 1, QQmlDelegateModelItem::get_index)));
p->setSetter(0);
proto->insertMember(s, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
}
- modelItemProto.set(v4, proto);
+ modelItemProto.set(v4Engine, proto);
}
int QQmlDelegateModelItemMetaType::parseGroups(const QStringList &groups) const
@@ -1786,7 +1787,7 @@ int QQmlDelegateModelItemMetaType::parseGroups(const QStringList &groups) const
int QQmlDelegateModelItemMetaType::parseGroups(const QV4::Value &groups) const
{
int groupFlags = 0;
- QV4::Scope scope(QV8Engine::getV4(v8Engine));
+ QV4::Scope scope(v4Engine);
QV4::ScopedString s(scope, groups);
if (s) {
@@ -1812,26 +1813,24 @@ int QQmlDelegateModelItemMetaType::parseGroups(const QV4::Value &groups) const
return groupFlags;
}
-void QQmlDelegateModelItem::get_model(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQmlDelegateModelItem::get_model(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>());
- if (!o) {
- scope.result = scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object"));
- return;
- }
+ QV4::Scope scope(b);
+ QV4::Scoped<QQmlDelegateModelItemObject> o(scope, thisObject->as<QQmlDelegateModelItemObject>());
+ if (!o)
+ return b->engine()->throwTypeError(QStringLiteral("Not a valid VisualData object"));
if (!o->d()->item->metaType->model)
RETURN_UNDEFINED();
- scope.result = o->d()->item->get();
+ return o->d()->item->get();
}
-void QQmlDelegateModelItem::get_groups(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQmlDelegateModelItem::get_groups(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>());
- if (!o) {
- scope.result = scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object"));
- return;
- }
+ QV4::Scope scope(b);
+ QV4::Scoped<QQmlDelegateModelItemObject> o(scope, thisObject->as<QQmlDelegateModelItemObject>());
+ if (!o)
+ return scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object"));
QStringList groups;
for (int i = 1; i < o->d()->item->metaType->groupCount; ++i) {
@@ -1839,29 +1838,28 @@ void QQmlDelegateModelItem::get_groups(const QV4::BuiltinFunction *, QV4::Scope
groups.append(o->d()->item->metaType->groupNames.at(i - 1));
}
- scope.result = scope.engine->fromVariant(groups);
+ return scope.engine->fromVariant(groups);
}
-void QQmlDelegateModelItem::set_groups(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQmlDelegateModelItem::set_groups(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>());
- if (!o) {
- scope.result = scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object"));
- return;
- }
+ QV4::Scope scope(b);
+ QV4::Scoped<QQmlDelegateModelItemObject> o(scope, thisObject->as<QQmlDelegateModelItemObject>());
+ if (!o)
+ return scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object"));
- if (!callData->argc)
+ if (!argc)
THROW_TYPE_ERROR();
if (!o->d()->item->metaType->model)
RETURN_UNDEFINED();
QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(o->d()->item->metaType->model);
- const int groupFlags = model->m_cacheMetaType->parseGroups(callData->args[0]);
+ const int groupFlags = model->m_cacheMetaType->parseGroups(argv[0]);
const int cacheIndex = model->m_cache.indexOf(o->d()->item);
Compositor::iterator it = model->m_compositor.find(Compositor::Cache, cacheIndex);
model->setGroups(it, 1, Compositor::Cache, groupFlags);
- scope.result = QV4::Encode::undefined();
+ return QV4::Encode::undefined();
}
QV4::ReturnedValue QQmlDelegateModelItem::get_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &)
@@ -1909,7 +1907,7 @@ void QV4::Heap::QQmlDelegateModelItemObject::destroy()
QQmlDelegateModelItem::QQmlDelegateModelItem(
QQmlDelegateModelItemMetaType *metaType, int modelIndex)
- : v4(QV8Engine::getV4(metaType->v8Engine))
+ : v4(metaType->v4Engine)
, metaType(metaType)
, contextData(0)
, object(0)
@@ -1953,29 +1951,6 @@ void QQmlDelegateModelItem::Dispose()
delete this;
}
-/*
- This is essentially a copy of QQmlComponent::create(); except it takes the QQmlContextData
- arguments instead of QQmlContext which means we don't have to construct the rather weighty
- wrapper class for every delegate item.
-*/
-void QQmlDelegateModelItem::incubateObject(
- QQmlComponent *component,
- QQmlEngine *engine,
- QQmlContextData *context,
- QQmlContextData *forContext)
-{
- QQmlIncubatorPrivate *incubatorPriv = QQmlIncubatorPrivate::get(incubationTask);
- QQmlEnginePrivate *enginePriv = QQmlEnginePrivate::get(engine);
- QQmlComponentPrivate *componentPriv = QQmlComponentPrivate::get(component);
-
- incubatorPriv->compilationUnit = componentPriv->compilationUnit;
- incubatorPriv->enginePriv = enginePriv;
- incubatorPriv->creator.reset(new QQmlObjectCreator(context, componentPriv->compilationUnit, componentPriv->creationContext));
- incubatorPriv->subComponentToCreate = componentPriv->start;
-
- enginePriv->incubate(*incubationTask, forContext);
-}
-
void QQmlDelegateModelItem::destroyObject()
{
Q_ASSERT(object);
@@ -2270,13 +2245,13 @@ bool QQmlDelegateModelGroupPrivate::isChangedConnected()
IS_SIGNAL_CONNECTED(q, QQmlDelegateModelGroup, changed, (const QQmlV4Handle &,const QQmlV4Handle &));
}
-void QQmlDelegateModelGroupPrivate::emitChanges(QV8Engine *engine)
+void QQmlDelegateModelGroupPrivate::emitChanges(QV4::ExecutionEngine *v4)
{
Q_Q(QQmlDelegateModelGroup);
if (isChangedConnected() && !changeSet.isEmpty()) {
- QV4::Scope scope(QV8Engine::getV4(engine));
- QV4::ScopedValue removed(scope, engineData(scope.engine)->array(engine, changeSet.removes()));
- QV4::ScopedValue inserted(scope, engineData(scope.engine)->array(engine, changeSet.inserts()));
+ QV4::Scope scope(v4);
+ QV4::ScopedValue removed(scope, engineData(scope.engine)->array(v4, changeSet.removes()));
+ QV4::ScopedValue inserted(scope, engineData(scope.engine)->array(v4, changeSet.inserts()));
emit q->changed(QQmlV4Handle(removed), QQmlV4Handle(inserted));
}
if (changeSet.difference() != 0)
@@ -2505,8 +2480,7 @@ QQmlV4Handle QQmlDelegateModelGroup::get(int index)
if (model->m_cacheMetaType->modelItemProto.isUndefined())
model->m_cacheMetaType->initializePrototype();
- QV8Engine *v8 = model->m_cacheMetaType->v8Engine;
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(v8);
+ QV4::ExecutionEngine *v4 = model->m_cacheMetaType->v4Engine;
QV4::Scope scope(v4);
QV4::ScopedObject o(scope, v4->memoryManager->allocObject<QQmlDelegateModelItemObject>(cacheItem));
QV4::ScopedObject p(scope, model->m_cacheMetaType->modelItemProto.value());
@@ -3266,25 +3240,28 @@ struct QQmlDelegateModelGroupChange : QV4::Object
return e->memoryManager->allocObject<QQmlDelegateModelGroupChange>();
}
- static void method_get_index(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) {
- QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, callData->thisObject.as<QQmlDelegateModelGroupChange>());
+ static QV4::ReturnedValue method_get_index(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) {
+ QV4::Scope scope(b);
+ QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, thisObject->as<QQmlDelegateModelGroupChange>());
if (!that)
THROW_TYPE_ERROR();
- scope.result = QV4::Encode(that->d()->change.index);
+ return QV4::Encode(that->d()->change.index);
}
- static void method_get_count(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) {
- QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, callData->thisObject.as<QQmlDelegateModelGroupChange>());
+ static QV4::ReturnedValue method_get_count(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) {
+ QV4::Scope scope(b);
+ QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, thisObject->as<QQmlDelegateModelGroupChange>());
if (!that)
THROW_TYPE_ERROR();
- scope.result = QV4::Encode(that->d()->change.count);
+ return QV4::Encode(that->d()->change.count);
}
- static void method_get_moveId(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) {
- QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, callData->thisObject.as<QQmlDelegateModelGroupChange>());
+ static QV4::ReturnedValue method_get_moveId(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int) {
+ QV4::Scope scope(b);
+ QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, thisObject->as<QQmlDelegateModelGroupChange>());
if (!that)
THROW_TYPE_ERROR();
if (that->d()->change.moveId < 0)
RETURN_UNDEFINED();
- scope.result = QV4::Encode(that->d()->change.moveId);
+ return QV4::Encode(that->d()->change.moveId);
}
};
@@ -3369,9 +3346,9 @@ QQmlDelegateModelEngineData::~QQmlDelegateModelEngineData()
{
}
-QV4::ReturnedValue QQmlDelegateModelEngineData::array(QV8Engine *engine, const QVector<QQmlChangeSet::Change> &changes)
+QV4::ReturnedValue QQmlDelegateModelEngineData::array(QV4::ExecutionEngine *v4,
+ const QVector<QQmlChangeSet::Change> &changes)
{
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
QV4::Scope scope(v4);
QV4::ScopedObject o(scope, QQmlDelegateModelGroupChangeArray::create(v4, changes));
return o.asReturnedValue();
diff --git a/src/qml/types/qqmldelegatemodel_p_p.h b/src/qml/types/qqmldelegatemodel_p_p.h
index d8e61b05a1..7b60bcddc0 100644
--- a/src/qml/types/qqmldelegatemodel_p_p.h
+++ b/src/qml/types/qqmldelegatemodel_p_p.h
@@ -69,7 +69,7 @@ class QQmlDelegateModelAttachedMetaObject;
class QQmlDelegateModelItemMetaType : public QQmlRefCount
{
public:
- QQmlDelegateModelItemMetaType(QV8Engine *engine, QQmlDelegateModel *model, const QStringList &groupNames);
+ QQmlDelegateModelItemMetaType(QV4::ExecutionEngine *engine, QQmlDelegateModel *model, const QStringList &groupNames);
~QQmlDelegateModelItemMetaType();
void initializeMetaObject();
@@ -80,7 +80,7 @@ public:
QPointer<QQmlDelegateModel> model;
const int groupCount;
- QV8Engine * const v8Engine;
+ QV4::ExecutionEngine * const v4Engine;
QQmlDelegateModelAttachedMetaObject *metaObject;
const QStringList groupNames;
QV4::PersistentValue modelItemProto;
@@ -112,11 +112,6 @@ public:
QObject *modelObject() { return this; }
- void incubateObject(
- QQmlComponent *component,
- QQmlEngine *engine,
- QQmlContextData *context,
- QQmlContextData *forContext);
void destroyObject();
static QQmlDelegateModelItem *dataForObject(QObject *object);
@@ -131,9 +126,9 @@ public:
virtual void setValue(const QString &role, const QVariant &value) { Q_UNUSED(role); Q_UNUSED(value); }
virtual bool resolveIndex(const QQmlAdaptorModel &, int) { return false; }
- static void get_model(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void get_groups(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void set_groups(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static QV4::ReturnedValue get_model(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue get_groups(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue set_groups(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
static QV4::ReturnedValue get_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &);
static QV4::ReturnedValue set_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg);
static QV4::ReturnedValue get_index(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg);
@@ -225,7 +220,7 @@ public:
void setModel(QQmlDelegateModel *model, Compositor::Group group);
bool isChangedConnected();
- void emitChanges(QV8Engine *engine);
+ void emitChanges(QV4::ExecutionEngine *engine);
void emitModelUpdated(bool reset);
void createdPackage(int index, QQuickPackage *package);
diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp
index 2b4e906617..b5c45d3aa4 100644
--- a/src/qml/types/qqmllistmodel.cpp
+++ b/src/qml/types/qqmllistmodel.cpp
@@ -42,6 +42,7 @@
#include <private/qqmlopenmetaobject_p.h>
#include <private/qqmljsast_p.h>
#include <private/qqmljsengine_p.h>
+#include <private/qjsvalue_p.h>
#include <private/qqmlcustomparser_p.h>
#include <private/qqmlengine_p.h>
@@ -84,7 +85,7 @@ static QString roleTypeName(ListLayout::Role::DataType t)
static const QString roleTypeNames[] = {
QStringLiteral("String"), QStringLiteral("Number"), QStringLiteral("Bool"),
QStringLiteral("List"), QStringLiteral("QObject"), QStringLiteral("VariantMap"),
- QStringLiteral("DateTime")
+ QStringLiteral("DateTime"), QStringLiteral("Function")
};
if (t > ListLayout::Role::Invalid && t < ListLayout::Role::MaxDataType)
@@ -123,8 +124,8 @@ const ListLayout::Role &ListLayout::getRoleOrCreate(QV4::String *key, Role::Data
const ListLayout::Role &ListLayout::createRole(const QString &key, ListLayout::Role::DataType type)
{
- const int dataSizes[] = { sizeof(QString), sizeof(double), sizeof(bool), sizeof(ListModel *), sizeof(QPointer<QObject>), sizeof(QVariantMap), sizeof(QDateTime) };
- const int dataAlignments[] = { sizeof(QString), sizeof(double), sizeof(bool), sizeof(ListModel *), sizeof(QObject *), sizeof(QVariantMap), sizeof(QDateTime) };
+ const int dataSizes[] = { sizeof(QString), sizeof(double), sizeof(bool), sizeof(ListModel *), sizeof(QPointer<QObject>), sizeof(QVariantMap), sizeof(QDateTime), sizeof(QJSValue) };
+ const int dataAlignments[] = { sizeof(QString), sizeof(double), sizeof(bool), sizeof(ListModel *), sizeof(QObject *), sizeof(QVariantMap), sizeof(QDateTime), sizeof(QJSValue) };
Role *r = new Role;
r->name = key;
@@ -217,11 +218,20 @@ const ListLayout::Role *ListLayout::getRoleOrCreate(const QString &key, const QV
switch (data.type()) {
case QVariant::Double: type = Role::Number; break;
case QVariant::Int: type = Role::Number; break;
- case QVariant::UserType: type = Role::List; break;
case QVariant::Bool: type = Role::Bool; break;
case QVariant::String: type = Role::String; break;
case QVariant::Map: type = Role::VariantMap; break;
case QVariant::DateTime: type = Role::DateTime; break;
+ case QVariant::UserType: {
+ if (data.userType() == qMetaTypeId<QJSValue>() &&
+ data.value<QJSValue>().isCallable()) {
+ type = Role::Function;
+ break;
+ } else {
+ type = Role::List;
+ break;
+ }
+ }
default: type = Role::Invalid; break;
}
@@ -255,29 +265,34 @@ QObject *ListModel::getOrCreateModelObject(QQmlListModel *model, int elementInde
{
ListElement *e = elements[elementIndex];
if (e->m_objectCache == 0) {
- e->m_objectCache = new QObject;
+ void *memory = operator new(sizeof(QObject) + sizeof(QQmlData));
+ void *ddataMemory = ((char *)memory) + sizeof(QObject);
+ e->m_objectCache = new (memory) QObject;
+ QQmlData *ddata = new (ddataMemory) QQmlData;
+ ddata->ownMemory = false;
+ QObjectPrivate::get(e->m_objectCache)->declarativeData = ddata;
(void)new ModelNodeMetaObject(e->m_objectCache, model, elementIndex);
}
return e->m_objectCache;
}
-void ListModel::sync(ListModel *src, ListModel *target, QHash<int, ListModel *> *targetModelHash)
+bool ListModel::sync(ListModel *src, ListModel *target)
{
// Sanity check
- target->m_uid = src->m_uid;
- if (targetModelHash)
- targetModelHash->insert(target->m_uid, target);
+
+ bool hasChanges = false;
// Build hash of elements <-> uid for each of the lists
QHash<int, ElementSync> elementHash;
- for (int i=0 ; i < target->elements.count() ; ++i) {
+ for (int i = 0; i < target->elements.count(); ++i) {
ListElement *e = target->elements.at(i);
int uid = e->getUid();
ElementSync sync;
sync.target = e;
+ sync.targetIndex = i;
elementHash.insert(uid, sync);
}
- for (int i=0 ; i < src->elements.count() ; ++i) {
+ for (int i = 0; i < src->elements.count(); ++i) {
ListElement *e = src->elements.at(i);
int uid = e->getUid();
@@ -285,24 +300,39 @@ void ListModel::sync(ListModel *src, ListModel *target, QHash<int, ListModel *>
if (it == elementHash.end()) {
ElementSync sync;
sync.src = e;
+ sync.srcIndex = i;
elementHash.insert(uid, sync);
} else {
ElementSync &sync = it.value();
sync.src = e;
+ sync.srcIndex = i;
}
}
+ QQmlListModel *targetModel = target->m_modelCache;
+
// Get list of elements that are in the target but no longer in the source. These get deleted first.
- QHash<int, ElementSync>::iterator it = elementHash.begin();
- QHash<int, ElementSync>::iterator end = elementHash.end();
- while (it != end) {
- const ElementSync &s = it.value();
- if (s.src == 0) {
+ int rowsRemoved = 0;
+ for (int i = 0 ; i < target->elements.count() ; ++i) {
+ ListElement *element = target->elements.at(i);
+ ElementSync &s = elementHash.find(element->getUid()).value();
+ Q_ASSERT(s.targetIndex >= 0);
+ // need to update the targetIndex, to keep it correct after removals
+ s.targetIndex -= rowsRemoved;
+ if (s.src == nullptr) {
+ Q_ASSERT(s.targetIndex == i);
+ hasChanges = true;
+ if (targetModel)
+ targetModel->beginRemoveRows(QModelIndex(), i, i);
s.target->destroy(target->m_layout);
target->elements.removeOne(s.target);
delete s.target;
+ if (targetModel)
+ targetModel->endRemoveRows();
+ ++rowsRemoved;
+ --i;
+ continue;
}
- ++it;
}
// Sync the layouts
@@ -310,15 +340,15 @@ void ListModel::sync(ListModel *src, ListModel *target, QHash<int, ListModel *>
// Clear the target list, and append in correct order from the source
target->elements.clear();
- for (int i=0 ; i < src->elements.count() ; ++i) {
+ for (int i = 0; i < src->elements.count(); ++i) {
ListElement *srcElement = src->elements.at(i);
- it = elementHash.find(srcElement->getUid());
- const ElementSync &s = it.value();
+ ElementSync &s = elementHash.find(srcElement->getUid()).value();
+ Q_ASSERT(s.srcIndex >= 0);
ListElement *targetElement = s.target;
- if (targetElement == 0) {
+ if (targetElement == nullptr) {
targetElement = new ListElement(srcElement->getUid());
}
- ListElement::sync(srcElement, src->m_layout, targetElement, target->m_layout, targetModelHash);
+ s.changedRoles = ListElement::sync(srcElement, src->m_layout, targetElement, target->m_layout);
target->elements.append(targetElement);
}
@@ -330,13 +360,43 @@ void ListModel::sync(ListModel *src, ListModel *target, QHash<int, ListModel *>
if (ModelNodeMetaObject *mo = e->objectCache())
mo->updateValues();
}
+
+ // now emit the change notifications required. This can be safely done, as we're only emitting changes, moves and inserts,
+ // so the model indices can't be out of bounds
+ //
+ // to ensure things are kept in the correct order, emit inserts and moves first. This shouls ensure all persistent
+ // model indices are updated correctly
+ int rowsInserted = 0;
+ for (int i = 0 ; i < target->elements.count() ; ++i) {
+ ListElement *element = target->elements.at(i);
+ ElementSync &s = elementHash.find(element->getUid()).value();
+ Q_ASSERT(s.srcIndex >= 0);
+ s.srcIndex += rowsInserted;
+ if (s.srcIndex != s.targetIndex) {
+ if (targetModel) {
+ if (s.targetIndex == -1) {
+ targetModel->beginInsertRows(QModelIndex(), i, i);
+ targetModel->endInsertRows();
+ } else {
+ targetModel->beginMoveRows(QModelIndex(), i, i, QModelIndex(), s.srcIndex);
+ targetModel->endMoveRows();
+ }
+ }
+ hasChanges = true;
+ ++rowsInserted;
+ }
+ if (s.targetIndex != -1 && !s.changedRoles.isEmpty()) {
+ QModelIndex idx = targetModel->createIndex(i, 0);
+ if (targetModel)
+ targetModel->dataChanged(idx, idx, s.changedRoles);
+ hasChanges = true;
+ }
+ }
+ return hasChanges;
}
-ListModel::ListModel(ListLayout *layout, QQmlListModel *modelCache, int uid) : m_layout(layout), m_modelCache(modelCache)
+ListModel::ListModel(ListLayout *layout, QQmlListModel *modelCache) : m_layout(layout), m_modelCache(modelCache)
{
- if (uid == -1)
- uid = uidCounter.fetchAndAddOrdered(1);
- m_uid = uid;
}
void ListModel::destroy()
@@ -344,7 +404,6 @@ void ListModel::destroy()
for (const auto &destroyer : remove(0, elements.count()))
destroyer();
- m_uid = -1;
m_layout = 0;
if (m_modelCache && m_modelCache->m_primary == false)
delete m_modelCache;
@@ -361,7 +420,7 @@ int ListModel::appendElement()
void ListModel::insertElement(int index)
{
newElement(index);
- updateCacheIndices();
+ updateCacheIndices(index);
}
void ListModel::move(int from, int to, int n)
@@ -383,7 +442,7 @@ void ListModel::move(int from, int to, int n)
for (int i=0 ; i < store.count() ; ++i)
elements[from+i] = store[i];
- updateCacheIndices();
+ updateCacheIndices(from, to + n);
}
void ListModel::newElement(int index)
@@ -392,9 +451,14 @@ void ListModel::newElement(int index)
elements.insert(index, e);
}
-void ListModel::updateCacheIndices()
+void ListModel::updateCacheIndices(int start, int end)
{
- for (int i=0 ; i < elements.count() ; ++i) {
+ int count = elements.count();
+
+ if (end < 0 || end > count)
+ end = count;
+
+ for (int i = start; i < end; ++i) {
ListElement *e = elements.at(i);
if (ModelNodeMetaObject *mo = e->objectCache())
mo->m_elementIndex = i;
@@ -444,7 +508,7 @@ void ListModel::set(int elementIndex, QV4::Object *object, QVector<int> *roles)
roleIndex = e->setDoubleProperty(r, propertyValue->asDouble());
} else if (QV4::ArrayObject *a = propertyValue->as<QV4::ArrayObject>()) {
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::List);
- ListModel *subModel = new ListModel(r.subLayout, 0, -1);
+ ListModel *subModel = new ListModel(r.subLayout, 0);
int arrayLength = a->getLength();
for (int j=0 ; j < arrayLength ; ++j) {
@@ -460,6 +524,12 @@ void ListModel::set(int elementIndex, QV4::Object *object, QVector<int> *roles)
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::DateTime);
QDateTime dt = dd->toQDateTime();
roleIndex = e->setDateTimeProperty(r, dt);
+ } else if (QV4::FunctionObject *f = propertyValue->as<QV4::FunctionObject>()) {
+ const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Function);
+ QV4::ScopedFunctionObject func(scope, f);
+ QJSValue jsv;
+ QJSValuePrivate::setValue(&jsv, v4, func);
+ roleIndex = e->setFunctionProperty(r, jsv);
} else if (QV4::Object *o = propertyValue->as<QV4::Object>()) {
if (QV4::QObjectWrapper *wrapper = o->as<QV4::QObjectWrapper>()) {
QObject *o = wrapper->object();
@@ -519,7 +589,7 @@ void ListModel::set(int elementIndex, QV4::Object *object)
} else if (QV4::ArrayObject *a = propertyValue->as<QV4::ArrayObject>()) {
const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::List);
if (r.type == ListLayout::Role::List) {
- ListModel *subModel = new ListModel(r.subLayout, 0, -1);
+ ListModel *subModel = new ListModel(r.subLayout, 0);
int arrayLength = a->getLength();
for (int j=0 ; j < arrayLength ; ++j) {
@@ -571,7 +641,7 @@ QVector<std::function<void()>> ListModel::remove(int index, int count)
});
}
elements.remove(index, count);
- updateCacheIndices();
+ updateCacheIndices(index);
return toDestroy;
}
@@ -683,6 +753,17 @@ QDateTime *ListElement::getDateTimeProperty(const ListLayout::Role &role)
return dt;
}
+QJSValue *ListElement::getFunctionProperty(const ListLayout::Role &role)
+{
+ QJSValue *f = 0;
+
+ char *mem = getPropertyMemory(role);
+ if (isMemoryUsed<QJSValue>(mem))
+ f = reinterpret_cast<QJSValue *>(mem);
+
+ return f;
+}
+
QPointer<QObject> *ListElement::getGuardProperty(const ListLayout::Role &role)
{
char *mem = getPropertyMemory(role);
@@ -776,6 +857,14 @@ QVariant ListElement::getProperty(const ListLayout::Role &role, const QQmlListMo
}
}
break;
+ case ListLayout::Role::Function:
+ {
+ if (isMemoryUsed<QJSValue>(mem)) {
+ QJSValue *func = reinterpret_cast<QJSValue *>(mem);
+ data = QVariant::fromValue(*func);
+ }
+ }
+ break;
default:
break;
}
@@ -909,7 +998,11 @@ int ListElement::setVariantMapProperty(const ListLayout::Role &role, QVariantMap
char *mem = getPropertyMemory(role);
if (isMemoryUsed<QVariantMap>(mem)) {
QVariantMap *map = reinterpret_cast<QVariantMap *>(mem);
+ if (m && map->isSharedWith(*m))
+ return roleIndex;
map->~QMap();
+ } else if (!m) {
+ return roleIndex;
}
if (m)
new (mem) QVariantMap(*m);
@@ -938,6 +1031,24 @@ int ListElement::setDateTimeProperty(const ListLayout::Role &role, const QDateTi
return roleIndex;
}
+int ListElement::setFunctionProperty(const ListLayout::Role &role, const QJSValue &f)
+{
+ int roleIndex = -1;
+
+ if (role.type == ListLayout::Role::Function) {
+ char *mem = getPropertyMemory(role);
+ if (isMemoryUsed<QJSValue>(mem)) {
+ QJSValue *f = reinterpret_cast<QJSValue *>(mem);
+ f->~QJSValue();
+ }
+ new (mem) QJSValue(f);
+ roleIndex = role.index;
+ }
+
+ return roleIndex;
+}
+
+
void ListElement::setStringPropertyFast(const ListLayout::Role &role, const QString &s)
{
char *mem = getPropertyMemory(role);
@@ -984,6 +1095,12 @@ void ListElement::setDateTimePropertyFast(const ListLayout::Role &role, const QD
new (mem) QDateTime(dt);
}
+void ListElement::setFunctionPropertyFast(const ListLayout::Role &role, const QJSValue &f)
+{
+ char *mem = getPropertyMemory(role);
+ new (mem) QJSValue(f);
+}
+
void ListElement::clearProperty(const ListLayout::Role &role)
{
switch (role.type) {
@@ -1008,6 +1125,9 @@ void ListElement::clearProperty(const ListLayout::Role &role)
case ListLayout::Role::VariantMap:
setVariantMapProperty(role, (QVariantMap *)0);
break;
+ case ListLayout::Role::Function:
+ setFunctionProperty(role, QJSValue());
+ break;
default:
break;
}
@@ -1034,12 +1154,14 @@ ListElement::~ListElement()
delete next;
}
-void ListElement::sync(ListElement *src, ListLayout *srcLayout, ListElement *target, ListLayout *targetLayout, QHash<int, ListModel *> *targetModelHash)
+QVector<int> ListElement::sync(ListElement *src, ListLayout *srcLayout, ListElement *target, ListLayout *targetLayout)
{
+ QVector<int> changedRoles;
for (int i=0 ; i < srcLayout->roleCount() ; ++i) {
const ListLayout::Role &srcRole = srcLayout->getExistingRole(i);
const ListLayout::Role &targetRole = targetLayout->getExistingRole(i);
+ int roleIndex = -1;
switch (srcRole.type) {
case ListLayout::Role::List:
{
@@ -1048,39 +1170,44 @@ void ListElement::sync(ListElement *src, ListLayout *srcLayout, ListElement *tar
if (srcSubModel) {
if (targetSubModel == 0) {
- targetSubModel = new ListModel(targetRole.subLayout, 0, srcSubModel->getUid());
+ targetSubModel = new ListModel(targetRole.subLayout, 0);
target->setListPropertyFast(targetRole, targetSubModel);
}
- ListModel::sync(srcSubModel, targetSubModel, targetModelHash);
+ if (ListModel::sync(srcSubModel, targetSubModel))
+ roleIndex = targetRole.index;
}
}
break;
case ListLayout::Role::QObject:
{
QObject *object = src->getQObjectProperty(srcRole);
- target->setQObjectProperty(targetRole, object);
+ roleIndex = target->setQObjectProperty(targetRole, object);
}
break;
case ListLayout::Role::String:
case ListLayout::Role::Number:
case ListLayout::Role::Bool:
case ListLayout::Role::DateTime:
+ case ListLayout::Role::Function:
{
QVariant v = src->getProperty(srcRole, 0, 0);
- target->setVariantProperty(targetRole, v);
+ roleIndex = target->setVariantProperty(targetRole, v);
}
break;
case ListLayout::Role::VariantMap:
{
QVariantMap *map = src->getVariantMapProperty(srcRole);
- target->setVariantMapProperty(targetRole, map);
+ roleIndex = target->setVariantMapProperty(targetRole, map);
}
break;
default:
break;
}
+ if (roleIndex >= 0)
+ changedRoles << roleIndex;
}
+ return changedRoles;
}
void ListElement::destroy(ListLayout *layout)
@@ -1127,6 +1254,13 @@ void ListElement::destroy(ListLayout *layout)
dt->~QDateTime();
}
break;
+ case ListLayout::Role::Function:
+ {
+ QJSValue *f = getFunctionProperty(r);
+ if (f)
+ f->~QJSValue();
+ }
+ break;
default:
// other types don't need explicit cleanup.
break;
@@ -1166,6 +1300,9 @@ int ListElement::setVariantProperty(const ListLayout::Role &role, const QVariant
case ListLayout::Role::DateTime:
roleIndex = setDateTimeProperty(role, d.toDateTime());
break;
+ case ListLayout::Role::Function:
+ roleIndex = setFunctionProperty(role, d.value<QJSValue>());
+ break;
default:
break;
}
@@ -1192,7 +1329,7 @@ int ListElement::setJsProperty(const ListLayout::Role &role, const QV4::Value &d
QV4::Scope scope(a->engine());
QV4::ScopedObject o(scope);
- ListModel *subModel = new ListModel(role.subLayout, 0, -1);
+ ListModel *subModel = new ListModel(role.subLayout, 0);
int arrayLength = a->getLength();
for (int j=0 ; j < arrayLength ; ++j) {
o = a->getIndexed(j);
@@ -1208,6 +1345,11 @@ int ListElement::setJsProperty(const ListLayout::Role &role, const QV4::Value &d
QV4::Scoped<QV4::DateObject> dd(scope, d);
QDateTime dt = dd->toQDateTime();
roleIndex = setDateTimeProperty(role, dt);
+ } else if (d.as<QV4::FunctionObject>()) {
+ QV4::ScopedFunctionObject f(scope, d);
+ QJSValue jsv;
+ QJSValuePrivate::setValue(&jsv, eng, f);
+ roleIndex = setFunctionProperty(role, jsv);
} else if (d.isObject()) {
QV4::ScopedObject o(scope, d);
QV4::QObjectWrapper *wrapper = o->as<QV4::QObjectWrapper>();
@@ -1332,7 +1474,7 @@ void ModelNodeMetaObject::emitDirectNotifies(const int *changedRoles, int roleCo
namespace QV4 {
-void ModelObject::put(Managed *m, String *name, const Value &value)
+bool ModelObject::put(Managed *m, String *name, const Value &value)
{
ModelObject *that = static_cast<ModelObject*>(m);
@@ -1346,6 +1488,7 @@ void ModelObject::put(Managed *m, String *name, const Value &value)
ModelNodeMetaObject *mo = ModelNodeMetaObject::get(that->object());
if (mo->initialized())
mo->emitPropertyNotification(name->toQString().toUtf8());
+ return true;
}
ReturnedValue ModelObject::get(const Managed *m, String *name, bool *hasProperty)
@@ -1409,20 +1552,22 @@ DynamicRoleModelNode *DynamicRoleModelNode::create(const QVariantMap &obj, QQmlL
return object;
}
-void DynamicRoleModelNode::sync(DynamicRoleModelNode *src, DynamicRoleModelNode *target, QHash<int, QQmlListModel *> *targetModelHash)
+QVector<int> DynamicRoleModelNode::sync(DynamicRoleModelNode *src, DynamicRoleModelNode *target)
{
- for (int i=0 ; i < src->m_meta->count() ; ++i) {
+ QVector<int> changedRoles;
+ for (int i = 0; i < src->m_meta->count(); ++i) {
const QByteArray &name = src->m_meta->name(i);
QVariant value = src->m_meta->value(i);
QQmlListModel *srcModel = qobject_cast<QQmlListModel *>(value.value<QObject *>());
QQmlListModel *targetModel = qobject_cast<QQmlListModel *>(target->m_meta->value(i).value<QObject *>());
+ bool modelHasChanges = false;
if (srcModel) {
if (targetModel == 0)
targetModel = QQmlListModel::createWithOwner(target->m_owner);
- QQmlListModel::sync(srcModel, targetModel, targetModelHash);
+ modelHasChanges = QQmlListModel::sync(srcModel, targetModel);
QObject *targetModelObject = targetModel;
value = QVariant::fromValue(targetModelObject);
@@ -1430,8 +1575,10 @@ void DynamicRoleModelNode::sync(DynamicRoleModelNode *src, DynamicRoleModelNode
delete targetModel;
}
- target->setValue(name, value);
+ if (target->setValue(name, value) || modelHasChanges)
+ changedRoles << target->m_owner->m_roles.indexOf(QString::fromUtf8(name));
}
+ return changedRoles;
}
void DynamicRoleModelNode::updateValues(const QVariantMap &object, QVector<int> &roles)
@@ -1641,11 +1788,10 @@ QQmlListModel::QQmlListModel(QObject *parent)
m_mainThread = true;
m_primary = true;
m_agent = 0;
- m_uid = uidCounter.fetchAndAddOrdered(1);
m_dynamicRoles = false;
m_layout = new ListLayout;
- m_listModel = new ListModel(m_layout, this, -1);
+ m_listModel = new ListModel(m_layout, this);
m_engine = 0;
}
@@ -1674,12 +1820,12 @@ QQmlListModel::QQmlListModel(QQmlListModel *orig, QQmlListModelWorkerAgent *agen
m_dynamicRoles = orig->m_dynamicRoles;
m_layout = new ListLayout(orig->m_layout);
- m_listModel = new ListModel(m_layout, this, orig->m_listModel->getUid());
+ m_listModel = new ListModel(m_layout, this);
if (m_dynamicRoles)
- sync(orig, this, 0);
+ sync(orig, this);
else
- ListModel::sync(orig->m_listModel, m_listModel, 0);
+ ListModel::sync(orig->m_listModel, m_listModel);
m_engine = 0;
}
@@ -1724,31 +1870,31 @@ QQmlListModel *QQmlListModel::createWithOwner(QQmlListModel *newOwner)
QV4::ExecutionEngine *QQmlListModel::engine() const
{
if (m_engine == 0) {
- m_engine = QQmlEnginePrivate::get(qmlEngine(this))->v4engine();
+ m_engine = qmlEngine(this)->handle();
}
return m_engine;
}
-void QQmlListModel::sync(QQmlListModel *src, QQmlListModel *target, QHash<int, QQmlListModel *> *targetModelHash)
+bool QQmlListModel::sync(QQmlListModel *src, QQmlListModel *target)
{
Q_ASSERT(src->m_dynamicRoles && target->m_dynamicRoles);
- target->m_uid = src->m_uid;
- if (targetModelHash)
- targetModelHash->insert(target->m_uid, target);
+ bool hasChanges = false;
+
target->m_roles = src->m_roles;
// Build hash of elements <-> uid for each of the lists
QHash<int, ElementSync> elementHash;
- for (int i=0 ; i < target->m_modelObjects.count() ; ++i) {
+ for (int i = 0 ; i < target->m_modelObjects.count(); ++i) {
DynamicRoleModelNode *e = target->m_modelObjects.at(i);
int uid = e->getUid();
ElementSync sync;
sync.target = e;
+ sync.targetIndex = i;
elementHash.insert(uid, sync);
}
- for (int i=0 ; i < src->m_modelObjects.count() ; ++i) {
+ for (int i = 0 ; i < src->m_modelObjects.count(); ++i) {
DynamicRoleModelNode *e = src->m_modelObjects.at(i);
int uid = e->getUid();
@@ -1756,118 +1902,102 @@ void QQmlListModel::sync(QQmlListModel *src, QQmlListModel *target, QHash<int, Q
if (it == elementHash.end()) {
ElementSync sync;
sync.src = e;
+ sync.srcIndex = i;
elementHash.insert(uid, sync);
} else {
ElementSync &sync = it.value();
sync.src = e;
+ sync.srcIndex = i;
}
}
// Get list of elements that are in the target but no longer in the source. These get deleted first.
- QHash<int, ElementSync>::iterator it = elementHash.begin();
- QHash<int, ElementSync>::iterator end = elementHash.end();
- while (it != end) {
- const ElementSync &s = it.value();
- if (s.src == 0) {
- int targetIndex = target->m_modelObjects.indexOf(s.target);
- target->m_modelObjects.remove(targetIndex, 1);
+ int rowsRemoved = 0;
+ for (int i = 0 ; i < target->m_modelObjects.count() ; ++i) {
+ DynamicRoleModelNode *element = target->m_modelObjects.at(i);
+ ElementSync &s = elementHash.find(element->getUid()).value();
+ Q_ASSERT(s.targetIndex >= 0);
+ // need to update the targetIndex, to keep it correct after removals
+ s.targetIndex -= rowsRemoved;
+ if (s.src == nullptr) {
+ Q_ASSERT(s.targetIndex == i);
+ hasChanges = true;
+ target->beginRemoveRows(QModelIndex(), i, i);
+ target->m_modelObjects.remove(i, 1);
+ target->endRemoveRows();
delete s.target;
+ ++rowsRemoved;
+ --i;
+ continue;
}
- ++it;
}
// Clear the target list, and append in correct order from the source
target->m_modelObjects.clear();
- for (int i=0 ; i < src->m_modelObjects.count() ; ++i) {
- DynamicRoleModelNode *srcElement = src->m_modelObjects.at(i);
- it = elementHash.find(srcElement->getUid());
- const ElementSync &s = it.value();
+ for (int i = 0 ; i < src->m_modelObjects.count() ; ++i) {
+ DynamicRoleModelNode *element = src->m_modelObjects.at(i);
+ ElementSync &s = elementHash.find(element->getUid()).value();
+ Q_ASSERT(s.srcIndex >= 0);
DynamicRoleModelNode *targetElement = s.target;
if (targetElement == 0) {
- targetElement = new DynamicRoleModelNode(target, srcElement->getUid());
+ targetElement = new DynamicRoleModelNode(target, element->getUid());
}
- DynamicRoleModelNode::sync(srcElement, targetElement, targetModelHash);
+ s.changedRoles = DynamicRoleModelNode::sync(element, targetElement);
target->m_modelObjects.append(targetElement);
}
-}
-void QQmlListModel::emitItemsChanged(int index, int count, const QVector<int> &roles)
-{
- if (count <= 0)
- return;
-
- if (m_mainThread) {
- emit dataChanged(createIndex(index, 0), createIndex(index + count - 1, 0), roles);;
- } else {
- int uid = m_dynamicRoles ? getUid() : m_listModel->getUid();
- m_agent->data.changedChange(uid, index, count, roles);
+ // now emit the change notifications required. This can be safely done, as we're only emitting changes, moves and inserts,
+ // so the model indices can't be out of bounds
+ //
+ // to ensure things are kept in the correct order, emit inserts and moves first. This shouls ensure all persistent
+ // model indices are updated correctly
+ int rowsInserted = 0;
+ for (int i = 0 ; i < target->m_modelObjects.count() ; ++i) {
+ DynamicRoleModelNode *element = target->m_modelObjects.at(i);
+ ElementSync &s = elementHash.find(element->getUid()).value();
+ Q_ASSERT(s.srcIndex >= 0);
+ s.srcIndex += rowsInserted;
+ if (s.srcIndex != s.targetIndex) {
+ if (s.targetIndex == -1) {
+ target->beginInsertRows(QModelIndex(), i, i);
+ target->endInsertRows();
+ } else {
+ target->beginMoveRows(QModelIndex(), i, i, QModelIndex(), s.srcIndex);
+ target->endMoveRows();
+ }
+ hasChanges = true;
+ ++rowsInserted;
+ }
+ if (s.targetIndex != -1 && !s.changedRoles.isEmpty()) {
+ QModelIndex idx = target->createIndex(i, 0);
+ emit target->dataChanged(idx, idx, s.changedRoles);
+ hasChanges = true;
+ }
}
+ return hasChanges;
}
-void QQmlListModel::emitItemsAboutToBeRemoved(int index, int count)
-{
- if (count <= 0 || !m_mainThread)
- return;
-
- beginRemoveRows(QModelIndex(), index, index + count - 1);
-}
-
-void QQmlListModel::emitItemsRemoved(int index, int count)
+void QQmlListModel::emitItemsChanged(int index, int count, const QVector<int> &roles)
{
if (count <= 0)
return;
- if (m_mainThread) {
- endRemoveRows();
- emit countChanged();
- } else {
- int uid = m_dynamicRoles ? getUid() : m_listModel->getUid();
- if (index == 0 && count == this->count())
- m_agent->data.clearChange(uid);
- m_agent->data.removeChange(uid, index, count);
- }
+ if (m_mainThread)
+ emit dataChanged(createIndex(index, 0), createIndex(index + count - 1, 0), roles);;
}
void QQmlListModel::emitItemsAboutToBeInserted(int index, int count)
{
- if (count <= 0 || !m_mainThread)
- return;
-
- beginInsertRows(QModelIndex(), index, index + count - 1);
+ Q_ASSERT(index >= 0 && count >= 0);
+ if (m_mainThread)
+ beginInsertRows(QModelIndex(), index, index + count - 1);
}
-void QQmlListModel::emitItemsInserted(int index, int count)
+void QQmlListModel::emitItemsInserted()
{
- if (count <= 0)
- return;
-
if (m_mainThread) {
endInsertRows();
emit countChanged();
- } else {
- int uid = m_dynamicRoles ? getUid() : m_listModel->getUid();
- m_agent->data.insertChange(uid, index, count);
- }
-}
-
-void QQmlListModel::emitItemsAboutToBeMoved(int from, int to, int n)
-{
- if (n <= 0 || !m_mainThread)
- return;
-
- beginMoveRows(QModelIndex(), from, from + n - 1, QModelIndex(), to > from ? to + n : to);
-}
-
-void QQmlListModel::emitItemsMoved(int from, int to, int n)
-{
- if (n <= 0)
- return;
-
- if (m_mainThread) {
- endMoveRows();
- } else {
- int uid = m_dynamicRoles ? getUid() : m_listModel->getUid();
- m_agent->data.moveChange(uid, from, n, to);
}
}
@@ -1984,12 +2114,12 @@ void QQmlListModel::setDynamicRoles(bool enableDynamicRoles)
if (m_mainThread && m_agent == 0) {
if (enableDynamicRoles) {
if (m_layout->roleCount())
- qmlWarning(this) << tr("unable to enable dynamic roles as this model is not empty!");
+ qmlWarning(this) << tr("unable to enable dynamic roles as this model is not empty");
else
m_dynamicRoles = true;
} else {
if (m_roles.count()) {
- qmlWarning(this) << tr("unable to enable static roles as this model is not empty!");
+ qmlWarning(this) << tr("unable to enable static roles as this model is not empty");
} else {
m_dynamicRoles = false;
}
@@ -2049,7 +2179,13 @@ void QQmlListModel::remove(QQmlV4Function *args)
void QQmlListModel::removeElements(int index, int removeCount)
{
- emitItemsAboutToBeRemoved(index, removeCount);
+ Q_ASSERT(index >= 0 && removeCount >= 0);
+
+ if (!removeCount)
+ return;
+
+ if (m_mainThread)
+ beginRemoveRows(QModelIndex(), index, index + removeCount - 1);
QVector<std::function<void()>> toDestroy;
if (m_dynamicRoles) {
@@ -2064,7 +2200,10 @@ void QQmlListModel::removeElements(int index, int removeCount)
toDestroy = m_listModel->remove(index, removeCount);
}
- emitItemsRemoved(index, removeCount);
+ if (m_mainThread) {
+ endRemoveRows();
+ emit countChanged();
+ }
for (const auto &destroyer : toDestroy)
destroyer();
}
@@ -2113,7 +2252,7 @@ void QQmlListModel::insert(QQmlV4Function *args)
m_listModel->insert(index+i, argObject);
}
}
- emitItemsInserted(index, objectArrayLength);
+ emitItemsInserted();
} else if (argObject) {
emitItemsAboutToBeInserted(index, 1);
@@ -2123,7 +2262,7 @@ void QQmlListModel::insert(QQmlV4Function *args)
m_listModel->insert(index, argObject);
}
- emitItemsInserted(index, 1);
+ emitItemsInserted();
} else {
qmlWarning(this) << tr("insert: value is not an object");
}
@@ -2148,14 +2287,15 @@ void QQmlListModel::insert(QQmlV4Function *args)
*/
void QQmlListModel::move(int from, int to, int n)
{
- if (n==0 || from==to)
+ if (n == 0 || from == to)
return;
if (!canMove(from, to, n)) {
qmlWarning(this) << tr("move: out of range");
return;
}
- emitItemsAboutToBeMoved(from, to, n);
+ if (m_mainThread)
+ beginMoveRows(QModelIndex(), from, from + n - 1, QModelIndex(), to > from ? to + n : to);
if (m_dynamicRoles) {
@@ -2184,7 +2324,8 @@ void QQmlListModel::move(int from, int to, int n)
m_listModel->move(from, to, n);
}
- emitItemsMoved(from, to, n);
+ if (m_mainThread)
+ endMoveRows();
}
/*!
@@ -2224,7 +2365,7 @@ void QQmlListModel::append(QQmlV4Function *args)
}
}
- emitItemsInserted(index, objectArrayLength);
+ emitItemsInserted();
} else if (argObject) {
int index;
@@ -2238,7 +2379,7 @@ void QQmlListModel::append(QQmlV4Function *args)
m_listModel->append(argObject);
}
- emitItemsInserted(index, 1);
+ emitItemsInserted();
} else {
qmlWarning(this) << tr("append: value is not an object");
}
@@ -2292,8 +2433,7 @@ QQmlV4Handle QQmlListModel::get(int index) const
QObject *object = m_listModel->getOrCreateModelObject(const_cast<QQmlListModel *>(this), index);
result = scope.engine->memoryManager->allocObject<QV4::ModelObject>(object, const_cast<QQmlListModel *>(this), index);
// Keep track of the QObjectWrapper in persistent value storage
- QV4::Value *val = scope.engine->memoryManager->m_weakValues->allocate();
- *val = result;
+ QQmlData::get(object)->jsWrapper.set(scope.engine, result);
}
}
@@ -2340,7 +2480,7 @@ void QQmlListModel::set(int index, const QQmlV4Handle &handle)
m_listModel->insert(index, object);
}
- emitItemsInserted(index, 1);
+ emitItemsInserted();
} else {
QVector<int> roles;
@@ -2437,7 +2577,7 @@ bool QQmlListModelParser::verifyProperty(const QV4::CompiledData::Unit *qmlUnit,
}
} else if (binding->type == QV4::CompiledData::Binding::Type_Script) {
QString scriptStr = binding->valueAsScriptString(qmlUnit);
- if (!definesEmptyList(scriptStr)) {
+ if (!binding->isFunctionExpression() && !definesEmptyList(scriptStr)) {
QByteArray script = scriptStr.toUtf8();
bool ok;
evaluateEnum(script, &ok);
@@ -2451,7 +2591,7 @@ bool QQmlListModelParser::verifyProperty(const QV4::CompiledData::Unit *qmlUnit,
return true;
}
-bool QQmlListModelParser::applyProperty(const QV4::CompiledData::Unit *qmlUnit, const QV4::CompiledData::Binding *binding, ListModel *model, int outterElementIndex)
+bool QQmlListModelParser::applyProperty(QV4::CompiledData::CompilationUnit *compilationUnit, const QV4::CompiledData::Unit *qmlUnit, const QV4::CompiledData::Binding *binding, ListModel *model, int outterElementIndex)
{
const QString elementName = qmlUnit->stringAt(binding->propertyNameIndex);
@@ -2468,7 +2608,7 @@ bool QQmlListModelParser::applyProperty(const QV4::CompiledData::Unit *qmlUnit,
if (role.type == ListLayout::Role::List) {
subModel = model->getListProperty(outterElementIndex, role);
if (subModel == 0) {
- subModel = new ListModel(role.subLayout, 0, -1);
+ subModel = new ListModel(role.subLayout, 0);
QVariant vModel = QVariant::fromValue(subModel);
model->setOrCreateProperty(outterElementIndex, elementName, vModel);
}
@@ -2479,7 +2619,7 @@ bool QQmlListModelParser::applyProperty(const QV4::CompiledData::Unit *qmlUnit,
const QV4::CompiledData::Binding *subBinding = target->bindingTable();
for (quint32 i = 0; i < target->nBindings; ++i, ++subBinding) {
- roleSet |= applyProperty(qmlUnit, subBinding, subModel, elementIndex);
+ roleSet |= applyProperty(compilationUnit, qmlUnit, subBinding, subModel, elementIndex);
}
} else {
@@ -2495,8 +2635,23 @@ bool QQmlListModelParser::applyProperty(const QV4::CompiledData::Unit *qmlUnit,
QString scriptStr = binding->valueAsScriptString(qmlUnit);
if (definesEmptyList(scriptStr)) {
const ListLayout::Role &role = model->getOrCreateListRole(elementName);
- ListModel *emptyModel = new ListModel(role.subLayout, 0, -1);
+ ListModel *emptyModel = new ListModel(role.subLayout, 0);
value = QVariant::fromValue(emptyModel);
+ } else if (binding->isFunctionExpression()) {
+ QQmlBinding::Identifier id = binding->value.compiledScriptIndex;
+ Q_ASSERT(id != QQmlBinding::Invalid);
+
+ auto v4 = compilationUnit->engine;
+ QV4::Scope scope(v4);
+ // for now we do not provide a context object; data from the ListElement must be passed to the function
+ QV4::ScopedContext context(scope, QV4::QmlContext::create(v4->rootContext(), QQmlContextData::get(qmlContext(model->m_modelCache)), nullptr));
+ QV4::ScopedFunctionObject function(scope, QV4::FunctionObject::createScriptFunction(context, compilationUnit->runtimeFunctions[id]));
+
+ QV4::ReturnedValue result = function->call(v4->globalObject, nullptr, 0);
+
+ QJSValue v;
+ QJSValuePrivate::setValue(&v, v4, result);
+ value.setValue<QJSValue>(v);
} else {
QByteArray script = scriptStr.toUtf8();
bool ok;
@@ -2531,7 +2686,7 @@ void QQmlListModelParser::applyBindings(QObject *obj, QV4::CompiledData::Compila
{
QQmlListModel *rv = static_cast<QQmlListModel *>(obj);
- rv->m_engine = QV8Engine::getV4(qmlEngine(rv));
+ rv->m_engine = qmlEngine(rv)->handle();
const QV4::CompiledData::Unit *qmlUnit = compilationUnit->data;
@@ -2540,7 +2695,7 @@ void QQmlListModelParser::applyBindings(QObject *obj, QV4::CompiledData::Compila
for (const QV4::CompiledData::Binding *binding : bindings) {
if (binding->type != QV4::CompiledData::Binding::Type_Object)
continue;
- setRoles |= applyProperty(qmlUnit, binding, rv->m_listModel, /*outter element index*/-1);
+ setRoles |= applyProperty(compilationUnit, qmlUnit, binding, rv->m_listModel, /*outter element index*/-1);
}
if (setRoles == false)
@@ -2580,6 +2735,9 @@ bool QQmlListModelParser::definesEmptyList(const QString &s)
strings (quoted and optionally within a call to QT_TR_NOOP), boolean values
(true, false), numbers, or enumeration values (such as AlignText.AlignHCenter).
+ Beginning with Qt 5.11 ListElement also allows assigning a function declaration to
+ a role. This allows the definition of ListElements with callable actions.
+
\section1 Referencing Roles
The role names are used by delegates to obtain data from list elements.
diff --git a/src/qml/types/qqmllistmodel_p.h b/src/qml/types/qqmllistmodel_p.h
index 1fda703797..cbb12caa20 100644
--- a/src/qml/types/qqmllistmodel_p.h
+++ b/src/qml/types/qqmllistmodel_p.h
@@ -143,28 +143,22 @@ private:
QVector<class DynamicRoleModelNode *> m_modelObjects;
QVector<QString> m_roles;
- int m_uid;
struct ElementSync
{
- ElementSync() : src(0), target(0) {}
-
- DynamicRoleModelNode *src;
- DynamicRoleModelNode *target;
+ DynamicRoleModelNode *src = nullptr;
+ DynamicRoleModelNode *target = nullptr;
+ int srcIndex = -1;
+ int targetIndex = -1;
+ QVector<int> changedRoles;
};
- int getUid() const { return m_uid; }
-
- static void sync(QQmlListModel *src, QQmlListModel *target, QHash<int, QQmlListModel *> *targetModelHash);
+ static bool sync(QQmlListModel *src, QQmlListModel *target);
static QQmlListModel *createWithOwner(QQmlListModel *newOwner);
void emitItemsChanged(int index, int count, const QVector<int> &roles);
- void emitItemsAboutToBeRemoved(int index, int count);
- void emitItemsRemoved(int index, int count);
void emitItemsAboutToBeInserted(int index, int count);
- void emitItemsInserted(int index, int count);
- void emitItemsAboutToBeMoved(int from, int to, int n);
- void emitItemsMoved(int from, int to, int n);
+ void emitItemsInserted();
void removeElements(int index, int removeCount);
};
@@ -189,13 +183,13 @@ public:
QQmlListModelParser() : QQmlCustomParser(QQmlCustomParser::AcceptsSignalHandlers) {}
- void verifyBindings(const QV4::CompiledData::Unit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings) Q_DECL_OVERRIDE;
- void applyBindings(QObject *obj, QV4::CompiledData::CompilationUnit *compilationUnit, const QList<const QV4::CompiledData::Binding *> &bindings) Q_DECL_OVERRIDE;
+ void verifyBindings(const QV4::CompiledData::Unit *qmlUnit, const QList<const QV4::CompiledData::Binding *> &bindings) override;
+ void applyBindings(QObject *obj, QV4::CompiledData::CompilationUnit *compilationUnit, const QList<const QV4::CompiledData::Binding *> &bindings) override;
private:
bool verifyProperty(const QV4::CompiledData::Unit *qmlUnit, const QV4::CompiledData::Binding *binding);
// returns true if a role was set
- bool applyProperty(const QV4::CompiledData::Unit *qmlUnit, const QV4::CompiledData::Binding *binding, ListModel *model, int outterElementIndex);
+ bool applyProperty(QV4::CompiledData::CompilationUnit *compilationUnit, const QV4::CompiledData::Unit *qmlUnit, const QV4::CompiledData::Binding *binding, ListModel *model, int outterElementIndex);
static bool definesEmptyList(const QString &);
diff --git a/src/qml/types/qqmllistmodel_p_p.h b/src/qml/types/qqmllistmodel_p_p.h
index 10916f10db..81b9956ecb 100644
--- a/src/qml/types/qqmllistmodel_p_p.h
+++ b/src/qml/types/qqmllistmodel_p_p.h
@@ -108,7 +108,7 @@ public:
return m_uid;
}
- static void sync(DynamicRoleModelNode *src, DynamicRoleModelNode *target, QHash<int, QQmlListModel *> *targetModelHash);
+ static QVector<int> sync(DynamicRoleModelNode *src, DynamicRoleModelNode *target);
private:
QQmlListModel *m_owner;
@@ -179,7 +179,7 @@ struct ModelObject : public QObjectWrapper {
struct ModelObject : public QObjectWrapper
{
- static void put(Managed *m, String *name, const Value& value);
+ static bool put(Managed *m, String *name, const Value& value);
static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
@@ -216,6 +216,7 @@ public:
QObject,
VariantMap,
DateTime,
+ Function,
MaxDataType
};
@@ -260,7 +261,7 @@ public:
ListElement(int existingUid);
~ListElement();
- static void sync(ListElement *src, ListLayout *srcLayout, ListElement *target, ListLayout *targetLayout, QHash<int, ListModel *> *targetModelHash);
+ static QVector<int> sync(ListElement *src, ListLayout *srcLayout, ListElement *target, ListLayout *targetLayout);
enum
{
@@ -283,6 +284,7 @@ private:
int setVariantMapProperty(const ListLayout::Role &role, QV4::Object *o);
int setVariantMapProperty(const ListLayout::Role &role, QVariantMap *m);
int setDateTimeProperty(const ListLayout::Role &role, const QDateTime &dt);
+ int setFunctionProperty(const ListLayout::Role &role, const QJSValue &f);
void setStringPropertyFast(const ListLayout::Role &role, const QString &s);
void setDoublePropertyFast(const ListLayout::Role &role, double n);
@@ -291,6 +293,7 @@ private:
void setListPropertyFast(const ListLayout::Role &role, ListModel *m);
void setVariantMapFast(const ListLayout::Role &role, QV4::Object *o);
void setDateTimePropertyFast(const ListLayout::Role &role, const QDateTime &dt);
+ void setFunctionPropertyFast(const ListLayout::Role &role, const QJSValue &f);
void clearProperty(const ListLayout::Role &role);
@@ -301,6 +304,7 @@ private:
QPointer<QObject> *getGuardProperty(const ListLayout::Role &role);
QVariantMap *getVariantMapProperty(const ListLayout::Role &role);
QDateTime *getDateTimeProperty(const ListLayout::Role &role);
+ QJSValue *getFunctionProperty(const ListLayout::Role &role);
inline char *getPropertyMemory(const ListLayout::Role &role);
@@ -324,7 +328,7 @@ class ListModel
{
public:
- ListModel(ListLayout *layout, QQmlListModel *modelCache, int uid);
+ ListModel(ListLayout *layout, QQmlListModel *modelCache);
~ListModel() {}
void destroy();
@@ -373,33 +377,32 @@ public:
void move(int from, int to, int n);
- int getUid() const { return m_uid; }
-
- static void sync(ListModel *src, ListModel *target, QHash<int, ListModel *> *srcModelHash);
+ static bool sync(ListModel *src, ListModel *target);
QObject *getOrCreateModelObject(QQmlListModel *model, int elementIndex);
private:
QPODVector<ListElement *, 4> elements;
ListLayout *m_layout;
- int m_uid;
QQmlListModel *m_modelCache;
struct ElementSync
{
- ElementSync() : src(0), target(0) {}
-
- ListElement *src;
- ListElement *target;
+ ListElement *src = nullptr;
+ ListElement *target = nullptr;
+ int srcIndex = -1;
+ int targetIndex = -1;
+ QVector<int> changedRoles;
};
void newElement(int index);
- void updateCacheIndices();
+ void updateCacheIndices(int start = 0, int end = -1);
friend class ListElement;
friend class QQmlListModelWorkerAgent;
+ friend class QQmlListModelParser;
};
QT_END_NAMESPACE
diff --git a/src/qml/types/qqmllistmodelworkeragent.cpp b/src/qml/types/qqmllistmodelworkeragent.cpp
index 0a5adbf292..a2750c926a 100644
--- a/src/qml/types/qqmllistmodelworkeragent.cpp
+++ b/src/qml/types/qqmllistmodelworkeragent.cpp
@@ -50,39 +50,8 @@
QT_BEGIN_NAMESPACE
-
-void QQmlListModelWorkerAgent::Data::clearChange(int uid)
-{
- for (int i=0 ; i < changes.count() ; ++i) {
- if (changes[i].modelUid == uid) {
- changes.removeAt(i);
- --i;
- }
- }
-}
-
-void QQmlListModelWorkerAgent::Data::insertChange(int uid, int index, int count)
+QQmlListModelWorkerAgent::Sync::~Sync()
{
- Change c = { uid, Change::Inserted, index, count, 0, QVector<int>() };
- changes << c;
-}
-
-void QQmlListModelWorkerAgent::Data::removeChange(int uid, int index, int count)
-{
- Change c = { uid, Change::Removed, index, count, 0, QVector<int>() };
- changes << c;
-}
-
-void QQmlListModelWorkerAgent::Data::moveChange(int uid, int index, int count, int to)
-{
- Change c = { uid, Change::Moved, index, count, to, QVector<int>() };
- changes << c;
-}
-
-void QQmlListModelWorkerAgent::Data::changedChange(int uid, int index, int count, const QVector<int> &roles)
-{
- Change c = { uid, Change::Changed, index, count, 0, roles };
- changes << c;
}
QQmlListModelWorkerAgent::QQmlListModelWorkerAgent(QQmlListModel *model)
@@ -167,8 +136,7 @@ void QQmlListModelWorkerAgent::move(int from, int to, int count)
void QQmlListModelWorkerAgent::sync()
{
- Sync *s = new Sync(data, m_copy);
- data.changes.clear();
+ Sync *s = new Sync(m_copy);
mutex.lock();
QCoreApplication::postEvent(this, s);
@@ -183,61 +151,14 @@ bool QQmlListModelWorkerAgent::event(QEvent *e)
QMutexLocker locker(&mutex);
if (m_orig) {
Sync *s = static_cast<Sync *>(e);
- const QList<Change> &changes = s->data.changes;
- cc = m_orig->count() != s->list->count();
-
- QHash<int, QQmlListModel *> targetModelDynamicHash;
- QHash<int, ListModel *> targetModelStaticHash;
+ cc = (m_orig->count() != s->list->count());
Q_ASSERT(m_orig->m_dynamicRoles == s->list->m_dynamicRoles);
if (m_orig->m_dynamicRoles)
- QQmlListModel::sync(s->list, m_orig, &targetModelDynamicHash);
+ QQmlListModel::sync(s->list, m_orig);
else
- ListModel::sync(s->list->m_listModel, m_orig->m_listModel, &targetModelStaticHash);
-
- for (int ii = 0; ii < changes.count(); ++ii) {
- const Change &change = changes.at(ii);
-
- QQmlListModel *model = 0;
- if (m_orig->m_dynamicRoles) {
- model = targetModelDynamicHash.value(change.modelUid);
- } else {
- ListModel *lm = targetModelStaticHash.value(change.modelUid);
- if (lm)
- model = lm->m_modelCache;
- }
-
- if (model) {
- switch (change.type) {
- case Change::Inserted:
- model->beginInsertRows(
- QModelIndex(), change.index, change.index + change.count - 1);
- model->endInsertRows();
- break;
- case Change::Removed:
- model->beginRemoveRows(
- QModelIndex(), change.index, change.index + change.count - 1);
- model->endRemoveRows();
- break;
- case Change::Moved:
- model->beginMoveRows(
- QModelIndex(),
- change.index,
- change.index + change.count - 1,
- QModelIndex(),
- change.to > change.index ? change.to + change.count : change.to);
- model->endMoveRows();
- break;
- case Change::Changed:
- emit model->dataChanged(
- model->createIndex(change.index, 0),
- model->createIndex(change.index + change.count - 1, 0),
- change.roles);
- break;
- }
- }
- }
+ ListModel::sync(s->list->m_listModel, m_orig->m_listModel);
}
syncDone.wakeAll();
diff --git a/src/qml/types/qqmllistmodelworkeragent_p.h b/src/qml/types/qqmllistmodelworkeragent_p.h
index 5a39651bf7..761a467e89 100644
--- a/src/qml/types/qqmllistmodelworkeragent_p.h
+++ b/src/qml/types/qqmllistmodelworkeragent_p.h
@@ -114,35 +114,12 @@ private:
friend class QQuickWorkerScriptEnginePrivate;
friend class QQmlListModel;
- struct Change
- {
- int modelUid;
- enum { Inserted, Removed, Moved, Changed } type;
- int index; // Inserted/Removed/Moved/Changed
- int count; // Inserted/Removed/Moved/Changed
- int to; // Moved
- QVector<int> roles;
- };
-
- struct Data
- {
- QList<Change> changes;
-
- void clearChange(int uid);
- void insertChange(int uid, int index, int count);
- void removeChange(int uid, int index, int count);
- void moveChange(int uid, int index, int count, int to);
- void changedChange(int uid, int index, int count, const QVector<int> &roles);
- };
- Data data;
-
struct Sync : public QEvent {
- Sync(const Data &d, QQmlListModel *l)
+ Sync(QQmlListModel *l)
: QEvent(QEvent::User)
- , data(d)
, list(l)
{}
- Data data;
+ ~Sync();
QQmlListModel *list;
};
diff --git a/src/qml/types/qquickpackage.cpp b/src/qml/types/qquickpackage.cpp
index 7fb14a95f6..e0d1888f33 100644
--- a/src/qml/types/qquickpackage.cpp
+++ b/src/qml/types/qquickpackage.cpp
@@ -89,7 +89,7 @@ public:
{
DataGuard(QObject *obj, QList<DataGuard> *l) : list(l) { (QQmlGuard<QObject>&)*this = obj; }
QList<DataGuard> *list;
- void objectDestroyed(QObject *) {
+ void objectDestroyed(QObject *) override {
// we assume priv will always be destroyed after objectDestroyed calls
list->removeOne(*this);
}
diff --git a/src/qml/types/qquickworkerscript.cpp b/src/qml/types/qquickworkerscript.cpp
index 6159355afc..32c0c86ff6 100644
--- a/src/qml/types/qquickworkerscript.cpp
+++ b/src/qml/types/qquickworkerscript.cpp
@@ -65,6 +65,7 @@
#include <private/qv4functionobject_p.h>
#include <private/qv4script_p.h>
#include <private/qv4scopedvalue_p.h>
+#include <private/qv4jscall_p.h>
QT_BEGIN_NAMESPACE
@@ -185,7 +186,7 @@ public:
int m_nextId;
- static void method_sendMessage(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static QV4::ReturnedValue method_sendMessage(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
signals:
void stopThread();
@@ -200,7 +201,7 @@ private:
};
QQuickWorkerScriptEnginePrivate::WorkerEngine::WorkerEngine(QQuickWorkerScriptEnginePrivate *parent)
-: QV8Engine(0), p(parent)
+ : QV8Engine(nullptr, new QV4::ExecutionEngine), p(parent)
#if QT_CONFIG(qml_network)
, accessManager(0)
#endif
@@ -213,6 +214,7 @@ QQuickWorkerScriptEnginePrivate::WorkerEngine::~WorkerEngine()
#if QT_CONFIG(qml_network)
delete accessManager;
#endif
+ delete m_v4Engine;
}
void QQuickWorkerScriptEnginePrivate::WorkerEngine::init()
@@ -239,19 +241,18 @@ void QQuickWorkerScriptEnginePrivate::WorkerEngine::init()
QV4::Scope scope(m_v4Engine);
QV4::ExecutionContext *globalContext = scope.engine->rootContext();
- onmessage.set(scope.engine, QV4::Script(globalContext, QString::fromUtf8(CALL_ONMESSAGE_SCRIPT)).run()); // do not use QStringLiteral here, MSVC2012 cannot apply this cleanly to the macro
+ onmessage.set(scope.engine, QV4::Script(globalContext, QV4::Compiler::GlobalCode, QString::fromUtf8(CALL_ONMESSAGE_SCRIPT)).run()); // do not use QStringLiteral here, MSVC2012 cannot apply this cleanly to the macro
Q_ASSERT(!scope.engine->hasException);
- QV4::Script createsendscript(globalContext, QString::fromUtf8(SEND_MESSAGE_CREATE_SCRIPT)); // do not use QStringLiteral here, MSVC2012 cannot apply this cleanly to the macro
+ QV4::Script createsendscript(globalContext, QV4::Compiler::GlobalCode, QString::fromUtf8(SEND_MESSAGE_CREATE_SCRIPT)); // do not use QStringLiteral here, MSVC2012 cannot apply this cleanly to the macro
QV4::ScopedFunctionObject createsendconstructor(scope, createsendscript.run());
Q_ASSERT(!scope.engine->hasException);
QV4::ScopedString name(scope, m_v4Engine->newString(QStringLiteral("sendMessage")));
- QV4::ScopedValue function(scope, QV4::BuiltinFunction::create(globalContext, name,
- QQuickWorkerScriptEnginePrivate::method_sendMessage));
- QV4::ScopedCallData callData(scope, 1);
- callData->args[0] = function;
- callData->thisObject = global();
- createsendconstructor->call(scope, callData);
- createsend.set(scope.engine, scope.result.asReturnedValue());
+ QV4::ScopedValue function(scope, QV4::FunctionObject::createBuiltinFunction(globalContext, name,
+ QQuickWorkerScriptEnginePrivate::method_sendMessage));
+ QV4::JSCallData jsCallData(scope, 1);
+ jsCallData->args[0] = function;
+ *jsCallData->thisObject = m_v4Engine->global();
+ createsend.set(scope.engine, createsendconstructor->call(jsCallData));
}
// Requires handle and context scope
@@ -264,13 +265,14 @@ QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::WorkerEngine::sendFunction(i
QV4::Scope scope(v4);
QV4::ScopedFunctionObject f(scope, createsend.value());
- QV4::ScopedCallData callData(scope, 1);
- callData->args[0] = QV4::Primitive::fromInt32(id);
- callData->thisObject = global();
- f->call(scope, callData);
+ QV4::ScopedValue v(scope);
+ QV4::JSCallData jsCallData(scope, 1);
+ jsCallData->args[0] = QV4::Primitive::fromInt32(id);
+ *jsCallData->thisObject = m_v4Engine->global();
+ v = f->call(jsCallData);
if (scope.hasException())
- scope.result = scope.engine->catchException();
- return scope.result.asReturnedValue();
+ v = scope.engine->catchException();
+ return v->asReturnedValue();
}
#if QT_CONFIG(qml_network)
@@ -292,13 +294,15 @@ QQuickWorkerScriptEnginePrivate::QQuickWorkerScriptEnginePrivate(QQmlEngine *eng
{
}
-void QQuickWorkerScriptEnginePrivate::method_sendMessage(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::method_sendMessage(const QV4::FunctionObject *b,
+ const QV4::Value *, const QV4::Value *argv, int argc)
{
- WorkerEngine *engine = (WorkerEngine*)scope.engine->v8Engine;
+ QV4::Scope scope(b);
+ WorkerEngine *engine = static_cast<WorkerEngine *>(scope.engine->v8Engine);
- int id = callData->argc > 1 ? callData->args[1].toInt32() : 0;
+ int id = argc > 1 ? argv[1].toInt32() : 0;
- QV4::ScopedValue v(scope, callData->argument(2));
+ QV4::ScopedValue v(scope, argc > 2 ? argv[2] : QV4::Primitive::undefinedValue());
QByteArray data = QV4::Serialize::serialize(v, scope.engine);
QMutexLocker locker(&engine->p->m_lock);
@@ -306,7 +310,7 @@ void QQuickWorkerScriptEnginePrivate::method_sendMessage(const QV4::BuiltinFunct
if (script && script->owner)
QCoreApplication::postEvent(script->owner, new WorkerDataEvent(0, data));
- scope.result = QV4::Encode::undefined();
+ return QV4::Encode::undefined();
}
QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::getWorker(WorkerScript *script)
@@ -363,11 +367,11 @@ void QQuickWorkerScriptEnginePrivate::processMessage(int id, const QByteArray &d
QV4::Scoped<QV4::QmlContext> qmlContext(scope, script->qmlContext.value());
Q_ASSERT(!!qmlContext);
- QV4::ScopedCallData callData(scope, 2);
- callData->thisObject = workerEngine->global();
- callData->args[0] = qmlContext->d()->qml; // ###
- callData->args[1] = value;
- f->call(scope, callData);
+ QV4::JSCallData jsCallData(scope, 2);
+ *jsCallData->thisObject = v4->global();
+ jsCallData->args[0] = qmlContext->d()->qml(); // ###
+ jsCallData->args[1] = value;
+ f->call(jsCallData);
if (scope.hasException()) {
QQmlError error = scope.engine->catchExceptionAsQmlError();
reportScriptException(script, error);
@@ -393,22 +397,10 @@ void QQuickWorkerScriptEnginePrivate::processLoad(int id, const QUrl &url)
QV4::Scoped<QV4::QmlContext> qmlContext(scope, getWorker(script));
Q_ASSERT(!!qmlContext);
- if (const QQmlPrivate::CachedQmlUnit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(url)) {
- QV4::CompiledData::CompilationUnit *jsUnit = cachedUnit->createCompilationUnit();
- program.reset(new QV4::Script(v4, qmlContext, jsUnit));
- } else {
- QFile f(fileName);
- if (!f.open(QIODevice::ReadOnly)) {
- qWarning().nospace() << "WorkerScript: Cannot find source file " << url.toString();
- return;
- }
-
- QByteArray data = f.readAll();
- QString sourceCode = QString::fromUtf8(data);
- QmlIR::Document::removeScriptPragmas(sourceCode);
-
- program.reset(new QV4::Script(v4, qmlContext, sourceCode, url.toString()));
- program->parse();
+ program.reset(QV4::Script::createFromFileOrCache(v4, qmlContext, fileName, url));
+ if (program.isNull()) {
+ qWarning().nospace() << "WorkerScript: Cannot find source file " << url.toString();
+ return;
}
if (!v4->hasException)
@@ -739,8 +731,7 @@ bool QQuickWorkerScript::event(QEvent *event)
QQmlEngine *engine = qmlEngine(this);
if (engine) {
WorkerDataEvent *workerEvent = static_cast<WorkerDataEvent *>(event);
- QV8Engine *v8engine = QQmlEnginePrivate::get(engine)->v8engine();
- QV4::Scope scope(QV8Engine::getV4(v8engine));
+ QV4::Scope scope(engine->handle());
QV4::ScopedValue value(scope, QV4::Serialize::deserialize(workerEvent->data(), scope.engine));
emit message(QQmlV4Handle(value));
}
diff --git a/src/qml/types/qquickworkerscript_p.h b/src/qml/types/qquickworkerscript_p.h
index dce3acc3e1..8ea630c685 100644
--- a/src/qml/types/qquickworkerscript_p.h
+++ b/src/qml/types/qquickworkerscript_p.h
@@ -51,7 +51,7 @@
// We mean it.
//
-#include "qqml.h"
+#include <qqml.h>
#include <QtQml/qqmlparserstatus.h>
#include <QtCore/qthread.h>
diff --git a/src/qml/util/qqmladaptormodel.cpp b/src/qml/util/qqmladaptormodel.cpp
index 927f740935..7afafec1fe 100644
--- a/src/qml/util/qqmladaptormodel.cpp
+++ b/src/qml/util/qqmladaptormodel.cpp
@@ -61,9 +61,10 @@ public:
V4_DEFINE_EXTENSION(QQmlAdaptorModelEngineData, engineData)
-static void get_index(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+static QV4::ReturnedValue get_index(const QV4::FunctionObject *f, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>());
+ QV4::Scope scope(f);
+ QV4::Scoped<QQmlDelegateModelItemObject> o(scope, thisObject->as<QQmlDelegateModelItemObject>());
if (!o)
RETURN_RESULT(scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object")));
@@ -102,11 +103,11 @@ public:
virtual QVariant value(int role) const = 0;
virtual void setValue(int role, const QVariant &value) = 0;
- void setValue(const QString &role, const QVariant &value);
- bool resolveIndex(const QQmlAdaptorModel &model, int idx);
+ void setValue(const QString &role, const QVariant &value) override;
+ bool resolveIndex(const QQmlAdaptorModel &model, int idx) override;
- static QV4::ReturnedValue get_property(QV4::CallContext *ctx, uint propertyId);
- static QV4::ReturnedValue set_property(QV4::CallContext *ctx, uint propertyId);
+ static QV4::ReturnedValue get_property(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue set_property(const QV4::FunctionObject *, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
VDMModelDelegateDataType *type;
QVector<QVariant> cachedData;
@@ -140,7 +141,7 @@ public:
const QList<QQmlDelegateModelItem *> &items,
int index,
int count,
- const QVector<int> &roles) const
+ const QVector<int> &roles) const override
{
bool changed = roles.isEmpty() && !watchedRoles.isEmpty();
if (!changed && !watchedRoles.isEmpty() && watchedRoleIds.isEmpty()) {
@@ -184,7 +185,7 @@ public:
void replaceWatchedRoles(
QQmlAdaptorModel &,
const QList<QByteArray> &oldRoles,
- const QList<QByteArray> &newRoles) const
+ const QList<QByteArray> &newRoles) const override
{
VDMModelDelegateDataType *dataType = const_cast<VDMModelDelegateDataType *>(this);
@@ -194,9 +195,10 @@ public:
dataType->watchedRoles += newRoles;
}
- static void get_hasModelChildren(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ static QV4::ReturnedValue get_hasModelChildren(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQmlDelegateModelItemObject> o(scope, thisObject->as<QQmlDelegateModelItemObject>());
if (!o)
RETURN_RESULT(scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object")));
@@ -237,12 +239,12 @@ public:
// QAbstractDynamicMetaObject
- void objectDestroyed(QObject *)
+ void objectDestroyed(QObject *) override
{
release();
}
- int metaCall(QObject *object, QMetaObject::Call call, int id, void **arguments)
+ int metaCall(QObject *object, QMetaObject::Call call, int id, void **arguments) override
{
return static_cast<QQmlDMCachedModelData *>(object)->metaCall(call, id, arguments);
}
@@ -341,12 +343,14 @@ bool QQmlDMCachedModelData::resolveIndex(const QQmlAdaptorModel &, int idx)
}
}
-QV4::ReturnedValue QQmlDMCachedModelData::get_property(QV4::CallContext *ctx, uint propertyId)
+QV4::ReturnedValue QQmlDMCachedModelData::get_property(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, ctx->thisObject().as<QQmlDelegateModelItemObject>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQmlDelegateModelItemObject> o(scope, thisObject->as<QQmlDelegateModelItemObject>());
if (!o)
- return ctx->engine()->throwTypeError(QStringLiteral("Not a valid VisualData object"));
+ return scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object"));
+
+ uint propertyId = static_cast<const QV4::IndexedBuiltinFunction *>(b)->d()->index;
QQmlDMCachedModelData *modelData = static_cast<QQmlDMCachedModelData *>(o->d()->item);
if (o->d()->item->index == -1) {
@@ -361,23 +365,25 @@ QV4::ReturnedValue QQmlDMCachedModelData::get_property(QV4::CallContext *ctx, ui
return QV4::Encode::undefined();
}
-QV4::ReturnedValue QQmlDMCachedModelData::set_property(QV4::CallContext *ctx, uint propertyId)
+QV4::ReturnedValue QQmlDMCachedModelData::set_property(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, ctx->thisObject().as<QQmlDelegateModelItemObject>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQmlDelegateModelItemObject> o(scope, thisObject->as<QQmlDelegateModelItemObject>());
if (!o)
- return ctx->engine()->throwTypeError(QStringLiteral("Not a valid VisualData object"));
- if (!ctx->argc())
- return ctx->engine()->throwTypeError();
+ return scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object"));
+ if (!argc)
+ return scope.engine->throwTypeError();
+
+ uint propertyId = static_cast<const QV4::IndexedBuiltinFunction *>(b)->d()->index;
if (o->d()->item->index == -1) {
QQmlDMCachedModelData *modelData = static_cast<QQmlDMCachedModelData *>(o->d()->item);
if (!modelData->cachedData.isEmpty()) {
if (modelData->cachedData.count() > 1) {
- modelData->cachedData[propertyId] = scope.engine->toVariant(ctx->args()[0], QVariant::Invalid);
+ modelData->cachedData[propertyId] = scope.engine->toVariant(argv[0], QVariant::Invalid);
QMetaObject::activate(o->d()->item, o->d()->item->metaObject(), propertyId, 0);
} else if (modelData->cachedData.count() == 1) {
- modelData->cachedData[0] = scope.engine->toVariant(ctx->args()[0], QVariant::Invalid);
+ modelData->cachedData[0] = scope.engine->toVariant(argv[0], QVariant::Invalid);
QMetaObject::activate(o->d()->item, o->d()->item->metaObject(), 0, 0);
QMetaObject::activate(o->d()->item, o->d()->item->metaObject(), 1, 0);
}
@@ -413,18 +419,18 @@ public:
}
}
- QVariant value(int role) const
+ QVariant value(int role) const override
{
return type->model->aim()->index(index, 0, type->model->rootIndex).data(role);
}
- void setValue(int role, const QVariant &value)
+ void setValue(int role, const QVariant &value) override
{
type->model->aim()->setData(
type->model->aim()->index(index, 0, type->model->rootIndex), value, role);
}
- QV4::ReturnedValue get()
+ QV4::ReturnedValue get() override
{
if (type->prototype.isUndefined()) {
QQmlAdaptorModelEngineData * const data = engineData(v4);
@@ -515,7 +521,7 @@ public:
QQmlDelegateModelItem *createItem(
QQmlAdaptorModel &model,
QQmlDelegateModelItemMetaType *metaType,
- int index) const Q_DECL_OVERRIDE
+ int index) const override
{
VDMAbstractItemModelDataType *dataType = const_cast<VDMAbstractItemModelDataType *>(this);
if (!metaObject)
@@ -580,28 +586,30 @@ public:
}
}
- static void get_modelData(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ static QV4::ReturnedValue get_modelData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>());
+ QV4::ExecutionEngine *v4 = b->engine();
+ const QQmlDelegateModelItemObject *o = thisObject->as<QQmlDelegateModelItemObject>();
if (!o)
- RETURN_RESULT(scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object")));
+ return v4->throwTypeError(QStringLiteral("Not a valid VisualData object"));
- RETURN_RESULT(scope.engine->fromVariant(static_cast<QQmlDMListAccessorData *>(o->d()->item)->cachedData));
+ return v4->fromVariant(static_cast<QQmlDMListAccessorData *>(o->d()->item)->cachedData);
}
- static void set_modelData(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+ static QV4::ReturnedValue set_modelData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>());
+ QV4::ExecutionEngine *v4 = b->engine();
+ const QQmlDelegateModelItemObject *o = thisObject->as<QQmlDelegateModelItemObject>();
if (!o)
- RETURN_RESULT(scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object")));
- if (!callData->argc)
- RETURN_RESULT(scope.engine->throwTypeError());
+ return v4->throwTypeError(QStringLiteral("Not a valid VisualData object"));
+ if (!argc)
+ return v4->throwTypeError();
- static_cast<QQmlDMListAccessorData *>(o->d()->item)->setModelData(scope.engine->toVariant(callData->args[0], QVariant::Invalid));
- RETURN_RESULT(QV4::Encode::undefined());
+ static_cast<QQmlDMListAccessorData *>(o->d()->item)->setModelData(v4->toVariant(argv[0], QVariant::Invalid));
+ return QV4::Encode::undefined();
}
- QV4::ReturnedValue get()
+ QV4::ReturnedValue get() override
{
QQmlAdaptorModelEngineData *data = engineData(v4);
QV4::Scope scope(v4);
@@ -612,13 +620,13 @@ public:
return o.asReturnedValue();
}
- void setValue(const QString &role, const QVariant &value)
+ void setValue(const QString &role, const QVariant &value) override
{
if (role == QLatin1String("modelData"))
cachedData = value;
}
- bool resolveIndex(const QQmlAdaptorModel &model, int idx)
+ bool resolveIndex(const QQmlAdaptorModel &model, int idx) override
{
if (index == -1) {
index = idx;
@@ -660,7 +668,7 @@ public:
QQmlDelegateModelItem *createItem(
QQmlAdaptorModel &model,
QQmlDelegateModelItemMetaType *metaType,
- int index) const Q_DECL_OVERRIDE
+ int index) const override
{
return new QQmlDMListAccessorData(
metaType,
@@ -687,7 +695,7 @@ public:
QObject *object);
QObject *modelData() const { return object; }
- QObject *proxiedObject() { return object; }
+ QObject *proxiedObject() override { return object; }
QPointer<QObject> object;
};
@@ -744,7 +752,7 @@ public:
QQmlDelegateModelItem *createItem(
QQmlAdaptorModel &model,
QQmlDelegateModelItemMetaType *metaType,
- int index) const Q_DECL_OVERRIDE
+ int index) const override
{
VDMObjectDelegateDataType *dataType = const_cast<VDMObjectDelegateDataType *>(this);
if (!metaObject)
@@ -785,7 +793,7 @@ public:
m_type->release();
}
- int metaCall(QObject *o, QMetaObject::Call call, int id, void **arguments)
+ int metaCall(QObject *o, QMetaObject::Call call, int id, void **arguments) override
{
Q_ASSERT(o == m_data);
Q_UNUSED(o);
@@ -806,7 +814,7 @@ public:
}
}
- int createProperty(const char *name, const char *)
+ int createProperty(const char *name, const char *) override
{
if (!m_data->object)
return -1;
diff --git a/src/qml/util/qqmlpropertymap.cpp b/src/qml/util/qqmlpropertymap.cpp
index 6e6554f2c3..578c05086f 100644
--- a/src/qml/util/qqmlpropertymap.cpp
+++ b/src/qml/util/qqmlpropertymap.cpp
@@ -186,9 +186,8 @@ int QQmlPropertyMapMetaObject::createProperty(const char *name, const char *valu
Constructs a bindable map with parent object \a parent.
*/
QQmlPropertyMap::QQmlPropertyMap(QObject *parent)
-: QObject(*allocatePrivate(), parent)
+: QQmlPropertyMap(&staticMetaObject, parent)
{
- init(metaObject());
}
/*!
@@ -339,18 +338,13 @@ QVariant QQmlPropertyMap::updateValue(const QString &key, const QVariant &input)
}
/*! \internal */
-void QQmlPropertyMap::init(const QMetaObject *staticMetaObject)
+QQmlPropertyMap::QQmlPropertyMap(const QMetaObject *staticMetaObject, QObject *parent)
+ : QObject(*(new QQmlPropertyMapPrivate), parent)
{
Q_D(QQmlPropertyMap);
d->mo = new QQmlPropertyMapMetaObject(this, d, staticMetaObject);
}
-/*! \internal */
-QObjectPrivate *QQmlPropertyMap::allocatePrivate()
-{
- return new QQmlPropertyMapPrivate;
-}
-
/*!
\fn void QQmlPropertyMap::valueChanged(const QString &key, const QVariant &value)
This signal is emitted whenever one of the values in the map is changed. \a key
@@ -361,7 +355,7 @@ QObjectPrivate *QQmlPropertyMap::allocatePrivate()
*/
/*!
- \fn QQmlPropertyMap::QQmlPropertyMap(DerivedType *derived, QObject *parent)
+ \fn template<class DerivedType> QQmlPropertyMap::QQmlPropertyMap(DerivedType *derived, QObject *parent)
Constructs a bindable map with parent object \a parent. Use this constructor
in classes derived from QQmlPropertyMap.
diff --git a/src/qml/util/qqmlpropertymap.h b/src/qml/util/qqmlpropertymap.h
index 01048f3662..3930ac00a8 100644
--- a/src/qml/util/qqmlpropertymap.h
+++ b/src/qml/util/qqmlpropertymap.h
@@ -55,7 +55,7 @@ class Q_QML_EXPORT QQmlPropertyMap : public QObject
{
Q_OBJECT
public:
- explicit QQmlPropertyMap(QObject *parent = Q_NULLPTR);
+ explicit QQmlPropertyMap(QObject *parent = nullptr);
virtual ~QQmlPropertyMap();
QVariant value(const QString &key) const;
@@ -80,15 +80,13 @@ protected:
template<class DerivedType>
QQmlPropertyMap(DerivedType *derived, QObject *parentObj)
- : QObject(*allocatePrivate(), parentObj)
+ : QQmlPropertyMap(&DerivedType::staticMetaObject, parentObj)
{
Q_UNUSED(derived)
- init(&DerivedType::staticMetaObject);
}
private:
- void init(const QMetaObject *staticMetaObject);
- static QObjectPrivate *allocatePrivate();
+ QQmlPropertyMap(const QMetaObject *staticMetaObject, QObject *parent);
Q_DECLARE_PRIVATE(QQmlPropertyMap)
Q_DISABLE_COPY(QQmlPropertyMap)
diff --git a/src/qmldebug/qmldebug.pro b/src/qmldebug/qmldebug.pro
index e5f6de3314..2539414d8f 100644
--- a/src/qmldebug/qmldebug.pro
+++ b/src/qmldebug/qmldebug.pro
@@ -7,15 +7,25 @@ load(qt_module)
SOURCES += \
qqmldebugclient.cpp \
qqmldebugconnection.cpp \
+ qqmldebugmessageclient.cpp \
qqmlenginecontrolclient.cpp \
- qqmlprofilerclient.cpp
+ qqmlprofilerclient.cpp \
+ qqmlprofilerevent.cpp \
+ qqmlprofilereventlocation.cpp \
+ qqmlprofilereventtype.cpp \
+ qqmlprofilertypedevent.cpp
HEADERS += \
qqmldebugclient_p.h \
qqmldebugclient_p_p.h \
qqmldebugconnection_p.h \
+ qqmldebugmessageclient_p.h \
qqmlenginecontrolclient_p.h \
qqmlenginecontrolclient_p_p.h \
- qqmleventlocation_p.h \
qqmlprofilerclient_p.h \
- qqmlprofilerclient_p_p.h
+ qqmlprofilerclient_p_p.h \
+ qqmlprofilerevent_p.h \
+ qqmlprofilereventlocation_p.h \
+ qqmlprofilereventreceiver_p.h \
+ qqmlprofilereventtype_p.h \
+ qqmlprofilertypedevent_p.h
diff --git a/src/qmldebug/qqmldebugmessageclient.cpp b/src/qmldebug/qqmldebugmessageclient.cpp
new file mode 100644
index 0000000000..a03c1f8af2
--- /dev/null
+++ b/src/qmldebug/qqmldebugmessageclient.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmldebugmessageclient_p.h"
+
+#include <QtCore/qdatastream.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QQmlDebugMessageClient
+ \internal
+
+ \brief Client for the debug message service
+
+ The QQmlDebugMessageClient receives debug messages routed through the QML
+ debug connection via QDebugMessageService.
+ */
+
+QQmlDebugMessageClient::QQmlDebugMessageClient(QQmlDebugConnection *client)
+ : QQmlDebugClient(QLatin1String("DebugMessages"), client)
+{
+}
+
+void QQmlDebugMessageClient::stateChanged(State state)
+{
+ emit newState(state);
+}
+
+void QQmlDebugMessageClient::messageReceived(const QByteArray &data)
+{
+ QDataStream ds(data);
+ QByteArray command;
+ ds >> command;
+
+ if (command == "MESSAGE") {
+ int type;
+ int line;
+ QByteArray debugMessage;
+ QByteArray file;
+ QByteArray function;
+ ds >> type >> debugMessage >> file >> line >> function;
+ QQmlDebugContextInfo info;
+ info.line = line;
+ info.file = QString::fromUtf8(file);
+ info.function = QString::fromUtf8(function);
+ info.timestamp = -1;
+ if (!ds.atEnd()) {
+ QByteArray category;
+ ds >> category;
+ info.category = QString::fromUtf8(category);
+ if (!ds.atEnd())
+ ds >> info.timestamp;
+ }
+ emit message(QtMsgType(type), QString::fromUtf8(debugMessage), info);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/qmldebug/qqmldebugmessageclient_p.h b/src/qmldebug/qqmldebugmessageclient_p.h
new file mode 100644
index 0000000000..75c70044e4
--- /dev/null
+++ b/src/qmldebug/qqmldebugmessageclient_p.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLDEBUGMESSAGECLIENT_P_H
+#define QQMLDEBUGMESSAGECLIENT_P_H
+
+#include "qqmldebugclient_p.h"
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+struct QQmlDebugContextInfo
+{
+ int line;
+ QString file;
+ QString function;
+ QString category;
+ qint64 timestamp;
+};
+
+class QQmlDebugMessageClient : public QQmlDebugClient
+{
+ Q_OBJECT
+
+public:
+ explicit QQmlDebugMessageClient(QQmlDebugConnection *client);
+
+ virtual void stateChanged(State state) override;
+ virtual void messageReceived(const QByteArray &) override;
+
+signals:
+ void newState(QQmlDebugClient::State);
+ void message(QtMsgType, const QString &, const QQmlDebugContextInfo &);
+
+private:
+ Q_DISABLE_COPY(QQmlDebugMessageClient)
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLDEBUGMESSAGECLIENT_P_H
diff --git a/src/qmldebug/qqmlenginecontrolclient.cpp b/src/qmldebug/qqmlenginecontrolclient.cpp
index 3f75298e51..13f216ce38 100644
--- a/src/qmldebug/qqmlenginecontrolclient.cpp
+++ b/src/qmldebug/qqmlenginecontrolclient.cpp
@@ -108,32 +108,37 @@ void QQmlEngineControlClient::messageReceived(const QByteArray &data)
if (!stream.atEnd())
stream >> name;
- QQmlEngineControlClientPrivate::EngineState &state = d->blockedEngines[id];
- Q_ASSERT(state.blockers == 0);
- Q_ASSERT(state.releaseCommand == QQmlEngineControlClientPrivate::InvalidCommand);
+ auto handleWaiting = [&](
+ QQmlEngineControlClientPrivate::CommandType command, std::function<void()> emitter) {
+ QQmlEngineControlClientPrivate::EngineState &state = d->blockedEngines[id];
+ Q_ASSERT(state.blockers == 0);
+ Q_ASSERT(state.releaseCommand == QQmlEngineControlClientPrivate::InvalidCommand);
+ state.releaseCommand = command;
+ emitter();
+ if (state.blockers == 0) {
+ d->sendCommand(state.releaseCommand, id);
+ d->blockedEngines.remove(id);
+ }
+ };
switch (message) {
case QQmlEngineControlClientPrivate::EngineAboutToBeAdded:
- state.releaseCommand = QQmlEngineControlClientPrivate::StartWaitingEngine;
- emit engineAboutToBeAdded(id, name);
+ handleWaiting(QQmlEngineControlClientPrivate::StartWaitingEngine, [&](){
+ emit engineAboutToBeAdded(id, name);
+ });
break;
case QQmlEngineControlClientPrivate::EngineAdded:
emit engineAdded(id, name);
break;
case QQmlEngineControlClientPrivate::EngineAboutToBeRemoved:
- state.releaseCommand = QQmlEngineControlClientPrivate::StopWaitingEngine;
- emit engineAboutToBeRemoved(id, name);
+ handleWaiting(QQmlEngineControlClientPrivate::StopWaitingEngine, [&](){
+ emit engineAboutToBeRemoved(id, name);
+ });
break;
case QQmlEngineControlClientPrivate::EngineRemoved:
emit engineRemoved(id, name);
break;
}
-
- if (state.blockers == 0 &&
- state.releaseCommand != QQmlEngineControlClientPrivate::InvalidCommand) {
- d->sendCommand(state.releaseCommand, id);
- d->blockedEngines.remove(id);
- }
}
QQmlEngineControlClientPrivate::QQmlEngineControlClientPrivate(QQmlDebugConnection *connection) :
diff --git a/src/qmldebug/qqmlprofilerclient.cpp b/src/qmldebug/qqmlprofilerclient.cpp
index 3676bd933c..d2a2d24f13 100644
--- a/src/qmldebug/qqmlprofilerclient.cpp
+++ b/src/qmldebug/qqmlprofilerclient.cpp
@@ -43,337 +43,316 @@
QT_BEGIN_NAMESPACE
-QQmlProfilerClient::QQmlProfilerClient(QQmlDebugConnection *connection) :
- QQmlDebugClient(*(new QQmlProfilerClientPrivate(connection)))
+int QQmlProfilerClientPrivate::resolveType(const QQmlProfilerTypedEvent &event)
{
-}
+ int typeIndex = -1;
+ if (event.serverTypeId != 0) {
+ QHash<qint64, int>::ConstIterator it = serverTypeIds.constFind(event.serverTypeId);
-QQmlProfilerClient::QQmlProfilerClient(QQmlProfilerClientPrivate &dd) :
- QQmlDebugClient(dd)
-{
+ if (it != serverTypeIds.constEnd()) {
+ typeIndex = it.value();
+ } else {
+ typeIndex = eventReceiver->numLoadedEventTypes();
+ eventReceiver->addEventType(event.type);
+ serverTypeIds[event.serverTypeId] = typeIndex;
+ }
+ } else {
+ QHash<QQmlProfilerEventType, int>::ConstIterator it = eventTypeIds.constFind(event.type);
+
+ if (it != eventTypeIds.constEnd()) {
+ typeIndex = it.value();
+ } else {
+ typeIndex = eventReceiver->numLoadedEventTypes();
+ eventReceiver->addEventType(event.type);
+ eventTypeIds[event.type] = typeIndex;
+ }
+ }
+ return typeIndex;
}
-QQmlProfilerClientPrivate::QQmlProfilerClientPrivate(QQmlDebugConnection *connection) :
- QQmlDebugClientPrivate(QQmlProfilerService::s_key, connection),
- features(std::numeric_limits<quint64>::max())
+int QQmlProfilerClientPrivate::resolveStackTop()
{
+ if (rangesInProgress.isEmpty())
+ return -1;
+
+ QQmlProfilerTypedEvent &typedEvent = rangesInProgress.top();
+ int typeIndex = typedEvent.event.typeIndex();
+ if (typeIndex >= 0)
+ return typeIndex;
+
+ typeIndex = resolveType(typedEvent);
+ typedEvent.event.setTypeIndex(typeIndex);
+ while (!pendingMessages.isEmpty()
+ && pendingMessages.head().timestamp() < typedEvent.event.timestamp()) {
+ forwardEvents(pendingMessages.dequeue());
+ }
+ forwardEvents(typedEvent.event);
+ return typeIndex;
}
-void QQmlProfilerClient::setFeatures(quint64 features)
+void QQmlProfilerClientPrivate::forwardEvents(const QQmlProfilerEvent &last)
{
- Q_D(QQmlProfilerClient);
- d->features = features;
+ while (!pendingDebugMessages.isEmpty()
+ && pendingDebugMessages.front().timestamp() <= last.timestamp()) {
+ eventReceiver->addEvent(pendingDebugMessages.dequeue());
+ }
+ eventReceiver->addEvent(last);
}
-void QQmlProfilerClient::sendRecordingStatus(bool record, int engineId, quint32 flushInterval)
+void QQmlProfilerClientPrivate::processCurrentEvent()
{
- Q_D(const QQmlProfilerClient);
-
- QPacket stream(d->connection->currentDataStreamVersion());
- stream << record << engineId << d->features << flushInterval << true;
- sendMessage(stream.data());
+ // RangeData and RangeLocation always apply to the range on the top of the stack. Furthermore,
+ // all ranges are perfectly nested. This is why we can defer the type resolution until either
+ // the range ends or a child range starts. With only the information in RangeStart we wouldn't
+ // be able to uniquely identify the event type.
+ Message rangeStage = currentEvent.type.rangeType() == MaximumRangeType ?
+ currentEvent.type.message() : currentEvent.event.rangeStage();
+ switch (rangeStage) {
+ case RangeStart:
+ resolveStackTop();
+ rangesInProgress.push(currentEvent);
+ break;
+ case RangeEnd: {
+ int typeIndex = resolveStackTop();
+ if (typeIndex == -1)
+ break;
+ currentEvent.event.setTypeIndex(typeIndex);
+ while (!pendingMessages.isEmpty())
+ forwardEvents(pendingMessages.dequeue());
+ forwardEvents(currentEvent.event);
+ rangesInProgress.pop();
+ break;
+ }
+ case RangeData:
+ if (!rangesInProgress.isEmpty())
+ rangesInProgress.top().type.setData(currentEvent.type.data());
+ break;
+ case RangeLocation:
+ if (!rangesInProgress.isEmpty())
+ rangesInProgress.top().type.setLocation(currentEvent.type.location());
+ break;
+ case DebugMessage:
+ currentEvent.event.setTypeIndex(resolveType(currentEvent));
+ pendingDebugMessages.enqueue(currentEvent.event);
+ break;
+ default: {
+ int typeIndex = resolveType(currentEvent);
+ currentEvent.event.setTypeIndex(typeIndex);
+ if (rangesInProgress.isEmpty())
+ eventReceiver->addEvent(currentEvent.event);
+ else
+ pendingMessages.enqueue(currentEvent.event);
+ break;
+ }
+ }
}
-void QQmlProfilerClient::traceStarted(qint64 time, int engineId)
+void QQmlProfilerClientPrivate::sendRecordingStatus(int engineId)
{
- Q_UNUSED(time);
- Q_UNUSED(engineId);
+ Q_Q(QQmlProfilerClient);
+ QPacket stream(connection->currentDataStreamVersion());
+ stream << recording << engineId; // engineId -1 is OK. It means "all of them"
+ if (recording) {
+ stream << requestedFeatures << flushInterval;
+ stream << true; // yes, we support type IDs
+ }
+ q->sendMessage(stream.data());
}
-void QQmlProfilerClient::traceFinished(qint64 time, int engineId)
+QQmlProfilerClient::QQmlProfilerClient(QQmlDebugConnection *connection,
+ QQmlProfilerEventReceiver *eventReceiver,
+ quint64 features)
+ : QQmlDebugClient(*(new QQmlProfilerClientPrivate(connection, eventReceiver)))
{
- Q_UNUSED(time);
- Q_UNUSED(engineId);
+ Q_D(QQmlProfilerClient);
+ setRequestedFeatures(features);
+ connect(d->engineControl.data(), &QQmlEngineControlClient::engineAboutToBeAdded,
+ this, &QQmlProfilerClient::sendRecordingStatus);
+ connect(d->engineControl.data(), &QQmlEngineControlClient::engineAboutToBeRemoved,
+ this, [d](int engineId) {
+ // We may already be done with that engine. Then we don't need to block it.
+ if (d->trackedEngines.contains(engineId))
+ d->engineControl->blockEngine(engineId);
+ });
+ connect(this, &QQmlProfilerClient::traceFinished,
+ d->engineControl.data(), [d](qint64 timestamp, const QList<int> &engineIds) {
+ Q_UNUSED(timestamp);
+ // The engines might not be blocked because the trace can get finished before engine control
+ // sees them.
+ for (int blocked : d->engineControl->blockedEngines()) {
+ if (engineIds.contains(blocked))
+ d->engineControl->releaseEngine(blocked);
+ }
+ });
}
-void QQmlProfilerClient::rangeStart(QQmlProfilerDefinitions::RangeType type, qint64 startTime)
+QQmlProfilerClient::~QQmlProfilerClient()
{
- Q_UNUSED(type);
- Q_UNUSED(startTime);
+ //Disable profiling if started by client
+ //Profiling data will be lost!!
+ if (isRecording())
+ setRecording(false);
}
-void QQmlProfilerClient::rangeData(QQmlProfilerDefinitions::RangeType type, qint64 time,
- const QString &data)
+void QQmlProfilerClient::clearEvents()
{
- Q_UNUSED(type);
- Q_UNUSED(time);
- Q_UNUSED(data);
+ Q_D(QQmlProfilerClient);
+ d->rangesInProgress.clear();
+ d->pendingMessages.clear();
+ d->pendingDebugMessages.clear();
+ if (d->recordedFeatures != 0) {
+ d->recordedFeatures = 0;
+ emit recordedFeaturesChanged(0);
+ }
+ emit cleared();
}
-void QQmlProfilerClient::rangeLocation(QQmlProfilerDefinitions::RangeType type, qint64 time,
- const QQmlEventLocation &location)
+void QQmlProfilerClient::clearAll()
{
- Q_UNUSED(type);
- Q_UNUSED(time);
- Q_UNUSED(location);
+ Q_D(QQmlProfilerClient);
+ d->serverTypeIds.clear();
+ d->eventTypeIds.clear();
+ d->trackedEngines.clear();
+ clearEvents();
}
-void QQmlProfilerClient::rangeEnd(QQmlProfilerDefinitions::RangeType type, qint64 endTime)
+void QQmlProfilerClientPrivate::finalize()
{
- Q_UNUSED(type);
- Q_UNUSED(endTime);
+ while (!rangesInProgress.isEmpty()) {
+ currentEvent = rangesInProgress.top();
+ currentEvent.event.setRangeStage(RangeEnd);
+ currentEvent.event.setTimestamp(maximumTime);
+ processCurrentEvent();
+ }
+ while (!pendingDebugMessages.isEmpty())
+ eventReceiver->addEvent(pendingDebugMessages.dequeue());
}
-void QQmlProfilerClient::animationFrame(qint64 time, int frameRate, int animationCount,
- int threadId)
+
+void QQmlProfilerClient::sendRecordingStatus(int engineId)
{
- Q_UNUSED(time);
- Q_UNUSED(frameRate);
- Q_UNUSED(animationCount);
- Q_UNUSED(threadId);
+ Q_D(QQmlProfilerClient);
+ d->sendRecordingStatus(engineId);
}
-void QQmlProfilerClient::sceneGraphEvent(QQmlProfilerDefinitions::SceneGraphFrameType type,
- qint64 time, qint64 numericData1, qint64 numericData2,
- qint64 numericData3, qint64 numericData4,
- qint64 numericData5)
+bool QQmlProfilerClient::isRecording() const
{
- Q_UNUSED(type);
- Q_UNUSED(time);
- Q_UNUSED(numericData1);
- Q_UNUSED(numericData2);
- Q_UNUSED(numericData3);
- Q_UNUSED(numericData4);
- Q_UNUSED(numericData5);
+ Q_D(const QQmlProfilerClient);
+ return d->recording;
}
-void QQmlProfilerClient::pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type,
- qint64 time, const QString &url, int numericData1,
- int numericData2)
+void QQmlProfilerClient::setRecording(bool v)
{
- Q_UNUSED(type);
- Q_UNUSED(time);
- Q_UNUSED(url);
- Q_UNUSED(numericData1);
- Q_UNUSED(numericData2);
+ Q_D(QQmlProfilerClient);
+ if (v == d->recording)
+ return;
+
+ d->recording = v;
+
+ if (state() == Enabled)
+ sendRecordingStatus();
+
+ emit recordingChanged(v);
}
-void QQmlProfilerClient::memoryAllocation(QQmlProfilerDefinitions::MemoryType type, qint64 time,
- qint64 amount)
+quint64 QQmlProfilerClient::recordedFeatures() const
{
- Q_UNUSED(type);
- Q_UNUSED(time);
- Q_UNUSED(amount);
+ Q_D(const QQmlProfilerClient);
+ return d->recordedFeatures;
}
-void QQmlProfilerClient::inputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time,
- int a, int b)
+void QQmlProfilerClient::setRequestedFeatures(quint64 features)
{
- Q_UNUSED(type);
- Q_UNUSED(time);
- Q_UNUSED(a);
- Q_UNUSED(b);
+ Q_D(QQmlProfilerClient);
+ d->requestedFeatures = features;
+ if (features & static_cast<quint64>(1) << ProfileDebugMessages) {
+ if (d->messageClient.isNull()) {
+ d->messageClient.reset(new QQmlDebugMessageClient(connection()));
+ connect(d->messageClient.data(), &QQmlDebugMessageClient::message, this,
+ [this](QtMsgType type, const QString &text, const QQmlDebugContextInfo &context)
+ {
+ Q_D(QQmlProfilerClient);
+ d->updateFeatures(ProfileDebugMessages);
+ d->currentEvent.event.setTimestamp(context.timestamp > 0 ? context.timestamp : 0);
+ d->currentEvent.event.setTypeIndex(-1);
+ d->currentEvent.event.setString(text);
+ d->currentEvent.type = QQmlProfilerEventType(
+ DebugMessage, MaximumRangeType, type,
+ QQmlProfilerEventLocation(context.file, context.line, 1));
+ d->currentEvent.serverTypeId = 0;
+ d->processCurrentEvent();
+ });
+ }
+ } else {
+ d->messageClient.reset();
+ }
}
-void QQmlProfilerClient::complete()
+void QQmlProfilerClient::setFlushInterval(quint32 flushInterval)
{
+ Q_D(QQmlProfilerClient);
+ d->flushInterval = flushInterval;
}
-void QQmlProfilerClient::unknownEvent(QQmlProfilerDefinitions::Message messageType, qint64 time,
- int detailType)
+QQmlProfilerClient::QQmlProfilerClient(QQmlProfilerClientPrivate &dd) :
+ QQmlDebugClient(dd)
{
- Q_UNUSED(messageType);
- Q_UNUSED(time);
- Q_UNUSED(detailType);
+ Q_D(QQmlProfilerClient);
+ connect(d->engineControl.data(), &QQmlEngineControlClient::engineAboutToBeAdded,
+ this, &QQmlProfilerClient::sendRecordingStatus);
}
-void QQmlProfilerClient::unknownData(QPacket &stream)
+bool QQmlProfilerClientPrivate::updateFeatures(ProfileFeature feature)
{
- Q_UNUSED(stream);
+ Q_Q(QQmlProfilerClient);
+ quint64 flag = 1ULL << feature;
+ if (!(requestedFeatures & flag))
+ return false;
+ if (!(recordedFeatures & flag)) {
+ recordedFeatures |= flag;
+ emit q->recordedFeaturesChanged(recordedFeatures);
+ }
+ return true;
}
-inline QQmlProfilerDefinitions::ProfileFeature featureFromRangeType(
- QQmlProfilerDefinitions::RangeType range)
+void QQmlProfilerClient::stateChanged(State status)
{
- switch (range) {
- case QQmlProfilerDefinitions::Painting:
- return QQmlProfilerDefinitions::ProfilePainting;
- case QQmlProfilerDefinitions::Compiling:
- return QQmlProfilerDefinitions::ProfileCompiling;
- case QQmlProfilerDefinitions::Creating:
- return QQmlProfilerDefinitions::ProfileCreating;
- case QQmlProfilerDefinitions::Binding:
- return QQmlProfilerDefinitions::ProfileBinding;
- case QQmlProfilerDefinitions::HandlingSignal:
- return QQmlProfilerDefinitions::ProfileHandlingSignal;
- case QQmlProfilerDefinitions::Javascript:
- return QQmlProfilerDefinitions::ProfileJavaScript;
- default:
- return QQmlProfilerDefinitions::MaximumProfileFeature;
+ if (status == Enabled) {
+ sendRecordingStatus(-1);
+ } else {
+ Q_D(QQmlProfilerClient);
+ d->finalize();
}
+
}
void QQmlProfilerClient::messageReceived(const QByteArray &data)
{
Q_D(QQmlProfilerClient);
-
QPacket stream(d->connection->currentDataStreamVersion(), data);
- // Force all the 1 << <FLAG> expressions to be done in 64 bit, to silence some warnings
- const quint64 one = static_cast<quint64>(1);
-
- qint64 time;
- int messageType;
-
- stream >> time >> messageType;
-
- if (messageType >= QQmlProfilerDefinitions::MaximumMessage) {
- unknownEvent(static_cast<QQmlProfilerDefinitions::Message>(messageType), time, -1);
- return;
+ stream >> d->currentEvent;
+
+ d->maximumTime = qMax(d->currentEvent.event.timestamp(), d->maximumTime);
+ if (d->currentEvent.type.message() == Complete) {
+ d->finalize();
+ emit complete(d->maximumTime);
+ } else if (d->currentEvent.type.message() == Event
+ && d->currentEvent.type.detailType() == StartTrace) {
+ const QList<int> engineIds = d->currentEvent.event.numbers<QList<int>, qint32>();
+ d->trackedEngines.append(engineIds);
+ emit traceStarted(d->currentEvent.event.timestamp(), engineIds);
+ } else if (d->currentEvent.type.message() == Event
+ && d->currentEvent.type.detailType() == EndTrace) {
+ const QList<int> engineIds = d->currentEvent.event.numbers<QList<int>, qint32>();
+ for (int engineId : engineIds)
+ d->trackedEngines.removeAll(engineId);
+ emit traceFinished(d->currentEvent.event.timestamp(), engineIds);
+ } else if (d->updateFeatures(d->currentEvent.type.feature())) {
+ d->processCurrentEvent();
}
-
- if (messageType == QQmlProfilerDefinitions::Event) {
- int type;
- stream >> type;
-
- QQmlProfilerDefinitions::EventType eventType =
- static_cast<QQmlProfilerDefinitions::EventType>(type);
-
- if (eventType == QQmlProfilerDefinitions::EndTrace) {
- int engineId = -1;
- if (!stream.atEnd())
- stream >> engineId;
- traceFinished(time, engineId);
- } else if (eventType == QQmlProfilerDefinitions::AnimationFrame) {
- if (!(d->features & one << QQmlProfilerDefinitions::ProfileAnimations))
- return;
-
- int frameRate, animationCount;
- int threadId = 0;
- stream >> frameRate >> animationCount;
- if (!stream.atEnd())
- stream >> threadId;
-
- animationFrame(time, frameRate, animationCount, threadId);
- } else if (type == QQmlProfilerDefinitions::StartTrace) {
- int engineId = -1;
- if (!stream.atEnd())
- stream >> engineId;
- traceStarted(time, engineId);
- } else if (eventType == QQmlProfilerDefinitions::Key ||
- eventType == QQmlProfilerDefinitions::Mouse) {
-
- if (!(d->features & one << QQmlProfilerDefinitions::ProfileInputEvents))
- return;
-
- int type;
- if (!stream.atEnd()) {
- stream >> type;
- } else {
- type = (eventType == QQmlProfilerDefinitions::Key) ?
- QQmlProfilerDefinitions::InputKeyUnknown :
- QQmlProfilerDefinitions::InputMouseUnknown;
- }
-
- int a = 0;
- if (!stream.atEnd())
- stream >> a;
-
- int b = 0;
- if (!stream.atEnd())
- stream >> b;
-
- inputEvent(static_cast<QQmlProfilerDefinitions::InputEventType>(type), time, a, b);
- } else {
- unknownEvent(QQmlProfilerDefinitions::Event, time, type);
- }
- } else if (messageType == QQmlProfilerDefinitions::Complete) {
- complete();
- } else if (messageType == QQmlProfilerDefinitions::SceneGraphFrame) {
- if (!(d->features & one << QQmlProfilerDefinitions::ProfileSceneGraph))
- return;
-
- int type;
- int count = 0;
- qint64 params[5];
-
- stream >> type;
- while (!stream.atEnd())
- stream >> params[count++];
-
- while (count < 5)
- params[count++] = 0;
-
- sceneGraphEvent(static_cast<QQmlProfilerDefinitions::SceneGraphFrameType>(type), time,
- params[0], params[1], params[2], params[3], params[4]);
- } else if (messageType == QQmlProfilerDefinitions::PixmapCacheEvent) {
- if (!(d->features & one << QQmlProfilerDefinitions::ProfilePixmapCache))
- return;
-
- int type, param1 = 0, param2 = 0;
- QString pixUrl;
- stream >> type >> pixUrl;
-
- QQmlProfilerDefinitions::PixmapEventType pixmapEventType =
- static_cast<QQmlProfilerDefinitions::PixmapEventType>(type);
-
- if (pixmapEventType == QQmlProfilerDefinitions::PixmapReferenceCountChanged ||
- pixmapEventType == QQmlProfilerDefinitions::PixmapCacheCountChanged) {
- stream >> param1;
- } else if (pixmapEventType == QQmlProfilerDefinitions::PixmapSizeKnown) {
- stream >> param1 >> param2;
- }
-
- pixmapCacheEvent(pixmapEventType, time, pixUrl, param1, param2);
- } else if (messageType == QQmlProfilerDefinitions::MemoryAllocation) {
- if (!(d->features & one << QQmlProfilerDefinitions::ProfileMemory))
- return;
- int type;
- qint64 delta;
- stream >> type >> delta;
- memoryAllocation((QQmlProfilerDefinitions::MemoryType)type, time, delta);
- } else {
- int range;
- stream >> range;
-
- QQmlProfilerDefinitions::RangeType rangeType =
- static_cast<QQmlProfilerDefinitions::RangeType>(range);
-
- if (range >= QQmlProfilerDefinitions::MaximumRangeType ||
- !(d->features & one << featureFromRangeType(rangeType)))
- return;
-
- qint64 typeId = 0;
- if (messageType == QQmlProfilerDefinitions::RangeStart) {
- rangeStart(rangeType, time);
- if (!stream.atEnd()) {
- stream >> typeId;
- auto i = d->types.constFind(typeId);
- if (i != d->types.constEnd()) {
- rangeLocation(rangeType, time, i->location);
- rangeData(rangeType, time, i->name);
- }
- }
- } else if (messageType == QQmlProfilerDefinitions::RangeData) {
- QString data;
- stream >> data;
- rangeData(rangeType, time, data);
- if (!stream.atEnd()) {
- stream >> typeId;
- d->types[typeId].name = data;
- }
- } else if (messageType == QQmlProfilerDefinitions::RangeLocation) {
- QQmlEventLocation location;
- stream >> location.filename >> location.line;
-
- if (!stream.atEnd())
- stream >> location.column;
-
- rangeLocation(rangeType, time, location);
- if (!stream.atEnd()) {
- stream >> typeId;
- d->types[typeId].location = location;
- }
- } else if (messageType == QQmlProfilerDefinitions::RangeEnd) {
- rangeEnd(rangeType, time);
- } else {
- unknownEvent(static_cast<QQmlProfilerDefinitions::Message>(messageType), time, range);
- }
- }
-
- if (!stream.atEnd())
- unknownData(stream);
}
+
QT_END_NAMESPACE
#include "moc_qqmlprofilerclient_p.cpp"
diff --git a/src/qmldebug/qqmlprofilerclient_p.h b/src/qmldebug/qqmlprofilerclient_p.h
index a328cad26c..68a32a1a5a 100644
--- a/src/qmldebug/qqmlprofilerclient_p.h
+++ b/src/qmldebug/qqmlprofilerclient_p.h
@@ -41,7 +41,9 @@
#define QQMLPROFILERCLIENT_P_H
#include "qqmldebugclient_p.h"
-#include "qqmleventlocation_p.h"
+#include "qqmlprofilereventlocation_p.h"
+#include "qqmlprofilereventreceiver_p.h"
+
#include <private/qqmlprofilerdefinitions_p.h>
#include <private/qpacket_p.h>
@@ -59,52 +61,42 @@
QT_BEGIN_NAMESPACE
class QQmlProfilerClientPrivate;
-class QQmlProfilerClient : public QQmlDebugClient
+class QQmlProfilerClient : public QQmlDebugClient, public QQmlProfilerDefinitions
{
Q_OBJECT
Q_DECLARE_PRIVATE(QQmlProfilerClient)
+ Q_PROPERTY(bool recording READ isRecording WRITE setRecording NOTIFY recordingChanged)
public:
- QQmlProfilerClient(QQmlDebugConnection *connection);
- void setFeatures(quint64 features);
- void sendRecordingStatus(bool record, int engineId = -1, quint32 flushInterval = 0);
-
-protected:
- QQmlProfilerClient(QQmlProfilerClientPrivate &dd);
-
-private:
- void messageReceived(const QByteArray &message) override;
+ QQmlProfilerClient(QQmlDebugConnection *connection, QQmlProfilerEventReceiver *eventReceiver,
+ quint64 features = std::numeric_limits<quint64>::max());
+ ~QQmlProfilerClient();
- virtual void traceStarted(qint64 time, int engineId);
- virtual void traceFinished(qint64 time, int engineId);
+ bool isRecording() const;
+ void setRecording(bool);
+ quint64 recordedFeatures() const;
+ virtual void messageReceived(const QByteArray &) override;
+ virtual void stateChanged(State status) override;
- virtual void rangeStart(QQmlProfilerDefinitions::RangeType type, qint64 startTime);
- virtual void rangeData(QQmlProfilerDefinitions::RangeType type, qint64 time,
- const QString &data);
- virtual void rangeLocation(QQmlProfilerDefinitions::RangeType type, qint64 time,
- const QQmlEventLocation &location);
- virtual void rangeEnd(QQmlProfilerDefinitions::RangeType type, qint64 endTime);
+ void clearEvents();
+ void clearAll();
- virtual void animationFrame(qint64 time, int frameRate, int animationCount, int threadId);
+ void sendRecordingStatus(int engineId = -1);
+ void setRequestedFeatures(quint64 features);
+ void setFlushInterval(quint32 flushInterval);
- virtual void sceneGraphEvent(QQmlProfilerDefinitions::SceneGraphFrameType type, qint64 time,
- qint64 numericData1, qint64 numericData2, qint64 numericData3,
- qint64 numericData4, qint64 numericData5);
-
- virtual void pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type, qint64 time,
- const QString &url, int numericData1, int numericData2);
-
- virtual void memoryAllocation(QQmlProfilerDefinitions::MemoryType type, qint64 time,
- qint64 amount);
+protected:
+ QQmlProfilerClient(QQmlProfilerClientPrivate &dd);
- virtual void inputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time, int a,
- int b);
+signals:
+ void complete(qint64 maximumTime);
+ void traceFinished(qint64 timestamp, const QList<int> &engineIds);
+ void traceStarted(qint64 timestamp, const QList<int> &engineIds);
- virtual void complete();
+ void recordingChanged(bool arg);
+ void recordedFeaturesChanged(quint64 features);
- virtual void unknownEvent(QQmlProfilerDefinitions::Message messageType, qint64 time,
- int detailType);
- virtual void unknownData(QPacket &stream);
+ void cleared();
};
QT_END_NAMESPACE
diff --git a/src/qmldebug/qqmlprofilerclient_p_p.h b/src/qmldebug/qqmlprofilerclient_p_p.h
index 9c44113aa8..0caef8e448 100644
--- a/src/qmldebug/qqmlprofilerclient_p_p.h
+++ b/src/qmldebug/qqmlprofilerclient_p_p.h
@@ -40,8 +40,15 @@
#ifndef QQMLPROFILERCLIENT_P_P_H
#define QQMLPROFILERCLIENT_P_P_H
-#include "qqmlprofilerclient_p.h"
#include "qqmldebugclient_p_p.h"
+#include "qqmldebugmessageclient_p.h"
+#include "qqmlenginecontrolclient_p.h"
+#include "qqmlprofilerclient_p.h"
+#include "qqmlprofilertypedevent_p.h"
+
+#include <private/qqmlprofilerdefinitions_p.h>
+
+#include <QtCore/qqueue.h>
//
// W A R N I N G
@@ -56,20 +63,50 @@
QT_BEGIN_NAMESPACE
-struct QQmlProfilerRangeType
-{
- QQmlEventLocation location;
- QString name;
-};
-
-class QQmlProfilerClientPrivate : public QQmlDebugClientPrivate
-{
+class QQmlProfilerClientPrivate : public QQmlDebugClientPrivate, public QQmlProfilerDefinitions {
Q_DECLARE_PUBLIC(QQmlProfilerClient)
public:
- QQmlProfilerClientPrivate(QQmlDebugConnection *connection);
- quint64 features;
+ QQmlProfilerClientPrivate(QQmlDebugConnection *connection,
+ QQmlProfilerEventReceiver *eventReceiver)
+ : QQmlDebugClientPrivate(QLatin1String("CanvasFrameRate"), connection)
+ , eventReceiver(eventReceiver)
+ , engineControl(new QQmlEngineControlClient(connection))
+ , maximumTime(0)
+ , recording(false)
+ , requestedFeatures(0)
+ , recordedFeatures(0)
+ , flushInterval(0)
+ {
+ }
+
+ virtual ~QQmlProfilerClientPrivate() override {}
+
+ void sendRecordingStatus(int engineId);
+ bool updateFeatures(ProfileFeature feature);
+ int resolveType(const QQmlProfilerTypedEvent &type);
+ int resolveStackTop();
+ void forwardEvents(const QQmlProfilerEvent &last);
+ void processCurrentEvent();
+ void finalize();
+
+ QQmlProfilerEventReceiver *eventReceiver;
+ QScopedPointer<QQmlEngineControlClient> engineControl;
+ QScopedPointer<QQmlDebugMessageClient> messageClient;
+ qint64 maximumTime;
+ bool recording;
+ quint64 requestedFeatures;
+ quint64 recordedFeatures;
+ quint32 flushInterval;
+
+ // Reuse the same event, so that we don't have to constantly reallocate all the data.
+ QQmlProfilerTypedEvent currentEvent;
+ QHash<QQmlProfilerEventType, int> eventTypeIds;
+ QHash<qint64, int> serverTypeIds;
+ QStack<QQmlProfilerTypedEvent> rangesInProgress;
+ QQueue<QQmlProfilerEvent> pendingMessages;
+ QQueue<QQmlProfilerEvent> pendingDebugMessages;
- QHash<qint64, QQmlProfilerRangeType> types;
+ QList<int> trackedEngines;
};
QT_END_NAMESPACE
diff --git a/src/qmldebug/qqmlprofilerevent.cpp b/src/qmldebug/qqmlprofilerevent.cpp
new file mode 100644
index 0000000000..30ae1c79a1
--- /dev/null
+++ b/src/qmldebug/qqmlprofilerevent.cpp
@@ -0,0 +1,273 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmlprofilerevent_p.h"
+#include <QtCore/qdatastream.h>
+
+QT_BEGIN_NAMESPACE
+
+bool operator==(const QQmlProfilerEvent &event1, const QQmlProfilerEvent &event2)
+{
+ if (event1.timestamp() != event2.timestamp() || event1.typeIndex() != event2.typeIndex())
+ return false;
+
+ // This is not particularly efficient, but we also don't need to do this very often.
+ return event1.numbers<QVarLengthArray<qint64>>() == event2.numbers<QVarLengthArray<qint64>>();
+}
+
+bool operator!=(const QQmlProfilerEvent &event1, const QQmlProfilerEvent &event2)
+{
+ return !(event1 == event2);
+}
+
+enum SerializationType {
+ OneByte = 0,
+ TwoByte = 1,
+ FourByte = 2,
+ EightByte = 3,
+ TypeMask = 0x3
+};
+
+enum SerializationTypeOffset {
+ TimestampOffset = 0,
+ TypeIndexOffset = 2,
+ DataLengthOffset = 4,
+ DataOffset = 6
+};
+
+template<typename Number>
+static inline void readNumbers(QDataStream &stream, Number *data, quint16 length)
+{
+ for (quint16 i = 0; i != length; ++i)
+ stream >> data[i];
+}
+
+template<typename Number>
+static inline Number readNumber(QDataStream &stream, qint8 type)
+{
+ switch (type) {
+ case OneByte: {
+ qint8 value;
+ stream >> value;
+ return static_cast<Number>(value);
+ }
+ case TwoByte: {
+ qint16 value;
+ stream >> value;
+ return static_cast<Number>(value);
+ }
+ case FourByte: {
+ qint32 value;
+ stream >> value;
+ return static_cast<Number>(value);
+ }
+ case EightByte: {
+ qint64 value;
+ stream >> value;
+ return static_cast<Number>(value);
+ }
+ default:
+ Q_UNREACHABLE();
+ return 0;
+ }
+}
+
+QDataStream &operator>>(QDataStream &stream, QQmlProfilerEvent &event)
+{
+ qint8 type;
+ stream >> type;
+
+ event.m_timestamp = readNumber<qint64>(stream, (type >> TimestampOffset) & TypeMask);
+ event.m_typeIndex = readNumber<qint32>(stream, (type >> TypeIndexOffset) & TypeMask);
+ event.m_dataLength = readNumber<quint16>(stream, (type >> DataLengthOffset) & TypeMask);
+
+ uint bytesPerNumber = 1 << ((type >> DataOffset) & TypeMask);
+
+ if (event.m_dataLength * bytesPerNumber > sizeof(event.m_data)) {
+ event.m_dataType = static_cast<QQmlProfilerEvent::Type>((bytesPerNumber * 8)
+ | QQmlProfilerEvent::External);
+ event.m_data.external = malloc(event.m_dataLength * bytesPerNumber);
+ } else {
+ event.m_dataType = static_cast<QQmlProfilerEvent::Type>(bytesPerNumber * 8);
+ }
+
+ switch (event.m_dataType) {
+ case QQmlProfilerEvent::Inline8Bit:
+ readNumbers<qint8>(stream, event.m_data.internal8bit, event.m_dataLength);
+ break;
+ case QQmlProfilerEvent::External8Bit:
+ readNumbers<qint8>(stream, static_cast<qint8 *>(event.m_data.external),
+ event.m_dataLength);
+ break;
+ case QQmlProfilerEvent::Inline16Bit:
+ readNumbers<qint16>(stream, event.m_data.internal16bit, event.m_dataLength);
+ break;
+ case QQmlProfilerEvent::External16Bit:
+ readNumbers<qint16>(stream, static_cast<qint16 *>(event.m_data.external),
+ event.m_dataLength);
+ break;
+ case QQmlProfilerEvent::Inline32Bit:
+ readNumbers<qint32>(stream, event.m_data.internal32bit, event.m_dataLength);
+ break;
+ case QQmlProfilerEvent::External32Bit:
+ readNumbers<qint32>(stream, static_cast<qint32 *>(event.m_data.external),
+ event.m_dataLength);
+ break;
+ case QQmlProfilerEvent::Inline64Bit:
+ readNumbers<qint64>(stream, event.m_data.internal64bit, event.m_dataLength);
+ break;
+ case QQmlProfilerEvent::External64Bit:
+ readNumbers<qint64>(stream, static_cast<qint64 *>(event.m_data.external),
+ event.m_dataLength);
+ break;
+ default:
+ Q_UNREACHABLE();
+ break;
+ }
+
+ return stream;
+}
+
+static inline qint8 minimumType(const QQmlProfilerEvent &event, quint16 length,
+ quint16 origBitsPerNumber)
+{
+ qint8 type = OneByte;
+ bool ok = true;
+ for (quint16 i = 0; i < length;) {
+ if ((1 << type) == origBitsPerNumber / 8)
+ return type;
+ switch (type) {
+ case OneByte:
+ ok = (event.number<qint8>(i) == event.number<qint64>(i));
+ break;
+ case TwoByte:
+ ok = (event.number<qint16>(i) == event.number<qint64>(i));
+ break;
+ case FourByte:
+ ok = (event.number<qint32>(i) == event.number<qint64>(i));
+ break;
+ default:
+ // EightByte isn't possible, as (1 << type) == origBitsPerNumber / 8 then.
+ Q_UNREACHABLE();
+ break;
+ }
+
+ if (ok)
+ ++i;
+ else
+ ++type;
+ }
+ return type;
+}
+
+template<typename Number>
+static inline qint8 minimumType(Number number)
+{
+ if (static_cast<qint8>(number) == number)
+ return OneByte;
+ if (static_cast<qint16>(number) == number)
+ return TwoByte;
+ if (static_cast<qint32>(number) == number)
+ return FourByte;
+ return EightByte;
+}
+
+template<typename Number>
+static inline void writeNumbers(QDataStream &stream, const QQmlProfilerEvent &event, quint16 length)
+{
+ for (quint16 i = 0; i != length; ++i)
+ stream << event.number<Number>(i);
+}
+
+template<typename Number>
+static inline void writeNumber(QDataStream &stream, Number number, qint8 type)
+{
+ switch (type) {
+ case OneByte:
+ stream << static_cast<qint8>(number);
+ break;
+ case TwoByte:
+ stream << static_cast<qint16>(number);
+ break;
+ case FourByte:
+ stream << static_cast<qint32>(number);
+ break;
+ case EightByte:
+ stream << static_cast<qint64>(number);
+ break;
+ default:
+ Q_UNREACHABLE();
+ break;
+ }
+}
+
+QDataStream &operator<<(QDataStream &stream, const QQmlProfilerEvent &event)
+{
+ qint8 type = minimumType(event.m_timestamp); // << TimestampOffset;
+ type |= minimumType(event.m_typeIndex) << TypeIndexOffset;
+ type |= minimumType(event.m_dataLength) << DataLengthOffset;
+ type |= minimumType(event, event.m_dataLength, event.m_dataType) << DataOffset;
+ stream << type;
+
+ writeNumber(stream, event.m_timestamp, (type >> TimestampOffset) & TypeMask);
+ writeNumber(stream, event.m_typeIndex, (type >> TypeIndexOffset) & TypeMask);
+ writeNumber(stream, event.m_dataLength, (type >> DataLengthOffset) & TypeMask);
+
+ switch ((type >> DataOffset) & TypeMask) {
+ case OneByte:
+ writeNumbers<qint8>(stream, event, event.m_dataLength);
+ break;
+ case TwoByte:
+ writeNumbers<qint16>(stream, event, event.m_dataLength);
+ break;
+ case FourByte:
+ writeNumbers<qint32>(stream, event, event.m_dataLength);
+ break;
+ case EightByte:
+ writeNumbers<qint64>(stream, event, event.m_dataLength);
+ break;
+ default:
+ Q_UNREACHABLE();
+ break;
+ }
+
+ return stream;
+}
+
+QT_END_NAMESPACE
diff --git a/src/qmldebug/qqmlprofilerevent_p.h b/src/qmldebug/qqmlprofilerevent_p.h
new file mode 100644
index 0000000000..93562302e9
--- /dev/null
+++ b/src/qmldebug/qqmlprofilerevent_p.h
@@ -0,0 +1,355 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLPROFILEREVENT_P_H
+#define QQMLPROFILEREVENT_P_H
+
+#include <private/qqmlprofilerdefinitions_p.h>
+
+#include <QtCore/qstring.h>
+#include <QtCore/qbytearray.h>
+#include <QtCore/qvarlengtharray.h>
+#include <QtCore/qmetatype.h>
+
+#include <initializer_list>
+#include <type_traits>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+struct QQmlProfilerEvent : public QQmlProfilerDefinitions {
+ QQmlProfilerEvent() :
+ m_timestamp(-1), m_typeIndex(-1), m_dataType(Inline8Bit), m_dataLength(0)
+ {}
+
+ template<typename Number>
+ QQmlProfilerEvent(qint64 timestamp, int typeIndex, std::initializer_list<Number> list)
+ : m_timestamp(timestamp), m_typeIndex(typeIndex)
+ {
+ assignNumbers<std::initializer_list<Number>, Number>(list);
+ }
+
+ QQmlProfilerEvent(qint64 timestamp, int typeIndex, const QString &data)
+ : m_timestamp(timestamp), m_typeIndex(typeIndex)
+ {
+ assignNumbers<QByteArray, qint8>(data.toUtf8());
+ }
+
+ template<typename Number>
+ QQmlProfilerEvent(qint64 timestamp, int typeIndex, const QVector<Number> &data)
+ : m_timestamp(timestamp), m_typeIndex(typeIndex)
+ {
+ assignNumbers<QVector<Number>, Number>(data);
+ }
+
+ QQmlProfilerEvent(const QQmlProfilerEvent &other)
+ : m_timestamp(other.m_timestamp), m_typeIndex(other.m_typeIndex),
+ m_dataType(other.m_dataType), m_dataLength(other.m_dataLength)
+ {
+ assignData(other);
+ }
+
+ QQmlProfilerEvent(QQmlProfilerEvent &&other)
+ {
+ memcpy(this, &other, sizeof(QQmlProfilerEvent));
+ other.m_dataType = Inline8Bit; // prevent dtor from deleting the pointer
+ }
+
+ QQmlProfilerEvent &operator=(const QQmlProfilerEvent &other)
+ {
+ if (this != &other) {
+ clearPointer();
+ m_timestamp = other.m_timestamp;
+ m_typeIndex = other.m_typeIndex;
+ m_dataType = other.m_dataType;
+ m_dataLength = other.m_dataLength;
+ assignData(other);
+ }
+ return *this;
+ }
+
+ QQmlProfilerEvent &operator=(QQmlProfilerEvent &&other)
+ {
+ if (this != &other) {
+ memcpy(this, &other, sizeof(QQmlProfilerEvent));
+ other.m_dataType = Inline8Bit;
+ }
+ return *this;
+ }
+
+ ~QQmlProfilerEvent()
+ {
+ clearPointer();
+ }
+
+ qint64 timestamp() const { return m_timestamp; }
+ void setTimestamp(qint64 timestamp) { m_timestamp = timestamp; }
+
+ int typeIndex() const { return m_typeIndex; }
+ void setTypeIndex(int typeIndex) { m_typeIndex = typeIndex; }
+
+ template<typename Number>
+ Number number(int i) const
+ {
+ // Trailing zeroes can be omitted, for example for SceneGraph events
+ if (i >= m_dataLength)
+ return 0;
+ switch (m_dataType) {
+ case Inline8Bit:
+ return m_data.internal8bit[i];
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_GCC("-Warray-bounds") // Mingw 5.3 gcc doesn't get the type/length logic.
+ case Inline16Bit:
+ return m_data.internal16bit[i];
+ case Inline32Bit:
+ return m_data.internal32bit[i];
+ case Inline64Bit:
+ return m_data.internal64bit[i];
+QT_WARNING_POP
+ case External8Bit:
+ return static_cast<const qint8 *>(m_data.external)[i];
+ case External16Bit:
+ return static_cast<const qint16 *>(m_data.external)[i];
+ case External32Bit:
+ return static_cast<const qint32 *>(m_data.external)[i];
+ case External64Bit:
+ return static_cast<const qint64 *>(m_data.external)[i];
+ default:
+ return 0;
+ }
+ }
+
+ template<typename Number>
+ void setNumber(int i, Number number)
+ {
+ QVarLengthArray<Number> nums = numbers<QVarLengthArray<Number>, Number>();
+ int prevSize = nums.size();
+ if (i >= prevSize) {
+ nums.resize(i + 1);
+ // Fill with zeroes. We don't want to accidentally prevent squeezing.
+ while (prevSize < i)
+ nums[prevSize++] = 0;
+ }
+ nums[i] = number;
+ setNumbers<QVarLengthArray<Number>, Number>(nums);
+ }
+
+ template<typename Container, typename Number>
+ void setNumbers(const Container &numbers)
+ {
+ clearPointer();
+ assignNumbers<Container, Number>(numbers);
+ }
+
+ template<typename Number>
+ void setNumbers(std::initializer_list<Number> numbers)
+ {
+ setNumbers<std::initializer_list<Number>, Number>(numbers);
+ }
+
+ template<typename Container, typename Number = qint64>
+ Container numbers() const
+ {
+ Container container;
+ for (int i = 0; i < m_dataLength; ++i)
+ container.append(number<Number>(i));
+ return container;
+ }
+
+ QString string() const
+ {
+ switch (m_dataType) {
+ case External8Bit:
+ return QString::fromUtf8(static_cast<const char *>(m_data.external), m_dataLength);
+ case Inline8Bit:
+ return QString::fromUtf8(m_data.internalChar, m_dataLength);
+ default:
+ Q_UNREACHABLE();
+ return QString();
+ }
+ }
+
+ void setString(const QString &data)
+ {
+ clearPointer();
+ assignNumbers<QByteArray, char>(data.toUtf8());
+ }
+
+ Message rangeStage() const
+ {
+ Q_ASSERT(m_dataType == Inline8Bit);
+ return static_cast<Message>(m_data.internal8bit[0]);
+ }
+
+ void setRangeStage(Message stage)
+ {
+ clearPointer();
+ m_dataType = Inline8Bit;
+ m_dataLength = 1;
+ m_data.internal8bit[0] = stage;
+ }
+
+ bool isValid() const
+ {
+ return m_timestamp != -1;
+ }
+
+private:
+ enum Type: quint16 {
+ External = 1,
+ Inline8Bit = 8,
+ External8Bit = Inline8Bit | External,
+ Inline16Bit = 16,
+ External16Bit = Inline16Bit | External,
+ Inline32Bit = 32,
+ External32Bit = Inline32Bit | External,
+ Inline64Bit = 64,
+ External64Bit = Inline64Bit | External
+ };
+
+ qint64 m_timestamp;
+
+ static const int s_internalDataLength = 8;
+ union {
+ void *external;
+ char internalChar [s_internalDataLength];
+ qint8 internal8bit [s_internalDataLength];
+ qint16 internal16bit[s_internalDataLength / 2];
+ qint32 internal32bit[s_internalDataLength / 4];
+ qint64 internal64bit[s_internalDataLength / 8];
+ } m_data;
+
+ qint32 m_typeIndex;
+ Type m_dataType;
+ quint16 m_dataLength;
+
+ void assignData(const QQmlProfilerEvent &other)
+ {
+ if (m_dataType & External) {
+ uint length = m_dataLength * (other.m_dataType / 8);
+ m_data.external = malloc(length);
+ memcpy(m_data.external, other.m_data.external, length);
+ } else {
+ memcpy(&m_data, &other.m_data, sizeof(m_data));
+ }
+ }
+
+ template<typename Big, typename Small>
+ bool squeezable(Big source)
+ {
+ return static_cast<Small>(source) == source;
+ }
+
+ template<typename Container, typename Number>
+ typename std::enable_if<(sizeof(Number) > 1), bool>::type
+ squeeze(const Container &numbers)
+ {
+ typedef typename QIntegerForSize<sizeof(Number) / 2>::Signed Small;
+ foreach (Number item, numbers) {
+ if (!squeezable<Number, Small>(item))
+ return false;
+ }
+ assignNumbers<Container, Small>(numbers);
+ return true;
+ }
+
+ template<typename Container, typename Number>
+ typename std::enable_if<(sizeof(Number) <= 1), bool>::type
+ squeeze(const Container &)
+ {
+ return false;
+ }
+
+ template<typename Container, typename Number>
+ void assignNumbers(const Container &numbers)
+ {
+ Number *data;
+ m_dataLength = squeezable<size_t, quint16>(static_cast<size_t>(numbers.size())) ?
+ static_cast<quint16>(numbers.size()) : std::numeric_limits<quint16>::max();
+ if (m_dataLength > sizeof(m_data) / sizeof(Number)) {
+ if (squeeze<Container, Number>(numbers))
+ return;
+ m_dataType = static_cast<Type>((sizeof(Number) * 8) | External);
+ m_data.external = malloc(m_dataLength * sizeof(Number));
+ data = static_cast<Number *>(m_data.external);
+ } else {
+ m_dataType = static_cast<Type>(sizeof(Number) * 8);
+ data = static_cast<Number *>(m_dataType & External ? m_data.external : &m_data);
+ }
+ quint16 i = 0;
+ for (Number item : numbers) {
+ if (i >= m_dataLength)
+ break;
+ data[i++] = item;
+ }
+ }
+
+ void clearPointer()
+ {
+ if (m_dataType & External)
+ free(m_data.external);
+ }
+
+ friend QDataStream &operator>>(QDataStream &stream, QQmlProfilerEvent &event);
+ friend QDataStream &operator<<(QDataStream &stream, const QQmlProfilerEvent &event);
+};
+
+bool operator==(const QQmlProfilerEvent &event1, const QQmlProfilerEvent &event2);
+bool operator!=(const QQmlProfilerEvent &event1, const QQmlProfilerEvent &event2);
+
+QDataStream &operator>>(QDataStream &stream, QQmlProfilerEvent &event);
+QDataStream &operator<<(QDataStream &stream, const QQmlProfilerEvent &event);
+
+Q_DECLARE_TYPEINFO(QQmlProfilerEvent, Q_MOVABLE_TYPE);
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QQmlProfilerEvent)
+
+#endif // QQMLPROFILEREVENT_P_H
diff --git a/src/qmldebug/qqmlprofilereventlocation.cpp b/src/qmldebug/qqmlprofilereventlocation.cpp
new file mode 100644
index 0000000000..8be44c17a3
--- /dev/null
+++ b/src/qmldebug/qqmlprofilereventlocation.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmlprofilereventlocation_p.h"
+
+#include <QtCore/qdatastream.h>
+
+QT_BEGIN_NAMESPACE
+
+QDataStream &operator>>(QDataStream &stream, QQmlProfilerEventLocation &location)
+{
+ return stream >> location.m_filename >> location.m_line >> location.m_column;
+}
+
+QDataStream &operator<<(QDataStream &stream, const QQmlProfilerEventLocation &location)
+{
+ return stream << location.m_filename << location.m_line << location.m_column;
+}
+
+QT_END_NAMESPACE
diff --git a/src/qmldebug/qqmlprofilereventlocation_p.h b/src/qmldebug/qqmlprofilereventlocation_p.h
new file mode 100644
index 0000000000..6f37eab14b
--- /dev/null
+++ b/src/qmldebug/qqmlprofilereventlocation_p.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLPROFILEREVENTLOCATION_P_H
+#define QQMLPROFILEREVENTLOCATION_P_H
+
+#include <QtCore/qstring.h>
+#include <QtCore/qhash.h>
+#include <QtCore/qdatastream.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+class QQmlProfilerEventLocation
+{
+public:
+ QQmlProfilerEventLocation() : m_line(-1),m_column(-1) {}
+ QQmlProfilerEventLocation(const QString &file, int lineNumber, int columnNumber) :
+ m_filename(file), m_line(lineNumber), m_column(columnNumber)
+ {}
+
+ void clear()
+ {
+ m_filename.clear();
+ m_line = m_column = -1;
+ }
+
+ bool isValid() const
+ {
+ return !m_filename.isEmpty();
+ }
+
+ QString filename() const { return m_filename; }
+ int line() const { return m_line; }
+ int column() const { return m_column; }
+
+private:
+ friend QDataStream &operator>>(QDataStream &stream, QQmlProfilerEventLocation &location);
+ friend QDataStream &operator<<(QDataStream &stream, const QQmlProfilerEventLocation &location);
+
+ QString m_filename;
+ int m_line;
+ int m_column;
+};
+
+inline bool operator==(const QQmlProfilerEventLocation &location1,
+ const QQmlProfilerEventLocation &location2)
+{
+ // compare filename last as it's expensive.
+ return location1.line() == location2.line() && location1.column() == location2.column()
+ && location1.filename() == location2.filename();
+}
+
+inline bool operator!=(const QQmlProfilerEventLocation &location1,
+ const QQmlProfilerEventLocation &location2)
+{
+ return !(location1 == location2);
+}
+
+inline uint qHash(const QQmlProfilerEventLocation &location)
+{
+ return qHash(location.filename())
+ ^ ((location.line() & 0xfff) // 12 bits of line number
+ | ((location.column() << 16) & 0xff0000)); // 8 bits of column
+
+}
+
+QDataStream &operator>>(QDataStream &stream, QQmlProfilerEventLocation &location);
+QDataStream &operator<<(QDataStream &stream, const QQmlProfilerEventLocation &location);
+
+Q_DECLARE_TYPEINFO(QQmlProfilerEventLocation, Q_MOVABLE_TYPE);
+
+QT_END_NAMESPACE
+
+#endif // QQMLPROFILEREVENTLOCATION_P_H
diff --git a/src/qmldebug/qqmlprofilereventreceiver_p.h b/src/qmldebug/qqmlprofilereventreceiver_p.h
new file mode 100644
index 0000000000..defe64a42e
--- /dev/null
+++ b/src/qmldebug/qqmlprofilereventreceiver_p.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLPROFILEREVENTRECEIVER_P_H
+#define QQMLPROFILEREVENTRECEIVER_P_H
+
+#include "qqmlprofilerevent_p.h"
+#include "qqmlprofilereventtype_p.h"
+
+#include <QtCore/qobject.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+class QQmlProfilerEventReceiver : public QObject
+{
+ Q_OBJECT
+public:
+ QQmlProfilerEventReceiver(QObject *parent = nullptr) : QObject(parent) {}
+
+ virtual int numLoadedEventTypes() const = 0;
+ virtual void addEventType(const QQmlProfilerEventType &type) = 0;
+ virtual void addEvent(const QQmlProfilerEvent &event) = 0;
+};
+
+QT_END_NAMESPACE
+
+#endif // QQMLPROFILEREVENTRECEIVER_P_H
diff --git a/src/qmldebug/qqmlprofilereventtype.cpp b/src/qmldebug/qqmlprofilereventtype.cpp
new file mode 100644
index 0000000000..b0aad3fc5b
--- /dev/null
+++ b/src/qmldebug/qqmlprofilereventtype.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmlprofilereventtype_p.h"
+
+#include <QtCore/qdatastream.h>
+
+QT_BEGIN_NAMESPACE
+
+QDataStream &operator>>(QDataStream &stream, QQmlProfilerEventType &type)
+{
+ quint8 message;
+ quint8 rangeType;
+ stream >> type.m_displayName >> type.m_data >> type.m_location >> message >> rangeType
+ >> type.m_detailType;
+ type.m_message = static_cast<QQmlProfilerDefinitions::Message>(message);
+ type.m_rangeType = static_cast<QQmlProfilerDefinitions::RangeType>(rangeType);
+ return stream;
+}
+
+QDataStream &operator<<(QDataStream &stream, const QQmlProfilerEventType &type)
+{
+ return stream << type.m_displayName << type.m_data << type.m_location
+ << static_cast<quint8>(type.m_message) << static_cast<quint8>(type.m_rangeType)
+ << type.m_detailType;
+}
+
+QQmlProfilerDefinitions::ProfileFeature QQmlProfilerEventType::feature() const
+{
+ switch (m_message) {
+ case Event: {
+ switch (m_detailType) {
+ case Mouse:
+ case Key:
+ return ProfileInputEvents;
+ case AnimationFrame:
+ return ProfileAnimations;
+ default:
+ return MaximumProfileFeature;
+ }
+ }
+ case PixmapCacheEvent:
+ return ProfilePixmapCache;
+ case SceneGraphFrame:
+ return ProfileSceneGraph;
+ case MemoryAllocation:
+ return ProfileMemory;
+ case DebugMessage:
+ return ProfileDebugMessages;
+ default:
+ return featureFromRangeType(m_rangeType);
+ }
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/qmldebug/qqmlprofilereventtype_p.h b/src/qmldebug/qqmlprofilereventtype_p.h
new file mode 100644
index 0000000000..7bd67f9ca8
--- /dev/null
+++ b/src/qmldebug/qqmlprofilereventtype_p.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLPROFILEREVENTTYPE_P_H
+#define QQMLPROFILEREVENTTYPE_P_H
+
+#include "qqmlprofilereventlocation_p.h"
+
+#include <private/qqmlprofilerdefinitions_p.h>
+
+#include <QtCore/qstring.h>
+#include <QtCore/qmetatype.h>
+#include <QtCore/qhash.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+class QQmlProfilerEventType : public QQmlProfilerDefinitions {
+public:
+ QQmlProfilerEventType(Message message = MaximumMessage, RangeType rangeType = MaximumRangeType,
+ int detailType = -1,
+ const QQmlProfilerEventLocation &location = QQmlProfilerEventLocation(),
+ const QString &data = QString(), const QString displayName = QString()) :
+ m_displayName(displayName), m_data(data), m_location(location), m_message(message),
+ m_rangeType(rangeType), m_detailType(detailType)
+ {}
+
+ void setDisplayName(const QString &displayName) { m_displayName = displayName; }
+ void setData(const QString &data) { m_data = data; }
+ void setLocation(const QQmlProfilerEventLocation &location) { m_location = location; }
+
+ ProfileFeature feature() const;
+ QString displayName() const { return m_displayName; }
+ QString data() const { return m_data; }
+ QQmlProfilerEventLocation location() const { return m_location; }
+ Message message() const { return m_message; }
+ RangeType rangeType() const { return m_rangeType; }
+ int detailType() const { return m_detailType; }
+
+private:
+ friend QDataStream &operator>>(QDataStream &stream, QQmlProfilerEventType &type);
+ friend QDataStream &operator<<(QDataStream &stream, const QQmlProfilerEventType &type);
+
+ QString m_displayName;
+ QString m_data;
+ QQmlProfilerEventLocation m_location;
+ Message m_message;
+ RangeType m_rangeType;
+ int m_detailType; // can be EventType, BindingType, PixmapEventType or SceneGraphFrameType
+};
+
+QDataStream &operator>>(QDataStream &stream, QQmlProfilerEventType &type);
+QDataStream &operator<<(QDataStream &stream, const QQmlProfilerEventType &type);
+
+inline uint qHash(const QQmlProfilerEventType &type)
+{
+ return qHash(type.location())
+ ^ (((type.message() << 12) & 0xf000) // 4 bits message
+ | ((type.rangeType() << 24) & 0xf000000) // 4 bits rangeType
+ | ((static_cast<uint>(type.detailType()) << 28) & 0xf0000000)); // 4 bits detailType
+}
+
+inline bool operator==(const QQmlProfilerEventType &type1, const QQmlProfilerEventType &type2)
+{
+ return type1.message() == type2.message() && type1.rangeType() == type2.rangeType()
+ && type1.detailType() == type2.detailType() && type1.location() == type2.location();
+}
+
+inline bool operator!=(const QQmlProfilerEventType &type1, const QQmlProfilerEventType &type2)
+{
+ return !(type1 == type2);
+}
+
+Q_DECLARE_TYPEINFO(QQmlProfilerEventType, Q_MOVABLE_TYPE);
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QQmlProfilerEventType)
+
+#endif // QQMLPROFILEREVENTTYPE_P_H
diff --git a/src/qmldebug/qqmlprofilertypedevent.cpp b/src/qmldebug/qqmlprofilertypedevent.cpp
new file mode 100644
index 0000000000..9b00481e17
--- /dev/null
+++ b/src/qmldebug/qqmlprofilertypedevent.cpp
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmlprofilertypedevent_p.h"
+#include <QtCore/qvarlengtharray.h>
+
+QT_BEGIN_NAMESPACE
+
+QDataStream &operator>>(QDataStream &stream, QQmlProfilerTypedEvent &event)
+{
+ qint64 time;
+ qint32 messageType;
+ qint32 subtype;
+
+ stream >> time >> messageType;
+
+ if (messageType < 0 || messageType > QQmlProfilerDefinitions::MaximumMessage)
+ messageType = QQmlProfilerDefinitions::MaximumMessage;
+
+ QQmlProfilerDefinitions::RangeType rangeType = QQmlProfilerDefinitions::MaximumRangeType;
+ if (!stream.atEnd()) {
+ stream >> subtype;
+ rangeType = static_cast<QQmlProfilerDefinitions::RangeType>(subtype);
+ if (rangeType < 0 || rangeType > QQmlProfilerDefinitions::MaximumRangeType)
+ rangeType = QQmlProfilerDefinitions::MaximumRangeType;
+ } else {
+ subtype = -1;
+ }
+
+ event.event.setTimestamp(time > 0 ? time : 0);
+ event.event.setTypeIndex(-1);
+ event.serverTypeId = 0;
+
+ switch (messageType) {
+ case QQmlProfilerDefinitions::Event: {
+ event.type = QQmlProfilerEventType(
+ static_cast<QQmlProfilerDefinitions::Message>(messageType),
+ QQmlProfilerDefinitions::MaximumRangeType, subtype);
+ switch (subtype) {
+ case QQmlProfilerDefinitions::StartTrace:
+ case QQmlProfilerDefinitions::EndTrace: {
+ QVarLengthArray<qint32> engineIds;
+ while (!stream.atEnd()) {
+ qint32 id;
+ stream >> id;
+ engineIds << id;
+ }
+ event.event.setNumbers<QVarLengthArray<qint32>, qint32>(engineIds);
+ break;
+ }
+ case QQmlProfilerDefinitions::AnimationFrame: {
+ qint32 frameRate, animationCount;
+ qint32 threadId;
+ stream >> frameRate >> animationCount;
+ if (!stream.atEnd())
+ stream >> threadId;
+ else
+ threadId = 0;
+
+ event.event.setNumbers<qint32>({frameRate, animationCount, threadId});
+ break;
+ }
+ case QQmlProfilerDefinitions::Mouse:
+ case QQmlProfilerDefinitions::Key:
+ int inputType = (subtype == QQmlProfilerDefinitions::Key
+ ? QQmlProfilerDefinitions::InputKeyUnknown
+ : QQmlProfilerDefinitions::InputMouseUnknown);
+ if (!stream.atEnd())
+ stream >> inputType;
+ qint32 a = -1;
+ if (!stream.atEnd())
+ stream >> a;
+ qint32 b = -1;
+ if (!stream.atEnd())
+ stream >> b;
+
+ event.event.setNumbers<qint32>({inputType, a, b});
+ break;
+ }
+
+ break;
+ }
+ case QQmlProfilerDefinitions::Complete: {
+ event.type = QQmlProfilerEventType(
+ static_cast<QQmlProfilerDefinitions::Message>(messageType),
+ QQmlProfilerDefinitions::MaximumRangeType, subtype);
+ break;
+ }
+ case QQmlProfilerDefinitions::SceneGraphFrame: {
+ QVarLengthArray<qint64> params;
+ qint64 param;
+
+ while (!stream.atEnd()) {
+ stream >> param;
+ params.push_back(param);
+ }
+
+ event.type = QQmlProfilerEventType(
+ static_cast<QQmlProfilerDefinitions::Message>(messageType),
+ QQmlProfilerDefinitions::MaximumRangeType, subtype);
+ event.event.setNumbers<QVarLengthArray<qint64>, qint64>(params);
+ break;
+ }
+ case QQmlProfilerDefinitions::PixmapCacheEvent: {
+ qint32 width = 0, height = 0, refcount = 0;
+ QString filename;
+ stream >> filename;
+ if (subtype == QQmlProfilerDefinitions::PixmapReferenceCountChanged
+ || subtype == QQmlProfilerDefinitions::PixmapCacheCountChanged) {
+ stream >> refcount;
+ } else if (subtype == QQmlProfilerDefinitions::PixmapSizeKnown) {
+ stream >> width >> height;
+ refcount = 1;
+ }
+
+ event.type = QQmlProfilerEventType(
+ static_cast<QQmlProfilerDefinitions::Message>(messageType),
+ QQmlProfilerDefinitions::MaximumRangeType, subtype,
+ QQmlProfilerEventLocation(filename, 0, 0));
+ event.event.setNumbers<qint32>({width, height, refcount});
+ break;
+ }
+ case QQmlProfilerDefinitions::MemoryAllocation: {
+ qint64 delta;
+ stream >> delta;
+
+ event.type = QQmlProfilerEventType(
+ static_cast<QQmlProfilerDefinitions::Message>(messageType),
+ QQmlProfilerDefinitions::MaximumRangeType, subtype);
+ event.event.setNumbers<qint64>({delta});
+ break;
+ }
+ case QQmlProfilerDefinitions::RangeStart: {
+ if (!stream.atEnd()) {
+ qint64 typeId;
+ stream >> typeId;
+ if (stream.status() == QDataStream::Ok)
+ event.serverTypeId = typeId;
+ // otherwise it's the old binding type of 4 bytes
+ }
+
+ event.type = QQmlProfilerEventType(QQmlProfilerDefinitions::MaximumMessage, rangeType, -1);
+ event.event.setRangeStage(QQmlProfilerDefinitions::RangeStart);
+ break;
+ }
+ case QQmlProfilerDefinitions::RangeData: {
+ QString data;
+ stream >> data;
+
+ event.type = QQmlProfilerEventType(QQmlProfilerDefinitions::MaximumMessage, rangeType, -1,
+ QQmlProfilerEventLocation(), data);
+ event.event.setRangeStage(QQmlProfilerDefinitions::RangeData);
+ if (!stream.atEnd())
+ stream >> event.serverTypeId;
+ break;
+ }
+ case QQmlProfilerDefinitions::RangeLocation: {
+ QString filename;
+ qint32 line = 0;
+ qint32 column = 0;
+ stream >> filename >> line;
+
+ if (!stream.atEnd()) {
+ stream >> column;
+ if (!stream.atEnd())
+ stream >> event.serverTypeId;
+ }
+
+ event.type = QQmlProfilerEventType(QQmlProfilerDefinitions::MaximumMessage, rangeType, -1,
+ QQmlProfilerEventLocation(filename, line, column));
+ event.event.setRangeStage(QQmlProfilerDefinitions::RangeLocation);
+ break;
+ }
+ case QQmlProfilerDefinitions::RangeEnd: {
+ event.type = QQmlProfilerEventType(QQmlProfilerDefinitions::MaximumMessage, rangeType, -1);
+ event.event.setRangeStage(QQmlProfilerDefinitions::RangeEnd);
+ break;
+ }
+ default:
+ event.event.setNumbers<char>({});
+ event.type = QQmlProfilerEventType(
+ static_cast<QQmlProfilerDefinitions::Message>(messageType),
+ QQmlProfilerDefinitions::MaximumRangeType, subtype);
+ break;
+ }
+
+ return stream;
+}
+
+QT_END_NAMESPACE
diff --git a/src/qmldebug/qqmlprofilertypedevent_p.h b/src/qmldebug/qqmlprofilertypedevent_p.h
new file mode 100644
index 0000000000..e7e947f2ef
--- /dev/null
+++ b/src/qmldebug/qqmlprofilertypedevent_p.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLPROFILERTYPEDEVENT_P_H
+#define QQMLPROFILERTYPEDEVENT_P_H
+
+#include "qqmlprofilerevent_p.h"
+#include "qqmlprofilereventtype_p.h"
+
+#include <QtCore/qdatastream.h>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+struct QQmlProfilerTypedEvent
+{
+ QQmlProfilerEvent event;
+ QQmlProfilerEventType type;
+ qint64 serverTypeId = 0;
+};
+
+QDataStream &operator>>(QDataStream &stream, QQmlProfilerTypedEvent &event);
+
+Q_DECLARE_TYPEINFO(QQmlProfilerTypedEvent, Q_MOVABLE_TYPE);
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QQmlProfilerTypedEvent)
+
+#endif // QQMLPROFILERTYPEDEVENT_P_H
diff --git a/src/qmldevtools/qmldevtools.pro b/src/qmldevtools/qmldevtools.pro
index a21988b915..5ee97776b8 100644
--- a/src/qmldevtools/qmldevtools.pro
+++ b/src/qmldevtools/qmldevtools.pro
@@ -16,6 +16,5 @@ include(../qml/parser/parser.pri)
include(../qml/jsruntime/jsruntime.pri)
include(../qml/compiler/compiler.pri)
include(../qml/memory/memory.pri)
-include(../qml/jit/jit.pri)
load(qt_module)
diff --git a/src/qmltest/doc/qtqmltest.qdocconf b/src/qmltest/doc/qtqmltest.qdocconf
new file mode 100644
index 0000000000..e51007d2b2
--- /dev/null
+++ b/src/qmltest/doc/qtqmltest.qdocconf
@@ -0,0 +1,42 @@
+include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
+
+project = QtQuickTest
+description = Qt Quick Test Reference Documentation
+version = $QT_VERSION
+
+qhp.projects = QtQuickTest
+
+qhp.QtQuickTest.file = qtqmltest.qhp
+qhp.QtQuickTest.namespace = org.qt-project.qtquicktest.$QT_VERSION_TAG
+qhp.QtQuickTest.virtualFolder = qtquicktest
+qhp.QtQuickTest.indexTitle = Qt Quick Test
+qhp.QtQuickTest.indexRoot =
+
+qhp.QtQuickTest.filterAttributes = qtquicktest $QT_VERSION qtrefdoc
+qhp.QtQuickTest.customFilters.Qt.name = QtQuickTest $QT_VERSION
+qhp.QtQuickTest.customFilters.Qt.filterAttributes = qtquicktest $QT_VERSION
+qhp.QtQuickTest.subprojects = qmltypes classes examples
+qhp.QtQuickTest.subprojects.classes.title = C++ Classes
+qhp.QtQuickTest.subprojects.classes.indexTitle = Qt Quick Test C++ Classes
+qhp.QtQuickTest.subprojects.classes.selectors = class doc:headerfile
+qhp.QtQuickTest.subprojects.classes.sortPages = true
+qhp.QtQuickTest.subprojects.examples.title = Examples
+qhp.QtQuickTest.subprojects.examples.indexTitle = Qt Quick Test Examples
+qhp.QtQuickTest.subprojects.examples.selectors = doc:example
+qhp.QtQuickTest.subprojects.qmltypes.title = QML Types
+qhp.QtQuickTest.subprojects.qmltypes.indexTitle = Qt Quick Test QML Types
+qhp.QtQuickTest.subprojects.qmltypes.selectors = qmlclass
+qhp.QtQuickTest.subprojects.qmltypes.sortPages = true
+
+
+tagfile = ../../../doc/qtquicktest/qtquicktest.tags
+
+depends += qtcore qtxmlpatterns qtgui qttestlib qtqml qtquick qtdoc
+
+headerdirs += ..
+
+sourcedirs += ..
+
+navigation.landingpage = "Qt Quick Test"
+navigation.cppclassespage = "Qt Quick Test C++ Classes"
+navigation.qmltypespage = "Qt Quick Test QML Types"
diff --git a/src/qmltest/doc/src/qtquicktest-index.qdoc b/src/qmltest/doc/src/qtquicktest-index.qdoc
new file mode 100644
index 0000000000..6b5f8fdf4c
--- /dev/null
+++ b/src/qmltest/doc/src/qtquicktest-index.qdoc
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** 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. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \page qtquicktest-index.html
+ \title Qt Quick Test
+ \brief Unit testing framework for QML.
+
+ \section1 Introduction
+
+ \l {Qt Quick Test QML Types}{Qt Quick Test} is a unit test framework for QML applications.
+ Test cases are written as JavaScript functions within a \l [QML] TestCase
+ type:
+
+ \qml
+ import QtQuick 2.3
+ import QtTest 1.0
+
+ TestCase {
+ name: "MathTests"
+
+ function test_math() {
+ compare(2 + 2, 4, "2 + 2 = 4")
+ }
+
+ function test_fail() {
+ compare(2 + 2, 5, "2 + 2 = 5")
+ }
+ }
+ \endqml
+
+ Functions whose names start with \c{test_} are treated as test cases
+ to be executed. See the documentation for the \l [QML] TestCase and
+ \l [QML] SignalSpy types for more information on writing test cases.
+
+ \section1 Running Tests
+
+ Test cases are launched by a C++ harness that consists of
+ the following code:
+
+ \code
+ #include <QtQuickTest/quicktest.h>
+ QUICK_TEST_MAIN(example)
+ \endcode
+
+ Where "example" is the identifier to use to uniquely identify
+ this set of tests. Finally, add \c{CONFIG += qmltestcase} to the project
+ file:
+
+ \badcode
+ TEMPLATE = app
+ TARGET = tst_example
+ CONFIG += warn_on qmltestcase
+ SOURCES += tst_example.cpp
+ \endcode
+
+ The test harness scans the specified source directory recursively
+ for "tst_*.qml" files. If \c{QUICK_TEST_SOURCE_DIR} is not defined,
+ then the current directory will be scanned when the harness is run.
+ Other *.qml files may appear for auxillary QML components that are
+ used by the test.
+
+ The \c{-input} command-line option can be set at runtime to run
+ test cases from a different directory. This may be needed to run
+ tests on a target device where the compiled-in directory name refers
+ to a host. For example:
+
+ \badcode
+ tst_example -input /mnt/SDCard/qmltests
+ \endcode
+
+ It is also possible to run a single file using the \c{-input} option.
+ For example:
+
+ \badcode
+ tst_example -input data/test.qml
+ \endcode
+
+ \badcode
+ tst_example -input <full_path>/test.qml
+ \endcode
+
+ \note Specifying the full path to the qml test file is for example
+ needed for shadow builds.
+
+ If your test case needs QML imports, then you can add them as
+ \c{-import} options to the test program command-line.
+
+ If \c IMPORTPATH is specified in your .pro file, each import path added to \c IMPORTPATH
+ will be passed as a command-line argument when the test is run using "make check":
+
+ \badcode
+ IMPORTPATH += $$PWD/../imports/my_module1 $$PWD/../imports/my_module2
+ \endcode
+
+ The \c{-functions} command-line option will return a list of the current
+ tests functions. It is possible to run a single test function using the name
+ of the test function as an argument. For example:
+
+ \badcode
+ tst_example Test_Name::function1
+ \endcode
+
+ The \c{-help} command-line option will return all the options available.
+
+ \badcode
+ tst_example -help
+ \endcode
+
+ \section1 Executing C++ Before QML Tests
+
+ To execute C++ code before any of the QML tests are run, the
+ \c QUICK_TEST_MAIN_WITH_SETUP macro can be used. This can be useful for
+ setting context properties on the QML engine, amongst other things.
+
+ The macro is identical to \l QUICK_TEST_MAIN, except that it takes an
+ additional \c QObject* argument. The test framework will call slots and
+ invokable functions with the following names:
+
+ \table
+ \header
+ \li Name
+ \li Purpose
+ \row
+ \li void qmlEngineAvailable(QQmlEngine*)
+ \li Called when the QML engine is available.
+ Any \l {QQmlEngine::addImportPath}{import paths},
+ \l {QQmlEngine::addPluginPath}{plugin paths},
+ and \l {QQmlFileSelector::setExtraSelectors}{extra file selectors}
+ will have been set on the engine by this point.
+ \endtable
+
+ Each function will be called once for each \c tst_*.qml file, so any
+ arguments are unique to that test. For example, this means that each QML
+ test file will have its own QML engine.
+
+ The following example demonstrates how the macro can be used to set context
+ properties on the QML engine:
+
+ \code
+ #include <QtQuickTest>
+ #include <QQmlEngine>
+ #include <QQmlContext>
+
+ class Setup : public QObject
+ {
+ public:
+ Setup() {}
+
+ public slots:
+ void qmlEngineAvailable(QQmlEngine *engine)
+ {
+ engine->rootContext()->setContextProperty("myContextProperty", QVariant(true));
+ }
+ };
+
+ QUICK_TEST_MAIN_WITH_SETUP(mytest, Setup)
+
+ #include "tst_mytest.moc"
+ \endcode
+*/
diff --git a/src/qmltest/qmltest.pro b/src/qmltest/qmltest.pro
index c36cdb5b87..e2200e5abb 100644
--- a/src/qmltest/qmltest.pro
+++ b/src/qmltest/qmltest.pro
@@ -1,5 +1,7 @@
TARGET = QtQuickTest
+QMAKE_DOCS = $$PWD/doc/qtqmltest.qdocconf
+
DEFINES += QT_NO_URL_CAST_FROM_STRING QT_NO_FOREACH
QT = core testlib-private
QT_PRIVATE = quick qml-private gui core-private gui-private
@@ -24,6 +26,6 @@ HEADERS += \
$$PWD/quicktestresult_p.h \
$$PWD/qtestoptions_p.h
-!contains(QT_CONFIG, no-qml-debug): DEFINES += QT_QML_DEBUG_NO_WARNING
+qtConfig(qml-debug): DEFINES += QT_QML_DEBUG_NO_WARNING
load(qt_module)
diff --git a/src/qmltest/quicktest.cpp b/src/qmltest/quicktest.cpp
index 8cf0d2918e..817f9a5389 100644
--- a/src/qmltest/quicktest.cpp
+++ b/src/qmltest/quicktest.cpp
@@ -62,6 +62,9 @@
#include <QtGui/QGuiApplication>
#include <QtCore/QTranslator>
#include <QtTest/QSignalSpy>
+#include <QtQml/QQmlFileSelector>
+
+#include <private/qqmlcomponent_p.h>
#ifdef QT_QMLTEST_WITH_WIDGETS
#include <QtWidgets/QApplication>
@@ -87,7 +90,7 @@ public:
static QTestRootObject *instance() {
static QPointer<QTestRootObject> object = new QTestRootObject;
if (!object) {
- qWarning("A new test root object has been created, the behavior may be compromised");
+ // QTestRootObject was deleted when previous test ended, create a new one
object = new QTestRootObject;
}
return object;
@@ -195,8 +198,140 @@ bool qWaitForSignal(QObject *obj, const char* signal, int timeout = 5000)
return spy.size();
}
+using namespace QV4::CompiledData;
+
+class TestCaseCollector
+{
+public:
+ typedef QList<QString> TestCaseList;
+
+ TestCaseCollector(const QFileInfo &fileInfo, QQmlEngine *engine)
+ {
+ QQmlComponent component(engine, fileInfo.absoluteFilePath());
+ m_errors += component.errors();
+
+ if (component.isReady()) {
+ CompilationUnit *rootCompilationUnit = QQmlComponentPrivate::get(&component)->compilationUnit;
+ TestCaseEnumerationResult result = enumerateTestCases(rootCompilationUnit);
+ m_testCases = result.testCases + result.finalizedPartialTestCases();
+ m_errors += result.errors;
+ }
+ }
+
+ TestCaseList testCases() const { return m_testCases; }
+ QList<QQmlError> errors() const { return m_errors; }
+
+private:
+ TestCaseList m_testCases;
+ QList<QQmlError> m_errors;
+
+ struct TestCaseEnumerationResult
+ {
+ TestCaseList testCases;
+ QList<QQmlError> errors;
+
+ // Partially constructed test cases
+ bool isTestCase = false;
+ TestCaseList testFunctions;
+ QString testCaseName;
+
+ TestCaseList finalizedPartialTestCases() const
+ {
+ TestCaseList result;
+ for (const QString &function : testFunctions)
+ result << QString(QStringLiteral("%1::%2")).arg(testCaseName).arg(function);
+ return result;
+ }
+
+ TestCaseEnumerationResult &operator<<(const TestCaseEnumerationResult &other)
+ {
+ testCases += other.testCases + other.finalizedPartialTestCases();
+ errors += other.errors;
+ return *this;
+ }
+ };
+
+ TestCaseEnumerationResult enumerateTestCases(CompilationUnit *compilationUnit, const Object *object = nullptr)
+ {
+ QQmlType testCaseType;
+ for (quint32 i = 0; i < compilationUnit->data->nImports; ++i) {
+ const Import *import = compilationUnit->data->importAt(i);
+ if (compilationUnit->stringAt(import->uriIndex) != QLatin1Literal("QtTest"))
+ continue;
+
+ QString testCaseTypeName(QStringLiteral("TestCase"));
+ QString typeQualifier = compilationUnit->stringAt(import->qualifierIndex);
+ if (!typeQualifier.isEmpty())
+ testCaseTypeName = typeQualifier % QLatin1Char('.') % testCaseTypeName;
+
+ testCaseType = compilationUnit->typeNameCache->query(testCaseTypeName).type;
+ if (testCaseType.isValid())
+ break;
+ }
+
+ TestCaseEnumerationResult result;
+
+ if (!object) // Start at root of compilation unit if not enumerating a specific child
+ object = compilationUnit->objectAt(0);
+
+ if (CompilationUnit *superTypeUnit = compilationUnit->resolvedTypes.value(object->inheritedTypeNameIndex)->compilationUnit) {
+ // We have a non-C++ super type, which could indicate we're a subtype of a TestCase
+ if (testCaseType.isValid() && superTypeUnit->url() == testCaseType.sourceUrl())
+ result.isTestCase = true;
+ else
+ result = enumerateTestCases(superTypeUnit);
+
+ if (result.isTestCase) {
+ // Look for override of name in this type
+ for (auto binding = object->bindingsBegin(); binding != object->bindingsEnd(); ++binding) {
+ if (compilationUnit->stringAt(binding->propertyNameIndex) == QLatin1Literal("name")) {
+ if (binding->type == QV4::CompiledData::Binding::Type_String) {
+ result.testCaseName = compilationUnit->stringAt(binding->stringIndex);
+ } else {
+ QQmlError error;
+ error.setUrl(compilationUnit->url());
+ error.setLine(binding->location.line);
+ error.setColumn(binding->location.column);
+ error.setDescription(QStringLiteral("the 'name' property of a TestCase must be a literal string"));
+ result.errors << error;
+ }
+ break;
+ }
+ }
+
+ // Look for additional functions in this type
+ auto functionsEnd = compilationUnit->objectFunctionsEnd(object);
+ for (auto function = compilationUnit->objectFunctionsBegin(object); function != functionsEnd; ++function) {
+ QString functionName = compilationUnit->stringAt(function->nameIndex);
+ if (!(functionName.startsWith(QLatin1Literal("test_")) || functionName.startsWith(QLatin1Literal("benchmark_"))))
+ continue;
+
+ if (functionName.endsWith(QLatin1Literal("_data")))
+ continue;
+
+ result.testFunctions << functionName;
+ }
+ }
+ }
+
+ for (auto binding = object->bindingsBegin(); binding != object->bindingsEnd(); ++binding) {
+ if (binding->type == QV4::CompiledData::Binding::Type_Object) {
+ const Object *child = compilationUnit->objectAt(binding->value.objectIndex);
+ result << enumerateTestCases(compilationUnit, child);
+ }
+ }
+
+ return result;
+ }
+};
+
int quick_test_main(int argc, char **argv, const char *name, const char *sourceDir)
{
+ return quick_test_main_with_setup(argc, argv, name, sourceDir, nullptr);
+}
+
+int quick_test_main_with_setup(int argc, char **argv, const char *name, const char *sourceDir, QObject *setup)
+{
// Peek at arguments to check for '-widgets' argument
#ifdef QT_QMLTEST_WITH_WIDGETS
bool withWidgets = false;
@@ -225,10 +360,12 @@ int quick_test_main(int argc, char **argv, const char *name, const char *sourceD
// -plugins dir Specify a directory where to search for plugins.
// -input dir Specify the input directory for test cases.
// -translation file Specify the translation file.
+ // -file-selector Specify a file selector
QStringList imports;
QStringList pluginPaths;
QString testPath;
QString translationFile;
+ QStringList fileSelectors;
int index = 1;
QScopedArrayPointer<char *> testArgV(new char *[argc + 1]);
testArgV[0] = argv[0];
@@ -253,6 +390,9 @@ int quick_test_main(int argc, char **argv, const char *name, const char *sourceD
} else if (strcmp(argv[index], "-translation") == 0 && (index + 1) < argc) {
translationFile = stripQuotes(QString::fromLocal8Bit(argv[index + 1]));
index += 2;
+ } else if (strcmp(argv[index], "-file-selector") == 0 && (index + 1) < argc) {
+ fileSelectors += stripQuotes(QString::fromLocal8Bit(argv[index + 1]));
+ index += 2;
} else {
testArgV[testArgC++] = argv[index++];
}
@@ -331,43 +471,77 @@ int quick_test_main(int argc, char **argv, const char *name, const char *sourceD
// Register the test object
qmlRegisterSingletonType<QTestRootObject>("Qt.test.qtestroot", 1, 0, "QTestRootObject", testRootObject);
+
// Scan through all of the "tst_*.qml" files and run each of them
- // in turn with a QQuickView.
- QQuickView *view = new QQuickView;
- view->setFlags(Qt::Window | Qt::WindowSystemMenuHint
- | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint
- | Qt::WindowCloseButtonHint);
- QEventLoop eventLoop;
- QObject::connect(view->engine(), SIGNAL(quit()),
- QTestRootObject::instance(), SLOT(quit()));
- QObject::connect(view->engine(), SIGNAL(quit()),
- &eventLoop, SLOT(quit()));
- view->rootContext()->setContextProperty
- (QLatin1String("qtest"), QTestRootObject::instance()); // Deprecated. Use QTestRootObject from Qt.test.qtestroot instead
- for (const QString &path : qAsConst(imports))
- view->engine()->addImportPath(path);
- for (const QString &path : qAsConst(pluginPaths))
- view->engine()->addPluginPath(path);
+ // in turn with a separate QQuickView (for test isolation).
for (const QString &file : qAsConst(files)) {
const QFileInfo fi(file);
if (!fi.exists())
continue;
- view->setObjectName(fi.baseName());
- view->setTitle(view->objectName());
+ QQmlEngine engine;
+ for (const QString &path : qAsConst(imports))
+ engine.addImportPath(path);
+ for (const QString &path : qAsConst(pluginPaths))
+ engine.addPluginPath(path);
+
+ if (!fileSelectors.isEmpty()) {
+ QQmlFileSelector* const qmlFileSelector = new QQmlFileSelector(&engine, &engine);
+ qmlFileSelector->setExtraSelectors(fileSelectors);
+ }
+
+ TestCaseCollector testCaseCollector(fi, &engine);
+ if (!testCaseCollector.errors().isEmpty()) {
+ for (const QQmlError &error : testCaseCollector.errors())
+ qWarning() << error;
+ exit(1);
+ }
+
+ TestCaseCollector::TestCaseList availableTestFunctions = testCaseCollector.testCases();
+ if (QTest::printAvailableFunctions) {
+ for (const QString &function : availableTestFunctions)
+ qDebug("%s()", qPrintable(function));
+ continue;
+ }
+
+ static const QSet<QString> commandLineTestFunctions = QTest::testFunctions.toSet();
+ if (!commandLineTestFunctions.isEmpty() &&
+ !availableTestFunctions.toSet().intersects(commandLineTestFunctions))
+ continue;
+
+ QQuickView view(&engine, nullptr);
+ view.setFlags(Qt::Window | Qt::WindowSystemMenuHint
+ | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint
+ | Qt::WindowCloseButtonHint);
+ QEventLoop eventLoop;
+ QObject::connect(view.engine(), SIGNAL(quit()),
+ QTestRootObject::instance(), SLOT(quit()));
+ QObject::connect(view.engine(), SIGNAL(quit()),
+ &eventLoop, SLOT(quit()));
+ view.rootContext()->setContextProperty
+ (QLatin1String("qtest"), QTestRootObject::instance()); // Deprecated. Use QTestRootObject from Qt.test.qtestroot instead
+
+ // Do this down here so that import paths, plugin paths,
+ // file selectors, etc. are available in case the user needs access to them.
+ if (setup) {
+ // Don't check the return value; it's OK if it doesn't exist.
+ // If we add more callbacks in the future, it makes sense if the user only implements one of them.
+ QMetaObject::invokeMethod(setup, "qmlEngineAvailable", Q_ARG(QQmlEngine*, view.engine()));
+ }
+
+ view.setObjectName(fi.baseName());
+ view.setTitle(view.objectName());
QTestRootObject::instance()->init();
QString path = fi.absoluteFilePath();
if (path.startsWith(QLatin1String(":/")))
- view->setSource(QUrl(QLatin1String("qrc:") + path.midRef(2)));
+ view.setSource(QUrl(QLatin1String("qrc:") + path.midRef(2)));
else
- view->setSource(QUrl::fromLocalFile(path));
+ view.setSource(QUrl::fromLocalFile(path));
- if (QTest::printAvailableFunctions)
- continue;
- while (view->status() == QQuickView::Loading)
+ while (view.status() == QQuickView::Loading)
QTest::qWait(10);
- if (view->status() == QQuickView::Error) {
- handleCompileErrors(fi, view);
+ if (view.status() == QQuickView::Error) {
+ handleCompileErrors(fi, &view);
continue;
}
if (!QTestRootObject::instance()->hasQuit) {
@@ -376,21 +550,21 @@ int quick_test_main(int argc, char **argv, const char *name, const char *sourceD
// an asynchronous test and we need to show the window
// and wait for the first frame to be rendered
// and then wait for quit indication.
- view->setFramePosition(QPoint(50, 50));
- if (view->size().isEmpty()) { // Avoid hangs with empty windows.
- view->resize(200, 200);
+ view.setFramePosition(QPoint(50, 50));
+ if (view.size().isEmpty()) { // Avoid hangs with empty windows.
+ view.resize(200, 200);
}
- view->show();
- if (!QTest::qWaitForWindowExposed(view)) {
+ view.show();
+ if (!QTest::qWaitForWindowExposed(&view)) {
qWarning().nospace()
<< "Test '" << QDir::toNativeSeparators(path) << "' window not exposed after show().";
}
- view->requestActivate();
- if (!QTest::qWaitForWindowActive(view)) {
+ view.requestActivate();
+ if (!QTest::qWaitForWindowActive(&view)) {
qWarning().nospace()
<< "Test '" << QDir::toNativeSeparators(path) << "' window not active after requestActivate().";
}
- if (view->isExposed()) {
+ if (view.isExposed()) {
QTestRootObject::instance()->setWindowShown(true);
} else {
qWarning().nospace()
@@ -399,13 +573,11 @@ int quick_test_main(int argc, char **argv, const char *name, const char *sourceD
}
if (!QTestRootObject::instance()->hasQuit && QTestRootObject::instance()->hasTestCase())
eventLoop.exec();
- // view->hide(); Causes a crash in Qt 3D due to deletion of the GL context, see QTBUG-27696
}
}
// Flush the current logging stream.
QuickTestResult::setProgramName(0);
- delete view;
delete app;
// Return the number of failures as the exit code.
diff --git a/src/qmltest/quicktest.h b/src/qmltest/quicktest.h
index 6486accb9e..62ed749722 100644
--- a/src/qmltest/quicktest.h
+++ b/src/qmltest/quicktest.h
@@ -48,6 +48,7 @@ QT_BEGIN_NAMESPACE
QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS
Q_QUICK_TEST_EXPORT int quick_test_main(int argc, char **argv, const char *name, const char *sourceDir);
+Q_QUICK_TEST_EXPORT int quick_test_main_with_setup(int argc, char **argv, const char *name, const char *sourceDir, QObject *setup);
#ifdef QUICK_TEST_SOURCE_DIR
@@ -67,6 +68,15 @@ Q_QUICK_TEST_EXPORT int quick_test_main(int argc, char **argv, const char *name,
return quick_test_main(argc, argv, #name, QUICK_TEST_SOURCE_DIR); \
}
+#define QUICK_TEST_MAIN_WITH_SETUP(name, QuickTestSetupClass) \
+ int main(int argc, char **argv) \
+ { \
+ QTEST_ADD_GPU_BLACKLIST_SUPPORT \
+ QTEST_SET_MAIN_SOURCE_PATH \
+ QuickTestSetupClass setup; \
+ return quick_test_main_with_setup(argc, argv, #name, QUICK_TEST_SOURCE_DIR, &setup); \
+ }
+
#else
#define QUICK_TEST_MAIN(name) \
@@ -74,7 +84,7 @@ Q_QUICK_TEST_EXPORT int quick_test_main(int argc, char **argv, const char *name,
{ \
QTEST_ADD_GPU_BLACKLIST_SUPPORT \
QTEST_SET_MAIN_SOURCE_PATH \
- return quick_test_main(argc, argv, #name, 0); \
+ return quick_test_main(argc, argv, #name, nullptr); \
}
#define QUICK_TEST_OPENGL_MAIN(name) \
@@ -82,7 +92,16 @@ Q_QUICK_TEST_EXPORT int quick_test_main(int argc, char **argv, const char *name,
{ \
QTEST_ADD_GPU_BLACKLIST_SUPPORT \
QTEST_SET_MAIN_SOURCE_PATH \
- return quick_test_main(argc, argv, #name, 0); \
+ return quick_test_main(argc, argv, #name, nullptr); \
+ }
+
+#define QUICK_TEST_MAIN_WITH_SETUP(name, QuickTestSetupClass) \
+ int main(int argc, char **argv) \
+ { \
+ QTEST_ADD_GPU_BLACKLIST_SUPPORT \
+ QTEST_SET_MAIN_SOURCE_PATH \
+ QuickTestSetupClass setup; \
+ return quick_test_main_with_setup(argc, argv, #name, nullptr, &setup); \
}
#endif
diff --git a/src/qmltest/quicktestevent.cpp b/src/qmltest/quicktestevent.cpp
index dc7b917bc4..bf255e9cda 100644
--- a/src/qmltest/quicktestevent.cpp
+++ b/src/qmltest/quicktestevent.cpp
@@ -121,6 +121,23 @@ bool QuickTestEvent::keyClickChar(const QString &character, int modifiers, int d
return true;
}
+// valueToKeySequence() is copied from qquickshortcut.cpp
+static QKeySequence valueToKeySequence(const QVariant &value)
+{
+ if (value.type() == QVariant::Int)
+ return QKeySequence(static_cast<QKeySequence::StandardKey>(value.toInt()));
+ return QKeySequence::fromString(value.toString());
+}
+
+bool QuickTestEvent::keySequence(const QVariant &keySequence)
+{
+ QWindow *window = activeWindow();
+ if (!window)
+ return false;
+ QTest::keySequence(window, valueToKeySequence(keySequence));
+ return true;
+}
+
namespace QtQuickTest
{
enum MouseAction { MousePress, MouseRelease, MouseClick, MouseDoubleClick, MouseMove, MouseDoubleClickSequence };
@@ -156,7 +173,7 @@ namespace QtQuickTest
return;
}
- QPoint pos;
+ QPoint pos = _pos.toPoint();
QQuickItem *sgitem = qobject_cast<QQuickItem *>(item);
if (sgitem)
pos = sgitem->mapToScene(_pos).toPoint();
diff --git a/src/qmltest/quicktestevent_p.h b/src/qmltest/quicktestevent_p.h
index 89065b8880..92477399bc 100644
--- a/src/qmltest/quicktestevent_p.h
+++ b/src/qmltest/quicktestevent_p.h
@@ -94,6 +94,8 @@ public Q_SLOTS:
bool keyReleaseChar(const QString &character, int modifiers, int delay);
bool keyClickChar(const QString &character, int modifiers, int delay);
+ Q_REVISION(2) bool keySequence(const QVariant &keySequence);
+
bool mousePress(QObject *item, qreal x, qreal y, int button,
int modifiers, int delay);
bool mouseRelease(QObject *item, qreal x, qreal y, int button,
diff --git a/src/qmltest/quicktestresult.cpp b/src/qmltest/quicktestresult.cpp
index 8c62196128..d7d692a80d 100644
--- a/src/qmltest/quicktestresult.cpp
+++ b/src/qmltest/quicktestresult.cpp
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2017 Crimson AS <info@crimson.no>
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
@@ -56,12 +57,16 @@
#include <QtCore/qmap.h>
#include <QtCore/qbytearray.h>
#include <QtCore/qcoreapplication.h>
+#include <QtCore/qdatetime.h>
#include <QtCore/qdebug.h>
#include <QtCore/QUrl>
#include <QtCore/QDir>
#include <QtQuick/qquickwindow.h>
#include <QtGui/qvector3d.h>
+#include <QtGui/qimagewriter.h>
#include <QtQml/private/qqmlglobal_p.h>
+#include <QtQml/QQmlEngine>
+#include <QtQml/QQmlContext>
#include <private/qv4qobjectwrapper_p.h>
#include <algorithm>
@@ -77,6 +82,11 @@ extern bool qWaitForSignal(QObject *obj, const char* signal, int timeout = 5000)
class Q_QUICK_TEST_EXPORT QuickTestImageObject : public QObject
{
Q_OBJECT
+
+ Q_PROPERTY(int width READ width CONSTANT)
+ Q_PROPERTY(int height READ height CONSTANT)
+ Q_PROPERTY(QSize size READ size CONSTANT)
+
public:
QuickTestImageObject(const QImage& img, QObject *parent = 0)
: QObject(parent)
@@ -127,6 +137,33 @@ public Q_SLOTS:
return m_image == other->m_image;
}
+
+ void save(const QString &filePath)
+ {
+ QImageWriter writer(filePath);
+ if (!writer.write(m_image)) {
+ QQmlEngine *engine = qmlContext(this)->engine();
+ QV4::ExecutionEngine *v4 = engine->handle();
+ v4->throwError(QStringLiteral("Can't save to %1: %2").arg(filePath, writer.errorString()));
+ }
+ }
+
+public:
+ int width() const
+ {
+ return m_image.width();
+ }
+
+ int height() const
+ {
+ return m_image.height();
+ }
+
+ QSize size() const
+ {
+ return m_image.size();
+ }
+
private:
QImage m_image;
};
@@ -718,7 +755,9 @@ QObject *QuickTestResult::grabImage(QQuickItem *item)
QImage grabbed = window->grabWindow();
QRectF rf(item->x(), item->y(), item->width(), item->height());
rf = rf.intersected(QRectF(0, 0, grabbed.width(), grabbed.height()));
- return new QuickTestImageObject(grabbed.copy(rf.toAlignedRect()));
+ QObject *o = new QuickTestImageObject(grabbed.copy(rf.toAlignedRect()));
+ QQmlEngine::setContextForObject(o, qmlContext(this));
+ return o;
}
return 0;
}
diff --git a/src/quick/accessible/qaccessiblequickitem.cpp b/src/quick/accessible/qaccessiblequickitem.cpp
index fbde5d354d..2d6bb02af4 100644
--- a/src/quick/accessible/qaccessiblequickitem.cpp
+++ b/src/quick/accessible/qaccessiblequickitem.cpp
@@ -142,9 +142,6 @@ QAccessibleInterface *QAccessibleQuickItem::child(int index) const
return 0;
QQuickItem *child = children.at(index);
- if (!child) // FIXME can this happen?
- return 0;
-
return QAccessible::queryAccessibleInterface(child);
}
diff --git a/src/quick/accessible/qaccessiblequickitem_p.h b/src/quick/accessible/qaccessiblequickitem_p.h
index 577a105627..5375d37bf0 100644
--- a/src/quick/accessible/qaccessiblequickitem_p.h
+++ b/src/quick/accessible/qaccessiblequickitem_p.h
@@ -66,73 +66,73 @@ class QAccessibleQuickItem : public QAccessibleObject, public QAccessibleActionI
public:
QAccessibleQuickItem(QQuickItem *item);
- QWindow *window() const Q_DECL_OVERRIDE;
+ QWindow *window() const override;
- QRect rect() const Q_DECL_OVERRIDE;
+ QRect rect() const override;
QRect viewRect() const;
bool clipsChildren() const;
- QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE;
+ QAccessibleInterface *childAt(int x, int y) const override;
- QAccessibleInterface *parent() const Q_DECL_OVERRIDE;
- QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE;
- int childCount() const Q_DECL_OVERRIDE;
- int indexOfChild(const QAccessibleInterface *iface) const Q_DECL_OVERRIDE;
+ QAccessibleInterface *parent() const override;
+ QAccessibleInterface *child(int index) const override;
+ int childCount() const override;
+ int indexOfChild(const QAccessibleInterface *iface) const override;
QList<QQuickItem *> childItems() const;
- QAccessible::State state() const Q_DECL_OVERRIDE;
- QAccessible::Role role() const Q_DECL_OVERRIDE;
- QString text(QAccessible::Text) const Q_DECL_OVERRIDE;
+ QAccessible::State state() const override;
+ QAccessible::Role role() const override;
+ QString text(QAccessible::Text) const override;
bool isAccessible() const;
// Action Interface
- QStringList actionNames() const Q_DECL_OVERRIDE;
- void doAction(const QString &actionName) Q_DECL_OVERRIDE;
- QStringList keyBindingsForAction(const QString &actionName) const Q_DECL_OVERRIDE;
+ QStringList actionNames() const override;
+ void doAction(const QString &actionName) override;
+ QStringList keyBindingsForAction(const QString &actionName) const override;
// Value Interface
- QVariant currentValue() const Q_DECL_OVERRIDE;
- void setCurrentValue(const QVariant &value) Q_DECL_OVERRIDE;
- QVariant maximumValue() const Q_DECL_OVERRIDE;
- QVariant minimumValue() const Q_DECL_OVERRIDE;
- QVariant minimumStepSize() const Q_DECL_OVERRIDE;
+ QVariant currentValue() const override;
+ void setCurrentValue(const QVariant &value) override;
+ QVariant maximumValue() const override;
+ QVariant minimumValue() const override;
+ QVariant minimumStepSize() const override;
// Text Interface
- void selection(int selectionIndex, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE;
- int selectionCount() const Q_DECL_OVERRIDE;
- void addSelection(int startOffset, int endOffset) Q_DECL_OVERRIDE;
- void removeSelection(int selectionIndex) Q_DECL_OVERRIDE;
- void setSelection(int selectionIndex, int startOffset, int endOffset) Q_DECL_OVERRIDE;
+ void selection(int selectionIndex, int *startOffset, int *endOffset) const override;
+ int selectionCount() const override;
+ void addSelection(int startOffset, int endOffset) override;
+ void removeSelection(int selectionIndex) override;
+ void setSelection(int selectionIndex, int startOffset, int endOffset) override;
// cursor
- int cursorPosition() const Q_DECL_OVERRIDE;
- void setCursorPosition(int position) Q_DECL_OVERRIDE;
+ int cursorPosition() const override;
+ void setCursorPosition(int position) override;
// text
- QString text(int startOffset, int endOffset) const Q_DECL_OVERRIDE;
+ QString text(int startOffset, int endOffset) const override;
QString textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType,
- int *startOffset, int *endOffset) const Q_DECL_OVERRIDE;
+ int *startOffset, int *endOffset) const override;
QString textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType,
- int *startOffset, int *endOffset) const Q_DECL_OVERRIDE;
+ int *startOffset, int *endOffset) const override;
QString textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType,
- int *startOffset, int *endOffset) const Q_DECL_OVERRIDE;
- int characterCount() const Q_DECL_OVERRIDE;
+ int *startOffset, int *endOffset) const override;
+ int characterCount() const override;
// character <-> geometry
- QRect characterRect(int /* offset */) const Q_DECL_OVERRIDE { return QRect(); }
- int offsetAtPoint(const QPoint & /* point */) const Q_DECL_OVERRIDE { return -1; }
+ QRect characterRect(int /* offset */) const override { return QRect(); }
+ int offsetAtPoint(const QPoint & /* point */) const override { return -1; }
- void scrollToSubstring(int /* startIndex */, int /* endIndex */) Q_DECL_OVERRIDE {}
- QString attributes(int /* offset */, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE
+ void scrollToSubstring(int /* startIndex */, int /* endIndex */) override {}
+ QString attributes(int /* offset */, int *startOffset, int *endOffset) const override
{ *startOffset = 0; *endOffset = 0; return QString(); }
QTextDocument *textDocument() const;
protected:
QQuickItem *item() const { return static_cast<QQuickItem*>(object()); }
- void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE;
+ void *interface_cast(QAccessible::InterfaceType t) override;
private:
QTextDocument *m_doc;
diff --git a/src/quick/configure.json b/src/quick/configure.json
index 65ad5b810b..7004ea7f7b 100644
--- a/src/quick/configure.json
+++ b/src/quick/configure.json
@@ -139,6 +139,14 @@
"privateFeature"
]
},
+ "quick-repeater": {
+ "label": "Repeater item",
+ "purpose": "Provides the Repeater item.",
+ "section": "Qt Quick",
+ "output": [
+ "privateFeature"
+ ]
+ },
"quick-shadereffect": {
"label": "ShaderEffect item",
"purpose": "Provides Shader effects.",
@@ -171,6 +179,7 @@
"quick-path",
"quick-pathview",
"quick-positioners",
+ "quick-repeater",
"quick-shadereffect",
"quick-sprite"
]
diff --git a/src/quick/designer/qqmldesignermetaobject.cpp b/src/quick/designer/qqmldesignermetaobject.cpp
index 33ea442b76..63364192c6 100644
--- a/src/quick/designer/qqmldesignermetaobject.cpp
+++ b/src/quick/designer/qqmldesignermetaobject.cpp
@@ -127,7 +127,7 @@ void QQmlDesignerMetaObject::init(QObject *object, QQmlEngine *engine)
}
QQmlDesignerMetaObject::QQmlDesignerMetaObject(QObject *object, QQmlEngine *engine)
- : QQmlVMEMetaObject(QQmlEnginePrivate::getV4Engine(engine), object, cacheForObject(object, engine), /*qml compilation unit*/nullptr, /*qmlObjectId*/-1),
+ : QQmlVMEMetaObject(engine->handle(), object, cacheForObject(object, engine), /*qml compilation unit*/nullptr, /*qmlObjectId*/-1),
m_context(engine->contextForObject(object)),
m_data(new MetaPropertyData)
{
diff --git a/src/quick/designer/qquickdesignersupport.cpp b/src/quick/designer/qquickdesignersupport.cpp
index 749ece8221..88971e3172 100644
--- a/src/quick/designer/qquickdesignersupport.cpp
+++ b/src/quick/designer/qquickdesignersupport.cpp
@@ -90,10 +90,11 @@ void QQuickDesignerSupport::refFromEffectItem(QQuickItem *referencedItem, bool h
QSGRenderContext *rc = QQuickWindowPrivate::get(referencedItem->window())->context;
QSGLayer *texture = rc->sceneGraphContext()->createLayer(rc);
+ QSizeF itemSize = referencedItem->size();
texture->setLive(true);
texture->setItem(QQuickItemPrivate::get(referencedItem)->rootNode());
- texture->setRect(referencedItem->boundingRect());
- texture->setSize(referencedItem->boundingRect().size().toSize());
+ texture->setRect(QRectF(QPointF(0, 0), itemSize));
+ texture->setSize(itemSize.toSize());
texture->setRecursive(true);
#if QT_CONFIG(opengl)
#ifndef QT_OPENGL_ES
diff --git a/src/quick/doc/images/declarative-arcrotation.png b/src/quick/doc/images/declarative-arcrotation.png
new file mode 100644
index 0000000000..03f009bc12
--- /dev/null
+++ b/src/quick/doc/images/declarative-arcrotation.png
Binary files differ
diff --git a/src/quick/doc/images/pathitem-code-example.png b/src/quick/doc/images/pathitem-code-example.png
new file mode 100644
index 0000000000..25dbe8b311
--- /dev/null
+++ b/src/quick/doc/images/pathitem-code-example.png
Binary files differ
diff --git a/src/quick/doc/images/pointDistanceThreshold.png b/src/quick/doc/images/pointDistanceThreshold.png
new file mode 100644
index 0000000000..c883f5f8a1
--- /dev/null
+++ b/src/quick/doc/images/pointDistanceThreshold.png
Binary files differ
diff --git a/src/quick/doc/images/pointDistanceThreshold.svg b/src/quick/doc/images/pointDistanceThreshold.svg
new file mode 100644
index 0000000000..30d04e0df6
--- /dev/null
+++ b/src/quick/doc/images/pointDistanceThreshold.svg
@@ -0,0 +1,217 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg6318"
+ inkscape:version="0.92.2 5c3e80d, 2017-08-06"
+ viewBox="0 0 249.99999 100"
+ version="1.1"
+ sodipodi:docname="pointDistanceThreshold.svg"
+ width="250"
+ height="100"
+ inkscape:export-filename="/home/rutledge/dev/qt510/qtdeclarative/src/quick/doc/images/pointDistanceThreshold.png"
+ inkscape:export-xdpi="96"
+ inkscape:export-ydpi="96">
+ <title
+ id="title892">pointDistanceThreshold</title>
+ <defs
+ id="defs20">
+ <marker
+ inkscape:isstock="true"
+ style="overflow:visible"
+ id="marker1145"
+ refX="0"
+ refY="0"
+ orient="auto"
+ inkscape:stockid="Arrow2Mstart">
+ <path
+ inkscape:connector-curvature="0"
+ transform="scale(0.6)"
+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+ id="path1143" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow2Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="marker5708"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ id="path5710"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+ transform="scale(-0.6)"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow2Mstart"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="marker5656"
+ style="overflow:visible"
+ inkscape:isstock="true"
+ inkscape:collect="always">
+ <path
+ id="path5658"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+ transform="scale(0.6)"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Mstart"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Mstart"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ id="path4267"
+ d="M 0,0 5,-5 -12.5,0 5,5 Z"
+ style="fill:#e2ff8b;fill-opacity:0.25098039;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+ transform="matrix(0.4,0,0,0.4,4,0)"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Lend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Lend"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ id="path4264"
+ d="M 0,0 5,-5 -12.5,0 5,5 Z"
+ style="fill:#e2ff8b;fill-opacity:0.25098039;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+ transform="matrix(-0.8,0,0,-0.8,-10,0)"
+ inkscape:connector-curvature="0" />
+ </marker>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ bordercolor="#666666"
+ inkscape:pageshadow="2"
+ inkscape:window-y="10"
+ pagecolor="#ffffff"
+ inkscape:zoom="2.1818696"
+ inkscape:window-width="3025"
+ inkscape:window-maximized="0"
+ inkscape:window-x="275"
+ showgrid="false"
+ borderopacity="1.0"
+ inkscape:current-layer="layer1"
+ inkscape:cx="-180.21887"
+ inkscape:cy="-3.6626369"
+ inkscape:window-height="2115"
+ inkscape:pageopacity="0.0"
+ inkscape:document-units="px"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0" />
+ <g
+ id="layer1"
+ inkscape:label="Camada 1"
+ inkscape:groupmode="layer"
+ transform="translate(14.90473,-165.12199)">
+ <rect
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#006eed;stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect4231"
+ width="30.622982"
+ height="41.004536"
+ x="127.52915"
+ y="204.5533"
+ ry="3.3911796"
+ transform="rotate(-6.0579549)" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:125%;font-family:Sans;-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#006eed;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="129.10042"
+ y="218.27599"
+ id="text4234"
+ transform="rotate(-6.0579549)"><tspan
+ sodipodi:role="line"
+ id="tspan4236"
+ x="129.10042"
+ y="218.27599">Item</tspan></text>
+ <rect
+ ry="4.7313037"
+ y="196.45122"
+ x="121.42953"
+ height="57.208683"
+ width="42.822224"
+ id="rect1011"
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#006eed;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1, 3;stroke-dashoffset:0;stroke-opacity:1"
+ transform="rotate(-6.0579549)" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#marker5656)"
+ d="m 152.47483,208.41921 12.89093,-1.36808"
+ id="path1013"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path6337"
+ d="m 189.62569,349.61549 -24.29,-54.26 -12.83194,-58.84322 c -2.6119,-12.7355 2.2926,-19.07175 9.23283,-20.18303 6.94022,-1.11127 15.91617,3.00243 21.44717,11.16683 8.071,9.1465 4.33419,25.07247 11.96207,39.28935 7.62787,14.21687 15.16237,31.30787 22.85987,51.95087 l 5.2215,-4.5404 14.80555,-23.66072 -9.48553,-65.8264 -19.7978,-27.78564 -25.75599,2.46365 c -15.01523,-4.56498 -8.7269,-29.71674 14.1138,-30.8189 0,0 24.50188,-6.93892 30.57911,0.83552 6.07722,7.77444 30.208,23.27674 35.52842,29.53381 6.64558,7.81553 12.02547,67.49345 12.02547,67.49345"
+ sodipodi:nodetypes="cccscscccccccssc"
+ style="fill:#f2ecd5;fill-opacity:0.88108108;stroke:#4d4d4d;stroke-width:5.15140009;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0.25098039"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path1141"
+ d="m 142.4415,209.48402 -12.89093,1.36807"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#marker1145)" />
+ <text
+ id="text1335"
+ y="227.02623"
+ x="-37.15416"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:125%;font-family:Sans;-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"
+ transform="rotate(-6.0579549)"><tspan
+ y="227.02623"
+ x="-37.15416"
+ id="tspan1333"
+ sodipodi:role="line">pointDistanceThreshold</tspan></text>
+ </g>
+ <metadata
+ id="metadata19">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="https://www.gnu.org/licenses/fdl-1.3.html" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title></dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title>pointDistanceThreshold</dc:title>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>The Qt Company</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Shawn Rutledge</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ <dc:date>20170921</dc:date>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+</svg>
diff --git a/src/quick/doc/images/shape-radial-gradient.png b/src/quick/doc/images/shape-radial-gradient.png
new file mode 100644
index 0000000000..bfff2e4b6b
--- /dev/null
+++ b/src/quick/doc/images/shape-radial-gradient.png
Binary files differ
diff --git a/src/quick/doc/images/touchpoint-metrics.svg b/src/quick/doc/images/touchpoint-metrics.svg
new file mode 100644
index 0000000000..cbf4cb3257
--- /dev/null
+++ b/src/quick/doc/images/touchpoint-metrics.svg
@@ -0,0 +1,580 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg6318"
+ inkscape:version="0.92.2 5c3e80d, 2017-08-06"
+ viewBox="0 0 443.12941 596.85604"
+ version="1.1"
+ sodipodi:docname="touchpoint-metrics.svg"
+ width="443.12943"
+ height="596.85602"
+ inkscape:export-filename="/home/rutledge/dev/qt5/qtdeclarative/src/quick/doc/images/touchpoint-metrics.png"
+ inkscape:export-xdpi="90.474083"
+ inkscape:export-ydpi="90.474083">
+ <defs
+ id="defs20">
+ <marker
+ inkscape:stockid="Arrow2Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="marker5708"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ id="path5710"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+ transform="scale(-0.6,-0.6)"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow2Mstart"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="marker5656"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ id="path5658"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+ transform="scale(0.6,0.6)"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:isstock="true"
+ style="overflow:visible"
+ id="marker5436"
+ refX="0"
+ refY="0"
+ orient="auto"
+ inkscape:stockid="Arrow2Mend"
+ inkscape:collect="always">
+ <path
+ transform="scale(-0.6,-0.6)"
+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+ id="path5438"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:isstock="true"
+ style="overflow:visible"
+ id="marker5378"
+ refX="0"
+ refY="0"
+ orient="auto"
+ inkscape:stockid="Arrow2Mstart"
+ inkscape:collect="always">
+ <path
+ transform="scale(0.6,0.6)"
+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+ id="path5380"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow2Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow2Mend"
+ style="overflow:visible"
+ inkscape:isstock="true"
+ inkscape:collect="always">
+ <path
+ id="path4288"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+ transform="scale(-0.6,-0.6)"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow2Mstart"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow2Mstart"
+ style="overflow:visible"
+ inkscape:isstock="true"
+ inkscape:collect="always">
+ <path
+ id="path4285"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+ transform="scale(0.6,0.6)"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Mstart"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Mstart"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ id="path4267"
+ d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
+ style="fill:#e2ff8b;fill-opacity:0.25098039;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
+ transform="matrix(0.4,0,0,0.4,4,0)"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Lend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow1Lend"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ id="path4264"
+ d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
+ style="fill:#e2ff8b;fill-opacity:0.25098039;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
+ transform="matrix(-0.8,0,0,-0.8,-10,0)"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <filter
+ inkscape:collect="always"
+ style="color-interpolation-filters:sRGB"
+ id="filter4958-5"
+ x="-0.084455244"
+ width="1.1689105"
+ y="-0.74658436"
+ height="2.4931686">
+ <feGaussianBlur
+ inkscape:collect="always"
+ stdDeviation="97.211503"
+ id="feGaussianBlur4960-1" />
+ </filter>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4317"
+ id="linearGradient5092"
+ gradientUnits="userSpaceOnUse"
+ x1="6603.8599"
+ y1="946.87665"
+ x2="6603.8599"
+ y2="-1479.8376"
+ gradientTransform="matrix(0.14148321,0,0,0.26337982,-551.07006,366.30969)" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4317">
+ <stop
+ style="stop-color:#000000;stop-opacity:0"
+ offset="0"
+ id="stop4319" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.661"
+ offset="1"
+ id="stop4321" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4149"
+ id="linearGradient4155-1"
+ x1="3145.3071"
+ y1="1359.6201"
+ x2="3082.0513"
+ y2="1461.0105"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4149">
+ <stop
+ style="stop-color:#000000;stop-opacity:1"
+ offset="0"
+ id="stop4151" />
+ <stop
+ style="stop-color:#4d4d4d;stop-opacity:1"
+ offset="1"
+ id="stop4153" />
+ </linearGradient>
+ </defs>
+ <title
+ id="title6969">press button</title>
+ <sodipodi:namedview
+ id="base"
+ bordercolor="#666666"
+ inkscape:pageshadow="2"
+ inkscape:window-y="10"
+ pagecolor="#ffffff"
+ inkscape:zoom="2.1818696"
+ inkscape:window-width="3025"
+ inkscape:window-maximized="0"
+ inkscape:window-x="275"
+ showgrid="false"
+ borderopacity="1.0"
+ inkscape:current-layer="layer1"
+ inkscape:cx="294.2435"
+ inkscape:cy="305.24727"
+ inkscape:window-height="2115"
+ inkscape:pageopacity="0.0"
+ inkscape:document-units="px"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0" />
+ <g
+ id="layer1"
+ inkscape:label="Camada 1"
+ inkscape:groupmode="layer"
+ transform="translate(-19.10777,28.71728)">
+ <ellipse
+ transform="matrix(0.17845239,0,0,-0.11180897,-891.75636,813.19424)"
+ ry="156.25"
+ rx="1381.25"
+ cy="2349.6123"
+ cx="6356.25"
+ id="path4860-7"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.35;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.47037899;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter4958-5);color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <g
+ id="g4433"
+ transform="matrix(0.68820663,0,0,0.68820663,5.9576757,-8.9538574)">
+ <rect
+ ry="15.802789"
+ y="-28.717279"
+ x="19.107775"
+ height="848.34637"
+ width="643.89008"
+ id="rect5025-7"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#333333;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.47037899;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#333333;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.47037899;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4244-3"
+ width="643.89008"
+ height="848.34637"
+ x="19.107775"
+ y="-23.449682"
+ ry="15.802789" />
+ <rect
+ ry="15.802789"
+ y="-23.449682"
+ x="19.107775"
+ height="848.34637"
+ width="643.89008"
+ id="rect4315-1"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.90399996;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient5092);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.47037899;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <path
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#1a1a1a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.47037899;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ d="m 34.910559,-23.449671 306.821051,0 315.87514,692.820621 0,139.72299 c 0,8.75475 -7.04805,15.80279 -15.80279,15.80279 l -606.893401,0 c -8.754745,0 -15.802789,-7.04804 -15.802789,-15.80279 l 0,-816.7408215 c 0,-8.7547455 7.048044,-15.8027895 15.802789,-15.8027895 z"
+ id="rect4325-4"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sccssssss" />
+ <rect
+ y="25.141434"
+ x="62.871906"
+ height="740.51996"
+ width="554.67615"
+ id="rect5094"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:64.19769287;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#939393;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:64.19769287;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4248-1"
+ width="520.93262"
+ height="706.77637"
+ x="79.74366"
+ y="42.013233" />
+ <g
+ id="g4779-1"
+ transform="matrix(0.33396996,0,0,0.33396996,-712.61797,319.71649)">
+ <circle
+ r="59.752544"
+ cy="1410.4148"
+ cx="3113.8386"
+ id="path4147-2"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient4155-1);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.47037899;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <path
+ id="circle4157-9"
+ d="m 3122.5371,1358.1816 -0.8867,7.8477 a 45.109688,45.109688 0 0 1 37.2988,44.3848 45.109688,45.109688 0 0 1 -45.1113,45.1113 45.109688,45.109688 0 0 1 -45.1094,-45.1113 45.109688,45.109688 0 0 1 37.293,-44.42 l -0.8789,-7.7656 a 52.966831,52.966831 0 0 0 -44.2715,52.1856 52.966831,52.966831 0 0 0 52.9668,52.9668 52.966831,52.966831 0 0 0 52.9668,-52.9668 52.966831,52.966831 0 0 0 -44.2676,-52.2325 z"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#2affd5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.47037899;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ <rect
+ ry="0"
+ y="1357.4473"
+ x="3109.9236"
+ height="53.033009"
+ width="7.8286819"
+ id="rect4767-5"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#2affd5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.47037899;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ </g>
+ </g>
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.00000003, 1.00000003;stroke-dashoffset:0;stroke-opacity:1"
+ d="m -93.997225,215.5841 -46.290585,0"
+ id="path4158"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4162"
+ d="m -117.94458,184.189 0,62.79019"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.00000006, 1.00000006;stroke-dashoffset:0;stroke-opacity:1" />
+ <g
+ id="g4174"
+ transform="translate(-403.15923,36.297289)">
+ <ellipse
+ ry="24.954388"
+ rx="15.555983"
+ cy="178.94307"
+ cx="284.64172"
+ id="path4148"
+ style="opacity:1;fill:#e2ff8b;fill-opacity:0.25098039;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4156"
+ d="m 284.87089,179.28681 15.23922,0"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4160"
+ d="m 285.21463,179.28681 0,-25.4369"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ </g>
+ <rect
+ style="opacity:1;fill:#e6e6e6;fill-opacity:1;stroke:#358e12;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect4238"
+ width="321.4903"
+ height="289.082"
+ x="75.304832"
+ y="94.97757" />
+ <rect
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#006eed;stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect4231"
+ width="156.85616"
+ height="110.83637"
+ x="168.64072"
+ y="119.2838"
+ ry="9.1664505" />
+ <path
+ id="path6337"
+ d="m 320.3128,565.52961 -13.62,-29.96 c -45.92,-30.16 -78.8,-67.18 -98.53,-111.24 l -48.58,-108.52 c -5.2238,-25.471 19.618,-25.345 30.68,-9.0162 16.142,18.293 30.885,45.371 46.28,86.657 l 5.2215,-4.5404 -59.025,-218.39 c -4.2637,-29.243 23.814,-32.925 34.28,-12.486 l 49.717,145.07 3.6827,-2.1073 c -16.547,-46.113 32.245,-68.82 43.104,-12.947 l 2.4051,8.2164 0.63738,-0.20605 c -18.07,-41.645 26.255,-63.863 41.465,-20.253 l 3.9923,15.864 0.25639,-0.0618 c -4.7466,-31.9 24.489,-34.442 36.128,-17.563 15.213,22.024 62.049,126.67 36.323,223.39 l 14.529,64.473"
+ sodipodi:nodetypes="ccsccccccccccccccccc"
+ style="fill:#f2ecd5;fill-opacity:0.88108108;stroke:#4d4d4d;stroke-width:5.15140009;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0.25098039"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4179"
+ d="m 257.62466,169.84909 -75.0045,0"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.70000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0.70000006, 0.70000006;stroke-dashoffset:0;stroke-opacity:1" />
+ <ellipse
+ ry="20.747375"
+ rx="15.555983"
+ cy="210.94308"
+ cx="157.19211"
+ id="ellipse4185"
+ style="opacity:1;fill:#d2ff44;fill-opacity:0.69019608;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ transform="matrix(0.97361357,-0.228203,0.228203,0.97361357,0,0)" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4187"
+ d="m 186.02082,173.21041 30.3228,-7.41015"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4189"
+ d="m 206.0817,189.77229 -9.79896,-40.5339"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4203"
+ d="m 202.70075,321.07311 -46.29058,0"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.00000003, 1.00000003;stroke-dashoffset:0;stroke-opacity:1" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1.00000006, 1.00000006;stroke-dashoffset:0;stroke-opacity:1"
+ d="m 179.88768,290.65026 0,62.79019"
+ id="path4205"
+ inkscape:connector-curvature="0" />
+ <ellipse
+ ry="24.954388"
+ rx="15.555983"
+ cy="366.34235"
+ cx="-33.562881"
+ id="ellipse4209"
+ style="opacity:1;fill:#d2ff44;fill-opacity:0.69005845;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ transform="matrix(0.82504909,-0.56506106,0.56506106,0.82504909,0,0)" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4211"
+ d="m 166.58656,330.02978 25.45643,-17.62857"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4213"
+ d="M 193.54247,341.84882 165.08708,300.58218"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.70000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0.70000005, 0.70000005;stroke-dashoffset:0;stroke-opacity:1"
+ d="m 255.58123,156.48354 -55.13917,13.07972"
+ id="path4253"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.50683999;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-start:url(#Arrow2Mstart);marker-end:url(#Arrow2Mend)"
+ id="path4255"
+ sodipodi:type="arc"
+ sodipodi:cx="88.504486"
+ sodipodi:cy="192.79727"
+ sodipodi:rx="99.028755"
+ sodipodi:ry="60.303371"
+ sodipodi:start="0.0081667968"
+ sodipodi:end="0.18640007"
+ sodipodi:open="true"
+ d="m 187.52994,193.28975 a 99.028755,60.303371 0 0 1 -1.7121,10.6831"
+ inkscape:transform-center-x="-97.138756"
+ inkscape:transform-center-y="-2.1359185"
+ transform="matrix(0.99260218,-0.12141219,0.34645175,0.93806779,0,0)" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path5368"
+ d="m 197.32294,149.03759 -25.3509,5.88287"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.70000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0.70000006, 0.70000006;stroke-dashoffset:0;stroke-opacity:1" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.50000006;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#marker5378);marker-end:url(#marker5436)"
+ d="m 174.13381,155.92063 10.90284,37.60336"
+ id="path5370"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path5650"
+ d="m 186.19518,173.42441 6.5705,28.76449"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.70000011;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0.70000007, 0.70000007;stroke-dashoffset:0;stroke-opacity:1"
+ inkscape:transform-center-x="0.57875414"
+ inkscape:transform-center-y="-3.0663012" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.70000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0.70000006, 0.70000006;stroke-dashoffset:0;stroke-opacity:1"
+ d="m 216.29427,166.04651 6.78267,28.89901"
+ id="path5652"
+ inkscape:connector-curvature="0"
+ inkscape:transform-center-x="11.459489"
+ inkscape:transform-center-y="17.730719" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path5654"
+ d="m 193.42658,199.80678 27.98449,-7.24458"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.50000006;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#marker5656);marker-end:url(#marker5708)"
+ inkscape:transform-center-x="3.7104844"
+ inkscape:transform-center-y="53.812545" />
+ <rect
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#877553;stroke-width:0.49999997;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect6618"
+ width="32.408298"
+ height="41.563641"
+ x="184.97807"
+ y="148.72353" />
+ <rect
+ y="298.08408"
+ x="159.8698"
+ height="46.262844"
+ width="38.889957"
+ id="rect6620"
+ style="opacity:1;fill:none;fill-opacity:1;stroke:#877553;stroke-width:0.49999997;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:125%;font-family:Sans;-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="258.05429"
+ y="166.59993"
+ id="text6622"><tspan
+ sodipodi:role="line"
+ id="tspan6624"
+ x="258.05429"
+ y="166.59993">rotation</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:125%;font-family:Sans;-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="203.90126"
+ y="207.63615"
+ id="text6626"><tspan
+ sodipodi:role="line"
+ id="tspan6628"
+ x="203.90126"
+ y="207.63615">horizontalDiameter</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:125%;font-family:Sans;-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="76.891922"
+ y="180.37347"
+ id="text6630"><tspan
+ sodipodi:role="line"
+ id="tspan6632"
+ x="76.891922"
+ y="180.37347">verticalDiameter</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:125%;font-family:Sans;-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#877553;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="219.07135"
+ y="151.56999"
+ id="text4233"><tspan
+ sodipodi:role="line"
+ id="tspan4235"
+ x="219.07135"
+ y="151.56999">bounding box</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:125%;font-family:Sans;-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#006eed;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="173.82605"
+ y="134.1916"
+ id="text4234"><tspan
+ sodipodi:role="line"
+ id="tspan4236"
+ x="173.82605"
+ y="134.1916">Item</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12px;line-height:125%;font-family:Sans;-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#358e12;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="81.786491"
+ y="109.88538"
+ id="text4240"><tspan
+ sodipodi:role="line"
+ id="tspan4242"
+ x="81.786491"
+ y="109.88538">Scene (Window)</tspan></text>
+ <path
+ inkscape:connector-curvature="0"
+ id="path4219"
+ d="m 261.39257,176.47248 -78.11808,18.63309"
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.70000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0.70000005, 0.70000005;stroke-dashoffset:0;stroke-opacity:1" />
+ </g>
+ <metadata
+ id="metadata19">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="https://www.gnu.org/licenses/fdl-1.3.html" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title />
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title>Touch Point Metrics</dc:title>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>The Qt Company</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Shawn Rutledge</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ <dc:date>20170921</dc:date>
+ <dc:description>The hand image is from https://openclipart.org/detail/192689/press-button
+The generic tablet device is from https://openclipart.org/detail/244440/computer-tablet-and-phone-vectors</dc:description>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+</svg>
diff --git a/src/quick/doc/images/touchpoints-pinchhandler.png b/src/quick/doc/images/touchpoints-pinchhandler.png
new file mode 100644
index 0000000000..1cf1393364
--- /dev/null
+++ b/src/quick/doc/images/touchpoints-pinchhandler.png
Binary files differ
diff --git a/src/quick/doc/images/visualpath-code-example.png b/src/quick/doc/images/visualpath-code-example.png
new file mode 100644
index 0000000000..429e85aa32
--- /dev/null
+++ b/src/quick/doc/images/visualpath-code-example.png
Binary files differ
diff --git a/src/quick/doc/qtquick.qdocconf b/src/quick/doc/qtquick.qdocconf
index fae2eeae2e..028b30dba1 100644
--- a/src/quick/doc/qtquick.qdocconf
+++ b/src/quick/doc/qtquick.qdocconf
@@ -71,6 +71,14 @@ examples.fileextensions += "*.qm"
manifestmeta.thumbnail.names += "QtQuick/Threaded ListModel Example" \
"QtQuick/QML Dynamic View Ordering Tutorial*"
+manifestmeta.highlighted.names = "QtQuick/Qt Quick Demo - Same Game" \
+ "QtQuick/Qt Quick Demo - Photo Surface" \
+ "QtQuick/Qt Quick Demo - Tweet Search" \
+ "QtQuick/Qt Quick Demo - Calqlatr" \
+ "QtQuick/Qt Quick Demo - StocQt" \
+ "QtQuick/Qt Quick Demo - Clocks" \
+ "QtQuick/Qt Quick Examples - Shader Effects"
+
navigation.landingpage = "Qt Quick"
navigation.cppclassespage = "Qt Quick C++ Classes"
navigation.qmltypespage = "Qt Quick QML Types"
diff --git a/src/quick/doc/snippets/pointerHandlers/dragHandler.qml b/src/quick/doc/snippets/pointerHandlers/dragHandler.qml
new file mode 100644
index 0000000000..78a7db5b0c
--- /dev/null
+++ b/src/quick/doc/snippets/pointerHandlers/dragHandler.qml
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//![0]
+import QtQuick 2.10
+import Qt.labs.handlers 1.0
+
+Rectangle {
+ width: 100
+ height: 100
+ color: "lightsteelblue"
+ DragHandler { }
+}
+//![0]
diff --git a/src/quick/doc/snippets/pointerHandlers/dragHandlerDifferentTarget.qml b/src/quick/doc/snippets/pointerHandlers/dragHandlerDifferentTarget.qml
new file mode 100644
index 0000000000..4c4168de83
--- /dev/null
+++ b/src/quick/doc/snippets/pointerHandlers/dragHandlerDifferentTarget.qml
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//![0]
+import QtQuick 2.10
+import Qt.labs.handlers 1.0
+
+Item {
+ width: 640
+ height: 480
+
+ Rectangle {
+ id: feedback
+ border.color: "red"
+ width: Math.max(10, handler.point.ellipseDiameters.width)
+ height: Math.max(10, handler.point.ellipseDiameters.height)
+ radius: Math.max(width, height) / 2
+ visible: handler.active
+ }
+
+ DragHandler {
+ id: handler
+ target: feedback
+ }
+}
+//![0]
diff --git a/src/quick/doc/snippets/pointerHandlers/dragHandlerNullTarget.qml b/src/quick/doc/snippets/pointerHandlers/dragHandlerNullTarget.qml
new file mode 100644
index 0000000000..09429ec1d2
--- /dev/null
+++ b/src/quick/doc/snippets/pointerHandlers/dragHandlerNullTarget.qml
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//![0]
+import QtQuick 2.10
+import Qt.labs.handlers 1.0
+
+Item {
+ width: 640
+ height: 480
+
+ DragHandler {
+ id: handler
+ target: null
+ }
+
+ Text {
+ color: handler.active ? "darkgreen" : "black"
+ text: handler.point.position.x.toFixed(1) + "," + handler.point.position.y.toFixed(1)
+ x: handler.point.position.x - width / 2
+ y: handler.point.position.y - height
+ }
+}
+//![0]
diff --git a/src/quick/doc/snippets/pointerHandlers/pinchHandler.qml b/src/quick/doc/snippets/pointerHandlers/pinchHandler.qml
new file mode 100644
index 0000000000..955047d115
--- /dev/null
+++ b/src/quick/doc/snippets/pointerHandlers/pinchHandler.qml
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//![0]
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+
+Rectangle {
+ width: 400
+ height: 300
+ color: "lightsteelblue"
+ PinchHandler { }
+}
+//![0]
diff --git a/src/quick/doc/snippets/pointerHandlers/pinchHandlerDifferentTarget.qml b/src/quick/doc/snippets/pointerHandlers/pinchHandlerDifferentTarget.qml
new file mode 100644
index 0000000000..a5255a64e3
--- /dev/null
+++ b/src/quick/doc/snippets/pointerHandlers/pinchHandlerDifferentTarget.qml
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//![0]
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+
+Item {
+ width: 640
+ height: 480
+
+ Rectangle {
+ id: map
+ color: "aqua"
+ width: 400
+ height: 300
+ }
+
+ PinchHandler {
+ target: map
+ }
+}
+//![0]
diff --git a/src/quick/doc/snippets/pointerHandlers/pinchHandlerNullTarget.qml b/src/quick/doc/snippets/pointerHandlers/pinchHandlerNullTarget.qml
new file mode 100644
index 0000000000..7d21efcb84
--- /dev/null
+++ b/src/quick/doc/snippets/pointerHandlers/pinchHandlerNullTarget.qml
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//![0]
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+
+Item {
+ width: 640
+ height: 480
+
+ PinchHandler {
+ id: handler
+ target: null
+ }
+
+ Text {
+ color: handler.active ? "darkgreen" : "black"
+ text: handler.rotation.toFixed(1) + " degrees\n" +
+ handler.translation.x.toFixed(1) + ", " + handler.translation.y.toFixed(1) + "\n" +
+ (handler.scale * 100).toFixed(1) + "%"
+ }
+}
+//![0]
diff --git a/src/quick/doc/snippets/pointerHandlers/pointHandler.qml b/src/quick/doc/snippets/pointerHandlers/pointHandler.qml
new file mode 100644
index 0000000000..262eb607b6
--- /dev/null
+++ b/src/quick/doc/snippets/pointerHandlers/pointHandler.qml
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+//![0]
+import QtQuick 2.10
+import QtQuick.Window 2.2
+import Qt.labs.handlers 1.0
+
+Window {
+ width: 480
+ height: 320
+ visible: true
+
+ Item {
+ id: glassPane
+ z: 10000
+ anchors.fill: parent
+
+ PointHandler {
+ id: handler
+ acceptedDevices: PointerDevice.TouchScreen | PointerDevice.TouchPad
+ target: Rectangle {
+ parent: glassPane
+ color: "red"
+ visible: handler.active
+ x: handler.point.position.x - width / 2
+ y: handler.point.position.y - height / 2
+ width: 20; height: width; radius: width / 2
+ }
+ }
+ }
+}
+//![0]
diff --git a/src/quick/doc/snippets/qml/layerblending.qml b/src/quick/doc/snippets/qml/layerblending.qml
index 1791df5864..71804d722a 100644
--- a/src/quick/doc/snippets/qml/layerblending.qml
+++ b/src/quick/doc/snippets/qml/layerblending.qml
@@ -72,7 +72,7 @@ Item {
uniform highp vec2 pixelSize;
varying highp vec2 qt_TexCoord0;
void main() {
- highp vec2 tc = sign(sin(3.14152 * qt_TexCoord0 * pixelSize));
+ highp vec2 tc = sign(sin(3.14159265358979323846 * qt_TexCoord0 * pixelSize));
if (tc.x != tc.y)
gl_FragColor = color1;
else
diff --git a/src/quick/doc/snippets/qml/layout-simple.qml b/src/quick/doc/snippets/qml/layout-simple.qml
new file mode 100644
index 0000000000..6afdbe3ec9
--- /dev/null
+++ b/src/quick/doc/snippets/qml/layout-simple.qml
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+import QtQuick.Layouts 1.2
+import QtQuick.Window 2.2
+
+//! [1]
+Window {
+ RowLayout {
+ anchors.fill: parent
+ //! [spacing]
+ spacing: 6
+ //! [spacing]
+ Rectangle {
+ color: 'azure'
+ Layout.preferredWidth: 100
+ Layout.preferredHeight: 150
+ }
+ Rectangle {
+ color: "plum"
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ }
+ }
+}
+//! [1]
diff --git a/src/quick/doc/snippets/qml/opacitymask.qml b/src/quick/doc/snippets/qml/opacitymask.qml
index 7f073ae783..f58180b6d2 100644
--- a/src/quick/doc/snippets/qml/opacitymask.qml
+++ b/src/quick/doc/snippets/qml/opacitymask.qml
@@ -73,7 +73,7 @@ Item {
uniform highp vec2 pixelSize;
varying highp vec2 qt_TexCoord0;
void main() {
- highp vec2 tc = sign(sin(3.14152 * qt_TexCoord0 * pixelSize));
+ highp vec2 tc = sign(sin(3.14159265358979323846 * qt_TexCoord0 * pixelSize));
if (tc.x != tc.y)
gl_FragColor = color1;
else
diff --git a/src/quick/doc/snippets/qml/path/arcrotation.qml b/src/quick/doc/snippets/qml/path/arcrotation.qml
new file mode 100644
index 0000000000..985ac51d8a
--- /dev/null
+++ b/src/quick/doc/snippets/qml/path/arcrotation.qml
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+//![0]
+Path {
+ startX: 50; startY: 100
+
+ PathArc {
+ x: 150; y: 100
+ radiusX: 50; radiusY: 20
+ xAxisRotation: 45
+ }
+}
+//![0]
diff --git a/src/quick/doc/src/concepts/layouts/qtquicklayouts-overview.qdoc b/src/quick/doc/src/concepts/layouts/qtquicklayouts-overview.qdoc
index 05e4465f2a..06ebe2d3d1 100644
--- a/src/quick/doc/src/concepts/layouts/qtquicklayouts-overview.qdoc
+++ b/src/quick/doc/src/concepts/layouts/qtquicklayouts-overview.qdoc
@@ -74,8 +74,31 @@
\endlist
+ \section1 A Simple Layout
+
+ \snippet qml/layout-simple.qml 1
+
+ As the intention of using a layout is to rearrange its children whenever the layout changes
+ size, the application should make sure that the layout gets resized. In the above snippet the
+ RowLayout ensures that by specifying \c{anchors.fill: parent}. However, it can also be by other
+ means, such as directly specifying \l{Item::width}{width} and \l{Item::height}{height}
+ properties. In the same snippet, the \c azure Rectangle has a fixed size of \c{(100, 150)}
+ pixels, and the \c plum Rectangle will expand to occupy all the space it gets allocated.
+
+ \note A layout is responsible for its children's geometry. You should
+ therefore not specify \l{Item::width}{width}, \l{Item::height}{height}, \l{Item::x}{x},
+ \l{Item::y}{y} or any other properties that might influence those properties (such as
+ \l{Item::anchors}{anchors}) on those items. Otherwise there would be a conflict of interest,
+ and the result is undefined. This is also the case if the child item is a layout. Therefore,
+ only layouts with no parent layout can have \c{anchors.fill: parent}.
+
+ All items in the layout will have 6 pixels of spacing between them:
+
+ \snippet qml/layout-simple.qml spacing
+
+
+ \section2 Size Constraints
- \section1 Size Constraints
Since an item can be resized by its layout, the layout needs to know the
\l{Layout::minimumWidth}{minimum}, \l{Layout::preferredWidth}{preferred},
and \l{Layout::maximumWidth}{maximum} sizes of all items where \l{Layout::fillWidth}{Layout.fillWidth} or
diff --git a/src/quick/doc/src/concepts/pointerhandlers/qtquickhandlers-index.qdoc b/src/quick/doc/src/concepts/pointerhandlers/qtquickhandlers-index.qdoc
new file mode 100644
index 0000000000..b17c5ab728
--- /dev/null
+++ b/src/quick/doc/src/concepts/pointerhandlers/qtquickhandlers-index.qdoc
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** 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. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \page qtquickhandlers-index.html
+ \title Qt Quick Pointer Handlers
+ \brief A module with a set of QML elements that handle events from pointing devices in a user interface.
+
+ Qt Quick Pointer Handlers are a set of QML types used to handle events from
+ touch, mouse, and stylus devices in a UI. In contrast to event-handling
+ Items, such as \l MouseArea, Pointer Handlers require less memory and are
+ intended to be used in greater numbers: one handler per type of
+ interaction. Each Pointer Handler handles events on behalf of its \c parent
+ Item. One Item can have multiple Pointer Handlers.
+
+ The module is introduced in Qt 5.10.
+
+ \section1 Pointer Handlers
+
+ \annotatedlist pointerhandlers
+
+ \section1 Getting Started
+
+ The QML types can be imported into your application using the following import statement in your \c {.qml} file.
+
+ \code
+ import Qt.labs.handlers 1.0
+ \endcode
+
+ \section1 Key Features
+
+ Some of the key features are:
+
+ \list
+ \li Handle gestures such as tapping or dragging regardless which device it comes from
+ \li Handle gestures from different classes of devices in different ways
+ \li Each Item can have unlimited Handlers
+ \endlist
+
+ \omit TODO actual overview with snippets and stuff \endomit
+
+ \section1 Related Information
+
+ \list
+ \li \l{Qt Quick}
+ \li \l{Qt Quick Pointer Handlers Overview}
+ \li \l{Qt Quick Pointer Handlers QML Types}{Qt Quick Pointer Handlers QML Types}
+ \endlist
+*/
diff --git a/src/quick/doc/src/concepts/pointerhandlers/qtquickhandlers.qdoc b/src/quick/doc/src/concepts/pointerhandlers/qtquickhandlers.qdoc
new file mode 100644
index 0000000000..cf87c75e8c
--- /dev/null
+++ b/src/quick/doc/src/concepts/pointerhandlers/qtquickhandlers.qdoc
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** 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. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \qmlmodule Qt.labs.handlers 1.0
+ \title Qt Quick Pointer Handlers QML Types
+ \ingroup qmlmodules
+ \brief Provides QML types for handling events from pointing devices in a user interface.
+
+ The \l{Qt Quick Pointer Handlers} module provides QML types for handling
+ events from pointing devices in a UI. These QML types work in conjunction
+ with \l{Qt Quick}.
+
+ The QML types can be imported into your application using the
+ following import statement in your .qml file.
+
+ \code
+ import Qt.labs.handlers 1.0
+ \endcode
+*/
diff --git a/src/quick/doc/src/qmltypereference.qdoc b/src/quick/doc/src/qmltypereference.qdoc
index 152ff1ba30..f5b189c580 100644
--- a/src/quick/doc/src/qmltypereference.qdoc
+++ b/src/quick/doc/src/qmltypereference.qdoc
@@ -170,6 +170,8 @@ available when you import \c QtQuick.
\li \l enumeration \c font.capitalization
\li \l real \c font.letterSpacing
\li \l real \c font.wordSpacing
+ \li \l bool \c font.kerning
+ \li \l bool \c font.preferShaping
\li \l enumeration \c font.hintingPreference
\endlist
@@ -892,5 +894,5 @@ import QtTest 1.1
\endcode
For more information about how to use these types, see
-\l{Qt Quick Test Reference Documentation}.
+\l{Qt Quick Test}.
*/
diff --git a/src/quick/handlers/handlers.pri b/src/quick/handlers/handlers.pri
new file mode 100644
index 0000000000..8bd74d95da
--- /dev/null
+++ b/src/quick/handlers/handlers.pri
@@ -0,0 +1,22 @@
+HEADERS += \
+ $$PWD/qquickdraghandler_p.h \
+ $$PWD/qquickhandlersmodule_p.h \
+ $$PWD/qquickmultipointhandler_p.h \
+ $$PWD/qquickpinchhandler_p.h \
+ $$PWD/qquickpointerdevicehandler_p.h \
+ $$PWD/qquickpointerhandler_p.h \
+ $$PWD/qquickpointhandler_p.h \
+ $$PWD/qquicksinglepointhandler_p.h \
+ $$PWD/qquicktaphandler_p.h \
+
+SOURCES += \
+ $$PWD/qquickdraghandler.cpp \
+ $$PWD/qquickhandlersmodule.cpp \
+ $$PWD/qquickmultipointhandler.cpp \
+ $$PWD/qquickpinchhandler.cpp \
+ $$PWD/qquickpointerdevicehandler.cpp \
+ $$PWD/qquickpointerhandler.cpp \
+ $$PWD/qquickpointhandler.cpp \
+ $$PWD/qquicksinglepointhandler.cpp \
+ $$PWD/qquicktaphandler.cpp \
+
diff --git a/src/quick/handlers/qquickdraghandler.cpp b/src/quick/handlers/qquickdraghandler.cpp
new file mode 100644
index 0000000000..d4a8f06db8
--- /dev/null
+++ b/src/quick/handlers/qquickdraghandler.cpp
@@ -0,0 +1,254 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickdraghandler_p.h"
+#include <private/qquickwindow_p.h>
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype DragHandler
+ \instantiates QQuickDragHandler
+ \inherits SinglePointHandler
+ \inqmlmodule Qt.labs.handlers
+ \ingroup qtquick-handlers
+ \brief Handler for dragging
+
+ DragHandler is a handler that is used to interactively move an Item.
+ Like other Pointer Handlers, by default it is fully functional, and
+ manipulates its \l target.
+
+ \snippet pointerHandlers/dragHandler.qml 0
+
+ It has properties to restrict the range of dragging.
+
+ If it is declared within one Item but is assigned a different \l target,
+ then it handles events within the bounds of the \l parent Item but
+ manipulates the \c target Item instead:
+
+ \snippet pointerHandlers/dragHandlerDifferentTarget.qml 0
+
+ A third way to use it is to set \l target to \c null and react to property
+ changes in some other way:
+
+ \snippet pointerHandlers/dragHandlerNullTarget.qml 0
+
+ At this time, drag-and-drop is not yet supported.
+
+ \sa Drag, MouseArea
+*/
+
+QQuickDragHandler::QQuickDragHandler(QObject *parent)
+ : QQuickSinglePointHandler(parent)
+{
+}
+
+QQuickDragHandler::~QQuickDragHandler()
+{
+}
+
+bool QQuickDragHandler::wantsEventPoint(QQuickEventPoint *point)
+{
+ // If we've already been interested in a point, stay interested, even if it has strayed outside bounds.
+ return ((point->state() != QQuickEventPoint::Pressed && this->point().id() == point->pointId())
+ || QQuickSinglePointHandler::wantsEventPoint(point));
+}
+
+void QQuickDragHandler::onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point)
+{
+ if (grabber == this && stateChange == QQuickEventPoint::GrabExclusive && m_targetStartPos.isNull())
+ // In case the grab got handled over from another grabber, we might not get the Press.
+ // Therefore, prefer the m_targetStartPos we got when it got Pressed.
+ initializeTargetStartPos(point);
+ enforceConstraints();
+ QQuickSinglePointHandler::onGrabChanged(grabber, stateChange, point);
+}
+
+void QQuickDragHandler::onActiveChanged()
+{
+ if (!active())
+ m_targetStartPos = QPointF();
+}
+
+void QQuickDragHandler::handleEventPoint(QQuickEventPoint *point)
+{
+ point->setAccepted();
+ switch (point->state()) {
+ case QQuickEventPoint::Pressed:
+ initializeTargetStartPos(point);
+ setPassiveGrab(point);
+ break;
+ case QQuickEventPoint::Updated: {
+ QPointF delta = point->scenePosition() - point->scenePressPosition();
+ if (!m_xAxis.enabled())
+ delta.setX(0);
+ if (!m_yAxis.enabled())
+ delta.setY(0);
+ if (active()) {
+ setTranslation(QVector2D(delta));
+ if (target() && target()->parentItem()) {
+ QPointF pos = target()->parentItem()->mapFromScene(m_targetStartPos + delta);
+ enforceAxisConstraints(&pos);
+ moveTarget(pos, point);
+ }
+ } else if (!point->exclusiveGrabber() &&
+ ((m_xAxis.enabled() && QQuickWindowPrivate::dragOverThreshold(delta.x(), Qt::XAxis, point)) ||
+ (m_yAxis.enabled() && QQuickWindowPrivate::dragOverThreshold(delta.y(), Qt::YAxis, point)))) {
+ setExclusiveGrab(point);
+ if (auto parent = parentItem()) {
+ if (point->pointerEvent()->asPointerTouchEvent())
+ parent->setKeepTouchGrab(true);
+ // tablet and mouse are treated the same by Item's legacy event handling, and
+ // touch becomes synth-mouse for Flickable, so we need to prevent stealing
+ // mouse grab too, whenever dragging occurs in an enabled direction
+ parent->setKeepMouseGrab(true);
+ }
+ }
+ } break;
+ default:
+ break;
+ }
+}
+
+void QQuickDragHandler::enforceConstraints()
+{
+ if (!target() || !target()->parentItem())
+ return;
+ QPointF pos = target()->position();
+ QPointF copy(pos);
+ enforceAxisConstraints(&pos);
+ if (pos != copy)
+ target()->setPosition(pos);
+}
+
+void QQuickDragHandler::enforceAxisConstraints(QPointF *localPos)
+{
+ if (m_xAxis.enabled())
+ localPos->setX(qBound(m_xAxis.minimum(), localPos->x(), m_xAxis.maximum()));
+ if (m_yAxis.enabled())
+ localPos->setY(qBound(m_yAxis.minimum(), localPos->y(), m_yAxis.maximum()));
+}
+
+void QQuickDragHandler::initializeTargetStartPos(QQuickEventPoint *point)
+{
+ if (target() && target()->parentItem()) {
+ m_targetStartPos = target()->parentItem()->mapToScene(target()->position());
+ if (!target()->contains(point->position())) {
+ // If pressed outside of target item, move the target item so that the touchpoint is in its center,
+ // while still respecting the axis constraints.
+ const QPointF center = target()->parentItem()->mapFromScene(point->scenePosition());
+ const QPointF pointCenteredInItemPos = target()->parentItem()->mapToScene(center - QPointF(target()->width(), target()->height())/2);
+ if (m_xAxis.enabled())
+ m_targetStartPos.setX(pointCenteredInItemPos.x());
+ if (m_yAxis.enabled())
+ m_targetStartPos.setY(pointCenteredInItemPos.y());
+ }
+ }
+}
+
+void QQuickDragHandler::setTranslation(const QVector2D &trans)
+{
+ if (trans == m_translation) // fuzzy compare?
+ return;
+ m_translation = trans;
+ emit translationChanged();
+}
+
+/*!
+ \qmlpropertygroup QtQuick::DragHandler::xAxis
+ \qmlpropertygroup QtQuick::DragHandler::yAxis
+ \qmlproperty real QtQuick::DragHandler::DragAxis::minimum
+ \qmlproperty real QtQuick::DragHandler::DragAxis::maximum
+ \qmlproperty real QtQuick::DragHandler::DragAxis::enabled
+
+ \c xAxis and yAxis control the constraints for horizontal and vertical
+ dragging, respectively.
+
+ \value minimum
+ The minimum acceptable value of \l {Item::x}{x} or \l {Item::y}{y}
+ to be applied to the \l target
+ \value maximum
+ The maximum acceptable value of \l {Item::x}{x} or \l {Item::y}{y}
+ to be applied to the \l target
+ \value enabled
+ Whether dragging in this direction is allowed at all
+*/
+QQuickDragAxis::QQuickDragAxis()
+ : m_minimum(-DBL_MAX)
+ , m_maximum(DBL_MAX)
+ , m_enabled(true)
+{
+}
+
+void QQuickDragAxis::setMinimum(qreal minimum)
+{
+ if (m_minimum == minimum)
+ return;
+
+ m_minimum = minimum;
+ emit minimumChanged();
+}
+
+void QQuickDragAxis::setMaximum(qreal maximum)
+{
+ if (m_maximum == maximum)
+ return;
+
+ m_maximum = maximum;
+ emit maximumChanged();
+}
+
+void QQuickDragAxis::setEnabled(bool enabled)
+{
+ if (m_enabled == enabled)
+ return;
+
+ m_enabled = enabled;
+ emit enabledChanged();
+}
+
+/*!
+ \readonly
+ \qmlproperty QVector2D QtQuick::DragHandler::translation
+
+ The translation since the gesture began.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/quick/handlers/qquickdraghandler_p.h b/src/quick/handlers/qquickdraghandler_p.h
new file mode 100644
index 0000000000..d10084c654
--- /dev/null
+++ b/src/quick/handlers/qquickdraghandler_p.h
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKDRAGHANDLER_H
+#define QQUICKDRAGHANDLER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qquicksinglepointhandler_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class Q_AUTOTEST_EXPORT QQuickDragAxis : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal minimum READ minimum WRITE setMinimum NOTIFY minimumChanged)
+ Q_PROPERTY(qreal maximum READ maximum WRITE setMaximum NOTIFY maximumChanged)
+ Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
+
+public:
+ QQuickDragAxis();
+
+ qreal minimum() const { return m_minimum; }
+ void setMinimum(qreal minimum);
+
+ qreal maximum() const { return m_maximum; }
+ void setMaximum(qreal maximum);
+
+ bool enabled() const { return m_enabled; }
+ void setEnabled(bool enabled);
+
+signals:
+ void minimumChanged();
+ void maximumChanged();
+ void enabledChanged();
+
+private:
+ qreal m_minimum;
+ qreal m_maximum;
+ bool m_enabled;
+};
+
+class Q_AUTOTEST_EXPORT QQuickDragHandler : public QQuickSinglePointHandler
+{
+ Q_OBJECT
+ Q_PROPERTY(QQuickDragAxis * xAxis READ xAxis CONSTANT)
+ Q_PROPERTY(QQuickDragAxis * yAxis READ yAxis CONSTANT)
+ Q_PROPERTY(QVector2D translation READ translation NOTIFY translationChanged)
+
+public:
+ explicit QQuickDragHandler(QObject *parent = 0);
+ ~QQuickDragHandler();
+
+ void handleEventPoint(QQuickEventPoint *point) override;
+
+ QQuickDragAxis *xAxis() { return &m_xAxis; }
+ QQuickDragAxis *yAxis() { return &m_yAxis; }
+
+ QVector2D translation() const { return m_translation; }
+ void setTranslation(const QVector2D &trans);
+
+ Q_INVOKABLE void enforceConstraints();
+
+Q_SIGNALS:
+// void gestureStarted(QQuickGestureEvent *gesture);
+ void translationChanged();
+
+protected:
+ bool wantsEventPoint(QQuickEventPoint *point) override;
+ void onActiveChanged() override;
+ void onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point) override;
+
+private:
+ void ungrab();
+ void enforceAxisConstraints(QPointF *localPos);
+ void initializeTargetStartPos(QQuickEventPoint *point);
+
+private:
+ QPointF m_targetStartPos;
+ QVector2D m_translation;
+ QQuickDragAxis m_xAxis;
+ QQuickDragAxis m_yAxis;
+
+ friend class QQuickDragAxis;
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickDragHandler)
+QML_DECLARE_TYPE(QQuickDragAxis)
+
+#endif // QQUICKDRAGHANDLER_H
diff --git a/src/quick/handlers/qquickhandlersmodule.cpp b/src/quick/handlers/qquickhandlersmodule.cpp
new file mode 100644
index 0000000000..c9e08fe4f2
--- /dev/null
+++ b/src/quick/handlers/qquickhandlersmodule.cpp
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickhandlersmodule_p.h"
+#include "qquickpointerhandler_p.h"
+#include "qquickdraghandler_p.h"
+#include "qquickpinchhandler_p.h"
+#include "qquickpointhandler_p.h"
+#include "qquicktaphandler_p.h"
+
+static void initResources()
+{
+#ifdef QT_STATIC
+ Q_INIT_RESOURCE(qmake_Qt_labs_handlers);
+#endif
+}
+
+QT_BEGIN_NAMESPACE
+
+static QQmlPrivate::AutoParentResult handler_autoParent(QObject *obj, QObject *parent)
+{
+ if (qmlobject_cast<QQuickItem *>(parent)) {
+ QQuickPointerHandler *handler = qmlobject_cast<QQuickPointerHandler *>(obj);
+ if (handler) {
+ handler->setParent(parent);
+ return QQmlPrivate::Parented;
+ }
+ }
+ return QQmlPrivate::IncompatibleObject;
+}
+
+static void qt_quickhandlers_defineModule(const char *uri, int major, int minor)
+{
+ QQmlPrivate::RegisterAutoParent autoparent = { 0, &handler_autoParent };
+ QQmlPrivate::qmlregister(QQmlPrivate::AutoParentRegistration, &autoparent);
+ qmlRegisterUncreatableType<QQuickPointerEvent>(uri, major, minor, "PointerEvent",
+ QQuickPointerHandler::tr("PointerEvent is only available as a parameter of several signals in PointerHandler"));
+ qmlRegisterUncreatableType<QQuickEventPoint>(uri, major, minor, "EventPoint",
+ QQuickPointerHandler::tr("EventPoint is only available as a member of PointerEvent"));
+ qmlRegisterUncreatableType<QQuickEventTouchPoint>(uri, major, minor, "EventTouchPoint",
+ QQuickPointerHandler::tr("EventTouchPoint is only available as a member of PointerEvent"));
+ qmlRegisterUncreatableType<QQuickPointerDevice>(uri, major, minor, "PointerDevice",
+ QQuickPointerHandler::tr("PointerDevice is only available as a property of PointerEvent"));
+ qRegisterMetaType<QPointingDeviceUniqueId>("QPointingDeviceUniqueId");
+ qmlRegisterUncreatableType<QPointingDeviceUniqueId>(uri, major, minor, "PointingDeviceUniqueId",
+ QQuickPointerHandler::tr("PointingDeviceUniqueId is only available as a property of PointerEvent"));
+
+ qmlRegisterUncreatableType<QQuickPointerHandler>(uri,major,minor,"PointerHandler",
+ QQuickPointerHandler::tr("PointerHandler is an abstract base class"));
+ qmlRegisterType<QQuickPointHandler>(uri,major,minor,"PointHandler");
+ qmlRegisterType<QQuickDragHandler>(uri,major,minor,"DragHandler");
+ qmlRegisterUncreatableType<QQuickDragAxis>(uri, major, minor, "DragAxis",
+ QQuickDragHandler::tr("DragAxis is only available as a grouped property of DragHandler"));
+ qmlRegisterType<QQuickPinchHandler>(uri,major,minor,"PinchHandler");
+ qmlRegisterType<QQuickTapHandler>(uri,major,minor,"TapHandler");
+ qRegisterMetaType<QQuickHandlerPoint>();
+}
+
+void QQuickHandlersModule::defineModule()
+{
+ initResources();
+
+ const char uri[] = "Qt.labs.handlers";
+ int majorVersion = 1;
+ int minorVersion = 0;
+
+ qt_quickhandlers_defineModule(uri, majorVersion, minorVersion);
+}
+
+QT_END_NAMESPACE
diff --git a/src/qmldebug/qqmleventlocation_p.h b/src/quick/handlers/qquickhandlersmodule_p.h
index c3a2b93f0f..7eb8d39b98 100644
--- a/src/qmldebug/qqmleventlocation_p.h
+++ b/src/quick/handlers/qquickhandlersmodule_p.h
@@ -3,7 +3,7 @@
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the QtQml module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -37,10 +37,8 @@
**
****************************************************************************/
-#ifndef QQMLEVENTLOCATION_P_H
-#define QQMLEVENTLOCATION_P_H
-
-#include <QtCore/qstring.h>
+#ifndef QQUICKHANDLERSMODULE_P_H
+#define QQUICKHANDLERSMODULE_P_H
//
// W A R N I N G
@@ -53,21 +51,18 @@
// We mean it.
//
+#include <qqml.h>
+#include <private/qtquickglobal_p.h>
+
QT_BEGIN_NAMESPACE
-struct QQmlEventLocation
+class Q_QUICK_PRIVATE_EXPORT QQuickHandlersModule
{
- QQmlEventLocation() : line(-1), column(-1) {}
- QQmlEventLocation(const QString &file, int lineNumber, int columnNumber) :
- filename(file), line(lineNumber), column(columnNumber) {}
-
- QString filename;
- int line;
- int column;
+public:
+ static void defineModule();
};
-Q_DECLARE_TYPEINFO(QQmlEventLocation, Q_MOVABLE_TYPE);
-
QT_END_NAMESPACE
-#endif // QQMLEVENTLOCATION_P_H
+#endif // QQUICKHANDLERSMODULE_P_H
+
diff --git a/src/quick/handlers/qquickmultipointhandler.cpp b/src/quick/handlers/qquickmultipointhandler.cpp
new file mode 100644
index 0000000000..b126b93211
--- /dev/null
+++ b/src/quick/handlers/qquickmultipointhandler.cpp
@@ -0,0 +1,315 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickmultipointhandler_p.h"
+#include <private/qquickitem_p.h>
+#include <QLineF>
+#include <QMouseEvent>
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype MultiPointHandler
+ \since 5.10
+ \preliminary
+ \instantiates QQuickMultiPointHandler
+ \inherits PointerDeviceHandler
+ \inqmlmodule Qt.labs.handlers
+ \ingroup qtquick-handlers
+ \brief Abstract handler for multi-point Pointer Events.
+
+ An intermediate class (not registered as a QML type)
+ for any type of handler which requires and acts upon a specific number
+ of multiple touchpoints.
+*/
+QQuickMultiPointHandler::QQuickMultiPointHandler(QObject *parent, int minimumPointCount)
+ : QQuickPointerDeviceHandler(parent)
+ , m_minimumPointCount(minimumPointCount)
+ , m_maximumPointCount(-1)
+ , m_pointDistanceThreshold(0)
+{
+}
+
+QQuickMultiPointHandler::~QQuickMultiPointHandler()
+{
+}
+
+bool QQuickMultiPointHandler::wantsPointerEvent(QQuickPointerEvent *event)
+{
+ if (!QQuickPointerDeviceHandler::wantsPointerEvent(event))
+ return false;
+
+ if (event->asPointerNativeGestureEvent())
+ return true;
+
+ if (sameAsCurrentPoints(event))
+ return true;
+
+ const QVector<QQuickEventPoint *> candidatePoints = eligiblePoints(event);
+ const bool ret = (candidatePoints.size() >= minimumPointCount() && candidatePoints.size() <= maximumPointCount());
+ if (ret)
+ m_currentPoints = candidatePoints;
+ return ret;
+}
+
+QVector<QQuickEventPoint *> QQuickMultiPointHandler::eligiblePoints(QQuickPointerEvent *event)
+{
+ QVector<QQuickEventPoint *> ret;
+ int c = event->pointCount();
+ QRectF parentBounds = parentItem()->mapRectToScene(parentItem()->boundingRect())
+ .marginsAdded(QMarginsF(m_pointDistanceThreshold, m_pointDistanceThreshold, m_pointDistanceThreshold, m_pointDistanceThreshold));
+ // If one or more points are newly pressed or released, all non-released points are candidates for this handler.
+ // In other cases however, do not steal the grab: that is, if a point has a grabber,
+ // it's not a candidate for this handler.
+ bool stealingAllowed = event->isPressEvent() || event->isReleaseEvent();
+ for (int i = 0; i < c; ++i) {
+ QQuickEventPoint *p = event->point(i);
+ if (!stealingAllowed) {
+ QObject *exclusiveGrabber = p->exclusiveGrabber();
+ if (exclusiveGrabber && exclusiveGrabber != this)
+ continue;
+ }
+ if (p->state() != QQuickEventPoint::Released && parentBounds.contains(p->scenePosition()))
+ ret << p;
+ }
+ return ret;
+}
+
+/*!
+ \qmlproperty int MultiPointHandler::minimumPointCount
+
+ The minimum number of touchpoints required to activate this handler.
+
+ If a smaller number of touchpoints are in contact with the
+ \l {PointerHandler::parent}{parent}, they will be ignored.
+
+ Any ignored points are eligible to activate other Pointer Handlers that
+ have different constraints, on the same Item or on other Items.
+
+ The default value is 2.
+*/
+void QQuickMultiPointHandler::setMinimumPointCount(int c)
+{
+ if (m_minimumPointCount == c)
+ return;
+
+ m_minimumPointCount = c;
+ emit minimumPointCountChanged();
+ if (m_maximumPointCount < 0)
+ emit maximumPointCountChanged();
+}
+
+/*!
+ \qmlproperty int MultiPointHandler::maximumPointCount
+
+ The maximum number of touchpoints this handler can utilize.
+
+ If a larger number of touchpoints are in contact with the
+ \l {PointerHandler::parent}{parent}, the required number of points will be
+ chosen in the order that they are pressed, and the remaining points will
+ be ignored.
+
+ Any ignored points are eligible to activate other Pointer Handlers that
+ have different constraints, on the same Item or on other Items.
+
+ The default value is the same as \l minimumPointCount.
+*/
+void QQuickMultiPointHandler::setMaximumPointCount(int maximumPointCount)
+{
+ if (m_maximumPointCount == maximumPointCount)
+ return;
+
+ m_maximumPointCount = maximumPointCount;
+ emit maximumPointCountChanged();
+}
+
+/*!
+ \qmlproperty real MultiPointHandler::pointDistanceThreshold
+
+ The margin beyond the bounds of the \l {PointerHandler::parent}{parent}
+ item within which a touch point can activate this handler. For example, on
+ a PinchHandler where the \l {PointerHandler::target}{target} is also the
+ \c parent, it's useful to set this to a distance at least half the width
+ of a typical user's finger, so that if the \c parent has been scaled down
+ to a very small size, the pinch gesture is still possible.
+
+ The default value is 0.
+
+ \image pointDistanceThreshold.png
+*/
+void QQuickMultiPointHandler::setPointDistanceThreshold(qreal pointDistanceThreshold)
+{
+ if (m_pointDistanceThreshold == pointDistanceThreshold)
+ return;
+
+ m_pointDistanceThreshold = pointDistanceThreshold;
+ emit pointDistanceThresholdChanged();
+}
+
+bool QQuickMultiPointHandler::sameAsCurrentPoints(QQuickPointerEvent *event)
+{
+ bool ret = true;
+ int c = event->pointCount();
+ if (c != m_currentPoints.size())
+ return false;
+ // TODO optimize: either ensure the points are sorted,
+ // or use std::equal with a predicate
+ for (int i = 0; ret && i < c; ++i) {
+ if (event->point(i)->state() == QQuickEventPoint::Released)
+ return false;
+ bool found = false;
+ int pointId = event->point(i)->pointId();
+ for (QQuickEventPoint *o : qAsConst(m_currentPoints))
+ if (o && pointId == o->pointId())
+ found = true;
+ if (!found)
+ ret = false;
+ }
+ return ret;
+}
+
+// TODO make templates for these functions somehow?
+QPointF QQuickMultiPointHandler::touchPointCentroid()
+{
+ QPointF ret;
+ if (Q_UNLIKELY(m_currentPoints.size() == 0))
+ return ret;
+ for (QQuickEventPoint *point : qAsConst(m_currentPoints))
+ ret += point->scenePosition();
+ return ret / m_currentPoints.size();
+}
+
+QVector2D QQuickMultiPointHandler::touchPointCentroidVelocity()
+{
+ QVector2D ret;
+ if (Q_UNLIKELY(m_currentPoints.size() == 0))
+ return ret;
+ for (QQuickEventPoint *point : qAsConst(m_currentPoints))
+ ret += point->velocity();
+ return ret / m_currentPoints.size();
+}
+
+qreal QQuickMultiPointHandler::averageTouchPointDistance(const QPointF &ref)
+{
+ qreal ret = 0;
+ if (Q_UNLIKELY(m_currentPoints.size() == 0))
+ return ret;
+ for (QQuickEventPoint *point : qAsConst(m_currentPoints))
+ ret += QVector2D(point->scenePosition() - ref).length();
+ return ret / m_currentPoints.size();
+}
+
+qreal QQuickMultiPointHandler::averageStartingDistance(const QPointF &ref)
+{
+ // TODO cache it in setActive()?
+ qreal ret = 0;
+ if (Q_UNLIKELY(m_currentPoints.size() == 0))
+ return ret;
+ for (QQuickEventPoint *point : qAsConst(m_currentPoints))
+ ret += QVector2D(point->sceneGrabPosition() - ref).length();
+ return ret / m_currentPoints.size();
+}
+
+QVector<QQuickMultiPointHandler::PointData> QQuickMultiPointHandler::angles(const QPointF &ref) const
+{
+ QVector<PointData> angles;
+ angles.reserve(m_currentPoints.count());
+ for (QQuickEventPoint *point : qAsConst(m_currentPoints)) {
+ qreal angle = QLineF(ref, point->scenePosition()).angle();
+ angles.append(PointData(point->pointId(), -angle)); // convert to clockwise, to be consistent with QQuickItem::rotation
+ }
+ return angles;
+}
+
+qreal QQuickMultiPointHandler::averageAngleDelta(const QVector<PointData> &old, const QVector<PointData> &newAngles)
+{
+ qreal avgAngleDelta = 0;
+ int numSamples = 0;
+
+ auto oldBegin = old.constBegin();
+
+ for (PointData newData : newAngles) {
+ quint64 id = newData.id;
+ auto it = std::find_if(oldBegin, old.constEnd(), [id] (PointData pd) { return pd.id == id; });
+ qreal angleD = 0;
+ if (it != old.constEnd()) {
+ PointData oldData = *it;
+ // We might rotate from 359 degrees to 1 degree. However, this
+ // should be interpreted as a rotation of +2 degrees instead of
+ // -358 degrees. Therefore, we call remainder() to translate the angle
+ // to be in the range [-180, 180] (-350 to +10 etc)
+ angleD = remainder(newData.angle - oldData.angle, qreal(360));
+ // optimization: narrow down the O(n^2) search to optimally O(n)
+ // if both vectors have the same points and they are in the same order
+ if (it == oldBegin)
+ ++oldBegin;
+ numSamples++;
+ }
+ avgAngleDelta += angleD;
+ }
+ if (numSamples > 1)
+ avgAngleDelta /= numSamples;
+
+ return avgAngleDelta;
+}
+
+void QQuickMultiPointHandler::acceptPoints(const QVector<QQuickEventPoint *> &points)
+{
+ for (QQuickEventPoint* point : points)
+ point->setAccepted();
+}
+
+bool QQuickMultiPointHandler::grabPoints(QVector<QQuickEventPoint *> points)
+{
+ bool allowed = true;
+ for (QQuickEventPoint* point : points) {
+ if (!canGrab(point)) {
+ allowed = false;
+ break;
+ }
+ }
+ if (allowed) {
+ for (QQuickEventPoint* point : points)
+ setExclusiveGrab(point);
+ }
+ return allowed;
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/handlers/qquickmultipointhandler_p.h b/src/quick/handlers/qquickmultipointhandler_p.h
new file mode 100644
index 0000000000..05c3876246
--- /dev/null
+++ b/src/quick/handlers/qquickmultipointhandler_p.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKPOINTERMULTIHANDLER_H
+#define QQUICKPOINTERMULTIHANDLER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qquickitem.h"
+#include "qevent.h"
+#include "qquickpointerdevicehandler_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class Q_AUTOTEST_EXPORT QQuickMultiPointHandler : public QQuickPointerDeviceHandler
+{
+ Q_OBJECT
+ Q_PROPERTY(int minimumPointCount READ minimumPointCount WRITE setMinimumPointCount NOTIFY minimumPointCountChanged)
+ Q_PROPERTY(int maximumPointCount READ maximumPointCount WRITE setMaximumPointCount NOTIFY maximumPointCountChanged)
+ Q_PROPERTY(qreal pointDistanceThreshold READ pointDistanceThreshold WRITE setPointDistanceThreshold NOTIFY pointDistanceThresholdChanged)
+
+public:
+ explicit QQuickMultiPointHandler(QObject *parent = 0, int minimumPointCount = 2);
+ ~QQuickMultiPointHandler();
+
+ int minimumPointCount() const { return m_minimumPointCount; }
+ void setMinimumPointCount(int c);
+
+ int maximumPointCount() const { return m_maximumPointCount >= 0 ? m_maximumPointCount : m_minimumPointCount; }
+ void setMaximumPointCount(int maximumPointCount);
+
+ qreal pointDistanceThreshold() const { return m_pointDistanceThreshold; }
+ void setPointDistanceThreshold(qreal pointDistanceThreshold);
+
+signals:
+ void minimumPointCountChanged();
+ void maximumPointCountChanged();
+ void pointDistanceThresholdChanged();
+
+protected:
+ struct PointData {
+ PointData() : id(0), angle(0) {}
+ PointData(quint64 id, qreal angle) : id(id), angle(angle) {}
+ quint64 id;
+ qreal angle;
+ };
+
+ bool wantsPointerEvent(QQuickPointerEvent *event) override;
+ bool sameAsCurrentPoints(QQuickPointerEvent *event);
+ QVector<QQuickEventPoint *> eligiblePoints(QQuickPointerEvent *event);
+ QPointF touchPointCentroid();
+ QVector2D touchPointCentroidVelocity();
+ qreal averageTouchPointDistance(const QPointF &ref);
+ qreal averageStartingDistance(const QPointF &ref);
+ qreal averageTouchPointAngle(const QPointF &ref);
+ qreal averageStartingAngle(const QPointF &ref);
+ QVector<PointData> angles(const QPointF &ref) const;
+ static qreal averageAngleDelta(const QVector<PointData> &old, const QVector<PointData> &newAngles);
+ void acceptPoints(const QVector<QQuickEventPoint *> &points);
+ bool grabPoints(QVector<QQuickEventPoint *> points);
+
+protected:
+ QVector<QQuickEventPoint *> m_currentPoints;
+ int m_minimumPointCount;
+ int m_maximumPointCount;
+ qreal m_pointDistanceThreshold;
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickMultiPointHandler)
+
+#endif // QQUICKPOINTERMULTIHANDLER_H
diff --git a/src/quick/handlers/qquickpinchhandler.cpp b/src/quick/handlers/qquickpinchhandler.cpp
new file mode 100644
index 0000000000..155822197f
--- /dev/null
+++ b/src/quick/handlers/qquickpinchhandler.cpp
@@ -0,0 +1,490 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickpinchhandler_p.h"
+#include <QtQuick/qquickwindow.h>
+#include <private/qsgadaptationlayer_p.h>
+#include <private/qquickitem_p.h>
+#include <private/qguiapplication_p.h>
+#include <private/qquickwindow_p.h>
+#include <QEvent>
+#include <QMouseEvent>
+#include <QDebug>
+#include <qpa/qplatformnativeinterface.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(lcPinchHandler, "qt.quick.handler.pinch")
+
+/*!
+ \qmltype PinchHandler
+ \instantiates QQuickPinchHandler
+ \inherits MultiPointHandler
+ \inqmlmodule Qt.labs.handlers
+ \ingroup qtquick-handlers
+ \brief Handler for pinch gestures
+
+ PinchHandler is a handler that interprets a multi-finger gesture to
+ interactively rotate, zoom, and drag an Item. Like other Pointer Handlers,
+ by default it is fully functional, and manipulates its \l target,
+ which is the Item within which it is declared.
+
+ \snippet pointerHandlers/pinchHandler.qml 0
+
+ It has properties to restrict the range of dragging, rotation, and zoom.
+
+ If it is declared within one Item but is assigned a different \l target, it
+ handles events within the bounds of the outer Item but manipulates the
+ \c target Item instead:
+
+ \snippet pointerHandlers/pinchHandlerDifferentTarget.qml 0
+
+ A third way to use it is to set \l target to \c null and react to property
+ changes in some other way:
+
+ \snippet pointerHandlers/pinchHandlerNullTarget.qml 0
+
+ \image touchpoints-pinchhandler.png
+
+ \sa PinchArea
+*/
+
+QQuickPinchHandler::QQuickPinchHandler(QObject *parent)
+ : QQuickMultiPointHandler(parent, 2)
+ , m_activeScale(1)
+ , m_activeRotation(0)
+ , m_activeTranslation(0,0)
+ , m_minimumScale(-qInf())
+ , m_maximumScale(qInf())
+ , m_minimumRotation(-qInf())
+ , m_maximumRotation(qInf())
+ , m_minimumX(-qInf())
+ , m_maximumX(qInf())
+ , m_minimumY(-qInf())
+ , m_maximumY(qInf())
+ , m_pinchOrigin(PinchCenter)
+ , m_startScale(1)
+ , m_startRotation(0)
+{
+}
+
+QQuickPinchHandler::~QQuickPinchHandler()
+{
+}
+
+/*!
+ \qmlproperty real QtQuick::PinchHandler::minimumScale
+
+ The minimum acceptable \l {Item::scale}{scale} to be applied
+ to the \l target.
+*/
+void QQuickPinchHandler::setMinimumScale(qreal minimumScale)
+{
+ if (m_minimumScale == minimumScale)
+ return;
+
+ m_minimumScale = minimumScale;
+ emit minimumScaleChanged();
+}
+
+/*!
+ \qmlproperty real QtQuick::PinchHandler::maximumScale
+
+ The maximum acceptable \l {Item::scale}{scale} to be applied
+ to the \l target.
+*/
+void QQuickPinchHandler::setMaximumScale(qreal maximumScale)
+{
+ if (m_maximumScale == maximumScale)
+ return;
+
+ m_maximumScale = maximumScale;
+ emit maximumScaleChanged();
+}
+
+/*!
+ \qmlproperty real QtQuick::PinchHandler::minimumRotation
+
+ The minimum acceptable \l {Item::rotation}{rotation} to be applied
+ to the \l target.
+*/
+void QQuickPinchHandler::setMinimumRotation(qreal minimumRotation)
+{
+ if (m_minimumRotation == minimumRotation)
+ return;
+
+ m_minimumRotation = minimumRotation;
+ emit minimumRotationChanged();
+}
+
+/*!
+ \qmlproperty real QtQuick::PinchHandler::maximumRotation
+
+ The maximum acceptable \l {Item::rotation}{rotation} to be applied
+ to the \l target.
+*/
+void QQuickPinchHandler::setMaximumRotation(qreal maximumRotation)
+{
+ if (m_maximumRotation == maximumRotation)
+ return;
+
+ m_maximumRotation = maximumRotation;
+ emit maximumRotationChanged();
+}
+
+/*!
+ \qmlproperty real QtQuick::PinchHandler::pinchOrigin
+
+ The point to be held in place, around which the \l target is scaled and
+ rotated.
+
+ \value FirstPoint
+ the first touch point, wherever the first finger is pressed
+ \value PinchCenter
+ the centroid between all the touch points at the time when the
+ PinchHandler becomes \l active
+ \value TargetCenter
+ the center of the \l target
+*/
+void QQuickPinchHandler::setPinchOrigin(QQuickPinchHandler::PinchOrigin pinchOrigin)
+{
+ if (m_pinchOrigin == pinchOrigin)
+ return;
+
+ m_pinchOrigin = pinchOrigin;
+ emit pinchOriginChanged();
+}
+
+/*!
+ \qmlproperty real QtQuick::PinchHandler::minimumX
+
+ The minimum acceptable x coordinate of the centroid
+*/
+void QQuickPinchHandler::setMinimumX(qreal minX)
+{
+ if (m_minimumX == minX)
+ return;
+ m_minimumX = minX;
+ emit minimumXChanged();
+}
+
+/*!
+ \qmlproperty real QtQuick::PinchHandler::maximumX
+
+ The maximum acceptable x coordinate of the centroid
+*/
+void QQuickPinchHandler::setMaximumX(qreal maxX)
+{
+ if (m_maximumX == maxX)
+ return;
+ m_maximumX = maxX;
+ emit maximumXChanged();
+}
+
+/*!
+ \qmlproperty real QtQuick::PinchHandler::minimumY
+
+ The minimum acceptable y coordinate of the centroid
+*/
+void QQuickPinchHandler::setMinimumY(qreal minY)
+{
+ if (m_minimumY == minY)
+ return;
+ m_minimumY = minY;
+ emit minimumYChanged();
+}
+
+/*!
+ \qmlproperty real QtQuick::PinchHandler::maximumY
+
+ The maximum acceptable y coordinate of the centroid
+*/
+void QQuickPinchHandler::setMaximumY(qreal maxY)
+{
+ if (m_maximumY == maxY)
+ return;
+ m_maximumY = maxY;
+ emit maximumYChanged();
+}
+
+bool QQuickPinchHandler::wantsPointerEvent(QQuickPointerEvent *event)
+{
+ if (!QQuickMultiPointHandler::wantsPointerEvent(event))
+ return false;
+
+ if (const auto gesture = event->asPointerNativeGestureEvent()) {
+ if (minimumPointCount() == 2) {
+ switch (gesture->type()) {
+ case Qt::BeginNativeGesture:
+ case Qt::EndNativeGesture:
+ case Qt::ZoomNativeGesture:
+ case Qt::RotateNativeGesture:
+ return parentContains(event->point(0));
+ default:
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/*!
+ \qmlproperty int QtQuick::PinchHandler::minimumTouchPoints
+
+ The pinch begins when this number of fingers are pressed.
+ Until then, PinchHandler tracks the positions of any pressed fingers,
+ but if it's an insufficient number, it does not scale or rotate
+ its \l target, and the \l active property will remain false.
+*/
+
+/*!
+ \qmlproperty bool QtQuick::PinchHandler::active
+
+ This property is true when all the constraints (epecially \l minimumTouchPoints)
+ are satisfied and the \l target, if any, is being manipulated.
+*/
+
+void QQuickPinchHandler::onActiveChanged()
+{
+ if (active()) {
+ m_startMatrix = QMatrix4x4();
+ m_startCentroid = touchPointCentroid();
+ m_startAngles = angles(m_startCentroid);
+ m_startDistance = averageTouchPointDistance(m_startCentroid);
+ m_activeRotation = 0;
+ m_activeTranslation = QVector2D();
+ if (const QQuickItem *t = target()) {
+ m_startScale = t->scale(); // TODO incompatible with independent x/y scaling
+ m_startRotation = t->rotation();
+ QVector3D xformOrigin(t->transformOriginPoint());
+ m_startMatrix.translate(t->x(), t->y());
+ m_startMatrix.translate(xformOrigin);
+ m_startMatrix.scale(m_startScale);
+ m_startMatrix.rotate(m_startRotation, 0, 0, -1);
+ m_startMatrix.translate(-xformOrigin);
+ } else {
+ m_startScale = 1;
+ m_startRotation = 0;
+ }
+ qCInfo(lcPinchHandler) << "activated with starting scale" << m_startScale << "rotation" << m_startRotation;
+ } else {
+ qCInfo(lcPinchHandler) << "deactivated with scale" << m_activeScale << "rotation" << m_activeRotation;
+ }
+}
+
+void QQuickPinchHandler::handlePointerEventImpl(QQuickPointerEvent *event)
+{
+ if (Q_UNLIKELY(lcPinchHandler().isDebugEnabled())) {
+ for (QQuickEventPoint *point : qAsConst(m_currentPoints))
+ qCDebug(lcPinchHandler) << point->state() << point->sceneGrabPosition() << "->" << point->scenePosition();
+ }
+
+ qreal dist = 0;
+ if (const auto gesture = event->asPointerNativeGestureEvent()) {
+ switch (gesture->type()) {
+ case Qt::EndNativeGesture:
+ m_activeScale = 1;
+ m_activeRotation = 0;
+ m_activeTranslation = QVector2D();
+ m_centroid = QPointF();
+ m_centroidVelocity = QVector2D();
+ setActive(false);
+ emit updated();
+ return;
+ case Qt::ZoomNativeGesture:
+ m_activeScale *= 1 + gesture->value();
+ break;
+ case Qt::RotateNativeGesture:
+ m_activeRotation += gesture->value();
+ break;
+ default:
+ // Nothing of interest (which is unexpected, because wantsPointerEvent() should have returned false)
+ return;
+ }
+ if (!active()) {
+ m_centroid = gesture->point(0)->scenePosition();
+ setActive(true);
+ m_startCentroid = m_centroid;
+ // Native gestures for 2-finger pinch do not allow dragging, so
+ // the centroid won't move during the gesture, and translation stays at zero
+ m_centroidVelocity = QVector2D();
+ m_activeTranslation = QVector2D();
+ }
+ } else {
+ bool containsReleasedPoints = event->isReleaseEvent();
+ if (!active()) {
+ // Verify that at least one of the points has moved beyond threshold needed to activate the handler
+ for (QQuickEventPoint *point : qAsConst(m_currentPoints)) {
+ if (!containsReleasedPoints && QQuickWindowPrivate::dragOverThreshold(point) && grabPoints(m_currentPoints)) {
+ setActive(true);
+ break;
+ } else {
+ setPassiveGrab(point);
+ }
+ if (point->state() == QQuickEventPoint::Pressed) {
+ point->setAccepted(false); // don't stop propagation
+ setPassiveGrab(point);
+ }
+ }
+ if (!active())
+ return;
+ }
+ // TODO check m_pinchOrigin: right now it acts like it's set to PinchCenter
+ m_centroid = touchPointCentroid();
+ m_centroidVelocity = touchPointCentroidVelocity();
+ // avoid mapping the minima and maxima, as they might have unmappable values
+ // such as -inf/+inf. Because of this we perform the bounding to min/max in local coords.
+ // 1. scale
+ dist = averageTouchPointDistance(m_centroid);
+ m_activeScale = dist / m_startDistance;
+ m_activeScale = qBound(m_minimumScale/m_startScale, m_activeScale, m_maximumScale/m_startScale);
+
+ // 2. rotate
+ QVector<PointData> newAngles = angles(m_centroid);
+ const qreal angleDelta = averageAngleDelta(m_startAngles, newAngles);
+ m_activeRotation += angleDelta;
+ m_startAngles = std::move(newAngles);
+
+ if (!containsReleasedPoints)
+ acceptPoints(m_currentPoints);
+ }
+
+ QPointF centroidParentPos;
+ QRectF bounds(m_minimumX, m_minimumY, m_maximumX - m_minimumX, m_maximumY - m_minimumY);
+ if (target() && target()->parentItem()) {
+ centroidParentPos = target()->parentItem()->mapFromScene(m_centroid);
+ centroidParentPos = QPointF(qBound(bounds.left(), centroidParentPos.x(), bounds.right()),
+ qBound(bounds.top(), centroidParentPos.y(), bounds.bottom()));
+ }
+ const qreal totalRotation = m_startRotation + m_activeRotation;
+ const qreal rotation = qBound(m_minimumRotation, totalRotation, m_maximumRotation);
+ m_activeRotation += (rotation - totalRotation); //adjust for the potential bounding above
+ const qreal scale = m_startScale * m_activeScale;
+
+ if (target() && target()->parentItem()) {
+ // 3. Drag/translate
+ const QPointF centroidStartParentPos = target()->parentItem()->mapFromScene(m_startCentroid);
+ m_activeTranslation = QVector2D(centroidParentPos - centroidStartParentPos);
+
+ // apply rotation + scaling around the centroid - then apply translation.
+ QMatrix4x4 mat;
+
+ const QVector3D centroidParentVector(centroidParentPos);
+ mat.translate(centroidParentVector);
+ mat.rotate(m_activeRotation, 0, 0, 1);
+ mat.scale(m_activeScale);
+ mat.translate(-centroidParentVector);
+ mat.translate(QVector3D(m_activeTranslation));
+
+ mat = mat * m_startMatrix;
+
+ QPointF xformOriginPoint = target()->transformOriginPoint();
+ QPointF pos = mat * xformOriginPoint;
+ pos -= xformOriginPoint;
+
+ target()->setPosition(pos);
+ target()->setRotation(rotation);
+ target()->setScale(scale);
+
+ // TODO some translation inadvertently happens; try to hold the chosen pinch origin in place
+ } else {
+ m_activeTranslation = QVector2D(m_centroid - m_startCentroid);
+ }
+
+ qCDebug(lcPinchHandler) << "centroid" << m_startCentroid << "->" << m_centroid
+ << ", distance" << m_startDistance << "->" << dist
+ << ", startScale" << m_startScale << "->" << scale
+ << ", activeRotation" << m_activeRotation
+ << ", rotation" << rotation
+ << " from " << event->device()->type();
+
+ emit updated();
+}
+
+/*!
+ \readonly
+ \qmlproperty QPointF QtQuick::PinchHandler::centroid
+
+ A point exactly in the middle of the currently-pressed touch points.
+ If \l pinchOrigin is set to \c PinchCenter, the \l target will be rotated
+ around this point.
+*/
+
+/*!
+ \readonly
+ \qmlproperty QVector2D QtQuick::PinchHandler::centroidVelocity
+
+ The average velocity of the \l centroid: a vector representing the speed
+ and direction of movement of the whole group of touchpoints, in logical
+ pixels per second.
+*/
+
+/*!
+ \readonly
+ \qmlproperty real QtQuick::PinchHandler::scale
+
+ The scale factor. It is 1.0 when the gesture begins, increases as the
+ touchpoints are spread apart, and decreases as the touchpoints are brought
+ together. If \l target is not null, this will be automatically applied to its
+ \l {Item::scale}{scale}. Otherwise, bindings can be used to do arbitrary
+ things with this value.
+*/
+
+/*!
+ \readonly
+ \qmlproperty real QtQuick::PinchHandler::rotation
+
+ The rotation of the pinch gesture in degrees, with positive values clockwise.
+ It is 0 when the gesture begins. If \l target is not null, this will be
+ automatically applied to its \l {Item::rotation}{rotation}. Otherwise,
+ bindings can be used to do arbitrary things with this value.
+*/
+
+/*!
+ \readonly
+ \qmlproperty QVector2D QtQuick::PinchHandler::translation
+
+ The translation of the gesture \l centroid. It is \c (0, 0) when the
+ gesture begins.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/quick/handlers/qquickpinchhandler_p.h b/src/quick/handlers/qquickpinchhandler_p.h
new file mode 100644
index 0000000000..7d6b7d9509
--- /dev/null
+++ b/src/quick/handlers/qquickpinchhandler_p.h
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKPINCHHANDLER_H
+#define QQUICKPINCHHANDLER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qquickitem.h"
+#include "qevent.h"
+#include "qquickmultipointhandler_p.h"
+#include <private/qquicktranslate_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_AUTOTEST_EXPORT QQuickPinchHandler : public QQuickMultiPointHandler
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal minimumScale READ minimumScale WRITE setMinimumScale NOTIFY minimumScaleChanged)
+ Q_PROPERTY(qreal maximumScale READ maximumScale WRITE setMaximumScale NOTIFY maximumScaleChanged)
+ Q_PROPERTY(qreal minimumRotation READ minimumRotation WRITE setMinimumRotation NOTIFY minimumRotationChanged)
+ Q_PROPERTY(qreal maximumRotation READ maximumRotation WRITE setMaximumRotation NOTIFY maximumRotationChanged)
+ Q_PROPERTY(PinchOrigin pinchOrigin READ pinchOrigin WRITE setPinchOrigin NOTIFY pinchOriginChanged)
+ Q_PROPERTY(QPointF centroid READ centroid NOTIFY updated)
+ Q_PROPERTY(QVector2D centroidVelocity READ centroidVelocity NOTIFY updated)
+ Q_PROPERTY(qreal scale READ scale NOTIFY updated)
+ Q_PROPERTY(qreal rotation READ rotation NOTIFY updated)
+ Q_PROPERTY(QVector2D translation READ translation NOTIFY updated)
+ Q_PROPERTY(qreal minimumX READ minimumX WRITE setMinimumX NOTIFY minimumXChanged)
+ Q_PROPERTY(qreal maximumX READ maximumX WRITE setMaximumX NOTIFY maximumXChanged)
+ Q_PROPERTY(qreal minimumY READ minimumY WRITE setMinimumY NOTIFY minimumYChanged)
+ Q_PROPERTY(qreal maximumY READ maximumY WRITE setMaximumY NOTIFY maximumYChanged)
+
+public:
+ enum PinchOrigin {
+ FirstPoint, PinchCenter, TargetCenter
+ };
+ Q_ENUM(PinchOrigin)
+
+ explicit QQuickPinchHandler(QObject *parent = 0);
+ ~QQuickPinchHandler();
+
+ qreal minimumScale() const { return m_minimumScale; }
+ void setMinimumScale(qreal minimumScale);
+
+ qreal maximumScale() const { return m_maximumScale; }
+ void setMaximumScale(qreal maximumScale);
+
+ qreal minimumRotation() const { return m_minimumRotation; }
+ void setMinimumRotation(qreal minimumRotation);
+
+ qreal maximumRotation() const { return m_maximumRotation; }
+ void setMaximumRotation(qreal maximumRotation);
+
+ PinchOrigin pinchOrigin() const { return m_pinchOrigin; }
+ void setPinchOrigin(PinchOrigin pinchOrigin);
+
+ QVector2D translation() const { return m_activeTranslation; }
+ qreal scale() const { return m_activeScale; }
+ qreal rotation() const { return m_activeRotation; }
+ QPointF centroid() const { return m_centroid; }
+ QVector2D centroidVelocity() const { return m_centroidVelocity; }
+
+ qreal minimumX() const { return m_minimumX; }
+ void setMinimumX(qreal minX);
+ qreal maximumX() const { return m_maximumX; }
+ void setMaximumX(qreal maxX);
+ qreal minimumY() const { return m_minimumY; }
+ void setMinimumY(qreal minY);
+ qreal maximumY() const { return m_maximumY; }
+ void setMaximumY(qreal maxY);
+
+signals:
+ void minimumScaleChanged();
+ void maximumScaleChanged();
+ void minimumRotationChanged();
+ void maximumRotationChanged();
+ void minimumXChanged();
+ void maximumXChanged();
+ void minimumYChanged();
+ void maximumYChanged();
+ void pinchOriginChanged();
+ void updated();
+
+protected:
+ bool wantsPointerEvent(QQuickPointerEvent *event) override;
+ void onActiveChanged() override;
+ void handlePointerEventImpl(QQuickPointerEvent *event) override;
+
+private:
+ // properties
+ qreal m_activeScale;
+ qreal m_activeRotation;
+ QVector2D m_activeTranslation;
+ QPointF m_centroid;
+ QVector2D m_centroidVelocity;
+
+ qreal m_minimumScale;
+ qreal m_maximumScale;
+
+ qreal m_minimumRotation;
+ qreal m_maximumRotation;
+
+ qreal m_minimumX;
+ qreal m_maximumX;
+ qreal m_minimumY;
+ qreal m_maximumY;
+
+ PinchOrigin m_pinchOrigin;
+
+ // internal
+ qreal m_startScale;
+ qreal m_startRotation;
+ QPointF m_startCentroid;
+ qreal m_startDistance;
+ QPointF m_startPos;
+
+ QVector<PointData> m_startAngles;
+ QMatrix4x4 m_startMatrix;
+ QQuickMatrix4x4 m_transform;
+
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickPinchHandler)
+
+#endif // QQUICKPINCHHANDLER_H
diff --git a/src/quick/handlers/qquickpointerdevicehandler.cpp b/src/quick/handlers/qquickpointerdevicehandler.cpp
new file mode 100644
index 0000000000..1521b58d57
--- /dev/null
+++ b/src/quick/handlers/qquickpointerdevicehandler.cpp
@@ -0,0 +1,196 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickpointerdevicehandler_p.h"
+#include <private/qquickitem_p.h>
+#include <QMouseEvent>
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype PointerDeviceHandler
+ \qmlabstract
+ \since 5.10
+ \preliminary
+ \instantiates QQuickPointerDeviceHandler
+ \inherits PointerHandler
+ \inqmlmodule Qt.labs.handlers
+ \ingroup qtquick-handlers
+ \brief Abstract handler for pointer events with device-specific constraints.
+
+ An intermediate class (not registered as a QML type) for handlers which
+ allow filtering based on device type, pointer type, or keyboard modifiers.
+*/
+QQuickPointerDeviceHandler::QQuickPointerDeviceHandler(QObject *parent)
+ : QQuickPointerHandler(parent)
+ , m_acceptedDevices(QQuickPointerDevice::AllDevices)
+ , m_acceptedPointerTypes(QQuickPointerDevice::AllPointerTypes)
+ , m_acceptedModifiers(Qt::KeyboardModifierMask)
+{
+}
+
+QQuickPointerDeviceHandler::~QQuickPointerDeviceHandler()
+{
+}
+
+/*!
+ \qmlproperty int PointerDeviceHandler::acceptedDevices
+
+ The types of pointing devices that can activate this Pointer Handler.
+
+ By default, this property is set to \l PointerDevice.AllDevices.
+ If you set it to an OR combination of device types, it will ignore events
+ from non-matching devices.
+
+ For example, a control could be made to respond to mouse and stylus clicks
+ in one way, and touchscreen taps in another way, with two handlers:
+
+ \qml
+ Item {
+ TapHandler {
+ acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
+ onTapped: console.log("clicked")
+ }
+ TapHandler {
+ acceptedDevices: PointerDevice.TouchScreen
+ onTapped: console.log("tapped")
+ }
+ }
+ \endqml
+*/
+void QQuickPointerDeviceHandler::setAcceptedDevices(QQuickPointerDevice::DeviceTypes acceptedDevices)
+{
+ if (m_acceptedDevices == acceptedDevices)
+ return;
+
+ m_acceptedDevices = acceptedDevices;
+ emit acceptedDevicesChanged();
+}
+
+/*!
+ \qmlproperty int PointerDeviceHandler::acceptedPointerTypes
+
+ The types of pointing instruments (finger, stylus, eraser, etc.)
+ that can activate this Pointer Handler.
+
+ By default, this property is set to \l PointerDevice.AllPointerTypes.
+ If you set it to an OR combination of device types, it will ignore events
+ from non-matching events.
+
+ For example, a control could be made to respond to mouse, touch, and stylus clicks
+ in some way, but delete itself if tapped with an eraser tool on a graphics tablet,
+ with two handlers:
+
+ \qml
+ Rectangle {
+ id: rect
+ TapHandler {
+ acceptedPointerTypes: PointerDevice.GenericPointer | PointerDevice.Finger | PointerDevice.Pen
+ onTapped: console.log("clicked")
+ }
+ TapHandler {
+ acceptedPointerTypes: PointerDevice.Eraser
+ onTapped: rect.destroy()
+ }
+ }
+ \endqml
+*/
+void QQuickPointerDeviceHandler::setAcceptedPointerTypes(QQuickPointerDevice::PointerTypes acceptedPointerTypes)
+{
+ if (m_acceptedPointerTypes == acceptedPointerTypes)
+ return;
+
+ m_acceptedPointerTypes = acceptedPointerTypes;
+ emit acceptedPointerTypesChanged();
+}
+
+/*!
+ \qmlproperty int PointerDeviceHandler::acceptedModifiers
+
+ If this property is set, it will require the given keyboard modifiers to
+ be pressed in order to react to pointer events, and otherwise ignore them.
+
+ If this property is set to \c Qt.KeyboardModifierMask (the default value),
+ then the PointerHandler ignores the modifier keys.
+
+ For example, an \l [QML] Item could have two handlers of the same type,
+ one of which is enabled only if the required keyboard modifiers are
+ pressed:
+
+ \qml
+ Item {
+ TapHandler {
+ acceptedModifiers: Qt.ControlModifier
+ onTapped: console.log("control-tapped")
+ }
+ TapHandler {
+ acceptedModifiers: Qt.NoModifier
+ onTapped: console.log("tapped")
+ }
+ }
+ \endqml
+*/
+void QQuickPointerDeviceHandler::setAcceptedModifiers(Qt::KeyboardModifiers acceptedModifiers)
+{
+ if (m_acceptedModifiers == acceptedModifiers)
+ return;
+
+ m_acceptedModifiers = acceptedModifiers;
+ emit acceptedModifiersChanged();
+}
+
+bool QQuickPointerDeviceHandler::wantsPointerEvent(QQuickPointerEvent *event)
+{
+ if (!QQuickPointerHandler::wantsPointerEvent(event))
+ return false;
+ qCDebug(lcPointerHandlerDispatch) << objectName()
+ << "checking device type" << m_acceptedDevices
+ << "pointer type" << m_acceptedPointerTypes
+ << "modifiers" << m_acceptedModifiers;
+ if ((event->device()->type() & m_acceptedDevices) == 0)
+ return false;
+ if ((event->device()->pointerType() & m_acceptedPointerTypes) == 0)
+ return false;
+ if (m_acceptedModifiers != Qt::KeyboardModifierMask && event->modifiers() != m_acceptedModifiers)
+ return false;
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/handlers/qquickpointerdevicehandler_p.h b/src/quick/handlers/qquickpointerdevicehandler_p.h
new file mode 100644
index 0000000000..9e30fa0be4
--- /dev/null
+++ b/src/quick/handlers/qquickpointerdevicehandler_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKPOINTERDEVICEHANDLER_H
+#define QQUICKPOINTERDEVICEHANDLER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qquickpointerhandler_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class Q_AUTOTEST_EXPORT QQuickPointerDeviceHandler : public QQuickPointerHandler
+{
+ Q_OBJECT
+ Q_PROPERTY(QQuickPointerDevice::DeviceTypes acceptedDevices READ acceptedDevices WRITE setAcceptedDevices NOTIFY acceptedDevicesChanged)
+ Q_PROPERTY(QQuickPointerDevice::PointerTypes acceptedPointerTypes READ acceptedPointerTypes WRITE setAcceptedPointerTypes NOTIFY acceptedPointerTypesChanged)
+ Q_PROPERTY(Qt::KeyboardModifiers acceptedModifiers READ acceptedModifiers WRITE setAcceptedModifiers NOTIFY acceptedModifiersChanged)
+
+public:
+ explicit QQuickPointerDeviceHandler(QObject *parent = 0);
+ ~QQuickPointerDeviceHandler();
+
+ QQuickPointerDevice::DeviceTypes acceptedDevices() const { return m_acceptedDevices; }
+ QQuickPointerDevice::PointerTypes acceptedPointerTypes() const { return m_acceptedPointerTypes; }
+ Qt::KeyboardModifiers acceptedModifiers() const { return m_acceptedModifiers; }
+
+public slots:
+ void setAcceptedDevices(QQuickPointerDevice::DeviceTypes acceptedDevices);
+ void setAcceptedPointerTypes(QQuickPointerDevice::PointerTypes acceptedPointerTypes);
+ void setAcceptedModifiers(Qt::KeyboardModifiers acceptedModifiers);
+
+Q_SIGNALS:
+ void acceptedDevicesChanged();
+ void acceptedPointerTypesChanged();
+ void acceptedModifiersChanged();
+
+protected:
+ bool wantsPointerEvent(QQuickPointerEvent *event) override;
+
+protected:
+ QQuickPointerDevice::DeviceTypes m_acceptedDevices;
+ QQuickPointerDevice::PointerTypes m_acceptedPointerTypes;
+ Qt::KeyboardModifiers m_acceptedModifiers;
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickPointerDeviceHandler)
+
+#endif // QQUICKPOINTERDEVICEHANDLER_H
diff --git a/src/quick/handlers/qquickpointerhandler.cpp b/src/quick/handlers/qquickpointerhandler.cpp
new file mode 100644
index 0000000000..d6d3a52d95
--- /dev/null
+++ b/src/quick/handlers/qquickpointerhandler.cpp
@@ -0,0 +1,425 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickpointerhandler_p.h"
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(lcPointerHandlerDispatch, "qt.quick.handler.dispatch")
+Q_LOGGING_CATEGORY(lcPointerHandlerGrab, "qt.quick.handler.grab")
+Q_LOGGING_CATEGORY(lcPointerHandlerActive, "qt.quick.handler.active")
+
+/*!
+ \qmltype PointerHandler
+ \qmlabstract
+ \since 5.10
+ \preliminary
+ \instantiates QQuickPointerHandler
+ \inqmlmodule Qt.labs.handlers
+ \ingroup qtquick-handlers
+ \brief Abstract handler for pointer events.
+
+ PointerHandler is the base class handler (not registered as a QML type) for
+ pointer events without regard to source (touch, mouse or graphics tablet).
+*/
+
+QQuickPointerHandler::QQuickPointerHandler(QObject *parent)
+ : QObject(parent)
+ , m_currentEvent(nullptr)
+ , m_target(nullptr)
+ , m_enabled(true)
+ , m_active(false)
+ , m_targetExplicitlySet(false)
+ , m_hadKeepMouseGrab(false)
+ , m_hadKeepTouchGrab(false)
+ , m_grabPermissions(CanTakeOverFromItems | CanTakeOverFromHandlersOfDifferentType | ApprovesTakeOverByAnything)
+{
+}
+
+QQuickPointerHandler::~QQuickPointerHandler()
+{
+ QQuickItem *parItem = parentItem();
+ if (parItem) {
+ QQuickItemPrivate *p = QQuickItemPrivate::get(parItem);
+ p->extra.value().pointerHandlers.removeOne(this);
+ }
+}
+
+/*!
+ Notification that the grab has changed in some way which is relevant to this handler.
+ The \a grabber (subject) will be the PointerHandler whose state is changing,
+ or null if the state change regards an Item.
+ The \a stateChange (verb) tells what happened.
+ The \a point (object) is the point that was grabbed or ungrabbed.
+ EventPoint has the sole responsibility to call this function.
+ The PointerHandler must react in whatever way is appropriate, and must
+ emit the relevant signals (for the benefit of QML code).
+ A subclass is allowed to override this virtual function, but must always
+ call its parent class's implementation in addition to (usually after)
+ whatever custom behavior it implements.
+*/
+void QQuickPointerHandler::onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point)
+{
+ qCDebug(lcPointerHandlerGrab) << point << stateChange << grabber;
+ Q_ASSERT(point);
+ if (grabber == this) {
+ bool wasCanceled = false;
+ switch (stateChange) {
+ case QQuickEventPoint::GrabPassive:
+ case QQuickEventPoint::GrabExclusive:
+ break;
+ case QQuickEventPoint::CancelGrabPassive:
+ case QQuickEventPoint::CancelGrabExclusive:
+ wasCanceled = true; // the grab was stolen by something else
+ Q_FALLTHROUGH();
+ case QQuickEventPoint::UngrabPassive:
+ case QQuickEventPoint::UngrabExclusive:
+ setActive(false);
+ point->setAccepted(false);
+ if (auto par = parentItem()) {
+ par->setKeepMouseGrab(m_hadKeepMouseGrab);
+ par->setKeepTouchGrab(m_hadKeepTouchGrab);
+ }
+ break;
+ case QQuickEventPoint::OverrideGrabPassive:
+ // Passive grab is still there, but we won't receive point updates right now.
+ // No need to notify about this.
+ return;
+ }
+ if (wasCanceled)
+ emit canceled(point);
+ else
+ emit grabChanged(point);
+ }
+}
+
+/*!
+ \internal
+ Acquire or give up a passive grab of the given \a point, according to the \a grab state.
+
+ Unlike the exclusive grab, multiple PointerHandlers can have passive grabs
+ simultaneously. This means that each of them will receive further events
+ when the \a point moves, and when it is finally released. Typically a
+ PointerHandler should acquire a passive grab as soon as a point is pressed,
+ if the handler's constraints do not clearly rule out any interest in that
+ point. For example, DragHandler needs a passive grab in order to watch the
+ movement of a point to see whether it will be dragged past the drag
+ threshold. When a handler is actively manipulating its \l target (that is,
+ when \l active is true), it may be able to do its work with only a passive
+ grab, or it may acquire an exclusive grab if the gesture clearly must not
+ be interpreted in another way by another handler.
+*/
+void QQuickPointerHandler::setPassiveGrab(QQuickEventPoint *point, bool grab)
+{
+ qCDebug(lcPointerHandlerGrab) << point << grab;
+ if (grab) {
+ point->setGrabberPointerHandler(this, false);
+ } else {
+ point->removePassiveGrabber(this);
+ }
+}
+
+/*!
+ Check whether it's OK to take an exclusive grab of the \a point.
+
+ The default implementation will call approveGrabTransition() to check this
+ handler's \l grabPermissions. If grabbing can be done only by taking over
+ the exclusive grab from an Item, approveGrabTransition() checks the Item's
+ \l keepMouseGrab or \l keepTouchGrab flags appropriately. If grabbing can
+ be done only by taking over another handler's exclusive grab, canGrab()
+ also calls approveGrabTransition() on the handler which is about to lose
+ its grab. Either one can deny the takeover.
+*/
+bool QQuickPointerHandler::canGrab(QQuickEventPoint *point)
+{
+ QQuickPointerHandler *existingPhGrabber = point->grabberPointerHandler();
+ return approveGrabTransition(point, this) &&
+ (existingPhGrabber ? existingPhGrabber->approveGrabTransition(point, this) : true);
+}
+
+/*!
+ Check this handler's rules to see if \l proposedGrabber will be allowed to take
+ the exclusive grab. This function may be called twice: once on the instance which
+ will take the grab, and once on the instance which would thereby lose its grab,
+ in case of a takeover scenario.
+*/
+bool QQuickPointerHandler::approveGrabTransition(QQuickEventPoint *point, QObject *proposedGrabber)
+{
+ bool allowed = false;
+ if (proposedGrabber == this) {
+ QObject* existingGrabber = point->exclusiveGrabber();
+ allowed = (existingGrabber == nullptr) || ((m_grabPermissions & CanTakeOverFromAnything) == CanTakeOverFromAnything);
+ if (existingGrabber) {
+ if (QQuickPointerHandler *existingPhGrabber = point->grabberPointerHandler()) {
+ if (!allowed && (m_grabPermissions & CanTakeOverFromHandlersOfDifferentType) &&
+ existingPhGrabber->metaObject()->className() != metaObject()->className())
+ allowed = true;
+ if (!allowed && (m_grabPermissions & CanTakeOverFromHandlersOfSameType) &&
+ existingPhGrabber->metaObject()->className() == metaObject()->className())
+ allowed = true;
+ } else if ((m_grabPermissions & CanTakeOverFromItems)) {
+ QQuickItem * existingItemGrabber = point->grabberItem();
+ if (existingItemGrabber && !((existingItemGrabber->keepMouseGrab() && point->pointerEvent()->asPointerMouseEvent()) ||
+ (existingItemGrabber->keepTouchGrab() && point->pointerEvent()->asPointerTouchEvent())))
+ allowed = true;
+ }
+ }
+ } else {
+ // proposedGrabber is different: that means this instance will lose its grab
+ if (proposedGrabber) {
+ if ((m_grabPermissions & ApprovesTakeOverByAnything) == ApprovesTakeOverByAnything)
+ allowed = true;
+ if (!allowed && (m_grabPermissions & ApprovesTakeOverByHandlersOfDifferentType) &&
+ proposedGrabber->metaObject()->className() != metaObject()->className())
+ allowed = true;
+ if (!allowed && (m_grabPermissions & ApprovesTakeOverByHandlersOfSameType) &&
+ proposedGrabber->metaObject()->className() == metaObject()->className())
+ allowed = true;
+ if (!allowed && (m_grabPermissions & ApprovesTakeOverByItems) && proposedGrabber->inherits("QQuickItem"))
+ allowed = true;
+ } else {
+ if (!allowed && (m_grabPermissions & ApprovesCancellation))
+ allowed = true;
+ }
+ }
+ qCDebug(lcPointerHandlerGrab) << "point" << hex << point->pointId() << "permission" <<
+ QMetaEnum::fromType<GrabPermissions>().valueToKeys(grabPermissions()) <<
+ ':' << this << (allowed ? "approved to" : "denied to") << proposedGrabber;
+ return allowed;
+}
+
+/*!
+ \qmlproperty bool QtQuick::PointerHandler::grabPermission
+
+ This property specifies the permissions when this handler's logic decides
+ to take over the exclusive grab, or when it is asked to approve grab
+ takeover or cancellation by another handler.
+
+ The default is
+ \c {CanTakeOverFromItems | CanTakeOverFromHandlersOfDifferentType | ApprovesTakeOverByAnything}
+ which allows most takeover scenarios but avoids e.g. two PinchHandlers fighting
+ over the same touchpoints.
+*/
+void QQuickPointerHandler::setGrabPermissions(GrabPermissions grabPermission)
+{
+ if (m_grabPermissions == grabPermission)
+ return;
+
+ m_grabPermissions = grabPermission;
+ emit grabPermissionChanged();
+}
+
+/*!
+ \internal
+ Acquire or give up the exclusive grab of the given \a point, according to
+ the \a grab state, and subject to the rules: canGrab(), and the rule not to
+ relinquish another handler's grab. Returns true if permission is granted,
+ or if the exclusive grab has already been acquired or relinquished as
+ specified. Returns false if permission is denied either by this handler or
+ by the handler or item from which this handler would take over
+*/
+bool QQuickPointerHandler::setExclusiveGrab(QQuickEventPoint *point, bool grab)
+{
+ if ((grab && point->exclusiveGrabber() == this) || (!grab && point->exclusiveGrabber() != this))
+ return true;
+ // TODO m_hadKeepMouseGrab m_hadKeepTouchGrab
+ bool allowed = true;
+ if (grab) {
+ allowed = canGrab(point);
+ } else {
+ QQuickPointerHandler *existingPhGrabber = point->grabberPointerHandler();
+ // Ask before allowing one handler to cancel another's grab
+ if (existingPhGrabber && existingPhGrabber != this && !existingPhGrabber->approveGrabTransition(point, nullptr))
+ allowed = false;
+ }
+ qCDebug(lcPointerHandlerGrab) << point << (grab ? "grab" : "ungrab") << (allowed ? "allowed" : "forbidden") <<
+ point->exclusiveGrabber() << "->" << (grab ? this : nullptr);
+ if (allowed)
+ point->setGrabberPointerHandler(grab ? this : nullptr, true);
+ return allowed;
+}
+
+/*!
+ \internal
+ Cancel any existing grab of the given \a point.
+*/
+void QQuickPointerHandler::cancelAllGrabs(QQuickEventPoint *point)
+{
+ qCDebug(lcPointerHandlerGrab) << point;
+ point->cancelAllGrabs(this);
+}
+
+QPointF QQuickPointerHandler::eventPos(const QQuickEventPoint *point) const
+{
+ return (target() ? target()->mapFromScene(point->scenePosition()) : point->scenePosition());
+}
+
+bool QQuickPointerHandler::parentContains(const QQuickEventPoint *point) const
+{
+ if (point) {
+ if (QQuickItem *par = parentItem())
+ return par->contains(par->mapFromScene(point->scenePosition()));
+ }
+ return false;
+}
+
+/*!
+ \qmlproperty bool QtQuick::PointerHandler::enabled
+
+ If a PointerHandler is disabled, it will reject all events
+ and no signals will be emitted.
+*/
+void QQuickPointerHandler::setEnabled(bool enabled)
+{
+ if (m_enabled == enabled)
+ return;
+
+ m_enabled = enabled;
+ emit enabledChanged();
+}
+
+/*!
+ \qmlproperty Item QtQuick::PointerHandler::target
+
+ The Item which this handler will manipulate.
+
+ By default, it is the same as the \l parent: the Item within which
+ the handler is declared. However, it can sometimes be useful to set the
+ target to a different Item, in order to handle events within one item
+ but manipulate another; or to \c null, to disable the default behavior
+ and do something else instead.
+*/
+void QQuickPointerHandler::setTarget(QQuickItem *target)
+{
+ m_targetExplicitlySet = true;
+ if (m_target == target)
+ return;
+
+ QQuickItem *oldTarget = m_target;
+ m_target = target;
+ onTargetChanged(oldTarget);
+ emit targetChanged();
+}
+
+QQuickItem *QQuickPointerHandler::target() const
+{
+ if (!m_targetExplicitlySet)
+ return parentItem();
+ return m_target;
+}
+
+void QQuickPointerHandler::handlePointerEvent(QQuickPointerEvent *event)
+{
+ bool wants = wantsPointerEvent(event);
+ qCDebug(lcPointerHandlerDispatch) << metaObject()->className() << objectName()
+ << "on" << parentItem()->metaObject()->className() << parentItem()->objectName()
+ << (wants ? "WANTS" : "DECLINES") << event;
+ if (wants) {
+ handlePointerEventImpl(event);
+ } else {
+ setActive(false);
+ int pCount = event->pointCount();
+ for (int i = 0; i < pCount; ++i) {
+ QQuickEventPoint *pt = event->point(i);
+ if (pt->grabberPointerHandler() == this && pt->state() != QQuickEventPoint::Stationary)
+ pt->cancelExclusiveGrab();
+ }
+ }
+ event->device()->eventDeliveryTargets().append(this);
+}
+
+bool QQuickPointerHandler::wantsPointerEvent(QQuickPointerEvent *event)
+{
+ Q_UNUSED(event)
+ return m_enabled;
+}
+
+/*!
+ \readonly
+ \qmlproperty bool QtQuick::PointerHandler::active
+
+ This holds true whenever this PointerHandler has taken sole responsibility
+ for handing one or more EventPoints, by successfully taking an exclusive
+ grab of those points. This means that it is keeping its properties
+ up-to-date according to the movements of those Event Points and actively
+ manipulating its \l target (if any).
+*/
+void QQuickPointerHandler::setActive(bool active)
+{
+ if (m_active != active) {
+ qCDebug(lcPointerHandlerActive) << this << m_active << "->" << active;
+ m_active = active;
+ onActiveChanged();
+ emit activeChanged();
+ }
+}
+
+void QQuickPointerHandler::handlePointerEventImpl(QQuickPointerEvent *event)
+{
+ m_currentEvent = event;
+}
+
+/*!
+ \readonly
+ \qmlproperty Item QtQuick::PointerHandler::parent
+
+ The \l Item which is the scope of the handler; the Item in which it was declared.
+ The handler will handle events on behalf of this Item, which means a
+ pointer event is relevant if at least one of its event points occurs within
+ the Item's interior. Initially \l target() is the same, but target()
+ can be reassigned.
+
+ \sa QQuick::PointerHandler::target(), QObject::parent()
+*/
+
+/*!
+ \qmlsignal QtQuick::PointerHandler::grabChanged(EventPoint point)
+
+ This signal is emitted when this handler has acquired or relinquished a
+ passive or exclusive grab of the given \a point.
+*/
+
+/*!
+ \qmlsignal QtQuick::PointerHandler::canceled(EventPoint point)
+
+ If this handler has already grabbed the given \a point, this signal is
+ emitted when the grab is stolen by a different Pointer Handler or Item.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/quick/handlers/qquickpointerhandler_p.h b/src/quick/handlers/qquickpointerhandler_p.h
new file mode 100644
index 0000000000..06a8248468
--- /dev/null
+++ b/src/quick/handlers/qquickpointerhandler_p.h
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKPOINTERHANDLER_H
+#define QQUICKPOINTERHANDLER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qevent.h"
+
+#include <QtQuick/private/qquickevents_p_p.h>
+#include <QtQuick/private/qquickitem_p.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(lcPointerHandlerDispatch)
+
+class Q_QUICK_PRIVATE_EXPORT QQuickPointerHandler : public QObject, public QQmlParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QQmlParserStatus)
+
+ Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
+ Q_PROPERTY(bool active READ active NOTIFY activeChanged)
+ Q_PROPERTY(QQuickItem * target READ target WRITE setTarget NOTIFY targetChanged)
+ Q_PROPERTY(QQuickItem * parent READ parentItem CONSTANT)
+ Q_PROPERTY(GrabPermissions grabPermissions READ grabPermissions WRITE setGrabPermissions NOTIFY grabPermissionChanged)
+
+public:
+ explicit QQuickPointerHandler(QObject *parent = 0);
+ virtual ~QQuickPointerHandler();
+
+ enum GrabPermission {
+ TakeOverForbidden = 0x0,
+ CanTakeOverFromHandlersOfSameType = 0x01,
+ CanTakeOverFromHandlersOfDifferentType= 0x02,
+ CanTakeOverFromItems = 0x04,
+ CanTakeOverFromAnything = 0x0F,
+ ApprovesTakeOverByHandlersOfSameType = 0x10,
+ ApprovesTakeOverByHandlersOfDifferentType= 0x20,
+ ApprovesTakeOverByItems = 0x40,
+ ApprovesCancellation = 0x80,
+ ApprovesTakeOverByAnything = 0xF0
+ };
+ Q_DECLARE_FLAGS(GrabPermissions, GrabPermission)
+ Q_FLAG(GrabPermissions)
+
+public:
+ bool enabled() const { return m_enabled; }
+ void setEnabled(bool enabled);
+
+ bool active() const { return m_active; }
+
+ QQuickItem *target() const;
+ void setTarget(QQuickItem *target);
+
+ QQuickItem * parentItem() const { return static_cast<QQuickItem *>(QObject::parent()); }
+
+ void handlePointerEvent(QQuickPointerEvent *event);
+
+ GrabPermissions grabPermissions() const { return static_cast<GrabPermissions>(m_grabPermissions); }
+ void setGrabPermissions(GrabPermissions grabPermissions);
+
+ void classBegin() override { }
+ void componentComplete() override { }
+
+Q_SIGNALS:
+ void enabledChanged();
+ void activeChanged();
+ void targetChanged();
+ void grabChanged(QQuickEventPoint *point);
+ void grabPermissionChanged();
+ void canceled(QQuickEventPoint *point);
+
+protected:
+ QQuickPointerEvent *currentEvent() { return m_currentEvent; }
+ virtual bool wantsPointerEvent(QQuickPointerEvent *event);
+ virtual void handlePointerEventImpl(QQuickPointerEvent *event);
+ void setActive(bool active);
+ virtual void onTargetChanged(QQuickItem *oldTarget) { Q_UNUSED(oldTarget); }
+ virtual void onActiveChanged() { }
+ virtual void onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point);
+ virtual bool canGrab(QQuickEventPoint *point);
+ virtual bool approveGrabTransition(QQuickEventPoint *point, QObject *proposedGrabber);
+ void setPassiveGrab(QQuickEventPoint *point, bool grab = true);
+ bool setExclusiveGrab(QQuickEventPoint *point, bool grab = true);
+ void cancelAllGrabs(QQuickEventPoint *point);
+ QPointF eventPos(const QQuickEventPoint *point) const;
+ bool parentContains(const QQuickEventPoint *point) const;
+
+private:
+ QQuickPointerEvent *m_currentEvent;
+ QQuickItem *m_target;
+ bool m_enabled : 1;
+ bool m_active : 1;
+ bool m_targetExplicitlySet : 1;
+ bool m_hadKeepMouseGrab : 1; // some handlers override target()->setKeepMouseGrab(); this remembers previous state
+ bool m_hadKeepTouchGrab : 1; // some handlers override target()->setKeepTouchGrab(); this remembers previous state
+ uint m_reserved : 19;
+ uint8_t m_grabPermissions : 8;
+
+ friend class QQuickEventPoint;
+ friend class QQuickWindowPrivate;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickPointerHandler::GrabPermissions)
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickPointerHandler)
+
+#endif // QQUICKPOINTERHANDLER_H
diff --git a/src/quick/handlers/qquickpointhandler.cpp b/src/quick/handlers/qquickpointhandler.cpp
new file mode 100644
index 0000000000..ed03685252
--- /dev/null
+++ b/src/quick/handlers/qquickpointhandler.cpp
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquickpointhandler_p.h"
+#include <private/qquickwindow_p.h>
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \qmltype PointHandler
+ \instantiates QQuickPointHandler
+ \inherits SinglePointHandler
+ \inqmlmodule Qt.labs.handlers
+ \ingroup qtquick-handlers
+ \brief Handler for reacting to a single touchpoint.
+
+ PointHandler can be used to show feedback about a touchpoint or the mouse
+ position, or to otherwise react to pointer events.
+
+ When a press event occurs, each instance of PointHandler chooses a single
+ point which is not yet "taken" at that moment: if the press occurs within
+ the bounds of the \l parent, and no sibling PointHandler within the same
+ \l parent has yet acquired a passive grab on that point, and if the other
+ constraints such as \l acceptedMouseButtons, \l acceptedDevices etc. are
+ satisfied, it's eligible, and the PointHandler then acquires a passive
+ grab. In this way, the \l parent acts like an exclusive group: there can be
+ multiple instances of PointHandler, and the set of pressed touchpoints will
+ be distributed among them. Each PointHandler which has chosen a point to
+ track has its \l active property \c true. It then continues to track its
+ chosen point until release: the properties of the \l point will be kept
+ up-to-date. Any Item can bind to these properties, and thereby follow the
+ point's movements.
+
+ By being only a passive grabber, it has the ability to keep independent
+ oversight of all movements. The passive grab cannot be stolen or overridden
+ even when other gestures are detected and exclusive grabs occur.
+
+ If your goal is orthogonal surveillance of eventpoints, an older
+ alternative was QObject::installEventFilter(), but that has never been a
+ built-in QtQuick feature: it requires some C++ code, such as a QQuickItem
+ subclass. PointHandler is more efficient than that, because only pointer
+ events will be delivered to it, during the course of normal event delivery
+ in QQuickWindow; whereas an event filter needs to filter all QEvents of all
+ types, and thus sets itself up as a potential event delivery bottleneck.
+
+ One possible use case is to add this handler to a transparent Item which is
+ on top of the rest of the scene (by having a high \l z value), so that when
+ a point is freshly pressed, it will be delivered to that Item and its
+ handlers first, providing the opportunity to take the passive grab as early
+ as possible. Such an item (like a pane of glass over the whole UI) can be a
+ convenient parent for other Items which visualize the kind of reactive
+ feedback which must always be on top; and likewise it can be the parent for
+ popups, popovers, dialogs and so on. If it will be used in that way, it can
+ be helpful for your main.cpp to use QQmlContext::setContextProperty() to
+ make the "glass pane" accessible by ID to the entire UI, so that other
+ Items and PointHandlers can be reparented to it.
+
+ \snippet pointerHandlers/pointHandler.qml 0
+
+ Like all pointer handlers, a PointHandler has a \l target property, which
+ may be used as a convenient place to put a point-tracking Item; but
+ PointHandler will not automatically manipulate the \c target item in any way.
+ You need to use bindings to make it react to the \l point.
+
+ \note On macOS, PointHandler does not react to the trackpad by default.
+ That is because macOS can provide either native gesture recognition, or raw
+ touchpoints, but not both. We prefer to use the native gesture event in
+ PinchHandler, so we do not want to disable it by enabling touch. However
+ MultiPointTouchArea does enable touch, thus disabling native gesture
+ recognition within the entire window; so it's an alternative if you only
+ want to react to all the touchpoints but do not require the smooth
+ native-gesture experience.
+
+ \sa MultiPointTouchArea
+*/
+
+QQuickPointHandler::QQuickPointHandler(QObject *parent)
+ : QQuickSinglePointHandler(parent)
+{
+ setIgnoreAdditionalPoints();
+}
+
+QQuickPointHandler::~QQuickPointHandler()
+{
+}
+
+bool QQuickPointHandler::wantsEventPoint(QQuickEventPoint *pt)
+{
+ // On press, we want it unless a sibling of the same type also does.
+ if (pt->state() == QQuickEventPoint::Pressed && QQuickSinglePointHandler::wantsEventPoint(pt)) {
+ for (const QQuickPointerHandler *grabber : pt->passiveGrabbers()) {
+ if (grabber && grabber->parent() == parent() &&
+ grabber->metaObject()->className() == metaObject()->className())
+ return false;
+ }
+ return true;
+ }
+ // If we've already been interested in a point, stay interested, even if it has strayed outside bounds.
+ return (pt->state() != QQuickEventPoint::Pressed && point().id() == pt->pointId());
+}
+
+void QQuickPointHandler::handleEventPoint(QQuickEventPoint *point)
+{
+ switch (point->state()) {
+ case QQuickEventPoint::Pressed:
+ setPassiveGrab(point);
+ setActive(true);
+ break;
+ case QQuickEventPoint::Released:
+ setActive(false);
+ break;
+ default:
+ break;
+ }
+ point->setAccepted(false); // Just lurking... don't interfere with propagation
+ emit translationChanged();
+}
+
+QVector2D QQuickPointHandler::translation() const
+{
+ return QVector2D(point().position() - point().pressPosition());
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/handlers/qquickpointhandler_p.h b/src/quick/handlers/qquickpointhandler_p.h
new file mode 100644
index 0000000000..5babab0c4d
--- /dev/null
+++ b/src/quick/handlers/qquickpointhandler_p.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKPONTHANDLER_H
+#define QQUICKPONTHANDLER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qquicksinglepointhandler_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class Q_AUTOTEST_EXPORT QQuickPointHandler : public QQuickSinglePointHandler
+{
+ Q_OBJECT
+ Q_PROPERTY(QVector2D translation READ translation NOTIFY translationChanged)
+
+public:
+ explicit QQuickPointHandler(QObject *parent = 0);
+ ~QQuickPointHandler();
+
+ QVector2D translation() const;
+
+Q_SIGNALS:
+ void translationChanged();
+
+protected:
+ bool wantsEventPoint(QQuickEventPoint *pt) override;
+ void handleEventPoint(QQuickEventPoint *point) override;
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickPointHandler)
+
+#endif // QQUICKPONTHANDLER_H
diff --git a/src/quick/handlers/qquicksinglepointhandler.cpp b/src/quick/handlers/qquicksinglepointhandler.cpp
new file mode 100644
index 0000000000..dee168a8e4
--- /dev/null
+++ b/src/quick/handlers/qquicksinglepointhandler.cpp
@@ -0,0 +1,475 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquicksinglepointhandler_p.h"
+
+QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(DBG_TOUCH_TARGET)
+
+/*!
+ \qmltype SinglePointHandler
+ \qmlabstract
+ \preliminary
+ \instantiates QQuickSinglePointHandler
+ \inherits PointerDeviceHandler
+ \inqmlmodule Qt.labs.handlers
+ \ingroup qtquick-handlers
+ \brief Abstract handler for single-point Pointer Events.
+
+ An intermediate class (not registered as a QML type)
+ for the most common handlers: those which expect only a single point.
+ wantsPointerEvent() will choose the first point which is inside the
+ \l target item, and return true as long as the event contains that point.
+ Override handleEventPoint() to implement a single-point handler.
+*/
+
+QQuickSinglePointHandler::QQuickSinglePointHandler(QObject *parent)
+ : QQuickPointerDeviceHandler(parent)
+ , m_acceptedButtons(Qt::LeftButton)
+ , m_ignoreAdditionalPoints(false)
+{
+}
+
+bool QQuickSinglePointHandler::wantsPointerEvent(QQuickPointerEvent *event)
+{
+ if (!QQuickPointerDeviceHandler::wantsPointerEvent(event))
+ return false;
+ if (event->device()->pointerType() != QQuickPointerDevice::Finger &&
+ (event->buttons() & m_acceptedButtons) == 0 && (event->button() & m_acceptedButtons) == 0)
+ return false;
+
+ if (m_pointInfo.m_id) {
+ // We already know which one we want, so check whether it's there.
+ // It's expected to be an update or a release.
+ // If we no longer want it, cancel the grab.
+ int candidatePointCount = 0;
+ QQuickEventPoint *point = nullptr;
+ int c = event->pointCount();
+ for (int i = 0; i < c; ++i) {
+ QQuickEventPoint *p = event->point(i);
+ if (wantsEventPoint(p)) {
+ ++candidatePointCount;
+ if (p->pointId() == m_pointInfo.m_id)
+ point = p;
+ }
+ }
+ if (point) {
+ if (candidatePointCount == 1 || (candidatePointCount > 1 && m_ignoreAdditionalPoints)) {
+ point->setAccepted();
+ return true;
+ } else {
+ point->cancelAllGrabs(this);
+ }
+ } else {
+ qCWarning(DBG_TOUCH_TARGET) << this << "pointId" << hex << m_pointInfo.m_id
+ << "is missing from current event, but was neither canceled nor released";
+ return false;
+ }
+ } else {
+ // We have not yet chosen a point; choose the first one for which wantsEventPoint() returns true.
+ int candidatePointCount = 0;
+ int c = event->pointCount();
+ QQuickEventPoint *chosen = nullptr;
+ for (int i = 0; i < c; ++i) {
+ QQuickEventPoint *p = event->point(i);
+ if (!p->exclusiveGrabber() && wantsEventPoint(p)) {
+ if (!chosen)
+ chosen = p;
+ ++candidatePointCount;
+ }
+ }
+ if (chosen && candidatePointCount == 1) {
+ m_pointInfo.m_id = chosen->pointId();
+ chosen->setAccepted();
+ }
+ }
+ return m_pointInfo.m_id;
+}
+
+void QQuickSinglePointHandler::handlePointerEventImpl(QQuickPointerEvent *event)
+{
+ QQuickPointerDeviceHandler::handlePointerEventImpl(event);
+ QQuickEventPoint *currentPoint = event->pointById(m_pointInfo.m_id);
+ Q_ASSERT(currentPoint);
+ if (!m_pointInfo.m_id || !currentPoint->isAccepted()) {
+ reset();
+ } else {
+ if (event->asPointerTouchEvent()) {
+ QQuickEventTouchPoint *tp = static_cast<QQuickEventTouchPoint *>(currentPoint);
+ m_pointInfo.m_uniqueId = tp->uniqueId();
+ m_pointInfo.m_rotation = tp->rotation();
+ m_pointInfo.m_pressure = tp->pressure();
+ m_pointInfo.m_ellipseDiameters = tp->ellipseDiameters();
+ } else if (event->asPointerTabletEvent()) {
+ // TODO
+ } else {
+ m_pointInfo.m_uniqueId = event->device()->uniqueId();
+ m_pointInfo.m_rotation = 0;
+ m_pointInfo.m_pressure = event->buttons() ? 1 : 0;
+ m_pointInfo.m_ellipseDiameters = QSizeF();
+ }
+ m_pointInfo.m_position = currentPoint->position();
+ m_pointInfo.m_scenePosition = currentPoint->scenePosition();
+ if (currentPoint->state() == QQuickEventPoint::Updated)
+ m_pointInfo.m_velocity = currentPoint->velocity();
+ handleEventPoint(currentPoint);
+ switch (currentPoint->state()) {
+ case QQuickEventPoint::Pressed:
+ m_pointInfo.m_pressPosition = currentPoint->position();
+ m_pointInfo.m_scenePressPosition = currentPoint->scenePosition();
+ m_pointInfo.m_pressedButtons = event->buttons();
+ break;
+ case QQuickEventPoint::Released:
+ setExclusiveGrab(currentPoint, false);
+ reset();
+ break;
+ default:
+ m_pointInfo.m_pressedButtons = event->buttons();
+ break;
+ }
+ emit pointChanged();
+ }
+}
+
+bool QQuickSinglePointHandler::wantsEventPoint(QQuickEventPoint *point)
+{
+ return parentContains(point);
+}
+
+void QQuickSinglePointHandler::onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point)
+{
+ if (grabber != this)
+ return;
+ switch (stateChange) {
+ case QQuickEventPoint::GrabExclusive:
+ m_pointInfo.m_sceneGrabPosition = point->sceneGrabPosition();
+ setActive(true);
+ QQuickPointerHandler::onGrabChanged(grabber, stateChange, point);
+ break;
+ case QQuickEventPoint::GrabPassive:
+ m_pointInfo.m_sceneGrabPosition = point->sceneGrabPosition();
+ QQuickPointerHandler::onGrabChanged(grabber, stateChange, point);
+ break;
+ case QQuickEventPoint::OverrideGrabPassive:
+ return; // don't emit
+ case QQuickEventPoint::UngrabPassive:
+ case QQuickEventPoint::UngrabExclusive:
+ case QQuickEventPoint::CancelGrabPassive:
+ case QQuickEventPoint::CancelGrabExclusive:
+ // the grab is lost or relinquished, so the point is no longer relevant
+ QQuickPointerHandler::onGrabChanged(grabber, stateChange, point);
+ reset();
+ break;
+ }
+ emit singlePointGrabChanged();
+}
+
+void QQuickSinglePointHandler::setIgnoreAdditionalPoints(bool v)
+{
+ m_ignoreAdditionalPoints = v;
+}
+
+void QQuickSinglePointHandler::moveTarget(QPointF pos, QQuickEventPoint *point)
+{
+ target()->setPosition(pos);
+ m_pointInfo.m_scenePosition = point->scenePosition();
+ m_pointInfo.m_position = target()->mapFromScene(m_pointInfo.m_scenePosition);
+}
+
+/*!
+ \qmlproperty int QtQuick::SinglePointHandler::acceptedButtons
+
+ The mouse buttons which can activate this Pointer Handler.
+
+ By default, this property is set to \l Qt.LeftButton.
+ It can be set to an OR combination of mouse buttons, and will ignore events
+ from other buttons.
+
+ For example, a control could be made to respond to left and right clicks
+ in different ways, with two handlers:
+
+ \qml
+ Item {
+ TapHandler {
+ onTapped: console.log("left clicked")
+ }
+ TapHandler {
+ acceptedButtons: Qt.RightButton
+ onTapped: console.log("right clicked")
+ }
+ }
+ \endqml
+
+ \note Tapping on a touchscreen or tapping the stylus on a graphics tablet
+ emulates clicking the left mouse button. This behavior can be altered via
+ \l {PointerDeviceHandler::acceptedDevices}{acceptedDevices} or
+ \l {PointerDeviceHandler::acceptedPointerTypes}{acceptedPointerTypes}.
+*/
+void QQuickSinglePointHandler::setAcceptedButtons(Qt::MouseButtons buttons)
+{
+ if (m_acceptedButtons == buttons)
+ return;
+
+ m_acceptedButtons = buttons;
+ emit acceptedButtonsChanged();
+}
+
+void QQuickSinglePointHandler::reset()
+{
+ setActive(false);
+ m_pointInfo.reset();
+}
+
+/*!
+ \readonly
+ \qmlproperty HandlerPoint QtQuick::SinglePointHandler::point
+
+ The event point currently being handled. When no point is currently being
+ handled, this object is reset to default values (all coordinates are 0).
+*/
+
+/*!
+ \qmltype HandlerPoint
+ \instantiates QQuickHandlerPoint
+ \inqmlmodule Qt.labs.handlers
+ \ingroup qtquick-handlers
+ \brief An event point
+
+ A QML representation of a QQuickEventPoint.
+
+ It's possible to make bindings to properties of a \l SinglePointHandler's
+ current point. For example:
+
+ \snippet pointerHandlers/dragHandlerNullTarget.qml 0
+
+ The point is kept up-to-date when the DragHandler is actively responding to
+ an EventPoint; but when the point is released, or the current point is
+ being handled by a different handler, \c position.x and \c position.y are 0.
+
+ \note This is practically identical to QtQuick::EventPoint; however an
+ EventPoint is a long-lived QObject which is invalidated between gestures
+ and reused for subsequent event deliveries. Continuous bindings to its
+ properties are not possible, and an individual handler cannot rely on it
+ outside the period when that point is part of an active gesture which that
+ handler is handling. HandlerPoint is a Q_GADGET that the handler owns.
+ This allows you to make lifetime bindings to its properties.
+
+ \sa SinglePointHandler::point
+*/
+
+QQuickHandlerPoint::QQuickHandlerPoint()
+ : m_id(0)
+ , m_rotation(0)
+ , m_pressure(0)
+{}
+
+void QQuickHandlerPoint::reset()
+{
+ m_id = 0;
+ m_uniqueId = QPointingDeviceUniqueId();
+ m_position = QPointF();
+ m_scenePosition = QPointF();
+ m_pressPosition = QPointF();
+ m_scenePressPosition = QPointF();
+ m_sceneGrabPosition = QPointF();
+ m_velocity = QVector2D();
+ m_rotation = 0;
+ m_pressure = 0;
+ m_ellipseDiameters = QSizeF();
+ m_pressedButtons = Qt::NoButton;
+}
+
+/*!
+ \readonly
+ \qmlproperty int QtQuick::HandlerPoint::id
+ \brief The ID number of the point
+
+ During a touch gesture, from the time that the first finger is pressed
+ until the last finger is released, each touchpoint will have a unique ID
+ number. Likewise, if input from multiple devices occurs (for example
+ simultaneous mouse and touch presses), all the current event points from
+ all the devices will have unique IDs.
+
+ \note Do not assume that id numbers start at zero or that they are
+ sequential. Such an assumption is often false due to the way the underlying
+ drivers work.
+
+ \sa QTouchEvent::TouchPoint::id
+*/
+
+/*!
+ \readonly
+ \qmlproperty PointingDeviceUniqueId QtQuick::HandlerPoint::uniqueId
+ \brief The unique ID of the point, if any
+
+ This is normally empty, because touchscreens cannot uniquely identify fingers.
+
+ On some types of touchscreens, especially those using TUIO drivers,
+ it's possible to use recognizable physical tokens (fiducial objects)
+ in addition to fingers. So if this point is a touch point, and
+ uniqueId is set, it is the identifier for such an object.
+
+ On a graphics tablet, each type of stylus or other tool often has a unique
+ ID or serial number, which can be useful to respond in different ways to
+ different tools.
+
+ Interpreting the contents of this ID requires knowledge of the hardware and
+ drivers in use.
+
+ \sa QTabletEvent::uniqueId, QtQuick::TouchPoint::uniqueId, QtQuick::EventTouchPoint::uniqueId
+*/
+
+/*!
+ \readonly
+ \qmlproperty QPointF QtQuick::HandlerPoint::position
+ \brief The position within the \c parent Item
+
+ This is the position of the event point relative to the bounds of the \l parent.
+*/
+
+/*!
+ \readonly
+ \qmlproperty QPointF QtQuick::HandlerPoint::scenePosition
+ \brief The position within the scene
+
+ This is the position of the event point relative to the bounds of the Qt
+ Quick scene (typically the whole window).
+*/
+
+/*!
+ \readonly
+ \qmlproperty QPointF QtQuick::HandlerPoint::pressPosition
+ \brief The pressed position within the \c parent Item
+
+ This is the position at which this point was pressed, relative to the
+ bounds of the \l parent.
+*/
+
+/*!
+ \readonly
+ \qmlproperty QPointF QtQuick::HandlerPoint::scenePressPosition
+ \brief The pressed position within the scene
+
+ This is the position at which this point was pressed, in the coordinate
+ system of the \l {Qt Quick Scene Graph}{scene graph}.
+*/
+
+/*!
+ \readonly
+ \qmlproperty QPointF QtQuick::HandlerPoint::sceneGrabPosition
+ \brief The grabbed position within the scene
+
+ If this point has been grabbed by a Pointer Handler or an Item, it means
+ that object has taken sole responsibility for handling the movement and the
+ release if this point. In that case, this is the position at which the grab
+ occurred, in the coordinate system of the \l {Qt Quick Scene Graph}{scene graph}.
+*/
+
+/*!
+ \readonly
+ \qmlproperty enum QtQuick::HandlerPoint::pressedButtons
+ \brief Which mouse or stylus buttons are currently pressed
+
+ \sa MouseArea::pressedButtons
+*/
+
+/*!
+ \readonly
+ \qmlproperty QVector2D QtQuick::HandlerPoint::velocity
+ \brief A vector representing the average speed and direction of movement
+
+ This is a velocity vector pointing in the direction of movement, in logical
+ pixels per second. It has x and y components, at least one of which will be
+ nonzero when this point is in motion. It holds the average recent velocity:
+ how fast and in which direction the event point has been moving recently.
+
+ \sa QtQuick::EventPoint::velocity, QtQuick::TouchPoint::velocity, QTouchEvent::TouchPoint::velocity
+*/
+
+/*!
+ \readonly
+ \qmlproperty qreal QtQuick::HandlerPoint::rotation
+
+ This property holds the rotation angle of the stylus on a graphics tablet
+ or the contact patch of a touchpoint on a touchscreen.
+
+ It is valid only with certain tablet stylus devices and touchscreens that
+ can measure the rotation angle. Otherwise, it will be zero.
+*/
+
+/*!
+ \readonly
+ \qmlproperty qreal QtQuick::HandlerPoint::pressure
+
+ This property tells how hard the user is pressing the stylus on a graphics
+ tablet or the finger against a touchscreen, in the range from \c 0 (no
+ measurable pressure) to \c 1.0 (maximum pressure which the device can
+ measure).
+
+ It is valid only with certain tablets and touchscreens that can measure
+ pressure. Otherwise, it will be zero.
+*/
+
+/*!
+ \readonly
+ \qmlproperty size QtQuick::HandlerPoint::ellipseDiameters
+
+ This property holds the diameters of the contact patch, if the event
+ comes from a touchpoint and the device provides this information.
+
+ A touchpoint is modeled as an elliptical area where the finger is pressed
+ against the touchscreen. (In fact, it could also be modeled as a bitmap;
+ but in that case we expect an elliptical bounding estimate to be fitted to
+ the contact patch before the event is sent.) The harder the user presses,
+ the larger the contact patch; so, these diameters provide an alternate way
+ of detecting pressure, in case the device does not include a separate
+ pressure sensor. The ellipse is centered on \l scenePosition (\l position
+ in the PointerHandler's Item's local coordinates). The \l rotation property
+ provides the rotation of the ellipse, if known. It is expected that if the
+ \l rotation is zero, the \l {QSize::height}{height} is the larger dimension
+ (the major axis), because of the usual hand position, reaching upward or
+ outward across the surface.
+
+ If the contact patch is unknown, or the device is not a touchscreen,
+ these values will be zero.
+
+ \sa QtQuick::EventPoint::ellipseDiameters, QtQuick::TouchPoint::ellipseDiameters, QTouchEvent::TouchPoint::ellipseDiameters
+*/
+
+QT_END_NAMESPACE
diff --git a/src/quick/handlers/qquicksinglepointhandler_p.h b/src/quick/handlers/qquicksinglepointhandler_p.h
new file mode 100644
index 0000000000..386cea253a
--- /dev/null
+++ b/src/quick/handlers/qquicksinglepointhandler_p.h
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKPOINTERSINGLEHANDLER_H
+#define QQUICKPOINTERSINGLEHANDLER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qquickpointerdevicehandler_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QQuickSinglePointHandler;
+
+class Q_QUICK_PRIVATE_EXPORT QQuickHandlerPoint {
+ Q_GADGET
+ Q_PROPERTY(int id READ id)
+ Q_PROPERTY(QPointingDeviceUniqueId uniqueId READ uniqueId)
+ Q_PROPERTY(QPointF position READ position)
+ Q_PROPERTY(QPointF scenePosition READ scenePosition)
+ Q_PROPERTY(QPointF pressPosition READ pressPosition)
+ Q_PROPERTY(QPointF scenePressPosition READ scenePressPosition)
+ Q_PROPERTY(QPointF sceneGrabPosition READ sceneGrabPosition)
+ Q_PROPERTY(Qt::MouseButtons pressedButtons READ pressedButtons)
+ Q_PROPERTY(QVector2D velocity READ velocity)
+ Q_PROPERTY(qreal rotation READ rotation)
+ Q_PROPERTY(qreal pressure READ pressure)
+ Q_PROPERTY(QSizeF ellipseDiameters READ ellipseDiameters)
+
+public:
+ QQuickHandlerPoint();
+
+ int id() const { return m_id; }
+ Qt::MouseButtons pressedButtons() const { return m_pressedButtons; }
+ QPointF pressPosition() const { return m_pressPosition; }
+ QPointF scenePressPosition() const { return m_scenePressPosition; }
+ QPointF sceneGrabPosition() const { return m_sceneGrabPosition; }
+ QPointF position() const { return m_position; }
+ QPointF scenePosition() const { return m_scenePosition; }
+ QVector2D velocity() const { return m_velocity; }
+ qreal rotation() const { return m_rotation; }
+ qreal pressure() const { return m_pressure; }
+ QSizeF ellipseDiameters() const { return m_ellipseDiameters; }
+ QPointingDeviceUniqueId uniqueId() const { return m_uniqueId; }
+
+private:
+ void reset();
+ int m_id;
+ QPointingDeviceUniqueId m_uniqueId;
+ Qt::MouseButtons m_pressedButtons;
+ QPointF m_position;
+ QPointF m_scenePosition;
+ QPointF m_pressPosition;
+ QPointF m_scenePressPosition;
+ QPointF m_sceneGrabPosition;
+ QVector2D m_velocity;
+ qreal m_rotation;
+ qreal m_pressure;
+ QSizeF m_ellipseDiameters;
+ friend class QQuickSinglePointHandler;
+};
+
+class Q_QUICK_PRIVATE_EXPORT QQuickSinglePointHandler : public QQuickPointerDeviceHandler
+{
+ Q_OBJECT
+ Q_PROPERTY(Qt::MouseButtons acceptedButtons READ acceptedButtons WRITE setAcceptedButtons NOTIFY acceptedButtonsChanged)
+ Q_PROPERTY(QQuickHandlerPoint point READ point NOTIFY pointChanged)
+public:
+ explicit QQuickSinglePointHandler(QObject *parent = 0);
+ virtual ~QQuickSinglePointHandler() { }
+
+ Qt::MouseButtons acceptedButtons() const { return m_acceptedButtons; }
+ void setAcceptedButtons(Qt::MouseButtons buttons);
+
+ QQuickHandlerPoint point() const { return m_pointInfo; }
+
+Q_SIGNALS:
+ void pointChanged();
+ void singlePointGrabChanged(); // QQuickPointerHandler::grabChanged signal can't be a property notifier here
+ void acceptedButtonsChanged();
+
+protected:
+ bool wantsPointerEvent(QQuickPointerEvent *event) override;
+ virtual bool wantsEventPoint(QQuickEventPoint *point);
+ void handlePointerEventImpl(QQuickPointerEvent *event) override;
+ virtual void handleEventPoint(QQuickEventPoint *point) = 0;
+
+ QQuickEventPoint *currentPoint(QQuickPointerEvent *ev) { return ev->pointById(m_pointInfo.m_id); }
+ void onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point) override;
+
+ void setIgnoreAdditionalPoints(bool v = true);
+
+ void moveTarget(QPointF pos, QQuickEventPoint *point);
+
+private:
+ void reset();
+
+private:
+ QQuickHandlerPoint m_pointInfo;
+ Qt::MouseButtons m_acceptedButtons;
+ bool m_ignoreAdditionalPoints : 1;
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickHandlerPoint)
+QML_DECLARE_TYPE(QQuickSinglePointHandler)
+
+#endif // QQUICKPOINTERSINGLEHANDLER_H
diff --git a/src/quick/handlers/qquicktaphandler.cpp b/src/quick/handlers/qquicktaphandler.cpp
new file mode 100644
index 0000000000..a1b4f961ed
--- /dev/null
+++ b/src/quick/handlers/qquicktaphandler.cpp
@@ -0,0 +1,371 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qquicktaphandler_p.h"
+#include <qpa/qplatformtheme.h>
+#include <private/qguiapplication_p.h>
+#include <QtGui/qstylehints.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(lcTapHandler, "qt.quick.handler.tap")
+
+qreal QQuickTapHandler::m_multiTapInterval(0.0);
+// single tap distance is the same as the drag threshold
+int QQuickTapHandler::m_mouseMultiClickDistanceSquared(-1);
+int QQuickTapHandler::m_touchMultiTapDistanceSquared(-1);
+
+/*!
+ \qmltype TapHandler
+ \instantiates QQuickTapHandler
+ \inherits SinglePointHandler
+ \inqmlmodule Qt.labs.handlers
+ \ingroup qtquick-handlers
+ \brief Handler for taps and clicks.
+
+ TapHandler is a handler for taps on a touchscreen or clicks on a mouse.
+
+ Detection of a valid tap gesture depends on \l gesturePolicy. The default
+ value is DragThreshold, which requires the press and release to be close
+ together in both space and time. In this case, DragHandler is able to
+ function using only a passive grab, and therefore does not interfere with
+ event delivery to any other Items or Pointer Handlers. So the default
+ gesturePolicy is useful when you want to modify behavior of an existing
+ control or Item by adding a TapHandler with bindings and/or JavaScript
+ callbacks.
+
+ Note that buttons (such as QPushButton) are often implemented not to care
+ whether the press and release occur close together: if you press the button
+ and then change your mind, you need to drag all the way off the edge of the
+ button in order to cancel the click. For this use case, set the
+ \l gesturePolicy to \c TapHandler.ReleaseWithinBounds.
+
+ For multi-tap gestures (double-tap, triple-tap etc.), the distance moved
+ must not exceed QPlatformTheme::MouseDoubleClickDistance with mouse and
+ QPlatformTheme::TouchDoubleTapDistance with touch, and the time between
+ taps must not exceed QStyleHints::mouseDoubleClickInterval().
+
+ \sa MouseArea
+*/
+
+QQuickTapHandler::QQuickTapHandler(QObject *parent)
+ : QQuickSinglePointHandler(parent)
+ , m_pressed(false)
+ , m_gesturePolicy(DragThreshold)
+ , m_tapCount(0)
+ , m_longPressThreshold(-1)
+ , m_lastTapTimestamp(0.0)
+{
+ if (m_mouseMultiClickDistanceSquared < 0) {
+ m_multiTapInterval = qApp->styleHints()->mouseDoubleClickInterval() / 1000.0;
+ m_mouseMultiClickDistanceSquared = QGuiApplicationPrivate::platformTheme()->
+ themeHint(QPlatformTheme::MouseDoubleClickDistance).toInt();
+ m_mouseMultiClickDistanceSquared *= m_mouseMultiClickDistanceSquared;
+ m_touchMultiTapDistanceSquared = QGuiApplicationPrivate::platformTheme()->
+ themeHint(QPlatformTheme::TouchDoubleTapDistance).toInt();
+ m_touchMultiTapDistanceSquared *= m_touchMultiTapDistanceSquared;
+ }
+}
+
+QQuickTapHandler::~QQuickTapHandler()
+{
+}
+
+static bool dragOverThreshold(QQuickEventPoint *point)
+{
+ QPointF delta = point->scenePosition() - point->scenePressPosition();
+ return (QQuickWindowPrivate::dragOverThreshold(delta.x(), Qt::XAxis, point) ||
+ QQuickWindowPrivate::dragOverThreshold(delta.y(), Qt::YAxis, point));
+}
+
+bool QQuickTapHandler::wantsEventPoint(QQuickEventPoint *point)
+{
+ // If the user has not violated any constraint, it could be a tap.
+ // Otherwise we want to give up the grab so that a competing handler
+ // (e.g. DragHandler) gets a chance to take over.
+ // Don't forget to emit released in case of a cancel.
+ bool ret = false;
+ switch (point->state()) {
+ case QQuickEventPoint::Pressed:
+ case QQuickEventPoint::Released:
+ ret = parentContains(point);
+ break;
+ case QQuickEventPoint::Updated:
+ switch (m_gesturePolicy) {
+ case DragThreshold:
+ ret = !dragOverThreshold(point);
+ break;
+ case WithinBounds:
+ ret = parentContains(point);
+ break;
+ case ReleaseWithinBounds:
+ ret = point->pointId() == this->point().id();
+ break;
+ }
+ break;
+ case QQuickEventPoint::Stationary:
+ // Never react in any way when the point hasn't moved.
+ // In autotests, the point's position may not even be correct, because
+ // QTest::touchEvent(window, touchDevice).stationary(1)
+ // provides no opportunity to give a position, so it ends up being random.
+ break;
+ }
+ // If this is the grabber, returning false from this function will cancel the grab,
+ // so onGrabChanged(this, CancelGrabExclusive, point) and setPressed(false) will be called.
+ // But when m_gesturePolicy is DragThreshold, we don't get an exclusive grab, but
+ // we still don't want to be pressed anymore.
+ if (!ret && point->pointId() == this->point().id() && point->state() != QQuickEventPoint::Stationary)
+ setPressed(false, true, point);
+ return ret;
+}
+
+void QQuickTapHandler::handleEventPoint(QQuickEventPoint *point)
+{
+ switch (point->state()) {
+ case QQuickEventPoint::Pressed:
+ setPressed(true, false, point);
+ break;
+ case QQuickEventPoint::Released:
+ if ((point->pointerEvent()->buttons() & acceptedButtons()) == Qt::NoButton)
+ setPressed(false, false, point);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ \qmlproperty real TapHandler::longPressThreshold
+
+ The time in seconds that an event point must be pressed in order to
+ trigger a long press gesture and emit the \l longPressed() signal.
+ If the point is released before this time limit, a tap can be detected
+ if the \l gesturePolicy constraint is satisfied. The default value is
+ QStyleHints::mousePressAndHoldInterval() converted to seconds.
+*/
+qreal QQuickTapHandler::longPressThreshold() const
+{
+ return longPressThresholdMilliseconds() / 1000.0;
+}
+
+void QQuickTapHandler::setLongPressThreshold(qreal longPressThreshold)
+{
+ int ms = qRound(longPressThreshold * 1000);
+ if (m_longPressThreshold == ms)
+ return;
+
+ m_longPressThreshold = ms;
+ emit longPressThresholdChanged();
+}
+
+int QQuickTapHandler::longPressThresholdMilliseconds() const
+{
+ return (m_longPressThreshold < 0 ? QGuiApplication::styleHints()->mousePressAndHoldInterval() : m_longPressThreshold);
+}
+
+void QQuickTapHandler::timerEvent(QTimerEvent *event)
+{
+ if (event->timerId() == m_longPressTimer.timerId()) {
+ m_longPressTimer.stop();
+ qCDebug(lcTapHandler) << objectName() << "longPressed";
+ emit longPressed();
+ }
+}
+
+/*!
+ \qmlproperty enumeration TapHandler::gesturePolicy
+
+ The spatial constraint for a tap or long press gesture to be recognized,
+ in addition to the constraint that the release must occur before
+ \l longPressThreshold has elapsed. If these constraints are not satisfied,
+ the \l tapped signal is not emitted, and \l tapCount is not incremented.
+ If the spatial constraint is violated, \l isPressed transitions immediately
+ from true to false, regardless of the time held.
+
+ \value TapHandler.DragThreshold
+ The event point must not move significantly. If the mouse, finger
+ or stylus moves past the system-wide drag threshold
+ (QStyleHints::startDragDistance), the tap gesture is canceled, even
+ if the button or finger is still pressed. This policy can be useful
+ whenever TapHandler needs to cooperate with other pointer handlers
+ (for example \l DragHandler), because in this case TapHandler will
+ never grab.
+
+ \value TapHandler.WithinBounds
+ If the event point leaves the bounds of the \l target item, the tap
+ gesture is canceled. The TapHandler will grab on press, but release
+ the grab as soon as the boundary constraint is no longer satisfied.
+
+ \value TapHandler.ReleaseWithinBounds
+ (the default value) At the time of release (the mouse button is
+ released or the finger is lifted), if the event point is outside
+ the bounds of the \l target item, a tap gesture is not recognized.
+ This is the default value, because it corresponds to typical button
+ behavior: you can cancel a click by dragging outside the button,
+ and you can also change your mind by dragging back inside the button
+ before release. Note that it's necessary for TapHandler to grab on
+ press and retain it until release (greedy grab) in order to detect
+ this gesture.
+*/
+void QQuickTapHandler::setGesturePolicy(QQuickTapHandler::GesturePolicy gesturePolicy)
+{
+ if (m_gesturePolicy == gesturePolicy)
+ return;
+
+ m_gesturePolicy = gesturePolicy;
+ emit gesturePolicyChanged();
+}
+
+/*!
+ \qmlproperty bool TapHandler::pressed
+ \readonly
+
+ Holds true whenever the mouse or touch point is pressed,
+ and any movement since the press is compliant with the current
+ \l gesturePolicy. When the event point is released or the policy is
+ violated, \e pressed will change to false.
+*/
+void QQuickTapHandler::setPressed(bool press, bool cancel, QQuickEventPoint *point)
+{
+ if (m_pressed != press) {
+ qCDebug(lcTapHandler) << objectName() << "pressed" << m_pressed << "->" << press << (cancel ? "CANCEL" : "") << point;
+ m_pressed = press;
+ connectPreRenderSignal(press);
+ updateTimeHeld();
+ if (press) {
+ m_longPressTimer.start(longPressThresholdMilliseconds(), this);
+ m_holdTimer.start();
+ } else {
+ m_longPressTimer.stop();
+ m_holdTimer.invalidate();
+ }
+ if (press) {
+ // on press, grab before emitting changed signals
+ if (m_gesturePolicy == DragThreshold)
+ setPassiveGrab(point, press);
+ else
+ setExclusiveGrab(point, press);
+ }
+ if (!cancel && !press && parentContains(point)) {
+ if (point->timeHeld() < longPressThreshold()) {
+ // Assuming here that pointerEvent()->timestamp() is in ms.
+ qreal ts = point->pointerEvent()->timestamp() / 1000.0;
+ if (ts - m_lastTapTimestamp < m_multiTapInterval &&
+ QVector2D(point->scenePosition() - m_lastTapPos).lengthSquared() <
+ (point->pointerEvent()->device()->type() == QQuickPointerDevice::Mouse ?
+ m_mouseMultiClickDistanceSquared : m_touchMultiTapDistanceSquared))
+ ++m_tapCount;
+ else
+ m_tapCount = 1;
+ qCDebug(lcTapHandler) << objectName() << "tapped" << m_tapCount << "times";
+ emit tapped();
+ emit tapCountChanged();
+ m_lastTapTimestamp = ts;
+ m_lastTapPos = point->scenePosition();
+ } else {
+ qCDebug(lcTapHandler) << objectName() << "tap threshold" << longPressThreshold() << "exceeded:" << point->timeHeld();
+ }
+ }
+ emit pressedChanged();
+ if (!press && m_gesturePolicy != DragThreshold) {
+ // on release, ungrab after emitting changed signals
+ setExclusiveGrab(point, press);
+ }
+ if (cancel)
+ emit canceled(point);
+ }
+}
+
+void QQuickTapHandler::onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point)
+{
+ QQuickSinglePointHandler::onGrabChanged(grabber, stateChange, point);
+ bool isCanceled = stateChange == QQuickEventPoint::CancelGrabExclusive || stateChange == QQuickEventPoint::CancelGrabPassive;
+ if (grabber == this && (isCanceled || point->state() == QQuickEventPoint::Released))
+ setPressed(false, isCanceled, point);
+}
+
+void QQuickTapHandler::connectPreRenderSignal(bool conn)
+{
+ if (conn)
+ connect(parentItem()->window(), &QQuickWindow::beforeSynchronizing, this, &QQuickTapHandler::updateTimeHeld);
+ else
+ disconnect(parentItem()->window(), &QQuickWindow::beforeSynchronizing, this, &QQuickTapHandler::updateTimeHeld);
+}
+
+void QQuickTapHandler::updateTimeHeld()
+{
+ emit timeHeldChanged();
+}
+
+/*!
+ \qmlproperty int TapHandler::tapCount
+ \readonly
+
+ The number of taps which have occurred within the time and space
+ constraints to be considered a single gesture. For example, to detect
+ a double-tap, you can write:
+
+ \qml
+ Rectangle {
+ width: 100; height: 30
+ signal doubleTap
+ TapHandler {
+ acceptedButtons: Qt.AllButtons
+ onTapped: if (tapCount == 2) doubleTap()
+ }
+ }
+ \endqml
+*/
+
+/*!
+ \qmlproperty real TapHandler::timeHeld
+ \readonly
+
+ The amount of time in seconds that a pressed point has been held, without
+ moving beyond the drag threshold. It will be updated at least once per
+ frame rendered, which enables rendering an animation showing the progress
+ towards an action which will be triggered by a long-press. It is also
+ possible to trigger one of a series of actions depending on how long the
+ press is held.
+
+ A value of less than zero means no point is being held within this
+ handler's \l [QML] Item.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/quick/handlers/qquicktaphandler_p.h b/src/quick/handlers/qquicktaphandler_p.h
new file mode 100644
index 0000000000..6504ec87f0
--- /dev/null
+++ b/src/quick/handlers/qquicktaphandler_p.h
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQUICKTAPHANDLER_H
+#define QQUICKTAPHANDLER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qquickitem.h"
+#include "qevent.h"
+#include "qquicksinglepointhandler_p.h"
+#include <QtCore/qbasictimer.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_AUTOTEST_EXPORT QQuickTapHandler : public QQuickSinglePointHandler
+{
+ Q_OBJECT
+ Q_PROPERTY(bool pressed READ isPressed NOTIFY pressedChanged)
+ Q_PROPERTY(int tapCount READ tapCount NOTIFY tapCountChanged)
+ Q_PROPERTY(qreal timeHeld READ timeHeld NOTIFY timeHeldChanged)
+ Q_PROPERTY(qreal longPressThreshold READ longPressThreshold WRITE setLongPressThreshold NOTIFY longPressThresholdChanged)
+ Q_PROPERTY(GesturePolicy gesturePolicy READ gesturePolicy WRITE setGesturePolicy NOTIFY gesturePolicyChanged)
+
+public:
+ enum GesturePolicy {
+ DragThreshold,
+ WithinBounds,
+ ReleaseWithinBounds
+ };
+ Q_ENUM(GesturePolicy)
+
+ explicit QQuickTapHandler(QObject *parent = 0);
+ ~QQuickTapHandler();
+
+ bool isPressed() const { return m_pressed; }
+
+ int tapCount() const { return m_tapCount; }
+ qreal timeHeld() const { return (m_holdTimer.isValid() ? m_holdTimer.elapsed() / 1000.0 : -1.0); }
+
+ qreal longPressThreshold() const;
+ void setLongPressThreshold(qreal longPressThreshold);
+
+ GesturePolicy gesturePolicy() const { return m_gesturePolicy; }
+ void setGesturePolicy(GesturePolicy gesturePolicy);
+
+Q_SIGNALS:
+ void pressedChanged();
+ void tapCountChanged();
+ void timeHeldChanged();
+ void longPressThresholdChanged();
+ void gesturePolicyChanged();
+ void tapped();
+ void longPressed();
+
+protected:
+ void onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point) override;
+ void timerEvent(QTimerEvent *event) override;
+ bool wantsEventPoint(QQuickEventPoint *point) override;
+ void handleEventPoint(QQuickEventPoint *point) override;
+
+private:
+ void setPressed(bool press, bool cancel, QQuickEventPoint *point);
+ int longPressThresholdMilliseconds() const;
+ void connectPreRenderSignal(bool conn = true);
+ void updateTimeHeld();
+
+private:
+ bool m_pressed;
+ GesturePolicy m_gesturePolicy;
+ int m_tapCount;
+ int m_longPressThreshold;
+ QBasicTimer m_longPressTimer;
+ QElapsedTimer m_holdTimer;
+ QPointF m_lastTapPos;
+ qreal m_lastTapTimestamp;
+
+ static qreal m_multiTapInterval;
+ static int m_mouseMultiClickDistanceSquared;
+ static int m_touchMultiTapDistanceSquared;
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QQuickTapHandler)
+
+#endif // QQUICKTAPHANDLER_H
diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp
index 670dc6d032..0739889e67 100644
--- a/src/quick/items/context2d/qquickcanvasitem.cpp
+++ b/src/quick/items/context2d/qquickcanvasitem.cpp
@@ -57,6 +57,7 @@
#include <private/qv4value_p.h>
#include <private/qv4functionobject_p.h>
#include <private/qv4scopedvalue_p.h>
+#include <private/qv4jscall_p.h>
#include <private/qv4qobjectwrapper_p.h>
QT_BEGIN_NAMESPACE
@@ -65,7 +66,7 @@ class QQuickCanvasTextureProvider : public QSGTextureProvider
{
public:
QSGTexture *tex;
- QSGTexture *texture() const Q_DECL_OVERRIDE { return tex; }
+ QSGTexture *texture() const override { return tex; }
void fireTextureChanged() { emit textureChanged(); }
};
@@ -726,15 +727,16 @@ void QQuickCanvasItem::updatePolish()
QMap<int, QV4::PersistentValue> animationCallbacks = d->animationCallbacks;
d->animationCallbacks.clear();
- QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(qmlEngine(this));
+ QV4::ExecutionEngine *v4 = qmlEngine(this)->handle();
QV4::Scope scope(v4);
- QV4::ScopedCallData callData(scope, 1);
- callData->thisObject = QV4::QObjectWrapper::wrap(v4, this);
+ QV4::ScopedFunctionObject function(scope);
+ QV4::JSCallData jsCall(scope, 1);
+ *jsCall->thisObject = QV4::QObjectWrapper::wrap(v4, this);
for (auto it = animationCallbacks.cbegin(), end = animationCallbacks.cend(); it != end; ++it) {
- QV4::ScopedFunctionObject f(scope, it.value().value());
- callData->args[0] = QV4::Primitive::fromUInt32(QDateTime::currentMSecsSinceEpoch() / 1000);
- f->call(scope, callData);
+ function = it.value().value();
+ jsCall->args[0] = QV4::Primitive::fromUInt32(QDateTime::currentMSecsSinceEpoch() / 1000);
+ function->call(jsCall);
}
}
else {
@@ -1208,7 +1210,7 @@ void QQuickCanvasItem::initializeContext(QQuickCanvasContext *context, const QVa
d->context = context;
d->context->init(this, args);
- d->context->setV4Engine(QQmlEnginePrivate::get(qmlEngine(this))->v4engine());
+ d->context->setV4Engine(qmlEngine(this)->handle());
connect(d->context, SIGNAL(textureChanged()), SLOT(update()));
connect(d->context, SIGNAL(textureChanged()), SIGNAL(painted()));
emit contextChanged();
diff --git a/src/quick/items/context2d/qquickcanvasitem_p.h b/src/quick/items/context2d/qquickcanvasitem_p.h
index 217ae9bb69..59de847680 100644
--- a/src/quick/items/context2d/qquickcanvasitem_p.h
+++ b/src/quick/items/context2d/qquickcanvasitem_p.h
@@ -155,8 +155,8 @@ public:
Q_INVOKABLE QString toDataURL(const QString& type = QLatin1String("image/png")) const;
QQmlRefPointer<QQuickCanvasPixmap> loadedPixmap(const QUrl& url);
- bool isTextureProvider() const Q_DECL_OVERRIDE;
- QSGTextureProvider *textureProvider() const Q_DECL_OVERRIDE;
+ bool isTextureProvider() const override;
+ QSGTextureProvider *textureProvider() const override;
Q_SIGNALS:
void paint(const QRect &region);
@@ -185,13 +185,13 @@ private Q_SLOTS:
void schedulePolish();
protected:
- void componentComplete() Q_DECL_OVERRIDE;
- void itemChange(QQuickItem::ItemChange, const QQuickItem::ItemChangeData &) Q_DECL_OVERRIDE;
- void updatePolish() Q_DECL_OVERRIDE;
- QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE;
- void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
- void releaseResources() Q_DECL_OVERRIDE;
- bool event(QEvent *event) Q_DECL_OVERRIDE;
+ void componentComplete() override;
+ void itemChange(QQuickItem::ItemChange, const QQuickItem::ItemChangeData &) override;
+ void updatePolish() override;
+ QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
+ void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
+ void releaseResources() override;
+ bool event(QEvent *event) override;
private:
Q_DECLARE_PRIVATE(QQuickCanvasItem)
Q_INVOKABLE void delayedCreate();
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index 5674326d6c..645f1b72f4 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -40,6 +40,7 @@
#include "qquickcontext2d_p.h"
#include "qquickcontext2dcommandbuffer_p.h"
#include "qquickcanvasitem_p.h"
+#include <private/qtquickglobal_p.h>
#include <private/qquickcontext2dtexture_p.h>
#include <private/qquickitem_p.h>
#if QT_CONFIG(quick_shadereffect)
@@ -129,8 +130,6 @@ QT_BEGIN_NAMESPACE
Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok);
-#define DEGREES(t) ((t) * 180.0 / M_PI)
-
#define CHECK_CONTEXT(r) if (!r || !r->d()->context || !r->d()->context->bufferValid()) \
THROW_GENERIC_ERROR("Not a Context2D object");
@@ -138,7 +137,7 @@ Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok);
THROW_GENERIC_ERROR("Not a Context2D object");
#define qClamp(val, min, max) qMin(qMax(val, min), max)
#define CHECK_RGBA(c) (c == '-' || c == '.' || (c >=0 && c <= 9))
-QColor qt_color_from_string(const QV4::Value &name)
+Q_QUICK_PRIVATE_EXPORT QColor qt_color_from_string(const QV4::Value &name)
{
QByteArray str = name.toQString().toUtf8();
@@ -530,6 +529,11 @@ struct QQuickJSContext2DPixelData : Object {
struct QQuickJSContext2DImageData : Object {
void init();
+ static void markObjects(QV4::Heap::Base *that, QV4::MarkStack *markStack) {
+ static_cast<QQuickJSContext2DImageData *>(that)->pixelData.mark(markStack);
+ Object::markObjects(that, markStack);
+ }
+
QV4::Value pixelData;
};
@@ -540,46 +544,46 @@ struct QQuickJSContext2D : public QV4::Object
{
V4_OBJECT2(QQuickJSContext2D, QV4::Object)
- static void method_get_globalAlpha(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_globalAlpha(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_globalCompositeOperation(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_globalCompositeOperation(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_fillStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_fillStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_fillRule(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_fillRule(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_strokeStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_strokeStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
-
- static void method_get_lineCap(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_lineCap(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_lineJoin(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_lineJoin(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_lineWidth(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_lineWidth(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_miterLimit(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_miterLimit(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
-
- static void method_get_shadowBlur(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_shadowBlur(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_shadowColor(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_shadowColor(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_shadowOffsetX(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_shadowOffsetX(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_shadowOffsetY(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_shadowOffsetY(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static QV4::ReturnedValue method_get_globalAlpha(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_set_globalAlpha(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_globalCompositeOperation(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_set_globalCompositeOperation(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_fillStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_set_fillStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_fillRule(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_set_fillRule(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_strokeStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_set_strokeStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+
+ static QV4::ReturnedValue method_get_lineCap(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_set_lineCap(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_lineJoin(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_set_lineJoin(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_lineWidth(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_set_lineWidth(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_miterLimit(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_set_miterLimit(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+
+ static QV4::ReturnedValue method_get_shadowBlur(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_set_shadowBlur(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_shadowColor(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_set_shadowColor(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_shadowOffsetX(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_set_shadowOffsetX(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_shadowOffsetY(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_set_shadowOffsetY(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
// should these two be on the proto?
#if QT_CONFIG(quick_path)
- static void method_get_path(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_path(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static QV4::ReturnedValue method_get_path(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_set_path(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
#endif
- static void method_get_font(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_font(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_textAlign(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_textAlign(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_textBaseline(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_textBaseline(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static QV4::ReturnedValue method_get_font(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_set_font(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_textAlign(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_set_textAlign(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_textBaseline(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_set_textBaseline(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
};
DEFINE_OBJECT_VTABLE(QQuickJSContext2D);
@@ -642,50 +646,50 @@ public:
return o->d();
}
- static void method_get_canvas(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_restore(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_reset(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_save(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_rotate(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_scale(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_translate(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_setTransform(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_transform(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_resetTransform(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_shear(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_createLinearGradient(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_createRadialGradient(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_createConicalGradient(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_createPattern(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_clearRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_fillRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_strokeRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_arc(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_arcTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_beginPath(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_bezierCurveTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_clip(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_closePath(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_fill(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_lineTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_moveTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_quadraticCurveTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_rect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_roundedRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_ellipse(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_text(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_stroke(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_isPointInPath(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_drawFocusRing(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_setCaretSelectionRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_caretBlinkRate(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_fillText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_strokeText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_measureText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_drawImage(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_createImageData(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_getImageData(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_putImageData(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static QV4::ReturnedValue method_get_canvas(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_restore(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_reset(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_save(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_rotate(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_scale(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_translate(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_setTransform(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_transform(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_resetTransform(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_shear(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_createLinearGradient(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_createRadialGradient(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_createConicalGradient(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_createPattern(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_clearRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_fillRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_strokeRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_arc(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_arcTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_beginPath(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_bezierCurveTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_clip(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_closePath(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_fill(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_lineTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_moveTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_quadraticCurveTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_rect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_roundedRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_ellipse(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_text(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_stroke(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_isPointInPath(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_drawFocusRing(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_setCaretSelectionRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_caretBlinkRate(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_fillText(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_strokeText(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_measureText(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_drawImage(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_createImageData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_getImageData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_putImageData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
};
@@ -697,7 +701,7 @@ struct QQuickContext2DStyle : public QV4::Object
V4_OBJECT2(QQuickContext2DStyle, QV4::Object)
V4_NEEDS_DESTROY
- static void gradient_proto_addColorStop(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static QV4::ReturnedValue gradient_proto_addColorStop(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
};
@@ -905,9 +909,9 @@ struct QQuickJSContext2DPixelData : public QV4::Object
V4_NEEDS_DESTROY
static QV4::ReturnedValue getIndexed(const QV4::Managed *m, uint index, bool *hasProperty);
- static void putIndexed(QV4::Managed *m, uint index, const QV4::Value &value);
+ static bool putIndexed(QV4::Managed *m, uint index, const QV4::Value &value);
- static void proto_get_length(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static QV4::ReturnedValue proto_get_length(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
};
void QV4::Heap::QQuickJSContext2DPixelData::init()
@@ -925,14 +929,10 @@ struct QQuickJSContext2DImageData : public QV4::Object
{
V4_OBJECT2(QQuickJSContext2DImageData, QV4::Object)
- static void method_get_width(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_height(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_data(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static QV4::ReturnedValue method_get_width(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_height(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
+ static QV4::ReturnedValue method_get_data(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc);
- static void markObjects(QV4::Heap::Base *that, QV4::ExecutionEngine *engine) {
- static_cast<QQuickJSContext2DImageData::Data *>(that)->pixelData.mark(engine);
- QV4::Object::markObjects(that, engine);
- }
};
void QV4::Heap::QQuickJSContext2DImageData::init()
@@ -979,12 +979,13 @@ static QV4::ReturnedValue qt_create_image_data(qreal w, qreal h, QV4::ExecutionE
This property is read only.
*/
-void QQuickJSContext2DPrototype::method_get_canvas(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_get_canvas(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- scope.result = QV4::QObjectWrapper::wrap(scope.engine, r->d()->context->canvas());
+ RETURN_RESULT(QV4::QObjectWrapper::wrap(scope.engine, r->d()->context->canvas()));
}
/*!
@@ -993,27 +994,29 @@ void QQuickJSContext2DPrototype::method_get_canvas(const QV4::BuiltinFunction *,
\sa save()
*/
-void QQuickJSContext2DPrototype::method_restore(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_restore(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
r->d()->context->popState();
- scope.result = callData->thisObject.asReturnedValue();
+ RETURN_RESULT(thisObject->asReturnedValue());
}
/*!
\qmlmethod object QtQuick::Context2D::reset()
Resets the context state and properties to the default values.
*/
-void QQuickJSContext2DPrototype::method_reset(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_reset(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
r->d()->context->reset();
- scope.result = callData->thisObject.asReturnedValue();
+ RETURN_RESULT(thisObject->asReturnedValue());
}
/*!
@@ -1046,14 +1049,15 @@ void QQuickJSContext2DPrototype::method_reset(const QV4::BuiltinFunction *, QV4:
The current path is NOT part of the drawing state. The path can be reset by
invoking the beginPath() method.
*/
-void QQuickJSContext2DPrototype::method_save(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_save(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
r->d()->context->pushState();
- scope.result = callData->thisObject;
+ RETURN_RESULT(*thisObject);
}
// transformations
@@ -1074,14 +1078,15 @@ void QQuickJSContext2DPrototype::method_save(const QV4::BuiltinFunction *, QV4::
where the \a angle of rotation is in radians.
*/
-void QQuickJSContext2DPrototype::method_rotate(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_rotate(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (callData->argc >= 1)
- r->d()->context->rotate(callData->args[0].toNumber());
- scope.result = callData->thisObject;
+ if (argc >= 1)
+ r->d()->context->rotate(argv[0].toNumber());
+ RETURN_RESULT(*thisObject);
}
/*!
@@ -1101,15 +1106,16 @@ void QQuickJSContext2DPrototype::method_rotate(const QV4::BuiltinFunction *, QV4
\image qml-item-canvas-scale.png
*/
-void QQuickJSContext2DPrototype::method_scale(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_scale(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (callData->argc >= 2)
- r->d()->context->scale(callData->args[0].toNumber(), callData->args[1].toNumber());
- scope.result = callData->thisObject;
+ if (argc >= 2)
+ r->d()->context->scale(argv[0].toNumber(), argv[1].toNumber());
+ RETURN_RESULT(*thisObject);
}
@@ -1147,21 +1153,22 @@ void QQuickJSContext2DPrototype::method_scale(const QV4::BuiltinFunction *, QV4:
\sa transform()
*/
-void QQuickJSContext2DPrototype::method_setTransform(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_setTransform(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (callData->argc >= 6)
- r->d()->context->setTransform( callData->args[0].toNumber()
- , callData->args[1].toNumber()
- , callData->args[2].toNumber()
- , callData->args[3].toNumber()
- , callData->args[4].toNumber()
- , callData->args[5].toNumber());
+ if (argc >= 6)
+ r->d()->context->setTransform( argv[0].toNumber()
+ , argv[1].toNumber()
+ , argv[2].toNumber()
+ , argv[3].toNumber()
+ , argv[4].toNumber()
+ , argv[5].toNumber());
- scope.result = callData->thisObject;
+ RETURN_RESULT(*thisObject);
}
@@ -1176,20 +1183,21 @@ void QQuickJSContext2DPrototype::method_setTransform(const QV4::BuiltinFunction
\sa setTransform()
*/
-void QQuickJSContext2DPrototype::method_transform(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_transform(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (callData->argc >= 6)
- r->d()->context->transform( callData->args[0].toNumber()
- , callData->args[1].toNumber()
- , callData->args[2].toNumber()
- , callData->args[3].toNumber()
- , callData->args[4].toNumber()
- , callData->args[5].toNumber());
+ if (argc >= 6)
+ r->d()->context->transform( argv[0].toNumber()
+ , argv[1].toNumber()
+ , argv[2].toNumber()
+ , argv[3].toNumber()
+ , argv[4].toNumber()
+ , argv[5].toNumber());
- scope.result = callData->thisObject;
+ RETURN_RESULT(*thisObject);
}
@@ -1202,14 +1210,15 @@ void QQuickJSContext2DPrototype::method_transform(const QV4::BuiltinFunction *,
Translating the origin enables you to draw patterns of different objects on the canvas
without having to measure the coordinates manually for each shape.
*/
-void QQuickJSContext2DPrototype::method_translate(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_translate(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (callData->argc >= 2)
- r->d()->context->translate(callData->args[0].toNumber(), callData->args[1].toNumber());
- scope.result = callData->thisObject;
+ if (argc >= 2)
+ r->d()->context->translate(argv[0].toNumber(), argv[1].toNumber());
+ RETURN_RESULT(*thisObject);
}
@@ -1222,14 +1231,15 @@ void QQuickJSContext2DPrototype::method_translate(const QV4::BuiltinFunction *,
\sa transform(), setTransform(), reset()
*/
-void QQuickJSContext2DPrototype::method_resetTransform(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_resetTransform(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
r->d()->context->setTransform(1, 0, 0, 1, 0, 0);
- scope.result = callData->thisObject;
+ RETURN_RESULT(*thisObject);
}
@@ -1240,15 +1250,16 @@ void QQuickJSContext2DPrototype::method_resetTransform(const QV4::BuiltinFunctio
Shears the transformation matrix by \a sh in the horizontal direction and
\a sv in the vertical direction.
*/
-void QQuickJSContext2DPrototype::method_shear(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_shear(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (callData->argc >= 2)
- r->d()->context->shear(callData->args[0].toNumber(), callData->args[1].toNumber());
+ if (argc >= 2)
+ r->d()->context->shear(argv[0].toNumber(), argv[1].toNumber());
- scope.result = callData->thisObject;
+ RETURN_RESULT(*thisObject);
}
// compositing
@@ -1260,30 +1271,32 @@ void QQuickJSContext2DPrototype::method_shear(const QV4::BuiltinFunction *, QV4:
The value must be in the range from \c 0.0 (fully transparent) to \c 1.0 (fully opaque).
The default value is \c 1.0.
*/
-void QQuickJSContext2D::method_get_globalAlpha(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_get_globalAlpha(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- scope.result = QV4::Encode(r->d()->context->state.globalAlpha);
+ RETURN_RESULT(QV4::Encode(r->d()->context->state.globalAlpha));
}
-void QQuickJSContext2D::method_set_globalAlpha(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_set_globalAlpha(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT_SETTER(r)
- double globalAlpha = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double globalAlpha = argc ? argv[0].toNumber() : qt_qnan();
- scope.result = QV4::Encode::undefined();
if (!qt_is_finite(globalAlpha))
- return;
+ RETURN_UNDEFINED();
if (globalAlpha >= 0.0 && globalAlpha <= 1.0 && r->d()->context->state.globalAlpha != globalAlpha) {
r->d()->context->state.globalAlpha = globalAlpha;
r->d()->context->buffer()->setGlobalAlpha(r->d()->context->state.globalAlpha);
}
+ RETURN_UNDEFINED();
}
/*!
@@ -1312,33 +1325,35 @@ void QQuickJSContext2D::method_set_globalAlpha(const QV4::BuiltinFunction *, QV4
extension composition modes are provided as "vendorName-operationName" syntax, for example: QPainter::CompositionMode_Exclusion is provided as
"qt-exclusion".
*/
-void QQuickJSContext2D::method_get_globalCompositeOperation(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_get_globalCompositeOperation(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- scope.result = scope.engine->newString(qt_composite_mode_to_string(r->d()->context->state.globalCompositeOperation));
+ RETURN_RESULT(scope.engine->newString(qt_composite_mode_to_string(r->d()->context->state.globalCompositeOperation)));
}
-void QQuickJSContext2D::method_set_globalCompositeOperation(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_set_globalCompositeOperation(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT_SETTER(r)
- if (!callData->argc)
+ if (!argc)
THROW_TYPE_ERROR();
- scope.result = QV4::Encode::undefined();
-
- QString mode = callData->args[0].toQString();
+ QString mode = argv[0].toQString();
QPainter::CompositionMode cm = qt_composite_mode_from_string(mode);
if (cm == QPainter::CompositionMode_SourceOver && mode != QLatin1String("source-over"))
- return;
+ RETURN_UNDEFINED();
if (cm != r->d()->context->state.globalCompositeOperation) {
r->d()->context->state.globalCompositeOperation = cm;
r->d()->context->buffer()->setGlobalCompositeOperation(cm);
}
+
+ RETURN_UNDEFINED();
}
// colors and styles
@@ -1364,9 +1379,10 @@ void QQuickJSContext2D::method_set_globalCompositeOperation(const QV4::BuiltinFu
\sa createPattern()
\sa strokeStyle
*/
-void QQuickJSContext2D::method_get_fillStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_get_fillStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
QColor color = r->d()->context->state.fillStyle.color();
@@ -1381,15 +1397,16 @@ void QQuickJSContext2D::method_get_fillStyle(const QV4::BuiltinFunction *, QV4::
QString str = QString::fromLatin1("rgba(%1, %2, %3, %4)").arg(color.red()).arg(color.green()).arg(color.blue()).arg(alphaString);
RETURN_RESULT(scope.engine->newString(str));
}
- scope.result = r->d()->context->m_fillStyle.value();
+ RETURN_RESULT(r->d()->context->m_fillStyle.value());
}
-void QQuickJSContext2D::method_set_fillStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_set_fillStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT_SETTER(r)
- QV4::ScopedValue value(scope, callData->argument(0));
+ QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Primitive::undefinedValue());
if (value->as<Object>()) {
QColor color = scope.engine->toVariant(value, qMetaTypeId<QColor>()).value<QColor>();
@@ -1415,7 +1432,7 @@ void QQuickJSContext2D::method_set_fillStyle(const QV4::BuiltinFunction *, QV4::
r->d()->context->m_fillStyle.set(scope.engine, value);
}
}
- scope.result = QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
/*!
\qmlproperty enumeration QtQuick::Context2D::fillRule
@@ -1429,20 +1446,22 @@ void QQuickJSContext2D::method_set_fillStyle(const QV4::BuiltinFunction *, QV4::
\sa fillStyle
*/
-void QQuickJSContext2D::method_get_fillRule(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_get_fillRule(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- scope.result = scope.engine->fromVariant(r->d()->context->state.fillRule);
+ RETURN_RESULT(scope.engine->fromVariant(r->d()->context->state.fillRule));
}
-void QQuickJSContext2D::method_set_fillRule(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_set_fillRule(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT_SETTER(r)
- QV4::ScopedValue value(scope, callData->argument(0));
+ QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Primitive::undefinedValue());
if ((value->isString() && value->toQString() == QLatin1String("WindingFill"))
|| (value->isInt32() && value->integerValue() == Qt::WindingFill)) {
@@ -1454,7 +1473,7 @@ void QQuickJSContext2D::method_set_fillRule(const QV4::BuiltinFunction *, QV4::S
//error
}
r->d()->context->m_path.setFillRule(r->d()->context->state.fillRule);
- scope.result = QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
/*!
\qmlproperty variant QtQuick::Context2D::strokeStyle
@@ -1469,9 +1488,10 @@ void QQuickJSContext2D::method_set_fillRule(const QV4::BuiltinFunction *, QV4::S
\sa createPattern()
\sa fillStyle
*/
-void QQuickJSContext2D::method_get_strokeStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_get_strokeStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
QColor color = r->d()->context->state.strokeStyle.color();
@@ -1486,15 +1506,16 @@ void QQuickJSContext2D::method_get_strokeStyle(const QV4::BuiltinFunction *, QV4
QString str = QString::fromLatin1("rgba(%1, %2, %3, %4)").arg(color.red()).arg(color.green()).arg(color.blue()).arg(alphaString);
RETURN_RESULT(scope.engine->newString(str));
}
- scope.result = r->d()->context->m_strokeStyle.value();
+ RETURN_RESULT(r->d()->context->m_strokeStyle.value());
}
-void QQuickJSContext2D::method_set_strokeStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_set_strokeStyle(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT_SETTER(r)
- QV4::ScopedValue value(scope, callData->argument(0));
+ QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Primitive::undefinedValue());
if (value->as<Object>()) {
QColor color = scope.engine->toVariant(value, qMetaTypeId<QColor>()).value<QColor>();
@@ -1521,7 +1542,7 @@ void QQuickJSContext2D::method_set_strokeStyle(const QV4::BuiltinFunction *, QV4
r->d()->context->m_strokeStyle.set(scope.engine, value);
}
}
- scope.result = QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
/*!
@@ -1541,16 +1562,17 @@ void QQuickJSContext2D::method_set_strokeStyle(const QV4::BuiltinFunction *, QV4
\sa strokeStyle
*/
-void QQuickJSContext2DPrototype::method_createLinearGradient(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_createLinearGradient(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (callData->argc >= 4) {
- qreal x0 = callData->args[0].toNumber();
- qreal y0 = callData->args[1].toNumber();
- qreal x1 = callData->args[2].toNumber();
- qreal y1 = callData->args[3].toNumber();
+ if (argc >= 4) {
+ qreal x0 = argv[0].toNumber();
+ qreal y0 = argv[1].toNumber();
+ qreal x1 = argv[2].toNumber();
+ qreal y1 = argv[3].toNumber();
if (!qt_is_finite(x0)
|| !qt_is_finite(y0)
@@ -1564,10 +1586,10 @@ void QQuickJSContext2DPrototype::method_createLinearGradient(const QV4::BuiltinF
QV4::ScopedObject p(scope, ed->gradientProto.value());
gradient->setPrototype(p);
*gradient->d()->brush = QLinearGradient(x0, y0, x1, y1);
- RETURN_RESULT(gradient);
+ RETURN_RESULT(*gradient);
}
- scope.result = callData->thisObject;
+ RETURN_RESULT(*thisObject);
}
@@ -1584,18 +1606,19 @@ void QQuickJSContext2DPrototype::method_createLinearGradient(const QV4::BuiltinF
\sa strokeStyle
*/
-void QQuickJSContext2DPrototype::method_createRadialGradient(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_createRadialGradient(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (callData->argc >= 6) {
- qreal x0 = callData->args[0].toNumber();
- qreal y0 = callData->args[1].toNumber();
- qreal r0 = callData->args[2].toNumber();
- qreal x1 = callData->args[3].toNumber();
- qreal y1 = callData->args[4].toNumber();
- qreal r1 = callData->args[5].toNumber();
+ if (argc >= 6) {
+ qreal x0 = argv[0].toNumber();
+ qreal y0 = argv[1].toNumber();
+ qreal r0 = argv[2].toNumber();
+ qreal x1 = argv[3].toNumber();
+ qreal y1 = argv[4].toNumber();
+ qreal r1 = argv[5].toNumber();
if (!qt_is_finite(x0)
|| !qt_is_finite(y0)
@@ -1615,10 +1638,10 @@ void QQuickJSContext2DPrototype::method_createRadialGradient(const QV4::BuiltinF
QV4::ScopedObject p(scope, ed->gradientProto.value());
gradient->setPrototype(p);
*gradient->d()->brush = QRadialGradient(QPointF(x1, y1), r0+r1, QPointF(x0, y0));
- RETURN_RESULT(gradient);
+ RETURN_RESULT(*gradient);
}
- scope.result = callData->thisObject;
+ RETURN_RESULT(*thisObject);
}
@@ -1635,15 +1658,16 @@ void QQuickJSContext2DPrototype::method_createRadialGradient(const QV4::BuiltinF
\sa strokeStyle
*/
-void QQuickJSContext2DPrototype::method_createConicalGradient(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_createConicalGradient(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (callData->argc >= 3) {
- qreal x = callData->args[0].toNumber();
- qreal y = callData->args[1].toNumber();
- qreal angle = DEGREES(callData->args[2].toNumber());
+ if (argc >= 3) {
+ qreal x = argv[0].toNumber();
+ qreal y = argv[1].toNumber();
+ qreal angle = qRadiansToDegrees(argv[2].toNumber());
if (!qt_is_finite(x) || !qt_is_finite(y)) {
THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "createConicalGradient(): Incorrect arguments");
}
@@ -1658,10 +1682,10 @@ void QQuickJSContext2DPrototype::method_createConicalGradient(const QV4::Builtin
QV4::ScopedObject p(scope, ed->gradientProto.value());
gradient->setPrototype(p);
*gradient->d()->brush = QConicalGradient(x, y, angle);
- RETURN_RESULT(gradient);
+ RETURN_RESULT(*gradient);
}
- scope.result = callData->thisObject;
+ RETURN_RESULT(*thisObject);
}
/*!
@@ -1707,17 +1731,18 @@ void QQuickJSContext2DPrototype::method_createConicalGradient(const QV4::Builtin
\sa strokeStyle
\sa fillStyle
*/
-void QQuickJSContext2DPrototype::method_createPattern(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_createPattern(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
- if (callData->argc >= 2) {
+ if (argc >= 2) {
QV4::Scoped<QQuickContext2DStyle> pattern(scope, scope.engine->memoryManager->allocObject<QQuickContext2DStyle>());
- QColor color = scope.engine->toVariant(callData->args[0], qMetaTypeId<QColor>()).value<QColor>();
+ QColor color = scope.engine->toVariant(argv[0], qMetaTypeId<QColor>()).value<QColor>();
if (color.isValid()) {
- int patternMode = callData->args[1].toInt32();
+ int patternMode = argv[1].toInt32();
Qt::BrushStyle style = Qt::SolidPattern;
if (patternMode >= 0 && patternMode < Qt::LinearGradientPattern) {
style = static_cast<Qt::BrushStyle>(patternMode);
@@ -1726,20 +1751,20 @@ void QQuickJSContext2DPrototype::method_createPattern(const QV4::BuiltinFunction
} else {
QImage patternTexture;
- if (const QV4::Object *o = callData->args[0].as<Object>()) {
+ if (const QV4::Object *o = argv[0].as<Object>()) {
QV4::ScopedString s(scope, scope.engine->newString(QStringLiteral("data")));
QV4::Scoped<QQuickJSContext2DPixelData> pixelData(scope, o->get(s));
if (!!pixelData) {
patternTexture = *pixelData->d()->image;
}
} else {
- patternTexture = r->d()->context->createPixmap(QUrl(callData->args[0].toQStringNoThrow()))->image();
+ patternTexture = r->d()->context->createPixmap(QUrl(argv[0].toQStringNoThrow()))->image();
}
if (!patternTexture.isNull()) {
pattern->d()->brush->setTextureImage(patternTexture);
- QString repetition = callData->args[1].toQStringNoThrow();
+ QString repetition = argv[1].toQStringNoThrow();
if (repetition == QLatin1String("repeat") || repetition.isEmpty()) {
pattern->d()->patternRepeatX = true;
pattern->d()->patternRepeatY = true;
@@ -1759,10 +1784,10 @@ void QQuickJSContext2DPrototype::method_createPattern(const QV4::BuiltinFunction
}
}
- RETURN_RESULT(pattern);
+ RETURN_RESULT(*pattern);
}
- scope.result = QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
// line styles
@@ -1777,9 +1802,10 @@ void QQuickJSContext2DPrototype::method_createPattern(const QV4::BuiltinFunction
\endlist
Other values are ignored.
*/
-void QQuickJSContext2D::method_get_lineCap(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_get_lineCap(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
switch (r->d()->context->state.lineCap) {
@@ -1794,12 +1820,16 @@ void QQuickJSContext2D::method_get_lineCap(const QV4::BuiltinFunction *, QV4::Sc
RETURN_RESULT(scope.engine->newString(QStringLiteral("butt")));
}
-void QQuickJSContext2D::method_set_lineCap(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_set_lineCap(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ if (!argc)
+ return QV4::Encode::undefined();
+
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT_SETTER(r)
- QString lineCap = callData->args[0].toQString();
+ QString lineCap = argv[0].toQString();
Qt::PenCapStyle cap;
if (lineCap == QLatin1String("round"))
cap = Qt::RoundCap;
@@ -1831,9 +1861,10 @@ void QQuickJSContext2D::method_set_lineCap(const QV4::BuiltinFunction *, QV4::Sc
\endlist
Other values are ignored.
*/
-void QQuickJSContext2D::method_get_lineJoin(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_get_lineJoin(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
switch (r->d()->context->state.lineJoin) {
@@ -1848,15 +1879,16 @@ void QQuickJSContext2D::method_get_lineJoin(const QV4::BuiltinFunction *, QV4::S
RETURN_RESULT(scope.engine->newString(QStringLiteral("miter")));
}
-void QQuickJSContext2D::method_set_lineJoin(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_set_lineJoin(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT_SETTER(r)
- if (!callData->argc)
+ if (!argc)
THROW_TYPE_ERROR();
- QString lineJoin = callData->args[0].toQString();
+ QString lineJoin = argv[0].toQString();
Qt::PenJoinStyle join;
if (lineJoin == QLatin1String("round"))
join = Qt::RoundJoin;
@@ -1878,20 +1910,22 @@ void QQuickJSContext2D::method_set_lineJoin(const QV4::BuiltinFunction *, QV4::S
\qmlproperty real QtQuick::Context2D::lineWidth
Holds the current line width. Values that are not finite values greater than zero are ignored.
*/
-void QQuickJSContext2D::method_get_lineWidth(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_get_lineWidth(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
RETURN_RESULT(QV4::Encode(r->d()->context->state.lineWidth));
}
-void QQuickJSContext2D::method_set_lineWidth(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_set_lineWidth(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT_SETTER(r)
- qreal w = callData->argc ? callData->args[0].toNumber() : -1;
+ qreal w = argc ? argv[0].toNumber() : -1;
if (w > 0 && qt_is_finite(w) && w != r->d()->context->state.lineWidth) {
r->d()->context->state.lineWidth = w;
@@ -1905,20 +1939,22 @@ void QQuickJSContext2D::method_set_lineWidth(const QV4::BuiltinFunction *, QV4::
Holds the current miter limit ratio.
The default miter limit value is 10.0.
*/
-void QQuickJSContext2D::method_get_miterLimit(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_get_miterLimit(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
RETURN_RESULT(QV4::Encode(r->d()->context->state.miterLimit));
}
-void QQuickJSContext2D::method_set_miterLimit(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_set_miterLimit(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT_SETTER(r)
- qreal ml = callData->argc ? callData->args[0].toNumber() : -1;
+ qreal ml = argc ? argv[0].toNumber() : -1;
if (ml > 0 && qt_is_finite(ml) && ml != r->d()->context->state.miterLimit) {
r->d()->context->state.miterLimit = ml;
@@ -1932,20 +1968,22 @@ void QQuickJSContext2D::method_set_miterLimit(const QV4::BuiltinFunction *, QV4:
\qmlproperty real QtQuick::Context2D::shadowBlur
Holds the current level of blur applied to shadows
*/
-void QQuickJSContext2D::method_get_shadowBlur(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_get_shadowBlur(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
RETURN_RESULT(QV4::Encode(r->d()->context->state.shadowBlur));
}
-void QQuickJSContext2D::method_set_shadowBlur(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_set_shadowBlur(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT_SETTER(r)
- qreal blur = callData->argc ? callData->args[0].toNumber() : -1;
+ qreal blur = argc ? argv[0].toNumber() : -1;
if (blur > 0 && qt_is_finite(blur) && blur != r->d()->context->state.shadowBlur) {
r->d()->context->state.shadowBlur = blur;
@@ -1958,22 +1996,24 @@ void QQuickJSContext2D::method_set_shadowBlur(const QV4::BuiltinFunction *, QV4:
\qmlproperty string QtQuick::Context2D::shadowColor
Holds the current shadow color.
*/
-void QQuickJSContext2D::method_get_shadowColor(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_get_shadowColor(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
RETURN_RESULT(scope.engine->newString(r->d()->context->state.shadowColor.name()));
}
-void QQuickJSContext2D::method_set_shadowColor(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_set_shadowColor(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT_SETTER(r)
QColor color;
- if (callData->argc)
- color = qt_color_from_string(callData->args[0]);
+ if (argc)
+ color = qt_color_from_string(argv[0]);
if (color.isValid() && color != r->d()->context->state.shadowColor) {
r->d()->context->state.shadowColor = color;
@@ -1989,20 +2029,22 @@ void QQuickJSContext2D::method_set_shadowColor(const QV4::BuiltinFunction *, QV4
\sa shadowOffsetY
*/
-void QQuickJSContext2D::method_get_shadowOffsetX(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_get_shadowOffsetX(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
RETURN_RESULT(QV4::Encode(r->d()->context->state.shadowOffsetX));
}
-void QQuickJSContext2D::method_set_shadowOffsetX(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_set_shadowOffsetX(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT_SETTER(r)
- qreal offsetX = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ qreal offsetX = argc ? argv[0].toNumber() : qt_qnan();
if (qt_is_finite(offsetX) && offsetX != r->d()->context->state.shadowOffsetX) {
r->d()->context->state.shadowOffsetX = offsetX;
r->d()->context->buffer()->setShadowOffsetX(offsetX);
@@ -2015,20 +2057,22 @@ void QQuickJSContext2D::method_set_shadowOffsetX(const QV4::BuiltinFunction *, Q
\sa shadowOffsetX
*/
-void QQuickJSContext2D::method_get_shadowOffsetY(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_get_shadowOffsetY(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
RETURN_RESULT(QV4::Encode(r->d()->context->state.shadowOffsetY));
}
-void QQuickJSContext2D::method_set_shadowOffsetY(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_set_shadowOffsetY(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT_SETTER(r)
- qreal offsetY = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ qreal offsetY = argc ? argv[0].toNumber() : qt_qnan();
if (qt_is_finite(offsetY) && offsetY != r->d()->context->state.shadowOffsetY) {
r->d()->context->state.shadowOffsetY = offsetY;
r->d()->context->buffer()->setShadowOffsetY(offsetY);
@@ -2037,20 +2081,22 @@ void QQuickJSContext2D::method_set_shadowOffsetY(const QV4::BuiltinFunction *, Q
}
#if QT_CONFIG(quick_path)
-void QQuickJSContext2D::method_get_path(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_get_path(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
- scope.result = r->d()->context->m_v4path.value();
+ RETURN_RESULT(r->d()->context->m_v4path.value());
}
-void QQuickJSContext2D::method_set_path(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_set_path(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT_SETTER(r)
- QV4::ScopedValue value(scope, callData->argument(0));
+ QV4::ScopedValue value(scope, argc ? argv[0] : QV4::Primitive::undefinedValue());
r->d()->context->beginPath();
QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, value);
if (!!qobjectWrapper) {
@@ -2070,19 +2116,20 @@ void QQuickJSContext2D::method_set_path(const QV4::BuiltinFunction *, QV4::Scope
\qmlmethod object QtQuick::Context2D::clearRect(real x, real y, real w, real h)
Clears all pixels on the canvas in the given rectangle to transparent black.
*/
-void QQuickJSContext2DPrototype::method_clearRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_clearRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
- if (callData->argc >= 4)
- r->d()->context->clearRect(callData->args[0].toNumber(),
- callData->args[1].toNumber(),
- callData->args[2].toNumber(),
- callData->args[3].toNumber());
+ if (argc >= 4)
+ r->d()->context->clearRect(argv[0].toNumber(),
+ argv[1].toNumber(),
+ argv[2].toNumber(),
+ argv[3].toNumber());
- scope.result = callData->thisObject;
+ RETURN_RESULT(*thisObject);
}
/*!
@@ -2091,14 +2138,15 @@ void QQuickJSContext2DPrototype::method_clearRect(const QV4::BuiltinFunction *,
\sa fillStyle
*/
-void QQuickJSContext2DPrototype::method_fillRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_fillRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
- if (callData->argc >= 4)
- r->d()->context->fillRect(callData->args[0].toNumber(), callData->args[1].toNumber(), callData->args[2].toNumber(), callData->args[3].toNumber());
- scope.result = callData->thisObject;
+ if (argc >= 4)
+ r->d()->context->fillRect(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber());
+ RETURN_RESULT(*thisObject);
}
@@ -2112,15 +2160,16 @@ void QQuickJSContext2DPrototype::method_fillRect(const QV4::BuiltinFunction *, Q
\sa lineJoin
\sa miterLimit
*/
-void QQuickJSContext2DPrototype::method_strokeRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_strokeRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
- if (callData->argc >= 4)
- r->d()->context->strokeRect(callData->args[0].toNumber(), callData->args[1].toNumber(), callData->args[2].toNumber(), callData->args[3].toNumber());
+ if (argc >= 4)
+ r->d()->context->strokeRect(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber());
- scope.result = callData->thisObject;
+ RETURN_RESULT(*thisObject);
}
@@ -2145,31 +2194,32 @@ void QQuickJSContext2DPrototype::method_strokeRect(const QV4::BuiltinFunction *,
\sa arcTo, {http://www.w3.org/TR/2dcontext/#dom-context-2d-arc}{W3C's 2D
Context Standard for arc()}
*/
-void QQuickJSContext2DPrototype::method_arc(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_arc(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
- if (callData->argc >= 5) {
+ if (argc >= 5) {
bool antiClockwise = false;
- if (callData->argc == 6)
- antiClockwise = callData->args[5].toBoolean();
+ if (argc == 6)
+ antiClockwise = argv[5].toBoolean();
- qreal radius = callData->args[2].toNumber();
+ qreal radius = argv[2].toNumber();
if (qt_is_finite(radius) && radius < 0)
THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "Incorrect argument radius");
- r->d()->context->arc(callData->args[0].toNumber(),
- callData->args[1].toNumber(),
+ r->d()->context->arc(argv[0].toNumber(),
+ argv[1].toNumber(),
radius,
- callData->args[3].toNumber(),
- callData->args[4].toNumber(),
+ argv[3].toNumber(),
+ argv[4].toNumber(),
antiClockwise);
}
- scope.result = callData->thisObject;
+ RETURN_RESULT(*thisObject);
}
@@ -2196,25 +2246,26 @@ void QQuickJSContext2DPrototype::method_arc(const QV4::BuiltinFunction *, QV4::S
\sa arc, {http://www.w3.org/TR/2dcontext/#dom-context-2d-arcto}{W3C's 2D
Context Standard for arcTo()}
*/
-void QQuickJSContext2DPrototype::method_arcTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_arcTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
- if (callData->argc >= 5) {
- qreal radius = callData->args[4].toNumber();
+ if (argc >= 5) {
+ qreal radius = argv[4].toNumber();
if (qt_is_finite(radius) && radius < 0)
THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "Incorrect argument radius");
- r->d()->context->arcTo(callData->args[0].toNumber(),
- callData->args[1].toNumber(),
- callData->args[2].toNumber(),
- callData->args[3].toNumber(),
+ r->d()->context->arcTo(argv[0].toNumber(),
+ argv[1].toNumber(),
+ argv[2].toNumber(),
+ argv[3].toNumber(),
radius);
}
- scope.result = callData->thisObject;
+ RETURN_RESULT(*thisObject);
}
@@ -2223,14 +2274,15 @@ void QQuickJSContext2DPrototype::method_arcTo(const QV4::BuiltinFunction *, QV4:
Resets the current path to a new path.
*/
-void QQuickJSContext2DPrototype::method_beginPath(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_beginPath(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
r->d()->context->beginPath();
- scope.result = callData->thisObject;
+ RETURN_RESULT(*thisObject);
}
@@ -2253,26 +2305,26 @@ void QQuickJSContext2DPrototype::method_beginPath(const QV4::BuiltinFunction *,
\sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-beziercurveto}{W3C 2d context standard for bezierCurveTo}
\sa {http://www.openrise.com/lab/FlowerPower/}{The beautiful flower demo by using bezierCurveTo}
*/
-void QQuickJSContext2DPrototype::method_bezierCurveTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_bezierCurveTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
- scope.result = callData->thisObject;
-
- if (callData->argc >= 6) {
- qreal cp1x = callData->args[0].toNumber();
- qreal cp1y = callData->args[1].toNumber();
- qreal cp2x = callData->args[2].toNumber();
- qreal cp2y = callData->args[3].toNumber();
- qreal x = callData->args[4].toNumber();
- qreal y = callData->args[5].toNumber();
+ if (argc >= 6) {
+ qreal cp1x = argv[0].toNumber();
+ qreal cp1y = argv[1].toNumber();
+ qreal cp2x = argv[2].toNumber();
+ qreal cp2y = argv[3].toNumber();
+ qreal x = argv[4].toNumber();
+ qreal y = argv[5].toNumber();
if (!qt_is_finite(cp1x) || !qt_is_finite(cp1y) || !qt_is_finite(cp2x) || !qt_is_finite(cp2y) || !qt_is_finite(x) || !qt_is_finite(y))
- return;
+ RETURN_UNDEFINED();
r->d()->context->bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
}
+ RETURN_RESULT(*thisObject);
}
/*!
@@ -2299,13 +2351,14 @@ void QQuickJSContext2DPrototype::method_bezierCurveTo(const QV4::BuiltinFunction
\sa fill()
\sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-clip}{W3C 2d context standard for clip}
*/
-void QQuickJSContext2DPrototype::method_clip(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_clip(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
r->d()->context->clip();
- scope.result = callData->thisObject;
+ RETURN_RESULT(*thisObject);
}
/*!
@@ -2315,15 +2368,15 @@ void QQuickJSContext2DPrototype::method_clip(const QV4::BuiltinFunction *, QV4::
\sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-closepath}{W3C 2d context standard for closePath}
*/
-void QQuickJSContext2DPrototype::method_closePath(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_closePath(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
-
r->d()->context->closePath();
- scope.result = callData->thisObject;
+ RETURN_RESULT(*thisObject);
}
/*!
@@ -2335,12 +2388,13 @@ void QQuickJSContext2DPrototype::method_closePath(const QV4::BuiltinFunction *,
\sa fillStyle
*/
-void QQuickJSContext2DPrototype::method_fill(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_fill(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r);
r->d()->context->fill();
- scope.result = callData->thisObject;
+ RETURN_RESULT(*thisObject);
}
/*!
@@ -2348,22 +2402,23 @@ void QQuickJSContext2DPrototype::method_fill(const QV4::BuiltinFunction *, QV4::
Draws a line from the current position to the point (x, y).
*/
-void QQuickJSContext2DPrototype::method_lineTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_lineTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
- scope.result = callData->thisObject;
-
- if (callData->argc >= 2) {
- qreal x = callData->args[0].toNumber();
- qreal y = callData->args[1].toNumber();
+ if (argc >= 2) {
+ qreal x = argv[0].toNumber();
+ qreal y = argv[1].toNumber();
if (!qt_is_finite(x) || !qt_is_finite(y))
- return;
+ RETURN_UNDEFINED();
r->d()->context->lineTo(x, y);
}
+
+ RETURN_RESULT(*thisObject);
}
/*!
@@ -2371,21 +2426,22 @@ void QQuickJSContext2DPrototype::method_lineTo(const QV4::BuiltinFunction *, QV4
Creates a new subpath with the given point.
*/
-void QQuickJSContext2DPrototype::method_moveTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_moveTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
- scope.result = callData->thisObject;
-
- if (callData->argc >= 2) {
- qreal x = callData->args[0].toNumber();
- qreal y = callData->args[1].toNumber();
+ if (argc >= 2) {
+ qreal x = argv[0].toNumber();
+ qreal y = argv[1].toNumber();
if (!qt_is_finite(x) || !qt_is_finite(y))
- return;
+ RETURN_UNDEFINED();
r->d()->context->moveTo(x, y);
}
+
+ RETURN_RESULT(*thisObject);
}
/*!
@@ -2395,24 +2451,25 @@ void QQuickJSContext2DPrototype::method_moveTo(const QV4::BuiltinFunction *, QV4
See \l{http://www.w3.org/TR/2dcontext/#dom-context-2d-quadraticcurveto}{W3C 2d context standard for quadraticCurveTo}
*/
-void QQuickJSContext2DPrototype::method_quadraticCurveTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_quadraticCurveTo(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
- scope.result = callData->thisObject;
-
- if (callData->argc >= 4) {
- qreal cpx = callData->args[0].toNumber();
- qreal cpy = callData->args[1].toNumber();
- qreal x = callData->args[2].toNumber();
- qreal y = callData->args[3].toNumber();
+ if (argc >= 4) {
+ qreal cpx = argv[0].toNumber();
+ qreal cpy = argv[1].toNumber();
+ qreal x = argv[2].toNumber();
+ qreal y = argv[3].toNumber();
if (!qt_is_finite(cpx) || !qt_is_finite(cpy) || !qt_is_finite(x) || !qt_is_finite(y))
- return;
+ RETURN_UNDEFINED();
r->d()->context->quadraticCurveTo(cpx, cpy, x, y);
}
+
+ RETURN_RESULT(*thisObject);
}
/*!
@@ -2420,14 +2477,15 @@ void QQuickJSContext2DPrototype::method_quadraticCurveTo(const QV4::BuiltinFunct
Adds a rectangle at position (\c x, \c y), with the given width \c w and height \c h, as a closed subpath.
*/
-void QQuickJSContext2DPrototype::method_rect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_rect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
- if (callData->argc >= 4)
- r->d()->context->rect(callData->args[0].toNumber(), callData->args[1].toNumber(), callData->args[2].toNumber(), callData->args[3].toNumber());
- scope.result = callData->thisObject;
+ if (argc >= 4)
+ r->d()->context->rect(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber());
+ RETURN_RESULT(*thisObject);
}
@@ -2437,19 +2495,20 @@ void QQuickJSContext2DPrototype::method_rect(const QV4::BuiltinFunction *, QV4::
Adds the given rectangle rect with rounded corners to the path. The \c xRadius and \c yRadius arguments specify the radius of the
ellipses defining the corners of the rounded rectangle.
*/
-void QQuickJSContext2DPrototype::method_roundedRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_roundedRect(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
- if (callData->argc >= 6)
- r->d()->context->roundedRect(callData->args[0].toNumber()
- , callData->args[1].toNumber()
- , callData->args[2].toNumber()
- , callData->args[3].toNumber()
- , callData->args[4].toNumber()
- , callData->args[5].toNumber());
- scope.result = callData->thisObject;
+ if (argc >= 6)
+ r->d()->context->roundedRect(argv[0].toNumber()
+ , argv[1].toNumber()
+ , argv[2].toNumber()
+ , argv[3].toNumber()
+ , argv[4].toNumber()
+ , argv[5].toNumber());
+ RETURN_RESULT(*thisObject);
}
@@ -2461,16 +2520,16 @@ void QQuickJSContext2DPrototype::method_roundedRect(const QV4::BuiltinFunction *
The ellipse is composed of a clockwise curve, starting and finishing at zero degrees (the 3 o'clock position).
*/
-void QQuickJSContext2DPrototype::method_ellipse(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_ellipse(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
+ if (argc >= 4)
+ r->d()->context->ellipse(argv[0].toNumber(), argv[1].toNumber(), argv[2].toNumber(), argv[3].toNumber());
- if (callData->argc >= 4)
- r->d()->context->ellipse(callData->args[0].toNumber(), callData->args[1].toNumber(), callData->args[2].toNumber(), callData->args[3].toNumber());
-
- scope.result = callData->thisObject;
+ RETURN_RESULT(*thisObject);
}
@@ -2480,22 +2539,22 @@ void QQuickJSContext2DPrototype::method_ellipse(const QV4::BuiltinFunction *, QV
Adds the given \c text to the path as a set of closed subpaths created from the current context font supplied.
The subpaths are positioned so that the left end of the text's baseline lies at the point specified by (\c x, \c y).
*/
-void QQuickJSContext2DPrototype::method_text(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_text(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
- scope.result = callData->thisObject;
-
- if (callData->argc >= 3) {
- qreal x = callData->args[1].toNumber();
- qreal y = callData->args[2].toNumber();
+ if (argc >= 3) {
+ qreal x = argv[1].toNumber();
+ qreal y = argv[2].toNumber();
if (!qt_is_finite(x) || !qt_is_finite(y))
- return;
- r->d()->context->text(callData->args[0].toQStringNoThrow(), x, y);
+ RETURN_UNDEFINED();
+ r->d()->context->text(argv[0].toQStringNoThrow(), x, y);
}
+ RETURN_RESULT(*thisObject);
}
/*!
@@ -2507,13 +2566,14 @@ void QQuickJSContext2DPrototype::method_text(const QV4::BuiltinFunction *, QV4::
\sa strokeStyle
*/
-void QQuickJSContext2DPrototype::method_stroke(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_stroke(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
r->d()->context->stroke();
- scope.result = callData->thisObject;
+ RETURN_RESULT(*thisObject);
}
@@ -2524,29 +2584,33 @@ void QQuickJSContext2DPrototype::method_stroke(const QV4::BuiltinFunction *, QV4
\sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-ispointinpath}{W3C 2d context standard for isPointInPath}
*/
-void QQuickJSContext2DPrototype::method_isPointInPath(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_isPointInPath(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
bool pointInPath = false;
- if (callData->argc >= 2)
- pointInPath = r->d()->context->isPointInPath(callData->args[0].toNumber(), callData->args[1].toNumber());
- scope.result = QV4::Primitive::fromBoolean(pointInPath).asReturnedValue();
+ if (argc >= 2)
+ pointInPath = r->d()->context->isPointInPath(argv[0].toNumber(), argv[1].toNumber());
+ RETURN_RESULT(QV4::Primitive::fromBoolean(pointInPath).asReturnedValue());
}
-void QQuickJSContext2DPrototype::method_drawFocusRing(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawFocusRing(const QV4::FunctionObject *b, const QV4::Value *, const QV4::Value *, int)
{
+ QV4::Scope scope(b);
THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::drawFocusRing is not supported");
}
-void QQuickJSContext2DPrototype::method_setCaretSelectionRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_setCaretSelectionRect(const QV4::FunctionObject *b, const QV4::Value *, const QV4::Value *, int)
{
+ QV4::Scope scope(b);
THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::setCaretSelectionRect is not supported");
}
-void QQuickJSContext2DPrototype::method_caretBlinkRate(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_caretBlinkRate(const QV4::FunctionObject *b, const QV4::Value *, const QV4::Value *, int)
{
+ QV4::Scope scope(b);
THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::caretBlinkRate is not supported");
}
@@ -2573,20 +2637,22 @@ void QQuickJSContext2DPrototype::method_caretBlinkRate(const QV4::BuiltinFunctio
The default font value is "10px sans-serif".
*/
-void QQuickJSContext2D::method_get_font(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_get_font(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
RETURN_RESULT(scope.engine->newString(r->d()->context->state.font.toString()));
}
-void QQuickJSContext2D::method_set_font(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_set_font(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT_SETTER(r)
- QV4::ScopedString s(scope, callData->argument(0), QV4::ScopedString::Convert);
+ QV4::ScopedString s(scope, argc ? argv[0] : QV4::Primitive::undefinedValue(), QV4::ScopedString::Convert);
if (scope.engine->hasException)
RETURN_UNDEFINED();
QFont font = qt_font_from_string(s->toQString(), r->d()->context->state.font);
@@ -2610,9 +2676,10 @@ void QQuickJSContext2D::method_set_font(const QV4::BuiltinFunction *, QV4::Scope
\endlist
Other values are ignored. The default value is "start".
*/
-void QQuickJSContext2D::method_get_textAlign(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_get_textAlign(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
switch (r->d()->context->state.textAlign) {
@@ -2631,12 +2698,13 @@ void QQuickJSContext2D::method_get_textAlign(const QV4::BuiltinFunction *, QV4::
RETURN_RESULT(scope.engine->newString(QStringLiteral("start")));
}
-void QQuickJSContext2D::method_set_textAlign(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_set_textAlign(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT_SETTER(r)
- QV4::ScopedString s(scope, callData->argument(0), QV4::ScopedString::Convert);
+ QV4::ScopedString s(scope, argc ? argv[0] : QV4::Primitive::undefinedValue(), QV4::ScopedString::Convert);
if (scope.engine->hasException)
RETURN_UNDEFINED();
QString textAlign = s->toQString();
@@ -2676,9 +2744,10 @@ void QQuickJSContext2D::method_set_textAlign(const QV4::BuiltinFunction *, QV4::
\endlist
Other values are ignored. The default value is "alphabetic".
*/
-void QQuickJSContext2D::method_get_textBaseline(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_get_textBaseline(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
switch (r->d()->context->state.textBaseline) {
@@ -2697,11 +2766,12 @@ void QQuickJSContext2D::method_get_textBaseline(const QV4::BuiltinFunction *, QV
RETURN_RESULT(scope.engine->newString(QStringLiteral("alphabetic")));
}
-void QQuickJSContext2D::method_set_textBaseline(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2D::method_set_textBaseline(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT_SETTER(r)
- QV4::ScopedString s(scope, callData->argument(0), QV4::ScopedString::Convert);
+ QV4::ScopedString s(scope, argc ? argv[0] : QV4::Primitive::undefinedValue(), QV4::ScopedString::Convert);
if (scope.engine->hasException)
RETURN_UNDEFINED();
QString textBaseline = s->toQString();
@@ -2734,21 +2804,22 @@ void QQuickJSContext2D::method_set_textBaseline(const QV4::BuiltinFunction *, QV
\sa textBaseline
\sa strokeText
*/
-void QQuickJSContext2DPrototype::method_fillText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_fillText(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
- scope.result = callData->thisObject;
-
- if (callData->argc >= 3) {
- qreal x = callData->args[1].toNumber();
- qreal y = callData->args[2].toNumber();
+ if (argc >= 3) {
+ qreal x = argv[1].toNumber();
+ qreal y = argv[2].toNumber();
if (!qt_is_finite(x) || !qt_is_finite(y))
- return;
- QPainterPath textPath = r->d()->context->createTextGlyphs(x, y, callData->args[0].toQStringNoThrow());
+ RETURN_UNDEFINED();
+ QPainterPath textPath = r->d()->context->createTextGlyphs(x, y, argv[0].toQStringNoThrow());
r->d()->context->buffer()->fill(textPath);
}
+
+ RETURN_RESULT(*thisObject);
}
/*!
\qmlmethod object QtQuick::Context2D::strokeText(text, x, y)
@@ -2758,15 +2829,16 @@ void QQuickJSContext2DPrototype::method_fillText(const QV4::BuiltinFunction *, Q
\sa textBaseline
\sa fillText
*/
-void QQuickJSContext2DPrototype::method_strokeText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_strokeText(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
- if (callData->argc >= 3)
- r->d()->context->drawText(callData->args[0].toQStringNoThrow(), callData->args[1].toNumber(), callData->args[2].toNumber(), false);
- scope.result = callData->thisObject;
+ if (argc >= 3)
+ r->d()->context->drawText(argv[0].toQStringNoThrow(), argv[1].toNumber(), argv[2].toNumber(), false);
+ RETURN_RESULT(*thisObject);
}
/*!
@@ -2775,18 +2847,19 @@ void QQuickJSContext2DPrototype::method_strokeText(const QV4::BuiltinFunction *,
Returns an object with a \c width property, whose value is equivalent to
calling \l {QFontMetrics::width()} with the given \a text in the current font.
*/
-void QQuickJSContext2DPrototype::method_measureText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_measureText(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
- if (callData->argc >= 1) {
+ if (argc >= 1) {
QFontMetrics fm(r->d()->context->state.font);
- uint width = fm.width(callData->args[0].toQStringNoThrow());
+ uint width = fm.width(argv[0].toQStringNoThrow());
QV4::ScopedObject tm(scope, scope.engine->newObject());
tm->put(QV4::ScopedString(scope, scope.engine->newIdentifier(QStringLiteral("width"))).getPointer(),
QV4::ScopedValue(scope, QV4::Primitive::fromDouble(width)));
- RETURN_RESULT(tm);
+ RETURN_RESULT(*tm);
}
RETURN_UNDEFINED();
}
@@ -2850,25 +2923,24 @@ void QQuickJSContext2DPrototype::method_measureText(const QV4::BuiltinFunction *
\sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-drawimage}{W3C 2d context standard for drawImage}
*/
-void QQuickJSContext2DPrototype::method_drawImage(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, *thisObject);
CHECK_CONTEXT(r)
- scope.result = callData->thisObject;
-
qreal sx, sy, sw, sh, dx, dy, dw, dh;
- if (!callData->argc)
- return;
+ if (!argc)
+ RETURN_UNDEFINED();
//FIXME:This function should be moved to QQuickContext2D::drawImage(...)
if (!r->d()->context->state.invertibleCTM)
- return;
+ RETURN_UNDEFINED();
QQmlRefPointer<QQuickCanvasPixmap> pixmap;
- QV4::ScopedValue arg(scope, callData->args[0]);
+ QV4::ScopedValue arg(scope, argv[0]);
if (arg->isString()) {
QUrl url(arg->toQString());
if (!url.isValid())
@@ -2909,29 +2981,29 @@ void QQuickJSContext2DPrototype::method_drawImage(const QV4::BuiltinFunction *,
}
if (pixmap.isNull() || !pixmap->isValid())
- return;
+ RETURN_UNDEFINED();
- if (callData->argc >= 9) {
- sx = callData->args[1].toNumber();
- sy = callData->args[2].toNumber();
- sw = callData->args[3].toNumber();
- sh = callData->args[4].toNumber();
- dx = callData->args[5].toNumber();
- dy = callData->args[6].toNumber();
- dw = callData->args[7].toNumber();
- dh = callData->args[8].toNumber();
- } else if (callData->argc >= 5) {
+ if (argc >= 9) {
+ sx = argv[1].toNumber();
+ sy = argv[2].toNumber();
+ sw = argv[3].toNumber();
+ sh = argv[4].toNumber();
+ dx = argv[5].toNumber();
+ dy = argv[6].toNumber();
+ dw = argv[7].toNumber();
+ dh = argv[8].toNumber();
+ } else if (argc >= 5) {
sx = 0;
sy = 0;
sw = pixmap->width();
sh = pixmap->height();
- dx = callData->args[1].toNumber();
- dy = callData->args[2].toNumber();
- dw = callData->args[3].toNumber();
- dh = callData->args[4].toNumber();
- } else if (callData->argc >= 3) {
- dx = callData->args[1].toNumber();
- dy = callData->args[2].toNumber();
+ dx = argv[1].toNumber();
+ dy = argv[2].toNumber();
+ dw = argv[3].toNumber();
+ dh = argv[4].toNumber();
+ } else if (argc >= 3) {
+ dx = argv[1].toNumber();
+ dy = argv[2].toNumber();
sx = 0;
sy = 0;
sw = pixmap->width();
@@ -2939,7 +3011,7 @@ void QQuickJSContext2DPrototype::method_drawImage(const QV4::BuiltinFunction *,
dw = sw;
dh = sh;
} else {
- return;
+ RETURN_UNDEFINED();
}
if (!qt_is_finite(sx)
@@ -2950,7 +3022,7 @@ void QQuickJSContext2DPrototype::method_drawImage(const QV4::BuiltinFunction *,
|| !qt_is_finite(dy)
|| !qt_is_finite(dw)
|| !qt_is_finite(dh))
- return;
+ RETURN_UNDEFINED();
if (sx < 0
|| sy < 0
@@ -2963,6 +3035,8 @@ void QQuickJSContext2DPrototype::method_drawImage(const QV4::BuiltinFunction *,
}
r->d()->context->buffer()->drawPixmap(pixmap, QRectF(sx, sy, sw, sh), QRectF(dx, dy, dw, dh));
+
+ RETURN_RESULT(*thisObject);
}
// pixel manipulation
@@ -2989,40 +3063,43 @@ void QQuickJSContext2DPrototype::method_drawImage(const QV4::BuiltinFunction *,
\qmlproperty int QtQuick::CanvasImageData::width
Holds the actual width dimension of the data in the ImageData object, in device pixels.
*/
-void QQuickJSContext2DImageData::method_get_width(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DImageData::method_get_width(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, *thisObject);
if (!imageData)
THROW_TYPE_ERROR();
QV4::Scoped<QQuickJSContext2DPixelData> r(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
int width = r ? r->d()->image->width() : 0;
- scope.result = QV4::Encode(width);
+ RETURN_RESULT(QV4::Encode(width));
}
/*!
\qmlproperty int QtQuick::CanvasImageData::height
Holds the actual height dimension of the data in the ImageData object, in device pixels.
*/
-void QQuickJSContext2DImageData::method_get_height(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DImageData::method_get_height(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, *thisObject);
if (!imageData)
THROW_TYPE_ERROR();
QV4::Scoped<QQuickJSContext2DPixelData> r(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
int height = r ? r->d()->image->height() : 0;
- scope.result = QV4::Encode(height);
+ RETURN_RESULT(QV4::Encode(height));
}
/*!
\qmlproperty object QtQuick::CanvasImageData::data
Holds the one-dimensional array containing the data in RGBA order, as integers in the range 0 to 255.
*/
-void QQuickJSContext2DImageData::method_get_data(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DImageData::method_get_data(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, callData->thisObject);
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, *thisObject);
if (!imageData)
THROW_TYPE_ERROR();
- scope.result = imageData->d()->pixelData;
+ RETURN_RESULT(imageData->d()->pixelData);
}
/*!
@@ -3043,9 +3120,10 @@ void QQuickJSContext2DImageData::method_get_data(const QV4::BuiltinFunction *, Q
The length attribute of a CanvasPixelArray object must return this h×w×4 number value.
This property is read only.
*/
-void QQuickJSContext2DPixelData::proto_get_length(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPixelData::proto_get_length(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *, int)
{
- QV4::Scoped<QQuickJSContext2DPixelData> r(scope, callData->thisObject.as<QQuickJSContext2DPixelData>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2DPixelData> r(scope, thisObject->as<QQuickJSContext2DPixelData>());
if (!r || r->d()->image->isNull())
RETURN_UNDEFINED();
@@ -3083,13 +3161,13 @@ QV4::ReturnedValue QQuickJSContext2DPixelData::getIndexed(const QV4::Managed *m,
return QV4::Encode::undefined();
}
-void QQuickJSContext2DPixelData::putIndexed(QV4::Managed *m, uint index, const QV4::Value &value)
+bool QQuickJSContext2DPixelData::putIndexed(QV4::Managed *m, uint index, const QV4::Value &value)
{
Q_ASSERT(m->as<QQuickJSContext2DPixelData>());
QV4::ExecutionEngine *v4 = static_cast<QQuickJSContext2DPixelData *>(m)->engine();
QV4::Scope scope(v4);
if (scope.hasException())
- return;
+ return false;
QV4::Scoped<QQuickJSContext2DPixelData> r(scope, static_cast<QQuickJSContext2DPixelData *>(m));
@@ -3115,7 +3193,10 @@ void QQuickJSContext2DPixelData::putIndexed(QV4::Managed *m, uint index, const Q
*pixel = qRgba(qRed(*pixel), qGreen(*pixel), qBlue(*pixel), v);
break;
}
+ return true;
}
+
+ return false;
}
/*!
\qmlmethod CanvasImageData QtQuick::Context2D::createImageData(real sw, real sh)
@@ -3138,13 +3219,14 @@ void QQuickJSContext2DPixelData::putIndexed(QV4::Managed *m, uint index, const Q
\sa Canvas::loadImage(), QtQuick::Canvas::unloadImage(),
QtQuick::Canvas::isImageLoaded
*/
-void QQuickJSContext2DPrototype::method_createImageData(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_createImageData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (callData->argc == 1) {
- QV4::ScopedValue arg0(scope, callData->args[0]);
+ if (argc == 1) {
+ QV4::ScopedValue arg0(scope, argv[0]);
QV4::Scoped<QQuickJSContext2DImageData> imgData(scope, arg0);
if (!!imgData) {
QV4::Scoped<QQuickJSContext2DPixelData> pa(scope, imgData->d()->pixelData.as<QQuickJSContext2DPixelData>());
@@ -3157,9 +3239,9 @@ void QQuickJSContext2DPrototype::method_createImageData(const QV4::BuiltinFuncti
QImage image = r->d()->context->createPixmap(QUrl(arg0->toQStringNoThrow()))->image();
RETURN_RESULT(qt_create_image_data(image.width(), image.height(), scope.engine, image));
}
- } else if (callData->argc == 2) {
- qreal w = callData->args[0].toNumber();
- qreal h = callData->args[1].toNumber();
+ } else if (argc == 2) {
+ qreal w = argv[0].toNumber();
+ qreal h = argv[1].toNumber();
if (!qt_is_finite(w) || !qt_is_finite(h))
THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "createImageData(): invalid arguments");
@@ -3176,16 +3258,17 @@ void QQuickJSContext2DPrototype::method_createImageData(const QV4::BuiltinFuncti
\qmlmethod CanvasImageData QtQuick::Context2D::getImageData(real sx, real sy, real sw, real sh)
Returns an CanvasImageData object containing the image data for the given rectangle of the canvas.
*/
-void QQuickJSContext2DPrototype::method_getImageData(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_getImageData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (callData->argc >= 4) {
- qreal x = callData->args[0].toNumber();
- qreal y = callData->args[1].toNumber();
- qreal w = callData->args[2].toNumber();
- qreal h = callData->args[3].toNumber();
+ if (argc >= 4) {
+ qreal x = argv[0].toNumber();
+ qreal y = argv[1].toNumber();
+ qreal w = argv[2].toNumber();
+ qreal h = argv[3].toNumber();
if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "getImageData(): Invalid arguments");
@@ -3195,47 +3278,46 @@ void QQuickJSContext2DPrototype::method_getImageData(const QV4::BuiltinFunction
QImage image = r->d()->context->canvas()->toImage(QRectF(x, y, w, h));
RETURN_RESULT(qt_create_image_data(w, h, scope.engine, image));
}
- scope.result = QV4::Encode::null();
+ RETURN_RESULT(QV4::Encode::null());
}
/*!
\qmlmethod object QtQuick::Context2D::putImageData(CanvasImageData imageData, real dx, real dy, real dirtyX, real dirtyY, real dirtyWidth, real dirtyHeight)
Paints the data from the given ImageData object onto the canvas. If a dirty rectangle (\a dirtyX, \a dirtyY, \a dirtyWidth, \a dirtyHeight) is provided, only the pixels from that rectangle are painted.
*/
-void QQuickJSContext2DPrototype::method_putImageData(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickJSContext2DPrototype::method_putImageData(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickJSContext2D> r(scope, thisObject->as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (callData->argc < 7)
+ if (argc < 7)
RETURN_UNDEFINED();
- QV4::ScopedValue arg0(scope, callData->args[0]);
+ QV4::ScopedValue arg0(scope, argv[0]);
if (!arg0->isObject())
THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "Context2D::putImageData, the image data type mismatch");
- qreal dx = callData->args[1].toNumber();
- qreal dy = callData->args[2].toNumber();
+ qreal dx = argv[1].toNumber();
+ qreal dy = argv[2].toNumber();
qreal w, h, dirtyX, dirtyY, dirtyWidth, dirtyHeight;
if (!qt_is_finite(dx) || !qt_is_finite(dy))
THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "putImageData() : Invalid arguments");
- scope.result = callData->thisObject;
-
QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, arg0);
if (!imageData)
- return;
+ RETURN_UNDEFINED();
QV4::Scoped<QQuickJSContext2DPixelData> pixelArray(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
if (pixelArray) {
w = pixelArray->d()->image->width();
h = pixelArray->d()->image->height();
- if (callData->argc == 7) {
- dirtyX = callData->args[3].toNumber();
- dirtyY = callData->args[4].toNumber();
- dirtyWidth = callData->args[5].toNumber();
- dirtyHeight = callData->args[6].toNumber();
+ if (argc == 7) {
+ dirtyX = argv[3].toNumber();
+ dirtyY = argv[4].toNumber();
+ dirtyWidth = argv[5].toNumber();
+ dirtyHeight = argv[6].toNumber();
if (!qt_is_finite(dirtyX) || !qt_is_finite(dirtyY) || !qt_is_finite(dirtyWidth) || !qt_is_finite(dirtyHeight))
THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "putImageData() : Invalid arguments");
@@ -3270,7 +3352,7 @@ void QQuickJSContext2DPrototype::method_putImageData(const QV4::BuiltinFunction
}
if (dirtyWidth <=0 || dirtyHeight <= 0)
- return;
+ RETURN_UNDEFINED();
} else {
dirtyX = 0;
dirtyY = 0;
@@ -3281,6 +3363,8 @@ void QQuickJSContext2DPrototype::method_putImageData(const QV4::BuiltinFunction
QImage image = pixelArray->d()->image->copy(dirtyX, dirtyY, dirtyWidth, dirtyHeight);
r->d()->context->buffer()->drawImage(image, QRectF(dirtyX, dirtyY, dirtyWidth, dirtyHeight), QRectF(dx, dy, dirtyWidth, dirtyHeight));
}
+
+ RETURN_RESULT(*thisObject);
}
/*!
@@ -3303,24 +3387,25 @@ void QQuickJSContext2DPrototype::method_putImageData(const QV4::BuiltinFunction
gradient.addColorStop(0.7, 'rgba(0, 255, 255, 1');
\endcode
*/
-void QQuickContext2DStyle::gradient_proto_addColorStop(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
+QV4::ReturnedValue QQuickContext2DStyle::gradient_proto_addColorStop(const QV4::FunctionObject *b, const QV4::Value *thisObject, const QV4::Value *argv, int argc)
{
- QV4::Scoped<QQuickContext2DStyle> style(scope, callData->thisObject.as<QQuickContext2DStyle>());
+ QV4::Scope scope(b);
+ QV4::Scoped<QQuickContext2DStyle> style(scope, thisObject->as<QQuickContext2DStyle>());
if (!style)
THROW_GENERIC_ERROR("Not a CanvasGradient object");
- if (callData->argc == 2) {
+ if (argc == 2) {
if (!style->d()->brush->gradient())
THROW_GENERIC_ERROR("Not a valid CanvasGradient object, can't get the gradient information");
QGradient gradient = *(style->d()->brush->gradient());
- qreal pos = callData->args[0].toNumber();
+ qreal pos = argv[0].toNumber();
QColor color;
- if (callData->args[1].as<Object>()) {
- color = scope.engine->toVariant(callData->args[1], qMetaTypeId<QColor>()).value<QColor>();
+ if (argv[1].as<Object>()) {
+ color = scope.engine->toVariant(argv[1], qMetaTypeId<QColor>()).value<QColor>();
} else {
- color = qt_color_from_string(callData->args[1]);
+ color = qt_color_from_string(argv[1]);
}
if (pos < 0.0 || pos > 1.0 || !qt_is_finite(pos)) {
THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "CanvasGradient: parameter offset out of range");
@@ -3334,7 +3419,7 @@ void QQuickContext2DStyle::gradient_proto_addColorStop(const QV4::BuiltinFunctio
*style->d()->brush = gradient;
}
- scope.result = callData->thisObject;
+ return thisObject->asReturnedValue();
}
void QQuickContext2D::scale(qreal x, qreal y)
@@ -3367,7 +3452,7 @@ void QQuickContext2D::rotate(qreal angle)
return;
QTransform newTransform =state.matrix;
- newTransform.rotate(DEGREES(angle));
+ newTransform.rotate(qRadiansToDegrees(angle));
if (!newTransform.isInvertible()) {
state.invertibleCTM = false;
@@ -3376,7 +3461,7 @@ void QQuickContext2D::rotate(qreal angle)
state.matrix = newTransform;
buffer()->updateMatrix(state.matrix);
- m_path = QTransform().rotate(-DEGREES(angle)).map(m_path);
+ m_path = QTransform().rotate(-qRadiansToDegrees(angle)).map(m_path);
}
void QQuickContext2D::shear(qreal h, qreal v)
@@ -3773,8 +3858,8 @@ void QQuickContext2D::arc(qreal xc, qreal yc, qreal radius, qreal sar, qreal ear
antiClockWise = !antiClockWise;
//end hack
- float sa = DEGREES(sar);
- float ea = DEGREES(ear);
+ float sa = qRadiansToDegrees(sar);
+ float ea = qRadiansToDegrees(ear);
double span = 0;
@@ -3958,7 +4043,7 @@ class QQuickContext2DTextureCleanup : public QRunnable
{
public:
QQuickContext2DTexture *texture;
- void run() Q_DECL_OVERRIDE { delete texture; }
+ void run() override { delete texture; }
};
QMutex QQuickContext2D::mutex;
diff --git a/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp b/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp
index b985cb0ccc..30895d9b0e 100644
--- a/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp
+++ b/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp
@@ -100,8 +100,8 @@ namespace {
{
}
- void paint(QPainter *p) const Q_DECL_OVERRIDE { p->fillRect(m_rect, m_brush); }
- QRectF boundingRect() const Q_DECL_OVERRIDE { return m_rect; }
+ void paint(QPainter *p) const override { p->fillRect(m_rect, m_brush); }
+ QRectF boundingRect() const override { return m_rect; }
private:
QRectF m_rect;
@@ -117,8 +117,8 @@ namespace {
{
}
- void paint(QPainter *p) const Q_DECL_OVERRIDE { p->fillPath(m_path, m_brush); }
- QRectF boundingRect() const Q_DECL_OVERRIDE { return m_path.boundingRect(); }
+ void paint(QPainter *p) const override { p->fillPath(m_path, m_brush); }
+ QRectF boundingRect() const override { return m_path.boundingRect(); }
private:
QPainterPath m_path;
@@ -134,9 +134,9 @@ namespace {
{
}
- void paint(QPainter *p) const Q_DECL_OVERRIDE { p->strokePath(m_path, m_pen); }
+ void paint(QPainter *p) const override { p->strokePath(m_path, m_pen); }
- QRectF boundingRect() const Q_DECL_OVERRIDE
+ QRectF boundingRect() const override
{
qreal d = qMax(qreal(1), m_pen.widthF());
return m_path.boundingRect().adjusted(-d, -d, d, d);
@@ -156,9 +156,9 @@ namespace {
{
}
- void paint(QPainter *p) const Q_DECL_OVERRIDE { p->drawImage(m_offset, m_image); }
+ void paint(QPainter *p) const override { p->drawImage(m_offset, m_image); }
- QRectF boundingRect() const Q_DECL_OVERRIDE { return QRectF(m_image.rect()).translated(m_offset); }
+ QRectF boundingRect() const override { return QRectF(m_image.rect()).translated(m_offset); }
private:
QImage m_image;
diff --git a/src/quick/items/context2d/qquickcontext2dtexture_p.h b/src/quick/items/context2d/qquickcontext2dtexture_p.h
index 81896dcdc1..0e1fbd5d34 100644
--- a/src/quick/items/context2d/qquickcontext2dtexture_p.h
+++ b/src/quick/items/context2d/qquickcontext2dtexture_p.h
@@ -189,21 +189,21 @@ class QQuickContext2DFBOTexture : public QQuickContext2DTexture
public:
QQuickContext2DFBOTexture();
~QQuickContext2DFBOTexture();
- QQuickContext2DTile* createTile() const Q_DECL_OVERRIDE;
- QPaintDevice* beginPainting() Q_DECL_OVERRIDE;
- void endPainting() Q_DECL_OVERRIDE;
+ QQuickContext2DTile* createTile() const override;
+ QPaintDevice* beginPainting() override;
+ void endPainting() override;
QRectF normalizedTextureSubRect() const;
- QQuickCanvasItem::RenderTarget renderTarget() const Q_DECL_OVERRIDE;
- void compositeTile(QQuickContext2DTile* tile) Q_DECL_OVERRIDE;
- QSize adjustedTileSize(const QSize &ts) Q_DECL_OVERRIDE;
+ QQuickCanvasItem::RenderTarget renderTarget() const override;
+ void compositeTile(QQuickContext2DTile* tile) override;
+ QSize adjustedTileSize(const QSize &ts) override;
- QSGTexture *textureForNextFrame(QSGTexture *, QQuickWindow *window) Q_DECL_OVERRIDE;
+ QSGTexture *textureForNextFrame(QSGTexture *, QQuickWindow *window) override;
protected:
- QVector2D scaleFactor() const Q_DECL_OVERRIDE;
+ QVector2D scaleFactor() const override;
public Q_SLOTS:
- void grabImage(const QRectF& region = QRectF()) Q_DECL_OVERRIDE;
+ void grabImage(const QRectF& region = QRectF()) override;
private:
bool doMultisampling() const;
diff --git a/src/quick/items/context2d/qquickcontext2dtile_p.h b/src/quick/items/context2d/qquickcontext2dtile_p.h
index d5255edcfc..c3d4dfef64 100644
--- a/src/quick/items/context2d/qquickcontext2dtile_p.h
+++ b/src/quick/items/context2d/qquickcontext2dtile_p.h
@@ -93,7 +93,7 @@ class QQuickContext2DFBOTile : public QQuickContext2DTile
public:
QQuickContext2DFBOTile();
~QQuickContext2DFBOTile();
- virtual void setRect(const QRect& r) override;
+ void setRect(const QRect& r) override;
QOpenGLFramebufferObject* fbo() const {return m_fbo;}
void drawFinished() override;
diff --git a/src/quick/items/items.pri b/src/quick/items/items.pri
index 0f8061b5ef..1acb3b5265 100644
--- a/src/quick/items/items.pri
+++ b/src/quick/items/items.pri
@@ -41,8 +41,6 @@ HEADERS += \
$$PWD/qquickflickable_p.h \
$$PWD/qquickflickable_p_p.h \
$$PWD/qquickflickablebehavior_p.h \
- $$PWD/qquickrepeater_p.h \
- $$PWD/qquickrepeater_p_p.h \
$$PWD/qquickloader_p.h \
$$PWD/qquickloader_p_p.h \
$$PWD/qquicktranslate_p.h \
@@ -89,7 +87,6 @@ SOURCES += \
$$PWD/qquickmousearea.cpp \
$$PWD/qquickpincharea.cpp \
$$PWD/qquickflickable.cpp \
- $$PWD/qquickrepeater.cpp \
$$PWD/qquickloader.cpp \
$$PWD/qquicktranslate.cpp \
$$PWD/qquickclipnode.cpp \
@@ -168,6 +165,15 @@ qtConfig(quick-flipable) {
$$PWD/qquickflipable.cpp
}
+qtConfig(quick-repeater) {
+ HEADERS += \
+ $$PWD/qquickrepeater_p.h \
+ $$PWD/qquickrepeater_p_p.h
+
+ SOURCES += \
+ $$PWD/qquickrepeater.cpp
+}
+
qtConfig(quick-shadereffect) {
HEADERS += \
$$PWD/qquickshadereffectsource_p.h \
diff --git a/src/quick/items/qquickanchors.cpp b/src/quick/items/qquickanchors.cpp
index c0bec7d716..45b405bd82 100644
--- a/src/quick/items/qquickanchors.cpp
+++ b/src/quick/items/qquickanchors.cpp
@@ -832,7 +832,7 @@ void QQuickAnchors::resetTop()
Q_D(QQuickAnchors);
d->usedAnchors &= ~TopAnchor;
d->remDepend(d->topAnchorItem);
- d->topAnchorItem = Q_NULLPTR;
+ d->topAnchorItem = nullptr;
d->topAnchorLine = QQuickAnchors::InvalidAnchor;
emit topChanged();
d->updateVerticalAnchors();
@@ -872,7 +872,7 @@ void QQuickAnchors::resetBottom()
Q_D(QQuickAnchors);
d->usedAnchors &= ~BottomAnchor;
d->remDepend(d->bottomAnchorItem);
- d->bottomAnchorItem = Q_NULLPTR;
+ d->bottomAnchorItem = nullptr;
d->bottomAnchorLine = QQuickAnchors::InvalidAnchor;
emit bottomChanged();
d->updateVerticalAnchors();
@@ -912,7 +912,7 @@ void QQuickAnchors::resetVerticalCenter()
Q_D(QQuickAnchors);
d->usedAnchors &= ~VCenterAnchor;
d->remDepend(d->vCenterAnchorItem);
- d->vCenterAnchorItem = Q_NULLPTR;
+ d->vCenterAnchorItem = nullptr;
d->vCenterAnchorLine = QQuickAnchors::InvalidAnchor;
emit verticalCenterChanged();
d->updateVerticalAnchors();
@@ -952,7 +952,7 @@ void QQuickAnchors::resetBaseline()
Q_D(QQuickAnchors);
d->usedAnchors &= ~BaselineAnchor;
d->remDepend(d->baselineAnchorItem);
- d->baselineAnchorItem = Q_NULLPTR;
+ d->baselineAnchorItem = nullptr;
d->baselineAnchorLine = QQuickAnchors::InvalidAnchor;
emit baselineChanged();
d->updateVerticalAnchors();
@@ -992,7 +992,7 @@ void QQuickAnchors::resetLeft()
Q_D(QQuickAnchors);
d->usedAnchors &= ~LeftAnchor;
d->remDepend(d->leftAnchorItem);
- d->leftAnchorItem = Q_NULLPTR;
+ d->leftAnchorItem = nullptr;
d->leftAnchorLine = QQuickAnchors::InvalidAnchor;
emit leftChanged();
d->updateHorizontalAnchors();
@@ -1032,7 +1032,7 @@ void QQuickAnchors::resetRight()
Q_D(QQuickAnchors);
d->usedAnchors &= ~RightAnchor;
d->remDepend(d->rightAnchorItem);
- d->rightAnchorItem = Q_NULLPTR;
+ d->rightAnchorItem = nullptr;
d->rightAnchorLine = QQuickAnchors::InvalidAnchor;
emit rightChanged();
d->updateHorizontalAnchors();
@@ -1072,7 +1072,7 @@ void QQuickAnchors::resetHorizontalCenter()
Q_D(QQuickAnchors);
d->usedAnchors &= ~HCenterAnchor;
d->remDepend(d->hCenterAnchorItem);
- d->hCenterAnchorItem = Q_NULLPTR;
+ d->hCenterAnchorItem = nullptr;
d->hCenterAnchorLine = QQuickAnchors::InvalidAnchor;
emit horizontalCenterChanged();
d->updateHorizontalAnchors();
diff --git a/src/quick/items/qquickanchors_p_p.h b/src/quick/items/qquickanchors_p_p.h
index 906f607302..ae6ca02786 100644
--- a/src/quick/items/qquickanchors_p_p.h
+++ b/src/quick/items/qquickanchors_p_p.h
@@ -90,15 +90,15 @@ public:
, hCenterOffset(0)
, baselineOffset(0)
, item(i)
- , fill(Q_NULLPTR)
- , centerIn(Q_NULLPTR)
- , leftAnchorItem(Q_NULLPTR)
- , rightAnchorItem(Q_NULLPTR)
- , topAnchorItem(Q_NULLPTR)
- , bottomAnchorItem(Q_NULLPTR)
- , vCenterAnchorItem(Q_NULLPTR)
- , hCenterAnchorItem(Q_NULLPTR)
- , baselineAnchorItem(Q_NULLPTR)
+ , fill(nullptr)
+ , centerIn(nullptr)
+ , leftAnchorItem(nullptr)
+ , rightAnchorItem(nullptr)
+ , topAnchorItem(nullptr)
+ , bottomAnchorItem(nullptr)
+ , vCenterAnchorItem(nullptr)
+ , hCenterAnchorItem(nullptr)
+ , baselineAnchorItem(nullptr)
, leftAnchorLine(QQuickAnchors::InvalidAnchor)
, leftMarginExplicit(false)
, rightAnchorLine(QQuickAnchors::InvalidAnchor)
@@ -141,8 +141,8 @@ public:
void updateMe();
// QQuickItemGeometryListener interface
- void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) Q_DECL_OVERRIDE;
- QQuickAnchorsPrivate *anchorPrivate() Q_DECL_OVERRIDE { return this; }
+ void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) override;
+ QQuickAnchorsPrivate *anchorPrivate() override { return this; }
bool checkHValid() const;
bool checkVValid() const;
diff --git a/src/quick/items/qquickanimatedimage.cpp b/src/quick/items/qquickanimatedimage.cpp
index 2f76671b1a..5c9f893b63 100644
--- a/src/quick/items/qquickanimatedimage.cpp
+++ b/src/quick/items/qquickanimatedimage.cpp
@@ -260,6 +260,32 @@ int QQuickAnimatedImage::frameCount() const
return d->movie->frameCount();
}
+/*!
+ \qmlproperty real QtQuick::AnimatedImage::speed
+ \since QtQuick 2.11
+
+ This property holds the speed of the animation.
+
+ The speed is measured in percentage of the original animated image speed.
+ The default speed is 1.0 (original speed).
+*/
+qreal QQuickAnimatedImage::speed() const
+{
+ Q_D(const QQuickAnimatedImage);
+ return d->speed;
+}
+
+void QQuickAnimatedImage::setSpeed(qreal speed)
+{
+ Q_D(QQuickAnimatedImage);
+ if (d->speed != speed) {
+ d->speed = speed;
+ if (d->movie)
+ d->movie->setSpeed(qRound(speed * 100.0));
+ emit speedChanged();
+ }
+}
+
void QQuickAnimatedImage::setSource(const QUrl &url)
{
Q_D(QQuickAnimatedImage);
@@ -389,6 +415,7 @@ void QQuickAnimatedImage::movieRequestFinished()
connect(d->movie, &QMovie::frameChanged, this, &QQuickAnimatedImage::movieUpdate);
if (d->cache)
d->movie->setCacheMode(QMovie::CacheAll);
+ d->movie->setSpeed(qRound(d->speed * 100.0));
d->status = Ready;
emit statusChanged(d->status);
diff --git a/src/quick/items/qquickanimatedimage_p.h b/src/quick/items/qquickanimatedimage_p.h
index d0d8ec7c5c..678907a6e2 100644
--- a/src/quick/items/qquickanimatedimage_p.h
+++ b/src/quick/items/qquickanimatedimage_p.h
@@ -70,6 +70,7 @@ class Q_AUTOTEST_EXPORT QQuickAnimatedImage : public QQuickImage
Q_PROPERTY(bool paused READ isPaused WRITE setPaused NOTIFY pausedChanged)
Q_PROPERTY(int currentFrame READ currentFrame WRITE setCurrentFrame NOTIFY frameChanged)
Q_PROPERTY(int frameCount READ frameCount NOTIFY frameCountChanged)
+ Q_PROPERTY(qreal speed READ speed WRITE setSpeed NOTIFY speedChanged REVISION 11)
// read-only for AnimatedImage
Q_PROPERTY(QSize sourceSize READ sourceSize NOTIFY sourceSizeChanged)
@@ -89,16 +90,19 @@ public:
int frameCount() const;
+ qreal speed() const;
+ void setSpeed(qreal speed);
+
// Extends QQuickImage's src property
- void setSource(const QUrl&) Q_DECL_OVERRIDE;
+ void setSource(const QUrl&) override;
virtual QSize sourceSize();
Q_SIGNALS:
void playingChanged();
void pausedChanged();
void frameChanged();
- void sourceSizeChanged();
void frameCountChanged();
+ Q_REVISION(11) void speedChanged();
private Q_SLOTS:
void movieUpdate();
@@ -107,8 +111,8 @@ private Q_SLOTS:
void onCacheChanged();
protected:
- void load() Q_DECL_OVERRIDE;
- void componentComplete() Q_DECL_OVERRIDE;
+ void load() override;
+ void componentComplete() override;
private:
Q_DISABLE_COPY(QQuickAnimatedImage)
diff --git a/src/quick/items/qquickanimatedimage_p_p.h b/src/quick/items/qquickanimatedimage_p_p.h
index e172962ee4..1a74f67424 100644
--- a/src/quick/items/qquickanimatedimage_p_p.h
+++ b/src/quick/items/qquickanimatedimage_p_p.h
@@ -71,7 +71,7 @@ class QQuickAnimatedImagePrivate : public QQuickImagePrivate
public:
QQuickAnimatedImagePrivate()
: playing(true), paused(false), oldPlaying(false), padding(0)
- , presetCurrentFrame(0) , currentSourceSize(0, 0), movie(nullptr)
+ , presetCurrentFrame(0), speed(1.0), currentSourceSize(0, 0), movie(nullptr)
#if QT_CONFIG(qml_network)
, reply(nullptr), redirectCount(0)
#endif
@@ -86,6 +86,7 @@ public:
bool oldPlaying : 1;
unsigned padding: 29;
int presetCurrentFrame;
+ qreal speed;
QSize currentSourceSize;
QMovie *movie;
#if QT_CONFIG(qml_network)
diff --git a/src/quick/items/qquickanimatedsprite_p.h b/src/quick/items/qquickanimatedsprite_p.h
index 850461a011..276e6fbb92 100644
--- a/src/quick/items/qquickanimatedsprite_p.h
+++ b/src/quick/items/qquickanimatedsprite_p.h
@@ -169,8 +169,8 @@ protected Q_SLOTS:
void reset();
protected:
- void componentComplete() Q_DECL_OVERRIDE;
- QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE;
+ void componentComplete() override;
+ QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
private:
void maybeUpdate();
bool isCurrentFrameChangedConnected();
diff --git a/src/quick/items/qquickborderimage_p.h b/src/quick/items/qquickborderimage_p.h
index 844f71e2c9..f43e6c8e1e 100644
--- a/src/quick/items/qquickborderimage_p.h
+++ b/src/quick/items/qquickborderimage_p.h
@@ -83,7 +83,7 @@ public:
TileMode verticalTileMode() const;
void setVerticalTileMode(TileMode);
- void setSource(const QUrl &url) Q_DECL_OVERRIDE;
+ void setSource(const QUrl &url) override;
Q_SIGNALS:
void horizontalTileModeChanged();
@@ -91,16 +91,16 @@ Q_SIGNALS:
void sourceSizeChanged();
protected:
- void load() Q_DECL_OVERRIDE;
- void pixmapChange() Q_DECL_OVERRIDE;
- QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE;
+ void load() override;
+ void pixmapChange() override;
+ QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
private:
void setGridScaledImage(const QQuickGridScaledImage& sci);
private Q_SLOTS:
void doUpdate();
- void requestFinished() Q_DECL_OVERRIDE;
+ void requestFinished() override;
#if QT_CONFIG(qml_network)
void sciRequestFinished();
#endif
diff --git a/src/quick/items/qquickdrag.cpp b/src/quick/items/qquickdrag.cpp
index 7c936ff21c..6dc005a03c 100644
--- a/src/quick/items/qquickdrag.cpp
+++ b/src/quick/items/qquickdrag.cpp
@@ -82,8 +82,8 @@ public:
{
}
- void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) Q_DECL_OVERRIDE;
- void itemParentChanged(QQuickItem *, QQuickItem *parent) Q_DECL_OVERRIDE;
+ void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) override;
+ void itemParentChanged(QQuickItem *, QQuickItem *parent) override;
void updatePosition();
void restartDrag();
void deliverEnterEvent();
diff --git a/src/quick/items/qquickdroparea_p.h b/src/quick/items/qquickdroparea_p.h
index 0c4c072db7..d25cd4decc 100644
--- a/src/quick/items/qquickdroparea_p.h
+++ b/src/quick/items/qquickdroparea_p.h
@@ -175,10 +175,10 @@ Q_SIGNALS:
void dropped(QQuickDropEvent *drop);
protected:
- void dragMoveEvent(QDragMoveEvent *event) Q_DECL_OVERRIDE;
- void dragEnterEvent(QDragEnterEvent *event) Q_DECL_OVERRIDE;
- void dragLeaveEvent(QDragLeaveEvent *event) Q_DECL_OVERRIDE;
- void dropEvent(QDropEvent *event) Q_DECL_OVERRIDE;
+ void dragMoveEvent(QDragMoveEvent *event) override;
+ void dragEnterEvent(QDragEnterEvent *event) override;
+ void dragLeaveEvent(QDragLeaveEvent *event) override;
+ void dropEvent(QDropEvent *event) override;
private:
Q_DISABLE_COPY(QQuickDropArea)
diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp
index 448b63c347..260b302121 100644
--- a/src/quick/items/qquickevents.cpp
+++ b/src/quick/items/qquickevents.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -38,8 +38,11 @@
****************************************************************************/
#include "qquickevents_p_p.h"
+#include <QtCore/qmap.h>
#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/private/qtouchdevice_p.h>
#include <QtQuick/private/qquickitem_p.h>
+#include <QtQuick/private/qquickpointerhandler_p.h>
#include <QtQuick/private/qquickwindow_p.h>
#include <private/qdebug_p.h>
@@ -323,6 +326,18 @@ Item {
*/
/*!
+ \qmlproperty int QtQuick::MouseEvent::flags
+ \since 5.11
+
+ This property holds the flags that provide additional information about the
+ mouse event.
+
+ \value Qt.MouseEventCreatedDoubleClick Indicates that Qt has created a
+ double click event from this event. This flag is set in the event originating
+ from a button press, and not in the resulting double click event.
+*/
+
+/*!
\qmltype WheelEvent
\instantiates QQuickWheelEvent
\inqmlmodule QtQuick
@@ -445,10 +460,96 @@ Item {
\l inverted always returns false.
*/
-typedef QHash<QTouchDevice *, QQuickPointerDevice *> PointerDeviceForTouchDeviceHash;
+/*!
+ \qmltype PointerDevice
+ \instantiates QQuickPointerDevice
+ \inqmlmodule QtQuick
+ \ingroup qtquick-input-events
+
+ \brief Provides information about a pointing device
+
+ A pointing device can be a mouse, a touchscreen, or a stylus on a graphics
+ tablet.
+
+ \sa PointerEvent, PointerHandler
+*/
+
+/*!
+ \readonly
+ \qmlproperty enumeration QtQuick::PointerDevice::type
+
+ This property holds the type of the pointing device.
+
+ Valid values are:
+
+ \value DeviceType.UnknownDevice
+ the device cannot be identified
+ \value DeviceType.Mouse
+ a mouse
+ \value DeviceType.TouchScreen
+ a touchscreen providing absolute coordinates
+ \value DeviceType.TouchPad
+ a trackpad or touchpad providing relative coordinates
+ \value DeviceType.Stylus
+ a pen-like device
+ \value DeviceType.Airbrush
+ a stylus with a thumbwheel to adjust
+ \l {QTabletEvent::tangentialPressure}{tangentialPressure}
+ \value DeviceType.Puck
+ a device that is similar to a flat mouse with a
+ transparent circle with cross-hairs (same as \l QTabletEvent::Puck)
+
+ \sa QTouchDevice::DeviceType
+*/
+
+/*!
+ \readonly
+ \qmlproperty enumeration QtQuick::PointerDevice::capabilities
+
+ This property holds a bitwise combination of the capabilities of the
+ pointing device. It tells you under which conditions events are sent,
+ and which properties of PointerEvent are expected to be valid.
+
+ Valid values are:
+
+ \value CapabilityFlag.Position
+ the \l {QtQuick::EventPoint::position}{position} and
+ \l {QtQuick::EventPoint::scenePosition}{scenePosition} properties
+ \value CapabilityFlag.Area
+ the \l {QtQuick::EventTouchPoint::ellipseDiameters}{ellipseDiameters} property
+ \value CapabilityFlag.Pressure
+ the \l {QtQuick::EventTouchPoint::pressure}{pressure} property
+ \value CapabilityFlag.Velocity
+ the \l {QtQuick::PointerEvent::velocity}{velocity} property
+ \value CapabilityFlag.Scroll
+ a \l {QtQuick::PointerDevice::DeviceType::Mouse}{Mouse} has a wheel, or the
+ operating system recognizes scroll gestures on a
+ \l {QtQuick::PointerDevice::DeviceType::TouchPad}{TouchPad}
+ \value CapabilityFlag.Hover
+ events are sent even when no button is pressed, or the finger or stylus
+ is not in contact with the surface
+ \value CapabilityFlag.Rotation
+ the \l {QtQuick::EventTouchPoint::rotation}{rotation} property
+ \value CapabilityFlag.XTilt
+ horizontal angle between a stylus and the axis perpendicular to the surface
+ \value CapabilityFlag.YTilt
+ vertical angle between a stylus and the axis perpendicular to the surface
+
+ \sa QTouchDevice::capabilities
+*/
+
+typedef QHash<const QTouchDevice *, QQuickPointerDevice *> PointerDeviceForTouchDeviceHash;
Q_GLOBAL_STATIC(PointerDeviceForTouchDeviceHash, g_touchDevices)
-Q_GLOBAL_STATIC_WITH_ARGS(QQuickPointerDevice, g_genericMouseDevice,
+struct ConstructableQQuickPointerDevice : public QQuickPointerDevice
+{
+ ConstructableQQuickPointerDevice(DeviceType devType, PointerType pType, Capabilities caps,
+ int maxPoints, int buttonCount, const QString &name,
+ qint64 uniqueId = 0)
+ : QQuickPointerDevice(devType, pType, caps, maxPoints, buttonCount, name, uniqueId) {}
+
+};
+Q_GLOBAL_STATIC_WITH_ARGS(ConstructableQQuickPointerDevice, g_genericMouseDevice,
(QQuickPointerDevice::Mouse,
QQuickPointerDevice::GenericPointer,
QQuickPointerDevice::Position | QQuickPointerDevice::Scroll | QQuickPointerDevice::Hover,
@@ -457,7 +558,23 @@ Q_GLOBAL_STATIC_WITH_ARGS(QQuickPointerDevice, g_genericMouseDevice,
typedef QHash<qint64, QQuickPointerDevice *> PointerDeviceForDeviceIdHash;
Q_GLOBAL_STATIC(PointerDeviceForDeviceIdHash, g_tabletDevices)
-QQuickPointerDevice *QQuickPointerDevice::touchDevice(QTouchDevice *d)
+// debugging helpers
+static const char *pointStateString(const QQuickEventPoint *point)
+{
+ static const QMetaEnum stateMetaEnum = point->metaObject()->enumerator(point->metaObject()->indexOfEnumerator("State"));
+ return stateMetaEnum.valueToKey(point->state());
+}
+
+static const QString pointDeviceName(const QQuickEventPoint *point)
+{
+ auto device = static_cast<const QQuickPointerEvent *>(point->parent())->device();
+ QString deviceName = (device ? device->name() : QLatin1String("null device"));
+ deviceName.resize(16, ' '); // shorten, and align in case of sequential output
+ return deviceName;
+}
+
+
+QQuickPointerDevice *QQuickPointerDevice::touchDevice(const QTouchDevice *d)
{
if (g_touchDevices->contains(d))
return g_touchDevices->value(d);
@@ -505,37 +622,358 @@ QQuickPointerDevice *QQuickPointerDevice::tabletDevice(qint64 id)
return nullptr;
}
-void QQuickEventPoint::reset(Qt::TouchPointState state, QPointF scenePos, quint64 pointId, ulong timestamp)
+/*!
+ \qmltype EventPoint
+ \qmlabstract
+ \instantiates QQuickEventPoint
+ \inqmlmodule QtQuick
+ \ingroup qtquick-input-events
+ \brief Provides information about an individual point within a PointerEvent
+
+ A PointerEvent contains an EventPoint for each point of contact: one corresponding
+ to the mouse cursor, or one for each finger touching a touchscreen.
+
+ \sa PointerEvent, PointerHandler
+*/
+
+/*!
+ \readonly
+ \qmlproperty point QtQuick::EventPoint::position
+
+ This property holds the coordinates of the position supplied by the event,
+ relative to the upper-left corner of the Item which has the PointerHandler.
+ If a contact patch is available from the pointing device, this point
+ represents its centroid.
+*/
+
+/*!
+ \readonly
+ \qmlproperty point QtQuick::EventPoint::scenePosition
+
+ This property holds the coordinates of the position supplied by the event,
+ relative to the scene. If a contact patch is available from the \l device,
+ this point represents its centroid.
+*/
+
+/*!
+ \readonly
+ \qmlproperty point QtQuick::EventPoint::scenePressPosition
+
+ This property holds the scene-relative position at which the press event
+ (on a touch device) or most recent change in QQuickPointerEvent::buttons()
+ (on a mouse or tablet stylus) occurred.
+*/
+
+/*!
+ \readonly
+ \qmlproperty point QtQuick::EventPoint::sceneGrabPosition
+
+ This property holds the scene-relative position at which the EventPoint was
+ located when setGrabber() was called most recently.
+*/
+
+/*!
+ \readonly
+ \qmlproperty vector2d QtQuick::EventPoint::velocity
+
+ This property holds average recent velocity: how fast and in which
+ direction the event point has been moving recently.
+*/
+
+/*!
+ \readonly
+ \qmlproperty int QtQuick::EventPoint::state
+
+ This property tells what the user is currently doing at this point.
+
+ It can be one of:
+ \value Pressed
+ The user's finger is now pressing a touchscreen, button or stylus
+ which was not pressed already
+ \value Updated
+ The touchpoint or position is being moved, with no change in pressed state
+ \value Stationary
+ The touchpoint or position is not being moved, and there is also
+ no change in pressed state
+ \value Released
+ The user's finger has now released a touch point, button or stylus
+ which was pressed
+*/
+
+/*!
+ \readonly
+ \qmlproperty int QtQuick::EventPoint::pointId
+
+ This property holds the ID of the event, if any.
+
+ Touchpoints have automatically-incrementing IDs: each time the user
+ presses a finger against the touchscreen, it will be a larger number.
+ In other cases, it will be -1.
+
+ \sa PointerDevice.uniqueId
+*/
+
+/*!
+ \readonly
+ \qmlproperty bool QtQuick::EventPoint::accepted
+
+ Setting \a accepted to true prevents the event from being propagated to
+ Items below the PointerHandler's Item.
+
+ Generally, if the handler acts on the mouse event, then it should be
+ accepted so that items lower in the stacking order do not also respond to
+ the same event.
+*/
+
+/*!
+ \readonly
+ \qmlproperty real QtQuick::EventPoint::timeHeld
+
+ This property holds the amount of time in seconds that the button or touchpoint has
+ been held. It can be used to detect a "long press", and can drive an
+ animation to show progress toward activation of the "long press" action.
+*/
+
+void QQuickEventPoint::reset(Qt::TouchPointState state, const QPointF &scenePos, int pointId, ulong timestamp, const QVector2D &velocity)
{
m_scenePos = scenePos;
m_pointId = pointId;
- m_valid = true;
m_accept = false;
m_state = static_cast<QQuickEventPoint::State>(state);
m_timestamp = timestamp;
- if (state == Qt::TouchPointPressed)
+ if (state == Qt::TouchPointPressed) {
m_pressTimestamp = timestamp;
- // TODO calculate velocity
+ m_scenePressPos = scenePos;
+ }
+ m_velocity = (Q_LIKELY(velocity.isNull()) ? estimatedVelocity() : velocity);
+}
+
+void QQuickEventPoint::localizePosition(QQuickItem *target)
+{
+ if (target)
+ m_pos = target->mapFromScene(scenePosition());
+ else
+ m_pos = QPointF();
+}
+
+/*!
+ If this point has an exclusive grabber, returns a pointer to it; else
+ returns null, if there is no grabber. The grabber could be either
+ an Item or a PointerHandler.
+*/
+QObject *QQuickEventPoint::exclusiveGrabber() const
+{
+ return m_exclusiveGrabber.data();
+}
+
+/*!
+ Set the given Item or PointerHandler as the exclusive grabber of this point.
+ If there was already an exclusive grab, it will be canceled. If there
+ were passive grabbers, they will continue to lurk, but the exclusive grab
+ is a behavioral override of the passive grab as long as it remains.
+ If you already know whether the grabber is to be an Item or a PointerHandler,
+ you should instead call setGrabberItem() or setGrabberPointerHandler(),
+ because it is slightly more efficient.
+*/
+void QQuickEventPoint::setExclusiveGrabber(QObject *grabber)
+{
+ if (QQuickPointerHandler *phGrabber = qmlobject_cast<QQuickPointerHandler *>(grabber))
+ setGrabberPointerHandler(phGrabber, true);
+ else
+ setGrabberItem(static_cast<QQuickItem *>(grabber));
+}
+
+/*!
+ If the exclusive grabber of this point is an Item, returns a
+ pointer to that Item; else returns null, if there is no grabber or if
+ the grabber is a PointerHandler.
+*/
+QQuickItem *QQuickEventPoint::grabberItem() const
+{
+ return (m_grabberIsHandler ? nullptr : static_cast<QQuickItem *>(m_exclusiveGrabber.data()));
+}
+
+/*!
+ Set the given Item \a grabber as the exclusive grabber of this point.
+ If there was already an exclusive grab, it will be canceled. If there
+ were passive grabbers, they will continue to lurk, but the exclusive grab
+ is a behavioral override of the passive grab as long as it remains.
+*/
+void QQuickEventPoint::setGrabberItem(QQuickItem *grabber)
+{
+ if (grabber != m_exclusiveGrabber.data()) {
+ QQuickPointerHandler *oldGrabberHandler = grabberPointerHandler();
+ if (oldGrabberHandler && !oldGrabberHandler->approveGrabTransition(this, grabber))
+ return;
+ if (Q_UNLIKELY(lcPointerGrab().isDebugEnabled())) {
+ qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << hex << m_pointId << pointStateString(this)
+ << ": grab" << m_exclusiveGrabber << "->" << grabber;
+ }
+ m_exclusiveGrabber = QPointer<QObject>(grabber);
+ m_grabberIsHandler = false;
+ m_sceneGrabPos = m_scenePos;
+ QQuickItem *oldGrabberItem = grabberItem();
+ if (oldGrabberHandler)
+ oldGrabberHandler->onGrabChanged(oldGrabberHandler, (grabber ? CancelGrabExclusive : UngrabExclusive), this);
+ else if (oldGrabberItem && oldGrabberItem != grabber && grabber && pointerEvent()->asPointerTouchEvent())
+ oldGrabberItem->touchUngrabEvent();
+ for (QPointer<QQuickPointerHandler> passiveGrabber : m_passiveGrabbers)
+ passiveGrabber->onGrabChanged(passiveGrabber, OverrideGrabPassive, this);
+ }
+}
+
+/*!
+ If the exclusive grabber of this point is a PointerHandler, returns a
+ pointer to that handler; else returns null, if there is no grabber or if
+ the grabber is an Item.
+*/
+QQuickPointerHandler *QQuickEventPoint::grabberPointerHandler() const
+{
+ return (m_grabberIsHandler ? static_cast<QQuickPointerHandler *>(m_exclusiveGrabber.data()) : nullptr);
+}
+
+/*!
+ Set the given PointerHandler \a grabber as grabber of this point. If \a
+ exclusive is true, it will override any other grabs; if false, \a grabber
+ will be added to the list of passive grabbers of this point.
+*/
+void QQuickEventPoint::setGrabberPointerHandler(QQuickPointerHandler *grabber, bool exclusive)
+{
+ if (Q_UNLIKELY(lcPointerGrab().isDebugEnabled())) {
+ if (exclusive) {
+ if (m_exclusiveGrabber != grabber)
+ qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << hex << m_pointId << pointStateString(this)
+ << ": grab (exclusive)" << m_exclusiveGrabber << "->" << grabber;
+ } else {
+ qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << hex << m_pointId << pointStateString(this)
+ << ": grab (passive)" << grabber;
+ }
+ }
+ if (exclusive) {
+ if (grabber != m_exclusiveGrabber.data()) {
+ QQuickPointerHandler *oldGrabberHandler = grabberPointerHandler();
+ QQuickItem *oldGrabberItem = grabberItem();
+ m_exclusiveGrabber = QPointer<QObject>(grabber);
+ m_grabberIsHandler = true;
+ m_sceneGrabPos = m_scenePos;
+ if (grabber) {
+ grabber->onGrabChanged(grabber, GrabExclusive, this);
+ for (QPointer<QQuickPointerHandler> passiveGrabber : m_passiveGrabbers) {
+ if (passiveGrabber != grabber)
+ passiveGrabber->onGrabChanged(grabber, OverrideGrabPassive, this);
+ }
+ }
+ if (oldGrabberHandler)
+ oldGrabberHandler->onGrabChanged(oldGrabberHandler, (grabber ? CancelGrabExclusive : UngrabExclusive), this);
+ else if (oldGrabberItem && pointerEvent()->asPointerTouchEvent())
+ oldGrabberItem->touchUngrabEvent();
+ // touchUngrabEvent() can result in the grabber being set to null (MPTA does that, for example).
+ // So set it again to ensure that final state is what we want.
+ m_exclusiveGrabber = QPointer<QObject>(grabber);
+ m_grabberIsHandler = true;
+ m_sceneGrabPos = m_scenePos;
+ }
+ } else {
+ if (!grabber) {
+ qDebug() << "can't set passive grabber to null";
+ return;
+ }
+ auto ptr = QPointer<QQuickPointerHandler>(grabber);
+ if (!m_passiveGrabbers.contains(ptr)) {
+ m_passiveGrabbers.append(ptr);
+ grabber->onGrabChanged(grabber, GrabPassive, this);
+ }
+ }
+}
+
+/*!
+ If this point has an existing exclusive grabber (Item or PointerHandler),
+ inform the grabber that its grab is canceled, and remove it as grabber.
+ This normally happens when the grab is stolen by another Item.
+*/
+void QQuickEventPoint::cancelExclusiveGrab()
+{
+ if (m_exclusiveGrabber.isNull())
+ qWarning("cancelGrab: no grabber");
+ else
+ cancelExclusiveGrabImpl();
+}
+
+void QQuickEventPoint::cancelExclusiveGrabImpl(QTouchEvent *cancelEvent)
+{
+ if (m_exclusiveGrabber.isNull())
+ return;
+ if (Q_UNLIKELY(lcPointerGrab().isDebugEnabled())) {
+ qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << hex << m_pointId << pointStateString(this)
+ << ": grab (exclusive)" << m_exclusiveGrabber << "-> nullptr";
+ }
+ if (auto handler = grabberPointerHandler()) {
+ handler->onGrabChanged(handler, CancelGrabExclusive, this);
+ } else if (auto item = grabberItem()) {
+ if (cancelEvent)
+ QCoreApplication::sendEvent(item, cancelEvent);
+ else
+ item->touchUngrabEvent();
+ }
+ m_exclusiveGrabber.clear();
}
-QQuickItem *QQuickEventPoint::grabber() const
+/*!
+ If this point has the given \a handler as a passive grabber,
+ inform the grabber that its grab is canceled, and remove it as grabber.
+ This normally happens when another Item or PointerHandler does an exclusive grab.
+*/
+void QQuickEventPoint::cancelPassiveGrab(QQuickPointerHandler *handler)
+{
+ if (removePassiveGrabber(handler)) {
+ if (Q_UNLIKELY(lcPointerGrab().isDebugEnabled())) {
+ qCDebug(lcPointerGrab) << pointDeviceName(this) << "point" << hex << m_pointId << pointStateString(this)
+ << ": grab (passive)" << handler << "removed";
+ }
+ handler->onGrabChanged(handler, CancelGrabPassive, this);
+ }
+}
+
+/*!
+ If this point has the given \a handler as a passive grabber, remove it as grabber.
+ Returns true if it was removed, false if it wasn't a grabber.
+*/
+bool QQuickEventPoint::removePassiveGrabber(QQuickPointerHandler *handler)
{
- return m_grabber.data();
+ return m_passiveGrabbers.removeOne(handler);
}
-void QQuickEventPoint::setGrabber(QQuickItem *grabber)
+/*!
+ If the given \a handler is grabbing this point passively, exclusively
+ or both, cancel the grab and remove it as grabber.
+ This normally happens when the handler decides that the behavior of this
+ point can no longer satisfy the handler's behavioral constraints within
+ the remainder of the gesture which the user is performing: for example
+ the handler tries to detect a tap but a drag is occurring instead, or
+ it tries to detect a drag in one direction but the drag is going in
+ another direction. In such cases the handler no longer needs or wants
+ to be informed of any further movements of this point.
+*/
+void QQuickEventPoint::cancelAllGrabs(QQuickPointerHandler *handler)
{
- if (Q_UNLIKELY(lcPointerGrab().isDebugEnabled()) && m_grabber.data() != grabber) {
- auto device = static_cast<const QQuickPointerEvent *>(parent())->device();
- static const QMetaEnum stateMetaEnum = metaObject()->enumerator(metaObject()->indexOfEnumerator("State"));
- QString deviceName = (device ? device->name() : QLatin1String("null device"));
- deviceName.resize(16, ' '); // shorten, and align in case of sequential output
- qCDebug(lcPointerGrab) << deviceName << "point" << hex << m_pointId << stateMetaEnum.valueToKey(state())
- << ": grab" << m_grabber << "->" << grabber;
+ if (m_exclusiveGrabber == handler) {
+ handler->onGrabChanged(handler, CancelGrabExclusive, this);
+ m_exclusiveGrabber.clear();
}
- m_grabber = QPointer<QQuickItem>(grabber);
+ cancelPassiveGrab(handler);
}
+/*!
+ Sets this point as \a accepted (true) or rejected (false).
+
+ During delivery of the current event to the Items in the scene, each Item
+ or Pointer Handler should accept the points for which it is taking
+ responsibility. As soon as all points within the event are accepted, event
+ propagation stops. However accepting the point does not imply any kind of
+ grab, passive or exclusive.
+
+ \sa setExclusiveGrabber, QQuickPointerHandler::setPassiveGrab, QQuickPointerHandler::setExclusiveGrab
+*/
void QQuickEventPoint::setAccepted(bool accepted)
{
if (m_accept != accepted) {
@@ -544,18 +982,175 @@ void QQuickEventPoint::setAccepted(bool accepted)
}
}
+
+/*!
+ \qmltype EventTouchPoint
+ \qmlabstract
+ \instantiates QQuickEventTouchPoint
+ \inqmlmodule QtQuick
+ \ingroup qtquick-input-events
+ \brief Provides information about an individual touch point within a PointerEvent
+
+ \sa PointerEvent, PointerHandler
+*/
+
+/*!
+ \readonly
+ \qmlproperty QPointerUniqueId QtQuick::EventTouchPoint::uniqueId
+
+ This property holds the unique ID of the fiducial or stylus in use, if any.
+
+ On touchscreens that can track physical objects (such as knobs or game
+ pieces) in addition to fingers, each object usually has a unique ID.
+ Likewise, each stylus that can be used with a graphics tablet usually has a
+ unique serial number. Qt so far only supports numeric IDs. You can get the
+ actual number as uniqueId.numeric, but that is a device-specific detail.
+ In the future, there may be support for non-numeric IDs, so you should
+ not assume that the number is meaningful.
+
+ If you need to identify specific objects, your application should provide
+ UI for registering objects and mapping them to functionality: allow the
+ user to select a meaning, virtual tool, or action, prompt the user to bring
+ the object into proximity, and store a mapping from uniqueId to its
+ purpose, for example in \l Settings.
+*/
+
+/*!
+ \readonly
+ \qmlproperty qreal QtQuick::EventTouchPoint::rotation
+
+ This property holds the rotation angle of the stylus on a graphics tablet
+ or the contact patch of a touchpoint on a touchscreen.
+
+ It is valid only with certain tablet stylus devices and touchscreens that
+ can measure the rotation angle. Otherwise, it will be zero.
+*/
+
+/*!
+ \readonly
+ \qmlproperty qreal QtQuick::EventTouchPoint::pressure
+
+ This property tells how hard the user is pressing the stylus on a graphics
+ tablet or the finger against a touchscreen, in the range from \c 0 (no
+ measurable pressure) to \c 1.0 (maximum pressure which the device can
+ measure).
+
+ It is valid only with certain tablets and touchscreens that can measure
+ pressure. Otherwise, it will be \c 1.0 when pressed.
+*/
+
+/*!
+ \readonly
+ \qmlproperty size QtQuick::EventTouchPoint::ellipseDiameters
+
+ This property holds the diameters of the contact patch, if the event
+ comes from a touchpoint and the \l device provides this information.
+
+ A touchpoint is modeled as an elliptical area where the finger is pressed
+ against the touchscreen. (In fact, it could also be modeled as a bitmap; but
+ in that case we expect an elliptical bounding estimate to be fitted to the
+ contact patch before the event is sent.) The harder the user presses, the
+ larger the contact patch; so, these diameters provide an alternate way of
+ detecting pressure, in case the device does not include a separate pressure
+ sensor. The ellipse is centered on \l scenePos (\l pos in the PointerHandler's
+ Item's local coordinates). The \l rotation property provides the
+ rotation of the ellipse, if known. It is expected that if the \l rotation
+ is zero, the verticalDiameter of the ellipse is the larger one (the major axis),
+ because of the usual hand position, reaching upward or outward across the surface.
+
+ If the contact patch is unknown, or the \l device is not a touchscreen,
+ these values will be zero.
+*/
+
QQuickEventTouchPoint::QQuickEventTouchPoint(QQuickPointerTouchEvent *parent)
: QQuickEventPoint(parent), m_rotation(0), m_pressure(0)
{}
void QQuickEventTouchPoint::reset(const QTouchEvent::TouchPoint &tp, ulong timestamp)
{
- QQuickEventPoint::reset(tp.state(), tp.scenePos(), tp.id(), timestamp);
+ QQuickEventPoint::reset(tp.state(), tp.scenePos(), tp.id(), timestamp, tp.velocity());
+ m_exclusiveGrabber.clear();
+ m_passiveGrabbers.clear();
m_rotation = tp.rotation();
m_pressure = tp.pressure();
+ m_ellipseDiameters = tp.ellipseDiameters();
m_uniqueId = tp.uniqueId();
}
+struct PointVelocityData {
+ QVector2D velocity;
+ QPointF pos;
+ ulong timestamp;
+};
+
+typedef QMap<quint64, PointVelocityData*> PointDataForPointIdMap;
+Q_GLOBAL_STATIC(PointDataForPointIdMap, g_previousPointData)
+static const int PointVelocityAgeLimit = 500; // milliseconds
+
+/*!
+ \internal
+ Estimates the velocity based on a weighted average of all previous velocities.
+ The older the velocity is, the less significant it becomes for the estimate.
+*/
+QVector2D QQuickEventPoint::estimatedVelocity() const
+{
+ PointVelocityData *prevPoint = g_previousPointData->value(m_pointId);
+ if (!prevPoint) {
+ // cleanup events older than PointVelocityAgeLimit
+ auto end = g_previousPointData->end();
+ for (auto it = g_previousPointData->begin(); it != end; ) {
+ PointVelocityData *data = it.value();
+ if (m_timestamp - data->timestamp > PointVelocityAgeLimit) {
+ it = g_previousPointData->erase(it);
+ delete data;
+ } else {
+ ++it;
+ }
+ }
+ // TODO optimize: stop this dynamic memory thrashing
+ prevPoint = new PointVelocityData;
+ prevPoint->velocity = QVector2D();
+ prevPoint->timestamp = 0;
+ prevPoint->pos = QPointF();
+ g_previousPointData->insert(m_pointId, prevPoint);
+ }
+ const ulong timeElapsed = m_timestamp - prevPoint->timestamp;
+ if (timeElapsed == 0) // in case we call estimatedVelocity() twice on the same QQuickEventPoint
+ return m_velocity;
+
+ QVector2D newVelocity;
+ if (prevPoint->timestamp != 0)
+ newVelocity = QVector2D(m_scenePos - prevPoint->pos)/timeElapsed;
+
+ // VERY simple kalman filter: does a weighted average
+ // where the older velocities get less and less significant
+ static const float KalmanGain = 0.7f;
+ QVector2D filteredVelocity = newVelocity * KalmanGain + m_velocity * (1.0f - KalmanGain);
+
+ prevPoint->velocity = filteredVelocity;
+ prevPoint->pos = m_scenePos;
+ prevPoint->timestamp = m_timestamp;
+ return filteredVelocity;
+}
+
+/*!
+ \qmltype PointerEvent
+ \instantiates QQuickPointerEvent
+ \inqmlmodule QtQuick
+ \ingroup qtquick-input-events
+
+ \brief Provides information about an event from a pointing device
+
+ A PointerEvent is an event describing contact or movement across a surface,
+ provided by a mouse, a touchpoint (single finger on a touchscreen), or a
+ stylus on a graphics tablet. The \l device property provides more
+ information about where the event came from.
+
+ \sa PointerHandler
+
+ \image touchpoint-metrics.png
+*/
+
/*!
\internal
\class QQuickPointerEvent
@@ -570,6 +1165,68 @@ void QQuickEventTouchPoint::reset(const QTouchEvent::TouchPoint &tp, ulong times
dynamically create and destroy objects of this type for each event.
*/
+/*!
+ \readonly
+ \qmlproperty enumeration QtQuick::PointerEvent::button
+
+ This property holds the \l {Qt::MouseButton}{button} that caused the event,
+ if any. If the \l device does not have buttons, or the event is a hover
+ event, it will be \c Qt.NoButton.
+*/
+
+/*!
+ \readonly
+ \qmlproperty int QtQuick::PointerEvent::buttons
+
+ This property holds the combination of mouse or stylus
+ \l {Qt::MouseButton}{buttons} pressed when the event was generated. For move
+ events, this is all buttons that are pressed down. For press events, this
+ includes the button that caused the event, as well as any others that were
+ already held. For release events, this excludes the button that caused the
+ event.
+*/
+
+/*!
+ \readonly
+ \qmlproperty int QtQuick::PointerEvent::modifiers
+
+ This property holds the \l {Qt::KeyboardModifier}{keyboard modifier} flags
+ that existed immediately before the event occurred.
+
+ It contains a bitwise combination of the following flags:
+ \value Qt.NoModifier
+ No modifier key is pressed.
+ \value Qt.ShiftModifier
+ A Shift key on the keyboard is pressed.
+ \value Qt.ControlModifier
+ A Ctrl key on the keyboard is pressed.
+ \value Qt.AltModifier
+ An Alt key on the keyboard is pressed.
+ \value Qt.MetaModifier
+ A Meta key on the keyboard is pressed.
+ \value Qt.KeypadModifier
+ A keypad button is pressed.
+
+ For example, to react to a Shift key + Left mouse button click:
+ \qml
+ Item {
+ TapHandler {
+ onTapped: {
+ if ((event.button == Qt.LeftButton) && (event.modifiers & Qt.ShiftModifier))
+ doSomething();
+ }
+ }
+ }
+ \endqml
+*/
+
+/*!
+ \readonly
+ \qmlproperty PointerDevice QtQuick::PointerEvent::device
+
+ This property holds the device that generated the event.
+*/
+
QQuickPointerEvent::~QQuickPointerEvent()
{}
@@ -581,11 +1238,14 @@ QQuickPointerEvent *QQuickPointerMouseEvent::reset(QEvent *event)
return this;
m_device = QQuickPointerDevice::genericMouseDevice();
+ m_device->eventDeliveryTargets().clear();
m_button = ev->button();
m_pressedButtons = ev->buttons();
Qt::TouchPointState state = Qt::TouchPointStationary;
switch (ev->type()) {
case QEvent::MouseButtonPress:
+ m_mousePoint->clearPassiveGrabbers();
+ Q_FALLTHROUGH();
case QEvent::MouseButtonDblClick:
state = Qt::TouchPointPressed;
break;
@@ -598,10 +1258,15 @@ QQuickPointerEvent *QQuickPointerMouseEvent::reset(QEvent *event)
default:
break;
}
- m_mousePoint->reset(state, ev->windowPos(), 0, ev->timestamp()); // mouse is 0
+ m_mousePoint->reset(state, ev->windowPos(), quint64(1) << 24, ev->timestamp()); // mouse has device ID 1
return this;
}
+void QQuickPointerMouseEvent::localize(QQuickItem *target)
+{
+ m_mousePoint->localizePosition(target);
+}
+
QQuickPointerEvent *QQuickPointerTouchEvent::reset(QEvent *event)
{
auto ev = static_cast<QTouchEvent*>(event);
@@ -610,6 +1275,7 @@ QQuickPointerEvent *QQuickPointerTouchEvent::reset(QEvent *event)
return this;
m_device = QQuickPointerDevice::touchDevice(ev->device());
+ m_device->eventDeliveryTargets().clear();
m_button = Qt::NoButton;
m_pressedButtons = Qt::NoButton;
@@ -620,32 +1286,93 @@ QQuickPointerEvent *QQuickPointerTouchEvent::reset(QEvent *event)
for (int i = m_touchPoints.size(); i < newPointCount; ++i)
m_touchPoints.insert(i, new QQuickEventTouchPoint(this));
- // Make sure the grabbers are right from one event to the next
- QVector<QQuickItem*> grabbers;
- // Copy all grabbers, because the order of points might have changed in the event.
+ // Make sure the grabbers and on-pressed values are right from one event to the next
+ struct ToPreserve {
+ int pointId; // just for double-checking
+ ulong pressTimestamp;
+ QPointF scenePressPos;
+ QPointF sceneGrabPos;
+ QObject * grabber;
+ QVector <QPointer <QQuickPointerHandler> > passiveGrabbers;
+
+ ToPreserve() : pointId(0), pressTimestamp(0), grabber(nullptr) {}
+ };
+ QVector<ToPreserve> preserves(newPointCount); // jar of pickled touchpoints, in order of points in the _new_ event
+
+ // Copy stuff we need to preserve, because the order of points might have changed in the event.
// The ID is all that we can rely on (release might remove the first point etc).
for (int i = 0; i < newPointCount; ++i) {
- QQuickItem *grabber = nullptr;
- if (auto point = pointById(tps.at(i).id()))
- grabber = point->grabber();
- grabbers.append(grabber);
+ int pid = tps.at(i).id();
+ if (auto point = pointById(pid)) {
+ preserves[i].pointId = pid;
+ preserves[i].pressTimestamp = point->m_pressTimestamp;
+ preserves[i].scenePressPos = point->scenePressPosition();
+ preserves[i].sceneGrabPos = point->sceneGrabPosition();
+ preserves[i].grabber = point->exclusiveGrabber();
+ preserves[i].passiveGrabbers = point->passiveGrabbers();
+ }
}
for (int i = 0; i < newPointCount; ++i) {
auto point = m_touchPoints.at(i);
point->reset(tps.at(i), ev->timestamp());
+ const auto &preserved = preserves.at(i);
if (point->state() == QQuickEventPoint::Pressed) {
- if (grabbers.at(i))
+ if (preserved.grabber)
qWarning() << "TouchPointPressed without previous release event" << point;
- point->setGrabber(nullptr);
+ point->setGrabberItem(nullptr);
+ point->clearPassiveGrabbers();
} else {
- point->setGrabber(grabbers.at(i));
+ // Restore the grabbers without notifying (don't call onGrabChanged)
+ Q_ASSERT(preserved.pointId == 0 || preserved.pointId == point->pointId());
+ point->m_pressTimestamp = preserved.pressTimestamp;
+ point->m_scenePressPos = preserved.scenePressPos;
+ point->m_sceneGrabPos = preserved.sceneGrabPos;
+ point->m_exclusiveGrabber = preserved.grabber;
+ point->m_grabberIsHandler = (qmlobject_cast<QQuickPointerHandler *>(point->m_exclusiveGrabber) != nullptr);
+ point->m_passiveGrabbers = preserved.passiveGrabbers;
}
}
m_pointCount = newPointCount;
return this;
}
+void QQuickPointerTouchEvent::localize(QQuickItem *target)
+{
+ for (auto point : qAsConst(m_touchPoints))
+ point->localizePosition(target);
+}
+
+QQuickPointerEvent *QQuickPointerNativeGestureEvent::reset(QEvent *event)
+{
+ auto ev = static_cast<QNativeGestureEvent*>(event);
+ m_event = ev;
+ if (!event)
+ return this;
+
+ m_device = QQuickPointerDevice::touchDevice(ev->device());
+ m_device->eventDeliveryTargets().clear();
+ Qt::TouchPointState state = Qt::TouchPointMoved;
+ switch (type()) {
+ case Qt::BeginNativeGesture:
+ state = Qt::TouchPointPressed;
+ break;
+ case Qt::EndNativeGesture:
+ state = Qt::TouchPointReleased;
+ break;
+ default:
+ break;
+ }
+ quint64 deviceId = QTouchDevicePrivate::get(const_cast<QTouchDevice *>(ev->device()))->id; // a bit roundabout since QTouchDevice::mTouchDeviceId is protected
+ m_gesturePoint->reset(state, ev->windowPos(), deviceId << 24, ev->timestamp());
+ return this;
+}
+
+void QQuickPointerNativeGestureEvent::localize(QQuickItem *target)
+{
+ m_gesturePoint->localizePosition(target);
+}
+
QQuickEventPoint *QQuickPointerMouseEvent::point(int i) const {
if (i == 0)
return m_mousePoint;
@@ -658,9 +1385,15 @@ QQuickEventPoint *QQuickPointerTouchEvent::point(int i) const {
return nullptr;
}
+QQuickEventPoint *QQuickPointerNativeGestureEvent::point(int i) const {
+ if (i == 0)
+ return m_gesturePoint;
+ return nullptr;
+}
+
QQuickEventPoint::QQuickEventPoint(QQuickPointerEvent *parent)
- : QObject(parent), m_pointId(0), m_grabber(nullptr), m_timestamp(0), m_pressTimestamp(0),
- m_state(QQuickEventPoint::Released), m_valid(false), m_accept(false)
+ : QObject(parent), m_pointId(0), m_exclusiveGrabber(nullptr), m_timestamp(0), m_pressTimestamp(0),
+ m_state(QQuickEventPoint::Released), m_accept(false), m_grabberIsHandler(false)
{
Q_UNUSED(m_reserved);
}
@@ -674,6 +1407,15 @@ bool QQuickPointerMouseEvent::allPointsAccepted() const {
return m_mousePoint->isAccepted();
}
+bool QQuickPointerMouseEvent::allUpdatedPointsAccepted() const {
+ return m_mousePoint->state() == QQuickEventPoint::Pressed || m_mousePoint->isAccepted();
+}
+
+bool QQuickPointerMouseEvent::allPointsGrabbed() const
+{
+ return m_mousePoint->exclusiveGrabber() != nullptr;
+}
+
QMouseEvent *QQuickPointerMouseEvent::asMouseEvent(const QPointF &localPos) const
{
auto event = static_cast<QMouseEvent *>(m_event);
@@ -681,16 +1423,31 @@ QMouseEvent *QQuickPointerMouseEvent::asMouseEvent(const QPointF &localPos) cons
return event;
}
-QVector<QQuickItem *> QQuickPointerMouseEvent::grabbers() const
+/*!
+ Returns the exclusive grabber of this event, if any, in a vector.
+*/
+QVector<QObject *> QQuickPointerMouseEvent::exclusiveGrabbers() const
{
- QVector<QQuickItem *> result;
- if (QQuickItem *grabber = m_mousePoint->grabber())
+ QVector<QObject *> result;
+ if (QObject *grabber = m_mousePoint->exclusiveGrabber())
result << grabber;
return result;
}
+/*!
+ Remove all passive and exclusive grabbers of this event, without notifying.
+*/
void QQuickPointerMouseEvent::clearGrabbers() const {
- m_mousePoint->setGrabber(nullptr);
+ m_mousePoint->setGrabberItem(nullptr);
+ m_mousePoint->clearPassiveGrabbers();
+}
+
+/*!
+ Returns whether the given \a handler is the exclusive grabber of this event.
+*/
+bool QQuickPointerMouseEvent::hasExclusiveGrabber(const QQuickPointerHandler *handler) const
+{
+ return m_mousePoint->exclusiveGrabber() == handler;
}
bool QQuickPointerMouseEvent::isPressEvent() const
@@ -700,6 +1457,24 @@ bool QQuickPointerMouseEvent::isPressEvent() const
(me->buttons() & me->button()) == me->buttons());
}
+bool QQuickPointerMouseEvent::isDoubleClickEvent() const
+{
+ auto me = static_cast<QMouseEvent*>(m_event);
+ return (me->type() == QEvent::MouseButtonDblClick);
+}
+
+bool QQuickPointerMouseEvent::isUpdateEvent() const
+{
+ auto me = static_cast<QMouseEvent*>(m_event);
+ return me->type() == QEvent::MouseMove;
+}
+
+bool QQuickPointerMouseEvent::isReleaseEvent() const
+{
+ auto me = static_cast<QMouseEvent*>(m_event);
+ return me && me->type() == QEvent::MouseButtonRelease;
+}
+
bool QQuickPointerTouchEvent::allPointsAccepted() const {
for (int i = 0; i < m_pointCount; ++i) {
if (!m_touchPoints.at(i)->isAccepted())
@@ -708,12 +1483,32 @@ bool QQuickPointerTouchEvent::allPointsAccepted() const {
return true;
}
-QVector<QQuickItem *> QQuickPointerTouchEvent::grabbers() const
-{
- QVector<QQuickItem *> result;
+bool QQuickPointerTouchEvent::allUpdatedPointsAccepted() const {
for (int i = 0; i < m_pointCount; ++i) {
auto point = m_touchPoints.at(i);
- if (QQuickItem *grabber = point->grabber()) {
+ if (point->state() != QQuickEventPoint::Pressed && !point->isAccepted())
+ return false;
+ }
+ return true;
+}
+
+bool QQuickPointerTouchEvent::allPointsGrabbed() const
+{
+ for (int i = 0; i < m_pointCount; ++i) {
+ if (!m_touchPoints.at(i)->exclusiveGrabber())
+ return false;
+ }
+ return true;
+}
+
+/*!
+ Returns the exclusive grabbers of all points in this event, if any, in a vector.
+*/
+QVector<QObject *> QQuickPointerTouchEvent::exclusiveGrabbers() const
+{
+ QVector<QObject *> result;
+ for (int i = 0; i < m_pointCount; ++i) {
+ if (QObject *grabber = m_touchPoints.at(i)->exclusiveGrabber()) {
if (!result.contains(grabber))
result << grabber;
}
@@ -721,9 +1516,27 @@ QVector<QQuickItem *> QQuickPointerTouchEvent::grabbers() const
return result;
}
+/*!
+ Remove all passive and exclusive grabbers of all touchpoints in this event,
+ without notifying.
+*/
void QQuickPointerTouchEvent::clearGrabbers() const {
+ for (auto point: m_touchPoints) {
+ point->setGrabberItem(nullptr);
+ point->clearPassiveGrabbers();
+ }
+}
+
+/*!
+ Returns whether the given \a handler is the exclusive grabber of any
+ touchpoint within this event.
+*/
+bool QQuickPointerTouchEvent::hasExclusiveGrabber(const QQuickPointerHandler *handler) const
+{
for (auto point: m_touchPoints)
- point->setGrabber(nullptr);
+ if (point->exclusiveGrabber() == handler)
+ return true;
+ return false;
}
bool QQuickPointerTouchEvent::isPressEvent() const
@@ -731,12 +1544,22 @@ bool QQuickPointerTouchEvent::isPressEvent() const
return static_cast<QTouchEvent*>(m_event)->touchPointStates() & Qt::TouchPointPressed;
}
+bool QQuickPointerTouchEvent::isUpdateEvent() const
+{
+ return static_cast<QTouchEvent*>(m_event)->touchPointStates() & (Qt::TouchPointMoved | Qt::TouchPointStationary);
+}
+
+bool QQuickPointerTouchEvent::isReleaseEvent() const
+{
+ return static_cast<QTouchEvent*>(m_event)->touchPointStates() & Qt::TouchPointReleased;
+}
+
QVector<QPointF> QQuickPointerEvent::unacceptedPressedPointScenePositions() const
{
QVector<QPointF> points;
for (int i = 0; i < pointCount(); ++i) {
if (!point(i)->isAccepted() && point(i)->state() == QQuickEventPoint::Pressed)
- points << point(i)->scenePos();
+ points << point(i)->scenePosition();
}
return points;
}
@@ -788,20 +1611,78 @@ QMouseEvent *QQuickPointerTouchEvent::syntheticMouseEvent(int pointID, QQuickIte
}
/*!
+ Returns the exclusive grabber of this event, if any, in a vector.
+*/
+QVector<QObject *> QQuickPointerNativeGestureEvent::exclusiveGrabbers() const
+{
+ QVector<QObject *> result;
+ if (QObject *grabber = m_gesturePoint->exclusiveGrabber())
+ result << grabber;
+ return result;
+}
+
+/*!
+ Remove all passive and exclusive grabbers of this event, without notifying.
+*/
+void QQuickPointerNativeGestureEvent::clearGrabbers() const {
+ m_gesturePoint->setGrabberItem(nullptr);
+ m_gesturePoint->clearPassiveGrabbers();
+}
+
+/*!
+ Returns whether the given \a handler is the exclusive grabber of this event.
+*/
+bool QQuickPointerNativeGestureEvent::hasExclusiveGrabber(const QQuickPointerHandler *handler) const
+{
+ return m_gesturePoint->exclusiveGrabber() == handler;
+}
+
+bool QQuickPointerNativeGestureEvent::isPressEvent() const
+{
+ return type() == Qt::BeginNativeGesture;
+}
+
+bool QQuickPointerNativeGestureEvent::isUpdateEvent() const
+{
+ switch (type()) {
+ case Qt::BeginNativeGesture:
+ case Qt::EndNativeGesture:
+ return false;
+ default:
+ return true;
+ }
+}
+
+bool QQuickPointerNativeGestureEvent::isReleaseEvent() const
+{
+ return type() == Qt::EndNativeGesture;
+}
+
+Qt::NativeGestureType QQuickPointerNativeGestureEvent::type() const
+{
+ return static_cast<QNativeGestureEvent *>(m_event)->gestureType();
+}
+
+qreal QQuickPointerNativeGestureEvent::value() const
+{
+ return static_cast<QNativeGestureEvent *>(m_event)->value();
+}
+
+/*!
\internal
Returns a pointer to the QQuickEventPoint which has the \a pointId as
\l {QQuickEventPoint::pointId}{pointId}.
Returns nullptr if there is no point with that ID.
- \fn QQuickPointerEvent::pointById(quint64 pointId) const
+ \fn QQuickPointerEvent::pointById(int pointId) const
*/
-QQuickEventPoint *QQuickPointerMouseEvent::pointById(quint64 pointId) const {
+QQuickEventPoint *QQuickPointerMouseEvent::pointById(int pointId) const {
if (m_mousePoint && pointId == m_mousePoint->pointId())
return m_mousePoint;
return nullptr;
}
-QQuickEventPoint *QQuickPointerTouchEvent::pointById(quint64 pointId) const {
+QQuickEventPoint *QQuickPointerTouchEvent::pointById(int pointId) const {
auto it = std::find_if(m_touchPoints.constBegin(), m_touchPoints.constEnd(),
[pointId](const QQuickEventTouchPoint *tp) { return tp->pointId() == pointId; } );
if (it != m_touchPoints.constEnd())
@@ -809,6 +1690,12 @@ QQuickEventPoint *QQuickPointerTouchEvent::pointById(quint64 pointId) const {
return nullptr;
}
+QQuickEventPoint *QQuickPointerNativeGestureEvent::pointById(int pointId) const {
+ if (m_gesturePoint && pointId == m_gesturePoint->pointId())
+ return m_gesturePoint;
+ return nullptr;
+}
+
/*!
\internal
@@ -831,7 +1718,12 @@ const QTouchEvent::TouchPoint *QQuickPointerTouchEvent::touchPointById(int point
\internal
Make a new QTouchEvent, giving it a subset of the original touch points.
- Returns a nullptr if all points are stationary or there are no points inside the item.
+ Returns a nullptr if all points are stationary, or there are no points inside the item,
+ or none of the points were pressed inside and the item was not grabbing any of them
+ and isFiltering is false. When isFiltering is true, it is assumed that the item
+ cares about all points which are inside its bounds, because most filtering items
+ need to monitor eventpoint movements until a drag threshold is exceeded or the
+ requirements for a gesture to be recognized are met in some other way.
*/
QTouchEvent *QQuickPointerTouchEvent::touchEventForItem(QQuickItem *item, bool isFiltering) const
{
@@ -841,19 +1733,24 @@ QTouchEvent *QQuickPointerTouchEvent::touchEventForItem(QQuickItem *item, bool i
// Or else just document that velocity is always scene-relative and is not scaled and rotated with the item
// but that would require changing tst_qquickwindow::touchEvent_velocity(): it expects transformed velocity
+ bool anyPressOrReleaseInside = false;
+ bool anyGrabber = false;
QMatrix4x4 transformMatrix(QQuickItemPrivate::get(item)->windowToItemTransform());
for (int i = 0; i < m_pointCount; ++i) {
auto p = m_touchPoints.at(i);
if (p->isAccepted())
continue;
// include points where item is the grabber
- bool isGrabber = p->grabber() == item;
- // include newly pressed points inside the bounds
- bool isPressInside = p->state() == QQuickEventPoint::Pressed && item->contains(item->mapFromScene(p->scenePos()));
+ bool isGrabber = p->exclusiveGrabber() == item;
+ if (isGrabber)
+ anyGrabber = true;
+ // include points inside the bounds if no other item is the grabber or if the item is filtering
+ bool isInside = item->contains(item->mapFromScene(p->scenePosition()));
+ bool hasAnotherGrabber = p->exclusiveGrabber() && p->exclusiveGrabber() != item;
// filtering: (childMouseEventFilter) include points that are grabbed by children of the target item
bool grabberIsChild = false;
- auto parent = p->grabber();
+ auto parent = p->grabberItem();
while (isFiltering && parent) {
if (parent == item) {
grabberIsChild = true;
@@ -862,11 +1759,11 @@ QTouchEvent *QQuickPointerTouchEvent::touchEventForItem(QQuickItem *item, bool i
parent = parent->parentItem();
}
- // when filtering, send points that are grabbed by a child and points that are not grabbed but inside
- bool filterRelevant = isFiltering && (grabberIsChild || (!p->grabber() && item->contains(item->mapFromScene(p->scenePos()))));
- if (!(isGrabber || isPressInside || filterRelevant))
+ bool filterRelevant = isFiltering && grabberIsChild;
+ if (!(isGrabber || (isInside && (!hasAnotherGrabber || isFiltering)) || filterRelevant))
continue;
-
+ if ((p->state() == QQuickEventPoint::Pressed || p->state() == QQuickEventPoint::Released) && isInside)
+ anyPressOrReleaseInside = true;
const QTouchEvent::TouchPoint *tp = touchPointById(p->pointId());
if (tp) {
eventStates |= tp->state();
@@ -880,7 +1777,9 @@ QTouchEvent *QQuickPointerTouchEvent::touchEventForItem(QQuickItem *item, bool i
}
}
- if (eventStates == Qt::TouchPointStationary || touchPoints.isEmpty())
+ // Now touchPoints will have only points which are inside the item.
+ // But if none of them were just pressed inside, and the item has no other reason to care, ignore them anyway.
+ if (eventStates == Qt::TouchPointStationary || touchPoints.isEmpty() || (!anyPressOrReleaseInside && !anyGrabber && !isFiltering))
return nullptr;
// if all points have the same state, set the event type accordingly
@@ -915,6 +1814,19 @@ QTouchEvent *QQuickPointerTouchEvent::asTouchEvent() const
return static_cast<QTouchEvent *>(m_event);
}
+bool QQuickPointerNativeGestureEvent::allPointsAccepted() const {
+ return m_gesturePoint->isAccepted();
+}
+
+bool QQuickPointerNativeGestureEvent::allUpdatedPointsAccepted() const {
+ return m_gesturePoint->state() == QQuickEventPoint::Pressed || m_gesturePoint->isAccepted();
+}
+
+bool QQuickPointerNativeGestureEvent::allPointsGrabbed() const
+{
+ return m_gesturePoint->exclusiveGrabber() != nullptr;
+}
+
#ifndef QT_NO_DEBUG_STREAM
Q_QUICK_PRIVATE_EXPORT QDebug operator<<(QDebug dbg, const QQuickPointerDevice *dev) {
@@ -942,7 +1854,9 @@ Q_QUICK_PRIVATE_EXPORT QDebug operator<<(QDebug dbg, const QQuickPointerDevice *
Q_QUICK_PRIVATE_EXPORT QDebug operator<<(QDebug dbg, const QQuickPointerEvent *event) {
QDebugStateSaver saver(dbg);
dbg.nospace();
- dbg << "QQuickPointerEvent(dev:";
+ dbg << "QQuickPointerEvent(";
+ dbg << event->timestamp();
+ dbg << " dev:";
QtDebugUtils::formatQEnum(dbg, event->device()->type());
if (event->buttons() != Qt::NoButton) {
dbg << " buttons:";
@@ -959,10 +1873,10 @@ Q_QUICK_PRIVATE_EXPORT QDebug operator<<(QDebug dbg, const QQuickPointerEvent *e
Q_QUICK_PRIVATE_EXPORT QDebug operator<<(QDebug dbg, const QQuickEventPoint *event) {
QDebugStateSaver saver(dbg);
dbg.nospace();
- dbg << "QQuickEventPoint(valid:" << event->isValid() << " accepted:" << event->isAccepted()
+ dbg << "QQuickEventPoint(accepted:" << event->isAccepted()
<< " state:";
QtDebugUtils::formatQEnum(dbg, event->state());
- dbg << " scenePos:" << event->scenePos() << " id:" << hex << event->pointId() << dec
+ dbg << " scenePos:" << event->scenePosition() << " id:" << hex << event->pointId() << dec
<< " timeHeld:" << event->timeHeld() << ')';
return dbg;
}
diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h
index 3735d68a85..0f7e44e0e2 100644
--- a/src/quick/items/qquickevents_p_p.h
+++ b/src/quick/items/qquickevents_p_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -66,8 +66,10 @@ QT_BEGIN_NAMESPACE
class QQuickPointerDevice;
class QQuickPointerEvent;
class QQuickPointerMouseEvent;
+class QQuickPointerNativeGestureEvent;
class QQuickPointerTabletEvent;
class QQuickPointerTouchEvent;
+class QQuickPointerHandler;
class QQuickKeyEvent : public QObject
{
@@ -129,15 +131,18 @@ class Q_QUICK_PRIVATE_EXPORT QQuickMouseEvent : public QObject
Q_PROPERTY(bool wasHeld READ wasHeld)
Q_PROPERTY(bool isClick READ isClick)
Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
+ Q_REVISION(11) Q_PROPERTY(int flags READ flags)
public:
QQuickMouseEvent()
: _x(0), _y(0), _button(Qt::NoButton), _buttons(Qt::NoButton), _modifiers(Qt::NoModifier)
, _source(Qt::MouseEventNotSynthesized), _wasHeld(false), _isClick(false), _accepted(false)
+ , _flags(Qt::MouseEventFlags(0))
{}
void reset(qreal x, qreal y, Qt::MouseButton button, Qt::MouseButtons buttons,
- Qt::KeyboardModifiers modifiers, bool isClick = false, bool wasHeld = false)
+ Qt::KeyboardModifiers modifiers, bool isClick = false, bool wasHeld = false,
+ Qt::MouseEventFlags flags = 0)
{
_x = x;
_y = y;
@@ -148,6 +153,7 @@ public:
_wasHeld = wasHeld;
_isClick = isClick;
_accepted = true;
+ _flags = flags;
}
qreal x() const { return _x; }
@@ -167,7 +173,7 @@ public:
bool isAccepted() { return _accepted; }
void setAccepted(bool accepted) { _accepted = accepted; }
-
+ int flags() const { return _flags; }
private:
qreal _x;
qreal _y;
@@ -178,6 +184,7 @@ private:
bool _wasHeld : 1;
bool _isClick : 1;
bool _accepted : 1;
+ Qt::MouseEventFlags _flags;
};
class QQuickWheelEvent : public QObject
@@ -251,12 +258,17 @@ private:
class Q_QUICK_PRIVATE_EXPORT QQuickEventPoint : public QObject
{
Q_OBJECT
- Q_PROPERTY(QPointF scenePos READ scenePos)
+ Q_PROPERTY(QQuickPointerEvent *event READ pointerEvent)
+ Q_PROPERTY(QPointF position READ position)
+ Q_PROPERTY(QPointF scenePosition READ scenePosition)
+ Q_PROPERTY(QPointF scenePressPosition READ scenePressPosition)
+ Q_PROPERTY(QPointF sceneGrabPosition READ sceneGrabPosition)
Q_PROPERTY(State state READ state)
- Q_PROPERTY(quint64 pointId READ pointId)
+ Q_PROPERTY(int pointId READ pointId)
Q_PROPERTY(qreal timeHeld READ timeHeld)
+ Q_PROPERTY(QVector2D velocity READ velocity)
Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted)
- Q_PROPERTY(QQuickItem *grabber READ grabber WRITE setGrabber)
+ Q_PROPERTY(QObject *exclusiveGrabber READ exclusiveGrabber WRITE setExclusiveGrabber)
public:
enum State {
@@ -264,37 +276,79 @@ public:
Updated = Qt::TouchPointMoved,
Stationary = Qt::TouchPointStationary,
Released = Qt::TouchPointReleased
- // Canceled = Qt::TouchPointReleased << 1 // 0x10 // TODO maybe
};
- Q_ENUM(State)
+ Q_DECLARE_FLAGS(States, State)
+ Q_FLAG(States)
+
+ enum GrabState {
+ GrabPassive = 0x01,
+ UngrabPassive = 0x02,
+ CancelGrabPassive = 0x03,
+ OverrideGrabPassive = 0x04,
+ GrabExclusive = 0x10,
+ UngrabExclusive = 0x20,
+ CancelGrabExclusive = 0x30,
+ };
+ Q_ENUM(GrabState)
QQuickEventPoint(QQuickPointerEvent *parent);
- void reset(Qt::TouchPointState state, QPointF scenePos, quint64 pointId, ulong timestamp);
-
- void invalidate() { m_valid = false; }
+ void reset(Qt::TouchPointState state, const QPointF &scenePosition, int pointId, ulong timestamp, const QVector2D &velocity = QVector2D());
+ void localizePosition(QQuickItem *target);
QQuickPointerEvent *pointerEvent() const;
- QPointF scenePos() const { return m_scenePos; }
+ QPointF position() const { return m_pos; }
+ QPointF scenePosition() const { return m_scenePos; }
+ QPointF scenePressPosition() const { return m_scenePressPos; }
+ QPointF sceneGrabPosition() const { return m_sceneGrabPos; }
+ QVector2D velocity() const { return m_velocity; }
State state() const { return m_state; }
- quint64 pointId() const { return m_pointId; }
- bool isValid() const { return m_valid; }
+ int pointId() const { return m_pointId; }
qreal timeHeld() const { return (m_timestamp - m_pressTimestamp) / 1000.0; }
bool isAccepted() const { return m_accept; }
void setAccepted(bool accepted = true);
- QQuickItem *grabber() const;
- void setGrabber(QQuickItem *grabber);
+ QObject *exclusiveGrabber() const;
+ void setExclusiveGrabber(QObject *exclusiveGrabber);
+
+ QQuickItem *grabberItem() const;
+ void setGrabberItem(QQuickItem *exclusiveGrabber);
+
+ QQuickPointerHandler *grabberPointerHandler() const;
+ void setGrabberPointerHandler(QQuickPointerHandler *exclusiveGrabber, bool exclusive = false);
+
+ void cancelExclusiveGrab();
+ void cancelPassiveGrab(QQuickPointerHandler *handler);
+ bool removePassiveGrabber(QQuickPointerHandler *handler);
+ void cancelAllGrabs(QQuickPointerHandler *handler);
+
+ QVector<QPointer <QQuickPointerHandler> > passiveGrabbers() const { return m_passiveGrabbers; }
+ void setPassiveGrabbers(const QVector<QPointer <QQuickPointerHandler> > &grabbers) { m_passiveGrabbers = grabbers; }
+ void clearPassiveGrabbers() { m_passiveGrabbers.clear(); }
+
+protected:
+ void cancelExclusiveGrabImpl(QTouchEvent *cancelEvent = nullptr);
private:
+ QVector2D estimatedVelocity() const;
+
+protected:
+ QPointF m_pos;
QPointF m_scenePos;
- quint64 m_pointId;
- QPointer<QQuickItem> m_grabber;
+ QPointF m_scenePressPos;
+ QPointF m_sceneGrabPos;
+ QVector2D m_velocity;
+ int m_pointId;
+ QPointer<QObject> m_exclusiveGrabber;
+ QVector<QPointer <QQuickPointerHandler> > m_passiveGrabbers;
ulong m_timestamp;
ulong m_pressTimestamp;
State m_state;
- bool m_valid : 1;
bool m_accept : 1;
- int m_reserved : 30;
+ bool m_grabberIsHandler : 1;
+ int m_reserved : 29;
+
+ friend class QQuickPointerTouchEvent;
+ friend class QQuickWindowPrivate;
Q_DISABLE_COPY(QQuickEventPoint)
};
@@ -304,6 +358,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickEventTouchPoint : public QQuickEventPoint
Q_OBJECT
Q_PROPERTY(qreal rotation READ rotation)
Q_PROPERTY(qreal pressure READ pressure)
+ Q_PROPERTY(QSizeF ellipseDiameters READ ellipseDiameters)
Q_PROPERTY(QPointingDeviceUniqueId uniqueId READ uniqueId)
public:
@@ -313,13 +368,17 @@ public:
qreal rotation() const { return m_rotation; }
qreal pressure() const { return m_pressure; }
+ QSizeF ellipseDiameters() const { return m_ellipseDiameters; }
QPointingDeviceUniqueId uniqueId() const { return m_uniqueId; }
private:
qreal m_rotation;
qreal m_pressure;
+ QSizeF m_ellipseDiameters;
QPointingDeviceUniqueId m_uniqueId;
+ friend class QQuickPointerTouchEvent;
+
Q_DISABLE_COPY(QQuickEventTouchPoint)
};
@@ -350,25 +409,33 @@ public: // property accessors
public: // helpers for C++ only (during event delivery)
virtual QQuickPointerEvent *reset(QEvent *ev) = 0;
+ virtual void localize(QQuickItem *target) = 0;
virtual bool isPressEvent() const = 0;
+ virtual bool isDoubleClickEvent() const { return false; }
+ virtual bool isUpdateEvent() const = 0;
+ virtual bool isReleaseEvent() const = 0;
virtual QQuickPointerMouseEvent *asPointerMouseEvent() { return nullptr; }
virtual QQuickPointerTouchEvent *asPointerTouchEvent() { return nullptr; }
virtual QQuickPointerTabletEvent *asPointerTabletEvent() { return nullptr; }
+ virtual QQuickPointerNativeGestureEvent *asPointerNativeGestureEvent() { return nullptr; }
virtual const QQuickPointerMouseEvent *asPointerMouseEvent() const { return nullptr; }
virtual const QQuickPointerTouchEvent *asPointerTouchEvent() const { return nullptr; }
virtual const QQuickPointerTabletEvent *asPointerTabletEvent() const { return nullptr; }
- bool isValid() const { return m_event != nullptr; }
+ virtual const QQuickPointerNativeGestureEvent *asPointerNativeGestureEvent() const { return nullptr; }
virtual bool allPointsAccepted() const = 0;
+ virtual bool allUpdatedPointsAccepted() const = 0;
+ virtual bool allPointsGrabbed() const = 0;
bool isAccepted() { return m_event->isAccepted(); }
void setAccepted(bool accepted) { m_event->setAccepted(accepted); }
QVector<QPointF> unacceptedPressedPointScenePositions() const;
virtual int pointCount() const = 0;
virtual QQuickEventPoint *point(int i) const = 0;
- virtual QQuickEventPoint *pointById(quint64 pointId) const = 0;
- virtual QVector<QQuickItem *> grabbers() const = 0;
+ virtual QQuickEventPoint *pointById(int pointId) const = 0;
+ virtual QVector<QObject *> exclusiveGrabbers() const = 0;
virtual void clearGrabbers() const = 0;
+ virtual bool hasExclusiveGrabber(const QQuickPointerHandler *handler) const = 0;
ulong timestamp() const { return m_event->timestamp(); }
@@ -389,15 +456,22 @@ public:
: QQuickPointerEvent(parent, device), m_mousePoint(new QQuickEventPoint(this)) { }
QQuickPointerEvent *reset(QEvent *) override;
+ void localize(QQuickItem *target) override;
bool isPressEvent() const override;
+ bool isDoubleClickEvent() const override;
+ bool isUpdateEvent() const override;
+ bool isReleaseEvent() const override;
QQuickPointerMouseEvent *asPointerMouseEvent() override { return this; }
const QQuickPointerMouseEvent *asPointerMouseEvent() const override { return this; }
int pointCount() const override { return 1; }
QQuickEventPoint *point(int i) const override;
- QQuickEventPoint *pointById(quint64 pointId) const override;
+ QQuickEventPoint *pointById(int pointId) const override;
bool allPointsAccepted() const override;
- QVector<QQuickItem *> grabbers() const override;
+ bool allUpdatedPointsAccepted() const override;
+ bool allPointsGrabbed() const override;
+ QVector<QObject *> exclusiveGrabbers() const override;
void clearGrabbers() const override;
+ bool hasExclusiveGrabber(const QQuickPointerHandler *handler) const override;
QMouseEvent *asMouseEvent(const QPointF& localPos) const;
@@ -418,16 +492,22 @@ public:
{ }
QQuickPointerEvent *reset(QEvent *) override;
+ void localize(QQuickItem *target) override;
bool isPressEvent() const override;
+ bool isUpdateEvent() const override;
+ bool isReleaseEvent() const override;
QQuickPointerTouchEvent *asPointerTouchEvent() override { return this; }
const QQuickPointerTouchEvent *asPointerTouchEvent() const override { return this; }
int pointCount() const override { return m_pointCount; }
QQuickEventPoint *point(int i) const override;
- QQuickEventPoint *pointById(quint64 pointId) const override;
+ QQuickEventPoint *pointById(int pointId) const override;
const QTouchEvent::TouchPoint *touchPointById(int pointId) const;
bool allPointsAccepted() const override;
- QVector<QQuickItem *> grabbers() const override;
+ bool allUpdatedPointsAccepted() const override;
+ bool allPointsGrabbed() const override;
+ QVector<QObject *> exclusiveGrabbers() const override;
void clearGrabbers() const override;
+ bool hasExclusiveGrabber(const QQuickPointerHandler *handler) const override;
QMouseEvent *syntheticMouseEvent(int pointID, QQuickItem *relativeTo) const;
QTouchEvent *touchEventForItem(QQuickItem *item, bool isFiltering = false) const;
@@ -442,6 +522,42 @@ private:
Q_DISABLE_COPY(QQuickPointerTouchEvent)
};
+class Q_QUICK_PRIVATE_EXPORT QQuickPointerNativeGestureEvent : public QQuickPointerEvent
+{
+ Q_OBJECT
+ Q_PROPERTY(Qt::NativeGestureType type READ type CONSTANT)
+ Q_PROPERTY(qreal value READ value CONSTANT)
+
+public:
+ QQuickPointerNativeGestureEvent(QObject *parent = nullptr, QQuickPointerDevice *device = nullptr)
+ : QQuickPointerEvent(parent, device), m_gesturePoint(new QQuickEventPoint(this)) { }
+
+ QQuickPointerEvent *reset(QEvent *) override;
+ void localize(QQuickItem *target) override;
+ bool isPressEvent() const override;
+ bool isUpdateEvent() const override;
+ bool isReleaseEvent() const override;
+ QQuickPointerNativeGestureEvent *asPointerNativeGestureEvent() override { return this; }
+ const QQuickPointerNativeGestureEvent *asPointerNativeGestureEvent() const override { return this; }
+ int pointCount() const override { return 1; }
+ QQuickEventPoint *point(int i) const override;
+ QQuickEventPoint *pointById(int pointId) const override;
+ bool allPointsAccepted() const override;
+ bool allUpdatedPointsAccepted() const override;
+ bool allPointsGrabbed() const override;
+ QVector<QObject *> exclusiveGrabbers() const override;
+ void clearGrabbers() const override;
+ bool hasExclusiveGrabber(const QQuickPointerHandler *handler) const override;
+ Qt::NativeGestureType type() const;
+ qreal value() const;
+
+private:
+ QQuickEventPoint *m_gesturePoint;
+
+ Q_DISABLE_COPY(QQuickPointerNativeGestureEvent)
+};
+
+
// ### Qt 6: move this to qtbase, replace QTouchDevice and the enums in QTabletEvent
class Q_QUICK_PRIVATE_EXPORT QQuickPointerDevice : public QObject
{
@@ -497,13 +613,6 @@ public:
Q_ENUM(CapabilityFlag)
Q_FLAG(Capabilities)
- QQuickPointerDevice(DeviceType devType, PointerType pType, Capabilities caps, int maxPoints, int buttonCount, const QString &name, qint64 uniqueId = 0)
- : m_deviceType(devType), m_pointerType(pType), m_capabilities(caps)
- , m_maximumTouchPoints(maxPoints), m_buttonCount(buttonCount), m_name(name)
- , m_uniqueId(QPointingDeviceUniqueId::fromNumericId(uniqueId))
- {
- }
-
DeviceType type() const { return m_deviceType; }
PointerType pointerType() const { return m_pointerType; }
Capabilities capabilities() const { return m_capabilities; }
@@ -513,11 +622,22 @@ public:
QString name() const { return m_name; }
QPointingDeviceUniqueId uniqueId() const { return m_uniqueId; }
- static QQuickPointerDevice *touchDevice(QTouchDevice *d);
+ static QQuickPointerDevice *touchDevice(const QTouchDevice *d);
static QList<QQuickPointerDevice *> touchDevices();
static QQuickPointerDevice *genericMouseDevice();
static QQuickPointerDevice *tabletDevice(qint64);
+ QVector<QQuickPointerHandler *> &eventDeliveryTargets() { return m_eventDeliveryTargets; }
+
+private:
+ QQuickPointerDevice(DeviceType devType, PointerType pType, Capabilities caps, int maxPoints, int buttonCount, const QString &name, qint64 uniqueId = 0)
+ : m_deviceType(devType), m_pointerType(pType), m_capabilities(caps)
+ , m_maximumTouchPoints(maxPoints), m_buttonCount(buttonCount), m_name(name)
+ , m_uniqueId(QPointingDeviceUniqueId::fromNumericId(uniqueId))
+ {
+ }
+ ~QQuickPointerDevice() { }
+
private:
DeviceType m_deviceType;
PointerType m_pointerType;
@@ -526,8 +646,10 @@ private:
int m_buttonCount;
QString m_name;
QPointingDeviceUniqueId m_uniqueId;
+ QVector<QQuickPointerHandler *> m_eventDeliveryTargets; // during delivery, handlers which have already seen the event
Q_DISABLE_COPY(QQuickPointerDevice)
+ friend struct ConstructableQQuickPointerDevice;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickPointerDevice::DeviceTypes)
diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
index 44612edc49..95d1229c8d 100644
--- a/src/quick/items/qquickflickable.cpp
+++ b/src/quick/items/qquickflickable.cpp
@@ -44,6 +44,7 @@
#include "qquickwindow_p.h"
#include "qquickevents_p_p.h"
+#include <QtQuick/private/qquickpointerhandler_p.h>
#include <QtQuick/private/qquicktransition_p.h>
#include <private/qqmlglobal_p.h>
@@ -212,7 +213,7 @@ public:
}
protected:
- void finished() Q_DECL_OVERRIDE {
+ void finished() override {
if (!flickable)
return;
axisData->move.setValue(axisData->transitionTo);
@@ -255,6 +256,7 @@ QQuickFlickablePrivate::QQuickFlickablePrivate()
, flickBoost(1.0), fixupMode(Normal), vTime(0), visibleArea(0)
, flickableDirection(QQuickFlickable::AutoFlickDirection)
, boundsBehavior(QQuickFlickable::DragAndOvershootBounds)
+ , boundsMovement(QQuickFlickable::FollowBoundsBehavior)
, rebound(0)
{
}
@@ -269,6 +271,7 @@ void QQuickFlickablePrivate::init()
qmlobject_connect(&velocityTimeline, QQuickTimeLine, SIGNAL(completed()),
q, QQuickFlickable, SLOT(velocityTimelineCompleted()))
q->setAcceptedMouseButtons(Qt::LeftButton);
+ q->setAcceptTouchEvents(false); // rely on mouse events synthesized from touch
q->setFiltersChildMouseEvents(true);
QQuickItemPrivate *viewportPrivate = QQuickItemPrivate::get(contentItem);
viewportPrivate->addItemChangeListener(this, QQuickItemPrivate::Geometry);
@@ -564,18 +567,6 @@ void QQuickFlickablePrivate::updateBeginningEnd()
visibleArea->updateVisible();
}
-/*
-XXXTODO add docs describing moving, dragging, flicking properties, e.g.
-
-When the user starts dragging the Flickable, the dragging and moving properties
-will be true.
-
-If the velocity is sufficient when the drag is ended, flicking may begin.
-
-The moving properties will remain true until all dragging and flicking
-is finished.
-*/
-
/*!
\qmlsignal QtQuick::Flickable::dragStarted()
@@ -1579,6 +1570,8 @@ void QQuickFlickablePrivate::replayDelayedPress()
// If we have the grab, release before delivering the event
if (QQuickWindow *w = q->window()) {
+ QQuickWindowPrivate *wpriv = QQuickWindowPrivate::get(w);
+ wpriv->allowChildEventFiltering = false; // don't allow re-filtering during replay
replayingPressEvent = true;
if (w->mouseGrabberItem() == q)
q->ungrabMouse();
@@ -1586,6 +1579,7 @@ void QQuickFlickablePrivate::replayDelayedPress()
// Use the event handler that will take care of finding the proper item to propagate the event
QCoreApplication::sendEvent(w, mouseEvent.data());
replayingPressEvent = false;
+ wpriv->allowChildEventFiltering = true;
}
}
}
@@ -1594,16 +1588,18 @@ void QQuickFlickablePrivate::replayDelayedPress()
void QQuickFlickablePrivate::setViewportX(qreal x)
{
Q_Q(QQuickFlickable);
- if (pixelAligned)
- x = -Round(-x);
-
- contentItem->setX(x);
- if (contentItem->x() != x)
- return; // reentered
+ qreal effectiveX = pixelAligned ? -Round(-x) : x;
const qreal maxX = q->maxXExtent();
const qreal minX = q->minXExtent();
+ if (boundsMovement == int(QQuickFlickable::StopAtBounds))
+ effectiveX = qBound(maxX, effectiveX, minX);
+
+ contentItem->setX(effectiveX);
+ if (contentItem->x() != effectiveX)
+ return; // reentered
+
qreal overshoot = 0.0;
if (x <= maxX)
overshoot = maxX - x;
@@ -1619,16 +1615,18 @@ void QQuickFlickablePrivate::setViewportX(qreal x)
void QQuickFlickablePrivate::setViewportY(qreal y)
{
Q_Q(QQuickFlickable);
- if (pixelAligned)
- y = -Round(-y);
-
- contentItem->setY(y);
- if (contentItem->y() != y)
- return; // reentered
+ qreal effectiveY = pixelAligned ? -Round(-y) : y;
const qreal maxY = q->maxYExtent();
const qreal minY = q->minYExtent();
+ if (boundsMovement == int(QQuickFlickable::StopAtBounds))
+ effectiveY = qBound(maxY, effectiveY, minY);
+
+ contentItem->setY(effectiveY);
+ if (contentItem->y() != effectiveY)
+ return; // reentered
+
qreal overshoot = 0.0;
if (y <= maxY)
overshoot = maxY - y;
@@ -1889,8 +1887,9 @@ QQmlListProperty<QQuickItem> QQuickFlickable::flickableChildren()
beyond the Flickable's boundaries, or overshoot the
Flickable's boundaries when flicked.
- This enables the feeling that the edges of the view are soft,
- rather than a hard physical boundary.
+ When the \l boundsMovement is \c Flickable.FollowBoundsBehavior, a value
+ other than \c Flickable.StopAtBounds will give a feeling that the edges of
+ the view are soft, rather than a hard physical boundary.
The \c boundsBehavior can be one of:
@@ -1906,7 +1905,7 @@ QQmlListProperty<QQuickItem> QQuickFlickable::flickableChildren()
boundary when flicked.
\endlist
- \sa horizontalOvershoot, verticalOvershoot
+ \sa horizontalOvershoot, verticalOvershoot, boundsMovement
*/
QQuickFlickable::BoundsBehavior QQuickFlickable::boundsBehavior() const
{
@@ -2721,7 +2720,11 @@ void QQuickFlickablePrivate::updateVelocity()
The value is negative when the content is dragged or flicked beyond the beginning,
and positive when beyond the end; \c 0.0 otherwise.
- \sa verticalOvershoot, boundsBehavior
+ Whether the values are reported for dragging and/or flicking is determined by
+ \l boundsBehavior. The overshoot distance is reported even when \l boundsMovement
+ is \c Flickable.StopAtBounds.
+
+ \sa verticalOvershoot, boundsBehavior, boundsMovement
*/
qreal QQuickFlickable::horizontalOvershoot() const
{
@@ -2738,7 +2741,11 @@ qreal QQuickFlickable::horizontalOvershoot() const
The value is negative when the content is dragged or flicked beyond the beginning,
and positive when beyond the end; \c 0.0 otherwise.
- \sa horizontalOvershoot, boundsBehavior
+ Whether the values are reported for dragging and/or flicking is determined by
+ \l boundsBehavior. The overshoot distance is reported even when \l boundsMovement
+ is \c Flickable.StopAtBounds.
+
+ \sa horizontalOvershoot, boundsBehavior, boundsMovement
*/
qreal QQuickFlickable::verticalOvershoot() const
{
@@ -2746,6 +2753,68 @@ qreal QQuickFlickable::verticalOvershoot() const
return d->vData.overshoot;
}
+/*!
+ \qmlproperty enumeration QtQuick::Flickable::boundsMovement
+ \since 5.10
+
+ This property holds whether the flickable will give a feeling that the edges of the
+ view are soft, rather than a hard physical boundary.
+
+ The \c boundsMovement can be one of:
+
+ \list
+ \li Flickable.StopAtBounds - this allows implementing custom edge effects where the
+ contents do not follow drags or flicks beyond the bounds of the flickable. The values
+ of \l horizontalOvershoot and \l verticalOvershoot can be utilized to implement custom
+ edge effects.
+ \li Flickable.FollowBoundsBehavior (default) - whether the contents follow drags or
+ flicks beyond the bounds of the flickable is determined by \l boundsBehavior.
+ \endlist
+
+ The following example keeps the contents within bounds and instead applies a flip
+ effect when flicked over horizontal bounds:
+ \code
+ Flickable {
+ id: flickable
+ boundsMovement: Flickable.StopAtBounds
+ boundsBehavior: Flickable.DragAndOvershootBounds
+ transform: Rotation {
+ axis { x: 0; y: 1; z: 0 }
+ origin.x: flickable.width / 2
+ origin.y: flickable.height / 2
+ angle: Math.min(30, Math.max(-30, flickable.horizontalOvershoot))
+ }
+ }
+ \endcode
+
+ The following example keeps the contents within bounds and instead applies an opacity
+ effect when dragged over vertical bounds:
+ \code
+ Flickable {
+ boundsMovement: Flickable.StopAtBounds
+ boundsBehavior: Flickable.DragOverBounds
+ opacity: Math.max(0.5, 1.0 - Math.abs(verticalOvershoot) / height)
+ }
+ \endcode
+
+ \sa boundsBehavior, verticalOvershoot, horizontalOvershoot
+*/
+QQuickFlickable::BoundsMovement QQuickFlickable::boundsMovement() const
+{
+ Q_D(const QQuickFlickable);
+ return d->boundsMovement;
+}
+
+void QQuickFlickable::setBoundsMovement(BoundsMovement movement)
+{
+ Q_D(QQuickFlickable);
+ if (d->boundsMovement == movement)
+ return;
+
+ d->boundsMovement = movement;
+ emit boundsMovementChanged();
+}
+
QT_END_NAMESPACE
#include "moc_qquickflickable_p.cpp"
diff --git a/src/quick/items/qquickflickable_p.h b/src/quick/items/qquickflickable_p.h
index 52cade1472..4ad01323a4 100644
--- a/src/quick/items/qquickflickable_p.h
+++ b/src/quick/items/qquickflickable_p.h
@@ -80,6 +80,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickFlickable : public QQuickItem
Q_PROPERTY(qreal verticalVelocity READ verticalVelocity NOTIFY verticalVelocityChanged)
Q_PROPERTY(BoundsBehavior boundsBehavior READ boundsBehavior WRITE setBoundsBehavior NOTIFY boundsBehaviorChanged)
+ Q_PROPERTY(BoundsMovement boundsMovement READ boundsMovement WRITE setBoundsMovement NOTIFY boundsMovementChanged REVISION 10)
Q_PROPERTY(QQuickTransition *rebound READ rebound WRITE setRebound NOTIFY reboundChanged)
Q_PROPERTY(qreal maximumFlickVelocity READ maximumFlickVelocity WRITE setMaximumFlickVelocity NOTIFY maximumFlickVelocityChanged)
Q_PROPERTY(qreal flickDeceleration READ flickDeceleration WRITE setFlickDeceleration NOTIFY flickDecelerationChanged)
@@ -132,6 +133,15 @@ public:
BoundsBehavior boundsBehavior() const;
void setBoundsBehavior(BoundsBehavior);
+ enum BoundsMovement {
+ // StopAtBounds = 0x0,
+ FollowBoundsBehavior = 0x1
+ };
+ Q_ENUM(BoundsMovement)
+
+ BoundsMovement boundsMovement() const;
+ void setBoundsMovement(BoundsMovement movement);
+
QQuickTransition *rebound() const;
void setRebound(QQuickTransition *transition);
@@ -237,6 +247,7 @@ Q_SIGNALS:
void flickableDirectionChanged();
void interactiveChanged();
void boundsBehaviorChanged();
+ Q_REVISION(10) void boundsMovementChanged();
void reboundChanged();
void maximumFlickVelocityChanged();
void flickDecelerationChanged();
@@ -252,14 +263,14 @@ Q_SIGNALS:
Q_REVISION(9) void verticalOvershootChanged();
protected:
- bool childMouseEventFilter(QQuickItem *, QEvent *) Q_DECL_OVERRIDE;
- void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
- void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
- void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
+ bool childMouseEventFilter(QQuickItem *, QEvent *) override;
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
#if QT_CONFIG(wheelevent)
- void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE;
+ void wheelEvent(QWheelEvent *event) override;
#endif
- void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE;
+ void timerEvent(QTimerEvent *event) override;
QQuickFlickableVisibleArea *visibleArea();
@@ -277,11 +288,11 @@ protected:
virtual qreal maxYExtent() const;
qreal vWidth() const;
qreal vHeight() const;
- void componentComplete() Q_DECL_OVERRIDE;
+ void componentComplete() override;
virtual void viewportMoved(Qt::Orientations orient);
void geometryChanged(const QRectF &newGeometry,
- const QRectF &oldGeometry) Q_DECL_OVERRIDE;
- void mouseUngrabEvent() Q_DECL_OVERRIDE;
+ const QRectF &oldGeometry) override;
+ void mouseUngrabEvent() override;
bool filterMouseEvent(QQuickItem *receiver, QMouseEvent *event);
bool xflick() const;
diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h
index 451146329c..c2531e6012 100644
--- a/src/quick/items/qquickflickable_p_p.h
+++ b/src/quick/items/qquickflickable_p_p.h
@@ -87,7 +87,7 @@ public:
{
Velocity(QQuickFlickablePrivate *p)
: parent(p) {}
- void setValue(qreal v) Q_DECL_OVERRIDE {
+ void setValue(qreal v) override {
if (v != value()) {
QQuickTimeLineValue::setValue(v);
parent->updateVelocity();
@@ -197,7 +197,7 @@ public:
qreal overShootDistance(qreal size) const;
- void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) Q_DECL_OVERRIDE;
+ void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) override;
void draggingStarting();
void draggingEnding();
@@ -249,6 +249,7 @@ public:
QQuickFlickableVisibleArea *visibleArea;
QQuickFlickable::FlickableDirection flickableDirection;
QQuickFlickable::BoundsBehavior boundsBehavior;
+ QQuickFlickable::BoundsMovement boundsMovement;
QQuickTransition *rebound;
void viewportAxisMoved(AxisData &data, qreal minExtent, qreal maxExtent, qreal vSize,
diff --git a/src/quick/items/qquickflipable.cpp b/src/quick/items/qquickflipable.cpp
index a960cd8b80..4273ed4881 100644
--- a/src/quick/items/qquickflipable.cpp
+++ b/src/quick/items/qquickflipable.cpp
@@ -57,7 +57,7 @@ public:
transform = t;
update();
}
- void applyTo(QMatrix4x4 *matrix) const Q_DECL_OVERRIDE {
+ void applyTo(QMatrix4x4 *matrix) const override {
*matrix *= transform;
}
private:
@@ -70,7 +70,7 @@ class QQuickFlipablePrivate : public QQuickItemPrivate
public:
QQuickFlipablePrivate() : current(QQuickFlipable::Front), front(0), back(0), sideDirty(false) {}
- void transformChanged() Q_DECL_OVERRIDE;
+ void transformChanged() override;
void updateSide();
void setBackTransform();
diff --git a/src/quick/items/qquickflipable_p.h b/src/quick/items/qquickflipable_p.h
index a76977d4ac..ec922725ef 100644
--- a/src/quick/items/qquickflipable_p.h
+++ b/src/quick/items/qquickflipable_p.h
@@ -93,7 +93,7 @@ Q_SIGNALS:
void sideChanged();
protected:
- void updatePolish() Q_DECL_OVERRIDE;
+ void updatePolish() override;
private Q_SLOTS:
void retransformBack();
diff --git a/src/quick/items/qquickframebufferobject.cpp b/src/quick/items/qquickframebufferobject.cpp
index 20ba067a6b..9b133a823e 100644
--- a/src/quick/items/qquickframebufferobject.cpp
+++ b/src/quick/items/qquickframebufferobject.cpp
@@ -219,7 +219,7 @@ public:
window->update();
}
- QSGTexture *texture() const Q_DECL_OVERRIDE
+ QSGTexture *texture() const override
{
return QSGSimpleTextureNode::texture();
}
diff --git a/src/quick/items/qquickframebufferobject.h b/src/quick/items/qquickframebufferobject.h
index 13eeb931ad..d66ca40b3a 100644
--- a/src/quick/items/qquickframebufferobject.h
+++ b/src/quick/items/qquickframebufferobject.h
@@ -75,7 +75,7 @@ public:
void *data;
};
- QQuickFramebufferObject(QQuickItem *parent = Q_NULLPTR);
+ QQuickFramebufferObject(QQuickItem *parent = nullptr);
bool textureFollowsItemSize() const;
void setTextureFollowsItemSize(bool follows);
@@ -85,15 +85,15 @@ public:
virtual Renderer *createRenderer() const = 0;
- bool isTextureProvider() const Q_DECL_OVERRIDE;
- QSGTextureProvider *textureProvider() const Q_DECL_OVERRIDE;
- void releaseResources() Q_DECL_OVERRIDE;
+ bool isTextureProvider() const override;
+ QSGTextureProvider *textureProvider() const override;
+ void releaseResources() override;
protected:
- void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
+ void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
protected:
- QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE;
+ QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
Q_SIGNALS:
void textureFollowsItemSizeChanged(bool);
diff --git a/src/quick/items/qquickgenericshadereffect.cpp b/src/quick/items/qquickgenericshadereffect.cpp
index b366071962..305ef7e778 100644
--- a/src/quick/items/qquickgenericshadereffect.cpp
+++ b/src/quick/items/qquickgenericshadereffect.cpp
@@ -546,7 +546,10 @@ void QQuickGenericShaderEffect::updateShaderVars(Shader shaderType)
// Have a QSignalMapper that emits mapped() with an index+type on each property change notify signal.
auto &sm(m_signalMappers[shaderType][i]);
if (!sm.mapper) {
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
sm.mapper = new QSignalMapper;
+QT_WARNING_POP
sm.mapper->setMapping(m_item, i | (shaderType << 16));
}
sm.active = true;
diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp
index 2be64362b2..b2adf96f0e 100644
--- a/src/quick/items/qquickgridview.cpp
+++ b/src/quick/items/qquickgridview.cpp
@@ -745,8 +745,7 @@ void QQuickGridViewPrivate::updateHighlight()
// auto-update highlight
highlightXAnimator->to = currentItem->itemX();
highlightYAnimator->to = currentItem->itemY();
- highlight->item->setWidth(currentItem->item->width());
- highlight->item->setHeight(currentItem->item->height());
+ highlight->item->setSize(currentItem->item->size());
highlightXAnimator->restart();
highlightYAnimator->restart();
diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp
index dacb43a421..7e13e5e0e1 100644
--- a/src/quick/items/qquickimage.cpp
+++ b/src/quick/items/qquickimage.cpp
@@ -515,37 +515,41 @@ void QQuickImage::updatePaintedGeometry()
setImplicitSize(0, 0);
return;
}
- qreal w = widthValid() ? width() : d->pix.width();
- qreal widthScale = w / qreal(d->pix.width());
- qreal h = heightValid() ? height() : d->pix.height();
- qreal heightScale = h / qreal(d->pix.height());
+ const qreal pixWidth = d->pix.width() / d->devicePixelRatio;
+ const qreal pixHeight = d->pix.height() / d->devicePixelRatio;
+ const qreal w = widthValid() ? width() : pixWidth;
+ const qreal widthScale = w / pixWidth;
+ const qreal h = heightValid() ? height() : pixHeight;
+ const qreal heightScale = h / pixHeight;
if (widthScale <= heightScale) {
d->paintedWidth = w;
- d->paintedHeight = widthScale * qreal(d->pix.height());
+ d->paintedHeight = widthScale * pixHeight;
} else if (heightScale < widthScale) {
- d->paintedWidth = heightScale * qreal(d->pix.width());
+ d->paintedWidth = heightScale * pixWidth;
d->paintedHeight = h;
}
- qreal iHeight = (widthValid() && !heightValid()) ? d->paintedHeight : d->pix.height();
- qreal iWidth = (heightValid() && !widthValid()) ? d->paintedWidth : d->pix.width();
+ const qreal iHeight = (widthValid() && !heightValid()) ? d->paintedHeight : pixHeight;
+ const qreal iWidth = (heightValid() && !widthValid()) ? d->paintedWidth : pixWidth;
setImplicitSize(iWidth, iHeight);
} else if (d->fillMode == PreserveAspectCrop) {
if (!d->pix.width() || !d->pix.height())
return;
- qreal widthScale = width() / qreal(d->pix.width());
- qreal heightScale = height() / qreal(d->pix.height());
+ const qreal pixWidth = d->pix.width() / d->devicePixelRatio;
+ const qreal pixHeight = d->pix.height() / d->devicePixelRatio;
+ qreal widthScale = width() / pixWidth;
+ qreal heightScale = height() / pixHeight;
if (widthScale < heightScale) {
widthScale = heightScale;
} else if (heightScale < widthScale) {
heightScale = widthScale;
}
- d->paintedHeight = heightScale * qreal(d->pix.height());
- d->paintedWidth = widthScale * qreal(d->pix.width());
+ d->paintedHeight = heightScale * pixHeight;
+ d->paintedWidth = widthScale * pixWidth;
} else if (d->fillMode == Pad) {
- d->paintedWidth = d->pix.width();
- d->paintedHeight = d->pix.height();
+ d->paintedWidth = d->pix.width() / d->devicePixelRatio;
+ d->paintedHeight = d->pix.height() / d->devicePixelRatio;
} else {
d->paintedWidth = width();
d->paintedHeight = height();
@@ -556,7 +560,8 @@ void QQuickImage::updatePaintedGeometry()
void QQuickImage::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
QQuickImageBase::geometryChanged(newGeometry, oldGeometry);
- updatePaintedGeometry();
+ if (newGeometry.size() != oldGeometry.size())
+ updatePaintedGeometry();
}
QRectF QQuickImage::boundingRect() const
diff --git a/src/quick/items/qquickimage_p.h b/src/quick/items/qquickimage_p.h
index a5331266c9..09b2c1eeb7 100644
--- a/src/quick/items/qquickimage_p.h
+++ b/src/quick/items/qquickimage_p.h
@@ -91,7 +91,7 @@ public:
qreal paintedWidth() const;
qreal paintedHeight() const;
- QRectF boundingRect() const Q_DECL_OVERRIDE;
+ QRectF boundingRect() const override;
HAlignment horizontalAlignment() const;
void setHorizontalAlignment(HAlignment align);
@@ -99,13 +99,13 @@ public:
VAlignment verticalAlignment() const;
void setVerticalAlignment(VAlignment align);
- bool isTextureProvider() const Q_DECL_OVERRIDE { return true; }
- QSGTextureProvider *textureProvider() const Q_DECL_OVERRIDE;
+ bool isTextureProvider() const override { return true; }
+ QSGTextureProvider *textureProvider() const override;
bool mipmap() const;
void setMipmap(bool use);
- virtual void emitAutoTransformBaseChanged() Q_DECL_OVERRIDE { emit autoTransformChanged(); }
+ void emitAutoTransformBaseChanged() override { emit autoTransformChanged(); }
Q_SIGNALS:
void fillModeChanged();
@@ -120,12 +120,12 @@ private Q_SLOTS:
protected:
QQuickImage(QQuickImagePrivate &dd, QQuickItem *parent);
- void pixmapChange() Q_DECL_OVERRIDE;
+ void pixmapChange() override;
void updatePaintedGeometry();
- void releaseResources() Q_DECL_OVERRIDE;
+ void releaseResources() override;
- void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
- QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE;
+ void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
+ QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
private:
Q_DISABLE_COPY(QQuickImage)
diff --git a/src/quick/items/qquickimage_p_p.h b/src/quick/items/qquickimage_p_p.h
index 522dbca803..afc33def0f 100644
--- a/src/quick/items/qquickimage_p_p.h
+++ b/src/quick/items/qquickimage_p_p.h
@@ -58,7 +58,7 @@ QT_BEGIN_NAMESPACE
class QQuickImageTextureProvider;
-class QQuickImagePrivate : public QQuickImageBasePrivate
+class Q_QUICK_PRIVATE_EXPORT QQuickImagePrivate : public QQuickImageBasePrivate
{
Q_DECLARE_PUBLIC(QQuickImage)
diff --git a/src/quick/items/qquickimagebase.cpp b/src/quick/items/qquickimagebase.cpp
index e8200bb97f..74ee859f77 100644
--- a/src/quick/items/qquickimagebase.cpp
+++ b/src/quick/items/qquickimagebase.cpp
@@ -49,6 +49,30 @@
QT_BEGIN_NAMESPACE
+// This function gives derived classes the chance set the devicePixelRatio
+// if they're not happy with our implementation of it.
+bool QQuickImageBasePrivate::updateDevicePixelRatio(qreal targetDevicePixelRatio)
+{
+ // QQuickImageProvider and SVG can generate a high resolution image when
+ // sourceSize is set (this function is only called if it's set).
+ // If sourceSize is not set then the provider default size will be used, as usual.
+ bool setDevicePixelRatio = false;
+ if (url.scheme() == QLatin1String("image")) {
+ setDevicePixelRatio = true;
+ } else {
+ QString stringUrl = url.path(QUrl::PrettyDecoded);
+ if (stringUrl.endsWith(QLatin1String("svg")) ||
+ stringUrl.endsWith(QLatin1String("svgz"))) {
+ setDevicePixelRatio = true;
+ }
+ }
+
+ if (setDevicePixelRatio)
+ devicePixelRatio = targetDevicePixelRatio;
+
+ return setDevicePixelRatio;
+}
+
QQuickImageBase::QQuickImageBase(QQuickItem *parent)
: QQuickImplicitSizeItem(*(new QQuickImageBasePrivate), parent)
{
@@ -221,26 +245,11 @@ void QQuickImageBase::load()
QUrl loadUrl = d->url;
- // QQuickImageProvider and SVG can generate a high resolution image when
- // sourceSize is set. If sourceSize is not set then the provider default size
- // will be used, as usual.
- bool setDevicePixelRatio = false;
- if (d->sourcesize.isValid()) {
- if (loadUrl.scheme() == QLatin1String("image")) {
- setDevicePixelRatio = true;
- } else {
- QString stringUrl = loadUrl.path(QUrl::PrettyDecoded);
- if (stringUrl.endsWith(QLatin1String("svg")) ||
- stringUrl.endsWith(QLatin1String("svgz"))) {
- setDevicePixelRatio = true;
- }
- }
-
- if (setDevicePixelRatio)
- d->devicePixelRatio = targetDevicePixelRatio;
- }
+ bool updatedDevicePixelRatio = false;
+ if (d->sourcesize.isValid())
+ updatedDevicePixelRatio = d->updateDevicePixelRatio(targetDevicePixelRatio);
- if (!setDevicePixelRatio) {
+ if (!updatedDevicePixelRatio) {
// (possible) local file: loadUrl and d->devicePixelRatio will be modified if
// an "@2x" file is found.
resolve2xLocalFile(d->url, targetDevicePixelRatio, &loadUrl, &d->devicePixelRatio);
@@ -319,18 +328,18 @@ void QQuickImageBase::requestProgress(qint64 received, qint64 total)
void QQuickImageBase::itemChange(ItemChange change, const ItemChangeData &value)
{
- if (change == ItemSceneChange && value.window)
- connect(value.window, &QQuickWindow::screenChanged, this, &QQuickImageBase::handleScreenChanged);
+ Q_D(QQuickImageBase);
+ // If the screen DPI changed, reload image.
+ if (change == ItemDevicePixelRatioHasChanged && value.realValue != d->devicePixelRatio) {
+ // ### how can we get here with !qmlEngine(this)? that implies
+ // itemChange() on an item pending deletion, which seems strange.
+ if (qmlEngine(this) && isComponentComplete() && d->url.isValid()) {
+ load();
+ }
+ }
QQuickItem::itemChange(change, value);
}
-void QQuickImageBase::handleScreenChanged(QScreen* screen)
-{
- // Screen DPI might have changed, reload images on screen change.
- if (qmlEngine(this) && screen && isComponentComplete())
- load();
-}
-
void QQuickImageBase::componentComplete()
{
Q_D(QQuickImageBase);
diff --git a/src/quick/items/qquickimagebase_p.h b/src/quick/items/qquickimagebase_p.h
index 532f6ce683..4d4a6fceaf 100644
--- a/src/quick/items/qquickimagebase_p.h
+++ b/src/quick/items/qquickimagebase_p.h
@@ -115,15 +115,14 @@ Q_SIGNALS:
protected:
virtual void load();
- void componentComplete() Q_DECL_OVERRIDE;
+ void componentComplete() override;
virtual void pixmapChange();
- void itemChange(ItemChange change, const ItemChangeData &value) Q_DECL_OVERRIDE;
+ void itemChange(ItemChange change, const ItemChangeData &value) override;
QQuickImageBase(QQuickImageBasePrivate &dd, QQuickItem *parent);
private Q_SLOTS:
virtual void requestFinished();
void requestProgress(qint64,qint64);
- void handleScreenChanged(QScreen *screen);
private:
Q_DISABLE_COPY(QQuickImageBase)
diff --git a/src/quick/items/qquickimagebase_p_p.h b/src/quick/items/qquickimagebase_p_p.h
index d9b609c7fe..1b771166a2 100644
--- a/src/quick/items/qquickimagebase_p_p.h
+++ b/src/quick/items/qquickimagebase_p_p.h
@@ -59,7 +59,7 @@
QT_BEGIN_NAMESPACE
class QNetworkReply;
-class QQuickImageBasePrivate : public QQuickImplicitSizeItemPrivate
+class Q_QUICK_PRIVATE_EXPORT QQuickImageBasePrivate : public QQuickImplicitSizeItemPrivate
{
Q_DECLARE_PUBLIC(QQuickImageBase)
@@ -75,6 +75,8 @@ public:
{
}
+ virtual bool updateDevicePixelRatio(qreal targetDevicePixelRatio);
+
QQuickPixmap pix;
QQuickImageBase::Status status;
QUrl url;
diff --git a/src/quick/items/qquickimplicitsizeitem.cpp b/src/quick/items/qquickimplicitsizeitem.cpp
index 1996fb9489..2569b2a224 100644
--- a/src/quick/items/qquickimplicitsizeitem.cpp
+++ b/src/quick/items/qquickimplicitsizeitem.cpp
@@ -45,29 +45,11 @@ QT_BEGIN_NAMESPACE
/*!
\internal
- The purpose of QQuickImplicitSizeItem is not immediately clear, as both
- the implicit size properties and signals exist on QQuickItem. However,
- for some items - where the implicit size has an underlying meaning (such as
- Image, where the implicit size represents the real size of the image)
- having implicit size writable is an undesirable thing.
-
- QQuickImplicitSizeItem redefines the properties as being readonly.
- Unfortunately, this also means they need to redefine the change signals.
- See QTBUG-30258 for more information.
+ QQuickImplicitSizeItem redefines the implicitWidth and implicitHeight
+ properties as readonly, as some items (e.g. Image, where the implicit size
+ represents the real size of the image) should not be able to have their
+ implicit size modified.
*/
-void QQuickImplicitSizeItemPrivate::implicitWidthChanged()
-{
- Q_Q(QQuickImplicitSizeItem);
- QQuickItemPrivate::implicitWidthChanged();
- emit q->implicitWidthChanged2();
-}
-
-void QQuickImplicitSizeItemPrivate::implicitHeightChanged()
-{
- Q_Q(QQuickImplicitSizeItem);
- QQuickItemPrivate::implicitHeightChanged();
- emit q->implicitHeightChanged2();
-}
QQuickImplicitSizeItem::QQuickImplicitSizeItem(QQuickImplicitSizeItemPrivate &dd, QQuickItem *parent)
: QQuickItem(dd, parent)
diff --git a/src/quick/items/qquickimplicitsizeitem_p.h b/src/quick/items/qquickimplicitsizeitem_p.h
index 75b04449f8..8ae8f9f447 100644
--- a/src/quick/items/qquickimplicitsizeitem_p.h
+++ b/src/quick/items/qquickimplicitsizeitem_p.h
@@ -60,16 +60,12 @@ class QQuickImplicitSizeItemPrivate;
class Q_QUICK_PRIVATE_EXPORT QQuickImplicitSizeItem : public QQuickItem
{
Q_OBJECT
- Q_PROPERTY(qreal implicitWidth READ implicitWidth NOTIFY implicitWidthChanged2)
- Q_PROPERTY(qreal implicitHeight READ implicitHeight NOTIFY implicitHeightChanged2)
+ Q_PROPERTY(qreal implicitWidth READ implicitWidth NOTIFY implicitWidthChanged)
+ Q_PROPERTY(qreal implicitHeight READ implicitHeight NOTIFY implicitHeightChanged)
protected:
QQuickImplicitSizeItem(QQuickImplicitSizeItemPrivate &dd, QQuickItem *parent);
-Q_SIGNALS:
- Q_REVISION(1) void implicitWidthChanged2();
- Q_REVISION(1) void implicitHeightChanged2();
-
private:
Q_DISABLE_COPY(QQuickImplicitSizeItem)
Q_DECLARE_PRIVATE(QQuickImplicitSizeItem)
diff --git a/src/quick/items/qquickimplicitsizeitem_p_p.h b/src/quick/items/qquickimplicitsizeitem_p_p.h
index 2c42fa62f2..0495cf87e1 100644
--- a/src/quick/items/qquickimplicitsizeitem_p_p.h
+++ b/src/quick/items/qquickimplicitsizeitem_p_p.h
@@ -65,9 +65,6 @@ public:
QQuickImplicitSizeItemPrivate()
{
}
-
- void implicitWidthChanged() Q_DECL_OVERRIDE;
- void implicitHeightChanged() Q_DECL_OVERRIDE;
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 8499c37010..18e0d30ed5 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -67,6 +67,7 @@
#include <QtQuick/private/qquickstate_p.h>
#include <private/qquickitem_p.h>
#include <QtQuick/private/qquickaccessibleattached_p.h>
+#include <QtQuick/private/qquickpointerhandler_p.h>
#include <private/qv4engine_p.h>
#include <private/qv4object_p.h>
@@ -165,7 +166,7 @@ void QQuickTransform::update()
}
QQuickContents::QQuickContents(QQuickItem *item)
-: m_item(item), m_x(0), m_y(0), m_width(0), m_height(0)
+: m_item(item)
{
}
@@ -180,8 +181,8 @@ QQuickContents::~QQuickContents()
bool QQuickContents::calcHeight(QQuickItem *changed)
{
- qreal oldy = m_y;
- qreal oldheight = m_height;
+ qreal oldy = m_contents.y();
+ qreal oldheight = m_contents.height();
if (changed) {
qreal top = oldy;
@@ -191,8 +192,8 @@ bool QQuickContents::calcHeight(QQuickItem *changed)
bottom = y + changed->height();
if (y < top)
top = y;
- m_y = top;
- m_height = bottom - top;
+ m_contents.setY(top);
+ m_contents.setHeight(bottom - top);
} else {
qreal top = std::numeric_limits<qreal>::max();
qreal bottom = -std::numeric_limits<qreal>::max();
@@ -206,17 +207,17 @@ bool QQuickContents::calcHeight(QQuickItem *changed)
top = y;
}
if (!children.isEmpty())
- m_y = top;
- m_height = qMax(bottom - top, qreal(0.0));
+ m_contents.setY(top);
+ m_contents.setHeight(qMax(bottom - top, qreal(0.0)));
}
- return (m_height != oldheight || m_y != oldy);
+ return (m_contents.height() != oldheight || m_contents.y() != oldy);
}
bool QQuickContents::calcWidth(QQuickItem *changed)
{
- qreal oldx = m_x;
- qreal oldwidth = m_width;
+ qreal oldx = m_contents.x();
+ qreal oldwidth = m_contents.width();
if (changed) {
qreal left = oldx;
@@ -226,8 +227,8 @@ bool QQuickContents::calcWidth(QQuickItem *changed)
right = x + changed->width();
if (x < left)
left = x;
- m_x = left;
- m_width = right - left;
+ m_contents.setX(left);
+ m_contents.setWidth(right - left);
} else {
qreal left = std::numeric_limits<qreal>::max();
qreal right = -std::numeric_limits<qreal>::max();
@@ -241,11 +242,11 @@ bool QQuickContents::calcWidth(QQuickItem *changed)
left = x;
}
if (!children.isEmpty())
- m_x = left;
- m_width = qMax(right - left, qreal(0.0));
+ m_contents.setX(left);
+ m_contents.setWidth(qMax(right - left, qreal(0.0)));
}
- return (m_width != oldwidth || m_x != oldx);
+ return (m_contents.width() != oldwidth || m_contents.x() != oldx);
}
void QQuickContents::complete()
@@ -2140,6 +2141,9 @@ void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
\value ItemAntialiasingHasChanged The antialiasing has changed. The current
(boolean) value can be found in QQuickItem::antialiasing.
+
+ \value ItemEnabledHasChanged The item's enabled state has changed.
+ ItemChangeData::boolValue contains the new enabled state. (since Qt 5.10)
*/
/*!
@@ -2486,13 +2490,13 @@ QQuickItem *QQuickItemPrivate::nextTabChildItem(const QQuickItem *item, int star
{
if (!item) {
qWarning() << "QQuickItemPrivate::nextTabChildItem called with null item.";
- return Q_NULLPTR;
+ return nullptr;
}
const QList<QQuickItem *> &children = item->childItems();
const int count = children.count();
if (start < 0 || start >= count) {
qWarning() << "QQuickItemPrivate::nextTabChildItem: Start index value out of range for item" << item;
- return Q_NULLPTR;
+ return nullptr;
}
while (start < count) {
QQuickItem *child = children.at(start);
@@ -2500,14 +2504,14 @@ QQuickItem *QQuickItemPrivate::nextTabChildItem(const QQuickItem *item, int star
return child;
++start;
}
- return Q_NULLPTR;
+ return nullptr;
}
QQuickItem *QQuickItemPrivate::prevTabChildItem(const QQuickItem *item, int start)
{
if (!item) {
qWarning() << "QQuickItemPrivate::prevTabChildItem called with null item.";
- return Q_NULLPTR;
+ return nullptr;
}
const QList<QQuickItem *> &children = item->childItems();
const int count = children.count();
@@ -2515,7 +2519,7 @@ QQuickItem *QQuickItemPrivate::prevTabChildItem(const QQuickItem *item, int star
start = count - 1;
if (start < 0 || start >= count) {
qWarning() << "QQuickItemPrivate::prevTabChildItem: Start index value out of range for item" << item;
- return Q_NULLPTR;
+ return nullptr;
}
while (start >= 0) {
QQuickItem *child = children.at(start);
@@ -2523,7 +2527,7 @@ QQuickItem *QQuickItemPrivate::prevTabChildItem(const QQuickItem *item, int star
return child;
--start;
}
- return Q_NULLPTR;
+ return nullptr;
}
QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, bool forward)
@@ -2563,8 +2567,8 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
QQuickItem *last = current;
bool hasChildren = !current->childItems().isEmpty() && current->isEnabled() && current->isVisible();
- QQuickItem *firstChild = Q_NULLPTR;
- QQuickItem *lastChild = Q_NULLPTR;
+ QQuickItem *firstChild = nullptr;
+ QQuickItem *lastChild = nullptr;
if (hasChildren) {
firstChild = nextTabChildItem(current, 0);
if (!firstChild)
@@ -2596,11 +2600,11 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
if (!current->childItems().isEmpty())
skip = true;
// back to the parent
- } else if (QQuickItem *parent = !isTabFence ? current->parentItem() : Q_NULLPTR) {
+ } else if (QQuickItem *parent = !isTabFence ? current->parentItem() : nullptr) {
// we would evaluate the parent twice, thus we skip
if (forward) {
skip = true;
- } else if (QQuickItem *firstSibling = !forward ? nextTabChildItem(parent, 0) : Q_NULLPTR) {
+ } else if (QQuickItem *firstSibling = !forward ? nextTabChildItem(parent, 0) : nullptr) {
if (last != firstSibling
|| (parent->isFocusScope() && parent->activeFocusOnTab() && parent->hasActiveFocus()))
skip = true;
@@ -2941,6 +2945,7 @@ void QQuickItemPrivate::addChild(QQuickItem *child)
if (childPrivate->subtreeHoverEnabled && !subtreeHoverEnabled)
setHasHoverInChild(true);
+ childPrivate->recursiveRefFromEffectItem(extra.value().recursiveEffectRefCount);
markSortedChildrenDirty(child);
dirty(QQuickItemPrivate::ChildrenChanged);
@@ -2969,6 +2974,7 @@ void QQuickItemPrivate::removeChild(QQuickItem *child)
if (childPrivate->subtreeHoverEnabled && subtreeHoverEnabled)
setHasHoverInChild(false);
+ childPrivate->recursiveRefFromEffectItem(-extra.value().recursiveEffectRefCount);
markSortedChildrenDirty(child);
dirty(QQuickItemPrivate::ChildrenChanged);
@@ -3190,6 +3196,11 @@ QQuickItemPrivate::QQuickItemPrivate()
, antialiasingValid(false)
, isTabFence(false)
, replayingPressEvent(false)
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ , touchEnabled(true)
+#else
+ , touchEnabled(false)
+#endif
, dirtyAttributes(0)
, nextDirtyItem(0)
, prevDirtyItem(0)
@@ -3241,7 +3252,14 @@ void QQuickItemPrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o)
} else {
if (o->inherits("QGraphicsItem"))
qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
- else {
+ else if (QQuickPointerHandler *pointerHandler = qmlobject_cast<QQuickPointerHandler *>(o)) {
+ Q_ASSERT(pointerHandler->parentItem() == that);
+ // Accept all buttons, and leave filtering to pointerEvent() and/or user JS,
+ // because there can be multiple handlers...
+ that->setAcceptedMouseButtons(Qt::AllButtons);
+ QQuickItemPrivate *p = QQuickItemPrivate::get(that);
+ p->extra.value().pointerHandlers.prepend(pointerHandler);
+ } else {
QQuickWindow *thisWindow = qmlobject_cast<QQuickWindow *>(o);
QQuickItem *item = that;
QQuickWindow *itemWindow = that->window();
@@ -5020,22 +5038,31 @@ void QQuickItemPrivate::transformChanged()
#endif
}
+bool QQuickItemPrivate::filterKeyEvent(QKeyEvent *e, bool post)
+{
+ if (!extra.isAllocated() || !extra->keyHandler)
+ return false;
+
+ if (post)
+ e->accept();
+
+ if (e->type() == QEvent::KeyPress)
+ extra->keyHandler->keyPressed(e, post);
+ else
+ extra->keyHandler->keyReleased(e, post);
+
+ return e->isAccepted();
+}
+
void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
{
Q_Q(QQuickItem);
Q_ASSERT(e->isAccepted());
- if (extra.isAllocated() && extra->keyHandler) {
- if (e->type() == QEvent::KeyPress)
- extra->keyHandler->keyPressed(e, false);
- else
- extra->keyHandler->keyReleased(e, false);
-
- if (e->isAccepted())
- return;
- else
- e->accept();
- }
+ if (filterKeyEvent(e, false))
+ return;
+ else
+ e->accept();
if (e->type() == QEvent::KeyPress)
q->keyPressEvent(e);
@@ -5045,16 +5072,7 @@ void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
if (e->isAccepted())
return;
- if (extra.isAllocated() && extra->keyHandler) {
- e->accept();
-
- if (e->type() == QEvent::KeyPress)
- extra->keyHandler->keyPressed(e, true);
- else
- extra->keyHandler->keyReleased(e, true);
- }
-
- if (e->isAccepted() || !q->window())
+ if (filterKeyEvent(e, true) || !q->window())
return;
//only care about KeyPress now
@@ -5109,6 +5127,28 @@ void QQuickItemPrivate::deliverShortcutOverrideEvent(QKeyEvent *event)
}
/*!
+ \internal
+ Deliver the \a event to all PointerHandlers which are in the pre-determined
+ eventDeliveryTargets() vector. If \a avoidExclusiveGrabber is true, it skips
+ delivery to any handler which is the exclusive grabber of any point within this event
+ (because delivery to exclusive grabbers is handled separately).
+*/
+bool QQuickItemPrivate::handlePointerEvent(QQuickPointerEvent *event, bool avoidExclusiveGrabber)
+{
+ bool delivered = false;
+ QVector<QQuickPointerHandler *> &eventDeliveryTargets = event->device()->eventDeliveryTargets();
+ if (extra.isAllocated()) {
+ for (QQuickPointerHandler *handler : extra->pointerHandlers) {
+ if ((!avoidExclusiveGrabber || !event->hasExclusiveGrabber(handler)) && !eventDeliveryTargets.contains(handler)) {
+ handler->handlePointerEvent(event);
+ delivered = true;
+ }
+ }
+ }
+ return delivered;
+}
+
+/*!
Called when \a change occurs for this item.
\a value contains extra information relating to the change, when
@@ -5939,6 +5979,7 @@ void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffec
scope, q, Qt::OtherFocusReason, QQuickWindowPrivate::DontChangeFocusProperty | QQuickWindowPrivate::DontChangeSubFocusItem);
}
+ itemChange(QQuickItem::ItemEnabledHasChanged, effectiveEnable);
emit q->enabledChanged();
}
@@ -6034,28 +6075,48 @@ void QQuickItemPrivate::removeFromDirtyList()
void QQuickItemPrivate::refFromEffectItem(bool hide)
{
++extra.value().effectRefCount;
- if (1 == extra->effectRefCount) {
+ if (extra->effectRefCount == 1) {
dirty(EffectReference);
- if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
+ if (parentItem)
+ QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
}
if (hide) {
if (++extra->hideRefCount == 1)
dirty(HideReference);
}
+ recursiveRefFromEffectItem(1);
+}
+
+void QQuickItemPrivate::recursiveRefFromEffectItem(int refs)
+{
+ Q_Q(QQuickItem);
+ if (!refs)
+ return;
+ extra.value().recursiveEffectRefCount += refs;
+ for (int ii = 0; ii < childItems.count(); ++ii) {
+ QQuickItem *child = childItems.at(ii);
+ QQuickItemPrivate::get(child)->recursiveRefFromEffectItem(refs);
+ }
+ // Polish may rely on the effect ref count so trigger one, if item is not visible
+ // (if visible, it will be triggered automatically).
+ if (!effectiveVisible && refs > 0 && extra.value().recursiveEffectRefCount == 1) // it wasn't referenced, now it's referenced
+ q->polish();
}
void QQuickItemPrivate::derefFromEffectItem(bool unhide)
{
Q_ASSERT(extra->effectRefCount);
--extra->effectRefCount;
- if (0 == extra->effectRefCount) {
+ if (extra->effectRefCount == 0) {
dirty(EffectReference);
- if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
+ if (parentItem)
+ QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
}
if (unhide) {
if (--extra->hideRefCount == 0)
dirty(HideReference);
}
+ recursiveRefFromEffectItem(-1);
}
void QQuickItemPrivate::setCulled(bool cull)
@@ -6111,6 +6172,18 @@ void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickIt
}
break;
}
+ case QQuickItem::ItemEnabledHasChanged: {
+ q->itemChange(change, data);
+ if (!changeListeners.isEmpty()) {
+ const auto listeners = changeListeners; // NOTE: intentional copy (QTBUG-54732)
+ for (const QQuickItemPrivate::ChangeListener &change : listeners) {
+ if (change.types & QQuickItemPrivate::Enabled) {
+ change.listener->itemEnabledChanged(q);
+ }
+ }
+ }
+ break;
+ }
case QQuickItem::ItemParentHasChanged: {
q->itemChange(change, data);
if (!changeListeners.isEmpty()) {
@@ -6775,8 +6848,27 @@ bool QQuickItem::heightValid() const
}
/*!
- \internal
- */
+ \since 5.10
+
+ Returns the size of the item.
+
+ \sa setSize, width, height
+ */
+
+QSizeF QQuickItem::size() const
+{
+ Q_D(const QQuickItem);
+ return QSizeF(d->width, d->height);
+}
+
+
+/*!
+ \since 5.10
+
+ Sets the size of the item to \a size.
+
+ \sa size, setWidth, setHeight
+ */
void QQuickItem::setSize(const QSizeF &size)
{
Q_D(QQuickItem);
@@ -7166,6 +7258,36 @@ void QQuickItem::setAcceptHoverEvents(bool enabled)
d->setHasHoverInChild(enabled);
}
+/*!
+ Returns whether touch events are accepted by this item.
+
+ The default value is false.
+
+ If this is false, then the item will not receive any touch events through
+ the touchEvent() function.
+
+ \since 5.10
+*/
+bool QQuickItem::acceptTouchEvents() const
+{
+ Q_D(const QQuickItem);
+ return d->touchEnabled;
+}
+
+/*!
+ If \a enabled is true, this sets the item to accept touch events;
+ otherwise, touch events are not accepted by this item.
+
+ \since 5.10
+
+ \sa acceptTouchEvents()
+*/
+void QQuickItem::setAcceptTouchEvents(bool enabled)
+{
+ Q_D(QQuickItem);
+ d->touchEnabled = enabled;
+}
+
void QQuickItemPrivate::setHasCursorInChild(bool hasCursor)
{
#if QT_CONFIG(cursor)
@@ -7328,8 +7450,8 @@ void QQuickItem::grabMouse()
windowPriv->pointerEventInstance(windowPriv->touchMouseDevice)->pointById(windowPriv->touchMouseId) :
windowPriv->pointerEventInstance(QQuickPointerDevice::genericMouseDevice())->point(0);
if (point) {
- QQuickItem *oldGrabber = point->grabber();
- point->setGrabber(this);
+ QQuickItem *oldGrabber = point->grabberItem();
+ point->setGrabberItem(this);
windowPriv->sendUngrabEvent(oldGrabber, fromTouch);
}
}
@@ -7349,7 +7471,7 @@ void QQuickItem::ungrabMouse()
if (!d->window)
return;
QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(d->window);
- windowPriv->removeGrabber(this, true, (windowPriv->touchMouseId != -1 && windowPriv->touchMouseDevice));
+ windowPriv->removeGrabber(this, true, windowPriv->isDeliveringTouchAsMouse());
}
@@ -7479,9 +7601,75 @@ void QQuickItem::setKeepTouchGrab(bool keep)
bool QQuickItem::contains(const QPointF &point) const
{
Q_D(const QQuickItem);
- qreal x = point.x();
- qreal y = point.y();
- return x >= 0 && y >= 0 && x <= d->width && y <= d->height;
+ if (d->mask) {
+ bool res = false;
+ d->extra->maskContains.invoke(d->mask,
+ Qt::DirectConnection,
+ Q_RETURN_ARG(bool, res),
+ Q_ARG(QPointF, point));
+ return res;
+ } else {
+ qreal x = point.x();
+ qreal y = point.y();
+ return x >= 0 && y >= 0 && x <= d->width && y <= d->height;
+ }
+}
+
+/*!
+ \qmlproperty QObject * QtQuick::Item::containsMask
+ \since 5.11
+ This property holds an optional mask for the Item to be used in the
+ QtQuick::Item::contains method.
+ QtQuick::Item::contains main use is currently to determine whether
+ an input event has landed into the item or not.
+
+ By default the \l contains method will return true for any point
+ within the Item's bounding box. \c containsMask allows for a
+ more fine-grained control. For example, the developer could
+ define and use an AnotherItem element as containsMask,
+ which has a specialized contains method, like:
+
+ \code
+ Item { id: item; containsMask: AnotherItem { id: anotherItem } }
+ \endcode
+
+ \e{item}'s contains method would then return true only if
+ \e{anotherItem}'s contains implementation returns true.
+*/
+QObject *QQuickItem::containsMask() const
+{
+ Q_D(const QQuickItem);
+ return d->mask.data();
+}
+
+void QQuickItem::setContainsMask(QObject *mask)
+{
+ Q_D(QQuickItem);
+ // an Item can't mask itself (to prevent infinite loop in contains())
+ if (d->mask.data() == mask || mask == static_cast<QObject *>(this))
+ return;
+
+ QQuickItem *quickMask = qobject_cast<QQuickItem *>(d->mask);
+ if (quickMask) {
+ QQuickItemPrivate *maskPrivate = QQuickItemPrivate::get(quickMask);
+ maskPrivate->registerAsContainsMask(this, false); // removed from use as my mask
+ }
+
+ if (mask) {
+ int methodIndex = mask->metaObject()->indexOfMethod(QByteArrayLiteral("contains(QPointF)"));
+ if (methodIndex < 0) {
+ qmlWarning(this) << QStringLiteral("QQuickItem: Object set as mask does not have an invokable contains method, ignoring it.");
+ return;
+ }
+ d->extra.value().maskContains = mask->metaObject()->method(methodIndex);
+ }
+ d->mask = mask;
+ quickMask = qobject_cast<QQuickItem *>(mask);
+ if (quickMask) {
+ QQuickItemPrivate *maskPrivate = QQuickItemPrivate::get(quickMask);
+ maskPrivate->registerAsContainsMask(this, true); // telling maskPrivate that "this" is using it as mask
+ }
+ emit containsMaskChanged();
}
/*!
@@ -7892,6 +8080,11 @@ QQuickItemLayer *QQuickItemPrivate::layer() const
#endif
}
+bool QQuickItemPrivate::hasPointerHandlers() const
+{
+ return extra.isAllocated() && !extra->pointerHandlers.isEmpty();
+}
+
#if QT_CONFIG(quick_shadereffect)
QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
: m_item(item)
@@ -7906,6 +8099,7 @@ QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
, m_effect(0)
, m_effectSource(0)
, m_textureMirroring(QQuickShaderEffectSource::MirrorVertically)
+ , m_samples(0)
{
}
@@ -7980,6 +8174,7 @@ void QQuickItemLayer::activate()
m_effectSource->setWrapMode(m_wrapMode);
m_effectSource->setFormat(m_format);
m_effectSource->setTextureMirroring(m_textureMirroring);
+ m_effectSource->setSamples(m_samples);
if (m_effectComponent)
activateEffect();
@@ -8273,6 +8468,44 @@ void QQuickItemLayer::setTextureMirroring(QQuickShaderEffectSource::TextureMirro
}
/*!
+ \qmlproperty enumeration QtQuick::Item::layer.samples
+ \since 5.10
+
+ This property allows requesting multisampled rendering in the layer.
+
+ By default multisampling is enabled whenever multisampling is
+ enabled for the entire window, assuming the scenegraph renderer in
+ use and the underlying graphics API supports this.
+
+ By setting the value to 2, 4, etc. multisampled rendering can be requested
+ for a part of the scene without enabling multisampling for the entire
+ scene. This way multisampling is applied only to a given subtree, which can
+ lead to significant performance gains since multisampling is not applied to
+ other parts of the scene.
+
+ \note Enabling multisampling can be potentially expensive regardless of the
+ layer's size, as it incurs a hardware and driver dependent performance and
+ memory cost.
+
+ \note This property is only functional when support for multisample
+ renderbuffers and framebuffer blits is available. Otherwise the value is
+ silently ignored.
+ */
+
+void QQuickItemLayer::setSamples(int count)
+{
+ if (m_samples == count)
+ return;
+
+ m_samples = count;
+
+ if (m_effectSource)
+ m_effectSource->setSamples(m_samples);
+
+ emit samplesChanged(count);
+}
+
+/*!
\qmlproperty string QtQuick::Item::layer.samplerName
Holds the name of the effect's source texture property.
@@ -8358,10 +8591,8 @@ void QQuickItemLayer::updateGeometry()
QQuickItem *l = m_effect ? (QQuickItem *) m_effect : (QQuickItem *) m_effectSource;
Q_ASSERT(l);
QRectF bounds = m_item->clipRect();
- l->setWidth(bounds.width());
- l->setHeight(bounds.height());
- l->setX(bounds.x() + m_item->x());
- l->setY(bounds.y() + m_item->y());
+ l->setSize(bounds.size());
+ l->setPosition(bounds.topLeft() + m_item->position());
}
void QQuickItemLayer::updateMatrix()
@@ -8391,6 +8622,7 @@ QQuickItemPrivate::ExtraData::ExtraData()
layer(0),
#endif
effectRefCount(0), hideRefCount(0),
+ recursiveEffectRefCount(0),
opacityNode(0), clipNode(0), rootNode(0),
acceptedMouseButtons(0), origin(QQuickItem::Center),
transparentForPositioner(false)
@@ -8415,25 +8647,25 @@ QAccessible::Role QQuickItemPrivate::accessibleRole() const
namespace QV4 {
namespace Heap {
struct QQuickItemWrapper : public QObjectWrapper {
+ static void markObjects(QV4::Heap::Base *that, QV4::MarkStack *markStack);
};
}
}
struct QQuickItemWrapper : public QV4::QObjectWrapper {
V4_OBJECT2(QQuickItemWrapper, QV4::QObjectWrapper)
- static void markObjects(QV4::Heap::Base *that, QV4::ExecutionEngine *e);
};
DEFINE_OBJECT_VTABLE(QQuickItemWrapper);
-void QQuickItemWrapper::markObjects(QV4::Heap::Base *that, QV4::ExecutionEngine *e)
+void QV4::Heap::QQuickItemWrapper::markObjects(QV4::Heap::Base *that, QV4::MarkStack *markStack)
{
- QObjectWrapper::Data *This = static_cast<QObjectWrapper::Data *>(that);
+ QObjectWrapper *This = static_cast<QObjectWrapper *>(that);
if (QQuickItem *item = static_cast<QQuickItem*>(This->object())) {
for (QQuickItem *child : qAsConst(QQuickItemPrivate::get(item)->childItems))
- QV4::QObjectWrapper::markWrapper(child, e);
+ QV4::QObjectWrapper::markWrapper(child, markStack);
}
- QV4::QObjectWrapper::markObjects(that, e);
+ QObjectWrapper::markObjects(that, markStack);
}
quint64 QQuickItemPrivate::_q_createJSWrapper(QV4::ExecutionEngine *engine)
diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h
index c9494d91bd..e38c276b9f 100644
--- a/src/quick/items/qquickitem.h
+++ b/src/quick/items/qquickitem.h
@@ -59,7 +59,7 @@ class Q_QUICK_EXPORT QQuickTransform : public QObject
{
Q_OBJECT
public:
- explicit QQuickTransform(QObject *parent = Q_NULLPTR);
+ explicit QQuickTransform(QObject *parent = nullptr);
~QQuickTransform();
void appendToItem(QQuickItem *);
@@ -144,6 +144,7 @@ class Q_QUICK_EXPORT QQuickItem : public QObject, public QQmlParserStatus
Q_PROPERTY(bool antialiasing READ antialiasing WRITE setAntialiasing NOTIFY antialiasingChanged RESET resetAntialiasing)
Q_PROPERTY(qreal implicitWidth READ implicitWidth WRITE setImplicitWidth NOTIFY implicitWidthChanged)
Q_PROPERTY(qreal implicitHeight READ implicitHeight WRITE setImplicitHeight NOTIFY implicitHeightChanged)
+ Q_PROPERTY(QObject *containsMask READ containsMask WRITE setContainsMask NOTIFY containsMaskChanged REVISION 11)
Q_PRIVATE_PROPERTY(QQuickItem::d_func(), QQuickItemLayer *layer READ layer DESIGNABLE false CONSTANT FINAL)
@@ -173,7 +174,8 @@ public:
ItemActiveFocusHasChanged, // value.boolValue
ItemRotationHasChanged, // value.realValue
ItemAntialiasingHasChanged, // value.boolValue
- ItemDevicePixelRatioHasChanged // value.realValue
+ ItemDevicePixelRatioHasChanged, // value.realValue
+ ItemEnabledHasChanged // value.boolValue
};
union ItemChangeData {
@@ -195,7 +197,7 @@ public:
};
Q_ENUM(TransformOrigin)
- explicit QQuickItem(QQuickItem *parent = Q_NULLPTR);
+ explicit QQuickItem(QQuickItem *parent = nullptr);
virtual ~QQuickItem();
QQuickWindow *window() const;
@@ -237,6 +239,7 @@ public:
void setImplicitHeight(qreal);
qreal implicitHeight() const;
+ QSizeF size() const;
void setSize(const QSizeF &size);
TransformOrigin transformOrigin() const;
@@ -291,6 +294,8 @@ public:
void setAcceptedMouseButtons(Qt::MouseButtons buttons);
bool acceptHoverEvents() const;
void setAcceptHoverEvents(bool enabled);
+ bool acceptTouchEvents() const;
+ void setAcceptTouchEvents(bool accept);
#if QT_CONFIG(cursor)
QCursor cursor() const;
@@ -316,6 +321,8 @@ public:
QSharedPointer<QQuickItemGrabResult> grabToImage(const QSize &targetSize = QSize());
Q_INVOKABLE virtual bool contains(const QPointF &point) const;
+ QObject *containsMask() const;
+ void setContainsMask(QObject *mask);
QTransform itemTransform(QQuickItem *, bool *) const;
QPointF mapToItem(const QQuickItem *item, const QPointF &point) const;
@@ -386,9 +393,10 @@ Q_SIGNALS:
void zChanged();
void implicitWidthChanged();
void implicitHeightChanged();
+ Q_REVISION(11) void containsMaskChanged();
protected:
- bool event(QEvent *) Q_DECL_OVERRIDE;
+ bool event(QEvent *) override;
bool isComponentComplete() const;
virtual void itemChange(ItemChange, const ItemChangeData &);
@@ -401,8 +409,8 @@ protected:
bool heightValid() const; // ### better name?
void setImplicitSize(qreal, qreal);
- void classBegin() Q_DECL_OVERRIDE;
- void componentComplete() Q_DECL_OVERRIDE;
+ void classBegin() override;
+ void componentComplete() override;
virtual void keyPressEvent(QKeyEvent *event);
virtual void keyReleaseEvent(QKeyEvent *event);
@@ -441,12 +449,13 @@ protected:
virtual void updatePolish();
protected:
- QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent = Q_NULLPTR);
+ QQuickItem(QQuickItemPrivate &dd, QQuickItem *parent = nullptr);
private:
Q_PRIVATE_SLOT(d_func(), void _q_resourceObjectDeleted(QObject *))
Q_PRIVATE_SLOT(d_func(), quint64 _q_createJSWrapper(QV4::ExecutionEngine *))
+ friend class QQuickEventPoint;
friend class QQuickWindow;
friend class QQuickWindowPrivate;
friend class QSGRenderer;
diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h
index ffb91e61eb..ee854bb2ac 100644
--- a/src/quick/items/qquickitem_p.h
+++ b/src/quick/items/qquickitem_p.h
@@ -87,6 +87,7 @@ class QQuickItemKeyFilter;
class QQuickLayoutMirroringAttached;
class QQuickEnterKeyAttached;
class QQuickScreenAttached;
+class QQuickPointerHandler;
class QQuickContents : public QQuickItemChangeListener
{
@@ -94,16 +95,16 @@ public:
QQuickContents(QQuickItem *item);
~QQuickContents();
- QRectF rectF() const { return QRectF(m_x, m_y, m_width, m_height); }
+ QRectF rectF() const { return m_contents; }
inline void calcGeometry(QQuickItem *changed = 0);
void complete();
protected:
- void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &) Q_DECL_OVERRIDE;
- void itemDestroyed(QQuickItem *item) Q_DECL_OVERRIDE;
- void itemChildAdded(QQuickItem *, QQuickItem *) Q_DECL_OVERRIDE;
- void itemChildRemoved(QQuickItem *, QQuickItem *) Q_DECL_OVERRIDE;
+ void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &) override;
+ void itemDestroyed(QQuickItem *item) override;
+ void itemChildAdded(QQuickItem *, QQuickItem *) override;
+ void itemChildRemoved(QQuickItem *, QQuickItem *) override;
//void itemVisibilityChanged(QQuickItem *item)
private:
@@ -112,10 +113,7 @@ private:
void updateRect();
QQuickItem *m_item;
- qreal m_x;
- qreal m_y;
- qreal m_width;
- qreal m_height;
+ QRectF m_contents;
};
void QQuickContents::calcGeometry(QQuickItem *changed)
@@ -152,6 +150,8 @@ class QQuickItemLayer : public QObject, public QQuickItemChangeListener
Q_PROPERTY(QByteArray samplerName READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(QQmlComponent *effect READ effect WRITE setEffect NOTIFY effectChanged)
Q_PROPERTY(QQuickShaderEffectSource::TextureMirroring textureMirroring READ textureMirroring WRITE setTextureMirroring NOTIFY textureMirroringChanged)
+ Q_PROPERTY(int samples READ samples WRITE setSamples NOTIFY samplesChanged)
+
public:
QQuickItemLayer(QQuickItem *item);
~QQuickItemLayer();
@@ -189,13 +189,16 @@ public:
QQuickShaderEffectSource::TextureMirroring textureMirroring() const { return m_textureMirroring; }
void setTextureMirroring(QQuickShaderEffectSource::TextureMirroring mirroring);
+ int samples() const { return m_samples; }
+ void setSamples(int count);
+
QQuickShaderEffectSource *effectSource() const { return m_effectSource; }
- void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) Q_DECL_OVERRIDE;
- void itemOpacityChanged(QQuickItem *) Q_DECL_OVERRIDE;
- void itemParentChanged(QQuickItem *, QQuickItem *) Q_DECL_OVERRIDE;
- void itemSiblingOrderChanged(QQuickItem *) Q_DECL_OVERRIDE;
- void itemVisibilityChanged(QQuickItem *) Q_DECL_OVERRIDE;
+ void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) override;
+ void itemOpacityChanged(QQuickItem *) override;
+ void itemParentChanged(QQuickItem *, QQuickItem *) override;
+ void itemSiblingOrderChanged(QQuickItem *) override;
+ void itemVisibilityChanged(QQuickItem *) override;
void updateMatrix();
void updateGeometry();
@@ -213,6 +216,7 @@ Q_SIGNALS:
void formatChanged(QQuickShaderEffectSource::Format format);
void sourceRectChanged(const QRectF &sourceRect);
void textureMirroringChanged(QQuickShaderEffectSource::TextureMirroring mirroring);
+ void samplesChanged(int count);
private:
friend class QQuickTransformAnimatorJob;
@@ -237,6 +241,7 @@ private:
QQuickItem *m_effect;
QQuickShaderEffectSource *m_effectSource;
QQuickShaderEffectSource::TextureMirroring m_textureMirroring;
+ int m_samples;
};
#endif
@@ -274,6 +279,8 @@ public:
QQuickItemLayer *layer() const;
+ bool hasPointerHandlers() const;
+
// data property
static void data_append(QQmlListProperty<QObject> *, QObject *);
static int data_count(QQmlListProperty<QObject> *);
@@ -316,7 +323,8 @@ public:
Children = 0x40,
Rotation = 0x80,
ImplicitWidth = 0x100,
- ImplicitHeight = 0x200
+ ImplicitHeight = 0x200,
+ Enabled = 0x400,
};
Q_DECLARE_FLAGS(ChangeTypes, ChangeType)
@@ -343,6 +351,7 @@ public:
QQuickLayoutMirroringAttached* layoutDirectionAttached;
QQuickEnterKeyAttached *enterKeyAttached;
QQuickItemKeyFilter *keyHandler;
+ QVector<QQuickPointerHandler *> pointerHandlers;
#if QT_CONFIG(quick_shadereffect)
mutable QQuickItemLayer *layer;
#endif
@@ -351,13 +360,19 @@ public:
#endif
QPointF userTransformOriginPoint;
+ // these do not include child items
int effectRefCount;
int hideRefCount;
+ // updated recursively for child items as well
+ int recursiveEffectRefCount;
QSGOpacityNode *opacityNode;
QQuickDefaultClipNode *clipNode;
QSGRootNode *rootNode;
+ // Mask contains() method
+ QMetaMethod maskContains;
+
QObjectList resourcesList;
// Although acceptedMouseButtons is inside ExtraData, we actually store
@@ -372,6 +387,10 @@ public:
// 26 bits padding
};
QLazilyAllocated<ExtraData> extra;
+ // Contains mask
+ QPointer<QObject> mask;
+ // If the mask is an Item, inform it that it's being used as a mask (true) or is no longer being used (false)
+ virtual void registerAsContainsMask(QQuickItem * /* maskedItem */, bool /* set */) { }
QQuickAnchors *anchors() const;
mutable QQuickAnchors *_anchors;
@@ -432,6 +451,7 @@ public:
// focus chain and prevents tabbing outside.
bool isTabFence:1;
bool replayingPressEvent:1;
+ bool touchEnabled:1;
enum DirtyType {
TransformOrigin = 0x00000001,
@@ -555,11 +575,14 @@ public:
virtual void transformChanged();
void deliverKeyEvent(QKeyEvent *);
+ bool filterKeyEvent(QKeyEvent *, bool post);
#if QT_CONFIG(im)
void deliverInputMethodEvent(QInputMethodEvent *);
#endif
void deliverShortcutOverrideEvent(QKeyEvent *);
+ virtual bool handlePointerEvent(QQuickPointerEvent *, bool avoidExclusiveGrabber = false);
+
virtual void setVisible(bool visible);
bool isTransparentForPositioner() const;
@@ -594,6 +617,7 @@ public:
// A reference from an effect item means that this item is used by the effect, so
// it should insert a root node.
void refFromEffectItem(bool hide);
+ void recursiveRefFromEffectItem(int refs);
void derefFromEffectItem(bool unhide);
void itemChange(QQuickItem::ItemChange, const QQuickItem::ItemChangeData &);
@@ -702,8 +726,8 @@ Q_SIGNALS:
void priorityChanged();
private:
- void keyPressed(QKeyEvent *event, bool post) Q_DECL_OVERRIDE;
- void keyReleased(QKeyEvent *event, bool post) Q_DECL_OVERRIDE;
+ void keyPressed(QKeyEvent *event, bool post) override;
+ void keyReleased(QKeyEvent *event, bool post) override;
void setFocusNavigation(QQuickItem *currentItem, const char *dir,
Qt::FocusReason reason = Qt::OtherFocusReason);
};
@@ -739,7 +763,7 @@ class QQuickEnterKeyAttached : public QObject
Q_PROPERTY(Qt::EnterKeyType type READ type WRITE setType NOTIFY typeChanged)
public:
- explicit QQuickEnterKeyAttached(QObject *parent = Q_NULLPTR);
+ explicit QQuickEnterKeyAttached(QObject *parent = nullptr);
Qt::EnterKeyType type() const;
void setType(Qt::EnterKeyType type);
@@ -807,7 +831,7 @@ public:
return QQmlListProperty<QQuickItem>(this, d->targets);
}
- void componentComplete() Q_DECL_OVERRIDE;
+ void componentComplete() override;
static QQuickKeysAttached *qmlAttachedProperties(QObject *);
@@ -859,11 +883,11 @@ Q_SIGNALS:
void volumeDownPressed(QQuickKeyEvent *event);
private:
- void keyPressed(QKeyEvent *event, bool post) Q_DECL_OVERRIDE;
- void keyReleased(QKeyEvent *event, bool post) Q_DECL_OVERRIDE;
+ void keyPressed(QKeyEvent *event, bool post) override;
+ void keyReleased(QKeyEvent *event, bool post) override;
#if QT_CONFIG(im)
- void inputMethodEvent(QInputMethodEvent *, bool post) Q_DECL_OVERRIDE;
- QVariant inputMethodQuery(Qt::InputMethodQuery query) const Q_DECL_OVERRIDE;
+ void inputMethodEvent(QInputMethodEvent *, bool post) override;
+ QVariant inputMethodQuery(Qt::InputMethodQuery query) const override;
#endif
void shortcutOverride(QKeyEvent *event) override;
static QByteArray keyToSignal(int key);
diff --git a/src/quick/items/qquickitemanimation.cpp b/src/quick/items/qquickitemanimation.cpp
index 714a1a9012..4b5c81b4d4 100644
--- a/src/quick/items/qquickitemanimation.cpp
+++ b/src/quick/items/qquickitemanimation.cpp
@@ -211,7 +211,7 @@ struct QQuickParentAnimationData : public QAbstractAnimationAction
//### reverse should probably apply on a per-action basis
bool reverse;
QList<QQuickParentChange *> pc;
- void doAction() Q_DECL_OVERRIDE
+ void doAction() override
{
for (int ii = 0; ii < actions.count(); ++ii) {
const QQuickStateAction &action = actions.at(ii);
@@ -327,7 +327,7 @@ QAbstractAnimationJob* QQuickParentAnimation::transition(QQuickStateActions &act
}
if (scale != 0)
- rotation = qAtan2(transform.m12()/scale, transform.m11()/scale) * 180/M_PI;
+ rotation = qRadiansToDegrees(qAtan2(transform.m12() / scale, transform.m11() / scale));
else {
qmlWarning(this) << QQuickParentAnimation::tr("Unable to preserve appearance under scale of 0");
ok = false;
diff --git a/src/quick/items/qquickitemanimation_p.h b/src/quick/items/qquickitemanimation_p.h
index a503cff223..3b3fad9cc4 100644
--- a/src/quick/items/qquickitemanimation_p.h
+++ b/src/quick/items/qquickitemanimation_p.h
@@ -89,7 +89,7 @@ protected:
QAbstractAnimationJob* transition(QQuickStateActions &actions,
QQmlProperties &modified,
TransitionDirection direction,
- QObject *defaultTarget = 0) Q_DECL_OVERRIDE;
+ QObject *defaultTarget = 0) override;
};
class QQuickAnchorAnimationPrivate;
@@ -121,7 +121,7 @@ protected:
QAbstractAnimationJob* transition(QQuickStateActions &actions,
QQmlProperties &modified,
TransitionDirection direction,
- QObject *defaultTarget = 0) Q_DECL_OVERRIDE;
+ QObject *defaultTarget = 0) override;
};
#if QT_CONFIG(quick_path)
@@ -188,7 +188,7 @@ protected:
QAbstractAnimationJob* transition(QQuickStateActions &actions,
QQmlProperties &modified,
TransitionDirection direction,
- QObject *defaultTarget = 0) Q_DECL_OVERRIDE;
+ QObject *defaultTarget = 0) override;
Q_SIGNALS:
void durationChanged(int);
void easingChanged(const QEasingCurve &);
diff --git a/src/quick/items/qquickitemchangelistener_p.h b/src/quick/items/qquickitemchangelistener_p.h
index 83c69a9330..cb0af75c4c 100644
--- a/src/quick/items/qquickitemchangelistener_p.h
+++ b/src/quick/items/qquickitemchangelistener_p.h
@@ -125,6 +125,7 @@ public:
virtual void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF & /* oldGeometry */) {}
virtual void itemSiblingOrderChanged(QQuickItem *) {}
virtual void itemVisibilityChanged(QQuickItem *) {}
+ virtual void itemEnabledChanged(QQuickItem *) {}
virtual void itemOpacityChanged(QQuickItem *) {}
virtual void itemDestroyed(QQuickItem *) {}
virtual void itemChildAdded(QQuickItem *, QQuickItem * /* child */ ) {}
diff --git a/src/quick/items/qquickitemgrabresult.h b/src/quick/items/qquickitemgrabresult.h
index 30f8f0c2ef..3dc10e2d75 100644
--- a/src/quick/items/qquickitemgrabresult.h
+++ b/src/quick/items/qquickitemgrabresult.h
@@ -82,7 +82,7 @@ private Q_SLOTS:
private:
friend class QQuickItem;
- QQuickItemGrabResult(QObject *parent = Q_NULLPTR);
+ QQuickItemGrabResult(QObject *parent = nullptr);
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index b411e676c2..51a91e1f7a 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -74,7 +74,9 @@
#if QT_CONFIG(quick_positioners)
#include "qquickpositioners_p.h"
#endif
+#if QT_CONFIG(quick_repeater)
#include "qquickrepeater_p.h"
+#endif
#include "qquickloader_p.h"
#if QT_CONFIG(quick_animatedimage)
#include "qquickanimatedimage_p.h"
@@ -162,6 +164,9 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
QQmlPrivate::RegisterAutoParent autoparent = { 0, &qquickitem_autoParent };
QQmlPrivate::qmlregister(QQmlPrivate::AutoParentRegistration, &autoparent);
+ // Register the latest version, even if there are no new types or new revisions for existing types yet.
+ qmlRegisterModule(uri, 2, QT_VERSION_MINOR);
+
#if !QT_CONFIG(quick_animatedimage)
qmlRegisterTypeNotAvailable(uri,major,minor,"AnimatedImage", QCoreApplication::translate("QQuickAnimatedImage","Qt was built without support for QMovie"));
#else
@@ -210,7 +215,9 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickPathView>(uri,major,minor,"PathView");
#endif
qmlRegisterType<QQuickRectangle>(uri,major,minor,"Rectangle");
+#if QT_CONFIG(quick_repeater)
qmlRegisterType<QQuickRepeater>(uri,major,minor,"Repeater");
+#endif
qmlRegisterType<QQuickTranslate>(uri,major,minor,"Translate");
qmlRegisterType<QQuickRotation>(uri,major,minor,"Rotation");
qmlRegisterType<QQuickScale>(uri,major,minor,"Scale");
@@ -383,6 +390,12 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickFlickable, 9>(uri, 2, 9, "Flickable");
qmlRegisterType<QQuickMouseArea, 9>(uri, 2, 9, "MouseArea");
+
+#if QT_CONFIG(quick_path)
+ qmlRegisterType<QQuickPathArc, 2>(uri, 2, 9, "PathArc");
+ qmlRegisterType<QQuickPathMove>(uri, 2, 9, "PathMove");
+#endif
+
qmlRegisterType<QQuickText, 9>(uri, 2, 9, "Text");
qmlRegisterType<QQuickTextInput, 9>(uri, 2, 9, "TextInput");
qmlRegisterType<QQuickTouchPoint>(uri, 2, 9, "TouchPoint");
@@ -392,6 +405,23 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterUncreatableType<QQuickBasePositioner, 9>(uri, 2, 9, "Positioner",
QStringLiteral("Positioner is an abstract type that is only available as an attached property."));
#endif
+
+#if QT_CONFIG(quick_shadereffect)
+ qmlRegisterType<QQuickShaderEffectSource, 2>(uri, 2, 9, "ShaderEffectSource");
+#endif
+
+ qmlRegisterType<QQuickFlickable, 10>(uri, 2, 10, "Flickable");
+ qmlRegisterType<QQuickTextEdit, 10>(uri, 2, 10, "TextEdit");
+ qmlRegisterType<QQuickText, 10>(uri, 2, 10, "Text");
+
+#if QT_CONFIG(quick_path)
+ qmlRegisterType<QQuickPathAngleArc>(uri, 2, 11, "PathAngleArc");
+#endif
+
+#if QT_CONFIG(quick_animatedimage)
+ qmlRegisterType<QQuickAnimatedImage, 11>(uri, 2, 11,"AnimatedImage");
+#endif
+ qmlRegisterType<QQuickItem, 11>(uri, 2, 11,"Item");
}
static void initResources()
diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h
index 622ebb430f..e250cf0ccb 100644
--- a/src/quick/items/qquickitemview_p_p.h
+++ b/src/quick/items/qquickitemview_p_p.h
@@ -201,7 +201,7 @@ public:
void regenerate(bool orientationChanged=false);
void layout();
- virtual void animationFinished(QAbstractAnimationJob *) override;
+ void animationFinished(QAbstractAnimationJob *) override;
void refill();
void refill(qreal from, qreal to);
void mirrorChange() override;
diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp
index a3e8379368..33e22c1e95 100644
--- a/src/quick/items/qquickloader.cpp
+++ b/src/quick/items/qquickloader.cpp
@@ -98,6 +98,12 @@ void QQuickLoaderPrivate::clear()
delete itemContext;
itemContext = 0;
+ // Prevent any bindings from running while waiting for deletion. Without
+ // this we may get transient errors from use of 'parent', for example.
+ QQmlContext *context = qmlContext(object);
+ if (context)
+ QQmlContextData::get(context)->invalidate();
+
if (loadingFromSource && component) {
// disconnect since we deleteLater
QObject::disconnect(component, SIGNAL(statusChanged(QQmlComponent::Status)),
@@ -353,6 +359,12 @@ void QQuickLoader::setActive(bool newVal)
d->itemContext = 0;
}
+ // Prevent any bindings from running while waiting for deletion. Without
+ // this we may get transient errors from use of 'parent', for example.
+ QQmlContext *context = qmlContext(d->object);
+ if (context)
+ QQmlContextData::get(context)->invalidate();
+
if (d->item) {
QQuickItemPrivate *p = QQuickItemPrivate::get(d->item);
p->removeItemChangeListener(d, watchedChanges);
@@ -652,7 +664,7 @@ void QQuickLoaderPrivate::setInitialState(QObject *obj)
QQmlComponentPrivate *d = QQmlComponentPrivate::get(component);
Q_ASSERT(d && d->engine);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(d->engine);
+ QV4::ExecutionEngine *v4 = d->engine->handle();
Q_ASSERT(v4);
QV4::Scope scope(v4);
QV4::ScopedValue ipv(scope, initialPropertyValues.value());
diff --git a/src/quick/items/qquickloader_p.h b/src/quick/items/qquickloader_p.h
index 8f0a9980b9..b5137c0783 100644
--- a/src/quick/items/qquickloader_p.h
+++ b/src/quick/items/qquickloader_p.h
@@ -105,8 +105,8 @@ Q_SIGNALS:
void asynchronousChanged();
protected:
- void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
- void componentComplete() Q_DECL_OVERRIDE;
+ void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;
+ void componentComplete() override;
void itemChange(ItemChange change, const ItemChangeData &value) override;
private:
diff --git a/src/quick/items/qquickloader_p_p.h b/src/quick/items/qquickloader_p_p.h
index 9b6267e011..7492527401 100644
--- a/src/quick/items/qquickloader_p_p.h
+++ b/src/quick/items/qquickloader_p_p.h
@@ -68,8 +68,8 @@ public:
QQuickLoaderIncubator(QQuickLoaderPrivate *l, IncubationMode mode) : QQmlIncubator(mode), loader(l) {}
protected:
- void statusChanged(Status) Q_DECL_OVERRIDE;
- void setInitialState(QObject *) Q_DECL_OVERRIDE;
+ void statusChanged(Status) override;
+ void setInitialState(QObject *) override;
private:
QQuickLoaderPrivate *loader;
@@ -84,9 +84,9 @@ public:
QQuickLoaderPrivate();
~QQuickLoaderPrivate();
- void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
- void itemImplicitWidthChanged(QQuickItem *) Q_DECL_OVERRIDE;
- void itemImplicitHeightChanged(QQuickItem *) Q_DECL_OVERRIDE;
+ void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &oldGeometry) override;
+ void itemImplicitWidthChanged(QQuickItem *) override;
+ void itemImplicitHeightChanged(QQuickItem *) override;
void clear();
void initResize();
void load();
@@ -97,8 +97,8 @@ public:
static QUrl resolveSourceUrl(QQmlV4Function *args);
QV4::ReturnedValue extractInitialPropertyValues(QQmlV4Function *args, QObject *loader, bool *error);
- qreal getImplicitWidth() const Q_DECL_OVERRIDE;
- qreal getImplicitHeight() const Q_DECL_OVERRIDE;
+ qreal getImplicitWidth() const override;
+ qreal getImplicitHeight() const override;
QUrl source;
QQuickItem *item;
diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp
index d8bad7d793..cea8293ceb 100644
--- a/src/quick/items/qquickmousearea.cpp
+++ b/src/quick/items/qquickmousearea.cpp
@@ -85,6 +85,7 @@ void QQuickMouseAreaPrivate::init()
{
Q_Q(QQuickMouseArea);
q->setAcceptedMouseButtons(Qt::LeftButton);
+ q->setAcceptTouchEvents(false); // rely on mouse events synthesized from touch
q->setFiltersChildMouseEvents(true);
if (qmlVisualTouchDebugging()) {
q->setFlag(QQuickItem::ItemHasContents);
@@ -98,6 +99,7 @@ void QQuickMouseAreaPrivate::saveEvent(QMouseEvent *event)
lastButton = event->button();
lastButtons = event->buttons();
lastModifiers = event->modifiers();
+ lastFlags = event->flags();
}
bool QQuickMouseAreaPrivate::isPressAndHoldConnected()
@@ -783,7 +785,7 @@ void QQuickMouseArea::mouseMoveEvent(QMouseEvent *event)
#endif
QQuickMouseEvent &me = d->quickMouseEvent;
- me.reset(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress);
+ me.reset(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress, event->flags());
me.setSource(event->source());
emit mouseXChanged(&me);
me.setPosition(d->lastPos);
@@ -826,7 +828,8 @@ void QQuickMouseArea::mouseDoubleClickEvent(QMouseEvent *event)
if (d->enabled) {
d->saveEvent(event);
QQuickMouseEvent &me = d->quickMouseEvent;
- me.reset(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, true, false);
+ me.reset(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, true,
+ false, event->flags());
me.setSource(event->source());
me.setAccepted(d->isDoubleClickConnected());
emit this->doubleClicked(&me);
@@ -1027,7 +1030,7 @@ void QQuickMouseArea::timerEvent(QTimerEvent *event)
if (d->pressed && dragged == false && d->hovered == true) {
d->longPress = true;
QQuickMouseEvent &me = d->quickMouseEvent;
- me.reset(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress);
+ me.reset(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress, d->lastFlags);
me.setSource(Qt::MouseEventSynthesizedByQt);
me.setAccepted(d->isPressAndHoldConnected());
emit pressAndHold(&me);
@@ -1206,7 +1209,7 @@ bool QQuickMouseArea::setPressed(Qt::MouseButton button, bool p, Qt::MouseEventS
if (wasPressed != p) {
QQuickMouseEvent &me = d->quickMouseEvent;
- me.reset(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, isclick, d->longPress);
+ me.reset(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, isclick, d->longPress, d->lastFlags);
me.setSource(source);
if (p) {
d->pressed |= button;
diff --git a/src/quick/items/qquickmousearea_p.h b/src/quick/items/qquickmousearea_p.h
index ee166a2082..ae6c56726e 100644
--- a/src/quick/items/qquickmousearea_p.h
+++ b/src/quick/items/qquickmousearea_p.h
@@ -164,25 +164,25 @@ protected:
bool setPressed(Qt::MouseButton button, bool p, Qt::MouseEventSource source);
bool sendMouseEvent(QMouseEvent *event);
- void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
- void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
- void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
- void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
- void mouseUngrabEvent() Q_DECL_OVERRIDE;
- void hoverEnterEvent(QHoverEvent *event) Q_DECL_OVERRIDE;
- void hoverMoveEvent(QHoverEvent *event) Q_DECL_OVERRIDE;
- void hoverLeaveEvent(QHoverEvent *event) Q_DECL_OVERRIDE;
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
+ void mouseDoubleClickEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+ void mouseUngrabEvent() override;
+ void hoverEnterEvent(QHoverEvent *event) override;
+ void hoverMoveEvent(QHoverEvent *event) override;
+ void hoverLeaveEvent(QHoverEvent *event) override;
#if QT_CONFIG(wheelevent)
- void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE;
+ void wheelEvent(QWheelEvent *event) override;
#endif
- bool childMouseEventFilter(QQuickItem *i, QEvent *e) Q_DECL_OVERRIDE;
- void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE;
- void windowDeactivateEvent() Q_DECL_OVERRIDE;
+ bool childMouseEventFilter(QQuickItem *i, QEvent *e) override;
+ void timerEvent(QTimerEvent *event) override;
+ void windowDeactivateEvent() override;
void geometryChanged(const QRectF &newGeometry,
- const QRectF &oldGeometry) Q_DECL_OVERRIDE;
- void itemChange(ItemChange change, const ItemChangeData& value) Q_DECL_OVERRIDE;
- QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE;
+ const QRectF &oldGeometry) override;
+ void itemChange(ItemChange change, const ItemChangeData& value) override;
+ QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
private:
void handlePress();
diff --git a/src/quick/items/qquickmousearea_p_p.h b/src/quick/items/qquickmousearea_p_p.h
index 2fa5f7cd44..0dd2690d43 100644
--- a/src/quick/items/qquickmousearea_p_p.h
+++ b/src/quick/items/qquickmousearea_p_p.h
@@ -61,6 +61,7 @@ QT_BEGIN_NAMESPACE
class QQuickMouseEvent;
class QQuickMouseArea;
+class QQuickPointerMask;
class QQuickMouseAreaPrivate : public QQuickItemPrivate
{
Q_DECLARE_PUBLIC(QQuickMouseArea)
@@ -99,6 +100,7 @@ public:
#if QT_CONFIG(draganddrop)
QQuickDrag *drag;
#endif
+ QPointer<QQuickPointerMask> mask;
QPointF startScene;
QPointF targetStartPos;
QPointF lastPos;
@@ -112,6 +114,7 @@ public:
#endif
QQuickMouseEvent quickMouseEvent;
QQuickWheelEvent quickWheelEvent;
+ Qt::MouseEventFlags lastFlags;
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp
index 8866ca2be5..514d0f5d37 100644
--- a/src/quick/items/qquickmultipointtoucharea.cpp
+++ b/src/quick/items/qquickmultipointtoucharea.cpp
@@ -455,6 +455,7 @@ QQuickMultiPointTouchArea::QQuickMultiPointTouchArea(QQuickItem *parent)
if (qmlVisualTouchDebugging()) {
setFlag(QQuickItem::ItemHasContents);
}
+ setAcceptTouchEvents(true);
#ifdef Q_OS_OSX
setAcceptHoverEvents(true); // needed to enable touch events on mouse hover.
#endif
@@ -527,7 +528,7 @@ void QQuickMultiPointTouchArea::setMouseEnabled(bool arg)
if (_mouseEnabled != arg) {
_mouseEnabled = arg;
if (_mouseTouchPoint && !arg)
- _mouseTouchPoint = Q_NULLPTR;
+ _mouseTouchPoint = nullptr;
emit mouseEnabledChanged();
}
}
@@ -871,7 +872,7 @@ void QQuickMultiPointTouchArea::mouseReleaseEvent(QMouseEvent *event)
updateTouchData(event);
_mouseTouchPoint->setInUse(false);
_releasedTouchPoints.removeAll(_mouseTouchPoint);
- _mouseTouchPoint = Q_NULLPTR;
+ _mouseTouchPoint = nullptr;
}
QQuickWindow *c = window();
diff --git a/src/quick/items/qquickmultipointtoucharea_p.h b/src/quick/items/qquickmultipointtoucharea_p.h
index 25e1056712..64fe81563d 100644
--- a/src/quick/items/qquickmultipointtoucharea_p.h
+++ b/src/quick/items/qquickmultipointtoucharea_p.h
@@ -265,13 +265,13 @@ Q_SIGNALS:
void mouseEnabledChanged();
protected:
- void touchEvent(QTouchEvent *) Q_DECL_OVERRIDE;
- bool childMouseEventFilter(QQuickItem *receiver, QEvent *event) Q_DECL_OVERRIDE;
- void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
- void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
- void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
- void mouseUngrabEvent() Q_DECL_OVERRIDE;
- void touchUngrabEvent() Q_DECL_OVERRIDE;
+ void touchEvent(QTouchEvent *) override;
+ bool childMouseEventFilter(QQuickItem *receiver, QEvent *event) override;
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+ void mouseUngrabEvent() override;
+ void touchUngrabEvent() override;
void addTouchPrototype(QQuickTouchPoint* prototype);
void addTouchPoint(const QTouchEvent::TouchPoint *p);
@@ -285,10 +285,10 @@ protected:
bool sendMouseEvent(QMouseEvent *event);
bool shouldFilter(QEvent *event);
void grabGesture();
- QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE;
+ QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
#ifdef Q_OS_OSX
- void hoverEnterEvent(QHoverEvent *event) Q_DECL_OVERRIDE;
- void hoverLeaveEvent(QHoverEvent *event) Q_DECL_OVERRIDE;
+ void hoverEnterEvent(QHoverEvent *event) override;
+ void hoverLeaveEvent(QHoverEvent *event) override;
void setTouchEventsEnabled(bool enable);
#endif
diff --git a/src/quick/items/qquickopenglshadereffect.cpp b/src/quick/items/qquickopenglshadereffect.cpp
index 193478484e..3194aa3cd0 100644
--- a/src/quick/items/qquickopenglshadereffect.cpp
+++ b/src/quick/items/qquickopenglshadereffect.cpp
@@ -139,7 +139,7 @@ namespace {
expected = TypeIdentifier;
break;
}
- // Fall through.
+ Q_FALLTHROUGH();
case TypeIdentifier:
typeIndex = idIndex;
typeLength = idLength;
@@ -230,7 +230,7 @@ void QQuickOpenGLShaderEffectCommon::disconnectPropertySignals(QQuickItem *item,
auto mapper = signalMappers[shaderType].at(i);
void *a = mapper;
QObjectPrivate::disconnect(item, mapper->signalIndex(), &a);
- if (d.specialType == UniformData::Sampler) {
+ if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) {
QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(d.value));
if (source) {
if (item->window())
@@ -272,7 +272,7 @@ void QQuickOpenGLShaderEffectCommon::connectPropertySignals(QQuickItem *item,
qWarning("QQuickOpenGLShaderEffect: '%s' does not have a matching property!", d.name.constData());
}
- if (d.specialType == UniformData::Sampler) {
+ if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) {
QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(d.value));
if (source) {
if (item->window())
@@ -335,6 +335,7 @@ void QQuickOpenGLShaderEffectCommon::lookThroughShaderCode(QQuickItem *item,
Q_ASSERT(decl == UniformQualifier);
const int sampLen = sizeof("sampler2D") - 1;
+ const int sampExtLen = sizeof("samplerExternalOES") - 1;
const int opLen = sizeof("qt_Opacity") - 1;
const int matLen = sizeof("qt_Matrix") - 1;
const int srLen = sizeof("qt_SubRect_") - 1;
@@ -357,8 +358,12 @@ void QQuickOpenGLShaderEffectCommon::lookThroughShaderCode(QQuickItem *item,
mapper = new QtPrivate::MappedSlotObject([this, mappedId](){
this->mappedPropertyChanged(mappedId);
});
- bool sampler = typeLength == sampLen && qstrncmp("sampler2D", s + typeIndex, sampLen) == 0;
- d.specialType = sampler ? UniformData::Sampler : UniformData::None;
+ if (typeLength == sampLen && qstrncmp("sampler2D", s + typeIndex, sampLen) == 0)
+ d.specialType = UniformData::Sampler;
+ else if (typeLength == sampExtLen && qstrncmp("samplerExternalOES", s + typeIndex, sampExtLen) == 0)
+ d.specialType = UniformData::SamplerExternal;
+ else
+ d.specialType = UniformData::None;
d.setValueFromProperty(item, itemMetaObject);
}
uniformData[shaderType].append(d);
@@ -417,8 +422,9 @@ void QQuickOpenGLShaderEffectCommon::updateShader(QQuickItem *item,
d.specialType = UniformData::Opacity;
uniformData[Key::FragmentShader].append(d);
signalMappers[Key::FragmentShader].append(0);
- const int mappedId = 1 | (Key::FragmentShader << 16);
- auto mapper = new QtPrivate::MappedSlotObject([this, mappedId](){mappedPropertyChanged(mappedId);});
+ auto mapper = new QtPrivate::MappedSlotObject([this](){
+ mappedPropertyChanged(1 | (Key::FragmentShader << 16));
+ });
const char *sourceName = "source";
d.name = sourceName;
d.setValueFromProperty(item, itemMetaObject);
@@ -451,7 +457,8 @@ void QQuickOpenGLShaderEffectCommon::updateMaterial(QQuickOpenGLShaderEffectNode
int textureProviderCount = 0;
for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) {
for (int i = 0; i < uniformData[shaderType].size(); ++i) {
- if (uniformData[shaderType].at(i).specialType == UniformData::Sampler)
+ if (uniformData[shaderType].at(i).specialType == UniformData::Sampler ||
+ uniformData[shaderType].at(i).specialType == UniformData::SamplerExternal)
++textureProviderCount;
}
material->uniforms[shaderType] = uniformData[shaderType];
@@ -474,7 +481,7 @@ void QQuickOpenGLShaderEffectCommon::updateMaterial(QQuickOpenGLShaderEffectNode
for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) {
for (int i = 0; i < uniformData[shaderType].size(); ++i) {
const UniformData &d = uniformData[shaderType].at(i);
- if (d.specialType != UniformData::Sampler)
+ if (d.specialType != UniformData::Sampler && d.specialType != UniformData::SamplerExternal)
continue;
QSGTextureProvider *oldProvider = material->textureProviders.at(index);
QSGTextureProvider *newProvider = 0;
@@ -513,7 +520,7 @@ void QQuickOpenGLShaderEffectCommon::updateWindow(QQuickWindow *window)
for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) {
for (int i = 0; i < uniformData[shaderType].size(); ++i) {
const UniformData &d = uniformData[shaderType].at(i);
- if (d.specialType == UniformData::Sampler) {
+ if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) {
QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(d.value));
if (source)
QQuickItemPrivate::get(source)->refWindow(window);
@@ -524,7 +531,7 @@ void QQuickOpenGLShaderEffectCommon::updateWindow(QQuickWindow *window)
for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) {
for (int i = 0; i < uniformData[shaderType].size(); ++i) {
const UniformData &d = uniformData[shaderType].at(i);
- if (d.specialType == UniformData::Sampler) {
+ if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) {
QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(d.value));
if (source)
QQuickItemPrivate::get(source)->derefWindow();
@@ -539,7 +546,7 @@ void QQuickOpenGLShaderEffectCommon::sourceDestroyed(QObject *object)
for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) {
for (int i = 0; i < uniformData[shaderType].size(); ++i) {
UniformData &d = uniformData[shaderType][i];
- if (d.specialType == UniformData::Sampler && d.value.canConvert<QObject *>()) {
+ if ((d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) && d.value.canConvert<QObject *>()) {
if (qvariant_cast<QObject *>(d.value) == object)
d.value = QVariant();
}
@@ -554,7 +561,7 @@ static bool qquick_uniqueInUniformData(QQuickItem *source, const QVector<QQuickO
if (s == typeToSkip && i == indexToSkip)
continue;
const QQuickOpenGLShaderEffectMaterial::UniformData &d = uniformData[s][i];
- if (d.specialType == QQuickOpenGLShaderEffectMaterial::UniformData::Sampler && qvariant_cast<QObject *>(d.value) == source)
+ if ((d.specialType == QQuickOpenGLShaderEffectMaterial::UniformData::Sampler || d.specialType == QQuickOpenGLShaderEffectMaterial::UniformData::SamplerExternal) && qvariant_cast<QObject *>(d.value) == source)
return false;
}
}
@@ -568,7 +575,7 @@ void QQuickOpenGLShaderEffectCommon::propertyChanged(QQuickItem *item,
Key::ShaderType shaderType = Key::ShaderType(mappedId >> 16);
int index = mappedId & 0xffff;
UniformData &d = uniformData[shaderType][index];
- if (d.specialType == UniformData::Sampler) {
+ if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) {
QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(d.value));
if (source) {
if (item->window())
diff --git a/src/quick/items/qquickopenglshadereffectnode.cpp b/src/quick/items/qquickopenglshadereffectnode.cpp
index e1ea98641d..a6431135eb 100644
--- a/src/quick/items/qquickopenglshadereffectnode.cpp
+++ b/src/quick/items/qquickopenglshadereffectnode.cpp
@@ -47,6 +47,10 @@
#include <QtCore/qmutex.h>
#include <QtGui/qopenglfunctions.h>
+#ifndef GL_TEXTURE_EXTERNAL_OES
+#define GL_TEXTURE_EXTERNAL_OES 0x8D65
+#endif
+
QT_BEGIN_NAMESPACE
static bool hasAtlasTexture(const QVector<QSGTextureProvider *> &textureProviders)
@@ -63,16 +67,16 @@ class QQuickCustomMaterialShader : public QSGMaterialShader
{
public:
QQuickCustomMaterialShader(const QQuickOpenGLShaderEffectMaterialKey &key, const QVector<QByteArray> &attributes);
- void deactivate() Q_DECL_OVERRIDE;
- void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) Q_DECL_OVERRIDE;
- char const *const *attributeNames() const Q_DECL_OVERRIDE;
+ void deactivate() override;
+ void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
+ char const *const *attributeNames() const override;
protected:
friend class QQuickOpenGLShaderEffectNode;
- void compile() Q_DECL_OVERRIDE;
- const char *vertexShader() const Q_DECL_OVERRIDE;
- const char *fragmentShader() const Q_DECL_OVERRIDE;
+ void compile() override;
+ const char *vertexShader() const override;
+ const char *fragmentShader() const override;
const QQuickOpenGLShaderEffectMaterialKey m_key;
QVector<QByteArray> m_attributes;
@@ -124,7 +128,7 @@ void QQuickCustomMaterialShader::updateState(const RenderState &state, QSGMateri
for (int i = 0; i < material->uniforms[shaderType].size(); ++i) {
const UniformData &d = material->uniforms[shaderType].at(i);
QByteArray name = d.name;
- if (d.specialType == UniformData::Sampler) {
+ if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) {
program()->setUniformValue(d.name.constData(), textureProviderIndex++);
// We don't need to store the sampler uniform locations, since their values
// only need to be set once. Look for the "qt_SubRect_" uniforms instead.
@@ -143,7 +147,7 @@ void QQuickCustomMaterialShader::updateState(const RenderState &state, QSGMateri
for (int i = 0; i < material->uniforms[shaderType].size(); ++i) {
const UniformData &d = material->uniforms[shaderType].at(i);
int loc = m_uniformLocs[shaderType].at(i);
- if (d.specialType == UniformData::Sampler) {
+ if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) {
int idx = textureProviderIndex++;
functions->glActiveTexture(GL_TEXTURE0 + idx);
if (QSGTextureProvider *provider = material->textureProviders.at(idx)) {
@@ -164,7 +168,10 @@ void QQuickCustomMaterialShader::updateState(const RenderState &state, QSGMateri
continue;
}
}
- functions->glBindTexture(GL_TEXTURE_2D, 0);
+ if (d.specialType == UniformData::Sampler)
+ functions->glBindTexture(GL_TEXTURE_2D, 0);
+ else if (d.specialType == UniformData::SamplerExternal)
+ functions->glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
} else if (d.specialType == UniformData::Opacity) {
program()->setUniformValue(loc, state.opacity());
} else if (d.specialType == UniformData::Matrix) {
@@ -396,7 +403,7 @@ bool QQuickOpenGLShaderEffectMaterial::UniformData::operator == (const UniformDa
if (name != other.name)
return false;
- if (specialType == UniformData::Sampler) {
+ if (specialType == UniformData::Sampler || specialType == UniformData::SamplerExternal) {
// We can't check the source objects as these live in the GUI thread,
// so return true here and rely on the textureProvider check for
// equality of these..
diff --git a/src/quick/items/qquickopenglshadereffectnode_p.h b/src/quick/items/qquickopenglshadereffectnode_p.h
index aea28e6612..68eece7660 100644
--- a/src/quick/items/qquickopenglshadereffectnode_p.h
+++ b/src/quick/items/qquickopenglshadereffectnode_p.h
@@ -90,7 +90,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickOpenGLShaderEffectMaterial : public QSGMateri
public:
struct UniformData
{
- enum SpecialType { None, Sampler, SubRect, Opacity, Matrix };
+ enum SpecialType { None, Sampler, SamplerExternal, SubRect, Opacity, Matrix };
QByteArray name;
QVariant value;
@@ -110,9 +110,9 @@ public:
};
explicit QQuickOpenGLShaderEffectMaterial(QQuickOpenGLShaderEffectNode *node = 0);
- QSGMaterialType *type() const Q_DECL_OVERRIDE;
- QSGMaterialShader *createShader() const Q_DECL_OVERRIDE;
- int compare(const QSGMaterial *other) const Q_DECL_OVERRIDE;
+ QSGMaterialType *type() const override;
+ QSGMaterialShader *createShader() const override;
+ int compare(const QSGMaterial *other) const override;
QVector<QByteArray> attributes;
QVector<UniformData> uniforms[QQuickOpenGLShaderEffectMaterialKey::ShaderTypeCount];
@@ -151,7 +151,7 @@ public:
QQuickOpenGLShaderEffectNode();
virtual ~QQuickOpenGLShaderEffectNode();
- void preprocess() Q_DECL_OVERRIDE;
+ void preprocess() override;
Q_SIGNALS:
void logAndStatusChanged(const QString &, int status);
diff --git a/src/quick/items/qquickpainteditem.h b/src/quick/items/qquickpainteditem.h
index e8b471ac01..66a0ea83c9 100644
--- a/src/quick/items/qquickpainteditem.h
+++ b/src/quick/items/qquickpainteditem.h
@@ -57,7 +57,7 @@ class Q_QUICK_EXPORT QQuickPaintedItem : public QQuickItem
Q_PROPERTY(QSize textureSize READ textureSize WRITE setTextureSize NOTIFY textureSizeChanged)
public:
- explicit QQuickPaintedItem(QQuickItem *parent = Q_NULLPTR);
+ explicit QQuickPaintedItem(QQuickItem *parent = nullptr);
virtual ~QQuickPaintedItem();
enum RenderTarget {
@@ -107,8 +107,8 @@ public:
virtual void paint(QPainter *painter) = 0;
- bool isTextureProvider() const Q_DECL_OVERRIDE;
- QSGTextureProvider *textureProvider() const Q_DECL_OVERRIDE;
+ bool isTextureProvider() const override;
+ QSGTextureProvider *textureProvider() const override;
Q_SIGNALS:
void fillColorChanged();
@@ -118,10 +118,10 @@ Q_SIGNALS:
void textureSizeChanged();
protected:
- QQuickPaintedItem(QQuickPaintedItemPrivate &dd, QQuickItem *parent = Q_NULLPTR);
- QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE;
- void releaseResources() Q_DECL_OVERRIDE;
- void itemChange(ItemChange, const ItemChangeData &) Q_DECL_OVERRIDE;
+ QQuickPaintedItem(QQuickPaintedItemPrivate &dd, QQuickItem *parent = nullptr);
+ QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
+ void releaseResources() override;
+ void itemChange(ItemChange, const ItemChangeData &) override;
private Q_SLOTS:
void invalidateSceneGraph();
diff --git a/src/quick/items/qquickpathview_p_p.h b/src/quick/items/qquickpathview_p_p.h
index d58c986d1a..274086ea7c 100644
--- a/src/quick/items/qquickpathview_p_p.h
+++ b/src/quick/items/qquickpathview_p_p.h
@@ -153,7 +153,6 @@ public:
bool moving : 1;
bool flicking : 1;
bool dragging : 1;
- bool requestedOnPath : 1;
bool inRequest : 1;
bool delegateValidated : 1;
bool inRefill : 1;
diff --git a/src/quick/items/qquickpincharea.cpp b/src/quick/items/qquickpincharea.cpp
index 3f6ce7b8ba..9f10705449 100644
--- a/src/quick/items/qquickpincharea.cpp
+++ b/src/quick/items/qquickpincharea.cpp
@@ -288,6 +288,7 @@ QQuickPinchArea::QQuickPinchArea(QQuickItem *parent)
{
Q_D(QQuickPinchArea);
d->init();
+ setAcceptTouchEvents(true);
#ifdef Q_OS_OSX
setAcceptHoverEvents(true); // needed to enable touch events on mouse hover.
#endif
@@ -643,7 +644,8 @@ bool QQuickPinchArea::childMouseEventFilter(QQuickItem *i, QEvent *e)
return QQuickItem::childMouseEventFilter(i, e);
switch (e->type()) {
case QEvent::TouchBegin:
- clearPinch(); // fall through
+ clearPinch();
+ Q_FALLTHROUGH();
case QEvent::TouchUpdate: {
QTouchEvent *touch = static_cast<QTouchEvent*>(e);
d->touchPoints.clear();
diff --git a/src/quick/items/qquickpincharea_p.h b/src/quick/items/qquickpincharea_p.h
index fc96594a4b..2363f1e2d4 100644
--- a/src/quick/items/qquickpincharea_p.h
+++ b/src/quick/items/qquickpincharea_p.h
@@ -286,13 +286,13 @@ Q_SIGNALS:
Q_REVISION(1) void smartZoom(QQuickPinchEvent *pinch);
protected:
- bool childMouseEventFilter(QQuickItem *i, QEvent *e) Q_DECL_OVERRIDE;
- void touchEvent(QTouchEvent *event) Q_DECL_OVERRIDE;
+ bool childMouseEventFilter(QQuickItem *i, QEvent *e) override;
+ void touchEvent(QTouchEvent *event) override;
void geometryChanged(const QRectF &newGeometry,
- const QRectF &oldGeometry) Q_DECL_OVERRIDE;
- void itemChange(ItemChange change, const ItemChangeData& value) Q_DECL_OVERRIDE;
- bool event(QEvent *) Q_DECL_OVERRIDE;
+ const QRectF &oldGeometry) override;
+ void itemChange(ItemChange change, const ItemChangeData& value) override;
+ bool event(QEvent *) override;
private:
void clearPinch();
diff --git a/src/quick/items/qquickpositioners.cpp b/src/quick/items/qquickpositioners.cpp
index 06b18d714b..e752e2538f 100644
--- a/src/quick/items/qquickpositioners.cpp
+++ b/src/quick/items/qquickpositioners.cpp
@@ -44,9 +44,6 @@
#include <QtQml/qqmlinfo.h>
#include <QtCore/qcoreapplication.h>
-#include <QtQuick/private/qquickstate_p.h>
-#include <QtQuick/private/qquickstategroup_p.h>
-#include <private/qquickstatechangescript_p.h>
#include <QtQuick/private/qquicktransition_p.h>
QT_BEGIN_NAMESPACE
@@ -1137,7 +1134,7 @@ public:
: QQuickBasePositionerPrivate()
{}
- void effectiveLayoutDirectionChange()
+ void effectiveLayoutDirectionChange() override
{
Q_Q(QQuickRow);
// For RTL layout the positioning changes when the width changes.
@@ -1436,7 +1433,7 @@ public:
: QQuickBasePositionerPrivate()
{}
- void effectiveLayoutDirectionChange()
+ void effectiveLayoutDirectionChange() override
{
Q_Q(QQuickGrid);
// For RTL layout the positioning changes when the width changes.
@@ -2023,7 +2020,7 @@ public:
: QQuickBasePositionerPrivate(), flow(QQuickFlow::LeftToRight)
{}
- void effectiveLayoutDirectionChange()
+ void effectiveLayoutDirectionChange() override
{
Q_Q(QQuickFlow);
// Don't postpone, as it might be the only trigger for visible changes.
diff --git a/src/quick/items/qquickpositioners_p.h b/src/quick/items/qquickpositioners_p.h
index ae6e795794..ce583aefe8 100644
--- a/src/quick/items/qquickpositioners_p.h
+++ b/src/quick/items/qquickpositioners_p.h
@@ -58,7 +58,6 @@ QT_REQUIRE_CONFIG(quick_positioners);
#include "qquickimplicitsizeitem_p.h"
#include "qquickitemviewtransition_p.h"
-#include <QtQuick/private/qquickstate_p.h>
#include <private/qpodvector_p.h>
#include <QtCore/qobject.h>
@@ -159,10 +158,10 @@ public:
protected:
QQuickBasePositioner(QQuickBasePositionerPrivate &dd, PositionerType at, QQuickItem *parent);
- void componentComplete() Q_DECL_OVERRIDE;
- void itemChange(ItemChange, const ItemChangeData &) Q_DECL_OVERRIDE;
+ void componentComplete() override;
+ void itemChange(ItemChange, const ItemChangeData &) override;
- void updatePolish() Q_DECL_OVERRIDE;
+ void updatePolish() override;
Q_SIGNALS:
void spacingChanged();
@@ -235,8 +234,8 @@ public:
QQuickColumn(QQuickItem *parent=0);
protected:
- void doPositioning(QSizeF *contentSize) Q_DECL_OVERRIDE;
- void reportConflictingAnchors() Q_DECL_OVERRIDE;
+ void doPositioning(QSizeF *contentSize) override;
+ void reportConflictingAnchors() override;
private:
Q_DISABLE_COPY(QQuickColumn)
};
@@ -259,8 +258,8 @@ Q_SIGNALS:
void effectiveLayoutDirectionChanged();
protected:
- void doPositioning(QSizeF *contentSize) Q_DECL_OVERRIDE;
- void reportConflictingAnchors() Q_DECL_OVERRIDE;
+ void doPositioning(QSizeF *contentSize) override;
+ void reportConflictingAnchors() override;
private:
Q_DISABLE_COPY(QQuickRow)
Q_DECLARE_PRIVATE(QQuickRow)
@@ -336,8 +335,8 @@ Q_SIGNALS:
Q_REVISION(1) void verticalAlignmentChanged(VAlignment alignment);
protected:
- void doPositioning(QSizeF *contentSize) Q_DECL_OVERRIDE;
- void reportConflictingAnchors() Q_DECL_OVERRIDE;
+ void doPositioning(QSizeF *contentSize) override;
+ void reportConflictingAnchors() override;
private:
int m_rows;
@@ -378,8 +377,8 @@ Q_SIGNALS:
void effectiveLayoutDirectionChanged();
protected:
- void doPositioning(QSizeF *contentSize) Q_DECL_OVERRIDE;
- void reportConflictingAnchors() Q_DECL_OVERRIDE;
+ void doPositioning(QSizeF *contentSize) override;
+ void reportConflictingAnchors() override;
protected:
QQuickFlow(QQuickFlowPrivate &dd, QQuickItem *parent);
private:
diff --git a/src/quick/items/qquickpositioners_p_p.h b/src/quick/items/qquickpositioners_p_p.h
index 6dd84e6098..f4cb283a22 100644
--- a/src/quick/items/qquickpositioners_p_p.h
+++ b/src/quick/items/qquickpositioners_p_p.h
@@ -58,9 +58,6 @@ QT_REQUIRE_CONFIG(quick_positioners);
#include "qquickpositioners_p.h"
#include "qquickimplicitsizeitem_p_p.h"
-#include <QtQuick/private/qquickstate_p.h>
-#include <private/qquicktransitionmanager_p_p.h>
-#include <private/qquickstatechangescript_p.h>
#include <private/qlazilyallocated_p.h>
#include <QtCore/qobject.h>
@@ -125,7 +122,7 @@ public:
Qt::LayoutDirection layoutDirection;
- void mirrorChange() Q_DECL_OVERRIDE {
+ void mirrorChange() override {
effectiveLayoutDirectionChange();
}
bool isLeftToRight() const {
@@ -135,24 +132,24 @@ public:
return effectiveLayoutMirror ? layoutDirection == Qt::RightToLeft : layoutDirection == Qt::LeftToRight;
}
- void itemSiblingOrderChanged(QQuickItem* other) Q_DECL_OVERRIDE
+ void itemSiblingOrderChanged(QQuickItem* other) override
{
Q_UNUSED(other);
setPositioningDirty();
}
- void itemGeometryChanged(QQuickItem *, QQuickGeometryChange change, const QRectF &) Q_DECL_OVERRIDE
+ void itemGeometryChanged(QQuickItem *, QQuickGeometryChange change, const QRectF &) override
{
if (change.sizeChange())
setPositioningDirty();
}
- void itemVisibilityChanged(QQuickItem *) Q_DECL_OVERRIDE
+ void itemVisibilityChanged(QQuickItem *) override
{
setPositioningDirty();
}
- void itemDestroyed(QQuickItem *item) Q_DECL_OVERRIDE
+ void itemDestroyed(QQuickItem *item) override
{
Q_Q(QQuickBasePositioner);
int index = q->positionedItems.find(QQuickBasePositioner::PositionedItem(item));
diff --git a/src/quick/items/qquickrectangle.cpp b/src/quick/items/qquickrectangle.cpp
index 8ac982f74c..9308553a79 100644
--- a/src/quick/items/qquickrectangle.cpp
+++ b/src/quick/items/qquickrectangle.cpp
@@ -90,6 +90,7 @@ void QQuickPen::setWidth(qreal w)
m_width = w;
m_valid = m_color.alpha() && (qRound(m_width) >= 1 || (!m_aligned && m_width > 0));
+ static_cast<QQuickItem*>(parent())->update();
emit penChanged();
}
@@ -102,6 +103,7 @@ void QQuickPen::setColor(const QColor &c)
{
m_color = c;
m_valid = m_color.alpha() && (qRound(m_width) >= 1 || (!m_aligned && m_width > 0));
+ static_cast<QQuickItem*>(parent())->update();
emit penChanged();
}
@@ -116,6 +118,7 @@ void QQuickPen::setPixelAligned(bool aligned)
return;
m_aligned = aligned;
m_valid = m_color.alpha() && (qRound(m_width) >= 1 || (!m_aligned && m_width > 0));
+ static_cast<QQuickItem*>(parent())->update();
emit penChanged();
}
@@ -322,6 +325,9 @@ QQuickRectangle::QQuickRectangle(QQuickItem *parent)
: QQuickItem(*(new QQuickRectanglePrivate), parent)
{
setFlag(ItemHasContents);
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ setAcceptTouchEvents(false);
+#endif
}
void QQuickRectangle::doUpdate()
@@ -356,7 +362,11 @@ void QQuickRectangle::doUpdate()
QQuickPen *QQuickRectangle::border()
{
Q_D(QQuickRectangle);
- return d->getPen();
+ if (!d->pen) {
+ d->pen = new QQuickPen;
+ QQml_setParent_noEvent(d->pen, this);
+ }
+ return d->pen;
}
/*!
diff --git a/src/quick/items/qquickrectangle_p.h b/src/quick/items/qquickrectangle_p.h
index 724a06013c..52f0bc975b 100644
--- a/src/quick/items/qquickrectangle_p.h
+++ b/src/quick/items/qquickrectangle_p.h
@@ -170,7 +170,7 @@ Q_SIGNALS:
void radiusChanged();
protected:
- QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE;
+ QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
private Q_SLOTS:
void doUpdate();
diff --git a/src/quick/items/qquickrectangle_p_p.h b/src/quick/items/qquickrectangle_p_p.h
index 50d5817951..3c1aaf7661 100644
--- a/src/quick/items/qquickrectangle_p_p.h
+++ b/src/quick/items/qquickrectangle_p_p.h
@@ -70,7 +70,6 @@ public:
~QQuickRectanglePrivate()
{
- delete pen;
}
QColor color;
@@ -78,20 +77,6 @@ public:
QQuickPen *pen;
qreal radius;
static int doUpdateSlotIdx;
-
- QQuickPen *getPen() {
- if (!pen) {
- Q_Q(QQuickRectangle);
- pen = new QQuickPen;
- static int penChangedSignalIdx = -1;
- if (penChangedSignalIdx < 0)
- penChangedSignalIdx = QMetaMethod::fromSignal(&QQuickPen::penChanged).methodIndex();
- if (doUpdateSlotIdx < 0)
- doUpdateSlotIdx = QQuickRectangle::staticMetaObject.indexOfSlot("doUpdate()");
- QMetaObject::connect(pen, penChangedSignalIdx, q, doUpdateSlotIdx);
- }
- return pen;
- }
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickrendercontrol.cpp b/src/quick/items/qquickrendercontrol.cpp
index 7e995936af..58b76fa862 100644
--- a/src/quick/items/qquickrendercontrol.cpp
+++ b/src/quick/items/qquickrendercontrol.cpp
@@ -393,6 +393,8 @@ QImage QQuickRenderControl::grab()
#endif
} else if (d->window->rendererInterface()->graphicsApi() == QSGRendererInterface::Software) {
QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window);
+ cd->polishItems();
+ cd->syncSceneGraph();
QSGSoftwareRenderer *softwareRenderer = static_cast<QSGSoftwareRenderer *>(cd->renderer);
if (softwareRenderer) {
const qreal dpr = d->window->effectiveDevicePixelRatio();
@@ -402,8 +404,6 @@ QImage QQuickRenderControl::grab()
QPaintDevice *prevDev = softwareRenderer->currentPaintDevice();
softwareRenderer->setCurrentPaintDevice(&grabContent);
softwareRenderer->markDirty();
- cd->polishItems();
- cd->syncSceneGraph();
d->rc->endSync();
render();
softwareRenderer->setCurrentPaintDevice(prevDev);
diff --git a/src/quick/items/qquickrendercontrol.h b/src/quick/items/qquickrendercontrol.h
index 31ea176cc1..a626216f84 100644
--- a/src/quick/items/qquickrendercontrol.h
+++ b/src/quick/items/qquickrendercontrol.h
@@ -55,7 +55,7 @@ class Q_QUICK_EXPORT QQuickRenderControl : public QObject
Q_OBJECT
public:
- explicit QQuickRenderControl(QObject *parent = Q_NULLPTR);
+ explicit QQuickRenderControl(QObject *parent = nullptr);
~QQuickRenderControl();
void prepareThread(QThread *targetThread);
@@ -68,8 +68,8 @@ public:
QImage grab();
- static QWindow *renderWindowFor(QQuickWindow *win, QPoint *offset = Q_NULLPTR);
- virtual QWindow *renderWindow(QPoint *offset) { Q_UNUSED(offset); return Q_NULLPTR; }
+ static QWindow *renderWindowFor(QQuickWindow *win, QPoint *offset = nullptr);
+ virtual QWindow *renderWindow(QPoint *offset) { Q_UNUSED(offset); return nullptr; }
Q_SIGNALS:
void renderRequested();
diff --git a/src/quick/items/qquickrepeater_p.h b/src/quick/items/qquickrepeater_p.h
index c14c1fb8cb..39e29937f9 100644
--- a/src/quick/items/qquickrepeater_p.h
+++ b/src/quick/items/qquickrepeater_p.h
@@ -53,6 +53,10 @@
#include "qquickitem.h"
+#include <private/qtquickglobal_p.h>
+
+QT_REQUIRE_CONFIG(quick_repeater);
+
QT_BEGIN_NAMESPACE
class QQmlChangeSet;
@@ -94,8 +98,8 @@ private:
void regenerate();
protected:
- void componentComplete() Q_DECL_OVERRIDE;
- void itemChange(ItemChange change, const ItemChangeData &value) Q_DECL_OVERRIDE;
+ void componentComplete() override;
+ void itemChange(ItemChange change, const ItemChangeData &value) override;
private Q_SLOTS:
void createdItem(int index, QObject *item);
diff --git a/src/quick/items/qquickrepeater_p_p.h b/src/quick/items/qquickrepeater_p_p.h
index 64380688c9..942f428904 100644
--- a/src/quick/items/qquickrepeater_p_p.h
+++ b/src/quick/items/qquickrepeater_p_p.h
@@ -56,6 +56,8 @@
#include <QtCore/qpointer.h>
+QT_REQUIRE_CONFIG(quick_repeater);
+
QT_BEGIN_NAMESPACE
class QQmlContext;
diff --git a/src/quick/items/qquickscreen.cpp b/src/quick/items/qquickscreen.cpp
index 9b54b7fba9..6a3eab957e 100644
--- a/src/quick/items/qquickscreen.cpp
+++ b/src/quick/items/qquickscreen.cpp
@@ -100,6 +100,27 @@ QT_BEGIN_NAMESPACE
The y coordinate of the screen within the virtual desktop.
*/
/*!
+ \qmlattachedproperty string Screen::manufacturer
+ \readonly
+ \since 5.10
+
+ The manufacturer of the screen.
+*/
+/*!
+ \qmlattachedproperty string Screen::model
+ \readonly
+ \since 5.10
+
+ The model of the screen.
+*/
+/*!
+ \qmlattachedproperty string Screen::serialNumber
+ \readonly
+ \since 5.10
+
+ The serial number of the screen.
+*/
+/*!
\qmlattachedproperty int Screen::width
\readonly
@@ -234,6 +255,27 @@ QString QQuickScreenInfo::name() const
return m_screen->name();
}
+QString QQuickScreenInfo::manufacturer() const
+{
+ if (!m_screen)
+ return QString();
+ return m_screen->manufacturer();
+}
+
+QString QQuickScreenInfo::model() const
+{
+ if (!m_screen)
+ return QString();
+ return m_screen->model();
+}
+
+QString QQuickScreenInfo::serialNumber() const
+{
+ if (!m_screen)
+ return QString();
+ return m_screen->serialNumber();
+}
+
int QQuickScreenInfo::width() const
{
if (!m_screen)
@@ -335,6 +377,12 @@ void QQuickScreenInfo::setWrappedScreen(QScreen *screen)
}
if (!oldScreen || screen->name() != oldScreen->name())
emit nameChanged();
+ if (!oldScreen || screen->manufacturer() != oldScreen->manufacturer())
+ emit manufacturerChanged();
+ if (!oldScreen || screen->model() != oldScreen->model())
+ emit modelChanged();
+ if (!oldScreen || screen->serialNumber() != oldScreen->serialNumber())
+ emit serialNumberChanged();
if (!oldScreen || screen->orientation() != oldScreen->orientation())
emit orientationChanged();
if (!oldScreen || screen->primaryOrientation() != oldScreen->primaryOrientation())
diff --git a/src/quick/items/qquickscreen_p.h b/src/quick/items/qquickscreen_p.h
index 99e1466631..e9db07d14c 100644
--- a/src/quick/items/qquickscreen_p.h
+++ b/src/quick/items/qquickscreen_p.h
@@ -68,6 +68,9 @@ class Q_AUTOTEST_EXPORT QQuickScreenInfo : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
+ Q_PROPERTY(QString manufacturer READ manufacturer NOTIFY manufacturerChanged REVISION 10)
+ Q_PROPERTY(QString model READ model NOTIFY modelChanged REVISION 10)
+ Q_PROPERTY(QString serialNumber READ serialNumber NOTIFY serialNumberChanged REVISION 10)
Q_PROPERTY(int width READ width NOTIFY widthChanged)
Q_PROPERTY(int height READ height NOTIFY heightChanged)
Q_PROPERTY(int desktopAvailableWidth READ desktopAvailableWidth NOTIFY desktopGeometryChanged)
@@ -87,6 +90,9 @@ public:
QQuickScreenInfo(QObject *parent = nullptr, QScreen *wrappedScreen = nullptr);
QString name() const;
+ QString manufacturer() const;
+ QString model() const;
+ QString serialNumber() const;
int width() const;
int height() const;
int desktopAvailableWidth() const;
@@ -104,6 +110,9 @@ public:
Q_SIGNALS:
void nameChanged();
+ Q_REVISION(10) void manufacturerChanged();
+ Q_REVISION(10) void modelChanged();
+ Q_REVISION(10) void serialNumberChanged();
void widthChanged();
void heightChanged();
void desktopGeometryChanged();
diff --git a/src/quick/items/qquickshadereffect.cpp b/src/quick/items/qquickshadereffect.cpp
index 8f0866f417..592485d6fa 100644
--- a/src/quick/items/qquickshadereffect.cpp
+++ b/src/quick/items/qquickshadereffect.cpp
@@ -876,7 +876,7 @@ void QQuickShaderEffectPrivate::updatePolish()
#if QT_CONFIG(opengl)
bool QQuickShaderEffect::isOpenGLShaderEffect() const
{
- return m_glImpl != Q_NULLPTR;
+ return m_glImpl != nullptr;
}
#endif
diff --git a/src/quick/items/qquickshadereffectmesh_p.h b/src/quick/items/qquickshadereffectmesh_p.h
index aa3112b5a5..f3ac956f60 100644
--- a/src/quick/items/qquickshadereffectmesh_p.h
+++ b/src/quick/items/qquickshadereffectmesh_p.h
@@ -95,10 +95,10 @@ class QQuickGridMesh : public QQuickShaderEffectMesh
Q_PROPERTY(QSize resolution READ resolution WRITE setResolution NOTIFY resolutionChanged)
public:
QQuickGridMesh(QObject *parent = 0);
- bool validateAttributes(const QVector<QByteArray> &attributes, int *posIndex) Q_DECL_OVERRIDE;
+ bool validateAttributes(const QVector<QByteArray> &attributes, int *posIndex) override;
QSGGeometry *updateGeometry(QSGGeometry *geometry, int attrCount, int posIndex,
- const QRectF &srcRect, const QRectF &rect) Q_DECL_OVERRIDE;
- QString log() const Q_DECL_OVERRIDE { return m_log; }
+ const QRectF &srcRect, const QRectF &rect) override;
+ QString log() const override { return m_log; }
void setResolution(const QSize &res);
QSize resolution() const;
diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp
index 6b1b16618a..b4a45431c5 100644
--- a/src/quick/items/qquickshadereffectsource.cpp
+++ b/src/quick/items/qquickshadereffectsource.cpp
@@ -87,7 +87,7 @@ public:
: texture(t)
, provider(p)
{}
- void run() Q_DECL_OVERRIDE {
+ void run() override {
delete texture;
delete provider;
}
@@ -189,6 +189,7 @@ QQuickShaderEffectSource::QQuickShaderEffectSource(QQuickItem *parent)
, m_sourceItem(0)
, m_textureSize(0, 0)
, m_format(RGBA)
+ , m_samples(0)
, m_live(true)
, m_hideSource(false)
, m_mipmap(false)
@@ -582,6 +583,44 @@ void QQuickShaderEffectSource::setTextureMirroring(TextureMirroring mirroring)
}
/*!
+ \qmlproperty int QtQuick::ShaderEffectSource::samples
+ \since 5.10
+
+ This property allows requesting multisampled rendering.
+
+ By default multisampling is enabled whenever multisampling is enabled for
+ the entire window, assuming the scenegraph renderer in use and the
+ underlying graphics API supports this.
+
+ By setting the value to 2, 4, etc. multisampled rendering can be requested
+ for a part of the scene without enabling multisampling for the entire
+ scene. This way multisampling is applied only to a given subtree, which can
+ lead to significant performance gains since multisampling is not applied to
+ other parts of the scene.
+
+ \note Enabling multisampling can be potentially expensive regardless of the
+ layer's size, as it incurs a hardware and driver dependent performance and
+ memory cost.
+
+ \note This property is only functional when support for multisample
+ renderbuffers and framebuffer blits is available. Otherwise the value is
+ silently ignored.
+ */
+int QQuickShaderEffectSource::samples() const
+{
+ return m_samples;
+}
+
+void QQuickShaderEffectSource::setSamples(int count)
+{
+ if (count == m_samples)
+ return;
+ m_samples = count;
+ update();
+ emit samplesChanged();
+}
+
+/*!
\qmlmethod QtQuick::ShaderEffectSource::scheduleUpdate()
Schedules a re-rendering of the texture for the next frame.
@@ -683,6 +722,7 @@ QSGNode *QQuickShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaint
m_texture->setHasMipmaps(m_mipmap);
m_texture->setMirrorHorizontal(m_textureMirroring & MirrorHorizontally);
m_texture->setMirrorVertical(m_textureMirroring & MirrorVertically);
+ m_texture->setSamples(m_samples);
if (m_grab)
m_texture->scheduleUpdate();
diff --git a/src/quick/items/qquickshadereffectsource_p.h b/src/quick/items/qquickshadereffectsource_p.h
index 5e7e354feb..185c5179b6 100644
--- a/src/quick/items/qquickshadereffectsource_p.h
+++ b/src/quick/items/qquickshadereffectsource_p.h
@@ -88,6 +88,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickShaderEffectSource : public QQuickItem, publi
Q_PROPERTY(bool mipmap READ mipmap WRITE setMipmap NOTIFY mipmapChanged)
Q_PROPERTY(bool recursive READ recursive WRITE setRecursive NOTIFY recursiveChanged)
Q_PROPERTY(TextureMirroring textureMirroring READ textureMirroring WRITE setTextureMirroring NOTIFY textureMirroringChanged REVISION 1)
+ Q_PROPERTY(int samples READ samples WRITE setSamples NOTIFY samplesChanged REVISION 2)
public:
enum WrapMode {
@@ -145,11 +146,14 @@ public:
TextureMirroring textureMirroring() const;
void setTextureMirroring(TextureMirroring mirroring);
- bool isTextureProvider() const Q_DECL_OVERRIDE { return true; }
- QSGTextureProvider *textureProvider() const Q_DECL_OVERRIDE;
+ bool isTextureProvider() const override { return true; }
+ QSGTextureProvider *textureProvider() const override;
Q_INVOKABLE void scheduleUpdate();
+ int samples() const;
+ void setSamples(int count);
+
Q_SIGNALS:
void wrapModeChanged();
void sourceItemChanged();
@@ -161,6 +165,7 @@ Q_SIGNALS:
void mipmapChanged();
void recursiveChanged();
void textureMirroringChanged();
+ void samplesChanged();
void scheduledUpdateCompleted();
@@ -169,11 +174,11 @@ private Q_SLOTS:
void invalidateSceneGraph();
protected:
- void releaseResources() Q_DECL_OVERRIDE;
- QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE;
+ void releaseResources() override;
+ QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
- void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &) Q_DECL_OVERRIDE;
- void itemChange(ItemChange change, const ItemChangeData &value) Q_DECL_OVERRIDE;
+ void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &) override;
+ void itemChange(ItemChange change, const ItemChangeData &value) override;
private:
void ensureTexture();
@@ -185,6 +190,7 @@ private:
QRectF m_sourceRect;
QSize m_textureSize;
Format m_format;
+ int m_samples;
uint m_live : 1;
uint m_hideSource : 1;
uint m_mipmap : 1;
diff --git a/src/quick/items/qquicksprite.cpp b/src/quick/items/qquicksprite.cpp
index aae657b749..42b8fb8174 100644
--- a/src/quick/items/qquicksprite.cpp
+++ b/src/quick/items/qquicksprite.cpp
@@ -40,6 +40,7 @@
#include "qquicksprite_p.h"
#include <qqml.h>
#include <QDebug>
+#include <QRandomGenerator>
QT_BEGIN_NAMESPACE
@@ -236,12 +237,12 @@ int QQuickSprite::variedDuration() const //Deals with precedence when multiple d
if (m_frameRate != unsetDuration) {
qreal fpms = (m_frameRate
- + (m_frameRateVariation * ((qreal)qrand()/RAND_MAX) * 2)
+ + (m_frameRateVariation * QRandomGenerator::global()->generateDouble() * 2)
- m_frameRateVariation) / 1000.0;
return qMax(qreal(0.0) , m_frames / fpms);
} else if (m_frameDuration != unsetDuration) {
int mspf = m_frameDuration
- + (m_frameDurationVariation * ((qreal)qrand()/RAND_MAX) * 2)
+ + (m_frameDurationVariation * QRandomGenerator::global()->generateDouble() * 2)
- m_frameDurationVariation;
return qMax(0, m_frames * mspf);
} else if (duration() >= 0) {
diff --git a/src/quick/items/qquicksprite_p.h b/src/quick/items/qquicksprite_p.h
index d68a45ecc0..2f7f6da5c0 100644
--- a/src/quick/items/qquicksprite_p.h
+++ b/src/quick/items/qquicksprite_p.h
@@ -161,7 +161,7 @@ public:
return m_frameDurationVariation;
}
- int variedDuration() const Q_DECL_OVERRIDE;
+ int variedDuration() const override;
bool frameSync() const
{
diff --git a/src/quick/items/qquickspriteengine.cpp b/src/quick/items/qquickspriteengine.cpp
index 92b60a8e3a..1fd15e61e3 100644
--- a/src/quick/items/qquickspriteengine.cpp
+++ b/src/quick/items/qquickspriteengine.cpp
@@ -43,6 +43,7 @@
#include <qqml.h>
#include <QDebug>
#include <QPainter>
+#include <QRandomGenerator>
#include <QSet>
#include <QtGui/qopengl.h>
#include <QOpenGLFunctions>
@@ -543,7 +544,7 @@ void QQuickStochasticEngine::restart(int index)
if (m_addAdvance)
m_startTimes[index] += m_advanceTime.elapsed();
if (randomStart)
- m_startTimes[index] -= qrand() % m_duration.at(index);
+ m_startTimes[index] -= QRandomGenerator::global()->bounded(m_duration.at(index));
int time = m_duration.at(index) + m_startTimes.at(index);
for (int i=0; i<m_stateUpdates.count(); i++)
m_stateUpdates[i].second.removeAll(index);
@@ -557,13 +558,13 @@ void QQuickSpriteEngine::restart(int index) //Reimplemented to recognize and han
if (m_loaded && m_sprites.at(m_things.at(index))->frameSync()) {//Manually advanced
m_startTimes[index] = 0;
if (randomStart && m_sprites.at(m_things.at(index))->m_generatedCount)
- m_startTimes[index] += qrand() % m_sprites.at(m_things.at(index))->m_generatedCount;
+ m_startTimes[index] += QRandomGenerator::global()->bounded(m_sprites.at(m_things.at(index))->m_generatedCount);
} else {
m_startTimes[index] = m_timeOffset;
if (m_addAdvance)
m_startTimes[index] += m_advanceTime.elapsed();
if (randomStart)
- m_startTimes[index] -= qrand() % m_duration.at(index);
+ m_startTimes[index] -= QRandomGenerator::global()->bounded(m_duration.at(index));
int time = spriteDuration(index) + m_startTimes.at(index);
if (randomStart) {
int curTime = m_timeOffset + (m_addAdvance ? m_advanceTime.elapsed() : 0);
@@ -629,7 +630,7 @@ int QQuickStochasticEngine::nextState(int curState, int curThing)
int nextIdx = -1;
int goalPath = goalSeek(curState, curThing);
if (goalPath == -1){//Random
- qreal r =(qreal) qrand() / (qreal) RAND_MAX;
+ qreal r = QRandomGenerator::global()->generateDouble();
qreal total = 0.0;
for (QVariantMap::const_iterator iter=m_states.at(curState)->m_to.constBegin();
iter!=m_states.at(curState)->m_to.constEnd(); ++iter)
@@ -719,7 +720,7 @@ int QQuickStochasticEngine::goalSeek(int curIdx, int spriteIdx, int dist)
if (options.count()==1)
return *(options.begin());
int option = -1;
- qreal r =(qreal) qrand() / (qreal) RAND_MAX;
+ qreal r = QRandomGenerator::global()->generateDouble();
qreal total = 0;
for (QSet<int>::const_iterator iter=options.constBegin();
iter!=options.constEnd(); ++iter)
diff --git a/src/quick/items/qquickspriteengine_p.h b/src/quick/items/qquickspriteengine_p.h
index 90ee68b2f6..ff02135799 100644
--- a/src/quick/items/qquickspriteengine_p.h
+++ b/src/quick/items/qquickspriteengine_p.h
@@ -63,6 +63,7 @@ QT_REQUIRE_CONFIG(quick_sprite);
#include <QQmlListProperty>
#include <QImage>
#include <QPair>
+#include <QRandomGenerator>
#include <private/qquickpixmapcache_p.h>
#include <private/qtquickglobal_p.h>
@@ -112,7 +113,7 @@ public:
virtual int variedDuration() const
{
return qMax(qreal(0.0) , m_duration
- + (m_durationVariation * ((qreal)qrand()/RAND_MAX) * 2)
+ + (m_durationVariation * QRandomGenerator::global()->bounded(2.0))
- m_durationVariation);
}
@@ -289,8 +290,8 @@ public:
int spriteCount() const;//Like state count
int maxFrames() const;
- void restart(int index=0) Q_DECL_OVERRIDE;
- void advance(int index=0) Q_DECL_OVERRIDE;
+ void restart(int index=0) override;
+ void advance(int index=0) override;
//Similar API to QQuickPixmap for async loading convenience
bool isNull() const { return status() == QQuickPixmap::Null; }
diff --git a/src/quick/items/qquickspritesequence_p.h b/src/quick/items/qquickspritesequence_p.h
index b80a8348aa..ffcefecaec 100644
--- a/src/quick/items/qquickspritesequence_p.h
+++ b/src/quick/items/qquickspritesequence_p.h
@@ -105,7 +105,7 @@ private Q_SLOTS:
protected:
void reset();
- QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE;
+ QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
private:
void prepareNextFrame(QSGSpriteNode *node);
QSGSpriteNode* initNode();
diff --git a/src/quick/items/qquickstateoperations.cpp b/src/quick/items/qquickstateoperations.cpp
index b40a9e2843..386bb058b5 100644
--- a/src/quick/items/qquickstateoperations.cpp
+++ b/src/quick/items/qquickstateoperations.cpp
@@ -101,7 +101,7 @@ void QQuickParentChangePrivate::doChange(QQuickItem *targetParent, QQuickItem *s
}
if (scale != 0)
- rotation = qAtan2(transform.m12()/scale, transform.m11()/scale) * 180/M_PI;
+ rotation = qRadiansToDegrees(qAtan2(transform.m12() / scale, transform.m11() / scale));
else {
qmlWarning(q) << QQuickParentChange::tr("Unable to preserve appearance under scale of 0");
ok = false;
@@ -510,7 +510,7 @@ QQuickStateActionEvent::EventType QQuickParentChange::type() const
return ParentChange;
}
-bool QQuickParentChange::override(QQuickStateActionEvent*other)
+bool QQuickParentChange::mayOverride(QQuickStateActionEvent*other)
{
Q_D(QQuickParentChange);
if (other->type() != ParentChange)
@@ -1302,7 +1302,7 @@ void QQuickAnchorChanges::clearBindings()
}
}
-bool QQuickAnchorChanges::override(QQuickStateActionEvent*other)
+bool QQuickAnchorChanges::mayOverride(QQuickStateActionEvent*other)
{
if (other->type() != AnchorChanges)
return false;
diff --git a/src/quick/items/qquickstateoperations_p.h b/src/quick/items/qquickstateoperations_p.h
index 48b4b23a76..d61ed294cb 100644
--- a/src/quick/items/qquickstateoperations_p.h
+++ b/src/quick/items/qquickstateoperations_p.h
@@ -110,17 +110,17 @@ public:
void setRotation(QQmlScriptString rotation);
bool rotationIsSet() const;
- ActionList actions() Q_DECL_OVERRIDE;
+ ActionList actions() override;
- void saveOriginals() Q_DECL_OVERRIDE;
+ void saveOriginals() override;
//virtual void copyOriginals(QQuickStateActionEvent*);
- void execute() Q_DECL_OVERRIDE;
- bool isReversable() Q_DECL_OVERRIDE;
- void reverse() Q_DECL_OVERRIDE;
- EventType type() const Q_DECL_OVERRIDE;
- bool override(QQuickStateActionEvent*other) Q_DECL_OVERRIDE;
- void rewind() Q_DECL_OVERRIDE;
- void saveCurrentValues() Q_DECL_OVERRIDE;
+ void execute() override;
+ bool isReversable() override;
+ void reverse() override;
+ EventType type() const override;
+ bool mayOverride(QQuickStateActionEvent*other) override;
+ void rewind() override;
+ void saveCurrentValues() override;
};
class QQuickAnchorChanges;
@@ -190,28 +190,28 @@ public:
QQuickAnchorChanges(QObject *parent=0);
~QQuickAnchorChanges();
- ActionList actions() Q_DECL_OVERRIDE;
+ ActionList actions() override;
QQuickAnchorSet *anchors() const;
QQuickItem *object() const;
void setObject(QQuickItem *);
- void execute() Q_DECL_OVERRIDE;
- bool isReversable() Q_DECL_OVERRIDE;
- void reverse() Q_DECL_OVERRIDE;
- EventType type() const Q_DECL_OVERRIDE;
- bool override(QQuickStateActionEvent*other) Q_DECL_OVERRIDE;
- bool changesBindings() Q_DECL_OVERRIDE;
- void saveOriginals() Q_DECL_OVERRIDE;
- bool needsCopy() Q_DECL_OVERRIDE { return true; }
- void copyOriginals(QQuickStateActionEvent*) Q_DECL_OVERRIDE;
- void clearBindings() Q_DECL_OVERRIDE;
- void rewind() Q_DECL_OVERRIDE;
- void saveCurrentValues() Q_DECL_OVERRIDE;
+ void execute() override;
+ bool isReversable() override;
+ void reverse() override;
+ EventType type() const override;
+ bool mayOverride(QQuickStateActionEvent*other) override;
+ bool changesBindings() override;
+ void saveOriginals() override;
+ bool needsCopy() override { return true; }
+ void copyOriginals(QQuickStateActionEvent*) override;
+ void clearBindings() override;
+ void rewind() override;
+ void saveCurrentValues() override;
QList<QQuickStateAction> additionalActions() const;
- void saveTargetValues() Q_DECL_OVERRIDE;
+ void saveTargetValues() override;
};
QT_END_NAMESPACE
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index 6d73af80fe..d601087296 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -80,11 +80,7 @@ QQuickTextPrivate::QQuickTextPrivate()
, elideMode(QQuickText::ElideNone), hAlign(QQuickText::AlignLeft), vAlign(QQuickText::AlignTop)
, format(QQuickText::AutoText), wrapMode(QQuickText::NoWrap)
, style(QQuickText::Normal)
-#if defined(QT_QUICK_DEFAULT_TEXT_RENDER_TYPE)
- , renderType(QQuickText::QT_QUICK_DEFAULT_TEXT_RENDER_TYPE)
-#else
- , renderType(QQuickText::QtRendering)
-#endif
+ , renderType(QQuickTextUtil::textRenderType<QQuickText>())
, updateType(UpdatePaintNode)
, maximumLineCountValid(false), updateOnComponentComplete(true), richText(false)
, styledText(false), widthExceeded(false), heightExceeded(false), internalWidthUpdate(false)
@@ -269,9 +265,6 @@ void QQuickTextPrivate::updateLayout()
formatModifiesFontSize = fontSizeModified;
multilengthEos = -1;
} else {
- layout.clearFormats();
- if (elideLayout)
- elideLayout->clearFormats();
QString tmp = text;
multilengthEos = tmp.indexOf(QLatin1Char('\x9c'));
if (multilengthEos != -1)
@@ -359,8 +352,8 @@ void QQuickTextPrivate::updateSize()
}
if (!requireImplicitSize) {
- emit q->implicitWidthChanged();
- emit q->implicitHeightChanged();
+ implicitWidthChanged();
+ implicitHeightChanged();
// if the implicitWidth is used, then updateSize() has already been called (recursively)
if (requireImplicitSize)
return;
@@ -384,6 +377,7 @@ void QQuickTextPrivate::updateSize()
updateBaseline(fm.ascent(), q->height() - fontHeight - vPadding);
q->setImplicitSize(hPadding, fontHeight + vPadding);
layedOutTextRect = QRectF(0, 0, 0, fontHeight);
+ advance = QSizeF();
emit q->contentSizeChanged();
updateType = UpdatePaintNode;
q->update();
@@ -457,8 +451,26 @@ void QQuickTextPrivate::updateSize()
if (iWidth == -1)
q->setImplicitHeight(size.height() + vPadding);
+
+ QTextBlock firstBlock = extra->doc->firstBlock();
+ while (firstBlock.layout()->lineCount() == 0)
+ firstBlock = firstBlock.next();
+
+ QTextBlock lastBlock = extra->doc->lastBlock();
+ while (lastBlock.layout()->lineCount() == 0)
+ lastBlock = lastBlock.previous();
+
+ if (firstBlock.lineCount() > 0 && lastBlock.lineCount() > 0) {
+ QTextLine firstLine = firstBlock.layout()->lineAt(0);
+ QTextLine lastLine = lastBlock.layout()->lineAt(lastBlock.layout()->lineCount() - 1);
+ advance = QSizeF(lastLine.horizontalAdvance(),
+ (lastLine.y() + lastBlock.layout()->position().y()) - (firstLine.y() + firstBlock.layout()->position().y()));
+ } else {
+ advance = QSizeF();
+ }
}
+
if (layedOutTextRect.size() != previousSize)
emit q->contentSizeChanged();
updateType = UpdatePaintNode;
@@ -613,6 +625,13 @@ QString QQuickTextPrivate::elidedText(qreal lineWidth, const QTextLine &line, QT
}
}
+void QQuickTextPrivate::clearFormats()
+{
+ layout.clearFormats();
+ if (elideLayout)
+ elideLayout->clearFormats();
+}
+
/*!
Lays out the QQuickTextPrivate::layout QTextLayout in the constraints of the QQuickText.
@@ -968,6 +987,16 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
br.moveTop(0);
+ // Find the advance of the text layout
+ if (layout.lineCount() > 0) {
+ QTextLine firstLine = layout.lineAt(0);
+ QTextLine lastLine = layout.lineAt(layout.lineCount() - 1);
+ advance = QSizeF(lastLine.horizontalAdvance(),
+ lastLine.y() - firstLine.y());
+ } else {
+ advance = QSizeF();
+ }
+
if (!horizontalFit && !verticalFit)
break;
@@ -1026,12 +1055,15 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
if (eos != multilengthEos)
truncated = true;
+ assignedFont = QFontInfo(font).family();
+
if (elide) {
if (!elideLayout) {
elideLayout = new QTextLayout;
elideLayout->setCacheEnabled(true);
}
- if (styledText) {
+ QTextEngine *engine = layout.engine();
+ if (engine && engine->hasFormats()) {
QVector<QTextLayout::FormatRange> formats;
switch (elideMode) {
case QQuickText::ElideRight:
@@ -1470,6 +1502,36 @@ QQuickText::~QQuickText()
Text { text: "Hello"; renderType: Text.NativeRendering; font.hintingPreference: Font.PreferVerticalHinting }
\endqml
*/
+
+/*!
+ \qmlproperty bool QtQuick::Text::font.kerning
+ \since 5.10
+
+ Enables or disables the kerning OpenType feature when shaping the text. Disabling this may
+ improve performance when creating or changing the text, at the expense of some cosmetic
+ features. The default value is true.
+
+ \qml
+ Text { text: "OATS FLAVOUR WAY"; font.kerning: false }
+ \endqml
+*/
+
+/*!
+ \qmlproperty bool QtQuick::Text::font.preferShaping
+ \since 5.10
+
+ Sometimes, a font will apply complex rules to a set of characters in order to
+ display them correctly. In some writing systems, such as Brahmic scripts, this is
+ required in order for the text to be legible, but in e.g. Latin script, it is merely
+ a cosmetic feature. Setting the \c preferShaping property to false will disable all
+ such features when they are not required, which will improve performance in most cases.
+
+ The default value is true.
+
+ \qml
+ Text { text: "Some text"; font.preferShaping: false }
+ \endqml
+*/
QFont QQuickText::font() const
{
Q_D(const QQuickText);
@@ -1570,6 +1632,7 @@ void QQuickText::setText(const QString &n)
d->extra->doc->setText(n);
d->rightToLeftText = d->extra->doc->toPlainText().isRightToLeft();
} else {
+ d->clearFormats();
d->rightToLeftText = d->text.isRightToLeft();
}
d->determineHorizontalAlignment();
@@ -2060,6 +2123,7 @@ void QQuickText::setTextFormat(TextFormat format)
d->extra->doc->setText(d->text);
d->rightToLeftText = d->extra->doc->toPlainText().isRightToLeft();
} else {
+ d->clearFormats();
d->rightToLeftText = d->text.isRightToLeft();
d->textHasChanged = true;
}
@@ -2365,6 +2429,12 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data
void QQuickText::updatePolish()
{
Q_D(QQuickText);
+ // If the fonts used for rendering are different from the ones used in the GUI thread,
+ // it means we will get warnings and corrupted text. If this case is detected, we need
+ // to update the text layout before creating the scenegraph nodes.
+ if (!d->assignedFont.isEmpty() && QFontInfo(d->font).family() != d->assignedFont)
+ d->polishSize = true;
+
if (d->polishSize) {
d->updateSize();
d->polishSize = false;
@@ -2770,7 +2840,7 @@ void QQuickText::hoverLeaveEvent(QHoverEvent *event)
Supported render types are:
\list
- \li Text.QtRendering - the default
+ \li Text.QtRendering
\li Text.NativeRendering
\endlist
@@ -2778,6 +2848,8 @@ void QQuickText::hoverLeaveEvent(QHoverEvent *event)
not require advanced features such as transformation of the text. Using such features in
combination with the NativeRendering render type will lend poor and sometimes pixelated
results.
+
+ The default rendering type is determined by \l QQuickWindow::textRenderType().
*/
QQuickText::RenderType QQuickText::renderType() const
{
@@ -3055,6 +3127,24 @@ QJSValue QQuickText::fontInfo() const
return value;
}
+/*!
+ \qmlproperty size QtQuick::Text::advance
+ \since 5.10
+
+ The distance, in pixels, from the baseline origin of the first
+ character of the text item, to the baseline origin of the first
+ character in a text item occurring directly after this one
+ in a text flow.
+
+ Note that the advance can be negative if the text flows from
+ the right to the left.
+*/
+QSizeF QQuickText::advance() const
+{
+ Q_D(const QQuickText);
+ return d->advance;
+}
+
QT_END_NAMESPACE
#include "moc_qquicktext_p.cpp"
diff --git a/src/quick/items/qquicktext_p.h b/src/quick/items/qquicktext_p.h
index b190738cfb..6c48dd86a9 100644
--- a/src/quick/items/qquicktext_p.h
+++ b/src/quick/items/qquicktext_p.h
@@ -99,6 +99,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickText : public QQuickImplicitSizeItem
Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6)
Q_PROPERTY(QJSValue fontInfo READ fontInfo NOTIFY fontInfoChanged REVISION 9)
+ Q_PROPERTY(QSizeF advance READ advance NOTIFY contentSizeChanged REVISION 10)
public:
QQuickText(QQuickItem *parent=0);
@@ -211,15 +212,15 @@ public:
FontSizeMode fontSizeMode() const;
void setFontSizeMode(FontSizeMode mode);
- void componentComplete() Q_DECL_OVERRIDE;
+ void componentComplete() override;
int resourcesLoading() const; // mainly for testing
qreal contentWidth() const;
qreal contentHeight() const;
- QRectF boundingRect() const Q_DECL_OVERRIDE;
- QRectF clipRect() const Q_DECL_OVERRIDE;
+ QRectF boundingRect() const override;
+ QRectF clipRect() const override;
Q_INVOKABLE void doLayout(); // ### Qt 6: remove
Q_REVISION(9) Q_INVOKABLE void forceLayout();
@@ -251,6 +252,7 @@ public:
void resetBottomPadding();
QJSValue fontInfo() const;
+ QSizeF advance() const;
Q_SIGNALS:
void textChanged(const QString &text);
@@ -289,18 +291,18 @@ Q_SIGNALS:
protected:
QQuickText(QQuickTextPrivate &dd, QQuickItem *parent = 0);
- void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
- void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
- void itemChange(ItemChange change, const ItemChangeData &value) Q_DECL_OVERRIDE;
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
+ void itemChange(ItemChange change, const ItemChangeData &value) override;
void geometryChanged(const QRectF &newGeometry,
- const QRectF &oldGeometry) Q_DECL_OVERRIDE;
- QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE;
+ const QRectF &oldGeometry) override;
+ QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
- void updatePolish() Q_DECL_OVERRIDE;
+ void updatePolish() override;
- void hoverEnterEvent(QHoverEvent *event) Q_DECL_OVERRIDE;
- void hoverMoveEvent(QHoverEvent *event) Q_DECL_OVERRIDE;
- void hoverLeaveEvent(QHoverEvent *event) Q_DECL_OVERRIDE;
+ void hoverEnterEvent(QHoverEvent *event) override;
+ void hoverMoveEvent(QHoverEvent *event) override;
+ void hoverLeaveEvent(QHoverEvent *event) override;
void invalidateFontCaches();
private Q_SLOTS:
diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h
index 6456750359..6fd0876a5f 100644
--- a/src/quick/items/qquicktext_p_p.h
+++ b/src/quick/items/qquicktext_p_p.h
@@ -78,17 +78,19 @@ public:
void updateLayout();
bool determineHorizontalAlignment();
bool setHAlign(QQuickText::HAlignment, bool forceAlign = false);
- void mirrorChange() Q_DECL_OVERRIDE;
+ void mirrorChange() override;
bool isLineLaidOutConnected();
void setLineGeometry(QTextLine &line, qreal lineWidth, qreal &height);
int lineHeightOffset() const;
QString elidedText(qreal lineWidth, const QTextLine &line, QTextLine *nextLine = 0) const;
void elideFormats(int start, int length, int offset, QVector<QTextLayout::FormatRange> *elidedFormats);
+ void clearFormats();
void processHoverEvent(QHoverEvent *event);
QRectF layedOutTextRect;
+ QSizeF advance;
struct ExtraData {
ExtraData();
@@ -152,6 +154,8 @@ public:
QQuickText::RenderType renderType;
UpdateType updateType;
+ QString assignedFont;
+
bool maximumLineCountValid:1;
bool updateOnComponentComplete:1;
bool richText:1;
@@ -173,8 +177,8 @@ public:
static const QChar elideChar;
- qreal getImplicitWidth() const Q_DECL_OVERRIDE;
- qreal getImplicitHeight() const Q_DECL_OVERRIDE;
+ qreal getImplicitWidth() const override;
+ qreal getImplicitHeight() const override;
qreal availableWidth() const;
qreal availableHeight() const;
diff --git a/src/quick/items/qquicktextcontrol_p.h b/src/quick/items/qquicktextcontrol_p.h
index 70104a97e0..862a81af28 100644
--- a/src/quick/items/qquicktextcontrol_p.h
+++ b/src/quick/items/qquicktextcontrol_p.h
@@ -177,9 +177,9 @@ public:
bool cursorOn() const;
protected:
- void timerEvent(QTimerEvent *e) Q_DECL_OVERRIDE;
+ void timerEvent(QTimerEvent *e) override;
- bool event(QEvent *e) Q_DECL_OVERRIDE;
+ bool event(QEvent *e) override;
private:
Q_DISABLE_COPY(QQuickTextControl)
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index 3714af2bc3..10abc1176a 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -45,7 +45,6 @@
#include "qquickwindow.h"
#include "qquicktextnode_p.h"
#include "qquicktextnodeengine_p.h"
-#include "qquicktextutil_p.h"
#include <QtCore/qmath.h>
#include <QtGui/qguiapplication.h>
@@ -356,6 +355,36 @@ QString QQuickTextEdit::text() const
*/
/*!
+ \qmlproperty bool QtQuick::TextEdit::font.kerning
+ \since 5.10
+
+ Enables or disables the kerning OpenType feature when shaping the text. Disabling this may
+ improve performance when creating or changing the text, at the expense of some cosmetic
+ features. The default value is true.
+
+ \qml
+ TextEdit { text: "OATS FLAVOUR WAY"; kerning: font.false }
+ \endqml
+*/
+
+/*!
+ \qmlproperty bool QtQuick::TextEdit::font.preferShaping
+ \since 5.10
+
+ Sometimes, a font will apply complex rules to a set of characters in order to
+ display them correctly. In some writing systems, such as Brahmic scripts, this is
+ required in order for the text to be legible, but in e.g. Latin script, it is merely
+ a cosmetic feature. Setting the \c preferShaping property to false will disable all
+ such features when they are not required, which will improve performance in most cases.
+
+ The default value is true.
+
+ \qml
+ TextEdit { text: "Some text"; font.preferShaping: false }
+ \endqml
+*/
+
+/*!
\qmlproperty string QtQuick::TextEdit::text
The text to display. If the text format is AutoText the text edit will
@@ -482,7 +511,7 @@ void QQuickTextEdit::setTextFormat(TextFormat format)
Supported render types are:
\list
- \li Text.QtRendering - the default
+ \li Text.QtRendering
\li Text.NativeRendering
\endlist
@@ -490,6 +519,8 @@ void QQuickTextEdit::setTextFormat(TextFormat format)
not require advanced features such as transformation of the text. Using such features in
combination with the NativeRendering render type will lend poor and sometimes pixelated
results.
+
+ The default rendering type is determined by \l QQuickWindow::textRenderType().
*/
QQuickTextEdit::RenderType QQuickTextEdit::renderType() const
{
@@ -1937,12 +1968,11 @@ void QQuickTextEdit::triggerPreprocess()
}
typedef QQuickTextEditPrivate::Node TextNode;
-typedef QList<TextNode*>::iterator TextNodeIterator;
-
+using TextNodeIterator = QQuickTextEditPrivate::TextNodeIterator;
-static bool comesBefore(TextNode* n1, TextNode* n2)
+static inline bool operator<(const TextNode &n1, const TextNode &n2)
{
- return n1->startPos() < n2->startPos();
+ return n1.startPos() < n2.startPos();
}
static inline void updateNodeTransform(QQuickTextNode* node, const QPointF &topLeft)
@@ -1995,13 +2025,12 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
if (!oldNode) {
// If we had any QQuickTextNode node references, they were deleted along with the root node
// But here we must delete the Node structures in textNodeMap
- qDeleteAll(d->textNodeMap);
d->textNodeMap.clear();
}
RootNode *rootNode = static_cast<RootNode *>(oldNode);
TextNodeIterator nodeIterator = d->textNodeMap.begin();
- while (nodeIterator != d->textNodeMap.end() && !(*nodeIterator)->dirty())
+ while (nodeIterator != d->textNodeMap.end() && !nodeIterator->dirty())
++nodeIterator;
QQuickTextNodeEngine engine;
@@ -2014,13 +2043,12 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
int firstDirtyPos = 0;
if (nodeIterator != d->textNodeMap.end()) {
- firstDirtyPos = (*nodeIterator)->startPos();
+ firstDirtyPos = nodeIterator->startPos();
do {
- rootNode->removeChildNode((*nodeIterator)->textNode());
- delete (*nodeIterator)->textNode();
- delete *nodeIterator;
+ rootNode->removeChildNode(nodeIterator->textNode());
+ delete nodeIterator->textNode();
nodeIterator = d->textNodeMap.erase(nodeIterator);
- } while (nodeIterator != d->textNodeMap.end() && (*nodeIterator)->dirty());
+ } while (nodeIterator != d->textNodeMap.end() && nodeIterator->dirty());
}
// FIXME: the text decorations could probably be handled separately (only updated for affected textFrames)
@@ -2037,7 +2065,8 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
rootNode->setMatrix(basePositionMatrix);
QPointF nodeOffset;
- TextNode *firstCleanNode = (nodeIterator != d->textNodeMap.end()) ? *nodeIterator : 0;
+ const TextNode firstCleanNode = (nodeIterator != d->textNodeMap.end()) ? *nodeIterator
+ : TextNode();
QList<QTextFrame *> frames;
frames.append(d->document->rootFrame());
@@ -2047,7 +2076,8 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
frames.append(textFrame->childFrames());
frameDecorationsEngine.addFrameDecorations(d->document, textFrame);
- if (textFrame->lastPosition() < firstDirtyPos || (firstCleanNode && textFrame->firstPosition() >= firstCleanNode->startPos()))
+ if (textFrame->lastPosition() < firstDirtyPos
+ || textFrame->firstPosition() >= firstCleanNode.startPos())
continue;
node = d->createTextNode();
resetEngine(&engine, d->color, d->selectedTextColor, d->selectionColor);
@@ -2087,8 +2117,8 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
engine.addTextBlock(d->document, block, -nodeOffset, d->color, QColor(), selectionStart(), selectionEnd() - 1);
currentNodeSize += block.length();
- if ((it.atEnd()) || (firstCleanNode && block.next().position() >= firstCleanNode->startPos())) // last node that needed replacing or last block of the frame
- break;
+ if ((it.atEnd()) || block.next().position() >= firstCleanNode.startPos())
+ break; // last node that needed replacing or last block of the frame
QList<int>::const_iterator lowerBound = std::lower_bound(frameBoundaries.constBegin(), frameBoundaries.constEnd(), block.next().position());
if (currentNodeSize > nodeBreakingSize || lowerBound == frameBoundaries.constEnd() || *lowerBound > nodeStart) {
@@ -2106,16 +2136,19 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
// Now prepend the frame decorations since we want them rendered first, with the text nodes and cursor in front.
rootNode->prependChildNode(rootNode->frameDecorationsNode);
- Q_ASSERT(nodeIterator == d->textNodeMap.end() || (*nodeIterator) == firstCleanNode);
+ Q_ASSERT(nodeIterator == d->textNodeMap.end()
+ || (nodeIterator->textNode() == firstCleanNode.textNode()
+ && nodeIterator->startPos() == firstCleanNode.startPos()));
// Update the position of the subsequent text blocks.
- if (firstCleanNode) {
- QPointF oldOffset = firstCleanNode->textNode()->matrix().map(QPointF(0,0));
- QPointF currentOffset = d->document->documentLayout()->blockBoundingRect(d->document->findBlock(firstCleanNode->startPos())).topLeft();
+ if (firstCleanNode.textNode() != nullptr) {
+ QPointF oldOffset = firstCleanNode.textNode()->matrix().map(QPointF(0,0));
+ QPointF currentOffset = d->document->documentLayout()->blockBoundingRect(
+ d->document->findBlock(firstCleanNode.startPos())).topLeft();
QPointF delta = currentOffset - oldOffset;
while (nodeIterator != d->textNodeMap.end()) {
- QMatrix4x4 transformMatrix = (*nodeIterator)->textNode()->matrix();
+ QMatrix4x4 transformMatrix = nodeIterator->textNode()->matrix();
transformMatrix.translate(delta.x(), delta.y());
- (*nodeIterator)->textNode()->setMatrix(transformMatrix);
+ nodeIterator->textNode()->setMatrix(transformMatrix);
++nodeIterator;
}
@@ -2123,7 +2156,7 @@ QSGNode *QQuickTextEdit::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *
// Since we iterate over blocks from different text frames that are potentially not sorted
// we need to ensure that our list of nodes is sorted again:
- std::sort(d->textNodeMap.begin(), d->textNodeMap.end(), &comesBefore);
+ std::sort(d->textNodeMap.begin(), d->textNodeMap.end());
}
if (d->cursorComponent == 0) {
@@ -2302,22 +2335,26 @@ void QQuickTextEdit::markDirtyNodesForRange(int start, int end, int charDelta)
if (start == end)
return;
- TextNode dummyNode(start, 0);
- TextNodeIterator it = std::lower_bound(d->textNodeMap.begin(), d->textNodeMap.end(), &dummyNode, &comesBefore);
+ TextNode dummyNode(start);
+
+ const TextNodeIterator textNodeMapBegin = d->textNodeMap.begin();
+ const TextNodeIterator textNodeMapEnd = d->textNodeMap.end();
+
+ TextNodeIterator it = std::lower_bound(textNodeMapBegin, textNodeMapEnd, dummyNode);
// qLowerBound gives us the first node past the start of the affected portion, rewind to the first node
// that starts at the last position before the edit position. (there might be several because of images)
- if (it != d->textNodeMap.begin()) {
+ if (it != textNodeMapBegin) {
--it;
- TextNode otherDummy((*it)->startPos(), 0);
- it = std::lower_bound(d->textNodeMap.begin(), d->textNodeMap.end(), &otherDummy, &comesBefore);
+ TextNode otherDummy(it->startPos());
+ it = std::lower_bound(textNodeMapBegin, textNodeMapEnd, otherDummy);
}
// mark the affected nodes as dirty
- while (it != d->textNodeMap.end()) {
- if ((*it)->startPos() <= end)
- (*it)->setDirty();
+ while (it != textNodeMapEnd) {
+ if (it->startPos() <= end)
+ it->setDirty();
else if (charDelta)
- (*it)->moveStartPos(charDelta);
+ it->moveStartPos(charDelta);
else
return;
++it;
@@ -2502,8 +2539,8 @@ void QQuickTextEdit::updateWholeDocument()
{
Q_D(QQuickTextEdit);
if (!d->textNodeMap.isEmpty()) {
- for (TextNode* node : qAsConst(d->textNodeMap))
- node->setDirty();
+ for (TextNode &node : d->textNodeMap)
+ node.setDirty();
}
polish();
@@ -2647,7 +2684,7 @@ void QQuickTextEditPrivate::handleFocusEvent(QFocusEvent *event)
void QQuickTextEditPrivate::addCurrentTextNodeToRoot(QQuickTextNodeEngine *engine, QSGTransformNode *root, QQuickTextNode *node, TextNodeIterator &it, int startPos)
{
engine->addToSceneGraph(node, QQuickText::Normal, QColor());
- it = textNodeMap.insert(it, new TextNode(startPos, node));
+ it = textNodeMap.insert(it, TextNode(startPos, node));
++it;
root->appendChildNode(node);
}
@@ -3038,6 +3075,32 @@ void QQuickTextEdit::resetBottomPadding()
}
/*!
+ \qmlproperty real QtQuick::TextEdit::tabStopDistance
+ \since 5.10
+
+ The default distance, in device units, between tab stops.
+
+ \sa QTextOption::setTabStop()
+*/
+int QQuickTextEdit::tabStopDistance() const
+{
+ Q_D(const QQuickTextEdit);
+ return d->document->defaultTextOption().tabStopDistance();
+}
+
+void QQuickTextEdit::setTabStopDistance(qreal distance)
+{
+ Q_D(QQuickTextEdit);
+ QTextOption textOptions = d->document->defaultTextOption();
+ if (textOptions.tabStopDistance() == distance)
+ return;
+
+ textOptions.setTabStopDistance(distance);
+ d->document->setDefaultTextOption(textOptions);
+ emit tabStopDistanceChanged(distance);
+}
+
+/*!
\qmlmethod QtQuick::TextEdit::clear()
\since 5.7
diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h
index c8d3515be1..c883e39168 100644
--- a/src/quick/items/qquicktextedit_p.h
+++ b/src/quick/items/qquicktextedit_p.h
@@ -111,6 +111,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTextEdit : public QQuickImplicitSizeItem
Q_PROPERTY(qreal rightPadding READ rightPadding WRITE setRightPadding RESET resetRightPadding NOTIFY rightPaddingChanged REVISION 6)
Q_PROPERTY(qreal bottomPadding READ bottomPadding WRITE setBottomPadding RESET resetBottomPadding NOTIFY bottomPaddingChanged REVISION 6)
Q_PROPERTY(QString preeditText READ preeditText NOTIFY preeditTextChanged REVISION 7)
+ Q_PROPERTY(qreal tabStopDistance READ tabStopDistance WRITE setTabStopDistance NOTIFY tabStopDistanceChanged REVISION 10)
public:
QQuickTextEdit(QQuickItem *parent=0);
@@ -234,7 +235,7 @@ public:
bool canUndo() const;
bool canRedo() const;
- void componentComplete() Q_DECL_OVERRIDE;
+ void componentComplete() override;
/* FROM EDIT */
void setReadOnly(bool);
@@ -243,7 +244,7 @@ public:
QRectF cursorRectangle() const;
#if QT_CONFIG(im)
- QVariant inputMethodQuery(Qt::InputMethodQuery property) const Q_DECL_OVERRIDE;
+ QVariant inputMethodQuery(Qt::InputMethodQuery property) const override;
Q_REVISION(4) Q_INVOKABLE QVariant inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const;
#endif
@@ -259,8 +260,8 @@ public:
Q_INVOKABLE void moveCursorSelection(int pos);
Q_INVOKABLE void moveCursorSelection(int pos, SelectionMode mode);
- QRectF boundingRect() const Q_DECL_OVERRIDE;
- QRectF clipRect() const Q_DECL_OVERRIDE;
+ QRectF boundingRect() const override;
+ QRectF clipRect() const override;
bool isInputMethodComposing() const;
@@ -296,6 +297,9 @@ public:
void setBottomPadding(qreal padding);
void resetBottomPadding();
+ int tabStopDistance() const;
+ void setTabStopDistance(qreal distance);
+
Q_SIGNALS:
void textChanged();
Q_REVISION(7) void preeditTextChanged();
@@ -340,6 +344,7 @@ Q_SIGNALS:
Q_REVISION(6) void leftPaddingChanged();
Q_REVISION(6) void rightPaddingChanged();
Q_REVISION(6) void bottomPaddingChanged();
+ Q_REVISION(10) void tabStopDistanceChanged(qreal distance);
public Q_SLOTS:
void selectAll();
@@ -382,28 +387,28 @@ protected:
QQuickTextEdit(QQuickTextEditPrivate &dd, QQuickItem *parent = 0);
void geometryChanged(const QRectF &newGeometry,
- const QRectF &oldGeometry) Q_DECL_OVERRIDE;
+ const QRectF &oldGeometry) override;
- bool event(QEvent *) Q_DECL_OVERRIDE;
- void keyPressEvent(QKeyEvent *) Q_DECL_OVERRIDE;
- void keyReleaseEvent(QKeyEvent *) Q_DECL_OVERRIDE;
- void focusInEvent(QFocusEvent *event) Q_DECL_OVERRIDE;
- void focusOutEvent(QFocusEvent *event) Q_DECL_OVERRIDE;
+ bool event(QEvent *) override;
+ void keyPressEvent(QKeyEvent *) override;
+ void keyReleaseEvent(QKeyEvent *) override;
+ void focusInEvent(QFocusEvent *event) override;
+ void focusOutEvent(QFocusEvent *event) override;
- void hoverEnterEvent(QHoverEvent *event) Q_DECL_OVERRIDE;
- void hoverMoveEvent(QHoverEvent *event) Q_DECL_OVERRIDE;
- void hoverLeaveEvent(QHoverEvent *event) Q_DECL_OVERRIDE;
+ void hoverEnterEvent(QHoverEvent *event) override;
+ void hoverMoveEvent(QHoverEvent *event) override;
+ void hoverLeaveEvent(QHoverEvent *event) override;
// mouse filter?
- void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
- void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
- void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
- void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
+ void mouseDoubleClickEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
#if QT_CONFIG(im)
- void inputMethodEvent(QInputMethodEvent *e) Q_DECL_OVERRIDE;
+ void inputMethodEvent(QInputMethodEvent *e) override;
#endif
- QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData) Q_DECL_OVERRIDE;
- void updatePolish() Q_DECL_OVERRIDE;
+ QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData) override;
+ void updatePolish() override;
friend class QQuickTextUtil;
friend class QQuickTextDocument;
diff --git a/src/quick/items/qquicktextedit_p_p.h b/src/quick/items/qquicktextedit_p_p.h
index 03bce00cb0..ef2bdfd0ea 100644
--- a/src/quick/items/qquicktextedit_p_p.h
+++ b/src/quick/items/qquicktextedit_p_p.h
@@ -53,11 +53,14 @@
#include "qquicktextedit_p.h"
#include "qquickimplicitsizeitem_p_p.h"
+#include "qquicktextutil_p.h"
#include <QtQml/qqml.h>
#include <QtCore/qlist.h>
#include <private/qlazilyallocated_p.h>
+#include <limits>
+
QT_BEGIN_NAMESPACE
class QTextLayout;
class QQuickTextDocumentWithImageResources;
@@ -73,7 +76,8 @@ public:
typedef QQuickTextEdit Public;
struct Node {
- explicit Node(int startPos, QQuickTextNode* node)
+ explicit Node(int startPos = std::numeric_limits<int>::max(),
+ QQuickTextNode *node = nullptr)
: m_startPos(startPos), m_node(node), m_dirty(false) { }
QQuickTextNode* textNode() const { return m_node; }
void moveStartPos(int delta) { Q_ASSERT(m_startPos + delta > 0); m_startPos += delta; }
@@ -86,7 +90,7 @@ public:
QQuickTextNode* m_node;
bool m_dirty;
};
- typedef QList<Node*>::iterator TextNodeIterator;
+ typedef QList<Node>::iterator TextNodeIterator;
struct ExtraData {
ExtraData();
@@ -112,11 +116,7 @@ public:
, quickDocument(0), lastSelectionStart(0), lastSelectionEnd(0), lineCount(0)
, hAlign(QQuickTextEdit::AlignLeft), vAlign(QQuickTextEdit::AlignTop)
, format(QQuickTextEdit::PlainText), wrapMode(QQuickTextEdit::NoWrap)
-#if defined(QT_QUICK_DEFAULT_TEXT_RENDER_TYPE)
- , renderType(QQuickTextEdit::QT_QUICK_DEFAULT_TEXT_RENDER_TYPE)
-#else
- , renderType(QQuickTextEdit::QtRendering)
-#endif
+ , renderType(QQuickTextUtil::textRenderType<QQuickTextEdit>())
, contentDirection(Qt::LayoutDirectionAuto)
, mouseSelectionMode(QQuickTextEdit::SelectCharacters)
#if QT_CONFIG(im)
@@ -131,11 +131,6 @@ public:
{
}
- ~QQuickTextEditPrivate()
- {
- qDeleteAll(textNodeMap);
- }
-
static QQuickTextEditPrivate *get(QQuickTextEdit *item) {
return static_cast<QQuickTextEditPrivate *>(QObjectPrivate::get(item)); }
@@ -146,8 +141,8 @@ public:
void relayoutDocument();
bool determineHorizontalAlignment();
bool setHAlign(QQuickTextEdit::HAlignment, bool forceAlign = false);
- void mirrorChange() Q_DECL_OVERRIDE;
- qreal getImplicitWidth() const Q_DECL_OVERRIDE;
+ void mirrorChange() override;
+ qreal getImplicitWidth() const override;
Qt::LayoutDirection textDirection(const QString &text) const;
bool isLinkHoveredConnected();
@@ -189,7 +184,7 @@ public:
QQuickTextDocumentWithImageResources *document;
QQuickTextControl *control;
QQuickTextDocument *quickDocument;
- QList<Node*> textNodeMap;
+ QList<Node> textNodeMap;
int lastSelectionStart;
int lastSelectionEnd;
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index 0c1cb7a146..557ff393b4 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -40,7 +40,6 @@
#include "qquicktextinput_p.h"
#include "qquicktextinput_p_p.h"
#include "qquickwindow.h"
-#include "qquicktextutil_p.h"
#include <private/qqmlglobal_p.h>
#include <private/qv4scopedvalue_p.h>
@@ -157,7 +156,7 @@ void QQuickTextInput::setText(const QString &s)
Supported render types are:
\list
- \li Text.QtRendering - the default
+ \li Text.QtRendering
\li Text.NativeRendering
\endlist
@@ -165,6 +164,8 @@ void QQuickTextInput::setText(const QString &s)
not require advanced features such as transformation of the text. Using such features in
combination with the NativeRendering render type will lend poor and sometimes pixelated
results.
+
+ The default rendering type is determined by \l QQuickWindow::textRenderType().
*/
QQuickTextInput::RenderType QQuickTextInput::renderType() const
{
@@ -378,6 +379,36 @@ QString QQuickTextInputPrivate::realText() const
TextInput { text: "Hello"; renderType: TextInput.NativeRendering; font.hintingPreference: Font.PreferVerticalHinting }
\endqml
*/
+
+/*!
+ \qmlproperty bool QtQuick::TextInput::font.kerning
+ \since 5.10
+
+ Enables or disables the kerning OpenType feature when shaping the text. Disabling this may
+ improve performance when creating or changing the text, at the expense of some cosmetic
+ features. The default value is true.
+
+ \qml
+ TextInput { text: "OATS FLAVOUR WAY"; font.kerning: false }
+ \endqml
+*/
+
+/*!
+ \qmlproperty bool QtQuick::TextInput::font.preferShaping
+ \since 5.10
+
+ Sometimes, a font will apply complex rules to a set of characters in order to
+ display them correctly. In some writing systems, such as Brahmic scripts, this is
+ required in order for the text to be legible, but in e.g. Latin script, it is merely
+ a cosmetic feature. Setting the \c preferShaping property to false will disable all
+ such features when they are not required, which will improve performance in most cases.
+
+ The default value is true.
+
+ \qml
+ TextInput { text: "Some text"; font.preferShaping: false }
+ \endqml
+*/
QFont QQuickTextInput::font() const
{
Q_D(const QQuickTextInput);
diff --git a/src/quick/items/qquicktextinput_p.h b/src/quick/items/qquicktextinput_p.h
index c4da807471..b7d3fb00fa 100644
--- a/src/quick/items/qquicktextinput_p.h
+++ b/src/quick/items/qquicktextinput_p.h
@@ -118,7 +118,7 @@ public:
QQuickTextInput(QQuickItem * parent=0);
~QQuickTextInput();
- void componentComplete() Q_DECL_OVERRIDE;
+ void componentComplete() override;
enum EchoMode {//To match QLineEdit::EchoMode
Normal,
@@ -267,12 +267,12 @@ public:
bool hasAcceptableInput() const;
#if QT_CONFIG(im)
- QVariant inputMethodQuery(Qt::InputMethodQuery property) const Q_DECL_OVERRIDE;
+ QVariant inputMethodQuery(Qt::InputMethodQuery property) const override;
Q_REVISION(3) Q_INVOKABLE QVariant inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const;
#endif
- QRectF boundingRect() const Q_DECL_OVERRIDE;
- QRectF clipRect() const Q_DECL_OVERRIDE;
+ QRectF boundingRect() const override;
+ QRectF clipRect() const override;
bool canPaste() const;
@@ -366,23 +366,23 @@ protected:
QQuickTextInput(QQuickTextInputPrivate &dd, QQuickItem *parent = 0);
void geometryChanged(const QRectF &newGeometry,
- const QRectF &oldGeometry) Q_DECL_OVERRIDE;
+ const QRectF &oldGeometry) override;
- void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
- void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
- void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
- void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
- void keyPressEvent(QKeyEvent* ev) Q_DECL_OVERRIDE;
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
+ void mouseDoubleClickEvent(QMouseEvent *event) override;
+ void keyPressEvent(QKeyEvent* ev) override;
#if QT_CONFIG(im)
- void inputMethodEvent(QInputMethodEvent *) Q_DECL_OVERRIDE;
+ void inputMethodEvent(QInputMethodEvent *) override;
#endif
- void mouseUngrabEvent() Q_DECL_OVERRIDE;
- bool event(QEvent *e) Q_DECL_OVERRIDE;
- void focusOutEvent(QFocusEvent *event) Q_DECL_OVERRIDE;
- void focusInEvent(QFocusEvent *event) Q_DECL_OVERRIDE;
- void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE;
- QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) Q_DECL_OVERRIDE;
- void updatePolish() Q_DECL_OVERRIDE;
+ void mouseUngrabEvent() override;
+ bool event(QEvent *e) override;
+ void focusOutEvent(QFocusEvent *event) override;
+ void focusInEvent(QFocusEvent *event) override;
+ void timerEvent(QTimerEvent *event) override;
+ QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) override;
+ void updatePolish() override;
public Q_SLOTS:
void selectAll();
diff --git a/src/quick/items/qquicktextinput_p_p.h b/src/quick/items/qquicktextinput_p_p.h
index 0bf5779a53..c795aebfa9 100644
--- a/src/quick/items/qquicktextinput_p_p.h
+++ b/src/quick/items/qquicktextinput_p_p.h
@@ -43,6 +43,7 @@
#include "qquicktextinput_p.h"
#include "qquicktext_p.h"
#include "qquickimplicitsizeitem_p_p.h"
+#include "qquicktextutil_p.h"
#include <QtQml/qqml.h>
#include <QtCore/qelapsedtimer.h>
@@ -122,11 +123,7 @@ public:
, vAlign(QQuickTextInput::AlignTop)
, wrapMode(QQuickTextInput::NoWrap)
, m_echoMode(QQuickTextInput::Normal)
-#if defined(QT_QUICK_DEFAULT_TEXT_RENDER_TYPE)
- , renderType(QQuickTextInput::QT_QUICK_DEFAULT_TEXT_RENDER_TYPE)
-#else
- , renderType(QQuickTextInput::QtRendering)
-#endif
+ , renderType(QQuickTextUtil::textRenderType<QQuickTextInput>())
, updateType(UpdatePaintNode)
, mouseSelectionMode(QQuickTextInput::SelectCharacters)
, m_layoutDirection(Qt::LayoutDirectionAuto)
@@ -175,7 +172,7 @@ public:
void updateVerticalScroll();
bool determineHorizontalAlignment();
bool setHAlign(QQuickTextInput::HAlignment, bool forceAlign = false);
- void mirrorChange() Q_DECL_OVERRIDE;
+ void mirrorChange() override;
bool sendMouseEventToInputContext(QMouseEvent *event);
#if QT_CONFIG(im)
Qt::InputMethodHints effectiveInputMethodHints() const;
@@ -454,7 +451,7 @@ public:
void updateLayout();
void updateBaselineOffset();
- qreal getImplicitWidth() const Q_DECL_OVERRIDE;
+ qreal getImplicitWidth() const override;
inline qreal padding() const { return extra.isAllocated() ? extra->padding : 0.0; }
void setTopPadding(qreal value, bool reset = false);
diff --git a/src/quick/items/qquicktextutil_p.h b/src/quick/items/qquicktextutil_p.h
index 01055c95ec..bad5e738a8 100644
--- a/src/quick/items/qquicktextutil_p.h
+++ b/src/quick/items/qquicktextutil_p.h
@@ -54,6 +54,7 @@
#include <QtQml/qqml.h>
#include <QtQml/qqmlincubator.h>
#include <QtQuick/qquickitem.h>
+#include <QtQuick/qquickwindow.h>
QT_BEGIN_NAMESPACE
@@ -64,6 +65,7 @@ public:
template <typename Private> static void setCursorDelegate(Private *d, QQmlComponent *delegate);
template <typename Private> static void createCursor(Private *d);
+ template <typename T> static typename T::RenderType textRenderType();
static qreal alignedX(qreal textWidth, qreal itemWidth, int alignment);
static qreal alignedY(qreal textHeight, qreal itemHeight, int alignment);
@@ -124,6 +126,20 @@ void QQuickTextUtil::createCursor(Private *d)
parent->update();
}
+template <typename T>
+typename T::RenderType QQuickTextUtil::textRenderType()
+{
+ switch (QQuickWindow::textRenderType()) {
+ case QQuickWindow::QtTextRendering:
+ return T::QtRendering;
+ case QQuickWindow::NativeTextRendering:
+ return T::NativeRendering;
+ }
+
+ Q_UNREACHABLE();
+ return T::QtRendering;
+}
+
QT_END_NAMESPACE
#endif
diff --git a/src/quick/items/qquicktranslate_p.h b/src/quick/items/qquicktranslate_p.h
index 1bceba20cf..b0199cef40 100644
--- a/src/quick/items/qquicktranslate_p.h
+++ b/src/quick/items/qquicktranslate_p.h
@@ -75,7 +75,7 @@ public:
qreal y() const;
void setY(qreal);
- void applyTo(QMatrix4x4 *matrix) const Q_DECL_OVERRIDE;
+ void applyTo(QMatrix4x4 *matrix) const override;
Q_SIGNALS:
void xChanged();
@@ -111,7 +111,7 @@ public:
qreal zScale() const;
void setZScale(qreal);
- void applyTo(QMatrix4x4 *matrix) const Q_DECL_OVERRIDE;
+ void applyTo(QMatrix4x4 *matrix) const override;
Q_SIGNALS:
void originChanged();
@@ -146,7 +146,7 @@ public:
void setAxis(const QVector3D &axis);
void setAxis(Qt::Axis axis);
- void applyTo(QMatrix4x4 *matrix) const Q_DECL_OVERRIDE;
+ void applyTo(QMatrix4x4 *matrix) const override;
Q_SIGNALS:
void originChanged();
@@ -170,7 +170,7 @@ public:
QMatrix4x4 matrix() const;
void setMatrix(const QMatrix4x4& matrix);
- void applyTo(QMatrix4x4 *matrix) const Q_DECL_OVERRIDE;
+ void applyTo(QMatrix4x4 *matrix) const override;
Q_SIGNALS:
void matrixChanged();
diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp
index fca1805fc9..ff9789ad57 100644
--- a/src/quick/items/qquickview.cpp
+++ b/src/quick/items/qquickview.cpp
@@ -70,7 +70,7 @@ void QQuickViewPrivate::init(QQmlEngine* e)
{
// The content item has CppOwnership policy (set in QQuickWindow). Ensure the presence of a JS
// wrapper so that the garbage collector can see the policy.
- QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(engine.data());
+ QV4::ExecutionEngine *v4 = engine.data()->handle();
QV4::QObjectWrapper::wrap(v4, contentItem);
}
}
@@ -198,6 +198,16 @@ QQuickView::QQuickView(QQmlEngine* engine, QWindow *parent)
}
/*!
+ \internal
+*/
+QQuickView::QQuickView(const QUrl &source, QQuickRenderControl *control)
+ : QQuickWindow(*(new QQuickViewPrivate), control)
+{
+ d_func()->init();
+ setSource(source);
+}
+
+/*!
Destroys the QQuickView.
*/
QQuickView::~QQuickView()
diff --git a/src/quick/items/qquickview.h b/src/quick/items/qquickview.h
index 6d3b30e4c4..006a691387 100644
--- a/src/quick/items/qquickview.h
+++ b/src/quick/items/qquickview.h
@@ -42,7 +42,6 @@
#include <QtQuick/qquickwindow.h>
#include <QtCore/qurl.h>
-#include <QtQml/qqmldebug.h>
QT_BEGIN_NAMESPACE
@@ -60,9 +59,10 @@ class Q_QUICK_EXPORT QQuickView : public QQuickWindow
Q_PROPERTY(Status status READ status NOTIFY statusChanged)
Q_PROPERTY(QUrl source READ source WRITE setSource DESIGNABLE true)
public:
- explicit QQuickView(QWindow *parent = Q_NULLPTR);
+ explicit QQuickView(QWindow *parent = nullptr);
QQuickView(QQmlEngine* engine, QWindow *parent);
- explicit QQuickView(const QUrl &source, QWindow *parent = Q_NULLPTR);
+ explicit QQuickView(const QUrl &source, QWindow *parent = nullptr);
+ QQuickView(const QUrl &source, QQuickRenderControl *renderControl);
virtual ~QQuickView();
QUrl source() const;
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 15ade6767c..adf977fe9a 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -46,6 +46,7 @@
#include "qquickevents_p_p.h"
#include <private/qquickdrag_p.h>
+#include <private/qquickpointerhandler_p.h>
#include <QtQuick/private/qsgrenderer_p.h>
#include <QtQuick/private/qsgtexture_p.h>
@@ -96,6 +97,12 @@ extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_
bool QQuickWindowPrivate::defaultAlphaBuffer = false;
+#if defined(QT_QUICK_DEFAULT_TEXT_RENDER_TYPE)
+QQuickWindow::TextRenderType QQuickWindowPrivate::textRenderType = QQuickWindow::QT_QUICK_DEFAULT_TEXT_RENDER_TYPE;
+#else
+QQuickWindow::TextRenderType QQuickWindowPrivate::textRenderType = QQuickWindow::QtTextRendering;
+#endif
+
void QQuickWindowPrivate::updateFocusItemTransform()
{
#if QT_CONFIG(im)
@@ -129,7 +136,7 @@ public:
}
protected:
- void timerEvent(QTimerEvent *) Q_DECL_OVERRIDE
+ void timerEvent(QTimerEvent *) override
{
killTimer(m_timer);
m_timer = 0;
@@ -160,7 +167,7 @@ public slots:
void animationStopped() { incubate(); }
protected:
- void incubatingObjectCountChanged(int count) Q_DECL_OVERRIDE
+ void incubatingObjectCountChanged(int count) override
{
if (count && !m_renderLoop->interleaveIncubation())
incubateAgain();
@@ -503,6 +510,8 @@ QQuickWindowPrivate::QQuickWindowPrivate()
, persistentSceneGraph(true)
, lastWheelEventAccepted(false)
, componentCompleted(true)
+ , allowChildEventFiltering(true)
+ , allowDoubleClick(true)
, lastFocusReason(Qt::OtherFocusReason)
, renderTarget(0)
, renderTargetId(0)
@@ -664,7 +673,7 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve
if (!item->contains(pos))
break;
- qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << p.id() << "->" << item;
+ qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << hex << p.id() << "->" << item;
QScopedPointer<QMouseEvent> mousePress(touchToMouseEvent(QEvent::MouseButtonPress, p, event.data(), item, false));
// Send a single press and see if that's accepted
@@ -676,7 +685,7 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve
if (!q->mouseGrabberItem())
item->grabMouse();
auto pointerEventPoint = pointerEvent->pointById(p.id());
- pointerEventPoint->setGrabber(item);
+ pointerEventPoint->setGrabberItem(item);
if (checkIfDoubleClicked(event->timestamp())) {
QScopedPointer<QMouseEvent> mouseDoubleClick(touchToMouseEvent(QEvent::MouseButtonDblClick, p, event.data(), item, false));
@@ -700,7 +709,7 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve
QCoreApplication::sendEvent(item, me.data());
event->setAccepted(me->isAccepted());
if (me->isAccepted()) {
- qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << p.id() << "->" << mouseGrabberItem;
+ qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << hex << p.id() << "->" << mouseGrabberItem;
}
return event->isAccepted();
} else {
@@ -750,11 +759,9 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve
return false;
}
-void QQuickWindowPrivate::grabTouchPoints(QQuickItem *grabber, const QVector<int> &ids)
+void QQuickWindowPrivate::grabTouchPoints(QObject *grabber, const QVector<int> &ids)
{
- QSet<QQuickItem*> ungrab;
for (int i = 0; i < ids.count(); ++i) {
- // FIXME: deprecate this function, we need a device
int id = ids.at(i);
if (Q_UNLIKELY(id < 0)) {
qWarning("ignoring grab of touchpoint %d", id);
@@ -762,11 +769,11 @@ void QQuickWindowPrivate::grabTouchPoints(QQuickItem *grabber, const QVector<int
}
if (id == touchMouseId) {
auto point = pointerEventInstance(touchMouseDevice)->pointById(id);
- auto touchMouseGrabber = point->grabber();
+ auto touchMouseGrabber = point->grabberItem();
if (touchMouseGrabber) {
- point->setGrabber(nullptr);
+ point->setExclusiveGrabber(nullptr);
touchMouseGrabber->mouseUngrabEvent();
- ungrab.insert(touchMouseGrabber);
+ touchMouseGrabber->touchUngrabEvent();
touchMouseDevice = nullptr;
touchMouseId = -1;
}
@@ -778,19 +785,23 @@ void QQuickWindowPrivate::grabTouchPoints(QQuickItem *grabber, const QVector<int
auto point = pointerEventInstance(device)->pointById(id);
if (!point)
continue;
- QQuickItem *oldGrabber = point->grabber();
+ QObject *oldGrabber = point->exclusiveGrabber();
if (oldGrabber == grabber)
continue;
-
- point->setGrabber(grabber);
- if (oldGrabber)
- ungrab.insert(oldGrabber);
+ point->setExclusiveGrabber(grabber);
}
}
- for (QQuickItem *oldGrabber : qAsConst(ungrab))
- oldGrabber->touchUngrabEvent();
}
+/*!
+ Ungrabs all touchpoint grabs and/or the mouse grab from the given item \a grabber.
+ This should not be called when processing a release event - that's redundant.
+ It is called in other cases, when the points may not be released, but the item
+ nevertheless must lose its grab due to becoming disabled, invisible, etc.
+ QQuickEventPoint::setGrabberItem() calls touchUngrabEvent() when all points are released,
+ but if not all points are released, it cannot be sure whether to call touchUngrabEvent()
+ or not; so we have to do it here.
+*/
void QQuickWindowPrivate::removeGrabber(QQuickItem *grabber, bool mouse, bool touch)
{
Q_Q(QQuickWindow);
@@ -799,24 +810,26 @@ void QQuickWindowPrivate::removeGrabber(QQuickItem *grabber, bool mouse, bool to
auto point = fromTouch ?
pointerEventInstance(touchMouseDevice)->pointById(touchMouseId) :
pointerEventInstance(QQuickPointerDevice::genericMouseDevice())->point(0);
- QQuickItem *oldGrabber = point->grabber();
+ QQuickItem *oldGrabber = point->grabberItem();
qCDebug(DBG_MOUSE_TARGET) << "removeGrabber" << oldGrabber << "-> null";
- point->setGrabber(nullptr);
+ point->setGrabberItem(nullptr);
sendUngrabEvent(oldGrabber, fromTouch);
}
if (Q_LIKELY(touch)) {
+ bool ungrab = false;
const auto touchDevices = QQuickPointerDevice::touchDevices();
for (auto device : touchDevices) {
if (auto pointerEvent = queryPointerEventInstance(device)) {
for (int i = 0; i < pointerEvent->pointCount(); ++i) {
- if (pointerEvent->point(i)->grabber() == grabber) {
- pointerEvent->point(i)->setGrabber(nullptr);
- // FIXME send ungrab event only once
- grabber->touchUngrabEvent();
+ if (pointerEvent->point(i)->exclusiveGrabber() == grabber) {
+ pointerEvent->point(i)->setGrabberItem(nullptr);
+ ungrab = true;
}
}
}
}
+ if (ungrab)
+ grabber->touchUngrabEvent();
}
}
@@ -825,8 +838,8 @@ void QQuickWindowPrivate::sendUngrabEvent(QQuickItem *grabber, bool touch)
if (!grabber)
return;
QEvent e(QEvent::UngrabMouse);
- QSet<QQuickItem *> hasFiltered;
- if (!sendFilteredMouseEvent(grabber->parentItem(), grabber, &e, &hasFiltered)) {
+ hasFiltered.clear();
+ if (!sendFilteredMouseEvent(&e, grabber, grabber->parentItem())) {
grabber->mouseUngrabEvent();
if (touch)
grabber->touchUngrabEvent();
@@ -1268,7 +1281,15 @@ QQuickWindow::QQuickWindow(QQuickRenderControl *control)
d->init(this, control);
}
-
+/*!
+ \internal
+*/
+QQuickWindow::QQuickWindow(QQuickWindowPrivate &dd, QQuickRenderControl *control)
+ : QWindow(dd, 0)
+{
+ Q_D(QQuickWindow);
+ d->init(this, control);
+}
/*!
Destroys the window.
@@ -1494,11 +1515,11 @@ QQuickItem *QQuickWindow::mouseGrabberItem() const
if (d->isDeliveringTouchAsMouse()) {
if (QQuickPointerEvent *event = d->queryPointerEventInstance(d->touchMouseDevice)) {
auto point = event->pointById(d->touchMouseId);
- return point ? point->grabber() : nullptr;
+ return point ? point->grabberItem() : nullptr;
}
} else if (QQuickPointerEvent *event = d->queryPointerEventInstance(QQuickPointerDevice::genericMouseDevice())) {
Q_ASSERT(event->pointCount());
- return event->point(0)->grabber();
+ return event->point(0)->grabberItem();
}
return nullptr;
}
@@ -1627,10 +1648,15 @@ void QQuickWindow::keyReleaseEvent(QKeyEvent *e)
void QQuickWindowPrivate::deliverKeyEvent(QKeyEvent *e)
{
- Q_Q(QQuickWindow);
-
- if (activeFocusItem)
- q->sendEvent(activeFocusItem, e);
+ if (activeFocusItem) {
+ QQuickItem *item = activeFocusItem;
+ e->accept();
+ QCoreApplication::sendEvent(item, e);
+ while (!e->isAccepted() && (item = item->parentItem())) {
+ e->accept();
+ QCoreApplication::sendEvent(item, e);
+ }
+ }
}
QMouseEvent *QQuickWindowPrivate::cloneMouseEvent(QMouseEvent *event, QPointF *transformedLocalPos)
@@ -1647,41 +1673,108 @@ QMouseEvent *QQuickWindowPrivate::cloneMouseEvent(QMouseEvent *event, QPointF *t
return me;
}
+void QQuickWindowPrivate::deliverToPassiveGrabbers(const QVector<QPointer <QQuickPointerHandler> > &passiveGrabbers,
+ QQuickPointerEvent *pointerEvent)
+{
+ const QVector<QQuickPointerHandler *> &eventDeliveryTargets = pointerEvent->device()->eventDeliveryTargets();
+ QVarLengthArray<QPair<QQuickItem *, bool>, 4> sendFilteredPointerEventResult;
+ for (auto handler : passiveGrabbers) {
+ // a null pointer in passiveGrabbers is unlikely, unless the grabbing handler was deleted dynamically
+ if (Q_LIKELY(handler) && !eventDeliveryTargets.contains(handler)) {
+ bool alreadyFiltered = false;
+ QQuickItem *par = handler->parentItem();
+
+ // see if we already have sent a filter event to the parent
+ auto it = std::find_if(sendFilteredPointerEventResult.begin(), sendFilteredPointerEventResult.end(),
+ [par](const QPair<QQuickItem *, bool> &pair) { return pair.first == par; });
+ if (it != sendFilteredPointerEventResult.end()) {
+ // Yes, the event was already filtered to that parent, do not call it again but use
+ // the result of the previous call to determine if we should call the handler.
+ alreadyFiltered = it->second;
+ } else {
+ alreadyFiltered = sendFilteredPointerEvent(pointerEvent, par);
+ sendFilteredPointerEventResult << qMakePair<QQuickItem*, bool>(par, alreadyFiltered);
+ }
+ if (!alreadyFiltered) {
+ pointerEvent->localize(handler->parentItem());
+ handler->handlePointerEvent(pointerEvent);
+ }
+ }
+ }
+}
+
+
+
void QQuickWindowPrivate::deliverMouseEvent(QQuickPointerMouseEvent *pointerEvent)
{
- Q_Q(QQuickWindow);
auto point = pointerEvent->point(0);
- lastMousePosition = point->scenePos();
- QQuickItem *grabber = point->grabber();
- if (!grabber && isDeliveringTouchAsMouse())
- grabber = q->mouseGrabberItem();
-
- if (grabber) {
- // if the update consists of changing button state, then don't accept it
- // unless the button is one in which the item is interested
- if (pointerEvent->button() != Qt::NoButton
- && grabber->acceptedMouseButtons()
- && !(grabber->acceptedMouseButtons() & pointerEvent->button())) {
- pointerEvent->setAccepted(false);
- return;
- }
+ lastMousePosition = point->scenePosition();
+ const bool mouseIsReleased = (point->state() == QQuickEventPoint::Released && pointerEvent->buttons() == Qt::NoButton);
+
+ if (point->exclusiveGrabber()) {
+ if (auto grabber = point->grabberItem()) {
+ bool handled = false;
+ if (sendFilteredPointerEvent(pointerEvent, grabber))
+ handled = true;
+ // if the grabber is an Item:
+ // if the update consists of changing button state, don't accept it unless
+ // the button is one in which the grabber is interested
+ Qt::MouseButtons acceptedButtons = grabber->acceptedMouseButtons();
+ if (!handled && pointerEvent->button() != Qt::NoButton && acceptedButtons
+ && !(acceptedButtons & pointerEvent->button())) {
+ pointerEvent->setAccepted(false);
+ handled = true;
+ }
- // send update
- QPointF localPos = grabber->mapFromScene(lastMousePosition);
- auto me = pointerEvent->asMouseEvent(localPos);
- me->accept();
- q->sendEvent(grabber, me);
- point->setAccepted(me->isAccepted());
+ // send update
+ if (!handled) {
+ QPointF localPos = grabber->mapFromScene(lastMousePosition);
+ auto me = pointerEvent->asMouseEvent(localPos);
+ me->accept();
+ QCoreApplication::sendEvent(grabber, me);
+ point->setAccepted(me->isAccepted());
+ }
- // release event, make sure to ungrab if there still is a grabber
- if (me->type() == QEvent::MouseButtonRelease && !me->buttons() && q->mouseGrabberItem())
- q->mouseGrabberItem()->ungrabMouse();
+ // release event: ungrab if no buttons are pressed anymore
+ if (mouseIsReleased)
+ removeGrabber(grabber, true, isDeliveringTouchAsMouse());
+ } else {
+ // if the grabber is not an Item, it must be a PointerHandler
+ auto handler = point->grabberPointerHandler();
+ pointerEvent->localize(handler->parentItem());
+ if (!sendFilteredPointerEvent(pointerEvent, handler->parentItem()))
+ handler->handlePointerEvent(pointerEvent);
+ if (mouseIsReleased)
+ point->setGrabberPointerHandler(nullptr, true);
+ }
+ deliverToPassiveGrabbers(point->passiveGrabbers(), pointerEvent);
} else {
- // send initial press
bool delivered = false;
if (pointerEvent->isPressEvent()) {
- QSet<QQuickItem*> hasFiltered;
- delivered = deliverPressEvent(pointerEvent, &hasFiltered);
+ // send initial press
+ delivered = deliverPressOrReleaseEvent(pointerEvent);
+ } else if (pointerEvent->device()->type() == QQuickPointerDevice::Mouse) {
+ // if this is an update or release from an actual mouse,
+ // and the point wasn't grabbed, deliver only to PointerHandlers:
+ // passive grabbers first, then the rest
+ deliverToPassiveGrabbers(point->passiveGrabbers(), pointerEvent);
+
+ // If some points weren't grabbed, deliver to non-grabber PointerHandlers in reverse paint order
+ if (!pointerEvent->allPointsGrabbed() && pointerEvent->buttons()) {
+ QVector<QQuickItem *> targetItems = pointerTargets(contentItem, point->scenePosition(), false, false);
+ for (QQuickItem *item : targetItems) {
+ QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+ if (!itemPrivate->extra.isAllocated() || itemPrivate->extra->pointerHandlers.isEmpty())
+ continue;
+ pointerEvent->localize(item);
+ if (!sendFilteredPointerEvent(pointerEvent, item)) {
+ if (itemPrivate->handlePointerEvent(pointerEvent, true)) // avoid re-delivering to grabbers
+ delivered = true;
+ }
+ if (point->exclusiveGrabber())
+ break;
+ }
+ }
}
if (!delivered)
@@ -1702,10 +1795,9 @@ bool QQuickWindowPrivate::sendHoverEvent(QEvent::Type type, QQuickItem *item,
hoverEvent.setTimestamp(timestamp);
hoverEvent.setAccepted(accepted);
- QSet<QQuickItem *> hasFiltered;
- if (sendFilteredMouseEvent(item->parentItem(), item, &hoverEvent, &hasFiltered)) {
+ hasFiltered.clear();
+ if (sendFilteredMouseEvent(&hoverEvent, item, item->parentItem()))
return true;
- }
QCoreApplication::sendEvent(item, &hoverEvent);
@@ -1849,7 +1941,8 @@ bool QQuickWindowPrivate::deliverNativeGestureEvent(QQuickItem *item, QNativeGes
{
QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
- if ((itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) && !item->contains(event->localPos()))
+ QPointF p = item->mapFromScene(event->windowPos());
+ if ((itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) && !item->contains(p))
return false;
QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
@@ -1861,10 +1954,19 @@ bool QQuickWindowPrivate::deliverNativeGestureEvent(QQuickItem *item, QNativeGes
return true;
}
- QPointF p = item->mapFromScene(event->localPos());
+ // Try the Item's pointer handlers first
+ QQuickPointerEvent *pointerEvent = pointerEventInstance(event);
+ pointerEvent->localize(item);
+ if (itemPrivate->handlePointerEvent(pointerEvent, false)) {
+ if (pointerEvent->allPointsAccepted()) {
+ event->accept();
+ return true;
+ }
+ }
+ // If still not accepted, try direct delivery to the item
if (item->contains(p)) {
- QNativeGestureEvent copy(event->gestureType(), p, event->windowPos(), event->screenPos(),
+ QNativeGestureEvent copy(event->gestureType(), event->device(), p, event->windowPos(), event->screenPos(),
event->value(), 0L, 0L); // TODO can't copy things I can't access
event->accept();
item->event(&copy);
@@ -1883,20 +1985,18 @@ bool QQuickWindowPrivate::deliverTouchCancelEvent(QTouchEvent *event)
qCDebug(DBG_TOUCH) << event;
Q_Q(QQuickWindow);
- // A TouchCancel event will typically not contain any points.
- // Deliver it to all items that have active touches.
- QQuickPointerEvent *pointerEvent = pointerEventInstance(QQuickPointerDevice::touchDevice(event->device()));
- QVector<QQuickItem *> grabbers = pointerEvent->grabbers();
-
- for (QQuickItem *grabber: qAsConst(grabbers)) {
- q->sendEvent(grabber, event);
- }
- touchMouseId = -1;
- touchMouseDevice = nullptr;
if (q->mouseGrabberItem())
q->mouseGrabberItem()->ungrabMouse();
+ touchMouseId = -1;
+ touchMouseDevice = nullptr;
+
+ // A TouchCancel event will typically not contain any points.
+ // Deliver it to all items and handlers that have active touches.
+ QQuickPointerEvent *pointerEvent = pointerEventInstance(QQuickPointerDevice::touchDevice(event->device()));
+ for (int i = 0; i < pointerEvent->pointCount(); ++i)
+ pointerEvent->point(i)->cancelExclusiveGrabImpl(event);
- // The next touch event can only be a TouchBegin so clean up.
+ // The next touch event can only be a TouchBegin, so clean up.
pointerEvent->clearGrabbers();
return true;
}
@@ -2033,8 +2133,6 @@ void QQuickWindow::mouseReleaseEvent(QMouseEvent *event)
void QQuickWindowPrivate::handleMouseEvent(QMouseEvent *event)
{
- Q_Q(QQuickWindow);
-
if (event->source() == Qt::MouseEventSynthesizedBySystem) {
event->accept();
return;
@@ -2055,7 +2153,8 @@ void QQuickWindowPrivate::handleMouseEvent(QMouseEvent *event)
case QEvent::MouseButtonDblClick:
Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseDoubleClick,
event->button(), event->buttons());
- deliverPointerEvent(pointerEventInstance(event));
+ if (allowDoubleClick)
+ deliverPointerEvent(pointerEventInstance(event));
break;
case QEvent::MouseMove:
Q_QUICK_INPUT_PROFILE(QQuickProfiler::Mouse, QQuickProfiler::InputMouseMove,
@@ -2067,7 +2166,7 @@ void QQuickWindowPrivate::handleMouseEvent(QMouseEvent *event)
updateCursor(event->windowPos());
#endif
- if (!q->mouseGrabberItem()) {
+ if (!pointerEventInstance(QQuickPointerDevice::genericMouseDevice())->point(0)->exclusiveGrabber()) {
QPointF last = lastMousePosition.isNull() ? event->windowPos() : lastMousePosition;
lastMousePosition = event->windowPos();
@@ -2078,7 +2177,6 @@ void QQuickWindowPrivate::handleMouseEvent(QMouseEvent *event)
accepted = clearHover(event->timestamp());
}
event->setAccepted(accepted);
- return;
}
deliverPointerEvent(pointerEventInstance(event));
break;
@@ -2115,29 +2213,41 @@ void QQuickWindowPrivate::flushFrameSynchronousEvents()
}
}
-QQuickPointerEvent *QQuickWindowPrivate::queryPointerEventInstance(QQuickPointerDevice *device) const
+QQuickPointerEvent *QQuickWindowPrivate::queryPointerEventInstance(QQuickPointerDevice *device, QEvent::Type eventType) const
{
- // the list of devices should be very small so a linear search should be ok
- for (QQuickPointerEvent *e: pointerEventInstances) {
+ // Search for a matching reusable event object.
+ for (QQuickPointerEvent *e : pointerEventInstances) {
+ // If device can generate native gestures (e.g. a trackpad), there might be two QQuickPointerEvents:
+ // QQuickPointerNativeGestureEvent and QQuickPointerTouchEvent. Use eventType to disambiguate.
+ if (eventType == QEvent::NativeGesture && !qobject_cast<QQuickPointerNativeGestureEvent*>(e))
+ continue;
+ // Otherwise we assume there's only one event type per device.
+ // More disambiguation tests might need to be added above if that changes later.
if (e->device() == device)
return e;
}
return nullptr;
}
-QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QQuickPointerDevice *device) const
+QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QQuickPointerDevice *device, QEvent::Type eventType) const
{
- QQuickPointerEvent *ev = queryPointerEventInstance(device);
+ QQuickPointerEvent *ev = queryPointerEventInstance(device, eventType);
if (ev)
return ev;
QQuickWindow *q = const_cast<QQuickWindow*>(q_func());
switch (device->type()) {
case QQuickPointerDevice::Mouse:
+ // QWindowSystemInterface::handleMouseEvent() does not take a device parameter:
+ // we assume all mouse events come from one mouse (the "core pointer").
+ // So when the event is a mouse event, device == QQuickPointerDevice::genericMouseDevice()
ev = new QQuickPointerMouseEvent(q, device);
break;
case QQuickPointerDevice::TouchPad:
case QQuickPointerDevice::TouchScreen:
- ev = new QQuickPointerTouchEvent(q, device);
+ if (eventType == QEvent::NativeGesture)
+ ev = new QQuickPointerNativeGestureEvent(q, device);
+ else // assume QEvent::Type is one of TouchBegin/Update/End
+ ev = new QQuickPointerTouchEvent(q, device);
break;
default:
// TODO tablet event types
@@ -2157,40 +2267,47 @@ QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QQuickPointerDevic
QQuickPointerEvent *QQuickWindowPrivate::pointerEventInstance(QEvent *event) const
{
QQuickPointerDevice *dev = nullptr;
- QQuickPointerEvent *ev = nullptr;
switch (event->type()) {
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
case QEvent::MouseButtonDblClick:
case QEvent::MouseMove:
dev = QQuickPointerDevice::genericMouseDevice();
- ev = pointerEventInstance(dev);
break;
case QEvent::TouchBegin:
case QEvent::TouchUpdate:
case QEvent::TouchEnd:
case QEvent::TouchCancel:
dev = QQuickPointerDevice::touchDevice(static_cast<QTouchEvent *>(event)->device());
- ev = pointerEventInstance(dev);
break;
// TODO tablet event types
+ case QEvent::NativeGesture:
+ dev = QQuickPointerDevice::touchDevice(static_cast<QNativeGestureEvent *>(event)->device());
+ break;
default:
break;
}
- Q_ASSERT(ev);
- return ev->reset(event);
+ Q_ASSERT(dev);
+ return pointerEventInstance(dev, event->type())->reset(event);
}
void QQuickWindowPrivate::deliverPointerEvent(QQuickPointerEvent *event)
{
+ Q_Q(QQuickWindow);
// If users spin the eventloop as a result of event delivery, we disable
// event compression and send events directly. This is because we consider
// the usecase a bit evil, but we at least don't want to lose events.
++pointerEventRecursionGuard;
+ skipDelivery.clear();
if (event->asPointerMouseEvent()) {
deliverMouseEvent(event->asPointerMouseEvent());
+ // failsafe: never allow any kind of grab to persist after release
+ if (event->isReleaseEvent() && event->buttons() == Qt::NoButton) {
+ event->clearGrabbers();
+ sendUngrabEvent(q->mouseGrabberItem(), false);
+ }
} else if (event->asPointerTouchEvent()) {
deliverTouchEvent(event->asPointerTouchEvent());
} else {
@@ -2204,7 +2321,10 @@ void QQuickWindowPrivate::deliverPointerEvent(QQuickPointerEvent *event)
// check if item or any of its child items contain the point
// FIXME: should this be iterative instead of recursive?
-QVector<QQuickItem *> QQuickWindowPrivate::pointerTargets(QQuickItem *item, const QPointF &scenePos, bool checkMouseButtons) const
+// If checkMouseButtons is true, it means we are finding targets for a mouse event, so no item for which acceptedMouseButtons() is NoButton will be added.
+// If checkAcceptsTouch is true, it means we are finding targets for a touch event, so either acceptTouchEvents() must return true OR
+// it must accept a synth. mouse event, thus if acceptTouchEvents() returns false but acceptedMouseButtons() is true, gets added; if not, it doesn't.
+QVector<QQuickItem *> QQuickWindowPrivate::pointerTargets(QQuickItem *item, const QPointF &scenePos, bool checkMouseButtons, bool checkAcceptsTouch) const
{
QVector<QQuickItem *> targets;
auto itemPrivate = QQuickItemPrivate::get(item);
@@ -2222,13 +2342,18 @@ QVector<QQuickItem *> QQuickWindowPrivate::pointerTargets(QQuickItem *item, cons
auto childPrivate = QQuickItemPrivate::get(child);
if (!child->isVisible() || !child->isEnabled() || childPrivate->culled)
continue;
- targets << pointerTargets(child, scenePos, false);
+ targets << pointerTargets(child, scenePos, checkMouseButtons, checkAcceptsTouch);
}
- if (item->contains(itemPos) && (!checkMouseButtons || itemPrivate->acceptedMouseButtons())) {
- // add this item last - children take precedence
- targets << item;
+ bool relevant = item->contains(itemPos);
+ if (!(itemPrivate->hasPointerHandlers())) {
+ if (relevant && checkMouseButtons && item->acceptedMouseButtons() == Qt::NoButton)
+ relevant = false;
+ if (relevant && checkAcceptsTouch && !(item->acceptTouchEvents() || item->acceptedMouseButtons()))
+ relevant = false;
}
+ if (relevant)
+ targets << item; // add this item last: children take precedence
return targets;
}
@@ -2258,11 +2383,12 @@ void QQuickWindowPrivate::deliverTouchEvent(QQuickPointerTouchEvent *event)
{
qCDebug(DBG_TOUCH) << " - delivering" << event->asTouchEvent();
- QSet<QQuickItem *> hasFiltered;
if (event->isPressEvent())
- deliverPressEvent(event, &hasFiltered);
- if (!event->allPointsAccepted())
- deliverUpdatedTouchPoints(event, &hasFiltered);
+ deliverPressOrReleaseEvent(event);
+ if (!event->allUpdatedPointsAccepted())
+ deliverUpdatedTouchPoints(event);
+ if (event->isReleaseEvent())
+ deliverPressOrReleaseEvent(event, true);
// Remove released points from itemForTouchPointId
bool allReleased = true;
@@ -2272,7 +2398,7 @@ void QQuickWindowPrivate::deliverTouchEvent(QQuickPointerTouchEvent *event)
if (point->state() == QQuickEventPoint::Released) {
int id = point->pointId();
qCDebug(DBG_TOUCH_TARGET) << "TP" << hex << id << "released";
- point->setGrabber(nullptr);
+ point->setGrabberItem(nullptr);
if (id == touchMouseId) {
touchMouseId = -1;
touchMouseDevice = nullptr;
@@ -2282,29 +2408,85 @@ void QQuickWindowPrivate::deliverTouchEvent(QQuickPointerTouchEvent *event)
}
}
- if (allReleased && !event->grabbers().isEmpty()) {
- qWarning() << "No release received for some grabbers" << event->grabbers();
+ if (allReleased) {
+ if (Q_UNLIKELY(!event->exclusiveGrabbers().isEmpty()))
+ qWarning() << "No release received for some grabbers" << event->exclusiveGrabbers();
event->clearGrabbers();
}
}
// Deliver touch points to existing grabbers
-bool QQuickWindowPrivate::deliverUpdatedTouchPoints(QQuickPointerTouchEvent *event, QSet<QQuickItem *> *hasFiltered)
-{
- const auto grabbers = event->grabbers();
- for (auto grabber : grabbers)
- deliverMatchingPointsToItem(grabber, event, hasFiltered);
+void QQuickWindowPrivate::deliverUpdatedTouchPoints(QQuickPointerTouchEvent *event)
+{
+ bool done = false;
+ const auto grabbers = event->exclusiveGrabbers();
+ for (auto grabber : grabbers) {
+ // The grabber is guaranteed to be either an item or a handler.
+ QQuickItem *receiver = qmlobject_cast<QQuickItem *>(grabber);
+ if (!receiver) {
+ // The grabber is not an item? It's a handler then. Let it have the event first.
+ QQuickPointerHandler *handler = static_cast<QQuickPointerHandler *>(grabber);
+ receiver = static_cast<QQuickPointerHandler *>(grabber)->parentItem();
+ if (sendFilteredPointerEvent(event, receiver))
+ done = true;
+ event->localize(receiver);
+ handler->handlePointerEvent(event);
+ }
+ if (done)
+ break;
+ // If the grabber is an item or the grabbing handler didn't handle it,
+ // then deliver the event to the item (which may have multiple handlers).
+ deliverMatchingPointsToItem(receiver, event);
+ }
- return false;
+ // Deliver to each eventpoint's passive grabbers (but don't visit any handler more than once)
+ int pointCount = event->pointCount();
+ for (int i = 0; i < pointCount; ++i) {
+ QQuickEventPoint *point = event->point(i);
+ deliverToPassiveGrabbers(point->passiveGrabbers(), event);
+ }
+
+ if (done)
+ return;
+
+ // If some points weren't grabbed, deliver only to non-grabber PointerHandlers in reverse paint order
+ if (!event->allPointsGrabbed()) {
+ QVector<QQuickItem *> targetItems;
+ for (int i = 0; i < pointCount; ++i) {
+ QQuickEventPoint *point = event->point(i);
+ if (point->state() == QQuickEventPoint::Pressed)
+ continue; // presses were delivered earlier; not the responsibility of deliverUpdatedTouchPoints
+ QVector<QQuickItem *> targetItemsForPoint = pointerTargets(contentItem, point->scenePosition(), false, false);
+ if (targetItems.count()) {
+ targetItems = mergePointerTargets(targetItems, targetItemsForPoint);
+ } else {
+ targetItems = targetItemsForPoint;
+ }
+ }
+ for (QQuickItem *item : targetItems) {
+ if (grabbers.contains(item))
+ continue;
+ QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+ event->localize(item);
+ itemPrivate->handlePointerEvent(event, true); // avoid re-delivering to grabbers
+ if (event->allPointsGrabbed())
+ break;
+ }
+ }
}
-// Deliver newly pressed touch points
-bool QQuickWindowPrivate::deliverPressEvent(QQuickPointerEvent *event, QSet<QQuickItem *> *hasFiltered)
+// Deliver an event containing newly pressed or released touch points
+bool QQuickWindowPrivate::deliverPressOrReleaseEvent(QQuickPointerEvent *event, bool handlersOnly)
{
- const QVector<QPointF> points = event->unacceptedPressedPointScenePositions();
+ int pointCount = event->pointCount();
QVector<QQuickItem *> targetItems;
- for (QPointF point: points) {
- QVector<QQuickItem *> targetItemsForPoint = pointerTargets(contentItem, point, false);
+ bool isTouchEvent = (event->asPointerTouchEvent() != nullptr);
+ for (int i = 0; i < pointCount; ++i) {
+ auto point = event->point(i);
+ point->setAccepted(false); // because otherwise touchEventForItem will ignore it
+ if (point->grabberPointerHandler() && point->state() == QQuickEventPoint::Released)
+ point->setGrabberPointerHandler(nullptr, true);
+ QVector<QQuickItem *> targetItemsForPoint = pointerTargets(contentItem, point->scenePosition(), !isTouchEvent, isTouchEvent);
if (targetItems.count()) {
targetItems = mergePointerTargets(targetItems, targetItemsForPoint);
} else {
@@ -2312,34 +2494,62 @@ bool QQuickWindowPrivate::deliverPressEvent(QQuickPointerEvent *event, QSet<QQui
}
}
- for (QQuickItem *item: targetItems) {
- deliverMatchingPointsToItem(item, event, hasFiltered);
+ for (QQuickItem *item : targetItems) {
+ if (!handlersOnly && sendFilteredPointerEvent(event, item)) {
+ if (event->isAccepted()) {
+ for (int i = 0; i < event->pointCount(); ++i)
+ event->point(i)->setAccepted();
+ return true;
+ }
+ skipDelivery.append(item);
+ }
+
+ // Do not deliverMatchingPointsTo any item for which the filtering parent already intercepted the event,
+ // nor to any item which already had a chance to filter.
+ if (skipDelivery.contains(item))
+ continue;
+ deliverMatchingPointsToItem(item, event, handlersOnly);
if (event->allPointsAccepted())
- break;
+ handlersOnly = true;
}
return event->allPointsAccepted();
}
-bool QQuickWindowPrivate::deliverMatchingPointsToItem(QQuickItem *item, QQuickPointerEvent *pointerEvent, QSet<QQuickItem *> *hasFiltered)
+void QQuickWindowPrivate::deliverMatchingPointsToItem(QQuickItem *item, QQuickPointerEvent *pointerEvent, bool handlersOnly)
{
Q_Q(QQuickWindow);
+ QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+ pointerEvent->localize(item);
+
+ // Let the Item's handlers (if any) have the event first.
+ // However, double click should never be delivered to handlers.
+ if (!pointerEvent->isDoubleClickEvent()) {
+ bool wasAccepted = pointerEvent->allPointsAccepted();
+ itemPrivate->handlePointerEvent(pointerEvent);
+ allowDoubleClick = wasAccepted || !(pointerEvent->asPointerMouseEvent() && pointerEvent->isPressEvent() && pointerEvent->allPointsAccepted());
+ }
+ if (handlersOnly)
+ return;
+
+ // If all points are released and the item is not the grabber, it doesn't get the event.
+ // But if at least one point is still pressed, we might be in a potential gesture-takeover scenario.
+ if (pointerEvent->isReleaseEvent() && !pointerEvent->isUpdateEvent()
+ && !pointerEvent->exclusiveGrabbers().contains(item))
+ return;
// TODO: unite this mouse point delivery with the synthetic mouse event below
- if (auto event = pointerEvent->asPointerMouseEvent()) {
- if (item->acceptedMouseButtons() & event->button()) {
+ auto event = pointerEvent->asPointerMouseEvent();
+ if (event && item->acceptedMouseButtons() & event->button()) {
auto point = event->point(0);
- if (point->isAccepted())
- return false;
-
// The only reason to already have a mouse grabber here is
// synthetic events - flickable sends one when setPressDelay is used.
auto oldMouseGrabber = q->mouseGrabberItem();
- QPointF localPos = item->mapFromScene(point->scenePos());
+ QPointF localPos = item->mapFromScene(point->scenePosition());
Q_ASSERT(item->contains(localPos)); // transform is checked already
QMouseEvent *me = event->asMouseEvent(localPos);
me->accept();
- q->sendEvent(item, me);
+ QCoreApplication::sendEvent(item, me);
if (me->isAccepted()) {
auto mouseGrabber = q->mouseGrabberItem();
if (mouseGrabber && mouseGrabber != item && mouseGrabber != oldMouseGrabber) {
@@ -2349,33 +2559,23 @@ bool QQuickWindowPrivate::deliverMatchingPointsToItem(QQuickItem *item, QQuickPo
}
point->setAccepted(true);
}
- return me->isAccepted();
- }
- return false;
+ return;
}
- QQuickPointerTouchEvent *event = pointerEvent->asPointerTouchEvent();
- if (!event)
- return false;
+ QQuickPointerTouchEvent *ptEvent = pointerEvent->asPointerTouchEvent();
+ if (!ptEvent)
+ return;
- QScopedPointer<QTouchEvent> touchEvent(event->touchEventForItem(item));
+ QScopedPointer<QTouchEvent> touchEvent(ptEvent->touchEventForItem(item));
if (!touchEvent)
- return false;
+ return;
- qCDebug(DBG_TOUCH) << " - considering delivering " << touchEvent.data() << " to " << item;
+ qCDebug(DBG_TOUCH) << "considering delivering " << touchEvent.data() << " to " << item;
bool eventAccepted = false;
- // First check whether the parent wants to be a filter,
- // and if the parent accepts the event we are done.
- if (sendFilteredTouchEvent(item->parentItem(), item, event, hasFiltered)) {
- // If the touch was accepted (regardless by whom or in what form),
- // update acceptedNewPoints
- qCDebug(DBG_TOUCH) << " - can't. intercepted " << touchEvent.data() << " to " << item->parentItem() << " instead of " << item;
- for (auto point: qAsConst(touchEvent->touchPoints())) {
- event->pointById(point.id())->setAccepted();
- }
- return true;
- }
+ // If any parent filters the event, we're done.
+ if (sendFilteredPointerEvent(pointerEvent, item))
+ return;
// Deliver the touch event to the given item
qCDebug(DBG_TOUCH) << " - actually delivering " << touchEvent.data() << " to " << item;
@@ -2383,36 +2583,34 @@ bool QQuickWindowPrivate::deliverMatchingPointsToItem(QQuickItem *item, QQuickPo
eventAccepted = touchEvent->isAccepted();
// If the touch event wasn't accepted, synthesize a mouse event and see if the item wants it.
- QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
if (!eventAccepted && (itemPrivate->acceptedMouseButtons() & Qt::LeftButton)) {
// send mouse event
- if (deliverTouchAsMouse(item, event))
+ if (deliverTouchAsMouse(item, ptEvent))
eventAccepted = true;
}
if (eventAccepted) {
// If the touch was accepted (regardless by whom or in what form),
// update accepted new points.
+ bool isPressOrRelease = pointerEvent->isPressEvent() || pointerEvent->isReleaseEvent();
for (auto point: qAsConst(touchEvent->touchPoints())) {
- auto pointerEventPoint = event->pointById(point.id());
+ auto pointerEventPoint = ptEvent->pointById(point.id());
pointerEventPoint->setAccepted();
- if (point.state() == Qt::TouchPointPressed)
- pointerEventPoint->setGrabber(item);
+ if (isPressOrRelease)
+ pointerEventPoint->setGrabberItem(item);
}
} else {
// But if the event was not accepted then we know this item
// will not be interested in further updates for those touchpoint IDs either.
for (auto point: qAsConst(touchEvent->touchPoints())) {
if (point.state() == Qt::TouchPointPressed) {
- if (event->pointById(point.id())->grabber() == item) {
- qCDebug(DBG_TOUCH_TARGET) << "TP" << point.id() << "disassociated";
- event->pointById(point.id())->setGrabber(nullptr);
+ if (ptEvent->pointById(point.id())->exclusiveGrabber() == item) {
+ qCDebug(DBG_TOUCH_TARGET) << "TP" << hex << point.id() << "disassociated";
+ ptEvent->pointById(point.id())->setGrabberItem(nullptr);
}
}
}
}
-
- return eventAccepted;
}
#if QT_CONFIG(draganddrop)
@@ -2587,115 +2785,147 @@ QQuickItem *QQuickWindowPrivate::findCursorItem(QQuickItem *item, const QPointF
}
#endif
-bool QQuickWindowPrivate::sendFilteredTouchEvent(QQuickItem *target, QQuickItem *item, QQuickPointerTouchEvent *event, QSet<QQuickItem *> *hasFiltered)
+bool QQuickWindowPrivate::sendFilteredPointerEvent(QQuickPointerEvent *event, QQuickItem *receiver, QQuickItem *filteringParent)
{
- Q_Q(QQuickWindow);
+ hasFiltered.clear();
+ return sendFilteredPointerEventImpl(event, receiver, filteringParent ? filteringParent : receiver->parentItem());
+}
- if (!target)
+bool QQuickWindowPrivate::sendFilteredPointerEventImpl(QQuickPointerEvent *event, QQuickItem *receiver, QQuickItem *filteringParent)
+{
+ if (!allowChildEventFiltering)
+ return false;
+ if (!filteringParent)
return false;
-
bool filtered = false;
-
- QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(target);
- if (targetPrivate->filtersChildMouseEvents && !hasFiltered->contains(target)) {
- hasFiltered->insert(target);
- QScopedPointer<QTouchEvent> targetEvent(event->touchEventForItem(target, true));
- if (targetEvent) {
- if (target->childMouseEventFilter(item, targetEvent.data())) {
- qCDebug(DBG_TOUCH) << " - first chance intercepted on childMouseEventFilter by " << target;
- QVector<int> touchIds;
- const int touchPointCount = targetEvent->touchPoints().size();
- touchIds.reserve(touchPointCount);
- for (int i = 0; i < touchPointCount; ++i)
- touchIds.append(targetEvent->touchPoints().at(i).id());
- target->grabTouchPoints(touchIds);
- if (q->mouseGrabberItem()) {
- q->mouseGrabberItem()->ungrabMouse();
- touchMouseId = -1;
- touchMouseDevice = nullptr;
+ if (filteringParent->filtersChildMouseEvents() && !hasFiltered.contains(filteringParent)) {
+ hasFiltered.append(filteringParent);
+ if (QQuickPointerMouseEvent *pme = event->asPointerMouseEvent()) {
+ if (receiver->acceptedMouseButtons()) {
+ QPointF localPos = receiver->mapFromScene(pme->point(0)->scenePosition());
+ QMouseEvent *me = pme->asMouseEvent(localPos);
+ const bool wasAccepted = me->isAccepted();
+ me->setAccepted(true);
+ auto oldMouseGrabber = pme->point(0)->grabberItem();
+ if (filteringParent->childMouseEventFilter(receiver, me)) {
+ qCDebug(DBG_MOUSE) << "mouse event intercepted by childMouseEventFilter of " << filteringParent;
+ skipDelivery.append(filteringParent);
+ filtered = true;
+ if (me->isAccepted() && pme->isPressEvent()) {
+ auto mouseGrabber = pme->point(0)->grabberItem();
+ if (mouseGrabber && mouseGrabber != receiver && mouseGrabber != oldMouseGrabber) {
+ receiver->mouseUngrabEvent();
+ } else {
+ pme->point(0)->setGrabberItem(receiver);
+ }
+ }
+ } else {
+ // Restore accepted state if the event was not filtered.
+ me->setAccepted(wasAccepted);
}
- filtered = true;
}
+ } else if (QQuickPointerTouchEvent *pte = event->asPointerTouchEvent()) {
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ bool acceptsTouchEvents = receiver->acceptTouchEvents();
+#else
+ // In versions prior to Qt 6, we can't trust item->acceptTouchEvents() here, because it defaults to true.
+ bool acceptsTouchEvents = false;
+#endif
+ if (acceptsTouchEvents || receiver->acceptedMouseButtons()) {
+ // get a touch event customized for delivery to filteringParent
+ QScopedPointer<QTouchEvent> filteringParentTouchEvent(pte->touchEventForItem(receiver, true));
+ if (filteringParentTouchEvent) {
+ if (filteringParent->childMouseEventFilter(receiver, filteringParentTouchEvent.data())) {
+ qCDebug(DBG_TOUCH) << "touch event intercepted by childMouseEventFilter of " << filteringParent;
+ skipDelivery.append(filteringParent);
+ for (auto point: qAsConst(filteringParentTouchEvent->touchPoints())) {
+ QQuickEventPoint *pt = event->pointById(point.id());
+ pt->setAccepted();
+ pt->setGrabberItem(filteringParent);
+ }
+ return true;
+ } else {
+ // filteringParent didn't filter the touch event. Give it a chance to filter a synthetic mouse event.
+ for (int i = 0; i < filteringParentTouchEvent->touchPoints().size(); ++i) {
+ const QTouchEvent::TouchPoint &tp = filteringParentTouchEvent->touchPoints().at(i);
+
+ QEvent::Type t;
+ switch (tp.state()) {
+ case Qt::TouchPointPressed:
+ t = QEvent::MouseButtonPress;
+ break;
+ case Qt::TouchPointReleased:
+ t = QEvent::MouseButtonRelease;
+ break;
+ case Qt::TouchPointStationary:
+ continue;
+ default:
+ t = QEvent::MouseMove;
+ break;
+ }
- for (int i = 0; i < targetEvent->touchPoints().size(); ++i) {
- const QTouchEvent::TouchPoint &tp = targetEvent->touchPoints().at(i);
-
- QEvent::Type t;
- switch (tp.state()) {
- case Qt::TouchPointPressed:
- t = QEvent::MouseButtonPress;
- break;
- case Qt::TouchPointReleased:
- t = QEvent::MouseButtonRelease;
- break;
- case Qt::TouchPointStationary:
- continue;
- default:
- t = QEvent::MouseMove;
- break;
- }
-
- bool touchMouseUnset = (touchMouseId == -1);
- // Only deliver mouse event if it is the touchMouseId or it could become the touchMouseId
- if (touchMouseUnset || touchMouseId == tp.id()) {
- // targetEvent is already transformed wrt local position, velocity, etc.
-
- // FIXME: remove asTouchEvent!!!
- QScopedPointer<QMouseEvent> mouseEvent(touchToMouseEvent(t, tp, event->asTouchEvent(), item, false));
- // If a filtering item calls QQuickWindow::mouseGrabberItem(), it should
- // report the touchpoint's grabber. Whenever we send a synthetic mouse event,
- // touchMouseId and touchMouseDevice must be set, even if it's only temporarily and isn't grabbed.
- touchMouseId = tp.id();
- touchMouseDevice = event->device();
- if (target->childMouseEventFilter(item, mouseEvent.data())) {
- qCDebug(DBG_TOUCH) << " - second chance intercepted on childMouseEventFilter by " << target;
- if (t != QEvent::MouseButtonRelease) {
- qCDebug(DBG_TOUCH_TARGET) << "TP" << tp.id() << "->" << target;
- if (touchMouseUnset) {
- // the point was grabbed as a pure touch point before, now it will be treated as mouse
- // but the old receiver still needs to be informed
- if (auto oldGrabber = pointerEventInstance(touchMouseDevice)->pointById(tp.id())->grabber())
- oldGrabber->touchUngrabEvent();
+ bool touchMouseUnset = (touchMouseId == -1);
+ // Only deliver mouse event if it is the touchMouseId or it could become the touchMouseId
+ if (touchMouseUnset || touchMouseId == tp.id()) {
+ // convert filteringParentTouchEvent (which is already transformed wrt local position, velocity, etc.)
+ // into a synthetic mouse event, and let childMouseEventFilter() have another chance with that
+ QScopedPointer<QMouseEvent> mouseEvent(touchToMouseEvent(t, tp, filteringParentTouchEvent.data(), receiver, false));
+ // If a filtering item calls QQuickWindow::mouseGrabberItem(), it should
+ // report the touchpoint's grabber. Whenever we send a synthetic mouse event,
+ // touchMouseId and touchMouseDevice must be set, even if it's only temporarily and isn't grabbed.
+ touchMouseId = tp.id();
+ touchMouseDevice = event->device();
+ if (filteringParent->childMouseEventFilter(receiver, mouseEvent.data())) {
+ qCDebug(DBG_TOUCH) << "touch event intercepted as synth mouse event by childMouseEventFilter of " << filteringParent;
+ skipDelivery.append(filteringParent);
+ if (t != QEvent::MouseButtonRelease) {
+ qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << hex << tp.id() << "->" << filteringParent;
+ pointerEventInstance(touchMouseDevice)->pointById(tp.id())->setGrabberItem(filteringParent);
+ touchMouseUnset = false; // We want to leave touchMouseId and touchMouseDevice set
+ if (mouseEvent->isAccepted())
+ filteringParent->grabMouse();
+ }
+ filtered = true;
+ }
+ if (touchMouseUnset) {
+ // Now that we're done sending a synth mouse event, and it wasn't grabbed,
+ // the touchpoint is no longer acting as a synthetic mouse. Restore previous state.
+ touchMouseId = -1;
+ touchMouseDevice = nullptr;
+ }
+ // Only one touchpoint can be treated as a synthetic mouse, so after childMouseEventFilter
+ // has been called once, we're done with this loop over the touchpoints.
+ break;
}
- touchMouseUnset = false; // We want to leave touchMouseId and touchMouseDevice set
- target->grabMouse();
}
- filtered = true;
}
- if (touchMouseUnset) {
- // Now that we're done sending a synth mouse event, and it wasn't grabbed,
- // the touchpoint is no longer acting as a synthetic mouse. Restore previous state.
- touchMouseId = -1;
- touchMouseDevice = nullptr;
- }
- // Only one event can be filtered as a mouse event.
- break;
}
}
}
}
-
- return sendFilteredTouchEvent(target->parentItem(), item, event, hasFiltered) || filtered;
+ return sendFilteredPointerEventImpl(event, receiver, filteringParent->parentItem()) || filtered;
}
-bool QQuickWindowPrivate::sendFilteredMouseEvent(QQuickItem *target, QQuickItem *item, QEvent *event, QSet<QQuickItem *> *hasFiltered)
+bool QQuickWindowPrivate::sendFilteredMouseEvent(QEvent *event, QQuickItem *receiver, QQuickItem *filteringParent)
{
- if (!target)
+ if (!filteringParent)
return false;
- QQuickItemPrivate *targetPrivate = QQuickItemPrivate::get(target);
- if (targetPrivate->replayingPressEvent)
+ QQuickItemPrivate *filteringParentPrivate = QQuickItemPrivate::get(filteringParent);
+ if (filteringParentPrivate->replayingPressEvent)
return false;
bool filtered = false;
- if (targetPrivate->filtersChildMouseEvents && !hasFiltered->contains(target)) {
- hasFiltered->insert(target);
- if (target->childMouseEventFilter(item, event))
+ if (filteringParentPrivate->filtersChildMouseEvents && !hasFiltered.contains(filteringParent)) {
+ hasFiltered.append(filteringParent);
+ if (filteringParent->childMouseEventFilter(receiver, event)) {
filtered = true;
- qCDebug(DBG_MOUSE_TARGET) << target << "childMouseEventFilter ->" << filtered;
+ skipDelivery.append(filteringParent);
+ }
+ qCDebug(DBG_MOUSE_TARGET) << "for" << receiver << filteringParent << "childMouseEventFilter ->" << filtered;
}
- return sendFilteredMouseEvent(target->parentItem(), item, event, hasFiltered) || filtered;
+ return sendFilteredMouseEvent(event, receiver, filteringParent->parentItem()) || filtered;
}
bool QQuickWindowPrivate::dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent *event, int startDragThreshold)
@@ -2809,6 +3039,8 @@ void QQuickWindowPrivate::contextCreationFailureMessage(const QSurfaceFormat &fo
#endif // !Q_OS_WIN32
}
+#if QT_DEPRECATED_SINCE(5, 8)
+
/*!
Propagates an event \a e to a QQuickItem \a item on the window.
@@ -2845,8 +3077,8 @@ bool QQuickWindow::sendEvent(QQuickItem *item, QEvent *e)
case QEvent::MouseButtonDblClick:
case QEvent::MouseMove: {
// XXX todo - should sendEvent be doing this? how does it relate to forwarded events?
- QSet<QQuickItem *> hasFiltered;
- if (!d->sendFilteredMouseEvent(item->parentItem(), item, e, &hasFiltered)) {
+ d->hasFiltered.clear();
+ if (!d->sendFilteredMouseEvent(e, item, item->parentItem())) {
// accept because qml items by default accept and have to explicitly opt out of accepting
e->accept();
QCoreApplication::sendEvent(item, e);
@@ -2861,6 +3093,8 @@ bool QQuickWindow::sendEvent(QQuickItem *item, QEvent *e)
return false;
}
+#endif
+
void QQuickWindowPrivate::cleanupNodes()
{
for (int ii = 0; ii < cleanupNodeList.count(); ++ii)
@@ -3463,6 +3697,11 @@ void QQuickWindow::setRenderTarget(QOpenGLFramebufferObject *fbo)
The specified FBO must be created in the context of the window
or one that shares with it.
+ \note \a fboId can also be set to 0. In this case rendering will target the
+ default framebuffer of whichever surface is current when the scenegraph
+ renders. \a size must still be valid, specifying the dimensions of the
+ surface.
+
\note
This function only has an effect when using the default OpenGL scene
graph adaptation.
@@ -3644,6 +3883,23 @@ QQmlIncubationController *QQuickWindow::incubationController() const
*/
/*!
+ \enum QQuickWindow::TextRenderType
+ \since 5.10
+
+ This enum describes the default render type of text-like elements in Qt
+ Quick (\l Text, \l TextInput, etc.).
+
+ Select NativeTextRendering if you prefer text to look native on the target
+ platform and do not require advanced features such as transformation of the
+ text. Using such features in combination with the NativeTextRendering
+ render type will lend poor and sometimes pixelated results.
+
+ \value QtTextRendering Use Qt's own rasterization algorithm.
+
+ \value NativeTextRendering Use the operating system's native rasterizer for text.
+*/
+
+/*!
\fn void QQuickWindow::beforeSynchronizing()
This signal is emitted before the scene graph is synchronized with the QML state.
@@ -4613,7 +4869,7 @@ void QQuickWindow::setSceneGraphBackend(const QString &backend)
}
/*!
- Returns the requested Qt Quick scenegraph \a backend.
+ Returns the requested Qt Quick scenegraph backend.
\note The return value of this function may still be outdated by
subsequent calls to setSceneGraphBackend() until the first QQuickWindow in the
@@ -4665,6 +4921,34 @@ QSGNinePatchNode *QQuickWindow::createNinePatchNode() const
return isSceneGraphInitialized() ? d->context->sceneGraphContext()->createNinePatchNode() : nullptr;
}
+/*!
+ \since 5.10
+
+ Returns the render type of text-like elements in Qt Quick.
+ The default is QQuickWindow::QtTextRendering.
+
+ \sa setTextRenderType()
+*/
+QQuickWindow::TextRenderType QQuickWindow::textRenderType()
+{
+ return QQuickWindowPrivate::textRenderType;
+}
+
+/*!
+ \since 5.10
+
+ Sets the default render type of text-like elements in Qt Quick to \a renderType.
+
+ \note setting the render type will only affect elements created afterwards;
+ the render type of existing elements will not be modified.
+
+ \sa textRenderType()
+*/
+void QQuickWindow::setTextRenderType(QQuickWindow::TextRenderType renderType)
+{
+ QQuickWindowPrivate::textRenderType = renderType;
+}
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, const QQuickWindow *win)
{
diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h
index cc88300988..53e0581fbb 100644
--- a/src/quick/items/qquickwindow.h
+++ b/src/quick/items/qquickwindow.h
@@ -47,6 +47,7 @@
#include <QtGui/qwindow.h>
#include <QtGui/qevent.h>
#include <QtQml/qqml.h>
+#include <QtQml/qqmldebug.h>
QT_BEGIN_NAMESPACE
@@ -100,7 +101,13 @@ public:
};
Q_ENUM(SceneGraphError)
- explicit QQuickWindow(QWindow *parent = Q_NULLPTR);
+ enum TextRenderType {
+ QtTextRendering,
+ NativeTextRendering
+ };
+ Q_ENUM(TextRenderType)
+
+ explicit QQuickWindow(QWindow *parent = nullptr);
explicit QQuickWindow(QQuickRenderControl *renderControl);
virtual ~QQuickWindow();
@@ -108,11 +115,13 @@ public:
QQuickItem *contentItem() const;
QQuickItem *activeFocusItem() const;
- QObject *focusObject() const Q_DECL_OVERRIDE;
+ QObject *focusObject() const override;
QQuickItem *mouseGrabberItem() const;
- bool sendEvent(QQuickItem *, QEvent *);
+#if QT_DEPRECATED_SINCE(5, 8)
+ QT_DEPRECATED bool sendEvent(QQuickItem *, QEvent *);
+#endif
QImage grabWindow();
#if QT_CONFIG(opengl)
@@ -128,7 +137,7 @@ public:
QQmlIncubationController *incubationController() const;
#if QT_CONFIG(accessibility)
- QAccessibleInterface *accessibleRoot() const Q_DECL_OVERRIDE;
+ QAccessibleInterface *accessibleRoot() const override;
#endif
// Scene graph specific functions
@@ -168,6 +177,9 @@ public:
QSGImageNode *createImageNode() const;
QSGNinePatchNode *createNinePatchNode() const;
+ static TextRenderType textRenderType();
+ static void setTextRenderType(TextRenderType renderType);
+
Q_SIGNALS:
void frameSwapped();
Q_REVISION(2) void openglContextCreated(QOpenGLContext *context);
@@ -191,27 +203,28 @@ public Q_SLOTS:
void releaseResources();
protected:
- QQuickWindow(QQuickWindowPrivate &dd, QWindow *parent = Q_NULLPTR);
+ QQuickWindow(QQuickWindowPrivate &dd, QWindow *parent = nullptr);
+ QQuickWindow(QQuickWindowPrivate &dd, QQuickRenderControl *control);
- void exposeEvent(QExposeEvent *) Q_DECL_OVERRIDE;
- void resizeEvent(QResizeEvent *) Q_DECL_OVERRIDE;
+ void exposeEvent(QExposeEvent *) override;
+ void resizeEvent(QResizeEvent *) override;
- void showEvent(QShowEvent *) Q_DECL_OVERRIDE;
- void hideEvent(QHideEvent *) Q_DECL_OVERRIDE;
+ void showEvent(QShowEvent *) override;
+ void hideEvent(QHideEvent *) override;
// TODO Qt 6: reimplement QWindow::closeEvent to emit closing
- void focusInEvent(QFocusEvent *) Q_DECL_OVERRIDE;
- void focusOutEvent(QFocusEvent *) Q_DECL_OVERRIDE;
+ void focusInEvent(QFocusEvent *) override;
+ void focusOutEvent(QFocusEvent *) override;
- bool event(QEvent *) Q_DECL_OVERRIDE;
- void keyPressEvent(QKeyEvent *) Q_DECL_OVERRIDE;
- void keyReleaseEvent(QKeyEvent *) Q_DECL_OVERRIDE;
- void mousePressEvent(QMouseEvent *) Q_DECL_OVERRIDE;
- void mouseReleaseEvent(QMouseEvent *) Q_DECL_OVERRIDE;
- void mouseDoubleClickEvent(QMouseEvent *) Q_DECL_OVERRIDE;
- void mouseMoveEvent(QMouseEvent *) Q_DECL_OVERRIDE;
+ bool event(QEvent *) override;
+ void keyPressEvent(QKeyEvent *) override;
+ void keyReleaseEvent(QKeyEvent *) override;
+ void mousePressEvent(QMouseEvent *) override;
+ void mouseReleaseEvent(QMouseEvent *) override;
+ void mouseDoubleClickEvent(QMouseEvent *) override;
+ void mouseMoveEvent(QMouseEvent *) override;
#if QT_CONFIG(wheelevent)
- void wheelEvent(QWheelEvent *) Q_DECL_OVERRIDE;
+ void wheelEvent(QWheelEvent *) override;
#endif
private Q_SLOTS:
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index 7dbfed099e..ce9b98504c 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -143,12 +143,15 @@ public:
bool deliverTouchAsMouse(QQuickItem *item, QQuickPointerEvent *pointerEvent);
bool isDeliveringTouchAsMouse() const { return touchMouseId != -1 && touchMouseDevice; }
void translateTouchEvent(QTouchEvent *touchEvent);
- void grabTouchPoints(QQuickItem *grabber, const QVector<int> &ids);
+ void grabTouchPoints(QObject *grabber, const QVector<int> &ids);
void removeGrabber(QQuickItem *grabber, bool mouse = true, bool touch = true);
void sendUngrabEvent(QQuickItem *grabber, bool touch);
static QMouseEvent *cloneMouseEvent(QMouseEvent *event, QPointF *transformedLocalPos = 0);
+ void deliverToPassiveGrabbers(const QVector<QPointer <QQuickPointerHandler> > &passiveGrabbers, QQuickPointerEvent *pointerEvent);
void deliverMouseEvent(QQuickPointerMouseEvent *pointerEvent);
- bool sendFilteredMouseEvent(QQuickItem *, QQuickItem *, QEvent *, QSet<QQuickItem *> *);
+ bool sendFilteredMouseEvent(QEvent *event, QQuickItem *receiver, QQuickItem *filteringParent);
+ bool sendFilteredPointerEvent(QQuickPointerEvent *event, QQuickItem *receiver, QQuickItem *filteringParent = nullptr);
+ bool sendFilteredPointerEventImpl(QQuickPointerEvent *event, QQuickItem *receiver, QQuickItem *filteringParent);
#if QT_CONFIG(wheelevent)
bool deliverWheelEvent(QQuickItem *, QWheelEvent *);
#endif
@@ -165,20 +168,19 @@ public:
// the device-specific event instances which are reused during event delivery
mutable QVector<QQuickPointerEvent *> pointerEventInstances;
- QQuickPointerEvent *queryPointerEventInstance(QQuickPointerDevice *device) const;
- QQuickPointerEvent *pointerEventInstance(QQuickPointerDevice *device) const;
+ QQuickPointerEvent *queryPointerEventInstance(QQuickPointerDevice *device, QEvent::Type eventType = QEvent::None) const;
+ QQuickPointerEvent *pointerEventInstance(QQuickPointerDevice *device, QEvent::Type eventType = QEvent::None) const;
// delivery of pointer events:
QQuickPointerEvent *pointerEventInstance(QEvent *ev) const;
void deliverPointerEvent(QQuickPointerEvent *);
void deliverTouchEvent(QQuickPointerTouchEvent *);
bool deliverTouchCancelEvent(QTouchEvent *);
- bool deliverPressEvent(QQuickPointerEvent *, QSet<QQuickItem *> *);
- bool deliverUpdatedTouchPoints(QQuickPointerTouchEvent *event, QSet<QQuickItem *> *hasFiltered);
- bool deliverMatchingPointsToItem(QQuickItem *item, QQuickPointerEvent *pointerEvent, QSet<QQuickItem*> *filtered);
- bool sendFilteredTouchEvent(QQuickItem *target, QQuickItem *item, QQuickPointerTouchEvent *event, QSet<QQuickItem*> *filtered);
+ bool deliverPressOrReleaseEvent(QQuickPointerEvent *, bool handlersOnly = false);
+ void deliverUpdatedTouchPoints(QQuickPointerTouchEvent *event);
+ void deliverMatchingPointsToItem(QQuickItem *item, QQuickPointerEvent *pointerEvent, bool handlersOnly = false);
- QVector<QQuickItem *> pointerTargets(QQuickItem *, const QPointF &, bool checkMouseButtons) const;
+ QVector<QQuickItem *> pointerTargets(QQuickItem *, const QPointF &, bool checkMouseButtons, bool checkAcceptsTouch) const;
QVector<QQuickItem *> mergePointerTargets(const QVector<QQuickItem *> &list1, const QVector<QQuickItem *> &list2) const;
// hover delivery
@@ -228,6 +230,8 @@ public:
QList<QSGNode *> cleanupNodeList;
QVector<QQuickItem *> itemsToPolish;
+ QVector<QQuickItem *> hasFiltered; // during event delivery to a single receiver, the filtering parents for which childMouseEventFilter was already called
+ QVector<QQuickItem *> skipDelivery; // during delivery of one event to all receivers, Items to which we know delivery is no longer necessary
qreal devicePixelRatio;
QMetaObject::Connection physicalDpiChangedConnection;
@@ -265,6 +269,9 @@ public:
uint lastWheelEventAccepted : 1;
bool componentCompleted : 1;
+ bool allowChildEventFiltering : 1;
+ bool allowDoubleClick : 1;
+
Qt::FocusReason lastFocusReason;
QOpenGLFramebufferObject *renderTarget;
@@ -276,6 +283,7 @@ public:
mutable QQuickWindowIncubationController *incubationController;
static bool defaultAlphaBuffer;
+ static QQuickWindow::TextRenderType textRenderType;
static bool dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent *event, int startDragThreshold = -1);
@@ -292,6 +300,14 @@ public:
return overThreshold;
}
+ static bool dragOverThreshold(const QQuickEventPoint *point)
+ {
+ QPointF delta = point->scenePosition() - point->scenePressPosition();
+ return (QQuickWindowPrivate::dragOverThreshold(delta.x(), Qt::XAxis, point) ||
+ QQuickWindowPrivate::dragOverThreshold(delta.y(), Qt::YAxis, point));
+ }
+
+
// data property
static void data_append(QQmlListProperty<QObject> *, QObject *);
static int data_count(QQmlListProperty<QObject> *);
@@ -320,7 +336,7 @@ class QQuickWindowQObjectCleanupJob : public QRunnable
{
public:
QQuickWindowQObjectCleanupJob(QObject *o) : object(o) { }
- void run() Q_DECL_OVERRIDE { delete object; }
+ void run() override { delete object; }
QObject *object;
static void schedule(QQuickWindow *window, QObject *object) {
Q_ASSERT(window);
diff --git a/src/quick/items/qquickwindowattached.cpp b/src/quick/items/qquickwindowattached.cpp
index c8d71139ca..ae62a7a496 100644
--- a/src/quick/items/qquickwindowattached.cpp
+++ b/src/quick/items/qquickwindowattached.cpp
@@ -68,12 +68,12 @@ bool QQuickWindowAttached::isActive() const
QQuickItem *QQuickWindowAttached::activeFocusItem() const
{
- return (m_window ? m_window->activeFocusItem() : Q_NULLPTR);
+ return (m_window ? m_window->activeFocusItem() : nullptr);
}
QQuickItem *QQuickWindowAttached::contentItem() const
{
- return (m_window ? m_window->contentItem() : Q_NULLPTR);
+ return (m_window ? m_window->contentItem() : nullptr);
}
int QQuickWindowAttached::width() const
diff --git a/src/quick/items/qquickwindowmodule.cpp b/src/quick/items/qquickwindowmodule.cpp
index e702cc5a3e..ab3f49d5b6 100644
--- a/src/quick/items/qquickwindowmodule.cpp
+++ b/src/quick/items/qquickwindowmodule.cpp
@@ -114,7 +114,7 @@ void QQuickWindowQmlImpl::classBegin()
{
// The content item has CppOwnership policy (set in QQuickWindow). Ensure the presence of a JS
// wrapper so that the garbage collector can see the policy.
- QV4::ExecutionEngine *v4 = QQmlEnginePrivate::getV4Engine(e);
+ QV4::ExecutionEngine *v4 = e->handle();
QV4::QObjectWrapper::wrap(v4, d->contentItem);
}
}
@@ -209,6 +209,7 @@ void QQuickWindowModule::defineModule()
qmlRegisterUncreatableType<QQuickScreen>(uri, 2, 0, "Screen", QStringLiteral("Screen can only be used via the attached property."));
qmlRegisterUncreatableType<QQuickScreen,1>(uri, 2, 3, "Screen", QStringLiteral("Screen can only be used via the attached property."));
qmlRegisterUncreatableType<QQuickScreenInfo,2>(uri, 2, 3, "ScreenInfo", QStringLiteral("ScreenInfo can only be used via the attached property."));
+ qmlRegisterUncreatableType<QQuickScreenInfo,10>(uri, 2, 10, "ScreenInfo", QStringLiteral("ScreenInfo can only be used via the attached property."));
}
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickwindowmodule_p.h b/src/quick/items/qquickwindowmodule_p.h
index 869d5b9a8e..e7033e9b8d 100644
--- a/src/quick/items/qquickwindowmodule_p.h
+++ b/src/quick/items/qquickwindowmodule_p.h
@@ -70,7 +70,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickWindowQmlImpl : public QQuickWindow, public Q
Q_PROPERTY(QObject *screen READ screen WRITE setScreen NOTIFY screenChanged REVISION 2)
public:
- QQuickWindowQmlImpl(QWindow *parent = Q_NULLPTR);
+ QQuickWindowQmlImpl(QWindow *parent = nullptr);
void setVisible(bool visible);
void setVisibility(Visibility visibility);
@@ -86,8 +86,8 @@ Q_SIGNALS:
Q_REVISION(2) void screenChanged();
protected:
- void classBegin() Q_DECL_OVERRIDE;
- void componentComplete() Q_DECL_OVERRIDE;
+ void classBegin() override;
+ void componentComplete() override;
private Q_SLOTS:
void setWindowVisibility();
diff --git a/src/quick/qtquick2.cpp b/src/quick/qtquick2.cpp
index c6b89fabd3..00fc23645b 100644
--- a/src/quick/qtquick2.cpp
+++ b/src/quick/qtquick2.cpp
@@ -62,7 +62,7 @@ static void initResources()
QT_BEGIN_NAMESPACE
-#ifdef QT_NO_QML_DEBUGGER
+#if !QT_CONFIG(qml_debug)
class QQmlQtQuick2DebugStatesDelegate : public QQmlDebugStatesDelegate {};
@@ -181,7 +181,7 @@ void QQmlQtQuick2DebugStatesDelegate::resetBindingForInvalidProperty(QObject *ob
}
}
-#endif // QT_NO_QML_DEBUGGER
+#endif // QT_CONFIG(qml_debug)
void QQmlQtQuick2Module::defineModule()
{
diff --git a/src/quick/quick.pro b/src/quick/quick.pro
index eae9b09b2f..e9a8b84b2a 100644
--- a/src/quick/quick.pro
+++ b/src/quick/quick.pro
@@ -30,6 +30,7 @@ ANDROID_BUNDLED_FILES += \
include(util/util.pri)
include(scenegraph/scenegraph.pri)
include(items/items.pri)
+include(handlers/handlers.pri)
qtConfig(quick-designer): \
include(designer/designer.pri)
qtConfig(accessibility) {
diff --git a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp
index 4cec84646e..d715d900ba 100644
--- a/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgabstractsoftwarerenderer.cpp
@@ -255,14 +255,14 @@ QRect QSGAbstractSoftwareRenderer::backgroundRect()
void QSGAbstractSoftwareRenderer::nodeAdded(QSGNode *node)
{
- qCDebug(lc2DRender) << "nodeAdded" << (void*)node;
+ qCDebug(lc2DRender, "nodeAdded %p", (void*)node);
m_nodeUpdater->updateNodes(node);
}
void QSGAbstractSoftwareRenderer::nodeRemoved(QSGNode *node)
{
- qCDebug(lc2DRender) << "nodeRemoved" << (void*)node;
+ qCDebug(lc2DRender, "nodeRemoved %p", (void*)node);
auto renderable = renderableNode(node);
// remove mapping
@@ -286,7 +286,7 @@ void QSGAbstractSoftwareRenderer::nodeRemoved(QSGNode *node)
void QSGAbstractSoftwareRenderer::nodeGeometryUpdated(QSGNode *node)
{
- qCDebug(lc2DRender) << "nodeGeometryUpdated";
+ qCDebug(lc2DRender, "nodeGeometryUpdated");
// Mark node as dirty
auto renderable = renderableNode(node);
@@ -299,7 +299,7 @@ void QSGAbstractSoftwareRenderer::nodeGeometryUpdated(QSGNode *node)
void QSGAbstractSoftwareRenderer::nodeMaterialUpdated(QSGNode *node)
{
- qCDebug(lc2DRender) << "nodeMaterialUpdated";
+ qCDebug(lc2DRender, "nodeMaterialUpdated");
// Mark node as dirty
auto renderable = renderableNode(node);
@@ -312,7 +312,7 @@ void QSGAbstractSoftwareRenderer::nodeMaterialUpdated(QSGNode *node)
void QSGAbstractSoftwareRenderer::nodeMatrixUpdated(QSGNode *node)
{
- qCDebug(lc2DRender) << "nodeMaterialUpdated";
+ qCDebug(lc2DRender, "nodeMaterialUpdated");
// Update children nodes
m_nodeUpdater->updateNodes(node);
@@ -320,7 +320,7 @@ void QSGAbstractSoftwareRenderer::nodeMatrixUpdated(QSGNode *node)
void QSGAbstractSoftwareRenderer::nodeOpacityUpdated(QSGNode *node)
{
- qCDebug(lc2DRender) << "nodeOpacityUpdated";
+ qCDebug(lc2DRender, "nodeOpacityUpdated");
// Update children nodes
m_nodeUpdater->updateNodes(node);
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp
index f6898b3879..bf3141bc32 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode.cpp
@@ -227,8 +227,8 @@ void QSGSoftwareInternalRectangleNode::paint(QPainter *painter)
{
//We can only check for a device pixel ratio change when we know what
//paint device is being used.
- if (painter->device()->devicePixelRatio() != m_devicePixelRatio) {
- m_devicePixelRatio = painter->device()->devicePixelRatio();
+ if (!qFuzzyCompare(painter->device()->devicePixelRatioF(), m_devicePixelRatio)) {
+ m_devicePixelRatio = painter->device()->devicePixelRatioF();
generateCornerPixmap();
}
@@ -245,7 +245,7 @@ void QSGSoftwareInternalRectangleNode::paint(QPainter *painter)
} else {
//Rounded Rects and Rects with Borders
//Avoids broken behaviors of QPainter::drawRect/roundedRect
- QPixmap pixmap = QPixmap(m_rect.width() * m_devicePixelRatio, m_rect.height() * m_devicePixelRatio);
+ QPixmap pixmap = QPixmap(qRound(m_rect.width() * m_devicePixelRatio), qRound(m_rect.height() * m_devicePixelRatio));
pixmap.fill(Qt::transparent);
pixmap.setDevicePixelRatio(m_devicePixelRatio);
QPainter pixmapPainter(&pixmap);
@@ -356,7 +356,7 @@ void QSGSoftwareInternalRectangleNode::paintRectangle(QPainter *painter, const Q
} else {
//blit 4 corners to border
- int scaledRadius = radius * m_devicePixelRatio;
+ int scaledRadius = qRound(radius * m_devicePixelRatio);
QRectF topLeftCorner(QPointF(rect.x(), rect.y()),
QPointF(rect.x() + radius, rect.y() + radius));
painter->drawPixmap(topLeftCorner, m_cornerPixmap, QRectF(0, 0, scaledRadius, scaledRadius));
@@ -416,7 +416,7 @@ void QSGSoftwareInternalRectangleNode::generateCornerPixmap()
//Generate new corner Pixmap
int radius = qFloor(qMin(qMin(m_rect.width(), m_rect.height()) * 0.5, m_radius));
- m_cornerPixmap = QPixmap(radius * 2 * m_devicePixelRatio, radius * 2 * m_devicePixelRatio);
+ m_cornerPixmap = QPixmap(qRound(radius * 2 * m_devicePixelRatio), qRound(radius * 2 * m_devicePixelRatio));
m_cornerPixmap.setDevicePixelRatio(m_devicePixelRatio);
m_cornerPixmap.fill(Qt::transparent);
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode_p.h
index f363e279e1..1f87424d2a 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode_p.h
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwareinternalrectanglenode_p.h
@@ -95,7 +95,7 @@ private:
bool m_cornerPixmapIsDirty;
QPixmap m_cornerPixmap;
- int m_devicePixelRatio;
+ qreal m_devicePixelRatio;
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer_p.h
index d3f13e40b1..9f5a22e66f 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer_p.h
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer_p.h
@@ -93,6 +93,7 @@ public:
void setDevicePixelRatio(qreal ratio) override;
void setMirrorHorizontal(bool mirror) override;
void setMirrorVertical(bool mirror) override;
+ void setSamples(int) override { }
public slots:
void markDirtyTexture() override;
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp
index a56c126541..303f98c801 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaprenderer.cpp
@@ -64,7 +64,7 @@ void QSGSoftwarePixmapRenderer::renderScene(uint)
class B : public QSGBindable
{
public:
- void bind() const { }
+ void bind() const override { }
} bindable;
QSGRenderer::renderScene(bindable);
}
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp
index 384c124a02..77d21ec042 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepublicnodes.cpp
@@ -101,10 +101,10 @@ void QSGSoftwareImageNode::paint(QPainter *painter)
if (!m_cachedPixmap.isNull()) {
painter->drawPixmap(m_rect, m_cachedPixmap, m_sourceRect);
- } else if (QSGSoftwarePixmapTexture *pt = dynamic_cast<QSGSoftwarePixmapTexture *>(m_texture)) {
+ } else if (QSGSoftwarePixmapTexture *pt = qobject_cast<QSGSoftwarePixmapTexture *>(m_texture)) {
const QPixmap &pm = pt->pixmap();
painter->drawPixmap(m_rect, pm, m_sourceRect);
- } else if (QSGPlainTexture *pt = dynamic_cast<QSGPlainTexture *>(m_texture)) {
+ } else if (QSGPlainTexture *pt = qobject_cast<QSGPlainTexture *>(m_texture)) {
const QImage &im = pt->image();
painter->drawImage(m_rect, im, m_sourceRect);
}
@@ -116,14 +116,14 @@ void QSGSoftwareImageNode::updateCachedMirroredPixmap()
m_cachedPixmap = QPixmap();
} else {
- if (QSGSoftwarePixmapTexture *pt = dynamic_cast<QSGSoftwarePixmapTexture *>(m_texture)) {
+ if (QSGSoftwarePixmapTexture *pt = qobject_cast<QSGSoftwarePixmapTexture *>(m_texture)) {
QTransform mirrorTransform;
if (m_transformMode.testFlag(MirrorVertically))
mirrorTransform = mirrorTransform.scale(1, -1);
if (m_transformMode.testFlag(MirrorHorizontally))
mirrorTransform = mirrorTransform.scale(-1, 1);
m_cachedPixmap = pt->pixmap().transformed(mirrorTransform);
- } else if (QSGPlainTexture *pt = dynamic_cast<QSGPlainTexture *>(m_texture)) {
+ } else if (QSGPlainTexture *pt = qobject_cast<QSGPlainTexture *>(m_texture)) {
m_cachedPixmap = QPixmap::fromImage(pt->image().mirrored(m_transformMode.testFlag(MirrorHorizontally), m_transformMode.testFlag(MirrorVertically)));
} else {
m_cachedPixmap = QPixmap();
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp
index 781d565ce4..7fb531cca3 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderablenode.cpp
@@ -218,8 +218,9 @@ void QSGSoftwareRenderableNode::update()
m_boundingRectMin = QRect();
m_boundingRectMax = QRect();
} else {
- m_boundingRectMin = m_boundingRectMin.intersected(m_clipRegion.rects().constFirst());
- m_boundingRectMax = m_boundingRectMax.intersected(m_clipRegion.rects().constFirst());
+ const auto rects = m_clipRegion.begin();
+ m_boundingRectMin = m_boundingRectMin.intersected(rects[0]);
+ m_boundingRectMax = m_boundingRectMax.intersected(rects[0]);
}
}
@@ -263,18 +264,21 @@ QRegion QSGSoftwareRenderableNode::renderNode(QPainter *painter, bool forceOpaqu
QMatrix4x4 m = m_transform;
rd->m_matrix = &m;
rd->m_opacity = m_opacity;
- RenderNodeState rs;
- rs.cr = m_clipRegion;
- const QRect br = m_handle.renderNode->flags().testFlag(QSGRenderNode::BoundedRectRendering)
- ? m_boundingRectMax :
- QRect(0, 0, painter->device()->width(), painter->device()->height());
+ // all the clip region below is in world coordinates, taking m_transform into account already
+ QRegion cr = m_dirtyRegion;
+ if (m_clipRegion.rectCount() > 1)
+ cr &= m_clipRegion;
painter->save();
- painter->setClipRegion(br, Qt::ReplaceClip);
+ RenderNodeState rs;
+ rs.cr = cr;
m_handle.renderNode->render(&rs);
painter->restore();
+ const QRect br = m_handle.renderNode->flags().testFlag(QSGRenderNode::BoundedRectRendering)
+ ? m_boundingRectMax // already mapped to world
+ : QRect(0, 0, painter->device()->width(), painter->device()->height());
m_previousDirtyRegion = QRegion(br);
m_isDirty = false;
m_dirtyRegion = QRegion();
@@ -285,7 +289,7 @@ QRegion QSGSoftwareRenderableNode::renderNode(QPainter *painter, bool forceOpaqu
painter->save();
painter->setOpacity(m_opacity);
- // Set clipRegion to m_dirtyRegion (in world coordinates)
+ // Set clipRegion to m_dirtyRegion (in world coordinates, so must be done before the setTransform below)
// as m_dirtyRegion already accounts for clipRegion
painter->setClipRegion(m_dirtyRegion, Qt::ReplaceClip);
if (m_clipRegion.rectCount() > 1)
@@ -302,10 +306,10 @@ QRegion QSGSoftwareRenderableNode::renderNode(QPainter *painter, bool forceOpaqu
case QSGSoftwareRenderableNode::SimpleTexture:
{
QSGTexture *texture = m_handle.simpleTextureNode->texture();
- if (QSGSoftwarePixmapTexture *pt = dynamic_cast<QSGSoftwarePixmapTexture *>(texture)) {
+ if (QSGSoftwarePixmapTexture *pt = qobject_cast<QSGSoftwarePixmapTexture *>(texture)) {
const QPixmap &pm = pt->pixmap();
painter->drawPixmap(m_handle.simpleTextureNode->rect(), pm, m_handle.simpleTextureNode->sourceRect());
- } else if (QSGPlainTexture *pt = dynamic_cast<QSGPlainTexture *>(texture)) {
+ } else if (QSGPlainTexture *pt = qobject_cast<QSGPlainTexture *>(texture)) {
const QImage &im = pt->image();
painter->drawImage(m_handle.simpleTextureNode->rect(), im, m_handle.simpleTextureNode->sourceRect());
}
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp
index ddc7ec5d4c..d403884b4e 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp
@@ -90,7 +90,7 @@ void QSGSoftwareRenderer::renderScene(uint)
class B : public QSGBindable
{
public:
- void bind() const { }
+ void bind() const override { }
} bindable;
QSGRenderer::renderScene(bindable);
}
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
index 3f0d1383b9..423f5f7321 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp
@@ -97,7 +97,6 @@ void QSGSoftwareRenderLoop::windowDestroyed(QQuickWindow *window)
if (m_windows.size() == 0) {
rc->invalidate();
- QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
}
}
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
index 19f16a79fb..a7485a90eb 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
@@ -188,8 +188,8 @@ public:
delete rc;
}
- bool event(QEvent *e);
- void run();
+ bool event(QEvent *e) override;
+ void run() override;
void syncAndRender();
void sync(bool inExpose);
@@ -523,7 +523,7 @@ void QSGSoftwareRenderThread::syncAndRender()
// rate of the current screen the window is on.
int blockTime = vsyncDelta - (int) renderThrottleTimer.elapsed();
if (blockTime > 0) {
- qCDebug(QSG_RASTER_LOG_RENDERLOOP) << "RT - blocking for " << blockTime << "ms";
+ qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - blocking for %d ms", blockTime);
msleep(blockTime);
}
renderThrottleTimer.restart();
diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp
new file mode 100644
index 0000000000..301f2826dc
--- /dev/null
+++ b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture.cpp
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsgcompressedatlastexture_p.h"
+
+#include <QtCore/QVarLengthArray>
+#include <QtCore/QElapsedTimer>
+#include <QtCore/QtMath>
+
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QScreen>
+#include <QtGui/QSurface>
+#include <QtGui/QWindow>
+#include <QtGui/QOpenGLFunctions>
+#include <QtGui/QOpenGLTexture>
+#include <QDebug>
+
+#include <private/qqmlglobal_p.h>
+#include <private/qquickprofiler_p.h>
+#include <private/qsgtexture_p.h>
+#include <private/qsgcompressedtexture_p.h>
+#include <private/qsgpkmhandler_p.h>
+
+QT_BEGIN_NAMESPACE
+
+static QElapsedTimer qsg_renderer_timer;
+
+namespace QSGCompressedAtlasTexture
+{
+
+Atlas::Atlas(const QSize &size, uint format)
+ : QSGAtlasTexture::AtlasBase(size)
+ , m_format(format)
+{
+}
+
+Atlas::~Atlas()
+{
+}
+
+Texture *Atlas::create(const QByteArray &data, int dataLength, int dataOffset, const QSize &size, const QSize &paddedSize)
+{
+ // No need to lock, as manager already locked it.
+ QRect rect = m_allocator.allocate(paddedSize);
+ if (rect.width() > 0 && rect.height() > 0) {
+ Texture *t = new Texture(this, rect, data, dataLength, dataOffset, size);
+ m_pending_uploads << t;
+ return t;
+ }
+ return 0;
+}
+
+void Atlas::generateTexture()
+{
+ QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
+ funcs->glCompressedTexImage2D(GL_TEXTURE_2D, 0, m_format,
+ m_size.width(), m_size.height(), 0,
+ (m_size.width() * m_size.height()) / 2,
+ 0);
+}
+
+void Atlas::uploadPendingTexture(int i)
+{
+ Texture *texture = static_cast<Texture*>(m_pending_uploads.at(i));
+
+ const QRect &r = texture->atlasSubRect();
+
+ QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
+ funcs->glCompressedTexSubImage2D(GL_TEXTURE_2D, 0,
+ r.x(), r.y(), r.width(), r.height(), m_format,
+ texture->sizeInBytes(),
+ texture->data().constData() + texture->dataOffset());
+
+ qCDebug(QSG_LOG_TIME_TEXTURE).nospace() << "compressed atlastexture uploaded in: " << qsg_renderer_timer.elapsed()
+ << "ms (" << texture->textureSize().width() << "x"
+ << texture->textureSize().height() << ")";
+
+ // TODO: consider releasing the data (as is done in the regular atlas)?
+ // The advantage of keeping this data around is that it makes it much easier
+ // to remove the texture from the atlas
+}
+
+Texture::Texture(Atlas *atlas, const QRect &textureRect, const QByteArray &data, int dataLength, int dataOffset, const QSize &size)
+ : QSGAtlasTexture::TextureBase(atlas, textureRect)
+ , m_nonatlas_texture(0)
+ , m_data(data)
+ , m_size(size)
+ , m_dataLength(dataLength)
+ , m_dataOffset(dataOffset)
+{
+ float w = atlas->size().width();
+ float h = atlas->size().height();
+ QRect nopad = atlasSubRect();
+ // offset by half-pixel to prevent bleeding when scaling
+ m_texture_coords_rect = QRectF((nopad.x() + .5) / w,
+ (nopad.y() + .5) / h,
+ (nopad.width() - 1.) / w,
+ (nopad.height() - 1.) / h);
+}
+
+Texture::~Texture()
+{
+ delete m_nonatlas_texture;
+}
+
+bool Texture::hasAlphaChannel() const
+{
+ return QSGCompressedTexture::formatIsOpaque(static_cast<Atlas*>(m_atlas)->format());
+}
+
+QSGTexture *Texture::removedFromAtlas() const
+{
+ if (m_nonatlas_texture) {
+ m_nonatlas_texture->setMipmapFiltering(mipmapFiltering());
+ m_nonatlas_texture->setFiltering(filtering());
+ return m_nonatlas_texture;
+ }
+
+ if (!m_data.isEmpty()) {
+ QSGCompressedTexture::DataPtr texData(QSGCompressedTexture::DataPtr::create());
+ texData->data = m_data;
+ texData->size = m_size;
+ texData->format = static_cast<Atlas*>(m_atlas)->format();
+ texData->hasAlpha = hasAlphaChannel();
+ texData->dataLength = m_dataLength;
+ texData->dataOffset = m_dataOffset;
+ m_nonatlas_texture = new QSGCompressedTexture(texData);
+ m_nonatlas_texture->setMipmapFiltering(mipmapFiltering());
+ m_nonatlas_texture->setFiltering(filtering());
+ }
+
+ return m_nonatlas_texture;
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgdistancefieldutil_p.h b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h
index 354a48a81e..59e935b623 100644
--- a/src/quick/scenegraph/util/qsgdistancefieldutil_p.h
+++ b/src/quick/scenegraph/compressedtexture/qsgcompressedatlastexture_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef QSGDISTANCEFIELDUTIL_H
-#define QSGDISTANCEFIELDUTIL_H
+#ifndef QSGCOMPRESSEDATLASTEXTURE_P_H
+#define QSGCOMPRESSEDATLASTEXTURE_P_H
//
// W A R N I N G
@@ -51,43 +51,69 @@
// We mean it.
//
-#include <qrawfont.h>
-#include <private/qfontengine_p.h>
-#include <private/qsgadaptationlayer_p.h>
+#include <QtCore/QSize>
+
+#include <QtGui/qopengl.h>
+
+#include <QtQuick/QSGTexture>
+#include <QtQuick/private/qsgareaallocator_p.h>
+#include <QtQuick/private/qsgatlastexture_p.h>
QT_BEGIN_NAMESPACE
-typedef float (*ThresholdFunc)(float glyphScale);
-typedef float (*AntialiasingSpreadFunc)(float glyphScale);
+class QSGCompressedTextureFactory;
+
+namespace QSGCompressedAtlasTexture {
-class QOpenGLShaderProgram;
-class QSGDistanceFieldGlyphCache;
-class QSGContext;
+class Texture;
-class Q_QUICK_PRIVATE_EXPORT QSGDistanceFieldGlyphCacheManager
+class Atlas : public QSGAtlasTexture::AtlasBase
{
public:
- QSGDistanceFieldGlyphCacheManager();
- ~QSGDistanceFieldGlyphCacheManager();
+ Atlas(const QSize &size, uint format);
+ ~Atlas();
- QSGDistanceFieldGlyphCache *cache(const QRawFont &font);
- void insertCache(const QRawFont &font, QSGDistanceFieldGlyphCache *cache);
+ void generateTexture() override;
+ void uploadPendingTexture(int i) override;
- ThresholdFunc thresholdFunc() const { return m_threshold_func; }
- void setThresholdFunc(ThresholdFunc func) { m_threshold_func = func; }
+ Texture *create(const QByteArray &data, int dataLength, int dataOffset, const QSize &size, const QSize &paddedSize);
- AntialiasingSpreadFunc antialiasingSpreadFunc() const { return m_antialiasingSpread_func; }
- void setAntialiasingSpreadFunc(AntialiasingSpreadFunc func) { m_antialiasingSpread_func = func; }
+ uint format() const { return m_format; }
private:
- static QString fontKey(const QRawFont &font);
+ uint m_format;
+};
+
+class Texture : public QSGAtlasTexture::TextureBase
+{
+ Q_OBJECT
+public:
+ Texture(Atlas *atlas, const QRect &textureRect, const QByteArray &data, int dataLength, int dataOffset, const QSize &size);
+ ~Texture();
+
+ QSize textureSize() const override { return m_size; }
+ bool hasAlphaChannel() const override;
+ bool hasMipmaps() const override { return false; }
+
+ QRectF normalizedTextureSubRect() const override { return m_texture_coords_rect; }
- QHash<QString, QSGDistanceFieldGlyphCache *> m_caches;
+ QSGTexture *removedFromAtlas() const override;
- ThresholdFunc m_threshold_func;
- AntialiasingSpreadFunc m_antialiasingSpread_func;
+ const QByteArray &data() const { return m_data; }
+ int sizeInBytes() const { return m_dataLength; }
+ int dataOffset() const { return m_dataOffset; }
+
+private:
+ QRectF m_texture_coords_rect;
+ mutable QSGTexture *m_nonatlas_texture;
+ QByteArray m_data;
+ QSize m_size;
+ int m_dataLength;
+ int m_dataOffset;
};
+}
+
QT_END_NAMESPACE
-#endif // QSGDISTANCEFIELDUTIL_H
+#endif
diff --git a/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp
new file mode 100644
index 0000000000..839c562989
--- /dev/null
+++ b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture.cpp
@@ -0,0 +1,246 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qsgcompressedtexture_p.h"
+#include <QOpenGLContext>
+#include <QOpenGLTexture>
+#include <QOpenGLFunctions>
+#include <QDebug>
+#include <QtQuick/private/qquickwindow_p.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(QSG_LOG_TEXTUREIO, "qt.scenegraph.textureio");
+
+bool QSGCompressedTextureData::isValid() const
+{
+ if (data.isNull() || size.isEmpty() || !format)
+ return false;
+ if (dataLength < 0 || dataOffset < 0 || dataOffset >= data.length())
+ return false;
+ if (dataLength > 0 && qint64(dataOffset) + qint64(dataLength) > qint64(data.length()))
+ return false;
+
+ return true;
+}
+
+int QSGCompressedTextureData::sizeInBytes() const
+{
+ if (!isValid())
+ return 0;
+ return dataLength > 0 ? dataLength : data.length() - dataOffset;
+}
+
+Q_QUICK_PRIVATE_EXPORT QDebug operator<<(QDebug dbg, const QSGCompressedTextureData *d)
+{
+ QDebugStateSaver saver(dbg);
+
+ dbg.nospace() << "QSGCompressedTextureData(";
+ if (d) {
+ dbg << d->logName << ' ';
+ dbg << static_cast<QOpenGLTexture::TextureFormat>(d->format)
+ << "[0x" << hex << d->format << dec << "]";
+ dbg.space() << (d->hasAlpha ? "with" : "no") << "alpha" << d->size
+ << "databuffer" << d->data.size() << "offset" << d->dataOffset << "length";
+ dbg.nospace() << d->dataLength << ")";
+ } else {
+ dbg << "null)";
+ }
+ return dbg;
+}
+
+QSGCompressedTexture::QSGCompressedTexture(const DataPtr& texData)
+ : m_textureData(texData)
+{
+ if (m_textureData) {
+ m_size = m_textureData->size;
+ m_hasAlpha = m_textureData->hasAlpha;
+ }
+}
+
+QSGCompressedTexture::~QSGCompressedTexture()
+{
+#if QT_CONFIG(opengl)
+ if (m_textureId) {
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ QOpenGLFunctions *funcs = ctx ? ctx->functions() : nullptr;
+ if (!funcs)
+ return;
+
+ funcs->glDeleteTextures(1, &m_textureId);
+ }
+#endif
+}
+
+int QSGCompressedTexture::textureId() const
+{
+#if QT_CONFIG(opengl)
+ if (!m_textureId) {
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ QOpenGLFunctions *funcs = ctx ? ctx->functions() : nullptr;
+ if (!funcs)
+ return 0;
+
+ funcs->glGenTextures(1, &m_textureId);
+ }
+#endif
+ return m_textureId;
+}
+
+QSize QSGCompressedTexture::textureSize() const
+{
+ return m_size;
+}
+
+bool QSGCompressedTexture::hasAlphaChannel() const
+{
+ return m_hasAlpha;
+}
+
+bool QSGCompressedTexture::hasMipmaps() const
+{
+ return false;
+}
+
+void QSGCompressedTexture::bind()
+{
+#if QT_CONFIG(opengl)
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ QOpenGLFunctions *funcs = ctx ? ctx->functions() : nullptr;
+ if (!funcs)
+ return;
+
+ if (!textureId())
+ return;
+
+ funcs->glBindTexture(GL_TEXTURE_2D, m_textureId);
+
+ if (m_uploaded)
+ return;
+
+ QByteArray logName(m_textureData ? m_textureData->logName : QByteArrayLiteral("(unset)"));
+
+ if (!m_textureData || !m_textureData->isValid()) {
+ qCDebug(QSG_LOG_TEXTUREIO, "Invalid texture data for %s", logName.constData());
+ funcs->glBindTexture(GL_TEXTURE_2D, 0);
+ return;
+ }
+
+ if (Q_UNLIKELY(QSG_LOG_TEXTUREIO().isDebugEnabled())) {
+ qCDebug(QSG_LOG_TEXTUREIO) << "Uploading texture" << m_textureData.data();
+ while (funcs->glGetError() != GL_NO_ERROR);
+ }
+
+ funcs->glCompressedTexImage2D(GL_TEXTURE_2D, 0, m_textureData->format,
+ m_size.width(), m_size.height(), 0, m_textureData->sizeInBytes(),
+ m_textureData->data.constData() + m_textureData->dataOffset);
+
+ if (Q_UNLIKELY(QSG_LOG_TEXTUREIO().isDebugEnabled())) {
+ GLuint error = funcs->glGetError();
+ if (error != GL_NO_ERROR) {
+ qCDebug(QSG_LOG_TEXTUREIO, "glCompressedTexImage2D failed for %s, error 0x%x", logName.constData(), error);
+ }
+ }
+
+ m_textureData.clear(); // Release this memory, not needed anymore
+
+ updateBindOptions(true);
+ m_uploaded = true;
+#endif // QT_CONFIG(opengl)
+}
+
+bool QSGCompressedTexture::formatIsOpaque(quint32 glTextureFormat)
+{
+ switch (glTextureFormat) {
+ case QOpenGLTexture::RGB_DXT1:
+ case QOpenGLTexture::R_ATI1N_UNorm:
+ case QOpenGLTexture::R_ATI1N_SNorm:
+ case QOpenGLTexture::RG_ATI2N_UNorm:
+ case QOpenGLTexture::RG_ATI2N_SNorm:
+ case QOpenGLTexture::RGB_BP_UNSIGNED_FLOAT:
+ case QOpenGLTexture::RGB_BP_SIGNED_FLOAT:
+ case QOpenGLTexture::R11_EAC_UNorm:
+ case QOpenGLTexture::R11_EAC_SNorm:
+ case QOpenGLTexture::RG11_EAC_UNorm:
+ case QOpenGLTexture::RG11_EAC_SNorm:
+ case QOpenGLTexture::RGB8_ETC2:
+ case QOpenGLTexture::SRGB8_ETC2:
+ case QOpenGLTexture::RGB8_ETC1:
+ case QOpenGLTexture::SRGB_DXT1:
+ return true;
+ break;
+ default:
+ return false;
+ }
+}
+
+QSGCompressedTextureFactory::QSGCompressedTextureFactory(const QSGCompressedTexture::DataPtr &texData)
+ : m_textureData(texData)
+{
+}
+
+QSGTexture *QSGCompressedTextureFactory::createTexture(QQuickWindow *window) const
+{
+ if (!m_textureData || !m_textureData->isValid())
+ return nullptr;
+
+ // attempt to atlas the texture
+ QSGRenderContext *context = QQuickWindowPrivate::get(window)->context;
+ QSGTexture *t = context->compressedTextureForFactory(this);
+ if (t)
+ return t;
+
+ return new QSGCompressedTexture(m_textureData);
+}
+
+int QSGCompressedTextureFactory::textureByteCount() const
+{
+ return m_textureData ? m_textureData->sizeInBytes() : 0;
+}
+
+
+QSize QSGCompressedTextureFactory::textureSize() const
+{
+ if (m_textureData && m_textureData->isValid())
+ return m_textureData->size;
+ return QSize();
+}
+
+QT_END_NAMESPACE
diff --git a/src/qml/jit/qv4registerinfo_p.h b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture_p.h
index 214206db91..aa87316809 100644
--- a/src/qml/jit/qv4registerinfo_p.h
+++ b/src/quick/scenegraph/compressedtexture/qsgcompressedtexture_p.h
@@ -1,9 +1,9 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the QtQml module of the Qt Toolkit.
+** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef QV4REGISTERINFO_P_H
-#define QV4REGISTERINFO_P_H
+#ifndef QSGCOMPRESSEDTEXTURE_P_H
+#define QSGCOMPRESSEDTEXTURE_P_H
//
// W A R N I N G
@@ -51,62 +51,76 @@
// We mean it.
//
-#include <QtCore/QString>
+#include <QSGTexture>
+#include <QtQuick/private/qsgcontext_p.h>
+#include <QQuickTextureFactory>
+#include <QOpenGLFunctions>
QT_BEGIN_NAMESPACE
-namespace QV4 {
-namespace JIT {
+struct Q_QUICK_PRIVATE_EXPORT QSGCompressedTextureData
+{
+ QByteArray logName;
+ QByteArray data;
+ QSize size;
+ uint format = 0;
+ int dataOffset = 0;
+ int dataLength = 0;
+ bool hasAlpha = false;
+
+ bool isValid() const;
+ int sizeInBytes() const;
+};
+
+Q_QUICK_PRIVATE_EXPORT QDebug operator<<(QDebug, const QSGCompressedTextureData *);
-class RegisterInfo
+
+class Q_QUICK_PRIVATE_EXPORT QSGCompressedTexture : public QSGTexture
{
+ Q_OBJECT
public:
- enum { InvalidRegister = (1 << 29) - 1 };
- enum SavedBy { CallerSaved, CalleeSaved };
- enum RegisterType { RegularRegister, FloatingPointRegister };
- enum Usage { Predefined, RegAlloc };
+ typedef QSharedPointer<QSGCompressedTextureData> DataPtr;
+
+ QSGCompressedTexture(const DataPtr& texData);
+ virtual ~QSGCompressedTexture();
+
+ int textureId() const override;
+ QSize textureSize() const override;
+ bool hasAlphaChannel() const override;
+ bool hasMipmaps() const override;
+
+ void bind() override;
+ const QSGCompressedTextureData *textureData();
+
+ static bool formatIsOpaque(quint32 glTextureFormat);
+
+protected:
+ DataPtr m_textureData;
+ QSize m_size;
+ mutable uint m_textureId = 0;
+ bool m_hasAlpha = false;
+ bool m_uploaded = false;
+};
+
+namespace QSGAtlasTexture {
+ class Manager;
+}
+
+class Q_QUICK_PRIVATE_EXPORT QSGCompressedTextureFactory : public QQuickTextureFactory
+{
public:
- RegisterInfo()
- : _savedBy(CallerSaved)
- , _usage(Predefined)
- , _type(RegularRegister)
- , _reg(InvalidRegister)
- {}
-
- RegisterInfo(int reg, const QString &prettyName, RegisterType type, SavedBy savedBy, Usage usage)
- : _prettyName(prettyName)
- , _savedBy(savedBy)
- , _usage(usage)
- , _type(type)
- , _reg(reg)
- {}
-
- bool operator==(const RegisterInfo &other) const
- { return _type == other._type && _reg == other._reg; }
-
- bool isValid() const { return _reg != InvalidRegister; }
- template <typename T> T reg() const { return static_cast<T>(_reg); }
- QString prettyName() const { return _prettyName; }
- bool isCallerSaved() const { return _savedBy == CallerSaved; }
- bool isCalleeSaved() const { return _savedBy == CalleeSaved; }
- bool isFloatingPoint() const { return _type == FloatingPointRegister; }
- bool isRegularRegister() const { return _type == RegularRegister; }
- bool useForRegAlloc() const { return _usage == RegAlloc; }
- bool isPredefined() const { return _usage == Predefined; }
+ QSGCompressedTextureFactory(const QSGCompressedTexture::DataPtr& texData);
+ QSGTexture *createTexture(QQuickWindow *) const override;
+ int textureByteCount() const override;
+ QSize textureSize() const override;
+protected:
+ QSGCompressedTexture::DataPtr m_textureData;
private:
- QString _prettyName;
- unsigned _savedBy : 1;
- unsigned _usage : 1;
- unsigned _type : 1;
- unsigned _reg : 29;
+ friend class QSGAtlasTexture::Manager;
};
-typedef QVector<RegisterInfo> RegisterInformation;
-
-} // JIT namespace
-} // QV4 namespace
QT_END_NAMESPACE
-#endif // QV4REGISTERINFO_P_H
+#endif // QSGCOMPRESSEDTEXTURE_P_H
diff --git a/src/quick/scenegraph/compressedtexture/qsgktxhandler.cpp b/src/quick/scenegraph/compressedtexture/qsgktxhandler.cpp
new file mode 100644
index 0000000000..e3e4ca6824
--- /dev/null
+++ b/src/quick/scenegraph/compressedtexture/qsgktxhandler.cpp
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsgktxhandler_p.h"
+#include "qsgcompressedtexture_p.h"
+#include <QOpenGLTexture>
+#include <QtEndian>
+
+//#define KTX_DEBUG
+
+QT_BEGIN_NAMESPACE
+
+#define KTX_IDENTIFIER_LENGTH 12
+static const char ktxIdentifier[KTX_IDENTIFIER_LENGTH] = { '\xAB', 'K', 'T', 'X', ' ', '1', '1', '\xBB', '\r', '\n', '\x1A', '\n' };
+static const quint32 platformEndianIdentifier = 0x04030201;
+static const quint32 inversePlatformEndianIdentifier = 0x01020304;
+
+struct KTXHeader {
+ quint8 identifier[KTX_IDENTIFIER_LENGTH]; //Must match ktxIdentifier
+ quint32 endianness; //Either platformEndianIdentifier or inversePlatformEndianIdentifier, other values not allowed.
+ quint32 glType;
+ quint32 glTypeSize;
+ quint32 glFormat;
+ quint32 glInternalFormat;
+ quint32 glBaseInternalFormat;
+ quint32 pixelWidth;
+ quint32 pixelHeight;
+ quint32 pixelDepth;
+ quint32 numberOfArrayElements;
+ quint32 numberOfFaces;
+ quint32 numberOfMipmapLevels;
+ quint32 bytesOfKeyValueData;
+};
+
+static const int headerSize = sizeof(KTXHeader);
+
+// Currently unused, declared for future reference
+struct KTXKeyValuePairItem {
+ quint32 keyAndValueByteSize;
+ /*
+ quint8 keyAndValue[keyAndValueByteSize];
+ quint8 valuePadding[3 - ((keyAndValueByteSize + 3) % 4)];
+ */
+};
+
+struct KTXMipmapLevel {
+ quint32 imageSize;
+ /*
+ for each array_element in numberOfArrayElements*
+ for each face in numberOfFaces
+ for each z_slice in pixelDepth*
+ for each row or row_of_blocks in pixelHeight*
+ for each pixel or block_of_pixels in pixelWidth
+ Byte data[format-specific-number-of-bytes]**
+ end
+ end
+ end
+ Byte cubePadding[0-3]
+ end
+ end
+ quint8 mipPadding[3 - ((imageSize + 3) % 4)]
+ */
+};
+
+bool QSGKtxHandler::canRead(const QByteArray &suffix, const QByteArray &block)
+{
+ Q_UNUSED(suffix)
+
+ return (qstrncmp(block.constData(), ktxIdentifier, KTX_IDENTIFIER_LENGTH) == 0);
+}
+
+QQuickTextureFactory *QSGKtxHandler::read()
+{
+ if (!device())
+ return nullptr;
+
+ QByteArray buf = device()->readAll();
+ if (buf.size() < headerSize || !canRead(QByteArray(), buf)) {
+ qCDebug(QSG_LOG_TEXTUREIO, "Invalid KTX file %s", logName().constData());
+ return nullptr;
+ }
+
+ const KTXHeader *header = reinterpret_cast<const KTXHeader *>(buf.constData());
+ if (!checkHeader(*header)) {
+ qCDebug(QSG_LOG_TEXTUREIO, "Unsupported KTX file format in %s", logName().constData());
+ return nullptr;
+ }
+
+ QSGCompressedTexture::DataPtr texData(QSGCompressedTexture::DataPtr::create());
+
+ texData->size = QSize(decode(header->pixelWidth), decode(header->pixelHeight));
+ texData->format = decode(header->glInternalFormat);
+ texData->hasAlpha = !QSGCompressedTexture::formatIsOpaque(texData->format);
+
+ // For now, ignore any additional mipmap levels
+ int preambleSize = headerSize + decode(header->bytesOfKeyValueData);
+ if (buf.size() >= preambleSize + int(sizeof(KTXMipmapLevel))) {
+ texData->data = buf;
+ texData->dataOffset = preambleSize + sizeof(quint32); // for the imageSize
+ const KTXMipmapLevel *level = reinterpret_cast<const KTXMipmapLevel *>(buf.constData() + preambleSize);
+ texData->dataLength = decode(level->imageSize);
+ }
+
+ if (!texData->isValid()) {
+ qCDebug(QSG_LOG_TEXTUREIO, "Invalid values in header of KTX file %s", logName().constData());
+ return nullptr;
+ }
+
+ texData->logName = logName();
+#ifdef KTX_DEBUG
+ qDebug() << "KTX file handler read" << texData.data();
+#endif
+
+ return new QSGCompressedTextureFactory(texData);
+}
+
+bool QSGKtxHandler::checkHeader(const KTXHeader &header)
+{
+ if (header.endianness != platformEndianIdentifier && header.endianness != inversePlatformEndianIdentifier)
+ return false;
+ inverseEndian = (header.endianness == inversePlatformEndianIdentifier);
+#ifdef KTX_DEBUG
+ QMetaEnum tfme = QMetaEnum::fromType<QOpenGLTexture::TextureFormat>();
+ QMetaEnum ptme = QMetaEnum::fromType<QOpenGLTexture::PixelType>();
+ qDebug("Header of %s:", logName().constData());
+ qDebug(" glType: 0x%x (%s)", decode(header.glType), ptme.valueToKey(decode(header.glType)));
+ qDebug(" glTypeSize: %u", decode(header.glTypeSize));
+ qDebug(" glFormat: 0x%x (%s)", decode(header.glFormat), tfme.valueToKey(decode(header.glFormat)));
+ qDebug(" glInternalFormat: 0x%x (%s)", decode(header.glInternalFormat), tfme.valueToKey(decode(header.glInternalFormat)));
+ qDebug(" glBaseInternalFormat: 0x%x (%s)", decode(header.glBaseInternalFormat), tfme.valueToKey(decode(header.glBaseInternalFormat)));
+ qDebug(" pixelWidth: %u", decode(header.pixelWidth));
+ qDebug(" pixelHeight: %u", decode(header.pixelHeight));
+ qDebug(" pixelDepth: %u", decode(header.pixelDepth));
+ qDebug(" numberOfArrayElements: %u", decode(header.numberOfArrayElements));
+ qDebug(" numberOfFaces: %u", decode(header.numberOfFaces));
+ qDebug(" numberOfMipmapLevels: %u", decode(header.numberOfMipmapLevels));
+ qDebug(" bytesOfKeyValueData: %u", decode(header.bytesOfKeyValueData));
+#endif
+ return ((decode(header.glType) == 0) &&
+ (decode(header.glFormat) == 0) &&
+ (decode(header.pixelDepth) == 0) &&
+ (decode(header.numberOfFaces) == 1));
+}
+
+quint32 QSGKtxHandler::decode(quint32 val)
+{
+ return inverseEndian ? qbswap<quint32>(val) : val;
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/compressedtexture/qsgktxhandler_p.h b/src/quick/scenegraph/compressedtexture/qsgktxhandler_p.h
new file mode 100644
index 0000000000..22f4db65b2
--- /dev/null
+++ b/src/quick/scenegraph/compressedtexture/qsgktxhandler_p.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSGKTXHANDLER_H
+#define QSGKTXHANDLER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qsgtexturefilehandler_p.h"
+
+QT_BEGIN_NAMESPACE
+
+struct KTXHeader;
+
+class QSGKtxHandler : public QSGTextureFileHandler
+{
+public:
+ using QSGTextureFileHandler::QSGTextureFileHandler;
+
+ static bool canRead(const QByteArray &suffix, const QByteArray &block);
+
+ QQuickTextureFactory *read() override;
+
+private:
+ bool checkHeader(const KTXHeader &header);
+ quint32 decode(quint32 val);
+
+ bool inverseEndian = false;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGKTXHANDLER_H
diff --git a/src/quick/scenegraph/compressedtexture/qsgpkmhandler.cpp b/src/quick/scenegraph/compressedtexture/qsgpkmhandler.cpp
new file mode 100644
index 0000000000..daec23d478
--- /dev/null
+++ b/src/quick/scenegraph/compressedtexture/qsgpkmhandler.cpp
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsgpkmhandler_p.h"
+#include "qsgcompressedtexture_p.h"
+
+#include <QFile>
+#include <QDebug>
+#include <qendian.h>
+#include <qopenglfunctions.h>
+#include <qqmlfile.h>
+#include <QOpenGLTexture>
+
+//#define ETC_DEBUG
+
+QT_BEGIN_NAMESPACE
+
+static const int headerSize = 16;
+
+static unsigned int typeMap[5] = {
+ QOpenGLTexture::RGB8_ETC1, // GL_ETC1_RGB8_OES,
+ QOpenGLTexture::RGB8_ETC2, // GL_COMPRESSED_RGB8_ETC2,
+ 0, // unused (obsolete)
+ QOpenGLTexture::RGBA8_ETC2_EAC, // GL_COMPRESSED_RGBA8_ETC2_EAC,
+ QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2 // GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
+};
+
+bool QSGPkmHandler::canRead(const QByteArray &suffix, const QByteArray &block)
+{
+ Q_UNUSED(suffix)
+
+ return block.startsWith("PKM ");
+}
+
+QQuickTextureFactory *QSGPkmHandler::read()
+{
+ if (!device())
+ return nullptr;
+
+ QSGCompressedTexture::DataPtr texData(QSGCompressedTexture::DataPtr::create());
+
+ texData->data = device()->readAll();
+ if (texData->data.size() < headerSize || !canRead(QByteArray(), texData->data)) {
+ qCDebug(QSG_LOG_TEXTUREIO, "Invalid PKM file %s", logName().constData());
+ return nullptr;
+ }
+
+ const char *rawData = texData->data.constData();
+
+ // ignore version (rawData + 4 & 5)
+
+ // texture type
+ quint16 type = qFromBigEndian<quint16>(rawData + 6);
+ if (type > sizeof(typeMap)/sizeof(typeMap[0])) {
+ qCDebug(QSG_LOG_TEXTUREIO, "Unknown compression format in PKM file %s", logName().constData());
+ return nullptr;
+ }
+ texData->format = typeMap[type];
+ texData->hasAlpha = !QSGCompressedTexture::formatIsOpaque(texData->format);
+
+ // texture size
+ /* Actual data length depends on format; for now just use 0, i.e. rest-of-file
+ QSize paddedSize(qFromBigEndian<quint16>(rawData + 8), qFromBigEndian<quint16>(rawData + 10));
+ texData->dataLength = (paddedSize.width() / 4) * (paddedSize.height() / 4) * 8;
+ */
+ QSize texSize(qFromBigEndian<quint16>(rawData + 12), qFromBigEndian<quint16>(rawData + 14));
+ texData->size = texSize;
+
+ texData->dataOffset = headerSize;
+
+ if (!texData->isValid()) {
+ qCDebug(QSG_LOG_TEXTUREIO, "Invalid values in header of PKM file %s", logName().constData());
+ return nullptr;
+ }
+
+ texData->logName = logName();
+#ifdef ETC_DEBUG
+ qDebug() << "PKM file handler read" << texData.data();
+#endif
+ return new QSGCompressedTextureFactory(texData);
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/compressedtexture/qsgpkmhandler_p.h b/src/quick/scenegraph/compressedtexture/qsgpkmhandler_p.h
new file mode 100644
index 0000000000..6154c51b84
--- /dev/null
+++ b/src/quick/scenegraph/compressedtexture/qsgpkmhandler_p.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSGPKMHANDLER_H
+#define QSGPKMHANDLER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qsgtexturefilehandler_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QSGPkmHandler : public QSGTextureFileHandler
+{
+public:
+ using QSGTextureFileHandler::QSGTextureFileHandler;
+
+ static bool canRead(const QByteArray &suffix, const QByteArray &block);
+
+ QQuickTextureFactory *read() override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGPKMHANDLER_H
diff --git a/src/quick/scenegraph/compressedtexture/qsgtexturefilehandler_p.h b/src/quick/scenegraph/compressedtexture/qsgtexturefilehandler_p.h
new file mode 100644
index 0000000000..43358b2846
--- /dev/null
+++ b/src/quick/scenegraph/compressedtexture/qsgtexturefilehandler_p.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSGTEXTUREFILEHANDLER_P_H
+#define QSGTEXTUREFILEHANDLER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QLoggingCategory>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(QSG_LOG_TEXTUREIO)
+
+class QQuickTextureFactory;
+
+class QSGTextureFileHandler
+{
+public:
+ QSGTextureFileHandler(QIODevice *device, const QByteArray &logName = QByteArray())
+ : m_device(device)
+ {
+ m_logName = !logName.isEmpty() ? logName : QByteArrayLiteral("(unknown)");
+ }
+
+ virtual QQuickTextureFactory *read() = 0;
+ QIODevice *device() const { return m_device; }
+ QByteArray logName() const { return m_logName; }
+
+private:
+ QIODevice *m_device = nullptr;
+ QByteArray m_logName;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGTEXTUREFILEHANDLER_P_H
diff --git a/src/quick/scenegraph/coreapi/qsgabstractrenderer.h b/src/quick/scenegraph/coreapi/qsgabstractrenderer.h
index eb9e7cea7c..304dc008d5 100644
--- a/src/quick/scenegraph/coreapi/qsgabstractrenderer.h
+++ b/src/quick/scenegraph/coreapi/qsgabstractrenderer.h
@@ -90,7 +90,7 @@ Q_SIGNALS:
void sceneGraphChanged();
protected:
- explicit QSGAbstractRenderer(QObject *parent = Q_NULLPTR);
+ explicit QSGAbstractRenderer(QObject *parent = nullptr);
virtual void nodeChanged(QSGNode *node, QSGNode::DirtyState state) = 0;
private:
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
index a8b60c9e55..27b374e47f 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
@@ -55,6 +55,7 @@
#include <QtGui/QOpenGLFunctions_1_0>
#include <QtGui/QOpenGLFunctions_3_2_Core>
+#include <private/qnumeric_p.h>
#include <private/qquickprofiler_p.h>
#include "qsgmaterialshader_p.h"
@@ -225,7 +226,7 @@ void qsg_dumpShadowRoots(BatchRootInfo *i, int indent)
QByteArray ind(indent + extraIndent + 10, ' ');
if (!i) {
- qDebug() << ind.constData() << "- no info";
+ qDebug("%s - no info", ind.constData());
} else {
qDebug() << ind.constData() << "- parent:" << i->parentRoot << "orders" << i->firstOrder << "->" << i->lastOrder << ", avail:" << i->availableOrders;
for (QSet<Node *>::const_iterator it = i->subRoots.constBegin();
@@ -292,15 +293,15 @@ void Updater::updateStates(QSGNode *n)
qsg_dumpShadowRoots(sn);
if (Q_UNLIKELY(debug_build())) {
- qDebug() << "Updater::updateStates()";
+ qDebug("Updater::updateStates()");
if (sn->dirtyState & (QSGNode::DirtyNodeAdded << 16))
- qDebug() << " - nodes have been added";
+ qDebug(" - nodes have been added");
if (sn->dirtyState & (QSGNode::DirtyMatrix << 16))
- qDebug() << " - transforms have changed";
+ qDebug(" - transforms have changed");
if (sn->dirtyState & (QSGNode::DirtyOpacity << 16))
- qDebug() << " - opacity has changed";
+ qDebug(" - opacity has changed");
if (uint(sn->dirtyState) & uint(QSGNode::DirtyForceUpdate << 16))
- qDebug() << " - forceupdate";
+ qDebug(" - forceupdate");
}
if (Q_UNLIKELY(renderer->m_visualizeMode == Renderer::VisualizeChanges))
@@ -804,8 +805,11 @@ Renderer::Renderer(QSGDefaultRenderContext *ctx)
m_batchVertexThreshold = qt_sg_envInt("QSG_RENDERER_BATCH_VERTEX_THRESHOLD", 1024);
if (Q_UNLIKELY(debug_build() || debug_render())) {
- qDebug() << "Batch thresholds: nodes:" << m_batchNodeThreshold << " vertices:" << m_batchVertexThreshold;
- qDebug() << "Using buffer strategy:" << (m_bufferStrategy == GL_STATIC_DRAW ? "static" : (m_bufferStrategy == GL_DYNAMIC_DRAW ? "dynamic" : "stream"));
+ qDebug("Batch thresholds: nodes: %d vertices: %d",
+ m_batchNodeThreshold, m_batchVertexThreshold);
+ qDebug("Using buffer strategy: %s",
+ (m_bufferStrategy == GL_STATIC_DRAW
+ ? "static" : (m_bufferStrategy == GL_DYNAMIC_DRAW ? "dynamic" : "stream")));
}
// If rendering with an OpenGL Core profile context, we need to create a VAO
@@ -1111,7 +1115,7 @@ void Renderer::nodeWasRemoved(Node *node)
void Renderer::turnNodeIntoBatchRoot(Node *node)
{
- if (Q_UNLIKELY(debug_change())) qDebug() << " - new batch root";
+ if (Q_UNLIKELY(debug_change())) qDebug(" - new batch root");
m_rebuild |= FullRebuild;
node->isBatchRoot = true;
node->becameBatchRoot = true;
@@ -2318,7 +2322,7 @@ void Renderer::renderMergedBatch(const Batch *batch)
setActiveShader(program, sms);
m_current_opacity = gn->inheritedOpacity();
- if (sms->lastOpacity != m_current_opacity) {
+ if (!qFuzzyCompare(sms->lastOpacity, float(m_current_opacity))) {
dirty |= QSGMaterialShader::RenderState::DirtyOpacity;
sms->lastOpacity = m_current_opacity;
}
@@ -2327,7 +2331,7 @@ void Renderer::renderMergedBatch(const Batch *batch)
#ifndef QT_NO_DEBUG
if (qsg_test_and_clear_material_failure()) {
- qDebug() << "QSGMaterial::updateState triggered an error (merged), batch will be skipped:";
+ qDebug("QSGMaterial::updateState triggered an error (merged), batch will be skipped:");
Element *ee = e;
while (ee) {
qDebug() << " -" << ee->node;
@@ -2448,7 +2452,7 @@ void Renderer::renderUnmergedBatch(const Batch *batch)
#ifndef QT_NO_DEBUG
if (qsg_test_and_clear_material_failure()) {
- qDebug() << "QSGMaterial::updateState() triggered an error (unmerged), batch will be skipped:";
+ qDebug("QSGMaterial::updateState() triggered an error (unmerged), batch will be skipped:");
qDebug() << " - offending node is" << e->node;
QSGNodeDumper::dump(rootNode());
qFatal("Aborting: scene graph is invalid...");
@@ -2659,12 +2663,12 @@ void Renderer::render()
m_rebuild |= BuildBatches;
if (Q_UNLIKELY(debug_build())) {
- qDebug() << "Opaque render lists" << (complete ? "(complete)" : "(partial)") << ":";
+ qDebug("Opaque render lists %s:", (complete ? "(complete)" : "(partial)"));
for (int i=0; i<m_opaqueRenderList.size(); ++i) {
Element *e = m_opaqueRenderList.at(i);
qDebug() << " - element:" << e << " batch:" << e->batch << " node:" << e->node << " order:" << e->order;
}
- qDebug() << "Alpha render list:" << (complete ? "(complete)" : "(partial)") << ":";
+ qDebug("Alpha render list %s:", complete ? "(complete)" : "(partial)");
for (int i=0; i<m_alphaRenderList.size(); ++i) {
Element *e = m_alphaRenderList.at(i);
qDebug() << " - element:" << e << " batch:" << e->batch << " node:" << e->node << " order:" << e->order;
@@ -2689,7 +2693,7 @@ void Renderer::render()
if (Q_UNLIKELY(debug_render())) timePrepareAlpha = timer.restart();
if (Q_UNLIKELY(debug_build())) {
- qDebug() << "Opaque Batches:";
+ qDebug("Opaque Batches:");
for (int i=0; i<m_opaqueBatches.size(); ++i) {
Batch *b = m_opaqueBatches.at(i);
qDebug() << " - Batch " << i << b << (b->needsUpload ? "upload" : "") << " root:" << b->root;
@@ -2697,7 +2701,7 @@ void Renderer::render()
qDebug() << " - element:" << e << " node:" << e->node << e->order;
}
}
- qDebug() << "Alpha Batches:";
+ qDebug("Alpha Batches:");
for (int i=0; i<m_alphaBatches.size(); ++i) {
Batch *b = m_alphaBatches.at(i);
qDebug() << " - Batch " << i << b << (b->needsUpload ? "upload" : "") << " root:" << b->root;
@@ -2735,7 +2739,7 @@ void Renderer::render()
int largestIBO = 0;
#endif
- if (Q_UNLIKELY(debug_upload())) qDebug() << "Uploading Opaque Batches:";
+ if (Q_UNLIKELY(debug_upload())) qDebug("Uploading Opaque Batches:");
for (int i=0; i<m_opaqueBatches.size(); ++i) {
Batch *b = m_opaqueBatches.at(i);
largestVBO = qMax(b->vbo.size, largestVBO);
@@ -2747,7 +2751,7 @@ void Renderer::render()
if (Q_UNLIKELY(debug_render())) timeUploadOpaque = timer.restart();
- if (Q_UNLIKELY(debug_upload())) qDebug() << "Uploading Alpha Batches:";
+ if (Q_UNLIKELY(debug_upload())) qDebug("Uploading Alpha Batches:");
for (int i=0; i<m_alphaBatches.size(); ++i) {
Batch *b = m_alphaBatches.at(i);
uploadBatch(b);
diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
index 59fea87add..e99af2f4ef 100644
--- a/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
@@ -629,9 +629,9 @@ public:
};
protected:
- void nodeChanged(QSGNode *node, QSGNode::DirtyState state) Q_DECL_OVERRIDE;
- void render() Q_DECL_OVERRIDE;
- void releaseCachedResources() Q_DECL_OVERRIDE;
+ void nodeChanged(QSGNode *node, QSGNode::DirtyState state) override;
+ void render() override;
+ void releaseCachedResources() override;
private:
enum ClipTypeBit
@@ -700,7 +700,7 @@ private:
void visualizeOverdraw();
void visualizeOverdraw_helper(Node *node);
void visualizeDrawGeometry(const QSGGeometry *g);
- void setCustomRenderMode(const QByteArray &mode) Q_DECL_OVERRIDE;
+ void setCustomRenderMode(const QByteArray &mode) override;
QSGDefaultRenderContext *m_context;
QSet<Node *> m_taggedRoots;
diff --git a/src/quick/scenegraph/coreapi/qsggeometry.cpp b/src/quick/scenegraph/coreapi/qsggeometry.cpp
index 69a8c21ed2..52366bfc35 100644
--- a/src/quick/scenegraph/coreapi/qsggeometry.cpp
+++ b/src/quick/scenegraph/coreapi/qsggeometry.cpp
@@ -768,6 +768,19 @@ void QSGGeometry::updateColoredRectGeometry(QSGGeometry *g, const QRectF &rect)
v[3].y = rect.bottom();
}
+/*!
+ \enum QSGGeometry::AttributeType
+
+ This enum identifies several attribute types.
+
+ \value UnknownAttribute Don't care
+ \value PositionAttribute Position
+ \value ColorAttribute Color
+ \value TexCoordAttribute Texture coordinate
+ \value TexCoord1Attribute Texture coordinate 1
+ \value TexCoord2Attribute Texture coordinate 2
+
+ */
/*!
\enum QSGGeometry::DataPattern
diff --git a/src/quick/scenegraph/coreapi/qsgmaterial.cpp b/src/quick/scenegraph/coreapi/qsgmaterial.cpp
index 07dc87a643..5c28f4c82f 100644
--- a/src/quick/scenegraph/coreapi/qsgmaterial.cpp
+++ b/src/quick/scenegraph/coreapi/qsgmaterial.cpp
@@ -443,7 +443,12 @@ void QSGMaterialShader::compile()
otherwise returns \c false.
*/
+/*!
+ \fn bool QSGMaterialShader::RenderState::isCachedMaterialDataDirty() const
+ Returns \c true if the dirtyStates() contains the dirty cached material state,
+ otherwise returns \c false.
+ */
/*!
\fn QSGMaterialShader::RenderState::DirtyStates QSGMaterialShader::RenderState::dirtyStates() const
diff --git a/src/quick/scenegraph/coreapi/qsgnode.cpp b/src/quick/scenegraph/coreapi/qsgnode.cpp
index 22d57001fc..550a2182f8 100644
--- a/src/quick/scenegraph/coreapi/qsgnode.cpp
+++ b/src/quick/scenegraph/coreapi/qsgnode.cpp
@@ -114,6 +114,10 @@ static void qt_print_node_count()
\value DirtyOpacity The opacity of a QSGOpacityNode has changed.
\value DirtySubtreeBlocked The subtree has been blocked.
+ \omitvalue DirtyForceUpdate
+ \omitvalue DirtyUsePreprocess
+ \omitvalue DirtyPropagationMask
+
\sa QSGNode::markDirty()
*/
@@ -135,6 +139,8 @@ static void qt_print_node_count()
ownership over the opaque material and will delete it when the node is
destroyed or a material is assigned.
\value InternalReserved Reserved for internal use.
+
+ \omitvalue IsVisitableNode
*/
/*!
@@ -149,6 +155,8 @@ static void qt_print_node_count()
\value OpacityNodeType The type of QSGOpacityNode
\value RenderNodeType The type of QSGRenderNode
+ \omitvalue RootNodeType
+
\sa type()
*/
diff --git a/src/quick/scenegraph/coreapi/qsgnode.h b/src/quick/scenegraph/coreapi/qsgnode.h
index 1467f2233d..cd9d689dc1 100644
--- a/src/quick/scenegraph/coreapi/qsgnode.h
+++ b/src/quick/scenegraph/coreapi/qsgnode.h
@@ -77,9 +77,7 @@ public:
TransformNodeType,
ClipNodeType,
OpacityNodeType,
-#ifndef qdoc
RootNodeType,
-#endif
RenderNodeType
};
@@ -96,9 +94,8 @@ public:
OwnsOpaqueMaterial = 0x00040000,
// Uppermost 8 bits are reserved for internal use.
-#ifndef qdoc
IsVisitableNode = 0x01000000
-#else
+#ifdef Q_CLANG_QDOC
InternalReserved = 0x01000000
#endif
};
@@ -113,7 +110,6 @@ public:
DirtyMaterial = 0x2000,
DirtyOpacity = 0x4000,
-#ifndef qdoc
DirtyForceUpdate = 0x8000,
DirtyUsePreprocess = UsePreprocess,
@@ -122,7 +118,6 @@ public:
| DirtyNodeAdded
| DirtyOpacity
| DirtyForceUpdate
-#endif
};
Q_DECLARE_FLAGS(DirtyState, DirtyStateBit)
@@ -151,7 +146,7 @@ public:
QT_DEPRECATED void clearDirty() { }
void markDirty(DirtyState bits);
- QT_DEPRECATED DirtyState dirtyState() const { return Q_NULLPTR; }
+ QT_DEPRECATED DirtyState dirtyState() const { return nullptr; }
virtual bool isSubtreeBlocked() const;
diff --git a/src/quick/scenegraph/coreapi/qsgrenderer.cpp b/src/quick/scenegraph/coreapi/qsgrenderer.cpp
index 67bd265801..3ae79a933f 100644
--- a/src/quick/scenegraph/coreapi/qsgrenderer.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrenderer.cpp
@@ -136,6 +136,7 @@ QSGRenderer::QSGRenderer(QSGRenderContext *context)
, m_bindable(0)
, m_changed_emitted(false)
, m_is_rendering(false)
+ , m_is_preprocessing(false)
{
}
@@ -191,7 +192,7 @@ void QSGRenderer::renderScene(uint fboId)
class B : public QSGBindable
{
public:
- void bind() const { QOpenGLFramebufferObject::bindDefault(); }
+ void bind() const override { QOpenGLFramebufferObject::bindDefault(); }
} bindable;
renderScene(bindable);
}
@@ -289,6 +290,8 @@ void QSGRenderer::nodeChanged(QSGNode *node, QSGNode::DirtyState state)
void QSGRenderer::preprocess()
{
+ m_is_preprocessing = true;
+
QSGRootNode *root = rootNode();
Q_ASSERT(root);
@@ -300,6 +303,11 @@ void QSGRenderer::preprocess()
for (QSet<QSGNode *>::const_iterator it = items.constBegin();
it != items.constEnd(); ++it) {
QSGNode *n = *it;
+
+ // If we are currently preprocessing, check this node hasn't been
+ // deleted or something. we don't want a use-after-free!
+ if (m_nodes_dont_preprocess.contains(n)) // skip
+ continue;
if (!nodeUpdater()->isNodeBlocked(n, root)) {
n->preprocess();
}
@@ -317,8 +325,13 @@ void QSGRenderer::preprocess()
updatePassTime = frameTimer.nsecsElapsed();
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRendererFrame,
QQuickProfiler::SceneGraphRendererUpdate);
+
+ m_is_preprocessing = false;
+ m_nodes_dont_preprocess.clear();
}
+
+
void QSGRenderer::addNodesToPreprocess(QSGNode *node)
{
for (QSGNode *c = node->firstChild(); c; c = c->nextSibling())
@@ -331,8 +344,13 @@ void QSGRenderer::removeNodesToPreprocess(QSGNode *node)
{
for (QSGNode *c = node->firstChild(); c; c = c->nextSibling())
removeNodesToPreprocess(c);
- if (node->flags() & QSGNode::UsePreprocess)
+ if (node->flags() & QSGNode::UsePreprocess) {
m_nodes_to_preprocess.remove(node);
+
+ // If preprocessing *now*, mark the node as gone.
+ if (m_is_preprocessing)
+ m_nodes_dont_preprocess.insert(node);
+ }
}
diff --git a/src/quick/scenegraph/coreapi/qsgrenderer_p.h b/src/quick/scenegraph/coreapi/qsgrenderer_p.h
index d96d893ca5..b890728fd8 100644
--- a/src/quick/scenegraph/coreapi/qsgrenderer_p.h
+++ b/src/quick/scenegraph/coreapi/qsgrenderer_p.h
@@ -86,8 +86,8 @@ public:
bool isMirrored() const;
void renderScene(const QSGBindable &bindable);
- virtual void renderScene(uint fboId = 0) Q_DECL_OVERRIDE;
- virtual void nodeChanged(QSGNode *node, QSGNode::DirtyState state) Q_DECL_OVERRIDE;
+ void renderScene(uint fboId = 0) override;
+ void nodeChanged(QSGNode *node, QSGNode::DirtyState state) override;
QSGNodeUpdater *nodeUpdater() const;
void setNodeUpdater(QSGNodeUpdater *updater);
@@ -119,11 +119,13 @@ private:
QSGNodeUpdater *m_node_updater;
QSet<QSGNode *> m_nodes_to_preprocess;
+ QSet<QSGNode *> m_nodes_dont_preprocess;
const QSGBindable *m_bindable;
uint m_changed_emitted : 1;
uint m_is_rendering : 1;
+ uint m_is_preprocessing : 1;
};
class Q_QUICK_PRIVATE_EXPORT QSGBindable
diff --git a/src/quick/scenegraph/coreapi/qsgrendernode.cpp b/src/quick/scenegraph/coreapi/qsgrendernode.cpp
index 1bc0210b72..5e259f2083 100644
--- a/src/quick/scenegraph/coreapi/qsgrendernode.cpp
+++ b/src/quick/scenegraph/coreapi/qsgrendernode.cpp
@@ -213,6 +213,22 @@ void QSGRenderNode::releaseResources()
}
/*!
+ \enum QSGRenderNode::StateFlag
+
+ This enum is a bit mask identifying several states.
+
+ \value DepthState Depth
+ \value StencilState Stencil
+ \value ScissorState Scissor
+ \value ColorState Color
+ \value BlendState Blend
+ \value CullState Cull
+ \value ViewportState View poirt
+ \value RenderTargetState Render target
+
+ */
+
+/*!
\enum QSGRenderNode::RenderingFlag
Possible values for the bitmask returned from flags().
@@ -267,6 +283,10 @@ QSGRenderNode::RenderingFlags QSGRenderNode::flags() const
For rendernodes covering the entire area of a corresponding QQuickItem the
return value will be (0, 0, item->width(), item->height()).
+ \note Nodes are also free to render outside the boundaries specified by the
+ item's width and height, since the scenegraph nodes are not bounded by the
+ QQuickItem geometry, as long as this is reported correctly from this function.
+
\sa flags()
*/
QRectF QSGRenderNode::rect() const
@@ -350,7 +370,7 @@ QSGRenderNode::RenderState::~RenderState()
*/
/*!
- \fn const QRegion *QSGRenderNode::clipRegion() const
+ \fn const QRegion *QSGRenderNode::RenderState::clipRegion() const
\return the current clip region or null for backends where clipping is
implemented via stencil or scissoring.
@@ -359,7 +379,10 @@ QSGRenderNode::RenderState::~RenderState()
of the render state is not in use. However, the clip region that can be set
on the QPainter still has to be communicated since reconstructing this
manually in render() is not reasonable. It can therefore be queried via
- this function.
+ this function. The region is in world coordinates and can be passed
+ to QPainter::setClipRegion() with Qt::ReplaceClip. This must be done before
+ calling QPainter::setTransform() since the clip region is already mapped to
+ the transform provided in QSGRenderNode::matrix().
*/
/*!
diff --git a/src/quick/scenegraph/coreapi/qsgshaderrewriter.cpp b/src/quick/scenegraph/coreapi/qsgshaderrewriter.cpp
index 2b70139b37..1fdc1720f7 100644
--- a/src/quick/scenegraph/coreapi/qsgshaderrewriter.cpp
+++ b/src/quick/scenegraph/coreapi/qsgshaderrewriter.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include <QtCore/QByteArray>
+#include <QtCore/QString>
#include <QtGui/QSurfaceFormat>
// Duct Tape tokenizer for the purpose of parsing and rewriting
diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp
index 0f7e555aa7..c64360f955 100644
--- a/src/quick/scenegraph/qsgadaptationlayer.cpp
+++ b/src/quick/scenegraph/qsgadaptationlayer.cpp
@@ -40,7 +40,6 @@
#include "qsgadaptationlayer_p.h"
#include <qmath.h>
-#include <QtQuick/private/qsgdistancefieldutil_p.h>
#include <QtQuick/private/qsgdistancefieldglyphnode_p.h>
#include <QtQuick/private/qsgcontext_p.h>
#include <private/qrawfont_p.h>
@@ -57,9 +56,8 @@ static QElapsedTimer qsg_render_timer;
QSGDistanceFieldGlyphCache::Texture QSGDistanceFieldGlyphCache::s_emptyTexture;
-QSGDistanceFieldGlyphCache::QSGDistanceFieldGlyphCache(QSGDistanceFieldGlyphCacheManager *man, QOpenGLContext *c, const QRawFont &font)
- : m_manager(man)
- , m_pendingGlyphs(64)
+QSGDistanceFieldGlyphCache::QSGDistanceFieldGlyphCache(QOpenGLContext *c, const QRawFont &font)
+ : m_pendingGlyphs(64)
{
Q_ASSERT(font.isValid());
diff --git a/src/quick/scenegraph/qsgadaptationlayer_p.h b/src/quick/scenegraph/qsgadaptationlayer_p.h
index 03a1f7f281..ba146b884f 100644
--- a/src/quick/scenegraph/qsgadaptationlayer_p.h
+++ b/src/quick/scenegraph/qsgadaptationlayer_p.h
@@ -73,7 +73,6 @@ QT_BEGIN_NAMESPACE
class QSGNode;
class QImage;
class TextureReference;
-class QSGDistanceFieldGlyphCacheManager;
class QSGDistanceFieldGlyphNode;
class QOpenGLContext;
class QSGInternalImageNode;
@@ -209,6 +208,7 @@ public:
virtual void setDevicePixelRatio(qreal ratio) = 0;
virtual void setMirrorHorizontal(bool mirror) = 0;
virtual void setMirrorVertical(bool mirror) = 0;
+ virtual void setSamples(int samples) = 0;
Q_SLOT virtual void markDirtyTexture() = 0;
Q_SLOT virtual void invalidated() = 0;
@@ -408,7 +408,7 @@ public:
class Q_QUICK_PRIVATE_EXPORT QSGDistanceFieldGlyphCache
{
public:
- QSGDistanceFieldGlyphCache(QSGDistanceFieldGlyphCacheManager *man, QOpenGLContext *c, const QRawFont &font);
+ QSGDistanceFieldGlyphCache(QOpenGLContext *c, const QRawFont &font);
virtual ~QSGDistanceFieldGlyphCache();
struct Metrics {
@@ -442,8 +442,6 @@ public:
bool operator == (const Texture &other) const { return textureId == other.textureId; }
};
- const QSGDistanceFieldGlyphCacheManager *manager() const { return m_manager; }
-
const QRawFont &referenceFont() const { return m_referenceFont; }
qreal fontScale(qreal pixelSize) const
@@ -513,8 +511,6 @@ protected:
inline bool isCoreProfile() const { return m_coreProfile; }
private:
- QSGDistanceFieldGlyphCacheManager *m_manager;
-
QRawFont m_referenceFont;
int m_glyphCount;
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp
index c0a054a539..e5334d59e1 100644
--- a/src/quick/scenegraph/qsgcontext.cpp
+++ b/src/quick/scenegraph/qsgcontext.cpp
@@ -143,7 +143,7 @@ public:
qCDebug(QSG_LOG_INFO, "Animation Driver: using walltime");
}
- void start() Q_DECL_OVERRIDE
+ void start() override
{
m_time = 0;
m_timer.start();
@@ -151,14 +151,14 @@ public:
QAnimationDriver::start();
}
- qint64 elapsed() const Q_DECL_OVERRIDE
+ qint64 elapsed() const override
{
return m_mode == VSyncMode
? qint64(m_time)
: qint64(m_time) + m_wallTime.elapsed();
}
- void advance() Q_DECL_OVERRIDE
+ void advance() override
{
qint64 delta = m_timer.restart();
@@ -228,14 +228,6 @@ public:
int m_good;
};
-class QSGTextureCleanupEvent : public QEvent
-{
-public:
- QSGTextureCleanupEvent(QSGTexture *t) : QEvent(QEvent::User), texture(t) { }
- ~QSGTextureCleanupEvent() { delete texture; }
- QSGTexture *texture;
-};
-
/*!
\class QSGContext
@@ -333,7 +325,6 @@ QSGRendererInterface *QSGContext::rendererInterface(QSGRenderContext *renderCont
QSGRenderContext::QSGRenderContext(QSGContext *context)
: m_sg(context)
- , m_distanceFieldCacheManager(0)
{
}
@@ -413,6 +404,20 @@ void QSGRenderContext::textureFactoryDestroyed(QObject *o)
m_mutex.unlock();
}
+/*!
+ Return the texture corresponding to a texture factory.
+
+ This may optionally manipulate the texture in some way; for example by returning
+ an atlased texture.
+
+ This function is not a replacement for textureForFactory; both should be used
+ for a single texture (this might atlas, while the other might cache).
+*/
+QSGTexture *QSGRenderContext::compressedTextureForFactory(const QSGCompressedTextureFactory *) const
+{
+ return nullptr;
+}
+
#include "qsgcontext.moc"
#include "moc_qsgcontext_p.cpp"
diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h
index 1c4cd0ce90..da0adcd5d7 100644
--- a/src/quick/scenegraph/qsgcontext_p.h
+++ b/src/quick/scenegraph/qsgcontext_p.h
@@ -78,7 +78,7 @@ class QSGMaterial;
class QSGRenderLoop;
class QSGLayer;
class QQuickTextureFactory;
-class QSGDistanceFieldGlyphCacheManager;
+class QSGCompressedTextureFactory;
class QSGContext;
class QQuickPaintedItem;
class QSGRendererInterface;
@@ -174,6 +174,7 @@ public:
virtual QSGTexture *createTexture(const QImage &image, uint flags = CreateTexture_Alpha) const = 0;
virtual QSGRenderer *createRenderer() = 0;
+ virtual QSGTexture *compressedTextureForFactory(const QSGCompressedTextureFactory *) const;
virtual void setAttachToGraphicsContext(bool attach) { Q_UNUSED(attach); }
@@ -195,7 +196,7 @@ protected:
QMutex m_mutex;
QHash<QQuickTextureFactory *, QSGTexture *> m_textures;
QSet<QSGTexture *> m_texturesToDelete;
- QSGDistanceFieldGlyphCacheManager *m_distanceFieldCacheManager;
+ QHash<QString, QSGDistanceFieldGlyphCache *> m_glyphCaches;
QSet<QFontEngine *> m_fontEnginesToClean;
};
diff --git a/src/quick/scenegraph/qsgcontextplugin.cpp b/src/quick/scenegraph/qsgcontextplugin.cpp
index b8b5141957..634a492aa3 100644
--- a/src/quick/scenegraph/qsgcontextplugin.cpp
+++ b/src/quick/scenegraph/qsgcontextplugin.cpp
@@ -49,6 +49,9 @@
#include <QtQuick/private/qsgdefaultcontext_p.h>
#endif
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/qpa/qplatformintegration.h>
+
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(QSG_LOG_INFO)
@@ -119,24 +122,24 @@ QSGAdaptationBackendData *contextFactory()
}
}
- if (requestedBackend.isEmpty() && qEnvironmentVariableIsSet("QMLSCENE_DEVICE"))
- requestedBackend = QString::fromLocal8Bit(qgetenv("QMLSCENE_DEVICE"));
+ if (requestedBackend.isEmpty())
+ requestedBackend = qEnvironmentVariable("QMLSCENE_DEVICE");
// A modern alternative. Scenegraph adaptations can represent backends
// for different graphics APIs as well, instead of being specific to
// some device or platform.
- if (requestedBackend.isEmpty() && qEnvironmentVariableIsSet("QT_QUICK_BACKEND"))
- requestedBackend = QString::fromLocal8Bit(qgetenv("QT_QUICK_BACKEND"));
+ if (requestedBackend.isEmpty())
+ requestedBackend = qEnvironmentVariable("QT_QUICK_BACKEND");
-#if !QT_CONFIG(opengl)
- // If this is a build without OpenGL, and no backend has been set
+ // If this platform does not support OpenGL, and no backend has been set
// default to the software renderer
- if (requestedBackend.isEmpty())
+ if (requestedBackend.isEmpty()
+ && !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) {
requestedBackend = QString::fromLocal8Bit("software");
-#endif
+ }
if (!requestedBackend.isEmpty()) {
- qCDebug(QSG_LOG_INFO) << "Loading backend" << requestedBackend;
+ qCDebug(QSG_LOG_INFO, "Loading backend %s", qUtf8Printable(requestedBackend));
// First look for a built-in adaptation.
for (QSGContextFactoryInterface *builtInBackend : qAsConst(backendData->builtIns)) {
diff --git a/src/quick/scenegraph/qsgcontextplugin_p.h b/src/quick/scenegraph/qsgcontextplugin_p.h
index 5914b42809..02d4b79b76 100644
--- a/src/quick/scenegraph/qsgcontextplugin_p.h
+++ b/src/quick/scenegraph/qsgcontextplugin_p.h
@@ -90,7 +90,7 @@ public:
explicit QSGContextPlugin(QObject *parent = 0);
virtual ~QSGContextPlugin();
- virtual QStringList keys() const override = 0;
+ QStringList keys() const override = 0;
QQuickTextureFactory *createTextureFactoryFromImage(const QImage &) override { return 0; }
QSGRenderLoop *createWindowManager() override { return 0; }
diff --git a/src/quick/scenegraph/qsgdefaultcontext.cpp b/src/quick/scenegraph/qsgdefaultcontext.cpp
index 405f1d86a4..9a0ac66690 100644
--- a/src/quick/scenegraph/qsgdefaultcontext.cpp
+++ b/src/quick/scenegraph/qsgdefaultcontext.cpp
@@ -39,7 +39,6 @@
#include "qsgdefaultcontext_p.h"
-#include <QtQuick/private/qsgdistancefieldutil_p.h>
#include <QtQuick/private/qsgdefaultinternalrectanglenode_p.h>
#include <QtQuick/private/qsgdefaultinternalimagenode_p.h>
#include <QtQuick/private/qsgdefaultpainternode_p.h>
@@ -68,13 +67,13 @@ QT_BEGIN_NAMESPACE
namespace QSGMultisampleAntialiasing {
class ImageNode : public QSGDefaultInternalImageNode {
public:
- void setAntialiasing(bool) { }
+ void setAntialiasing(bool) override { }
};
class RectangleNode : public QSGDefaultInternalRectangleNode {
public:
- void setAntialiasing(bool) { }
+ void setAntialiasing(bool) override { }
};
}
@@ -150,20 +149,23 @@ void QSGDefaultContext::renderContextInitialized(QSGRenderContext *renderContext
dumped = true;
QSurfaceFormat format = openglRenderContext->openglContext()->format();
QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
- qCDebug(QSG_LOG_INFO) << "R/G/B/A Buffers: " << format.redBufferSize() << format.greenBufferSize() << format.blueBufferSize() << format.alphaBufferSize();
- qCDebug(QSG_LOG_INFO) << "Depth Buffer: " << format.depthBufferSize();
- qCDebug(QSG_LOG_INFO) << "Stencil Buffer: " << format.stencilBufferSize();
- qCDebug(QSG_LOG_INFO) << "Samples: " << format.samples();
- qCDebug(QSG_LOG_INFO) << "GL_VENDOR: " << (const char *) funcs->glGetString(GL_VENDOR);
- qCDebug(QSG_LOG_INFO) << "GL_RENDERER: " << (const char *) funcs->glGetString(GL_RENDERER);
- qCDebug(QSG_LOG_INFO) << "GL_VERSION: " << (const char *) funcs->glGetString(GL_VERSION);
+ qCDebug(QSG_LOG_INFO, "R/G/B/A Buffers: %d %d %d %d", format.redBufferSize(),
+ format.greenBufferSize(), format.blueBufferSize(), format.alphaBufferSize());
+ qCDebug(QSG_LOG_INFO, "Depth Buffer: %d", format.depthBufferSize());
+ qCDebug(QSG_LOG_INFO, "Stencil Buffer: %d", format.stencilBufferSize());
+ qCDebug(QSG_LOG_INFO, "Samples: %d", format.samples());
+ qCDebug(QSG_LOG_INFO, "GL_VENDOR: %s", (const char*)funcs->glGetString(GL_VENDOR));
+ qCDebug(QSG_LOG_INFO, "GL_RENDERER: %s",
+ (const char*)funcs->glGetString(GL_RENDERER));
+ qCDebug(QSG_LOG_INFO, "GL_VERSION: %s", (const char*)funcs->glGetString(GL_VERSION));
QSet<QByteArray> exts = openglRenderContext->openglContext()->extensions();
QByteArray all;
for (const QByteArray &e : qAsConst(exts))
all += ' ' + e;
- qCDebug(QSG_LOG_INFO) << "GL_EXTENSIONS: " << all.constData();
- qCDebug(QSG_LOG_INFO) << "Max Texture Size: " << openglRenderContext->maxTextureSize();
- qCDebug(QSG_LOG_INFO) << "Debug context: " << format.testOption(QSurfaceFormat::DebugContext);
+ qCDebug(QSG_LOG_INFO, "GL_EXTENSIONS: %s", all.constData());
+ qCDebug(QSG_LOG_INFO, "Max Texture Size: %d", openglRenderContext->maxTextureSize());
+ qCDebug(QSG_LOG_INFO, "Debug context: %s",
+ format.testOption(QSurfaceFormat::DebugContext) ? "true" : "false");
}
m_mutex.unlock();
diff --git a/src/quick/scenegraph/qsgdefaultcontext_p.h b/src/quick/scenegraph/qsgdefaultcontext_p.h
index ab319502ef..b2964bf403 100644
--- a/src/quick/scenegraph/qsgdefaultcontext_p.h
+++ b/src/quick/scenegraph/qsgdefaultcontext_p.h
@@ -53,7 +53,7 @@
#include <QtQuick/private/qsgcontext_p.h>
#include <QtQuick/private/qsgdistancefieldglyphnode_p.h>
-#include "qsgrendererinterface.h"
+#include <qsgrendererinterface.h>
QT_BEGIN_NAMESPACE
diff --git a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp
index f0a336e229..7789ef8fb1 100644
--- a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp
+++ b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache.cpp
@@ -42,7 +42,6 @@
#include <QtGui/private/qdistancefield_p.h>
#include <QtGui/private/qopenglcontext_p.h>
#include <QtQml/private/qqmlglobal_p.h>
-#include <QtQuick/private/qsgdistancefieldutil_p.h>
#include <qopenglfunctions.h>
#include <qopenglframebufferobject.h>
#include <qmath.h>
@@ -60,8 +59,8 @@ DEFINE_BOOL_CONFIG_OPTION(qsgPreferFullSizeGlyphCacheTextures, QSG_PREFER_FULLSI
# define QSG_DEFAULT_DISTANCEFIELD_GLYPH_CACHE_PADDING 2
#endif
-QSGDefaultDistanceFieldGlyphCache::QSGDefaultDistanceFieldGlyphCache(QSGDistanceFieldGlyphCacheManager *man, QOpenGLContext *c, const QRawFont &font)
- : QSGDistanceFieldGlyphCache(man, c, font)
+QSGDefaultDistanceFieldGlyphCache::QSGDefaultDistanceFieldGlyphCache(QOpenGLContext *c, const QRawFont &font)
+ : QSGDistanceFieldGlyphCache(c, font)
, m_maxTextureSize(0)
, m_maxTextureCount(3)
, m_blitProgram(0)
@@ -72,12 +71,15 @@ QSGDefaultDistanceFieldGlyphCache::QSGDefaultDistanceFieldGlyphCache(QSGDistance
, m_coreFuncs(0)
#endif
{
- m_blitBuffer.create();
- m_blitBuffer.bind();
- static GLfloat buffer[16] = {-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f,
- 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f};
- m_blitBuffer.allocate(buffer, sizeof(buffer));
- m_blitBuffer.release();
+ if (Q_LIKELY(m_blitBuffer.create())) {
+ m_blitBuffer.bind();
+ static const GLfloat buffer[16] = {-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f};
+ m_blitBuffer.allocate(buffer, sizeof(buffer));
+ m_blitBuffer.release();
+ } else {
+ qWarning("Buffer creation failed");
+ }
m_areaAllocator = new QSGAreaAllocator(QSize(maxTextureSize(), m_maxTextureCount * maxTextureSize()));
}
diff --git a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h
index 57dc4a5d07..fe365495c2 100644
--- a/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h
+++ b/src/quick/scenegraph/qsgdefaultdistancefieldglyphcache_p.h
@@ -69,7 +69,7 @@ class QOpenGLFunctions_3_2_Core;
class Q_QUICK_PRIVATE_EXPORT QSGDefaultDistanceFieldGlyphCache : public QSGDistanceFieldGlyphCache
{
public:
- QSGDefaultDistanceFieldGlyphCache(QSGDistanceFieldGlyphCacheManager *man, QOpenGLContext *c, const QRawFont &font);
+ QSGDefaultDistanceFieldGlyphCache(QOpenGLContext *c, const QRawFont &font);
virtual ~QSGDefaultDistanceFieldGlyphCache();
void requestGlyphs(const QSet<glyph_t> &glyphs) override;
diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
index b001899915..0169f097bc 100644
--- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
+++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
@@ -91,11 +91,11 @@ class QSGTextMaskShader : public QSGMaterialShader
public:
QSGTextMaskShader(QFontEngine::GlyphFormat glyphFormat);
- virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
- virtual char const *const *attributeNames() const;
+ void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
+ char const *const *attributeNames() const override;
protected:
- virtual void initialize();
+ void initialize() override;
int m_matrix_id;
int m_color_id;
@@ -181,7 +181,7 @@ public:
setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/8bittextmask.frag"));
}
- virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
+ void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
};
void QSG8BitTextMaskShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
@@ -206,10 +206,10 @@ public:
setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/24bittextmask.frag"));
}
- virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
- virtual void initialize();
- void activate();
- void deactivate();
+ void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
+ void initialize() override;
+ void activate() override;
+ void deactivate() override;
bool useSRGB() const;
uint m_useSRGB : 1;
@@ -301,7 +301,7 @@ public:
setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/32bitcolortext.frag"));
}
- void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) Q_DECL_OVERRIDE;
+ void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
};
void QSG32BitColorTextShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
@@ -310,7 +310,7 @@ void QSG32BitColorTextShader::updateState(const RenderState &state, QSGMaterial
QSGTextMaskMaterial *material = static_cast<QSGTextMaskMaterial *>(newEffect);
QSGTextMaskMaterial *oldMaterial = static_cast<QSGTextMaskMaterial *>(oldEffect);
- if (oldMaterial == Q_NULLPTR || material->color() != oldMaterial->color() || state.isOpacityDirty()) {
+ if (oldMaterial == nullptr || material->color() != oldMaterial->color() || state.isOpacityDirty()) {
float opacity = material->color().w() * state.opacity();
program()->setUniformValue(m_color_id, opacity);
}
@@ -326,10 +326,10 @@ public:
setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/styledtext.frag"));
}
- virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
+ void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
private:
- virtual void initialize();
+ void initialize() override;
int m_shift_id;
int m_styleColor_id;
diff --git a/src/quick/scenegraph/qsgdefaultinternalimagenode.cpp b/src/quick/scenegraph/qsgdefaultinternalimagenode.cpp
index 1d54628acd..a5a6da06a7 100644
--- a/src/quick/scenegraph/qsgdefaultinternalimagenode.cpp
+++ b/src/quick/scenegraph/qsgdefaultinternalimagenode.cpp
@@ -50,11 +50,11 @@ class SmoothTextureMaterialShader : public QSGTextureMaterialShader
public:
SmoothTextureMaterialShader();
- virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
- virtual char const *const *attributeNames() const;
+ void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
+ char const *const *attributeNames() const override;
protected:
- virtual void initialize();
+ void initialize() override;
int m_pixelSizeLoc;
};
diff --git a/src/quick/scenegraph/qsgdefaultinternalrectanglenode.cpp b/src/quick/scenegraph/qsgdefaultinternalrectanglenode.cpp
index 94414444ba..e52dcaad52 100644
--- a/src/quick/scenegraph/qsgdefaultinternalrectanglenode.cpp
+++ b/src/quick/scenegraph/qsgdefaultinternalrectanglenode.cpp
@@ -55,11 +55,11 @@ class SmoothColorMaterialShader : public QSGMaterialShader
public:
SmoothColorMaterialShader();
- virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
- virtual char const *const *attributeNames() const;
+ void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
+ char const *const *attributeNames() const override;
private:
- virtual void initialize();
+ void initialize() override;
int m_matrixLoc;
int m_opacityLoc;
diff --git a/src/quick/scenegraph/qsgdefaultlayer.cpp b/src/quick/scenegraph/qsgdefaultlayer.cpp
index 2897f53e32..cd9c4a9a90 100644
--- a/src/quick/scenegraph/qsgdefaultlayer.cpp
+++ b/src/quick/scenegraph/qsgdefaultlayer.cpp
@@ -60,7 +60,7 @@ namespace
public:
BindableFbo(QOpenGLFramebufferObject *fbo, QSGDepthStencilBuffer *depthStencil);
virtual ~BindableFbo();
- void bind() const Q_DECL_OVERRIDE;
+ void bind() const override;
private:
QOpenGLFramebufferObject *m_fbo;
QSGDepthStencilBuffer *m_depthStencil;
@@ -100,6 +100,7 @@ QSGDefaultLayer::QSGDefaultLayer(QSGRenderContext *context)
#ifdef QSG_DEBUG_FBO_OVERLAY
, m_debugOverlay(0)
#endif
+ , m_samples(0)
, m_mipmap(false)
, m_live(true)
, m_recursive(false)
@@ -314,11 +315,20 @@ void QSGDefaultLayer::grab()
QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
bool deleteFboLater = false;
- if (!m_fbo || m_fbo->size() != m_size || m_fbo->format().internalTextureFormat() != m_format
- || (!m_fbo->format().mipmap() && m_mipmap))
- {
+
+ int effectiveSamples = m_samples;
+ // By default m_samples is 0. Fall back to the context's setting in this case.
+ if (effectiveSamples == 0)
+ effectiveSamples = m_context->openglContext()->format().samples();
+
+ const bool needsNewFbo = !m_fbo || m_fbo->size() != m_size || m_fbo->format().internalTextureFormat() != m_format;
+ const bool mipmapGotEnabled = m_fbo && !m_fbo->format().mipmap() && m_mipmap;
+ const bool msaaGotEnabled = effectiveSamples > 1 && (!m_secondaryFbo || m_secondaryFbo->format().samples() != effectiveSamples);
+ const bool msaaGotDisabled = effectiveSamples <= 1 && m_secondaryFbo;
+
+ if (needsNewFbo || mipmapGotEnabled || msaaGotEnabled || msaaGotDisabled) {
if (!m_multisamplingChecked) {
- if (m_context->openglContext()->format().samples() <= 1) {
+ if (effectiveSamples <= 1) {
m_multisampling = false;
} else {
QOpenGLExtensions *e = static_cast<QOpenGLExtensions *>(funcs);
@@ -334,7 +344,7 @@ void QSGDefaultLayer::grab()
QOpenGLFramebufferObjectFormat format;
format.setInternalTextureFormat(m_format);
- format.setSamples(m_context->openglContext()->format().samples());
+ format.setSamples(effectiveSamples);
m_secondaryFbo = new QOpenGLFramebufferObject(m_size, format);
m_depthStencilBuffer = m_context->depthStencilBufferForFbo(m_secondaryFbo);
} else {
diff --git a/src/quick/scenegraph/qsgdefaultlayer_p.h b/src/quick/scenegraph/qsgdefaultlayer_p.h
index ae39994096..06355e0c21 100644
--- a/src/quick/scenegraph/qsgdefaultlayer_p.h
+++ b/src/quick/scenegraph/qsgdefaultlayer_p.h
@@ -69,53 +69,56 @@ public:
QSGDefaultLayer(QSGRenderContext *context);
~QSGDefaultLayer();
- bool updateTexture() Q_DECL_OVERRIDE;
+ bool updateTexture() override;
// The item's "paint node", not effect node.
QSGNode *item() const { return m_item; }
- void setItem(QSGNode *item) Q_DECL_OVERRIDE;
+ void setItem(QSGNode *item) override;
QRectF rect() const { return m_rect; }
- void setRect(const QRectF &rect) Q_DECL_OVERRIDE;
+ void setRect(const QRectF &rect) override;
QSize size() const { return m_size; }
- void setSize(const QSize &size) Q_DECL_OVERRIDE;
+ void setSize(const QSize &size) override;
- void setHasMipmaps(bool mipmap) Q_DECL_OVERRIDE;
+ void setHasMipmaps(bool mipmap) override;
- void bind() Q_DECL_OVERRIDE;
+ void bind() override;
- bool hasAlphaChannel() const Q_DECL_OVERRIDE;
- bool hasMipmaps() const Q_DECL_OVERRIDE;
- int textureId() const Q_DECL_OVERRIDE;
- QSize textureSize() const Q_DECL_OVERRIDE { return m_size; }
+ bool hasAlphaChannel() const override;
+ bool hasMipmaps() const override;
+ int textureId() const override;
+ QSize textureSize() const override { return m_size; }
GLenum format() const { return m_format; }
- void setFormat(GLenum format) Q_DECL_OVERRIDE;
+ void setFormat(GLenum format) override;
bool live() const { return bool(m_live); }
- void setLive(bool live) Q_DECL_OVERRIDE;
+ void setLive(bool live) override;
bool recursive() const { return bool(m_recursive); }
- void setRecursive(bool recursive) Q_DECL_OVERRIDE;
+ void setRecursive(bool recursive) override;
- void setDevicePixelRatio(qreal ratio) Q_DECL_OVERRIDE { m_device_pixel_ratio = ratio; }
+ void setDevicePixelRatio(qreal ratio) override { m_device_pixel_ratio = ratio; }
bool mirrorHorizontal() const { return bool(m_mirrorHorizontal); }
- void setMirrorHorizontal(bool mirror) Q_DECL_OVERRIDE;
+ void setMirrorHorizontal(bool mirror) override;
bool mirrorVertical() const { return bool(m_mirrorVertical); }
- void setMirrorVertical(bool mirror) Q_DECL_OVERRIDE;
+ void setMirrorVertical(bool mirror) override;
- void scheduleUpdate() Q_DECL_OVERRIDE;
+ void scheduleUpdate() override;
- QImage toImage() const Q_DECL_OVERRIDE;
+ QImage toImage() const override;
- QRectF normalizedTextureSubRect() const Q_DECL_OVERRIDE;
+ QRectF normalizedTextureSubRect() const override;
+
+ int samples() const { return m_samples; }
+ void setSamples(int samples) override { m_samples = samples; }
public Q_SLOTS:
- void markDirtyTexture() Q_DECL_OVERRIDE;
- void invalidated() Q_DECL_OVERRIDE;
+ void markDirtyTexture() override;
+ void invalidated() override;
private:
void grab();
@@ -138,6 +141,7 @@ private:
#endif
QSGDefaultRenderContext *m_context;
+ int m_samples;
uint m_mipmap : 1;
uint m_live : 1;
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
index b343f89cc0..12357f12c7 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp
+++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
@@ -44,8 +44,8 @@
#include <QtQuick/private/qsgbatchrenderer_p.h>
#include <QtQuick/private/qsgrenderer_p.h>
#include <QtQuick/private/qsgatlastexture_p.h>
+#include <QtQuick/private/qsgcompressedtexture_p.h>
#include <QtQuick/private/qsgdefaultdistancefieldglyphcache_p.h>
-#include <QtQuick/private/qsgdistancefieldutil_p.h>
QT_BEGIN_NAMESPACE
@@ -159,8 +159,8 @@ void QSGDefaultRenderContext::invalidate()
delete m_depthStencilManager;
m_depthStencilManager = 0;
- delete m_distanceFieldCacheManager;
- m_distanceFieldCacheManager = 0;
+ qDeleteAll(m_glyphCaches);
+ m_glyphCaches.clear();
if (m_gl->property(QSG_RENDERCONTEXT_PROPERTY) == QVariant::fromValue(this))
m_gl->setProperty(QSG_RENDERCONTEXT_PROPERTY, QVariant());
@@ -244,6 +244,14 @@ QSGRenderer *QSGDefaultRenderContext::createRenderer()
return new QSGBatchRenderer::Renderer(this);
}
+QSGTexture *QSGDefaultRenderContext::compressedTextureForFactory(const QSGCompressedTextureFactory *factory) const
+{
+ // The atlas implementation is only supported from the render thread
+ if (openglContext() && QThread::currentThread() == openglContext()->thread())
+ return m_atlasManager->create(factory);
+ return nullptr;
+}
+
/*!
Compile \a shader, optionally using \a vertexCode and \a fragmentCode as
replacement for the source code supplied by \a shader.
@@ -260,7 +268,7 @@ void QSGDefaultRenderContext::compileShader(QSGMaterialShader *shader, QSGMateri
if (vertexCode || fragmentCode) {
Q_ASSERT_X((material->flags() & QSGMaterial::CustomCompileStep) == 0,
"QSGRenderContext::compile()",
- "materials with custom compile step cannot have custom vertex/fragment code");
+ "materials with custom compile step cannot have modified vertex or fragment code");
QOpenGLShaderProgram *p = shader->program();
p->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, vertexCode ? vertexCode : shader->vertexShader());
p->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, fragmentCode ? fragmentCode : shader->fragmentShader());
@@ -272,6 +280,26 @@ void QSGDefaultRenderContext::compileShader(QSGMaterialShader *shader, QSGMateri
}
}
+QString QSGDefaultRenderContext::fontKey(const QRawFont &font)
+{
+ QFontEngine *fe = QRawFontPrivate::get(font)->fontEngine;
+ if (!fe->faceId().filename.isEmpty()) {
+ QByteArray keyName = fe->faceId().filename;
+ if (font.style() != QFont::StyleNormal)
+ keyName += QByteArray(" I");
+ if (font.weight() != QFont::Normal)
+ keyName += ' ' + QByteArray::number(font.weight());
+ keyName += QByteArray(" DF");
+ return QString::fromUtf8(keyName);
+ } else {
+ return QString::fromLatin1("%1_%2_%3_%4")
+ .arg(font.familyName())
+ .arg(font.styleName())
+ .arg(font.weight())
+ .arg(font.style());
+ }
+}
+
void QSGDefaultRenderContext::initializeShader(QSGMaterialShader *shader)
{
shader->program()->bind();
@@ -291,13 +319,11 @@ QSGDefaultRenderContext *QSGDefaultRenderContext::from(QOpenGLContext *context)
QSGDistanceFieldGlyphCache *QSGDefaultRenderContext::distanceFieldGlyphCache(const QRawFont &font)
{
- if (!m_distanceFieldCacheManager)
- m_distanceFieldCacheManager = new QSGDistanceFieldGlyphCacheManager;
-
- QSGDistanceFieldGlyphCache *cache = m_distanceFieldCacheManager->cache(font);
+ QString key = fontKey(font);
+ QSGDistanceFieldGlyphCache *cache = m_glyphCaches.value(key, 0);
if (!cache) {
- cache = new QSGDefaultDistanceFieldGlyphCache(m_distanceFieldCacheManager, openglContext(), font);
- m_distanceFieldCacheManager->insertCache(font, cache);
+ cache = new QSGDefaultDistanceFieldGlyphCache(openglContext(), font);
+ m_glyphCaches.insert(key, cache);
}
return cache;
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext_p.h b/src/quick/scenegraph/qsgdefaultrendercontext_p.h
index 0aed46b658..68329256f1 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext_p.h
+++ b/src/quick/scenegraph/qsgdefaultrendercontext_p.h
@@ -84,6 +84,7 @@ public:
QSGTexture *createTexture(const QImage &image, uint flags) const override;
QSGRenderer *createRenderer() override;
+ QSGTexture *compressedTextureForFactory(const QSGCompressedTextureFactory *factory) const override;
virtual void compileShader(QSGMaterialShader *shader, QSGMaterial *material, const char *vertexCode = 0, const char *fragmentCode = 0);
virtual void initializeShader(QSGMaterialShader *shader);
@@ -96,6 +97,8 @@ public:
int maxTextureSize() const override { return m_maxTextureSize; }
protected:
+ static QString fontKey(const QRawFont &font);
+
QOpenGLContext *m_gl;
QSGDepthStencilBufferManager *m_depthStencilManager;
int m_maxTextureSize;
diff --git a/src/quick/scenegraph/qsgdefaultspritenode.cpp b/src/quick/scenegraph/qsgdefaultspritenode.cpp
index 5eb8fb6e08..7fe6048d59 100644
--- a/src/quick/scenegraph/qsgdefaultspritenode.cpp
+++ b/src/quick/scenegraph/qsgdefaultspritenode.cpp
@@ -109,7 +109,7 @@ public:
setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/sprite.frag"));
}
- void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *) Q_DECL_OVERRIDE
+ void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *) override
{
QQuickSpriteMaterial *m = static_cast<QQuickSpriteMaterial *>(newEffect);
m->texture->bind();
@@ -122,14 +122,14 @@ public:
program()->setUniformValue(m_matrix_id, state.combinedMatrix());
}
- void initialize() Q_DECL_OVERRIDE {
+ void initialize() override {
m_matrix_id = program()->uniformLocation("qt_Matrix");
m_opacity_id = program()->uniformLocation("qt_Opacity");
m_animData_id = program()->uniformLocation("animData");
m_animPos_id = program()->uniformLocation("animPos");
}
- char const *const *attributeNames() const Q_DECL_OVERRIDE {
+ char const *const *attributeNames() const override {
static const char *attr[] = {
"vPos",
"vTex",
diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp b/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp
index 456a197ba1..32eda2d142 100644
--- a/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp
+++ b/src/quick/scenegraph/qsgdistancefieldglyphnode.cpp
@@ -39,7 +39,6 @@
#include "qsgdistancefieldglyphnode_p.h"
#include "qsgdistancefieldglyphnode_p_p.h"
-#include <QtQuick/private/qsgdistancefieldutil_p.h>
#include <QtQuick/private/qsgcontext_p.h>
QT_BEGIN_NAMESPACE
@@ -76,9 +75,6 @@ QSGDistanceFieldGlyphNode::~QSGDistanceFieldGlyphNode()
m_glyph_cache->unregisterGlyphNode(this);
m_glyph_cache->unregisterOwnerElement(ownerElement());
}
-
- while (m_nodesToDelete.count())
- delete m_nodesToDelete.takeLast();
}
void QSGDistanceFieldGlyphNode::setColor(const QColor &color)
@@ -158,9 +154,6 @@ void QSGDistanceFieldGlyphNode::preprocess()
{
Q_ASSERT(m_glyph_cache);
- while (m_nodesToDelete.count())
- delete m_nodesToDelete.takeLast();
-
m_glyph_cache->processPendingGlyphs();
m_glyph_cache->update();
@@ -188,13 +181,12 @@ void QSGDistanceFieldGlyphNode::updateGeometry()
// Remove previously created sub glyph nodes
// We assume all the children are sub glyph nodes
QSGNode *subnode = firstChild();
+ QSGNode *nextNode = 0;
while (subnode) {
- // We can't delete the node now as it might be in the preprocess list
- // It will be deleted in the next preprocess
- m_nodesToDelete.append(subnode);
- subnode = subnode->nextSibling();
+ nextNode = subnode->nextSibling();
+ delete subnode;
+ subnode = nextNode;
}
- removeAllChildNodes();
QSGGeometry *g = geometry();
diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp
index 1c88e33b10..03c5738e56 100644
--- a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp
+++ b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.cpp
@@ -38,7 +38,6 @@
****************************************************************************/
#include "qsgdistancefieldglyphnode_p_p.h"
-#include <QtQuick/private/qsgdistancefieldutil_p.h>
#include <QtQuick/private/qsgtexture_p.h>
#include <QtGui/qopenglfunctions.h>
#include <QtGui/qsurface.h>
@@ -52,13 +51,13 @@ class QSGDistanceFieldTextMaterialShader : public QSGMaterialShader
public:
QSGDistanceFieldTextMaterialShader();
- virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
- virtual char const *const *attributeNames() const;
+ void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
+ char const *const *attributeNames() const override;
protected:
- virtual void initialize();
+ void initialize() override;
- void updateAlphaRange(ThresholdFunc thresholdFunc, AntialiasingSpreadFunc spreadFunc);
+ void updateAlphaRange();
void updateColor(const QVector4D &c);
void updateTextureScale(const QVector2D &ts);
@@ -98,7 +97,31 @@ QSGDistanceFieldTextMaterialShader::QSGDistanceFieldTextMaterialShader()
setShaderSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/scenegraph/shaders/distancefieldtext.frag"));
}
-void QSGDistanceFieldTextMaterialShader::updateAlphaRange(ThresholdFunc thresholdFunc, AntialiasingSpreadFunc spreadFunc)
+static float qt_sg_envFloat(const char *name, float defaultValue)
+{
+ if (Q_LIKELY(!qEnvironmentVariableIsSet(name)))
+ return defaultValue;
+ bool ok = false;
+ const float value = qgetenv(name).toFloat(&ok);
+ return ok ? value : defaultValue;
+}
+
+static float thresholdFunc(float glyphScale)
+{
+ static const float base = qt_sg_envFloat("QT_DF_BASE", 0.5f);
+ static const float baseDev = qt_sg_envFloat("QT_DF_BASEDEVIATION", 0.065f);
+ static const float devScaleMin = qt_sg_envFloat("QT_DF_SCALEFORMAXDEV", 0.15f);
+ static const float devScaleMax = qt_sg_envFloat("QT_DF_SCALEFORNODEV", 0.3f);
+ return base - ((qBound(devScaleMin, glyphScale, devScaleMax) - devScaleMin) / (devScaleMax - devScaleMin) * -baseDev + baseDev);
+}
+
+static float spreadFunc(float glyphScale)
+{
+ static const float range = qt_sg_envFloat("QT_DF_RANGE", 0.06f);
+ return range / glyphScale;
+}
+
+void QSGDistanceFieldTextMaterialShader::updateAlphaRange()
{
float combinedScale = m_fontScale * m_matrixScale;
float base = thresholdFunc(combinedScale);
@@ -169,8 +192,7 @@ void QSGDistanceFieldTextMaterialShader::updateState(const RenderState &state, Q
updateRange = true;
}
if (updateRange) {
- updateAlphaRange(material->glyphCache()->manager()->thresholdFunc(),
- material->glyphCache()->manager()->antialiasingSpreadFunc());
+ updateAlphaRange();
}
Q_ASSERT(material->glyphCache());
@@ -261,10 +283,10 @@ class DistanceFieldStyledTextMaterialShader : public QSGDistanceFieldTextMateria
public:
DistanceFieldStyledTextMaterialShader();
- virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
+ void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
protected:
- virtual void initialize();
+ void initialize() override;
int m_styleColor_id;
};
@@ -329,12 +351,12 @@ class DistanceFieldOutlineTextMaterialShader : public DistanceFieldStyledTextMat
public:
DistanceFieldOutlineTextMaterialShader();
- virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
+ void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
protected:
- virtual void initialize();
+ void initialize() override;
- void updateOutlineAlphaRange(ThresholdFunc thresholdFunc, AntialiasingSpreadFunc spreadFunc, int dfRadius);
+ void updateOutlineAlphaRange(int dfRadius);
int m_outlineAlphaMax0_id;
int m_outlineAlphaMax1_id;
@@ -355,9 +377,7 @@ void DistanceFieldOutlineTextMaterialShader::initialize()
m_outlineAlphaMax1_id = program()->uniformLocation("outlineAlphaMax1");
}
-void DistanceFieldOutlineTextMaterialShader::updateOutlineAlphaRange(ThresholdFunc thresholdFunc,
- AntialiasingSpreadFunc spreadFunc,
- int dfRadius)
+void DistanceFieldOutlineTextMaterialShader::updateOutlineAlphaRange(int dfRadius)
{
float combinedScale = m_fontScale * m_matrixScale;
float base = thresholdFunc(combinedScale);
@@ -381,9 +401,7 @@ void DistanceFieldOutlineTextMaterialShader::updateState(const RenderState &stat
if (oldMaterial == 0
|| material->fontScale() != oldMaterial->fontScale()
|| state.isMatrixDirty())
- updateOutlineAlphaRange(material->glyphCache()->manager()->thresholdFunc(),
- material->glyphCache()->manager()->antialiasingSpreadFunc(),
- material->glyphCache()->distanceFieldRadius());
+ updateOutlineAlphaRange(material->glyphCache()->distanceFieldRadius());
}
@@ -413,10 +431,10 @@ class DistanceFieldShiftedStyleTextMaterialShader : public DistanceFieldStyledTe
public:
DistanceFieldShiftedStyleTextMaterialShader();
- virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
+ void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
protected:
- virtual void initialize();
+ void initialize() override;
void updateShift(qreal fontScale, const QPointF& shift);
@@ -492,10 +510,10 @@ class QSGHiQSubPixelDistanceFieldTextMaterialShader : public QSGDistanceFieldTex
public:
QSGHiQSubPixelDistanceFieldTextMaterialShader();
- virtual void initialize();
- virtual void activate();
- virtual void deactivate();
- virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
+ void initialize() override;
+ void activate() override;
+ void deactivate() override;
+ void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
private:
int m_fontScale_id;
diff --git a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.h b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.h
index c0c6bda718..7008f20925 100644
--- a/src/quick/scenegraph/qsgdistancefieldglyphnode_p.h
+++ b/src/quick/scenegraph/qsgdistancefieldglyphnode_p.h
@@ -59,7 +59,6 @@
QT_BEGIN_NAMESPACE
class QSGRenderContext;
-class QSGDistanceFieldGlyphCacheManager;
class QSGDistanceFieldTextMaterial;
class QSGDistanceFieldGlyphNode: public QSGGlyphNode, public QSGDistanceFieldGlyphConsumer
{
@@ -107,7 +106,6 @@ private:
AntialiasingMode m_antialiasingMode;
QRectF m_boundingRect;
const QSGDistanceFieldGlyphCache::Texture *m_texture;
- QLinkedList<QSGNode *> m_nodesToDelete;
struct GlyphInfo {
QVector<quint32> indexes;
diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp
index df41fa8369..ca1fb9ba5c 100644
--- a/src/quick/scenegraph/qsgrenderloop.cpp
+++ b/src/quick/scenegraph/qsgrenderloop.cpp
@@ -150,7 +150,7 @@ public:
QImage grab(QQuickWindow *window) override;
void maybeUpdate(QQuickWindow *window) override;
- void update(QQuickWindow *window) override{ maybeUpdate(window); } // identical for this implementation.
+ void update(QQuickWindow *window) override { maybeUpdate(window); } // identical for this implementation.
void handleUpdateRequest(QQuickWindow *) override;
void releaseResources(QQuickWindow *) override;
@@ -327,7 +327,7 @@ void QSGGuiThreadRenderLoop::windowDestroyed(QQuickWindow *window)
current = gl->makeCurrent(surface);
}
if (Q_UNLIKELY(!current))
- qCDebug(QSG_LOG_RENDERLOOP) << "cleanup without an OpenGL context";
+ qCDebug(QSG_LOG_RENDERLOOP, "cleanup without an OpenGL context");
#if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl)
QQuickOpenGLShaderEffectMaterial::cleanupMaterialCache();
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
index e0f78a9873..971694db42 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp
+++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
@@ -115,7 +115,7 @@
QT_BEGIN_NAMESPACE
-#define QSG_RT_PAD " (RT)"
+#define QSG_RT_PAD " (RT) %s"
static inline int qsgrl_animation_interval() {
qreal refreshRate = QGuiApplication::primaryScreen()->refreshRate();
@@ -295,8 +295,8 @@ public:
void invalidateOpenGL(QQuickWindow *window, bool inDestructor, QOffscreenSurface *backupSurface);
void initializeOpenGL();
- bool event(QEvent *);
- void run();
+ bool event(QEvent *) override;
+ void run() override;
void syncAndRender();
void sync(bool inExpose);
@@ -315,7 +315,7 @@ public:
public slots:
void sceneGraphChanged() {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "sceneGraphChanged";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "sceneGraphChanged");
syncResultedInChanges = true;
}
@@ -358,14 +358,14 @@ bool QSGRenderThread::event(QEvent *e)
switch ((int) e->type()) {
case WM_Obscure: {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "WM_Obscure";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "WM_Obscure");
Q_ASSERT(!window || window == static_cast<WMWindowEvent *>(e)->window);
mutex.lock();
if (window) {
QQuickWindowPrivate::get(window)->fireAboutToStop();
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- window removed";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- window removed");
window = 0;
}
waitCondition.wakeOne();
@@ -374,7 +374,7 @@ bool QSGRenderThread::event(QEvent *e)
return true; }
case WM_RequestSync: {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "WM_RequestSync";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "WM_RequestSync");
WMSyncEvent *se = static_cast<WMSyncEvent *>(e);
if (sleeping)
stopEventProcessing = true;
@@ -383,33 +383,33 @@ bool QSGRenderThread::event(QEvent *e)
pendingUpdate |= SyncRequest;
if (se->syncInExpose) {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- triggered from expose";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- triggered from expose");
pendingUpdate |= ExposeRequest;
}
if (se->forceRenderPass) {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- repaint regardless";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- repaint regardless");
pendingUpdate |= RepaintRequest;
}
return true; }
case WM_TryRelease: {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "WM_TryRelease";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "WM_TryRelease");
mutex.lock();
wm->m_lockedForSync = true;
WMTryReleaseEvent *wme = static_cast<WMTryReleaseEvent *>(e);
if (!window || wme->inDestructor) {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- setting exit flag and invalidating OpenGL";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- setting exit flag and invalidating OpenGL");
invalidateOpenGL(wme->window, wme->inDestructor, wme->fallbackSurface);
active = gl;
Q_ASSERT_X(!wme->inDestructor || !active, "QSGRenderThread::invalidateOpenGL()", "Thread's active state is not set to false when shutting down");
if (sleeping)
stopEventProcessing = true;
} else {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- not releasing because window is still active";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- not releasing because window is still active");
if (window) {
QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
if (d->renderer) {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- requesting renderer to release cached resources";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- requesting renderer to release cached resources");
d->renderer->releaseCachedResources();
}
}
@@ -421,7 +421,7 @@ bool QSGRenderThread::event(QEvent *e)
}
case WM_Grab: {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "WM_Grab";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "WM_Grab");
WMGrabEvent *ce = static_cast<WMGrabEvent *>(e);
Q_ASSERT(ce->window);
Q_ASSERT(ce->window == window || !window);
@@ -429,27 +429,27 @@ bool QSGRenderThread::event(QEvent *e)
if (ce->window) {
gl->makeCurrent(ce->window);
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- sync scene graph";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- sync scene graph");
QQuickWindowPrivate *d = QQuickWindowPrivate::get(ce->window);
d->syncSceneGraph();
sgrc->endSync();
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- rendering scene graph";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- rendering scene graph");
QQuickWindowPrivate::get(ce->window)->renderSceneGraph(ce->window->size());
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- grabbing result";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- grabbing result");
bool alpha = ce->window->format().alphaBufferSize() > 0 && ce->window->color().alpha() != 255;
*ce->image = qt_gl_read_framebuffer(windowSize * ce->window->effectiveDevicePixelRatio(), alpha, alpha);
ce->image->setDevicePixelRatio(ce->window->effectiveDevicePixelRatio());
}
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- waking gui to handle result";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- waking gui to handle result");
waitCondition.wakeOne();
mutex.unlock();
return true;
}
case WM_PostJob: {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "WM_PostJob";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "WM_PostJob");
WMJobEvent *ce = static_cast<WMJobEvent *>(e);
Q_ASSERT(ce->window == window);
if (window) {
@@ -457,13 +457,13 @@ bool QSGRenderThread::event(QEvent *e)
ce->job->run();
delete ce->job;
ce->job = 0;
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- job done";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- job done");
}
return true;
}
case WM_RequestRepaint:
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "WM_RequestPaint";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "WM_RequestPaint");
// When GUI posts this event, it is followed by a polishAndSync, so we mustn't
// exit the event loop yet.
pendingUpdate |= RepaintRequest;
@@ -477,13 +477,13 @@ bool QSGRenderThread::event(QEvent *e)
void QSGRenderThread::invalidateOpenGL(QQuickWindow *window, bool inDestructor, QOffscreenSurface *fallback)
{
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "invalidateOpenGL()";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "invalidateOpenGL()");
if (!gl)
return;
if (!window) {
- qCWarning(QSG_LOG_RENDERLOOP()) << "QSGThreadedRenderLoop:QSGRenderThread: no window to make current...";
+ qCWarning(QSG_LOG_RENDERLOOP, "QSGThreadedRenderLoop:QSGRenderThread: no window to make current...");
return;
}
@@ -493,7 +493,7 @@ void QSGRenderThread::invalidateOpenGL(QQuickWindow *window, bool inDestructor,
bool current = gl->makeCurrent(fallback ? static_cast<QSurface *>(fallback) : static_cast<QSurface *>(window));
if (Q_UNLIKELY(!current)) {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- cleanup without an OpenGL context";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- cleanup without an OpenGL context");
}
QQuickWindowPrivate *dd = QQuickWindowPrivate::get(window);
@@ -506,7 +506,7 @@ void QSGRenderThread::invalidateOpenGL(QQuickWindow *window, bool inDestructor,
if (wipeSG) {
dd->cleanupNodesOnShutdown();
} else {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- persistent SG, avoiding cleanup";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- persistent SG, avoiding cleanup");
if (current)
gl->doneCurrent();
return;
@@ -519,14 +519,14 @@ void QSGRenderThread::invalidateOpenGL(QQuickWindow *window, bool inDestructor,
delete dd->animationController;
if (current)
gl->doneCurrent();
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- invalidating scene graph";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- invalidating scene graph");
if (wipeGL) {
delete gl;
gl = 0;
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- invalidated OpenGL";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- invalidated OpenGL");
} else {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- persistent GL, avoiding cleanup";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- persistent GL, avoiding cleanup");
}
}
@@ -536,7 +536,7 @@ void QSGRenderThread::invalidateOpenGL(QQuickWindow *window, bool inDestructor,
*/
void QSGRenderThread::sync(bool inExpose)
{
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "sync()";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "sync()");
mutex.lock();
Q_ASSERT_X(wm->m_lockedForSync, "QSGRenderThread::sync()", "sync triggered on bad terms as gui is not already locked...");
@@ -562,7 +562,7 @@ void QSGRenderThread::sync(bool inExpose)
d->syncSceneGraph();
sgrc->endSync();
if (!hadRenderer && d->renderer) {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- renderer was created";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- renderer was created");
syncResultedInChanges = true;
connect(d->renderer, SIGNAL(sceneGraphChanged()), this, SLOT(sceneGraphChanged()), Qt::DirectConnection);
}
@@ -572,11 +572,11 @@ void QSGRenderThread::sync(bool inExpose)
// and the delete is a safe operation.
QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
} else {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- window has bad size, sync aborted";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- window has bad size, sync aborted");
}
if (!inExpose) {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- sync complete, waking Gui";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- sync complete, waking Gui");
waitCondition.wakeOne();
mutex.unlock();
}
@@ -594,7 +594,7 @@ void QSGRenderThread::syncAndRender()
QElapsedTimer waitTimer;
waitTimer.start();
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "syncAndRender()";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "syncAndRender()");
syncResultedInChanges = false;
QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
@@ -605,7 +605,7 @@ void QSGRenderThread::syncAndRender()
pendingUpdate = 0;
if (syncRequested) {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- updatePending, doing sync";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- updatePending, doing sync");
sync(exposeRequested);
}
#ifndef QSG_NO_RENDER_TIMING
@@ -616,14 +616,14 @@ void QSGRenderThread::syncAndRender()
QQuickProfiler::SceneGraphRenderLoopSync);
if (!syncResultedInChanges && !repaintRequested && sgrc->isValid()) {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- no changes, render aborted";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- no changes, render aborted");
int waitTime = vsyncDelta - (int) waitTimer.elapsed();
if (waitTime > 0)
msleep(waitTime);
return;
}
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- rendering started";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- rendering started");
if (animatorDriver->isRunning()) {
@@ -653,10 +653,10 @@ void QSGRenderThread::syncAndRender()
} else {
Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphRenderLoopFrame,
QQuickProfiler::SceneGraphRenderLoopSync, 1);
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- window not ready, skipping render";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- window not ready, skipping render");
}
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- rendering done";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- rendering done");
// Though it would be more correct to put this block directly after
// fireFrameSwapped in the if (current) branch above, we don't do
@@ -664,7 +664,7 @@ void QSGRenderThread::syncAndRender()
// has started rendering with a bad window, causing makeCurrent to
// fail or if the window has a bad size.
if (exposeRequested) {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "- wake Gui after initial expose";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "- wake Gui after initial expose");
waitCondition.wakeOne();
mutex.unlock();
}
@@ -692,30 +692,30 @@ void QSGRenderThread::postEvent(QEvent *e)
void QSGRenderThread::processEvents()
{
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "--- begin processEvents()";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "--- begin processEvents()");
while (eventQueue.hasMoreEvents()) {
QEvent *e = eventQueue.takeEvent(false);
event(e);
delete e;
}
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "--- done processEvents()";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "--- done processEvents()");
}
void QSGRenderThread::processEventsAndWaitForMore()
{
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "--- begin processEventsAndWaitForMore()";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "--- begin processEventsAndWaitForMore()");
stopEventProcessing = false;
while (!stopEventProcessing) {
QEvent *e = eventQueue.takeEvent(true);
event(e);
delete e;
}
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "--- done processEventsAndWaitForMore()";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "--- done processEventsAndWaitForMore()");
}
void QSGRenderThread::run()
{
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "run()";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "run()");
animatorDriver = sgrc->sceneGraphContext()->createAnimationDriver(0);
animatorDriver->install();
if (QQmlDebugConnector::service<QQmlProfilerService>())
@@ -733,7 +733,7 @@ void QSGRenderThread::run()
QCoreApplication::processEvents();
if (active && (pendingUpdate == 0 || !window)) {
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "done drawing, sleep...";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "done drawing, sleep...");
sleeping = true;
processEventsAndWaitForMore();
sleeping = false;
@@ -742,7 +742,7 @@ void QSGRenderThread::run()
Q_ASSERT_X(!gl, "QSGRenderThread::run()", "The OpenGL context should be cleaned up before exiting the render thread...");
- qCDebug(QSG_LOG_RENDERLOOP) << QSG_RT_PAD << "run() completed";
+ qCDebug(QSG_LOG_RENDERLOOP, QSG_RT_PAD, "run() completed");
delete animatorDriver;
animatorDriver = 0;
@@ -809,7 +809,7 @@ bool QSGThreadedRenderLoop::interleaveIncubation() const
void QSGThreadedRenderLoop::animationStarted()
{
- qCDebug(QSG_LOG_RENDERLOOP) << "- animationStarted()";
+ qCDebug(QSG_LOG_RENDERLOOP, "- animationStarted()");
startOrStopAnimationTimer();
for (int i=0; i<m_windows.size(); ++i)
@@ -818,7 +818,7 @@ void QSGThreadedRenderLoop::animationStarted()
void QSGThreadedRenderLoop::animationStopped()
{
- qCDebug(QSG_LOG_RENDERLOOP) << "- animationStopped()";
+ qCDebug(QSG_LOG_RENDERLOOP, "- animationStopped()");
startOrStopAnimationTimer();
}
@@ -836,14 +836,14 @@ void QSGThreadedRenderLoop::startOrStopAnimationTimer()
}
if (m_animation_timer != 0 && (exposedWindows == 1 || !m_animation_driver->isRunning())) {
- qCDebug(QSG_LOG_RENDERLOOP) << "*** Stopping animation timer";
+ qCDebug(QSG_LOG_RENDERLOOP, "*** Stopping animation timer");
killTimer(m_animation_timer);
m_animation_timer = 0;
// If animations are running, make sure we keep on animating
if (m_animation_driver->isRunning())
maybePostPolishRequest(const_cast<Window *>(theOne));
} else if (m_animation_timer == 0 && exposedWindows != 1 && m_animation_driver->isRunning()) {
- qCDebug(QSG_LOG_RENDERLOOP) << "*** Starting animation timer";
+ qCDebug(QSG_LOG_RENDERLOOP, "*** Starting animation timer");
m_animation_timer = startTimer(qsgrl_animation_interval());
}
}
@@ -930,7 +930,7 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window)
Window *w = windowFor(m_windows, window);
if (!w) {
- qCDebug(QSG_LOG_RENDERLOOP) << "- adding window to list";
+ qCDebug(QSG_LOG_RENDERLOOP, "- adding window to list");
Window win;
win.window = window;
win.actualWindowFormat = window->format();
@@ -962,7 +962,7 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window)
// Start render thread if it is not running
if (!w->thread->isRunning()) {
- qCDebug(QSG_LOG_RENDERLOOP) << "- starting render thread";
+ qCDebug(QSG_LOG_RENDERLOOP, "- starting render thread");
if (!w->thread->gl) {
w->thread->gl = new QOpenGLContext();
@@ -981,7 +981,7 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window)
QQuickWindowPrivate::get(w->window)->fireOpenGLContextCreated(w->thread->gl);
w->thread->gl->moveToThread(w->thread);
- qCDebug(QSG_LOG_RENDERLOOP) << "- OpenGL context created";
+ qCDebug(QSG_LOG_RENDERLOOP, "- OpenGL context created");
}
QQuickAnimatorController *controller = QQuickWindowPrivate::get(w->window)->animationController;
@@ -998,11 +998,11 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window)
qFatal("Render thread failed to start, aborting application.");
} else {
- qCDebug(QSG_LOG_RENDERLOOP) << "- render thread already running";
+ qCDebug(QSG_LOG_RENDERLOOP, "- render thread already running");
}
polishAndSync(w, true);
- qCDebug(QSG_LOG_RENDERLOOP) << "- done with handleExposure()";
+ qCDebug(QSG_LOG_RENDERLOOP, "- done with handleExposure()");
startOrStopAnimationTimer();
}
@@ -1029,7 +1029,7 @@ void QSGThreadedRenderLoop::handleObscurity(Window *w)
void QSGThreadedRenderLoop::handleUpdateRequest(QQuickWindow *window)
{
- qCDebug(QSG_LOG_RENDERLOOP) << "- polish and sync update request";
+ qCDebug(QSG_LOG_RENDERLOOP, "- polish and sync update request");
Window *w = windowFor(m_windows, window);
if (w)
polishAndSync(w);
@@ -1065,7 +1065,7 @@ void QSGThreadedRenderLoop::maybeUpdate(Window *w)
// Call this function from the Gui thread later as startTimer cannot be
// called from the render thread.
if (current == w->thread) {
- qCDebug(QSG_LOG_RENDERLOOP) << "- on render thread";
+ qCDebug(QSG_LOG_RENDERLOOP, "- on render thread");
w->updateDuringSync = true;
return;
}
@@ -1125,13 +1125,13 @@ void QSGThreadedRenderLoop::releaseResources(Window *w, bool inDestructor)
// create it here and pass it on to QSGRenderThread::invalidateGL()
QOffscreenSurface *fallback = 0;
if (!window->handle()) {
- qCDebug(QSG_LOG_RENDERLOOP) << "- using fallback surface";
+ qCDebug(QSG_LOG_RENDERLOOP, "- using fallback surface");
fallback = new QOffscreenSurface();
fallback->setFormat(w->actualWindowFormat);
fallback->create();
}
- qCDebug(QSG_LOG_RENDERLOOP) << "- posting release request to render thread";
+ qCDebug(QSG_LOG_RENDERLOOP, "- posting release request to render thread");
w->thread->postEvent(new WMTryReleaseEvent(window, inDestructor, fallback));
w->thread->waitCondition.wait(&w->thread->mutex);
delete fallback;
@@ -1161,7 +1161,7 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
QQuickWindow *window = w->window;
if (!w->thread || !w->thread->window) {
- qCDebug(QSG_LOG_RENDERLOOP) << "- not exposed, abort";
+ qCDebug(QSG_LOG_RENDERLOOP, "- not exposed, abort");
return;
}
@@ -1170,7 +1170,7 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
// The delivery of the event might have caused the window to stop rendering
w = windowFor(m_windows, window);
if (!w || !w->thread || !w->thread->window) {
- qCDebug(QSG_LOG_RENDERLOOP) << "- removed after event flushing, abort";
+ qCDebug(QSG_LOG_RENDERLOOP, "- removed after event flushing, abort");
return;
}
@@ -1196,13 +1196,13 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
emit window->afterAnimating();
- qCDebug(QSG_LOG_RENDERLOOP) << "- lock for sync";
+ qCDebug(QSG_LOG_RENDERLOOP, "- lock for sync");
w->thread->mutex.lock();
m_lockedForSync = true;
w->thread->postEvent(new WMSyncEvent(window, inExpose, w->forceRenderPass));
w->forceRenderPass = false;
- qCDebug(QSG_LOG_RENDERLOOP) << "- wait for sync";
+ qCDebug(QSG_LOG_RENDERLOOP, "- wait for sync");
if (profileFrames)
waitTime = timer.nsecsElapsed();
Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
@@ -1210,7 +1210,7 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
w->thread->waitCondition.wait(&w->thread->mutex);
m_lockedForSync = false;
w->thread->mutex.unlock();
- qCDebug(QSG_LOG_RENDERLOOP) << "- unlock after sync";
+ qCDebug(QSG_LOG_RENDERLOOP, "- unlock after sync");
if (profileFrames)
syncTime = timer.nsecsElapsed();
@@ -1218,9 +1218,9 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose)
QQuickProfiler::SceneGraphPolishAndSyncSync);
if (m_animation_timer == 0 && m_animation_driver->isRunning()) {
- qCDebug(QSG_LOG_RENDERLOOP) << "- advancing animations";
+ qCDebug(QSG_LOG_RENDERLOOP, "- advancing animations");
m_animation_driver->advance();
- qCDebug(QSG_LOG_RENDERLOOP) << "- animations done..";
+ qCDebug(QSG_LOG_RENDERLOOP, "- animations done..");
// We need to trigger another sync to keep animations running...
maybePostPolishRequest(w);
emit timeToIncubate();
@@ -1247,7 +1247,7 @@ bool QSGThreadedRenderLoop::event(QEvent *e)
case QEvent::Timer: {
QTimerEvent *te = static_cast<QTimerEvent *>(e);
if (te->timerId() == m_animation_timer) {
- qCDebug(QSG_LOG_RENDERLOOP) << "- ticking non-visual timer";
+ qCDebug(QSG_LOG_RENDERLOOP, "- ticking non-visual timer");
m_animation_driver->advance();
emit timeToIncubate();
return true;
@@ -1286,20 +1286,20 @@ QImage QSGThreadedRenderLoop::grab(QQuickWindow *window)
if (!window->handle())
window->create();
- qCDebug(QSG_LOG_RENDERLOOP) << "- polishing items";
+ qCDebug(QSG_LOG_RENDERLOOP, "- polishing items");
QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
d->polishItems();
QImage result;
w->thread->mutex.lock();
m_lockedForSync = true;
- qCDebug(QSG_LOG_RENDERLOOP) << "- posting grab event";
+ qCDebug(QSG_LOG_RENDERLOOP, "- posting grab event");
w->thread->postEvent(new WMGrabEvent(window, &result));
w->thread->waitCondition.wait(&w->thread->mutex);
m_lockedForSync = false;
w->thread->mutex.unlock();
- qCDebug(QSG_LOG_RENDERLOOP) << "- grab complete";
+ qCDebug(QSG_LOG_RENDERLOOP, "- grab complete");
return result;
}
diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
index e33f31f2ac..8072359e11 100644
--- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp
+++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp
@@ -64,7 +64,7 @@ QT_BEGIN_NAMESPACE
extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha);
-#define RLDEBUG(x) qCDebug(QSG_LOG_RENDERLOOP) << x;
+#define RLDEBUG(x) qCDebug(QSG_LOG_RENDERLOOP, x)
static QElapsedTimer qsg_render_timer;
#define QSG_LOG_TIME_SAMPLE(sampleName) \
@@ -243,7 +243,7 @@ void QSGWindowsRenderLoop::windowDestroyed(QQuickWindow *window)
current = m_gl->makeCurrent(surface);
}
if (Q_UNLIKELY(!current))
- qCDebug(QSG_LOG_RENDERLOOP) << "cleanup without an OpenGL context";
+ RLDEBUG("cleanup without an OpenGL context");
#if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl)
QQuickOpenGLShaderEffectMaterial::cleanupMaterialCache();
diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri
index edf4aa08c5..4fa3e7b6bf 100644
--- a/src/quick/scenegraph/scenegraph.pri
+++ b/src/quick/scenegraph/scenegraph.pri
@@ -45,7 +45,6 @@ HEADERS += \
$$PWD/util/qsgtexture.h \
$$PWD/util/qsgtexture_p.h \
$$PWD/util/qsgtextureprovider.h \
- $$PWD/util/qsgdistancefieldutil_p.h \
$$PWD/util/qsgflatcolormaterial.h \
$$PWD/util/qsgsimplematerial.h \
$$PWD/util/qsgtexturematerial.h \
@@ -62,7 +61,6 @@ SOURCES += \
$$PWD/util/qsgsimpletexturenode.cpp \
$$PWD/util/qsgtexture.cpp \
$$PWD/util/qsgtextureprovider.cpp \
- $$PWD/util/qsgdistancefieldutil.cpp \
$$PWD/util/qsgflatcolormaterial.cpp \
$$PWD/util/qsgsimplematerial.cpp \
$$PWD/util/qsgtexturematerial.cpp \
@@ -222,3 +220,25 @@ qtConfig(opengl(es1|es2)?) {
$$PWD/shaders/visualization.frag \
$$PWD/shaders/visualization.vert
}
+
+# Compressed Texture API
+HEADERS += \
+ $$PWD/util/qsgtexturereader_p.h
+
+SOURCES += \
+ $$PWD/util/qsgtexturereader.cpp
+
+qtConfig(opengl(es1|es2)?) {
+ HEADERS += \
+ $$PWD/compressedtexture/qsgcompressedatlastexture_p.h \
+ $$PWD/compressedtexture/qsgcompressedtexture_p.h \
+ $$PWD/compressedtexture/qsgtexturefilehandler_p.h \
+ $$PWD/compressedtexture/qsgpkmhandler_p.h \
+ $$PWD/compressedtexture/qsgktxhandler_p.h
+
+ SOURCES += \
+ $$PWD/compressedtexture/qsgcompressedatlastexture.cpp \
+ $$PWD/compressedtexture/qsgcompressedtexture.cpp \
+ $$PWD/compressedtexture/qsgpkmhandler.cpp \
+ $$PWD/compressedtexture/qsgktxhandler.cpp
+}
diff --git a/src/quick/scenegraph/util/qsgatlastexture.cpp b/src/quick/scenegraph/util/qsgatlastexture.cpp
index 22f0b13f46..529cdaf070 100644
--- a/src/quick/scenegraph/util/qsgatlastexture.cpp
+++ b/src/quick/scenegraph/util/qsgatlastexture.cpp
@@ -44,6 +44,7 @@
#include <QtCore/QtMath>
#include <QtGui/QOpenGLContext>
+#include <QtGui/QOpenGLTexture>
#include <QtGui/QOpenGLFunctions>
#include <QtGui/QGuiApplication>
#include <QtGui/QScreen>
@@ -52,6 +53,8 @@
#include <QtGui/qpa/qplatformnativeinterface.h>
#include <private/qsgtexture_p.h>
+#include <private/qsgcompressedtexture_p.h>
+#include <private/qsgcompressedatlastexture_p.h>
#include <private/qquickprofiler_p.h>
@@ -65,6 +68,8 @@ int qt_sg_envInt(const char *name, int defaultValue);
static QElapsedTimer qsg_renderer_timer;
+DEFINE_BOOL_CONFIG_OPTION(qsgEnableCompressedAtlas, QSG_ENABLE_COMPRESSED_ATLAS)
+
namespace QSGAtlasTexture
{
@@ -100,6 +105,7 @@ Manager::Manager()
Manager::~Manager()
{
Q_ASSERT(m_atlas == 0);
+ Q_ASSERT(m_atlases.isEmpty());
}
void Manager::invalidate()
@@ -109,6 +115,14 @@ void Manager::invalidate()
m_atlas->deleteLater();
m_atlas = 0;
}
+
+ QHash<unsigned int, QSGCompressedAtlasTexture::Atlas*>::iterator i = m_atlases.begin();
+ while (i != m_atlases.end()) {
+ i.value()->invalidate();
+ i.value()->deleteLater();
+ ++i;
+ }
+ m_atlases.clear();
}
QSGTexture *Manager::create(const QImage &image, bool hasAlphaChannel)
@@ -125,13 +139,147 @@ QSGTexture *Manager::create(const QImage &image, bool hasAlphaChannel)
return t;
}
-Atlas::Atlas(const QSize &size)
+QSGTexture *Manager::create(const QSGCompressedTextureFactory *factory)
+{
+ QSGTexture *t = 0;
+ if (!qsgEnableCompressedAtlas() || !factory->m_textureData || !factory->m_textureData->isValid())
+ return t;
+
+ // TODO: further abstract the atlas and remove this restriction
+ unsigned int format = factory->m_textureData->format;
+ switch (format) {
+ case QOpenGLTexture::RGB8_ETC1:
+ case QOpenGLTexture::RGB8_ETC2:
+ case QOpenGLTexture::RGBA8_ETC2_EAC:
+ case QOpenGLTexture::RGB8_PunchThrough_Alpha1_ETC2:
+ break;
+ default:
+ return t;
+ }
+
+ QSize size = factory->m_textureData->size;
+ if (size.width() < m_atlas_size_limit && size.height() < m_atlas_size_limit) {
+ QHash<unsigned int, QSGCompressedAtlasTexture::Atlas*>::iterator i = m_atlases.find(format);
+ if (i == m_atlases.end())
+ i = m_atlases.insert(format, new QSGCompressedAtlasTexture::Atlas(m_atlas_size, format));
+ // must be multiple of 4
+ QSize paddedSize(((size.width() + 3) / 4) * 4, ((size.height() + 3) / 4) * 4);
+ QByteArray data = factory->m_textureData->data;
+ t = i.value()->create(data, factory->m_textureData->sizeInBytes(), factory->m_textureData->dataOffset, size, paddedSize);
+ }
+ return t;
+}
+
+AtlasBase::AtlasBase(const QSize &size)
: m_allocator(size)
, m_texture_id(0)
, m_size(size)
- , m_atlas_transient_image_threshold(0)
, m_allocated(false)
{
+}
+
+AtlasBase::~AtlasBase()
+{
+ Q_ASSERT(!m_texture_id);
+}
+
+void AtlasBase::invalidate()
+{
+ if (m_texture_id && QOpenGLContext::currentContext())
+ QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &m_texture_id);
+ m_texture_id = 0;
+}
+
+int AtlasBase::textureId() const
+{
+ if (!m_texture_id) {
+ Q_ASSERT(QOpenGLContext::currentContext());
+ QOpenGLContext::currentContext()->functions()->glGenTextures(1, &const_cast<AtlasBase *>(this)->m_texture_id);
+ }
+
+ return m_texture_id;
+}
+
+void AtlasBase::bind(QSGTexture::Filtering filtering)
+{
+ QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
+ if (!m_allocated) {
+ m_allocated = true;
+
+ while (funcs->glGetError() != GL_NO_ERROR) ;
+
+ funcs->glGenTextures(1, &m_texture_id);
+ funcs->glBindTexture(GL_TEXTURE_2D, m_texture_id);
+ funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+#if !defined(QT_OPENGL_ES_2)
+ if (!QOpenGLContext::currentContext()->isOpenGLES())
+ funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
+#endif
+ generateTexture();
+
+ GLenum errorCode = funcs->glGetError();
+ if (errorCode == GL_OUT_OF_MEMORY) {
+ qDebug("QSGTextureAtlas: texture atlas allocation failed, out of memory");
+ funcs->glDeleteTextures(1, &m_texture_id);
+ m_texture_id = 0;
+ } else if (errorCode != GL_NO_ERROR) {
+ qDebug("QSGTextureAtlas: texture atlas allocation failed, code=%x", errorCode);
+ funcs->glDeleteTextures(1, &m_texture_id);
+ m_texture_id = 0;
+ }
+ } else {
+ funcs->glBindTexture(GL_TEXTURE_2D, m_texture_id);
+ }
+
+ if (m_texture_id == 0)
+ return;
+
+ // Upload all pending images..
+ for (int i=0; i<m_pending_uploads.size(); ++i) {
+
+ bool profileFrames = QSG_LOG_TIME_TEXTURE().isDebugEnabled();
+ if (profileFrames)
+ qsg_renderer_timer.start();
+
+ Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphTexturePrepare);
+
+ // Skip bind, convert, swizzle; they're irrelevant
+ Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare,
+ QQuickProfiler::SceneGraphTexturePrepareStart, 3);
+
+ uploadPendingTexture(i);
+
+ Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare,
+ QQuickProfiler::SceneGraphTexturePrepareUpload);
+
+ // Skip mipmap; unused
+ Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare,
+ QQuickProfiler::SceneGraphTexturePrepareUpload, 1);
+ Q_QUICK_SG_PROFILE_REPORT(QQuickProfiler::SceneGraphTexturePrepare,
+ QQuickProfiler::SceneGraphTexturePrepareMipmap);
+ }
+
+ GLenum f = filtering == QSGTexture::Nearest ? GL_NEAREST : GL_LINEAR;
+ funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, f);
+ funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, f);
+
+ m_pending_uploads.clear();
+}
+
+void AtlasBase::remove(TextureBase *t)
+{
+ QRect atlasRect = t->atlasSubRect();
+ m_allocator.deallocate(atlasRect);
+ m_pending_uploads.removeOne(t);
+}
+
+Atlas::Atlas(const QSize &size)
+ : AtlasBase(size)
+ , m_atlas_transient_image_threshold(0)
+{
m_internalFormat = GL_RGBA;
m_externalFormat = GL_BGRA;
@@ -188,14 +336,6 @@ Atlas::Atlas(const QSize &size)
Atlas::~Atlas()
{
- Q_ASSERT(!m_texture_id);
-}
-
-void Atlas::invalidate()
-{
- if (m_texture_id && QOpenGLContext::currentContext())
- QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &m_texture_id);
- m_texture_id = 0;
}
Texture *Atlas::create(const QImage &image)
@@ -210,17 +350,6 @@ Texture *Atlas::create(const QImage &image)
return 0;
}
-
-int Atlas::textureId() const
-{
- if (!m_texture_id) {
- Q_ASSERT(QOpenGLContext::currentContext());
- QOpenGLContext::currentContext()->functions()->glGenTextures(1, &const_cast<Atlas *>(this)->m_texture_id);
- }
-
- return m_texture_id;
-}
-
static void swizzleBGRAToRGBA(QImage *image)
{
const int width = image->width();
@@ -334,121 +463,69 @@ void Atlas::uploadBgra(Texture *texture)
}
}
-void Atlas::bind(QSGTexture::Filtering filtering)
+void Atlas::generateTexture()
{
QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
- if (!m_allocated) {
- m_allocated = true;
-
- while (funcs->glGetError() != GL_NO_ERROR) ;
-
- funcs->glGenTextures(1, &m_texture_id);
- funcs->glBindTexture(GL_TEXTURE_2D, m_texture_id);
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-#if !defined(QT_OPENGL_ES_2)
- if (!QOpenGLContext::currentContext()->isOpenGLES())
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
-#endif
- funcs->glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_size.width(), m_size.height(), 0, m_externalFormat, GL_UNSIGNED_BYTE, 0);
+ funcs->glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_size.width(), m_size.height(), 0, m_externalFormat, GL_UNSIGNED_BYTE, 0);
#if 0
- QImage pink(m_size.width(), m_size.height(), QImage::Format_ARGB32_Premultiplied);
- pink.fill(0);
- QPainter p(&pink);
- QLinearGradient redGrad(0, 0, m_size.width(), 0);
- redGrad.setColorAt(0, Qt::black);
- redGrad.setColorAt(1, Qt::red);
- p.fillRect(0, 0, m_size.width(), m_size.height(), redGrad);
- p.setCompositionMode(QPainter::CompositionMode_Plus);
- QLinearGradient blueGrad(0, 0, 0, m_size.height());
- blueGrad.setColorAt(0, Qt::black);
- blueGrad.setColorAt(1, Qt::blue);
- p.fillRect(0, 0, m_size.width(), m_size.height(), blueGrad);
- p.end();
-
- funcs->glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_size.width(), m_size.height(), 0, m_externalFormat, GL_UNSIGNED_BYTE, pink.constBits());
+ QImage pink(m_size.width(), m_size.height(), QImage::Format_ARGB32_Premultiplied);
+ pink.fill(0);
+ QPainter p(&pink);
+ QLinearGradient redGrad(0, 0, m_size.width(), 0);
+ redGrad.setColorAt(0, Qt::black);
+ redGrad.setColorAt(1, Qt::red);
+ p.fillRect(0, 0, m_size.width(), m_size.height(), redGrad);
+ p.setCompositionMode(QPainter::CompositionMode_Plus);
+ QLinearGradient blueGrad(0, 0, 0, m_size.height());
+ blueGrad.setColorAt(0, Qt::black);
+ blueGrad.setColorAt(1, Qt::blue);
+ p.fillRect(0, 0, m_size.width(), m_size.height(), blueGrad);
+ p.end();
+
+ funcs->glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_size.width(), m_size.height(), 0, m_externalFormat, GL_UNSIGNED_BYTE, pink.constBits());
#endif
+}
- GLenum errorCode = funcs->glGetError();
- if (errorCode == GL_OUT_OF_MEMORY) {
- qDebug("QSGTextureAtlas: texture atlas allocation failed, out of memory");
- funcs->glDeleteTextures(1, &m_texture_id);
- m_texture_id = 0;
- } else if (errorCode != GL_NO_ERROR) {
- qDebug("QSGTextureAtlas: texture atlas allocation failed, code=%x", errorCode);
- funcs->glDeleteTextures(1, &m_texture_id);
- m_texture_id = 0;
- }
+void Atlas::uploadPendingTexture(int i)
+{
+ Texture *t = static_cast<Texture*>(m_pending_uploads.at(i));
+ if (m_externalFormat == GL_BGRA &&
+ !m_use_bgra_fallback) {
+ uploadBgra(t);
} else {
- funcs->glBindTexture(GL_TEXTURE_2D, m_texture_id);
+ upload(t);
}
-
- if (m_texture_id == 0)
- return;
-
- // Upload all pending images..
- for (int i=0; i<m_pending_uploads.size(); ++i) {
-
- bool profileFrames = QSG_LOG_TIME_TEXTURE().isDebugEnabled();
- if (profileFrames)
- qsg_renderer_timer.start();
-
- Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphTexturePrepare);
-
- // Skip bind, convert, swizzle; they're irrelevant
- Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare,
- QQuickProfiler::SceneGraphTexturePrepareStart, 3);
-
- Texture *t = m_pending_uploads.at(i);
- if (m_externalFormat == GL_BGRA &&
- !m_use_bgra_fallback) {
- uploadBgra(t);
- } else {
- upload(t);
- }
- const QSize textureSize = t->textureSize();
- if (textureSize.width() > m_atlas_transient_image_threshold ||
- textureSize.height() > m_atlas_transient_image_threshold)
- t->releaseImage();
-
- qCDebug(QSG_LOG_TIME_TEXTURE).nospace() << "atlastexture uploaded in: " << qsg_renderer_timer.elapsed()
- << "ms (" << t->textureSize().width() << "x"
- << t->textureSize().height() << ")";
-
- Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphTexturePrepare,
- QQuickProfiler::SceneGraphTexturePrepareUpload);
-
- // Skip mipmap; unused
- Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphTexturePrepare,
- QQuickProfiler::SceneGraphTexturePrepareUpload, 1);
- Q_QUICK_SG_PROFILE_REPORT(QQuickProfiler::SceneGraphTexturePrepare,
- QQuickProfiler::SceneGraphTexturePrepareMipmap);
- }
-
- GLenum f = filtering == QSGTexture::Nearest ? GL_NEAREST : GL_LINEAR;
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, f);
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, f);
-
- m_pending_uploads.clear();
+ const QSize textureSize = t->textureSize();
+ if (textureSize.width() > m_atlas_transient_image_threshold ||
+ textureSize.height() > m_atlas_transient_image_threshold)
+ t->releaseImage();
+
+ qCDebug(QSG_LOG_TIME_TEXTURE, "atlastexture uploaded in: %lldms (%dx%d)",
+ qsg_renderer_timer.elapsed(),
+ t->textureSize().width(),
+ t->textureSize().height());
}
-void Atlas::remove(Texture *t)
+TextureBase::TextureBase(AtlasBase *atlas, const QRect &textureRect)
+ : m_allocated_rect(textureRect)
+ , m_atlas(atlas)
{
- QRect atlasRect = t->atlasSubRect();
- m_allocator.deallocate(atlasRect);
- m_pending_uploads.removeOne(t);
}
+TextureBase::~TextureBase()
+{
+ m_atlas->remove(this);
+}
+void TextureBase::bind()
+{
+ m_atlas->bind(filtering());
+}
Texture::Texture(Atlas *atlas, const QRect &textureRect, const QImage &image)
- : QSGTexture()
- , m_allocated_rect(textureRect)
+ : TextureBase(atlas, textureRect)
, m_image(image)
- , m_atlas(atlas)
, m_nonatlas_texture(0)
, m_has_alpha(image.hasAlphaChannel())
{
@@ -463,16 +540,10 @@ Texture::Texture(Atlas *atlas, const QRect &textureRect, const QImage &image)
Texture::~Texture()
{
- m_atlas->remove(this);
if (m_nonatlas_texture)
delete m_nonatlas_texture;
}
-void Texture::bind()
-{
- m_atlas->bind(filtering());
-}
-
QSGTexture *Texture::removedFromAtlas() const
{
if (m_nonatlas_texture) {
@@ -508,7 +579,7 @@ QSGTexture *Texture::removedFromAtlas() const
QRect r = atlasSubRectWithoutPadding();
// and copy atlas into our texture.
while (f->glGetError() != GL_NO_ERROR) ;
- f->glCopyTexImage2D(GL_TEXTURE_2D, 0, m_atlas->internalFormat(), r.x(), r.y(), r.width(), r.height(), 0);
+ f->glCopyTexImage2D(GL_TEXTURE_2D, 0, static_cast<Atlas*>(m_atlas)->internalFormat(), r.x(), r.y(), r.width(), r.height(), 0);
// BGRA may have been rejected by some GLES implementations
if (f->glGetError() != GL_NO_ERROR)
f->glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, r.x(), r.y(), r.width(), r.height(), 0);
diff --git a/src/quick/scenegraph/util/qsgatlastexture_p.h b/src/quick/scenegraph/util/qsgatlastexture_p.h
index 3dee539547..14dc8f7958 100644
--- a/src/quick/scenegraph/util/qsgatlastexture_p.h
+++ b/src/quick/scenegraph/util/qsgatlastexture_p.h
@@ -61,10 +61,16 @@
QT_BEGIN_NAMESPACE
+namespace QSGCompressedAtlasTexture {
+ class Atlas;
+}
+class QSGCompressedTextureFactory;
+
namespace QSGAtlasTexture
{
class Texture;
+class TextureBase;
class Atlas;
class Manager : public QObject
@@ -76,93 +82,121 @@ public:
~Manager();
QSGTexture *create(const QImage &image, bool hasAlphaChannel);
+ QSGTexture *create(const QSGCompressedTextureFactory *factory);
void invalidate();
private:
Atlas *m_atlas;
+ // set of atlases for different compressed formats
+ QHash<unsigned int, QSGCompressedAtlasTexture::Atlas*> m_atlases;
QSize m_atlas_size;
int m_atlas_size_limit;
};
-class Atlas : public QObject
+class AtlasBase : public QObject
{
+ Q_OBJECT
public:
- Atlas(const QSize &size);
- ~Atlas();
+ AtlasBase(const QSize &size);
+ ~AtlasBase();
void invalidate();
int textureId() const;
void bind(QSGTexture::Filtering filtering);
+ void remove(TextureBase *t);
+
+ QSize size() const { return m_size; }
+
+protected:
+ virtual void generateTexture() = 0;
+ virtual void uploadPendingTexture(int i) = 0;
+
+protected:
+ QSGAreaAllocator m_allocator;
+ unsigned int m_texture_id;
+ QSize m_size;
+ QList<TextureBase *> m_pending_uploads;
+
+private:
+ bool m_allocated;
+};
+
+class Atlas : public AtlasBase
+{
+public:
+ Atlas(const QSize &size);
+ ~Atlas();
+
+ void generateTexture() override;
+ void uploadPendingTexture(int i) override;
+
void upload(Texture *texture);
void uploadBgra(Texture *texture);
Texture *create(const QImage &image);
- void remove(Texture *t);
-
- QSize size() const { return m_size; }
uint internalFormat() const { return m_internalFormat; }
uint externalFormat() const { return m_externalFormat; }
private:
- QSGAreaAllocator m_allocator;
- unsigned int m_texture_id;
- QSize m_size;
- QList<Texture *> m_pending_uploads;
-
uint m_internalFormat;
uint m_externalFormat;
int m_atlas_transient_image_threshold;
- uint m_allocated : 1;
uint m_use_bgra_fallback: 1;
-
uint m_debug_overlay : 1;
};
-class Texture : public QSGTexture
+class TextureBase : public QSGTexture
+{
+ Q_OBJECT
+public:
+ TextureBase(AtlasBase *atlas, const QRect &textureRect);
+ ~TextureBase();
+
+ int textureId() const override { return m_atlas->textureId(); }
+ bool isAtlasTexture() const override { return true; }
+
+ QRect atlasSubRect() const { return m_allocated_rect; }
+
+ void bind() override;
+
+protected:
+ QRect m_allocated_rect;
+ AtlasBase *m_atlas;
+};
+
+class Texture : public TextureBase
{
Q_OBJECT
public:
Texture(Atlas *atlas, const QRect &textureRect, const QImage &image);
~Texture();
- int textureId() const override { return m_atlas->textureId(); }
QSize textureSize() const override { return atlasSubRectWithoutPadding().size(); }
void setHasAlphaChannel(bool alpha) { m_has_alpha = alpha; }
bool hasAlphaChannel() const override { return m_has_alpha; }
bool hasMipmaps() const override { return false; }
- bool isAtlasTexture() const override { return true; }
QRectF normalizedTextureSubRect() const override { return m_texture_coords_rect; }
QRect atlasSubRect() const { return m_allocated_rect; }
QRect atlasSubRectWithoutPadding() const { return m_allocated_rect.adjusted(1, 1, -1, -1); }
- bool isTexture() const { return true; }
-
QSGTexture *removedFromAtlas() const override;
void releaseImage() { m_image = QImage(); }
const QImage &image() const { return m_image; }
- void bind() override;
-
private:
- QRect m_allocated_rect;
QRectF m_texture_coords_rect;
-
QImage m_image;
-
- Atlas *m_atlas;
-
mutable QSGPlainTexture *m_nonatlas_texture;
-
- uint m_has_alpha : 1;
+ bool m_has_alpha;
};
}
diff --git a/src/quick/scenegraph/util/qsgdistancefieldutil.cpp b/src/quick/scenegraph/util/qsgdistancefieldutil.cpp
deleted file mode 100644
index 84df7f3393..0000000000
--- a/src/quick/scenegraph/util/qsgdistancefieldutil.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qsgdistancefieldutil_p.h"
-
-#include <private/qsgadaptationlayer_p.h>
-#if QT_CONFIG(opengl)
-# include <QtGui/private/qopenglengineshadersource_p.h>
-#endif
-#include <QtQuick/private/qsgcontext_p.h>
-
-QT_BEGIN_NAMESPACE
-
-static float qt_sg_envFloat(const char *name, float defaultValue)
-{
- if (Q_LIKELY(!qEnvironmentVariableIsSet(name)))
- return defaultValue;
- bool ok = false;
- const float value = qgetenv(name).toFloat(&ok);
- return ok ? value : defaultValue;
-}
-
-static float defaultThresholdFunc(float glyphScale)
-{
- static const float base = qt_sg_envFloat("QT_DF_BASE", 0.5f);
- static const float baseDev = qt_sg_envFloat("QT_DF_BASEDEVIATION", 0.065f);
- static const float devScaleMin = qt_sg_envFloat("QT_DF_SCALEFORMAXDEV", 0.15f);
- static const float devScaleMax = qt_sg_envFloat("QT_DF_SCALEFORNODEV", 0.3f);
- return base - ((qBound(devScaleMin, glyphScale, devScaleMax) - devScaleMin) / (devScaleMax - devScaleMin) * -baseDev + baseDev);
-}
-
-static float defaultAntialiasingSpreadFunc(float glyphScale)
-{
- static const float range = qt_sg_envFloat("QT_DF_RANGE", 0.06f);
- return range / glyphScale;
-}
-
-QSGDistanceFieldGlyphCacheManager::QSGDistanceFieldGlyphCacheManager()
- : m_threshold_func(defaultThresholdFunc)
- , m_antialiasingSpread_func(defaultAntialiasingSpreadFunc)
-{
-}
-
-QSGDistanceFieldGlyphCacheManager::~QSGDistanceFieldGlyphCacheManager()
-{
- qDeleteAll(m_caches);
-}
-
-QSGDistanceFieldGlyphCache *QSGDistanceFieldGlyphCacheManager::cache(const QRawFont &font)
-{
- return m_caches.value(fontKey(font), 0);
-}
-
-void QSGDistanceFieldGlyphCacheManager::insertCache(const QRawFont &font, QSGDistanceFieldGlyphCache *cache)
-{
- m_caches.insert(fontKey(font), cache);
-}
-
-QString QSGDistanceFieldGlyphCacheManager::fontKey(const QRawFont &font)
-{
- QFontEngine *fe = QRawFontPrivate::get(font)->fontEngine;
- if (!fe->faceId().filename.isEmpty()) {
- QByteArray keyName = fe->faceId().filename;
- if (font.style() != QFont::StyleNormal)
- keyName += QByteArray(" I");
- if (font.weight() != QFont::Normal)
- keyName += ' ' + QByteArray::number(font.weight());
- keyName += QByteArray(" DF");
- return QString::fromUtf8(keyName);
- } else {
- return QString::fromLatin1("%1_%2_%3_%4")
- .arg(font.familyName())
- .arg(font.styleName())
- .arg(font.weight())
- .arg(font.style());
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgengine.h b/src/quick/scenegraph/util/qsgengine.h
index 3c8b61852e..514e6e8c2b 100644
--- a/src/quick/scenegraph/util/qsgengine.h
+++ b/src/quick/scenegraph/util/qsgengine.h
@@ -67,7 +67,7 @@ public:
};
Q_DECLARE_FLAGS(CreateTextureOptions, CreateTextureOption)
- explicit QSGEngine(QObject *parent = Q_NULLPTR);
+ explicit QSGEngine(QObject *parent = nullptr);
~QSGEngine();
void initialize(QOpenGLContext *context);
diff --git a/src/quick/scenegraph/util/qsgflatcolormaterial.cpp b/src/quick/scenegraph/util/qsgflatcolormaterial.cpp
index 8ab7669891..a0c71b5340 100644
--- a/src/quick/scenegraph/util/qsgflatcolormaterial.cpp
+++ b/src/quick/scenegraph/util/qsgflatcolormaterial.cpp
@@ -50,13 +50,13 @@ class FlatColorMaterialShader : public QSGMaterialShader
public:
FlatColorMaterialShader();
- virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
- virtual char const *const *attributeNames() const;
+ void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
+ char const *const *attributeNames() const override;
static QSGMaterialType type;
private:
- virtual void initialize();
+ void initialize() override;
#if QT_CONFIG(opengl)
int m_matrix_id;
int m_color_id;
diff --git a/src/quick/scenegraph/util/qsgimagenode.cpp b/src/quick/scenegraph/util/qsgimagenode.cpp
index c03c91d1cb..b154023247 100644
--- a/src/quick/scenegraph/util/qsgimagenode.cpp
+++ b/src/quick/scenegraph/util/qsgimagenode.cpp
@@ -168,7 +168,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QSGImageNode::TextureCoordinatesTransformMode textureCoordinatesTransform() const
+ \fn QSGImageNode::TextureCoordinatesTransformMode QSGImageNode::textureCoordinatesTransform() const
Returns the mode used to generate texture coordinates for this node.
*/
@@ -187,6 +187,15 @@ QT_BEGIN_NAMESPACE
\return \c true if the node takes ownership of the texture; otherwise \c false.
*/
+/*!
+ Updates the geometry \a g with the \a texture, the coordinates
+ in \a rect, and the texture coordinates from \a sourceRect.
+
+ \a g is assumed to be a triangle strip of four vertices of type
+ QSGGeometry::TexturedPoint2D.
+
+ \a texCoordMode is used for normalizing the \a sourceRect.
+ */
void QSGImageNode::rebuildGeometry(QSGGeometry *g,
QSGTexture *texture,
const QRectF &rect,
diff --git a/src/quick/scenegraph/util/qsgsimplematerial.cpp b/src/quick/scenegraph/util/qsgsimplematerial.cpp
index f29c58ad9e..376f7dce5c 100644
--- a/src/quick/scenegraph/util/qsgsimplematerial.cpp
+++ b/src/quick/scenegraph/util/qsgsimplematerial.cpp
@@ -173,17 +173,17 @@
/*!
- \fn char const *const *QSGSimpleMaterialShader::attributeNames() const
+ \fn template <typename State> char const *const *QSGSimpleMaterialShader<State>::attributeNames() const
\internal
*/
/*!
- \fn void QSGSimpleMaterialShader::initialize()
+ \fn template <typename State> void QSGSimpleMaterialShader<State>::initialize()
\internal
*/
/*!
- \fn void QSGSimpleMaterialShader::resolveUniforms()
+ \fn template <typename State> void QSGSimpleMaterialShader<State>::resolveUniforms()
Reimplement this function to resolve the location of named uniforms
in the shader program.
@@ -192,34 +192,34 @@
*/
/*!
- \fn const char *QSGSimpleMaterialShader::uniformMatrixName() const
+ \fn template <typename State> const char *QSGSimpleMaterialShader<State>::uniformMatrixName() const
Returns the name for the transform matrix uniform of this item.
The default value is \c qt_Matrix.
*/
/*!
- \fn const char *QSGSimpleMaterialShader::uniformOpacityName() const
+ \fn template <typename State> const char *QSGSimpleMaterialShader<State>::uniformOpacityName() const
Returns the name for the opacity uniform of this item.
The default value is \c qt_Opacity.
*/
/*!
- \fn void QSGSimpleMaterialShader::updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
+ \fn template <typename State> void QSGSimpleMaterialShader<State>::updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial)
\internal
*/
/*!
- \fn QList<QByteArray> QSGSimpleMaterialShader::attributes() const
+ \fn template <typename State> QList<QByteArray> QSGSimpleMaterialShader<State>::attributes() const
Returns a list of names, declaring the vertex attributes in the
vertex shader.
*/
/*!
- \fn void QSGSimpleMaterialShader::updateState(const State *newState, const State *oldState)
+ \fn template <typename State> void QSGSimpleMaterialShader<State>::updateState(const State *newState, const State *oldState)
Called whenever the state of this shader should be updated from
\a oldState to \a newState, typical for each new set of
diff --git a/src/quick/scenegraph/util/qsgsimplematerial.h b/src/quick/scenegraph/util/qsgsimplematerial.h
index b5b8815b4a..8a81917bd2 100644
--- a/src/quick/scenegraph/util/qsgsimplematerial.h
+++ b/src/quick/scenegraph/util/qsgsimplematerial.h
@@ -138,7 +138,7 @@ template <typename State>
class QSGSimpleMaterial : public QSGMaterial
{
public:
-#ifndef qdoc
+#ifndef Q_CLANG_QDOC
QSGSimpleMaterial(const State &aState, PtrShaderCreateFunc func)
: m_state(aState)
, m_func(func)
diff --git a/src/quick/scenegraph/util/qsgtexture.cpp b/src/quick/scenegraph/util/qsgtexture.cpp
index 4abee3d568..d2599ebd72 100644
--- a/src/quick/scenegraph/util/qsgtexture.cpp
+++ b/src/quick/scenegraph/util/qsgtexture.cpp
@@ -53,7 +53,7 @@
#endif
#include <private/qsgmaterialshader_p.h>
-#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) && !defined(__UCLIBC__)
+#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) && defined(__GLIBC__)
#define CAN_BACKTRACE_EXECINFO
#endif
@@ -256,11 +256,15 @@ static void qt_debug_remove_texture(QSGTexture* texture)
Specifies how the texture should treat texture coordinates.
- \value Repeat Only the factional part of the texture coordiante is
+ \value Repeat Only the fractional part of the texture coordinate is
used, causing values above 1 and below 0 to repeat.
\value ClampToEdge Values above 1 are clamped to 1 and values
below 0 are clamped to 0.
+
+ \value MirroredRepeat When the texture coordinate is even, only the
+ fractional part is used. When odd, the texture coordinate is set to
+ \c{1 - fractional part}. This value has been introduced in Qt 5.10.
*/
/*!
@@ -605,7 +609,9 @@ void QSGTexture::updateBindOptions(bool force)
if (force || d->wrapChanged) {
#ifndef QT_NO_DEBUG
- if (d->horizontalWrap == Repeat || d->verticalWrap == Repeat) {
+ if (d->horizontalWrap == Repeat || d->verticalWrap == Repeat
+ || d->horizontalWrap == MirroredRepeat || d->verticalWrap == MirroredRepeat)
+ {
bool npotSupported = QOpenGLFunctions(QOpenGLContext::currentContext()).hasOpenGLFeature(QOpenGLFunctions::NPOTTextures);
QSize size = textureSize();
bool isNpot = !isPowerOfTwo(size.width()) || !isPowerOfTwo(size.height());
@@ -613,8 +619,18 @@ void QSGTexture::updateBindOptions(bool force)
qWarning("Scene Graph: This system does not support the REPEAT wrap mode for non-power-of-two textures.");
}
#endif
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, d->horizontalWrap == Repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE);
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, d->verticalWrap == Repeat ? GL_REPEAT : GL_CLAMP_TO_EDGE);
+ GLenum wrapS = GL_CLAMP_TO_EDGE;
+ if (d->horizontalWrap == Repeat)
+ wrapS = GL_REPEAT;
+ else if (d->horizontalWrap == MirroredRepeat)
+ wrapS = GL_MIRRORED_REPEAT;
+ GLenum wrapT = GL_CLAMP_TO_EDGE;
+ if (d->verticalWrap == Repeat)
+ wrapT = GL_REPEAT;
+ else if (d->verticalWrap == MirroredRepeat)
+ wrapT = GL_MIRRORED_REPEAT;
+ funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS);
+ funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT);
d->wrapChanged = false;
}
#else
diff --git a/src/quick/scenegraph/util/qsgtexture.h b/src/quick/scenegraph/util/qsgtexture.h
index 035acc02b1..032129434e 100644
--- a/src/quick/scenegraph/util/qsgtexture.h
+++ b/src/quick/scenegraph/util/qsgtexture.h
@@ -58,7 +58,8 @@ public:
enum WrapMode {
Repeat,
- ClampToEdge
+ ClampToEdge,
+ MirroredRepeat
};
enum Filtering {
diff --git a/src/quick/scenegraph/util/qsgtexture_p.h b/src/quick/scenegraph/util/qsgtexture_p.h
index 36f9b802ba..52dc6db2d0 100644
--- a/src/quick/scenegraph/util/qsgtexture_p.h
+++ b/src/quick/scenegraph/util/qsgtexture_p.h
@@ -71,8 +71,8 @@ public:
uint filteringChanged : 1;
uint anisotropyChanged : 1;
- uint horizontalWrap : 1;
- uint verticalWrap : 1;
+ uint horizontalWrap : 2;
+ uint verticalWrap : 2;
uint mipmapMode : 2;
uint filterMode : 2;
uint anisotropyLevel: 3;
diff --git a/src/quick/scenegraph/util/qsgtexturematerial.cpp b/src/quick/scenegraph/util/qsgtexturematerial.cpp
index c536445e82..0f9ee9cfde 100644
--- a/src/quick/scenegraph/util/qsgtexturematerial.cpp
+++ b/src/quick/scenegraph/util/qsgtexturematerial.cpp
@@ -280,7 +280,7 @@ void QSGOpaqueTextureMaterial::setTexture(QSGTexture *texture)
Returns this material's horizontal wrap mode.
- The default horizontal wrap mode is \c QSGTexutre::ClampToEdge.
+ The default horizontal wrap mode is \c QSGTexture::ClampToEdge.
*/
@@ -301,10 +301,20 @@ void QSGOpaqueTextureMaterial::setTexture(QSGTexture *texture)
Returns this material's vertical wrap mode.
- The default vertical wrap mode is \c QSGTexutre::ClampToEdge.
+ The default vertical wrap mode is \c QSGTexture::ClampToEdge.
*/
+/*!
+ \fn void QSGOpaqueTextureMaterial::setAnisotropyLevel(QSGTexture::AnisotropyLevel level)
+
+ Sets this material's anistropy level to \a level.
+*/
+
+/*!
+ \fn QSGTexture::AnisotropyLevel QSGOpaqueTextureMaterial::anisotropyLevel() const
+ Returns this material's anistropy level.
+*/
/*!
\internal
diff --git a/src/quick/scenegraph/util/qsgtexturereader.cpp b/src/quick/scenegraph/util/qsgtexturereader.cpp
new file mode 100644
index 0000000000..eb0caa59e4
--- /dev/null
+++ b/src/quick/scenegraph/util/qsgtexturereader.cpp
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsgtexturereader_p.h"
+
+#include <private/qtquickglobal_p.h>
+
+#if QT_CONFIG(opengl)
+#include <private/qsgpkmhandler_p.h>
+#include <private/qsgktxhandler_p.h>
+#endif
+
+#include <QFileInfo>
+
+QT_BEGIN_NAMESPACE
+
+QSGTextureReader::QSGTextureReader(QIODevice *device, const QString &fileName)
+ : m_device(device), m_fileInfo(fileName)
+{
+}
+
+QQuickTextureFactory *QSGTextureReader::read()
+{
+#if QT_CONFIG(opengl)
+ if (!isTexture())
+ return nullptr;
+ return m_handler->read();
+#else
+ return nullptr;
+#endif
+}
+
+bool QSGTextureReader::isTexture()
+{
+#if QT_CONFIG(opengl)
+ if (!checked) {
+ checked = true;
+ if (!init())
+ return false;
+
+ QByteArray headerBlock = m_device->peek(64);
+ QByteArray suffix = m_fileInfo.suffix().toLower().toLatin1();
+ QByteArray logName = m_fileInfo.fileName().toUtf8();
+
+ // Currently the handlers are hardcoded; later maybe a list of plugins
+ if (QSGPkmHandler::canRead(suffix, headerBlock)) {
+ m_handler = new QSGPkmHandler(m_device, logName);
+ } else if (QSGKtxHandler::canRead(suffix, headerBlock)) {
+ m_handler = new QSGKtxHandler(m_device, logName);
+ }
+ // else if OtherHandler::canRead() ...etc.
+ }
+ return (m_handler != nullptr);
+#else
+ return false;
+#endif
+}
+
+QList<QByteArray> QSGTextureReader::supportedFileFormats()
+{
+ // Hardcoded for now
+ return {QByteArrayLiteral("pkm"), QByteArrayLiteral("ktx")};
+}
+
+bool QSGTextureReader::init()
+{
+ if (!m_device)
+ return false;
+ return m_device->isReadable();
+}
+
+QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgtexturereader_p.h b/src/quick/scenegraph/util/qsgtexturereader_p.h
new file mode 100644
index 0000000000..1d874f840c
--- /dev/null
+++ b/src/quick/scenegraph/util/qsgtexturereader_p.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSGTEXTUREREADER_H
+#define QSGTEXTUREREADER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QString>
+#include <QFileInfo>
+
+QT_BEGIN_NAMESPACE
+
+class QIODevice;
+class QQuickTextureFactory;
+class QSGTextureFileHandler;
+
+class QSGTextureReader
+{
+public:
+ QSGTextureReader(QIODevice *device, const QString &fileName = QString());
+
+ QQuickTextureFactory *read();
+ bool isTexture();
+
+ // TBD access function to params
+ // TBD ask for identified fmt
+
+ static QList<QByteArray> supportedFileFormats();
+
+private:
+ bool init();
+ QIODevice *m_device = nullptr;
+ QFileInfo m_fileInfo;
+ QSGTextureFileHandler *m_handler = nullptr;
+ bool checked = false;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGTEXTUREREADER_H
diff --git a/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp b/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp
index 8c305d7fd4..42c589b14a 100644
--- a/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp
+++ b/src/quick/scenegraph/util/qsgvertexcolormaterial.cpp
@@ -48,13 +48,13 @@ class QSGVertexColorMaterialShader : public QSGMaterialShader
public:
QSGVertexColorMaterialShader();
- virtual void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect);
- virtual char const *const *attributeNames() const;
+ void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
+ char const *const *attributeNames() const override;
static QSGMaterialType type;
private:
- virtual void initialize();
+ void initialize() override;
#if QT_CONFIG(opengl)
int m_matrix_id;
int m_opacity_id;
diff --git a/src/quick/util/qquickanimation.cpp b/src/quick/util/qquickanimation.cpp
index bfac46adb9..76b9b8f343 100644
--- a/src/quick/util/qquickanimation.cpp
+++ b/src/quick/util/qquickanimation.cpp
@@ -2112,7 +2112,7 @@ void QQuickPropertyAnimation::setFrom(const QVariant &f)
return;
d->from = f;
d->fromIsDefined = f.isValid();
- emit fromChanged(f);
+ emit fromChanged();
}
/*!
@@ -2139,7 +2139,7 @@ void QQuickPropertyAnimation::setTo(const QVariant &t)
return;
d->to = t;
d->toIsDefined = t.isValid();
- emit toChanged(t);
+ emit toChanged();
}
/*!
diff --git a/src/quick/util/qquickanimation_p.h b/src/quick/util/qquickanimation_p.h
index e27871dcaa..5edbcc089a 100644
--- a/src/quick/util/qquickanimation_p.h
+++ b/src/quick/util/qquickanimation_p.h
@@ -309,8 +309,8 @@ protected:
QObject *defaultTarget = 0) override;
Q_SIGNALS:
void durationChanged(int);
- void fromChanged(const QVariant &);
- void toChanged(const QVariant &);
+ void fromChanged();
+ void toChanged();
void easingChanged(const QEasingCurve &);
void propertiesChanged(const QString &);
void targetChanged();
@@ -340,8 +340,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickNumberAnimation : public QQuickPropertyAnimat
Q_OBJECT
Q_DECLARE_PRIVATE(QQuickPropertyAnimation)
- Q_PROPERTY(qreal from READ from WRITE setFrom)
- Q_PROPERTY(qreal to READ to WRITE setTo)
+ Q_PROPERTY(qreal from READ from WRITE setFrom NOTIFY fromChanged)
+ Q_PROPERTY(qreal to READ to WRITE setTo NOTIFY toChanged)
public:
QQuickNumberAnimation(QObject *parent=0);
@@ -365,8 +365,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickVector3dAnimation : public QQuickPropertyAnim
Q_OBJECT
Q_DECLARE_PRIVATE(QQuickPropertyAnimation)
- Q_PROPERTY(QVector3D from READ from WRITE setFrom)
- Q_PROPERTY(QVector3D to READ to WRITE setTo)
+ Q_PROPERTY(QVector3D from READ from WRITE setFrom NOTIFY fromChanged)
+ Q_PROPERTY(QVector3D to READ to WRITE setTo NOTIFY toChanged)
public:
QQuickVector3dAnimation(QObject *parent=0);
@@ -385,8 +385,8 @@ class Q_QUICK_PRIVATE_EXPORT QQuickRotationAnimation : public QQuickPropertyAnim
Q_OBJECT
Q_DECLARE_PRIVATE(QQuickRotationAnimation)
- Q_PROPERTY(qreal from READ from WRITE setFrom)
- Q_PROPERTY(qreal to READ to WRITE setTo)
+ Q_PROPERTY(qreal from READ from WRITE setFrom NOTIFY fromChanged)
+ Q_PROPERTY(qreal to READ to WRITE setTo NOTIFY toChanged)
Q_PROPERTY(RotationDirection direction READ direction WRITE setDirection NOTIFY directionChanged)
public:
diff --git a/src/quick/util/qquickanimation_p_p.h b/src/quick/util/qquickanimation_p_p.h
index a7abc5a004..7a1bd8ff13 100644
--- a/src/quick/util/qquickanimation_p_p.h
+++ b/src/quick/util/qquickanimation_p_p.h
@@ -199,7 +199,7 @@ public:
QQuickAnimationGroup *group;
QAbstractAnimationJob* animationInstance;
- static QQmlProperty createProperty(QObject *obj, const QString &str, QObject *infoObj, QString *errorMessage = Q_NULLPTR);
+ static QQmlProperty createProperty(QObject *obj, const QString &str, QObject *infoObj, QString *errorMessage = nullptr);
};
class QQuickPauseAnimationPrivate : public QQuickAbstractAnimationPrivate
diff --git a/src/quick/util/qquickanimatorjob.cpp b/src/quick/util/qquickanimatorjob.cpp
index 50fb7090d1..43c8eb302a 100644
--- a/src/quick/util/qquickanimatorjob.cpp
+++ b/src/quick/util/qquickanimatorjob.cpp
@@ -325,8 +325,10 @@ void QQuickTransformAnimatorJob::preSync()
m_helper = nullptr;
}
- if (!m_target)
+ if (!m_target) {
+ invalidate();
return;
+ }
if (!m_helper) {
m_helper = qquick_transform_animatorjob_helper_store()->acquire(m_target);
@@ -346,27 +348,6 @@ void QQuickTransformAnimatorJob::preSync()
m_helper->sync();
}
-void QQuickTransformAnimatorJob::postSync()
-{
- Q_ASSERT((m_helper != nullptr) == (m_target != nullptr)); // If there is a target, there should also be a helper, ref: preSync
- Q_ASSERT(!m_helper || m_helper->item == m_target); // If there is a helper, it should point to our target
-
- if (!m_target || !m_helper) {
- invalidate();
- return;
- }
-
- QQuickItemPrivate *d = QQuickItemPrivate::get(m_target);
-#if QT_CONFIG(quick_shadereffect)
- if (d->extra.isAllocated()
- && d->extra->layer
- && d->extra->layer->enabled()) {
- d = QQuickItemPrivate::get(d->extra->layer->m_effectSource);
- }
-#endif
- m_helper->node = d->itemNode();
-}
-
void QQuickTransformAnimatorJob::invalidate()
{
if (m_helper)
diff --git a/src/quick/util/qquickanimatorjob_p.h b/src/quick/util/qquickanimatorjob_p.h
index a3ced4c21b..777da2ee6c 100644
--- a/src/quick/util/qquickanimatorjob_p.h
+++ b/src/quick/util/qquickanimatorjob_p.h
@@ -235,7 +235,6 @@ public:
protected:
QQuickTransformAnimatorJob();
- void postSync() override;
void invalidate() override;
Helper *m_helper;
diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp
index 5ba849c57f..5f8d2b94d3 100644
--- a/src/quick/util/qquickglobal.cpp
+++ b/src/quick/util/qquickglobal.cpp
@@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE
class QQuickColorProvider : public QQmlColorProvider
{
public:
- QVariant colorFromString(const QString &s, bool *ok)
+ QVariant colorFromString(const QString &s, bool *ok) override
{
QColor c(s);
if (c.isValid()) {
@@ -73,7 +73,7 @@ public:
return QVariant();
}
- unsigned rgbaFromString(const QString &s, bool *ok)
+ unsigned rgbaFromString(const QString &s, bool *ok) override
{
QColor c(s);
if (c.isValid()) {
@@ -95,36 +95,36 @@ public:
return QString();
}
- QVariant fromRgbF(double r, double g, double b, double a)
+ QVariant fromRgbF(double r, double g, double b, double a) override
{
return QVariant(QColor::fromRgbF(r, g, b, a));
}
- QVariant fromHslF(double h, double s, double l, double a)
+ QVariant fromHslF(double h, double s, double l, double a) override
{
return QVariant(QColor::fromHslF(h, s, l, a));
}
- QVariant fromHsvF(double h, double s, double v, double a)
+ QVariant fromHsvF(double h, double s, double v, double a) override
{
return QVariant(QColor::fromHsvF(h, s, v, a));
}
- QVariant lighter(const QVariant &var, qreal factor)
+ QVariant lighter(const QVariant &var, qreal factor) override
{
QColor color = var.value<QColor>();
color = color.lighter(int(qRound(factor*100.)));
return QVariant::fromValue(color);
}
- QVariant darker(const QVariant &var, qreal factor)
+ QVariant darker(const QVariant &var, qreal factor) override
{
QColor color = var.value<QColor>();
color = color.darker(int(qRound(factor*100.)));
return QVariant::fromValue(color);
}
- QVariant tint(const QVariant &baseVar, const QVariant &tintVar)
+ QVariant tint(const QVariant &baseVar, const QVariant &tintVar) override
{
QColor tintColor = tintVar.value<QColor>();
@@ -302,6 +302,8 @@ public:
QV4::ScopedValue vweight(scope, obj->get((s = v4->newString(QStringLiteral("weight")))));
QV4::ScopedValue vwspac(scope, obj->get((s = v4->newString(QStringLiteral("wordSpacing")))));
QV4::ScopedValue vhint(scope, obj->get((s = v4->newString(QStringLiteral("hintingPreference")))));
+ QV4::ScopedValue vkerning(scope, obj->get((s = v4->newString(QStringLiteral("kerning")))));
+ QV4::ScopedValue vshaping(scope, obj->get((s = v4->newString(QStringLiteral("preferShaping")))));
// pull out the values, set ok to true if at least one valid field is given.
if (vbold->isBoolean()) {
@@ -356,6 +358,17 @@ public:
retn.setHintingPreference(static_cast<QFont::HintingPreference>(vhint->integerValue()));
if (ok) *ok = true;
}
+ if (vkerning->isBoolean()) {
+ retn.setKerning(vkerning->booleanValue());
+ if (ok) *ok = true;
+ }
+ if (vshaping->isBoolean()) {
+ bool enable = vshaping->booleanValue();
+ if (enable)
+ retn.setStyleStrategy(static_cast<QFont::StyleStrategy>(retn.styleStrategy() & ~QFont::PreferNoShaping));
+ else
+ retn.setStyleStrategy(static_cast<QFont::StyleStrategy>(retn.styleStrategy() | QFont::PreferNoShaping));
+ }
return retn;
}
@@ -385,7 +398,7 @@ public:
return QMatrix4x4(matVals);
}
- const QMetaObject *getMetaObjectForMetaType(int type) Q_DECL_OVERRIDE
+ const QMetaObject *getMetaObjectForMetaType(int type) override
{
switch (type) {
case QMetaType::QColor:
@@ -409,7 +422,7 @@ public:
return 0;
}
- bool init(int type, QVariant& dst) Q_DECL_OVERRIDE
+ bool init(int type, QVariant& dst) override
{
switch (type) {
case QMetaType::QColor:
@@ -439,7 +452,7 @@ public:
return false;
}
- bool create(int type, int argc, const void *argv[], QVariant *v) Q_DECL_OVERRIDE
+ bool create(int type, int argc, const void *argv[], QVariant *v) override
{
switch (type) {
case QMetaType::QFont: // must specify via js-object.
@@ -506,7 +519,7 @@ public:
return true;
}
- bool createFromString(int type, const QString &s, void *data, size_t dataSize) Q_DECL_OVERRIDE
+ bool createFromString(int type, const QString &s, void *data, size_t dataSize) override
{
bool ok = false;
@@ -529,7 +542,7 @@ public:
return false;
}
- bool createStringFrom(int type, const void *data, QString *s) Q_DECL_OVERRIDE
+ bool createStringFrom(int type, const void *data, QString *s) override
{
if (type == QMetaType::QColor) {
const QColor *color = reinterpret_cast<const QColor *>(data);
@@ -540,7 +553,7 @@ public:
return false;
}
- bool variantFromString(const QString &s, QVariant *v) Q_DECL_OVERRIDE
+ bool variantFromString(const QString &s, QVariant *v) override
{
QColor c(s);
if (c.isValid()) {
@@ -583,7 +596,7 @@ public:
return false;
}
- bool variantFromString(int type, const QString &s, QVariant *v) Q_DECL_OVERRIDE
+ bool variantFromString(int type, const QString &s, QVariant *v) override
{
bool ok = false;
@@ -626,7 +639,7 @@ public:
return false;
}
- bool variantFromJsObject(int type, QQmlV4Handle object, QV4::ExecutionEngine *v4, QVariant *v) Q_DECL_OVERRIDE
+ bool variantFromJsObject(int type, QQmlV4Handle object, QV4::ExecutionEngine *v4, QVariant *v) override
{
QV4::Scope scope(v4);
#ifndef QT_NO_DEBUG
@@ -652,7 +665,7 @@ public:
return (*(reinterpret_cast<const T *>(lhs)) == rhs.value<T>());
}
- bool equal(int type, const void *lhs, const QVariant &rhs) Q_DECL_OVERRIDE
+ bool equal(int type, const void *lhs, const QVariant &rhs) override
{
switch (type) {
case QMetaType::QColor:
@@ -685,7 +698,7 @@ public:
return true;
}
- bool store(int type, const void *src, void *dst, size_t dstSize) Q_DECL_OVERRIDE
+ bool store(int type, const void *src, void *dst, size_t dstSize) override
{
Q_UNUSED(dstSize);
switch (type) {
@@ -715,7 +728,7 @@ public:
return true;
}
- bool read(const QVariant &src, void *dst, int dstType) Q_DECL_OVERRIDE
+ bool read(const QVariant &src, void *dst, int dstType) override
{
switch (dstType) {
case QMetaType::QColor:
@@ -749,7 +762,7 @@ public:
return false;
}
- bool write(int type, const void *src, QVariant& dst) Q_DECL_OVERRIDE
+ bool write(int type, const void *src, QVariant& dst) override
{
switch (type) {
case QMetaType::QColor:
@@ -778,13 +791,13 @@ public:
class QQuickGuiProvider : public QQmlGuiProvider
{
public:
- QQuickApplication *application(QObject *parent)
+ QQuickApplication *application(QObject *parent) override
{
return new QQuickApplication(parent);
}
#if QT_CONFIG(im)
- QInputMethod *inputMethod()
+ QInputMethod *inputMethod() override
{
QInputMethod *im = qGuiApp->inputMethod();
QQmlEngine::setObjectOwnership(im, QQmlEngine::CppOwnership);
@@ -792,20 +805,20 @@ public:
}
#endif
- QStyleHints *styleHints()
+ QStyleHints *styleHints() override
{
QStyleHints *sh = qGuiApp->styleHints();
QQmlEngine::setObjectOwnership(sh, QQmlEngine::CppOwnership);
return sh;
}
- QStringList fontFamilies()
+ QStringList fontFamilies() override
{
QFontDatabase database;
return database.families();
}
- bool openUrlExternally(QUrl &url)
+ bool openUrlExternally(QUrl &url) override
{
#ifndef QT_NO_DESKTOPSERVICES
return QDesktopServices::openUrl(url);
@@ -814,6 +827,11 @@ public:
return false;
#endif
}
+
+ QString pluginName() const override
+ {
+ return QGuiApplication::platformName();
+ }
};
diff --git a/src/quick/util/qquickimageprovider.cpp b/src/quick/util/qquickimageprovider.cpp
index 4eab5608b1..a1513336a5 100644
--- a/src/quick/util/qquickimageprovider.cpp
+++ b/src/quick/util/qquickimageprovider.cpp
@@ -183,7 +183,12 @@ QString QQuickImageResponse::errorString() const
It may be reimplemented to cancel a request in the provider side, however, it is not mandatory.
- A cancelled QQuickImageResponse still needs to emit finished().
+ A cancelled QQuickImageResponse still needs to emit finished() so that the
+ engine may clean up the QQuickImageResponse.
+
+ \note finished() should not be emitted until the response is complete,
+ regardless of whether or not cancel() was called. If it is called prematurely,
+ the engine may destroy the response while it is still active, leading to a crash.
*/
void QQuickImageResponse::cancel()
{
@@ -192,7 +197,12 @@ void QQuickImageResponse::cancel()
/*!
\fn void QQuickImageResponse::finished()
- Signals that the job execution has finished (be it successfully, because an error happened or because it was cancelled).
+ Signals that the job execution has finished (be it successfully, because an
+ error happened or because it was cancelled).
+
+ \note Emission of this signal must be the final action the response performs:
+ once the signal is received, the response will subsequently be destroyed by
+ the engine.
*/
/*!
@@ -673,13 +683,15 @@ QSize QQuickImageProviderWithOptions::loadSize(const QSize &originalSize, const
return res;
const bool preserveAspectCropOrFit = options.preserveAspectRatioCrop() || options.preserveAspectRatioFit();
- const bool force_scale = (format == "svg" || format == "svgz");
+
+ if (!preserveAspectCropOrFit && (format == "svg" || format == "svgz"))
+ return requestedSize;
qreal ratio = 0.0;
- if (requestedSize.width() && (preserveAspectCropOrFit || force_scale || requestedSize.width() < originalSize.width())) {
+ if (requestedSize.width() && (preserveAspectCropOrFit || requestedSize.width() < originalSize.width())) {
ratio = qreal(requestedSize.width()) / originalSize.width();
}
- if (requestedSize.height() && (preserveAspectCropOrFit || force_scale || requestedSize.height() < originalSize.height())) {
+ if (requestedSize.height() && (preserveAspectCropOrFit || requestedSize.height() < originalSize.height())) {
qreal hr = qreal(requestedSize.height()) / originalSize.height();
if (ratio == 0.0)
ratio = hr;
diff --git a/src/quick/util/qquickimageprovider.h b/src/quick/util/qquickimageprovider.h
index 681de4b6c2..4451105782 100644
--- a/src/quick/util/qquickimageprovider.h
+++ b/src/quick/util/qquickimageprovider.h
@@ -56,6 +56,7 @@ class QQuickWindow;
class Q_QUICK_EXPORT QQuickTextureFactory : public QObject
{
+ Q_OBJECT
public:
QQuickTextureFactory();
virtual ~QQuickTextureFactory();
diff --git a/src/quick/util/qquickpath.cpp b/src/quick/util/qquickpath.cpp
index 8abb9377a6..1ae9b78669 100644
--- a/src/quick/util/qquickpath.cpp
+++ b/src/quick/util/qquickpath.cpp
@@ -60,7 +60,8 @@ QT_BEGIN_NAMESPACE
This type is the base for all path types. It cannot
be instantiated.
- \sa Path, PathAttribute, PathPercent, PathLine, PathQuad, PathCubic, PathArc, PathCurve, PathSvg
+ \sa Path, PathAttribute, PathPercent, PathLine, PathQuad, PathCubic, PathArc,
+ PathAngleArc, PathCurve, PathSvg
*/
/*!
@@ -68,10 +69,10 @@ QT_BEGIN_NAMESPACE
\instantiates QQuickPath
\inqmlmodule QtQuick
\ingroup qtquick-animation-paths
- \brief Defines a path for use by \l PathView
+ \brief Defines a path for use by \l PathView and \l Shape
A Path is composed of one or more path segments - PathLine, PathQuad,
- PathCubic, PathArc, PathCurve, PathSvg.
+ PathCubic, PathArc, PathAngleArc, PathCurve, PathSvg.
The spacing of the items along the Path can be adjusted via a
PathPercent object.
@@ -79,13 +80,94 @@ QT_BEGIN_NAMESPACE
PathAttribute allows named attributes with values to be defined
along the path.
- \sa PathView, PathAttribute, PathPercent, PathLine, PathQuad, PathCubic, PathArc, PathCurve, PathSvg
+ Path and the other types for specifying path elements are shared between
+ \l PathView and \l Shape. The following table provides an overview of the
+ applicability of the various path elements:
+
+ \table
+ \header
+ \li Element
+ \li PathView
+ \li Shape
+ \li Shape, GL_NV_path_rendering
+ \li Shape, software
+ \row
+ \li PathMove
+ \li N/A
+ \li Yes
+ \li Yes
+ \li Yes
+ \row
+ \li PathLine
+ \li Yes
+ \li Yes
+ \li Yes
+ \li Yes
+ \row
+ \li PathQuad
+ \li Yes
+ \li Yes
+ \li Yes
+ \li Yes
+ \row
+ \li PathCubic
+ \li Yes
+ \li Yes
+ \li Yes
+ \li Yes
+ \row
+ \li PathArc
+ \li Yes
+ \li Yes
+ \li Yes
+ \li Yes
+ \row
+ \li PathAngleArc
+ \li Yes
+ \li Yes
+ \li Yes
+ \li Yes
+ \row
+ \li PathSvg
+ \li Yes
+ \li Yes
+ \li Yes
+ \li Yes
+ \row
+ \li PathAttribute
+ \li Yes
+ \li N/A
+ \li N/A
+ \li N/A
+ \row
+ \li PathPercent
+ \li Yes
+ \li N/A
+ \li N/A
+ \li N/A
+ \row
+ \li PathCurve
+ \li Yes
+ \li No
+ \li No
+ \li No
+ \endtable
+
+ \note Path is a non-visual type; it does not display anything on its own.
+ To draw a path, use \l Shape.
+
+ \sa PathView, Shape, PathAttribute, PathPercent, PathLine, PathMove, PathQuad, PathCubic, PathArc, PathAngleArc, PathCurve, PathSvg
*/
QQuickPath::QQuickPath(QObject *parent)
: QObject(*(new QQuickPathPrivate), parent)
{
}
+QQuickPath::QQuickPath(QQuickPathPrivate &dd, QObject *parent)
+ : QObject(dd, parent)
+{
+}
+
QQuickPath::~QQuickPath()
{
}
@@ -161,6 +243,7 @@ bool QQuickPath::isClosed() const
\li \l PathQuad - a quadratic Bezier curve to a given position with a control point.
\li \l PathCubic - a cubic Bezier curve to a given position with two control points.
\li \l PathArc - an arc to a given position with a radius.
+ \li \l PathAngleArc - an arc specified by center point, radii, and angles.
\li \l PathSvg - a path specified as an SVG path data string.
\li \l PathCurve - a point on a Catmull-Rom curve.
\li \l PathAttribute - an attribute at a given position in the path.
@@ -314,7 +397,12 @@ void QQuickPath::processPath()
d->_pointCache.clear();
d->prevBez.isValid = false;
- d->_path = createPath(QPointF(), QPointF(), d->_attributes, d->pathLength, d->_attributePoints, &d->closed);
+ if (d->isShapePath) {
+ // This path is a ShapePath, so avoid extra overhead
+ d->_path = createShapePath(QPointF(), QPointF(), d->pathLength, &d->closed);
+ } else {
+ d->_path = createPath(QPointF(), QPointF(), d->_attributes, d->pathLength, d->_attributePoints, &d->closed);
+ }
emit changed();
}
@@ -410,6 +498,42 @@ QPainterPath QQuickPath::createPath(const QPointF &startPoint, const QPointF &en
return path;
}
+QPainterPath QQuickPath::createShapePath(const QPointF &startPoint, const QPointF &endPoint, qreal &pathLength, bool *closed)
+{
+ Q_D(QQuickPath);
+
+ if (!d->componentComplete)
+ return QPainterPath();
+
+ QPainterPath path;
+
+ qreal startX = d->startX.isValid() ? d->startX.value : startPoint.x();
+ qreal startY = d->startY.isValid() ? d->startY.value : startPoint.y();
+ path.moveTo(startX, startY);
+
+ int index = 0;
+ for (QQuickCurve *curve : qAsConst(d->_pathCurves)) {
+ QQuickPathData data;
+ data.index = index;
+ data.endPoint = endPoint;
+ data.curves = d->_pathCurves;
+ curve->addToPath(path, data);
+ ++index;
+ }
+
+ if (closed) {
+ QPointF end = path.currentPosition();
+ *closed = startX == end.x() && startY == end.y();
+ }
+
+ // Note: Length of paths inside ShapePath is not used, so currently
+ // length is always 0. This avoids potentially heavy path.length()
+ //pathLength = path.length();
+ pathLength = 0;
+
+ return path;
+}
+
void QQuickPath::classBegin()
{
Q_D(QQuickPath);
@@ -1003,7 +1127,7 @@ void QQuickPathAttribute::setValue(qreal value)
}
\endqml
- \sa Path, PathQuad, PathCubic, PathArc, PathCurve, PathSvg
+ \sa Path, PathQuad, PathCubic, PathArc, PathAngleArc, PathCurve, PathSvg, PathMove
*/
/*!
@@ -1046,6 +1170,64 @@ void QQuickPathLine::addToPath(QPainterPath &path, const QQuickPathData &data)
/****************************************************************************/
/*!
+ \qmltype PathMove
+ \instantiates QQuickPathMove
+ \inqmlmodule QtQuick
+ \ingroup qtquick-animation-paths
+ \brief Moves the Path's position
+
+ The example below creates a path consisting of two horizontal lines with
+ some empty space between them. All three segments have a width of 100:
+
+ \qml
+ Path {
+ startX: 0; startY: 100
+ PathLine { relativeX: 100; y: 100 }
+ PathMove { relativeX: 100; y: 100 }
+ PathLine { relativeX: 100; y: 100 }
+ }
+ \endqml
+
+ \note PathMove should not be used in a Path associated with a PathView. Use
+ PathLine instead. For ShapePath however it is important to distinguish
+ between the operations of drawing a straight line and moving the path
+ position without drawing anything.
+
+ \sa Path, PathQuad, PathCubic, PathArc, PathAngleArc, PathCurve, PathSvg, PathLine
+*/
+
+/*!
+ \qmlproperty real QtQuick::PathMove::x
+ \qmlproperty real QtQuick::PathMove::y
+
+ Defines the position to move to.
+
+ \sa relativeX, relativeY
+*/
+
+/*!
+ \qmlproperty real QtQuick::PathMove::relativeX
+ \qmlproperty real QtQuick::PathMove::relativeY
+
+ Defines the position to move to relative to its start.
+
+ If both a relative and absolute end position are specified for a single axis, the relative
+ position will be used.
+
+ Relative and absolute positions can be mixed, for example it is valid to set a relative x
+ and an absolute y.
+
+ \sa x, y
+*/
+
+void QQuickPathMove::addToPath(QPainterPath &path, const QQuickPathData &data)
+{
+ path.moveTo(positionForCurve(data, path.currentPosition()));
+}
+
+/****************************************************************************/
+
+/*!
\qmltype PathQuad
\instantiates QQuickPathQuad
\inqmlmodule QtQuick
@@ -1065,7 +1247,7 @@ void QQuickPathLine::addToPath(QPainterPath &path, const QQuickPathData &data)
\endqml
\endtable
- \sa Path, PathCubic, PathLine, PathArc, PathCurve, PathSvg
+ \sa Path, PathCubic, PathLine, PathArc, PathAngleArc, PathCurve, PathSvg
*/
/*!
@@ -1221,7 +1403,7 @@ void QQuickPathQuad::addToPath(QPainterPath &path, const QQuickPathData &data)
\endqml
\endtable
- \sa Path, PathQuad, PathLine, PathArc, PathCurve, PathSvg
+ \sa Path, PathQuad, PathLine, PathArc, PathAngleArc, PathCurve, PathSvg
*/
/*!
@@ -1587,7 +1769,7 @@ void QQuickPathCatmullRomCurve::addToPath(QPainterPath &path, const QQuickPathDa
Note that a single PathArc cannot be used to specify a circle. Instead, you can
use two PathArc elements, each specifying half of the circle.
- \sa Path, PathLine, PathQuad, PathCubic, PathCurve, PathSvg
+ \sa Path, PathLine, PathQuad, PathCubic, PathAngleArc, PathCurve, PathSvg
*/
/*!
@@ -1641,6 +1823,7 @@ void QQuickPathArc::setRadiusX(qreal radius)
_radiusX = radius;
emit radiusXChanged();
+ emit changed();
}
qreal QQuickPathArc::radiusY() const
@@ -1655,6 +1838,7 @@ void QQuickPathArc::setRadiusY(qreal radius)
_radiusY = radius;
emit radiusYChanged();
+ emit changed();
}
/*!
@@ -1688,6 +1872,7 @@ void QQuickPathArc::setUseLargeArc(bool largeArc)
_useLargeArc = largeArc;
emit useLargeArcChanged();
+ emit changed();
}
/*!
@@ -1719,6 +1904,43 @@ void QQuickPathArc::setDirection(ArcDirection direction)
_direction = direction;
emit directionChanged();
+ emit changed();
+}
+
+/*!
+ \qmlproperty real QtQuick::PathArc::xAxisRotation
+
+ Defines the rotation of the arc, in degrees. The default value is 0.
+
+ An arc is a section of circles or ellipses. Given the radius and the start
+ and end points, there are two ellipses that connect the points. This
+ property defines the rotation of the X axis of these ellipses.
+
+ \note The value is only useful when the x and y radius differ, meaning the
+ arc is a section of ellipses.
+
+ The following QML demonstrates how different radius values can be used to change
+ the shape of the arc:
+ \table
+ \row
+ \li \image declarative-arcrotation.png
+ \li \snippet qml/path/arcrotation.qml 0
+ \endtable
+*/
+
+qreal QQuickPathArc::xAxisRotation() const
+{
+ return _xAxisRotation;
+}
+
+void QQuickPathArc::setXAxisRotation(qreal rotation)
+{
+ if (_xAxisRotation == rotation)
+ return;
+
+ _xAxisRotation = rotation;
+ emit xAxisRotationChanged();
+ emit changed();
}
void QQuickPathArc::addToPath(QPainterPath &path, const QQuickPathData &data)
@@ -1728,7 +1950,7 @@ void QQuickPathArc::addToPath(QPainterPath &path, const QQuickPathData &data)
QQuickSvgParser::pathArc(path,
_radiusX,
_radiusY,
- 0, //xAxisRotation
+ _xAxisRotation,
_useLargeArc,
_direction == Clockwise ? 1 : 0,
endPoint.x(),
@@ -1739,6 +1961,179 @@ void QQuickPathArc::addToPath(QPainterPath &path, const QQuickPathData &data)
/****************************************************************************/
/*!
+ \qmltype PathAngleArc
+ \instantiates QQuickPathAngleArc
+ \inqmlmodule QtQuick
+ \ingroup qtquick-animation-paths
+ \brief Defines an arc with the given radii and center
+
+ PathAngleArc provides a simple way of specifying an arc. While PathArc is designed
+ to work as part of a larger path (specifying start and end), PathAngleArc is designed
+ to make a path where the arc is primary (such as a circular progress indicator) more intuitive.
+
+ \sa Path, PathLine, PathQuad, PathCubic, PathCurve, PathSvg, PathArc
+*/
+
+/*!
+ \qmlproperty real QtQuick::PathAngleArc::centerX
+ \qmlproperty real QtQuick::PathAngleArc::centerY
+
+ Defines the center of the arc.
+*/
+
+qreal QQuickPathAngleArc::centerX() const
+{
+ return _centerX;
+}
+
+void QQuickPathAngleArc::setCenterX(qreal centerX)
+{
+ if (_centerX == centerX)
+ return;
+
+ _centerX = centerX;
+ emit centerXChanged();
+ emit changed();
+}
+
+qreal QQuickPathAngleArc::centerY() const
+{
+ return _centerY;
+}
+
+void QQuickPathAngleArc::setCenterY(qreal centerY)
+{
+ if (_centerY == centerY)
+ return;
+
+ _centerY = centerY;
+ emit centerXChanged();
+ emit changed();
+}
+
+/*!
+ \qmlproperty real QtQuick::PathAngleArc::radiusX
+ \qmlproperty real QtQuick::PathAngleArc::radiusY
+
+ Defines the radii of the ellipse of which the arc is part.
+*/
+
+qreal QQuickPathAngleArc::radiusX() const
+{
+ return _radiusX;
+}
+
+void QQuickPathAngleArc::setRadiusX(qreal radius)
+{
+ if (_radiusX == radius)
+ return;
+
+ _radiusX = radius;
+ emit radiusXChanged();
+ emit changed();
+}
+
+qreal QQuickPathAngleArc::radiusY() const
+{
+ return _radiusY;
+}
+
+void QQuickPathAngleArc::setRadiusY(qreal radius)
+{
+ if (_radiusY == radius)
+ return;
+
+ _radiusY = radius;
+ emit radiusYChanged();
+ emit changed();
+}
+
+/*!
+ \qmlproperty real QtQuick::PathAngleArc::startAngle
+
+ Defines the start angle of the arc.
+
+ The start angle is reported clockwise, with zero degrees at the 3 o'clock position.
+*/
+
+qreal QQuickPathAngleArc::startAngle() const
+{
+ return _startAngle;
+}
+
+void QQuickPathAngleArc::setStartAngle(qreal angle)
+{
+ if (_startAngle == angle)
+ return;
+
+ _startAngle = angle;
+ emit startAngleChanged();
+ emit changed();
+}
+
+/*!
+ \qmlproperty real QtQuick::PathAngleArc::sweepAngle
+
+ Defines the sweep angle of the arc.
+
+ The arc will begin at startAngle and continue sweepAngle degrees, with a value of 360
+ resulting in a full circle. Positive numbers are clockwise and negative numbers are counterclockwise.
+*/
+
+qreal QQuickPathAngleArc::sweepAngle() const
+{
+ return _sweepAngle;
+}
+
+void QQuickPathAngleArc::setSweepAngle(qreal angle)
+{
+ if (_sweepAngle == angle)
+ return;
+
+ _sweepAngle = angle;
+ emit sweepAngleChanged();
+ emit changed();
+}
+
+/*!
+ \qmlproperty bool QtQuick::PathAngleArc::moveToStart
+
+ Whether this element should be disconnected from the previous Path element (or startX/Y).
+
+ The default value is true. If set to false, the previous element's end-point
+ (or startX/Y if PathAngleArc is the first element) will be connected to the arc's
+ start-point with a straight line.
+*/
+
+bool QQuickPathAngleArc::moveToStart() const
+{
+ return _moveToStart;
+}
+
+void QQuickPathAngleArc::setMoveToStart(bool move)
+{
+ if (_moveToStart == move)
+ return;
+
+ _moveToStart = move;
+ emit moveToStartChanged();
+ emit changed();
+}
+
+void QQuickPathAngleArc::addToPath(QPainterPath &path, const QQuickPathData &)
+{
+ qreal x = _centerX - _radiusX;
+ qreal y = _centerY - _radiusY;
+ qreal width = _radiusX * 2;
+ qreal height = _radiusY * 2;
+ if (_moveToStart)
+ path.arcMoveTo(x, y, width, height, -_startAngle);
+ path.arcTo(x, y, width, height, -_startAngle, -_sweepAngle);
+}
+
+/****************************************************************************/
+
+/*!
\qmltype PathSvg
\instantiates QQuickPathSvg
\inqmlmodule QtQuick
@@ -1758,7 +2153,12 @@ void QQuickPathArc::addToPath(QPainterPath &path, const QQuickPathData &data)
\endqml
\endtable
- \sa Path, PathLine, PathQuad, PathCubic, PathArc, PathCurve
+ \note Mixing PathSvg with other type of elements is not always supported.
+ For example, when \l Shape is backed by \c{GL_NV_path_rendering}, a
+ ShapePath can contain one or more PathSvg elements, or one or more other
+ type of elements, but not both.
+
+ \sa Path, PathLine, PathQuad, PathCubic, PathArc, PathAngleArc, PathCurve
*/
/*!
@@ -1782,6 +2182,7 @@ void QQuickPathSvg::setPath(const QString &path)
_path = path;
emit pathChanged();
+ emit changed();
}
void QQuickPathSvg::addToPath(QPainterPath &path, const QQuickPathData &)
diff --git a/src/quick/util/qquickpath_p.h b/src/quick/util/qquickpath_p.h
index c0a96cad4f..a49403fd0e 100644
--- a/src/quick/util/qquickpath_p.h
+++ b/src/quick/util/qquickpath_p.h
@@ -159,6 +159,15 @@ public:
void addToPath(QPainterPath &path, const QQuickPathData &) override;
};
+class Q_QUICK_PRIVATE_EXPORT QQuickPathMove : public QQuickCurve
+{
+ Q_OBJECT
+public:
+ QQuickPathMove(QObject *parent=0) : QQuickCurve(parent) {}
+
+ void addToPath(QPainterPath &path, const QQuickPathData &) override;
+};
+
class Q_QUICK_PRIVATE_EXPORT QQuickPathQuad : public QQuickCurve
{
Q_OBJECT
@@ -281,10 +290,11 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPathArc : public QQuickCurve
Q_PROPERTY(qreal radiusY READ radiusY WRITE setRadiusY NOTIFY radiusYChanged)
Q_PROPERTY(bool useLargeArc READ useLargeArc WRITE setUseLargeArc NOTIFY useLargeArcChanged)
Q_PROPERTY(ArcDirection direction READ direction WRITE setDirection NOTIFY directionChanged)
+ Q_PROPERTY(qreal xAxisRotation READ xAxisRotation WRITE setXAxisRotation NOTIFY xAxisRotationChanged REVISION 2)
public:
QQuickPathArc(QObject *parent=0)
- : QQuickCurve(parent), _radiusX(0), _radiusY(0), _useLargeArc(false), _direction(Clockwise) {}
+ : QQuickCurve(parent), _radiusX(0), _radiusY(0), _useLargeArc(false), _direction(Clockwise), _xAxisRotation(0) {}
enum ArcDirection { Clockwise, Counterclockwise };
Q_ENUM(ArcDirection)
@@ -301,6 +311,9 @@ public:
ArcDirection direction() const;
void setDirection(ArcDirection direction);
+ qreal xAxisRotation() const;
+ void setXAxisRotation(qreal rotation);
+
void addToPath(QPainterPath &path, const QQuickPathData &) override;
Q_SIGNALS:
@@ -308,12 +321,71 @@ Q_SIGNALS:
void radiusYChanged();
void useLargeArcChanged();
void directionChanged();
+ Q_REVISION(2) void xAxisRotationChanged();
private:
qreal _radiusX;
qreal _radiusY;
bool _useLargeArc;
ArcDirection _direction;
+ qreal _xAxisRotation;
+};
+
+class Q_QUICK_PRIVATE_EXPORT QQuickPathAngleArc : public QQuickCurve
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal centerX READ centerX WRITE setCenterX NOTIFY centerXChanged)
+ Q_PROPERTY(qreal centerY READ centerY WRITE setCenterY NOTIFY centerYChanged)
+ Q_PROPERTY(qreal radiusX READ radiusX WRITE setRadiusX NOTIFY radiusXChanged)
+ Q_PROPERTY(qreal radiusY READ radiusY WRITE setRadiusY NOTIFY radiusYChanged)
+ Q_PROPERTY(qreal startAngle READ startAngle WRITE setStartAngle NOTIFY startAngleChanged)
+ Q_PROPERTY(qreal sweepAngle READ sweepAngle WRITE setSweepAngle NOTIFY sweepAngleChanged)
+ Q_PROPERTY(bool moveToStart READ moveToStart WRITE setMoveToStart NOTIFY moveToStartChanged)
+
+public:
+ QQuickPathAngleArc(QObject *parent=0)
+ : QQuickCurve(parent), _centerX(0), _centerY(0), _radiusX(0), _radiusY(0), _startAngle(0), _sweepAngle(0), _moveToStart(true) {}
+
+ qreal centerX() const;
+ void setCenterX(qreal);
+
+ qreal centerY() const;
+ void setCenterY(qreal);
+
+ qreal radiusX() const;
+ void setRadiusX(qreal);
+
+ qreal radiusY() const;
+ void setRadiusY(qreal);
+
+ qreal startAngle() const;
+ void setStartAngle(qreal);
+
+ qreal sweepAngle() const;
+ void setSweepAngle(qreal);
+
+ bool moveToStart() const;
+ void setMoveToStart(bool);
+
+ void addToPath(QPainterPath &path, const QQuickPathData &) override;
+
+Q_SIGNALS:
+ void centerXChanged();
+ void centerYChanged();
+ void radiusXChanged();
+ void radiusYChanged();
+ void startAngleChanged();
+ void sweepAngleChanged();
+ void moveToStartChanged();
+
+private:
+ qreal _centerX;
+ qreal _centerY;
+ qreal _radiusX;
+ qreal _radiusY;
+ qreal _startAngle;
+ qreal _sweepAngle;
+ bool _moveToStart;
};
class Q_QUICK_PRIVATE_EXPORT QQuickPathSvg : public QQuickCurve
@@ -404,6 +476,7 @@ Q_SIGNALS:
void startYChanged();
protected:
+ QQuickPath(QQuickPathPrivate &dd, QObject *parent = nullptr);
void componentComplete() override;
void classBegin() override;
void disconnectPathElements();
@@ -449,6 +522,7 @@ private:
public:
QPainterPath createPath(const QPointF &startPoint, const QPointF &endPoint, const QStringList &attributes, qreal &pathLength, QList<AttributePoint> &attributePoints, bool *closed = 0);
+ QPainterPath createShapePath(const QPointF &startPoint, const QPointF &endPoint, qreal &pathLength, bool *closed = 0);
static QPointF sequentialPointAt(const QPainterPath &path, const qreal &pathLength, const QList<AttributePoint> &attributePoints, QQuickCachedBezier &prevBez, qreal p, qreal *angle = 0);
};
@@ -458,10 +532,12 @@ QML_DECLARE_TYPE(QQuickPathElement)
QML_DECLARE_TYPE(QQuickPathAttribute)
QML_DECLARE_TYPE(QQuickCurve)
QML_DECLARE_TYPE(QQuickPathLine)
+QML_DECLARE_TYPE(QQuickPathMove)
QML_DECLARE_TYPE(QQuickPathQuad)
QML_DECLARE_TYPE(QQuickPathCubic)
QML_DECLARE_TYPE(QQuickPathCatmullRomCurve)
QML_DECLARE_TYPE(QQuickPathArc)
+QML_DECLARE_TYPE(QQuickPathAngleArc)
QML_DECLARE_TYPE(QQuickPathSvg)
QML_DECLARE_TYPE(QQuickPathPercent)
QML_DECLARE_TYPE(QQuickPath)
diff --git a/src/quick/util/qquickpath_p_p.h b/src/quick/util/qquickpath_p_p.h
index 1dc3c1c47a..f5c9664223 100644
--- a/src/quick/util/qquickpath_p_p.h
+++ b/src/quick/util/qquickpath_p_p.h
@@ -64,7 +64,7 @@ QT_REQUIRE_CONFIG(quick_path);
QT_BEGIN_NAMESPACE
-class QQuickPathPrivate : public QObjectPrivate
+class Q_QUICK_PRIVATE_EXPORT QQuickPathPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QQuickPath)
@@ -72,7 +72,7 @@ public:
static QQuickPathPrivate* get(QQuickPath *path) { return path->d_func(); }
static const QQuickPathPrivate* get(const QQuickPath *path) { return path->d_func(); }
- QQuickPathPrivate() : pathLength(0), closed(false), componentComplete(true) { }
+ QQuickPathPrivate() : pathLength(0), closed(false), componentComplete(true), isShapePath(false) { }
QPainterPath _path;
QList<QQuickPathElement*> _pathElements;
@@ -86,6 +86,7 @@ public:
qreal pathLength;
bool closed;
bool componentComplete;
+ bool isShapePath;
};
QT_END_NAMESPACE
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp
index 882482ad31..7097bcc156 100644
--- a/src/quick/util/qquickpixmapcache.cpp
+++ b/src/quick/util/qquickpixmapcache.cpp
@@ -49,6 +49,7 @@
#include <qpa/qplatformintegration.h>
#include <QtQuick/private/qsgtexture_p.h>
+#include <QtQuick/private/qsgtexturereader_p.h>
#include <QQuickWindow>
#include <QCoreApplication>
@@ -162,7 +163,7 @@ Q_SIGNALS:
void downloadProgress(qint64, qint64);
protected:
- bool event(QEvent *event);
+ bool event(QEvent *event) override;
private:
Q_DISABLE_COPY(QQuickPixmapReply)
@@ -200,7 +201,7 @@ public:
static QQuickPixmapReader *existingInstance(QQmlEngine *engine);
protected:
- void run();
+ void run() override;
private:
friend class QQuickPixmapReaderThreadObject;
@@ -413,6 +414,34 @@ static bool readImage(const QUrl& url, QIODevice *dev, QImage *image, QString *e
}
}
+static QStringList fromLatin1List(const QList<QByteArray> &list)
+{
+ QStringList res;
+ res.reserve(list.size());
+ for (const QByteArray &item : list)
+ res.append(QString::fromLatin1(item));
+ return res;
+}
+
+static QString existingImageFileForPath(const QString &localFile)
+{
+ // Do nothing if given filepath exists or already has a suffix
+ QFileInfo fi(localFile);
+ if (!fi.suffix().isEmpty() || fi.exists())
+ return localFile;
+
+ static const QStringList suffixes = fromLatin1List(QSGTextureReader::supportedFileFormats() +
+ QImageReader::supportedImageFormats());
+ QString tryFile = localFile + QStringLiteral(".xxxx");
+ const int suffixIdx = localFile.length() + 1;
+ for (const QString &suffix : suffixes) {
+ tryFile.replace(suffixIdx, 10, suffix);
+ if (QFileInfo::exists(tryFile))
+ return tryFile;
+ }
+ return localFile;
+}
+
QQuickPixmapReader::QQuickPixmapReader(QQmlEngine *eng)
: QThread(eng), engine(eng), threadObject(0)
#if QT_CONFIG(qml_network)
@@ -768,11 +797,32 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u
QImage image;
QQuickPixmapReply::ReadError errorCode = QQuickPixmapReply::NoError;
QString errorStr;
- QFile f(localFile);
+ QFile f(existingImageFileForPath(localFile));
QSize readSize;
if (f.open(QIODevice::ReadOnly)) {
- if (!readImage(url, &f, &image, &errorStr, &readSize, runningJob->requestSize, runningJob->providerOptions))
- errorCode = QQuickPixmapReply::Loading;
+ QSGTextureReader texReader(&f, localFile);
+ if (texReader.isTexture()) {
+ QQuickTextureFactory *factory = texReader.read();
+ if (factory) {
+ readSize = factory->textureSize();
+ } else {
+ errorStr = QQuickPixmap::tr("Error decoding: %1").arg(url.toString());
+ if (f.fileName() != localFile)
+ errorStr += QString::fromLatin1(" (%1)").arg(f.fileName());
+ errorCode = QQuickPixmapReply::Decoding;
+ }
+ mutex.lock();
+ if (!cancelled.contains(runningJob))
+ runningJob->postReply(errorCode, errorStr, readSize, factory);
+ mutex.unlock();
+ return;
+ } else {
+ if (!readImage(url, &f, &image, &errorStr, &readSize, runningJob->requestSize, runningJob->providerOptions)) {
+ errorCode = QQuickPixmapReply::Loading;
+ if (f.fileName() != localFile)
+ errorStr += QString::fromLatin1(" (%1)").arg(f.fileName());
+ }
+ }
} else {
errorStr = QQuickPixmap::tr("Cannot open: %1").arg(url.toString());
errorCode = QQuickPixmapReply::Loading;
@@ -1228,16 +1278,31 @@ static QQuickPixmapData* createPixmapDataSync(QQuickPixmap *declarativePixmap, Q
if (localFile.isEmpty())
return 0;
- QFile f(localFile);
+ QFile f(existingImageFileForPath(localFile));
QSize readSize;
QString errorString;
if (f.open(QIODevice::ReadOnly)) {
- QImage image;
- QQuickImageProviderOptions::AutoTransform appliedTransform = providerOptions.autoTransform();
- if (readImage(url, &f, &image, &errorString, &readSize, requestSize, providerOptions, &appliedTransform)) {
- *ok = true;
- return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, providerOptions, appliedTransform);
+ QSGTextureReader texReader(&f, localFile);
+ if (texReader.isTexture()) {
+ QQuickTextureFactory *factory = texReader.read();
+ if (factory) {
+ *ok = true;
+ return new QQuickPixmapData(declarativePixmap, url, factory, factory->textureSize(), requestSize, providerOptions, QQuickImageProviderOptions::UsePluginDefaultTransform);
+ } else {
+ errorString = QQuickPixmap::tr("Error decoding: %1").arg(url.toString());
+ if (f.fileName() != localFile)
+ errorString += QString::fromLatin1(" (%1)").arg(f.fileName());
+ }
+ } else {
+ QImage image;
+ QQuickImageProviderOptions::AutoTransform appliedTransform = providerOptions.autoTransform();
+ if (readImage(url, &f, &image, &errorString, &readSize, requestSize, providerOptions, &appliedTransform)) {
+ *ok = true;
+ return new QQuickPixmapData(declarativePixmap, url, QQuickTextureFactory::textureFactoryForImage(image), readSize, requestSize, providerOptions, appliedTransform);
+ } else if (f.fileName() != localFile) {
+ errorString += QString::fromLatin1(" (%1)").arg(f.fileName());
+ }
}
} else {
errorString = QQuickPixmap::tr("Cannot open: %1").arg(url.toString());
diff --git a/src/quick/util/qquickprofiler_p.h b/src/quick/util/qquickprofiler_p.h
index d2fa935ad4..38027a6abf 100644
--- a/src/quick/util/qquickprofiler_p.h
+++ b/src/quick/util/qquickprofiler_p.h
@@ -52,9 +52,12 @@
//
#include <QtCore/private/qabstractanimation_p.h>
-#include <QtQml/private/qqmlprofilerdefinitions_p.h>
#include <QtQuick/private/qtquickglobal_p.h>
+#if QT_CONFIG(qml_debug)
+#include <QtQml/private/qqmlprofilerdefinitions_p.h>
+#endif
+
#include <QtCore/qurl.h>
#include <QtCore/qsize.h>
#include <QtCore/qmutex.h>
@@ -62,7 +65,7 @@
QT_BEGIN_NAMESPACE
-#ifdef QT_NO_QML_DEBUGGER
+#if !QT_CONFIG(qml_debug)
#define Q_QUICK_PROFILE_IF_ENABLED(feature, Code)
@@ -358,7 +361,7 @@ protected:
void setTimer(const QElapsedTimer &t);
};
-#endif // QT_NO_QML_DEBUGGER
+#endif // QT_CONFIG(qml_debug)
#define Q_QUICK_PROFILE(feature, Method)\
Q_QUICK_PROFILE_IF_ENABLED(feature, QQuickProfiler::Method)
diff --git a/src/quick/util/qquickpropertychanges.cpp b/src/quick/util/qquickpropertychanges.cpp
index aecb7115ea..c585d4c16d 100644
--- a/src/quick/util/qquickpropertychanges.cpp
+++ b/src/quick/util/qquickpropertychanges.cpp
@@ -180,7 +180,7 @@ public:
rewindExpression = QQmlPropertyPrivate::signalExpression(property);
}
- bool override(QQuickStateActionEvent *other) override {
+ bool mayOverride(QQuickStateActionEvent *other) override {
if (other == this)
return true;
if (other->type() != type())
@@ -461,7 +461,7 @@ QQuickPropertyChanges::ActionList QQuickPropertyChanges::actions()
QQmlBinding *newBinding = 0;
if (e.id != QQmlBinding::Invalid) {
- QV4::Scope scope(QQmlEnginePrivate::getV4Engine(qmlEngine(this)));
+ QV4::Scope scope(qmlEngine(this)->handle());
QV4::Scoped<QV4::QmlContext> qmlContext(scope, QV4::QmlContext::create(scope.engine->rootContext(), context, object()));
newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(prop)->core,
d->compilationUnit->runtimeFunctions.at(e.id), object(), context, qmlContext);
diff --git a/src/quick/util/qquickshortcut_p.h b/src/quick/util/qquickshortcut_p.h
index db918058b2..c5d5501cb7 100644
--- a/src/quick/util/qquickshortcut_p.h
+++ b/src/quick/util/qquickshortcut_p.h
@@ -74,7 +74,7 @@ class QQuickShortcut : public QObject, public QQmlParserStatus
Q_PROPERTY(Qt::ShortcutContext context READ context WRITE setContext NOTIFY contextChanged FINAL)
public:
- explicit QQuickShortcut(QObject *parent = Q_NULLPTR);
+ explicit QQuickShortcut(QObject *parent = nullptr);
~QQuickShortcut();
QVariant sequence() const;
@@ -106,9 +106,9 @@ Q_SIGNALS:
void activatedAmbiguously();
protected:
- void classBegin() Q_DECL_OVERRIDE;
- void componentComplete() Q_DECL_OVERRIDE;
- bool event(QEvent *event) Q_DECL_OVERRIDE;
+ void classBegin() override;
+ void componentComplete() override;
+ bool event(QEvent *event) override;
struct Shortcut {
Shortcut() : id(0) { }
diff --git a/src/quick/util/qquickstate.cpp b/src/quick/util/qquickstate.cpp
index ca8b7bbc2b..3e0a2169a8 100644
--- a/src/quick/util/qquickstate.cpp
+++ b/src/quick/util/qquickstate.cpp
@@ -105,7 +105,7 @@ void QQuickStateActionEvent::clearBindings()
{
}
-bool QQuickStateActionEvent::override(QQuickStateActionEvent *other)
+bool QQuickStateActionEvent::mayOverride(QQuickStateActionEvent *other)
{
Q_UNUSED(other);
return false;
@@ -573,7 +573,7 @@ void QQuickState::apply(QQuickTransition *trans, QQuickState *revert)
for (int jj = 0; jj < d->revertList.count(); ++jj) {
QQuickStateActionEvent *event = d->revertList.at(jj).event();
if (event && event->type() == action.event->type()) {
- if (action.event->override(event)) {
+ if (action.event->mayOverride(event)) {
found = true;
if (action.event != d->revertList.at(jj).event() && action.event->needsCopy()) {
@@ -635,7 +635,7 @@ void QQuickState::apply(QQuickTransition *trans, QQuickState *revert)
for (int jj = 0; !found && jj < applyList.count(); ++jj) {
const QQuickStateAction &action = applyList.at(jj);
if (action.event && action.event->type() == event->type()) {
- if (action.event->override(event))
+ if (action.event->mayOverride(event))
found = true;
}
}
diff --git a/src/quick/util/qquickstate_p.h b/src/quick/util/qquickstate_p.h
index 3826daf283..f551402e80 100644
--- a/src/quick/util/qquickstate_p.h
+++ b/src/quick/util/qquickstate_p.h
@@ -115,7 +115,7 @@ public:
virtual bool changesBindings();
virtual void clearBindings();
- virtual bool override(QQuickStateActionEvent*other);
+ virtual bool mayOverride(QQuickStateActionEvent*other);
};
//### rename to QQuickStateChange?
diff --git a/src/quick/util/qquicksvgparser.cpp b/src/quick/util/qquicksvgparser.cpp
index 310b600965..086c6d0b28 100644
--- a/src/quick/util/qquicksvgparser.cpp
+++ b/src/quick/util/qquicksvgparser.cpp
@@ -45,8 +45,6 @@
QT_BEGIN_NAMESPACE
-static const double Q_PI = 3.14159265358979323846; // pi
-
//copied from Qt SVG (qsvghandler.cpp).
Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok);
// '0' is 0x30 and '9' is 0x39
@@ -253,11 +251,11 @@ void QQuickSvgParser::pathArc(QPainterPath &path,
th_arc = th1 - th0;
if (th_arc < 0 && sweep_flag)
- th_arc += 2 * Q_PI;
+ th_arc += 2 * M_PI;
else if (th_arc > 0 && !sweep_flag)
- th_arc -= 2 * Q_PI;
+ th_arc -= 2 * M_PI;
- n_segs = qCeil(qAbs(th_arc / (Q_PI * 0.5 + 0.001)));
+ n_segs = qCeil(qAbs(th_arc / (M_PI * 0.5 + 0.001)));
for (i = 0; i < n_segs; i++) {
pathArcSegment(path, xc, yc,
diff --git a/src/quick/util/qquicksvgparser_p.h b/src/quick/util/qquicksvgparser_p.h
index 44b0d1b6dd..1777b99bf4 100644
--- a/src/quick/util/qquicksvgparser_p.h
+++ b/src/quick/util/qquicksvgparser_p.h
@@ -51,6 +51,7 @@
// We mean it.
//
+#include <private/qtquickglobal_p.h>
#include <QtCore/qstring.h>
#include <QtGui/qpainterpath.h>
@@ -59,9 +60,9 @@ QT_BEGIN_NAMESPACE
namespace QQuickSvgParser
{
bool parsePathDataFast(const QString &dataStr, QPainterPath &path);
- void pathArc(QPainterPath &path, qreal rx, qreal ry, qreal x_axis_rotation,
- int large_arc_flag, int sweep_flag, qreal x, qreal y, qreal curx,
- qreal cury);
+ Q_QUICK_PRIVATE_EXPORT void pathArc(QPainterPath &path, qreal rx, qreal ry, qreal x_axis_rotation,
+ int large_arc_flag, int sweep_flag, qreal x, qreal y, qreal curx,
+ qreal cury);
}
QT_END_NAMESPACE
diff --git a/src/quick/util/qquickvaluetypes.cpp b/src/quick/util/qquickvaluetypes.cpp
index 4d34c6d661..e4a03f3b52 100644
--- a/src/quick/util/qquickvaluetypes.cpp
+++ b/src/quick/util/qquickvaluetypes.cpp
@@ -757,6 +757,29 @@ void QQuickFontValueType::setHintingPreference(QQuickFontValueType::HintingPrefe
v.setHintingPreference(QFont::HintingPreference(hintingPreference));
}
+bool QQuickFontValueType::kerning() const
+{
+ return v.kerning();
+}
+
+void QQuickFontValueType::setKerning(bool b)
+{
+ v.setKerning(b);
+}
+
+bool QQuickFontValueType::preferShaping() const
+{
+ return (v.styleStrategy() & QFont::PreferNoShaping) == 0;
+}
+
+void QQuickFontValueType::setPreferShaping(bool enable)
+{
+ if (enable)
+ v.setStyleStrategy(static_cast<QFont::StyleStrategy>(v.styleStrategy() & ~QFont::PreferNoShaping));
+ else
+ v.setStyleStrategy(static_cast<QFont::StyleStrategy>(v.styleStrategy() | QFont::PreferNoShaping));
+}
+
QT_END_NAMESPACE
#include "moc_qquickvaluetypes_p.cpp"
diff --git a/src/quick/util/qquickvaluetypes_p.h b/src/quick/util/qquickvaluetypes_p.h
index 4a1598ec5c..5a9af970e8 100644
--- a/src/quick/util/qquickvaluetypes_p.h
+++ b/src/quick/util/qquickvaluetypes_p.h
@@ -323,6 +323,8 @@ class QQuickFontValueType
Q_PROPERTY(qreal letterSpacing READ letterSpacing WRITE setLetterSpacing FINAL)
Q_PROPERTY(qreal wordSpacing READ wordSpacing WRITE setWordSpacing FINAL)
Q_PROPERTY(HintingPreference hintingPreference READ hintingPreference WRITE setHintingPreference FINAL)
+ Q_PROPERTY(bool kerning READ kerning WRITE setKerning FINAL)
+ Q_PROPERTY(bool preferShaping READ preferShaping WRITE setPreferShaping FINAL)
public:
enum FontWeight { Thin = QFont::Thin,
@@ -393,6 +395,12 @@ public:
HintingPreference hintingPreference() const;
void setHintingPreference(HintingPreference);
+
+ bool kerning() const;
+ void setKerning(bool b);
+
+ bool preferShaping() const;
+ void setPreferShaping(bool b);
};
QT_END_NAMESPACE
diff --git a/src/quick/util/util.pri b/src/quick/util/util.pri
index b53b132cce..edcb268cd9 100644
--- a/src/quick/util/util.pri
+++ b/src/quick/util/util.pri
@@ -28,7 +28,7 @@ SOURCES += \
$$PWD/qquicktextmetrics.cpp \
$$PWD/qquickvalidator.cpp
-!contains(QT_CONFIG, no-qml-debug): SOURCES += $$PWD/qquickprofiler.cpp
+qtConfig(qml-debug): SOURCES += $$PWD/qquickprofiler.cpp
HEADERS += \
$$PWD/qquickapplication_p.h\
diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp
index b15df88112..00aec0113c 100644
--- a/src/quickwidgets/qquickwidget.cpp
+++ b/src/quickwidgets/qquickwidget.cpp
@@ -80,7 +80,7 @@ class QQuickWidgetRenderControl : public QQuickRenderControl
{
public:
QQuickWidgetRenderControl(QQuickWidget *quickwidget) : m_quickWidget(quickwidget) {}
- QWindow *renderWindow(QPoint *offset) Q_DECL_OVERRIDE {
+ QWindow *renderWindow(QPoint *offset) override {
if (offset)
*offset = m_quickWidget->mapTo(m_quickWidget->window(), QPoint());
return m_quickWidget->window()->windowHandle();
@@ -773,6 +773,7 @@ void QQuickWidgetPrivate::updateSize()
QSize newSize = QSize(root->width(), root->height());
if (newSize.isValid() && newSize != q->size()) {
q->resize(newSize);
+ q->updateGeometry();
}
} else if (resizeMode == QQuickWidget::SizeRootObjectToView) {
bool needToUpdateWidth = !qFuzzyCompare(q->width(), root->width());
@@ -1661,12 +1662,12 @@ void QQuickWidget::paintEvent(QPaintEvent *event)
QTransform transform;
transform.scale(devicePixelRatioF(), devicePixelRatioF());
//Paint only the updated areas
- const auto rects = d->updateRegion.rects();
- for (auto targetRect : rects) {
+ QRegion targetRegion;
+ d->updateRegion.swap(targetRegion);
+ for (auto targetRect : targetRegion) {
auto sourceRect = transform.mapRect(QRectF(targetRect));
painter.drawImage(targetRect, d->softwareImage, sourceRect);
}
- d->updateRegion = QRegion();
}
}
}
diff --git a/src/quickwidgets/qquickwidget.h b/src/quickwidgets/qquickwidget.h
index 2d159778ed..8c9382e84b 100644
--- a/src/quickwidgets/qquickwidget.h
+++ b/src/quickwidgets/qquickwidget.h
@@ -43,7 +43,6 @@
#include <QtWidgets/qwidget.h>
#include <QtQuick/qquickwindow.h>
#include <QtCore/qurl.h>
-#include <QtQml/qqmldebug.h>
#include <QtQuickWidgets/qtquickwidgetsglobal.h>
#include <QtGui/qimage.h>
@@ -64,9 +63,9 @@ class Q_QUICKWIDGETS_EXPORT QQuickWidget : public QWidget
Q_PROPERTY(QUrl source READ source WRITE setSource DESIGNABLE true)
public:
- explicit QQuickWidget(QWidget *parent = Q_NULLPTR);
+ explicit QQuickWidget(QWidget *parent = nullptr);
QQuickWidget(QQmlEngine* engine, QWidget *parent);
- explicit QQuickWidget(const QUrl &source, QWidget *parent = Q_NULLPTR);
+ explicit QQuickWidget(const QUrl &source, QWidget *parent = nullptr);
virtual ~QQuickWidget();
QUrl source() const;
diff --git a/src/quickwidgets/qquickwidget_p.h b/src/quickwidgets/qquickwidget_p.h
index 9747315577..03571e8dc7 100644
--- a/src/quickwidgets/qquickwidget_p.h
+++ b/src/quickwidgets/qquickwidget_p.h
@@ -87,7 +87,7 @@ public:
~QQuickWidgetPrivate();
void execute();
- void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
+ void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &oldGeometry) override;
void initResize();
void updateSize();
void updatePosition();
@@ -100,8 +100,8 @@ public:
void handleContextCreationFailure(const QSurfaceFormat &format, bool isEs);
#if QT_CONFIG(opengl)
- GLuint textureId() const Q_DECL_OVERRIDE;
- QImage grabFramebuffer() Q_DECL_OVERRIDE;
+ GLuint textureId() const override;
+ QImage grabFramebuffer() override;
#else
QImage grabFramebuffer();
#endif
diff --git a/src/src.pro b/src/src.pro
index 3bb399acd4..33c47048b5 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -1,7 +1,8 @@
TEMPLATE = subdirs
CONFIG += ordered
+include($$OUT_PWD/qml/qtqml-config.pri)
include($$OUT_PWD/quick/qtquick-config.pri)
-QT_FOR_CONFIG += network quick-private
+QT_FOR_CONFIG += qml quick-private
SUBDIRS += \
qml
@@ -20,4 +21,7 @@ SUBDIRS += \
imports \
qmldevtools
-qtConfig(localserver):!contains(QT_CONFIG, no-qml-debug): SUBDIRS += qmldebug
+qtConfig(qml-network) {
+ QT_FOR_CONFIG += network
+ qtConfig(localserver):qtConfig(qml-debug): SUBDIRS += qmldebug
+}
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index f9c1fcce91..1e80f1bf65 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -18,7 +18,4 @@ qtHaveModule(gui):qtConfig(opengl(es1|es2)?) {
# console applications not supported
uikit: SUBDIRS -= qmltest
-# Restricted sub-set for now
-boot2qt: SUBDIRS = qml
-
installed_cmake.depends = cmake
diff --git a/tests/auto/bic/data/QtQml.5.10.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtQml.5.10.0.linux-gcc-amd64.txt
new file mode 100644
index 0000000000..f732634d95
--- /dev/null
+++ b/tests/auto/bic/data/QtQml.5.10.0.linux-gcc-amd64.txt
@@ -0,0 +1,5889 @@
+Class std::__failure_type
+ size=1 align=1
+ base size=0 base align=1
+std::__failure_type (0x0x7fbd1b2e7000) 0 empty
+
+Class std::__do_is_destructible_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_is_destructible_impl (0x0x7fbd18f31780) 0 empty
+
+Class std::__do_is_nt_destructible_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_is_nt_destructible_impl (0x0x7fbd18f319c0) 0 empty
+
+Class std::__do_is_default_constructible_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_is_default_constructible_impl (0x0x7fbd18f31c00) 0 empty
+
+Class std::__do_is_static_castable_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_is_static_castable_impl (0x0x7fbd18f31e40) 0 empty
+
+Class std::__do_is_direct_constructible_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_is_direct_constructible_impl (0x0x7fbd18f59000) 0 empty
+
+Class std::__do_is_nary_constructible_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_is_nary_constructible_impl (0x0x7fbd18f593c0) 0 empty
+
+Class std::__do_common_type_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_common_type_impl (0x0x7fbd18fe6b40) 0 empty
+
+Class std::__do_member_type_wrapper
+ size=1 align=1
+ base size=0 base align=1
+std::__do_member_type_wrapper (0x0x7fbd18fe6c00) 0 empty
+
+Class std::__result_of_memfun_ref_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__result_of_memfun_ref_impl (0x0x7fbd18fe6f60) 0 empty
+
+Class std::__result_of_memfun_deref_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__result_of_memfun_deref_impl (0x0x7fbd1901a060) 0 empty
+
+Class std::__result_of_memobj_ref_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__result_of_memobj_ref_impl (0x0x7fbd1901a120) 0 empty
+
+Class std::__result_of_memobj_deref_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__result_of_memobj_deref_impl (0x0x7fbd1901a1e0) 0 empty
+
+Class std::__result_of_other_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__result_of_other_impl (0x0x7fbd1901a480) 0 empty
+
+Class std::piecewise_construct_t
+ size=1 align=1
+ base size=0 base align=1
+std::piecewise_construct_t (0x0x7fbd1901a660) 0 empty
+
+Class std::__true_type
+ size=1 align=1
+ base size=0 base align=1
+std::__true_type (0x0x7fbd1901aae0) 0 empty
+
+Class std::__false_type
+ size=1 align=1
+ base size=0 base align=1
+std::__false_type (0x0x7fbd1901ab40) 0 empty
+
+Class std::input_iterator_tag
+ size=1 align=1
+ base size=0 base align=1
+std::input_iterator_tag (0x0x7fbd190c97e0) 0 empty
+
+Class std::output_iterator_tag
+ size=1 align=1
+ base size=0 base align=1
+std::output_iterator_tag (0x0x7fbd190c9840) 0 empty
+
+Class std::forward_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::forward_iterator_tag (0x0x7fbd1900c680) 0 empty
+ std::input_iterator_tag (0x0x7fbd190c98a0) 0 empty
+
+Class std::bidirectional_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::bidirectional_iterator_tag (0x0x7fbd1900c6e8) 0 empty
+ std::forward_iterator_tag (0x0x7fbd1900c750) 0 empty
+ std::input_iterator_tag (0x0x7fbd190c9900) 0 empty
+
+Class std::random_access_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::random_access_iterator_tag (0x0x7fbd1900c7b8) 0 empty
+ std::bidirectional_iterator_tag (0x0x7fbd1900c820) 0 empty
+ std::forward_iterator_tag (0x0x7fbd1900c888) 0 empty
+ std::input_iterator_tag (0x0x7fbd190c9960) 0 empty
+
+Class __gnu_cxx::__ops::_Iter_less_iter
+ size=1 align=1
+ base size=0 base align=1
+__gnu_cxx::__ops::_Iter_less_iter (0x0x7fbd18d09600) 0 empty
+
+Class __gnu_cxx::__ops::_Iter_less_val
+ size=1 align=1
+ base size=0 base align=1
+__gnu_cxx::__ops::_Iter_less_val (0x0x7fbd18d09660) 0 empty
+
+Class __gnu_cxx::__ops::_Val_less_iter
+ size=1 align=1
+ base size=0 base align=1
+__gnu_cxx::__ops::_Val_less_iter (0x0x7fbd18d096c0) 0 empty
+
+Class __gnu_cxx::__ops::_Iter_equal_to_iter
+ size=1 align=1
+ base size=0 base align=1
+__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7fbd18d09720) 0 empty
+
+Class __gnu_cxx::__ops::_Iter_equal_to_val
+ size=1 align=1
+ base size=0 base align=1
+__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7fbd18d09780) 0 empty
+
+Class wait
+ size=4 align=4
+ base size=4 base align=4
+wait (0x0x7fbd18e082a0) 0
+
+Class __locale_struct
+ size=232 align=8
+ base size=232 base align=8
+__locale_struct (0x0x7fbd18e084e0) 0
+
+Class timespec
+ size=16 align=8
+ base size=16 base align=8
+timespec (0x0x7fbd18e085a0) 0
+
+Class timeval
+ size=16 align=8
+ base size=16 base align=8
+timeval (0x0x7fbd18e08600) 0
+
+Class pthread_attr_t
+ size=56 align=8
+ base size=56 base align=8
+pthread_attr_t (0x0x7fbd18e086c0) 0
+
+Class __pthread_internal_list
+ size=16 align=8
+ base size=16 base align=8
+__pthread_internal_list (0x0x7fbd18e08720) 0
+
+Class random_data
+ size=48 align=8
+ base size=48 base align=8
+random_data (0x0x7fbd18e08ba0) 0
+
+Class drand48_data
+ size=24 align=8
+ base size=24 base align=8
+drand48_data (0x0x7fbd18e08c00) 0
+
+Vtable for std::exception
+std::exception::_ZTVSt9exception: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt9exception)
+16 (int (*)(...))std::exception::~exception
+24 (int (*)(...))std::exception::~exception
+32 (int (*)(...))std::exception::what
+
+Class std::exception
+ size=8 align=8
+ base size=8 base align=8
+std::exception (0x0x7fbd18e08c60) 0 nearly-empty
+ vptr=((& std::exception::_ZTVSt9exception) + 16u)
+
+Vtable for std::bad_exception
+std::bad_exception::_ZTVSt13bad_exception: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt13bad_exception)
+16 (int (*)(...))std::bad_exception::~bad_exception
+24 (int (*)(...))std::bad_exception::~bad_exception
+32 (int (*)(...))std::bad_exception::what
+
+Class std::bad_exception
+ size=8 align=8
+ base size=8 base align=8
+std::bad_exception (0x0x7fbd1900cdd0) 0 nearly-empty
+ vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u)
+ std::exception (0x0x7fbd18e08cc0) 0 nearly-empty
+ primary-for std::bad_exception (0x0x7fbd1900cdd0)
+
+Class std::__exception_ptr::exception_ptr
+ size=8 align=8
+ base size=8 base align=8
+std::__exception_ptr::exception_ptr (0x0x7fbd18e08d20) 0
+
+Vtable for std::nested_exception
+std::nested_exception::_ZTVSt16nested_exception: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt16nested_exception)
+16 (int (*)(...))std::nested_exception::~nested_exception
+24 (int (*)(...))std::nested_exception::~nested_exception
+
+Class std::nested_exception
+ size=16 align=8
+ base size=16 base align=8
+std::nested_exception (0x0x7fbd18e08d80) 0
+ vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16u)
+
+Vtable for std::bad_alloc
+std::bad_alloc::_ZTVSt9bad_alloc: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt9bad_alloc)
+16 (int (*)(...))std::bad_alloc::~bad_alloc
+24 (int (*)(...))std::bad_alloc::~bad_alloc
+32 (int (*)(...))std::bad_alloc::what
+
+Class std::bad_alloc
+ size=8 align=8
+ base size=8 base align=8
+std::bad_alloc (0x0x7fbd18b4e000) 0 nearly-empty
+ vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u)
+ std::exception (0x0x7fbd18b451e0) 0 nearly-empty
+ primary-for std::bad_alloc (0x0x7fbd18b4e000)
+
+Vtable for std::bad_array_new_length
+std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt20bad_array_new_length)
+16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length
+24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length
+32 (int (*)(...))std::bad_array_new_length::what
+
+Class std::bad_array_new_length
+ size=8 align=8
+ base size=8 base align=8
+std::bad_array_new_length (0x0x7fbd18b4e068) 0 nearly-empty
+ vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16u)
+ std::bad_alloc (0x0x7fbd18b4e0d0) 0 nearly-empty
+ primary-for std::bad_array_new_length (0x0x7fbd18b4e068)
+ std::exception (0x0x7fbd18b45240) 0 nearly-empty
+ primary-for std::bad_alloc (0x0x7fbd18b4e0d0)
+
+Class std::nothrow_t
+ size=1 align=1
+ base size=0 base align=1
+std::nothrow_t (0x0x7fbd18b452a0) 0 empty
+
+Class __exception
+ size=40 align=8
+ base size=40 base align=8
+__exception (0x0x7fbd18b45ea0) 0
+
+Class lconv
+ size=96 align=8
+ base size=96 base align=8
+lconv (0x0x7fbd18c8aba0) 0
+
+Vtable for __cxxabiv1::__forced_unwind
+__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class __cxxabiv1::__forced_unwind
+ size=8 align=8
+ base size=8 base align=8
+__cxxabiv1::__forced_unwind (0x0x7fbd18c8ac00) 0 nearly-empty
+ vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u)
+
+Class sched_param
+ size=4 align=4
+ base size=4 base align=4
+sched_param (0x0x7fbd18a42ae0) 0
+
+Class __sched_param
+ size=4 align=4
+ base size=4 base align=4
+__sched_param (0x0x7fbd18a42b40) 0
+
+Class timex
+ size=208 align=8
+ base size=208 base align=8
+timex (0x0x7fbd18a42c00) 0
+
+Class tm
+ size=56 align=8
+ base size=56 base align=8
+tm (0x0x7fbd18a42c60) 0
+
+Class itimerspec
+ size=32 align=8
+ base size=32 base align=8
+itimerspec (0x0x7fbd18a42cc0) 0
+
+Class _pthread_cleanup_buffer
+ size=32 align=8
+ base size=32 base align=8
+_pthread_cleanup_buffer (0x0x7fbd18a42d20) 0
+
+Class __pthread_cleanup_frame
+ size=24 align=8
+ base size=24 base align=8
+__pthread_cleanup_frame (0x0x7fbd18a42e40) 0
+
+Class __pthread_cleanup_class
+ size=24 align=8
+ base size=24 base align=8
+__pthread_cleanup_class (0x0x7fbd18a42ea0) 0
+
+Class _IO_marker
+ size=24 align=8
+ base size=24 base align=8
+_IO_marker (0x0x7fbd18737300) 0
+
+Class _IO_FILE
+ size=216 align=8
+ base size=216 base align=8
+_IO_FILE (0x0x7fbd18737360) 0
+
+Class std::_Hash_impl
+ size=1 align=1
+ base size=0 base align=1
+std::_Hash_impl (0x0x7fbd18599b40) 0 empty
+
+Class std::_Fnv_hash_impl
+ size=1 align=1
+ base size=0 base align=1
+std::_Fnv_hash_impl (0x0x7fbd18599ba0) 0 empty
+
+Class std::__numeric_limits_base
+ size=1 align=1
+ base size=0 base align=1
+std::__numeric_limits_base (0x0x7fbd185cfb40) 0 empty
+
+Class std::_Bit_reference
+ size=16 align=8
+ base size=16 base align=8
+std::_Bit_reference (0x0x7fbd1839b960) 0
+
+Class std::_Bit_iterator_base
+ size=16 align=8
+ base size=12 base align=8
+std::_Bit_iterator_base (0x0x7fbd185b1e38) 0
+ std::iterator<std::random_access_iterator_tag, bool> (0x0x7fbd1839ba20) 0 empty
+
+Class std::_Bit_iterator
+ size=16 align=8
+ base size=12 base align=8
+std::_Bit_iterator (0x0x7fbd185b1ea0) 0
+ std::_Bit_iterator_base (0x0x7fbd185b1f08) 0
+ std::iterator<std::random_access_iterator_tag, bool> (0x0x7fbd1839ba80) 0 empty
+
+Class std::_Bit_const_iterator
+ size=16 align=8
+ base size=12 base align=8
+std::_Bit_const_iterator (0x0x7fbd185b1f70) 0
+ std::_Bit_iterator_base (0x0x7fbd185b1618) 0
+ std::iterator<std::random_access_iterator_tag, bool> (0x0x7fbd1839bae0) 0 empty
+
+Class std::random_device
+ size=5000 align=8
+ base size=5000 base align=8
+std::random_device (0x0x7fbd1818c900) 0
+
+Class std::bernoulli_distribution::param_type
+ size=8 align=8
+ base size=8 base align=8
+std::bernoulli_distribution::param_type (0x0x7fbd182856c0) 0
+
+Class std::bernoulli_distribution
+ size=8 align=8
+ base size=8 base align=8
+std::bernoulli_distribution (0x0x7fbd18285660) 0
+
+Class std::seed_seq
+ size=24 align=8
+ base size=24 base align=8
+std::seed_seq (0x0x7fbd18068660) 0
+
+Class qIsNull(double)::U
+ size=8 align=8
+ base size=8 base align=8
+qIsNull(double)::U (0x0x7fbd16be4180) 0
+
+Class qIsNull(float)::U
+ size=4 align=4
+ base size=4 base align=4
+qIsNull(float)::U (0x0x7fbd16be41e0) 0
+
+Class QSysInfo
+ size=1 align=1
+ base size=0 base align=1
+QSysInfo (0x0x7fbd16c89c60) 0 empty
+
+Class QMessageLogContext
+ size=32 align=8
+ base size=32 base align=8
+QMessageLogContext (0x0x7fbd16c89cc0) 0
+
+Class QMessageLogger
+ size=32 align=8
+ base size=32 base align=8
+QMessageLogger (0x0x7fbd16c89d20) 0
+
+Class QFlag
+ size=4 align=4
+ base size=4 base align=4
+QFlag (0x0x7fbd16c89d80) 0
+
+Class QIncompatibleFlag
+ size=4 align=4
+ base size=4 base align=4
+QIncompatibleFlag (0x0x7fbd16cf0060) 0
+
+Class std::__atomic_flag_base
+ size=1 align=1
+ base size=1 base align=1
+std::__atomic_flag_base (0x0x7fbd16cf05a0) 0
+
+Class std::atomic_flag
+ size=1 align=1
+ base size=1 base align=1
+std::atomic_flag (0x0x7fbd16c8bd00) 0
+ std::__atomic_flag_base (0x0x7fbd16cf0600) 0
+
+Class QAtomicInt
+ size=4 align=4
+ base size=4 base align=4
+QAtomicInt (0x0x7fbd16717478) 0
+ QAtomicInteger<int> (0x0x7fbd167174e0) 0
+ QBasicAtomicInteger<int> (0x0x7fbd16ad1d20) 0
+
+Class QInternal
+ size=1 align=1
+ base size=0 base align=1
+QInternal (0x0x7fbd164b3300) 0 empty
+
+Class QtPrivate::QSlotObjectBase
+ size=16 align=8
+ base size=16 base align=8
+QtPrivate::QSlotObjectBase (0x0x7fbd16105360) 0
+
+Class QGenericArgument
+ size=16 align=8
+ base size=16 base align=8
+QGenericArgument (0x0x7fbd16105480) 0
+
+Class QGenericReturnArgument
+ size=16 align=8
+ base size=16 base align=8
+QGenericReturnArgument (0x0x7fbd1667af08) 0
+ QGenericArgument (0x0x7fbd161054e0) 0
+
+Class QMetaObject
+ size=48 align=8
+ base size=48 base align=8
+QMetaObject (0x0x7fbd16105660) 0
+
+Class QMetaObject::Connection
+ size=8 align=8
+ base size=8 base align=8
+QMetaObject::Connection (0x0x7fbd16105720) 0
+
+Class QLatin1Char
+ size=1 align=1
+ base size=1 base align=1
+QLatin1Char (0x0x7fbd161e6780) 0
+
+Class QChar
+ size=2 align=2
+ base size=2 base align=2
+QChar (0x0x7fbd161e67e0) 0
+
+Class QtPrivate::RefCount
+ size=4 align=4
+ base size=4 base align=4
+QtPrivate::RefCount (0x0x7fbd161e6a80) 0
+
+Class QArrayData
+ size=24 align=8
+ base size=24 base align=8
+QArrayData (0x0x7fbd161e6ae0) 0
+
+Class QtPrivate::QContainerImplHelper
+ size=1 align=1
+ base size=0 base align=1
+QtPrivate::QContainerImplHelper (0x0x7fbd161e6e40) 0 empty
+
+Class std::locale
+ size=8 align=8
+ base size=8 base align=8
+std::locale (0x0x7fbd161e6ea0) 0
+
+Vtable for std::locale::facet
+std::locale::facet::_ZTVNSt6locale5facetE: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt6locale5facetE)
+16 (int (*)(...))std::locale::facet::~facet
+24 (int (*)(...))std::locale::facet::~facet
+
+Class std::locale::facet
+ size=16 align=8
+ base size=12 base align=8
+std::locale::facet (0x0x7fbd161e6f00) 0
+ vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u)
+
+Class std::locale::id
+ size=8 align=8
+ base size=8 base align=8
+std::locale::id (0x0x7fbd161e6f60) 0
+
+Class std::locale::_Impl
+ size=40 align=8
+ base size=40 base align=8
+std::locale::_Impl (0x0x7fbd15f36000) 0
+
+Class std::__cow_string
+ size=8 align=8
+ base size=8 base align=8
+std::__cow_string (0x0x7fbd15f363c0) 0
+
+Vtable for std::logic_error
+std::logic_error::_ZTVSt11logic_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt11logic_error)
+16 (int (*)(...))std::logic_error::~logic_error
+24 (int (*)(...))std::logic_error::~logic_error
+32 (int (*)(...))std::logic_error::what
+
+Class std::logic_error
+ size=16 align=8
+ base size=16 base align=8
+std::logic_error (0x0x7fbd15f4e548) 0
+ vptr=((& std::logic_error::_ZTVSt11logic_error) + 16u)
+ std::exception (0x0x7fbd15f36480) 0 nearly-empty
+ primary-for std::logic_error (0x0x7fbd15f4e548)
+
+Vtable for std::domain_error
+std::domain_error::_ZTVSt12domain_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt12domain_error)
+16 (int (*)(...))std::domain_error::~domain_error
+24 (int (*)(...))std::domain_error::~domain_error
+32 (int (*)(...))std::logic_error::what
+
+Class std::domain_error
+ size=16 align=8
+ base size=16 base align=8
+std::domain_error (0x0x7fbd15f4e5b0) 0
+ vptr=((& std::domain_error::_ZTVSt12domain_error) + 16u)
+ std::logic_error (0x0x7fbd15f4e618) 0
+ primary-for std::domain_error (0x0x7fbd15f4e5b0)
+ std::exception (0x0x7fbd15f364e0) 0 nearly-empty
+ primary-for std::logic_error (0x0x7fbd15f4e618)
+
+Vtable for std::invalid_argument
+std::invalid_argument::_ZTVSt16invalid_argument: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt16invalid_argument)
+16 (int (*)(...))std::invalid_argument::~invalid_argument
+24 (int (*)(...))std::invalid_argument::~invalid_argument
+32 (int (*)(...))std::logic_error::what
+
+Class std::invalid_argument
+ size=16 align=8
+ base size=16 base align=8
+std::invalid_argument (0x0x7fbd15f4e680) 0
+ vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16u)
+ std::logic_error (0x0x7fbd15f4e6e8) 0
+ primary-for std::invalid_argument (0x0x7fbd15f4e680)
+ std::exception (0x0x7fbd15f36540) 0 nearly-empty
+ primary-for std::logic_error (0x0x7fbd15f4e6e8)
+
+Vtable for std::length_error
+std::length_error::_ZTVSt12length_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt12length_error)
+16 (int (*)(...))std::length_error::~length_error
+24 (int (*)(...))std::length_error::~length_error
+32 (int (*)(...))std::logic_error::what
+
+Class std::length_error
+ size=16 align=8
+ base size=16 base align=8
+std::length_error (0x0x7fbd15f4e750) 0
+ vptr=((& std::length_error::_ZTVSt12length_error) + 16u)
+ std::logic_error (0x0x7fbd15f4e7b8) 0
+ primary-for std::length_error (0x0x7fbd15f4e750)
+ std::exception (0x0x7fbd15f365a0) 0 nearly-empty
+ primary-for std::logic_error (0x0x7fbd15f4e7b8)
+
+Vtable for std::out_of_range
+std::out_of_range::_ZTVSt12out_of_range: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt12out_of_range)
+16 (int (*)(...))std::out_of_range::~out_of_range
+24 (int (*)(...))std::out_of_range::~out_of_range
+32 (int (*)(...))std::logic_error::what
+
+Class std::out_of_range
+ size=16 align=8
+ base size=16 base align=8
+std::out_of_range (0x0x7fbd15f4e820) 0
+ vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16u)
+ std::logic_error (0x0x7fbd15f4e888) 0
+ primary-for std::out_of_range (0x0x7fbd15f4e820)
+ std::exception (0x0x7fbd15f36600) 0 nearly-empty
+ primary-for std::logic_error (0x0x7fbd15f4e888)
+
+Vtable for std::runtime_error
+std::runtime_error::_ZTVSt13runtime_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt13runtime_error)
+16 (int (*)(...))std::runtime_error::~runtime_error
+24 (int (*)(...))std::runtime_error::~runtime_error
+32 (int (*)(...))std::runtime_error::what
+
+Class std::runtime_error
+ size=16 align=8
+ base size=16 base align=8
+std::runtime_error (0x0x7fbd15f4e8f0) 0
+ vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16u)
+ std::exception (0x0x7fbd15f36660) 0 nearly-empty
+ primary-for std::runtime_error (0x0x7fbd15f4e8f0)
+
+Vtable for std::range_error
+std::range_error::_ZTVSt11range_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt11range_error)
+16 (int (*)(...))std::range_error::~range_error
+24 (int (*)(...))std::range_error::~range_error
+32 (int (*)(...))std::runtime_error::what
+
+Class std::range_error
+ size=16 align=8
+ base size=16 base align=8
+std::range_error (0x0x7fbd15f4e958) 0
+ vptr=((& std::range_error::_ZTVSt11range_error) + 16u)
+ std::runtime_error (0x0x7fbd15f4e9c0) 0
+ primary-for std::range_error (0x0x7fbd15f4e958)
+ std::exception (0x0x7fbd15f366c0) 0 nearly-empty
+ primary-for std::runtime_error (0x0x7fbd15f4e9c0)
+
+Vtable for std::overflow_error
+std::overflow_error::_ZTVSt14overflow_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt14overflow_error)
+16 (int (*)(...))std::overflow_error::~overflow_error
+24 (int (*)(...))std::overflow_error::~overflow_error
+32 (int (*)(...))std::runtime_error::what
+
+Class std::overflow_error
+ size=16 align=8
+ base size=16 base align=8
+std::overflow_error (0x0x7fbd15f4ea28) 0
+ vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16u)
+ std::runtime_error (0x0x7fbd15f4ea90) 0
+ primary-for std::overflow_error (0x0x7fbd15f4ea28)
+ std::exception (0x0x7fbd15f36720) 0 nearly-empty
+ primary-for std::runtime_error (0x0x7fbd15f4ea90)
+
+Vtable for std::underflow_error
+std::underflow_error::_ZTVSt15underflow_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt15underflow_error)
+16 (int (*)(...))std::underflow_error::~underflow_error
+24 (int (*)(...))std::underflow_error::~underflow_error
+32 (int (*)(...))std::runtime_error::what
+
+Class std::underflow_error
+ size=16 align=8
+ base size=16 base align=8
+std::underflow_error (0x0x7fbd15f4eaf8) 0
+ vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16u)
+ std::runtime_error (0x0x7fbd15f4eb60) 0
+ primary-for std::underflow_error (0x0x7fbd15f4eaf8)
+ std::exception (0x0x7fbd15f36780) 0 nearly-empty
+ primary-for std::runtime_error (0x0x7fbd15f4eb60)
+
+Vtable for std::_V2::error_category
+std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt3_V214error_categoryE)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))std::_V2::error_category::_M_message
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))std::_V2::error_category::default_error_condition
+64 (int (*)(...))std::_V2::error_category::equivalent
+72 (int (*)(...))std::_V2::error_category::equivalent
+
+Class std::_V2::error_category
+ size=8 align=8
+ base size=8 base align=8
+std::_V2::error_category (0x0x7fbd15f36900) 0 nearly-empty
+ vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16u)
+
+Class std::error_code
+ size=16 align=8
+ base size=16 base align=8
+std::error_code (0x0x7fbd15f36b40) 0
+
+Class std::error_condition
+ size=16 align=8
+ base size=16 base align=8
+std::error_condition (0x0x7fbd15f36cc0) 0
+
+Vtable for std::system_error
+std::system_error::_ZTVSt12system_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt12system_error)
+16 (int (*)(...))std::system_error::~system_error
+24 (int (*)(...))std::system_error::~system_error
+32 (int (*)(...))std::runtime_error::what
+
+Class std::system_error
+ size=32 align=8
+ base size=32 base align=8
+std::system_error (0x0x7fbd15f4e340) 0
+ vptr=((& std::system_error::_ZTVSt12system_error) + 16u)
+ std::runtime_error (0x0x7fbd16010000) 0
+ primary-for std::system_error (0x0x7fbd15f4e340)
+ std::exception (0x0x7fbd15f36f00) 0 nearly-empty
+ primary-for std::runtime_error (0x0x7fbd16010000)
+
+Vtable for std::ios_base::failure
+std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E)
+16 (int (*)(...))std::ios_base::failure::~failure
+24 (int (*)(...))std::ios_base::failure::~failure
+32 (int (*)(...))std::ios_base::failure::what
+
+Class std::ios_base::failure
+ size=32 align=8
+ base size=32 base align=8
+std::ios_base::failure (0x0x7fbd16010bc8) 0
+ vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16u)
+ std::system_error (0x0x7fbd16010c30) 0
+ primary-for std::ios_base::failure (0x0x7fbd16010bc8)
+ std::runtime_error (0x0x7fbd16010c98) 0
+ primary-for std::system_error (0x0x7fbd16010c30)
+ std::exception (0x0x7fbd16024240) 0 nearly-empty
+ primary-for std::runtime_error (0x0x7fbd16010c98)
+
+Class std::ios_base::_Callback_list
+ size=24 align=8
+ base size=24 base align=8
+std::ios_base::_Callback_list (0x0x7fbd160242a0) 0
+
+Class std::ios_base::_Words
+ size=16 align=8
+ base size=16 base align=8
+std::ios_base::_Words (0x0x7fbd16024300) 0
+
+Class std::ios_base::Init
+ size=1 align=1
+ base size=0 base align=1
+std::ios_base::Init (0x0x7fbd16024360) 0 empty
+
+Vtable for std::ios_base
+std::ios_base::_ZTVSt8ios_base: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt8ios_base)
+16 (int (*)(...))std::ios_base::~ios_base
+24 (int (*)(...))std::ios_base::~ios_base
+
+Class std::ios_base
+ size=216 align=8
+ base size=216 base align=8
+std::ios_base (0x0x7fbd160241e0) 0
+ vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u)
+
+Class std::ctype_base
+ size=1 align=1
+ base size=0 base align=1
+std::ctype_base (0x0x7fbd16024ae0) 0 empty
+
+Class std::__num_base
+ size=1 align=1
+ base size=0 base align=1
+std::__num_base (0x0x7fbd15dbd1e0) 0 empty
+
+VTT for std::basic_ostream<char>
+std::basic_ostream<char>::_ZTTSo: 2u entries
+0 ((& std::basic_ostream<char>::_ZTVSo) + 24u)
+8 ((& std::basic_ostream<char>::_ZTVSo) + 64u)
+
+VTT for std::basic_ostream<wchar_t>
+std::basic_ostream<wchar_t>::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries
+0 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u)
+8 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u)
+
+VTT for std::basic_istream<char>
+std::basic_istream<char>::_ZTTSi: 2u entries
+0 ((& std::basic_istream<char>::_ZTVSi) + 24u)
+8 ((& std::basic_istream<char>::_ZTVSi) + 64u)
+
+VTT for std::basic_istream<wchar_t>
+std::basic_istream<wchar_t>::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries
+0 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u)
+8 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u)
+
+Construction vtable for std::basic_istream<char> (0x0x7fbd158c55b0 instance) in std::basic_iostream<char>
+std::basic_iostream<char>::_ZTCSd0_Si: 10u entries
+0 24u
+8 (int (*)(...))0
+16 (int (*)(...))(& _ZTISi)
+24 0u
+32 0u
+40 18446744073709551592u
+48 (int (*)(...))-24
+56 (int (*)(...))(& _ZTISi)
+64 0u
+72 0u
+
+Construction vtable for std::basic_ostream<char> (0x0x7fbd158c5680 instance) in std::basic_iostream<char>
+std::basic_iostream<char>::_ZTCSd16_So: 10u entries
+0 8u
+8 (int (*)(...))0
+16 (int (*)(...))(& _ZTISo)
+24 0u
+32 0u
+40 18446744073709551608u
+48 (int (*)(...))-8
+56 (int (*)(...))(& _ZTISo)
+64 0u
+72 0u
+
+VTT for std::basic_iostream<char>
+std::basic_iostream<char>::_ZTTSd: 7u entries
+0 ((& std::basic_iostream<char>::_ZTVSd) + 24u)
+8 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 24u)
+16 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 64u)
+24 ((& std::basic_iostream<char>::_ZTCSd16_So) + 24u)
+32 ((& std::basic_iostream<char>::_ZTCSd16_So) + 64u)
+40 ((& std::basic_iostream<char>::_ZTVSd) + 104u)
+48 ((& std::basic_iostream<char>::_ZTVSd) + 64u)
+
+Construction vtable for std::basic_istream<wchar_t> (0x0x7fbd158c5a28 instance) in std::basic_iostream<wchar_t>
+std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries
+0 24u
+8 (int (*)(...))0
+16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE)
+24 0u
+32 0u
+40 18446744073709551592u
+48 (int (*)(...))-24
+56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE)
+64 0u
+72 0u
+
+Construction vtable for std::basic_ostream<wchar_t> (0x0x7fbd158c5af8 instance) in std::basic_iostream<wchar_t>
+std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries
+0 8u
+8 (int (*)(...))0
+16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE)
+24 0u
+32 0u
+40 18446744073709551608u
+48 (int (*)(...))-8
+56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE)
+64 0u
+72 0u
+
+VTT for std::basic_iostream<wchar_t>
+std::basic_iostream<wchar_t>::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries
+0 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u)
+8 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u)
+16 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u)
+24 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u)
+32 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u)
+40 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u)
+48 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u)
+
+Class QByteArrayDataPtr
+ size=8 align=8
+ base size=8 base align=8
+QByteArrayDataPtr (0x0x7fbd15b76a20) 0
+
+Class QByteArray
+ size=8 align=8
+ base size=8 base align=8
+QByteArray (0x0x7fbd15b76a80) 0
+
+Class QByteRef
+ size=16 align=8
+ base size=12 base align=8
+QByteRef (0x0x7fbd15a21de0) 0
+
+Class QStringDataPtr
+ size=8 align=8
+ base size=8 base align=8
+QStringDataPtr (0x0x7fbd15702180) 0
+
+Class QStringView
+ size=16 align=8
+ base size=16 base align=8
+QStringView (0x0x7fbd15702600) 0
+
+Class QLatin1String
+ size=16 align=8
+ base size=16 base align=8
+QLatin1String (0x0x7fbd1578a480) 0
+
+Class QString::Null
+ size=1 align=1
+ base size=0 base align=1
+QString::Null (0x0x7fbd1578aae0) 0 empty
+
+Class QString
+ size=8 align=8
+ base size=8 base align=8
+QString (0x0x7fbd1578aa80) 0
+
+Class QCharRef
+ size=16 align=8
+ base size=12 base align=8
+QCharRef (0x0x7fbd15574ba0) 0
+
+Class QStringRef
+ size=16 align=8
+ base size=16 base align=8
+QStringRef (0x0x7fbd1530f7e0) 0
+
+Class QtPrivate::QHashCombine
+ size=1 align=1
+ base size=0 base align=1
+QtPrivate::QHashCombine (0x0x7fbd150e5420) 0 empty
+
+Class QtPrivate::QHashCombineCommutative
+ size=1 align=1
+ base size=0 base align=1
+QtPrivate::QHashCombineCommutative (0x0x7fbd150e5480) 0 empty
+
+Class std::__detail::_List_node_base
+ size=16 align=8
+ base size=16 base align=8
+std::__detail::_List_node_base (0x0x7fbd150e54e0) 0
+
+Class QListData::NotArrayCompatibleLayout
+ size=1 align=1
+ base size=0 base align=1
+QListData::NotArrayCompatibleLayout (0x0x7fbd150e58a0) 0 empty
+
+Class QListData::NotIndirectLayout
+ size=1 align=1
+ base size=0 base align=1
+QListData::NotIndirectLayout (0x0x7fbd150e5900) 0 empty
+
+Class QListData::ArrayCompatibleLayout
+ size=1 align=1
+ base size=1 base align=1
+QListData::ArrayCompatibleLayout (0x0x7fbd151124e0) 0 empty
+ QListData::NotIndirectLayout (0x0x7fbd150e5960) 0 empty
+
+Class QListData::InlineWithPaddingLayout
+ size=1 align=1
+ base size=1 base align=1
+QListData::InlineWithPaddingLayout (0x0x7fbd151dd1c0) 0 empty
+ QListData::NotArrayCompatibleLayout (0x0x7fbd150e59c0) 0 empty
+ QListData::NotIndirectLayout (0x0x7fbd150e5a20) 0 empty
+
+Class QListData::IndirectLayout
+ size=1 align=1
+ base size=1 base align=1
+QListData::IndirectLayout (0x0x7fbd15112548) 0 empty
+ QListData::NotArrayCompatibleLayout (0x0x7fbd150e5a80) 0 empty
+
+Class QListData::Data
+ size=24 align=8
+ base size=24 base align=8
+QListData::Data (0x0x7fbd150e5ae0) 0
+
+Class QListData
+ size=8 align=8
+ base size=8 base align=8
+QListData (0x0x7fbd150e5840) 0
+
+Class QRegExp
+ size=8 align=8
+ base size=8 base align=8
+QRegExp (0x0x7fbd150e5f60) 0
+
+Class QStringMatcher::Data
+ size=272 align=8
+ base size=272 base align=8
+QStringMatcher::Data (0x0x7fbd14f921e0) 0
+
+Class QStringMatcher
+ size=1048 align=8
+ base size=1048 base align=8
+QStringMatcher (0x0x7fbd14f92180) 0
+
+Class QStringList
+ size=8 align=8
+ base size=8 base align=8
+QStringList (0x0x7fbd14f7ff70) 0
+ QList<QString> (0x0x7fbd14fcf000) 0
+ QListSpecialMethods<QString> (0x0x7fbd14f923c0) 0 empty
+
+Class QScopedPointerPodDeleter
+ size=1 align=1
+ base size=0 base align=1
+QScopedPointerPodDeleter (0x0x7fbd14f927e0) 0 empty
+
+Class std::_Rb_tree_node_base
+ size=32 align=8
+ base size=32 base align=8
+std::_Rb_tree_node_base (0x0x7fbd1509f300) 0
+
+Class std::allocator_arg_t
+ size=1 align=1
+ base size=0 base align=1
+std::allocator_arg_t (0x0x7fbd1509f960) 0 empty
+
+Class std::__uses_alloc_base
+ size=1 align=1
+ base size=0 base align=1
+std::__uses_alloc_base (0x0x7fbd1509fae0) 0 empty
+
+Class std::__uses_alloc0::_Sink
+ size=1 align=1
+ base size=0 base align=1
+std::__uses_alloc0::_Sink (0x0x7fbd1509fba0) 0 empty
+
+Class std::__uses_alloc0
+ size=1 align=1
+ base size=1 base align=1
+std::__uses_alloc0 (0x0x7fbd14fcf8f0) 0
+ std::__uses_alloc_base (0x0x7fbd1509fb40) 0 empty
+
+Class std::_Swallow_assign
+ size=1 align=1
+ base size=0 base align=1
+std::_Swallow_assign (0x0x7fbd14e85c00) 0 empty
+
+Class QtPrivate::AbstractDebugStreamFunction
+ size=16 align=8
+ base size=16 base align=8
+QtPrivate::AbstractDebugStreamFunction (0x0x7fbd14e85e40) 0
+
+Class QtPrivate::AbstractComparatorFunction
+ size=24 align=8
+ base size=24 base align=8
+QtPrivate::AbstractComparatorFunction (0x0x7fbd14e85f00) 0
+
+Class QtPrivate::AbstractConverterFunction
+ size=8 align=8
+ base size=8 base align=8
+QtPrivate::AbstractConverterFunction (0x0x7fbd14be0060) 0
+
+Class QMetaType
+ size=80 align=8
+ base size=80 base align=8
+QMetaType (0x0x7fbd14be01e0) 0
+
+Class QtMetaTypePrivate::VariantData
+ size=24 align=8
+ base size=20 base align=8
+QtMetaTypePrivate::VariantData (0x0x7fbd14be0600) 0
+
+Class QtMetaTypePrivate::VectorBoolElements
+ size=1 align=1
+ base size=0 base align=1
+QtMetaTypePrivate::VectorBoolElements (0x0x7fbd14be0720) 0 empty
+
+Class QtMetaTypePrivate::QSequentialIterableImpl
+ size=104 align=8
+ base size=104 base align=8
+QtMetaTypePrivate::QSequentialIterableImpl (0x0x7fbd148f30c0) 0
+
+Class QtMetaTypePrivate::QAssociativeIterableImpl
+ size=112 align=8
+ base size=112 base align=8
+QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7fbd148f34e0) 0
+
+Class QtMetaTypePrivate::QPairVariantInterfaceImpl
+ size=40 align=8
+ base size=40 base align=8
+QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7fbd148f37e0) 0
+
+Class std::chrono::_V2::system_clock
+ size=1 align=1
+ base size=0 base align=1
+std::chrono::_V2::system_clock (0x0x7fbd147ce060) 0 empty
+
+Class std::chrono::_V2::steady_clock
+ size=1 align=1
+ base size=0 base align=1
+std::chrono::_V2::steady_clock (0x0x7fbd144a3ea0) 0 empty
+
+Vtable for QObjectData
+QObjectData::_ZTV11QObjectData: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QObjectData)
+16 (int (*)(...))__cxa_pure_virtual
+24 (int (*)(...))__cxa_pure_virtual
+
+Class QObjectData
+ size=48 align=8
+ base size=48 base align=8
+QObjectData (0x0x7fbd144a3f00) 0
+ vptr=((& QObjectData::_ZTV11QObjectData) + 16u)
+
+Class QObject::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QObject::QPrivateSignal (0x0x7fbd144eb120) 0 empty
+
+Vtable for QObject
+QObject::_ZTV7QObject: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QObject)
+16 (int (*)(...))QObject::metaObject
+24 (int (*)(...))QObject::qt_metacast
+32 (int (*)(...))QObject::qt_metacall
+40 (int (*)(...))QObject::~QObject
+48 (int (*)(...))QObject::~QObject
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QObject
+ size=16 align=8
+ base size=16 base align=8
+QObject (0x0x7fbd144eb0c0) 0
+ vptr=((& QObject::_ZTV7QObject) + 16u)
+
+Vtable for QObjectUserData
+QObjectUserData::_ZTV15QObjectUserData: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QObjectUserData)
+16 (int (*)(...))QObjectUserData::~QObjectUserData
+24 (int (*)(...))QObjectUserData::~QObjectUserData
+
+Class QObjectUserData
+ size=8 align=8
+ base size=8 base align=8
+QObjectUserData (0x0x7fbd145b13c0) 0 nearly-empty
+ vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u)
+
+Class QSignalBlocker
+ size=16 align=8
+ base size=10 base align=8
+QSignalBlocker (0x0x7fbd145b1420) 0
+
+Class QAbstractAnimation::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractAnimation::QPrivateSignal (0x0x7fbd145b14e0) 0 empty
+
+Vtable for QAbstractAnimation
+QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QAbstractAnimation)
+16 (int (*)(...))QAbstractAnimation::metaObject
+24 (int (*)(...))QAbstractAnimation::qt_metacast
+32 (int (*)(...))QAbstractAnimation::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QAbstractAnimation::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))QAbstractAnimation::updateState
+136 (int (*)(...))QAbstractAnimation::updateDirection
+
+Class QAbstractAnimation
+ size=16 align=8
+ base size=16 base align=8
+QAbstractAnimation (0x0x7fbd14588bc8) 0
+ vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u)
+ QObject (0x0x7fbd145b1480) 0
+ primary-for QAbstractAnimation (0x0x7fbd14588bc8)
+
+Class QAnimationDriver::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAnimationDriver::QPrivateSignal (0x0x7fbd145b15a0) 0 empty
+
+Vtable for QAnimationDriver
+QAnimationDriver::_ZTV16QAnimationDriver: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QAnimationDriver)
+16 (int (*)(...))QAnimationDriver::metaObject
+24 (int (*)(...))QAnimationDriver::qt_metacast
+32 (int (*)(...))QAnimationDriver::qt_metacall
+40 (int (*)(...))QAnimationDriver::~QAnimationDriver
+48 (int (*)(...))QAnimationDriver::~QAnimationDriver
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAnimationDriver::advance
+120 (int (*)(...))QAnimationDriver::elapsed
+128 (int (*)(...))QAnimationDriver::start
+136 (int (*)(...))QAnimationDriver::stop
+
+Class QAnimationDriver
+ size=16 align=8
+ base size=16 base align=8
+QAnimationDriver (0x0x7fbd14588c30) 0
+ vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u)
+ QObject (0x0x7fbd145b1540) 0
+ primary-for QAnimationDriver (0x0x7fbd14588c30)
+
+Class QEventLoop::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QEventLoop::QPrivateSignal (0x0x7fbd145b1660) 0 empty
+
+Vtable for QEventLoop
+QEventLoop::_ZTV10QEventLoop: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QEventLoop)
+16 (int (*)(...))QEventLoop::metaObject
+24 (int (*)(...))QEventLoop::qt_metacast
+32 (int (*)(...))QEventLoop::qt_metacall
+40 (int (*)(...))QEventLoop::~QEventLoop
+48 (int (*)(...))QEventLoop::~QEventLoop
+56 (int (*)(...))QEventLoop::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QEventLoop
+ size=16 align=8
+ base size=16 base align=8
+QEventLoop (0x0x7fbd14588c98) 0
+ vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u)
+ QObject (0x0x7fbd145b1600) 0
+ primary-for QEventLoop (0x0x7fbd14588c98)
+
+Class QEventLoopLocker
+ size=8 align=8
+ base size=8 base align=8
+QEventLoopLocker (0x0x7fbd145b1840) 0
+
+Class QAbstractEventDispatcher::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractEventDispatcher::QPrivateSignal (0x0x7fbd145b1900) 0 empty
+
+Class QAbstractEventDispatcher::TimerInfo
+ size=12 align=4
+ base size=12 base align=4
+QAbstractEventDispatcher::TimerInfo (0x0x7fbd145b1960) 0
+
+Vtable for QAbstractEventDispatcher
+QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher)
+16 (int (*)(...))QAbstractEventDispatcher::metaObject
+24 (int (*)(...))QAbstractEventDispatcher::qt_metacast
+32 (int (*)(...))QAbstractEventDispatcher::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))__cxa_pure_virtual
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))__cxa_pure_virtual
+176 (int (*)(...))__cxa_pure_virtual
+184 (int (*)(...))__cxa_pure_virtual
+192 (int (*)(...))__cxa_pure_virtual
+200 (int (*)(...))__cxa_pure_virtual
+208 (int (*)(...))QAbstractEventDispatcher::startingUp
+216 (int (*)(...))QAbstractEventDispatcher::closingDown
+
+Class QAbstractEventDispatcher
+ size=16 align=8
+ base size=16 base align=8
+QAbstractEventDispatcher (0x0x7fbd14588dd0) 0
+ vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u)
+ QObject (0x0x7fbd145b18a0) 0
+ primary-for QAbstractEventDispatcher (0x0x7fbd14588dd0)
+
+Vtable for std::type_info
+std::type_info::_ZTVSt9type_info: 8u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt9type_info)
+16 (int (*)(...))std::type_info::~type_info
+24 (int (*)(...))std::type_info::~type_info
+32 (int (*)(...))std::type_info::__is_pointer_p
+40 (int (*)(...))std::type_info::__is_function_p
+48 (int (*)(...))std::type_info::__do_catch
+56 (int (*)(...))std::type_info::__do_upcast
+
+Class std::type_info
+ size=16 align=8
+ base size=16 base align=8
+std::type_info (0x0x7fbd145b1c00) 0
+ vptr=((& std::type_info::_ZTVSt9type_info) + 16u)
+
+Vtable for std::bad_cast
+std::bad_cast::_ZTVSt8bad_cast: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt8bad_cast)
+16 (int (*)(...))std::bad_cast::~bad_cast
+24 (int (*)(...))std::bad_cast::~bad_cast
+32 (int (*)(...))std::bad_cast::what
+
+Class std::bad_cast
+ size=8 align=8
+ base size=8 base align=8
+std::bad_cast (0x0x7fbd14588000) 0 nearly-empty
+ vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16u)
+ std::exception (0x0x7fbd145b1c60) 0 nearly-empty
+ primary-for std::bad_cast (0x0x7fbd14588000)
+
+Vtable for std::bad_typeid
+std::bad_typeid::_ZTVSt10bad_typeid: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt10bad_typeid)
+16 (int (*)(...))std::bad_typeid::~bad_typeid
+24 (int (*)(...))std::bad_typeid::~bad_typeid
+32 (int (*)(...))std::bad_typeid::what
+
+Class std::bad_typeid
+ size=8 align=8
+ base size=8 base align=8
+std::bad_typeid (0x0x7fbd145880d0) 0 nearly-empty
+ vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16u)
+ std::exception (0x0x7fbd145b1cc0) 0 nearly-empty
+ primary-for std::bad_typeid (0x0x7fbd145880d0)
+
+Vtable for std::bad_function_call
+std::bad_function_call::_ZTVSt17bad_function_call: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt17bad_function_call)
+16 (int (*)(...))std::bad_function_call::~bad_function_call
+24 (int (*)(...))std::bad_function_call::~bad_function_call
+32 (int (*)(...))std::bad_function_call::what
+
+Class std::bad_function_call
+ size=8 align=8
+ base size=8 base align=8
+std::bad_function_call (0x0x7fbd143d3208) 0 nearly-empty
+ vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16u)
+ std::exception (0x0x7fbd14364d80) 0 nearly-empty
+ primary-for std::bad_function_call (0x0x7fbd143d3208)
+
+Class std::_Nocopy_types
+ size=16 align=8
+ base size=16 base align=8
+std::_Nocopy_types (0x0x7fbd14364e40) 0
+
+Class std::_Any_data
+ size=16 align=8
+ base size=16 base align=8
+std::_Any_data (0x0x7fbd14364ea0) 0
+
+Class std::_Function_base
+ size=24 align=8
+ base size=24 base align=8
+std::_Function_base (0x0x7fbd1440d000) 0
+
+Class QMapNodeBase
+ size=24 align=8
+ base size=24 base align=8
+QMapNodeBase (0x0x7fbd1440d4e0) 0
+
+Class QMapDataBase
+ size=40 align=8
+ base size=40 base align=8
+QMapDataBase (0x0x7fbd1440da20) 0
+
+Class QHashData::Node
+ size=16 align=8
+ base size=16 base align=8
+QHashData::Node (0x0x7fbd1440dde0) 0
+
+Class QHashData
+ size=48 align=8
+ base size=44 base align=8
+QHashData (0x0x7fbd1440dd80) 0
+
+Class QHashDummyValue
+ size=1 align=1
+ base size=0 base align=1
+QHashDummyValue (0x0x7fbd1440de40) 0 empty
+
+Class QVariant::PrivateShared
+ size=16 align=8
+ base size=12 base align=8
+QVariant::PrivateShared (0x0x7fbd141a3720) 0
+
+Class QVariant::Private::Data
+ size=8 align=8
+ base size=8 base align=8
+QVariant::Private::Data (0x0x7fbd141a37e0) 0
+
+Class QVariant::Private
+ size=16 align=8
+ base size=12 base align=8
+QVariant::Private (0x0x7fbd141a3780) 0
+
+Class QVariant::Handler
+ size=72 align=8
+ base size=72 base align=8
+QVariant::Handler (0x0x7fbd141a3840) 0
+
+Class QVariant
+ size=16 align=8
+ base size=16 base align=8
+QVariant (0x0x7fbd141a36c0) 0
+
+Class QVariantComparisonHelper
+ size=8 align=8
+ base size=8 base align=8
+QVariantComparisonHelper (0x0x7fbd13fec360) 0
+
+Class QSequentialIterable::const_iterator
+ size=112 align=8
+ base size=112 base align=8
+QSequentialIterable::const_iterator (0x0x7fbd13fec9c0) 0
+
+Class QSequentialIterable
+ size=104 align=8
+ base size=104 base align=8
+QSequentialIterable (0x0x7fbd13fec960) 0
+
+Class QAssociativeIterable::const_iterator
+ size=120 align=8
+ base size=120 base align=8
+QAssociativeIterable::const_iterator (0x0x7fbd13feca80) 0
+
+Class QAssociativeIterable
+ size=112 align=8
+ base size=112 base align=8
+QAssociativeIterable (0x0x7fbd13feca20) 0
+
+Class QModelIndex
+ size=24 align=8
+ base size=24 base align=8
+QModelIndex (0x0x7fbd13d1ad80) 0
+
+Class QPersistentModelIndex
+ size=8 align=8
+ base size=8 base align=8
+QPersistentModelIndex (0x0x7fbd13e49480) 0
+
+Class QAbstractItemModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractItemModel::QPrivateSignal (0x0x7fbd13ae4ba0) 0 empty
+
+Vtable for QAbstractItemModel
+QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QAbstractItemModel)
+16 (int (*)(...))QAbstractItemModel::metaObject
+24 (int (*)(...))QAbstractItemModel::qt_metacast
+32 (int (*)(...))QAbstractItemModel::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))QAbstractItemModel::sibling
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))QAbstractItemModel::hasChildren
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))QAbstractItemModel::setData
+176 (int (*)(...))QAbstractItemModel::headerData
+184 (int (*)(...))QAbstractItemModel::setHeaderData
+192 (int (*)(...))QAbstractItemModel::itemData
+200 (int (*)(...))QAbstractItemModel::setItemData
+208 (int (*)(...))QAbstractItemModel::mimeTypes
+216 (int (*)(...))QAbstractItemModel::mimeData
+224 (int (*)(...))QAbstractItemModel::canDropMimeData
+232 (int (*)(...))QAbstractItemModel::dropMimeData
+240 (int (*)(...))QAbstractItemModel::supportedDropActions
+248 (int (*)(...))QAbstractItemModel::supportedDragActions
+256 (int (*)(...))QAbstractItemModel::insertRows
+264 (int (*)(...))QAbstractItemModel::insertColumns
+272 (int (*)(...))QAbstractItemModel::removeRows
+280 (int (*)(...))QAbstractItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractItemModel::fetchMore
+312 (int (*)(...))QAbstractItemModel::canFetchMore
+320 (int (*)(...))QAbstractItemModel::flags
+328 (int (*)(...))QAbstractItemModel::sort
+336 (int (*)(...))QAbstractItemModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractItemModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractItemModel::submit
+376 (int (*)(...))QAbstractItemModel::revert
+
+Class QAbstractItemModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractItemModel (0x0x7fbd13ae3f70) 0
+ vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u)
+ QObject (0x0x7fbd13ae4b40) 0
+ primary-for QAbstractItemModel (0x0x7fbd13ae3f70)
+
+Class QAbstractTableModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractTableModel::QPrivateSignal (0x0x7fbd13ae4f00) 0 empty
+
+Vtable for QAbstractTableModel
+QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QAbstractTableModel)
+16 (int (*)(...))QAbstractTableModel::metaObject
+24 (int (*)(...))QAbstractTableModel::qt_metacast
+32 (int (*)(...))QAbstractTableModel::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAbstractTableModel::index
+120 (int (*)(...))QAbstractTableModel::parent
+128 (int (*)(...))QAbstractTableModel::sibling
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))QAbstractTableModel::hasChildren
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))QAbstractItemModel::setData
+176 (int (*)(...))QAbstractItemModel::headerData
+184 (int (*)(...))QAbstractItemModel::setHeaderData
+192 (int (*)(...))QAbstractItemModel::itemData
+200 (int (*)(...))QAbstractItemModel::setItemData
+208 (int (*)(...))QAbstractItemModel::mimeTypes
+216 (int (*)(...))QAbstractItemModel::mimeData
+224 (int (*)(...))QAbstractItemModel::canDropMimeData
+232 (int (*)(...))QAbstractTableModel::dropMimeData
+240 (int (*)(...))QAbstractItemModel::supportedDropActions
+248 (int (*)(...))QAbstractItemModel::supportedDragActions
+256 (int (*)(...))QAbstractItemModel::insertRows
+264 (int (*)(...))QAbstractItemModel::insertColumns
+272 (int (*)(...))QAbstractItemModel::removeRows
+280 (int (*)(...))QAbstractItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractItemModel::fetchMore
+312 (int (*)(...))QAbstractItemModel::canFetchMore
+320 (int (*)(...))QAbstractTableModel::flags
+328 (int (*)(...))QAbstractItemModel::sort
+336 (int (*)(...))QAbstractItemModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractItemModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractItemModel::submit
+376 (int (*)(...))QAbstractItemModel::revert
+
+Class QAbstractTableModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractTableModel (0x0x7fbd13b4c1a0) 0
+ vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u)
+ QAbstractItemModel (0x0x7fbd13b4c208) 0
+ primary-for QAbstractTableModel (0x0x7fbd13b4c1a0)
+ QObject (0x0x7fbd13ae4ea0) 0
+ primary-for QAbstractItemModel (0x0x7fbd13b4c208)
+
+Class QAbstractListModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractListModel::QPrivateSignal (0x0x7fbd13bb3000) 0 empty
+
+Vtable for QAbstractListModel
+QAbstractListModel::_ZTV18QAbstractListModel: 48u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QAbstractListModel)
+16 (int (*)(...))QAbstractListModel::metaObject
+24 (int (*)(...))QAbstractListModel::qt_metacast
+32 (int (*)(...))QAbstractListModel::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAbstractListModel::index
+120 (int (*)(...))QAbstractListModel::parent
+128 (int (*)(...))QAbstractListModel::sibling
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))QAbstractListModel::columnCount
+152 (int (*)(...))QAbstractListModel::hasChildren
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))QAbstractItemModel::setData
+176 (int (*)(...))QAbstractItemModel::headerData
+184 (int (*)(...))QAbstractItemModel::setHeaderData
+192 (int (*)(...))QAbstractItemModel::itemData
+200 (int (*)(...))QAbstractItemModel::setItemData
+208 (int (*)(...))QAbstractItemModel::mimeTypes
+216 (int (*)(...))QAbstractItemModel::mimeData
+224 (int (*)(...))QAbstractItemModel::canDropMimeData
+232 (int (*)(...))QAbstractListModel::dropMimeData
+240 (int (*)(...))QAbstractItemModel::supportedDropActions
+248 (int (*)(...))QAbstractItemModel::supportedDragActions
+256 (int (*)(...))QAbstractItemModel::insertRows
+264 (int (*)(...))QAbstractItemModel::insertColumns
+272 (int (*)(...))QAbstractItemModel::removeRows
+280 (int (*)(...))QAbstractItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractItemModel::fetchMore
+312 (int (*)(...))QAbstractItemModel::canFetchMore
+320 (int (*)(...))QAbstractListModel::flags
+328 (int (*)(...))QAbstractItemModel::sort
+336 (int (*)(...))QAbstractItemModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractItemModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractItemModel::submit
+376 (int (*)(...))QAbstractItemModel::revert
+
+Class QAbstractListModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractListModel (0x0x7fbd13b4c270) 0
+ vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u)
+ QAbstractItemModel (0x0x7fbd13b4c2d8) 0
+ primary-for QAbstractListModel (0x0x7fbd13b4c270)
+ QObject (0x0x7fbd13ae4f60) 0
+ primary-for QAbstractItemModel (0x0x7fbd13b4c2d8)
+
+Vtable for QAbstractNativeEventFilter
+QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class QAbstractNativeEventFilter
+ size=16 align=8
+ base size=16 base align=8
+QAbstractNativeEventFilter (0x0x7fbd13bb32a0) 0
+ vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u)
+
+Class QAbstractProxyModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractProxyModel::QPrivateSignal (0x0x7fbd13bb3360) 0 empty
+
+Vtable for QAbstractProxyModel
+QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QAbstractProxyModel)
+16 (int (*)(...))QAbstractProxyModel::metaObject
+24 (int (*)(...))QAbstractProxyModel::qt_metacast
+32 (int (*)(...))QAbstractProxyModel::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))QAbstractProxyModel::sibling
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))QAbstractProxyModel::hasChildren
+160 (int (*)(...))QAbstractProxyModel::data
+168 (int (*)(...))QAbstractProxyModel::setData
+176 (int (*)(...))QAbstractProxyModel::headerData
+184 (int (*)(...))QAbstractProxyModel::setHeaderData
+192 (int (*)(...))QAbstractProxyModel::itemData
+200 (int (*)(...))QAbstractProxyModel::setItemData
+208 (int (*)(...))QAbstractProxyModel::mimeTypes
+216 (int (*)(...))QAbstractProxyModel::mimeData
+224 (int (*)(...))QAbstractProxyModel::canDropMimeData
+232 (int (*)(...))QAbstractProxyModel::dropMimeData
+240 (int (*)(...))QAbstractProxyModel::supportedDropActions
+248 (int (*)(...))QAbstractProxyModel::supportedDragActions
+256 (int (*)(...))QAbstractItemModel::insertRows
+264 (int (*)(...))QAbstractItemModel::insertColumns
+272 (int (*)(...))QAbstractItemModel::removeRows
+280 (int (*)(...))QAbstractItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractProxyModel::fetchMore
+312 (int (*)(...))QAbstractProxyModel::canFetchMore
+320 (int (*)(...))QAbstractProxyModel::flags
+328 (int (*)(...))QAbstractProxyModel::sort
+336 (int (*)(...))QAbstractProxyModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractProxyModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractProxyModel::submit
+376 (int (*)(...))QAbstractProxyModel::revert
+384 (int (*)(...))QAbstractProxyModel::setSourceModel
+392 (int (*)(...))__cxa_pure_virtual
+400 (int (*)(...))__cxa_pure_virtual
+408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource
+416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource
+
+Class QAbstractProxyModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractProxyModel (0x0x7fbd13b4c410) 0
+ vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u)
+ QAbstractItemModel (0x0x7fbd13b4c478) 0
+ primary-for QAbstractProxyModel (0x0x7fbd13b4c410)
+ QObject (0x0x7fbd13bb3300) 0
+ primary-for QAbstractItemModel (0x0x7fbd13b4c478)
+
+Class QAbstractState::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractState::QPrivateSignal (0x0x7fbd13bb3420) 0 empty
+
+Vtable for QAbstractState
+QAbstractState::_ZTV14QAbstractState: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QAbstractState)
+16 (int (*)(...))QAbstractState::metaObject
+24 (int (*)(...))QAbstractState::qt_metacast
+32 (int (*)(...))QAbstractState::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QAbstractState::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+
+Class QAbstractState
+ size=16 align=8
+ base size=16 base align=8
+QAbstractState (0x0x7fbd13b4c4e0) 0
+ vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u)
+ QObject (0x0x7fbd13bb33c0) 0
+ primary-for QAbstractState (0x0x7fbd13b4c4e0)
+
+Class QAbstractTransition::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractTransition::QPrivateSignal (0x0x7fbd13bb34e0) 0 empty
+
+Vtable for QAbstractTransition
+QAbstractTransition::_ZTV19QAbstractTransition: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QAbstractTransition)
+16 (int (*)(...))QAbstractTransition::metaObject
+24 (int (*)(...))QAbstractTransition::qt_metacast
+32 (int (*)(...))QAbstractTransition::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QAbstractTransition::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+
+Class QAbstractTransition
+ size=16 align=8
+ base size=16 base align=8
+QAbstractTransition (0x0x7fbd13b4c548) 0
+ vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u)
+ QObject (0x0x7fbd13bb3480) 0
+ primary-for QAbstractTransition (0x0x7fbd13b4c548)
+
+Class QAnimationGroup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAnimationGroup::QPrivateSignal (0x0x7fbd13bb35a0) 0 empty
+
+Vtable for QAnimationGroup
+QAnimationGroup::_ZTV15QAnimationGroup: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QAnimationGroup)
+16 (int (*)(...))QAnimationGroup::metaObject
+24 (int (*)(...))QAnimationGroup::qt_metacast
+32 (int (*)(...))QAnimationGroup::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QAnimationGroup::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))QAbstractAnimation::updateState
+136 (int (*)(...))QAbstractAnimation::updateDirection
+
+Class QAnimationGroup
+ size=16 align=8
+ base size=16 base align=8
+QAnimationGroup (0x0x7fbd13b4c5b0) 0
+ vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u)
+ QAbstractAnimation (0x0x7fbd13b4c618) 0
+ primary-for QAnimationGroup (0x0x7fbd13b4c5b0)
+ QObject (0x0x7fbd13bb3540) 0
+ primary-for QAbstractAnimation (0x0x7fbd13b4c618)
+
+Class QBasicTimer
+ size=4 align=4
+ base size=4 base align=4
+QBasicTimer (0x0x7fbd13c88300) 0
+
+Class QBitArray
+ size=8 align=8
+ base size=8 base align=8
+QBitArray (0x0x7fbd13c885a0) 0
+
+Class QBitRef
+ size=16 align=8
+ base size=12 base align=8
+QBitRef (0x0x7fbd13c88660) 0
+
+Class QIODevice::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QIODevice::QPrivateSignal (0x0x7fbd13c88960) 0 empty
+
+Vtable for QIODevice
+QIODevice::_ZTV9QIODevice: 30u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QIODevice)
+16 (int (*)(...))QIODevice::metaObject
+24 (int (*)(...))QIODevice::qt_metacast
+32 (int (*)(...))QIODevice::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QIODevice::isSequential
+120 (int (*)(...))QIODevice::open
+128 (int (*)(...))QIODevice::close
+136 (int (*)(...))QIODevice::pos
+144 (int (*)(...))QIODevice::size
+152 (int (*)(...))QIODevice::seek
+160 (int (*)(...))QIODevice::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QIODevice::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))__cxa_pure_virtual
+224 (int (*)(...))QIODevice::readLineData
+232 (int (*)(...))__cxa_pure_virtual
+
+Class QIODevice
+ size=16 align=8
+ base size=16 base align=8
+QIODevice (0x0x7fbd13b4cc98) 0
+ vptr=((& QIODevice::_ZTV9QIODevice) + 16u)
+ QObject (0x0x7fbd13c88900) 0
+ primary-for QIODevice (0x0x7fbd13b4cc98)
+
+Class QBuffer::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QBuffer::QPrivateSignal (0x0x7fbd13c88ba0) 0 empty
+
+Vtable for QBuffer
+QBuffer::_ZTV7QBuffer: 30u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QBuffer)
+16 (int (*)(...))QBuffer::metaObject
+24 (int (*)(...))QBuffer::qt_metacast
+32 (int (*)(...))QBuffer::qt_metacall
+40 (int (*)(...))QBuffer::~QBuffer
+48 (int (*)(...))QBuffer::~QBuffer
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QBuffer::connectNotify
+104 (int (*)(...))QBuffer::disconnectNotify
+112 (int (*)(...))QIODevice::isSequential
+120 (int (*)(...))QBuffer::open
+128 (int (*)(...))QBuffer::close
+136 (int (*)(...))QBuffer::pos
+144 (int (*)(...))QBuffer::size
+152 (int (*)(...))QBuffer::seek
+160 (int (*)(...))QBuffer::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QBuffer::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))QBuffer::readData
+224 (int (*)(...))QIODevice::readLineData
+232 (int (*)(...))QBuffer::writeData
+
+Class QBuffer
+ size=16 align=8
+ base size=16 base align=8
+QBuffer (0x0x7fbd13b4cdd0) 0
+ vptr=((& QBuffer::_ZTV7QBuffer) + 16u)
+ QIODevice (0x0x7fbd13b4ce38) 0
+ primary-for QBuffer (0x0x7fbd13b4cdd0)
+ QObject (0x0x7fbd13c88b40) 0
+ primary-for QIODevice (0x0x7fbd13b4ce38)
+
+Class QByteArrayMatcher::Data
+ size=272 align=8
+ base size=272 base align=8
+QByteArrayMatcher::Data (0x0x7fbd13c88c60) 0
+
+Class QByteArrayMatcher
+ size=1040 align=8
+ base size=1040 base align=8
+QByteArrayMatcher (0x0x7fbd13c88c00) 0
+
+Class QStaticByteArrayMatcherBase::Skiptable
+ size=256 align=1
+ base size=256 base align=1
+QStaticByteArrayMatcherBase::Skiptable (0x0x7fbd13c88d80) 0
+
+Class QStaticByteArrayMatcherBase
+ size=256 align=16
+ base size=256 base align=16
+QStaticByteArrayMatcherBase (0x0x7fbd13c88d20) 0
+
+Class QSharedData
+ size=4 align=4
+ base size=4 base align=4
+QSharedData (0x0x7fbd13c88f60) 0
+
+Class QLocale
+ size=8 align=8
+ base size=8 base align=8
+QLocale (0x0x7fbd139b6180) 0
+
+Class QCollatorSortKey
+ size=8 align=8
+ base size=8 base align=8
+QCollatorSortKey (0x0x7fbd139b6780) 0
+
+Class QCollator
+ size=8 align=8
+ base size=8 base align=8
+QCollator (0x0x7fbd139b6840) 0
+
+Class QCommandLineOption
+ size=8 align=8
+ base size=8 base align=8
+QCommandLineOption (0x0x7fbd13709840) 0
+
+Vtable for QEvent
+QEvent::_ZTV6QEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QEvent)
+16 (int (*)(...))QEvent::~QEvent
+24 (int (*)(...))QEvent::~QEvent
+
+Class QEvent
+ size=24 align=8
+ base size=20 base align=8
+QEvent (0x0x7fbd13709cc0) 0
+ vptr=((& QEvent::_ZTV6QEvent) + 16u)
+
+Vtable for QTimerEvent
+QTimerEvent::_ZTV11QTimerEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTimerEvent)
+16 (int (*)(...))QTimerEvent::~QTimerEvent
+24 (int (*)(...))QTimerEvent::~QTimerEvent
+
+Class QTimerEvent
+ size=24 align=8
+ base size=24 base align=8
+QTimerEvent (0x0x7fbd1371d340) 0
+ vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u)
+ QEvent (0x0x7fbd13709d20) 0
+ primary-for QTimerEvent (0x0x7fbd1371d340)
+
+Vtable for QChildEvent
+QChildEvent::_ZTV11QChildEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QChildEvent)
+16 (int (*)(...))QChildEvent::~QChildEvent
+24 (int (*)(...))QChildEvent::~QChildEvent
+
+Class QChildEvent
+ size=32 align=8
+ base size=32 base align=8
+QChildEvent (0x0x7fbd1371d3a8) 0
+ vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u)
+ QEvent (0x0x7fbd13709d80) 0
+ primary-for QChildEvent (0x0x7fbd1371d3a8)
+
+Vtable for QDynamicPropertyChangeEvent
+QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent)
+16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+
+Class QDynamicPropertyChangeEvent
+ size=32 align=8
+ base size=32 base align=8
+QDynamicPropertyChangeEvent (0x0x7fbd1371d8f0) 0
+ vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u)
+ QEvent (0x0x7fbd137902a0) 0
+ primary-for QDynamicPropertyChangeEvent (0x0x7fbd1371d8f0)
+
+Vtable for QDeferredDeleteEvent
+QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent)
+16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent
+24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent
+
+Class QDeferredDeleteEvent
+ size=24 align=8
+ base size=24 base align=8
+QDeferredDeleteEvent (0x0x7fbd1371d958) 0
+ vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u)
+ QEvent (0x0x7fbd13790300) 0
+ primary-for QDeferredDeleteEvent (0x0x7fbd1371d958)
+
+Class QCoreApplication::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QCoreApplication::QPrivateSignal (0x0x7fbd137903c0) 0 empty
+
+Vtable for QCoreApplication
+QCoreApplication::_ZTV16QCoreApplication: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QCoreApplication)
+16 (int (*)(...))QCoreApplication::metaObject
+24 (int (*)(...))QCoreApplication::qt_metacast
+32 (int (*)(...))QCoreApplication::qt_metacall
+40 (int (*)(...))QCoreApplication::~QCoreApplication
+48 (int (*)(...))QCoreApplication::~QCoreApplication
+56 (int (*)(...))QCoreApplication::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QCoreApplication::notify
+120 (int (*)(...))QCoreApplication::compressEvent
+
+Class QCoreApplication
+ size=16 align=8
+ base size=16 base align=8
+QCoreApplication (0x0x7fbd1371d9c0) 0
+ vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u)
+ QObject (0x0x7fbd13790360) 0
+ primary-for QCoreApplication (0x0x7fbd1371d9c0)
+
+Class QCommandLineParser
+ size=8 align=8
+ base size=8 base align=8
+QCommandLineParser (0x0x7fbd13790420) 0
+
+Class QContiguousCacheData
+ size=24 align=4
+ base size=24 base align=4
+QContiguousCacheData (0x0x7fbd13790480) 0
+
+Class QCryptographicHash
+ size=8 align=8
+ base size=8 base align=8
+QCryptographicHash (0x0x7fbd13790a80) 0
+
+Class QDataStream
+ size=32 align=8
+ base size=32 base align=8
+QDataStream (0x0x7fbd13790ae0) 0
+
+Class QtPrivate::StreamStateSaver
+ size=16 align=8
+ base size=12 base align=8
+QtPrivate::StreamStateSaver (0x0x7fbd13790ba0) 0
+
+Class QDate
+ size=8 align=8
+ base size=8 base align=8
+QDate (0x0x7fbd134610c0) 0
+
+Class QTime
+ size=4 align=4
+ base size=4 base align=4
+QTime (0x0x7fbd13461360) 0
+
+Class QDateTime::ShortData
+ size=8 align=8
+ base size=8 base align=8
+QDateTime::ShortData (0x0x7fbd13461ae0) 0
+
+Class QDateTime::Data
+ size=8 align=8
+ base size=8 base align=8
+QDateTime::Data (0x0x7fbd13461b40) 0
+
+Class QDateTime
+ size=8 align=8
+ base size=8 base align=8
+QDateTime (0x0x7fbd13461a80) 0
+
+Class QElapsedTimer
+ size=16 align=8
+ base size=16 base align=8
+QElapsedTimer (0x0x7fbd13579c60) 0
+
+Class QDeadlineTimer
+ size=16 align=8
+ base size=16 base align=8
+QDeadlineTimer (0x0x7fbd135b5180) 0
+
+Vtable for QTextStream
+QTextStream::_ZTV11QTextStream: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTextStream)
+16 (int (*)(...))QTextStream::~QTextStream
+24 (int (*)(...))QTextStream::~QTextStream
+
+Class QTextStream
+ size=16 align=8
+ base size=16 base align=8
+QTextStream (0x0x7fbd132ea120) 0
+ vptr=((& QTextStream::_ZTV11QTextStream) + 16u)
+
+Class QTextStreamManipulator
+ size=40 align=8
+ base size=38 base align=8
+QTextStreamManipulator (0x0x7fbd132ea3c0) 0
+
+Class QtSharedPointer::NormalDeleter
+ size=1 align=1
+ base size=0 base align=1
+QtSharedPointer::NormalDeleter (0x0x7fbd132ea600) 0 empty
+
+Class QtSharedPointer::ExternalRefCountData
+ size=16 align=8
+ base size=16 base align=8
+QtSharedPointer::ExternalRefCountData (0x0x7fbd132ea780) 0
+
+Class QDebug::Stream
+ size=80 align=8
+ base size=76 base align=8
+QDebug::Stream (0x0x7fbd132eacc0) 0
+
+Class QDebug
+ size=8 align=8
+ base size=8 base align=8
+QDebug (0x0x7fbd132eac60) 0
+
+Class QDebugStateSaver
+ size=8 align=8
+ base size=8 base align=8
+QDebugStateSaver (0x0x7fbd1318a1e0) 0
+
+Class QNoDebug
+ size=1 align=1
+ base size=0 base align=1
+QNoDebug (0x0x7fbd1318a2a0) 0 empty
+
+Class QFileDevice::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFileDevice::QPrivateSignal (0x0x7fbd13231420) 0 empty
+
+Vtable for QFileDevice
+QFileDevice::_ZTV11QFileDevice: 34u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QFileDevice)
+16 (int (*)(...))QFileDevice::metaObject
+24 (int (*)(...))QFileDevice::qt_metacast
+32 (int (*)(...))QFileDevice::qt_metacall
+40 (int (*)(...))QFileDevice::~QFileDevice
+48 (int (*)(...))QFileDevice::~QFileDevice
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QFileDevice::isSequential
+120 (int (*)(...))QIODevice::open
+128 (int (*)(...))QFileDevice::close
+136 (int (*)(...))QFileDevice::pos
+144 (int (*)(...))QFileDevice::size
+152 (int (*)(...))QFileDevice::seek
+160 (int (*)(...))QFileDevice::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QIODevice::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))QFileDevice::readData
+224 (int (*)(...))QFileDevice::readLineData
+232 (int (*)(...))QFileDevice::writeData
+240 (int (*)(...))QFileDevice::fileName
+248 (int (*)(...))QFileDevice::resize
+256 (int (*)(...))QFileDevice::permissions
+264 (int (*)(...))QFileDevice::setPermissions
+
+Class QFileDevice
+ size=16 align=8
+ base size=16 base align=8
+QFileDevice (0x0x7fbd13227a90) 0
+ vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u)
+ QIODevice (0x0x7fbd13227af8) 0
+ primary-for QFileDevice (0x0x7fbd13227a90)
+ QObject (0x0x7fbd132313c0) 0
+ primary-for QIODevice (0x0x7fbd13227af8)
+
+Class QFile::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFile::QPrivateSignal (0x0x7fbd13231660) 0 empty
+
+Vtable for QFile
+QFile::_ZTV5QFile: 34u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI5QFile)
+16 (int (*)(...))QFile::metaObject
+24 (int (*)(...))QFile::qt_metacast
+32 (int (*)(...))QFile::qt_metacall
+40 (int (*)(...))QFile::~QFile
+48 (int (*)(...))QFile::~QFile
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QFileDevice::isSequential
+120 (int (*)(...))QFile::open
+128 (int (*)(...))QFileDevice::close
+136 (int (*)(...))QFileDevice::pos
+144 (int (*)(...))QFile::size
+152 (int (*)(...))QFileDevice::seek
+160 (int (*)(...))QFileDevice::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QIODevice::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))QFileDevice::readData
+224 (int (*)(...))QFileDevice::readLineData
+232 (int (*)(...))QFileDevice::writeData
+240 (int (*)(...))QFile::fileName
+248 (int (*)(...))QFile::resize
+256 (int (*)(...))QFile::permissions
+264 (int (*)(...))QFile::setPermissions
+
+Class QFile
+ size=16 align=8
+ base size=16 base align=8
+QFile (0x0x7fbd13227c30) 0
+ vptr=((& QFile::_ZTV5QFile) + 16u)
+ QFileDevice (0x0x7fbd13227c98) 0
+ primary-for QFile (0x0x7fbd13227c30)
+ QIODevice (0x0x7fbd13227d00) 0
+ primary-for QFileDevice (0x0x7fbd13227c98)
+ QObject (0x0x7fbd13231600) 0
+ primary-for QIODevice (0x0x7fbd13227d00)
+
+Class QFileInfo
+ size=8 align=8
+ base size=8 base align=8
+QFileInfo (0x0x7fbd13231840) 0
+
+Class QDir
+ size=8 align=8
+ base size=8 base align=8
+QDir (0x0x7fbd13231c60) 0
+
+Class QDirIterator
+ size=8 align=8
+ base size=8 base align=8
+QDirIterator (0x0x7fbd12f1d660) 0
+
+Class QEasingCurve
+ size=8 align=8
+ base size=8 base align=8
+QEasingCurve (0x0x7fbd12f1d8a0) 0
+
+Class QEventTransition::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QEventTransition::QPrivateSignal (0x0x7fbd13043cc0) 0 empty
+
+Vtable for QEventTransition
+QEventTransition::_ZTV16QEventTransition: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QEventTransition)
+16 (int (*)(...))QEventTransition::metaObject
+24 (int (*)(...))QEventTransition::qt_metacast
+32 (int (*)(...))QEventTransition::qt_metacall
+40 (int (*)(...))QEventTransition::~QEventTransition
+48 (int (*)(...))QEventTransition::~QEventTransition
+56 (int (*)(...))QEventTransition::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QEventTransition::eventTest
+120 (int (*)(...))QEventTransition::onTransition
+
+Class QEventTransition
+ size=16 align=8
+ base size=16 base align=8
+QEventTransition (0x0x7fbd13042d68) 0
+ vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u)
+ QAbstractTransition (0x0x7fbd13042dd0) 0
+ primary-for QEventTransition (0x0x7fbd13042d68)
+ QObject (0x0x7fbd13043c60) 0
+ primary-for QAbstractTransition (0x0x7fbd13042dd0)
+
+Vtable for QException
+QException::_ZTV10QException: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QException)
+16 (int (*)(...))QException::~QException
+24 (int (*)(...))QException::~QException
+32 (int (*)(...))std::exception::what
+40 (int (*)(...))QException::raise
+48 (int (*)(...))QException::clone
+
+Class QException
+ size=8 align=8
+ base size=8 base align=8
+QException (0x0x7fbd13042e38) 0 nearly-empty
+ vptr=((& QException::_ZTV10QException) + 16u)
+ std::exception (0x0x7fbd13043d20) 0 nearly-empty
+ primary-for QException (0x0x7fbd13042e38)
+
+Vtable for QUnhandledException
+QUnhandledException::_ZTV19QUnhandledException: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QUnhandledException)
+16 (int (*)(...))QUnhandledException::~QUnhandledException
+24 (int (*)(...))QUnhandledException::~QUnhandledException
+32 (int (*)(...))std::exception::what
+40 (int (*)(...))QUnhandledException::raise
+48 (int (*)(...))QUnhandledException::clone
+
+Class QUnhandledException
+ size=8 align=8
+ base size=8 base align=8
+QUnhandledException (0x0x7fbd13042ea0) 0 nearly-empty
+ vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u)
+ QException (0x0x7fbd13042f08) 0 nearly-empty
+ primary-for QUnhandledException (0x0x7fbd13042ea0)
+ std::exception (0x0x7fbd13043d80) 0 nearly-empty
+ primary-for QException (0x0x7fbd13042f08)
+
+Class QtPrivate::ExceptionHolder
+ size=8 align=8
+ base size=8 base align=8
+QtPrivate::ExceptionHolder (0x0x7fbd13043de0) 0
+
+Class QtPrivate::ExceptionStore
+ size=8 align=8
+ base size=8 base align=8
+QtPrivate::ExceptionStore (0x0x7fbd13043ea0) 0
+
+Vtable for QFactoryInterface
+QFactoryInterface::_ZTV17QFactoryInterface: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QFactoryInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class QFactoryInterface
+ size=8 align=8
+ base size=8 base align=8
+QFactoryInterface (0x0x7fbd13043f00) 0 nearly-empty
+ vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u)
+
+Class QFileSelector::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFileSelector::QPrivateSignal (0x0x7fbd12cc4060) 0 empty
+
+Vtable for QFileSelector
+QFileSelector::_ZTV13QFileSelector: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QFileSelector)
+16 (int (*)(...))QFileSelector::metaObject
+24 (int (*)(...))QFileSelector::qt_metacast
+32 (int (*)(...))QFileSelector::qt_metacall
+40 (int (*)(...))QFileSelector::~QFileSelector
+48 (int (*)(...))QFileSelector::~QFileSelector
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QFileSelector
+ size=16 align=8
+ base size=16 base align=8
+QFileSelector (0x0x7fbd13042f70) 0
+ vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u)
+ QObject (0x0x7fbd12cc4000) 0
+ primary-for QFileSelector (0x0x7fbd13042f70)
+
+Class QFileSystemWatcher::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFileSystemWatcher::QPrivateSignal (0x0x7fbd12cc4120) 0 empty
+
+Vtable for QFileSystemWatcher
+QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QFileSystemWatcher)
+16 (int (*)(...))QFileSystemWatcher::metaObject
+24 (int (*)(...))QFileSystemWatcher::qt_metacast
+32 (int (*)(...))QFileSystemWatcher::qt_metacall
+40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher
+48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QFileSystemWatcher
+ size=16 align=8
+ base size=16 base align=8
+QFileSystemWatcher (0x0x7fbd12cd0000) 0
+ vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u)
+ QObject (0x0x7fbd12cc40c0) 0
+ primary-for QFileSystemWatcher (0x0x7fbd12cd0000)
+
+Class QFinalState::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFinalState::QPrivateSignal (0x0x7fbd12cc41e0) 0 empty
+
+Vtable for QFinalState
+QFinalState::_ZTV11QFinalState: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QFinalState)
+16 (int (*)(...))QFinalState::metaObject
+24 (int (*)(...))QFinalState::qt_metacast
+32 (int (*)(...))QFinalState::qt_metacall
+40 (int (*)(...))QFinalState::~QFinalState
+48 (int (*)(...))QFinalState::~QFinalState
+56 (int (*)(...))QFinalState::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QFinalState::onEntry
+120 (int (*)(...))QFinalState::onExit
+
+Class QFinalState
+ size=16 align=8
+ base size=16 base align=8
+QFinalState (0x0x7fbd12cd0068) 0
+ vptr=((& QFinalState::_ZTV11QFinalState) + 16u)
+ QAbstractState (0x0x7fbd12cd00d0) 0
+ primary-for QFinalState (0x0x7fbd12cd0068)
+ QObject (0x0x7fbd12cc4180) 0
+ primary-for QAbstractState (0x0x7fbd12cd00d0)
+
+Vtable for QRunnable
+QRunnable::_ZTV9QRunnable: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QRunnable)
+16 (int (*)(...))__cxa_pure_virtual
+24 0u
+32 0u
+
+Class QRunnable
+ size=16 align=8
+ base size=12 base align=8
+QRunnable (0x0x7fbd12cc4240) 0
+ vptr=((& QRunnable::_ZTV9QRunnable) + 16u)
+
+Class QBasicMutex
+ size=8 align=8
+ base size=8 base align=8
+QBasicMutex (0x0x7fbd12cc42a0) 0
+
+Class QMutex
+ size=8 align=8
+ base size=8 base align=8
+QMutex (0x0x7fbd12cd0208) 0
+ QBasicMutex (0x0x7fbd12cc4480) 0
+
+Class QMutexLocker
+ size=8 align=8
+ base size=8 base align=8
+QMutexLocker (0x0x7fbd12cc44e0) 0
+
+Class QtPrivate::ResultItem
+ size=16 align=8
+ base size=16 base align=8
+QtPrivate::ResultItem (0x0x7fbd12cc4540) 0
+
+Class QtPrivate::ResultIteratorBase
+ size=16 align=8
+ base size=12 base align=8
+QtPrivate::ResultIteratorBase (0x0x7fbd12cc45a0) 0
+
+Vtable for QtPrivate::ResultStoreBase
+QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE)
+16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase
+24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase
+
+Class QtPrivate::ResultStoreBase
+ size=48 align=8
+ base size=44 base align=8
+QtPrivate::ResultStoreBase (0x0x7fbd12cc46c0) 0
+ vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u)
+
+Vtable for QFutureInterfaceBase
+QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QFutureInterfaceBase)
+16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase
+24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase
+
+Class QFutureInterfaceBase
+ size=16 align=8
+ base size=16 base align=8
+QFutureInterfaceBase (0x0x7fbd12cc4f00) 0
+ vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u)
+
+Class QFutureWatcherBase::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFutureWatcherBase::QPrivateSignal (0x0x7fbd12e09720) 0 empty
+
+Vtable for QFutureWatcherBase
+QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QFutureWatcherBase)
+16 (int (*)(...))QFutureWatcherBase::metaObject
+24 (int (*)(...))QFutureWatcherBase::qt_metacast
+32 (int (*)(...))QFutureWatcherBase::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QFutureWatcherBase::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QFutureWatcherBase::connectNotify
+104 (int (*)(...))QFutureWatcherBase::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+
+Class QFutureWatcherBase
+ size=16 align=8
+ base size=16 base align=8
+QFutureWatcherBase (0x0x7fbd12a57340) 0
+ vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u)
+ QObject (0x0x7fbd12e096c0) 0
+ primary-for QFutureWatcherBase (0x0x7fbd12a57340)
+
+Class QHistoryState::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QHistoryState::QPrivateSignal (0x0x7fbd12e09d20) 0 empty
+
+Vtable for QHistoryState
+QHistoryState::_ZTV13QHistoryState: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QHistoryState)
+16 (int (*)(...))QHistoryState::metaObject
+24 (int (*)(...))QHistoryState::qt_metacast
+32 (int (*)(...))QHistoryState::qt_metacall
+40 (int (*)(...))QHistoryState::~QHistoryState
+48 (int (*)(...))QHistoryState::~QHistoryState
+56 (int (*)(...))QHistoryState::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QHistoryState::onEntry
+120 (int (*)(...))QHistoryState::onExit
+
+Class QHistoryState
+ size=16 align=8
+ base size=16 base align=8
+QHistoryState (0x0x7fbd12a57c30) 0
+ vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u)
+ QAbstractState (0x0x7fbd12a57c98) 0
+ primary-for QHistoryState (0x0x7fbd12a57c30)
+ QObject (0x0x7fbd12e09cc0) 0
+ primary-for QAbstractState (0x0x7fbd12a57c98)
+
+Class QIdentityProxyModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QIdentityProxyModel::QPrivateSignal (0x0x7fbd12e09de0) 0 empty
+
+Vtable for QIdentityProxyModel
+QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QIdentityProxyModel)
+16 (int (*)(...))QIdentityProxyModel::metaObject
+24 (int (*)(...))QIdentityProxyModel::qt_metacast
+32 (int (*)(...))QIdentityProxyModel::qt_metacall
+40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel
+48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QIdentityProxyModel::index
+120 (int (*)(...))QIdentityProxyModel::parent
+128 (int (*)(...))QIdentityProxyModel::sibling
+136 (int (*)(...))QIdentityProxyModel::rowCount
+144 (int (*)(...))QIdentityProxyModel::columnCount
+152 (int (*)(...))QAbstractProxyModel::hasChildren
+160 (int (*)(...))QAbstractProxyModel::data
+168 (int (*)(...))QAbstractProxyModel::setData
+176 (int (*)(...))QIdentityProxyModel::headerData
+184 (int (*)(...))QAbstractProxyModel::setHeaderData
+192 (int (*)(...))QAbstractProxyModel::itemData
+200 (int (*)(...))QAbstractProxyModel::setItemData
+208 (int (*)(...))QAbstractProxyModel::mimeTypes
+216 (int (*)(...))QAbstractProxyModel::mimeData
+224 (int (*)(...))QAbstractProxyModel::canDropMimeData
+232 (int (*)(...))QIdentityProxyModel::dropMimeData
+240 (int (*)(...))QAbstractProxyModel::supportedDropActions
+248 (int (*)(...))QAbstractProxyModel::supportedDragActions
+256 (int (*)(...))QIdentityProxyModel::insertRows
+264 (int (*)(...))QIdentityProxyModel::insertColumns
+272 (int (*)(...))QIdentityProxyModel::removeRows
+280 (int (*)(...))QIdentityProxyModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractProxyModel::fetchMore
+312 (int (*)(...))QAbstractProxyModel::canFetchMore
+320 (int (*)(...))QAbstractProxyModel::flags
+328 (int (*)(...))QAbstractProxyModel::sort
+336 (int (*)(...))QAbstractProxyModel::buddy
+344 (int (*)(...))QIdentityProxyModel::match
+352 (int (*)(...))QAbstractProxyModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractProxyModel::submit
+376 (int (*)(...))QAbstractProxyModel::revert
+384 (int (*)(...))QIdentityProxyModel::setSourceModel
+392 (int (*)(...))QIdentityProxyModel::mapToSource
+400 (int (*)(...))QIdentityProxyModel::mapFromSource
+408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource
+416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource
+
+Class QIdentityProxyModel
+ size=16 align=8
+ base size=16 base align=8
+QIdentityProxyModel (0x0x7fbd12a57d00) 0
+ vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u)
+ QAbstractProxyModel (0x0x7fbd12a57d68) 0
+ primary-for QIdentityProxyModel (0x0x7fbd12a57d00)
+ QAbstractItemModel (0x0x7fbd12a57dd0) 0
+ primary-for QAbstractProxyModel (0x0x7fbd12a57d68)
+ QObject (0x0x7fbd12e09d80) 0
+ primary-for QAbstractItemModel (0x0x7fbd12a57dd0)
+
+Class QItemSelectionRange
+ size=16 align=8
+ base size=16 base align=8
+QItemSelectionRange (0x0x7fbd12e09e40) 0
+
+Class QItemSelectionModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QItemSelectionModel::QPrivateSignal (0x0x7fbd12b1f540) 0 empty
+
+Vtable for QItemSelectionModel
+QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QItemSelectionModel)
+16 (int (*)(...))QItemSelectionModel::metaObject
+24 (int (*)(...))QItemSelectionModel::qt_metacast
+32 (int (*)(...))QItemSelectionModel::qt_metacall
+40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel
+48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QItemSelectionModel::setCurrentIndex
+120 (int (*)(...))QItemSelectionModel::select
+128 (int (*)(...))QItemSelectionModel::select
+136 (int (*)(...))QItemSelectionModel::clear
+144 (int (*)(...))QItemSelectionModel::reset
+152 (int (*)(...))QItemSelectionModel::clearCurrentIndex
+
+Class QItemSelectionModel
+ size=16 align=8
+ base size=16 base align=8
+QItemSelectionModel (0x0x7fbd12b1e618) 0
+ vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u)
+ QObject (0x0x7fbd12b1f4e0) 0
+ primary-for QItemSelectionModel (0x0x7fbd12b1e618)
+
+Class QItemSelection
+ size=8 align=8
+ base size=8 base align=8
+QItemSelection (0x0x7fbd12b1e820) 0
+ QList<QItemSelectionRange> (0x0x7fbd12b1e888) 0
+ QListSpecialMethods<QItemSelectionRange> (0x0x7fbd12b1f840) 0 empty
+
+Class QJsonValue
+ size=24 align=8
+ base size=20 base align=8
+QJsonValue (0x0x7fbd12b1fd20) 0
+
+Class QJsonValueRef
+ size=16 align=8
+ base size=12 base align=8
+QJsonValueRef (0x0x7fbd1292a480) 0
+
+Class QJsonValuePtr
+ size=24 align=8
+ base size=24 base align=8
+QJsonValuePtr (0x0x7fbd1292a9c0) 0
+
+Class QJsonValueRefPtr
+ size=16 align=8
+ base size=16 base align=8
+QJsonValueRefPtr (0x0x7fbd1292aa20) 0
+
+Class QJsonArray::iterator
+ size=16 align=8
+ base size=12 base align=8
+QJsonArray::iterator (0x0x7fbd1292ac00) 0
+
+Class QJsonArray::const_iterator
+ size=16 align=8
+ base size=12 base align=8
+QJsonArray::const_iterator (0x0x7fbd1292ac60) 0
+
+Class QJsonArray
+ size=16 align=8
+ base size=16 base align=8
+QJsonArray (0x0x7fbd1292aba0) 0
+
+Class QJsonParseError
+ size=8 align=4
+ base size=8 base align=4
+QJsonParseError (0x0x7fbd12a2bea0) 0
+
+Class QJsonDocument
+ size=8 align=8
+ base size=8 base align=8
+QJsonDocument (0x0x7fbd12a2bf00) 0
+
+Class QJsonObject::iterator
+ size=16 align=8
+ base size=12 base align=8
+QJsonObject::iterator (0x0x7fbd1268c5a0) 0
+
+Class QJsonObject::const_iterator
+ size=16 align=8
+ base size=12 base align=8
+QJsonObject::const_iterator (0x0x7fbd1268c600) 0
+
+Class QJsonObject
+ size=16 align=8
+ base size=16 base align=8
+QJsonObject (0x0x7fbd1268c540) 0
+
+Class QLibrary::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QLibrary::QPrivateSignal (0x0x7fbd127458a0) 0 empty
+
+Vtable for QLibrary
+QLibrary::_ZTV8QLibrary: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QLibrary)
+16 (int (*)(...))QLibrary::metaObject
+24 (int (*)(...))QLibrary::qt_metacast
+32 (int (*)(...))QLibrary::qt_metacall
+40 (int (*)(...))QLibrary::~QLibrary
+48 (int (*)(...))QLibrary::~QLibrary
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QLibrary
+ size=32 align=8
+ base size=25 base align=8
+QLibrary (0x0x7fbd12742bc8) 0
+ vptr=((& QLibrary::_ZTV8QLibrary) + 16u)
+ QObject (0x0x7fbd12745840) 0
+ primary-for QLibrary (0x0x7fbd12742bc8)
+
+Class QVersionNumber::SegmentStorage
+ size=8 align=8
+ base size=8 base align=8
+QVersionNumber::SegmentStorage (0x0x7fbd12745f60) 0
+
+Class QVersionNumber
+ size=8 align=8
+ base size=8 base align=8
+QVersionNumber (0x0x7fbd12745a80) 0
+
+Class QLibraryInfo
+ size=1 align=1
+ base size=0 base align=1
+QLibraryInfo (0x0x7fbd127d6480) 0 empty
+
+Class QPoint
+ size=8 align=4
+ base size=8 base align=4
+QPoint (0x0x7fbd127d64e0) 0
+
+Class QPointF
+ size=16 align=8
+ base size=16 base align=8
+QPointF (0x0x7fbd127d6780) 0
+
+Class QLine
+ size=16 align=4
+ base size=16 base align=4
+QLine (0x0x7fbd127d6a20) 0
+
+Class QLineF
+ size=32 align=8
+ base size=32 base align=8
+QLineF (0x0x7fbd124cd3c0) 0
+
+Class QLinkedListData
+ size=32 align=8
+ base size=25 base align=8
+QLinkedListData (0x0x7fbd124cdd20) 0
+
+Class QLockFile
+ size=8 align=8
+ base size=8 base align=8
+QLockFile (0x0x7fbd125da0c0) 0
+
+Class QLoggingCategory::AtomicBools
+ size=4 align=1
+ base size=4 base align=1
+QLoggingCategory::AtomicBools (0x0x7fbd125da240) 0
+
+Class QLoggingCategory
+ size=24 align=8
+ base size=24 base align=8
+QLoggingCategory (0x0x7fbd125da1e0) 0
+
+Class QMargins
+ size=16 align=4
+ base size=16 base align=4
+QMargins (0x0x7fbd125da3c0) 0
+
+Class QMarginsF
+ size=32 align=8
+ base size=32 base align=8
+QMarginsF (0x0x7fbd125da660) 0
+
+Class QMessageAuthenticationCode
+ size=8 align=8
+ base size=8 base align=8
+QMessageAuthenticationCode (0x0x7fbd125dacc0) 0
+
+Class QMetaMethod
+ size=16 align=8
+ base size=12 base align=8
+QMetaMethod (0x0x7fbd125dad20) 0
+
+Class QMetaEnum
+ size=16 align=8
+ base size=12 base align=8
+QMetaEnum (0x0x7fbd12331360) 0
+
+Class QMetaProperty
+ size=32 align=8
+ base size=32 base align=8
+QMetaProperty (0x0x7fbd12331660) 0
+
+Class QMetaClassInfo
+ size=16 align=8
+ base size=12 base align=8
+QMetaClassInfo (0x0x7fbd123316c0) 0
+
+Class QMimeData::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QMimeData::QPrivateSignal (0x0x7fbd123319c0) 0 empty
+
+Vtable for QMimeData
+QMimeData::_ZTV9QMimeData: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QMimeData)
+16 (int (*)(...))QMimeData::metaObject
+24 (int (*)(...))QMimeData::qt_metacast
+32 (int (*)(...))QMimeData::qt_metacall
+40 (int (*)(...))QMimeData::~QMimeData
+48 (int (*)(...))QMimeData::~QMimeData
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QMimeData::hasFormat
+120 (int (*)(...))QMimeData::formats
+128 (int (*)(...))QMimeData::retrieveData
+
+Class QMimeData
+ size=16 align=8
+ base size=16 base align=8
+QMimeData (0x0x7fbd122a2e38) 0
+ vptr=((& QMimeData::_ZTV9QMimeData) + 16u)
+ QObject (0x0x7fbd12331960) 0
+ primary-for QMimeData (0x0x7fbd122a2e38)
+
+Class QMimeType
+ size=8 align=8
+ base size=8 base align=8
+QMimeType (0x0x7fbd12331a20) 0
+
+Class QMimeDatabase
+ size=8 align=8
+ base size=8 base align=8
+QMimeDatabase (0x0x7fbd12331d20) 0
+
+Class QObjectCleanupHandler::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QObjectCleanupHandler::QPrivateSignal (0x0x7fbd12331de0) 0 empty
+
+Vtable for QObjectCleanupHandler
+QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QObjectCleanupHandler)
+16 (int (*)(...))QObjectCleanupHandler::metaObject
+24 (int (*)(...))QObjectCleanupHandler::qt_metacast
+32 (int (*)(...))QObjectCleanupHandler::qt_metacall
+40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler
+48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QObjectCleanupHandler
+ size=24 align=8
+ base size=24 base align=8
+QObjectCleanupHandler (0x0x7fbd1238d068) 0
+ vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u)
+ QObject (0x0x7fbd12331d80) 0
+ primary-for QObjectCleanupHandler (0x0x7fbd1238d068)
+
+Class QOperatingSystemVersion
+ size=16 align=4
+ base size=16 base align=4
+QOperatingSystemVersion (0x0x7fbd12331e40) 0
+
+Class QParallelAnimationGroup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QParallelAnimationGroup::QPrivateSignal (0x0x7fbd123b9600) 0 empty
+
+Vtable for QParallelAnimationGroup
+QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QParallelAnimationGroup)
+16 (int (*)(...))QParallelAnimationGroup::metaObject
+24 (int (*)(...))QParallelAnimationGroup::qt_metacast
+32 (int (*)(...))QParallelAnimationGroup::qt_metacall
+40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup
+48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup
+56 (int (*)(...))QParallelAnimationGroup::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QParallelAnimationGroup::duration
+120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime
+128 (int (*)(...))QParallelAnimationGroup::updateState
+136 (int (*)(...))QParallelAnimationGroup::updateDirection
+
+Class QParallelAnimationGroup
+ size=16 align=8
+ base size=16 base align=8
+QParallelAnimationGroup (0x0x7fbd1238d7b8) 0
+ vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u)
+ QAnimationGroup (0x0x7fbd1238d820) 0
+ primary-for QParallelAnimationGroup (0x0x7fbd1238d7b8)
+ QAbstractAnimation (0x0x7fbd1238d888) 0
+ primary-for QAnimationGroup (0x0x7fbd1238d820)
+ QObject (0x0x7fbd123b95a0) 0
+ primary-for QAbstractAnimation (0x0x7fbd1238d888)
+
+Class QPauseAnimation::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPauseAnimation::QPrivateSignal (0x0x7fbd123b96c0) 0 empty
+
+Vtable for QPauseAnimation
+QPauseAnimation::_ZTV15QPauseAnimation: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QPauseAnimation)
+16 (int (*)(...))QPauseAnimation::metaObject
+24 (int (*)(...))QPauseAnimation::qt_metacast
+32 (int (*)(...))QPauseAnimation::qt_metacall
+40 (int (*)(...))QPauseAnimation::~QPauseAnimation
+48 (int (*)(...))QPauseAnimation::~QPauseAnimation
+56 (int (*)(...))QPauseAnimation::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QPauseAnimation::duration
+120 (int (*)(...))QPauseAnimation::updateCurrentTime
+128 (int (*)(...))QAbstractAnimation::updateState
+136 (int (*)(...))QAbstractAnimation::updateDirection
+
+Class QPauseAnimation
+ size=16 align=8
+ base size=16 base align=8
+QPauseAnimation (0x0x7fbd1238d8f0) 0
+ vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u)
+ QAbstractAnimation (0x0x7fbd1238d958) 0
+ primary-for QPauseAnimation (0x0x7fbd1238d8f0)
+ QObject (0x0x7fbd123b9660) 0
+ primary-for QAbstractAnimation (0x0x7fbd1238d958)
+
+Class QStaticPlugin
+ size=16 align=8
+ base size=16 base align=8
+QStaticPlugin (0x0x7fbd123b98a0) 0
+
+Class QPluginLoader::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPluginLoader::QPrivateSignal (0x0x7fbd123b9ba0) 0 empty
+
+Vtable for QPluginLoader
+QPluginLoader::_ZTV13QPluginLoader: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QPluginLoader)
+16 (int (*)(...))QPluginLoader::metaObject
+24 (int (*)(...))QPluginLoader::qt_metacast
+32 (int (*)(...))QPluginLoader::qt_metacall
+40 (int (*)(...))QPluginLoader::~QPluginLoader
+48 (int (*)(...))QPluginLoader::~QPluginLoader
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QPluginLoader
+ size=32 align=8
+ base size=25 base align=8
+QPluginLoader (0x0x7fbd1238db60) 0
+ vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u)
+ QObject (0x0x7fbd123b9b40) 0
+ primary-for QPluginLoader (0x0x7fbd1238db60)
+
+Class QProcessEnvironment
+ size=8 align=8
+ base size=8 base align=8
+QProcessEnvironment (0x0x7fbd123b9c00) 0
+
+Class QProcess::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QProcess::QPrivateSignal (0x0x7fbd1203c300) 0 empty
+
+Vtable for QProcess
+QProcess::_ZTV8QProcess: 31u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QProcess)
+16 (int (*)(...))QProcess::metaObject
+24 (int (*)(...))QProcess::qt_metacast
+32 (int (*)(...))QProcess::qt_metacall
+40 (int (*)(...))QProcess::~QProcess
+48 (int (*)(...))QProcess::~QProcess
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QProcess::isSequential
+120 (int (*)(...))QProcess::open
+128 (int (*)(...))QProcess::close
+136 (int (*)(...))QIODevice::pos
+144 (int (*)(...))QIODevice::size
+152 (int (*)(...))QIODevice::seek
+160 (int (*)(...))QProcess::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QProcess::bytesAvailable
+184 (int (*)(...))QProcess::bytesToWrite
+192 (int (*)(...))QProcess::canReadLine
+200 (int (*)(...))QProcess::waitForReadyRead
+208 (int (*)(...))QProcess::waitForBytesWritten
+216 (int (*)(...))QProcess::readData
+224 (int (*)(...))QIODevice::readLineData
+232 (int (*)(...))QProcess::writeData
+240 (int (*)(...))QProcess::setupChildProcess
+
+Class QProcess
+ size=16 align=8
+ base size=16 base align=8
+QProcess (0x0x7fbd1203f1a0) 0
+ vptr=((& QProcess::_ZTV8QProcess) + 16u)
+ QIODevice (0x0x7fbd1203f208) 0
+ primary-for QProcess (0x0x7fbd1203f1a0)
+ QObject (0x0x7fbd1203c2a0) 0
+ primary-for QIODevice (0x0x7fbd1203f208)
+
+Class QVariantAnimation::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QVariantAnimation::QPrivateSignal (0x0x7fbd1203c3c0) 0 empty
+
+Vtable for QVariantAnimation
+QVariantAnimation::_ZTV17QVariantAnimation: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QVariantAnimation)
+16 (int (*)(...))QVariantAnimation::metaObject
+24 (int (*)(...))QVariantAnimation::qt_metacast
+32 (int (*)(...))QVariantAnimation::qt_metacall
+40 (int (*)(...))QVariantAnimation::~QVariantAnimation
+48 (int (*)(...))QVariantAnimation::~QVariantAnimation
+56 (int (*)(...))QVariantAnimation::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QVariantAnimation::duration
+120 (int (*)(...))QVariantAnimation::updateCurrentTime
+128 (int (*)(...))QVariantAnimation::updateState
+136 (int (*)(...))QAbstractAnimation::updateDirection
+144 (int (*)(...))QVariantAnimation::updateCurrentValue
+152 (int (*)(...))QVariantAnimation::interpolated
+
+Class QVariantAnimation
+ size=16 align=8
+ base size=16 base align=8
+QVariantAnimation (0x0x7fbd1203f270) 0
+ vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u)
+ QAbstractAnimation (0x0x7fbd1203f2d8) 0
+ primary-for QVariantAnimation (0x0x7fbd1203f270)
+ QObject (0x0x7fbd1203c360) 0
+ primary-for QAbstractAnimation (0x0x7fbd1203f2d8)
+
+Class QPropertyAnimation::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPropertyAnimation::QPrivateSignal (0x0x7fbd1203c480) 0 empty
+
+Vtable for QPropertyAnimation
+QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QPropertyAnimation)
+16 (int (*)(...))QPropertyAnimation::metaObject
+24 (int (*)(...))QPropertyAnimation::qt_metacast
+32 (int (*)(...))QPropertyAnimation::qt_metacall
+40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation
+48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation
+56 (int (*)(...))QPropertyAnimation::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QVariantAnimation::duration
+120 (int (*)(...))QVariantAnimation::updateCurrentTime
+128 (int (*)(...))QPropertyAnimation::updateState
+136 (int (*)(...))QAbstractAnimation::updateDirection
+144 (int (*)(...))QPropertyAnimation::updateCurrentValue
+152 (int (*)(...))QVariantAnimation::interpolated
+
+Class QPropertyAnimation
+ size=16 align=8
+ base size=16 base align=8
+QPropertyAnimation (0x0x7fbd1203f3a8) 0
+ vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u)
+ QVariantAnimation (0x0x7fbd1203f410) 0
+ primary-for QPropertyAnimation (0x0x7fbd1203f3a8)
+ QAbstractAnimation (0x0x7fbd1203f478) 0
+ primary-for QVariantAnimation (0x0x7fbd1203f410)
+ QObject (0x0x7fbd1203c420) 0
+ primary-for QAbstractAnimation (0x0x7fbd1203f478)
+
+Class QRandomGenerator::Storage
+ size=2504 align=8
+ base size=2504 base align=8
+QRandomGenerator::Storage (0x0x7fbd1203c5a0) 0
+
+Class QRandomGenerator
+ size=2512 align=8
+ base size=2512 base align=8
+QRandomGenerator (0x0x7fbd1203c540) 0
+
+Class QRandomGenerator64
+ size=2512 align=8
+ base size=2512 base align=8
+QRandomGenerator64 (0x0x7fbd1211e750) 0
+ QRandomGenerator (0x0x7fbd12128540) 0
+
+Class QReadWriteLock
+ size=8 align=8
+ base size=8 base align=8
+QReadWriteLock (0x0x7fbd12128600) 0
+
+Class QReadLocker
+ size=8 align=8
+ base size=8 base align=8
+QReadLocker (0x0x7fbd121288a0) 0
+
+Class QWriteLocker
+ size=8 align=8
+ base size=8 base align=8
+QWriteLocker (0x0x7fbd12128960) 0
+
+Class QSize
+ size=8 align=4
+ base size=8 base align=4
+QSize (0x0x7fbd12128a20) 0
+
+Class QSizeF
+ size=16 align=8
+ base size=16 base align=8
+QSizeF (0x0x7fbd12128cc0) 0
+
+Class QRect
+ size=16 align=4
+ base size=16 base align=4
+QRect (0x0x7fbd12128f60) 0
+
+Class QRectF
+ size=32 align=8
+ base size=32 base align=8
+QRectF (0x0x7fbd11e87240) 0
+
+Class QRegularExpression
+ size=8 align=8
+ base size=8 base align=8
+QRegularExpression (0x0x7fbd11e874e0) 0
+
+Class QRegularExpressionMatch
+ size=8 align=8
+ base size=8 base align=8
+QRegularExpressionMatch (0x0x7fbd11e87ae0) 0
+
+Class QRegularExpressionMatchIterator
+ size=8 align=8
+ base size=8 base align=8
+QRegularExpressionMatchIterator (0x0x7fbd11e87de0) 0
+
+Class QResource
+ size=8 align=8
+ base size=8 base align=8
+QResource (0x0x7fbd11c38120) 0
+
+Class QSaveFile::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSaveFile::QPrivateSignal (0x0x7fbd11c382a0) 0 empty
+
+Vtable for QSaveFile
+QSaveFile::_ZTV9QSaveFile: 34u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QSaveFile)
+16 (int (*)(...))QSaveFile::metaObject
+24 (int (*)(...))QSaveFile::qt_metacast
+32 (int (*)(...))QSaveFile::qt_metacall
+40 (int (*)(...))QSaveFile::~QSaveFile
+48 (int (*)(...))QSaveFile::~QSaveFile
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QFileDevice::isSequential
+120 (int (*)(...))QSaveFile::open
+128 (int (*)(...))QSaveFile::close
+136 (int (*)(...))QFileDevice::pos
+144 (int (*)(...))QFileDevice::size
+152 (int (*)(...))QFileDevice::seek
+160 (int (*)(...))QFileDevice::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QIODevice::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))QFileDevice::readData
+224 (int (*)(...))QFileDevice::readLineData
+232 (int (*)(...))QSaveFile::writeData
+240 (int (*)(...))QSaveFile::fileName
+248 (int (*)(...))QFileDevice::resize
+256 (int (*)(...))QFileDevice::permissions
+264 (int (*)(...))QFileDevice::setPermissions
+
+Class QSaveFile
+ size=16 align=8
+ base size=16 base align=8
+QSaveFile (0x0x7fbd11e8b958) 0
+ vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u)
+ QFileDevice (0x0x7fbd11e8b9c0) 0
+ primary-for QSaveFile (0x0x7fbd11e8b958)
+ QIODevice (0x0x7fbd11e8ba28) 0
+ primary-for QFileDevice (0x0x7fbd11e8b9c0)
+ QObject (0x0x7fbd11c38240) 0
+ primary-for QIODevice (0x0x7fbd11e8ba28)
+
+Class QSemaphore
+ size=8 align=8
+ base size=8 base align=8
+QSemaphore (0x0x7fbd11c38360) 0
+
+Class QSemaphoreReleaser
+ size=16 align=8
+ base size=12 base align=8
+QSemaphoreReleaser (0x0x7fbd11c383c0) 0
+
+Class QSequentialAnimationGroup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSequentialAnimationGroup::QPrivateSignal (0x0x7fbd11d489c0) 0 empty
+
+Vtable for QSequentialAnimationGroup
+QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup)
+16 (int (*)(...))QSequentialAnimationGroup::metaObject
+24 (int (*)(...))QSequentialAnimationGroup::qt_metacast
+32 (int (*)(...))QSequentialAnimationGroup::qt_metacall
+40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup
+48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup
+56 (int (*)(...))QSequentialAnimationGroup::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QSequentialAnimationGroup::duration
+120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime
+128 (int (*)(...))QSequentialAnimationGroup::updateState
+136 (int (*)(...))QSequentialAnimationGroup::updateDirection
+
+Class QSequentialAnimationGroup
+ size=16 align=8
+ base size=16 base align=8
+QSequentialAnimationGroup (0x0x7fbd11d55270) 0
+ vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u)
+ QAnimationGroup (0x0x7fbd11d552d8) 0
+ primary-for QSequentialAnimationGroup (0x0x7fbd11d55270)
+ QAbstractAnimation (0x0x7fbd11d55340) 0
+ primary-for QAnimationGroup (0x0x7fbd11d552d8)
+ QObject (0x0x7fbd11d48960) 0
+ primary-for QAbstractAnimation (0x0x7fbd11d55340)
+
+Class QSettings::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSettings::QPrivateSignal (0x0x7fbd11d48a80) 0 empty
+
+Vtable for QSettings
+QSettings::_ZTV9QSettings: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QSettings)
+16 (int (*)(...))QSettings::metaObject
+24 (int (*)(...))QSettings::qt_metacast
+32 (int (*)(...))QSettings::qt_metacall
+40 (int (*)(...))QSettings::~QSettings
+48 (int (*)(...))QSettings::~QSettings
+56 (int (*)(...))QSettings::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QSettings
+ size=16 align=8
+ base size=16 base align=8
+QSettings (0x0x7fbd11d553a8) 0
+ vptr=((& QSettings::_ZTV9QSettings) + 16u)
+ QObject (0x0x7fbd11d48a20) 0
+ primary-for QSettings (0x0x7fbd11d553a8)
+
+Class QSharedMemory::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSharedMemory::QPrivateSignal (0x0x7fbd11d48b40) 0 empty
+
+Vtable for QSharedMemory
+QSharedMemory::_ZTV13QSharedMemory: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QSharedMemory)
+16 (int (*)(...))QSharedMemory::metaObject
+24 (int (*)(...))QSharedMemory::qt_metacast
+32 (int (*)(...))QSharedMemory::qt_metacall
+40 (int (*)(...))QSharedMemory::~QSharedMemory
+48 (int (*)(...))QSharedMemory::~QSharedMemory
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QSharedMemory
+ size=16 align=8
+ base size=16 base align=8
+QSharedMemory (0x0x7fbd11d55410) 0
+ vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u)
+ QObject (0x0x7fbd11d48ae0) 0
+ primary-for QSharedMemory (0x0x7fbd11d55410)
+
+Class QSignalMapper::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSignalMapper::QPrivateSignal (0x0x7fbd11d48c00) 0 empty
+
+Vtable for QSignalMapper
+QSignalMapper::_ZTV13QSignalMapper: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QSignalMapper)
+16 (int (*)(...))QSignalMapper::metaObject
+24 (int (*)(...))QSignalMapper::qt_metacast
+32 (int (*)(...))QSignalMapper::qt_metacall
+40 (int (*)(...))QSignalMapper::~QSignalMapper
+48 (int (*)(...))QSignalMapper::~QSignalMapper
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QSignalMapper
+ size=16 align=8
+ base size=16 base align=8
+QSignalMapper (0x0x7fbd11d55478) 0
+ vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u)
+ QObject (0x0x7fbd11d48ba0) 0
+ primary-for QSignalMapper (0x0x7fbd11d55478)
+
+Class QSignalTransition::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSignalTransition::QPrivateSignal (0x0x7fbd11d48cc0) 0 empty
+
+Vtable for QSignalTransition
+QSignalTransition::_ZTV17QSignalTransition: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QSignalTransition)
+16 (int (*)(...))QSignalTransition::metaObject
+24 (int (*)(...))QSignalTransition::qt_metacast
+32 (int (*)(...))QSignalTransition::qt_metacall
+40 (int (*)(...))QSignalTransition::~QSignalTransition
+48 (int (*)(...))QSignalTransition::~QSignalTransition
+56 (int (*)(...))QSignalTransition::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QSignalTransition::eventTest
+120 (int (*)(...))QSignalTransition::onTransition
+
+Class QSignalTransition
+ size=16 align=8
+ base size=16 base align=8
+QSignalTransition (0x0x7fbd11d554e0) 0
+ vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u)
+ QAbstractTransition (0x0x7fbd11d55548) 0
+ primary-for QSignalTransition (0x0x7fbd11d554e0)
+ QObject (0x0x7fbd11d48c60) 0
+ primary-for QAbstractTransition (0x0x7fbd11d55548)
+
+Class QSocketNotifier::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSocketNotifier::QPrivateSignal (0x0x7fbd11d48d80) 0 empty
+
+Vtable for QSocketNotifier
+QSocketNotifier::_ZTV15QSocketNotifier: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QSocketNotifier)
+16 (int (*)(...))QSocketNotifier::metaObject
+24 (int (*)(...))QSocketNotifier::qt_metacast
+32 (int (*)(...))QSocketNotifier::qt_metacall
+40 (int (*)(...))QSocketNotifier::~QSocketNotifier
+48 (int (*)(...))QSocketNotifier::~QSocketNotifier
+56 (int (*)(...))QSocketNotifier::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QSocketNotifier
+ size=16 align=8
+ base size=16 base align=8
+QSocketNotifier (0x0x7fbd11d555b0) 0
+ vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u)
+ QObject (0x0x7fbd11d48d20) 0
+ primary-for QSocketNotifier (0x0x7fbd11d555b0)
+
+Class QSortFilterProxyModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSortFilterProxyModel::QPrivateSignal (0x0x7fbd11d48e40) 0 empty
+
+Vtable for QSortFilterProxyModel
+QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QSortFilterProxyModel)
+16 (int (*)(...))QSortFilterProxyModel::metaObject
+24 (int (*)(...))QSortFilterProxyModel::qt_metacast
+32 (int (*)(...))QSortFilterProxyModel::qt_metacall
+40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel
+48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QSortFilterProxyModel::index
+120 (int (*)(...))QSortFilterProxyModel::parent
+128 (int (*)(...))QSortFilterProxyModel::sibling
+136 (int (*)(...))QSortFilterProxyModel::rowCount
+144 (int (*)(...))QSortFilterProxyModel::columnCount
+152 (int (*)(...))QSortFilterProxyModel::hasChildren
+160 (int (*)(...))QSortFilterProxyModel::data
+168 (int (*)(...))QSortFilterProxyModel::setData
+176 (int (*)(...))QSortFilterProxyModel::headerData
+184 (int (*)(...))QSortFilterProxyModel::setHeaderData
+192 (int (*)(...))QAbstractProxyModel::itemData
+200 (int (*)(...))QAbstractProxyModel::setItemData
+208 (int (*)(...))QSortFilterProxyModel::mimeTypes
+216 (int (*)(...))QSortFilterProxyModel::mimeData
+224 (int (*)(...))QAbstractProxyModel::canDropMimeData
+232 (int (*)(...))QSortFilterProxyModel::dropMimeData
+240 (int (*)(...))QSortFilterProxyModel::supportedDropActions
+248 (int (*)(...))QAbstractProxyModel::supportedDragActions
+256 (int (*)(...))QSortFilterProxyModel::insertRows
+264 (int (*)(...))QSortFilterProxyModel::insertColumns
+272 (int (*)(...))QSortFilterProxyModel::removeRows
+280 (int (*)(...))QSortFilterProxyModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QSortFilterProxyModel::fetchMore
+312 (int (*)(...))QSortFilterProxyModel::canFetchMore
+320 (int (*)(...))QSortFilterProxyModel::flags
+328 (int (*)(...))QSortFilterProxyModel::sort
+336 (int (*)(...))QSortFilterProxyModel::buddy
+344 (int (*)(...))QSortFilterProxyModel::match
+352 (int (*)(...))QSortFilterProxyModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractProxyModel::submit
+376 (int (*)(...))QAbstractProxyModel::revert
+384 (int (*)(...))QSortFilterProxyModel::setSourceModel
+392 (int (*)(...))QSortFilterProxyModel::mapToSource
+400 (int (*)(...))QSortFilterProxyModel::mapFromSource
+408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource
+416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource
+424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow
+432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn
+440 (int (*)(...))QSortFilterProxyModel::lessThan
+
+Class QSortFilterProxyModel
+ size=16 align=8
+ base size=16 base align=8
+QSortFilterProxyModel (0x0x7fbd11d55618) 0
+ vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u)
+ QAbstractProxyModel (0x0x7fbd11d55680) 0
+ primary-for QSortFilterProxyModel (0x0x7fbd11d55618)
+ QAbstractItemModel (0x0x7fbd11d556e8) 0
+ primary-for QAbstractProxyModel (0x0x7fbd11d55680)
+ QObject (0x0x7fbd11d48de0) 0
+ primary-for QAbstractItemModel (0x0x7fbd11d556e8)
+
+Class QStandardPaths
+ size=1 align=1
+ base size=0 base align=1
+QStandardPaths (0x0x7fbd11d48f00) 0 empty
+
+Class QState::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QState::QPrivateSignal (0x0x7fbd11e0f180) 0 empty
+
+Vtable for QState
+QState::_ZTV6QState: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QState)
+16 (int (*)(...))QState::metaObject
+24 (int (*)(...))QState::qt_metacast
+32 (int (*)(...))QState::qt_metacall
+40 (int (*)(...))QState::~QState
+48 (int (*)(...))QState::~QState
+56 (int (*)(...))QState::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QState::onEntry
+120 (int (*)(...))QState::onExit
+
+Class QState
+ size=16 align=8
+ base size=16 base align=8
+QState (0x0x7fbd11d55888) 0
+ vptr=((& QState::_ZTV6QState) + 16u)
+ QAbstractState (0x0x7fbd11d558f0) 0
+ primary-for QState (0x0x7fbd11d55888)
+ QObject (0x0x7fbd11e0f120) 0
+ primary-for QAbstractState (0x0x7fbd11d558f0)
+
+Class QStateMachine::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QStateMachine::QPrivateSignal (0x0x7fbd11e0f2a0) 0 empty
+
+Vtable for QStateMachine::SignalEvent
+QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE)
+16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent
+24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent
+
+Class QStateMachine::SignalEvent
+ size=48 align=8
+ base size=48 base align=8
+QStateMachine::SignalEvent (0x0x7fbd11d55a90) 0
+ vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u)
+ QEvent (0x0x7fbd11e0f300) 0
+ primary-for QStateMachine::SignalEvent (0x0x7fbd11d55a90)
+
+Vtable for QStateMachine::WrappedEvent
+QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE)
+16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent
+24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent
+
+Class QStateMachine::WrappedEvent
+ size=40 align=8
+ base size=40 base align=8
+QStateMachine::WrappedEvent (0x0x7fbd11d55af8) 0
+ vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u)
+ QEvent (0x0x7fbd11e0f360) 0
+ primary-for QStateMachine::WrappedEvent (0x0x7fbd11d55af8)
+
+Vtable for QStateMachine
+QStateMachine::_ZTV13QStateMachine: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QStateMachine)
+16 (int (*)(...))QStateMachine::metaObject
+24 (int (*)(...))QStateMachine::qt_metacast
+32 (int (*)(...))QStateMachine::qt_metacall
+40 (int (*)(...))QStateMachine::~QStateMachine
+48 (int (*)(...))QStateMachine::~QStateMachine
+56 (int (*)(...))QStateMachine::event
+64 (int (*)(...))QStateMachine::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QStateMachine::onEntry
+120 (int (*)(...))QStateMachine::onExit
+128 (int (*)(...))QStateMachine::beginSelectTransitions
+136 (int (*)(...))QStateMachine::endSelectTransitions
+144 (int (*)(...))QStateMachine::beginMicrostep
+152 (int (*)(...))QStateMachine::endMicrostep
+
+Class QStateMachine
+ size=16 align=8
+ base size=16 base align=8
+QStateMachine (0x0x7fbd11d55958) 0
+ vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u)
+ QState (0x0x7fbd11d559c0) 0
+ primary-for QStateMachine (0x0x7fbd11d55958)
+ QAbstractState (0x0x7fbd11d55a28) 0
+ primary-for QState (0x0x7fbd11d559c0)
+ QObject (0x0x7fbd11e0f240) 0
+ primary-for QAbstractState (0x0x7fbd11d55a28)
+
+Class QStorageInfo
+ size=8 align=8
+ base size=8 base align=8
+QStorageInfo (0x0x7fbd11e0f3c0) 0
+
+Class QAbstractConcatenable
+ size=1 align=1
+ base size=0 base align=1
+QAbstractConcatenable (0x0x7fbd11abf300) 0 empty
+
+Class QStringListModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QStringListModel::QPrivateSignal (0x0x7fbd11abfde0) 0 empty
+
+Vtable for QStringListModel
+QStringListModel::_ZTV16QStringListModel: 48u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QStringListModel)
+16 (int (*)(...))QStringListModel::metaObject
+24 (int (*)(...))QStringListModel::qt_metacast
+32 (int (*)(...))QStringListModel::qt_metacall
+40 (int (*)(...))QStringListModel::~QStringListModel
+48 (int (*)(...))QStringListModel::~QStringListModel
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAbstractListModel::index
+120 (int (*)(...))QAbstractListModel::parent
+128 (int (*)(...))QStringListModel::sibling
+136 (int (*)(...))QStringListModel::rowCount
+144 (int (*)(...))QAbstractListModel::columnCount
+152 (int (*)(...))QAbstractListModel::hasChildren
+160 (int (*)(...))QStringListModel::data
+168 (int (*)(...))QStringListModel::setData
+176 (int (*)(...))QAbstractItemModel::headerData
+184 (int (*)(...))QAbstractItemModel::setHeaderData
+192 (int (*)(...))QAbstractItemModel::itemData
+200 (int (*)(...))QAbstractItemModel::setItemData
+208 (int (*)(...))QAbstractItemModel::mimeTypes
+216 (int (*)(...))QAbstractItemModel::mimeData
+224 (int (*)(...))QAbstractItemModel::canDropMimeData
+232 (int (*)(...))QAbstractListModel::dropMimeData
+240 (int (*)(...))QStringListModel::supportedDropActions
+248 (int (*)(...))QAbstractItemModel::supportedDragActions
+256 (int (*)(...))QStringListModel::insertRows
+264 (int (*)(...))QAbstractItemModel::insertColumns
+272 (int (*)(...))QStringListModel::removeRows
+280 (int (*)(...))QAbstractItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractItemModel::fetchMore
+312 (int (*)(...))QAbstractItemModel::canFetchMore
+320 (int (*)(...))QStringListModel::flags
+328 (int (*)(...))QStringListModel::sort
+336 (int (*)(...))QAbstractItemModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractItemModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractItemModel::submit
+376 (int (*)(...))QAbstractItemModel::revert
+
+Class QStringListModel
+ size=24 align=8
+ base size=24 base align=8
+QStringListModel (0x0x7fbd11b4c000) 0
+ vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u)
+ QAbstractListModel (0x0x7fbd11b4c068) 0
+ primary-for QStringListModel (0x0x7fbd11b4c000)
+ QAbstractItemModel (0x0x7fbd11b4c0d0) 0
+ primary-for QAbstractListModel (0x0x7fbd11b4c068)
+ QObject (0x0x7fbd11abfd80) 0
+ primary-for QAbstractItemModel (0x0x7fbd11b4c0d0)
+
+Class QSystemSemaphore
+ size=8 align=8
+ base size=8 base align=8
+QSystemSemaphore (0x0x7fbd11abfe40) 0
+
+Class QTemporaryDir
+ size=8 align=8
+ base size=8 base align=8
+QTemporaryDir (0x0x7fbd11abff00) 0
+
+Class QTemporaryFile::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTemporaryFile::QPrivateSignal (0x0x7fbd11b77060) 0 empty
+
+Vtable for QTemporaryFile
+QTemporaryFile::_ZTV14QTemporaryFile: 34u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QTemporaryFile)
+16 (int (*)(...))QTemporaryFile::metaObject
+24 (int (*)(...))QTemporaryFile::qt_metacast
+32 (int (*)(...))QTemporaryFile::qt_metacall
+40 (int (*)(...))QTemporaryFile::~QTemporaryFile
+48 (int (*)(...))QTemporaryFile::~QTemporaryFile
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QFileDevice::isSequential
+120 (int (*)(...))QTemporaryFile::open
+128 (int (*)(...))QFileDevice::close
+136 (int (*)(...))QFileDevice::pos
+144 (int (*)(...))QFile::size
+152 (int (*)(...))QFileDevice::seek
+160 (int (*)(...))QFileDevice::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QIODevice::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))QFileDevice::readData
+224 (int (*)(...))QFileDevice::readLineData
+232 (int (*)(...))QFileDevice::writeData
+240 (int (*)(...))QTemporaryFile::fileName
+248 (int (*)(...))QFile::resize
+256 (int (*)(...))QFile::permissions
+264 (int (*)(...))QFile::setPermissions
+
+Class QTemporaryFile
+ size=16 align=8
+ base size=16 base align=8
+QTemporaryFile (0x0x7fbd11b4c138) 0
+ vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u)
+ QFile (0x0x7fbd11b4c1a0) 0
+ primary-for QTemporaryFile (0x0x7fbd11b4c138)
+ QFileDevice (0x0x7fbd11b4c208) 0
+ primary-for QFile (0x0x7fbd11b4c1a0)
+ QIODevice (0x0x7fbd11b4c270) 0
+ primary-for QFileDevice (0x0x7fbd11b4c208)
+ QObject (0x0x7fbd11b77000) 0
+ primary-for QIODevice (0x0x7fbd11b4c270)
+
+Class QTextBoundaryFinder
+ size=48 align=8
+ base size=48 base align=8
+QTextBoundaryFinder (0x0x7fbd11b770c0) 0
+
+Class QTextCodec::ConverterState
+ size=32 align=8
+ base size=32 base align=8
+QTextCodec::ConverterState (0x0x7fbd11b77300) 0
+
+Vtable for QTextCodec
+QTextCodec::_ZTV10QTextCodec: 9u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTextCodec)
+16 (int (*)(...))__cxa_pure_virtual
+24 (int (*)(...))QTextCodec::aliases
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 0u
+64 0u
+
+Class QTextCodec
+ size=8 align=8
+ base size=8 base align=8
+QTextCodec (0x0x7fbd11b772a0) 0 nearly-empty
+ vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u)
+
+Class QTextEncoder
+ size=40 align=8
+ base size=40 base align=8
+QTextEncoder (0x0x7fbd11b774e0) 0
+
+Class QTextDecoder
+ size=40 align=8
+ base size=40 base align=8
+QTextDecoder (0x0x7fbd11b77540) 0
+
+Class std::__mutex_base
+ size=40 align=8
+ base size=40 base align=8
+std::__mutex_base (0x0x7fbd11b775a0) 0
+
+Class std::__recursive_mutex_base
+ size=40 align=8
+ base size=40 base align=8
+std::__recursive_mutex_base (0x0x7fbd11b77600) 0
+
+Class std::mutex
+ size=40 align=8
+ base size=40 base align=8
+std::mutex (0x0x7fbd11b4c478) 0
+ std::__mutex_base (0x0x7fbd11b77660) 0
+
+Class std::recursive_mutex
+ size=40 align=8
+ base size=40 base align=8
+std::recursive_mutex (0x0x7fbd11b4c4e0) 0
+ std::__recursive_mutex_base (0x0x7fbd11b776c0) 0
+
+Class std::timed_mutex
+ size=40 align=8
+ base size=40 base align=8
+std::timed_mutex (0x0x7fbd1183f000) 0
+ std::__mutex_base (0x0x7fbd11b777e0) 0
+ std::__timed_mutex_impl<std::timed_mutex> (0x0x7fbd11b77840) 0 empty
+
+Class std::recursive_timed_mutex
+ size=40 align=8
+ base size=40 base align=8
+std::recursive_timed_mutex (0x0x7fbd1183fc40) 0
+ std::__recursive_mutex_base (0x0x7fbd11b77900) 0
+ std::__timed_mutex_impl<std::recursive_timed_mutex> (0x0x7fbd11b77960) 0 empty
+
+Class std::defer_lock_t
+ size=1 align=1
+ base size=0 base align=1
+std::defer_lock_t (0x0x7fbd11b779c0) 0 empty
+
+Class std::try_to_lock_t
+ size=1 align=1
+ base size=0 base align=1
+std::try_to_lock_t (0x0x7fbd11b77a20) 0 empty
+
+Class std::adopt_lock_t
+ size=1 align=1
+ base size=0 base align=1
+std::adopt_lock_t (0x0x7fbd11b77a80) 0 empty
+
+Class std::once_flag
+ size=4 align=4
+ base size=4 base align=4
+std::once_flag (0x0x7fbd11b77cc0) 0
+
+Vtable for __gnu_cxx::__concurrence_lock_error
+__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE)
+16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error
+24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error
+32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what
+
+Class __gnu_cxx::__concurrence_lock_error
+ size=8 align=8
+ base size=8 base align=8
+__gnu_cxx::__concurrence_lock_error (0x0x7fbd11b4c618) 0 nearly-empty
+ vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16u)
+ std::exception (0x0x7fbd11b77d80) 0 nearly-empty
+ primary-for __gnu_cxx::__concurrence_lock_error (0x0x7fbd11b4c618)
+
+Vtable for __gnu_cxx::__concurrence_unlock_error
+__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE)
+16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error
+24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error
+32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what
+
+Class __gnu_cxx::__concurrence_unlock_error
+ size=8 align=8
+ base size=8 base align=8
+__gnu_cxx::__concurrence_unlock_error (0x0x7fbd11b4c680) 0 nearly-empty
+ vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16u)
+ std::exception (0x0x7fbd11b77e40) 0 nearly-empty
+ primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7fbd11b4c680)
+
+Vtable for __gnu_cxx::__concurrence_broadcast_error
+__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE)
+16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error
+24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error
+32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what
+
+Class __gnu_cxx::__concurrence_broadcast_error
+ size=8 align=8
+ base size=8 base align=8
+__gnu_cxx::__concurrence_broadcast_error (0x0x7fbd11b4c6e8) 0 nearly-empty
+ vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16u)
+ std::exception (0x0x7fbd11b77f00) 0 nearly-empty
+ primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7fbd11b4c6e8)
+
+Vtable for __gnu_cxx::__concurrence_wait_error
+__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE)
+16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error
+24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error
+32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what
+
+Class __gnu_cxx::__concurrence_wait_error
+ size=8 align=8
+ base size=8 base align=8
+__gnu_cxx::__concurrence_wait_error (0x0x7fbd11b4c7b8) 0 nearly-empty
+ vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16u)
+ std::exception (0x0x7fbd118ab000) 0 nearly-empty
+ primary-for __gnu_cxx::__concurrence_wait_error (0x0x7fbd11b4c7b8)
+
+Class __gnu_cxx::__mutex
+ size=40 align=8
+ base size=40 base align=8
+__gnu_cxx::__mutex (0x0x7fbd118ab0c0) 0
+
+Class __gnu_cxx::__recursive_mutex
+ size=40 align=8
+ base size=40 base align=8
+__gnu_cxx::__recursive_mutex (0x0x7fbd118ab120) 0
+
+Class __gnu_cxx::__scoped_lock
+ size=8 align=8
+ base size=8 base align=8
+__gnu_cxx::__scoped_lock (0x0x7fbd118ab180) 0
+
+Class __gnu_cxx::__cond
+ size=48 align=8
+ base size=48 base align=8
+__gnu_cxx::__cond (0x0x7fbd118ab1e0) 0
+
+Vtable for std::bad_weak_ptr
+std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt12bad_weak_ptr)
+16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr
+24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr
+32 (int (*)(...))std::bad_weak_ptr::what
+
+Class std::bad_weak_ptr
+ size=8 align=8
+ base size=8 base align=8
+std::bad_weak_ptr (0x0x7fbd11b4ca90) 0 nearly-empty
+ vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16u)
+ std::exception (0x0x7fbd118ab540) 0 nearly-empty
+ primary-for std::bad_weak_ptr (0x0x7fbd11b4ca90)
+
+Class std::_Sp_make_shared_tag
+ size=1 align=1
+ base size=0 base align=1
+std::_Sp_make_shared_tag (0x0x7fbd118abd80) 0 empty
+
+Class std::_Sp_locker
+ size=2 align=1
+ base size=2 base align=1
+std::_Sp_locker (0x0x7fbd115515a0) 0
+
+Class std::thread::id
+ size=8 align=8
+ base size=8 base align=8
+std::thread::id (0x0x7fbd11551780) 0
+
+Vtable for std::thread::_Impl_base
+std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt6thread10_Impl_baseE)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class std::thread::_Impl_base
+ size=24 align=8
+ base size=24 base align=8
+std::thread::_Impl_base (0x0x7fbd115517e0) 0
+ vptr=((& std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE) + 16u)
+
+Class std::thread
+ size=8 align=8
+ base size=8 base align=8
+std::thread (0x0x7fbd11551720) 0
+
+Class std::condition_variable
+ size=48 align=8
+ base size=48 base align=8
+std::condition_variable (0x0x7fbd1135d420) 0
+
+Class std::__at_thread_exit_elt
+ size=16 align=8
+ base size=16 base align=8
+std::__at_thread_exit_elt (0x0x7fbd1135d4e0) 0
+
+Class std::_V2::condition_variable_any
+ size=64 align=8
+ base size=64 base align=8
+std::_V2::condition_variable_any (0x0x7fbd1135d540) 0
+
+Class std::__atomic_futex_unsigned_base
+ size=1 align=1
+ base size=0 base align=1
+std::__atomic_futex_unsigned_base (0x0x7fbd11419ba0) 0 empty
+
+Vtable for std::future_error
+std::future_error::_ZTVSt12future_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt12future_error)
+16 (int (*)(...))std::future_error::~future_error
+24 (int (*)(...))std::future_error::~future_error
+32 (int (*)(...))std::future_error::what
+
+Class std::future_error
+ size=32 align=8
+ base size=32 base align=8
+std::future_error (0x0x7fbd11421dd0) 0
+ vptr=((& std::future_error::_ZTVSt12future_error) + 16u)
+ std::logic_error (0x0x7fbd11421e38) 0
+ primary-for std::future_error (0x0x7fbd11421dd0)
+ std::exception (0x0x7fbd11419cc0) 0 nearly-empty
+ primary-for std::logic_error (0x0x7fbd11421e38)
+
+Class std::__future_base::_Result_base::_Deleter
+ size=1 align=1
+ base size=0 base align=1
+std::__future_base::_Result_base::_Deleter (0x0x7fbd11419de0) 0 empty
+
+Vtable for std::__future_base::_Result_base
+std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE)
+16 (int (*)(...))__cxa_pure_virtual
+24 0u
+32 0u
+
+Class std::__future_base::_Result_base
+ size=16 align=8
+ base size=16 base align=8
+std::__future_base::_Result_base (0x0x7fbd11419d80) 0
+ vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16u)
+
+Class std::__future_base::_State_baseV2::__exception_ptr_tag
+ size=1 align=1
+ base size=0 base align=1
+std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7fbd11190360) 0 empty
+
+Class std::__future_base::_State_baseV2::_Make_ready
+ size=32 align=8
+ base size=32 base align=8
+std::__future_base::_State_baseV2::_Make_ready (0x0x7fbd1118c410) 0
+ std::__at_thread_exit_elt (0x0x7fbd11190420) 0
+
+Vtable for std::__future_base::_State_baseV2
+std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E)
+16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2
+24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2
+32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async
+40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future
+
+Class std::__future_base::_State_baseV2
+ size=32 align=8
+ base size=28 base align=8
+std::__future_base::_State_baseV2 (0x0x7fbd11419f60) 0
+ vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16u)
+
+Class std::__future_base
+ size=1 align=1
+ base size=0 base align=1
+std::__future_base (0x0x7fbd11419d20) 0 empty
+
+Vtable for std::__future_base::_Async_state_commonV2
+std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E)
+16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2
+24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2
+32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async
+40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future
+
+Class std::__future_base::_Async_state_commonV2
+ size=48 align=8
+ base size=44 base align=8
+std::__future_base::_Async_state_commonV2 (0x0x7fbd10b2b000) 0
+ vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16u)
+ std::__future_base::_State_baseV2 (0x0x7fbd10ef8300) 0
+ primary-for std::__future_base::_Async_state_commonV2 (0x0x7fbd10b2b000)
+
+Class QThread::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QThread::QPrivateSignal (0x0x7fbd10ef8a20) 0 empty
+
+Vtable for QThread
+QThread::_ZTV7QThread: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QThread)
+16 (int (*)(...))QThread::metaObject
+24 (int (*)(...))QThread::qt_metacast
+32 (int (*)(...))QThread::qt_metacall
+40 (int (*)(...))QThread::~QThread
+48 (int (*)(...))QThread::~QThread
+56 (int (*)(...))QThread::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QThread::run
+
+Class QThread
+ size=16 align=8
+ base size=16 base align=8
+QThread (0x0x7fbd10b2ba90) 0
+ vptr=((& QThread::_ZTV7QThread) + 16u)
+ QObject (0x0x7fbd10ef89c0) 0
+ primary-for QThread (0x0x7fbd10b2ba90)
+
+Class QThreadPool::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QThreadPool::QPrivateSignal (0x0x7fbd10ef8b40) 0 empty
+
+Vtable for QThreadPool
+QThreadPool::_ZTV11QThreadPool: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QThreadPool)
+16 (int (*)(...))QThreadPool::metaObject
+24 (int (*)(...))QThreadPool::qt_metacast
+32 (int (*)(...))QThreadPool::qt_metacall
+40 (int (*)(...))QThreadPool::~QThreadPool
+48 (int (*)(...))QThreadPool::~QThreadPool
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QThreadPool
+ size=16 align=8
+ base size=16 base align=8
+QThreadPool (0x0x7fbd10b2baf8) 0
+ vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u)
+ QObject (0x0x7fbd10ef8ae0) 0
+ primary-for QThreadPool (0x0x7fbd10b2baf8)
+
+Class QThreadStorageData
+ size=4 align=4
+ base size=4 base align=4
+QThreadStorageData (0x0x7fbd10ef8ba0) 0
+
+Class QTimeLine::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTimeLine::QPrivateSignal (0x0x7fbd10ef8cc0) 0 empty
+
+Vtable for QTimeLine
+QTimeLine::_ZTV9QTimeLine: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QTimeLine)
+16 (int (*)(...))QTimeLine::metaObject
+24 (int (*)(...))QTimeLine::qt_metacast
+32 (int (*)(...))QTimeLine::qt_metacall
+40 (int (*)(...))QTimeLine::~QTimeLine
+48 (int (*)(...))QTimeLine::~QTimeLine
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QTimeLine::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QTimeLine::valueForTime
+
+Class QTimeLine
+ size=16 align=8
+ base size=16 base align=8
+QTimeLine (0x0x7fbd10b2bb60) 0
+ vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u)
+ QObject (0x0x7fbd10ef8c60) 0
+ primary-for QTimeLine (0x0x7fbd10b2bb60)
+
+Class QTimer::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTimer::QPrivateSignal (0x0x7fbd10ef8d80) 0 empty
+
+Vtable for QTimer
+QTimer::_ZTV6QTimer: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QTimer)
+16 (int (*)(...))QTimer::metaObject
+24 (int (*)(...))QTimer::qt_metacast
+32 (int (*)(...))QTimer::qt_metacall
+40 (int (*)(...))QTimer::~QTimer
+48 (int (*)(...))QTimer::~QTimer
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QTimer::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QTimer
+ size=32 align=8
+ base size=29 base align=8
+QTimer (0x0x7fbd10b2bbc8) 0
+ vptr=((& QTimer::_ZTV6QTimer) + 16u)
+ QObject (0x0x7fbd10ef8d20) 0
+ primary-for QTimer (0x0x7fbd10b2bbc8)
+
+Class QTimeZone::OffsetData
+ size=32 align=8
+ base size=28 base align=8
+QTimeZone::OffsetData (0x0x7fbd10be8480) 0
+
+Class QTimeZone
+ size=8 align=8
+ base size=8 base align=8
+QTimeZone (0x0x7fbd10be8420) 0
+
+Class QTranslator::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTranslator::QPrivateSignal (0x0x7fbd10be8a20) 0 empty
+
+Vtable for QTranslator
+QTranslator::_ZTV11QTranslator: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTranslator)
+16 (int (*)(...))QTranslator::metaObject
+24 (int (*)(...))QTranslator::qt_metacast
+32 (int (*)(...))QTranslator::qt_metacall
+40 (int (*)(...))QTranslator::~QTranslator
+48 (int (*)(...))QTranslator::~QTranslator
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QTranslator::translate
+120 (int (*)(...))QTranslator::isEmpty
+
+Class QTranslator
+ size=16 align=8
+ base size=16 base align=8
+QTranslator (0x0x7fbd10bee618) 0
+ vptr=((& QTranslator::_ZTV11QTranslator) + 16u)
+ QObject (0x0x7fbd10be89c0) 0
+ primary-for QTranslator (0x0x7fbd10bee618)
+
+Class QUrl
+ size=8 align=8
+ base size=8 base align=8
+QUrl (0x0x7fbd10be8b40) 0
+
+Class QUrlQuery
+ size=8 align=8
+ base size=8 base align=8
+QUrlQuery (0x0x7fbd1094c240) 0
+
+Class QUuid
+ size=16 align=4
+ base size=16 base align=4
+QUuid (0x0x7fbd1094c8a0) 0
+
+Class QWaitCondition
+ size=8 align=8
+ base size=8 base align=8
+QWaitCondition (0x0x7fbd1094cea0) 0
+
+Class QXmlStreamStringRef
+ size=16 align=8
+ base size=16 base align=8
+QXmlStreamStringRef (0x0x7fbd1094cf00) 0
+
+Class QXmlStreamAttribute
+ size=80 align=8
+ base size=73 base align=8
+QXmlStreamAttribute (0x0x7fbd10a41240) 0
+
+Class QXmlStreamAttributes
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamAttributes (0x0x7fbd10a91068) 0
+ QVector<QXmlStreamAttribute> (0x0x7fbd10a41600) 0
+
+Class QXmlStreamNamespaceDeclaration
+ size=40 align=8
+ base size=40 base align=8
+QXmlStreamNamespaceDeclaration (0x0x7fbd10a41660) 0
+
+Class QXmlStreamNotationDeclaration
+ size=56 align=8
+ base size=56 base align=8
+QXmlStreamNotationDeclaration (0x0x7fbd10a41900) 0
+
+Class QXmlStreamEntityDeclaration
+ size=88 align=8
+ base size=88 base align=8
+QXmlStreamEntityDeclaration (0x0x7fbd10a41ba0) 0
+
+Vtable for QXmlStreamEntityResolver
+QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver)
+16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity
+40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity
+
+Class QXmlStreamEntityResolver
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamEntityResolver (0x0x7fbd10a41e40) 0 nearly-empty
+ vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u)
+
+Class QXmlStreamReader
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamReader (0x0x7fbd10a41ea0) 0
+
+Class QXmlStreamWriter
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamWriter (0x0x7fbd10747900) 0
+
+Class QNetworkRequest
+ size=8 align=8
+ base size=8 base align=8
+QNetworkRequest (0x0x7fbd10747a20) 0
+
+Class QNetworkCacheMetaData
+ size=8 align=8
+ base size=8 base align=8
+QNetworkCacheMetaData (0x0x7fbd10747f60) 0
+
+Class QAbstractNetworkCache::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractNetworkCache::QPrivateSignal (0x0x7fbd107d6660) 0 empty
+
+Vtable for QAbstractNetworkCache
+QAbstractNetworkCache::_ZTV21QAbstractNetworkCache: 22u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QAbstractNetworkCache)
+16 (int (*)(...))QAbstractNetworkCache::metaObject
+24 (int (*)(...))QAbstractNetworkCache::qt_metacast
+32 (int (*)(...))QAbstractNetworkCache::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))__cxa_pure_virtual
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))__cxa_pure_virtual
+
+Class QAbstractNetworkCache
+ size=16 align=8
+ base size=16 base align=8
+QAbstractNetworkCache (0x0x7fbd107769c0) 0
+ vptr=((& QAbstractNetworkCache::_ZTV21QAbstractNetworkCache) + 16u)
+ QObject (0x0x7fbd107d6600) 0
+ primary-for QAbstractNetworkCache (0x0x7fbd107769c0)
+
+Class QAbstractSocket::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractSocket::QPrivateSignal (0x0x7fbd107d6720) 0 empty
+
+Vtable for QAbstractSocket
+QAbstractSocket::_ZTV15QAbstractSocket: 41u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QAbstractSocket)
+16 (int (*)(...))QAbstractSocket::metaObject
+24 (int (*)(...))QAbstractSocket::qt_metacast
+32 (int (*)(...))QAbstractSocket::qt_metacall
+40 (int (*)(...))QAbstractSocket::~QAbstractSocket
+48 (int (*)(...))QAbstractSocket::~QAbstractSocket
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAbstractSocket::isSequential
+120 (int (*)(...))QIODevice::open
+128 (int (*)(...))QAbstractSocket::close
+136 (int (*)(...))QIODevice::pos
+144 (int (*)(...))QIODevice::size
+152 (int (*)(...))QIODevice::seek
+160 (int (*)(...))QAbstractSocket::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QAbstractSocket::bytesAvailable
+184 (int (*)(...))QAbstractSocket::bytesToWrite
+192 (int (*)(...))QAbstractSocket::canReadLine
+200 (int (*)(...))QAbstractSocket::waitForReadyRead
+208 (int (*)(...))QAbstractSocket::waitForBytesWritten
+216 (int (*)(...))QAbstractSocket::readData
+224 (int (*)(...))QAbstractSocket::readLineData
+232 (int (*)(...))QAbstractSocket::writeData
+240 (int (*)(...))QAbstractSocket::resume
+248 (int (*)(...))QAbstractSocket::connectToHost
+256 (int (*)(...))QAbstractSocket::connectToHost
+264 (int (*)(...))QAbstractSocket::disconnectFromHost
+272 (int (*)(...))QAbstractSocket::setReadBufferSize
+280 (int (*)(...))QAbstractSocket::socketDescriptor
+288 (int (*)(...))QAbstractSocket::setSocketDescriptor
+296 (int (*)(...))QAbstractSocket::setSocketOption
+304 (int (*)(...))QAbstractSocket::socketOption
+312 (int (*)(...))QAbstractSocket::waitForConnected
+320 (int (*)(...))QAbstractSocket::waitForDisconnected
+
+Class QAbstractSocket
+ size=16 align=8
+ base size=16 base align=8
+QAbstractSocket (0x0x7fbd10776a28) 0
+ vptr=((& QAbstractSocket::_ZTV15QAbstractSocket) + 16u)
+ QIODevice (0x0x7fbd10776a90) 0
+ primary-for QAbstractSocket (0x0x7fbd10776a28)
+ QObject (0x0x7fbd107d66c0) 0
+ primary-for QIODevice (0x0x7fbd10776a90)
+
+Class QAuthenticator
+ size=8 align=8
+ base size=8 base align=8
+QAuthenticator (0x0x7fbd107d6cc0) 0
+
+Class QDnsDomainNameRecord
+ size=8 align=8
+ base size=8 base align=8
+QDnsDomainNameRecord (0x0x7fbd107d6d20) 0
+
+Class QDnsHostAddressRecord
+ size=8 align=8
+ base size=8 base align=8
+QDnsHostAddressRecord (0x0x7fbd108c7060) 0
+
+Class QDnsMailExchangeRecord
+ size=8 align=8
+ base size=8 base align=8
+QDnsMailExchangeRecord (0x0x7fbd108c7360) 0
+
+Class QDnsServiceRecord
+ size=8 align=8
+ base size=8 base align=8
+QDnsServiceRecord (0x0x7fbd108c7660) 0
+
+Class QDnsTextRecord
+ size=8 align=8
+ base size=8 base align=8
+QDnsTextRecord (0x0x7fbd108c7960) 0
+
+Class QDnsLookup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDnsLookup::QPrivateSignal (0x0x7fbd108c7cc0) 0 empty
+
+Vtable for QDnsLookup
+QDnsLookup::_ZTV10QDnsLookup: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QDnsLookup)
+16 (int (*)(...))QDnsLookup::metaObject
+24 (int (*)(...))QDnsLookup::qt_metacast
+32 (int (*)(...))QDnsLookup::qt_metacall
+40 (int (*)(...))QDnsLookup::~QDnsLookup
+48 (int (*)(...))QDnsLookup::~QDnsLookup
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QDnsLookup
+ size=16 align=8
+ base size=16 base align=8
+QDnsLookup (0x0x7fbd108f84e0) 0
+ vptr=((& QDnsLookup::_ZTV10QDnsLookup) + 16u)
+ QObject (0x0x7fbd108c7c60) 0
+ primary-for QDnsLookup (0x0x7fbd108f84e0)
+
+Class QIPv6Address
+ size=16 align=1
+ base size=16 base align=1
+QIPv6Address (0x0x7fbd108c7d20) 0
+
+Class QHostAddress
+ size=8 align=8
+ base size=8 base align=8
+QHostAddress (0x0x7fbd108c7d80) 0
+
+Class QHostInfo
+ size=8 align=8
+ base size=8 base align=8
+QHostInfo (0x0x7fbd1059f5a0) 0
+
+Class QHstsPolicy
+ size=8 align=8
+ base size=8 base align=8
+QHstsPolicy (0x0x7fbd1059fa80) 0
+
+Class QHttpPart
+ size=8 align=8
+ base size=8 base align=8
+QHttpPart (0x0x7fbd106332a0) 0
+
+Class QHttpMultiPart::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QHttpMultiPart::QPrivateSignal (0x0x7fbd10633600) 0 empty
+
+Vtable for QHttpMultiPart
+QHttpMultiPart::_ZTV14QHttpMultiPart: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QHttpMultiPart)
+16 (int (*)(...))QHttpMultiPart::metaObject
+24 (int (*)(...))QHttpMultiPart::qt_metacast
+32 (int (*)(...))QHttpMultiPart::qt_metacall
+40 (int (*)(...))QHttpMultiPart::~QHttpMultiPart
+48 (int (*)(...))QHttpMultiPart::~QHttpMultiPart
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QHttpMultiPart
+ size=16 align=8
+ base size=16 base align=8
+QHttpMultiPart (0x0x7fbd10603750) 0
+ vptr=((& QHttpMultiPart::_ZTV14QHttpMultiPart) + 16u)
+ QObject (0x0x7fbd106335a0) 0
+ primary-for QHttpMultiPart (0x0x7fbd10603750)
+
+Class QLocalServer::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QLocalServer::QPrivateSignal (0x0x7fbd106336c0) 0 empty
+
+Vtable for QLocalServer
+QLocalServer::_ZTV12QLocalServer: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QLocalServer)
+16 (int (*)(...))QLocalServer::metaObject
+24 (int (*)(...))QLocalServer::qt_metacast
+32 (int (*)(...))QLocalServer::qt_metacall
+40 (int (*)(...))QLocalServer::~QLocalServer
+48 (int (*)(...))QLocalServer::~QLocalServer
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QLocalServer::hasPendingConnections
+120 (int (*)(...))QLocalServer::nextPendingConnection
+128 (int (*)(...))QLocalServer::incomingConnection
+
+Class QLocalServer
+ size=16 align=8
+ base size=16 base align=8
+QLocalServer (0x0x7fbd106037b8) 0
+ vptr=((& QLocalServer::_ZTV12QLocalServer) + 16u)
+ QObject (0x0x7fbd10633660) 0
+ primary-for QLocalServer (0x0x7fbd106037b8)
+
+Class QLocalSocket::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QLocalSocket::QPrivateSignal (0x0x7fbd10633900) 0 empty
+
+Vtable for QLocalSocket
+QLocalSocket::_ZTV12QLocalSocket: 30u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QLocalSocket)
+16 (int (*)(...))QLocalSocket::metaObject
+24 (int (*)(...))QLocalSocket::qt_metacast
+32 (int (*)(...))QLocalSocket::qt_metacall
+40 (int (*)(...))QLocalSocket::~QLocalSocket
+48 (int (*)(...))QLocalSocket::~QLocalSocket
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QLocalSocket::isSequential
+120 (int (*)(...))QLocalSocket::open
+128 (int (*)(...))QLocalSocket::close
+136 (int (*)(...))QIODevice::pos
+144 (int (*)(...))QIODevice::size
+152 (int (*)(...))QIODevice::seek
+160 (int (*)(...))QIODevice::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QLocalSocket::bytesAvailable
+184 (int (*)(...))QLocalSocket::bytesToWrite
+192 (int (*)(...))QLocalSocket::canReadLine
+200 (int (*)(...))QLocalSocket::waitForReadyRead
+208 (int (*)(...))QLocalSocket::waitForBytesWritten
+216 (int (*)(...))QLocalSocket::readData
+224 (int (*)(...))QIODevice::readLineData
+232 (int (*)(...))QLocalSocket::writeData
+
+Class QLocalSocket
+ size=16 align=8
+ base size=16 base align=8
+QLocalSocket (0x0x7fbd10603958) 0
+ vptr=((& QLocalSocket::_ZTV12QLocalSocket) + 16u)
+ QIODevice (0x0x7fbd106039c0) 0
+ primary-for QLocalSocket (0x0x7fbd10603958)
+ QObject (0x0x7fbd106338a0) 0
+ primary-for QIODevice (0x0x7fbd106039c0)
+
+Class QTcpSocket::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTcpSocket::QPrivateSignal (0x0x7fbd106339c0) 0 empty
+
+Vtable for QTcpSocket
+QTcpSocket::_ZTV10QTcpSocket: 41u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTcpSocket)
+16 (int (*)(...))QTcpSocket::metaObject
+24 (int (*)(...))QTcpSocket::qt_metacast
+32 (int (*)(...))QTcpSocket::qt_metacall
+40 (int (*)(...))QTcpSocket::~QTcpSocket
+48 (int (*)(...))QTcpSocket::~QTcpSocket
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAbstractSocket::isSequential
+120 (int (*)(...))QIODevice::open
+128 (int (*)(...))QAbstractSocket::close
+136 (int (*)(...))QIODevice::pos
+144 (int (*)(...))QIODevice::size
+152 (int (*)(...))QIODevice::seek
+160 (int (*)(...))QAbstractSocket::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QAbstractSocket::bytesAvailable
+184 (int (*)(...))QAbstractSocket::bytesToWrite
+192 (int (*)(...))QAbstractSocket::canReadLine
+200 (int (*)(...))QAbstractSocket::waitForReadyRead
+208 (int (*)(...))QAbstractSocket::waitForBytesWritten
+216 (int (*)(...))QAbstractSocket::readData
+224 (int (*)(...))QAbstractSocket::readLineData
+232 (int (*)(...))QAbstractSocket::writeData
+240 (int (*)(...))QAbstractSocket::resume
+248 (int (*)(...))QAbstractSocket::connectToHost
+256 (int (*)(...))QAbstractSocket::connectToHost
+264 (int (*)(...))QAbstractSocket::disconnectFromHost
+272 (int (*)(...))QAbstractSocket::setReadBufferSize
+280 (int (*)(...))QAbstractSocket::socketDescriptor
+288 (int (*)(...))QAbstractSocket::setSocketDescriptor
+296 (int (*)(...))QAbstractSocket::setSocketOption
+304 (int (*)(...))QAbstractSocket::socketOption
+312 (int (*)(...))QAbstractSocket::waitForConnected
+320 (int (*)(...))QAbstractSocket::waitForDisconnected
+
+Class QTcpSocket
+ size=16 align=8
+ base size=16 base align=8
+QTcpSocket (0x0x7fbd10603a28) 0
+ vptr=((& QTcpSocket::_ZTV10QTcpSocket) + 16u)
+ QAbstractSocket (0x0x7fbd10603a90) 0
+ primary-for QTcpSocket (0x0x7fbd10603a28)
+ QIODevice (0x0x7fbd10603af8) 0
+ primary-for QAbstractSocket (0x0x7fbd10603a90)
+ QObject (0x0x7fbd10633960) 0
+ primary-for QIODevice (0x0x7fbd10603af8)
+
+Class QSslCertificate
+ size=8 align=8
+ base size=8 base align=8
+QSslCertificate (0x0x7fbd10633ba0) 0
+
+Class QSslError
+ size=8 align=8
+ base size=8 base align=8
+QSslError (0x0x7fbd1033e000) 0
+
+Class QSslSocket::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSslSocket::QPrivateSignal (0x0x7fbd1033e960) 0 empty
+
+Vtable for QSslSocket
+QSslSocket::_ZTV10QSslSocket: 41u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QSslSocket)
+16 (int (*)(...))QSslSocket::metaObject
+24 (int (*)(...))QSslSocket::qt_metacast
+32 (int (*)(...))QSslSocket::qt_metacall
+40 (int (*)(...))QSslSocket::~QSslSocket
+48 (int (*)(...))QSslSocket::~QSslSocket
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAbstractSocket::isSequential
+120 (int (*)(...))QIODevice::open
+128 (int (*)(...))QSslSocket::close
+136 (int (*)(...))QIODevice::pos
+144 (int (*)(...))QIODevice::size
+152 (int (*)(...))QIODevice::seek
+160 (int (*)(...))QSslSocket::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QSslSocket::bytesAvailable
+184 (int (*)(...))QSslSocket::bytesToWrite
+192 (int (*)(...))QSslSocket::canReadLine
+200 (int (*)(...))QSslSocket::waitForReadyRead
+208 (int (*)(...))QSslSocket::waitForBytesWritten
+216 (int (*)(...))QSslSocket::readData
+224 (int (*)(...))QAbstractSocket::readLineData
+232 (int (*)(...))QSslSocket::writeData
+240 (int (*)(...))QSslSocket::resume
+248 (int (*)(...))QSslSocket::connectToHost
+256 (int (*)(...))QAbstractSocket::connectToHost
+264 (int (*)(...))QSslSocket::disconnectFromHost
+272 (int (*)(...))QSslSocket::setReadBufferSize
+280 (int (*)(...))QAbstractSocket::socketDescriptor
+288 (int (*)(...))QSslSocket::setSocketDescriptor
+296 (int (*)(...))QSslSocket::setSocketOption
+304 (int (*)(...))QSslSocket::socketOption
+312 (int (*)(...))QSslSocket::waitForConnected
+320 (int (*)(...))QSslSocket::waitForDisconnected
+
+Class QSslSocket
+ size=16 align=8
+ base size=16 base align=8
+QSslSocket (0x0x7fbd1035c4e0) 0
+ vptr=((& QSslSocket::_ZTV10QSslSocket) + 16u)
+ QTcpSocket (0x0x7fbd1035c548) 0
+ primary-for QSslSocket (0x0x7fbd1035c4e0)
+ QAbstractSocket (0x0x7fbd1035c5b0) 0
+ primary-for QTcpSocket (0x0x7fbd1035c548)
+ QIODevice (0x0x7fbd1035c618) 0
+ primary-for QAbstractSocket (0x0x7fbd1035c5b0)
+ QObject (0x0x7fbd1033e900) 0
+ primary-for QIODevice (0x0x7fbd1035c618)
+
+Class QSslConfiguration
+ size=8 align=8
+ base size=8 base align=8
+QSslConfiguration (0x0x7fbd1033e9c0) 0
+
+Class QSslPreSharedKeyAuthenticator
+ size=8 align=8
+ base size=8 base align=8
+QSslPreSharedKeyAuthenticator (0x0x7fbd103ee180) 0
+
+Class QNetworkAccessManager::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QNetworkAccessManager::QPrivateSignal (0x0x7fbd103eea80) 0 empty
+
+Vtable for QNetworkAccessManager
+QNetworkAccessManager::_ZTV21QNetworkAccessManager: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QNetworkAccessManager)
+16 (int (*)(...))QNetworkAccessManager::metaObject
+24 (int (*)(...))QNetworkAccessManager::qt_metacast
+32 (int (*)(...))QNetworkAccessManager::qt_metacall
+40 (int (*)(...))QNetworkAccessManager::~QNetworkAccessManager
+48 (int (*)(...))QNetworkAccessManager::~QNetworkAccessManager
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QNetworkAccessManager::createRequest
+
+Class QNetworkAccessManager
+ size=16 align=8
+ base size=16 base align=8
+QNetworkAccessManager (0x0x7fbd104172d8) 0
+ vptr=((& QNetworkAccessManager::_ZTV21QNetworkAccessManager) + 16u)
+ QObject (0x0x7fbd103eea20) 0
+ primary-for QNetworkAccessManager (0x0x7fbd104172d8)
+
+Class QNetworkConfiguration
+ size=8 align=8
+ base size=8 base align=8
+QNetworkConfiguration (0x0x7fbd103eeae0) 0
+
+Class QNetworkConfigurationManager::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QNetworkConfigurationManager::QPrivateSignal (0x0x7fbd103eef60) 0 empty
+
+Vtable for QNetworkConfigurationManager
+QNetworkConfigurationManager::_ZTV28QNetworkConfigurationManager: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI28QNetworkConfigurationManager)
+16 (int (*)(...))QNetworkConfigurationManager::metaObject
+24 (int (*)(...))QNetworkConfigurationManager::qt_metacast
+32 (int (*)(...))QNetworkConfigurationManager::qt_metacall
+40 (int (*)(...))QNetworkConfigurationManager::~QNetworkConfigurationManager
+48 (int (*)(...))QNetworkConfigurationManager::~QNetworkConfigurationManager
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QNetworkConfigurationManager
+ size=16 align=8
+ base size=16 base align=8
+QNetworkConfigurationManager (0x0x7fbd104174e0) 0
+ vptr=((& QNetworkConfigurationManager::_ZTV28QNetworkConfigurationManager) + 16u)
+ QObject (0x0x7fbd103eef00) 0
+ primary-for QNetworkConfigurationManager (0x0x7fbd104174e0)
+
+Class QNetworkCookie
+ size=8 align=8
+ base size=8 base align=8
+QNetworkCookie (0x0x7fbd10489300) 0
+
+Class QNetworkCookieJar::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QNetworkCookieJar::QPrivateSignal (0x0x7fbd10489ae0) 0 empty
+
+Vtable for QNetworkCookieJar
+QNetworkCookieJar::_ZTV17QNetworkCookieJar: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QNetworkCookieJar)
+16 (int (*)(...))QNetworkCookieJar::metaObject
+24 (int (*)(...))QNetworkCookieJar::qt_metacast
+32 (int (*)(...))QNetworkCookieJar::qt_metacall
+40 (int (*)(...))QNetworkCookieJar::~QNetworkCookieJar
+48 (int (*)(...))QNetworkCookieJar::~QNetworkCookieJar
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QNetworkCookieJar::cookiesForUrl
+120 (int (*)(...))QNetworkCookieJar::setCookiesFromUrl
+128 (int (*)(...))QNetworkCookieJar::insertCookie
+136 (int (*)(...))QNetworkCookieJar::updateCookie
+144 (int (*)(...))QNetworkCookieJar::deleteCookie
+152 (int (*)(...))QNetworkCookieJar::validateCookie
+
+Class QNetworkCookieJar
+ size=16 align=8
+ base size=16 base align=8
+QNetworkCookieJar (0x0x7fbd10417d00) 0
+ vptr=((& QNetworkCookieJar::_ZTV17QNetworkCookieJar) + 16u)
+ QObject (0x0x7fbd10489a80) 0
+ primary-for QNetworkCookieJar (0x0x7fbd10417d00)
+
+Class QNetworkDatagram
+ size=8 align=8
+ base size=8 base align=8
+QNetworkDatagram (0x0x7fbd10489b40) 0
+
+Class QNetworkDiskCache::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QNetworkDiskCache::QPrivateSignal (0x0x7fbd1018fb40) 0 empty
+
+Vtable for QNetworkDiskCache
+QNetworkDiskCache::_ZTV17QNetworkDiskCache: 23u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QNetworkDiskCache)
+16 (int (*)(...))QNetworkDiskCache::metaObject
+24 (int (*)(...))QNetworkDiskCache::qt_metacast
+32 (int (*)(...))QNetworkDiskCache::qt_metacall
+40 (int (*)(...))QNetworkDiskCache::~QNetworkDiskCache
+48 (int (*)(...))QNetworkDiskCache::~QNetworkDiskCache
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QNetworkDiskCache::metaData
+120 (int (*)(...))QNetworkDiskCache::updateMetaData
+128 (int (*)(...))QNetworkDiskCache::data
+136 (int (*)(...))QNetworkDiskCache::remove
+144 (int (*)(...))QNetworkDiskCache::cacheSize
+152 (int (*)(...))QNetworkDiskCache::prepare
+160 (int (*)(...))QNetworkDiskCache::insert
+168 (int (*)(...))QNetworkDiskCache::clear
+176 (int (*)(...))QNetworkDiskCache::expire
+
+Class QNetworkDiskCache
+ size=16 align=8
+ base size=16 base align=8
+QNetworkDiskCache (0x0x7fbd10196750) 0
+ vptr=((& QNetworkDiskCache::_ZTV17QNetworkDiskCache) + 16u)
+ QAbstractNetworkCache (0x0x7fbd101967b8) 0
+ primary-for QNetworkDiskCache (0x0x7fbd10196750)
+ QObject (0x0x7fbd1018fae0) 0
+ primary-for QAbstractNetworkCache (0x0x7fbd101967b8)
+
+Class QNetworkAddressEntry
+ size=8 align=8
+ base size=8 base align=8
+QNetworkAddressEntry (0x0x7fbd1018fba0) 0
+
+Class QNetworkInterface
+ size=8 align=8
+ base size=8 base align=8
+QNetworkInterface (0x0x7fbd101dd2a0) 0
+
+Class QNetworkProxyQuery
+ size=8 align=8
+ base size=8 base align=8
+QNetworkProxyQuery (0x0x7fbd101dd9c0) 0
+
+Class QNetworkProxy
+ size=8 align=8
+ base size=8 base align=8
+QNetworkProxy (0x0x7fbd10274060) 0
+
+Vtable for QNetworkProxyFactory
+QNetworkProxyFactory::_ZTV20QNetworkProxyFactory: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QNetworkProxyFactory)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class QNetworkProxyFactory
+ size=8 align=8
+ base size=8 base align=8
+QNetworkProxyFactory (0x0x7fbd10274840) 0 nearly-empty
+ vptr=((& QNetworkProxyFactory::_ZTV20QNetworkProxyFactory) + 16u)
+
+Class QNetworkReply::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QNetworkReply::QPrivateSignal (0x0x7fbd10274a20) 0 empty
+
+Vtable for QNetworkReply
+QNetworkReply::_ZTV13QNetworkReply: 36u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QNetworkReply)
+16 (int (*)(...))QNetworkReply::metaObject
+24 (int (*)(...))QNetworkReply::qt_metacast
+32 (int (*)(...))QNetworkReply::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QNetworkReply::isSequential
+120 (int (*)(...))QIODevice::open
+128 (int (*)(...))QNetworkReply::close
+136 (int (*)(...))QIODevice::pos
+144 (int (*)(...))QIODevice::size
+152 (int (*)(...))QIODevice::seek
+160 (int (*)(...))QIODevice::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QIODevice::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))__cxa_pure_virtual
+224 (int (*)(...))QIODevice::readLineData
+232 (int (*)(...))QNetworkReply::writeData
+240 (int (*)(...))QNetworkReply::setReadBufferSize
+248 (int (*)(...))__cxa_pure_virtual
+256 (int (*)(...))QNetworkReply::ignoreSslErrors
+264 (int (*)(...))QNetworkReply::sslConfigurationImplementation
+272 (int (*)(...))QNetworkReply::setSslConfigurationImplementation
+280 (int (*)(...))QNetworkReply::ignoreSslErrorsImplementation
+
+Class QNetworkReply
+ size=16 align=8
+ base size=16 base align=8
+QNetworkReply (0x0x7fbd10206e38) 0
+ vptr=((& QNetworkReply::_ZTV13QNetworkReply) + 16u)
+ QIODevice (0x0x7fbd10206ea0) 0
+ primary-for QNetworkReply (0x0x7fbd10206e38)
+ QObject (0x0x7fbd102749c0) 0
+ primary-for QIODevice (0x0x7fbd10206ea0)
+
+Class QNetworkSession::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QNetworkSession::QPrivateSignal (0x0x7fbd10274c00) 0 empty
+
+Vtable for QNetworkSession
+QNetworkSession::_ZTV15QNetworkSession: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QNetworkSession)
+16 (int (*)(...))QNetworkSession::metaObject
+24 (int (*)(...))QNetworkSession::qt_metacast
+32 (int (*)(...))QNetworkSession::qt_metacall
+40 (int (*)(...))QNetworkSession::~QNetworkSession
+48 (int (*)(...))QNetworkSession::~QNetworkSession
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QNetworkSession::connectNotify
+104 (int (*)(...))QNetworkSession::disconnectNotify
+
+Class QNetworkSession
+ size=24 align=8
+ base size=24 base align=8
+QNetworkSession (0x0x7fbd10206f08) 0
+ vptr=((& QNetworkSession::_ZTV15QNetworkSession) + 16u)
+ QObject (0x0x7fbd10274ba0) 0
+ primary-for QNetworkSession (0x0x7fbd10206f08)
+
+Class QTcpServer::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTcpServer::QPrivateSignal (0x0x7fbd0ff371e0) 0 empty
+
+Vtable for QTcpServer
+QTcpServer::_ZTV10QTcpServer: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTcpServer)
+16 (int (*)(...))QTcpServer::metaObject
+24 (int (*)(...))QTcpServer::qt_metacast
+32 (int (*)(...))QTcpServer::qt_metacall
+40 (int (*)(...))QTcpServer::~QTcpServer
+48 (int (*)(...))QTcpServer::~QTcpServer
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QTcpServer::hasPendingConnections
+120 (int (*)(...))QTcpServer::nextPendingConnection
+128 (int (*)(...))QTcpServer::incomingConnection
+
+Class QTcpServer
+ size=16 align=8
+ base size=16 base align=8
+QTcpServer (0x0x7fbd0ff3a068) 0
+ vptr=((& QTcpServer::_ZTV10QTcpServer) + 16u)
+ QObject (0x0x7fbd0ff37180) 0
+ primary-for QTcpServer (0x0x7fbd0ff3a068)
+
+Class QSslCertificateExtension
+ size=8 align=8
+ base size=8 base align=8
+QSslCertificateExtension (0x0x7fbd0ff37240) 0
+
+Class QSslCipher
+ size=8 align=8
+ base size=8 base align=8
+QSslCipher (0x0x7fbd0ff37540) 0
+
+Class QSslDiffieHellmanParameters
+ size=8 align=8
+ base size=8 base align=8
+QSslDiffieHellmanParameters (0x0x7fbd0ff37d20) 0
+
+Class QSslEllipticCurve
+ size=4 align=4
+ base size=4 base align=4
+QSslEllipticCurve (0x0x7fbd1001f840) 0
+
+Class QSslKey
+ size=8 align=8
+ base size=8 base align=8
+QSslKey (0x0x7fbd1001ff60) 0
+
+Class QUdpSocket::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QUdpSocket::QPrivateSignal (0x0x7fbd1005f300) 0 empty
+
+Vtable for QUdpSocket
+QUdpSocket::_ZTV10QUdpSocket: 41u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QUdpSocket)
+16 (int (*)(...))QUdpSocket::metaObject
+24 (int (*)(...))QUdpSocket::qt_metacast
+32 (int (*)(...))QUdpSocket::qt_metacall
+40 (int (*)(...))QUdpSocket::~QUdpSocket
+48 (int (*)(...))QUdpSocket::~QUdpSocket
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAbstractSocket::isSequential
+120 (int (*)(...))QIODevice::open
+128 (int (*)(...))QAbstractSocket::close
+136 (int (*)(...))QIODevice::pos
+144 (int (*)(...))QIODevice::size
+152 (int (*)(...))QIODevice::seek
+160 (int (*)(...))QAbstractSocket::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QAbstractSocket::bytesAvailable
+184 (int (*)(...))QAbstractSocket::bytesToWrite
+192 (int (*)(...))QAbstractSocket::canReadLine
+200 (int (*)(...))QAbstractSocket::waitForReadyRead
+208 (int (*)(...))QAbstractSocket::waitForBytesWritten
+216 (int (*)(...))QAbstractSocket::readData
+224 (int (*)(...))QAbstractSocket::readLineData
+232 (int (*)(...))QAbstractSocket::writeData
+240 (int (*)(...))QAbstractSocket::resume
+248 (int (*)(...))QAbstractSocket::connectToHost
+256 (int (*)(...))QAbstractSocket::connectToHost
+264 (int (*)(...))QAbstractSocket::disconnectFromHost
+272 (int (*)(...))QAbstractSocket::setReadBufferSize
+280 (int (*)(...))QAbstractSocket::socketDescriptor
+288 (int (*)(...))QAbstractSocket::setSocketDescriptor
+296 (int (*)(...))QAbstractSocket::setSocketOption
+304 (int (*)(...))QAbstractSocket::socketOption
+312 (int (*)(...))QAbstractSocket::waitForConnected
+320 (int (*)(...))QAbstractSocket::waitForDisconnected
+
+Class QUdpSocket
+ size=16 align=8
+ base size=16 base align=8
+QUdpSocket (0x0x7fbd10043618) 0
+ vptr=((& QUdpSocket::_ZTV10QUdpSocket) + 16u)
+ QAbstractSocket (0x0x7fbd10043680) 0
+ primary-for QUdpSocket (0x0x7fbd10043618)
+ QIODevice (0x0x7fbd100436e8) 0
+ primary-for QAbstractSocket (0x0x7fbd10043680)
+ QObject (0x0x7fbd1005f2a0) 0
+ primary-for QIODevice (0x0x7fbd100436e8)
+
+Class QJSValue
+ size=8 align=8
+ base size=8 base align=8
+QJSValue (0x0x7fbd1005f360) 0
+
+Class QJSEngine::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QJSEngine::QPrivateSignal (0x0x7fbd1005f660) 0 empty
+
+Vtable for QJSEngine
+QJSEngine::_ZTV9QJSEngine: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QJSEngine)
+16 (int (*)(...))QJSEngine::metaObject
+24 (int (*)(...))QJSEngine::qt_metacast
+32 (int (*)(...))QJSEngine::qt_metacall
+40 (int (*)(...))QJSEngine::~QJSEngine
+48 (int (*)(...))QJSEngine::~QJSEngine
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QJSEngine
+ size=24 align=8
+ base size=24 base align=8
+QJSEngine (0x0x7fbd10043820) 0
+ vptr=((& QJSEngine::_ZTV9QJSEngine) + 16u)
+ QObject (0x0x7fbd1005f600) 0
+ primary-for QJSEngine (0x0x7fbd10043820)
+
+Class QJSValueIterator
+ size=8 align=8
+ base size=8 base align=8
+QJSValueIterator (0x0x7fbd1005f840) 0
+
+Class QQmlPrivate::RegisterType
+ size=128 align=8
+ base size=124 base align=8
+QQmlPrivate::RegisterType (0x0x7fbd1005fd20) 0
+
+Class QQmlPrivate::RegisterInterface
+ size=24 align=8
+ base size=24 base align=8
+QQmlPrivate::RegisterInterface (0x0x7fbd1005fd80) 0
+
+Class QQmlPrivate::RegisterAutoParent
+ size=16 align=8
+ base size=16 base align=8
+QQmlPrivate::RegisterAutoParent (0x0x7fbd1005fde0) 0
+
+Class QQmlPrivate::RegisterSingletonType
+ size=64 align=8
+ base size=64 base align=8
+QQmlPrivate::RegisterSingletonType (0x0x7fbd1005fe40) 0
+
+Class QQmlPrivate::RegisterCompositeType
+ size=32 align=8
+ base size=32 base align=8
+QQmlPrivate::RegisterCompositeType (0x0x7fbd1005fea0) 0
+
+Class QQmlPrivate::RegisterCompositeSingletonType
+ size=32 align=8
+ base size=32 base align=8
+QQmlPrivate::RegisterCompositeSingletonType (0x0x7fbd1005ff00) 0
+
+Class QQmlPrivate::CachedQmlUnit
+ size=24 align=8
+ base size=24 base align=8
+QQmlPrivate::CachedQmlUnit (0x0x7fbd1005ff60) 0
+
+Class QQmlPrivate::RegisterQmlUnitCacheHook
+ size=16 align=8
+ base size=16 base align=8
+QQmlPrivate::RegisterQmlUnitCacheHook (0x0x7fbd0fd4d000) 0
+
+Vtable for QQmlParserStatus
+QQmlParserStatus::_ZTV16QQmlParserStatus: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QQmlParserStatus)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+
+Class QQmlParserStatus
+ size=16 align=8
+ base size=16 base align=8
+QQmlParserStatus (0x0x7fbd0fd4d060) 0
+ vptr=((& QQmlParserStatus::_ZTV16QQmlParserStatus) + 16u)
+
+Vtable for QQmlPropertyValueSource
+QQmlPropertyValueSource::_ZTV23QQmlPropertyValueSource: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QQmlPropertyValueSource)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class QQmlPropertyValueSource
+ size=8 align=8
+ base size=8 base align=8
+QQmlPropertyValueSource (0x0x7fbd0fd4d120) 0 nearly-empty
+ vptr=((& QQmlPropertyValueSource::_ZTV23QQmlPropertyValueSource) + 16u)
+
+Class QQmlListReference
+ size=8 align=8
+ base size=8 base align=8
+QQmlListReference (0x0x7fbd0fd4d240) 0
+
+Vtable for QQmlAbstractUrlInterceptor
+QQmlAbstractUrlInterceptor::_ZTV26QQmlAbstractUrlInterceptor: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QQmlAbstractUrlInterceptor)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class QQmlAbstractUrlInterceptor
+ size=8 align=8
+ base size=8 base align=8
+QQmlAbstractUrlInterceptor (0x0x7fbd0fd4d8a0) 0 nearly-empty
+ vptr=((& QQmlAbstractUrlInterceptor::_ZTV26QQmlAbstractUrlInterceptor) + 16u)
+
+Class QQmlError
+ size=8 align=8
+ base size=8 base align=8
+QQmlError (0x0x7fbd0fd4d900) 0
+
+Class QQmlDebuggingEnabler
+ size=1 align=1
+ base size=0 base align=1
+QQmlDebuggingEnabler (0x0x7fbd0fd4dba0) 0 empty
+
+Vtable for QQmlImageProviderBase
+QQmlImageProviderBase::_ZTV21QQmlImageProviderBase: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QQmlImageProviderBase)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+
+Class QQmlImageProviderBase
+ size=8 align=8
+ base size=8 base align=8
+QQmlImageProviderBase (0x0x7fbd0fd4dc00) 0 nearly-empty
+ vptr=((& QQmlImageProviderBase::_ZTV21QQmlImageProviderBase) + 16u)
+
+Class QQmlEngine::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQmlEngine::QPrivateSignal (0x0x7fbd0fd4de40) 0 empty
+
+Vtable for QQmlEngine
+QQmlEngine::_ZTV10QQmlEngine: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QQmlEngine)
+16 (int (*)(...))QQmlEngine::metaObject
+24 (int (*)(...))QQmlEngine::qt_metacast
+32 (int (*)(...))QQmlEngine::qt_metacall
+40 (int (*)(...))QQmlEngine::~QQmlEngine
+48 (int (*)(...))QQmlEngine::~QQmlEngine
+56 (int (*)(...))QQmlEngine::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QQmlEngine
+ size=24 align=8
+ base size=24 base align=8
+QQmlEngine (0x0x7fbd10043e38) 0
+ vptr=((& QQmlEngine::_ZTV10QQmlEngine) + 16u)
+ QJSEngine (0x0x7fbd10043ea0) 0
+ primary-for QQmlEngine (0x0x7fbd10043e38)
+ QObject (0x0x7fbd0fd4dde0) 0
+ primary-for QJSEngine (0x0x7fbd10043ea0)
+
+Class QQmlApplicationEngine::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQmlApplicationEngine::QPrivateSignal (0x0x7fbd0fd4df00) 0 empty
+
+Vtable for QQmlApplicationEngine
+QQmlApplicationEngine::_ZTV21QQmlApplicationEngine: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QQmlApplicationEngine)
+16 (int (*)(...))QQmlApplicationEngine::metaObject
+24 (int (*)(...))QQmlApplicationEngine::qt_metacast
+32 (int (*)(...))QQmlApplicationEngine::qt_metacall
+40 (int (*)(...))QQmlApplicationEngine::~QQmlApplicationEngine
+48 (int (*)(...))QQmlApplicationEngine::~QQmlApplicationEngine
+56 (int (*)(...))QQmlEngine::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QQmlApplicationEngine
+ size=24 align=8
+ base size=24 base align=8
+QQmlApplicationEngine (0x0x7fbd10043f08) 0
+ vptr=((& QQmlApplicationEngine::_ZTV21QQmlApplicationEngine) + 16u)
+ QQmlEngine (0x0x7fbd10043f70) 0
+ primary-for QQmlApplicationEngine (0x0x7fbd10043f08)
+ QJSEngine (0x0x7fbd0fe9e000) 0
+ primary-for QQmlEngine (0x0x7fbd10043f70)
+ QObject (0x0x7fbd0fd4dea0) 0
+ primary-for QJSEngine (0x0x7fbd0fe9e000)
+
+Class QQmlComponent::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQmlComponent::QPrivateSignal (0x0x7fbd0feb2000) 0 empty
+
+Vtable for QQmlComponent
+QQmlComponent::_ZTV13QQmlComponent: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QQmlComponent)
+16 (int (*)(...))QQmlComponent::metaObject
+24 (int (*)(...))QQmlComponent::qt_metacast
+32 (int (*)(...))QQmlComponent::qt_metacall
+40 (int (*)(...))QQmlComponent::~QQmlComponent
+48 (int (*)(...))QQmlComponent::~QQmlComponent
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QQmlComponent::create
+120 (int (*)(...))QQmlComponent::beginCreate
+128 (int (*)(...))QQmlComponent::completeCreate
+
+Class QQmlComponent
+ size=16 align=8
+ base size=16 base align=8
+QQmlComponent (0x0x7fbd0fe9e068) 0
+ vptr=((& QQmlComponent::_ZTV13QQmlComponent) + 16u)
+ QObject (0x0x7fbd0fd4df60) 0
+ primary-for QQmlComponent (0x0x7fbd0fe9e068)
+
+Class QQmlContext::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQmlContext::QPrivateSignal (0x0x7fbd0feb2840) 0 empty
+
+Vtable for QQmlContext
+QQmlContext::_ZTV11QQmlContext: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QQmlContext)
+16 (int (*)(...))QQmlContext::metaObject
+24 (int (*)(...))QQmlContext::qt_metacast
+32 (int (*)(...))QQmlContext::qt_metacall
+40 (int (*)(...))QQmlContext::~QQmlContext
+48 (int (*)(...))QQmlContext::~QQmlContext
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QQmlContext
+ size=16 align=8
+ base size=16 base align=8
+QQmlContext (0x0x7fbd0fe9e5b0) 0
+ vptr=((& QQmlContext::_ZTV11QQmlContext) + 16u)
+ QObject (0x0x7fbd0feb27e0) 0
+ primary-for QQmlContext (0x0x7fbd0fe9e5b0)
+
+Class QQmlScriptString
+ size=8 align=8
+ base size=8 base align=8
+QQmlScriptString (0x0x7fbd0feb29c0) 0
+
+Class QQmlExpression::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQmlExpression::QPrivateSignal (0x0x7fbd0feb2c00) 0 empty
+
+Vtable for QQmlExpression
+QQmlExpression::_ZTV14QQmlExpression: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QQmlExpression)
+16 (int (*)(...))QQmlExpression::metaObject
+24 (int (*)(...))QQmlExpression::qt_metacast
+32 (int (*)(...))QQmlExpression::qt_metacall
+40 (int (*)(...))QQmlExpression::~QQmlExpression
+48 (int (*)(...))QQmlExpression::~QQmlExpression
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QQmlExpression
+ size=16 align=8
+ base size=16 base align=8
+QQmlExpression (0x0x7fbd0fe9e618) 0
+ vptr=((& QQmlExpression::_ZTV14QQmlExpression) + 16u)
+ QObject (0x0x7fbd0feb2ba0) 0
+ primary-for QQmlExpression (0x0x7fbd0fe9e618)
+
+Vtable for QQmlTypesExtensionInterface
+QQmlTypesExtensionInterface::_ZTV27QQmlTypesExtensionInterface: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QQmlTypesExtensionInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class QQmlTypesExtensionInterface
+ size=8 align=8
+ base size=8 base align=8
+QQmlTypesExtensionInterface (0x0x7fbd0feb2c60) 0 nearly-empty
+ vptr=((& QQmlTypesExtensionInterface::_ZTV27QQmlTypesExtensionInterface) + 16u)
+
+Vtable for QQmlExtensionInterface
+QQmlExtensionInterface::_ZTV22QQmlExtensionInterface: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI22QQmlExtensionInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+
+Class QQmlExtensionInterface
+ size=8 align=8
+ base size=8 base align=8
+QQmlExtensionInterface (0x0x7fbd0fe9e680) 0 nearly-empty
+ vptr=((& QQmlExtensionInterface::_ZTV22QQmlExtensionInterface) + 16u)
+ QQmlTypesExtensionInterface (0x0x7fbd0feb2cc0) 0 nearly-empty
+ primary-for QQmlExtensionInterface (0x0x7fbd0fe9e680)
+
+Class QQmlExtensionPlugin::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQmlExtensionPlugin::QPrivateSignal (0x0x7fbd0feb2ea0) 0 empty
+
+Vtable for QQmlExtensionPlugin
+QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin: 22u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QQmlExtensionPlugin)
+16 (int (*)(...))QQmlExtensionPlugin::metaObject
+24 (int (*)(...))QQmlExtensionPlugin::qt_metacast
+32 (int (*)(...))QQmlExtensionPlugin::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))QQmlExtensionPlugin::initializeEngine
+128 (int (*)(...))-16
+136 (int (*)(...))(& _ZTI19QQmlExtensionPlugin)
+144 0u
+152 0u
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))QQmlExtensionPlugin::_ZThn16_N19QQmlExtensionPlugin16initializeEngineEP10QQmlEnginePKc
+
+Class QQmlExtensionPlugin
+ size=24 align=8
+ base size=24 base align=8
+QQmlExtensionPlugin (0x0x7fbd0fb50380) 0
+ vptr=((& QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin) + 16u)
+ QObject (0x0x7fbd0feb2de0) 0
+ primary-for QQmlExtensionPlugin (0x0x7fbd0fb50380)
+ QQmlExtensionInterface (0x0x7fbd0fe9e6e8) 16 nearly-empty
+ vptr=((& QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin) + 144u)
+ QQmlTypesExtensionInterface (0x0x7fbd0feb2e40) 16 nearly-empty
+ primary-for QQmlExtensionInterface (0x0x7fbd0fe9e6e8)
+
+Class QQmlFile
+ size=8 align=8
+ base size=8 base align=8
+QQmlFile (0x0x7fbd0feb2f00) 0
+
+Class QQmlFileSelector::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQmlFileSelector::QPrivateSignal (0x0x7fbd0fb77000) 0 empty
+
+Vtable for QQmlFileSelector
+QQmlFileSelector::_ZTV16QQmlFileSelector: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QQmlFileSelector)
+16 (int (*)(...))QQmlFileSelector::metaObject
+24 (int (*)(...))QQmlFileSelector::qt_metacast
+32 (int (*)(...))QQmlFileSelector::qt_metacall
+40 (int (*)(...))QQmlFileSelector::~QQmlFileSelector
+48 (int (*)(...))QQmlFileSelector::~QQmlFileSelector
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QQmlFileSelector
+ size=16 align=8
+ base size=16 base align=8
+QQmlFileSelector (0x0x7fbd0fe9e7b8) 0
+ vptr=((& QQmlFileSelector::_ZTV16QQmlFileSelector) + 16u)
+ QObject (0x0x7fbd0feb2f60) 0
+ primary-for QQmlFileSelector (0x0x7fbd0fe9e7b8)
+
+Vtable for QQmlIncubator
+QQmlIncubator::_ZTV13QQmlIncubator: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QQmlIncubator)
+16 (int (*)(...))QQmlIncubator::~QQmlIncubator
+24 (int (*)(...))QQmlIncubator::~QQmlIncubator
+32 (int (*)(...))QQmlIncubator::statusChanged
+40 (int (*)(...))QQmlIncubator::setInitialState
+
+Class QQmlIncubator
+ size=16 align=8
+ base size=16 base align=8
+QQmlIncubator (0x0x7fbd0fb77060) 0
+ vptr=((& QQmlIncubator::_ZTV13QQmlIncubator) + 16u)
+
+Vtable for QQmlIncubationController
+QQmlIncubationController::_ZTV24QQmlIncubationController: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QQmlIncubationController)
+16 (int (*)(...))QQmlIncubationController::~QQmlIncubationController
+24 (int (*)(...))QQmlIncubationController::~QQmlIncubationController
+32 (int (*)(...))QQmlIncubationController::incubatingObjectCountChanged
+
+Class QQmlIncubationController
+ size=16 align=8
+ base size=16 base align=8
+QQmlIncubationController (0x0x7fbd0fb770c0) 0
+ vptr=((& QQmlIncubationController::_ZTV24QQmlIncubationController) + 16u)
+
+Class QQmlInfo
+ size=16 align=8
+ base size=16 base align=8
+QQmlInfo (0x0x7fbd0fe9e820) 0
+ QDebug (0x0x7fbd0fb77120) 0
+
+Vtable for QQmlNetworkAccessManagerFactory
+QQmlNetworkAccessManagerFactory::_ZTV31QQmlNetworkAccessManagerFactory: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI31QQmlNetworkAccessManagerFactory)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class QQmlNetworkAccessManagerFactory
+ size=8 align=8
+ base size=8 base align=8
+QQmlNetworkAccessManagerFactory (0x0x7fbd0fc124e0) 0 nearly-empty
+ vptr=((& QQmlNetworkAccessManagerFactory::_ZTV31QQmlNetworkAccessManagerFactory) + 16u)
+
+Class QQmlProperty
+ size=8 align=8
+ base size=8 base align=8
+QQmlProperty (0x0x7fbd0fc12540) 0
+
+Class QQmlPropertyMap::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQmlPropertyMap::QPrivateSignal (0x0x7fbd0fc4c0c0) 0 empty
+
+Vtable for QQmlPropertyMap
+QQmlPropertyMap::_ZTV15QQmlPropertyMap: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QQmlPropertyMap)
+16 (int (*)(...))QQmlPropertyMap::metaObject
+24 (int (*)(...))QQmlPropertyMap::qt_metacast
+32 (int (*)(...))QQmlPropertyMap::qt_metacall
+40 (int (*)(...))QQmlPropertyMap::~QQmlPropertyMap
+48 (int (*)(...))QQmlPropertyMap::~QQmlPropertyMap
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QQmlPropertyMap::updateValue
+
+Class QQmlPropertyMap
+ size=16 align=8
+ base size=16 base align=8
+QQmlPropertyMap (0x0x7fbd0fc43548) 0
+ vptr=((& QQmlPropertyMap::_ZTV15QQmlPropertyMap) + 16u)
+ QObject (0x0x7fbd0fc4c060) 0
+ primary-for QQmlPropertyMap (0x0x7fbd0fc43548)
+
diff --git a/tests/auto/bic/data/QtQuick.5.10.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtQuick.5.10.0.linux-gcc-amd64.txt
new file mode 100644
index 0000000000..93332fc3c6
--- /dev/null
+++ b/tests/auto/bic/data/QtQuick.5.10.0.linux-gcc-amd64.txt
@@ -0,0 +1,10978 @@
+Class std::__failure_type
+ size=1 align=1
+ base size=0 base align=1
+std::__failure_type (0x0x7f3d4eabe720) 0 empty
+
+Class std::__do_is_destructible_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_is_destructible_impl (0x0x7f3d4eb18ea0) 0 empty
+
+Class std::__do_is_nt_destructible_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_is_nt_destructible_impl (0x0x7f3d4e647120) 0 empty
+
+Class std::__do_is_default_constructible_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_is_default_constructible_impl (0x0x7f3d4e647360) 0 empty
+
+Class std::__do_is_static_castable_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_is_static_castable_impl (0x0x7f3d4e6475a0) 0 empty
+
+Class std::__do_is_direct_constructible_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_is_direct_constructible_impl (0x0x7f3d4e647720) 0 empty
+
+Class std::__do_is_nary_constructible_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_is_nary_constructible_impl (0x0x7f3d4e647ae0) 0 empty
+
+Class std::__do_common_type_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_common_type_impl (0x0x7f3d4e7002a0) 0 empty
+
+Class std::__do_member_type_wrapper
+ size=1 align=1
+ base size=0 base align=1
+std::__do_member_type_wrapper (0x0x7f3d4e700360) 0 empty
+
+Class std::__result_of_memfun_ref_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__result_of_memfun_ref_impl (0x0x7f3d4e7006c0) 0 empty
+
+Class std::__result_of_memfun_deref_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__result_of_memfun_deref_impl (0x0x7f3d4e700780) 0 empty
+
+Class std::__result_of_memobj_ref_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__result_of_memobj_ref_impl (0x0x7f3d4e700840) 0 empty
+
+Class std::__result_of_memobj_deref_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__result_of_memobj_deref_impl (0x0x7f3d4e700900) 0 empty
+
+Class std::__result_of_other_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__result_of_other_impl (0x0x7f3d4e700ba0) 0 empty
+
+Class std::piecewise_construct_t
+ size=1 align=1
+ base size=0 base align=1
+std::piecewise_construct_t (0x0x7f3d4e700d80) 0 empty
+
+Class std::__true_type
+ size=1 align=1
+ base size=0 base align=1
+std::__true_type (0x0x7f3d4e77e240) 0 empty
+
+Class std::__false_type
+ size=1 align=1
+ base size=0 base align=1
+std::__false_type (0x0x7f3d4e77e2a0) 0 empty
+
+Class std::input_iterator_tag
+ size=1 align=1
+ base size=0 base align=1
+std::input_iterator_tag (0x0x7f3d4e7b8f00) 0 empty
+
+Class std::output_iterator_tag
+ size=1 align=1
+ base size=0 base align=1
+std::output_iterator_tag (0x0x7f3d4e7b8f60) 0 empty
+
+Class std::forward_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::forward_iterator_tag (0x0x7f3d4e730340) 0 empty
+ std::input_iterator_tag (0x0x7f3d4e7e7000) 0 empty
+
+Class std::bidirectional_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::bidirectional_iterator_tag (0x0x7f3d4e7303a8) 0 empty
+ std::forward_iterator_tag (0x0x7f3d4e730410) 0 empty
+ std::input_iterator_tag (0x0x7f3d4e7e7060) 0 empty
+
+Class std::random_access_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::random_access_iterator_tag (0x0x7f3d4e730478) 0 empty
+ std::bidirectional_iterator_tag (0x0x7f3d4e7304e0) 0 empty
+ std::forward_iterator_tag (0x0x7f3d4e730548) 0 empty
+ std::input_iterator_tag (0x0x7f3d4e7e70c0) 0 empty
+
+Class __gnu_cxx::__ops::_Iter_less_iter
+ size=1 align=1
+ base size=0 base align=1
+__gnu_cxx::__ops::_Iter_less_iter (0x0x7f3d4e7e7d20) 0 empty
+
+Class __gnu_cxx::__ops::_Iter_less_val
+ size=1 align=1
+ base size=0 base align=1
+__gnu_cxx::__ops::_Iter_less_val (0x0x7f3d4e7e7d80) 0 empty
+
+Class __gnu_cxx::__ops::_Val_less_iter
+ size=1 align=1
+ base size=0 base align=1
+__gnu_cxx::__ops::_Val_less_iter (0x0x7f3d4e7e7de0) 0 empty
+
+Class __gnu_cxx::__ops::_Iter_equal_to_iter
+ size=1 align=1
+ base size=0 base align=1
+__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7f3d4e7e7e40) 0 empty
+
+Class __gnu_cxx::__ops::_Iter_equal_to_val
+ size=1 align=1
+ base size=0 base align=1
+__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7f3d4e7e7ea0) 0 empty
+
+Class wait
+ size=4 align=4
+ base size=4 base align=4
+wait (0x0x7f3d4e4aa9c0) 0
+
+Class __locale_struct
+ size=232 align=8
+ base size=232 base align=8
+__locale_struct (0x0x7f3d4e4aac00) 0
+
+Class timespec
+ size=16 align=8
+ base size=16 base align=8
+timespec (0x0x7f3d4e4aacc0) 0
+
+Class timeval
+ size=16 align=8
+ base size=16 base align=8
+timeval (0x0x7f3d4e4aad20) 0
+
+Class pthread_attr_t
+ size=56 align=8
+ base size=56 base align=8
+pthread_attr_t (0x0x7f3d4e4aade0) 0
+
+Class __pthread_internal_list
+ size=16 align=8
+ base size=16 base align=8
+__pthread_internal_list (0x0x7f3d4e4aae40) 0
+
+Class random_data
+ size=48 align=8
+ base size=48 base align=8
+random_data (0x0x7f3d4e54d300) 0
+
+Class drand48_data
+ size=24 align=8
+ base size=24 base align=8
+drand48_data (0x0x7f3d4e54d360) 0
+
+Vtable for std::exception
+std::exception::_ZTVSt9exception: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt9exception)
+16 (int (*)(...))std::exception::~exception
+24 (int (*)(...))std::exception::~exception
+32 (int (*)(...))std::exception::what
+
+Class std::exception
+ size=8 align=8
+ base size=8 base align=8
+std::exception (0x0x7f3d4e54d3c0) 0 nearly-empty
+ vptr=((& std::exception::_ZTVSt9exception) + 16u)
+
+Vtable for std::bad_exception
+std::bad_exception::_ZTVSt13bad_exception: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt13bad_exception)
+16 (int (*)(...))std::bad_exception::~bad_exception
+24 (int (*)(...))std::bad_exception::~bad_exception
+32 (int (*)(...))std::bad_exception::what
+
+Class std::bad_exception
+ size=8 align=8
+ base size=8 base align=8
+std::bad_exception (0x0x7f3d4e730a90) 0 nearly-empty
+ vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u)
+ std::exception (0x0x7f3d4e54d420) 0 nearly-empty
+ primary-for std::bad_exception (0x0x7f3d4e730a90)
+
+Class std::__exception_ptr::exception_ptr
+ size=8 align=8
+ base size=8 base align=8
+std::__exception_ptr::exception_ptr (0x0x7f3d4e54d480) 0
+
+Vtable for std::nested_exception
+std::nested_exception::_ZTVSt16nested_exception: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt16nested_exception)
+16 (int (*)(...))std::nested_exception::~nested_exception
+24 (int (*)(...))std::nested_exception::~nested_exception
+
+Class std::nested_exception
+ size=16 align=8
+ base size=16 base align=8
+std::nested_exception (0x0x7f3d4e54d4e0) 0
+ vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16u)
+
+Vtable for std::bad_alloc
+std::bad_alloc::_ZTVSt9bad_alloc: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt9bad_alloc)
+16 (int (*)(...))std::bad_alloc::~bad_alloc
+24 (int (*)(...))std::bad_alloc::~bad_alloc
+32 (int (*)(...))std::bad_alloc::what
+
+Class std::bad_alloc
+ size=8 align=8
+ base size=8 base align=8
+std::bad_alloc (0x0x7f3d4e730c98) 0 nearly-empty
+ vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u)
+ std::exception (0x0x7f3d4e54d900) 0 nearly-empty
+ primary-for std::bad_alloc (0x0x7f3d4e730c98)
+
+Vtable for std::bad_array_new_length
+std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt20bad_array_new_length)
+16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length
+24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length
+32 (int (*)(...))std::bad_array_new_length::what
+
+Class std::bad_array_new_length
+ size=8 align=8
+ base size=8 base align=8
+std::bad_array_new_length (0x0x7f3d4e730d00) 0 nearly-empty
+ vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16u)
+ std::bad_alloc (0x0x7f3d4e730d68) 0 nearly-empty
+ primary-for std::bad_array_new_length (0x0x7f3d4e730d00)
+ std::exception (0x0x7f3d4e54d960) 0 nearly-empty
+ primary-for std::bad_alloc (0x0x7f3d4e730d68)
+
+Class std::nothrow_t
+ size=1 align=1
+ base size=0 base align=1
+std::nothrow_t (0x0x7f3d4e54d9c0) 0 empty
+
+Class __exception
+ size=40 align=8
+ base size=40 base align=8
+__exception (0x0x7f3d4e2c2600) 0
+
+Class lconv
+ size=96 align=8
+ base size=96 base align=8
+lconv (0x0x7f3d4e0d5300) 0
+
+Vtable for __cxxabiv1::__forced_unwind
+__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class __cxxabiv1::__forced_unwind
+ size=8 align=8
+ base size=8 base align=8
+__cxxabiv1::__forced_unwind (0x0x7f3d4e0d5360) 0 nearly-empty
+ vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u)
+
+Class sched_param
+ size=4 align=4
+ base size=4 base align=4
+sched_param (0x0x7f3d4e175240) 0
+
+Class __sched_param
+ size=4 align=4
+ base size=4 base align=4
+__sched_param (0x0x7f3d4e1752a0) 0
+
+Class timex
+ size=208 align=8
+ base size=208 base align=8
+timex (0x0x7f3d4e175360) 0
+
+Class tm
+ size=56 align=8
+ base size=56 base align=8
+tm (0x0x7f3d4e1753c0) 0
+
+Class itimerspec
+ size=32 align=8
+ base size=32 base align=8
+itimerspec (0x0x7f3d4e175420) 0
+
+Class _pthread_cleanup_buffer
+ size=32 align=8
+ base size=32 base align=8
+_pthread_cleanup_buffer (0x0x7f3d4e175480) 0
+
+Class __pthread_cleanup_frame
+ size=24 align=8
+ base size=24 base align=8
+__pthread_cleanup_frame (0x0x7f3d4e1755a0) 0
+
+Class __pthread_cleanup_class
+ size=24 align=8
+ base size=24 base align=8
+__pthread_cleanup_class (0x0x7f3d4e175600) 0
+
+Class _IO_marker
+ size=24 align=8
+ base size=24 base align=8
+_IO_marker (0x0x7f3d4e175a20) 0
+
+Class _IO_FILE
+ size=216 align=8
+ base size=216 base align=8
+_IO_FILE (0x0x7f3d4e175a80) 0
+
+Class std::_Hash_impl
+ size=1 align=1
+ base size=0 base align=1
+std::_Hash_impl (0x0x7f3d4dc952a0) 0 empty
+
+Class std::_Fnv_hash_impl
+ size=1 align=1
+ base size=0 base align=1
+std::_Fnv_hash_impl (0x0x7f3d4dc95300) 0 empty
+
+Class std::__numeric_limits_base
+ size=1 align=1
+ base size=0 base align=1
+std::__numeric_limits_base (0x0x7f3d4dd662a0) 0 empty
+
+Class std::_Bit_reference
+ size=16 align=8
+ base size=16 base align=8
+std::_Bit_reference (0x0x7f3d4db1e0c0) 0
+
+Class std::_Bit_iterator_base
+ size=16 align=8
+ base size=12 base align=8
+std::_Bit_iterator_base (0x0x7f3d4dcaeaf8) 0
+ std::iterator<std::random_access_iterator_tag, bool> (0x0x7f3d4db1e180) 0 empty
+
+Class std::_Bit_iterator
+ size=16 align=8
+ base size=12 base align=8
+std::_Bit_iterator (0x0x7f3d4dcaeb60) 0
+ std::_Bit_iterator_base (0x0x7f3d4dcaebc8) 0
+ std::iterator<std::random_access_iterator_tag, bool> (0x0x7f3d4db1e1e0) 0 empty
+
+Class std::_Bit_const_iterator
+ size=16 align=8
+ base size=12 base align=8
+std::_Bit_const_iterator (0x0x7f3d4dcaec30) 0
+ std::_Bit_iterator_base (0x0x7f3d4dcaec98) 0
+ std::iterator<std::random_access_iterator_tag, bool> (0x0x7f3d4db1e240) 0 empty
+
+Class std::random_device
+ size=5000 align=8
+ base size=5000 base align=8
+std::random_device (0x0x7f3d4d93f060) 0
+
+Class std::bernoulli_distribution::param_type
+ size=8 align=8
+ base size=8 base align=8
+std::bernoulli_distribution::param_type (0x0x7f3d4d93fde0) 0
+
+Class std::bernoulli_distribution
+ size=8 align=8
+ base size=8 base align=8
+std::bernoulli_distribution (0x0x7f3d4d93fd80) 0
+
+Class std::seed_seq
+ size=24 align=8
+ base size=24 base align=8
+std::seed_seq (0x0x7f3d4d688d80) 0
+
+Class qIsNull(double)::U
+ size=8 align=8
+ base size=8 base align=8
+qIsNull(double)::U (0x0x7f3d4c26e8a0) 0
+
+Class qIsNull(float)::U
+ size=4 align=4
+ base size=4 base align=4
+qIsNull(float)::U (0x0x7f3d4c26e900) 0
+
+Class QSysInfo
+ size=1 align=1
+ base size=0 base align=1
+QSysInfo (0x0x7f3d4c3563c0) 0 empty
+
+Class QMessageLogContext
+ size=32 align=8
+ base size=32 base align=8
+QMessageLogContext (0x0x7f3d4c356420) 0
+
+Class QMessageLogger
+ size=32 align=8
+ base size=32 base align=8
+QMessageLogger (0x0x7f3d4c356480) 0
+
+Class QFlag
+ size=4 align=4
+ base size=4 base align=4
+QFlag (0x0x7f3d4c3564e0) 0
+
+Class QIncompatibleFlag
+ size=4 align=4
+ base size=4 base align=4
+QIncompatibleFlag (0x0x7f3d4c356780) 0
+
+Class std::__atomic_flag_base
+ size=1 align=1
+ base size=1 base align=1
+std::__atomic_flag_base (0x0x7f3d4c356cc0) 0
+
+Class std::atomic_flag
+ size=1 align=1
+ base size=1 base align=1
+std::atomic_flag (0x0x7f3d4c3479c0) 0
+ std::__atomic_flag_base (0x0x7f3d4c356d20) 0
+
+Class QAtomicInt
+ size=4 align=4
+ base size=4 base align=4
+QAtomicInt (0x0x7f3d4bf79138) 0
+ QAtomicInteger<int> (0x0x7f3d4bf791a0) 0
+ QBasicAtomicInteger<int> (0x0x7f3d4bef7480) 0
+
+Class QInternal
+ size=1 align=1
+ base size=0 base align=1
+QInternal (0x0x7f3d4bdada20) 0 empty
+
+Class QtPrivate::QSlotObjectBase
+ size=16 align=8
+ base size=16 base align=8
+QtPrivate::QSlotObjectBase (0x0x7f3d4bbb0a80) 0
+
+Class QGenericArgument
+ size=16 align=8
+ base size=16 base align=8
+QGenericArgument (0x0x7f3d4bbb0ba0) 0
+
+Class QGenericReturnArgument
+ size=16 align=8
+ base size=16 base align=8
+QGenericReturnArgument (0x0x7f3d4bd80bc8) 0
+ QGenericArgument (0x0x7f3d4bbb0c00) 0
+
+Class QMetaObject
+ size=48 align=8
+ base size=48 base align=8
+QMetaObject (0x0x7f3d4bbb0d80) 0
+
+Class QMetaObject::Connection
+ size=8 align=8
+ base size=8 base align=8
+QMetaObject::Connection (0x0x7f3d4bbb0e40) 0
+
+Class QLatin1Char
+ size=1 align=1
+ base size=1 base align=1
+QLatin1Char (0x0x7f3d4b86aea0) 0
+
+Class QChar
+ size=2 align=2
+ base size=2 base align=2
+QChar (0x0x7f3d4b86af00) 0
+
+Class QtPrivate::RefCount
+ size=4 align=4
+ base size=4 base align=4
+QtPrivate::RefCount (0x0x7f3d4b9131e0) 0
+
+Class QArrayData
+ size=24 align=8
+ base size=24 base align=8
+QArrayData (0x0x7f3d4b913240) 0
+
+Class QtPrivate::QContainerImplHelper
+ size=1 align=1
+ base size=0 base align=1
+QtPrivate::QContainerImplHelper (0x0x7f3d4b9135a0) 0 empty
+
+Class std::locale
+ size=8 align=8
+ base size=8 base align=8
+std::locale (0x0x7f3d4b913600) 0
+
+Vtable for std::locale::facet
+std::locale::facet::_ZTVNSt6locale5facetE: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt6locale5facetE)
+16 (int (*)(...))std::locale::facet::~facet
+24 (int (*)(...))std::locale::facet::~facet
+
+Class std::locale::facet
+ size=16 align=8
+ base size=12 base align=8
+std::locale::facet (0x0x7f3d4b913660) 0
+ vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u)
+
+Class std::locale::id
+ size=8 align=8
+ base size=8 base align=8
+std::locale::id (0x0x7f3d4b9136c0) 0
+
+Class std::locale::_Impl
+ size=40 align=8
+ base size=40 base align=8
+std::locale::_Impl (0x0x7f3d4b913720) 0
+
+Class std::__cow_string
+ size=8 align=8
+ base size=8 base align=8
+std::__cow_string (0x0x7f3d4b913ae0) 0
+
+Vtable for std::logic_error
+std::logic_error::_ZTVSt11logic_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt11logic_error)
+16 (int (*)(...))std::logic_error::~logic_error
+24 (int (*)(...))std::logic_error::~logic_error
+32 (int (*)(...))std::logic_error::what
+
+Class std::logic_error
+ size=16 align=8
+ base size=16 base align=8
+std::logic_error (0x0x7f3d4b618138) 0
+ vptr=((& std::logic_error::_ZTVSt11logic_error) + 16u)
+ std::exception (0x0x7f3d4b913ba0) 0 nearly-empty
+ primary-for std::logic_error (0x0x7f3d4b618138)
+
+Vtable for std::domain_error
+std::domain_error::_ZTVSt12domain_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt12domain_error)
+16 (int (*)(...))std::domain_error::~domain_error
+24 (int (*)(...))std::domain_error::~domain_error
+32 (int (*)(...))std::logic_error::what
+
+Class std::domain_error
+ size=16 align=8
+ base size=16 base align=8
+std::domain_error (0x0x7f3d4b6181a0) 0
+ vptr=((& std::domain_error::_ZTVSt12domain_error) + 16u)
+ std::logic_error (0x0x7f3d4b618208) 0
+ primary-for std::domain_error (0x0x7f3d4b6181a0)
+ std::exception (0x0x7f3d4b913c00) 0 nearly-empty
+ primary-for std::logic_error (0x0x7f3d4b618208)
+
+Vtable for std::invalid_argument
+std::invalid_argument::_ZTVSt16invalid_argument: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt16invalid_argument)
+16 (int (*)(...))std::invalid_argument::~invalid_argument
+24 (int (*)(...))std::invalid_argument::~invalid_argument
+32 (int (*)(...))std::logic_error::what
+
+Class std::invalid_argument
+ size=16 align=8
+ base size=16 base align=8
+std::invalid_argument (0x0x7f3d4b618270) 0
+ vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16u)
+ std::logic_error (0x0x7f3d4b6182d8) 0
+ primary-for std::invalid_argument (0x0x7f3d4b618270)
+ std::exception (0x0x7f3d4b913c60) 0 nearly-empty
+ primary-for std::logic_error (0x0x7f3d4b6182d8)
+
+Vtable for std::length_error
+std::length_error::_ZTVSt12length_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt12length_error)
+16 (int (*)(...))std::length_error::~length_error
+24 (int (*)(...))std::length_error::~length_error
+32 (int (*)(...))std::logic_error::what
+
+Class std::length_error
+ size=16 align=8
+ base size=16 base align=8
+std::length_error (0x0x7f3d4b618340) 0
+ vptr=((& std::length_error::_ZTVSt12length_error) + 16u)
+ std::logic_error (0x0x7f3d4b6183a8) 0
+ primary-for std::length_error (0x0x7f3d4b618340)
+ std::exception (0x0x7f3d4b913cc0) 0 nearly-empty
+ primary-for std::logic_error (0x0x7f3d4b6183a8)
+
+Vtable for std::out_of_range
+std::out_of_range::_ZTVSt12out_of_range: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt12out_of_range)
+16 (int (*)(...))std::out_of_range::~out_of_range
+24 (int (*)(...))std::out_of_range::~out_of_range
+32 (int (*)(...))std::logic_error::what
+
+Class std::out_of_range
+ size=16 align=8
+ base size=16 base align=8
+std::out_of_range (0x0x7f3d4b618410) 0
+ vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16u)
+ std::logic_error (0x0x7f3d4b618478) 0
+ primary-for std::out_of_range (0x0x7f3d4b618410)
+ std::exception (0x0x7f3d4b913d20) 0 nearly-empty
+ primary-for std::logic_error (0x0x7f3d4b618478)
+
+Vtable for std::runtime_error
+std::runtime_error::_ZTVSt13runtime_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt13runtime_error)
+16 (int (*)(...))std::runtime_error::~runtime_error
+24 (int (*)(...))std::runtime_error::~runtime_error
+32 (int (*)(...))std::runtime_error::what
+
+Class std::runtime_error
+ size=16 align=8
+ base size=16 base align=8
+std::runtime_error (0x0x7f3d4b6184e0) 0
+ vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16u)
+ std::exception (0x0x7f3d4b913d80) 0 nearly-empty
+ primary-for std::runtime_error (0x0x7f3d4b6184e0)
+
+Vtable for std::range_error
+std::range_error::_ZTVSt11range_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt11range_error)
+16 (int (*)(...))std::range_error::~range_error
+24 (int (*)(...))std::range_error::~range_error
+32 (int (*)(...))std::runtime_error::what
+
+Class std::range_error
+ size=16 align=8
+ base size=16 base align=8
+std::range_error (0x0x7f3d4b618548) 0
+ vptr=((& std::range_error::_ZTVSt11range_error) + 16u)
+ std::runtime_error (0x0x7f3d4b6185b0) 0
+ primary-for std::range_error (0x0x7f3d4b618548)
+ std::exception (0x0x7f3d4b913de0) 0 nearly-empty
+ primary-for std::runtime_error (0x0x7f3d4b6185b0)
+
+Vtable for std::overflow_error
+std::overflow_error::_ZTVSt14overflow_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt14overflow_error)
+16 (int (*)(...))std::overflow_error::~overflow_error
+24 (int (*)(...))std::overflow_error::~overflow_error
+32 (int (*)(...))std::runtime_error::what
+
+Class std::overflow_error
+ size=16 align=8
+ base size=16 base align=8
+std::overflow_error (0x0x7f3d4b618618) 0
+ vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16u)
+ std::runtime_error (0x0x7f3d4b618680) 0
+ primary-for std::overflow_error (0x0x7f3d4b618618)
+ std::exception (0x0x7f3d4b913e40) 0 nearly-empty
+ primary-for std::runtime_error (0x0x7f3d4b618680)
+
+Vtable for std::underflow_error
+std::underflow_error::_ZTVSt15underflow_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt15underflow_error)
+16 (int (*)(...))std::underflow_error::~underflow_error
+24 (int (*)(...))std::underflow_error::~underflow_error
+32 (int (*)(...))std::runtime_error::what
+
+Class std::underflow_error
+ size=16 align=8
+ base size=16 base align=8
+std::underflow_error (0x0x7f3d4b6186e8) 0
+ vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16u)
+ std::runtime_error (0x0x7f3d4b618750) 0
+ primary-for std::underflow_error (0x0x7f3d4b6186e8)
+ std::exception (0x0x7f3d4b913ea0) 0 nearly-empty
+ primary-for std::runtime_error (0x0x7f3d4b618750)
+
+Vtable for std::_V2::error_category
+std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt3_V214error_categoryE)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))std::_V2::error_category::_M_message
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))std::_V2::error_category::default_error_condition
+64 (int (*)(...))std::_V2::error_category::equivalent
+72 (int (*)(...))std::_V2::error_category::equivalent
+
+Class std::_V2::error_category
+ size=8 align=8
+ base size=8 base align=8
+std::_V2::error_category (0x0x7f3d4b656060) 0 nearly-empty
+ vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16u)
+
+Class std::error_code
+ size=16 align=8
+ base size=16 base align=8
+std::error_code (0x0x7f3d4b6562a0) 0
+
+Class std::error_condition
+ size=16 align=8
+ base size=16 base align=8
+std::error_condition (0x0x7f3d4b656420) 0
+
+Vtable for std::system_error
+std::system_error::_ZTVSt12system_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt12system_error)
+16 (int (*)(...))std::system_error::~system_error
+24 (int (*)(...))std::system_error::~system_error
+32 (int (*)(...))std::runtime_error::what
+
+Class std::system_error
+ size=32 align=8
+ base size=32 base align=8
+std::system_error (0x0x7f3d4b618c30) 0
+ vptr=((& std::system_error::_ZTVSt12system_error) + 16u)
+ std::runtime_error (0x0x7f3d4b618c98) 0
+ primary-for std::system_error (0x0x7f3d4b618c30)
+ std::exception (0x0x7f3d4b656660) 0 nearly-empty
+ primary-for std::runtime_error (0x0x7f3d4b618c98)
+
+Vtable for std::ios_base::failure
+std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E)
+16 (int (*)(...))std::ios_base::failure::~failure
+24 (int (*)(...))std::ios_base::failure::~failure
+32 (int (*)(...))std::ios_base::failure::what
+
+Class std::ios_base::failure
+ size=32 align=8
+ base size=32 base align=8
+std::ios_base::failure (0x0x7f3d4b6b3888) 0
+ vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16u)
+ std::system_error (0x0x7f3d4b6b38f0) 0
+ primary-for std::ios_base::failure (0x0x7f3d4b6b3888)
+ std::runtime_error (0x0x7f3d4b6b3958) 0
+ primary-for std::system_error (0x0x7f3d4b6b38f0)
+ std::exception (0x0x7f3d4b656960) 0 nearly-empty
+ primary-for std::runtime_error (0x0x7f3d4b6b3958)
+
+Class std::ios_base::_Callback_list
+ size=24 align=8
+ base size=24 base align=8
+std::ios_base::_Callback_list (0x0x7f3d4b6569c0) 0
+
+Class std::ios_base::_Words
+ size=16 align=8
+ base size=16 base align=8
+std::ios_base::_Words (0x0x7f3d4b656a20) 0
+
+Class std::ios_base::Init
+ size=1 align=1
+ base size=0 base align=1
+std::ios_base::Init (0x0x7f3d4b656a80) 0 empty
+
+Vtable for std::ios_base
+std::ios_base::_ZTVSt8ios_base: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt8ios_base)
+16 (int (*)(...))std::ios_base::~ios_base
+24 (int (*)(...))std::ios_base::~ios_base
+
+Class std::ios_base
+ size=216 align=8
+ base size=216 base align=8
+std::ios_base (0x0x7f3d4b656900) 0
+ vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u)
+
+Class std::ctype_base
+ size=1 align=1
+ base size=0 base align=1
+std::ctype_base (0x0x7f3d4b38a240) 0 empty
+
+Class std::__num_base
+ size=1 align=1
+ base size=0 base align=1
+std::__num_base (0x0x7f3d4b38a900) 0 empty
+
+VTT for std::basic_ostream<char>
+std::basic_ostream<char>::_ZTTSo: 2u entries
+0 ((& std::basic_ostream<char>::_ZTVSo) + 24u)
+8 ((& std::basic_ostream<char>::_ZTVSo) + 64u)
+
+VTT for std::basic_ostream<wchar_t>
+std::basic_ostream<wchar_t>::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries
+0 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u)
+8 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u)
+
+VTT for std::basic_istream<char>
+std::basic_istream<char>::_ZTTSi: 2u entries
+0 ((& std::basic_istream<char>::_ZTVSi) + 24u)
+8 ((& std::basic_istream<char>::_ZTVSi) + 64u)
+
+VTT for std::basic_istream<wchar_t>
+std::basic_istream<wchar_t>::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries
+0 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u)
+8 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u)
+
+Construction vtable for std::basic_istream<char> (0x0x7f3d4b377208 instance) in std::basic_iostream<char>
+std::basic_iostream<char>::_ZTCSd0_Si: 10u entries
+0 24u
+8 (int (*)(...))0
+16 (int (*)(...))(& _ZTISi)
+24 0u
+32 0u
+40 18446744073709551592u
+48 (int (*)(...))-24
+56 (int (*)(...))(& _ZTISi)
+64 0u
+72 0u
+
+Construction vtable for std::basic_ostream<char> (0x0x7f3d4b3772d8 instance) in std::basic_iostream<char>
+std::basic_iostream<char>::_ZTCSd16_So: 10u entries
+0 8u
+8 (int (*)(...))0
+16 (int (*)(...))(& _ZTISo)
+24 0u
+32 0u
+40 18446744073709551608u
+48 (int (*)(...))-8
+56 (int (*)(...))(& _ZTISo)
+64 0u
+72 0u
+
+VTT for std::basic_iostream<char>
+std::basic_iostream<char>::_ZTTSd: 7u entries
+0 ((& std::basic_iostream<char>::_ZTVSd) + 24u)
+8 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 24u)
+16 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 64u)
+24 ((& std::basic_iostream<char>::_ZTCSd16_So) + 24u)
+32 ((& std::basic_iostream<char>::_ZTCSd16_So) + 64u)
+40 ((& std::basic_iostream<char>::_ZTVSd) + 104u)
+48 ((& std::basic_iostream<char>::_ZTVSd) + 64u)
+
+Construction vtable for std::basic_istream<wchar_t> (0x0x7f3d4b377680 instance) in std::basic_iostream<wchar_t>
+std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries
+0 24u
+8 (int (*)(...))0
+16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE)
+24 0u
+32 0u
+40 18446744073709551592u
+48 (int (*)(...))-24
+56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE)
+64 0u
+72 0u
+
+Construction vtable for std::basic_ostream<wchar_t> (0x0x7f3d4b377750 instance) in std::basic_iostream<wchar_t>
+std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries
+0 8u
+8 (int (*)(...))0
+16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE)
+24 0u
+32 0u
+40 18446744073709551608u
+48 (int (*)(...))-8
+56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE)
+64 0u
+72 0u
+
+VTT for std::basic_iostream<wchar_t>
+std::basic_iostream<wchar_t>::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries
+0 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u)
+8 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u)
+16 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u)
+24 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u)
+32 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u)
+40 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u)
+48 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u)
+
+Class QByteArrayDataPtr
+ size=8 align=8
+ base size=8 base align=8
+QByteArrayDataPtr (0x0x7f3d4afc6180) 0
+
+Class QByteArray
+ size=8 align=8
+ base size=8 base align=8
+QByteArray (0x0x7f3d4afc61e0) 0
+
+Class QByteRef
+ size=16 align=8
+ base size=12 base align=8
+QByteRef (0x0x7f3d4b0c3540) 0
+
+Class QStringDataPtr
+ size=8 align=8
+ base size=8 base align=8
+QStringDataPtr (0x0x7f3d4b0c38a0) 0
+
+Class QStringView
+ size=16 align=8
+ base size=16 base align=8
+QStringView (0x0x7f3d4b0c3d20) 0
+
+Class QLatin1String
+ size=16 align=8
+ base size=16 base align=8
+QLatin1String (0x0x7f3d4adf2ba0) 0
+
+Class QString::Null
+ size=1 align=1
+ base size=0 base align=1
+QString::Null (0x0x7f3d4ae81240) 0 empty
+
+Class QString
+ size=8 align=8
+ base size=8 base align=8
+QString (0x0x7f3d4ae811e0) 0
+
+Class QCharRef
+ size=16 align=8
+ base size=12 base align=8
+QCharRef (0x0x7f3d4ac29300) 0
+
+Class QStringRef
+ size=16 align=8
+ base size=16 base align=8
+QStringRef (0x0x7f3d4ac29f00) 0
+
+Class QtPrivate::QHashCombine
+ size=1 align=1
+ base size=0 base align=1
+QtPrivate::QHashCombine (0x0x7f3d4aa27b40) 0 empty
+
+Class QtPrivate::QHashCombineCommutative
+ size=1 align=1
+ base size=0 base align=1
+QtPrivate::QHashCombineCommutative (0x0x7f3d4aa27ba0) 0 empty
+
+Class std::__detail::_List_node_base
+ size=16 align=8
+ base size=16 base align=8
+std::__detail::_List_node_base (0x0x7f3d4aa27c00) 0
+
+Class QListData::NotArrayCompatibleLayout
+ size=1 align=1
+ base size=0 base align=1
+QListData::NotArrayCompatibleLayout (0x0x7f3d4a85f000) 0 empty
+
+Class QListData::NotIndirectLayout
+ size=1 align=1
+ base size=0 base align=1
+QListData::NotIndirectLayout (0x0x7f3d4a85f060) 0 empty
+
+Class QListData::ArrayCompatibleLayout
+ size=1 align=1
+ base size=1 base align=1
+QListData::ArrayCompatibleLayout (0x0x7f3d4a7a61a0) 0 empty
+ QListData::NotIndirectLayout (0x0x7f3d4a85f0c0) 0 empty
+
+Class QListData::InlineWithPaddingLayout
+ size=1 align=1
+ base size=1 base align=1
+QListData::InlineWithPaddingLayout (0x0x7f3d4a862150) 0 empty
+ QListData::NotArrayCompatibleLayout (0x0x7f3d4a85f120) 0 empty
+ QListData::NotIndirectLayout (0x0x7f3d4a85f180) 0 empty
+
+Class QListData::IndirectLayout
+ size=1 align=1
+ base size=1 base align=1
+QListData::IndirectLayout (0x0x7f3d4a7a6208) 0 empty
+ QListData::NotArrayCompatibleLayout (0x0x7f3d4a85f1e0) 0 empty
+
+Class QListData::Data
+ size=24 align=8
+ base size=24 base align=8
+QListData::Data (0x0x7f3d4a85f240) 0
+
+Class QListData
+ size=8 align=8
+ base size=8 base align=8
+QListData (0x0x7f3d4aa27f60) 0
+
+Class QRegExp
+ size=8 align=8
+ base size=8 base align=8
+QRegExp (0x0x7f3d4a85f6c0) 0
+
+Class QStringMatcher::Data
+ size=272 align=8
+ base size=272 base align=8
+QStringMatcher::Data (0x0x7f3d4a609900) 0
+
+Class QStringMatcher
+ size=1048 align=8
+ base size=1048 base align=8
+QStringMatcher (0x0x7f3d4a6098a0) 0
+
+Class QStringList
+ size=8 align=8
+ base size=8 base align=8
+QStringList (0x0x7f3d4a608c30) 0
+ QList<QString> (0x0x7f3d4a608c98) 0
+ QListSpecialMethods<QString> (0x0x7f3d4a609ae0) 0 empty
+
+Class QScopedPointerPodDeleter
+ size=1 align=1
+ base size=0 base align=1
+QScopedPointerPodDeleter (0x0x7f3d4a609f00) 0 empty
+
+Class std::_Rb_tree_node_base
+ size=32 align=8
+ base size=32 base align=8
+std::_Rb_tree_node_base (0x0x7f3d4a6aba20) 0
+
+Class std::allocator_arg_t
+ size=1 align=1
+ base size=0 base align=1
+std::allocator_arg_t (0x0x7f3d4a4b00c0) 0 empty
+
+Class std::__uses_alloc_base
+ size=1 align=1
+ base size=0 base align=1
+std::__uses_alloc_base (0x0x7f3d4a4b0240) 0 empty
+
+Class std::__uses_alloc0::_Sink
+ size=1 align=1
+ base size=0 base align=1
+std::__uses_alloc0::_Sink (0x0x7f3d4a4b0300) 0 empty
+
+Class std::__uses_alloc0
+ size=1 align=1
+ base size=1 base align=1
+std::__uses_alloc0 (0x0x7f3d4a6855b0) 0
+ std::__uses_alloc_base (0x0x7f3d4a4b02a0) 0 empty
+
+Class std::_Swallow_assign
+ size=1 align=1
+ base size=0 base align=1
+std::_Swallow_assign (0x0x7f3d4a19f360) 0 empty
+
+Class QtPrivate::AbstractDebugStreamFunction
+ size=16 align=8
+ base size=16 base align=8
+QtPrivate::AbstractDebugStreamFunction (0x0x7f3d4a19f5a0) 0
+
+Class QtPrivate::AbstractComparatorFunction
+ size=24 align=8
+ base size=24 base align=8
+QtPrivate::AbstractComparatorFunction (0x0x7f3d4a19f660) 0
+
+Class QtPrivate::AbstractConverterFunction
+ size=8 align=8
+ base size=8 base align=8
+QtPrivate::AbstractConverterFunction (0x0x7f3d4a19f780) 0
+
+Class QMetaType
+ size=80 align=8
+ base size=80 base align=8
+QMetaType (0x0x7f3d4a19f900) 0
+
+Class QtMetaTypePrivate::VariantData
+ size=24 align=8
+ base size=20 base align=8
+QtMetaTypePrivate::VariantData (0x0x7f3d4a19fd20) 0
+
+Class QtMetaTypePrivate::VectorBoolElements
+ size=1 align=1
+ base size=0 base align=1
+QtMetaTypePrivate::VectorBoolElements (0x0x7f3d4a19fe40) 0 empty
+
+Class QtMetaTypePrivate::QSequentialIterableImpl
+ size=104 align=8
+ base size=104 base align=8
+QtMetaTypePrivate::QSequentialIterableImpl (0x0x7f3d4a3057e0) 0
+
+Class QtMetaTypePrivate::QAssociativeIterableImpl
+ size=112 align=8
+ base size=112 base align=8
+QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7f3d4a305c00) 0
+
+Class QtMetaTypePrivate::QPairVariantInterfaceImpl
+ size=40 align=8
+ base size=40 base align=8
+QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7f3d4a305f00) 0
+
+Class std::chrono::_V2::system_clock
+ size=1 align=1
+ base size=0 base align=1
+std::chrono::_V2::system_clock (0x0x7f3d49df3780) 0 empty
+
+Class std::chrono::_V2::steady_clock
+ size=1 align=1
+ base size=0 base align=1
+std::chrono::_V2::steady_clock (0x0x7f3d49f42600) 0 empty
+
+Vtable for QObjectData
+QObjectData::_ZTV11QObjectData: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QObjectData)
+16 (int (*)(...))__cxa_pure_virtual
+24 (int (*)(...))__cxa_pure_virtual
+
+Class QObjectData
+ size=48 align=8
+ base size=48 base align=8
+QObjectData (0x0x7f3d49f42660) 0
+ vptr=((& QObjectData::_ZTV11QObjectData) + 16u)
+
+Class QObject::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QObject::QPrivateSignal (0x0x7f3d49f42840) 0 empty
+
+Vtable for QObject
+QObject::_ZTV7QObject: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QObject)
+16 (int (*)(...))QObject::metaObject
+24 (int (*)(...))QObject::qt_metacast
+32 (int (*)(...))QObject::qt_metacall
+40 (int (*)(...))QObject::~QObject
+48 (int (*)(...))QObject::~QObject
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QObject
+ size=16 align=8
+ base size=16 base align=8
+QObject (0x0x7f3d49f427e0) 0
+ vptr=((& QObject::_ZTV7QObject) + 16u)
+
+Vtable for QObjectUserData
+QObjectUserData::_ZTV15QObjectUserData: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QObjectUserData)
+16 (int (*)(...))QObjectUserData::~QObjectUserData
+24 (int (*)(...))QObjectUserData::~QObjectUserData
+
+Class QObjectUserData
+ size=8 align=8
+ base size=8 base align=8
+QObjectUserData (0x0x7f3d49c07ae0) 0 nearly-empty
+ vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u)
+
+Class QSignalBlocker
+ size=16 align=8
+ base size=10 base align=8
+QSignalBlocker (0x0x7f3d49c07b40) 0
+
+Class QAbstractAnimation::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractAnimation::QPrivateSignal (0x0x7f3d49c07c00) 0 empty
+
+Vtable for QAbstractAnimation
+QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QAbstractAnimation)
+16 (int (*)(...))QAbstractAnimation::metaObject
+24 (int (*)(...))QAbstractAnimation::qt_metacast
+32 (int (*)(...))QAbstractAnimation::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QAbstractAnimation::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))QAbstractAnimation::updateState
+136 (int (*)(...))QAbstractAnimation::updateDirection
+
+Class QAbstractAnimation
+ size=16 align=8
+ base size=16 base align=8
+QAbstractAnimation (0x0x7f3d49c317b8) 0
+ vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u)
+ QObject (0x0x7f3d49c07ba0) 0
+ primary-for QAbstractAnimation (0x0x7f3d49c317b8)
+
+Class QAnimationDriver::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAnimationDriver::QPrivateSignal (0x0x7f3d49c07cc0) 0 empty
+
+Vtable for QAnimationDriver
+QAnimationDriver::_ZTV16QAnimationDriver: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QAnimationDriver)
+16 (int (*)(...))QAnimationDriver::metaObject
+24 (int (*)(...))QAnimationDriver::qt_metacast
+32 (int (*)(...))QAnimationDriver::qt_metacall
+40 (int (*)(...))QAnimationDriver::~QAnimationDriver
+48 (int (*)(...))QAnimationDriver::~QAnimationDriver
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAnimationDriver::advance
+120 (int (*)(...))QAnimationDriver::elapsed
+128 (int (*)(...))QAnimationDriver::start
+136 (int (*)(...))QAnimationDriver::stop
+
+Class QAnimationDriver
+ size=16 align=8
+ base size=16 base align=8
+QAnimationDriver (0x0x7f3d49c31820) 0
+ vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u)
+ QObject (0x0x7f3d49c07c60) 0
+ primary-for QAnimationDriver (0x0x7f3d49c31820)
+
+Class QEventLoop::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QEventLoop::QPrivateSignal (0x0x7f3d49c07d80) 0 empty
+
+Vtable for QEventLoop
+QEventLoop::_ZTV10QEventLoop: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QEventLoop)
+16 (int (*)(...))QEventLoop::metaObject
+24 (int (*)(...))QEventLoop::qt_metacast
+32 (int (*)(...))QEventLoop::qt_metacall
+40 (int (*)(...))QEventLoop::~QEventLoop
+48 (int (*)(...))QEventLoop::~QEventLoop
+56 (int (*)(...))QEventLoop::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QEventLoop
+ size=16 align=8
+ base size=16 base align=8
+QEventLoop (0x0x7f3d49c31888) 0
+ vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u)
+ QObject (0x0x7f3d49c07d20) 0
+ primary-for QEventLoop (0x0x7f3d49c31888)
+
+Class QEventLoopLocker
+ size=8 align=8
+ base size=8 base align=8
+QEventLoopLocker (0x0x7f3d49c07f60) 0
+
+Class QAbstractEventDispatcher::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractEventDispatcher::QPrivateSignal (0x0x7f3d49cc0060) 0 empty
+
+Class QAbstractEventDispatcher::TimerInfo
+ size=12 align=4
+ base size=12 base align=4
+QAbstractEventDispatcher::TimerInfo (0x0x7f3d49cc00c0) 0
+
+Vtable for QAbstractEventDispatcher
+QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher)
+16 (int (*)(...))QAbstractEventDispatcher::metaObject
+24 (int (*)(...))QAbstractEventDispatcher::qt_metacast
+32 (int (*)(...))QAbstractEventDispatcher::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))__cxa_pure_virtual
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))__cxa_pure_virtual
+176 (int (*)(...))__cxa_pure_virtual
+184 (int (*)(...))__cxa_pure_virtual
+192 (int (*)(...))__cxa_pure_virtual
+200 (int (*)(...))__cxa_pure_virtual
+208 (int (*)(...))QAbstractEventDispatcher::startingUp
+216 (int (*)(...))QAbstractEventDispatcher::closingDown
+
+Class QAbstractEventDispatcher
+ size=16 align=8
+ base size=16 base align=8
+QAbstractEventDispatcher (0x0x7f3d49c319c0) 0
+ vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u)
+ QObject (0x0x7f3d49cc0000) 0
+ primary-for QAbstractEventDispatcher (0x0x7f3d49c319c0)
+
+Vtable for std::type_info
+std::type_info::_ZTVSt9type_info: 8u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt9type_info)
+16 (int (*)(...))std::type_info::~type_info
+24 (int (*)(...))std::type_info::~type_info
+32 (int (*)(...))std::type_info::__is_pointer_p
+40 (int (*)(...))std::type_info::__is_function_p
+48 (int (*)(...))std::type_info::__do_catch
+56 (int (*)(...))std::type_info::__do_upcast
+
+Class std::type_info
+ size=16 align=8
+ base size=16 base align=8
+std::type_info (0x0x7f3d49cc0360) 0
+ vptr=((& std::type_info::_ZTVSt9type_info) + 16u)
+
+Vtable for std::bad_cast
+std::bad_cast::_ZTVSt8bad_cast: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt8bad_cast)
+16 (int (*)(...))std::bad_cast::~bad_cast
+24 (int (*)(...))std::bad_cast::~bad_cast
+32 (int (*)(...))std::bad_cast::what
+
+Class std::bad_cast
+ size=8 align=8
+ base size=8 base align=8
+std::bad_cast (0x0x7f3d49c31bc8) 0 nearly-empty
+ vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16u)
+ std::exception (0x0x7f3d49cc03c0) 0 nearly-empty
+ primary-for std::bad_cast (0x0x7f3d49c31bc8)
+
+Vtable for std::bad_typeid
+std::bad_typeid::_ZTVSt10bad_typeid: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt10bad_typeid)
+16 (int (*)(...))std::bad_typeid::~bad_typeid
+24 (int (*)(...))std::bad_typeid::~bad_typeid
+32 (int (*)(...))std::bad_typeid::what
+
+Class std::bad_typeid
+ size=8 align=8
+ base size=8 base align=8
+std::bad_typeid (0x0x7f3d49c31c30) 0 nearly-empty
+ vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16u)
+ std::exception (0x0x7f3d49cc0420) 0 nearly-empty
+ primary-for std::bad_typeid (0x0x7f3d49c31c30)
+
+Vtable for std::bad_function_call
+std::bad_function_call::_ZTVSt17bad_function_call: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt17bad_function_call)
+16 (int (*)(...))std::bad_function_call::~bad_function_call
+24 (int (*)(...))std::bad_function_call::~bad_function_call
+32 (int (*)(...))std::bad_function_call::what
+
+Class std::bad_function_call
+ size=8 align=8
+ base size=8 base align=8
+std::bad_function_call (0x0x7f3d49982ea0) 0 nearly-empty
+ vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16u)
+ std::exception (0x0x7f3d49a594e0) 0 nearly-empty
+ primary-for std::bad_function_call (0x0x7f3d49982ea0)
+
+Class std::_Nocopy_types
+ size=16 align=8
+ base size=16 base align=8
+std::_Nocopy_types (0x0x7f3d49a595a0) 0
+
+Class std::_Any_data
+ size=16 align=8
+ base size=16 base align=8
+std::_Any_data (0x0x7f3d49a59600) 0
+
+Class std::_Function_base
+ size=24 align=8
+ base size=24 base align=8
+std::_Function_base (0x0x7f3d49a59720) 0
+
+Class QMapNodeBase
+ size=24 align=8
+ base size=24 base align=8
+QMapNodeBase (0x0x7f3d49a59c00) 0
+
+Class QMapDataBase
+ size=40 align=8
+ base size=40 base align=8
+QMapDataBase (0x0x7f3d49b0c180) 0
+
+Class QHashData::Node
+ size=16 align=8
+ base size=16 base align=8
+QHashData::Node (0x0x7f3d49b0c540) 0
+
+Class QHashData
+ size=48 align=8
+ base size=44 base align=8
+QHashData (0x0x7f3d49b0c4e0) 0
+
+Class QHashDummyValue
+ size=1 align=1
+ base size=0 base align=1
+QHashDummyValue (0x0x7f3d49b0c5a0) 0 empty
+
+Class QVariant::PrivateShared
+ size=16 align=8
+ base size=12 base align=8
+QVariant::PrivateShared (0x0x7f3d49b0ce40) 0
+
+Class QVariant::Private::Data
+ size=8 align=8
+ base size=8 base align=8
+QVariant::Private::Data (0x0x7f3d49b0cf00) 0
+
+Class QVariant::Private
+ size=16 align=8
+ base size=12 base align=8
+QVariant::Private (0x0x7f3d49b0cea0) 0
+
+Class QVariant::Handler
+ size=72 align=8
+ base size=72 base align=8
+QVariant::Handler (0x0x7f3d49b0cf60) 0
+
+Class QVariant
+ size=16 align=8
+ base size=16 base align=8
+QVariant (0x0x7f3d49b0cde0) 0
+
+Class QVariantComparisonHelper
+ size=8 align=8
+ base size=8 base align=8
+QVariantComparisonHelper (0x0x7f3d495e9a80) 0
+
+Class QSequentialIterable::const_iterator
+ size=112 align=8
+ base size=112 base align=8
+QSequentialIterable::const_iterator (0x0x7f3d49690120) 0
+
+Class QSequentialIterable
+ size=104 align=8
+ base size=104 base align=8
+QSequentialIterable (0x0x7f3d496900c0) 0
+
+Class QAssociativeIterable::const_iterator
+ size=120 align=8
+ base size=120 base align=8
+QAssociativeIterable::const_iterator (0x0x7f3d496901e0) 0
+
+Class QAssociativeIterable
+ size=112 align=8
+ base size=112 base align=8
+QAssociativeIterable (0x0x7f3d49690180) 0
+
+Class QModelIndex
+ size=24 align=8
+ base size=24 base align=8
+QModelIndex (0x0x7f3d493aa4e0) 0
+
+Class QPersistentModelIndex
+ size=8 align=8
+ base size=8 base align=8
+QPersistentModelIndex (0x0x7f3d493aaba0) 0
+
+Class QAbstractItemModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractItemModel::QPrivateSignal (0x0x7f3d49180300) 0 empty
+
+Vtable for QAbstractItemModel
+QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QAbstractItemModel)
+16 (int (*)(...))QAbstractItemModel::metaObject
+24 (int (*)(...))QAbstractItemModel::qt_metacast
+32 (int (*)(...))QAbstractItemModel::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))QAbstractItemModel::sibling
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))QAbstractItemModel::hasChildren
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))QAbstractItemModel::setData
+176 (int (*)(...))QAbstractItemModel::headerData
+184 (int (*)(...))QAbstractItemModel::setHeaderData
+192 (int (*)(...))QAbstractItemModel::itemData
+200 (int (*)(...))QAbstractItemModel::setItemData
+208 (int (*)(...))QAbstractItemModel::mimeTypes
+216 (int (*)(...))QAbstractItemModel::mimeData
+224 (int (*)(...))QAbstractItemModel::canDropMimeData
+232 (int (*)(...))QAbstractItemModel::dropMimeData
+240 (int (*)(...))QAbstractItemModel::supportedDropActions
+248 (int (*)(...))QAbstractItemModel::supportedDragActions
+256 (int (*)(...))QAbstractItemModel::insertRows
+264 (int (*)(...))QAbstractItemModel::insertColumns
+272 (int (*)(...))QAbstractItemModel::removeRows
+280 (int (*)(...))QAbstractItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractItemModel::fetchMore
+312 (int (*)(...))QAbstractItemModel::canFetchMore
+320 (int (*)(...))QAbstractItemModel::flags
+328 (int (*)(...))QAbstractItemModel::sort
+336 (int (*)(...))QAbstractItemModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractItemModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractItemModel::submit
+376 (int (*)(...))QAbstractItemModel::revert
+
+Class QAbstractItemModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractItemModel (0x0x7f3d4916ac30) 0
+ vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u)
+ QObject (0x0x7f3d491802a0) 0
+ primary-for QAbstractItemModel (0x0x7f3d4916ac30)
+
+Class QAbstractTableModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractTableModel::QPrivateSignal (0x0x7f3d49180660) 0 empty
+
+Vtable for QAbstractTableModel
+QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QAbstractTableModel)
+16 (int (*)(...))QAbstractTableModel::metaObject
+24 (int (*)(...))QAbstractTableModel::qt_metacast
+32 (int (*)(...))QAbstractTableModel::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAbstractTableModel::index
+120 (int (*)(...))QAbstractTableModel::parent
+128 (int (*)(...))QAbstractTableModel::sibling
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))QAbstractTableModel::hasChildren
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))QAbstractItemModel::setData
+176 (int (*)(...))QAbstractItemModel::headerData
+184 (int (*)(...))QAbstractItemModel::setHeaderData
+192 (int (*)(...))QAbstractItemModel::itemData
+200 (int (*)(...))QAbstractItemModel::setItemData
+208 (int (*)(...))QAbstractItemModel::mimeTypes
+216 (int (*)(...))QAbstractItemModel::mimeData
+224 (int (*)(...))QAbstractItemModel::canDropMimeData
+232 (int (*)(...))QAbstractTableModel::dropMimeData
+240 (int (*)(...))QAbstractItemModel::supportedDropActions
+248 (int (*)(...))QAbstractItemModel::supportedDragActions
+256 (int (*)(...))QAbstractItemModel::insertRows
+264 (int (*)(...))QAbstractItemModel::insertColumns
+272 (int (*)(...))QAbstractItemModel::removeRows
+280 (int (*)(...))QAbstractItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractItemModel::fetchMore
+312 (int (*)(...))QAbstractItemModel::canFetchMore
+320 (int (*)(...))QAbstractTableModel::flags
+328 (int (*)(...))QAbstractItemModel::sort
+336 (int (*)(...))QAbstractItemModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractItemModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractItemModel::submit
+376 (int (*)(...))QAbstractItemModel::revert
+
+Class QAbstractTableModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractTableModel (0x0x7f3d4916ae38) 0
+ vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u)
+ QAbstractItemModel (0x0x7f3d4916aea0) 0
+ primary-for QAbstractTableModel (0x0x7f3d4916ae38)
+ QObject (0x0x7f3d49180600) 0
+ primary-for QAbstractItemModel (0x0x7f3d4916aea0)
+
+Class QAbstractListModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractListModel::QPrivateSignal (0x0x7f3d49180720) 0 empty
+
+Vtable for QAbstractListModel
+QAbstractListModel::_ZTV18QAbstractListModel: 48u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QAbstractListModel)
+16 (int (*)(...))QAbstractListModel::metaObject
+24 (int (*)(...))QAbstractListModel::qt_metacast
+32 (int (*)(...))QAbstractListModel::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAbstractListModel::index
+120 (int (*)(...))QAbstractListModel::parent
+128 (int (*)(...))QAbstractListModel::sibling
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))QAbstractListModel::columnCount
+152 (int (*)(...))QAbstractListModel::hasChildren
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))QAbstractItemModel::setData
+176 (int (*)(...))QAbstractItemModel::headerData
+184 (int (*)(...))QAbstractItemModel::setHeaderData
+192 (int (*)(...))QAbstractItemModel::itemData
+200 (int (*)(...))QAbstractItemModel::setItemData
+208 (int (*)(...))QAbstractItemModel::mimeTypes
+216 (int (*)(...))QAbstractItemModel::mimeData
+224 (int (*)(...))QAbstractItemModel::canDropMimeData
+232 (int (*)(...))QAbstractListModel::dropMimeData
+240 (int (*)(...))QAbstractItemModel::supportedDropActions
+248 (int (*)(...))QAbstractItemModel::supportedDragActions
+256 (int (*)(...))QAbstractItemModel::insertRows
+264 (int (*)(...))QAbstractItemModel::insertColumns
+272 (int (*)(...))QAbstractItemModel::removeRows
+280 (int (*)(...))QAbstractItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractItemModel::fetchMore
+312 (int (*)(...))QAbstractItemModel::canFetchMore
+320 (int (*)(...))QAbstractListModel::flags
+328 (int (*)(...))QAbstractItemModel::sort
+336 (int (*)(...))QAbstractItemModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractItemModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractItemModel::submit
+376 (int (*)(...))QAbstractItemModel::revert
+
+Class QAbstractListModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractListModel (0x0x7f3d4916af08) 0
+ vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u)
+ QAbstractItemModel (0x0x7f3d4916af70) 0
+ primary-for QAbstractListModel (0x0x7f3d4916af08)
+ QObject (0x0x7f3d491806c0) 0
+ primary-for QAbstractItemModel (0x0x7f3d4916af70)
+
+Vtable for QAbstractNativeEventFilter
+QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class QAbstractNativeEventFilter
+ size=16 align=8
+ base size=16 base align=8
+QAbstractNativeEventFilter (0x0x7f3d491809c0) 0
+ vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u)
+
+Class QAbstractProxyModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractProxyModel::QPrivateSignal (0x0x7f3d49180a80) 0 empty
+
+Vtable for QAbstractProxyModel
+QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QAbstractProxyModel)
+16 (int (*)(...))QAbstractProxyModel::metaObject
+24 (int (*)(...))QAbstractProxyModel::qt_metacast
+32 (int (*)(...))QAbstractProxyModel::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))QAbstractProxyModel::sibling
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))QAbstractProxyModel::hasChildren
+160 (int (*)(...))QAbstractProxyModel::data
+168 (int (*)(...))QAbstractProxyModel::setData
+176 (int (*)(...))QAbstractProxyModel::headerData
+184 (int (*)(...))QAbstractProxyModel::setHeaderData
+192 (int (*)(...))QAbstractProxyModel::itemData
+200 (int (*)(...))QAbstractProxyModel::setItemData
+208 (int (*)(...))QAbstractProxyModel::mimeTypes
+216 (int (*)(...))QAbstractProxyModel::mimeData
+224 (int (*)(...))QAbstractProxyModel::canDropMimeData
+232 (int (*)(...))QAbstractProxyModel::dropMimeData
+240 (int (*)(...))QAbstractProxyModel::supportedDropActions
+248 (int (*)(...))QAbstractProxyModel::supportedDragActions
+256 (int (*)(...))QAbstractItemModel::insertRows
+264 (int (*)(...))QAbstractItemModel::insertColumns
+272 (int (*)(...))QAbstractItemModel::removeRows
+280 (int (*)(...))QAbstractItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractProxyModel::fetchMore
+312 (int (*)(...))QAbstractProxyModel::canFetchMore
+320 (int (*)(...))QAbstractProxyModel::flags
+328 (int (*)(...))QAbstractProxyModel::sort
+336 (int (*)(...))QAbstractProxyModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractProxyModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractProxyModel::submit
+376 (int (*)(...))QAbstractProxyModel::revert
+384 (int (*)(...))QAbstractProxyModel::setSourceModel
+392 (int (*)(...))__cxa_pure_virtual
+400 (int (*)(...))__cxa_pure_virtual
+408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource
+416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource
+
+Class QAbstractProxyModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractProxyModel (0x0x7f3d492560d0) 0
+ vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u)
+ QAbstractItemModel (0x0x7f3d49256138) 0
+ primary-for QAbstractProxyModel (0x0x7f3d492560d0)
+ QObject (0x0x7f3d49180a20) 0
+ primary-for QAbstractItemModel (0x0x7f3d49256138)
+
+Class QAbstractState::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractState::QPrivateSignal (0x0x7f3d49180b40) 0 empty
+
+Vtable for QAbstractState
+QAbstractState::_ZTV14QAbstractState: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QAbstractState)
+16 (int (*)(...))QAbstractState::metaObject
+24 (int (*)(...))QAbstractState::qt_metacast
+32 (int (*)(...))QAbstractState::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QAbstractState::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+
+Class QAbstractState
+ size=16 align=8
+ base size=16 base align=8
+QAbstractState (0x0x7f3d492561a0) 0
+ vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u)
+ QObject (0x0x7f3d49180ae0) 0
+ primary-for QAbstractState (0x0x7f3d492561a0)
+
+Class QAbstractTransition::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractTransition::QPrivateSignal (0x0x7f3d49180c00) 0 empty
+
+Vtable for QAbstractTransition
+QAbstractTransition::_ZTV19QAbstractTransition: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QAbstractTransition)
+16 (int (*)(...))QAbstractTransition::metaObject
+24 (int (*)(...))QAbstractTransition::qt_metacast
+32 (int (*)(...))QAbstractTransition::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QAbstractTransition::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+
+Class QAbstractTransition
+ size=16 align=8
+ base size=16 base align=8
+QAbstractTransition (0x0x7f3d49256208) 0
+ vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u)
+ QObject (0x0x7f3d49180ba0) 0
+ primary-for QAbstractTransition (0x0x7f3d49256208)
+
+Class QAnimationGroup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAnimationGroup::QPrivateSignal (0x0x7f3d49180cc0) 0 empty
+
+Vtable for QAnimationGroup
+QAnimationGroup::_ZTV15QAnimationGroup: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QAnimationGroup)
+16 (int (*)(...))QAnimationGroup::metaObject
+24 (int (*)(...))QAnimationGroup::qt_metacast
+32 (int (*)(...))QAnimationGroup::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QAnimationGroup::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))QAbstractAnimation::updateState
+136 (int (*)(...))QAbstractAnimation::updateDirection
+
+Class QAnimationGroup
+ size=16 align=8
+ base size=16 base align=8
+QAnimationGroup (0x0x7f3d49256270) 0
+ vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u)
+ QAbstractAnimation (0x0x7f3d492562d8) 0
+ primary-for QAnimationGroup (0x0x7f3d49256270)
+ QObject (0x0x7f3d49180c60) 0
+ primary-for QAbstractAnimation (0x0x7f3d492562d8)
+
+Class QBasicTimer
+ size=4 align=4
+ base size=4 base align=4
+QBasicTimer (0x0x7f3d492f6a20) 0
+
+Class QBitArray
+ size=8 align=8
+ base size=8 base align=8
+QBitArray (0x0x7f3d492f6cc0) 0
+
+Class QBitRef
+ size=16 align=8
+ base size=12 base align=8
+QBitRef (0x0x7f3d492f6d80) 0
+
+Class QIODevice::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QIODevice::QPrivateSignal (0x0x7f3d48f8b0c0) 0 empty
+
+Vtable for QIODevice
+QIODevice::_ZTV9QIODevice: 30u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QIODevice)
+16 (int (*)(...))QIODevice::metaObject
+24 (int (*)(...))QIODevice::qt_metacast
+32 (int (*)(...))QIODevice::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QIODevice::isSequential
+120 (int (*)(...))QIODevice::open
+128 (int (*)(...))QIODevice::close
+136 (int (*)(...))QIODevice::pos
+144 (int (*)(...))QIODevice::size
+152 (int (*)(...))QIODevice::seek
+160 (int (*)(...))QIODevice::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QIODevice::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))__cxa_pure_virtual
+224 (int (*)(...))QIODevice::readLineData
+232 (int (*)(...))__cxa_pure_virtual
+
+Class QIODevice
+ size=16 align=8
+ base size=16 base align=8
+QIODevice (0x0x7f3d49256958) 0
+ vptr=((& QIODevice::_ZTV9QIODevice) + 16u)
+ QObject (0x0x7f3d48f8b060) 0
+ primary-for QIODevice (0x0x7f3d49256958)
+
+Class QBuffer::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QBuffer::QPrivateSignal (0x0x7f3d48f8b300) 0 empty
+
+Vtable for QBuffer
+QBuffer::_ZTV7QBuffer: 30u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QBuffer)
+16 (int (*)(...))QBuffer::metaObject
+24 (int (*)(...))QBuffer::qt_metacast
+32 (int (*)(...))QBuffer::qt_metacall
+40 (int (*)(...))QBuffer::~QBuffer
+48 (int (*)(...))QBuffer::~QBuffer
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QBuffer::connectNotify
+104 (int (*)(...))QBuffer::disconnectNotify
+112 (int (*)(...))QIODevice::isSequential
+120 (int (*)(...))QBuffer::open
+128 (int (*)(...))QBuffer::close
+136 (int (*)(...))QBuffer::pos
+144 (int (*)(...))QBuffer::size
+152 (int (*)(...))QBuffer::seek
+160 (int (*)(...))QBuffer::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QBuffer::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))QBuffer::readData
+224 (int (*)(...))QIODevice::readLineData
+232 (int (*)(...))QBuffer::writeData
+
+Class QBuffer
+ size=16 align=8
+ base size=16 base align=8
+QBuffer (0x0x7f3d49256a90) 0
+ vptr=((& QBuffer::_ZTV7QBuffer) + 16u)
+ QIODevice (0x0x7f3d49256af8) 0
+ primary-for QBuffer (0x0x7f3d49256a90)
+ QObject (0x0x7f3d48f8b2a0) 0
+ primary-for QIODevice (0x0x7f3d49256af8)
+
+Class QByteArrayMatcher::Data
+ size=272 align=8
+ base size=272 base align=8
+QByteArrayMatcher::Data (0x0x7f3d48f8b3c0) 0
+
+Class QByteArrayMatcher
+ size=1040 align=8
+ base size=1040 base align=8
+QByteArrayMatcher (0x0x7f3d48f8b360) 0
+
+Class QStaticByteArrayMatcherBase::Skiptable
+ size=256 align=1
+ base size=256 base align=1
+QStaticByteArrayMatcherBase::Skiptable (0x0x7f3d48f8b4e0) 0
+
+Class QStaticByteArrayMatcherBase
+ size=256 align=16
+ base size=256 base align=16
+QStaticByteArrayMatcherBase (0x0x7f3d48f8b480) 0
+
+Class QSharedData
+ size=4 align=4
+ base size=4 base align=4
+QSharedData (0x0x7f3d48f8b6c0) 0
+
+Class QLocale
+ size=8 align=8
+ base size=8 base align=8
+QLocale (0x0x7f3d48f8b8a0) 0
+
+Class QCollatorSortKey
+ size=8 align=8
+ base size=8 base align=8
+QCollatorSortKey (0x0x7f3d48f8bea0) 0
+
+Class QCollator
+ size=8 align=8
+ base size=8 base align=8
+QCollator (0x0x7f3d48f8bf60) 0
+
+Class QCommandLineOption
+ size=8 align=8
+ base size=8 base align=8
+QCommandLineOption (0x0x7f3d48d72f60) 0
+
+Vtable for QEvent
+QEvent::_ZTV6QEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QEvent)
+16 (int (*)(...))QEvent::~QEvent
+24 (int (*)(...))QEvent::~QEvent
+
+Class QEvent
+ size=24 align=8
+ base size=20 base align=8
+QEvent (0x0x7f3d48da8420) 0
+ vptr=((& QEvent::_ZTV6QEvent) + 16u)
+
+Vtable for QTimerEvent
+QTimerEvent::_ZTV11QTimerEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTimerEvent)
+16 (int (*)(...))QTimerEvent::~QTimerEvent
+24 (int (*)(...))QTimerEvent::~QTimerEvent
+
+Class QTimerEvent
+ size=24 align=8
+ base size=24 base align=8
+QTimerEvent (0x0x7f3d48e01000) 0
+ vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u)
+ QEvent (0x0x7f3d48da8480) 0
+ primary-for QTimerEvent (0x0x7f3d48e01000)
+
+Vtable for QChildEvent
+QChildEvent::_ZTV11QChildEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QChildEvent)
+16 (int (*)(...))QChildEvent::~QChildEvent
+24 (int (*)(...))QChildEvent::~QChildEvent
+
+Class QChildEvent
+ size=32 align=8
+ base size=32 base align=8
+QChildEvent (0x0x7f3d48e01068) 0
+ vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u)
+ QEvent (0x0x7f3d48da84e0) 0
+ primary-for QChildEvent (0x0x7f3d48e01068)
+
+Vtable for QDynamicPropertyChangeEvent
+QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent)
+16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+
+Class QDynamicPropertyChangeEvent
+ size=32 align=8
+ base size=32 base align=8
+QDynamicPropertyChangeEvent (0x0x7f3d48e015b0) 0
+ vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u)
+ QEvent (0x0x7f3d48da89c0) 0
+ primary-for QDynamicPropertyChangeEvent (0x0x7f3d48e015b0)
+
+Vtable for QDeferredDeleteEvent
+QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent)
+16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent
+24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent
+
+Class QDeferredDeleteEvent
+ size=24 align=8
+ base size=24 base align=8
+QDeferredDeleteEvent (0x0x7f3d48e01618) 0
+ vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u)
+ QEvent (0x0x7f3d48da8a20) 0
+ primary-for QDeferredDeleteEvent (0x0x7f3d48e01618)
+
+Class QCoreApplication::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QCoreApplication::QPrivateSignal (0x0x7f3d48da8ae0) 0 empty
+
+Vtable for QCoreApplication
+QCoreApplication::_ZTV16QCoreApplication: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QCoreApplication)
+16 (int (*)(...))QCoreApplication::metaObject
+24 (int (*)(...))QCoreApplication::qt_metacast
+32 (int (*)(...))QCoreApplication::qt_metacall
+40 (int (*)(...))QCoreApplication::~QCoreApplication
+48 (int (*)(...))QCoreApplication::~QCoreApplication
+56 (int (*)(...))QCoreApplication::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QCoreApplication::notify
+120 (int (*)(...))QCoreApplication::compressEvent
+
+Class QCoreApplication
+ size=16 align=8
+ base size=16 base align=8
+QCoreApplication (0x0x7f3d48e01680) 0
+ vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u)
+ QObject (0x0x7f3d48da8a80) 0
+ primary-for QCoreApplication (0x0x7f3d48e01680)
+
+Class QCommandLineParser
+ size=8 align=8
+ base size=8 base align=8
+QCommandLineParser (0x0x7f3d48da8b40) 0
+
+Class QContiguousCacheData
+ size=24 align=4
+ base size=24 base align=4
+QContiguousCacheData (0x0x7f3d48da8ba0) 0
+
+Class QCryptographicHash
+ size=8 align=8
+ base size=8 base align=8
+QCryptographicHash (0x0x7f3d48e931e0) 0
+
+Class QDataStream
+ size=32 align=8
+ base size=32 base align=8
+QDataStream (0x0x7f3d48e93240) 0
+
+Class QtPrivate::StreamStateSaver
+ size=16 align=8
+ base size=12 base align=8
+QtPrivate::StreamStateSaver (0x0x7f3d48e93300) 0
+
+Class QDate
+ size=8 align=8
+ base size=8 base align=8
+QDate (0x0x7f3d48e937e0) 0
+
+Class QTime
+ size=4 align=4
+ base size=4 base align=4
+QTime (0x0x7f3d48e93a80) 0
+
+Class QDateTime::ShortData
+ size=8 align=8
+ base size=8 base align=8
+QDateTime::ShortData (0x0x7f3d48b66240) 0
+
+Class QDateTime::Data
+ size=8 align=8
+ base size=8 base align=8
+QDateTime::Data (0x0x7f3d48b662a0) 0
+
+Class QDateTime
+ size=8 align=8
+ base size=8 base align=8
+QDateTime (0x0x7f3d48b661e0) 0
+
+Class QElapsedTimer
+ size=16 align=8
+ base size=16 base align=8
+QElapsedTimer (0x0x7f3d48c0e3c0) 0
+
+Class QDeadlineTimer
+ size=16 align=8
+ base size=16 base align=8
+QDeadlineTimer (0x0x7f3d48c0e8a0) 0
+
+Vtable for QTextStream
+QTextStream::_ZTV11QTextStream: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTextStream)
+16 (int (*)(...))QTextStream::~QTextStream
+24 (int (*)(...))QTextStream::~QTextStream
+
+Class QTextStream
+ size=16 align=8
+ base size=16 base align=8
+QTextStream (0x0x7f3d4892c840) 0
+ vptr=((& QTextStream::_ZTV11QTextStream) + 16u)
+
+Class QTextStreamManipulator
+ size=40 align=8
+ base size=38 base align=8
+QTextStreamManipulator (0x0x7f3d4892cae0) 0
+
+Class QtSharedPointer::NormalDeleter
+ size=1 align=1
+ base size=0 base align=1
+QtSharedPointer::NormalDeleter (0x0x7f3d4892cd20) 0 empty
+
+Class QtSharedPointer::ExternalRefCountData
+ size=16 align=8
+ base size=16 base align=8
+QtSharedPointer::ExternalRefCountData (0x0x7f3d4892cea0) 0
+
+Class QDebug::Stream
+ size=80 align=8
+ base size=76 base align=8
+QDebug::Stream (0x0x7f3d48a77420) 0
+
+Class QDebug
+ size=8 align=8
+ base size=8 base align=8
+QDebug (0x0x7f3d48a773c0) 0
+
+Class QDebugStateSaver
+ size=8 align=8
+ base size=8 base align=8
+QDebugStateSaver (0x0x7f3d487ca900) 0
+
+Class QNoDebug
+ size=1 align=1
+ base size=0 base align=1
+QNoDebug (0x0x7f3d487ca9c0) 0 empty
+
+Class QFileDevice::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFileDevice::QPrivateSignal (0x0x7f3d4889ab40) 0 empty
+
+Vtable for QFileDevice
+QFileDevice::_ZTV11QFileDevice: 34u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QFileDevice)
+16 (int (*)(...))QFileDevice::metaObject
+24 (int (*)(...))QFileDevice::qt_metacast
+32 (int (*)(...))QFileDevice::qt_metacall
+40 (int (*)(...))QFileDevice::~QFileDevice
+48 (int (*)(...))QFileDevice::~QFileDevice
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QFileDevice::isSequential
+120 (int (*)(...))QIODevice::open
+128 (int (*)(...))QFileDevice::close
+136 (int (*)(...))QFileDevice::pos
+144 (int (*)(...))QFileDevice::size
+152 (int (*)(...))QFileDevice::seek
+160 (int (*)(...))QFileDevice::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QIODevice::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))QFileDevice::readData
+224 (int (*)(...))QFileDevice::readLineData
+232 (int (*)(...))QFileDevice::writeData
+240 (int (*)(...))QFileDevice::fileName
+248 (int (*)(...))QFileDevice::resize
+256 (int (*)(...))QFileDevice::permissions
+264 (int (*)(...))QFileDevice::setPermissions
+
+Class QFileDevice
+ size=16 align=8
+ base size=16 base align=8
+QFileDevice (0x0x7f3d488af5b0) 0
+ vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u)
+ QIODevice (0x0x7f3d488af618) 0
+ primary-for QFileDevice (0x0x7f3d488af5b0)
+ QObject (0x0x7f3d4889aae0) 0
+ primary-for QIODevice (0x0x7f3d488af618)
+
+Class QFile::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFile::QPrivateSignal (0x0x7f3d4889ad80) 0 empty
+
+Vtable for QFile
+QFile::_ZTV5QFile: 34u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI5QFile)
+16 (int (*)(...))QFile::metaObject
+24 (int (*)(...))QFile::qt_metacast
+32 (int (*)(...))QFile::qt_metacall
+40 (int (*)(...))QFile::~QFile
+48 (int (*)(...))QFile::~QFile
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QFileDevice::isSequential
+120 (int (*)(...))QFile::open
+128 (int (*)(...))QFileDevice::close
+136 (int (*)(...))QFileDevice::pos
+144 (int (*)(...))QFile::size
+152 (int (*)(...))QFileDevice::seek
+160 (int (*)(...))QFileDevice::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QIODevice::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))QFileDevice::readData
+224 (int (*)(...))QFileDevice::readLineData
+232 (int (*)(...))QFileDevice::writeData
+240 (int (*)(...))QFile::fileName
+248 (int (*)(...))QFile::resize
+256 (int (*)(...))QFile::permissions
+264 (int (*)(...))QFile::setPermissions
+
+Class QFile
+ size=16 align=8
+ base size=16 base align=8
+QFile (0x0x7f3d488af750) 0
+ vptr=((& QFile::_ZTV5QFile) + 16u)
+ QFileDevice (0x0x7f3d488af7b8) 0
+ primary-for QFile (0x0x7f3d488af750)
+ QIODevice (0x0x7f3d488af820) 0
+ primary-for QFileDevice (0x0x7f3d488af7b8)
+ QObject (0x0x7f3d4889ad20) 0
+ primary-for QIODevice (0x0x7f3d488af820)
+
+Class QFileInfo
+ size=8 align=8
+ base size=8 base align=8
+QFileInfo (0x0x7f3d4889af60) 0
+
+Class QDir
+ size=8 align=8
+ base size=8 base align=8
+QDir (0x0x7f3d4854c3c0) 0
+
+Class QDirIterator
+ size=8 align=8
+ base size=8 base align=8
+QDirIterator (0x0x7f3d4854cd80) 0
+
+Class QEasingCurve
+ size=8 align=8
+ base size=8 base align=8
+QEasingCurve (0x0x7f3d48640000) 0
+
+Class QEventTransition::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QEventTransition::QPrivateSignal (0x0x7f3d486ce420) 0 empty
+
+Vtable for QEventTransition
+QEventTransition::_ZTV16QEventTransition: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QEventTransition)
+16 (int (*)(...))QEventTransition::metaObject
+24 (int (*)(...))QEventTransition::qt_metacast
+32 (int (*)(...))QEventTransition::qt_metacall
+40 (int (*)(...))QEventTransition::~QEventTransition
+48 (int (*)(...))QEventTransition::~QEventTransition
+56 (int (*)(...))QEventTransition::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QEventTransition::eventTest
+120 (int (*)(...))QEventTransition::onTransition
+
+Class QEventTransition
+ size=16 align=8
+ base size=16 base align=8
+QEventTransition (0x0x7f3d486c1a28) 0
+ vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u)
+ QAbstractTransition (0x0x7f3d486c1a90) 0
+ primary-for QEventTransition (0x0x7f3d486c1a28)
+ QObject (0x0x7f3d486ce3c0) 0
+ primary-for QAbstractTransition (0x0x7f3d486c1a90)
+
+Vtable for QException
+QException::_ZTV10QException: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QException)
+16 (int (*)(...))QException::~QException
+24 (int (*)(...))QException::~QException
+32 (int (*)(...))std::exception::what
+40 (int (*)(...))QException::raise
+48 (int (*)(...))QException::clone
+
+Class QException
+ size=8 align=8
+ base size=8 base align=8
+QException (0x0x7f3d486c1af8) 0 nearly-empty
+ vptr=((& QException::_ZTV10QException) + 16u)
+ std::exception (0x0x7f3d486ce480) 0 nearly-empty
+ primary-for QException (0x0x7f3d486c1af8)
+
+Vtable for QUnhandledException
+QUnhandledException::_ZTV19QUnhandledException: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QUnhandledException)
+16 (int (*)(...))QUnhandledException::~QUnhandledException
+24 (int (*)(...))QUnhandledException::~QUnhandledException
+32 (int (*)(...))std::exception::what
+40 (int (*)(...))QUnhandledException::raise
+48 (int (*)(...))QUnhandledException::clone
+
+Class QUnhandledException
+ size=8 align=8
+ base size=8 base align=8
+QUnhandledException (0x0x7f3d486c1b60) 0 nearly-empty
+ vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u)
+ QException (0x0x7f3d486c1bc8) 0 nearly-empty
+ primary-for QUnhandledException (0x0x7f3d486c1b60)
+ std::exception (0x0x7f3d486ce4e0) 0 nearly-empty
+ primary-for QException (0x0x7f3d486c1bc8)
+
+Class QtPrivate::ExceptionHolder
+ size=8 align=8
+ base size=8 base align=8
+QtPrivate::ExceptionHolder (0x0x7f3d486ce540) 0
+
+Class QtPrivate::ExceptionStore
+ size=8 align=8
+ base size=8 base align=8
+QtPrivate::ExceptionStore (0x0x7f3d486ce600) 0
+
+Vtable for QFactoryInterface
+QFactoryInterface::_ZTV17QFactoryInterface: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QFactoryInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class QFactoryInterface
+ size=8 align=8
+ base size=8 base align=8
+QFactoryInterface (0x0x7f3d486ce660) 0 nearly-empty
+ vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u)
+
+Class QFileSelector::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFileSelector::QPrivateSignal (0x0x7f3d486ce780) 0 empty
+
+Vtable for QFileSelector
+QFileSelector::_ZTV13QFileSelector: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QFileSelector)
+16 (int (*)(...))QFileSelector::metaObject
+24 (int (*)(...))QFileSelector::qt_metacast
+32 (int (*)(...))QFileSelector::qt_metacall
+40 (int (*)(...))QFileSelector::~QFileSelector
+48 (int (*)(...))QFileSelector::~QFileSelector
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QFileSelector
+ size=16 align=8
+ base size=16 base align=8
+QFileSelector (0x0x7f3d486c1c30) 0
+ vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u)
+ QObject (0x0x7f3d486ce720) 0
+ primary-for QFileSelector (0x0x7f3d486c1c30)
+
+Class QFileSystemWatcher::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFileSystemWatcher::QPrivateSignal (0x0x7f3d486ce840) 0 empty
+
+Vtable for QFileSystemWatcher
+QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QFileSystemWatcher)
+16 (int (*)(...))QFileSystemWatcher::metaObject
+24 (int (*)(...))QFileSystemWatcher::qt_metacast
+32 (int (*)(...))QFileSystemWatcher::qt_metacall
+40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher
+48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QFileSystemWatcher
+ size=16 align=8
+ base size=16 base align=8
+QFileSystemWatcher (0x0x7f3d486c1c98) 0
+ vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u)
+ QObject (0x0x7f3d486ce7e0) 0
+ primary-for QFileSystemWatcher (0x0x7f3d486c1c98)
+
+Class QFinalState::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFinalState::QPrivateSignal (0x0x7f3d486ce900) 0 empty
+
+Vtable for QFinalState
+QFinalState::_ZTV11QFinalState: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QFinalState)
+16 (int (*)(...))QFinalState::metaObject
+24 (int (*)(...))QFinalState::qt_metacast
+32 (int (*)(...))QFinalState::qt_metacall
+40 (int (*)(...))QFinalState::~QFinalState
+48 (int (*)(...))QFinalState::~QFinalState
+56 (int (*)(...))QFinalState::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QFinalState::onEntry
+120 (int (*)(...))QFinalState::onExit
+
+Class QFinalState
+ size=16 align=8
+ base size=16 base align=8
+QFinalState (0x0x7f3d486c1d00) 0
+ vptr=((& QFinalState::_ZTV11QFinalState) + 16u)
+ QAbstractState (0x0x7f3d486c1d68) 0
+ primary-for QFinalState (0x0x7f3d486c1d00)
+ QObject (0x0x7f3d486ce8a0) 0
+ primary-for QAbstractState (0x0x7f3d486c1d68)
+
+Vtable for QRunnable
+QRunnable::_ZTV9QRunnable: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QRunnable)
+16 (int (*)(...))__cxa_pure_virtual
+24 0u
+32 0u
+
+Class QRunnable
+ size=16 align=8
+ base size=12 base align=8
+QRunnable (0x0x7f3d486ce960) 0
+ vptr=((& QRunnable::_ZTV9QRunnable) + 16u)
+
+Class QBasicMutex
+ size=8 align=8
+ base size=8 base align=8
+QBasicMutex (0x0x7f3d486ce9c0) 0
+
+Class QMutex
+ size=8 align=8
+ base size=8 base align=8
+QMutex (0x0x7f3d486c1ea0) 0
+ QBasicMutex (0x0x7f3d486ceba0) 0
+
+Class QMutexLocker
+ size=8 align=8
+ base size=8 base align=8
+QMutexLocker (0x0x7f3d486cec00) 0
+
+Class QtPrivate::ResultItem
+ size=16 align=8
+ base size=16 base align=8
+QtPrivate::ResultItem (0x0x7f3d486cec60) 0
+
+Class QtPrivate::ResultIteratorBase
+ size=16 align=8
+ base size=12 base align=8
+QtPrivate::ResultIteratorBase (0x0x7f3d486cecc0) 0
+
+Vtable for QtPrivate::ResultStoreBase
+QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE)
+16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase
+24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase
+
+Class QtPrivate::ResultStoreBase
+ size=48 align=8
+ base size=44 base align=8
+QtPrivate::ResultStoreBase (0x0x7f3d486cede0) 0
+ vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u)
+
+Vtable for QFutureInterfaceBase
+QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QFutureInterfaceBase)
+16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase
+24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase
+
+Class QFutureInterfaceBase
+ size=16 align=8
+ base size=16 base align=8
+QFutureInterfaceBase (0x0x7f3d48451660) 0
+ vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u)
+
+Class QFutureWatcherBase::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFutureWatcherBase::QPrivateSignal (0x0x7f3d48451e40) 0 empty
+
+Vtable for QFutureWatcherBase
+QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QFutureWatcherBase)
+16 (int (*)(...))QFutureWatcherBase::metaObject
+24 (int (*)(...))QFutureWatcherBase::qt_metacast
+32 (int (*)(...))QFutureWatcherBase::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QFutureWatcherBase::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QFutureWatcherBase::connectNotify
+104 (int (*)(...))QFutureWatcherBase::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+
+Class QFutureWatcherBase
+ size=16 align=8
+ base size=16 base align=8
+QFutureWatcherBase (0x0x7f3d484fe000) 0
+ vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u)
+ QObject (0x0x7f3d48451de0) 0
+ primary-for QFutureWatcherBase (0x0x7f3d484fe000)
+
+Class QHistoryState::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QHistoryState::QPrivateSignal (0x0x7f3d4812f480) 0 empty
+
+Vtable for QHistoryState
+QHistoryState::_ZTV13QHistoryState: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QHistoryState)
+16 (int (*)(...))QHistoryState::metaObject
+24 (int (*)(...))QHistoryState::qt_metacast
+32 (int (*)(...))QHistoryState::qt_metacall
+40 (int (*)(...))QHistoryState::~QHistoryState
+48 (int (*)(...))QHistoryState::~QHistoryState
+56 (int (*)(...))QHistoryState::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QHistoryState::onEntry
+120 (int (*)(...))QHistoryState::onExit
+
+Class QHistoryState
+ size=16 align=8
+ base size=16 base align=8
+QHistoryState (0x0x7f3d484fe8f0) 0
+ vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u)
+ QAbstractState (0x0x7f3d484fe958) 0
+ primary-for QHistoryState (0x0x7f3d484fe8f0)
+ QObject (0x0x7f3d4812f420) 0
+ primary-for QAbstractState (0x0x7f3d484fe958)
+
+Class QIdentityProxyModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QIdentityProxyModel::QPrivateSignal (0x0x7f3d4812f540) 0 empty
+
+Vtable for QIdentityProxyModel
+QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QIdentityProxyModel)
+16 (int (*)(...))QIdentityProxyModel::metaObject
+24 (int (*)(...))QIdentityProxyModel::qt_metacast
+32 (int (*)(...))QIdentityProxyModel::qt_metacall
+40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel
+48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QIdentityProxyModel::index
+120 (int (*)(...))QIdentityProxyModel::parent
+128 (int (*)(...))QIdentityProxyModel::sibling
+136 (int (*)(...))QIdentityProxyModel::rowCount
+144 (int (*)(...))QIdentityProxyModel::columnCount
+152 (int (*)(...))QAbstractProxyModel::hasChildren
+160 (int (*)(...))QAbstractProxyModel::data
+168 (int (*)(...))QAbstractProxyModel::setData
+176 (int (*)(...))QIdentityProxyModel::headerData
+184 (int (*)(...))QAbstractProxyModel::setHeaderData
+192 (int (*)(...))QAbstractProxyModel::itemData
+200 (int (*)(...))QAbstractProxyModel::setItemData
+208 (int (*)(...))QAbstractProxyModel::mimeTypes
+216 (int (*)(...))QAbstractProxyModel::mimeData
+224 (int (*)(...))QAbstractProxyModel::canDropMimeData
+232 (int (*)(...))QIdentityProxyModel::dropMimeData
+240 (int (*)(...))QAbstractProxyModel::supportedDropActions
+248 (int (*)(...))QAbstractProxyModel::supportedDragActions
+256 (int (*)(...))QIdentityProxyModel::insertRows
+264 (int (*)(...))QIdentityProxyModel::insertColumns
+272 (int (*)(...))QIdentityProxyModel::removeRows
+280 (int (*)(...))QIdentityProxyModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractProxyModel::fetchMore
+312 (int (*)(...))QAbstractProxyModel::canFetchMore
+320 (int (*)(...))QAbstractProxyModel::flags
+328 (int (*)(...))QAbstractProxyModel::sort
+336 (int (*)(...))QAbstractProxyModel::buddy
+344 (int (*)(...))QIdentityProxyModel::match
+352 (int (*)(...))QAbstractProxyModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractProxyModel::submit
+376 (int (*)(...))QAbstractProxyModel::revert
+384 (int (*)(...))QIdentityProxyModel::setSourceModel
+392 (int (*)(...))QIdentityProxyModel::mapToSource
+400 (int (*)(...))QIdentityProxyModel::mapFromSource
+408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource
+416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource
+
+Class QIdentityProxyModel
+ size=16 align=8
+ base size=16 base align=8
+QIdentityProxyModel (0x0x7f3d484fe9c0) 0
+ vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u)
+ QAbstractProxyModel (0x0x7f3d484fea28) 0
+ primary-for QIdentityProxyModel (0x0x7f3d484fe9c0)
+ QAbstractItemModel (0x0x7f3d484fea90) 0
+ primary-for QAbstractProxyModel (0x0x7f3d484fea28)
+ QObject (0x0x7f3d4812f4e0) 0
+ primary-for QAbstractItemModel (0x0x7f3d484fea90)
+
+Class QItemSelectionRange
+ size=16 align=8
+ base size=16 base align=8
+QItemSelectionRange (0x0x7f3d4812f5a0) 0
+
+Class QItemSelectionModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QItemSelectionModel::QPrivateSignal (0x0x7f3d4812fc60) 0 empty
+
+Vtable for QItemSelectionModel
+QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QItemSelectionModel)
+16 (int (*)(...))QItemSelectionModel::metaObject
+24 (int (*)(...))QItemSelectionModel::qt_metacast
+32 (int (*)(...))QItemSelectionModel::qt_metacall
+40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel
+48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QItemSelectionModel::setCurrentIndex
+120 (int (*)(...))QItemSelectionModel::select
+128 (int (*)(...))QItemSelectionModel::select
+136 (int (*)(...))QItemSelectionModel::clear
+144 (int (*)(...))QItemSelectionModel::reset
+152 (int (*)(...))QItemSelectionModel::clearCurrentIndex
+
+Class QItemSelectionModel
+ size=16 align=8
+ base size=16 base align=8
+QItemSelectionModel (0x0x7f3d4819d2d8) 0
+ vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u)
+ QObject (0x0x7f3d4812fc00) 0
+ primary-for QItemSelectionModel (0x0x7f3d4819d2d8)
+
+Class QItemSelection
+ size=8 align=8
+ base size=8 base align=8
+QItemSelection (0x0x7f3d4819d4e0) 0
+ QList<QItemSelectionRange> (0x0x7f3d4819d548) 0
+ QListSpecialMethods<QItemSelectionRange> (0x0x7f3d4812ff60) 0 empty
+
+Class QJsonValue
+ size=24 align=8
+ base size=20 base align=8
+QJsonValue (0x0x7f3d48228480) 0
+
+Class QJsonValueRef
+ size=16 align=8
+ base size=12 base align=8
+QJsonValueRef (0x0x7f3d47f9aba0) 0
+
+Class QJsonValuePtr
+ size=24 align=8
+ base size=24 base align=8
+QJsonValuePtr (0x0x7f3d48000120) 0
+
+Class QJsonValueRefPtr
+ size=16 align=8
+ base size=16 base align=8
+QJsonValueRefPtr (0x0x7f3d48000180) 0
+
+Class QJsonArray::iterator
+ size=16 align=8
+ base size=12 base align=8
+QJsonArray::iterator (0x0x7f3d48000360) 0
+
+Class QJsonArray::const_iterator
+ size=16 align=8
+ base size=12 base align=8
+QJsonArray::const_iterator (0x0x7f3d480003c0) 0
+
+Class QJsonArray
+ size=16 align=8
+ base size=16 base align=8
+QJsonArray (0x0x7f3d48000300) 0
+
+Class QJsonParseError
+ size=8 align=4
+ base size=8 base align=4
+QJsonParseError (0x0x7f3d480bd600) 0
+
+Class QJsonDocument
+ size=8 align=8
+ base size=8 base align=8
+QJsonDocument (0x0x7f3d480bd660) 0
+
+Class QJsonObject::iterator
+ size=16 align=8
+ base size=12 base align=8
+QJsonObject::iterator (0x0x7f3d480bdcc0) 0
+
+Class QJsonObject::const_iterator
+ size=16 align=8
+ base size=12 base align=8
+QJsonObject::const_iterator (0x0x7f3d480bdd20) 0
+
+Class QJsonObject
+ size=16 align=8
+ base size=16 base align=8
+QJsonObject (0x0x7f3d480bdc60) 0
+
+Class QLibrary::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QLibrary::QPrivateSignal (0x0x7f3d47e06000) 0 empty
+
+Vtable for QLibrary
+QLibrary::_ZTV8QLibrary: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QLibrary)
+16 (int (*)(...))QLibrary::metaObject
+24 (int (*)(...))QLibrary::qt_metacast
+32 (int (*)(...))QLibrary::qt_metacall
+40 (int (*)(...))QLibrary::~QLibrary
+48 (int (*)(...))QLibrary::~QLibrary
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QLibrary
+ size=32 align=8
+ base size=25 base align=8
+QLibrary (0x0x7f3d47dc5888) 0
+ vptr=((& QLibrary::_ZTV8QLibrary) + 16u)
+ QObject (0x0x7f3d47dabf60) 0
+ primary-for QLibrary (0x0x7f3d47dc5888)
+
+Class QVersionNumber::SegmentStorage
+ size=8 align=8
+ base size=8 base align=8
+QVersionNumber::SegmentStorage (0x0x7f3d47e066c0) 0
+
+Class QVersionNumber
+ size=8 align=8
+ base size=8 base align=8
+QVersionNumber (0x0x7f3d47e061e0) 0
+
+Class QLibraryInfo
+ size=1 align=1
+ base size=0 base align=1
+QLibraryInfo (0x0x7f3d47e06ba0) 0 empty
+
+Class QPoint
+ size=8 align=4
+ base size=8 base align=4
+QPoint (0x0x7f3d47e06c00) 0
+
+Class QPointF
+ size=16 align=8
+ base size=16 base align=8
+QPointF (0x0x7f3d47e06ea0) 0
+
+Class QLine
+ size=16 align=4
+ base size=16 base align=4
+QLine (0x0x7f3d47b0f180) 0
+
+Class QLineF
+ size=32 align=8
+ base size=32 base align=8
+QLineF (0x0x7f3d47b0fae0) 0
+
+Class QLinkedListData
+ size=32 align=8
+ base size=25 base align=8
+QLinkedListData (0x0x7f3d47b9c480) 0
+
+Class QLockFile
+ size=8 align=8
+ base size=8 base align=8
+QLockFile (0x0x7f3d47b9c7e0) 0
+
+Class QLoggingCategory::AtomicBools
+ size=4 align=1
+ base size=4 base align=1
+QLoggingCategory::AtomicBools (0x0x7f3d47b9c960) 0
+
+Class QLoggingCategory
+ size=24 align=8
+ base size=24 base align=8
+QLoggingCategory (0x0x7f3d47b9c900) 0
+
+Class QMargins
+ size=16 align=4
+ base size=16 base align=4
+QMargins (0x0x7f3d47b9cae0) 0
+
+Class QMarginsF
+ size=32 align=8
+ base size=32 base align=8
+QMarginsF (0x0x7f3d47b9cd80) 0
+
+Class QMessageAuthenticationCode
+ size=8 align=8
+ base size=8 base align=8
+QMessageAuthenticationCode (0x0x7f3d47922420) 0
+
+Class QMetaMethod
+ size=16 align=8
+ base size=12 base align=8
+QMetaMethod (0x0x7f3d47922480) 0
+
+Class QMetaEnum
+ size=16 align=8
+ base size=12 base align=8
+QMetaEnum (0x0x7f3d47922a80) 0
+
+Class QMetaProperty
+ size=32 align=8
+ base size=32 base align=8
+QMetaProperty (0x0x7f3d47922d80) 0
+
+Class QMetaClassInfo
+ size=16 align=8
+ base size=12 base align=8
+QMetaClassInfo (0x0x7f3d47922de0) 0
+
+Class QMimeData::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QMimeData::QPrivateSignal (0x0x7f3d479d8120) 0 empty
+
+Vtable for QMimeData
+QMimeData::_ZTV9QMimeData: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QMimeData)
+16 (int (*)(...))QMimeData::metaObject
+24 (int (*)(...))QMimeData::qt_metacast
+32 (int (*)(...))QMimeData::qt_metacall
+40 (int (*)(...))QMimeData::~QMimeData
+48 (int (*)(...))QMimeData::~QMimeData
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QMimeData::hasFormat
+120 (int (*)(...))QMimeData::formats
+128 (int (*)(...))QMimeData::retrieveData
+
+Class QMimeData
+ size=16 align=8
+ base size=16 base align=8
+QMimeData (0x0x7f3d4793faf8) 0
+ vptr=((& QMimeData::_ZTV9QMimeData) + 16u)
+ QObject (0x0x7f3d479d80c0) 0
+ primary-for QMimeData (0x0x7f3d4793faf8)
+
+Class QMimeType
+ size=8 align=8
+ base size=8 base align=8
+QMimeType (0x0x7f3d479d8180) 0
+
+Class QMimeDatabase
+ size=8 align=8
+ base size=8 base align=8
+QMimeDatabase (0x0x7f3d479d8480) 0
+
+Class QObjectCleanupHandler::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QObjectCleanupHandler::QPrivateSignal (0x0x7f3d479d8540) 0 empty
+
+Vtable for QObjectCleanupHandler
+QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QObjectCleanupHandler)
+16 (int (*)(...))QObjectCleanupHandler::metaObject
+24 (int (*)(...))QObjectCleanupHandler::qt_metacast
+32 (int (*)(...))QObjectCleanupHandler::qt_metacall
+40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler
+48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QObjectCleanupHandler
+ size=24 align=8
+ base size=24 base align=8
+QObjectCleanupHandler (0x0x7f3d4793fd00) 0
+ vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u)
+ QObject (0x0x7f3d479d84e0) 0
+ primary-for QObjectCleanupHandler (0x0x7f3d4793fd00)
+
+Class QOperatingSystemVersion
+ size=16 align=4
+ base size=16 base align=4
+QOperatingSystemVersion (0x0x7f3d479d85a0) 0
+
+Class QParallelAnimationGroup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QParallelAnimationGroup::QPrivateSignal (0x0x7f3d479d8d20) 0 empty
+
+Vtable for QParallelAnimationGroup
+QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QParallelAnimationGroup)
+16 (int (*)(...))QParallelAnimationGroup::metaObject
+24 (int (*)(...))QParallelAnimationGroup::qt_metacast
+32 (int (*)(...))QParallelAnimationGroup::qt_metacall
+40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup
+48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup
+56 (int (*)(...))QParallelAnimationGroup::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QParallelAnimationGroup::duration
+120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime
+128 (int (*)(...))QParallelAnimationGroup::updateState
+136 (int (*)(...))QParallelAnimationGroup::updateDirection
+
+Class QParallelAnimationGroup
+ size=16 align=8
+ base size=16 base align=8
+QParallelAnimationGroup (0x0x7f3d47a3a410) 0
+ vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u)
+ QAnimationGroup (0x0x7f3d47a3a478) 0
+ primary-for QParallelAnimationGroup (0x0x7f3d47a3a410)
+ QAbstractAnimation (0x0x7f3d47a3a4e0) 0
+ primary-for QAnimationGroup (0x0x7f3d47a3a478)
+ QObject (0x0x7f3d479d8cc0) 0
+ primary-for QAbstractAnimation (0x0x7f3d47a3a4e0)
+
+Class QPauseAnimation::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPauseAnimation::QPrivateSignal (0x0x7f3d479d8de0) 0 empty
+
+Vtable for QPauseAnimation
+QPauseAnimation::_ZTV15QPauseAnimation: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QPauseAnimation)
+16 (int (*)(...))QPauseAnimation::metaObject
+24 (int (*)(...))QPauseAnimation::qt_metacast
+32 (int (*)(...))QPauseAnimation::qt_metacall
+40 (int (*)(...))QPauseAnimation::~QPauseAnimation
+48 (int (*)(...))QPauseAnimation::~QPauseAnimation
+56 (int (*)(...))QPauseAnimation::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QPauseAnimation::duration
+120 (int (*)(...))QPauseAnimation::updateCurrentTime
+128 (int (*)(...))QAbstractAnimation::updateState
+136 (int (*)(...))QAbstractAnimation::updateDirection
+
+Class QPauseAnimation
+ size=16 align=8
+ base size=16 base align=8
+QPauseAnimation (0x0x7f3d47a3a548) 0
+ vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u)
+ QAbstractAnimation (0x0x7f3d47a3a5b0) 0
+ primary-for QPauseAnimation (0x0x7f3d47a3a548)
+ QObject (0x0x7f3d479d8d80) 0
+ primary-for QAbstractAnimation (0x0x7f3d47a3a5b0)
+
+Class QStaticPlugin
+ size=16 align=8
+ base size=16 base align=8
+QStaticPlugin (0x0x7f3d47a8a000) 0
+
+Class QPluginLoader::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPluginLoader::QPrivateSignal (0x0x7f3d47a8a300) 0 empty
+
+Vtable for QPluginLoader
+QPluginLoader::_ZTV13QPluginLoader: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QPluginLoader)
+16 (int (*)(...))QPluginLoader::metaObject
+24 (int (*)(...))QPluginLoader::qt_metacast
+32 (int (*)(...))QPluginLoader::qt_metacall
+40 (int (*)(...))QPluginLoader::~QPluginLoader
+48 (int (*)(...))QPluginLoader::~QPluginLoader
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QPluginLoader
+ size=32 align=8
+ base size=25 base align=8
+QPluginLoader (0x0x7f3d47a3a7b8) 0
+ vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u)
+ QObject (0x0x7f3d47a8a2a0) 0
+ primary-for QPluginLoader (0x0x7f3d47a3a7b8)
+
+Class QProcessEnvironment
+ size=8 align=8
+ base size=8 base align=8
+QProcessEnvironment (0x0x7f3d47a8a360) 0
+
+Class QProcess::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QProcess::QPrivateSignal (0x0x7f3d47a8aa20) 0 empty
+
+Vtable for QProcess
+QProcess::_ZTV8QProcess: 31u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QProcess)
+16 (int (*)(...))QProcess::metaObject
+24 (int (*)(...))QProcess::qt_metacast
+32 (int (*)(...))QProcess::qt_metacall
+40 (int (*)(...))QProcess::~QProcess
+48 (int (*)(...))QProcess::~QProcess
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QProcess::isSequential
+120 (int (*)(...))QProcess::open
+128 (int (*)(...))QProcess::close
+136 (int (*)(...))QIODevice::pos
+144 (int (*)(...))QIODevice::size
+152 (int (*)(...))QIODevice::seek
+160 (int (*)(...))QProcess::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QProcess::bytesAvailable
+184 (int (*)(...))QProcess::bytesToWrite
+192 (int (*)(...))QProcess::canReadLine
+200 (int (*)(...))QProcess::waitForReadyRead
+208 (int (*)(...))QProcess::waitForBytesWritten
+216 (int (*)(...))QProcess::readData
+224 (int (*)(...))QIODevice::readLineData
+232 (int (*)(...))QProcess::writeData
+240 (int (*)(...))QProcess::setupChildProcess
+
+Class QProcess
+ size=16 align=8
+ base size=16 base align=8
+QProcess (0x0x7f3d47a3ae38) 0
+ vptr=((& QProcess::_ZTV8QProcess) + 16u)
+ QIODevice (0x0x7f3d47a3aea0) 0
+ primary-for QProcess (0x0x7f3d47a3ae38)
+ QObject (0x0x7f3d47a8a9c0) 0
+ primary-for QIODevice (0x0x7f3d47a3aea0)
+
+Class QVariantAnimation::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QVariantAnimation::QPrivateSignal (0x0x7f3d47a8aae0) 0 empty
+
+Vtable for QVariantAnimation
+QVariantAnimation::_ZTV17QVariantAnimation: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QVariantAnimation)
+16 (int (*)(...))QVariantAnimation::metaObject
+24 (int (*)(...))QVariantAnimation::qt_metacast
+32 (int (*)(...))QVariantAnimation::qt_metacall
+40 (int (*)(...))QVariantAnimation::~QVariantAnimation
+48 (int (*)(...))QVariantAnimation::~QVariantAnimation
+56 (int (*)(...))QVariantAnimation::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QVariantAnimation::duration
+120 (int (*)(...))QVariantAnimation::updateCurrentTime
+128 (int (*)(...))QVariantAnimation::updateState
+136 (int (*)(...))QAbstractAnimation::updateDirection
+144 (int (*)(...))QVariantAnimation::updateCurrentValue
+152 (int (*)(...))QVariantAnimation::interpolated
+
+Class QVariantAnimation
+ size=16 align=8
+ base size=16 base align=8
+QVariantAnimation (0x0x7f3d47a3af08) 0
+ vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u)
+ QAbstractAnimation (0x0x7f3d47a3af70) 0
+ primary-for QVariantAnimation (0x0x7f3d47a3af08)
+ QObject (0x0x7f3d47a8aa80) 0
+ primary-for QAbstractAnimation (0x0x7f3d47a3af70)
+
+Class QPropertyAnimation::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPropertyAnimation::QPrivateSignal (0x0x7f3d47a8aba0) 0 empty
+
+Vtable for QPropertyAnimation
+QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QPropertyAnimation)
+16 (int (*)(...))QPropertyAnimation::metaObject
+24 (int (*)(...))QPropertyAnimation::qt_metacast
+32 (int (*)(...))QPropertyAnimation::qt_metacall
+40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation
+48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation
+56 (int (*)(...))QPropertyAnimation::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QVariantAnimation::duration
+120 (int (*)(...))QVariantAnimation::updateCurrentTime
+128 (int (*)(...))QPropertyAnimation::updateState
+136 (int (*)(...))QAbstractAnimation::updateDirection
+144 (int (*)(...))QPropertyAnimation::updateCurrentValue
+152 (int (*)(...))QVariantAnimation::interpolated
+
+Class QPropertyAnimation
+ size=16 align=8
+ base size=16 base align=8
+QPropertyAnimation (0x0x7f3d47713068) 0
+ vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u)
+ QVariantAnimation (0x0x7f3d477130d0) 0
+ primary-for QPropertyAnimation (0x0x7f3d47713068)
+ QAbstractAnimation (0x0x7f3d47713138) 0
+ primary-for QVariantAnimation (0x0x7f3d477130d0)
+ QObject (0x0x7f3d47a8ab40) 0
+ primary-for QAbstractAnimation (0x0x7f3d47713138)
+
+Class QRandomGenerator::Storage
+ size=2504 align=8
+ base size=2504 base align=8
+QRandomGenerator::Storage (0x0x7f3d47a8acc0) 0
+
+Class QRandomGenerator
+ size=2512 align=8
+ base size=2512 base align=8
+QRandomGenerator (0x0x7f3d47a8ac60) 0
+
+Class QRandomGenerator64
+ size=2512 align=8
+ base size=2512 base align=8
+QRandomGenerator64 (0x0x7f3d477b3410) 0
+ QRandomGenerator (0x0x7f3d47796c60) 0
+
+Class QReadWriteLock
+ size=8 align=8
+ base size=8 base align=8
+QReadWriteLock (0x0x7f3d47796d20) 0
+
+Class QReadLocker
+ size=8 align=8
+ base size=8 base align=8
+QReadLocker (0x0x7f3d47853000) 0
+
+Class QWriteLocker
+ size=8 align=8
+ base size=8 base align=8
+QWriteLocker (0x0x7f3d478530c0) 0
+
+Class QSize
+ size=8 align=4
+ base size=8 base align=4
+QSize (0x0x7f3d47853180) 0
+
+Class QSizeF
+ size=16 align=8
+ base size=16 base align=8
+QSizeF (0x0x7f3d47853420) 0
+
+Class QRect
+ size=16 align=4
+ base size=16 base align=4
+QRect (0x0x7f3d478536c0) 0
+
+Class QRectF
+ size=32 align=8
+ base size=32 base align=8
+QRectF (0x0x7f3d47853960) 0
+
+Class QRegularExpression
+ size=8 align=8
+ base size=8 base align=8
+QRegularExpression (0x0x7f3d47853c00) 0
+
+Class QRegularExpressionMatch
+ size=8 align=8
+ base size=8 base align=8
+QRegularExpressionMatch (0x0x7f3d47653240) 0
+
+Class QRegularExpressionMatchIterator
+ size=8 align=8
+ base size=8 base align=8
+QRegularExpressionMatchIterator (0x0x7f3d47653540) 0
+
+Class QResource
+ size=8 align=8
+ base size=8 base align=8
+QResource (0x0x7f3d47653840) 0
+
+Class QSaveFile::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSaveFile::QPrivateSignal (0x0x7f3d476539c0) 0 empty
+
+Vtable for QSaveFile
+QSaveFile::_ZTV9QSaveFile: 34u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QSaveFile)
+16 (int (*)(...))QSaveFile::metaObject
+24 (int (*)(...))QSaveFile::qt_metacast
+32 (int (*)(...))QSaveFile::qt_metacall
+40 (int (*)(...))QSaveFile::~QSaveFile
+48 (int (*)(...))QSaveFile::~QSaveFile
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QFileDevice::isSequential
+120 (int (*)(...))QSaveFile::open
+128 (int (*)(...))QSaveFile::close
+136 (int (*)(...))QFileDevice::pos
+144 (int (*)(...))QFileDevice::size
+152 (int (*)(...))QFileDevice::seek
+160 (int (*)(...))QFileDevice::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QIODevice::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))QFileDevice::readData
+224 (int (*)(...))QFileDevice::readLineData
+232 (int (*)(...))QSaveFile::writeData
+240 (int (*)(...))QSaveFile::fileName
+248 (int (*)(...))QFileDevice::resize
+256 (int (*)(...))QFileDevice::permissions
+264 (int (*)(...))QFileDevice::setPermissions
+
+Class QSaveFile
+ size=16 align=8
+ base size=16 base align=8
+QSaveFile (0x0x7f3d4762a618) 0
+ vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u)
+ QFileDevice (0x0x7f3d4762a680) 0
+ primary-for QSaveFile (0x0x7f3d4762a618)
+ QIODevice (0x0x7f3d4762a6e8) 0
+ primary-for QFileDevice (0x0x7f3d4762a680)
+ QObject (0x0x7f3d47653960) 0
+ primary-for QIODevice (0x0x7f3d4762a6e8)
+
+Class QSemaphore
+ size=8 align=8
+ base size=8 base align=8
+QSemaphore (0x0x7f3d47653a80) 0
+
+Class QSemaphoreReleaser
+ size=16 align=8
+ base size=12 base align=8
+QSemaphoreReleaser (0x0x7f3d47653ae0) 0
+
+Class QSequentialAnimationGroup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSequentialAnimationGroup::QPrivateSignal (0x0x7f3d473d7120) 0 empty
+
+Vtable for QSequentialAnimationGroup
+QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup)
+16 (int (*)(...))QSequentialAnimationGroup::metaObject
+24 (int (*)(...))QSequentialAnimationGroup::qt_metacast
+32 (int (*)(...))QSequentialAnimationGroup::qt_metacall
+40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup
+48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup
+56 (int (*)(...))QSequentialAnimationGroup::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QSequentialAnimationGroup::duration
+120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime
+128 (int (*)(...))QSequentialAnimationGroup::updateState
+136 (int (*)(...))QSequentialAnimationGroup::updateDirection
+
+Class QSequentialAnimationGroup
+ size=16 align=8
+ base size=16 base align=8
+QSequentialAnimationGroup (0x0x7f3d473b9f08) 0
+ vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u)
+ QAnimationGroup (0x0x7f3d473b9f70) 0
+ primary-for QSequentialAnimationGroup (0x0x7f3d473b9f08)
+ QAbstractAnimation (0x0x7f3d473da000) 0
+ primary-for QAnimationGroup (0x0x7f3d473b9f70)
+ QObject (0x0x7f3d473d70c0) 0
+ primary-for QAbstractAnimation (0x0x7f3d473da000)
+
+Class QSettings::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSettings::QPrivateSignal (0x0x7f3d473d71e0) 0 empty
+
+Vtable for QSettings
+QSettings::_ZTV9QSettings: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QSettings)
+16 (int (*)(...))QSettings::metaObject
+24 (int (*)(...))QSettings::qt_metacast
+32 (int (*)(...))QSettings::qt_metacall
+40 (int (*)(...))QSettings::~QSettings
+48 (int (*)(...))QSettings::~QSettings
+56 (int (*)(...))QSettings::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QSettings
+ size=16 align=8
+ base size=16 base align=8
+QSettings (0x0x7f3d473da068) 0
+ vptr=((& QSettings::_ZTV9QSettings) + 16u)
+ QObject (0x0x7f3d473d7180) 0
+ primary-for QSettings (0x0x7f3d473da068)
+
+Class QSharedMemory::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSharedMemory::QPrivateSignal (0x0x7f3d473d72a0) 0 empty
+
+Vtable for QSharedMemory
+QSharedMemory::_ZTV13QSharedMemory: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QSharedMemory)
+16 (int (*)(...))QSharedMemory::metaObject
+24 (int (*)(...))QSharedMemory::qt_metacast
+32 (int (*)(...))QSharedMemory::qt_metacall
+40 (int (*)(...))QSharedMemory::~QSharedMemory
+48 (int (*)(...))QSharedMemory::~QSharedMemory
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QSharedMemory
+ size=16 align=8
+ base size=16 base align=8
+QSharedMemory (0x0x7f3d473da0d0) 0
+ vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u)
+ QObject (0x0x7f3d473d7240) 0
+ primary-for QSharedMemory (0x0x7f3d473da0d0)
+
+Class QSignalMapper::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSignalMapper::QPrivateSignal (0x0x7f3d473d7360) 0 empty
+
+Vtable for QSignalMapper
+QSignalMapper::_ZTV13QSignalMapper: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QSignalMapper)
+16 (int (*)(...))QSignalMapper::metaObject
+24 (int (*)(...))QSignalMapper::qt_metacast
+32 (int (*)(...))QSignalMapper::qt_metacall
+40 (int (*)(...))QSignalMapper::~QSignalMapper
+48 (int (*)(...))QSignalMapper::~QSignalMapper
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QSignalMapper
+ size=16 align=8
+ base size=16 base align=8
+QSignalMapper (0x0x7f3d473da138) 0
+ vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u)
+ QObject (0x0x7f3d473d7300) 0
+ primary-for QSignalMapper (0x0x7f3d473da138)
+
+Class QSignalTransition::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSignalTransition::QPrivateSignal (0x0x7f3d473d7420) 0 empty
+
+Vtable for QSignalTransition
+QSignalTransition::_ZTV17QSignalTransition: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QSignalTransition)
+16 (int (*)(...))QSignalTransition::metaObject
+24 (int (*)(...))QSignalTransition::qt_metacast
+32 (int (*)(...))QSignalTransition::qt_metacall
+40 (int (*)(...))QSignalTransition::~QSignalTransition
+48 (int (*)(...))QSignalTransition::~QSignalTransition
+56 (int (*)(...))QSignalTransition::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QSignalTransition::eventTest
+120 (int (*)(...))QSignalTransition::onTransition
+
+Class QSignalTransition
+ size=16 align=8
+ base size=16 base align=8
+QSignalTransition (0x0x7f3d473da1a0) 0
+ vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u)
+ QAbstractTransition (0x0x7f3d473da208) 0
+ primary-for QSignalTransition (0x0x7f3d473da1a0)
+ QObject (0x0x7f3d473d73c0) 0
+ primary-for QAbstractTransition (0x0x7f3d473da208)
+
+Class QSocketNotifier::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSocketNotifier::QPrivateSignal (0x0x7f3d473d74e0) 0 empty
+
+Vtable for QSocketNotifier
+QSocketNotifier::_ZTV15QSocketNotifier: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QSocketNotifier)
+16 (int (*)(...))QSocketNotifier::metaObject
+24 (int (*)(...))QSocketNotifier::qt_metacast
+32 (int (*)(...))QSocketNotifier::qt_metacall
+40 (int (*)(...))QSocketNotifier::~QSocketNotifier
+48 (int (*)(...))QSocketNotifier::~QSocketNotifier
+56 (int (*)(...))QSocketNotifier::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QSocketNotifier
+ size=16 align=8
+ base size=16 base align=8
+QSocketNotifier (0x0x7f3d473da270) 0
+ vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u)
+ QObject (0x0x7f3d473d7480) 0
+ primary-for QSocketNotifier (0x0x7f3d473da270)
+
+Class QSortFilterProxyModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSortFilterProxyModel::QPrivateSignal (0x0x7f3d473d75a0) 0 empty
+
+Vtable for QSortFilterProxyModel
+QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QSortFilterProxyModel)
+16 (int (*)(...))QSortFilterProxyModel::metaObject
+24 (int (*)(...))QSortFilterProxyModel::qt_metacast
+32 (int (*)(...))QSortFilterProxyModel::qt_metacall
+40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel
+48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QSortFilterProxyModel::index
+120 (int (*)(...))QSortFilterProxyModel::parent
+128 (int (*)(...))QSortFilterProxyModel::sibling
+136 (int (*)(...))QSortFilterProxyModel::rowCount
+144 (int (*)(...))QSortFilterProxyModel::columnCount
+152 (int (*)(...))QSortFilterProxyModel::hasChildren
+160 (int (*)(...))QSortFilterProxyModel::data
+168 (int (*)(...))QSortFilterProxyModel::setData
+176 (int (*)(...))QSortFilterProxyModel::headerData
+184 (int (*)(...))QSortFilterProxyModel::setHeaderData
+192 (int (*)(...))QAbstractProxyModel::itemData
+200 (int (*)(...))QAbstractProxyModel::setItemData
+208 (int (*)(...))QSortFilterProxyModel::mimeTypes
+216 (int (*)(...))QSortFilterProxyModel::mimeData
+224 (int (*)(...))QAbstractProxyModel::canDropMimeData
+232 (int (*)(...))QSortFilterProxyModel::dropMimeData
+240 (int (*)(...))QSortFilterProxyModel::supportedDropActions
+248 (int (*)(...))QAbstractProxyModel::supportedDragActions
+256 (int (*)(...))QSortFilterProxyModel::insertRows
+264 (int (*)(...))QSortFilterProxyModel::insertColumns
+272 (int (*)(...))QSortFilterProxyModel::removeRows
+280 (int (*)(...))QSortFilterProxyModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QSortFilterProxyModel::fetchMore
+312 (int (*)(...))QSortFilterProxyModel::canFetchMore
+320 (int (*)(...))QSortFilterProxyModel::flags
+328 (int (*)(...))QSortFilterProxyModel::sort
+336 (int (*)(...))QSortFilterProxyModel::buddy
+344 (int (*)(...))QSortFilterProxyModel::match
+352 (int (*)(...))QSortFilterProxyModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractProxyModel::submit
+376 (int (*)(...))QAbstractProxyModel::revert
+384 (int (*)(...))QSortFilterProxyModel::setSourceModel
+392 (int (*)(...))QSortFilterProxyModel::mapToSource
+400 (int (*)(...))QSortFilterProxyModel::mapFromSource
+408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource
+416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource
+424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow
+432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn
+440 (int (*)(...))QSortFilterProxyModel::lessThan
+
+Class QSortFilterProxyModel
+ size=16 align=8
+ base size=16 base align=8
+QSortFilterProxyModel (0x0x7f3d473da2d8) 0
+ vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u)
+ QAbstractProxyModel (0x0x7f3d473da340) 0
+ primary-for QSortFilterProxyModel (0x0x7f3d473da2d8)
+ QAbstractItemModel (0x0x7f3d473da3a8) 0
+ primary-for QAbstractProxyModel (0x0x7f3d473da340)
+ QObject (0x0x7f3d473d7540) 0
+ primary-for QAbstractItemModel (0x0x7f3d473da3a8)
+
+Class QStandardPaths
+ size=1 align=1
+ base size=0 base align=1
+QStandardPaths (0x0x7f3d473d7660) 0 empty
+
+Class QState::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QState::QPrivateSignal (0x0x7f3d473d78a0) 0 empty
+
+Vtable for QState
+QState::_ZTV6QState: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QState)
+16 (int (*)(...))QState::metaObject
+24 (int (*)(...))QState::qt_metacast
+32 (int (*)(...))QState::qt_metacall
+40 (int (*)(...))QState::~QState
+48 (int (*)(...))QState::~QState
+56 (int (*)(...))QState::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QState::onEntry
+120 (int (*)(...))QState::onExit
+
+Class QState
+ size=16 align=8
+ base size=16 base align=8
+QState (0x0x7f3d473da548) 0
+ vptr=((& QState::_ZTV6QState) + 16u)
+ QAbstractState (0x0x7f3d473da5b0) 0
+ primary-for QState (0x0x7f3d473da548)
+ QObject (0x0x7f3d473d7840) 0
+ primary-for QAbstractState (0x0x7f3d473da5b0)
+
+Class QStateMachine::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QStateMachine::QPrivateSignal (0x0x7f3d473d79c0) 0 empty
+
+Vtable for QStateMachine::SignalEvent
+QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE)
+16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent
+24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent
+
+Class QStateMachine::SignalEvent
+ size=48 align=8
+ base size=48 base align=8
+QStateMachine::SignalEvent (0x0x7f3d473da750) 0
+ vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u)
+ QEvent (0x0x7f3d473d7a20) 0
+ primary-for QStateMachine::SignalEvent (0x0x7f3d473da750)
+
+Vtable for QStateMachine::WrappedEvent
+QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE)
+16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent
+24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent
+
+Class QStateMachine::WrappedEvent
+ size=40 align=8
+ base size=40 base align=8
+QStateMachine::WrappedEvent (0x0x7f3d473da7b8) 0
+ vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u)
+ QEvent (0x0x7f3d473d7a80) 0
+ primary-for QStateMachine::WrappedEvent (0x0x7f3d473da7b8)
+
+Vtable for QStateMachine
+QStateMachine::_ZTV13QStateMachine: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QStateMachine)
+16 (int (*)(...))QStateMachine::metaObject
+24 (int (*)(...))QStateMachine::qt_metacast
+32 (int (*)(...))QStateMachine::qt_metacall
+40 (int (*)(...))QStateMachine::~QStateMachine
+48 (int (*)(...))QStateMachine::~QStateMachine
+56 (int (*)(...))QStateMachine::event
+64 (int (*)(...))QStateMachine::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QStateMachine::onEntry
+120 (int (*)(...))QStateMachine::onExit
+128 (int (*)(...))QStateMachine::beginSelectTransitions
+136 (int (*)(...))QStateMachine::endSelectTransitions
+144 (int (*)(...))QStateMachine::beginMicrostep
+152 (int (*)(...))QStateMachine::endMicrostep
+
+Class QStateMachine
+ size=16 align=8
+ base size=16 base align=8
+QStateMachine (0x0x7f3d473da618) 0
+ vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u)
+ QState (0x0x7f3d473da680) 0
+ primary-for QStateMachine (0x0x7f3d473da618)
+ QAbstractState (0x0x7f3d473da6e8) 0
+ primary-for QState (0x0x7f3d473da680)
+ QObject (0x0x7f3d473d7960) 0
+ primary-for QAbstractState (0x0x7f3d473da6e8)
+
+Class QStorageInfo
+ size=8 align=8
+ base size=8 base align=8
+QStorageInfo (0x0x7f3d473d7ae0) 0
+
+Class QAbstractConcatenable
+ size=1 align=1
+ base size=0 base align=1
+QAbstractConcatenable (0x0x7f3d47120a20) 0 empty
+
+Class QStringListModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QStringListModel::QPrivateSignal (0x0x7f3d47196540) 0 empty
+
+Vtable for QStringListModel
+QStringListModel::_ZTV16QStringListModel: 48u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QStringListModel)
+16 (int (*)(...))QStringListModel::metaObject
+24 (int (*)(...))QStringListModel::qt_metacast
+32 (int (*)(...))QStringListModel::qt_metacall
+40 (int (*)(...))QStringListModel::~QStringListModel
+48 (int (*)(...))QStringListModel::~QStringListModel
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAbstractListModel::index
+120 (int (*)(...))QAbstractListModel::parent
+128 (int (*)(...))QStringListModel::sibling
+136 (int (*)(...))QStringListModel::rowCount
+144 (int (*)(...))QAbstractListModel::columnCount
+152 (int (*)(...))QAbstractListModel::hasChildren
+160 (int (*)(...))QStringListModel::data
+168 (int (*)(...))QStringListModel::setData
+176 (int (*)(...))QAbstractItemModel::headerData
+184 (int (*)(...))QAbstractItemModel::setHeaderData
+192 (int (*)(...))QAbstractItemModel::itemData
+200 (int (*)(...))QAbstractItemModel::setItemData
+208 (int (*)(...))QAbstractItemModel::mimeTypes
+216 (int (*)(...))QAbstractItemModel::mimeData
+224 (int (*)(...))QAbstractItemModel::canDropMimeData
+232 (int (*)(...))QAbstractListModel::dropMimeData
+240 (int (*)(...))QStringListModel::supportedDropActions
+248 (int (*)(...))QAbstractItemModel::supportedDragActions
+256 (int (*)(...))QStringListModel::insertRows
+264 (int (*)(...))QAbstractItemModel::insertColumns
+272 (int (*)(...))QStringListModel::removeRows
+280 (int (*)(...))QAbstractItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractItemModel::fetchMore
+312 (int (*)(...))QAbstractItemModel::canFetchMore
+320 (int (*)(...))QStringListModel::flags
+328 (int (*)(...))QStringListModel::sort
+336 (int (*)(...))QAbstractItemModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractItemModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractItemModel::submit
+376 (int (*)(...))QAbstractItemModel::revert
+
+Class QStringListModel
+ size=24 align=8
+ base size=24 base align=8
+QStringListModel (0x0x7f3d4713dc98) 0
+ vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u)
+ QAbstractListModel (0x0x7f3d4713dd00) 0
+ primary-for QStringListModel (0x0x7f3d4713dc98)
+ QAbstractItemModel (0x0x7f3d4713dd68) 0
+ primary-for QAbstractListModel (0x0x7f3d4713dd00)
+ QObject (0x0x7f3d471964e0) 0
+ primary-for QAbstractItemModel (0x0x7f3d4713dd68)
+
+Class QSystemSemaphore
+ size=8 align=8
+ base size=8 base align=8
+QSystemSemaphore (0x0x7f3d471965a0) 0
+
+Class QTemporaryDir
+ size=8 align=8
+ base size=8 base align=8
+QTemporaryDir (0x0x7f3d47196660) 0
+
+Class QTemporaryFile::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTemporaryFile::QPrivateSignal (0x0x7f3d47196780) 0 empty
+
+Vtable for QTemporaryFile
+QTemporaryFile::_ZTV14QTemporaryFile: 34u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QTemporaryFile)
+16 (int (*)(...))QTemporaryFile::metaObject
+24 (int (*)(...))QTemporaryFile::qt_metacast
+32 (int (*)(...))QTemporaryFile::qt_metacall
+40 (int (*)(...))QTemporaryFile::~QTemporaryFile
+48 (int (*)(...))QTemporaryFile::~QTemporaryFile
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QFileDevice::isSequential
+120 (int (*)(...))QTemporaryFile::open
+128 (int (*)(...))QFileDevice::close
+136 (int (*)(...))QFileDevice::pos
+144 (int (*)(...))QFile::size
+152 (int (*)(...))QFileDevice::seek
+160 (int (*)(...))QFileDevice::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QIODevice::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))QFileDevice::readData
+224 (int (*)(...))QFileDevice::readLineData
+232 (int (*)(...))QFileDevice::writeData
+240 (int (*)(...))QTemporaryFile::fileName
+248 (int (*)(...))QFile::resize
+256 (int (*)(...))QFile::permissions
+264 (int (*)(...))QFile::setPermissions
+
+Class QTemporaryFile
+ size=16 align=8
+ base size=16 base align=8
+QTemporaryFile (0x0x7f3d4713ddd0) 0
+ vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u)
+ QFile (0x0x7f3d4713de38) 0
+ primary-for QTemporaryFile (0x0x7f3d4713ddd0)
+ QFileDevice (0x0x7f3d4713dea0) 0
+ primary-for QFile (0x0x7f3d4713de38)
+ QIODevice (0x0x7f3d4713df08) 0
+ primary-for QFileDevice (0x0x7f3d4713dea0)
+ QObject (0x0x7f3d47196720) 0
+ primary-for QIODevice (0x0x7f3d4713df08)
+
+Class QTextBoundaryFinder
+ size=48 align=8
+ base size=48 base align=8
+QTextBoundaryFinder (0x0x7f3d471967e0) 0
+
+Class QTextCodec::ConverterState
+ size=32 align=8
+ base size=32 base align=8
+QTextCodec::ConverterState (0x0x7f3d47196a20) 0
+
+Vtable for QTextCodec
+QTextCodec::_ZTV10QTextCodec: 9u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTextCodec)
+16 (int (*)(...))__cxa_pure_virtual
+24 (int (*)(...))QTextCodec::aliases
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 0u
+64 0u
+
+Class QTextCodec
+ size=8 align=8
+ base size=8 base align=8
+QTextCodec (0x0x7f3d471969c0) 0 nearly-empty
+ vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u)
+
+Class QTextEncoder
+ size=40 align=8
+ base size=40 base align=8
+QTextEncoder (0x0x7f3d47196c00) 0
+
+Class QTextDecoder
+ size=40 align=8
+ base size=40 base align=8
+QTextDecoder (0x0x7f3d47196c60) 0
+
+Class std::__mutex_base
+ size=40 align=8
+ base size=40 base align=8
+std::__mutex_base (0x0x7f3d47196cc0) 0
+
+Class std::__recursive_mutex_base
+ size=40 align=8
+ base size=40 base align=8
+std::__recursive_mutex_base (0x0x7f3d47196d20) 0
+
+Class std::mutex
+ size=40 align=8
+ base size=40 base align=8
+std::mutex (0x0x7f3d4721b138) 0
+ std::__mutex_base (0x0x7f3d47196d80) 0
+
+Class std::recursive_mutex
+ size=40 align=8
+ base size=40 base align=8
+std::recursive_mutex (0x0x7f3d4721b1a0) 0
+ std::__recursive_mutex_base (0x0x7f3d47196de0) 0
+
+Class std::timed_mutex
+ size=40 align=8
+ base size=40 base align=8
+std::timed_mutex (0x0x7f3d472a6f50) 0
+ std::__mutex_base (0x0x7f3d47196f00) 0
+ std::__timed_mutex_impl<std::timed_mutex> (0x0x7f3d47196f60) 0 empty
+
+Class std::recursive_timed_mutex
+ size=40 align=8
+ base size=40 base align=8
+std::recursive_timed_mutex (0x0x7f3d472bfbd0) 0
+ std::__recursive_mutex_base (0x0x7f3d472cb060) 0
+ std::__timed_mutex_impl<std::recursive_timed_mutex> (0x0x7f3d472cb0c0) 0 empty
+
+Class std::defer_lock_t
+ size=1 align=1
+ base size=0 base align=1
+std::defer_lock_t (0x0x7f3d472cb120) 0 empty
+
+Class std::try_to_lock_t
+ size=1 align=1
+ base size=0 base align=1
+std::try_to_lock_t (0x0x7f3d472cb180) 0 empty
+
+Class std::adopt_lock_t
+ size=1 align=1
+ base size=0 base align=1
+std::adopt_lock_t (0x0x7f3d472cb1e0) 0 empty
+
+Class std::once_flag
+ size=4 align=4
+ base size=4 base align=4
+std::once_flag (0x0x7f3d472cb420) 0
+
+Vtable for __gnu_cxx::__concurrence_lock_error
+__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE)
+16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error
+24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error
+32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what
+
+Class __gnu_cxx::__concurrence_lock_error
+ size=8 align=8
+ base size=8 base align=8
+__gnu_cxx::__concurrence_lock_error (0x0x7f3d4721b2d8) 0 nearly-empty
+ vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16u)
+ std::exception (0x0x7f3d472cb4e0) 0 nearly-empty
+ primary-for __gnu_cxx::__concurrence_lock_error (0x0x7f3d4721b2d8)
+
+Vtable for __gnu_cxx::__concurrence_unlock_error
+__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE)
+16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error
+24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error
+32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what
+
+Class __gnu_cxx::__concurrence_unlock_error
+ size=8 align=8
+ base size=8 base align=8
+__gnu_cxx::__concurrence_unlock_error (0x0x7f3d4721b340) 0 nearly-empty
+ vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16u)
+ std::exception (0x0x7f3d472cb5a0) 0 nearly-empty
+ primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7f3d4721b340)
+
+Vtable for __gnu_cxx::__concurrence_broadcast_error
+__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE)
+16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error
+24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error
+32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what
+
+Class __gnu_cxx::__concurrence_broadcast_error
+ size=8 align=8
+ base size=8 base align=8
+__gnu_cxx::__concurrence_broadcast_error (0x0x7f3d4721b3a8) 0 nearly-empty
+ vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16u)
+ std::exception (0x0x7f3d472cb660) 0 nearly-empty
+ primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7f3d4721b3a8)
+
+Vtable for __gnu_cxx::__concurrence_wait_error
+__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE)
+16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error
+24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error
+32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what
+
+Class __gnu_cxx::__concurrence_wait_error
+ size=8 align=8
+ base size=8 base align=8
+__gnu_cxx::__concurrence_wait_error (0x0x7f3d4721b478) 0 nearly-empty
+ vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16u)
+ std::exception (0x0x7f3d472cb720) 0 nearly-empty
+ primary-for __gnu_cxx::__concurrence_wait_error (0x0x7f3d4721b478)
+
+Class __gnu_cxx::__mutex
+ size=40 align=8
+ base size=40 base align=8
+__gnu_cxx::__mutex (0x0x7f3d472cb7e0) 0
+
+Class __gnu_cxx::__recursive_mutex
+ size=40 align=8
+ base size=40 base align=8
+__gnu_cxx::__recursive_mutex (0x0x7f3d472cb840) 0
+
+Class __gnu_cxx::__scoped_lock
+ size=8 align=8
+ base size=8 base align=8
+__gnu_cxx::__scoped_lock (0x0x7f3d472cb8a0) 0
+
+Class __gnu_cxx::__cond
+ size=48 align=8
+ base size=48 base align=8
+__gnu_cxx::__cond (0x0x7f3d472cb900) 0
+
+Vtable for std::bad_weak_ptr
+std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt12bad_weak_ptr)
+16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr
+24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr
+32 (int (*)(...))std::bad_weak_ptr::what
+
+Class std::bad_weak_ptr
+ size=8 align=8
+ base size=8 base align=8
+std::bad_weak_ptr (0x0x7f3d4721b750) 0 nearly-empty
+ vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16u)
+ std::exception (0x0x7f3d472cbc60) 0 nearly-empty
+ primary-for std::bad_weak_ptr (0x0x7f3d4721b750)
+
+Class std::_Sp_make_shared_tag
+ size=1 align=1
+ base size=0 base align=1
+std::_Sp_make_shared_tag (0x0x7f3d470184e0) 0 empty
+
+Class std::_Sp_locker
+ size=2 align=1
+ base size=2 base align=1
+std::_Sp_locker (0x0x7f3d47018cc0) 0
+
+Class std::thread::id
+ size=8 align=8
+ base size=8 base align=8
+std::thread::id (0x0x7f3d47018ea0) 0
+
+Vtable for std::thread::_Impl_base
+std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt6thread10_Impl_baseE)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class std::thread::_Impl_base
+ size=24 align=8
+ base size=24 base align=8
+std::thread::_Impl_base (0x0x7f3d47018f00) 0
+ vptr=((& std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE) + 16u)
+
+Class std::thread
+ size=8 align=8
+ base size=8 base align=8
+std::thread (0x0x7f3d47018e40) 0
+
+Class std::condition_variable
+ size=48 align=8
+ base size=48 base align=8
+std::condition_variable (0x0x7f3d46ec4b40) 0
+
+Class std::__at_thread_exit_elt
+ size=16 align=8
+ base size=16 base align=8
+std::__at_thread_exit_elt (0x0x7f3d46ec4c00) 0
+
+Class std::_V2::condition_variable_any
+ size=64 align=8
+ base size=64 base align=8
+std::_V2::condition_variable_any (0x0x7f3d46ec4c60) 0
+
+Class std::__atomic_futex_unsigned_base
+ size=1 align=1
+ base size=0 base align=1
+std::__atomic_futex_unsigned_base (0x0x7f3d46bb3300) 0 empty
+
+Vtable for std::future_error
+std::future_error::_ZTVSt12future_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt12future_error)
+16 (int (*)(...))std::future_error::~future_error
+24 (int (*)(...))std::future_error::~future_error
+32 (int (*)(...))std::future_error::what
+
+Class std::future_error
+ size=32 align=8
+ base size=32 base align=8
+std::future_error (0x0x7f3d46baea90) 0
+ vptr=((& std::future_error::_ZTVSt12future_error) + 16u)
+ std::logic_error (0x0x7f3d46baeaf8) 0
+ primary-for std::future_error (0x0x7f3d46baea90)
+ std::exception (0x0x7f3d46bb3420) 0 nearly-empty
+ primary-for std::logic_error (0x0x7f3d46baeaf8)
+
+Class std::__future_base::_Result_base::_Deleter
+ size=1 align=1
+ base size=0 base align=1
+std::__future_base::_Result_base::_Deleter (0x0x7f3d46bb3540) 0 empty
+
+Vtable for std::__future_base::_Result_base
+std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE)
+16 (int (*)(...))__cxa_pure_virtual
+24 0u
+32 0u
+
+Class std::__future_base::_Result_base
+ size=16 align=8
+ base size=16 base align=8
+std::__future_base::_Result_base (0x0x7f3d46bb34e0) 0
+ vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16u)
+
+Class std::__future_base::_State_baseV2::__exception_ptr_tag
+ size=1 align=1
+ base size=0 base align=1
+std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7f3d468f0a80) 0 empty
+
+Class std::__future_base::_State_baseV2::_Make_ready
+ size=32 align=8
+ base size=32 base align=8
+std::__future_base::_State_baseV2::_Make_ready (0x0x7f3d469100d0) 0
+ std::__at_thread_exit_elt (0x0x7f3d468f0b40) 0
+
+Vtable for std::__future_base::_State_baseV2
+std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E)
+16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2
+24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2
+32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async
+40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future
+
+Class std::__future_base::_State_baseV2
+ size=32 align=8
+ base size=28 base align=8
+std::__future_base::_State_baseV2 (0x0x7f3d46bb36c0) 0
+ vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16u)
+
+Class std::__future_base
+ size=1 align=1
+ base size=0 base align=1
+std::__future_base (0x0x7f3d46bb3480) 0 empty
+
+Vtable for std::__future_base::_Async_state_commonV2
+std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E)
+16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2
+24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2
+32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async
+40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future
+
+Class std::__future_base::_Async_state_commonV2
+ size=48 align=8
+ base size=44 base align=8
+std::__future_base::_Async_state_commonV2 (0x0x7f3d46658c98) 0
+ vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16u)
+ std::__future_base::_State_baseV2 (0x0x7f3d4665ba20) 0
+ primary-for std::__future_base::_Async_state_commonV2 (0x0x7f3d46658c98)
+
+Class QThread::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QThread::QPrivateSignal (0x0x7f3d462dc180) 0 empty
+
+Vtable for QThread
+QThread::_ZTV7QThread: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QThread)
+16 (int (*)(...))QThread::metaObject
+24 (int (*)(...))QThread::qt_metacast
+32 (int (*)(...))QThread::qt_metacall
+40 (int (*)(...))QThread::~QThread
+48 (int (*)(...))QThread::~QThread
+56 (int (*)(...))QThread::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QThread::run
+
+Class QThread
+ size=16 align=8
+ base size=16 base align=8
+QThread (0x0x7f3d466bd750) 0
+ vptr=((& QThread::_ZTV7QThread) + 16u)
+ QObject (0x0x7f3d462dc120) 0
+ primary-for QThread (0x0x7f3d466bd750)
+
+Class QThreadPool::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QThreadPool::QPrivateSignal (0x0x7f3d462dc2a0) 0 empty
+
+Vtable for QThreadPool
+QThreadPool::_ZTV11QThreadPool: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QThreadPool)
+16 (int (*)(...))QThreadPool::metaObject
+24 (int (*)(...))QThreadPool::qt_metacast
+32 (int (*)(...))QThreadPool::qt_metacall
+40 (int (*)(...))QThreadPool::~QThreadPool
+48 (int (*)(...))QThreadPool::~QThreadPool
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QThreadPool
+ size=16 align=8
+ base size=16 base align=8
+QThreadPool (0x0x7f3d466bd7b8) 0
+ vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u)
+ QObject (0x0x7f3d462dc240) 0
+ primary-for QThreadPool (0x0x7f3d466bd7b8)
+
+Class QThreadStorageData
+ size=4 align=4
+ base size=4 base align=4
+QThreadStorageData (0x0x7f3d462dc300) 0
+
+Class QTimeLine::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTimeLine::QPrivateSignal (0x0x7f3d462dc420) 0 empty
+
+Vtable for QTimeLine
+QTimeLine::_ZTV9QTimeLine: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QTimeLine)
+16 (int (*)(...))QTimeLine::metaObject
+24 (int (*)(...))QTimeLine::qt_metacast
+32 (int (*)(...))QTimeLine::qt_metacall
+40 (int (*)(...))QTimeLine::~QTimeLine
+48 (int (*)(...))QTimeLine::~QTimeLine
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QTimeLine::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QTimeLine::valueForTime
+
+Class QTimeLine
+ size=16 align=8
+ base size=16 base align=8
+QTimeLine (0x0x7f3d466bd820) 0
+ vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u)
+ QObject (0x0x7f3d462dc3c0) 0
+ primary-for QTimeLine (0x0x7f3d466bd820)
+
+Class QTimer::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTimer::QPrivateSignal (0x0x7f3d462dc4e0) 0 empty
+
+Vtable for QTimer
+QTimer::_ZTV6QTimer: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QTimer)
+16 (int (*)(...))QTimer::metaObject
+24 (int (*)(...))QTimer::qt_metacast
+32 (int (*)(...))QTimer::qt_metacall
+40 (int (*)(...))QTimer::~QTimer
+48 (int (*)(...))QTimer::~QTimer
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QTimer::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QTimer
+ size=32 align=8
+ base size=29 base align=8
+QTimer (0x0x7f3d466bd888) 0
+ vptr=((& QTimer::_ZTV6QTimer) + 16u)
+ QObject (0x0x7f3d462dc480) 0
+ primary-for QTimer (0x0x7f3d466bd888)
+
+Class QTimeZone::OffsetData
+ size=32 align=8
+ base size=28 base align=8
+QTimeZone::OffsetData (0x0x7f3d462dcba0) 0
+
+Class QTimeZone
+ size=8 align=8
+ base size=8 base align=8
+QTimeZone (0x0x7f3d462dcb40) 0
+
+Class QTranslator::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTranslator::QPrivateSignal (0x0x7f3d463ac180) 0 empty
+
+Vtable for QTranslator
+QTranslator::_ZTV11QTranslator: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTranslator)
+16 (int (*)(...))QTranslator::metaObject
+24 (int (*)(...))QTranslator::qt_metacast
+32 (int (*)(...))QTranslator::qt_metacall
+40 (int (*)(...))QTranslator::~QTranslator
+48 (int (*)(...))QTranslator::~QTranslator
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QTranslator::translate
+120 (int (*)(...))QTranslator::isEmpty
+
+Class QTranslator
+ size=16 align=8
+ base size=16 base align=8
+QTranslator (0x0x7f3d463a52d8) 0
+ vptr=((& QTranslator::_ZTV11QTranslator) + 16u)
+ QObject (0x0x7f3d463ac120) 0
+ primary-for QTranslator (0x0x7f3d463a52d8)
+
+Class QUrl
+ size=8 align=8
+ base size=8 base align=8
+QUrl (0x0x7f3d463ac2a0) 0
+
+Class QUrlQuery
+ size=8 align=8
+ base size=8 base align=8
+QUrlQuery (0x0x7f3d464c3960) 0
+
+Class QUuid
+ size=16 align=4
+ base size=16 base align=4
+QUuid (0x0x7f3d46162000) 0
+
+Class QWaitCondition
+ size=8 align=8
+ base size=8 base align=8
+QWaitCondition (0x0x7f3d46162600) 0
+
+Class QXmlStreamStringRef
+ size=16 align=8
+ base size=16 base align=8
+QXmlStreamStringRef (0x0x7f3d46162660) 0
+
+Class QXmlStreamAttribute
+ size=80 align=8
+ base size=73 base align=8
+QXmlStreamAttribute (0x0x7f3d46162960) 0
+
+Class QXmlStreamAttributes
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamAttributes (0x0x7f3d46161dd0) 0
+ QVector<QXmlStreamAttribute> (0x0x7f3d46162d20) 0
+
+Class QXmlStreamNamespaceDeclaration
+ size=40 align=8
+ base size=40 base align=8
+QXmlStreamNamespaceDeclaration (0x0x7f3d46162d80) 0
+
+Class QXmlStreamNotationDeclaration
+ size=56 align=8
+ base size=56 base align=8
+QXmlStreamNotationDeclaration (0x0x7f3d4624d060) 0
+
+Class QXmlStreamEntityDeclaration
+ size=88 align=8
+ base size=88 base align=8
+QXmlStreamEntityDeclaration (0x0x7f3d4624d300) 0
+
+Vtable for QXmlStreamEntityResolver
+QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver)
+16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity
+40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity
+
+Class QXmlStreamEntityResolver
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamEntityResolver (0x0x7f3d4624d5a0) 0 nearly-empty
+ vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u)
+
+Class QXmlStreamReader
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamReader (0x0x7f3d4624d600) 0
+
+Class QXmlStreamWriter
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamWriter (0x0x7f3d45efb060) 0
+
+Class QRgba64
+ size=8 align=8
+ base size=8 base align=8
+QRgba64 (0x0x7f3d45efb180) 0
+
+Class QColor
+ size=16 align=4
+ base size=14 base align=4
+QColor (0x0x7f3d45efb420) 0
+
+Class QRegion::QRegionData
+ size=16 align=8
+ base size=16 base align=8
+QRegion::QRegionData (0x0x7f3d45efbde0) 0
+
+Class QRegion
+ size=8 align=8
+ base size=8 base align=8
+QRegion (0x0x7f3d45efbd80) 0
+
+Class QKeySequence
+ size=8 align=8
+ base size=8 base align=8
+QKeySequence (0x0x7f3d460b4180) 0
+
+Class QVector2D
+ size=8 align=4
+ base size=8 base align=4
+QVector2D (0x0x7f3d45d4e6c0) 0
+
+Class QTouchDevice
+ size=8 align=8
+ base size=8 base align=8
+QTouchDevice (0x0x7f3d45d4e960) 0
+
+Vtable for QInputEvent
+QInputEvent::_ZTV11QInputEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QInputEvent)
+16 (int (*)(...))QInputEvent::~QInputEvent
+24 (int (*)(...))QInputEvent::~QInputEvent
+
+Class QInputEvent
+ size=32 align=8
+ base size=32 base align=8
+QInputEvent (0x0x7f3d45d4dbc8) 0
+ vptr=((& QInputEvent::_ZTV11QInputEvent) + 16u)
+ QEvent (0x0x7f3d45d4eb40) 0
+ primary-for QInputEvent (0x0x7f3d45d4dbc8)
+
+Vtable for QEnterEvent
+QEnterEvent::_ZTV11QEnterEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QEnterEvent)
+16 (int (*)(...))QEnterEvent::~QEnterEvent
+24 (int (*)(...))QEnterEvent::~QEnterEvent
+
+Class QEnterEvent
+ size=72 align=8
+ base size=72 base align=8
+QEnterEvent (0x0x7f3d45d4dc30) 0
+ vptr=((& QEnterEvent::_ZTV11QEnterEvent) + 16u)
+ QEvent (0x0x7f3d45d4eba0) 0
+ primary-for QEnterEvent (0x0x7f3d45d4dc30)
+
+Vtable for QMouseEvent
+QMouseEvent::_ZTV11QMouseEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QMouseEvent)
+16 (int (*)(...))QMouseEvent::~QMouseEvent
+24 (int (*)(...))QMouseEvent::~QMouseEvent
+
+Class QMouseEvent
+ size=104 align=8
+ base size=100 base align=8
+QMouseEvent (0x0x7f3d45d4dc98) 0
+ vptr=((& QMouseEvent::_ZTV11QMouseEvent) + 16u)
+ QInputEvent (0x0x7f3d45d4dd00) 0
+ primary-for QMouseEvent (0x0x7f3d45d4dc98)
+ QEvent (0x0x7f3d45d4ec00) 0
+ primary-for QInputEvent (0x0x7f3d45d4dd00)
+
+Vtable for QHoverEvent
+QHoverEvent::_ZTV11QHoverEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QHoverEvent)
+16 (int (*)(...))QHoverEvent::~QHoverEvent
+24 (int (*)(...))QHoverEvent::~QHoverEvent
+
+Class QHoverEvent
+ size=64 align=8
+ base size=64 base align=8
+QHoverEvent (0x0x7f3d45d4dd68) 0
+ vptr=((& QHoverEvent::_ZTV11QHoverEvent) + 16u)
+ QInputEvent (0x0x7f3d45d4ddd0) 0
+ primary-for QHoverEvent (0x0x7f3d45d4dd68)
+ QEvent (0x0x7f3d45d4ec60) 0
+ primary-for QInputEvent (0x0x7f3d45d4ddd0)
+
+Vtable for QWheelEvent
+QWheelEvent::_ZTV11QWheelEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QWheelEvent)
+16 (int (*)(...))QWheelEvent::~QWheelEvent
+24 (int (*)(...))QWheelEvent::~QWheelEvent
+
+Class QWheelEvent
+ size=96 align=8
+ base size=96 base align=8
+QWheelEvent (0x0x7f3d45d4de38) 0
+ vptr=((& QWheelEvent::_ZTV11QWheelEvent) + 16u)
+ QInputEvent (0x0x7f3d45d4dea0) 0
+ primary-for QWheelEvent (0x0x7f3d45d4de38)
+ QEvent (0x0x7f3d45d4ecc0) 0
+ primary-for QInputEvent (0x0x7f3d45d4dea0)
+
+Vtable for QTabletEvent
+QTabletEvent::_ZTV12QTabletEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QTabletEvent)
+16 (int (*)(...))QTabletEvent::~QTabletEvent
+24 (int (*)(...))QTabletEvent::~QTabletEvent
+
+Class QTabletEvent
+ size=128 align=8
+ base size=128 base align=8
+QTabletEvent (0x0x7f3d45d4df08) 0
+ vptr=((& QTabletEvent::_ZTV12QTabletEvent) + 16u)
+ QInputEvent (0x0x7f3d45d4df70) 0
+ primary-for QTabletEvent (0x0x7f3d45d4df08)
+ QEvent (0x0x7f3d45d4ed20) 0
+ primary-for QInputEvent (0x0x7f3d45d4df70)
+
+Vtable for QNativeGestureEvent
+QNativeGestureEvent::_ZTV19QNativeGestureEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QNativeGestureEvent)
+16 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent
+24 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent
+
+Class QNativeGestureEvent
+ size=112 align=8
+ base size=112 base align=8
+QNativeGestureEvent (0x0x7f3d45e58000) 0
+ vptr=((& QNativeGestureEvent::_ZTV19QNativeGestureEvent) + 16u)
+ QInputEvent (0x0x7f3d45e58068) 0
+ primary-for QNativeGestureEvent (0x0x7f3d45e58000)
+ QEvent (0x0x7f3d45d4ed80) 0
+ primary-for QInputEvent (0x0x7f3d45e58068)
+
+Vtable for QKeyEvent
+QKeyEvent::_ZTV9QKeyEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QKeyEvent)
+16 (int (*)(...))QKeyEvent::~QKeyEvent
+24 (int (*)(...))QKeyEvent::~QKeyEvent
+
+Class QKeyEvent
+ size=64 align=8
+ base size=59 base align=8
+QKeyEvent (0x0x7f3d45e580d0) 0
+ vptr=((& QKeyEvent::_ZTV9QKeyEvent) + 16u)
+ QInputEvent (0x0x7f3d45e58138) 0
+ primary-for QKeyEvent (0x0x7f3d45e580d0)
+ QEvent (0x0x7f3d45d4ede0) 0
+ primary-for QInputEvent (0x0x7f3d45e58138)
+
+Vtable for QFocusEvent
+QFocusEvent::_ZTV11QFocusEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QFocusEvent)
+16 (int (*)(...))QFocusEvent::~QFocusEvent
+24 (int (*)(...))QFocusEvent::~QFocusEvent
+
+Class QFocusEvent
+ size=24 align=8
+ base size=24 base align=8
+QFocusEvent (0x0x7f3d45e581a0) 0
+ vptr=((& QFocusEvent::_ZTV11QFocusEvent) + 16u)
+ QEvent (0x0x7f3d45d4ee40) 0
+ primary-for QFocusEvent (0x0x7f3d45e581a0)
+
+Vtable for QPaintEvent
+QPaintEvent::_ZTV11QPaintEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QPaintEvent)
+16 (int (*)(...))QPaintEvent::~QPaintEvent
+24 (int (*)(...))QPaintEvent::~QPaintEvent
+
+Class QPaintEvent
+ size=56 align=8
+ base size=49 base align=8
+QPaintEvent (0x0x7f3d45e58208) 0
+ vptr=((& QPaintEvent::_ZTV11QPaintEvent) + 16u)
+ QEvent (0x0x7f3d45d4eea0) 0
+ primary-for QPaintEvent (0x0x7f3d45e58208)
+
+Vtable for QMoveEvent
+QMoveEvent::_ZTV10QMoveEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QMoveEvent)
+16 (int (*)(...))QMoveEvent::~QMoveEvent
+24 (int (*)(...))QMoveEvent::~QMoveEvent
+
+Class QMoveEvent
+ size=40 align=8
+ base size=36 base align=8
+QMoveEvent (0x0x7f3d45e58270) 0
+ vptr=((& QMoveEvent::_ZTV10QMoveEvent) + 16u)
+ QEvent (0x0x7f3d45d4ef00) 0
+ primary-for QMoveEvent (0x0x7f3d45e58270)
+
+Vtable for QExposeEvent
+QExposeEvent::_ZTV12QExposeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QExposeEvent)
+16 (int (*)(...))QExposeEvent::~QExposeEvent
+24 (int (*)(...))QExposeEvent::~QExposeEvent
+
+Class QExposeEvent
+ size=32 align=8
+ base size=32 base align=8
+QExposeEvent (0x0x7f3d45e582d8) 0
+ vptr=((& QExposeEvent::_ZTV12QExposeEvent) + 16u)
+ QEvent (0x0x7f3d45d4ef60) 0
+ primary-for QExposeEvent (0x0x7f3d45e582d8)
+
+Vtable for QPlatformSurfaceEvent
+QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QPlatformSurfaceEvent)
+16 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent
+24 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent
+
+Class QPlatformSurfaceEvent
+ size=24 align=8
+ base size=24 base align=8
+QPlatformSurfaceEvent (0x0x7f3d45e58340) 0
+ vptr=((& QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent) + 16u)
+ QEvent (0x0x7f3d45e8d000) 0
+ primary-for QPlatformSurfaceEvent (0x0x7f3d45e58340)
+
+Vtable for QResizeEvent
+QResizeEvent::_ZTV12QResizeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QResizeEvent)
+16 (int (*)(...))QResizeEvent::~QResizeEvent
+24 (int (*)(...))QResizeEvent::~QResizeEvent
+
+Class QResizeEvent
+ size=40 align=8
+ base size=36 base align=8
+QResizeEvent (0x0x7f3d45e583a8) 0
+ vptr=((& QResizeEvent::_ZTV12QResizeEvent) + 16u)
+ QEvent (0x0x7f3d45e8d060) 0
+ primary-for QResizeEvent (0x0x7f3d45e583a8)
+
+Vtable for QCloseEvent
+QCloseEvent::_ZTV11QCloseEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QCloseEvent)
+16 (int (*)(...))QCloseEvent::~QCloseEvent
+24 (int (*)(...))QCloseEvent::~QCloseEvent
+
+Class QCloseEvent
+ size=24 align=8
+ base size=20 base align=8
+QCloseEvent (0x0x7f3d45e58410) 0
+ vptr=((& QCloseEvent::_ZTV11QCloseEvent) + 16u)
+ QEvent (0x0x7f3d45e8d0c0) 0
+ primary-for QCloseEvent (0x0x7f3d45e58410)
+
+Vtable for QIconDragEvent
+QIconDragEvent::_ZTV14QIconDragEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QIconDragEvent)
+16 (int (*)(...))QIconDragEvent::~QIconDragEvent
+24 (int (*)(...))QIconDragEvent::~QIconDragEvent
+
+Class QIconDragEvent
+ size=24 align=8
+ base size=20 base align=8
+QIconDragEvent (0x0x7f3d45e58478) 0
+ vptr=((& QIconDragEvent::_ZTV14QIconDragEvent) + 16u)
+ QEvent (0x0x7f3d45e8d120) 0
+ primary-for QIconDragEvent (0x0x7f3d45e58478)
+
+Vtable for QShowEvent
+QShowEvent::_ZTV10QShowEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QShowEvent)
+16 (int (*)(...))QShowEvent::~QShowEvent
+24 (int (*)(...))QShowEvent::~QShowEvent
+
+Class QShowEvent
+ size=24 align=8
+ base size=20 base align=8
+QShowEvent (0x0x7f3d45e584e0) 0
+ vptr=((& QShowEvent::_ZTV10QShowEvent) + 16u)
+ QEvent (0x0x7f3d45e8d180) 0
+ primary-for QShowEvent (0x0x7f3d45e584e0)
+
+Vtable for QHideEvent
+QHideEvent::_ZTV10QHideEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QHideEvent)
+16 (int (*)(...))QHideEvent::~QHideEvent
+24 (int (*)(...))QHideEvent::~QHideEvent
+
+Class QHideEvent
+ size=24 align=8
+ base size=20 base align=8
+QHideEvent (0x0x7f3d45e58548) 0
+ vptr=((& QHideEvent::_ZTV10QHideEvent) + 16u)
+ QEvent (0x0x7f3d45e8d1e0) 0
+ primary-for QHideEvent (0x0x7f3d45e58548)
+
+Vtable for QContextMenuEvent
+QContextMenuEvent::_ZTV17QContextMenuEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QContextMenuEvent)
+16 (int (*)(...))QContextMenuEvent::~QContextMenuEvent
+24 (int (*)(...))QContextMenuEvent::~QContextMenuEvent
+
+Class QContextMenuEvent
+ size=56 align=8
+ base size=49 base align=8
+QContextMenuEvent (0x0x7f3d45e585b0) 0
+ vptr=((& QContextMenuEvent::_ZTV17QContextMenuEvent) + 16u)
+ QInputEvent (0x0x7f3d45e58618) 0
+ primary-for QContextMenuEvent (0x0x7f3d45e585b0)
+ QEvent (0x0x7f3d45e8d240) 0
+ primary-for QInputEvent (0x0x7f3d45e58618)
+
+Class QInputMethodEvent::Attribute
+ size=32 align=8
+ base size=32 base align=8
+QInputMethodEvent::Attribute (0x0x7f3d45e8d300) 0
+
+Vtable for QInputMethodEvent
+QInputMethodEvent::_ZTV17QInputMethodEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QInputMethodEvent)
+16 (int (*)(...))QInputMethodEvent::~QInputMethodEvent
+24 (int (*)(...))QInputMethodEvent::~QInputMethodEvent
+
+Class QInputMethodEvent
+ size=56 align=8
+ base size=56 base align=8
+QInputMethodEvent (0x0x7f3d45e58680) 0
+ vptr=((& QInputMethodEvent::_ZTV17QInputMethodEvent) + 16u)
+ QEvent (0x0x7f3d45e8d2a0) 0
+ primary-for QInputMethodEvent (0x0x7f3d45e58680)
+
+Class QInputMethodQueryEvent::QueryPair
+ size=24 align=8
+ base size=24 base align=8
+QInputMethodQueryEvent::QueryPair (0x0x7f3d45e8d780) 0
+
+Vtable for QInputMethodQueryEvent
+QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI22QInputMethodQueryEvent)
+16 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent
+24 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent
+
+Class QInputMethodQueryEvent
+ size=32 align=8
+ base size=32 base align=8
+QInputMethodQueryEvent (0x0x7f3d45e589c0) 0
+ vptr=((& QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent) + 16u)
+ QEvent (0x0x7f3d45e8d720) 0
+ primary-for QInputMethodQueryEvent (0x0x7f3d45e589c0)
+
+Vtable for QDropEvent
+QDropEvent::_ZTV10QDropEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QDropEvent)
+16 (int (*)(...))QDropEvent::~QDropEvent
+24 (int (*)(...))QDropEvent::~QDropEvent
+
+Class QDropEvent
+ size=72 align=8
+ base size=72 base align=8
+QDropEvent (0x0x7f3d45e58c98) 0
+ vptr=((& QDropEvent::_ZTV10QDropEvent) + 16u)
+ QEvent (0x0x7f3d45e8dae0) 0
+ primary-for QDropEvent (0x0x7f3d45e58c98)
+
+Vtable for QDragMoveEvent
+QDragMoveEvent::_ZTV14QDragMoveEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QDragMoveEvent)
+16 (int (*)(...))QDragMoveEvent::~QDragMoveEvent
+24 (int (*)(...))QDragMoveEvent::~QDragMoveEvent
+
+Class QDragMoveEvent
+ size=88 align=8
+ base size=88 base align=8
+QDragMoveEvent (0x0x7f3d45e58d00) 0
+ vptr=((& QDragMoveEvent::_ZTV14QDragMoveEvent) + 16u)
+ QDropEvent (0x0x7f3d45e58d68) 0
+ primary-for QDragMoveEvent (0x0x7f3d45e58d00)
+ QEvent (0x0x7f3d45e8db40) 0
+ primary-for QDropEvent (0x0x7f3d45e58d68)
+
+Vtable for QDragEnterEvent
+QDragEnterEvent::_ZTV15QDragEnterEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QDragEnterEvent)
+16 (int (*)(...))QDragEnterEvent::~QDragEnterEvent
+24 (int (*)(...))QDragEnterEvent::~QDragEnterEvent
+
+Class QDragEnterEvent
+ size=88 align=8
+ base size=88 base align=8
+QDragEnterEvent (0x0x7f3d45e58dd0) 0
+ vptr=((& QDragEnterEvent::_ZTV15QDragEnterEvent) + 16u)
+ QDragMoveEvent (0x0x7f3d45e58e38) 0
+ primary-for QDragEnterEvent (0x0x7f3d45e58dd0)
+ QDropEvent (0x0x7f3d45e58ea0) 0
+ primary-for QDragMoveEvent (0x0x7f3d45e58e38)
+ QEvent (0x0x7f3d45e8dba0) 0
+ primary-for QDropEvent (0x0x7f3d45e58ea0)
+
+Vtable for QDragLeaveEvent
+QDragLeaveEvent::_ZTV15QDragLeaveEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QDragLeaveEvent)
+16 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent
+24 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent
+
+Class QDragLeaveEvent
+ size=24 align=8
+ base size=20 base align=8
+QDragLeaveEvent (0x0x7f3d45e58f08) 0
+ vptr=((& QDragLeaveEvent::_ZTV15QDragLeaveEvent) + 16u)
+ QEvent (0x0x7f3d45e8dc00) 0
+ primary-for QDragLeaveEvent (0x0x7f3d45e58f08)
+
+Vtable for QHelpEvent
+QHelpEvent::_ZTV10QHelpEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QHelpEvent)
+16 (int (*)(...))QHelpEvent::~QHelpEvent
+24 (int (*)(...))QHelpEvent::~QHelpEvent
+
+Class QHelpEvent
+ size=40 align=8
+ base size=36 base align=8
+QHelpEvent (0x0x7f3d45e58f70) 0
+ vptr=((& QHelpEvent::_ZTV10QHelpEvent) + 16u)
+ QEvent (0x0x7f3d45e8dc60) 0
+ primary-for QHelpEvent (0x0x7f3d45e58f70)
+
+Vtable for QStatusTipEvent
+QStatusTipEvent::_ZTV15QStatusTipEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QStatusTipEvent)
+16 (int (*)(...))QStatusTipEvent::~QStatusTipEvent
+24 (int (*)(...))QStatusTipEvent::~QStatusTipEvent
+
+Class QStatusTipEvent
+ size=32 align=8
+ base size=32 base align=8
+QStatusTipEvent (0x0x7f3d45b5b000) 0
+ vptr=((& QStatusTipEvent::_ZTV15QStatusTipEvent) + 16u)
+ QEvent (0x0x7f3d45e8dcc0) 0
+ primary-for QStatusTipEvent (0x0x7f3d45b5b000)
+
+Vtable for QWhatsThisClickedEvent
+QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI22QWhatsThisClickedEvent)
+16 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent
+24 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent
+
+Class QWhatsThisClickedEvent
+ size=32 align=8
+ base size=32 base align=8
+QWhatsThisClickedEvent (0x0x7f3d45b5b068) 0
+ vptr=((& QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent) + 16u)
+ QEvent (0x0x7f3d45e8dd20) 0
+ primary-for QWhatsThisClickedEvent (0x0x7f3d45b5b068)
+
+Vtable for QActionEvent
+QActionEvent::_ZTV12QActionEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QActionEvent)
+16 (int (*)(...))QActionEvent::~QActionEvent
+24 (int (*)(...))QActionEvent::~QActionEvent
+
+Class QActionEvent
+ size=40 align=8
+ base size=40 base align=8
+QActionEvent (0x0x7f3d45b5b0d0) 0
+ vptr=((& QActionEvent::_ZTV12QActionEvent) + 16u)
+ QEvent (0x0x7f3d45e8dd80) 0
+ primary-for QActionEvent (0x0x7f3d45b5b0d0)
+
+Vtable for QFileOpenEvent
+QFileOpenEvent::_ZTV14QFileOpenEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QFileOpenEvent)
+16 (int (*)(...))QFileOpenEvent::~QFileOpenEvent
+24 (int (*)(...))QFileOpenEvent::~QFileOpenEvent
+
+Class QFileOpenEvent
+ size=40 align=8
+ base size=40 base align=8
+QFileOpenEvent (0x0x7f3d45b5b138) 0
+ vptr=((& QFileOpenEvent::_ZTV14QFileOpenEvent) + 16u)
+ QEvent (0x0x7f3d45e8dde0) 0
+ primary-for QFileOpenEvent (0x0x7f3d45b5b138)
+
+Vtable for QToolBarChangeEvent
+QToolBarChangeEvent::_ZTV19QToolBarChangeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QToolBarChangeEvent)
+16 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent
+24 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent
+
+Class QToolBarChangeEvent
+ size=24 align=8
+ base size=21 base align=8
+QToolBarChangeEvent (0x0x7f3d45b5b1a0) 0
+ vptr=((& QToolBarChangeEvent::_ZTV19QToolBarChangeEvent) + 16u)
+ QEvent (0x0x7f3d45e8de40) 0
+ primary-for QToolBarChangeEvent (0x0x7f3d45b5b1a0)
+
+Vtable for QShortcutEvent
+QShortcutEvent::_ZTV14QShortcutEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QShortcutEvent)
+16 (int (*)(...))QShortcutEvent::~QShortcutEvent
+24 (int (*)(...))QShortcutEvent::~QShortcutEvent
+
+Class QShortcutEvent
+ size=40 align=8
+ base size=40 base align=8
+QShortcutEvent (0x0x7f3d45b5b208) 0
+ vptr=((& QShortcutEvent::_ZTV14QShortcutEvent) + 16u)
+ QEvent (0x0x7f3d45e8dea0) 0
+ primary-for QShortcutEvent (0x0x7f3d45b5b208)
+
+Vtable for QWindowStateChangeEvent
+QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QWindowStateChangeEvent)
+16 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent
+24 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent
+
+Class QWindowStateChangeEvent
+ size=32 align=8
+ base size=25 base align=8
+QWindowStateChangeEvent (0x0x7f3d45b5b270) 0
+ vptr=((& QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent) + 16u)
+ QEvent (0x0x7f3d45e8df00) 0
+ primary-for QWindowStateChangeEvent (0x0x7f3d45b5b270)
+
+Class QPointingDeviceUniqueId
+ size=8 align=8
+ base size=8 base align=8
+QPointingDeviceUniqueId (0x0x7f3d45e8df60) 0
+
+Class QTouchEvent::TouchPoint
+ size=8 align=8
+ base size=8 base align=8
+QTouchEvent::TouchPoint (0x0x7f3d45b89660) 0
+
+Vtable for QTouchEvent
+QTouchEvent::_ZTV11QTouchEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTouchEvent)
+16 (int (*)(...))QTouchEvent::~QTouchEvent
+24 (int (*)(...))QTouchEvent::~QTouchEvent
+
+Class QTouchEvent
+ size=72 align=8
+ base size=72 base align=8
+QTouchEvent (0x0x7f3d45b5b8f0) 0
+ vptr=((& QTouchEvent::_ZTV11QTouchEvent) + 16u)
+ QInputEvent (0x0x7f3d45b5b958) 0
+ primary-for QTouchEvent (0x0x7f3d45b5b8f0)
+ QEvent (0x0x7f3d45b89600) 0
+ primary-for QInputEvent (0x0x7f3d45b5b958)
+
+Vtable for QScrollPrepareEvent
+QScrollPrepareEvent::_ZTV19QScrollPrepareEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QScrollPrepareEvent)
+16 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent
+24 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent
+
+Class QScrollPrepareEvent
+ size=112 align=8
+ base size=112 base align=8
+QScrollPrepareEvent (0x0x7f3d45c6c1a0) 0
+ vptr=((& QScrollPrepareEvent::_ZTV19QScrollPrepareEvent) + 16u)
+ QEvent (0x0x7f3d45c53cc0) 0
+ primary-for QScrollPrepareEvent (0x0x7f3d45c6c1a0)
+
+Vtable for QScrollEvent
+QScrollEvent::_ZTV12QScrollEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QScrollEvent)
+16 (int (*)(...))QScrollEvent::~QScrollEvent
+24 (int (*)(...))QScrollEvent::~QScrollEvent
+
+Class QScrollEvent
+ size=64 align=8
+ base size=60 base align=8
+QScrollEvent (0x0x7f3d45c6c208) 0
+ vptr=((& QScrollEvent::_ZTV12QScrollEvent) + 16u)
+ QEvent (0x0x7f3d45c53d20) 0
+ primary-for QScrollEvent (0x0x7f3d45c6c208)
+
+Vtable for QScreenOrientationChangeEvent
+QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI29QScreenOrientationChangeEvent)
+16 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent
+24 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent
+
+Class QScreenOrientationChangeEvent
+ size=40 align=8
+ base size=36 base align=8
+QScreenOrientationChangeEvent (0x0x7f3d45c6c270) 0
+ vptr=((& QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent) + 16u)
+ QEvent (0x0x7f3d45c53d80) 0
+ primary-for QScreenOrientationChangeEvent (0x0x7f3d45c6c270)
+
+Vtable for QApplicationStateChangeEvent
+QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI28QApplicationStateChangeEvent)
+16 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent
+24 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent
+
+Class QApplicationStateChangeEvent
+ size=24 align=8
+ base size=24 base align=8
+QApplicationStateChangeEvent (0x0x7f3d45c6c2d8) 0
+ vptr=((& QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent) + 16u)
+ QEvent (0x0x7f3d45c53de0) 0
+ primary-for QApplicationStateChangeEvent (0x0x7f3d45c6c2d8)
+
+Class QFont
+ size=16 align=8
+ base size=12 base align=8
+QFont (0x0x7f3d45c53e40) 0
+
+Class QPolygon
+ size=8 align=8
+ base size=8 base align=8
+QPolygon (0x0x7f3d4593a068) 0
+ QVector<QPoint> (0x0x7f3d45904b40) 0
+
+Class QPolygonF
+ size=8 align=8
+ base size=8 base align=8
+QPolygonF (0x0x7f3d4593a410) 0
+ QVector<QPointF> (0x0x7f3d459b8000) 0
+
+Class QMatrix
+ size=48 align=8
+ base size=48 base align=8
+QMatrix (0x0x7f3d459b83c0) 0
+
+Class QPainterPath::Element
+ size=24 align=8
+ base size=24 base align=8
+QPainterPath::Element (0x0x7f3d459b86c0) 0
+
+Class QPainterPath
+ size=8 align=8
+ base size=8 base align=8
+QPainterPath (0x0x7f3d459b8660) 0
+
+Class QPainterPathStroker
+ size=8 align=8
+ base size=8 base align=8
+QPainterPathStroker (0x0x7f3d45a880c0) 0
+
+Class QTransform
+ size=88 align=8
+ base size=88 base align=8
+QTransform (0x0x7f3d45a881e0) 0
+
+Vtable for QPaintDevice
+QPaintDevice::_ZTV12QPaintDevice: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QPaintDevice)
+16 0u
+24 0u
+32 (int (*)(...))QPaintDevice::devType
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))QPaintDevice::metric
+56 (int (*)(...))QPaintDevice::initPainter
+64 (int (*)(...))QPaintDevice::redirected
+72 (int (*)(...))QPaintDevice::sharedPainter
+
+Class QPaintDevice
+ size=24 align=8
+ base size=24 base align=8
+QPaintDevice (0x0x7f3d45a88900) 0
+ vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 16u)
+
+Class QPixelFormat
+ size=8 align=8
+ base size=8 base align=8
+QPixelFormat (0x0x7f3d45a88960) 0
+
+Vtable for QImage
+QImage::_ZTV6QImage: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QImage)
+16 (int (*)(...))QImage::~QImage
+24 (int (*)(...))QImage::~QImage
+32 (int (*)(...))QImage::devType
+40 (int (*)(...))QImage::paintEngine
+48 (int (*)(...))QImage::metric
+56 (int (*)(...))QPaintDevice::initPainter
+64 (int (*)(...))QPaintDevice::redirected
+72 (int (*)(...))QPaintDevice::sharedPainter
+
+Class QImage
+ size=32 align=8
+ base size=32 base align=8
+QImage (0x0x7f3d457af2d8) 0
+ vptr=((& QImage::_ZTV6QImage) + 16u)
+ QPaintDevice (0x0x7f3d457ab420) 0
+ primary-for QImage (0x0x7f3d457af2d8)
+
+Vtable for QPixmap
+QPixmap::_ZTV7QPixmap: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QPixmap)
+16 (int (*)(...))QPixmap::~QPixmap
+24 (int (*)(...))QPixmap::~QPixmap
+32 (int (*)(...))QPixmap::devType
+40 (int (*)(...))QPixmap::paintEngine
+48 (int (*)(...))QPixmap::metric
+56 (int (*)(...))QPaintDevice::initPainter
+64 (int (*)(...))QPaintDevice::redirected
+72 (int (*)(...))QPaintDevice::sharedPainter
+
+Class QPixmap
+ size=32 align=8
+ base size=32 base align=8
+QPixmap (0x0x7f3d45873e38) 0
+ vptr=((& QPixmap::_ZTV7QPixmap) + 16u)
+ QPaintDevice (0x0x7f3d4587d3c0) 0
+ primary-for QPixmap (0x0x7f3d45873e38)
+
+Class QBrush
+ size=8 align=8
+ base size=8 base align=8
+QBrush (0x0x7f3d4587d6c0) 0
+
+Class QBrushData
+ size=112 align=8
+ base size=112 base align=8
+QBrushData (0x0x7f3d4587de40) 0
+
+Class QGradient
+ size=64 align=8
+ base size=64 base align=8
+QGradient (0x0x7f3d4587dea0) 0
+
+Class QLinearGradient
+ size=64 align=8
+ base size=64 base align=8
+QLinearGradient (0x0x7f3d453db7b8) 0
+ QGradient (0x0x7f3d45458180) 0
+
+Class QRadialGradient
+ size=64 align=8
+ base size=64 base align=8
+QRadialGradient (0x0x7f3d453db820) 0
+ QGradient (0x0x7f3d454581e0) 0
+
+Class QConicalGradient
+ size=64 align=8
+ base size=64 base align=8
+QConicalGradient (0x0x7f3d453db888) 0
+ QGradient (0x0x7f3d45458240) 0
+
+Class QPen
+ size=8 align=8
+ base size=8 base align=8
+QPen (0x0x7f3d454582a0) 0
+
+Class QTextOption::Tab
+ size=16 align=8
+ base size=14 base align=8
+QTextOption::Tab (0x0x7f3d454ff4e0) 0
+
+Class QTextOption
+ size=32 align=8
+ base size=32 base align=8
+QTextOption (0x0x7f3d454ff480) 0
+
+Class QTextLength
+ size=16 align=8
+ base size=16 base align=8
+QTextLength (0x0x7f3d454ffc60) 0
+
+Class QTextFormat
+ size=16 align=8
+ base size=12 base align=8
+QTextFormat (0x0x7f3d455873c0) 0
+
+Class QTextCharFormat
+ size=16 align=8
+ base size=12 base align=8
+QTextCharFormat (0x0x7f3d451fc958) 0
+ QTextFormat (0x0x7f3d45258240) 0
+
+Class QTextBlockFormat
+ size=16 align=8
+ base size=12 base align=8
+QTextBlockFormat (0x0x7f3d451fcb60) 0
+ QTextFormat (0x0x7f3d452584e0) 0
+
+Class QTextListFormat
+ size=16 align=8
+ base size=12 base align=8
+QTextListFormat (0x0x7f3d451fcdd0) 0
+ QTextFormat (0x0x7f3d45258780) 0
+
+Class QTextImageFormat
+ size=16 align=8
+ base size=12 base align=8
+QTextImageFormat (0x0x7f3d451fc0d0) 0
+ QTextCharFormat (0x0x7f3d451fc270) 0
+ QTextFormat (0x0x7f3d45258a20) 0
+
+Class QTextFrameFormat
+ size=16 align=8
+ base size=12 base align=8
+QTextFrameFormat (0x0x7f3d453170d0) 0
+ QTextFormat (0x0x7f3d45258cc0) 0
+
+Class QTextTableFormat
+ size=16 align=8
+ base size=12 base align=8
+QTextTableFormat (0x0x7f3d453172d8) 0
+ QTextFrameFormat (0x0x7f3d45317340) 0
+ QTextFormat (0x0x7f3d45258f60) 0
+
+Class QTextTableCellFormat
+ size=16 align=8
+ base size=12 base align=8
+QTextTableCellFormat (0x0x7f3d45317548) 0
+ QTextCharFormat (0x0x7f3d453175b0) 0
+ QTextFormat (0x0x7f3d453532a0) 0
+
+Class QFontDatabase
+ size=8 align=8
+ base size=8 base align=8
+QFontDatabase (0x0x7f3d45353540) 0
+
+Class QRawFont
+ size=8 align=8
+ base size=8 base align=8
+QRawFont (0x0x7f3d453535a0) 0
+
+Class QGlyphRun
+ size=8 align=8
+ base size=8 base align=8
+QGlyphRun (0x0x7f3d45353a80) 0
+
+Class QTextCursor
+ size=8 align=8
+ base size=8 base align=8
+QTextCursor (0x0x7f3d45353d80) 0
+
+Class QTextInlineObject
+ size=16 align=8
+ base size=16 base align=8
+QTextInlineObject (0x0x7f3d450440c0) 0
+
+Class QTextLayout::FormatRange
+ size=24 align=8
+ base size=24 base align=8
+QTextLayout::FormatRange (0x0x7f3d45044180) 0
+
+Class QTextLayout
+ size=8 align=8
+ base size=8 base align=8
+QTextLayout (0x0x7f3d45044120) 0
+
+Class QTextLine
+ size=16 align=8
+ base size=16 base align=8
+QTextLine (0x0x7f3d45044ba0) 0
+
+Vtable for QAbstractUndoItem
+QAbstractUndoItem::_ZTV17QAbstractUndoItem: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QAbstractUndoItem)
+16 (int (*)(...))__cxa_pure_virtual
+24 (int (*)(...))__cxa_pure_virtual
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+
+Class QAbstractUndoItem
+ size=8 align=8
+ base size=8 base align=8
+QAbstractUndoItem (0x0x7f3d45044c00) 0 nearly-empty
+ vptr=((& QAbstractUndoItem::_ZTV17QAbstractUndoItem) + 16u)
+
+Class QTextDocument::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTextDocument::QPrivateSignal (0x0x7f3d45044cc0) 0 empty
+
+Vtable for QTextDocument
+QTextDocument::_ZTV13QTextDocument: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QTextDocument)
+16 (int (*)(...))QTextDocument::metaObject
+24 (int (*)(...))QTextDocument::qt_metacast
+32 (int (*)(...))QTextDocument::qt_metacall
+40 (int (*)(...))QTextDocument::~QTextDocument
+48 (int (*)(...))QTextDocument::~QTextDocument
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QTextDocument::clear
+120 (int (*)(...))QTextDocument::createObject
+128 (int (*)(...))QTextDocument::loadResource
+
+Class QTextDocument
+ size=16 align=8
+ base size=16 base align=8
+QTextDocument (0x0x7f3d450a08f0) 0
+ vptr=((& QTextDocument::_ZTV13QTextDocument) + 16u)
+ QObject (0x0x7f3d45044c60) 0
+ primary-for QTextDocument (0x0x7f3d450a08f0)
+
+Class QPalette::Data
+ size=4 align=4
+ base size=4 base align=4
+QPalette::Data (0x0x7f3d45044f00) 0
+
+Class QPalette
+ size=16 align=8
+ base size=12 base align=8
+QPalette (0x0x7f3d45044ea0) 0
+
+Class QAbstractTextDocumentLayout::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractTextDocumentLayout::QPrivateSignal (0x0x7f3d44dfb000) 0 empty
+
+Class QAbstractTextDocumentLayout::Selection
+ size=24 align=8
+ base size=24 base align=8
+QAbstractTextDocumentLayout::Selection (0x0x7f3d44dfb060) 0
+
+Class QAbstractTextDocumentLayout::PaintContext
+ size=64 align=8
+ base size=64 base align=8
+QAbstractTextDocumentLayout::PaintContext (0x0x7f3d44dfb0c0) 0
+
+Vtable for QAbstractTextDocumentLayout
+QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout: 24u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QAbstractTextDocumentLayout)
+16 (int (*)(...))QAbstractTextDocumentLayout::metaObject
+24 (int (*)(...))QAbstractTextDocumentLayout::qt_metacast
+32 (int (*)(...))QAbstractTextDocumentLayout::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))__cxa_pure_virtual
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))QAbstractTextDocumentLayout::resizeInlineObject
+176 (int (*)(...))QAbstractTextDocumentLayout::positionInlineObject
+184 (int (*)(...))QAbstractTextDocumentLayout::drawInlineObject
+
+Class QAbstractTextDocumentLayout
+ size=16 align=8
+ base size=16 base align=8
+QAbstractTextDocumentLayout (0x0x7f3d44dd6618) 0
+ vptr=((& QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout) + 16u)
+ QObject (0x0x7f3d451b6f60) 0
+ primary-for QAbstractTextDocumentLayout (0x0x7f3d44dd6618)
+
+Vtable for QTextObjectInterface
+QTextObjectInterface::_ZTV20QTextObjectInterface: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QTextObjectInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+
+Class QTextObjectInterface
+ size=8 align=8
+ base size=8 base align=8
+QTextObjectInterface (0x0x7f3d44dfb660) 0 nearly-empty
+ vptr=((& QTextObjectInterface::_ZTV20QTextObjectInterface) + 16u)
+
+Class QAccessible::State
+ size=8 align=8
+ base size=5 base align=8
+QAccessible::State (0x0x7f3d44dfb780) 0
+
+Vtable for QAccessible::ActivationObserver
+QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN11QAccessible18ActivationObserverE)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessible::ActivationObserver
+ size=8 align=8
+ base size=8 base align=8
+QAccessible::ActivationObserver (0x0x7f3d44dfb7e0) 0 nearly-empty
+ vptr=((& QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE) + 16u)
+
+Class QAccessible
+ size=1 align=1
+ base size=0 base align=1
+QAccessible (0x0x7f3d44dfb720) 0 empty
+
+Vtable for QAccessibleInterface
+QAccessibleInterface::_ZTV20QAccessibleInterface: 23u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QAccessibleInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))QAccessibleInterface::window
+56 (int (*)(...))QAccessibleInterface::relations
+64 (int (*)(...))QAccessibleInterface::focusChild
+72 (int (*)(...))__cxa_pure_virtual
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))__cxa_pure_virtual
+96 (int (*)(...))__cxa_pure_virtual
+104 (int (*)(...))__cxa_pure_virtual
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))QAccessibleInterface::foregroundColor
+160 (int (*)(...))QAccessibleInterface::backgroundColor
+168 (int (*)(...))QAccessibleInterface::virtual_hook
+176 (int (*)(...))QAccessibleInterface::interface_cast
+
+Class QAccessibleInterface
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleInterface (0x0x7f3d44dfb9c0) 0 nearly-empty
+ vptr=((& QAccessibleInterface::_ZTV20QAccessibleInterface) + 16u)
+
+Vtable for QAccessibleTextInterface
+QAccessibleTextInterface::_ZTV24QAccessibleTextInterface: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QAccessibleTextInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+72 (int (*)(...))__cxa_pure_virtual
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))__cxa_pure_virtual
+96 (int (*)(...))QAccessibleTextInterface::textBeforeOffset
+104 (int (*)(...))QAccessibleTextInterface::textAfterOffset
+112 (int (*)(...))QAccessibleTextInterface::textAtOffset
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleTextInterface
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleTextInterface (0x0x7f3d44dfba20) 0 nearly-empty
+ vptr=((& QAccessibleTextInterface::_ZTV24QAccessibleTextInterface) + 16u)
+
+Vtable for QAccessibleEditableTextInterface
+QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI32QAccessibleEditableTextInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleEditableTextInterface
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleEditableTextInterface (0x0x7f3d44dfba80) 0 nearly-empty
+ vptr=((& QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface) + 16u)
+
+Vtable for QAccessibleValueInterface
+QAccessibleValueInterface::_ZTV25QAccessibleValueInterface: 9u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI25QAccessibleValueInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleValueInterface
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleValueInterface (0x0x7f3d44dfbae0) 0 nearly-empty
+ vptr=((& QAccessibleValueInterface::_ZTV25QAccessibleValueInterface) + 16u)
+
+Vtable for QAccessibleTableCellInterface
+QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface: 12u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI29QAccessibleTableCellInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+72 (int (*)(...))__cxa_pure_virtual
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleTableCellInterface
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleTableCellInterface (0x0x7f3d44dfbb40) 0 nearly-empty
+ vptr=((& QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface) + 16u)
+
+Vtable for QAccessibleTableInterface
+QAccessibleTableInterface::_ZTV25QAccessibleTableInterface: 24u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI25QAccessibleTableInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+72 (int (*)(...))__cxa_pure_virtual
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))__cxa_pure_virtual
+96 (int (*)(...))__cxa_pure_virtual
+104 (int (*)(...))__cxa_pure_virtual
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))__cxa_pure_virtual
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))__cxa_pure_virtual
+176 (int (*)(...))__cxa_pure_virtual
+184 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleTableInterface
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleTableInterface (0x0x7f3d44dfbba0) 0 nearly-empty
+ vptr=((& QAccessibleTableInterface::_ZTV25QAccessibleTableInterface) + 16u)
+
+Vtable for QAccessibleActionInterface
+QAccessibleActionInterface::_ZTV26QAccessibleActionInterface: 9u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QAccessibleActionInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))QAccessibleActionInterface::localizedActionName
+48 (int (*)(...))QAccessibleActionInterface::localizedActionDescription
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleActionInterface
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleActionInterface (0x0x7f3d44dfbc00) 0 nearly-empty
+ vptr=((& QAccessibleActionInterface::_ZTV26QAccessibleActionInterface) + 16u)
+
+Vtable for QAccessibleImageInterface
+QAccessibleImageInterface::_ZTV25QAccessibleImageInterface: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI25QAccessibleImageInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleImageInterface
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleImageInterface (0x0x7f3d44dfbc60) 0 nearly-empty
+ vptr=((& QAccessibleImageInterface::_ZTV25QAccessibleImageInterface) + 16u)
+
+Vtable for QAccessibleEvent
+QAccessibleEvent::_ZTV16QAccessibleEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QAccessibleEvent)
+16 (int (*)(...))QAccessibleEvent::~QAccessibleEvent
+24 (int (*)(...))QAccessibleEvent::~QAccessibleEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleEvent
+ size=32 align=8
+ base size=28 base align=8
+QAccessibleEvent (0x0x7f3d44dfbcc0) 0
+ vptr=((& QAccessibleEvent::_ZTV16QAccessibleEvent) + 16u)
+
+Vtable for QAccessibleStateChangeEvent
+QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QAccessibleStateChangeEvent)
+16 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent
+24 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleStateChangeEvent
+ size=40 align=8
+ base size=40 base align=8
+QAccessibleStateChangeEvent (0x0x7f3d44efb068) 0
+ vptr=((& QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent) + 16u)
+ QAccessibleEvent (0x0x7f3d44ef5240) 0
+ primary-for QAccessibleStateChangeEvent (0x0x7f3d44efb068)
+
+Vtable for QAccessibleTextCursorEvent
+QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QAccessibleTextCursorEvent)
+16 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent
+24 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleTextCursorEvent
+ size=32 align=8
+ base size=32 base align=8
+QAccessibleTextCursorEvent (0x0x7f3d44efb0d0) 0
+ vptr=((& QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent) + 16u)
+ QAccessibleEvent (0x0x7f3d44ef52a0) 0
+ primary-for QAccessibleTextCursorEvent (0x0x7f3d44efb0d0)
+
+Vtable for QAccessibleTextSelectionEvent
+QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI29QAccessibleTextSelectionEvent)
+16 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent
+24 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleTextSelectionEvent
+ size=40 align=8
+ base size=40 base align=8
+QAccessibleTextSelectionEvent (0x0x7f3d44efb138) 0
+ vptr=((& QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent) + 16u)
+ QAccessibleTextCursorEvent (0x0x7f3d44efb1a0) 0
+ primary-for QAccessibleTextSelectionEvent (0x0x7f3d44efb138)
+ QAccessibleEvent (0x0x7f3d44ef5300) 0
+ primary-for QAccessibleTextCursorEvent (0x0x7f3d44efb1a0)
+
+Vtable for QAccessibleTextInsertEvent
+QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QAccessibleTextInsertEvent)
+16 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent
+24 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleTextInsertEvent
+ size=48 align=8
+ base size=48 base align=8
+QAccessibleTextInsertEvent (0x0x7f3d44efb208) 0
+ vptr=((& QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent) + 16u)
+ QAccessibleTextCursorEvent (0x0x7f3d44efb270) 0
+ primary-for QAccessibleTextInsertEvent (0x0x7f3d44efb208)
+ QAccessibleEvent (0x0x7f3d44ef5360) 0
+ primary-for QAccessibleTextCursorEvent (0x0x7f3d44efb270)
+
+Vtable for QAccessibleTextRemoveEvent
+QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QAccessibleTextRemoveEvent)
+16 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent
+24 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleTextRemoveEvent
+ size=48 align=8
+ base size=48 base align=8
+QAccessibleTextRemoveEvent (0x0x7f3d44efb2d8) 0
+ vptr=((& QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent) + 16u)
+ QAccessibleTextCursorEvent (0x0x7f3d44efb340) 0
+ primary-for QAccessibleTextRemoveEvent (0x0x7f3d44efb2d8)
+ QAccessibleEvent (0x0x7f3d44ef53c0) 0
+ primary-for QAccessibleTextCursorEvent (0x0x7f3d44efb340)
+
+Vtable for QAccessibleTextUpdateEvent
+QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QAccessibleTextUpdateEvent)
+16 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent
+24 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleTextUpdateEvent
+ size=56 align=8
+ base size=56 base align=8
+QAccessibleTextUpdateEvent (0x0x7f3d44efb3a8) 0
+ vptr=((& QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent) + 16u)
+ QAccessibleTextCursorEvent (0x0x7f3d44efb410) 0
+ primary-for QAccessibleTextUpdateEvent (0x0x7f3d44efb3a8)
+ QAccessibleEvent (0x0x7f3d44ef5420) 0
+ primary-for QAccessibleTextCursorEvent (0x0x7f3d44efb410)
+
+Vtable for QAccessibleValueChangeEvent
+QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QAccessibleValueChangeEvent)
+16 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent
+24 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleValueChangeEvent
+ size=48 align=8
+ base size=48 base align=8
+QAccessibleValueChangeEvent (0x0x7f3d44efb478) 0
+ vptr=((& QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent) + 16u)
+ QAccessibleEvent (0x0x7f3d44ef5480) 0
+ primary-for QAccessibleValueChangeEvent (0x0x7f3d44efb478)
+
+Vtable for QAccessibleTableModelChangeEvent
+QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI32QAccessibleTableModelChangeEvent)
+16 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent
+24 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleTableModelChangeEvent
+ size=48 align=8
+ base size=48 base align=8
+QAccessibleTableModelChangeEvent (0x0x7f3d44efb4e0) 0
+ vptr=((& QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent) + 16u)
+ QAccessibleEvent (0x0x7f3d44ef54e0) 0
+ primary-for QAccessibleTableModelChangeEvent (0x0x7f3d44efb4e0)
+
+Vtable for QAccessibleBridge
+QAccessibleBridge::_ZTV17QAccessibleBridge: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QAccessibleBridge)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleBridge
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleBridge (0x0x7f3d44ef55a0) 0 nearly-empty
+ vptr=((& QAccessibleBridge::_ZTV17QAccessibleBridge) + 16u)
+
+Class QAccessibleBridgePlugin::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAccessibleBridgePlugin::QPrivateSignal (0x0x7f3d44ef5660) 0 empty
+
+Vtable for QAccessibleBridgePlugin
+QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QAccessibleBridgePlugin)
+16 (int (*)(...))QAccessibleBridgePlugin::metaObject
+24 (int (*)(...))QAccessibleBridgePlugin::qt_metacast
+32 (int (*)(...))QAccessibleBridgePlugin::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleBridgePlugin
+ size=16 align=8
+ base size=16 base align=8
+QAccessibleBridgePlugin (0x0x7f3d44efb548) 0
+ vptr=((& QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin) + 16u)
+ QObject (0x0x7f3d44ef5600) 0
+ primary-for QAccessibleBridgePlugin (0x0x7f3d44efb548)
+
+Vtable for QAccessibleObject
+QAccessibleObject::_ZTV17QAccessibleObject: 23u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QAccessibleObject)
+16 0u
+24 0u
+32 (int (*)(...))QAccessibleObject::isValid
+40 (int (*)(...))QAccessibleObject::object
+48 (int (*)(...))QAccessibleInterface::window
+56 (int (*)(...))QAccessibleInterface::relations
+64 (int (*)(...))QAccessibleInterface::focusChild
+72 (int (*)(...))QAccessibleObject::childAt
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))__cxa_pure_virtual
+96 (int (*)(...))__cxa_pure_virtual
+104 (int (*)(...))__cxa_pure_virtual
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))QAccessibleObject::setText
+128 (int (*)(...))QAccessibleObject::rect
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))QAccessibleInterface::foregroundColor
+160 (int (*)(...))QAccessibleInterface::backgroundColor
+168 (int (*)(...))QAccessibleInterface::virtual_hook
+176 (int (*)(...))QAccessibleInterface::interface_cast
+
+Class QAccessibleObject
+ size=16 align=8
+ base size=16 base align=8
+QAccessibleObject (0x0x7f3d44efb5b0) 0
+ vptr=((& QAccessibleObject::_ZTV17QAccessibleObject) + 16u)
+ QAccessibleInterface (0x0x7f3d44ef56c0) 0 nearly-empty
+ primary-for QAccessibleObject (0x0x7f3d44efb5b0)
+
+Vtable for QAccessibleApplication
+QAccessibleApplication::_ZTV22QAccessibleApplication: 23u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI22QAccessibleApplication)
+16 (int (*)(...))QAccessibleApplication::~QAccessibleApplication
+24 (int (*)(...))QAccessibleApplication::~QAccessibleApplication
+32 (int (*)(...))QAccessibleObject::isValid
+40 (int (*)(...))QAccessibleObject::object
+48 (int (*)(...))QAccessibleApplication::window
+56 (int (*)(...))QAccessibleInterface::relations
+64 (int (*)(...))QAccessibleApplication::focusChild
+72 (int (*)(...))QAccessibleObject::childAt
+80 (int (*)(...))QAccessibleApplication::parent
+88 (int (*)(...))QAccessibleApplication::child
+96 (int (*)(...))QAccessibleApplication::childCount
+104 (int (*)(...))QAccessibleApplication::indexOfChild
+112 (int (*)(...))QAccessibleApplication::text
+120 (int (*)(...))QAccessibleObject::setText
+128 (int (*)(...))QAccessibleObject::rect
+136 (int (*)(...))QAccessibleApplication::role
+144 (int (*)(...))QAccessibleApplication::state
+152 (int (*)(...))QAccessibleInterface::foregroundColor
+160 (int (*)(...))QAccessibleInterface::backgroundColor
+168 (int (*)(...))QAccessibleInterface::virtual_hook
+176 (int (*)(...))QAccessibleInterface::interface_cast
+
+Class QAccessibleApplication
+ size=16 align=8
+ base size=16 base align=8
+QAccessibleApplication (0x0x7f3d44efb618) 0
+ vptr=((& QAccessibleApplication::_ZTV22QAccessibleApplication) + 16u)
+ QAccessibleObject (0x0x7f3d44efb680) 0
+ primary-for QAccessibleApplication (0x0x7f3d44efb618)
+ QAccessibleInterface (0x0x7f3d44ef5720) 0 nearly-empty
+ primary-for QAccessibleObject (0x0x7f3d44efb680)
+
+Class QAccessiblePlugin::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAccessiblePlugin::QPrivateSignal (0x0x7f3d44ef57e0) 0 empty
+
+Vtable for QAccessiblePlugin
+QAccessiblePlugin::_ZTV17QAccessiblePlugin: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QAccessiblePlugin)
+16 (int (*)(...))QAccessiblePlugin::metaObject
+24 (int (*)(...))QAccessiblePlugin::qt_metacast
+32 (int (*)(...))QAccessiblePlugin::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessiblePlugin
+ size=16 align=8
+ base size=16 base align=8
+QAccessiblePlugin (0x0x7f3d44efb6e8) 0
+ vptr=((& QAccessiblePlugin::_ZTV17QAccessiblePlugin) + 16u)
+ QObject (0x0x7f3d44ef5780) 0
+ primary-for QAccessiblePlugin (0x0x7f3d44efb6e8)
+
+Class QSurfaceFormat
+ size=8 align=8
+ base size=8 base align=8
+QSurfaceFormat (0x0x7f3d44ef5840) 0
+
+Vtable for QSurface
+QSurface::_ZTV8QSurface: 8u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QSurface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))__cxa_pure_virtual
+
+Class QSurface
+ size=24 align=8
+ base size=24 base align=8
+QSurface (0x0x7f3d44ef5a20) 0
+ vptr=((& QSurface::_ZTV8QSurface) + 16u)
+
+Class QIcon
+ size=8 align=8
+ base size=8 base align=8
+QIcon (0x0x7f3d44ef5ba0) 0
+
+Class QCursor
+ size=8 align=8
+ base size=8 base align=8
+QCursor (0x0x7f3d44cb4f60) 0
+
+Class QWindow::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QWindow::QPrivateSignal (0x0x7f3d44d675a0) 0 empty
+
+Vtable for QWindow
+QWindow::_ZTV7QWindow: 45u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QWindow)
+16 (int (*)(...))QWindow::metaObject
+24 (int (*)(...))QWindow::qt_metacast
+32 (int (*)(...))QWindow::qt_metacall
+40 (int (*)(...))QWindow::~QWindow
+48 (int (*)(...))QWindow::~QWindow
+56 (int (*)(...))QWindow::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWindow::surfaceType
+120 (int (*)(...))QWindow::format
+128 (int (*)(...))QWindow::size
+136 (int (*)(...))QWindow::accessibleRoot
+144 (int (*)(...))QWindow::focusObject
+152 (int (*)(...))QWindow::exposeEvent
+160 (int (*)(...))QWindow::resizeEvent
+168 (int (*)(...))QWindow::moveEvent
+176 (int (*)(...))QWindow::focusInEvent
+184 (int (*)(...))QWindow::focusOutEvent
+192 (int (*)(...))QWindow::showEvent
+200 (int (*)(...))QWindow::hideEvent
+208 (int (*)(...))QWindow::keyPressEvent
+216 (int (*)(...))QWindow::keyReleaseEvent
+224 (int (*)(...))QWindow::mousePressEvent
+232 (int (*)(...))QWindow::mouseReleaseEvent
+240 (int (*)(...))QWindow::mouseDoubleClickEvent
+248 (int (*)(...))QWindow::mouseMoveEvent
+256 (int (*)(...))QWindow::wheelEvent
+264 (int (*)(...))QWindow::touchEvent
+272 (int (*)(...))QWindow::tabletEvent
+280 (int (*)(...))QWindow::nativeEvent
+288 (int (*)(...))QWindow::surfaceHandle
+296 (int (*)(...))-16
+304 (int (*)(...))(& _ZTI7QWindow)
+312 (int (*)(...))QWindow::_ZThn16_N7QWindowD1Ev
+320 (int (*)(...))QWindow::_ZThn16_N7QWindowD0Ev
+328 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv
+336 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv
+344 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv
+352 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv
+
+Class QWindow
+ size=40 align=8
+ base size=40 base align=8
+QWindow (0x0x7f3d44d73150) 0
+ vptr=((& QWindow::_ZTV7QWindow) + 16u)
+ QObject (0x0x7f3d44d674e0) 0
+ primary-for QWindow (0x0x7f3d44d73150)
+ QSurface (0x0x7f3d44d67540) 16
+ vptr=((& QWindow::_ZTV7QWindow) + 312u)
+
+Class QBackingStore
+ size=8 align=8
+ base size=8 base align=8
+QBackingStore (0x0x7f3d44d676c0) 0
+
+Vtable for QBitmap
+QBitmap::_ZTV7QBitmap: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QBitmap)
+16 (int (*)(...))QBitmap::~QBitmap
+24 (int (*)(...))QBitmap::~QBitmap
+32 (int (*)(...))QPixmap::devType
+40 (int (*)(...))QPixmap::paintEngine
+48 (int (*)(...))QPixmap::metric
+56 (int (*)(...))QPaintDevice::initPainter
+64 (int (*)(...))QPaintDevice::redirected
+72 (int (*)(...))QPaintDevice::sharedPainter
+
+Class QBitmap
+ size=32 align=8
+ base size=32 base align=8
+QBitmap (0x0x7f3d44d5f750) 0
+ vptr=((& QBitmap::_ZTV7QBitmap) + 16u)
+ QPixmap (0x0x7f3d44d5f7b8) 0
+ primary-for QBitmap (0x0x7f3d44d5f750)
+ QPaintDevice (0x0x7f3d44d67780) 0
+ primary-for QPixmap (0x0x7f3d44d5f7b8)
+
+Class QClipboard::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QClipboard::QPrivateSignal (0x0x7f3d44d67ae0) 0 empty
+
+Vtable for QClipboard
+QClipboard::_ZTV10QClipboard: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QClipboard)
+16 (int (*)(...))QClipboard::metaObject
+24 (int (*)(...))QClipboard::qt_metacast
+32 (int (*)(...))QClipboard::qt_metacall
+40 (int (*)(...))QClipboard::~QClipboard
+48 (int (*)(...))QClipboard::~QClipboard
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QClipboard
+ size=16 align=8
+ base size=16 base align=8
+QClipboard (0x0x7f3d44d5fa28) 0
+ vptr=((& QClipboard::_ZTV10QClipboard) + 16u)
+ QObject (0x0x7f3d44d67a80) 0
+ primary-for QClipboard (0x0x7f3d44d5fa28)
+
+Class QDesktopServices
+ size=1 align=1
+ base size=0 base align=1
+QDesktopServices (0x0x7f3d44d67b40) 0 empty
+
+Class QDrag::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDrag::QPrivateSignal (0x0x7f3d44d67c00) 0 empty
+
+Vtable for QDrag
+QDrag::_ZTV5QDrag: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI5QDrag)
+16 (int (*)(...))QDrag::metaObject
+24 (int (*)(...))QDrag::qt_metacast
+32 (int (*)(...))QDrag::qt_metacall
+40 (int (*)(...))QDrag::~QDrag
+48 (int (*)(...))QDrag::~QDrag
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QDrag
+ size=16 align=8
+ base size=16 base align=8
+QDrag (0x0x7f3d44d5fa90) 0
+ vptr=((& QDrag::_ZTV5QDrag) + 16u)
+ QObject (0x0x7f3d44d67ba0) 0
+ primary-for QDrag (0x0x7f3d44d5fa90)
+
+Class QFontInfo
+ size=8 align=8
+ base size=8 base align=8
+QFontInfo (0x0x7f3d44d67c60) 0
+
+Class QFontMetrics
+ size=8 align=8
+ base size=8 base align=8
+QFontMetrics (0x0x7f3d44d67f00) 0
+
+Class QFontMetricsF
+ size=8 align=8
+ base size=8 base align=8
+QFontMetricsF (0x0x7f3d44a36240) 0
+
+Class QGenericPlugin::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGenericPlugin::QPrivateSignal (0x0x7f3d44b069c0) 0 empty
+
+Vtable for QGenericPlugin
+QGenericPlugin::_ZTV14QGenericPlugin: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QGenericPlugin)
+16 (int (*)(...))QGenericPlugin::metaObject
+24 (int (*)(...))QGenericPlugin::qt_metacast
+32 (int (*)(...))QGenericPlugin::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+
+Class QGenericPlugin
+ size=16 align=8
+ base size=16 base align=8
+QGenericPlugin (0x0x7f3d44a6a5b0) 0
+ vptr=((& QGenericPlugin::_ZTV14QGenericPlugin) + 16u)
+ QObject (0x0x7f3d44b06960) 0
+ primary-for QGenericPlugin (0x0x7f3d44a6a5b0)
+
+Class QGenericPluginFactory
+ size=1 align=1
+ base size=0 base align=1
+QGenericPluginFactory (0x0x7f3d44b06a20) 0 empty
+
+Class QInputMethod::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QInputMethod::QPrivateSignal (0x0x7f3d44b06ae0) 0 empty
+
+Vtable for QInputMethod
+QInputMethod::_ZTV12QInputMethod: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QInputMethod)
+16 (int (*)(...))QInputMethod::metaObject
+24 (int (*)(...))QInputMethod::qt_metacast
+32 (int (*)(...))QInputMethod::qt_metacall
+40 (int (*)(...))QInputMethod::~QInputMethod
+48 (int (*)(...))QInputMethod::~QInputMethod
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QInputMethod
+ size=16 align=8
+ base size=16 base align=8
+QInputMethod (0x0x7f3d44a6a618) 0
+ vptr=((& QInputMethod::_ZTV12QInputMethod) + 16u)
+ QObject (0x0x7f3d44b06a80) 0
+ primary-for QInputMethod (0x0x7f3d44a6a618)
+
+Class QGuiApplication::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGuiApplication::QPrivateSignal (0x0x7f3d44b06ba0) 0 empty
+
+Vtable for QGuiApplication
+QGuiApplication::_ZTV15QGuiApplication: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QGuiApplication)
+16 (int (*)(...))QGuiApplication::metaObject
+24 (int (*)(...))QGuiApplication::qt_metacast
+32 (int (*)(...))QGuiApplication::qt_metacall
+40 (int (*)(...))QGuiApplication::~QGuiApplication
+48 (int (*)(...))QGuiApplication::~QGuiApplication
+56 (int (*)(...))QGuiApplication::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGuiApplication::notify
+120 (int (*)(...))QGuiApplication::compressEvent
+
+Class QGuiApplication
+ size=16 align=8
+ base size=16 base align=8
+QGuiApplication (0x0x7f3d44a6a680) 0
+ vptr=((& QGuiApplication::_ZTV15QGuiApplication) + 16u)
+ QCoreApplication (0x0x7f3d44a6a6e8) 0
+ primary-for QGuiApplication (0x0x7f3d44a6a680)
+ QObject (0x0x7f3d44b06b40) 0
+ primary-for QCoreApplication (0x0x7f3d44a6a6e8)
+
+Class QIconEngine::AvailableSizesArgument
+ size=16 align=8
+ base size=16 base align=8
+QIconEngine::AvailableSizesArgument (0x0x7f3d447ec120) 0
+
+Class QIconEngine::ScaledPixmapArgument
+ size=56 align=8
+ base size=56 base align=8
+QIconEngine::ScaledPixmapArgument (0x0x7f3d447ec2a0) 0
+
+Vtable for QIconEngine
+QIconEngine::_ZTV11QIconEngine: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QIconEngine)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))QIconEngine::actualSize
+48 (int (*)(...))QIconEngine::pixmap
+56 (int (*)(...))QIconEngine::addPixmap
+64 (int (*)(...))QIconEngine::addFile
+72 (int (*)(...))QIconEngine::key
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))QIconEngine::read
+96 (int (*)(...))QIconEngine::write
+104 (int (*)(...))QIconEngine::availableSizes
+112 (int (*)(...))QIconEngine::iconName
+120 (int (*)(...))QIconEngine::virtual_hook
+
+Class QIconEngine
+ size=8 align=8
+ base size=8 base align=8
+QIconEngine (0x0x7f3d447ec0c0) 0 nearly-empty
+ vptr=((& QIconEngine::_ZTV11QIconEngine) + 16u)
+
+Class QIconEnginePlugin::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QIconEnginePlugin::QPrivateSignal (0x0x7f3d447ec360) 0 empty
+
+Vtable for QIconEnginePlugin
+QIconEnginePlugin::_ZTV17QIconEnginePlugin: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QIconEnginePlugin)
+16 (int (*)(...))QIconEnginePlugin::metaObject
+24 (int (*)(...))QIconEnginePlugin::qt_metacast
+32 (int (*)(...))QIconEnginePlugin::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+
+Class QIconEnginePlugin
+ size=16 align=8
+ base size=16 base align=8
+QIconEnginePlugin (0x0x7f3d44a6ad00) 0
+ vptr=((& QIconEnginePlugin::_ZTV17QIconEnginePlugin) + 16u)
+ QObject (0x0x7f3d447ec300) 0
+ primary-for QIconEnginePlugin (0x0x7f3d44a6ad00)
+
+Vtable for QImageIOHandler
+QImageIOHandler::_ZTV15QImageIOHandler: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QImageIOHandler)
+16 0u
+24 0u
+32 (int (*)(...))QImageIOHandler::name
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))QImageIOHandler::write
+64 (int (*)(...))QImageIOHandler::option
+72 (int (*)(...))QImageIOHandler::setOption
+80 (int (*)(...))QImageIOHandler::supportsOption
+88 (int (*)(...))QImageIOHandler::jumpToNextImage
+96 (int (*)(...))QImageIOHandler::jumpToImage
+104 (int (*)(...))QImageIOHandler::loopCount
+112 (int (*)(...))QImageIOHandler::imageCount
+120 (int (*)(...))QImageIOHandler::nextImageDelay
+128 (int (*)(...))QImageIOHandler::currentImageNumber
+136 (int (*)(...))QImageIOHandler::currentImageRect
+
+Class QImageIOHandler
+ size=16 align=8
+ base size=16 base align=8
+QImageIOHandler (0x0x7f3d447ec3c0) 0
+ vptr=((& QImageIOHandler::_ZTV15QImageIOHandler) + 16u)
+
+Class QImageIOPlugin::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QImageIOPlugin::QPrivateSignal (0x0x7f3d447ec540) 0 empty
+
+Vtable for QImageIOPlugin
+QImageIOPlugin::_ZTV14QImageIOPlugin: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QImageIOPlugin)
+16 (int (*)(...))QImageIOPlugin::metaObject
+24 (int (*)(...))QImageIOPlugin::qt_metacast
+32 (int (*)(...))QImageIOPlugin::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+
+Class QImageIOPlugin
+ size=16 align=8
+ base size=16 base align=8
+QImageIOPlugin (0x0x7f3d44a6ad68) 0
+ vptr=((& QImageIOPlugin::_ZTV14QImageIOPlugin) + 16u)
+ QObject (0x0x7f3d447ec4e0) 0
+ primary-for QImageIOPlugin (0x0x7f3d44a6ad68)
+
+Class QImageReader
+ size=8 align=8
+ base size=8 base align=8
+QImageReader (0x0x7f3d447ec720) 0
+
+Class QImageWriter
+ size=8 align=8
+ base size=8 base align=8
+QImageWriter (0x0x7f3d447ec780) 0
+
+Class QVector3D
+ size=12 align=4
+ base size=12 base align=4
+QVector3D (0x0x7f3d447ec7e0) 0
+
+Class QVector4D
+ size=16 align=4
+ base size=16 base align=4
+QVector4D (0x0x7f3d447eca80) 0
+
+Class QQuaternion
+ size=16 align=4
+ base size=16 base align=4
+QQuaternion (0x0x7f3d447ecd20) 0
+
+Class QMatrix4x4
+ size=68 align=4
+ base size=68 base align=4
+QMatrix4x4 (0x0x7f3d4499e360) 0
+
+Class QMovie::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QMovie::QPrivateSignal (0x0x7f3d4499eae0) 0 empty
+
+Vtable for QMovie
+QMovie::_ZTV6QMovie: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QMovie)
+16 (int (*)(...))QMovie::metaObject
+24 (int (*)(...))QMovie::qt_metacast
+32 (int (*)(...))QMovie::qt_metacall
+40 (int (*)(...))QMovie::~QMovie
+48 (int (*)(...))QMovie::~QMovie
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QMovie
+ size=16 align=8
+ base size=16 base align=8
+QMovie (0x0x7f3d44918f08) 0
+ vptr=((& QMovie::_ZTV6QMovie) + 16u)
+ QObject (0x0x7f3d4499ea80) 0
+ primary-for QMovie (0x0x7f3d44918f08)
+
+Class QOffscreenSurface::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOffscreenSurface::QPrivateSignal (0x0x7f3d4499ec00) 0 empty
+
+Vtable for QOffscreenSurface
+QOffscreenSurface::_ZTV17QOffscreenSurface: 26u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QOffscreenSurface)
+16 (int (*)(...))QOffscreenSurface::metaObject
+24 (int (*)(...))QOffscreenSurface::qt_metacast
+32 (int (*)(...))QOffscreenSurface::qt_metacall
+40 (int (*)(...))QOffscreenSurface::~QOffscreenSurface
+48 (int (*)(...))QOffscreenSurface::~QOffscreenSurface
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QOffscreenSurface::surfaceType
+120 (int (*)(...))QOffscreenSurface::format
+128 (int (*)(...))QOffscreenSurface::size
+136 (int (*)(...))QOffscreenSurface::surfaceHandle
+144 (int (*)(...))-16
+152 (int (*)(...))(& _ZTI17QOffscreenSurface)
+160 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD1Ev
+168 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD0Ev
+176 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface6formatEv
+184 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface13surfaceHandleEv
+192 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface11surfaceTypeEv
+200 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface4sizeEv
+
+Class QOffscreenSurface
+ size=40 align=8
+ base size=40 base align=8
+QOffscreenSurface (0x0x7f3d446e3e00) 0
+ vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 16u)
+ QObject (0x0x7f3d4499eb40) 0
+ primary-for QOffscreenSurface (0x0x7f3d446e3e00)
+ QSurface (0x0x7f3d4499eba0) 16
+ vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 160u)
+
+Class QOpenGLBuffer
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLBuffer (0x0x7f3d4499ecc0) 0
+
+Class QOpenGLVersionStatus
+ size=12 align=4
+ base size=12 base align=4
+QOpenGLVersionStatus (0x0x7f3d4499eea0) 0
+
+Class QOpenGLVersionFunctionsBackend
+ size=16 align=8
+ base size=12 base align=8
+QOpenGLVersionFunctionsBackend (0x0x7f3d440909c0) 0
+
+Class QOpenGLVersionFunctionsStorage
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLVersionFunctionsStorage (0x0x7f3d44090a20) 0
+
+Class QAbstractOpenGLFunctionsPrivate
+ size=16 align=8
+ base size=9 base align=8
+QAbstractOpenGLFunctionsPrivate (0x0x7f3d44090a80) 0
+
+Vtable for QAbstractOpenGLFunctions
+QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QAbstractOpenGLFunctions)
+16 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions
+24 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions
+32 (int (*)(...))QAbstractOpenGLFunctions::initializeOpenGLFunctions
+
+Class QAbstractOpenGLFunctions
+ size=16 align=8
+ base size=16 base align=8
+QAbstractOpenGLFunctions (0x0x7f3d44090ae0) 0
+ vptr=((& QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions) + 16u)
+
+Class QOpenGLFunctions_1_0_CoreBackend::Functions
+ size=384 align=8
+ base size=384 base align=8
+QOpenGLFunctions_1_0_CoreBackend::Functions (0x0x7f3d44090ba0) 0
+
+Class QOpenGLFunctions_1_0_CoreBackend
+ size=400 align=8
+ base size=400 base align=8
+QOpenGLFunctions_1_0_CoreBackend (0x0x7f3d440ab1a0) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d44090b40) 0
+
+Class QOpenGLFunctions_1_1_CoreBackend::Functions
+ size=128 align=8
+ base size=128 base align=8
+QOpenGLFunctions_1_1_CoreBackend::Functions (0x0x7f3d44090cc0) 0
+
+Class QOpenGLFunctions_1_1_CoreBackend
+ size=144 align=8
+ base size=144 base align=8
+QOpenGLFunctions_1_1_CoreBackend (0x0x7f3d440ab208) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d44090c60) 0
+
+Class QOpenGLFunctions_1_2_CoreBackend::Functions
+ size=48 align=8
+ base size=48 base align=8
+QOpenGLFunctions_1_2_CoreBackend::Functions (0x0x7f3d44090de0) 0
+
+Class QOpenGLFunctions_1_2_CoreBackend
+ size=64 align=8
+ base size=64 base align=8
+QOpenGLFunctions_1_2_CoreBackend (0x0x7f3d440ab270) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d44090d80) 0
+
+Class QOpenGLFunctions_1_3_CoreBackend::Functions
+ size=72 align=8
+ base size=72 base align=8
+QOpenGLFunctions_1_3_CoreBackend::Functions (0x0x7f3d44090f00) 0
+
+Class QOpenGLFunctions_1_3_CoreBackend
+ size=88 align=8
+ base size=88 base align=8
+QOpenGLFunctions_1_3_CoreBackend (0x0x7f3d440ab2d8) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d44090ea0) 0
+
+Class QOpenGLFunctions_1_4_CoreBackend::Functions
+ size=56 align=8
+ base size=56 base align=8
+QOpenGLFunctions_1_4_CoreBackend::Functions (0x0x7f3d440f00c0) 0
+
+Class QOpenGLFunctions_1_4_CoreBackend
+ size=72 align=8
+ base size=72 base align=8
+QOpenGLFunctions_1_4_CoreBackend (0x0x7f3d440ab340) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d440f0060) 0
+
+Class QOpenGLFunctions_1_5_CoreBackend::Functions
+ size=152 align=8
+ base size=152 base align=8
+QOpenGLFunctions_1_5_CoreBackend::Functions (0x0x7f3d440f01e0) 0
+
+Class QOpenGLFunctions_1_5_CoreBackend
+ size=168 align=8
+ base size=168 base align=8
+QOpenGLFunctions_1_5_CoreBackend (0x0x7f3d440ab3a8) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d440f0180) 0
+
+Class QOpenGLFunctions_2_0_CoreBackend::Functions
+ size=744 align=8
+ base size=744 base align=8
+QOpenGLFunctions_2_0_CoreBackend::Functions (0x0x7f3d440f0300) 0
+
+Class QOpenGLFunctions_2_0_CoreBackend
+ size=760 align=8
+ base size=760 base align=8
+QOpenGLFunctions_2_0_CoreBackend (0x0x7f3d440ab410) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d440f02a0) 0
+
+Class QOpenGLFunctions_2_1_CoreBackend::Functions
+ size=48 align=8
+ base size=48 base align=8
+QOpenGLFunctions_2_1_CoreBackend::Functions (0x0x7f3d440f0420) 0
+
+Class QOpenGLFunctions_2_1_CoreBackend
+ size=64 align=8
+ base size=64 base align=8
+QOpenGLFunctions_2_1_CoreBackend (0x0x7f3d440ab478) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d440f03c0) 0
+
+Class QOpenGLFunctions_3_0_CoreBackend::Functions
+ size=672 align=8
+ base size=672 base align=8
+QOpenGLFunctions_3_0_CoreBackend::Functions (0x0x7f3d440f0540) 0
+
+Class QOpenGLFunctions_3_0_CoreBackend
+ size=688 align=8
+ base size=688 base align=8
+QOpenGLFunctions_3_0_CoreBackend (0x0x7f3d440ab4e0) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d440f04e0) 0
+
+Class QOpenGLFunctions_3_1_CoreBackend::Functions
+ size=96 align=8
+ base size=96 base align=8
+QOpenGLFunctions_3_1_CoreBackend::Functions (0x0x7f3d440f0660) 0
+
+Class QOpenGLFunctions_3_1_CoreBackend
+ size=112 align=8
+ base size=112 base align=8
+QOpenGLFunctions_3_1_CoreBackend (0x0x7f3d440ab548) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d440f0600) 0
+
+Class QOpenGLFunctions_3_2_CoreBackend::Functions
+ size=152 align=8
+ base size=152 base align=8
+QOpenGLFunctions_3_2_CoreBackend::Functions (0x0x7f3d440f0780) 0
+
+Class QOpenGLFunctions_3_2_CoreBackend
+ size=168 align=8
+ base size=168 base align=8
+QOpenGLFunctions_3_2_CoreBackend (0x0x7f3d440ab5b0) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d440f0720) 0
+
+Class QOpenGLFunctions_3_3_CoreBackend::Functions
+ size=464 align=8
+ base size=464 base align=8
+QOpenGLFunctions_3_3_CoreBackend::Functions (0x0x7f3d440f08a0) 0
+
+Class QOpenGLFunctions_3_3_CoreBackend
+ size=480 align=8
+ base size=480 base align=8
+QOpenGLFunctions_3_3_CoreBackend (0x0x7f3d440ab618) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d440f0840) 0
+
+Class QOpenGLFunctions_4_0_CoreBackend::Functions
+ size=368 align=8
+ base size=368 base align=8
+QOpenGLFunctions_4_0_CoreBackend::Functions (0x0x7f3d440f09c0) 0
+
+Class QOpenGLFunctions_4_0_CoreBackend
+ size=384 align=8
+ base size=384 base align=8
+QOpenGLFunctions_4_0_CoreBackend (0x0x7f3d440ab680) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d440f0960) 0
+
+Class QOpenGLFunctions_4_1_CoreBackend::Functions
+ size=704 align=8
+ base size=704 base align=8
+QOpenGLFunctions_4_1_CoreBackend::Functions (0x0x7f3d440f0ae0) 0
+
+Class QOpenGLFunctions_4_1_CoreBackend
+ size=720 align=8
+ base size=720 base align=8
+QOpenGLFunctions_4_1_CoreBackend (0x0x7f3d440ab6e8) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d440f0a80) 0
+
+Class QOpenGLFunctions_4_2_CoreBackend::Functions
+ size=96 align=8
+ base size=96 base align=8
+QOpenGLFunctions_4_2_CoreBackend::Functions (0x0x7f3d440f0c00) 0
+
+Class QOpenGLFunctions_4_2_CoreBackend
+ size=112 align=8
+ base size=112 base align=8
+QOpenGLFunctions_4_2_CoreBackend (0x0x7f3d440ab750) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d440f0ba0) 0
+
+Class QOpenGLFunctions_4_3_CoreBackend::Functions
+ size=344 align=8
+ base size=344 base align=8
+QOpenGLFunctions_4_3_CoreBackend::Functions (0x0x7f3d440f0d20) 0
+
+Class QOpenGLFunctions_4_3_CoreBackend
+ size=360 align=8
+ base size=360 base align=8
+QOpenGLFunctions_4_3_CoreBackend (0x0x7f3d440ab7b8) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d440f0cc0) 0
+
+Class QOpenGLFunctions_4_4_CoreBackend::Functions
+ size=72 align=8
+ base size=72 base align=8
+QOpenGLFunctions_4_4_CoreBackend::Functions (0x0x7f3d440f0e40) 0
+
+Class QOpenGLFunctions_4_4_CoreBackend
+ size=88 align=8
+ base size=88 base align=8
+QOpenGLFunctions_4_4_CoreBackend (0x0x7f3d440ab820) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d440f0de0) 0
+
+Class QOpenGLFunctions_4_5_CoreBackend::Functions
+ size=848 align=8
+ base size=848 base align=8
+QOpenGLFunctions_4_5_CoreBackend::Functions (0x0x7f3d43de9000) 0
+
+Class QOpenGLFunctions_4_5_CoreBackend
+ size=864 align=8
+ base size=864 base align=8
+QOpenGLFunctions_4_5_CoreBackend (0x0x7f3d440ab888) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d440f0f60) 0
+
+Class QOpenGLFunctions_1_0_DeprecatedBackend::Functions
+ size=2064 align=8
+ base size=2064 base align=8
+QOpenGLFunctions_1_0_DeprecatedBackend::Functions (0x0x7f3d43de9120) 0
+
+Class QOpenGLFunctions_1_0_DeprecatedBackend
+ size=2080 align=8
+ base size=2080 base align=8
+QOpenGLFunctions_1_0_DeprecatedBackend (0x0x7f3d440ab8f0) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d43de90c0) 0
+
+Class QOpenGLFunctions_1_1_DeprecatedBackend::Functions
+ size=136 align=8
+ base size=136 base align=8
+QOpenGLFunctions_1_1_DeprecatedBackend::Functions (0x0x7f3d43de9240) 0
+
+Class QOpenGLFunctions_1_1_DeprecatedBackend
+ size=152 align=8
+ base size=152 base align=8
+QOpenGLFunctions_1_1_DeprecatedBackend (0x0x7f3d440ab958) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d43de91e0) 0
+
+Class QOpenGLFunctions_1_2_DeprecatedBackend::Functions
+ size=256 align=8
+ base size=256 base align=8
+QOpenGLFunctions_1_2_DeprecatedBackend::Functions (0x0x7f3d43de9360) 0
+
+Class QOpenGLFunctions_1_2_DeprecatedBackend
+ size=272 align=8
+ base size=272 base align=8
+QOpenGLFunctions_1_2_DeprecatedBackend (0x0x7f3d440ab9c0) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d43de9300) 0
+
+Class QOpenGLFunctions_1_3_DeprecatedBackend::Functions
+ size=296 align=8
+ base size=296 base align=8
+QOpenGLFunctions_1_3_DeprecatedBackend::Functions (0x0x7f3d43de9480) 0
+
+Class QOpenGLFunctions_1_3_DeprecatedBackend
+ size=312 align=8
+ base size=312 base align=8
+QOpenGLFunctions_1_3_DeprecatedBackend (0x0x7f3d440aba28) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d43de9420) 0
+
+Class QOpenGLFunctions_1_4_DeprecatedBackend::Functions
+ size=304 align=8
+ base size=304 base align=8
+QOpenGLFunctions_1_4_DeprecatedBackend::Functions (0x0x7f3d43de95a0) 0
+
+Class QOpenGLFunctions_1_4_DeprecatedBackend
+ size=320 align=8
+ base size=320 base align=8
+QOpenGLFunctions_1_4_DeprecatedBackend (0x0x7f3d440aba90) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d43de9540) 0
+
+Class QOpenGLFunctions_2_0_DeprecatedBackend::Functions
+ size=288 align=8
+ base size=288 base align=8
+QOpenGLFunctions_2_0_DeprecatedBackend::Functions (0x0x7f3d43de96c0) 0
+
+Class QOpenGLFunctions_2_0_DeprecatedBackend
+ size=304 align=8
+ base size=304 base align=8
+QOpenGLFunctions_2_0_DeprecatedBackend (0x0x7f3d440abaf8) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d43de9660) 0
+
+Class QOpenGLFunctions_3_0_DeprecatedBackend::Functions
+ size=160 align=8
+ base size=160 base align=8
+QOpenGLFunctions_3_0_DeprecatedBackend::Functions (0x0x7f3d43de97e0) 0
+
+Class QOpenGLFunctions_3_0_DeprecatedBackend
+ size=176 align=8
+ base size=176 base align=8
+QOpenGLFunctions_3_0_DeprecatedBackend (0x0x7f3d440abb60) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d43de9780) 0
+
+Class QOpenGLFunctions_3_3_DeprecatedBackend::Functions
+ size=240 align=8
+ base size=240 base align=8
+QOpenGLFunctions_3_3_DeprecatedBackend::Functions (0x0x7f3d43de9900) 0
+
+Class QOpenGLFunctions_3_3_DeprecatedBackend
+ size=256 align=8
+ base size=256 base align=8
+QOpenGLFunctions_3_3_DeprecatedBackend (0x0x7f3d440abbc8) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d43de98a0) 0
+
+Class QOpenGLFunctions_4_5_DeprecatedBackend::Functions
+ size=96 align=8
+ base size=96 base align=8
+QOpenGLFunctions_4_5_DeprecatedBackend::Functions (0x0x7f3d43de9a20) 0
+
+Class QOpenGLFunctions_4_5_DeprecatedBackend
+ size=112 align=8
+ base size=112 base align=8
+QOpenGLFunctions_4_5_DeprecatedBackend (0x0x7f3d440abc30) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f3d43de99c0) 0
+
+Class QOpenGLVersionProfile
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLVersionProfile (0x0x7f3d43de9ae0) 0
+
+Class QOpenGLContextGroup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLContextGroup::QPrivateSignal (0x0x7f3d43ef64e0) 0 empty
+
+Vtable for QOpenGLContextGroup
+QOpenGLContextGroup::_ZTV19QOpenGLContextGroup: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QOpenGLContextGroup)
+16 (int (*)(...))QOpenGLContextGroup::metaObject
+24 (int (*)(...))QOpenGLContextGroup::qt_metacast
+32 (int (*)(...))QOpenGLContextGroup::qt_metacall
+40 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup
+48 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QOpenGLContextGroup
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLContextGroup (0x0x7f3d43eec680) 0
+ vptr=((& QOpenGLContextGroup::_ZTV19QOpenGLContextGroup) + 16u)
+ QObject (0x0x7f3d43ef6480) 0
+ primary-for QOpenGLContextGroup (0x0x7f3d43eec680)
+
+Class QOpenGLContext::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLContext::QPrivateSignal (0x0x7f3d43ef65a0) 0 empty
+
+Vtable for QOpenGLContext
+QOpenGLContext::_ZTV14QOpenGLContext: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QOpenGLContext)
+16 (int (*)(...))QOpenGLContext::metaObject
+24 (int (*)(...))QOpenGLContext::qt_metacast
+32 (int (*)(...))QOpenGLContext::qt_metacall
+40 (int (*)(...))QOpenGLContext::~QOpenGLContext
+48 (int (*)(...))QOpenGLContext::~QOpenGLContext
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QOpenGLContext
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLContext (0x0x7f3d43eec6e8) 0
+ vptr=((& QOpenGLContext::_ZTV14QOpenGLContext) + 16u)
+ QObject (0x0x7f3d43ef6540) 0
+ primary-for QOpenGLContext (0x0x7f3d43eec6e8)
+
+Class QOpenGLDebugMessage
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLDebugMessage (0x0x7f3d43ef6600) 0
+
+Class QOpenGLDebugLogger::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLDebugLogger::QPrivateSignal (0x0x7f3d43ef6de0) 0 empty
+
+Vtable for QOpenGLDebugLogger
+QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QOpenGLDebugLogger)
+16 (int (*)(...))QOpenGLDebugLogger::metaObject
+24 (int (*)(...))QOpenGLDebugLogger::qt_metacast
+32 (int (*)(...))QOpenGLDebugLogger::qt_metacall
+40 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger
+48 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QOpenGLDebugLogger
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLDebugLogger (0x0x7f3d43eecb60) 0
+ vptr=((& QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger) + 16u)
+ QObject (0x0x7f3d43ef6d80) 0
+ primary-for QOpenGLDebugLogger (0x0x7f3d43eecb60)
+
+Class QOpenGLFunctions
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLFunctions (0x0x7f3d43ef6f60) 0
+
+Class QOpenGLFunctionsPrivate::Functions
+ size=1152 align=8
+ base size=1152 base align=8
+QOpenGLFunctionsPrivate::Functions (0x0x7f3d43c441e0) 0
+
+Class QOpenGLFunctionsPrivate
+ size=1152 align=8
+ base size=1152 base align=8
+QOpenGLFunctionsPrivate (0x0x7f3d43c44180) 0
+
+Class QOpenGLExtraFunctions
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLExtraFunctions (0x0x7f3d43eecdd0) 0
+ QOpenGLFunctions (0x0x7f3d43d68900) 0
+
+Class QOpenGLExtraFunctionsPrivate::Functions
+ size=1728 align=8
+ base size=1728 base align=8
+QOpenGLExtraFunctionsPrivate::Functions (0x0x7f3d43d689c0) 0
+
+Class QOpenGLExtraFunctionsPrivate
+ size=2880 align=8
+ base size=2880 base align=8
+QOpenGLExtraFunctionsPrivate (0x0x7f3d43eece38) 0
+ QOpenGLFunctionsPrivate (0x0x7f3d43d68960) 0
+
+Vtable for QOpenGLFramebufferObject
+QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QOpenGLFramebufferObject)
+16 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject
+24 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject
+
+Class QOpenGLFramebufferObject
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLFramebufferObject (0x0x7f3d437cb0c0) 0
+ vptr=((& QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject) + 16u)
+
+Class QOpenGLFramebufferObjectFormat
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLFramebufferObjectFormat (0x0x7f3d437cb1e0) 0
+
+Vtable for QOpenGLPaintDevice
+QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QOpenGLPaintDevice)
+16 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice
+24 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice
+32 (int (*)(...))QOpenGLPaintDevice::devType
+40 (int (*)(...))QOpenGLPaintDevice::paintEngine
+48 (int (*)(...))QOpenGLPaintDevice::metric
+56 (int (*)(...))QPaintDevice::initPainter
+64 (int (*)(...))QPaintDevice::redirected
+72 (int (*)(...))QPaintDevice::sharedPainter
+80 (int (*)(...))QOpenGLPaintDevice::ensureActiveTarget
+
+Class QOpenGLPaintDevice
+ size=32 align=8
+ base size=32 base align=8
+QOpenGLPaintDevice (0x0x7f3d43b9a138) 0
+ vptr=((& QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice) + 16u)
+ QPaintDevice (0x0x7f3d437cb240) 0
+ primary-for QOpenGLPaintDevice (0x0x7f3d43b9a138)
+
+Class QOpenGLPixelTransferOptions
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLPixelTransferOptions (0x0x7f3d437cb360) 0
+
+Class QOpenGLShader::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLShader::QPrivateSignal (0x0x7f3d437cb6c0) 0 empty
+
+Vtable for QOpenGLShader
+QOpenGLShader::_ZTV13QOpenGLShader: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QOpenGLShader)
+16 (int (*)(...))QOpenGLShader::metaObject
+24 (int (*)(...))QOpenGLShader::qt_metacast
+32 (int (*)(...))QOpenGLShader::qt_metacall
+40 (int (*)(...))QOpenGLShader::~QOpenGLShader
+48 (int (*)(...))QOpenGLShader::~QOpenGLShader
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QOpenGLShader
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLShader (0x0x7f3d43b9a340) 0
+ vptr=((& QOpenGLShader::_ZTV13QOpenGLShader) + 16u)
+ QObject (0x0x7f3d437cb660) 0
+ primary-for QOpenGLShader (0x0x7f3d43b9a340)
+
+Class QOpenGLShaderProgram::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLShaderProgram::QPrivateSignal (0x0x7f3d437cb900) 0 empty
+
+Vtable for QOpenGLShaderProgram
+QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QOpenGLShaderProgram)
+16 (int (*)(...))QOpenGLShaderProgram::metaObject
+24 (int (*)(...))QOpenGLShaderProgram::qt_metacast
+32 (int (*)(...))QOpenGLShaderProgram::qt_metacall
+40 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram
+48 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QOpenGLShaderProgram::link
+
+Class QOpenGLShaderProgram
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLShaderProgram (0x0x7f3d43b9a478) 0
+ vptr=((& QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram) + 16u)
+ QObject (0x0x7f3d437cb8a0) 0
+ primary-for QOpenGLShaderProgram (0x0x7f3d43b9a478)
+
+Class QOpenGLTexture
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLTexture (0x0x7f3d437cb960) 0
+
+Class QOpenGLTextureBlitter
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLTextureBlitter (0x0x7f3d437cbc00) 0
+
+Class QOpenGLTimerQuery::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLTimerQuery::QPrivateSignal (0x0x7f3d437cbd80) 0 empty
+
+Vtable for QOpenGLTimerQuery
+QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QOpenGLTimerQuery)
+16 (int (*)(...))QOpenGLTimerQuery::metaObject
+24 (int (*)(...))QOpenGLTimerQuery::qt_metacast
+32 (int (*)(...))QOpenGLTimerQuery::qt_metacall
+40 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery
+48 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QOpenGLTimerQuery
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLTimerQuery (0x0x7f3d43b9a5b0) 0
+ vptr=((& QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery) + 16u)
+ QObject (0x0x7f3d437cbd20) 0
+ primary-for QOpenGLTimerQuery (0x0x7f3d43b9a5b0)
+
+Class QOpenGLTimeMonitor::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLTimeMonitor::QPrivateSignal (0x0x7f3d437cbe40) 0 empty
+
+Vtable for QOpenGLTimeMonitor
+QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QOpenGLTimeMonitor)
+16 (int (*)(...))QOpenGLTimeMonitor::metaObject
+24 (int (*)(...))QOpenGLTimeMonitor::qt_metacast
+32 (int (*)(...))QOpenGLTimeMonitor::qt_metacall
+40 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor
+48 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QOpenGLTimeMonitor
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLTimeMonitor (0x0x7f3d43b9a618) 0
+ vptr=((& QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor) + 16u)
+ QObject (0x0x7f3d437cbde0) 0
+ primary-for QOpenGLTimeMonitor (0x0x7f3d43b9a618)
+
+Class QOpenGLVertexArrayObject::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLVertexArrayObject::QPrivateSignal (0x0x7f3d437cbf00) 0 empty
+
+Class QOpenGLVertexArrayObject::Binder
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLVertexArrayObject::Binder (0x0x7f3d437cbf60) 0
+
+Vtable for QOpenGLVertexArrayObject
+QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QOpenGLVertexArrayObject)
+16 (int (*)(...))QOpenGLVertexArrayObject::metaObject
+24 (int (*)(...))QOpenGLVertexArrayObject::qt_metacast
+32 (int (*)(...))QOpenGLVertexArrayObject::qt_metacall
+40 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject
+48 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QOpenGLVertexArrayObject
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLVertexArrayObject (0x0x7f3d43b9a680) 0
+ vptr=((& QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject) + 16u)
+ QObject (0x0x7f3d437cbea0) 0
+ primary-for QOpenGLVertexArrayObject (0x0x7f3d43b9a680)
+
+Class QPaintDeviceWindow::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPaintDeviceWindow::QPrivateSignal (0x0x7f3d4399f120) 0 empty
+
+Vtable for QPaintDeviceWindow
+QPaintDeviceWindow::_ZTV18QPaintDeviceWindow: 58u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QPaintDeviceWindow)
+16 (int (*)(...))QPaintDeviceWindow::metaObject
+24 (int (*)(...))QPaintDeviceWindow::qt_metacast
+32 (int (*)(...))QPaintDeviceWindow::qt_metacall
+40 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow
+48 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow
+56 (int (*)(...))QPaintDeviceWindow::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWindow::surfaceType
+120 (int (*)(...))QWindow::format
+128 (int (*)(...))QWindow::size
+136 (int (*)(...))QWindow::accessibleRoot
+144 (int (*)(...))QWindow::focusObject
+152 (int (*)(...))QPaintDeviceWindow::exposeEvent
+160 (int (*)(...))QWindow::resizeEvent
+168 (int (*)(...))QWindow::moveEvent
+176 (int (*)(...))QWindow::focusInEvent
+184 (int (*)(...))QWindow::focusOutEvent
+192 (int (*)(...))QWindow::showEvent
+200 (int (*)(...))QWindow::hideEvent
+208 (int (*)(...))QWindow::keyPressEvent
+216 (int (*)(...))QWindow::keyReleaseEvent
+224 (int (*)(...))QWindow::mousePressEvent
+232 (int (*)(...))QWindow::mouseReleaseEvent
+240 (int (*)(...))QWindow::mouseDoubleClickEvent
+248 (int (*)(...))QWindow::mouseMoveEvent
+256 (int (*)(...))QWindow::wheelEvent
+264 (int (*)(...))QWindow::touchEvent
+272 (int (*)(...))QWindow::tabletEvent
+280 (int (*)(...))QWindow::nativeEvent
+288 (int (*)(...))QWindow::surfaceHandle
+296 (int (*)(...))QPaintDeviceWindow::paintEvent
+304 (int (*)(...))QPaintDeviceWindow::metric
+312 (int (*)(...))QPaintDeviceWindow::paintEngine
+320 (int (*)(...))-16
+328 (int (*)(...))(& _ZTI18QPaintDeviceWindow)
+336 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD1Ev
+344 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD0Ev
+352 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv
+360 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv
+368 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv
+376 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv
+384 (int (*)(...))-40
+392 (int (*)(...))(& _ZTI18QPaintDeviceWindow)
+400 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD1Ev
+408 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD0Ev
+416 (int (*)(...))QPaintDevice::devType
+424 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv
+432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow6metricEN12QPaintDevice17PaintDeviceMetricE
+440 (int (*)(...))QPaintDevice::initPainter
+448 (int (*)(...))QPaintDevice::redirected
+456 (int (*)(...))QPaintDevice::sharedPainter
+
+Class QPaintDeviceWindow
+ size=64 align=8
+ base size=64 base align=8
+QPaintDeviceWindow (0x0x7f3d43999850) 0
+ vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 16u)
+ QWindow (0x0x7f3d439998c0) 0
+ primary-for QPaintDeviceWindow (0x0x7f3d43999850)
+ QObject (0x0x7f3d4399f000) 0
+ primary-for QWindow (0x0x7f3d439998c0)
+ QSurface (0x0x7f3d4399f060) 16
+ vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 336u)
+ QPaintDevice (0x0x7f3d4399f0c0) 40
+ vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 400u)
+
+Class QOpenGLWindow::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLWindow::QPrivateSignal (0x0x7f3d4399f2a0) 0 empty
+
+Vtable for QOpenGLWindow
+QOpenGLWindow::_ZTV13QOpenGLWindow: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QOpenGLWindow)
+16 (int (*)(...))QOpenGLWindow::metaObject
+24 (int (*)(...))QOpenGLWindow::qt_metacast
+32 (int (*)(...))QOpenGLWindow::qt_metacall
+40 (int (*)(...))QOpenGLWindow::~QOpenGLWindow
+48 (int (*)(...))QOpenGLWindow::~QOpenGLWindow
+56 (int (*)(...))QPaintDeviceWindow::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWindow::surfaceType
+120 (int (*)(...))QWindow::format
+128 (int (*)(...))QWindow::size
+136 (int (*)(...))QWindow::accessibleRoot
+144 (int (*)(...))QWindow::focusObject
+152 (int (*)(...))QPaintDeviceWindow::exposeEvent
+160 (int (*)(...))QOpenGLWindow::resizeEvent
+168 (int (*)(...))QWindow::moveEvent
+176 (int (*)(...))QWindow::focusInEvent
+184 (int (*)(...))QWindow::focusOutEvent
+192 (int (*)(...))QWindow::showEvent
+200 (int (*)(...))QWindow::hideEvent
+208 (int (*)(...))QWindow::keyPressEvent
+216 (int (*)(...))QWindow::keyReleaseEvent
+224 (int (*)(...))QWindow::mousePressEvent
+232 (int (*)(...))QWindow::mouseReleaseEvent
+240 (int (*)(...))QWindow::mouseDoubleClickEvent
+248 (int (*)(...))QWindow::mouseMoveEvent
+256 (int (*)(...))QWindow::wheelEvent
+264 (int (*)(...))QWindow::touchEvent
+272 (int (*)(...))QWindow::tabletEvent
+280 (int (*)(...))QWindow::nativeEvent
+288 (int (*)(...))QWindow::surfaceHandle
+296 (int (*)(...))QOpenGLWindow::paintEvent
+304 (int (*)(...))QOpenGLWindow::metric
+312 (int (*)(...))QPaintDeviceWindow::paintEngine
+320 (int (*)(...))QOpenGLWindow::initializeGL
+328 (int (*)(...))QOpenGLWindow::resizeGL
+336 (int (*)(...))QOpenGLWindow::paintGL
+344 (int (*)(...))QOpenGLWindow::paintUnderGL
+352 (int (*)(...))QOpenGLWindow::paintOverGL
+360 (int (*)(...))QOpenGLWindow::redirected
+368 (int (*)(...))-16
+376 (int (*)(...))(& _ZTI13QOpenGLWindow)
+384 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD1Ev
+392 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD0Ev
+400 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv
+408 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv
+416 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv
+424 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv
+432 (int (*)(...))-40
+440 (int (*)(...))(& _ZTI13QOpenGLWindow)
+448 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD1Ev
+456 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD0Ev
+464 (int (*)(...))QPaintDevice::devType
+472 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv
+480 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QPaintDevice::initPainter
+496 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow10redirectedEP6QPoint
+504 (int (*)(...))QPaintDevice::sharedPainter
+
+Class QOpenGLWindow
+ size=64 align=8
+ base size=64 base align=8
+QOpenGLWindow (0x0x7f3d43b9a750) 0
+ vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 16u)
+ QPaintDeviceWindow (0x0x7f3d43999e00) 0
+ primary-for QOpenGLWindow (0x0x7f3d43b9a750)
+ QWindow (0x0x7f3d43999e70) 0
+ primary-for QPaintDeviceWindow (0x0x7f3d43999e00)
+ QObject (0x0x7f3d4399f180) 0
+ primary-for QWindow (0x0x7f3d43999e70)
+ QSurface (0x0x7f3d4399f1e0) 16
+ vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 384u)
+ QPaintDevice (0x0x7f3d4399f240) 40
+ vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 448u)
+
+Class QPageSize
+ size=8 align=8
+ base size=8 base align=8
+QPageSize (0x0x7f3d4399f300) 0
+
+Class QPageLayout
+ size=8 align=8
+ base size=8 base align=8
+QPageLayout (0x0x7f3d4399fcc0) 0
+
+Class QPagedPaintDevice::Margins
+ size=32 align=8
+ base size=32 base align=8
+QPagedPaintDevice::Margins (0x0x7f3d43646720) 0
+
+Vtable for QPagedPaintDevice
+QPagedPaintDevice::_ZTV17QPagedPaintDevice: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QPagedPaintDevice)
+16 0u
+24 0u
+32 (int (*)(...))QPaintDevice::devType
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))QPaintDevice::metric
+56 (int (*)(...))QPaintDevice::initPainter
+64 (int (*)(...))QPaintDevice::redirected
+72 (int (*)(...))QPaintDevice::sharedPainter
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))QPagedPaintDevice::setPageSize
+96 (int (*)(...))QPagedPaintDevice::setPageSizeMM
+104 (int (*)(...))QPagedPaintDevice::setMargins
+
+Class QPagedPaintDevice
+ size=32 align=8
+ base size=32 base align=8
+QPagedPaintDevice (0x0x7f3d43648478) 0
+ vptr=((& QPagedPaintDevice::_ZTV17QPagedPaintDevice) + 16u)
+ QPaintDevice (0x0x7f3d436466c0) 0
+ primary-for QPagedPaintDevice (0x0x7f3d43648478)
+
+Class QPainter::PixmapFragment
+ size=80 align=8
+ base size=80 base align=8
+QPainter::PixmapFragment (0x0x7f3d436467e0) 0
+
+Class QPainter
+ size=8 align=8
+ base size=8 base align=8
+QPainter (0x0x7f3d43646780) 0
+
+Class QTextItem
+ size=1 align=1
+ base size=0 base align=1
+QTextItem (0x0x7f3d437a6600) 0 empty
+
+Vtable for QPaintEngine
+QPaintEngine::_ZTV12QPaintEngine: 24u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QPaintEngine)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))QPaintEngine::drawRects
+64 (int (*)(...))QPaintEngine::drawRects
+72 (int (*)(...))QPaintEngine::drawLines
+80 (int (*)(...))QPaintEngine::drawLines
+88 (int (*)(...))QPaintEngine::drawEllipse
+96 (int (*)(...))QPaintEngine::drawEllipse
+104 (int (*)(...))QPaintEngine::drawPath
+112 (int (*)(...))QPaintEngine::drawPoints
+120 (int (*)(...))QPaintEngine::drawPoints
+128 (int (*)(...))QPaintEngine::drawPolygon
+136 (int (*)(...))QPaintEngine::drawPolygon
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))QPaintEngine::drawTextItem
+160 (int (*)(...))QPaintEngine::drawTiledPixmap
+168 (int (*)(...))QPaintEngine::drawImage
+176 (int (*)(...))QPaintEngine::coordinateOffset
+184 (int (*)(...))__cxa_pure_virtual
+
+Class QPaintEngine
+ size=32 align=8
+ base size=32 base align=8
+QPaintEngine (0x0x7f3d437a68a0) 0
+ vptr=((& QPaintEngine::_ZTV12QPaintEngine) + 16u)
+
+Class QPaintEngineState
+ size=4 align=4
+ base size=4 base align=4
+QPaintEngineState (0x0x7f3d437a6b40) 0
+
+Class QPdfWriter::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPdfWriter::QPrivateSignal (0x0x7f3d437a6f60) 0 empty
+
+Vtable for QPdfWriter
+QPdfWriter::_ZTV10QPdfWriter: 34u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QPdfWriter)
+16 (int (*)(...))QPdfWriter::metaObject
+24 (int (*)(...))QPdfWriter::qt_metacast
+32 (int (*)(...))QPdfWriter::qt_metacall
+40 (int (*)(...))QPdfWriter::~QPdfWriter
+48 (int (*)(...))QPdfWriter::~QPdfWriter
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QPdfWriter::newPage
+120 (int (*)(...))QPdfWriter::setPageSize
+128 (int (*)(...))QPdfWriter::setPageSizeMM
+136 (int (*)(...))QPdfWriter::setMargins
+144 (int (*)(...))QPdfWriter::paintEngine
+152 (int (*)(...))QPdfWriter::metric
+160 (int (*)(...))-16
+168 (int (*)(...))(& _ZTI10QPdfWriter)
+176 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD1Ev
+184 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD0Ev
+192 (int (*)(...))QPaintDevice::devType
+200 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter11paintEngineEv
+208 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter6metricEN12QPaintDevice17PaintDeviceMetricE
+216 (int (*)(...))QPaintDevice::initPainter
+224 (int (*)(...))QPaintDevice::redirected
+232 (int (*)(...))QPaintDevice::sharedPainter
+240 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter7newPageEv
+248 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter11setPageSizeEN17QPagedPaintDevice8PageSizeE
+256 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter13setPageSizeMMERK6QSizeF
+264 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter10setMarginsERKN17QPagedPaintDevice7MarginsE
+
+Class QPdfWriter
+ size=48 align=8
+ base size=48 base align=8
+QPdfWriter (0x0x7f3d43535230) 0
+ vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 16u)
+ QObject (0x0x7f3d437a6ea0) 0
+ primary-for QPdfWriter (0x0x7f3d43535230)
+ QPagedPaintDevice (0x0x7f3d434534e0) 16
+ vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 176u)
+ QPaintDevice (0x0x7f3d437a6f00) 16
+ primary-for QPagedPaintDevice (0x0x7f3d434534e0)
+
+Vtable for QPicture
+QPicture::_ZTV8QPicture: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QPicture)
+16 (int (*)(...))QPicture::~QPicture
+24 (int (*)(...))QPicture::~QPicture
+32 (int (*)(...))QPicture::devType
+40 (int (*)(...))QPicture::paintEngine
+48 (int (*)(...))QPicture::metric
+56 (int (*)(...))QPaintDevice::initPainter
+64 (int (*)(...))QPaintDevice::redirected
+72 (int (*)(...))QPaintDevice::sharedPainter
+80 (int (*)(...))QPicture::setData
+
+Class QPicture
+ size=32 align=8
+ base size=32 base align=8
+QPicture (0x0x7f3d43453548) 0
+ vptr=((& QPicture::_ZTV8QPicture) + 16u)
+ QPaintDevice (0x0x7f3d43555120) 0
+ primary-for QPicture (0x0x7f3d43453548)
+
+Class QPictureIO
+ size=8 align=8
+ base size=8 base align=8
+QPictureIO (0x0x7f3d43555420) 0
+
+Class QPictureFormatPlugin::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPictureFormatPlugin::QPrivateSignal (0x0x7f3d435554e0) 0 empty
+
+Vtable for QPictureFormatPlugin
+QPictureFormatPlugin::_ZTV20QPictureFormatPlugin: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QPictureFormatPlugin)
+16 (int (*)(...))QPictureFormatPlugin::metaObject
+24 (int (*)(...))QPictureFormatPlugin::qt_metacast
+32 (int (*)(...))QPictureFormatPlugin::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QPictureFormatPlugin::loadPicture
+120 (int (*)(...))QPictureFormatPlugin::savePicture
+128 (int (*)(...))__cxa_pure_virtual
+
+Class QPictureFormatPlugin
+ size=16 align=8
+ base size=16 base align=8
+QPictureFormatPlugin (0x0x7f3d43453750) 0
+ vptr=((& QPictureFormatPlugin::_ZTV20QPictureFormatPlugin) + 16u)
+ QObject (0x0x7f3d43555480) 0
+ primary-for QPictureFormatPlugin (0x0x7f3d43453750)
+
+Class QPixmapCache::Key
+ size=8 align=8
+ base size=8 base align=8
+QPixmapCache::Key (0x0x7f3d435555a0) 0
+
+Class QPixmapCache
+ size=1 align=1
+ base size=0 base align=1
+QPixmapCache (0x0x7f3d43555540) 0 empty
+
+Class QRasterWindow::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QRasterWindow::QPrivateSignal (0x0x7f3d43210720) 0 empty
+
+Vtable for QRasterWindow
+QRasterWindow::_ZTV13QRasterWindow: 59u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QRasterWindow)
+16 (int (*)(...))QRasterWindow::metaObject
+24 (int (*)(...))QRasterWindow::qt_metacast
+32 (int (*)(...))QRasterWindow::qt_metacall
+40 (int (*)(...))QRasterWindow::~QRasterWindow
+48 (int (*)(...))QRasterWindow::~QRasterWindow
+56 (int (*)(...))QPaintDeviceWindow::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWindow::surfaceType
+120 (int (*)(...))QWindow::format
+128 (int (*)(...))QWindow::size
+136 (int (*)(...))QWindow::accessibleRoot
+144 (int (*)(...))QWindow::focusObject
+152 (int (*)(...))QPaintDeviceWindow::exposeEvent
+160 (int (*)(...))QWindow::resizeEvent
+168 (int (*)(...))QWindow::moveEvent
+176 (int (*)(...))QWindow::focusInEvent
+184 (int (*)(...))QWindow::focusOutEvent
+192 (int (*)(...))QWindow::showEvent
+200 (int (*)(...))QWindow::hideEvent
+208 (int (*)(...))QWindow::keyPressEvent
+216 (int (*)(...))QWindow::keyReleaseEvent
+224 (int (*)(...))QWindow::mousePressEvent
+232 (int (*)(...))QWindow::mouseReleaseEvent
+240 (int (*)(...))QWindow::mouseDoubleClickEvent
+248 (int (*)(...))QWindow::mouseMoveEvent
+256 (int (*)(...))QWindow::wheelEvent
+264 (int (*)(...))QWindow::touchEvent
+272 (int (*)(...))QWindow::tabletEvent
+280 (int (*)(...))QWindow::nativeEvent
+288 (int (*)(...))QWindow::surfaceHandle
+296 (int (*)(...))QPaintDeviceWindow::paintEvent
+304 (int (*)(...))QRasterWindow::metric
+312 (int (*)(...))QPaintDeviceWindow::paintEngine
+320 (int (*)(...))QRasterWindow::redirected
+328 (int (*)(...))-16
+336 (int (*)(...))(& _ZTI13QRasterWindow)
+344 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD1Ev
+352 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD0Ev
+360 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv
+368 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv
+376 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv
+384 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv
+392 (int (*)(...))-40
+400 (int (*)(...))(& _ZTI13QRasterWindow)
+408 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD1Ev
+416 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD0Ev
+424 (int (*)(...))QPaintDevice::devType
+432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv
+440 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow6metricEN12QPaintDevice17PaintDeviceMetricE
+448 (int (*)(...))QPaintDevice::initPainter
+456 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow10redirectedEP6QPoint
+464 (int (*)(...))QPaintDevice::sharedPainter
+
+Class QRasterWindow
+ size=64 align=8
+ base size=64 base align=8
+QRasterWindow (0x0x7f3d43209e38) 0
+ vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 16u)
+ QPaintDeviceWindow (0x0x7f3d43216930) 0
+ primary-for QRasterWindow (0x0x7f3d43209e38)
+ QWindow (0x0x7f3d432169a0) 0
+ primary-for QPaintDeviceWindow (0x0x7f3d43216930)
+ QObject (0x0x7f3d43210600) 0
+ primary-for QWindow (0x0x7f3d432169a0)
+ QSurface (0x0x7f3d43210660) 16
+ vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 344u)
+ QPaintDevice (0x0x7f3d432106c0) 40
+ vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 408u)
+
+Class QScreen::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QScreen::QPrivateSignal (0x0x7f3d432107e0) 0 empty
+
+Vtable for QScreen
+QScreen::_ZTV7QScreen: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QScreen)
+16 (int (*)(...))QScreen::metaObject
+24 (int (*)(...))QScreen::qt_metacast
+32 (int (*)(...))QScreen::qt_metacall
+40 (int (*)(...))QScreen::~QScreen
+48 (int (*)(...))QScreen::~QScreen
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QScreen
+ size=16 align=8
+ base size=16 base align=8
+QScreen (0x0x7f3d43209f08) 0
+ vptr=((& QScreen::_ZTV7QScreen) + 16u)
+ QObject (0x0x7f3d43210780) 0
+ primary-for QScreen (0x0x7f3d43209f08)
+
+Class QSessionManager::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSessionManager::QPrivateSignal (0x0x7f3d432108a0) 0 empty
+
+Vtable for QSessionManager
+QSessionManager::_ZTV15QSessionManager: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QSessionManager)
+16 (int (*)(...))QSessionManager::metaObject
+24 (int (*)(...))QSessionManager::qt_metacast
+32 (int (*)(...))QSessionManager::qt_metacall
+40 (int (*)(...))QSessionManager::~QSessionManager
+48 (int (*)(...))QSessionManager::~QSessionManager
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QSessionManager
+ size=16 align=8
+ base size=16 base align=8
+QSessionManager (0x0x7f3d43209f70) 0
+ vptr=((& QSessionManager::_ZTV15QSessionManager) + 16u)
+ QObject (0x0x7f3d43210840) 0
+ primary-for QSessionManager (0x0x7f3d43209f70)
+
+Vtable for QStandardItem
+QStandardItem::_ZTV13QStandardItem: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QStandardItem)
+16 (int (*)(...))QStandardItem::~QStandardItem
+24 (int (*)(...))QStandardItem::~QStandardItem
+32 (int (*)(...))QStandardItem::data
+40 (int (*)(...))QStandardItem::setData
+48 (int (*)(...))QStandardItem::clone
+56 (int (*)(...))QStandardItem::type
+64 (int (*)(...))QStandardItem::read
+72 (int (*)(...))QStandardItem::write
+80 (int (*)(...))QStandardItem::operator<
+
+Class QStandardItem
+ size=16 align=8
+ base size=16 base align=8
+QStandardItem (0x0x7f3d43210900) 0
+ vptr=((& QStandardItem::_ZTV13QStandardItem) + 16u)
+
+Class QStandardItemModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QStandardItemModel::QPrivateSignal (0x0x7f3d43324060) 0 empty
+
+Vtable for QStandardItemModel
+QStandardItemModel::_ZTV18QStandardItemModel: 48u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QStandardItemModel)
+16 (int (*)(...))QStandardItemModel::metaObject
+24 (int (*)(...))QStandardItemModel::qt_metacast
+32 (int (*)(...))QStandardItemModel::qt_metacall
+40 (int (*)(...))QStandardItemModel::~QStandardItemModel
+48 (int (*)(...))QStandardItemModel::~QStandardItemModel
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QStandardItemModel::index
+120 (int (*)(...))QStandardItemModel::parent
+128 (int (*)(...))QStandardItemModel::sibling
+136 (int (*)(...))QStandardItemModel::rowCount
+144 (int (*)(...))QStandardItemModel::columnCount
+152 (int (*)(...))QStandardItemModel::hasChildren
+160 (int (*)(...))QStandardItemModel::data
+168 (int (*)(...))QStandardItemModel::setData
+176 (int (*)(...))QStandardItemModel::headerData
+184 (int (*)(...))QStandardItemModel::setHeaderData
+192 (int (*)(...))QStandardItemModel::itemData
+200 (int (*)(...))QStandardItemModel::setItemData
+208 (int (*)(...))QStandardItemModel::mimeTypes
+216 (int (*)(...))QStandardItemModel::mimeData
+224 (int (*)(...))QAbstractItemModel::canDropMimeData
+232 (int (*)(...))QStandardItemModel::dropMimeData
+240 (int (*)(...))QStandardItemModel::supportedDropActions
+248 (int (*)(...))QAbstractItemModel::supportedDragActions
+256 (int (*)(...))QStandardItemModel::insertRows
+264 (int (*)(...))QStandardItemModel::insertColumns
+272 (int (*)(...))QStandardItemModel::removeRows
+280 (int (*)(...))QStandardItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractItemModel::fetchMore
+312 (int (*)(...))QAbstractItemModel::canFetchMore
+320 (int (*)(...))QStandardItemModel::flags
+328 (int (*)(...))QStandardItemModel::sort
+336 (int (*)(...))QAbstractItemModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractItemModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractItemModel::submit
+376 (int (*)(...))QAbstractItemModel::revert
+
+Class QStandardItemModel
+ size=16 align=8
+ base size=16 base align=8
+QStandardItemModel (0x0x7f3d432a1618) 0
+ vptr=((& QStandardItemModel::_ZTV18QStandardItemModel) + 16u)
+ QAbstractItemModel (0x0x7f3d432a1680) 0
+ primary-for QStandardItemModel (0x0x7f3d432a1618)
+ QObject (0x0x7f3d43324000) 0
+ primary-for QAbstractItemModel (0x0x7f3d432a1680)
+
+Class QStaticText
+ size=8 align=8
+ base size=8 base align=8
+QStaticText (0x0x7f3d433240c0) 0
+
+Class QStyleHints::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QStyleHints::QPrivateSignal (0x0x7f3d43324540) 0 empty
+
+Vtable for QStyleHints
+QStyleHints::_ZTV11QStyleHints: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QStyleHints)
+16 (int (*)(...))QStyleHints::metaObject
+24 (int (*)(...))QStyleHints::qt_metacast
+32 (int (*)(...))QStyleHints::qt_metacall
+40 (int (*)(...))QStyleHints::~QStyleHints
+48 (int (*)(...))QStyleHints::~QStyleHints
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QStyleHints
+ size=16 align=8
+ base size=16 base align=8
+QStyleHints (0x0x7f3d432a1888) 0
+ vptr=((& QStyleHints::_ZTV11QStyleHints) + 16u)
+ QObject (0x0x7f3d433244e0) 0
+ primary-for QStyleHints (0x0x7f3d432a1888)
+
+Class QTextObject::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTextObject::QPrivateSignal (0x0x7f3d43324600) 0 empty
+
+Vtable for QTextObject
+QTextObject::_ZTV11QTextObject: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTextObject)
+16 (int (*)(...))QTextObject::metaObject
+24 (int (*)(...))QTextObject::qt_metacast
+32 (int (*)(...))QTextObject::qt_metacall
+40 (int (*)(...))QTextObject::~QTextObject
+48 (int (*)(...))QTextObject::~QTextObject
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QTextObject
+ size=16 align=8
+ base size=16 base align=8
+QTextObject (0x0x7f3d432a18f0) 0
+ vptr=((& QTextObject::_ZTV11QTextObject) + 16u)
+ QObject (0x0x7f3d433245a0) 0
+ primary-for QTextObject (0x0x7f3d432a18f0)
+
+Class QTextBlockGroup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTextBlockGroup::QPrivateSignal (0x0x7f3d433246c0) 0 empty
+
+Vtable for QTextBlockGroup
+QTextBlockGroup::_ZTV15QTextBlockGroup: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QTextBlockGroup)
+16 (int (*)(...))QTextBlockGroup::metaObject
+24 (int (*)(...))QTextBlockGroup::qt_metacast
+32 (int (*)(...))QTextBlockGroup::qt_metacall
+40 (int (*)(...))QTextBlockGroup::~QTextBlockGroup
+48 (int (*)(...))QTextBlockGroup::~QTextBlockGroup
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QTextBlockGroup::blockInserted
+120 (int (*)(...))QTextBlockGroup::blockRemoved
+128 (int (*)(...))QTextBlockGroup::blockFormatChanged
+
+Class QTextBlockGroup
+ size=16 align=8
+ base size=16 base align=8
+QTextBlockGroup (0x0x7f3d432a1958) 0
+ vptr=((& QTextBlockGroup::_ZTV15QTextBlockGroup) + 16u)
+ QTextObject (0x0x7f3d432a19c0) 0
+ primary-for QTextBlockGroup (0x0x7f3d432a1958)
+ QObject (0x0x7f3d43324660) 0
+ primary-for QTextObject (0x0x7f3d432a19c0)
+
+Vtable for QTextFrameLayoutData
+QTextFrameLayoutData::_ZTV20QTextFrameLayoutData: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QTextFrameLayoutData)
+16 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData
+24 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData
+
+Class QTextFrameLayoutData
+ size=8 align=8
+ base size=8 base align=8
+QTextFrameLayoutData (0x0x7f3d43324720) 0 nearly-empty
+ vptr=((& QTextFrameLayoutData::_ZTV20QTextFrameLayoutData) + 16u)
+
+Class QTextFrame::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTextFrame::QPrivateSignal (0x0x7f3d433247e0) 0 empty
+
+Class QTextFrame::iterator
+ size=32 align=8
+ base size=28 base align=8
+QTextFrame::iterator (0x0x7f3d43324840) 0
+
+Vtable for QTextFrame
+QTextFrame::_ZTV10QTextFrame: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTextFrame)
+16 (int (*)(...))QTextFrame::metaObject
+24 (int (*)(...))QTextFrame::qt_metacast
+32 (int (*)(...))QTextFrame::qt_metacall
+40 (int (*)(...))QTextFrame::~QTextFrame
+48 (int (*)(...))QTextFrame::~QTextFrame
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QTextFrame
+ size=16 align=8
+ base size=16 base align=8
+QTextFrame (0x0x7f3d432a1a28) 0
+ vptr=((& QTextFrame::_ZTV10QTextFrame) + 16u)
+ QTextObject (0x0x7f3d432a1a90) 0
+ primary-for QTextFrame (0x0x7f3d432a1a28)
+ QObject (0x0x7f3d43324780) 0
+ primary-for QTextObject (0x0x7f3d432a1a90)
+
+Vtable for QTextBlockUserData
+QTextBlockUserData::_ZTV18QTextBlockUserData: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QTextBlockUserData)
+16 (int (*)(...))QTextBlockUserData::~QTextBlockUserData
+24 (int (*)(...))QTextBlockUserData::~QTextBlockUserData
+
+Class QTextBlockUserData
+ size=8 align=8
+ base size=8 base align=8
+QTextBlockUserData (0x0x7f3d43324ae0) 0 nearly-empty
+ vptr=((& QTextBlockUserData::_ZTV18QTextBlockUserData) + 16u)
+
+Class QTextBlock::iterator
+ size=24 align=8
+ base size=20 base align=8
+QTextBlock::iterator (0x0x7f3d43324ba0) 0
+
+Class QTextBlock
+ size=16 align=8
+ base size=12 base align=8
+QTextBlock (0x0x7f3d43324b40) 0
+
+Class QTextFragment
+ size=16 align=8
+ base size=16 base align=8
+QTextFragment (0x0x7f3d430160c0) 0
+
+Class QSyntaxHighlighter::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSyntaxHighlighter::QPrivateSignal (0x0x7f3d430163c0) 0 empty
+
+Vtable for QSyntaxHighlighter
+QSyntaxHighlighter::_ZTV18QSyntaxHighlighter: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QSyntaxHighlighter)
+16 (int (*)(...))QSyntaxHighlighter::metaObject
+24 (int (*)(...))QSyntaxHighlighter::qt_metacast
+32 (int (*)(...))QSyntaxHighlighter::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+
+Class QSyntaxHighlighter
+ size=16 align=8
+ base size=16 base align=8
+QSyntaxHighlighter (0x0x7f3d4302e1a0) 0
+ vptr=((& QSyntaxHighlighter::_ZTV18QSyntaxHighlighter) + 16u)
+ QObject (0x0x7f3d43016360) 0
+ primary-for QSyntaxHighlighter (0x0x7f3d4302e1a0)
+
+Class QTextDocumentFragment
+ size=8 align=8
+ base size=8 base align=8
+QTextDocumentFragment (0x0x7f3d43016420) 0
+
+Class QTextDocumentWriter
+ size=8 align=8
+ base size=8 base align=8
+QTextDocumentWriter (0x0x7f3d43016480) 0
+
+Class QTextList::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTextList::QPrivateSignal (0x0x7f3d43016540) 0 empty
+
+Vtable for QTextList
+QTextList::_ZTV9QTextList: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QTextList)
+16 (int (*)(...))QTextList::metaObject
+24 (int (*)(...))QTextList::qt_metacast
+32 (int (*)(...))QTextList::qt_metacall
+40 (int (*)(...))QTextList::~QTextList
+48 (int (*)(...))QTextList::~QTextList
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QTextBlockGroup::blockInserted
+120 (int (*)(...))QTextBlockGroup::blockRemoved
+128 (int (*)(...))QTextBlockGroup::blockFormatChanged
+
+Class QTextList
+ size=16 align=8
+ base size=16 base align=8
+QTextList (0x0x7f3d4302e208) 0
+ vptr=((& QTextList::_ZTV9QTextList) + 16u)
+ QTextBlockGroup (0x0x7f3d4302e270) 0
+ primary-for QTextList (0x0x7f3d4302e208)
+ QTextObject (0x0x7f3d4302e2d8) 0
+ primary-for QTextBlockGroup (0x0x7f3d4302e270)
+ QObject (0x0x7f3d430164e0) 0
+ primary-for QTextObject (0x0x7f3d4302e2d8)
+
+Class QTextTableCell
+ size=16 align=8
+ base size=12 base align=8
+QTextTableCell (0x0x7f3d430165a0) 0
+
+Class QTextTable::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTextTable::QPrivateSignal (0x0x7f3d43016660) 0 empty
+
+Vtable for QTextTable
+QTextTable::_ZTV10QTextTable: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTextTable)
+16 (int (*)(...))QTextTable::metaObject
+24 (int (*)(...))QTextTable::qt_metacast
+32 (int (*)(...))QTextTable::qt_metacall
+40 (int (*)(...))QTextTable::~QTextTable
+48 (int (*)(...))QTextTable::~QTextTable
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QTextTable
+ size=16 align=8
+ base size=16 base align=8
+QTextTable (0x0x7f3d4302e340) 0
+ vptr=((& QTextTable::_ZTV10QTextTable) + 16u)
+ QTextFrame (0x0x7f3d4302e3a8) 0
+ primary-for QTextTable (0x0x7f3d4302e340)
+ QTextObject (0x0x7f3d4302e410) 0
+ primary-for QTextFrame (0x0x7f3d4302e3a8)
+ QObject (0x0x7f3d43016600) 0
+ primary-for QTextObject (0x0x7f3d4302e410)
+
+Class QValidator::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QValidator::QPrivateSignal (0x0x7f3d43016720) 0 empty
+
+Vtable for QValidator
+QValidator::_ZTV10QValidator: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QValidator)
+16 (int (*)(...))QValidator::metaObject
+24 (int (*)(...))QValidator::qt_metacast
+32 (int (*)(...))QValidator::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))QValidator::fixup
+
+Class QValidator
+ size=16 align=8
+ base size=16 base align=8
+QValidator (0x0x7f3d4302e478) 0
+ vptr=((& QValidator::_ZTV10QValidator) + 16u)
+ QObject (0x0x7f3d430166c0) 0
+ primary-for QValidator (0x0x7f3d4302e478)
+
+Class QIntValidator::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QIntValidator::QPrivateSignal (0x0x7f3d430167e0) 0 empty
+
+Vtable for QIntValidator
+QIntValidator::_ZTV13QIntValidator: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QIntValidator)
+16 (int (*)(...))QIntValidator::metaObject
+24 (int (*)(...))QIntValidator::qt_metacast
+32 (int (*)(...))QIntValidator::qt_metacall
+40 (int (*)(...))QIntValidator::~QIntValidator
+48 (int (*)(...))QIntValidator::~QIntValidator
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QIntValidator::validate
+120 (int (*)(...))QIntValidator::fixup
+128 (int (*)(...))QIntValidator::setRange
+
+Class QIntValidator
+ size=24 align=8
+ base size=24 base align=8
+QIntValidator (0x0x7f3d4302e4e0) 0
+ vptr=((& QIntValidator::_ZTV13QIntValidator) + 16u)
+ QValidator (0x0x7f3d4302e548) 0
+ primary-for QIntValidator (0x0x7f3d4302e4e0)
+ QObject (0x0x7f3d43016780) 0
+ primary-for QValidator (0x0x7f3d4302e548)
+
+Class QDoubleValidator::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDoubleValidator::QPrivateSignal (0x0x7f3d430168a0) 0 empty
+
+Vtable for QDoubleValidator
+QDoubleValidator::_ZTV16QDoubleValidator: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QDoubleValidator)
+16 (int (*)(...))QDoubleValidator::metaObject
+24 (int (*)(...))QDoubleValidator::qt_metacast
+32 (int (*)(...))QDoubleValidator::qt_metacall
+40 (int (*)(...))QDoubleValidator::~QDoubleValidator
+48 (int (*)(...))QDoubleValidator::~QDoubleValidator
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QDoubleValidator::validate
+120 (int (*)(...))QValidator::fixup
+128 (int (*)(...))QDoubleValidator::setRange
+
+Class QDoubleValidator
+ size=40 align=8
+ base size=36 base align=8
+QDoubleValidator (0x0x7f3d4302e5b0) 0
+ vptr=((& QDoubleValidator::_ZTV16QDoubleValidator) + 16u)
+ QValidator (0x0x7f3d4302e618) 0
+ primary-for QDoubleValidator (0x0x7f3d4302e5b0)
+ QObject (0x0x7f3d43016840) 0
+ primary-for QValidator (0x0x7f3d4302e618)
+
+Class QRegExpValidator::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QRegExpValidator::QPrivateSignal (0x0x7f3d430169c0) 0 empty
+
+Vtable for QRegExpValidator
+QRegExpValidator::_ZTV16QRegExpValidator: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QRegExpValidator)
+16 (int (*)(...))QRegExpValidator::metaObject
+24 (int (*)(...))QRegExpValidator::qt_metacast
+32 (int (*)(...))QRegExpValidator::qt_metacall
+40 (int (*)(...))QRegExpValidator::~QRegExpValidator
+48 (int (*)(...))QRegExpValidator::~QRegExpValidator
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QRegExpValidator::validate
+120 (int (*)(...))QValidator::fixup
+
+Class QRegExpValidator
+ size=24 align=8
+ base size=24 base align=8
+QRegExpValidator (0x0x7f3d4302e680) 0
+ vptr=((& QRegExpValidator::_ZTV16QRegExpValidator) + 16u)
+ QValidator (0x0x7f3d4302e6e8) 0
+ primary-for QRegExpValidator (0x0x7f3d4302e680)
+ QObject (0x0x7f3d43016960) 0
+ primary-for QValidator (0x0x7f3d4302e6e8)
+
+Class QRegularExpressionValidator::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QRegularExpressionValidator::QPrivateSignal (0x0x7f3d43016a80) 0 empty
+
+Vtable for QRegularExpressionValidator
+QRegularExpressionValidator::_ZTV27QRegularExpressionValidator: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QRegularExpressionValidator)
+16 (int (*)(...))QRegularExpressionValidator::metaObject
+24 (int (*)(...))QRegularExpressionValidator::qt_metacast
+32 (int (*)(...))QRegularExpressionValidator::qt_metacall
+40 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator
+48 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QRegularExpressionValidator::validate
+120 (int (*)(...))QValidator::fixup
+
+Class QRegularExpressionValidator
+ size=16 align=8
+ base size=16 base align=8
+QRegularExpressionValidator (0x0x7f3d4302e750) 0
+ vptr=((& QRegularExpressionValidator::_ZTV27QRegularExpressionValidator) + 16u)
+ QValidator (0x0x7f3d4302e7b8) 0
+ primary-for QRegularExpressionValidator (0x0x7f3d4302e750)
+ QObject (0x0x7f3d43016a20) 0
+ primary-for QValidator (0x0x7f3d4302e7b8)
+
+Class QNetworkRequest
+ size=8 align=8
+ base size=8 base align=8
+QNetworkRequest (0x0x7f3d43016ae0) 0
+
+Class QNetworkCacheMetaData
+ size=8 align=8
+ base size=8 base align=8
+QNetworkCacheMetaData (0x0x7f3d43114060) 0
+
+Class QAbstractNetworkCache::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractNetworkCache::QPrivateSignal (0x0x7f3d43114720) 0 empty
+
+Vtable for QAbstractNetworkCache
+QAbstractNetworkCache::_ZTV21QAbstractNetworkCache: 22u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QAbstractNetworkCache)
+16 (int (*)(...))QAbstractNetworkCache::metaObject
+24 (int (*)(...))QAbstractNetworkCache::qt_metacast
+32 (int (*)(...))QAbstractNetworkCache::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))__cxa_pure_virtual
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))__cxa_pure_virtual
+
+Class QAbstractNetworkCache
+ size=16 align=8
+ base size=16 base align=8
+QAbstractNetworkCache (0x0x7f3d43140000) 0
+ vptr=((& QAbstractNetworkCache::_ZTV21QAbstractNetworkCache) + 16u)
+ QObject (0x0x7f3d431146c0) 0
+ primary-for QAbstractNetworkCache (0x0x7f3d43140000)
+
+Class QAbstractSocket::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractSocket::QPrivateSignal (0x0x7f3d431147e0) 0 empty
+
+Vtable for QAbstractSocket
+QAbstractSocket::_ZTV15QAbstractSocket: 41u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QAbstractSocket)
+16 (int (*)(...))QAbstractSocket::metaObject
+24 (int (*)(...))QAbstractSocket::qt_metacast
+32 (int (*)(...))QAbstractSocket::qt_metacall
+40 (int (*)(...))QAbstractSocket::~QAbstractSocket
+48 (int (*)(...))QAbstractSocket::~QAbstractSocket
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAbstractSocket::isSequential
+120 (int (*)(...))QIODevice::open
+128 (int (*)(...))QAbstractSocket::close
+136 (int (*)(...))QIODevice::pos
+144 (int (*)(...))QIODevice::size
+152 (int (*)(...))QIODevice::seek
+160 (int (*)(...))QAbstractSocket::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QAbstractSocket::bytesAvailable
+184 (int (*)(...))QAbstractSocket::bytesToWrite
+192 (int (*)(...))QAbstractSocket::canReadLine
+200 (int (*)(...))QAbstractSocket::waitForReadyRead
+208 (int (*)(...))QAbstractSocket::waitForBytesWritten
+216 (int (*)(...))QAbstractSocket::readData
+224 (int (*)(...))QAbstractSocket::readLineData
+232 (int (*)(...))QAbstractSocket::writeData
+240 (int (*)(...))QAbstractSocket::resume
+248 (int (*)(...))QAbstractSocket::connectToHost
+256 (int (*)(...))QAbstractSocket::connectToHost
+264 (int (*)(...))QAbstractSocket::disconnectFromHost
+272 (int (*)(...))QAbstractSocket::setReadBufferSize
+280 (int (*)(...))QAbstractSocket::socketDescriptor
+288 (int (*)(...))QAbstractSocket::setSocketDescriptor
+296 (int (*)(...))QAbstractSocket::setSocketOption
+304 (int (*)(...))QAbstractSocket::socketOption
+312 (int (*)(...))QAbstractSocket::waitForConnected
+320 (int (*)(...))QAbstractSocket::waitForDisconnected
+
+Class QAbstractSocket
+ size=16 align=8
+ base size=16 base align=8
+QAbstractSocket (0x0x7f3d43140068) 0
+ vptr=((& QAbstractSocket::_ZTV15QAbstractSocket) + 16u)
+ QIODevice (0x0x7f3d431400d0) 0
+ primary-for QAbstractSocket (0x0x7f3d43140068)
+ QObject (0x0x7f3d43114780) 0
+ primary-for QIODevice (0x0x7f3d431400d0)
+
+Class QAuthenticator
+ size=8 align=8
+ base size=8 base align=8
+QAuthenticator (0x0x7f3d43114d80) 0
+
+Class QDnsDomainNameRecord
+ size=8 align=8
+ base size=8 base align=8
+QDnsDomainNameRecord (0x0x7f3d43114de0) 0
+
+Class QDnsHostAddressRecord
+ size=8 align=8
+ base size=8 base align=8
+QDnsHostAddressRecord (0x0x7f3d42e18120) 0
+
+Class QDnsMailExchangeRecord
+ size=8 align=8
+ base size=8 base align=8
+QDnsMailExchangeRecord (0x0x7f3d42e18420) 0
+
+Class QDnsServiceRecord
+ size=8 align=8
+ base size=8 base align=8
+QDnsServiceRecord (0x0x7f3d42e18720) 0
+
+Class QDnsTextRecord
+ size=8 align=8
+ base size=8 base align=8
+QDnsTextRecord (0x0x7f3d42e18a20) 0
+
+Class QDnsLookup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDnsLookup::QPrivateSignal (0x0x7f3d42e18d80) 0 empty
+
+Vtable for QDnsLookup
+QDnsLookup::_ZTV10QDnsLookup: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QDnsLookup)
+16 (int (*)(...))QDnsLookup::metaObject
+24 (int (*)(...))QDnsLookup::qt_metacast
+32 (int (*)(...))QDnsLookup::qt_metacall
+40 (int (*)(...))QDnsLookup::~QDnsLookup
+48 (int (*)(...))QDnsLookup::~QDnsLookup
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QDnsLookup
+ size=16 align=8
+ base size=16 base align=8
+QDnsLookup (0x0x7f3d43140af8) 0
+ vptr=((& QDnsLookup::_ZTV10QDnsLookup) + 16u)
+ QObject (0x0x7f3d42e18d20) 0
+ primary-for QDnsLookup (0x0x7f3d43140af8)
+
+Class QIPv6Address
+ size=16 align=1
+ base size=16 base align=1
+QIPv6Address (0x0x7f3d42e18de0) 0
+
+Class QHostAddress
+ size=8 align=8
+ base size=8 base align=8
+QHostAddress (0x0x7f3d42e18e40) 0
+
+Class QHostInfo
+ size=8 align=8
+ base size=8 base align=8
+QHostInfo (0x0x7f3d42ec3660) 0
+
+Class QHstsPolicy
+ size=8 align=8
+ base size=8 base align=8
+QHstsPolicy (0x0x7f3d42ec3b40) 0
+
+Class QHttpPart
+ size=8 align=8
+ base size=8 base align=8
+QHttpPart (0x0x7f3d42f91360) 0
+
+Class QHttpMultiPart::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QHttpMultiPart::QPrivateSignal (0x0x7f3d42f916c0) 0 empty
+
+Vtable for QHttpMultiPart
+QHttpMultiPart::_ZTV14QHttpMultiPart: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QHttpMultiPart)
+16 (int (*)(...))QHttpMultiPart::metaObject
+24 (int (*)(...))QHttpMultiPart::qt_metacast
+32 (int (*)(...))QHttpMultiPart::qt_metacall
+40 (int (*)(...))QHttpMultiPart::~QHttpMultiPart
+48 (int (*)(...))QHttpMultiPart::~QHttpMultiPart
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QHttpMultiPart
+ size=16 align=8
+ base size=16 base align=8
+QHttpMultiPart (0x0x7f3d42efed68) 0
+ vptr=((& QHttpMultiPart::_ZTV14QHttpMultiPart) + 16u)
+ QObject (0x0x7f3d42f91660) 0
+ primary-for QHttpMultiPart (0x0x7f3d42efed68)
+
+Class QLocalServer::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QLocalServer::QPrivateSignal (0x0x7f3d42f91780) 0 empty
+
+Vtable for QLocalServer
+QLocalServer::_ZTV12QLocalServer: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QLocalServer)
+16 (int (*)(...))QLocalServer::metaObject
+24 (int (*)(...))QLocalServer::qt_metacast
+32 (int (*)(...))QLocalServer::qt_metacall
+40 (int (*)(...))QLocalServer::~QLocalServer
+48 (int (*)(...))QLocalServer::~QLocalServer
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QLocalServer::hasPendingConnections
+120 (int (*)(...))QLocalServer::nextPendingConnection
+128 (int (*)(...))QLocalServer::incomingConnection
+
+Class QLocalServer
+ size=16 align=8
+ base size=16 base align=8
+QLocalServer (0x0x7f3d42efedd0) 0
+ vptr=((& QLocalServer::_ZTV12QLocalServer) + 16u)
+ QObject (0x0x7f3d42f91720) 0
+ primary-for QLocalServer (0x0x7f3d42efedd0)
+
+Class QLocalSocket::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QLocalSocket::QPrivateSignal (0x0x7f3d42f919c0) 0 empty
+
+Vtable for QLocalSocket
+QLocalSocket::_ZTV12QLocalSocket: 30u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QLocalSocket)
+16 (int (*)(...))QLocalSocket::metaObject
+24 (int (*)(...))QLocalSocket::qt_metacast
+32 (int (*)(...))QLocalSocket::qt_metacall
+40 (int (*)(...))QLocalSocket::~QLocalSocket
+48 (int (*)(...))QLocalSocket::~QLocalSocket
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QLocalSocket::isSequential
+120 (int (*)(...))QLocalSocket::open
+128 (int (*)(...))QLocalSocket::close
+136 (int (*)(...))QIODevice::pos
+144 (int (*)(...))QIODevice::size
+152 (int (*)(...))QIODevice::seek
+160 (int (*)(...))QIODevice::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QLocalSocket::bytesAvailable
+184 (int (*)(...))QLocalSocket::bytesToWrite
+192 (int (*)(...))QLocalSocket::canReadLine
+200 (int (*)(...))QLocalSocket::waitForReadyRead
+208 (int (*)(...))QLocalSocket::waitForBytesWritten
+216 (int (*)(...))QLocalSocket::readData
+224 (int (*)(...))QIODevice::readLineData
+232 (int (*)(...))QLocalSocket::writeData
+
+Class QLocalSocket
+ size=16 align=8
+ base size=16 base align=8
+QLocalSocket (0x0x7f3d42efef70) 0
+ vptr=((& QLocalSocket::_ZTV12QLocalSocket) + 16u)
+ QIODevice (0x0x7f3d42c0b000) 0
+ primary-for QLocalSocket (0x0x7f3d42efef70)
+ QObject (0x0x7f3d42f91960) 0
+ primary-for QIODevice (0x0x7f3d42c0b000)
+
+Class QTcpSocket::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTcpSocket::QPrivateSignal (0x0x7f3d42f91a80) 0 empty
+
+Vtable for QTcpSocket
+QTcpSocket::_ZTV10QTcpSocket: 41u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTcpSocket)
+16 (int (*)(...))QTcpSocket::metaObject
+24 (int (*)(...))QTcpSocket::qt_metacast
+32 (int (*)(...))QTcpSocket::qt_metacall
+40 (int (*)(...))QTcpSocket::~QTcpSocket
+48 (int (*)(...))QTcpSocket::~QTcpSocket
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAbstractSocket::isSequential
+120 (int (*)(...))QIODevice::open
+128 (int (*)(...))QAbstractSocket::close
+136 (int (*)(...))QIODevice::pos
+144 (int (*)(...))QIODevice::size
+152 (int (*)(...))QIODevice::seek
+160 (int (*)(...))QAbstractSocket::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QAbstractSocket::bytesAvailable
+184 (int (*)(...))QAbstractSocket::bytesToWrite
+192 (int (*)(...))QAbstractSocket::canReadLine
+200 (int (*)(...))QAbstractSocket::waitForReadyRead
+208 (int (*)(...))QAbstractSocket::waitForBytesWritten
+216 (int (*)(...))QAbstractSocket::readData
+224 (int (*)(...))QAbstractSocket::readLineData
+232 (int (*)(...))QAbstractSocket::writeData
+240 (int (*)(...))QAbstractSocket::resume
+248 (int (*)(...))QAbstractSocket::connectToHost
+256 (int (*)(...))QAbstractSocket::connectToHost
+264 (int (*)(...))QAbstractSocket::disconnectFromHost
+272 (int (*)(...))QAbstractSocket::setReadBufferSize
+280 (int (*)(...))QAbstractSocket::socketDescriptor
+288 (int (*)(...))QAbstractSocket::setSocketDescriptor
+296 (int (*)(...))QAbstractSocket::setSocketOption
+304 (int (*)(...))QAbstractSocket::socketOption
+312 (int (*)(...))QAbstractSocket::waitForConnected
+320 (int (*)(...))QAbstractSocket::waitForDisconnected
+
+Class QTcpSocket
+ size=16 align=8
+ base size=16 base align=8
+QTcpSocket (0x0x7f3d42c0b068) 0
+ vptr=((& QTcpSocket::_ZTV10QTcpSocket) + 16u)
+ QAbstractSocket (0x0x7f3d42c0b0d0) 0
+ primary-for QTcpSocket (0x0x7f3d42c0b068)
+ QIODevice (0x0x7f3d42c0b138) 0
+ primary-for QAbstractSocket (0x0x7f3d42c0b0d0)
+ QObject (0x0x7f3d42f91a20) 0
+ primary-for QIODevice (0x0x7f3d42c0b138)
+
+Class QSslCertificate
+ size=8 align=8
+ base size=8 base align=8
+QSslCertificate (0x0x7f3d42f91c60) 0
+
+Class QSslError
+ size=8 align=8
+ base size=8 base align=8
+QSslError (0x0x7f3d42c9a0c0) 0
+
+Class QSslSocket::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSslSocket::QPrivateSignal (0x0x7f3d42c9aa20) 0 empty
+
+Vtable for QSslSocket
+QSslSocket::_ZTV10QSslSocket: 41u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QSslSocket)
+16 (int (*)(...))QSslSocket::metaObject
+24 (int (*)(...))QSslSocket::qt_metacast
+32 (int (*)(...))QSslSocket::qt_metacall
+40 (int (*)(...))QSslSocket::~QSslSocket
+48 (int (*)(...))QSslSocket::~QSslSocket
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAbstractSocket::isSequential
+120 (int (*)(...))QIODevice::open
+128 (int (*)(...))QSslSocket::close
+136 (int (*)(...))QIODevice::pos
+144 (int (*)(...))QIODevice::size
+152 (int (*)(...))QIODevice::seek
+160 (int (*)(...))QSslSocket::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QSslSocket::bytesAvailable
+184 (int (*)(...))QSslSocket::bytesToWrite
+192 (int (*)(...))QSslSocket::canReadLine
+200 (int (*)(...))QSslSocket::waitForReadyRead
+208 (int (*)(...))QSslSocket::waitForBytesWritten
+216 (int (*)(...))QSslSocket::readData
+224 (int (*)(...))QAbstractSocket::readLineData
+232 (int (*)(...))QSslSocket::writeData
+240 (int (*)(...))QSslSocket::resume
+248 (int (*)(...))QSslSocket::connectToHost
+256 (int (*)(...))QAbstractSocket::connectToHost
+264 (int (*)(...))QSslSocket::disconnectFromHost
+272 (int (*)(...))QSslSocket::setReadBufferSize
+280 (int (*)(...))QAbstractSocket::socketDescriptor
+288 (int (*)(...))QSslSocket::setSocketDescriptor
+296 (int (*)(...))QSslSocket::setSocketOption
+304 (int (*)(...))QSslSocket::socketOption
+312 (int (*)(...))QSslSocket::waitForConnected
+320 (int (*)(...))QSslSocket::waitForDisconnected
+
+Class QSslSocket
+ size=16 align=8
+ base size=16 base align=8
+QSslSocket (0x0x7f3d42c0baf8) 0
+ vptr=((& QSslSocket::_ZTV10QSslSocket) + 16u)
+ QTcpSocket (0x0x7f3d42c0bb60) 0
+ primary-for QSslSocket (0x0x7f3d42c0baf8)
+ QAbstractSocket (0x0x7f3d42c0bbc8) 0
+ primary-for QTcpSocket (0x0x7f3d42c0bb60)
+ QIODevice (0x0x7f3d42c0bc30) 0
+ primary-for QAbstractSocket (0x0x7f3d42c0bbc8)
+ QObject (0x0x7f3d42c9a9c0) 0
+ primary-for QIODevice (0x0x7f3d42c0bc30)
+
+Class QSslConfiguration
+ size=8 align=8
+ base size=8 base align=8
+QSslConfiguration (0x0x7f3d42c9aa80) 0
+
+Class QSslPreSharedKeyAuthenticator
+ size=8 align=8
+ base size=8 base align=8
+QSslPreSharedKeyAuthenticator (0x0x7f3d42d55240) 0
+
+Class QNetworkAccessManager::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QNetworkAccessManager::QPrivateSignal (0x0x7f3d42d55b40) 0 empty
+
+Vtable for QNetworkAccessManager
+QNetworkAccessManager::_ZTV21QNetworkAccessManager: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QNetworkAccessManager)
+16 (int (*)(...))QNetworkAccessManager::metaObject
+24 (int (*)(...))QNetworkAccessManager::qt_metacast
+32 (int (*)(...))QNetworkAccessManager::qt_metacall
+40 (int (*)(...))QNetworkAccessManager::~QNetworkAccessManager
+48 (int (*)(...))QNetworkAccessManager::~QNetworkAccessManager
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QNetworkAccessManager::createRequest
+
+Class QNetworkAccessManager
+ size=16 align=8
+ base size=16 base align=8
+QNetworkAccessManager (0x0x7f3d42d518f0) 0
+ vptr=((& QNetworkAccessManager::_ZTV21QNetworkAccessManager) + 16u)
+ QObject (0x0x7f3d42d55ae0) 0
+ primary-for QNetworkAccessManager (0x0x7f3d42d518f0)
+
+Class QNetworkConfiguration
+ size=8 align=8
+ base size=8 base align=8
+QNetworkConfiguration (0x0x7f3d42d55ba0) 0
+
+Class QNetworkConfigurationManager::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QNetworkConfigurationManager::QPrivateSignal (0x0x7f3d429e3060) 0 empty
+
+Vtable for QNetworkConfigurationManager
+QNetworkConfigurationManager::_ZTV28QNetworkConfigurationManager: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI28QNetworkConfigurationManager)
+16 (int (*)(...))QNetworkConfigurationManager::metaObject
+24 (int (*)(...))QNetworkConfigurationManager::qt_metacast
+32 (int (*)(...))QNetworkConfigurationManager::qt_metacall
+40 (int (*)(...))QNetworkConfigurationManager::~QNetworkConfigurationManager
+48 (int (*)(...))QNetworkConfigurationManager::~QNetworkConfigurationManager
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QNetworkConfigurationManager
+ size=16 align=8
+ base size=16 base align=8
+QNetworkConfigurationManager (0x0x7f3d42d51af8) 0
+ vptr=((& QNetworkConfigurationManager::_ZTV28QNetworkConfigurationManager) + 16u)
+ QObject (0x0x7f3d429e3000) 0
+ primary-for QNetworkConfigurationManager (0x0x7f3d42d51af8)
+
+Class QNetworkCookie
+ size=8 align=8
+ base size=8 base align=8
+QNetworkCookie (0x0x7f3d429e33c0) 0
+
+Class QNetworkCookieJar::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QNetworkCookieJar::QPrivateSignal (0x0x7f3d429e3ba0) 0 empty
+
+Vtable for QNetworkCookieJar
+QNetworkCookieJar::_ZTV17QNetworkCookieJar: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QNetworkCookieJar)
+16 (int (*)(...))QNetworkCookieJar::metaObject
+24 (int (*)(...))QNetworkCookieJar::qt_metacast
+32 (int (*)(...))QNetworkCookieJar::qt_metacall
+40 (int (*)(...))QNetworkCookieJar::~QNetworkCookieJar
+48 (int (*)(...))QNetworkCookieJar::~QNetworkCookieJar
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QNetworkCookieJar::cookiesForUrl
+120 (int (*)(...))QNetworkCookieJar::setCookiesFromUrl
+128 (int (*)(...))QNetworkCookieJar::insertCookie
+136 (int (*)(...))QNetworkCookieJar::updateCookie
+144 (int (*)(...))QNetworkCookieJar::deleteCookie
+152 (int (*)(...))QNetworkCookieJar::validateCookie
+
+Class QNetworkCookieJar
+ size=16 align=8
+ base size=16 base align=8
+QNetworkCookieJar (0x0x7f3d42a5f340) 0
+ vptr=((& QNetworkCookieJar::_ZTV17QNetworkCookieJar) + 16u)
+ QObject (0x0x7f3d429e3b40) 0
+ primary-for QNetworkCookieJar (0x0x7f3d42a5f340)
+
+Class QNetworkDatagram
+ size=8 align=8
+ base size=8 base align=8
+QNetworkDatagram (0x0x7f3d429e3c00) 0
+
+Class QNetworkDiskCache::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QNetworkDiskCache::QPrivateSignal (0x0x7f3d42af8c00) 0 empty
+
+Vtable for QNetworkDiskCache
+QNetworkDiskCache::_ZTV17QNetworkDiskCache: 23u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QNetworkDiskCache)
+16 (int (*)(...))QNetworkDiskCache::metaObject
+24 (int (*)(...))QNetworkDiskCache::qt_metacast
+32 (int (*)(...))QNetworkDiskCache::qt_metacall
+40 (int (*)(...))QNetworkDiskCache::~QNetworkDiskCache
+48 (int (*)(...))QNetworkDiskCache::~QNetworkDiskCache
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QNetworkDiskCache::metaData
+120 (int (*)(...))QNetworkDiskCache::updateMetaData
+128 (int (*)(...))QNetworkDiskCache::data
+136 (int (*)(...))QNetworkDiskCache::remove
+144 (int (*)(...))QNetworkDiskCache::cacheSize
+152 (int (*)(...))QNetworkDiskCache::prepare
+160 (int (*)(...))QNetworkDiskCache::insert
+168 (int (*)(...))QNetworkDiskCache::clear
+176 (int (*)(...))QNetworkDiskCache::expire
+
+Class QNetworkDiskCache
+ size=16 align=8
+ base size=16 base align=8
+QNetworkDiskCache (0x0x7f3d42afdd68) 0
+ vptr=((& QNetworkDiskCache::_ZTV17QNetworkDiskCache) + 16u)
+ QAbstractNetworkCache (0x0x7f3d42afddd0) 0
+ primary-for QNetworkDiskCache (0x0x7f3d42afdd68)
+ QObject (0x0x7f3d42af8ba0) 0
+ primary-for QAbstractNetworkCache (0x0x7f3d42afddd0)
+
+Class QNetworkAddressEntry
+ size=8 align=8
+ base size=8 base align=8
+QNetworkAddressEntry (0x0x7f3d42af8c60) 0
+
+Class QNetworkInterface
+ size=8 align=8
+ base size=8 base align=8
+QNetworkInterface (0x0x7f3d42b4f360) 0
+
+Class QNetworkProxyQuery
+ size=8 align=8
+ base size=8 base align=8
+QNetworkProxyQuery (0x0x7f3d42b4fa80) 0
+
+Class QNetworkProxy
+ size=8 align=8
+ base size=8 base align=8
+QNetworkProxy (0x0x7f3d427e5120) 0
+
+Vtable for QNetworkProxyFactory
+QNetworkProxyFactory::_ZTV20QNetworkProxyFactory: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QNetworkProxyFactory)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class QNetworkProxyFactory
+ size=8 align=8
+ base size=8 base align=8
+QNetworkProxyFactory (0x0x7f3d427e5900) 0 nearly-empty
+ vptr=((& QNetworkProxyFactory::_ZTV20QNetworkProxyFactory) + 16u)
+
+Class QNetworkReply::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QNetworkReply::QPrivateSignal (0x0x7f3d427e5ae0) 0 empty
+
+Vtable for QNetworkReply
+QNetworkReply::_ZTV13QNetworkReply: 36u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QNetworkReply)
+16 (int (*)(...))QNetworkReply::metaObject
+24 (int (*)(...))QNetworkReply::qt_metacast
+32 (int (*)(...))QNetworkReply::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QNetworkReply::isSequential
+120 (int (*)(...))QIODevice::open
+128 (int (*)(...))QNetworkReply::close
+136 (int (*)(...))QIODevice::pos
+144 (int (*)(...))QIODevice::size
+152 (int (*)(...))QIODevice::seek
+160 (int (*)(...))QIODevice::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QIODevice::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))__cxa_pure_virtual
+224 (int (*)(...))QIODevice::readLineData
+232 (int (*)(...))QNetworkReply::writeData
+240 (int (*)(...))QNetworkReply::setReadBufferSize
+248 (int (*)(...))__cxa_pure_virtual
+256 (int (*)(...))QNetworkReply::ignoreSslErrors
+264 (int (*)(...))QNetworkReply::sslConfigurationImplementation
+272 (int (*)(...))QNetworkReply::setSslConfigurationImplementation
+280 (int (*)(...))QNetworkReply::ignoreSslErrorsImplementation
+
+Class QNetworkReply
+ size=16 align=8
+ base size=16 base align=8
+QNetworkReply (0x0x7f3d4280c478) 0
+ vptr=((& QNetworkReply::_ZTV13QNetworkReply) + 16u)
+ QIODevice (0x0x7f3d4280c4e0) 0
+ primary-for QNetworkReply (0x0x7f3d4280c478)
+ QObject (0x0x7f3d427e5a80) 0
+ primary-for QIODevice (0x0x7f3d4280c4e0)
+
+Class QNetworkSession::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QNetworkSession::QPrivateSignal (0x0x7f3d427e5cc0) 0 empty
+
+Vtable for QNetworkSession
+QNetworkSession::_ZTV15QNetworkSession: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QNetworkSession)
+16 (int (*)(...))QNetworkSession::metaObject
+24 (int (*)(...))QNetworkSession::qt_metacast
+32 (int (*)(...))QNetworkSession::qt_metacall
+40 (int (*)(...))QNetworkSession::~QNetworkSession
+48 (int (*)(...))QNetworkSession::~QNetworkSession
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QNetworkSession::connectNotify
+104 (int (*)(...))QNetworkSession::disconnectNotify
+
+Class QNetworkSession
+ size=24 align=8
+ base size=24 base align=8
+QNetworkSession (0x0x7f3d4280c548) 0
+ vptr=((& QNetworkSession::_ZTV15QNetworkSession) + 16u)
+ QObject (0x0x7f3d427e5c60) 0
+ primary-for QNetworkSession (0x0x7f3d4280c548)
+
+Class QTcpServer::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTcpServer::QPrivateSignal (0x0x7f3d428ab2a0) 0 empty
+
+Vtable for QTcpServer
+QTcpServer::_ZTV10QTcpServer: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTcpServer)
+16 (int (*)(...))QTcpServer::metaObject
+24 (int (*)(...))QTcpServer::qt_metacast
+32 (int (*)(...))QTcpServer::qt_metacall
+40 (int (*)(...))QTcpServer::~QTcpServer
+48 (int (*)(...))QTcpServer::~QTcpServer
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QTcpServer::hasPendingConnections
+120 (int (*)(...))QTcpServer::nextPendingConnection
+128 (int (*)(...))QTcpServer::incomingConnection
+
+Class QTcpServer
+ size=16 align=8
+ base size=16 base align=8
+QTcpServer (0x0x7f3d4280c680) 0
+ vptr=((& QTcpServer::_ZTV10QTcpServer) + 16u)
+ QObject (0x0x7f3d428ab240) 0
+ primary-for QTcpServer (0x0x7f3d4280c680)
+
+Class QSslCertificateExtension
+ size=8 align=8
+ base size=8 base align=8
+QSslCertificateExtension (0x0x7f3d428ab300) 0
+
+Class QSslCipher
+ size=8 align=8
+ base size=8 base align=8
+QSslCipher (0x0x7f3d428ab600) 0
+
+Class QSslDiffieHellmanParameters
+ size=8 align=8
+ base size=8 base align=8
+QSslDiffieHellmanParameters (0x0x7f3d428abde0) 0
+
+Class QSslEllipticCurve
+ size=4 align=4
+ base size=4 base align=4
+QSslEllipticCurve (0x0x7f3d4299a900) 0
+
+Class QSslKey
+ size=8 align=8
+ base size=8 base align=8
+QSslKey (0x0x7f3d425ce060) 0
+
+Class QUdpSocket::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QUdpSocket::QPrivateSignal (0x0x7f3d425ce3c0) 0 empty
+
+Vtable for QUdpSocket
+QUdpSocket::_ZTV10QUdpSocket: 41u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QUdpSocket)
+16 (int (*)(...))QUdpSocket::metaObject
+24 (int (*)(...))QUdpSocket::qt_metacast
+32 (int (*)(...))QUdpSocket::qt_metacall
+40 (int (*)(...))QUdpSocket::~QUdpSocket
+48 (int (*)(...))QUdpSocket::~QUdpSocket
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAbstractSocket::isSequential
+120 (int (*)(...))QIODevice::open
+128 (int (*)(...))QAbstractSocket::close
+136 (int (*)(...))QIODevice::pos
+144 (int (*)(...))QIODevice::size
+152 (int (*)(...))QIODevice::seek
+160 (int (*)(...))QAbstractSocket::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QAbstractSocket::bytesAvailable
+184 (int (*)(...))QAbstractSocket::bytesToWrite
+192 (int (*)(...))QAbstractSocket::canReadLine
+200 (int (*)(...))QAbstractSocket::waitForReadyRead
+208 (int (*)(...))QAbstractSocket::waitForBytesWritten
+216 (int (*)(...))QAbstractSocket::readData
+224 (int (*)(...))QAbstractSocket::readLineData
+232 (int (*)(...))QAbstractSocket::writeData
+240 (int (*)(...))QAbstractSocket::resume
+248 (int (*)(...))QAbstractSocket::connectToHost
+256 (int (*)(...))QAbstractSocket::connectToHost
+264 (int (*)(...))QAbstractSocket::disconnectFromHost
+272 (int (*)(...))QAbstractSocket::setReadBufferSize
+280 (int (*)(...))QAbstractSocket::socketDescriptor
+288 (int (*)(...))QAbstractSocket::setSocketDescriptor
+296 (int (*)(...))QAbstractSocket::setSocketOption
+304 (int (*)(...))QAbstractSocket::socketOption
+312 (int (*)(...))QAbstractSocket::waitForConnected
+320 (int (*)(...))QAbstractSocket::waitForDisconnected
+
+Class QUdpSocket
+ size=16 align=8
+ base size=16 base align=8
+QUdpSocket (0x0x7f3d429a5c30) 0
+ vptr=((& QUdpSocket::_ZTV10QUdpSocket) + 16u)
+ QAbstractSocket (0x0x7f3d429a5c98) 0
+ primary-for QUdpSocket (0x0x7f3d429a5c30)
+ QIODevice (0x0x7f3d429a5d00) 0
+ primary-for QAbstractSocket (0x0x7f3d429a5c98)
+ QObject (0x0x7f3d425ce360) 0
+ primary-for QIODevice (0x0x7f3d429a5d00)
+
+Class QJSValue
+ size=8 align=8
+ base size=8 base align=8
+QJSValue (0x0x7f3d425ce420) 0
+
+Class QJSEngine::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QJSEngine::QPrivateSignal (0x0x7f3d425ce720) 0 empty
+
+Vtable for QJSEngine
+QJSEngine::_ZTV9QJSEngine: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QJSEngine)
+16 (int (*)(...))QJSEngine::metaObject
+24 (int (*)(...))QJSEngine::qt_metacast
+32 (int (*)(...))QJSEngine::qt_metacall
+40 (int (*)(...))QJSEngine::~QJSEngine
+48 (int (*)(...))QJSEngine::~QJSEngine
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QJSEngine
+ size=24 align=8
+ base size=24 base align=8
+QJSEngine (0x0x7f3d429a5e38) 0
+ vptr=((& QJSEngine::_ZTV9QJSEngine) + 16u)
+ QObject (0x0x7f3d425ce6c0) 0
+ primary-for QJSEngine (0x0x7f3d429a5e38)
+
+Class QJSValueIterator
+ size=8 align=8
+ base size=8 base align=8
+QJSValueIterator (0x0x7f3d425ce900) 0
+
+Class QQmlPrivate::RegisterType
+ size=128 align=8
+ base size=124 base align=8
+QQmlPrivate::RegisterType (0x0x7f3d425cede0) 0
+
+Class QQmlPrivate::RegisterInterface
+ size=24 align=8
+ base size=24 base align=8
+QQmlPrivate::RegisterInterface (0x0x7f3d425cee40) 0
+
+Class QQmlPrivate::RegisterAutoParent
+ size=16 align=8
+ base size=16 base align=8
+QQmlPrivate::RegisterAutoParent (0x0x7f3d425ceea0) 0
+
+Class QQmlPrivate::RegisterSingletonType
+ size=64 align=8
+ base size=64 base align=8
+QQmlPrivate::RegisterSingletonType (0x0x7f3d425cef00) 0
+
+Class QQmlPrivate::RegisterCompositeType
+ size=32 align=8
+ base size=32 base align=8
+QQmlPrivate::RegisterCompositeType (0x0x7f3d425cef60) 0
+
+Class QQmlPrivate::RegisterCompositeSingletonType
+ size=32 align=8
+ base size=32 base align=8
+QQmlPrivate::RegisterCompositeSingletonType (0x0x7f3d426cd000) 0
+
+Class QQmlPrivate::CachedQmlUnit
+ size=24 align=8
+ base size=24 base align=8
+QQmlPrivate::CachedQmlUnit (0x0x7f3d426cd060) 0
+
+Class QQmlPrivate::RegisterQmlUnitCacheHook
+ size=16 align=8
+ base size=16 base align=8
+QQmlPrivate::RegisterQmlUnitCacheHook (0x0x7f3d426cd0c0) 0
+
+Vtable for QQmlParserStatus
+QQmlParserStatus::_ZTV16QQmlParserStatus: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QQmlParserStatus)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+
+Class QQmlParserStatus
+ size=16 align=8
+ base size=16 base align=8
+QQmlParserStatus (0x0x7f3d426cd120) 0
+ vptr=((& QQmlParserStatus::_ZTV16QQmlParserStatus) + 16u)
+
+Vtable for QQmlPropertyValueSource
+QQmlPropertyValueSource::_ZTV23QQmlPropertyValueSource: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QQmlPropertyValueSource)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class QQmlPropertyValueSource
+ size=8 align=8
+ base size=8 base align=8
+QQmlPropertyValueSource (0x0x7f3d426cd1e0) 0 nearly-empty
+ vptr=((& QQmlPropertyValueSource::_ZTV23QQmlPropertyValueSource) + 16u)
+
+Class QQmlListReference
+ size=8 align=8
+ base size=8 base align=8
+QQmlListReference (0x0x7f3d426cd300) 0
+
+Vtable for QQmlAbstractUrlInterceptor
+QQmlAbstractUrlInterceptor::_ZTV26QQmlAbstractUrlInterceptor: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QQmlAbstractUrlInterceptor)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class QQmlAbstractUrlInterceptor
+ size=8 align=8
+ base size=8 base align=8
+QQmlAbstractUrlInterceptor (0x0x7f3d426cd960) 0 nearly-empty
+ vptr=((& QQmlAbstractUrlInterceptor::_ZTV26QQmlAbstractUrlInterceptor) + 16u)
+
+Class QQmlError
+ size=8 align=8
+ base size=8 base align=8
+QQmlError (0x0x7f3d426cd9c0) 0
+
+Class QQmlDebuggingEnabler
+ size=1 align=1
+ base size=0 base align=1
+QQmlDebuggingEnabler (0x0x7f3d426cdc60) 0 empty
+
+Vtable for QQmlImageProviderBase
+QQmlImageProviderBase::_ZTV21QQmlImageProviderBase: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QQmlImageProviderBase)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+
+Class QQmlImageProviderBase
+ size=8 align=8
+ base size=8 base align=8
+QQmlImageProviderBase (0x0x7f3d426cdcc0) 0 nearly-empty
+ vptr=((& QQmlImageProviderBase::_ZTV21QQmlImageProviderBase) + 16u)
+
+Class QQmlEngine::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQmlEngine::QPrivateSignal (0x0x7f3d426cdf00) 0 empty
+
+Vtable for QQmlEngine
+QQmlEngine::_ZTV10QQmlEngine: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QQmlEngine)
+16 (int (*)(...))QQmlEngine::metaObject
+24 (int (*)(...))QQmlEngine::qt_metacast
+32 (int (*)(...))QQmlEngine::qt_metacall
+40 (int (*)(...))QQmlEngine::~QQmlEngine
+48 (int (*)(...))QQmlEngine::~QQmlEngine
+56 (int (*)(...))QQmlEngine::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QQmlEngine
+ size=24 align=8
+ base size=24 base align=8
+QQmlEngine (0x0x7f3d426b3478) 0
+ vptr=((& QQmlEngine::_ZTV10QQmlEngine) + 16u)
+ QJSEngine (0x0x7f3d426b34e0) 0
+ primary-for QQmlEngine (0x0x7f3d426b3478)
+ QObject (0x0x7f3d426cdea0) 0
+ primary-for QJSEngine (0x0x7f3d426b34e0)
+
+Class QQmlApplicationEngine::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQmlApplicationEngine::QPrivateSignal (0x0x7f3d4242a000) 0 empty
+
+Vtable for QQmlApplicationEngine
+QQmlApplicationEngine::_ZTV21QQmlApplicationEngine: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QQmlApplicationEngine)
+16 (int (*)(...))QQmlApplicationEngine::metaObject
+24 (int (*)(...))QQmlApplicationEngine::qt_metacast
+32 (int (*)(...))QQmlApplicationEngine::qt_metacall
+40 (int (*)(...))QQmlApplicationEngine::~QQmlApplicationEngine
+48 (int (*)(...))QQmlApplicationEngine::~QQmlApplicationEngine
+56 (int (*)(...))QQmlEngine::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QQmlApplicationEngine
+ size=24 align=8
+ base size=24 base align=8
+QQmlApplicationEngine (0x0x7f3d426b3548) 0
+ vptr=((& QQmlApplicationEngine::_ZTV21QQmlApplicationEngine) + 16u)
+ QQmlEngine (0x0x7f3d426b35b0) 0
+ primary-for QQmlApplicationEngine (0x0x7f3d426b3548)
+ QJSEngine (0x0x7f3d426b3618) 0
+ primary-for QQmlEngine (0x0x7f3d426b35b0)
+ QObject (0x0x7f3d426cdf60) 0
+ primary-for QJSEngine (0x0x7f3d426b3618)
+
+Class QQmlComponent::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQmlComponent::QPrivateSignal (0x0x7f3d4242a0c0) 0 empty
+
+Vtable for QQmlComponent
+QQmlComponent::_ZTV13QQmlComponent: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QQmlComponent)
+16 (int (*)(...))QQmlComponent::metaObject
+24 (int (*)(...))QQmlComponent::qt_metacast
+32 (int (*)(...))QQmlComponent::qt_metacall
+40 (int (*)(...))QQmlComponent::~QQmlComponent
+48 (int (*)(...))QQmlComponent::~QQmlComponent
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QQmlComponent::create
+120 (int (*)(...))QQmlComponent::beginCreate
+128 (int (*)(...))QQmlComponent::completeCreate
+
+Class QQmlComponent
+ size=16 align=8
+ base size=16 base align=8
+QQmlComponent (0x0x7f3d426b3680) 0
+ vptr=((& QQmlComponent::_ZTV13QQmlComponent) + 16u)
+ QObject (0x0x7f3d4242a060) 0
+ primary-for QQmlComponent (0x0x7f3d426b3680)
+
+Class QQmlContext::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQmlContext::QPrivateSignal (0x0x7f3d4242a900) 0 empty
+
+Vtable for QQmlContext
+QQmlContext::_ZTV11QQmlContext: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QQmlContext)
+16 (int (*)(...))QQmlContext::metaObject
+24 (int (*)(...))QQmlContext::qt_metacast
+32 (int (*)(...))QQmlContext::qt_metacall
+40 (int (*)(...))QQmlContext::~QQmlContext
+48 (int (*)(...))QQmlContext::~QQmlContext
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QQmlContext
+ size=16 align=8
+ base size=16 base align=8
+QQmlContext (0x0x7f3d426b3bc8) 0
+ vptr=((& QQmlContext::_ZTV11QQmlContext) + 16u)
+ QObject (0x0x7f3d4242a8a0) 0
+ primary-for QQmlContext (0x0x7f3d426b3bc8)
+
+Class QQmlScriptString
+ size=8 align=8
+ base size=8 base align=8
+QQmlScriptString (0x0x7f3d4242aa80) 0
+
+Class QQmlExpression::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQmlExpression::QPrivateSignal (0x0x7f3d4242acc0) 0 empty
+
+Vtable for QQmlExpression
+QQmlExpression::_ZTV14QQmlExpression: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QQmlExpression)
+16 (int (*)(...))QQmlExpression::metaObject
+24 (int (*)(...))QQmlExpression::qt_metacast
+32 (int (*)(...))QQmlExpression::qt_metacall
+40 (int (*)(...))QQmlExpression::~QQmlExpression
+48 (int (*)(...))QQmlExpression::~QQmlExpression
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QQmlExpression
+ size=16 align=8
+ base size=16 base align=8
+QQmlExpression (0x0x7f3d426b3c30) 0
+ vptr=((& QQmlExpression::_ZTV14QQmlExpression) + 16u)
+ QObject (0x0x7f3d4242ac60) 0
+ primary-for QQmlExpression (0x0x7f3d426b3c30)
+
+Vtable for QQmlTypesExtensionInterface
+QQmlTypesExtensionInterface::_ZTV27QQmlTypesExtensionInterface: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QQmlTypesExtensionInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class QQmlTypesExtensionInterface
+ size=8 align=8
+ base size=8 base align=8
+QQmlTypesExtensionInterface (0x0x7f3d4242ad20) 0 nearly-empty
+ vptr=((& QQmlTypesExtensionInterface::_ZTV27QQmlTypesExtensionInterface) + 16u)
+
+Vtable for QQmlExtensionInterface
+QQmlExtensionInterface::_ZTV22QQmlExtensionInterface: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI22QQmlExtensionInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+
+Class QQmlExtensionInterface
+ size=8 align=8
+ base size=8 base align=8
+QQmlExtensionInterface (0x0x7f3d426b3c98) 0 nearly-empty
+ vptr=((& QQmlExtensionInterface::_ZTV22QQmlExtensionInterface) + 16u)
+ QQmlTypesExtensionInterface (0x0x7f3d4242ad80) 0 nearly-empty
+ primary-for QQmlExtensionInterface (0x0x7f3d426b3c98)
+
+Class QQmlExtensionPlugin::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQmlExtensionPlugin::QPrivateSignal (0x0x7f3d4242af60) 0 empty
+
+Vtable for QQmlExtensionPlugin
+QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin: 22u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QQmlExtensionPlugin)
+16 (int (*)(...))QQmlExtensionPlugin::metaObject
+24 (int (*)(...))QQmlExtensionPlugin::qt_metacast
+32 (int (*)(...))QQmlExtensionPlugin::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))QQmlExtensionPlugin::initializeEngine
+128 (int (*)(...))-16
+136 (int (*)(...))(& _ZTI19QQmlExtensionPlugin)
+144 0u
+152 0u
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))QQmlExtensionPlugin::_ZThn16_N19QQmlExtensionPlugin16initializeEngineEP10QQmlEnginePKc
+
+Class QQmlExtensionPlugin
+ size=24 align=8
+ base size=24 base align=8
+QQmlExtensionPlugin (0x0x7f3d424d37e0) 0
+ vptr=((& QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin) + 16u)
+ QObject (0x0x7f3d4242aea0) 0
+ primary-for QQmlExtensionPlugin (0x0x7f3d424d37e0)
+ QQmlExtensionInterface (0x0x7f3d426b3d00) 16 nearly-empty
+ vptr=((& QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin) + 144u)
+ QQmlTypesExtensionInterface (0x0x7f3d4242af00) 16 nearly-empty
+ primary-for QQmlExtensionInterface (0x0x7f3d426b3d00)
+
+Class QQmlFile
+ size=8 align=8
+ base size=8 base align=8
+QQmlFile (0x0x7f3d424eb000) 0
+
+Class QQmlFileSelector::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQmlFileSelector::QPrivateSignal (0x0x7f3d424eb0c0) 0 empty
+
+Vtable for QQmlFileSelector
+QQmlFileSelector::_ZTV16QQmlFileSelector: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QQmlFileSelector)
+16 (int (*)(...))QQmlFileSelector::metaObject
+24 (int (*)(...))QQmlFileSelector::qt_metacast
+32 (int (*)(...))QQmlFileSelector::qt_metacall
+40 (int (*)(...))QQmlFileSelector::~QQmlFileSelector
+48 (int (*)(...))QQmlFileSelector::~QQmlFileSelector
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QQmlFileSelector
+ size=16 align=8
+ base size=16 base align=8
+QQmlFileSelector (0x0x7f3d426b3dd0) 0
+ vptr=((& QQmlFileSelector::_ZTV16QQmlFileSelector) + 16u)
+ QObject (0x0x7f3d424eb060) 0
+ primary-for QQmlFileSelector (0x0x7f3d426b3dd0)
+
+Vtable for QQmlIncubator
+QQmlIncubator::_ZTV13QQmlIncubator: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QQmlIncubator)
+16 (int (*)(...))QQmlIncubator::~QQmlIncubator
+24 (int (*)(...))QQmlIncubator::~QQmlIncubator
+32 (int (*)(...))QQmlIncubator::statusChanged
+40 (int (*)(...))QQmlIncubator::setInitialState
+
+Class QQmlIncubator
+ size=16 align=8
+ base size=16 base align=8
+QQmlIncubator (0x0x7f3d424eb120) 0
+ vptr=((& QQmlIncubator::_ZTV13QQmlIncubator) + 16u)
+
+Vtable for QQmlIncubationController
+QQmlIncubationController::_ZTV24QQmlIncubationController: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QQmlIncubationController)
+16 (int (*)(...))QQmlIncubationController::~QQmlIncubationController
+24 (int (*)(...))QQmlIncubationController::~QQmlIncubationController
+32 (int (*)(...))QQmlIncubationController::incubatingObjectCountChanged
+
+Class QQmlIncubationController
+ size=16 align=8
+ base size=16 base align=8
+QQmlIncubationController (0x0x7f3d424eb180) 0
+ vptr=((& QQmlIncubationController::_ZTV24QQmlIncubationController) + 16u)
+
+Class QQmlInfo
+ size=16 align=8
+ base size=16 base align=8
+QQmlInfo (0x0x7f3d426b3e38) 0
+ QDebug (0x0x7f3d424eb1e0) 0
+
+Vtable for QQmlNetworkAccessManagerFactory
+QQmlNetworkAccessManagerFactory::_ZTV31QQmlNetworkAccessManagerFactory: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI31QQmlNetworkAccessManagerFactory)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class QQmlNetworkAccessManagerFactory
+ size=8 align=8
+ base size=8 base align=8
+QQmlNetworkAccessManagerFactory (0x0x7f3d4259e0c0) 0 nearly-empty
+ vptr=((& QQmlNetworkAccessManagerFactory::_ZTV31QQmlNetworkAccessManagerFactory) + 16u)
+
+Class QQmlProperty
+ size=8 align=8
+ base size=8 base align=8
+QQmlProperty (0x0x7f3d4259e120) 0
+
+Class QQmlPropertyMap::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQmlPropertyMap::QPrivateSignal (0x0x7f3d4259ec60) 0 empty
+
+Vtable for QQmlPropertyMap
+QQmlPropertyMap::_ZTV15QQmlPropertyMap: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QQmlPropertyMap)
+16 (int (*)(...))QQmlPropertyMap::metaObject
+24 (int (*)(...))QQmlPropertyMap::qt_metacast
+32 (int (*)(...))QQmlPropertyMap::qt_metacall
+40 (int (*)(...))QQmlPropertyMap::~QQmlPropertyMap
+48 (int (*)(...))QQmlPropertyMap::~QQmlPropertyMap
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QQmlPropertyMap::updateValue
+
+Class QQmlPropertyMap
+ size=16 align=8
+ base size=16 base align=8
+QQmlPropertyMap (0x0x7f3d425c2680) 0
+ vptr=((& QQmlPropertyMap::_ZTV15QQmlPropertyMap) + 16u)
+ QObject (0x0x7f3d4259ec00) 0
+ primary-for QQmlPropertyMap (0x0x7f3d425c2680)
+
+Class QQuickTransform::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQuickTransform::QPrivateSignal (0x0x7f3d4259ed20) 0 empty
+
+Vtable for QQuickTransform
+QQuickTransform::_ZTV15QQuickTransform: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QQuickTransform)
+16 (int (*)(...))QQuickTransform::metaObject
+24 (int (*)(...))QQuickTransform::qt_metacast
+32 (int (*)(...))QQuickTransform::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+
+Class QQuickTransform
+ size=16 align=8
+ base size=16 base align=8
+QQuickTransform (0x0x7f3d425c26e8) 0
+ vptr=((& QQuickTransform::_ZTV15QQuickTransform) + 16u)
+ QObject (0x0x7f3d4259ecc0) 0
+ primary-for QQuickTransform (0x0x7f3d425c26e8)
+
+Class QQuickItem::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQuickItem::QPrivateSignal (0x0x7f3d4259ee40) 0 empty
+
+Class QQuickItem::ItemChangeData
+ size=8 align=8
+ base size=8 base align=8
+QQuickItem::ItemChangeData (0x0x7f3d4259eea0) 0
+
+Class QQuickItem::UpdatePaintNodeData
+ size=8 align=8
+ base size=8 base align=8
+QQuickItem::UpdatePaintNodeData (0x0x7f3d4259ef00) 0
+
+Vtable for QQuickItem
+QQuickItem::_ZTV10QQuickItem: 55u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QQuickItem)
+16 (int (*)(...))QQuickItem::metaObject
+24 (int (*)(...))QQuickItem::qt_metacast
+32 (int (*)(...))QQuickItem::qt_metacall
+40 (int (*)(...))QQuickItem::~QQuickItem
+48 (int (*)(...))QQuickItem::~QQuickItem
+56 (int (*)(...))QQuickItem::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QQuickItem::boundingRect
+120 (int (*)(...))QQuickItem::clipRect
+128 (int (*)(...))QQuickItem::contains
+136 (int (*)(...))QQuickItem::inputMethodQuery
+144 (int (*)(...))QQuickItem::isTextureProvider
+152 (int (*)(...))QQuickItem::textureProvider
+160 (int (*)(...))QQuickItem::itemChange
+168 (int (*)(...))QQuickItem::classBegin
+176 (int (*)(...))QQuickItem::componentComplete
+184 (int (*)(...))QQuickItem::keyPressEvent
+192 (int (*)(...))QQuickItem::keyReleaseEvent
+200 (int (*)(...))QQuickItem::inputMethodEvent
+208 (int (*)(...))QQuickItem::focusInEvent
+216 (int (*)(...))QQuickItem::focusOutEvent
+224 (int (*)(...))QQuickItem::mousePressEvent
+232 (int (*)(...))QQuickItem::mouseMoveEvent
+240 (int (*)(...))QQuickItem::mouseReleaseEvent
+248 (int (*)(...))QQuickItem::mouseDoubleClickEvent
+256 (int (*)(...))QQuickItem::mouseUngrabEvent
+264 (int (*)(...))QQuickItem::touchUngrabEvent
+272 (int (*)(...))QQuickItem::wheelEvent
+280 (int (*)(...))QQuickItem::touchEvent
+288 (int (*)(...))QQuickItem::hoverEnterEvent
+296 (int (*)(...))QQuickItem::hoverMoveEvent
+304 (int (*)(...))QQuickItem::hoverLeaveEvent
+312 (int (*)(...))QQuickItem::dragEnterEvent
+320 (int (*)(...))QQuickItem::dragMoveEvent
+328 (int (*)(...))QQuickItem::dragLeaveEvent
+336 (int (*)(...))QQuickItem::dropEvent
+344 (int (*)(...))QQuickItem::childMouseEventFilter
+352 (int (*)(...))QQuickItem::windowDeactivateEvent
+360 (int (*)(...))QQuickItem::geometryChanged
+368 (int (*)(...))QQuickItem::updatePaintNode
+376 (int (*)(...))QQuickItem::releaseResources
+384 (int (*)(...))QQuickItem::updatePolish
+392 (int (*)(...))-16
+400 (int (*)(...))(& _ZTI10QQuickItem)
+408 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItemD1Ev
+416 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItemD0Ev
+424 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv
+432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv
+
+Class QQuickItem
+ size=32 align=8
+ base size=32 base align=8
+QQuickItem (0x0x7f3d421dc5b0) 0
+ vptr=((& QQuickItem::_ZTV10QQuickItem) + 16u)
+ QObject (0x0x7f3d4259ed80) 0
+ primary-for QQuickItem (0x0x7f3d421dc5b0)
+ QQmlParserStatus (0x0x7f3d4259ede0) 16
+ vptr=((& QQuickItem::_ZTV10QQuickItem) + 408u)
+
+Class QQuickFramebufferObject::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQuickFramebufferObject::QPrivateSignal (0x0x7f3d42243720) 0 empty
+
+Vtable for QQuickFramebufferObject::Renderer
+QQuickFramebufferObject::Renderer::_ZTVN23QQuickFramebufferObject8RendererE: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN23QQuickFramebufferObject8RendererE)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))QQuickFramebufferObject::Renderer::createFramebufferObject
+48 (int (*)(...))QQuickFramebufferObject::Renderer::synchronize
+
+Class QQuickFramebufferObject::Renderer
+ size=16 align=8
+ base size=16 base align=8
+QQuickFramebufferObject::Renderer (0x0x7f3d42243780) 0
+ vptr=((& QQuickFramebufferObject::Renderer::_ZTVN23QQuickFramebufferObject8RendererE) + 16u)
+
+Vtable for QQuickFramebufferObject
+QQuickFramebufferObject::_ZTV23QQuickFramebufferObject: 56u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QQuickFramebufferObject)
+16 (int (*)(...))QQuickFramebufferObject::metaObject
+24 (int (*)(...))QQuickFramebufferObject::qt_metacast
+32 (int (*)(...))QQuickFramebufferObject::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QQuickItem::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QQuickItem::boundingRect
+120 (int (*)(...))QQuickItem::clipRect
+128 (int (*)(...))QQuickItem::contains
+136 (int (*)(...))QQuickItem::inputMethodQuery
+144 (int (*)(...))QQuickFramebufferObject::isTextureProvider
+152 (int (*)(...))QQuickFramebufferObject::textureProvider
+160 (int (*)(...))QQuickItem::itemChange
+168 (int (*)(...))QQuickItem::classBegin
+176 (int (*)(...))QQuickItem::componentComplete
+184 (int (*)(...))QQuickItem::keyPressEvent
+192 (int (*)(...))QQuickItem::keyReleaseEvent
+200 (int (*)(...))QQuickItem::inputMethodEvent
+208 (int (*)(...))QQuickItem::focusInEvent
+216 (int (*)(...))QQuickItem::focusOutEvent
+224 (int (*)(...))QQuickItem::mousePressEvent
+232 (int (*)(...))QQuickItem::mouseMoveEvent
+240 (int (*)(...))QQuickItem::mouseReleaseEvent
+248 (int (*)(...))QQuickItem::mouseDoubleClickEvent
+256 (int (*)(...))QQuickItem::mouseUngrabEvent
+264 (int (*)(...))QQuickItem::touchUngrabEvent
+272 (int (*)(...))QQuickItem::wheelEvent
+280 (int (*)(...))QQuickItem::touchEvent
+288 (int (*)(...))QQuickItem::hoverEnterEvent
+296 (int (*)(...))QQuickItem::hoverMoveEvent
+304 (int (*)(...))QQuickItem::hoverLeaveEvent
+312 (int (*)(...))QQuickItem::dragEnterEvent
+320 (int (*)(...))QQuickItem::dragMoveEvent
+328 (int (*)(...))QQuickItem::dragLeaveEvent
+336 (int (*)(...))QQuickItem::dropEvent
+344 (int (*)(...))QQuickItem::childMouseEventFilter
+352 (int (*)(...))QQuickItem::windowDeactivateEvent
+360 (int (*)(...))QQuickFramebufferObject::geometryChanged
+368 (int (*)(...))QQuickFramebufferObject::updatePaintNode
+376 (int (*)(...))QQuickFramebufferObject::releaseResources
+384 (int (*)(...))QQuickItem::updatePolish
+392 (int (*)(...))__cxa_pure_virtual
+400 (int (*)(...))-16
+408 (int (*)(...))(& _ZTI23QQuickFramebufferObject)
+416 0u
+424 0u
+432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv
+440 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv
+
+Class QQuickFramebufferObject
+ size=32 align=8
+ base size=32 base align=8
+QQuickFramebufferObject (0x0x7f3d425c2820) 0
+ vptr=((& QQuickFramebufferObject::_ZTV23QQuickFramebufferObject) + 16u)
+ QQuickItem (0x0x7f3d4228cbd0) 0
+ primary-for QQuickFramebufferObject (0x0x7f3d425c2820)
+ QObject (0x0x7f3d42243660) 0
+ primary-for QQuickItem (0x0x7f3d4228cbd0)
+ QQmlParserStatus (0x0x7f3d422436c0) 16
+ vptr=((& QQuickFramebufferObject::_ZTV23QQuickFramebufferObject) + 416u)
+
+Vtable for QQuickTextureFactory
+QQuickTextureFactory::_ZTV20QQuickTextureFactory: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QQuickTextureFactory)
+16 (int (*)(...))QObject::metaObject
+24 (int (*)(...))QObject::qt_metacast
+32 (int (*)(...))QObject::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))QQuickTextureFactory::image
+
+Class QQuickTextureFactory
+ size=16 align=8
+ base size=16 base align=8
+QQuickTextureFactory (0x0x7f3d425c2888) 0
+ vptr=((& QQuickTextureFactory::_ZTV20QQuickTextureFactory) + 16u)
+ QObject (0x0x7f3d422437e0) 0
+ primary-for QQuickTextureFactory (0x0x7f3d425c2888)
+
+Class QQuickImageResponse::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQuickImageResponse::QPrivateSignal (0x0x7f3d422438a0) 0 empty
+
+Vtable for QQuickImageResponse
+QQuickImageResponse::_ZTV19QQuickImageResponse: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QQuickImageResponse)
+16 (int (*)(...))QQuickImageResponse::metaObject
+24 (int (*)(...))QQuickImageResponse::qt_metacast
+32 (int (*)(...))QQuickImageResponse::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))QQuickImageResponse::errorString
+128 (int (*)(...))QQuickImageResponse::cancel
+
+Class QQuickImageResponse
+ size=16 align=8
+ base size=16 base align=8
+QQuickImageResponse (0x0x7f3d425c28f0) 0
+ vptr=((& QQuickImageResponse::_ZTV19QQuickImageResponse) + 16u)
+ QObject (0x0x7f3d42243840) 0
+ primary-for QQuickImageResponse (0x0x7f3d425c28f0)
+
+Vtable for QQuickImageProvider
+QQuickImageProvider::_ZTV19QQuickImageProvider: 9u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QQuickImageProvider)
+16 (int (*)(...))QQuickImageProvider::~QQuickImageProvider
+24 (int (*)(...))QQuickImageProvider::~QQuickImageProvider
+32 (int (*)(...))QQuickImageProvider::imageType
+40 (int (*)(...))QQuickImageProvider::flags
+48 (int (*)(...))QQuickImageProvider::requestImage
+56 (int (*)(...))QQuickImageProvider::requestPixmap
+64 (int (*)(...))QQuickImageProvider::requestTexture
+
+Class QQuickImageProvider
+ size=16 align=8
+ base size=16 base align=8
+QQuickImageProvider (0x0x7f3d425c2958) 0
+ vptr=((& QQuickImageProvider::_ZTV19QQuickImageProvider) + 16u)
+ QQmlImageProviderBase (0x0x7f3d42243900) 0 nearly-empty
+ primary-for QQuickImageProvider (0x0x7f3d425c2958)
+
+Vtable for QQuickAsyncImageProvider
+QQuickAsyncImageProvider::_ZTV24QQuickAsyncImageProvider: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QQuickAsyncImageProvider)
+16 0u
+24 0u
+32 (int (*)(...))QQuickImageProvider::imageType
+40 (int (*)(...))QQuickImageProvider::flags
+48 (int (*)(...))QQuickImageProvider::requestImage
+56 (int (*)(...))QQuickImageProvider::requestPixmap
+64 (int (*)(...))QQuickImageProvider::requestTexture
+72 (int (*)(...))__cxa_pure_virtual
+
+Class QQuickAsyncImageProvider
+ size=24 align=8
+ base size=24 base align=8
+QQuickAsyncImageProvider (0x0x7f3d425c29c0) 0
+ vptr=((& QQuickAsyncImageProvider::_ZTV24QQuickAsyncImageProvider) + 16u)
+ QQuickImageProvider (0x0x7f3d425c2a28) 0
+ primary-for QQuickAsyncImageProvider (0x0x7f3d425c29c0)
+ QQmlImageProviderBase (0x0x7f3d42243960) 0 nearly-empty
+ primary-for QQuickImageProvider (0x0x7f3d425c2a28)
+
+Class QQuickItemGrabResult::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQuickItemGrabResult::QPrivateSignal (0x0x7f3d42243a20) 0 empty
+
+Vtable for QQuickItemGrabResult
+QQuickItemGrabResult::_ZTV20QQuickItemGrabResult: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QQuickItemGrabResult)
+16 (int (*)(...))QQuickItemGrabResult::metaObject
+24 (int (*)(...))QQuickItemGrabResult::qt_metacast
+32 (int (*)(...))QQuickItemGrabResult::qt_metacall
+40 (int (*)(...))QQuickItemGrabResult::~QQuickItemGrabResult
+48 (int (*)(...))QQuickItemGrabResult::~QQuickItemGrabResult
+56 (int (*)(...))QQuickItemGrabResult::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QQuickItemGrabResult
+ size=16 align=8
+ base size=16 base align=8
+QQuickItemGrabResult (0x0x7f3d425c2a90) 0
+ vptr=((& QQuickItemGrabResult::_ZTV20QQuickItemGrabResult) + 16u)
+ QObject (0x0x7f3d422439c0) 0
+ primary-for QQuickItemGrabResult (0x0x7f3d425c2a90)
+
+Class QQuickPaintedItem::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQuickPaintedItem::QPrivateSignal (0x0x7f3d42243b40) 0 empty
+
+Vtable for QQuickPaintedItem
+QQuickPaintedItem::_ZTV17QQuickPaintedItem: 56u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QQuickPaintedItem)
+16 (int (*)(...))QQuickPaintedItem::metaObject
+24 (int (*)(...))QQuickPaintedItem::qt_metacast
+32 (int (*)(...))QQuickPaintedItem::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QQuickItem::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QQuickItem::boundingRect
+120 (int (*)(...))QQuickItem::clipRect
+128 (int (*)(...))QQuickItem::contains
+136 (int (*)(...))QQuickItem::inputMethodQuery
+144 (int (*)(...))QQuickPaintedItem::isTextureProvider
+152 (int (*)(...))QQuickPaintedItem::textureProvider
+160 (int (*)(...))QQuickPaintedItem::itemChange
+168 (int (*)(...))QQuickItem::classBegin
+176 (int (*)(...))QQuickItem::componentComplete
+184 (int (*)(...))QQuickItem::keyPressEvent
+192 (int (*)(...))QQuickItem::keyReleaseEvent
+200 (int (*)(...))QQuickItem::inputMethodEvent
+208 (int (*)(...))QQuickItem::focusInEvent
+216 (int (*)(...))QQuickItem::focusOutEvent
+224 (int (*)(...))QQuickItem::mousePressEvent
+232 (int (*)(...))QQuickItem::mouseMoveEvent
+240 (int (*)(...))QQuickItem::mouseReleaseEvent
+248 (int (*)(...))QQuickItem::mouseDoubleClickEvent
+256 (int (*)(...))QQuickItem::mouseUngrabEvent
+264 (int (*)(...))QQuickItem::touchUngrabEvent
+272 (int (*)(...))QQuickItem::wheelEvent
+280 (int (*)(...))QQuickItem::touchEvent
+288 (int (*)(...))QQuickItem::hoverEnterEvent
+296 (int (*)(...))QQuickItem::hoverMoveEvent
+304 (int (*)(...))QQuickItem::hoverLeaveEvent
+312 (int (*)(...))QQuickItem::dragEnterEvent
+320 (int (*)(...))QQuickItem::dragMoveEvent
+328 (int (*)(...))QQuickItem::dragLeaveEvent
+336 (int (*)(...))QQuickItem::dropEvent
+344 (int (*)(...))QQuickItem::childMouseEventFilter
+352 (int (*)(...))QQuickItem::windowDeactivateEvent
+360 (int (*)(...))QQuickItem::geometryChanged
+368 (int (*)(...))QQuickPaintedItem::updatePaintNode
+376 (int (*)(...))QQuickPaintedItem::releaseResources
+384 (int (*)(...))QQuickItem::updatePolish
+392 (int (*)(...))__cxa_pure_virtual
+400 (int (*)(...))-16
+408 (int (*)(...))(& _ZTI17QQuickPaintedItem)
+416 0u
+424 0u
+432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv
+440 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv
+
+Class QQuickPaintedItem
+ size=32 align=8
+ base size=32 base align=8
+QQuickPaintedItem (0x0x7f3d425c2af8) 0
+ vptr=((& QQuickPaintedItem::_ZTV17QQuickPaintedItem) + 16u)
+ QQuickItem (0x0x7f3d422bde00) 0
+ primary-for QQuickPaintedItem (0x0x7f3d425c2af8)
+ QObject (0x0x7f3d42243a80) 0
+ primary-for QQuickItem (0x0x7f3d422bde00)
+ QQmlParserStatus (0x0x7f3d42243ae0) 16
+ vptr=((& QQuickPaintedItem::_ZTV17QQuickPaintedItem) + 416u)
+
+Class QQuickRenderControl::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQuickRenderControl::QPrivateSignal (0x0x7f3d42243d80) 0 empty
+
+Vtable for QQuickRenderControl
+QQuickRenderControl::_ZTV19QQuickRenderControl: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QQuickRenderControl)
+16 (int (*)(...))QQuickRenderControl::metaObject
+24 (int (*)(...))QQuickRenderControl::qt_metacast
+32 (int (*)(...))QQuickRenderControl::qt_metacall
+40 (int (*)(...))QQuickRenderControl::~QQuickRenderControl
+48 (int (*)(...))QQuickRenderControl::~QQuickRenderControl
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QQuickRenderControl::renderWindow
+
+Class QQuickRenderControl
+ size=16 align=8
+ base size=16 base align=8
+QQuickRenderControl (0x0x7f3d425c2c98) 0
+ vptr=((& QQuickRenderControl::_ZTV19QQuickRenderControl) + 16u)
+ QObject (0x0x7f3d42243d20) 0
+ primary-for QQuickRenderControl (0x0x7f3d425c2c98)
+
+Class QQuickTextDocument::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQuickTextDocument::QPrivateSignal (0x0x7f3d42243e40) 0 empty
+
+Vtable for QQuickTextDocument
+QQuickTextDocument::_ZTV18QQuickTextDocument: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QQuickTextDocument)
+16 (int (*)(...))QQuickTextDocument::metaObject
+24 (int (*)(...))QQuickTextDocument::qt_metacast
+32 (int (*)(...))QQuickTextDocument::qt_metacall
+40 (int (*)(...))QQuickTextDocument::~QQuickTextDocument
+48 (int (*)(...))QQuickTextDocument::~QQuickTextDocument
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QQuickTextDocument
+ size=16 align=8
+ base size=16 base align=8
+QQuickTextDocument (0x0x7f3d425c2d00) 0
+ vptr=((& QQuickTextDocument::_ZTV18QQuickTextDocument) + 16u)
+ QObject (0x0x7f3d42243de0) 0
+ primary-for QQuickTextDocument (0x0x7f3d425c2d00)
+
+Class QSGGeometry::Attribute
+ size=16 align=4
+ base size=16 base align=4
+QSGGeometry::Attribute (0x0x7f3d4235c1e0) 0
+
+Class QSGGeometry::AttributeSet
+ size=16 align=8
+ base size=16 base align=8
+QSGGeometry::AttributeSet (0x0x7f3d4235c240) 0
+
+Class QSGGeometry::Point2D
+ size=8 align=4
+ base size=8 base align=4
+QSGGeometry::Point2D (0x0x7f3d4235c2a0) 0
+
+Class QSGGeometry::TexturedPoint2D
+ size=16 align=4
+ base size=16 base align=4
+QSGGeometry::TexturedPoint2D (0x0x7f3d4235c300) 0
+
+Class QSGGeometry::ColoredPoint2D
+ size=12 align=4
+ base size=12 base align=4
+QSGGeometry::ColoredPoint2D (0x0x7f3d4235c360) 0
+
+Vtable for QSGGeometry
+QSGGeometry::_ZTV11QSGGeometry: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QSGGeometry)
+16 (int (*)(...))QSGGeometry::~QSGGeometry
+24 (int (*)(...))QSGGeometry::~QSGGeometry
+
+Class QSGGeometry
+ size=128 align=8
+ base size=128 base align=8
+QSGGeometry (0x0x7f3d4235c180) 0
+ vptr=((& QSGGeometry::_ZTV11QSGGeometry) + 16u)
+
+Vtable for QSGNode
+QSGNode::_ZTV7QSGNode: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QSGNode)
+16 (int (*)(...))QSGNode::~QSGNode
+24 (int (*)(...))QSGNode::~QSGNode
+32 (int (*)(...))QSGNode::isSubtreeBlocked
+40 (int (*)(...))QSGNode::preprocess
+
+Class QSGNode
+ size=80 align=8
+ base size=80 base align=8
+QSGNode (0x0x7f3d4235c840) 0
+ vptr=((& QSGNode::_ZTV7QSGNode) + 16u)
+
+Vtable for QSGBasicGeometryNode
+QSGBasicGeometryNode::_ZTV20QSGBasicGeometryNode: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QSGBasicGeometryNode)
+16 (int (*)(...))QSGBasicGeometryNode::~QSGBasicGeometryNode
+24 (int (*)(...))QSGBasicGeometryNode::~QSGBasicGeometryNode
+32 (int (*)(...))QSGNode::isSubtreeBlocked
+40 (int (*)(...))QSGNode::preprocess
+
+Class QSGBasicGeometryNode
+ size=112 align=8
+ base size=112 base align=8
+QSGBasicGeometryNode (0x0x7f3d42393410) 0
+ vptr=((& QSGBasicGeometryNode::_ZTV20QSGBasicGeometryNode) + 16u)
+ QSGNode (0x0x7f3d4235cc00) 0
+ primary-for QSGBasicGeometryNode (0x0x7f3d42393410)
+
+Vtable for QSGGeometryNode
+QSGGeometryNode::_ZTV15QSGGeometryNode: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QSGGeometryNode)
+16 (int (*)(...))QSGGeometryNode::~QSGGeometryNode
+24 (int (*)(...))QSGGeometryNode::~QSGGeometryNode
+32 (int (*)(...))QSGNode::isSubtreeBlocked
+40 (int (*)(...))QSGNode::preprocess
+
+Class QSGGeometryNode
+ size=144 align=8
+ base size=144 base align=8
+QSGGeometryNode (0x0x7f3d42393478) 0
+ vptr=((& QSGGeometryNode::_ZTV15QSGGeometryNode) + 16u)
+ QSGBasicGeometryNode (0x0x7f3d423934e0) 0
+ primary-for QSGGeometryNode (0x0x7f3d42393478)
+ QSGNode (0x0x7f3d4235cc60) 0
+ primary-for QSGBasicGeometryNode (0x0x7f3d423934e0)
+
+Vtable for QSGClipNode
+QSGClipNode::_ZTV11QSGClipNode: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QSGClipNode)
+16 (int (*)(...))QSGClipNode::~QSGClipNode
+24 (int (*)(...))QSGClipNode::~QSGClipNode
+32 (int (*)(...))QSGNode::isSubtreeBlocked
+40 (int (*)(...))QSGNode::preprocess
+
+Class QSGClipNode
+ size=152 align=8
+ base size=152 base align=8
+QSGClipNode (0x0x7f3d42393548) 0
+ vptr=((& QSGClipNode::_ZTV11QSGClipNode) + 16u)
+ QSGBasicGeometryNode (0x0x7f3d423935b0) 0
+ primary-for QSGClipNode (0x0x7f3d42393548)
+ QSGNode (0x0x7f3d4235ccc0) 0
+ primary-for QSGBasicGeometryNode (0x0x7f3d423935b0)
+
+Vtable for QSGTransformNode
+QSGTransformNode::_ZTV16QSGTransformNode: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QSGTransformNode)
+16 (int (*)(...))QSGTransformNode::~QSGTransformNode
+24 (int (*)(...))QSGTransformNode::~QSGTransformNode
+32 (int (*)(...))QSGNode::isSubtreeBlocked
+40 (int (*)(...))QSGNode::preprocess
+
+Class QSGTransformNode
+ size=216 align=8
+ base size=216 base align=8
+QSGTransformNode (0x0x7f3d42393618) 0
+ vptr=((& QSGTransformNode::_ZTV16QSGTransformNode) + 16u)
+ QSGNode (0x0x7f3d4235cd20) 0
+ primary-for QSGTransformNode (0x0x7f3d42393618)
+
+Vtable for QSGRootNode
+QSGRootNode::_ZTV11QSGRootNode: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QSGRootNode)
+16 (int (*)(...))QSGRootNode::~QSGRootNode
+24 (int (*)(...))QSGRootNode::~QSGRootNode
+32 (int (*)(...))QSGNode::isSubtreeBlocked
+40 (int (*)(...))QSGNode::preprocess
+
+Class QSGRootNode
+ size=88 align=8
+ base size=88 base align=8
+QSGRootNode (0x0x7f3d42393680) 0
+ vptr=((& QSGRootNode::_ZTV11QSGRootNode) + 16u)
+ QSGNode (0x0x7f3d4235cd80) 0
+ primary-for QSGRootNode (0x0x7f3d42393680)
+
+Vtable for QSGOpacityNode
+QSGOpacityNode::_ZTV14QSGOpacityNode: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QSGOpacityNode)
+16 (int (*)(...))QSGOpacityNode::~QSGOpacityNode
+24 (int (*)(...))QSGOpacityNode::~QSGOpacityNode
+32 (int (*)(...))QSGOpacityNode::isSubtreeBlocked
+40 (int (*)(...))QSGNode::preprocess
+
+Class QSGOpacityNode
+ size=96 align=8
+ base size=96 base align=8
+QSGOpacityNode (0x0x7f3d42393820) 0
+ vptr=((& QSGOpacityNode::_ZTV14QSGOpacityNode) + 16u)
+ QSGNode (0x0x7f3d4235cf00) 0
+ primary-for QSGOpacityNode (0x0x7f3d42393820)
+
+Vtable for QSGNodeVisitor
+QSGNodeVisitor::_ZTV14QSGNodeVisitor: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QSGNodeVisitor)
+16 (int (*)(...))QSGNodeVisitor::~QSGNodeVisitor
+24 (int (*)(...))QSGNodeVisitor::~QSGNodeVisitor
+32 (int (*)(...))QSGNodeVisitor::enterTransformNode
+40 (int (*)(...))QSGNodeVisitor::leaveTransformNode
+48 (int (*)(...))QSGNodeVisitor::enterClipNode
+56 (int (*)(...))QSGNodeVisitor::leaveClipNode
+64 (int (*)(...))QSGNodeVisitor::enterGeometryNode
+72 (int (*)(...))QSGNodeVisitor::leaveGeometryNode
+80 (int (*)(...))QSGNodeVisitor::enterOpacityNode
+88 (int (*)(...))QSGNodeVisitor::leaveOpacityNode
+96 (int (*)(...))QSGNodeVisitor::visitNode
+104 (int (*)(...))QSGNodeVisitor::visitChildren
+
+Class QSGNodeVisitor
+ size=8 align=8
+ base size=8 base align=8
+QSGNodeVisitor (0x0x7f3d4235cf60) 0 nearly-empty
+ vptr=((& QSGNodeVisitor::_ZTV14QSGNodeVisitor) + 16u)
+
+Vtable for QSGRendererInterface
+QSGRendererInterface::_ZTV20QSGRendererInterface: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QSGRendererInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))QSGRendererInterface::getResource
+48 (int (*)(...))QSGRendererInterface::getResource
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+72 (int (*)(...))__cxa_pure_virtual
+
+Class QSGRendererInterface
+ size=8 align=8
+ base size=8 base align=8
+QSGRendererInterface (0x0x7f3d420e3000) 0 nearly-empty
+ vptr=((& QSGRendererInterface::_ZTV20QSGRendererInterface) + 16u)
+
+Class QQuickWindow::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQuickWindow::QPrivateSignal (0x0x7f3d420e3420) 0 empty
+
+Vtable for QQuickWindow
+QQuickWindow::_ZTV12QQuickWindow: 45u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QQuickWindow)
+16 (int (*)(...))QQuickWindow::metaObject
+24 (int (*)(...))QQuickWindow::qt_metacast
+32 (int (*)(...))QQuickWindow::qt_metacall
+40 (int (*)(...))QQuickWindow::~QQuickWindow
+48 (int (*)(...))QQuickWindow::~QQuickWindow
+56 (int (*)(...))QQuickWindow::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWindow::surfaceType
+120 (int (*)(...))QWindow::format
+128 (int (*)(...))QWindow::size
+136 (int (*)(...))QQuickWindow::accessibleRoot
+144 (int (*)(...))QQuickWindow::focusObject
+152 (int (*)(...))QQuickWindow::exposeEvent
+160 (int (*)(...))QQuickWindow::resizeEvent
+168 (int (*)(...))QWindow::moveEvent
+176 (int (*)(...))QQuickWindow::focusInEvent
+184 (int (*)(...))QQuickWindow::focusOutEvent
+192 (int (*)(...))QQuickWindow::showEvent
+200 (int (*)(...))QQuickWindow::hideEvent
+208 (int (*)(...))QQuickWindow::keyPressEvent
+216 (int (*)(...))QQuickWindow::keyReleaseEvent
+224 (int (*)(...))QQuickWindow::mousePressEvent
+232 (int (*)(...))QQuickWindow::mouseReleaseEvent
+240 (int (*)(...))QQuickWindow::mouseDoubleClickEvent
+248 (int (*)(...))QQuickWindow::mouseMoveEvent
+256 (int (*)(...))QQuickWindow::wheelEvent
+264 (int (*)(...))QWindow::touchEvent
+272 (int (*)(...))QWindow::tabletEvent
+280 (int (*)(...))QWindow::nativeEvent
+288 (int (*)(...))QWindow::surfaceHandle
+296 (int (*)(...))-16
+304 (int (*)(...))(& _ZTI12QQuickWindow)
+312 (int (*)(...))QQuickWindow::_ZThn16_N12QQuickWindowD1Ev
+320 (int (*)(...))QQuickWindow::_ZThn16_N12QQuickWindowD0Ev
+328 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv
+336 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv
+344 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv
+352 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv
+
+Class QQuickWindow
+ size=40 align=8
+ base size=40 base align=8
+QQuickWindow (0x0x7f3d42393a28) 0
+ vptr=((& QQuickWindow::_ZTV12QQuickWindow) + 16u)
+ QWindow (0x0x7f3d42120e00) 0
+ primary-for QQuickWindow (0x0x7f3d42393a28)
+ QObject (0x0x7f3d420e3360) 0
+ primary-for QWindow (0x0x7f3d42120e00)
+ QSurface (0x0x7f3d420e33c0) 16
+ vptr=((& QQuickWindow::_ZTV12QQuickWindow) + 312u)
+
+Class QQuickView::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQuickView::QPrivateSignal (0x0x7f3d420e37e0) 0 empty
+
+Vtable for QQuickView
+QQuickView::_ZTV10QQuickView: 45u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QQuickView)
+16 (int (*)(...))QQuickView::metaObject
+24 (int (*)(...))QQuickView::qt_metacast
+32 (int (*)(...))QQuickView::qt_metacall
+40 (int (*)(...))QQuickView::~QQuickView
+48 (int (*)(...))QQuickView::~QQuickView
+56 (int (*)(...))QQuickWindow::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QQuickView::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWindow::surfaceType
+120 (int (*)(...))QWindow::format
+128 (int (*)(...))QWindow::size
+136 (int (*)(...))QQuickWindow::accessibleRoot
+144 (int (*)(...))QQuickWindow::focusObject
+152 (int (*)(...))QQuickWindow::exposeEvent
+160 (int (*)(...))QQuickView::resizeEvent
+168 (int (*)(...))QWindow::moveEvent
+176 (int (*)(...))QQuickWindow::focusInEvent
+184 (int (*)(...))QQuickWindow::focusOutEvent
+192 (int (*)(...))QQuickWindow::showEvent
+200 (int (*)(...))QQuickWindow::hideEvent
+208 (int (*)(...))QQuickView::keyPressEvent
+216 (int (*)(...))QQuickView::keyReleaseEvent
+224 (int (*)(...))QQuickView::mousePressEvent
+232 (int (*)(...))QQuickView::mouseReleaseEvent
+240 (int (*)(...))QQuickWindow::mouseDoubleClickEvent
+248 (int (*)(...))QQuickView::mouseMoveEvent
+256 (int (*)(...))QQuickWindow::wheelEvent
+264 (int (*)(...))QWindow::touchEvent
+272 (int (*)(...))QWindow::tabletEvent
+280 (int (*)(...))QWindow::nativeEvent
+288 (int (*)(...))QWindow::surfaceHandle
+296 (int (*)(...))-16
+304 (int (*)(...))(& _ZTI10QQuickView)
+312 (int (*)(...))QQuickView::_ZThn16_N10QQuickViewD1Ev
+320 (int (*)(...))QQuickView::_ZThn16_N10QQuickViewD0Ev
+328 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv
+336 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv
+344 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv
+352 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv
+
+Class QQuickView
+ size=40 align=8
+ base size=40 base align=8
+QQuickView (0x0x7f3d42393b60) 0
+ vptr=((& QQuickView::_ZTV10QQuickView) + 16u)
+ QQuickWindow (0x0x7f3d42393bc8) 0
+ primary-for QQuickView (0x0x7f3d42393b60)
+ QWindow (0x0x7f3d421914d0) 0
+ primary-for QQuickWindow (0x0x7f3d42393bc8)
+ QObject (0x0x7f3d420e3720) 0
+ primary-for QWindow (0x0x7f3d421914d0)
+ QSurface (0x0x7f3d420e3780) 16
+ vptr=((& QQuickView::_ZTV10QQuickView) + 312u)
+
+Class QSGAbstractRenderer::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSGAbstractRenderer::QPrivateSignal (0x0x7f3d420e38a0) 0 empty
+
+Vtable for QSGAbstractRenderer
+QSGAbstractRenderer::_ZTV19QSGAbstractRenderer: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QSGAbstractRenderer)
+16 (int (*)(...))QSGAbstractRenderer::metaObject
+24 (int (*)(...))QSGAbstractRenderer::qt_metacast
+32 (int (*)(...))QSGAbstractRenderer::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+
+Class QSGAbstractRenderer
+ size=16 align=8
+ base size=16 base align=8
+QSGAbstractRenderer (0x0x7f3d42393c30) 0
+ vptr=((& QSGAbstractRenderer::_ZTV19QSGAbstractRenderer) + 16u)
+ QObject (0x0x7f3d420e3840) 0
+ primary-for QSGAbstractRenderer (0x0x7f3d42393c30)
+
+Class QSGEngine::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSGEngine::QPrivateSignal (0x0x7f3d420e3ae0) 0 empty
+
+Vtable for QSGEngine
+QSGEngine::_ZTV9QSGEngine: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QSGEngine)
+16 (int (*)(...))QSGEngine::metaObject
+24 (int (*)(...))QSGEngine::qt_metacast
+32 (int (*)(...))QSGEngine::qt_metacall
+40 (int (*)(...))QSGEngine::~QSGEngine
+48 (int (*)(...))QSGEngine::~QSGEngine
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QSGEngine
+ size=16 align=8
+ base size=16 base align=8
+QSGEngine (0x0x7f3d42393d68) 0
+ vptr=((& QSGEngine::_ZTV9QSGEngine) + 16u)
+ QObject (0x0x7f3d420e3a80) 0
+ primary-for QSGEngine (0x0x7f3d42393d68)
+
+Class QSGMaterialShader::RenderState
+ size=16 align=8
+ base size=16 base align=8
+QSGMaterialShader::RenderState (0x0x7f3d420e3d80) 0
+
+Vtable for QSGMaterialShader
+QSGMaterialShader::_ZTV17QSGMaterialShader: 12u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QSGMaterialShader)
+16 0u
+24 0u
+32 (int (*)(...))QSGMaterialShader::activate
+40 (int (*)(...))QSGMaterialShader::deactivate
+48 (int (*)(...))QSGMaterialShader::updateState
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))QSGMaterialShader::compile
+72 (int (*)(...))QSGMaterialShader::initialize
+80 (int (*)(...))QSGMaterialShader::vertexShader
+88 (int (*)(...))QSGMaterialShader::fragmentShader
+
+Class QSGMaterialShader
+ size=32 align=8
+ base size=32 base align=8
+QSGMaterialShader (0x0x7f3d420e3d20) 0
+ vptr=((& QSGMaterialShader::_ZTV17QSGMaterialShader) + 16u)
+
+Class QSGMaterialType
+ size=1 align=1
+ base size=0 base align=1
+QSGMaterialType (0x0x7f3d41e56060) 0 empty
+
+Vtable for QSGMaterial
+QSGMaterial::_ZTV11QSGMaterial: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QSGMaterial)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))QSGMaterial::compare
+
+Class QSGMaterial
+ size=24 align=8
+ base size=24 base align=8
+QSGMaterial (0x0x7f3d41e560c0) 0
+ vptr=((& QSGMaterial::_ZTV11QSGMaterial) + 16u)
+
+Vtable for QSGFlatColorMaterial
+QSGFlatColorMaterial::_ZTV20QSGFlatColorMaterial: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QSGFlatColorMaterial)
+16 (int (*)(...))QSGFlatColorMaterial::~QSGFlatColorMaterial
+24 (int (*)(...))QSGFlatColorMaterial::~QSGFlatColorMaterial
+32 (int (*)(...))QSGFlatColorMaterial::type
+40 (int (*)(...))QSGFlatColorMaterial::createShader
+48 (int (*)(...))QSGFlatColorMaterial::compare
+
+Class QSGFlatColorMaterial
+ size=40 align=8
+ base size=40 base align=8
+QSGFlatColorMaterial (0x0x7f3d41e630d0) 0
+ vptr=((& QSGFlatColorMaterial::_ZTV20QSGFlatColorMaterial) + 16u)
+ QSGMaterial (0x0x7f3d41e562a0) 0
+ primary-for QSGFlatColorMaterial (0x0x7f3d41e630d0)
+
+Class QSGTexture::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSGTexture::QPrivateSignal (0x0x7f3d41e56360) 0 empty
+
+Vtable for QSGTexture
+QSGTexture::_ZTV10QSGTexture: 22u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QSGTexture)
+16 (int (*)(...))QSGTexture::metaObject
+24 (int (*)(...))QSGTexture::qt_metacast
+32 (int (*)(...))QSGTexture::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))QSGTexture::normalizedTextureSubRect
+152 (int (*)(...))QSGTexture::isAtlasTexture
+160 (int (*)(...))QSGTexture::removedFromAtlas
+168 (int (*)(...))__cxa_pure_virtual
+
+Class QSGTexture
+ size=16 align=8
+ base size=16 base align=8
+QSGTexture (0x0x7f3d41e63138) 0
+ vptr=((& QSGTexture::_ZTV10QSGTexture) + 16u)
+ QObject (0x0x7f3d41e56300) 0
+ primary-for QSGTexture (0x0x7f3d41e63138)
+
+Class QSGDynamicTexture::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSGDynamicTexture::QPrivateSignal (0x0x7f3d41e56420) 0 empty
+
+Vtable for QSGDynamicTexture
+QSGDynamicTexture::_ZTV17QSGDynamicTexture: 23u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QSGDynamicTexture)
+16 (int (*)(...))QSGDynamicTexture::metaObject
+24 (int (*)(...))QSGDynamicTexture::qt_metacast
+32 (int (*)(...))QSGDynamicTexture::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))QSGTexture::normalizedTextureSubRect
+152 (int (*)(...))QSGTexture::isAtlasTexture
+160 (int (*)(...))QSGTexture::removedFromAtlas
+168 (int (*)(...))__cxa_pure_virtual
+176 (int (*)(...))__cxa_pure_virtual
+
+Class QSGDynamicTexture
+ size=16 align=8
+ base size=16 base align=8
+QSGDynamicTexture (0x0x7f3d41e631a0) 0
+ vptr=((& QSGDynamicTexture::_ZTV17QSGDynamicTexture) + 16u)
+ QSGTexture (0x0x7f3d41e63208) 0
+ primary-for QSGDynamicTexture (0x0x7f3d41e631a0)
+ QObject (0x0x7f3d41e563c0) 0
+ primary-for QSGTexture (0x0x7f3d41e63208)
+
+Vtable for QSGImageNode
+QSGImageNode::_ZTV12QSGImageNode: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QSGImageNode)
+16 0u
+24 0u
+32 (int (*)(...))QSGNode::isSubtreeBlocked
+40 (int (*)(...))QSGNode::preprocess
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+72 (int (*)(...))__cxa_pure_virtual
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))__cxa_pure_virtual
+96 (int (*)(...))__cxa_pure_virtual
+104 (int (*)(...))__cxa_pure_virtual
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))__cxa_pure_virtual
+
+Class QSGImageNode
+ size=144 align=8
+ base size=144 base align=8
+QSGImageNode (0x0x7f3d41e63270) 0
+ vptr=((& QSGImageNode::_ZTV12QSGImageNode) + 16u)
+ QSGGeometryNode (0x0x7f3d41e632d8) 0
+ primary-for QSGImageNode (0x0x7f3d41e63270)
+ QSGBasicGeometryNode (0x0x7f3d41e63340) 0
+ primary-for QSGGeometryNode (0x0x7f3d41e632d8)
+ QSGNode (0x0x7f3d41e56480) 0
+ primary-for QSGBasicGeometryNode (0x0x7f3d41e63340)
+
+Vtable for QSGNinePatchNode
+QSGNinePatchNode::_ZTV16QSGNinePatchNode: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QSGNinePatchNode)
+16 0u
+24 0u
+32 (int (*)(...))QSGNode::isSubtreeBlocked
+40 (int (*)(...))QSGNode::preprocess
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+72 (int (*)(...))__cxa_pure_virtual
+80 (int (*)(...))__cxa_pure_virtual
+
+Class QSGNinePatchNode
+ size=144 align=8
+ base size=144 base align=8
+QSGNinePatchNode (0x0x7f3d41e63478) 0
+ vptr=((& QSGNinePatchNode::_ZTV16QSGNinePatchNode) + 16u)
+ QSGGeometryNode (0x0x7f3d41e634e0) 0
+ primary-for QSGNinePatchNode (0x0x7f3d41e63478)
+ QSGBasicGeometryNode (0x0x7f3d41e63548) 0
+ primary-for QSGGeometryNode (0x0x7f3d41e634e0)
+ QSGNode (0x0x7f3d41e56660) 0
+ primary-for QSGBasicGeometryNode (0x0x7f3d41e63548)
+
+Vtable for QSGRectangleNode
+QSGRectangleNode::_ZTV16QSGRectangleNode: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QSGRectangleNode)
+16 0u
+24 0u
+32 (int (*)(...))QSGNode::isSubtreeBlocked
+40 (int (*)(...))QSGNode::preprocess
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+72 (int (*)(...))__cxa_pure_virtual
+
+Class QSGRectangleNode
+ size=144 align=8
+ base size=144 base align=8
+QSGRectangleNode (0x0x7f3d41e635b0) 0
+ vptr=((& QSGRectangleNode::_ZTV16QSGRectangleNode) + 16u)
+ QSGGeometryNode (0x0x7f3d41e63618) 0
+ primary-for QSGRectangleNode (0x0x7f3d41e635b0)
+ QSGBasicGeometryNode (0x0x7f3d41e63680) 0
+ primary-for QSGGeometryNode (0x0x7f3d41e63618)
+ QSGNode (0x0x7f3d41e566c0) 0
+ primary-for QSGBasicGeometryNode (0x0x7f3d41e63680)
+
+Vtable for QSGRenderNode::RenderState
+QSGRenderNode::RenderState::_ZTVN13QSGRenderNode11RenderStateE: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN13QSGRenderNode11RenderStateE)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+72 (int (*)(...))__cxa_pure_virtual
+80 (int (*)(...))QSGRenderNode::RenderState::get
+
+Class QSGRenderNode::RenderState
+ size=8 align=8
+ base size=8 base align=8
+QSGRenderNode::RenderState (0x0x7f3d41e56780) 0 nearly-empty
+ vptr=((& QSGRenderNode::RenderState::_ZTVN13QSGRenderNode11RenderStateE) + 16u)
+
+Vtable for QSGRenderNode
+QSGRenderNode::_ZTV13QSGRenderNode: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QSGRenderNode)
+16 0u
+24 0u
+32 (int (*)(...))QSGNode::isSubtreeBlocked
+40 (int (*)(...))QSGNode::preprocess
+48 (int (*)(...))QSGRenderNode::changedStates
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))QSGRenderNode::releaseResources
+72 (int (*)(...))QSGRenderNode::flags
+80 (int (*)(...))QSGRenderNode::rect
+
+Class QSGRenderNode
+ size=88 align=8
+ base size=88 base align=8
+QSGRenderNode (0x0x7f3d41e636e8) 0
+ vptr=((& QSGRenderNode::_ZTV13QSGRenderNode) + 16u)
+ QSGNode (0x0x7f3d41e56720) 0
+ primary-for QSGRenderNode (0x0x7f3d41e636e8)
+
+Vtable for QSGSimpleRectNode
+QSGSimpleRectNode::_ZTV17QSGSimpleRectNode: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QSGSimpleRectNode)
+16 (int (*)(...))QSGSimpleRectNode::~QSGSimpleRectNode
+24 (int (*)(...))QSGSimpleRectNode::~QSGSimpleRectNode
+32 (int (*)(...))QSGNode::isSubtreeBlocked
+40 (int (*)(...))QSGNode::preprocess
+
+Class QSGSimpleRectNode
+ size=320 align=8
+ base size=320 base align=8
+QSGSimpleRectNode (0x0x7f3d41e63b60) 0
+ vptr=((& QSGSimpleRectNode::_ZTV17QSGSimpleRectNode) + 16u)
+ QSGGeometryNode (0x0x7f3d41e63bc8) 0
+ primary-for QSGSimpleRectNode (0x0x7f3d41e63b60)
+ QSGBasicGeometryNode (0x0x7f3d41e63c30) 0
+ primary-for QSGGeometryNode (0x0x7f3d41e63bc8)
+ QSGNode (0x0x7f3d41e56d80) 0
+ primary-for QSGBasicGeometryNode (0x0x7f3d41e63c30)
+
+Vtable for QSGOpaqueTextureMaterial
+QSGOpaqueTextureMaterial::_ZTV24QSGOpaqueTextureMaterial: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QSGOpaqueTextureMaterial)
+16 (int (*)(...))QSGOpaqueTextureMaterial::~QSGOpaqueTextureMaterial
+24 (int (*)(...))QSGOpaqueTextureMaterial::~QSGOpaqueTextureMaterial
+32 (int (*)(...))QSGOpaqueTextureMaterial::type
+40 (int (*)(...))QSGOpaqueTextureMaterial::createShader
+48 (int (*)(...))QSGOpaqueTextureMaterial::compare
+
+Class QSGOpaqueTextureMaterial
+ size=40 align=8
+ base size=36 base align=8
+QSGOpaqueTextureMaterial (0x0x7f3d41e63c98) 0
+ vptr=((& QSGOpaqueTextureMaterial::_ZTV24QSGOpaqueTextureMaterial) + 16u)
+ QSGMaterial (0x0x7f3d41e56de0) 0
+ primary-for QSGOpaqueTextureMaterial (0x0x7f3d41e63c98)
+
+Vtable for QSGTextureMaterial
+QSGTextureMaterial::_ZTV18QSGTextureMaterial: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QSGTextureMaterial)
+16 (int (*)(...))QSGTextureMaterial::~QSGTextureMaterial
+24 (int (*)(...))QSGTextureMaterial::~QSGTextureMaterial
+32 (int (*)(...))QSGTextureMaterial::type
+40 (int (*)(...))QSGTextureMaterial::createShader
+48 (int (*)(...))QSGOpaqueTextureMaterial::compare
+
+Class QSGTextureMaterial
+ size=40 align=8
+ base size=36 base align=8
+QSGTextureMaterial (0x0x7f3d41e63d00) 0
+ vptr=((& QSGTextureMaterial::_ZTV18QSGTextureMaterial) + 16u)
+ QSGOpaqueTextureMaterial (0x0x7f3d41e63d68) 0
+ primary-for QSGTextureMaterial (0x0x7f3d41e63d00)
+ QSGMaterial (0x0x7f3d41e56e40) 0
+ primary-for QSGOpaqueTextureMaterial (0x0x7f3d41e63d68)
+
+Vtable for QSGSimpleTextureNode
+QSGSimpleTextureNode::_ZTV20QSGSimpleTextureNode: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QSGSimpleTextureNode)
+16 (int (*)(...))QSGSimpleTextureNode::~QSGSimpleTextureNode
+24 (int (*)(...))QSGSimpleTextureNode::~QSGSimpleTextureNode
+32 (int (*)(...))QSGNode::isSubtreeBlocked
+40 (int (*)(...))QSGNode::preprocess
+
+Class QSGSimpleTextureNode
+ size=384 align=8
+ base size=384 base align=8
+QSGSimpleTextureNode (0x0x7f3d41e63dd0) 0
+ vptr=((& QSGSimpleTextureNode::_ZTV20QSGSimpleTextureNode) + 16u)
+ QSGGeometryNode (0x0x7f3d41e63e38) 0
+ primary-for QSGSimpleTextureNode (0x0x7f3d41e63dd0)
+ QSGBasicGeometryNode (0x0x7f3d41e63ea0) 0
+ primary-for QSGGeometryNode (0x0x7f3d41e63e38)
+ QSGNode (0x0x7f3d41e56ea0) 0
+ primary-for QSGBasicGeometryNode (0x0x7f3d41e63ea0)
+
+Class QSGTextureProvider::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSGTextureProvider::QPrivateSignal (0x0x7f3d41c20180) 0 empty
+
+Vtable for QSGTextureProvider
+QSGTextureProvider::_ZTV18QSGTextureProvider: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QSGTextureProvider)
+16 (int (*)(...))QSGTextureProvider::metaObject
+24 (int (*)(...))QSGTextureProvider::qt_metacast
+32 (int (*)(...))QSGTextureProvider::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+
+Class QSGTextureProvider
+ size=16 align=8
+ base size=16 base align=8
+QSGTextureProvider (0x0x7f3d41c23068) 0
+ vptr=((& QSGTextureProvider::_ZTV18QSGTextureProvider) + 16u)
+ QObject (0x0x7f3d41c20120) 0
+ primary-for QSGTextureProvider (0x0x7f3d41c23068)
+
+Vtable for QSGVertexColorMaterial
+QSGVertexColorMaterial::_ZTV22QSGVertexColorMaterial: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI22QSGVertexColorMaterial)
+16 (int (*)(...))QSGVertexColorMaterial::~QSGVertexColorMaterial
+24 (int (*)(...))QSGVertexColorMaterial::~QSGVertexColorMaterial
+32 (int (*)(...))QSGVertexColorMaterial::type
+40 (int (*)(...))QSGVertexColorMaterial::createShader
+48 (int (*)(...))QSGVertexColorMaterial::compare
+
+Class QSGVertexColorMaterial
+ size=24 align=8
+ base size=24 base align=8
+QSGVertexColorMaterial (0x0x7f3d41c230d0) 0
+ vptr=((& QSGVertexColorMaterial::_ZTV22QSGVertexColorMaterial) + 16u)
+ QSGMaterial (0x0x7f3d41c201e0) 0
+ primary-for QSGVertexColorMaterial (0x0x7f3d41c230d0)
+
diff --git a/tests/auto/bic/data/QtQuickTest.5.10.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtQuickTest.5.10.0.linux-gcc-amd64.txt
new file mode 100644
index 0000000000..dd9e0aba00
--- /dev/null
+++ b/tests/auto/bic/data/QtQuickTest.5.10.0.linux-gcc-amd64.txt
@@ -0,0 +1,19193 @@
+Class std::__failure_type
+ size=1 align=1
+ base size=0 base align=1
+std::__failure_type (0x0x7f88529cc720) 0 empty
+
+Class std::__do_is_destructible_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_is_destructible_impl (0x0x7f8852a26ea0) 0 empty
+
+Class std::__do_is_nt_destructible_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_is_nt_destructible_impl (0x0x7f8852a4e120) 0 empty
+
+Class std::__do_is_default_constructible_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_is_default_constructible_impl (0x0x7f8852a4e360) 0 empty
+
+Class std::__do_is_static_castable_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_is_static_castable_impl (0x0x7f8852a4e5a0) 0 empty
+
+Class std::__do_is_direct_constructible_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_is_direct_constructible_impl (0x0x7f8852a4e720) 0 empty
+
+Class std::__do_is_nary_constructible_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_is_nary_constructible_impl (0x0x7f8852a4eae0) 0 empty
+
+Class std::__do_common_type_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_common_type_impl (0x0x7f8852b082a0) 0 empty
+
+Class std::__do_member_type_wrapper
+ size=1 align=1
+ base size=0 base align=1
+std::__do_member_type_wrapper (0x0x7f8852b08360) 0 empty
+
+Class std::__result_of_memfun_ref_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__result_of_memfun_ref_impl (0x0x7f8852b086c0) 0 empty
+
+Class std::__result_of_memfun_deref_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__result_of_memfun_deref_impl (0x0x7f8852b08780) 0 empty
+
+Class std::__result_of_memobj_ref_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__result_of_memobj_ref_impl (0x0x7f8852b08840) 0 empty
+
+Class std::__result_of_memobj_deref_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__result_of_memobj_deref_impl (0x0x7f8852b08900) 0 empty
+
+Class std::__result_of_other_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__result_of_other_impl (0x0x7f8852b08ba0) 0 empty
+
+Class std::piecewise_construct_t
+ size=1 align=1
+ base size=0 base align=1
+std::piecewise_construct_t (0x0x7f8852b08d80) 0 empty
+
+Class std::__true_type
+ size=1 align=1
+ base size=0 base align=1
+std::__true_type (0x0x7f8852682240) 0 empty
+
+Class std::__false_type
+ size=1 align=1
+ base size=0 base align=1
+std::__false_type (0x0x7f88526822a0) 0 empty
+
+Class std::input_iterator_tag
+ size=1 align=1
+ base size=0 base align=1
+std::input_iterator_tag (0x0x7f88526bcf00) 0 empty
+
+Class std::output_iterator_tag
+ size=1 align=1
+ base size=0 base align=1
+std::output_iterator_tag (0x0x7f88526bcf60) 0 empty
+
+Class std::forward_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::forward_iterator_tag (0x0x7f8852b393a8) 0 empty
+ std::input_iterator_tag (0x0x7f88526ec000) 0 empty
+
+Class std::bidirectional_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::bidirectional_iterator_tag (0x0x7f8852b39410) 0 empty
+ std::forward_iterator_tag (0x0x7f8852b39478) 0 empty
+ std::input_iterator_tag (0x0x7f88526ec060) 0 empty
+
+Class std::random_access_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::random_access_iterator_tag (0x0x7f8852b394e0) 0 empty
+ std::bidirectional_iterator_tag (0x0x7f8852b39548) 0 empty
+ std::forward_iterator_tag (0x0x7f8852b395b0) 0 empty
+ std::input_iterator_tag (0x0x7f88526ec0c0) 0 empty
+
+Class __gnu_cxx::__ops::_Iter_less_iter
+ size=1 align=1
+ base size=0 base align=1
+__gnu_cxx::__ops::_Iter_less_iter (0x0x7f88526ecd20) 0 empty
+
+Class __gnu_cxx::__ops::_Iter_less_val
+ size=1 align=1
+ base size=0 base align=1
+__gnu_cxx::__ops::_Iter_less_val (0x0x7f88526ecd80) 0 empty
+
+Class __gnu_cxx::__ops::_Val_less_iter
+ size=1 align=1
+ base size=0 base align=1
+__gnu_cxx::__ops::_Val_less_iter (0x0x7f88526ecde0) 0 empty
+
+Class __gnu_cxx::__ops::_Iter_equal_to_iter
+ size=1 align=1
+ base size=0 base align=1
+__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7f88526ece40) 0 empty
+
+Class __gnu_cxx::__ops::_Iter_equal_to_val
+ size=1 align=1
+ base size=0 base align=1
+__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7f88526ecea0) 0 empty
+
+Class wait
+ size=4 align=4
+ base size=4 base align=4
+wait (0x0x7f88527b49c0) 0
+
+Class __locale_struct
+ size=232 align=8
+ base size=232 base align=8
+__locale_struct (0x0x7f88527b4c00) 0
+
+Class timespec
+ size=16 align=8
+ base size=16 base align=8
+timespec (0x0x7f88527b4cc0) 0
+
+Class timeval
+ size=16 align=8
+ base size=16 base align=8
+timeval (0x0x7f88527b4d20) 0
+
+Class pthread_attr_t
+ size=56 align=8
+ base size=56 base align=8
+pthread_attr_t (0x0x7f88527b4de0) 0
+
+Class __pthread_internal_list
+ size=16 align=8
+ base size=16 base align=8
+__pthread_internal_list (0x0x7f88527b4e40) 0
+
+Class random_data
+ size=48 align=8
+ base size=48 base align=8
+random_data (0x0x7f885285b300) 0
+
+Class drand48_data
+ size=24 align=8
+ base size=24 base align=8
+drand48_data (0x0x7f885285b360) 0
+
+Vtable for std::exception
+std::exception::_ZTVSt9exception: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt9exception)
+16 (int (*)(...))std::exception::~exception
+24 (int (*)(...))std::exception::~exception
+32 (int (*)(...))std::exception::what
+
+Class std::exception
+ size=8 align=8
+ base size=8 base align=8
+std::exception (0x0x7f885285b3c0) 0 nearly-empty
+ vptr=((& std::exception::_ZTVSt9exception) + 16u)
+
+Vtable for std::bad_exception
+std::bad_exception::_ZTVSt13bad_exception: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt13bad_exception)
+16 (int (*)(...))std::bad_exception::~bad_exception
+24 (int (*)(...))std::bad_exception::~bad_exception
+32 (int (*)(...))std::bad_exception::what
+
+Class std::bad_exception
+ size=8 align=8
+ base size=8 base align=8
+std::bad_exception (0x0x7f8852b39af8) 0 nearly-empty
+ vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u)
+ std::exception (0x0x7f885285b420) 0 nearly-empty
+ primary-for std::bad_exception (0x0x7f8852b39af8)
+
+Class std::__exception_ptr::exception_ptr
+ size=8 align=8
+ base size=8 base align=8
+std::__exception_ptr::exception_ptr (0x0x7f885285b480) 0
+
+Vtable for std::nested_exception
+std::nested_exception::_ZTVSt16nested_exception: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt16nested_exception)
+16 (int (*)(...))std::nested_exception::~nested_exception
+24 (int (*)(...))std::nested_exception::~nested_exception
+
+Class std::nested_exception
+ size=16 align=8
+ base size=16 base align=8
+std::nested_exception (0x0x7f885285b4e0) 0
+ vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16u)
+
+Vtable for std::bad_alloc
+std::bad_alloc::_ZTVSt9bad_alloc: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt9bad_alloc)
+16 (int (*)(...))std::bad_alloc::~bad_alloc
+24 (int (*)(...))std::bad_alloc::~bad_alloc
+32 (int (*)(...))std::bad_alloc::what
+
+Class std::bad_alloc
+ size=8 align=8
+ base size=8 base align=8
+std::bad_alloc (0x0x7f8852b39d00) 0 nearly-empty
+ vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u)
+ std::exception (0x0x7f885285b900) 0 nearly-empty
+ primary-for std::bad_alloc (0x0x7f8852b39d00)
+
+Vtable for std::bad_array_new_length
+std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt20bad_array_new_length)
+16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length
+24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length
+32 (int (*)(...))std::bad_array_new_length::what
+
+Class std::bad_array_new_length
+ size=8 align=8
+ base size=8 base align=8
+std::bad_array_new_length (0x0x7f8852b39d68) 0 nearly-empty
+ vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16u)
+ std::bad_alloc (0x0x7f8852b39dd0) 0 nearly-empty
+ primary-for std::bad_array_new_length (0x0x7f8852b39d68)
+ std::exception (0x0x7f885285b960) 0 nearly-empty
+ primary-for std::bad_alloc (0x0x7f8852b39dd0)
+
+Class std::nothrow_t
+ size=1 align=1
+ base size=0 base align=1
+std::nothrow_t (0x0x7f885285b9c0) 0 empty
+
+Class __exception
+ size=40 align=8
+ base size=40 base align=8
+__exception (0x0x7f88525d5600) 0
+
+Class lconv
+ size=96 align=8
+ base size=96 base align=8
+lconv (0x0x7f88523e6300) 0
+
+Vtable for __cxxabiv1::__forced_unwind
+__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class __cxxabiv1::__forced_unwind
+ size=8 align=8
+ base size=8 base align=8
+__cxxabiv1::__forced_unwind (0x0x7f88523e6360) 0 nearly-empty
+ vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u)
+
+Class sched_param
+ size=4 align=4
+ base size=4 base align=4
+sched_param (0x0x7f8852085240) 0
+
+Class __sched_param
+ size=4 align=4
+ base size=4 base align=4
+__sched_param (0x0x7f88520852a0) 0
+
+Class timex
+ size=208 align=8
+ base size=208 base align=8
+timex (0x0x7f8852085360) 0
+
+Class tm
+ size=56 align=8
+ base size=56 base align=8
+tm (0x0x7f88520853c0) 0
+
+Class itimerspec
+ size=32 align=8
+ base size=32 base align=8
+itimerspec (0x0x7f8852085420) 0
+
+Class _pthread_cleanup_buffer
+ size=32 align=8
+ base size=32 base align=8
+_pthread_cleanup_buffer (0x0x7f8852085480) 0
+
+Class __pthread_cleanup_frame
+ size=24 align=8
+ base size=24 base align=8
+__pthread_cleanup_frame (0x0x7f88520855a0) 0
+
+Class __pthread_cleanup_class
+ size=24 align=8
+ base size=24 base align=8
+__pthread_cleanup_class (0x0x7f8852085600) 0
+
+Class _IO_marker
+ size=24 align=8
+ base size=24 base align=8
+_IO_marker (0x0x7f8852085a20) 0
+
+Class _IO_FILE
+ size=216 align=8
+ base size=216 base align=8
+_IO_FILE (0x0x7f8852085a80) 0
+
+Class std::_Hash_impl
+ size=1 align=1
+ base size=0 base align=1
+std::_Hash_impl (0x0x7f8851fbb2a0) 0 empty
+
+Class std::_Fnv_hash_impl
+ size=1 align=1
+ base size=0 base align=1
+std::_Fnv_hash_impl (0x0x7f8851fbb300) 0 empty
+
+Class std::__numeric_limits_base
+ size=1 align=1
+ base size=0 base align=1
+std::__numeric_limits_base (0x0x7f8851c8b2a0) 0 empty
+
+Class std::_Bit_reference
+ size=16 align=8
+ base size=16 base align=8
+std::_Bit_reference (0x0x7f8851e460c0) 0
+
+Class std::_Bit_iterator_base
+ size=16 align=8
+ base size=12 base align=8
+std::_Bit_iterator_base (0x0x7f8851fd0b60) 0
+ std::iterator<std::random_access_iterator_tag, bool> (0x0x7f8851e46180) 0 empty
+
+Class std::_Bit_iterator
+ size=16 align=8
+ base size=12 base align=8
+std::_Bit_iterator (0x0x7f8851fd0bc8) 0
+ std::_Bit_iterator_base (0x0x7f8851fd0c30) 0
+ std::iterator<std::random_access_iterator_tag, bool> (0x0x7f8851e461e0) 0 empty
+
+Class std::_Bit_const_iterator
+ size=16 align=8
+ base size=12 base align=8
+std::_Bit_const_iterator (0x0x7f8851fd0c98) 0
+ std::_Bit_iterator_base (0x0x7f8851fd0d00) 0
+ std::iterator<std::random_access_iterator_tag, bool> (0x0x7f8851e46240) 0 empty
+
+Class std::random_device
+ size=5000 align=8
+ base size=5000 base align=8
+std::random_device (0x0x7f8851c69060) 0
+
+Class std::bernoulli_distribution::param_type
+ size=8 align=8
+ base size=8 base align=8
+std::bernoulli_distribution::param_type (0x0x7f8851c69de0) 0
+
+Class std::bernoulli_distribution
+ size=8 align=8
+ base size=8 base align=8
+std::bernoulli_distribution (0x0x7f8851c69d80) 0
+
+Class std::seed_seq
+ size=24 align=8
+ base size=24 base align=8
+std::seed_seq (0x0x7f88519afd80) 0
+
+Class qIsNull(double)::U
+ size=8 align=8
+ base size=8 base align=8
+qIsNull(double)::U (0x0x7f88505bd8a0) 0
+
+Class qIsNull(float)::U
+ size=4 align=4
+ base size=4 base align=4
+qIsNull(float)::U (0x0x7f88505bd900) 0
+
+Class QSysInfo
+ size=1 align=1
+ base size=0 base align=1
+QSysInfo (0x0x7f88502aa3c0) 0 empty
+
+Class QMessageLogContext
+ size=32 align=8
+ base size=32 base align=8
+QMessageLogContext (0x0x7f88502aa420) 0
+
+Class QMessageLogger
+ size=32 align=8
+ base size=32 base align=8
+QMessageLogger (0x0x7f88502aa480) 0
+
+Class QFlag
+ size=4 align=4
+ base size=4 base align=4
+QFlag (0x0x7f88502aa4e0) 0
+
+Class QIncompatibleFlag
+ size=4 align=4
+ base size=4 base align=4
+QIncompatibleFlag (0x0x7f88502aa780) 0
+
+Class std::__atomic_flag_base
+ size=1 align=1
+ base size=1 base align=1
+std::__atomic_flag_base (0x0x7f88502aacc0) 0
+
+Class std::atomic_flag
+ size=1 align=1
+ base size=1 base align=1
+std::atomic_flag (0x0x7f885029ca28) 0
+ std::__atomic_flag_base (0x0x7f88502aad20) 0
+
+Class QAtomicInt
+ size=4 align=4
+ base size=4 base align=4
+QAtomicInt (0x0x7f88502071a0) 0
+ QAtomicInteger<int> (0x0x7f8850207208) 0
+ QBasicAtomicInteger<int> (0x0x7f8850251480) 0
+
+Class QInternal
+ size=1 align=1
+ base size=0 base align=1
+QInternal (0x0x7f884fd08a20) 0 empty
+
+Class QtPrivate::QSlotObjectBase
+ size=16 align=8
+ base size=16 base align=8
+QtPrivate::QSlotObjectBase (0x0x7f884fadca80) 0
+
+Class QGenericArgument
+ size=16 align=8
+ base size=16 base align=8
+QGenericArgument (0x0x7f884fadcba0) 0
+
+Class QGenericReturnArgument
+ size=16 align=8
+ base size=16 base align=8
+QGenericReturnArgument (0x0x7f884fccac30) 0
+ QGenericArgument (0x0x7f884fadcc00) 0
+
+Class QMetaObject
+ size=48 align=8
+ base size=48 base align=8
+QMetaObject (0x0x7f884fadcd80) 0
+
+Class QMetaObject::Connection
+ size=8 align=8
+ base size=8 base align=8
+QMetaObject::Connection (0x0x7f884fadce40) 0
+
+Class QLatin1Char
+ size=1 align=1
+ base size=1 base align=1
+QLatin1Char (0x0x7f884fbd6ea0) 0
+
+Class QChar
+ size=2 align=2
+ base size=2 base align=2
+QChar (0x0x7f884fbd6f00) 0
+
+Class QtPrivate::RefCount
+ size=4 align=4
+ base size=4 base align=4
+QtPrivate::RefCount (0x0x7f884f87f1e0) 0
+
+Class QArrayData
+ size=24 align=8
+ base size=24 base align=8
+QArrayData (0x0x7f884f87f240) 0
+
+Class QtPrivate::QContainerImplHelper
+ size=1 align=1
+ base size=0 base align=1
+QtPrivate::QContainerImplHelper (0x0x7f884f87f5a0) 0 empty
+
+Class std::locale
+ size=8 align=8
+ base size=8 base align=8
+std::locale (0x0x7f884f87f600) 0
+
+Vtable for std::locale::facet
+std::locale::facet::_ZTVNSt6locale5facetE: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt6locale5facetE)
+16 (int (*)(...))std::locale::facet::~facet
+24 (int (*)(...))std::locale::facet::~facet
+
+Class std::locale::facet
+ size=16 align=8
+ base size=12 base align=8
+std::locale::facet (0x0x7f884f87f660) 0
+ vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u)
+
+Class std::locale::id
+ size=8 align=8
+ base size=8 base align=8
+std::locale::id (0x0x7f884f87f6c0) 0
+
+Class std::locale::_Impl
+ size=40 align=8
+ base size=40 base align=8
+std::locale::_Impl (0x0x7f884f87f720) 0
+
+Class std::__cow_string
+ size=8 align=8
+ base size=8 base align=8
+std::__cow_string (0x0x7f884f87fae0) 0
+
+Vtable for std::logic_error
+std::logic_error::_ZTVSt11logic_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt11logic_error)
+16 (int (*)(...))std::logic_error::~logic_error
+24 (int (*)(...))std::logic_error::~logic_error
+32 (int (*)(...))std::logic_error::what
+
+Class std::logic_error
+ size=16 align=8
+ base size=16 base align=8
+std::logic_error (0x0x7f884f989208) 0
+ vptr=((& std::logic_error::_ZTVSt11logic_error) + 16u)
+ std::exception (0x0x7f884f87fba0) 0 nearly-empty
+ primary-for std::logic_error (0x0x7f884f989208)
+
+Vtable for std::domain_error
+std::domain_error::_ZTVSt12domain_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt12domain_error)
+16 (int (*)(...))std::domain_error::~domain_error
+24 (int (*)(...))std::domain_error::~domain_error
+32 (int (*)(...))std::logic_error::what
+
+Class std::domain_error
+ size=16 align=8
+ base size=16 base align=8
+std::domain_error (0x0x7f884f989270) 0
+ vptr=((& std::domain_error::_ZTVSt12domain_error) + 16u)
+ std::logic_error (0x0x7f884f9892d8) 0
+ primary-for std::domain_error (0x0x7f884f989270)
+ std::exception (0x0x7f884f87fc00) 0 nearly-empty
+ primary-for std::logic_error (0x0x7f884f9892d8)
+
+Vtable for std::invalid_argument
+std::invalid_argument::_ZTVSt16invalid_argument: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt16invalid_argument)
+16 (int (*)(...))std::invalid_argument::~invalid_argument
+24 (int (*)(...))std::invalid_argument::~invalid_argument
+32 (int (*)(...))std::logic_error::what
+
+Class std::invalid_argument
+ size=16 align=8
+ base size=16 base align=8
+std::invalid_argument (0x0x7f884f989340) 0
+ vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16u)
+ std::logic_error (0x0x7f884f9893a8) 0
+ primary-for std::invalid_argument (0x0x7f884f989340)
+ std::exception (0x0x7f884f87fc60) 0 nearly-empty
+ primary-for std::logic_error (0x0x7f884f9893a8)
+
+Vtable for std::length_error
+std::length_error::_ZTVSt12length_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt12length_error)
+16 (int (*)(...))std::length_error::~length_error
+24 (int (*)(...))std::length_error::~length_error
+32 (int (*)(...))std::logic_error::what
+
+Class std::length_error
+ size=16 align=8
+ base size=16 base align=8
+std::length_error (0x0x7f884f989410) 0
+ vptr=((& std::length_error::_ZTVSt12length_error) + 16u)
+ std::logic_error (0x0x7f884f989478) 0
+ primary-for std::length_error (0x0x7f884f989410)
+ std::exception (0x0x7f884f87fcc0) 0 nearly-empty
+ primary-for std::logic_error (0x0x7f884f989478)
+
+Vtable for std::out_of_range
+std::out_of_range::_ZTVSt12out_of_range: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt12out_of_range)
+16 (int (*)(...))std::out_of_range::~out_of_range
+24 (int (*)(...))std::out_of_range::~out_of_range
+32 (int (*)(...))std::logic_error::what
+
+Class std::out_of_range
+ size=16 align=8
+ base size=16 base align=8
+std::out_of_range (0x0x7f884f9894e0) 0
+ vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16u)
+ std::logic_error (0x0x7f884f989548) 0
+ primary-for std::out_of_range (0x0x7f884f9894e0)
+ std::exception (0x0x7f884f87fd20) 0 nearly-empty
+ primary-for std::logic_error (0x0x7f884f989548)
+
+Vtable for std::runtime_error
+std::runtime_error::_ZTVSt13runtime_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt13runtime_error)
+16 (int (*)(...))std::runtime_error::~runtime_error
+24 (int (*)(...))std::runtime_error::~runtime_error
+32 (int (*)(...))std::runtime_error::what
+
+Class std::runtime_error
+ size=16 align=8
+ base size=16 base align=8
+std::runtime_error (0x0x7f884f9895b0) 0
+ vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16u)
+ std::exception (0x0x7f884f87fd80) 0 nearly-empty
+ primary-for std::runtime_error (0x0x7f884f9895b0)
+
+Vtable for std::range_error
+std::range_error::_ZTVSt11range_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt11range_error)
+16 (int (*)(...))std::range_error::~range_error
+24 (int (*)(...))std::range_error::~range_error
+32 (int (*)(...))std::runtime_error::what
+
+Class std::range_error
+ size=16 align=8
+ base size=16 base align=8
+std::range_error (0x0x7f884f989618) 0
+ vptr=((& std::range_error::_ZTVSt11range_error) + 16u)
+ std::runtime_error (0x0x7f884f989680) 0
+ primary-for std::range_error (0x0x7f884f989618)
+ std::exception (0x0x7f884f87fde0) 0 nearly-empty
+ primary-for std::runtime_error (0x0x7f884f989680)
+
+Vtable for std::overflow_error
+std::overflow_error::_ZTVSt14overflow_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt14overflow_error)
+16 (int (*)(...))std::overflow_error::~overflow_error
+24 (int (*)(...))std::overflow_error::~overflow_error
+32 (int (*)(...))std::runtime_error::what
+
+Class std::overflow_error
+ size=16 align=8
+ base size=16 base align=8
+std::overflow_error (0x0x7f884f9896e8) 0
+ vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16u)
+ std::runtime_error (0x0x7f884f989750) 0
+ primary-for std::overflow_error (0x0x7f884f9896e8)
+ std::exception (0x0x7f884f87fe40) 0 nearly-empty
+ primary-for std::runtime_error (0x0x7f884f989750)
+
+Vtable for std::underflow_error
+std::underflow_error::_ZTVSt15underflow_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt15underflow_error)
+16 (int (*)(...))std::underflow_error::~underflow_error
+24 (int (*)(...))std::underflow_error::~underflow_error
+32 (int (*)(...))std::runtime_error::what
+
+Class std::underflow_error
+ size=16 align=8
+ base size=16 base align=8
+std::underflow_error (0x0x7f884f9897b8) 0
+ vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16u)
+ std::runtime_error (0x0x7f884f989820) 0
+ primary-for std::underflow_error (0x0x7f884f9897b8)
+ std::exception (0x0x7f884f87fea0) 0 nearly-empty
+ primary-for std::runtime_error (0x0x7f884f989820)
+
+Vtable for std::_V2::error_category
+std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt3_V214error_categoryE)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))std::_V2::error_category::_M_message
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))std::_V2::error_category::default_error_condition
+64 (int (*)(...))std::_V2::error_category::equivalent
+72 (int (*)(...))std::_V2::error_category::equivalent
+
+Class std::_V2::error_category
+ size=8 align=8
+ base size=8 base align=8
+std::_V2::error_category (0x0x7f884f9c8060) 0 nearly-empty
+ vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16u)
+
+Class std::error_code
+ size=16 align=8
+ base size=16 base align=8
+std::error_code (0x0x7f884f9c82a0) 0
+
+Class std::error_condition
+ size=16 align=8
+ base size=16 base align=8
+std::error_condition (0x0x7f884f9c8420) 0
+
+Vtable for std::system_error
+std::system_error::_ZTVSt12system_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt12system_error)
+16 (int (*)(...))std::system_error::~system_error
+24 (int (*)(...))std::system_error::~system_error
+32 (int (*)(...))std::runtime_error::what
+
+Class std::system_error
+ size=32 align=8
+ base size=32 base align=8
+std::system_error (0x0x7f884f989d00) 0
+ vptr=((& std::system_error::_ZTVSt12system_error) + 16u)
+ std::runtime_error (0x0x7f884f989d68) 0
+ primary-for std::system_error (0x0x7f884f989d00)
+ std::exception (0x0x7f884f9c8660) 0 nearly-empty
+ primary-for std::runtime_error (0x0x7f884f989d68)
+
+Vtable for std::ios_base::failure
+std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E)
+16 (int (*)(...))std::ios_base::failure::~failure
+24 (int (*)(...))std::ios_base::failure::~failure
+32 (int (*)(...))std::ios_base::failure::what
+
+Class std::ios_base::failure
+ size=32 align=8
+ base size=32 base align=8
+std::ios_base::failure (0x0x7f884fa238f0) 0
+ vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16u)
+ std::system_error (0x0x7f884fa23958) 0
+ primary-for std::ios_base::failure (0x0x7f884fa238f0)
+ std::runtime_error (0x0x7f884fa239c0) 0
+ primary-for std::system_error (0x0x7f884fa23958)
+ std::exception (0x0x7f884f9c8960) 0 nearly-empty
+ primary-for std::runtime_error (0x0x7f884fa239c0)
+
+Class std::ios_base::_Callback_list
+ size=24 align=8
+ base size=24 base align=8
+std::ios_base::_Callback_list (0x0x7f884f9c89c0) 0
+
+Class std::ios_base::_Words
+ size=16 align=8
+ base size=16 base align=8
+std::ios_base::_Words (0x0x7f884f9c8a20) 0
+
+Class std::ios_base::Init
+ size=1 align=1
+ base size=0 base align=1
+std::ios_base::Init (0x0x7f884f9c8a80) 0 empty
+
+Vtable for std::ios_base
+std::ios_base::_ZTVSt8ios_base: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt8ios_base)
+16 (int (*)(...))std::ios_base::~ios_base
+24 (int (*)(...))std::ios_base::~ios_base
+
+Class std::ios_base
+ size=216 align=8
+ base size=216 base align=8
+std::ios_base (0x0x7f884f9c8900) 0
+ vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u)
+
+Class std::ctype_base
+ size=1 align=1
+ base size=0 base align=1
+std::ctype_base (0x0x7f884f6fa240) 0 empty
+
+Class std::__num_base
+ size=1 align=1
+ base size=0 base align=1
+std::__num_base (0x0x7f884f6fa900) 0 empty
+
+VTT for std::basic_ostream<char>
+std::basic_ostream<char>::_ZTTSo: 2u entries
+0 ((& std::basic_ostream<char>::_ZTVSo) + 24u)
+8 ((& std::basic_ostream<char>::_ZTVSo) + 64u)
+
+VTT for std::basic_ostream<wchar_t>
+std::basic_ostream<wchar_t>::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries
+0 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u)
+8 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u)
+
+VTT for std::basic_istream<char>
+std::basic_istream<char>::_ZTTSi: 2u entries
+0 ((& std::basic_istream<char>::_ZTVSi) + 24u)
+8 ((& std::basic_istream<char>::_ZTVSi) + 64u)
+
+VTT for std::basic_istream<wchar_t>
+std::basic_istream<wchar_t>::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries
+0 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u)
+8 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u)
+
+Construction vtable for std::basic_istream<char> (0x0x7f884f2e4270 instance) in std::basic_iostream<char>
+std::basic_iostream<char>::_ZTCSd0_Si: 10u entries
+0 24u
+8 (int (*)(...))0
+16 (int (*)(...))(& _ZTISi)
+24 0u
+32 0u
+40 18446744073709551592u
+48 (int (*)(...))-24
+56 (int (*)(...))(& _ZTISi)
+64 0u
+72 0u
+
+Construction vtable for std::basic_ostream<char> (0x0x7f884f2e4340 instance) in std::basic_iostream<char>
+std::basic_iostream<char>::_ZTCSd16_So: 10u entries
+0 8u
+8 (int (*)(...))0
+16 (int (*)(...))(& _ZTISo)
+24 0u
+32 0u
+40 18446744073709551608u
+48 (int (*)(...))-8
+56 (int (*)(...))(& _ZTISo)
+64 0u
+72 0u
+
+VTT for std::basic_iostream<char>
+std::basic_iostream<char>::_ZTTSd: 7u entries
+0 ((& std::basic_iostream<char>::_ZTVSd) + 24u)
+8 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 24u)
+16 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 64u)
+24 ((& std::basic_iostream<char>::_ZTCSd16_So) + 24u)
+32 ((& std::basic_iostream<char>::_ZTCSd16_So) + 64u)
+40 ((& std::basic_iostream<char>::_ZTVSd) + 104u)
+48 ((& std::basic_iostream<char>::_ZTVSd) + 64u)
+
+Construction vtable for std::basic_istream<wchar_t> (0x0x7f884f2e46e8 instance) in std::basic_iostream<wchar_t>
+std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries
+0 24u
+8 (int (*)(...))0
+16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE)
+24 0u
+32 0u
+40 18446744073709551592u
+48 (int (*)(...))-24
+56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE)
+64 0u
+72 0u
+
+Construction vtable for std::basic_ostream<wchar_t> (0x0x7f884f2e47b8 instance) in std::basic_iostream<wchar_t>
+std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries
+0 8u
+8 (int (*)(...))0
+16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE)
+24 0u
+32 0u
+40 18446744073709551608u
+48 (int (*)(...))-8
+56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE)
+64 0u
+72 0u
+
+VTT for std::basic_iostream<wchar_t>
+std::basic_iostream<wchar_t>::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries
+0 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u)
+8 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u)
+16 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u)
+24 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u)
+32 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u)
+40 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u)
+48 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u)
+
+Class QByteArrayDataPtr
+ size=8 align=8
+ base size=8 base align=8
+QByteArrayDataPtr (0x0x7f884f335180) 0
+
+Class QByteArray
+ size=8 align=8
+ base size=8 base align=8
+QByteArray (0x0x7f884f3351e0) 0
+
+Class QByteRef
+ size=16 align=8
+ base size=12 base align=8
+QByteRef (0x0x7f884f432540) 0
+
+Class QStringDataPtr
+ size=8 align=8
+ base size=8 base align=8
+QStringDataPtr (0x0x7f884f4328a0) 0
+
+Class QStringView
+ size=16 align=8
+ base size=16 base align=8
+QStringView (0x0x7f884f432d20) 0
+
+Class QLatin1String
+ size=16 align=8
+ base size=16 base align=8
+QLatin1String (0x0x7f884f163ba0) 0
+
+Class QString::Null
+ size=1 align=1
+ base size=0 base align=1
+QString::Null (0x0x7f884f1f1240) 0 empty
+
+Class QString
+ size=8 align=8
+ base size=8 base align=8
+QString (0x0x7f884f1f11e0) 0
+
+Class QCharRef
+ size=16 align=8
+ base size=12 base align=8
+QCharRef (0x0x7f884ef9b300) 0
+
+Class QStringRef
+ size=16 align=8
+ base size=16 base align=8
+QStringRef (0x0x7f884ef9bf00) 0
+
+Class QtPrivate::QHashCombine
+ size=1 align=1
+ base size=0 base align=1
+QtPrivate::QHashCombine (0x0x7f884ed9cb40) 0 empty
+
+Class QtPrivate::QHashCombineCommutative
+ size=1 align=1
+ base size=0 base align=1
+QtPrivate::QHashCombineCommutative (0x0x7f884ed9cba0) 0 empty
+
+Class std::__detail::_List_node_base
+ size=16 align=8
+ base size=16 base align=8
+std::__detail::_List_node_base (0x0x7f884ed9cc00) 0
+
+Class QListData::NotArrayCompatibleLayout
+ size=1 align=1
+ base size=0 base align=1
+QListData::NotArrayCompatibleLayout (0x0x7f884ebe2000) 0 empty
+
+Class QListData::NotIndirectLayout
+ size=1 align=1
+ base size=0 base align=1
+QListData::NotIndirectLayout (0x0x7f884ebe2060) 0 empty
+
+Class QListData::ArrayCompatibleLayout
+ size=1 align=1
+ base size=1 base align=1
+QListData::ArrayCompatibleLayout (0x0x7f884eb1a208) 0 empty
+ QListData::NotIndirectLayout (0x0x7f884ebe20c0) 0 empty
+
+Class QListData::InlineWithPaddingLayout
+ size=1 align=1
+ base size=1 base align=1
+QListData::InlineWithPaddingLayout (0x0x7f884ebdd540) 0 empty
+ QListData::NotArrayCompatibleLayout (0x0x7f884ebe2120) 0 empty
+ QListData::NotIndirectLayout (0x0x7f884ebe2180) 0 empty
+
+Class QListData::IndirectLayout
+ size=1 align=1
+ base size=1 base align=1
+QListData::IndirectLayout (0x0x7f884eb1a270) 0 empty
+ QListData::NotArrayCompatibleLayout (0x0x7f884ebe21e0) 0 empty
+
+Class QListData::Data
+ size=24 align=8
+ base size=24 base align=8
+QListData::Data (0x0x7f884ebe2240) 0
+
+Class QListData
+ size=8 align=8
+ base size=8 base align=8
+QListData (0x0x7f884ed9cf60) 0
+
+Class QRegExp
+ size=8 align=8
+ base size=8 base align=8
+QRegExp (0x0x7f884ebe26c0) 0
+
+Class QStringMatcher::Data
+ size=272 align=8
+ base size=272 base align=8
+QStringMatcher::Data (0x0x7f884e989900) 0
+
+Class QStringMatcher
+ size=1048 align=8
+ base size=1048 base align=8
+QStringMatcher (0x0x7f884e9898a0) 0
+
+Class QStringList
+ size=8 align=8
+ base size=8 base align=8
+QStringList (0x0x7f884e987c98) 0
+ QList<QString> (0x0x7f884e987d00) 0
+ QListSpecialMethods<QString> (0x0x7f884e989ae0) 0 empty
+
+Class QScopedPointerPodDeleter
+ size=1 align=1
+ base size=0 base align=1
+QScopedPointerPodDeleter (0x0x7f884e989f00) 0 empty
+
+Class std::_Rb_tree_node_base
+ size=32 align=8
+ base size=32 base align=8
+std::_Rb_tree_node_base (0x0x7f884ea2ba20) 0
+
+Class std::allocator_arg_t
+ size=1 align=1
+ base size=0 base align=1
+std::allocator_arg_t (0x0x7f884e82e0c0) 0 empty
+
+Class std::__uses_alloc_base
+ size=1 align=1
+ base size=0 base align=1
+std::__uses_alloc_base (0x0x7f884e82e240) 0 empty
+
+Class std::__uses_alloc0::_Sink
+ size=1 align=1
+ base size=0 base align=1
+std::__uses_alloc0::_Sink (0x0x7f884e82e300) 0 empty
+
+Class std::__uses_alloc0
+ size=1 align=1
+ base size=1 base align=1
+std::__uses_alloc0 (0x0x7f884ea05618) 0
+ std::__uses_alloc_base (0x0x7f884e82e2a0) 0 empty
+
+Class std::_Swallow_assign
+ size=1 align=1
+ base size=0 base align=1
+std::_Swallow_assign (0x0x7f884e51f360) 0 empty
+
+Class QtPrivate::AbstractDebugStreamFunction
+ size=16 align=8
+ base size=16 base align=8
+QtPrivate::AbstractDebugStreamFunction (0x0x7f884e51f5a0) 0
+
+Class QtPrivate::AbstractComparatorFunction
+ size=24 align=8
+ base size=24 base align=8
+QtPrivate::AbstractComparatorFunction (0x0x7f884e51f660) 0
+
+Class QtPrivate::AbstractConverterFunction
+ size=8 align=8
+ base size=8 base align=8
+QtPrivate::AbstractConverterFunction (0x0x7f884e51f780) 0
+
+Class QMetaType
+ size=80 align=8
+ base size=80 base align=8
+QMetaType (0x0x7f884e51f900) 0
+
+Class QtMetaTypePrivate::VariantData
+ size=24 align=8
+ base size=20 base align=8
+QtMetaTypePrivate::VariantData (0x0x7f884e51fd20) 0
+
+Class QtMetaTypePrivate::VectorBoolElements
+ size=1 align=1
+ base size=0 base align=1
+QtMetaTypePrivate::VectorBoolElements (0x0x7f884e51fe40) 0 empty
+
+Class QtMetaTypePrivate::QSequentialIterableImpl
+ size=104 align=8
+ base size=104 base align=8
+QtMetaTypePrivate::QSequentialIterableImpl (0x0x7f884e2847e0) 0
+
+Class QtMetaTypePrivate::QAssociativeIterableImpl
+ size=112 align=8
+ base size=112 base align=8
+QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7f884e284c00) 0
+
+Class QtMetaTypePrivate::QPairVariantInterfaceImpl
+ size=40 align=8
+ base size=40 base align=8
+QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7f884e284f00) 0
+
+Class std::chrono::_V2::system_clock
+ size=1 align=1
+ base size=0 base align=1
+std::chrono::_V2::system_clock (0x0x7f884e182780) 0 empty
+
+Class std::chrono::_V2::steady_clock
+ size=1 align=1
+ base size=0 base align=1
+std::chrono::_V2::steady_clock (0x0x7f884dec1600) 0 empty
+
+Vtable for QObjectData
+QObjectData::_ZTV11QObjectData: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QObjectData)
+16 (int (*)(...))__cxa_pure_virtual
+24 (int (*)(...))__cxa_pure_virtual
+
+Class QObjectData
+ size=48 align=8
+ base size=48 base align=8
+QObjectData (0x0x7f884dec1660) 0
+ vptr=((& QObjectData::_ZTV11QObjectData) + 16u)
+
+Class QObject::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QObject::QPrivateSignal (0x0x7f884dec1840) 0 empty
+
+Vtable for QObject
+QObject::_ZTV7QObject: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QObject)
+16 (int (*)(...))QObject::metaObject
+24 (int (*)(...))QObject::qt_metacast
+32 (int (*)(...))QObject::qt_metacall
+40 (int (*)(...))QObject::~QObject
+48 (int (*)(...))QObject::~QObject
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QObject
+ size=16 align=8
+ base size=16 base align=8
+QObject (0x0x7f884dec17e0) 0
+ vptr=((& QObject::_ZTV7QObject) + 16u)
+
+Vtable for QObjectUserData
+QObjectUserData::_ZTV15QObjectUserData: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QObjectUserData)
+16 (int (*)(...))QObjectUserData::~QObjectUserData
+24 (int (*)(...))QObjectUserData::~QObjectUserData
+
+Class QObjectUserData
+ size=8 align=8
+ base size=8 base align=8
+QObjectUserData (0x0x7f884df8aae0) 0 nearly-empty
+ vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u)
+
+Class QSignalBlocker
+ size=16 align=8
+ base size=10 base align=8
+QSignalBlocker (0x0x7f884df8ab40) 0
+
+Class QAbstractAnimation::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractAnimation::QPrivateSignal (0x0x7f884df8ac00) 0 empty
+
+Vtable for QAbstractAnimation
+QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QAbstractAnimation)
+16 (int (*)(...))QAbstractAnimation::metaObject
+24 (int (*)(...))QAbstractAnimation::qt_metacast
+32 (int (*)(...))QAbstractAnimation::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QAbstractAnimation::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))QAbstractAnimation::updateState
+136 (int (*)(...))QAbstractAnimation::updateDirection
+
+Class QAbstractAnimation
+ size=16 align=8
+ base size=16 base align=8
+QAbstractAnimation (0x0x7f884dfb2820) 0
+ vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u)
+ QObject (0x0x7f884df8aba0) 0
+ primary-for QAbstractAnimation (0x0x7f884dfb2820)
+
+Class QAnimationDriver::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAnimationDriver::QPrivateSignal (0x0x7f884df8acc0) 0 empty
+
+Vtable for QAnimationDriver
+QAnimationDriver::_ZTV16QAnimationDriver: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QAnimationDriver)
+16 (int (*)(...))QAnimationDriver::metaObject
+24 (int (*)(...))QAnimationDriver::qt_metacast
+32 (int (*)(...))QAnimationDriver::qt_metacall
+40 (int (*)(...))QAnimationDriver::~QAnimationDriver
+48 (int (*)(...))QAnimationDriver::~QAnimationDriver
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAnimationDriver::advance
+120 (int (*)(...))QAnimationDriver::elapsed
+128 (int (*)(...))QAnimationDriver::start
+136 (int (*)(...))QAnimationDriver::stop
+
+Class QAnimationDriver
+ size=16 align=8
+ base size=16 base align=8
+QAnimationDriver (0x0x7f884dfb2888) 0
+ vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u)
+ QObject (0x0x7f884df8ac60) 0
+ primary-for QAnimationDriver (0x0x7f884dfb2888)
+
+Class QEventLoop::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QEventLoop::QPrivateSignal (0x0x7f884df8ad80) 0 empty
+
+Vtable for QEventLoop
+QEventLoop::_ZTV10QEventLoop: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QEventLoop)
+16 (int (*)(...))QEventLoop::metaObject
+24 (int (*)(...))QEventLoop::qt_metacast
+32 (int (*)(...))QEventLoop::qt_metacall
+40 (int (*)(...))QEventLoop::~QEventLoop
+48 (int (*)(...))QEventLoop::~QEventLoop
+56 (int (*)(...))QEventLoop::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QEventLoop
+ size=16 align=8
+ base size=16 base align=8
+QEventLoop (0x0x7f884dfb28f0) 0
+ vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u)
+ QObject (0x0x7f884df8ad20) 0
+ primary-for QEventLoop (0x0x7f884dfb28f0)
+
+Class QEventLoopLocker
+ size=8 align=8
+ base size=8 base align=8
+QEventLoopLocker (0x0x7f884df8af60) 0
+
+Class QAbstractEventDispatcher::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractEventDispatcher::QPrivateSignal (0x0x7f884dc3f060) 0 empty
+
+Class QAbstractEventDispatcher::TimerInfo
+ size=12 align=4
+ base size=12 base align=4
+QAbstractEventDispatcher::TimerInfo (0x0x7f884dc3f0c0) 0
+
+Vtable for QAbstractEventDispatcher
+QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher)
+16 (int (*)(...))QAbstractEventDispatcher::metaObject
+24 (int (*)(...))QAbstractEventDispatcher::qt_metacast
+32 (int (*)(...))QAbstractEventDispatcher::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))__cxa_pure_virtual
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))__cxa_pure_virtual
+176 (int (*)(...))__cxa_pure_virtual
+184 (int (*)(...))__cxa_pure_virtual
+192 (int (*)(...))__cxa_pure_virtual
+200 (int (*)(...))__cxa_pure_virtual
+208 (int (*)(...))QAbstractEventDispatcher::startingUp
+216 (int (*)(...))QAbstractEventDispatcher::closingDown
+
+Class QAbstractEventDispatcher
+ size=16 align=8
+ base size=16 base align=8
+QAbstractEventDispatcher (0x0x7f884dfb2a28) 0
+ vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u)
+ QObject (0x0x7f884dc3f000) 0
+ primary-for QAbstractEventDispatcher (0x0x7f884dfb2a28)
+
+Vtable for std::type_info
+std::type_info::_ZTVSt9type_info: 8u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt9type_info)
+16 (int (*)(...))std::type_info::~type_info
+24 (int (*)(...))std::type_info::~type_info
+32 (int (*)(...))std::type_info::__is_pointer_p
+40 (int (*)(...))std::type_info::__is_function_p
+48 (int (*)(...))std::type_info::__do_catch
+56 (int (*)(...))std::type_info::__do_upcast
+
+Class std::type_info
+ size=16 align=8
+ base size=16 base align=8
+std::type_info (0x0x7f884dc3f360) 0
+ vptr=((& std::type_info::_ZTVSt9type_info) + 16u)
+
+Vtable for std::bad_cast
+std::bad_cast::_ZTVSt8bad_cast: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt8bad_cast)
+16 (int (*)(...))std::bad_cast::~bad_cast
+24 (int (*)(...))std::bad_cast::~bad_cast
+32 (int (*)(...))std::bad_cast::what
+
+Class std::bad_cast
+ size=8 align=8
+ base size=8 base align=8
+std::bad_cast (0x0x7f884dfb2c30) 0 nearly-empty
+ vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16u)
+ std::exception (0x0x7f884dc3f3c0) 0 nearly-empty
+ primary-for std::bad_cast (0x0x7f884dfb2c30)
+
+Vtable for std::bad_typeid
+std::bad_typeid::_ZTVSt10bad_typeid: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt10bad_typeid)
+16 (int (*)(...))std::bad_typeid::~bad_typeid
+24 (int (*)(...))std::bad_typeid::~bad_typeid
+32 (int (*)(...))std::bad_typeid::what
+
+Class std::bad_typeid
+ size=8 align=8
+ base size=8 base align=8
+std::bad_typeid (0x0x7f884dfb2c98) 0 nearly-empty
+ vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16u)
+ std::exception (0x0x7f884dc3f420) 0 nearly-empty
+ primary-for std::bad_typeid (0x0x7f884dfb2c98)
+
+Vtable for std::bad_function_call
+std::bad_function_call::_ZTVSt17bad_function_call: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt17bad_function_call)
+16 (int (*)(...))std::bad_function_call::~bad_function_call
+24 (int (*)(...))std::bad_function_call::~bad_function_call
+32 (int (*)(...))std::bad_function_call::what
+
+Class std::bad_function_call
+ size=8 align=8
+ base size=8 base align=8
+std::bad_function_call (0x0x7f884dcfdf08) 0 nearly-empty
+ vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16u)
+ std::exception (0x0x7f884ddd84e0) 0 nearly-empty
+ primary-for std::bad_function_call (0x0x7f884dcfdf08)
+
+Class std::_Nocopy_types
+ size=16 align=8
+ base size=16 base align=8
+std::_Nocopy_types (0x0x7f884ddd85a0) 0
+
+Class std::_Any_data
+ size=16 align=8
+ base size=16 base align=8
+std::_Any_data (0x0x7f884ddd8600) 0
+
+Class std::_Function_base
+ size=24 align=8
+ base size=24 base align=8
+std::_Function_base (0x0x7f884ddd8720) 0
+
+Class QMapNodeBase
+ size=24 align=8
+ base size=24 base align=8
+QMapNodeBase (0x0x7f884ddd8c00) 0
+
+Class QMapDataBase
+ size=40 align=8
+ base size=40 base align=8
+QMapDataBase (0x0x7f884da8d180) 0
+
+Class QHashData::Node
+ size=16 align=8
+ base size=16 base align=8
+QHashData::Node (0x0x7f884da8d540) 0
+
+Class QHashData
+ size=48 align=8
+ base size=44 base align=8
+QHashData (0x0x7f884da8d4e0) 0
+
+Class QHashDummyValue
+ size=1 align=1
+ base size=0 base align=1
+QHashDummyValue (0x0x7f884da8d5a0) 0 empty
+
+Class QVariant::PrivateShared
+ size=16 align=8
+ base size=12 base align=8
+QVariant::PrivateShared (0x0x7f884da8de40) 0
+
+Class QVariant::Private::Data
+ size=8 align=8
+ base size=8 base align=8
+QVariant::Private::Data (0x0x7f884da8df00) 0
+
+Class QVariant::Private
+ size=16 align=8
+ base size=12 base align=8
+QVariant::Private (0x0x7f884da8dea0) 0
+
+Class QVariant::Handler
+ size=72 align=8
+ base size=72 base align=8
+QVariant::Handler (0x0x7f884da8df60) 0
+
+Class QVariant
+ size=16 align=8
+ base size=16 base align=8
+QVariant (0x0x7f884da8dde0) 0
+
+Class QVariantComparisonHelper
+ size=8 align=8
+ base size=8 base align=8
+QVariantComparisonHelper (0x0x7f884d967a80) 0
+
+Class QSequentialIterable::const_iterator
+ size=112 align=8
+ base size=112 base align=8
+QSequentialIterable::const_iterator (0x0x7f884da10120) 0
+
+Class QSequentialIterable
+ size=104 align=8
+ base size=104 base align=8
+QSequentialIterable (0x0x7f884da100c0) 0
+
+Class QAssociativeIterable::const_iterator
+ size=120 align=8
+ base size=120 base align=8
+QAssociativeIterable::const_iterator (0x0x7f884da101e0) 0
+
+Class QAssociativeIterable
+ size=112 align=8
+ base size=112 base align=8
+QAssociativeIterable (0x0x7f884da10180) 0
+
+Class QModelIndex
+ size=24 align=8
+ base size=24 base align=8
+QModelIndex (0x0x7f884d72b4e0) 0
+
+Class QPersistentModelIndex
+ size=8 align=8
+ base size=8 base align=8
+QPersistentModelIndex (0x0x7f884d72bba0) 0
+
+Class QAbstractItemModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractItemModel::QPrivateSignal (0x0x7f884d501300) 0 empty
+
+Vtable for QAbstractItemModel
+QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QAbstractItemModel)
+16 (int (*)(...))QAbstractItemModel::metaObject
+24 (int (*)(...))QAbstractItemModel::qt_metacast
+32 (int (*)(...))QAbstractItemModel::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))QAbstractItemModel::sibling
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))QAbstractItemModel::hasChildren
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))QAbstractItemModel::setData
+176 (int (*)(...))QAbstractItemModel::headerData
+184 (int (*)(...))QAbstractItemModel::setHeaderData
+192 (int (*)(...))QAbstractItemModel::itemData
+200 (int (*)(...))QAbstractItemModel::setItemData
+208 (int (*)(...))QAbstractItemModel::mimeTypes
+216 (int (*)(...))QAbstractItemModel::mimeData
+224 (int (*)(...))QAbstractItemModel::canDropMimeData
+232 (int (*)(...))QAbstractItemModel::dropMimeData
+240 (int (*)(...))QAbstractItemModel::supportedDropActions
+248 (int (*)(...))QAbstractItemModel::supportedDragActions
+256 (int (*)(...))QAbstractItemModel::insertRows
+264 (int (*)(...))QAbstractItemModel::insertColumns
+272 (int (*)(...))QAbstractItemModel::removeRows
+280 (int (*)(...))QAbstractItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractItemModel::fetchMore
+312 (int (*)(...))QAbstractItemModel::canFetchMore
+320 (int (*)(...))QAbstractItemModel::flags
+328 (int (*)(...))QAbstractItemModel::sort
+336 (int (*)(...))QAbstractItemModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractItemModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractItemModel::submit
+376 (int (*)(...))QAbstractItemModel::revert
+
+Class QAbstractItemModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractItemModel (0x0x7f884d4ecc98) 0
+ vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u)
+ QObject (0x0x7f884d5012a0) 0
+ primary-for QAbstractItemModel (0x0x7f884d4ecc98)
+
+Class QAbstractTableModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractTableModel::QPrivateSignal (0x0x7f884d501660) 0 empty
+
+Vtable for QAbstractTableModel
+QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QAbstractTableModel)
+16 (int (*)(...))QAbstractTableModel::metaObject
+24 (int (*)(...))QAbstractTableModel::qt_metacast
+32 (int (*)(...))QAbstractTableModel::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAbstractTableModel::index
+120 (int (*)(...))QAbstractTableModel::parent
+128 (int (*)(...))QAbstractTableModel::sibling
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))QAbstractTableModel::hasChildren
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))QAbstractItemModel::setData
+176 (int (*)(...))QAbstractItemModel::headerData
+184 (int (*)(...))QAbstractItemModel::setHeaderData
+192 (int (*)(...))QAbstractItemModel::itemData
+200 (int (*)(...))QAbstractItemModel::setItemData
+208 (int (*)(...))QAbstractItemModel::mimeTypes
+216 (int (*)(...))QAbstractItemModel::mimeData
+224 (int (*)(...))QAbstractItemModel::canDropMimeData
+232 (int (*)(...))QAbstractTableModel::dropMimeData
+240 (int (*)(...))QAbstractItemModel::supportedDropActions
+248 (int (*)(...))QAbstractItemModel::supportedDragActions
+256 (int (*)(...))QAbstractItemModel::insertRows
+264 (int (*)(...))QAbstractItemModel::insertColumns
+272 (int (*)(...))QAbstractItemModel::removeRows
+280 (int (*)(...))QAbstractItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractItemModel::fetchMore
+312 (int (*)(...))QAbstractItemModel::canFetchMore
+320 (int (*)(...))QAbstractTableModel::flags
+328 (int (*)(...))QAbstractItemModel::sort
+336 (int (*)(...))QAbstractItemModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractItemModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractItemModel::submit
+376 (int (*)(...))QAbstractItemModel::revert
+
+Class QAbstractTableModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractTableModel (0x0x7f884d4ecea0) 0
+ vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u)
+ QAbstractItemModel (0x0x7f884d4ecf08) 0
+ primary-for QAbstractTableModel (0x0x7f884d4ecea0)
+ QObject (0x0x7f884d501600) 0
+ primary-for QAbstractItemModel (0x0x7f884d4ecf08)
+
+Class QAbstractListModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractListModel::QPrivateSignal (0x0x7f884d501720) 0 empty
+
+Vtable for QAbstractListModel
+QAbstractListModel::_ZTV18QAbstractListModel: 48u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QAbstractListModel)
+16 (int (*)(...))QAbstractListModel::metaObject
+24 (int (*)(...))QAbstractListModel::qt_metacast
+32 (int (*)(...))QAbstractListModel::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAbstractListModel::index
+120 (int (*)(...))QAbstractListModel::parent
+128 (int (*)(...))QAbstractListModel::sibling
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))QAbstractListModel::columnCount
+152 (int (*)(...))QAbstractListModel::hasChildren
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))QAbstractItemModel::setData
+176 (int (*)(...))QAbstractItemModel::headerData
+184 (int (*)(...))QAbstractItemModel::setHeaderData
+192 (int (*)(...))QAbstractItemModel::itemData
+200 (int (*)(...))QAbstractItemModel::setItemData
+208 (int (*)(...))QAbstractItemModel::mimeTypes
+216 (int (*)(...))QAbstractItemModel::mimeData
+224 (int (*)(...))QAbstractItemModel::canDropMimeData
+232 (int (*)(...))QAbstractListModel::dropMimeData
+240 (int (*)(...))QAbstractItemModel::supportedDropActions
+248 (int (*)(...))QAbstractItemModel::supportedDragActions
+256 (int (*)(...))QAbstractItemModel::insertRows
+264 (int (*)(...))QAbstractItemModel::insertColumns
+272 (int (*)(...))QAbstractItemModel::removeRows
+280 (int (*)(...))QAbstractItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractItemModel::fetchMore
+312 (int (*)(...))QAbstractItemModel::canFetchMore
+320 (int (*)(...))QAbstractListModel::flags
+328 (int (*)(...))QAbstractItemModel::sort
+336 (int (*)(...))QAbstractItemModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractItemModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractItemModel::submit
+376 (int (*)(...))QAbstractItemModel::revert
+
+Class QAbstractListModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractListModel (0x0x7f884d4ecf70) 0
+ vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u)
+ QAbstractItemModel (0x0x7f884d5b4000) 0
+ primary-for QAbstractListModel (0x0x7f884d4ecf70)
+ QObject (0x0x7f884d5016c0) 0
+ primary-for QAbstractItemModel (0x0x7f884d5b4000)
+
+Vtable for QAbstractNativeEventFilter
+QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class QAbstractNativeEventFilter
+ size=16 align=8
+ base size=16 base align=8
+QAbstractNativeEventFilter (0x0x7f884d5019c0) 0
+ vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u)
+
+Class QAbstractProxyModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractProxyModel::QPrivateSignal (0x0x7f884d501a80) 0 empty
+
+Vtable for QAbstractProxyModel
+QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QAbstractProxyModel)
+16 (int (*)(...))QAbstractProxyModel::metaObject
+24 (int (*)(...))QAbstractProxyModel::qt_metacast
+32 (int (*)(...))QAbstractProxyModel::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))QAbstractProxyModel::sibling
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))QAbstractProxyModel::hasChildren
+160 (int (*)(...))QAbstractProxyModel::data
+168 (int (*)(...))QAbstractProxyModel::setData
+176 (int (*)(...))QAbstractProxyModel::headerData
+184 (int (*)(...))QAbstractProxyModel::setHeaderData
+192 (int (*)(...))QAbstractProxyModel::itemData
+200 (int (*)(...))QAbstractProxyModel::setItemData
+208 (int (*)(...))QAbstractProxyModel::mimeTypes
+216 (int (*)(...))QAbstractProxyModel::mimeData
+224 (int (*)(...))QAbstractProxyModel::canDropMimeData
+232 (int (*)(...))QAbstractProxyModel::dropMimeData
+240 (int (*)(...))QAbstractProxyModel::supportedDropActions
+248 (int (*)(...))QAbstractProxyModel::supportedDragActions
+256 (int (*)(...))QAbstractItemModel::insertRows
+264 (int (*)(...))QAbstractItemModel::insertColumns
+272 (int (*)(...))QAbstractItemModel::removeRows
+280 (int (*)(...))QAbstractItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractProxyModel::fetchMore
+312 (int (*)(...))QAbstractProxyModel::canFetchMore
+320 (int (*)(...))QAbstractProxyModel::flags
+328 (int (*)(...))QAbstractProxyModel::sort
+336 (int (*)(...))QAbstractProxyModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractProxyModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractProxyModel::submit
+376 (int (*)(...))QAbstractProxyModel::revert
+384 (int (*)(...))QAbstractProxyModel::setSourceModel
+392 (int (*)(...))__cxa_pure_virtual
+400 (int (*)(...))__cxa_pure_virtual
+408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource
+416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource
+
+Class QAbstractProxyModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractProxyModel (0x0x7f884d5b4138) 0
+ vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u)
+ QAbstractItemModel (0x0x7f884d5b41a0) 0
+ primary-for QAbstractProxyModel (0x0x7f884d5b4138)
+ QObject (0x0x7f884d501a20) 0
+ primary-for QAbstractItemModel (0x0x7f884d5b41a0)
+
+Class QAbstractState::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractState::QPrivateSignal (0x0x7f884d501b40) 0 empty
+
+Vtable for QAbstractState
+QAbstractState::_ZTV14QAbstractState: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QAbstractState)
+16 (int (*)(...))QAbstractState::metaObject
+24 (int (*)(...))QAbstractState::qt_metacast
+32 (int (*)(...))QAbstractState::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QAbstractState::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+
+Class QAbstractState
+ size=16 align=8
+ base size=16 base align=8
+QAbstractState (0x0x7f884d5b4208) 0
+ vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u)
+ QObject (0x0x7f884d501ae0) 0
+ primary-for QAbstractState (0x0x7f884d5b4208)
+
+Class QAbstractTransition::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractTransition::QPrivateSignal (0x0x7f884d501c00) 0 empty
+
+Vtable for QAbstractTransition
+QAbstractTransition::_ZTV19QAbstractTransition: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QAbstractTransition)
+16 (int (*)(...))QAbstractTransition::metaObject
+24 (int (*)(...))QAbstractTransition::qt_metacast
+32 (int (*)(...))QAbstractTransition::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QAbstractTransition::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+
+Class QAbstractTransition
+ size=16 align=8
+ base size=16 base align=8
+QAbstractTransition (0x0x7f884d5b4270) 0
+ vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u)
+ QObject (0x0x7f884d501ba0) 0
+ primary-for QAbstractTransition (0x0x7f884d5b4270)
+
+Class QAnimationGroup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAnimationGroup::QPrivateSignal (0x0x7f884d501cc0) 0 empty
+
+Vtable for QAnimationGroup
+QAnimationGroup::_ZTV15QAnimationGroup: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QAnimationGroup)
+16 (int (*)(...))QAnimationGroup::metaObject
+24 (int (*)(...))QAnimationGroup::qt_metacast
+32 (int (*)(...))QAnimationGroup::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QAnimationGroup::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))QAbstractAnimation::updateState
+136 (int (*)(...))QAbstractAnimation::updateDirection
+
+Class QAnimationGroup
+ size=16 align=8
+ base size=16 base align=8
+QAnimationGroup (0x0x7f884d5b42d8) 0
+ vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u)
+ QAbstractAnimation (0x0x7f884d5b4340) 0
+ primary-for QAnimationGroup (0x0x7f884d5b42d8)
+ QObject (0x0x7f884d501c60) 0
+ primary-for QAbstractAnimation (0x0x7f884d5b4340)
+
+Class QBasicTimer
+ size=4 align=4
+ base size=4 base align=4
+QBasicTimer (0x0x7f884d276a20) 0
+
+Class QBitArray
+ size=8 align=8
+ base size=8 base align=8
+QBitArray (0x0x7f884d276cc0) 0
+
+Class QBitRef
+ size=16 align=8
+ base size=12 base align=8
+QBitRef (0x0x7f884d276d80) 0
+
+Class QIODevice::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QIODevice::QPrivateSignal (0x0x7f884d30a0c0) 0 empty
+
+Vtable for QIODevice
+QIODevice::_ZTV9QIODevice: 30u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QIODevice)
+16 (int (*)(...))QIODevice::metaObject
+24 (int (*)(...))QIODevice::qt_metacast
+32 (int (*)(...))QIODevice::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QIODevice::isSequential
+120 (int (*)(...))QIODevice::open
+128 (int (*)(...))QIODevice::close
+136 (int (*)(...))QIODevice::pos
+144 (int (*)(...))QIODevice::size
+152 (int (*)(...))QIODevice::seek
+160 (int (*)(...))QIODevice::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QIODevice::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))__cxa_pure_virtual
+224 (int (*)(...))QIODevice::readLineData
+232 (int (*)(...))__cxa_pure_virtual
+
+Class QIODevice
+ size=16 align=8
+ base size=16 base align=8
+QIODevice (0x0x7f884d5b49c0) 0
+ vptr=((& QIODevice::_ZTV9QIODevice) + 16u)
+ QObject (0x0x7f884d30a060) 0
+ primary-for QIODevice (0x0x7f884d5b49c0)
+
+Class QBuffer::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QBuffer::QPrivateSignal (0x0x7f884d30a300) 0 empty
+
+Vtable for QBuffer
+QBuffer::_ZTV7QBuffer: 30u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QBuffer)
+16 (int (*)(...))QBuffer::metaObject
+24 (int (*)(...))QBuffer::qt_metacast
+32 (int (*)(...))QBuffer::qt_metacall
+40 (int (*)(...))QBuffer::~QBuffer
+48 (int (*)(...))QBuffer::~QBuffer
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QBuffer::connectNotify
+104 (int (*)(...))QBuffer::disconnectNotify
+112 (int (*)(...))QIODevice::isSequential
+120 (int (*)(...))QBuffer::open
+128 (int (*)(...))QBuffer::close
+136 (int (*)(...))QBuffer::pos
+144 (int (*)(...))QBuffer::size
+152 (int (*)(...))QBuffer::seek
+160 (int (*)(...))QBuffer::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QBuffer::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))QBuffer::readData
+224 (int (*)(...))QIODevice::readLineData
+232 (int (*)(...))QBuffer::writeData
+
+Class QBuffer
+ size=16 align=8
+ base size=16 base align=8
+QBuffer (0x0x7f884d5b4af8) 0
+ vptr=((& QBuffer::_ZTV7QBuffer) + 16u)
+ QIODevice (0x0x7f884d5b4b60) 0
+ primary-for QBuffer (0x0x7f884d5b4af8)
+ QObject (0x0x7f884d30a2a0) 0
+ primary-for QIODevice (0x0x7f884d5b4b60)
+
+Class QByteArrayMatcher::Data
+ size=272 align=8
+ base size=272 base align=8
+QByteArrayMatcher::Data (0x0x7f884d30a3c0) 0
+
+Class QByteArrayMatcher
+ size=1040 align=8
+ base size=1040 base align=8
+QByteArrayMatcher (0x0x7f884d30a360) 0
+
+Class QStaticByteArrayMatcherBase::Skiptable
+ size=256 align=1
+ base size=256 base align=1
+QStaticByteArrayMatcherBase::Skiptable (0x0x7f884d30a4e0) 0
+
+Class QStaticByteArrayMatcherBase
+ size=256 align=16
+ base size=256 base align=16
+QStaticByteArrayMatcherBase (0x0x7f884d30a480) 0
+
+Class QSharedData
+ size=4 align=4
+ base size=4 base align=4
+QSharedData (0x0x7f884d30a6c0) 0
+
+Class QLocale
+ size=8 align=8
+ base size=8 base align=8
+QLocale (0x0x7f884d30a8a0) 0
+
+Class QCollatorSortKey
+ size=8 align=8
+ base size=8 base align=8
+QCollatorSortKey (0x0x7f884d30aea0) 0
+
+Class QCollator
+ size=8 align=8
+ base size=8 base align=8
+QCollator (0x0x7f884d30af60) 0
+
+Class QCommandLineOption
+ size=8 align=8
+ base size=8 base align=8
+QCommandLineOption (0x0x7f884d13ff60) 0
+
+Vtable for QEvent
+QEvent::_ZTV6QEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QEvent)
+16 (int (*)(...))QEvent::~QEvent
+24 (int (*)(...))QEvent::~QEvent
+
+Class QEvent
+ size=24 align=8
+ base size=20 base align=8
+QEvent (0x0x7f884d176420) 0
+ vptr=((& QEvent::_ZTV6QEvent) + 16u)
+
+Vtable for QTimerEvent
+QTimerEvent::_ZTV11QTimerEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTimerEvent)
+16 (int (*)(...))QTimerEvent::~QTimerEvent
+24 (int (*)(...))QTimerEvent::~QTimerEvent
+
+Class QTimerEvent
+ size=24 align=8
+ base size=24 base align=8
+QTimerEvent (0x0x7f884d191068) 0
+ vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u)
+ QEvent (0x0x7f884d176480) 0
+ primary-for QTimerEvent (0x0x7f884d191068)
+
+Vtable for QChildEvent
+QChildEvent::_ZTV11QChildEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QChildEvent)
+16 (int (*)(...))QChildEvent::~QChildEvent
+24 (int (*)(...))QChildEvent::~QChildEvent
+
+Class QChildEvent
+ size=32 align=8
+ base size=32 base align=8
+QChildEvent (0x0x7f884d1910d0) 0
+ vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u)
+ QEvent (0x0x7f884d1764e0) 0
+ primary-for QChildEvent (0x0x7f884d1910d0)
+
+Vtable for QDynamicPropertyChangeEvent
+QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent)
+16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+
+Class QDynamicPropertyChangeEvent
+ size=32 align=8
+ base size=32 base align=8
+QDynamicPropertyChangeEvent (0x0x7f884d191618) 0
+ vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u)
+ QEvent (0x0x7f884d1769c0) 0
+ primary-for QDynamicPropertyChangeEvent (0x0x7f884d191618)
+
+Vtable for QDeferredDeleteEvent
+QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent)
+16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent
+24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent
+
+Class QDeferredDeleteEvent
+ size=24 align=8
+ base size=24 base align=8
+QDeferredDeleteEvent (0x0x7f884d191680) 0
+ vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u)
+ QEvent (0x0x7f884d176a20) 0
+ primary-for QDeferredDeleteEvent (0x0x7f884d191680)
+
+Class QCoreApplication::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QCoreApplication::QPrivateSignal (0x0x7f884d176ae0) 0 empty
+
+Vtable for QCoreApplication
+QCoreApplication::_ZTV16QCoreApplication: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QCoreApplication)
+16 (int (*)(...))QCoreApplication::metaObject
+24 (int (*)(...))QCoreApplication::qt_metacast
+32 (int (*)(...))QCoreApplication::qt_metacall
+40 (int (*)(...))QCoreApplication::~QCoreApplication
+48 (int (*)(...))QCoreApplication::~QCoreApplication
+56 (int (*)(...))QCoreApplication::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QCoreApplication::notify
+120 (int (*)(...))QCoreApplication::compressEvent
+
+Class QCoreApplication
+ size=16 align=8
+ base size=16 base align=8
+QCoreApplication (0x0x7f884d1916e8) 0
+ vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u)
+ QObject (0x0x7f884d176a80) 0
+ primary-for QCoreApplication (0x0x7f884d1916e8)
+
+Class QCommandLineParser
+ size=8 align=8
+ base size=8 base align=8
+QCommandLineParser (0x0x7f884d176b40) 0
+
+Class QContiguousCacheData
+ size=24 align=4
+ base size=24 base align=4
+QContiguousCacheData (0x0x7f884d176ba0) 0
+
+Class QCryptographicHash
+ size=8 align=8
+ base size=8 base align=8
+QCryptographicHash (0x0x7f884ce131e0) 0
+
+Class QDataStream
+ size=32 align=8
+ base size=32 base align=8
+QDataStream (0x0x7f884ce13240) 0
+
+Class QtPrivate::StreamStateSaver
+ size=16 align=8
+ base size=12 base align=8
+QtPrivate::StreamStateSaver (0x0x7f884ce13300) 0
+
+Class QDate
+ size=8 align=8
+ base size=8 base align=8
+QDate (0x0x7f884ce137e0) 0
+
+Class QTime
+ size=4 align=4
+ base size=4 base align=4
+QTime (0x0x7f884ce13a80) 0
+
+Class QDateTime::ShortData
+ size=8 align=8
+ base size=8 base align=8
+QDateTime::ShortData (0x0x7f884ceeb240) 0
+
+Class QDateTime::Data
+ size=8 align=8
+ base size=8 base align=8
+QDateTime::Data (0x0x7f884ceeb2a0) 0
+
+Class QDateTime
+ size=8 align=8
+ base size=8 base align=8
+QDateTime (0x0x7f884ceeb1e0) 0
+
+Class QElapsedTimer
+ size=16 align=8
+ base size=16 base align=8
+QElapsedTimer (0x0x7f884cf923c0) 0
+
+Class QDeadlineTimer
+ size=16 align=8
+ base size=16 base align=8
+QDeadlineTimer (0x0x7f884cf928a0) 0
+
+Vtable for QTextStream
+QTextStream::_ZTV11QTextStream: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTextStream)
+16 (int (*)(...))QTextStream::~QTextStream
+24 (int (*)(...))QTextStream::~QTextStream
+
+Class QTextStream
+ size=16 align=8
+ base size=16 base align=8
+QTextStream (0x0x7f884ccb0840) 0
+ vptr=((& QTextStream::_ZTV11QTextStream) + 16u)
+
+Class QTextStreamManipulator
+ size=40 align=8
+ base size=38 base align=8
+QTextStreamManipulator (0x0x7f884ccb0ae0) 0
+
+Class QtSharedPointer::NormalDeleter
+ size=1 align=1
+ base size=0 base align=1
+QtSharedPointer::NormalDeleter (0x0x7f884ccb0d20) 0 empty
+
+Class QtSharedPointer::ExternalRefCountData
+ size=16 align=8
+ base size=16 base align=8
+QtSharedPointer::ExternalRefCountData (0x0x7f884ccb0ea0) 0
+
+Class QDebug::Stream
+ size=80 align=8
+ base size=76 base align=8
+QDebug::Stream (0x0x7f884c9fa420) 0
+
+Class QDebug
+ size=8 align=8
+ base size=8 base align=8
+QDebug (0x0x7f884c9fa3c0) 0
+
+Class QDebugStateSaver
+ size=8 align=8
+ base size=8 base align=8
+QDebugStateSaver (0x0x7f884cb4b900) 0
+
+Class QNoDebug
+ size=1 align=1
+ base size=0 base align=1
+QNoDebug (0x0x7f884cb4b9c0) 0 empty
+
+Class QFileDevice::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFileDevice::QPrivateSignal (0x0x7f884c822b40) 0 empty
+
+Vtable for QFileDevice
+QFileDevice::_ZTV11QFileDevice: 34u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QFileDevice)
+16 (int (*)(...))QFileDevice::metaObject
+24 (int (*)(...))QFileDevice::qt_metacast
+32 (int (*)(...))QFileDevice::qt_metacall
+40 (int (*)(...))QFileDevice::~QFileDevice
+48 (int (*)(...))QFileDevice::~QFileDevice
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QFileDevice::isSequential
+120 (int (*)(...))QIODevice::open
+128 (int (*)(...))QFileDevice::close
+136 (int (*)(...))QFileDevice::pos
+144 (int (*)(...))QFileDevice::size
+152 (int (*)(...))QFileDevice::seek
+160 (int (*)(...))QFileDevice::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QIODevice::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))QFileDevice::readData
+224 (int (*)(...))QFileDevice::readLineData
+232 (int (*)(...))QFileDevice::writeData
+240 (int (*)(...))QFileDevice::fileName
+248 (int (*)(...))QFileDevice::resize
+256 (int (*)(...))QFileDevice::permissions
+264 (int (*)(...))QFileDevice::setPermissions
+
+Class QFileDevice
+ size=16 align=8
+ base size=16 base align=8
+QFileDevice (0x0x7f884c835618) 0
+ vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u)
+ QIODevice (0x0x7f884c835680) 0
+ primary-for QFileDevice (0x0x7f884c835618)
+ QObject (0x0x7f884c822ae0) 0
+ primary-for QIODevice (0x0x7f884c835680)
+
+Class QFile::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFile::QPrivateSignal (0x0x7f884c822d80) 0 empty
+
+Vtable for QFile
+QFile::_ZTV5QFile: 34u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI5QFile)
+16 (int (*)(...))QFile::metaObject
+24 (int (*)(...))QFile::qt_metacast
+32 (int (*)(...))QFile::qt_metacall
+40 (int (*)(...))QFile::~QFile
+48 (int (*)(...))QFile::~QFile
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QFileDevice::isSequential
+120 (int (*)(...))QFile::open
+128 (int (*)(...))QFileDevice::close
+136 (int (*)(...))QFileDevice::pos
+144 (int (*)(...))QFile::size
+152 (int (*)(...))QFileDevice::seek
+160 (int (*)(...))QFileDevice::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QIODevice::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))QFileDevice::readData
+224 (int (*)(...))QFileDevice::readLineData
+232 (int (*)(...))QFileDevice::writeData
+240 (int (*)(...))QFile::fileName
+248 (int (*)(...))QFile::resize
+256 (int (*)(...))QFile::permissions
+264 (int (*)(...))QFile::setPermissions
+
+Class QFile
+ size=16 align=8
+ base size=16 base align=8
+QFile (0x0x7f884c8357b8) 0
+ vptr=((& QFile::_ZTV5QFile) + 16u)
+ QFileDevice (0x0x7f884c835820) 0
+ primary-for QFile (0x0x7f884c8357b8)
+ QIODevice (0x0x7f884c835888) 0
+ primary-for QFileDevice (0x0x7f884c835820)
+ QObject (0x0x7f884c822d20) 0
+ primary-for QIODevice (0x0x7f884c835888)
+
+Class QFileInfo
+ size=8 align=8
+ base size=8 base align=8
+QFileInfo (0x0x7f884c822f60) 0
+
+Class QDir
+ size=8 align=8
+ base size=8 base align=8
+QDir (0x0x7f884c8d33c0) 0
+
+Class QDirIterator
+ size=8 align=8
+ base size=8 base align=8
+QDirIterator (0x0x7f884c8d3d80) 0
+
+Class QEasingCurve
+ size=8 align=8
+ base size=8 base align=8
+QEasingCurve (0x0x7f884c9c3000) 0
+
+Class QEventTransition::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QEventTransition::QPrivateSignal (0x0x7f884c655420) 0 empty
+
+Vtable for QEventTransition
+QEventTransition::_ZTV16QEventTransition: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QEventTransition)
+16 (int (*)(...))QEventTransition::metaObject
+24 (int (*)(...))QEventTransition::qt_metacast
+32 (int (*)(...))QEventTransition::qt_metacall
+40 (int (*)(...))QEventTransition::~QEventTransition
+48 (int (*)(...))QEventTransition::~QEventTransition
+56 (int (*)(...))QEventTransition::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QEventTransition::eventTest
+120 (int (*)(...))QEventTransition::onTransition
+
+Class QEventTransition
+ size=16 align=8
+ base size=16 base align=8
+QEventTransition (0x0x7f884c645a90) 0
+ vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u)
+ QAbstractTransition (0x0x7f884c645af8) 0
+ primary-for QEventTransition (0x0x7f884c645a90)
+ QObject (0x0x7f884c6553c0) 0
+ primary-for QAbstractTransition (0x0x7f884c645af8)
+
+Vtable for QException
+QException::_ZTV10QException: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QException)
+16 (int (*)(...))QException::~QException
+24 (int (*)(...))QException::~QException
+32 (int (*)(...))std::exception::what
+40 (int (*)(...))QException::raise
+48 (int (*)(...))QException::clone
+
+Class QException
+ size=8 align=8
+ base size=8 base align=8
+QException (0x0x7f884c645b60) 0 nearly-empty
+ vptr=((& QException::_ZTV10QException) + 16u)
+ std::exception (0x0x7f884c655480) 0 nearly-empty
+ primary-for QException (0x0x7f884c645b60)
+
+Vtable for QUnhandledException
+QUnhandledException::_ZTV19QUnhandledException: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QUnhandledException)
+16 (int (*)(...))QUnhandledException::~QUnhandledException
+24 (int (*)(...))QUnhandledException::~QUnhandledException
+32 (int (*)(...))std::exception::what
+40 (int (*)(...))QUnhandledException::raise
+48 (int (*)(...))QUnhandledException::clone
+
+Class QUnhandledException
+ size=8 align=8
+ base size=8 base align=8
+QUnhandledException (0x0x7f884c645bc8) 0 nearly-empty
+ vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u)
+ QException (0x0x7f884c645c30) 0 nearly-empty
+ primary-for QUnhandledException (0x0x7f884c645bc8)
+ std::exception (0x0x7f884c6554e0) 0 nearly-empty
+ primary-for QException (0x0x7f884c645c30)
+
+Class QtPrivate::ExceptionHolder
+ size=8 align=8
+ base size=8 base align=8
+QtPrivate::ExceptionHolder (0x0x7f884c655540) 0
+
+Class QtPrivate::ExceptionStore
+ size=8 align=8
+ base size=8 base align=8
+QtPrivate::ExceptionStore (0x0x7f884c655600) 0
+
+Vtable for QFactoryInterface
+QFactoryInterface::_ZTV17QFactoryInterface: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QFactoryInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class QFactoryInterface
+ size=8 align=8
+ base size=8 base align=8
+QFactoryInterface (0x0x7f884c655660) 0 nearly-empty
+ vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u)
+
+Class QFileSelector::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFileSelector::QPrivateSignal (0x0x7f884c655780) 0 empty
+
+Vtable for QFileSelector
+QFileSelector::_ZTV13QFileSelector: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QFileSelector)
+16 (int (*)(...))QFileSelector::metaObject
+24 (int (*)(...))QFileSelector::qt_metacast
+32 (int (*)(...))QFileSelector::qt_metacall
+40 (int (*)(...))QFileSelector::~QFileSelector
+48 (int (*)(...))QFileSelector::~QFileSelector
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QFileSelector
+ size=16 align=8
+ base size=16 base align=8
+QFileSelector (0x0x7f884c645c98) 0
+ vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u)
+ QObject (0x0x7f884c655720) 0
+ primary-for QFileSelector (0x0x7f884c645c98)
+
+Class QFileSystemWatcher::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFileSystemWatcher::QPrivateSignal (0x0x7f884c655840) 0 empty
+
+Vtable for QFileSystemWatcher
+QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QFileSystemWatcher)
+16 (int (*)(...))QFileSystemWatcher::metaObject
+24 (int (*)(...))QFileSystemWatcher::qt_metacast
+32 (int (*)(...))QFileSystemWatcher::qt_metacall
+40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher
+48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QFileSystemWatcher
+ size=16 align=8
+ base size=16 base align=8
+QFileSystemWatcher (0x0x7f884c645d00) 0
+ vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u)
+ QObject (0x0x7f884c6557e0) 0
+ primary-for QFileSystemWatcher (0x0x7f884c645d00)
+
+Class QFinalState::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFinalState::QPrivateSignal (0x0x7f884c655900) 0 empty
+
+Vtable for QFinalState
+QFinalState::_ZTV11QFinalState: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QFinalState)
+16 (int (*)(...))QFinalState::metaObject
+24 (int (*)(...))QFinalState::qt_metacast
+32 (int (*)(...))QFinalState::qt_metacall
+40 (int (*)(...))QFinalState::~QFinalState
+48 (int (*)(...))QFinalState::~QFinalState
+56 (int (*)(...))QFinalState::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QFinalState::onEntry
+120 (int (*)(...))QFinalState::onExit
+
+Class QFinalState
+ size=16 align=8
+ base size=16 base align=8
+QFinalState (0x0x7f884c645d68) 0
+ vptr=((& QFinalState::_ZTV11QFinalState) + 16u)
+ QAbstractState (0x0x7f884c645dd0) 0
+ primary-for QFinalState (0x0x7f884c645d68)
+ QObject (0x0x7f884c6558a0) 0
+ primary-for QAbstractState (0x0x7f884c645dd0)
+
+Vtable for QRunnable
+QRunnable::_ZTV9QRunnable: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QRunnable)
+16 (int (*)(...))__cxa_pure_virtual
+24 0u
+32 0u
+
+Class QRunnable
+ size=16 align=8
+ base size=12 base align=8
+QRunnable (0x0x7f884c655960) 0
+ vptr=((& QRunnable::_ZTV9QRunnable) + 16u)
+
+Class QBasicMutex
+ size=8 align=8
+ base size=8 base align=8
+QBasicMutex (0x0x7f884c6559c0) 0
+
+Class QMutex
+ size=8 align=8
+ base size=8 base align=8
+QMutex (0x0x7f884c645f08) 0
+ QBasicMutex (0x0x7f884c655ba0) 0
+
+Class QMutexLocker
+ size=8 align=8
+ base size=8 base align=8
+QMutexLocker (0x0x7f884c655c00) 0
+
+Class QtPrivate::ResultItem
+ size=16 align=8
+ base size=16 base align=8
+QtPrivate::ResultItem (0x0x7f884c655c60) 0
+
+Class QtPrivate::ResultIteratorBase
+ size=16 align=8
+ base size=12 base align=8
+QtPrivate::ResultIteratorBase (0x0x7f884c655cc0) 0
+
+Vtable for QtPrivate::ResultStoreBase
+QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE)
+16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase
+24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase
+
+Class QtPrivate::ResultStoreBase
+ size=48 align=8
+ base size=44 base align=8
+QtPrivate::ResultStoreBase (0x0x7f884c655de0) 0
+ vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u)
+
+Vtable for QFutureInterfaceBase
+QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QFutureInterfaceBase)
+16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase
+24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase
+
+Class QFutureInterfaceBase
+ size=16 align=8
+ base size=16 base align=8
+QFutureInterfaceBase (0x0x7f884c3d6660) 0
+ vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u)
+
+Class QFutureWatcherBase::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFutureWatcherBase::QPrivateSignal (0x0x7f884c3d6e40) 0 empty
+
+Vtable for QFutureWatcherBase
+QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QFutureWatcherBase)
+16 (int (*)(...))QFutureWatcherBase::metaObject
+24 (int (*)(...))QFutureWatcherBase::qt_metacast
+32 (int (*)(...))QFutureWatcherBase::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QFutureWatcherBase::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QFutureWatcherBase::connectNotify
+104 (int (*)(...))QFutureWatcherBase::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+
+Class QFutureWatcherBase
+ size=16 align=8
+ base size=16 base align=8
+QFutureWatcherBase (0x0x7f884c461068) 0
+ vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u)
+ QObject (0x0x7f884c3d6de0) 0
+ primary-for QFutureWatcherBase (0x0x7f884c461068)
+
+Class QHistoryState::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QHistoryState::QPrivateSignal (0x0x7f884c4b5480) 0 empty
+
+Vtable for QHistoryState
+QHistoryState::_ZTV13QHistoryState: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QHistoryState)
+16 (int (*)(...))QHistoryState::metaObject
+24 (int (*)(...))QHistoryState::qt_metacast
+32 (int (*)(...))QHistoryState::qt_metacall
+40 (int (*)(...))QHistoryState::~QHistoryState
+48 (int (*)(...))QHistoryState::~QHistoryState
+56 (int (*)(...))QHistoryState::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QHistoryState::onEntry
+120 (int (*)(...))QHistoryState::onExit
+
+Class QHistoryState
+ size=16 align=8
+ base size=16 base align=8
+QHistoryState (0x0x7f884c461958) 0
+ vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u)
+ QAbstractState (0x0x7f884c4619c0) 0
+ primary-for QHistoryState (0x0x7f884c461958)
+ QObject (0x0x7f884c4b5420) 0
+ primary-for QAbstractState (0x0x7f884c4619c0)
+
+Class QIdentityProxyModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QIdentityProxyModel::QPrivateSignal (0x0x7f884c4b5540) 0 empty
+
+Vtable for QIdentityProxyModel
+QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QIdentityProxyModel)
+16 (int (*)(...))QIdentityProxyModel::metaObject
+24 (int (*)(...))QIdentityProxyModel::qt_metacast
+32 (int (*)(...))QIdentityProxyModel::qt_metacall
+40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel
+48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QIdentityProxyModel::index
+120 (int (*)(...))QIdentityProxyModel::parent
+128 (int (*)(...))QIdentityProxyModel::sibling
+136 (int (*)(...))QIdentityProxyModel::rowCount
+144 (int (*)(...))QIdentityProxyModel::columnCount
+152 (int (*)(...))QAbstractProxyModel::hasChildren
+160 (int (*)(...))QAbstractProxyModel::data
+168 (int (*)(...))QAbstractProxyModel::setData
+176 (int (*)(...))QIdentityProxyModel::headerData
+184 (int (*)(...))QAbstractProxyModel::setHeaderData
+192 (int (*)(...))QAbstractProxyModel::itemData
+200 (int (*)(...))QAbstractProxyModel::setItemData
+208 (int (*)(...))QAbstractProxyModel::mimeTypes
+216 (int (*)(...))QAbstractProxyModel::mimeData
+224 (int (*)(...))QAbstractProxyModel::canDropMimeData
+232 (int (*)(...))QIdentityProxyModel::dropMimeData
+240 (int (*)(...))QAbstractProxyModel::supportedDropActions
+248 (int (*)(...))QAbstractProxyModel::supportedDragActions
+256 (int (*)(...))QIdentityProxyModel::insertRows
+264 (int (*)(...))QIdentityProxyModel::insertColumns
+272 (int (*)(...))QIdentityProxyModel::removeRows
+280 (int (*)(...))QIdentityProxyModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractProxyModel::fetchMore
+312 (int (*)(...))QAbstractProxyModel::canFetchMore
+320 (int (*)(...))QAbstractProxyModel::flags
+328 (int (*)(...))QAbstractProxyModel::sort
+336 (int (*)(...))QAbstractProxyModel::buddy
+344 (int (*)(...))QIdentityProxyModel::match
+352 (int (*)(...))QAbstractProxyModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractProxyModel::submit
+376 (int (*)(...))QAbstractProxyModel::revert
+384 (int (*)(...))QIdentityProxyModel::setSourceModel
+392 (int (*)(...))QIdentityProxyModel::mapToSource
+400 (int (*)(...))QIdentityProxyModel::mapFromSource
+408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource
+416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource
+
+Class QIdentityProxyModel
+ size=16 align=8
+ base size=16 base align=8
+QIdentityProxyModel (0x0x7f884c461a28) 0
+ vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u)
+ QAbstractProxyModel (0x0x7f884c461a90) 0
+ primary-for QIdentityProxyModel (0x0x7f884c461a28)
+ QAbstractItemModel (0x0x7f884c461af8) 0
+ primary-for QAbstractProxyModel (0x0x7f884c461a90)
+ QObject (0x0x7f884c4b54e0) 0
+ primary-for QAbstractItemModel (0x0x7f884c461af8)
+
+Class QItemSelectionRange
+ size=16 align=8
+ base size=16 base align=8
+QItemSelectionRange (0x0x7f884c4b55a0) 0
+
+Class QItemSelectionModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QItemSelectionModel::QPrivateSignal (0x0x7f884c4b5c60) 0 empty
+
+Vtable for QItemSelectionModel
+QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QItemSelectionModel)
+16 (int (*)(...))QItemSelectionModel::metaObject
+24 (int (*)(...))QItemSelectionModel::qt_metacast
+32 (int (*)(...))QItemSelectionModel::qt_metacall
+40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel
+48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QItemSelectionModel::setCurrentIndex
+120 (int (*)(...))QItemSelectionModel::select
+128 (int (*)(...))QItemSelectionModel::select
+136 (int (*)(...))QItemSelectionModel::clear
+144 (int (*)(...))QItemSelectionModel::reset
+152 (int (*)(...))QItemSelectionModel::clearCurrentIndex
+
+Class QItemSelectionModel
+ size=16 align=8
+ base size=16 base align=8
+QItemSelectionModel (0x0x7f884c524340) 0
+ vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u)
+ QObject (0x0x7f884c4b5c00) 0
+ primary-for QItemSelectionModel (0x0x7f884c524340)
+
+Class QItemSelection
+ size=8 align=8
+ base size=8 base align=8
+QItemSelection (0x0x7f884c524548) 0
+ QList<QItemSelectionRange> (0x0x7f884c5245b0) 0
+ QListSpecialMethods<QItemSelectionRange> (0x0x7f884c4b5f60) 0 empty
+
+Class QJsonValue
+ size=24 align=8
+ base size=20 base align=8
+QJsonValue (0x0x7f884c5aa480) 0
+
+Class QJsonValueRef
+ size=16 align=8
+ base size=12 base align=8
+QJsonValueRef (0x0x7f884c322ba0) 0
+
+Class QJsonValuePtr
+ size=24 align=8
+ base size=24 base align=8
+QJsonValuePtr (0x0x7f884c387120) 0
+
+Class QJsonValueRefPtr
+ size=16 align=8
+ base size=16 base align=8
+QJsonValueRefPtr (0x0x7f884c387180) 0
+
+Class QJsonArray::iterator
+ size=16 align=8
+ base size=12 base align=8
+QJsonArray::iterator (0x0x7f884c387360) 0
+
+Class QJsonArray::const_iterator
+ size=16 align=8
+ base size=12 base align=8
+QJsonArray::const_iterator (0x0x7f884c3873c0) 0
+
+Class QJsonArray
+ size=16 align=8
+ base size=16 base align=8
+QJsonArray (0x0x7f884c387300) 0
+
+Class QJsonParseError
+ size=8 align=4
+ base size=8 base align=4
+QJsonParseError (0x0x7f884c043600) 0
+
+Class QJsonDocument
+ size=8 align=8
+ base size=8 base align=8
+QJsonDocument (0x0x7f884c043660) 0
+
+Class QJsonObject::iterator
+ size=16 align=8
+ base size=12 base align=8
+QJsonObject::iterator (0x0x7f884c043cc0) 0
+
+Class QJsonObject::const_iterator
+ size=16 align=8
+ base size=12 base align=8
+QJsonObject::const_iterator (0x0x7f884c043d20) 0
+
+Class QJsonObject
+ size=16 align=8
+ base size=16 base align=8
+QJsonObject (0x0x7f884c043c60) 0
+
+Class QLibrary::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QLibrary::QPrivateSignal (0x0x7f884c1ad000) 0 empty
+
+Vtable for QLibrary
+QLibrary::_ZTV8QLibrary: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QLibrary)
+16 (int (*)(...))QLibrary::metaObject
+24 (int (*)(...))QLibrary::qt_metacast
+32 (int (*)(...))QLibrary::qt_metacall
+40 (int (*)(...))QLibrary::~QLibrary
+48 (int (*)(...))QLibrary::~QLibrary
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QLibrary
+ size=32 align=8
+ base size=25 base align=8
+QLibrary (0x0x7f884c1688f0) 0
+ vptr=((& QLibrary::_ZTV8QLibrary) + 16u)
+ QObject (0x0x7f884c152f60) 0
+ primary-for QLibrary (0x0x7f884c1688f0)
+
+Class QVersionNumber::SegmentStorage
+ size=8 align=8
+ base size=8 base align=8
+QVersionNumber::SegmentStorage (0x0x7f884c1ad6c0) 0
+
+Class QVersionNumber
+ size=8 align=8
+ base size=8 base align=8
+QVersionNumber (0x0x7f884c1ad1e0) 0
+
+Class QLibraryInfo
+ size=1 align=1
+ base size=0 base align=1
+QLibraryInfo (0x0x7f884c1adba0) 0 empty
+
+Class QPoint
+ size=8 align=4
+ base size=8 base align=4
+QPoint (0x0x7f884c1adc00) 0
+
+Class QPointF
+ size=16 align=8
+ base size=16 base align=8
+QPointF (0x0x7f884c1adea0) 0
+
+Class QLine
+ size=16 align=4
+ base size=16 base align=4
+QLine (0x0x7f884be94180) 0
+
+Class QLineF
+ size=32 align=8
+ base size=32 base align=8
+QLineF (0x0x7f884be94ae0) 0
+
+Class QLinkedListData
+ size=32 align=8
+ base size=25 base align=8
+QLinkedListData (0x0x7f884bf20480) 0
+
+Class QLockFile
+ size=8 align=8
+ base size=8 base align=8
+QLockFile (0x0x7f884bf207e0) 0
+
+Class QLoggingCategory::AtomicBools
+ size=4 align=1
+ base size=4 base align=1
+QLoggingCategory::AtomicBools (0x0x7f884bf20960) 0
+
+Class QLoggingCategory
+ size=24 align=8
+ base size=24 base align=8
+QLoggingCategory (0x0x7f884bf20900) 0
+
+Class QMargins
+ size=16 align=4
+ base size=16 base align=4
+QMargins (0x0x7f884bf20ae0) 0
+
+Class QMarginsF
+ size=32 align=8
+ base size=32 base align=8
+QMarginsF (0x0x7f884bf20d80) 0
+
+Class QMessageAuthenticationCode
+ size=8 align=8
+ base size=8 base align=8
+QMessageAuthenticationCode (0x0x7f884bca4420) 0
+
+Class QMetaMethod
+ size=16 align=8
+ base size=12 base align=8
+QMetaMethod (0x0x7f884bca4480) 0
+
+Class QMetaEnum
+ size=16 align=8
+ base size=12 base align=8
+QMetaEnum (0x0x7f884bca4a80) 0
+
+Class QMetaProperty
+ size=32 align=8
+ base size=32 base align=8
+QMetaProperty (0x0x7f884bca4d80) 0
+
+Class QMetaClassInfo
+ size=16 align=8
+ base size=12 base align=8
+QMetaClassInfo (0x0x7f884bca4de0) 0
+
+Class QMimeData::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QMimeData::QPrivateSignal (0x0x7f884bd5c120) 0 empty
+
+Vtable for QMimeData
+QMimeData::_ZTV9QMimeData: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QMimeData)
+16 (int (*)(...))QMimeData::metaObject
+24 (int (*)(...))QMimeData::qt_metacast
+32 (int (*)(...))QMimeData::qt_metacall
+40 (int (*)(...))QMimeData::~QMimeData
+48 (int (*)(...))QMimeData::~QMimeData
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QMimeData::hasFormat
+120 (int (*)(...))QMimeData::formats
+128 (int (*)(...))QMimeData::retrieveData
+
+Class QMimeData
+ size=16 align=8
+ base size=16 base align=8
+QMimeData (0x0x7f884bcc2b60) 0
+ vptr=((& QMimeData::_ZTV9QMimeData) + 16u)
+ QObject (0x0x7f884bd5c0c0) 0
+ primary-for QMimeData (0x0x7f884bcc2b60)
+
+Class QMimeType
+ size=8 align=8
+ base size=8 base align=8
+QMimeType (0x0x7f884bd5c180) 0
+
+Class QMimeDatabase
+ size=8 align=8
+ base size=8 base align=8
+QMimeDatabase (0x0x7f884bd5c480) 0
+
+Class QObjectCleanupHandler::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QObjectCleanupHandler::QPrivateSignal (0x0x7f884bd5c540) 0 empty
+
+Vtable for QObjectCleanupHandler
+QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QObjectCleanupHandler)
+16 (int (*)(...))QObjectCleanupHandler::metaObject
+24 (int (*)(...))QObjectCleanupHandler::qt_metacast
+32 (int (*)(...))QObjectCleanupHandler::qt_metacall
+40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler
+48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QObjectCleanupHandler
+ size=24 align=8
+ base size=24 base align=8
+QObjectCleanupHandler (0x0x7f884bcc2d68) 0
+ vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u)
+ QObject (0x0x7f884bd5c4e0) 0
+ primary-for QObjectCleanupHandler (0x0x7f884bcc2d68)
+
+Class QOperatingSystemVersion
+ size=16 align=4
+ base size=16 base align=4
+QOperatingSystemVersion (0x0x7f884bd5c5a0) 0
+
+Class QParallelAnimationGroup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QParallelAnimationGroup::QPrivateSignal (0x0x7f884bd5cd20) 0 empty
+
+Vtable for QParallelAnimationGroup
+QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QParallelAnimationGroup)
+16 (int (*)(...))QParallelAnimationGroup::metaObject
+24 (int (*)(...))QParallelAnimationGroup::qt_metacast
+32 (int (*)(...))QParallelAnimationGroup::qt_metacall
+40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup
+48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup
+56 (int (*)(...))QParallelAnimationGroup::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QParallelAnimationGroup::duration
+120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime
+128 (int (*)(...))QParallelAnimationGroup::updateState
+136 (int (*)(...))QParallelAnimationGroup::updateDirection
+
+Class QParallelAnimationGroup
+ size=16 align=8
+ base size=16 base align=8
+QParallelAnimationGroup (0x0x7f884b9bc478) 0
+ vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u)
+ QAnimationGroup (0x0x7f884b9bc4e0) 0
+ primary-for QParallelAnimationGroup (0x0x7f884b9bc478)
+ QAbstractAnimation (0x0x7f884b9bc548) 0
+ primary-for QAnimationGroup (0x0x7f884b9bc4e0)
+ QObject (0x0x7f884bd5ccc0) 0
+ primary-for QAbstractAnimation (0x0x7f884b9bc548)
+
+Class QPauseAnimation::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPauseAnimation::QPrivateSignal (0x0x7f884bd5cde0) 0 empty
+
+Vtable for QPauseAnimation
+QPauseAnimation::_ZTV15QPauseAnimation: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QPauseAnimation)
+16 (int (*)(...))QPauseAnimation::metaObject
+24 (int (*)(...))QPauseAnimation::qt_metacast
+32 (int (*)(...))QPauseAnimation::qt_metacall
+40 (int (*)(...))QPauseAnimation::~QPauseAnimation
+48 (int (*)(...))QPauseAnimation::~QPauseAnimation
+56 (int (*)(...))QPauseAnimation::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QPauseAnimation::duration
+120 (int (*)(...))QPauseAnimation::updateCurrentTime
+128 (int (*)(...))QAbstractAnimation::updateState
+136 (int (*)(...))QAbstractAnimation::updateDirection
+
+Class QPauseAnimation
+ size=16 align=8
+ base size=16 base align=8
+QPauseAnimation (0x0x7f884b9bc5b0) 0
+ vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u)
+ QAbstractAnimation (0x0x7f884b9bc618) 0
+ primary-for QPauseAnimation (0x0x7f884b9bc5b0)
+ QObject (0x0x7f884bd5cd80) 0
+ primary-for QAbstractAnimation (0x0x7f884b9bc618)
+
+Class QStaticPlugin
+ size=16 align=8
+ base size=16 base align=8
+QStaticPlugin (0x0x7f884ba0e000) 0
+
+Class QPluginLoader::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPluginLoader::QPrivateSignal (0x0x7f884ba0e300) 0 empty
+
+Vtable for QPluginLoader
+QPluginLoader::_ZTV13QPluginLoader: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QPluginLoader)
+16 (int (*)(...))QPluginLoader::metaObject
+24 (int (*)(...))QPluginLoader::qt_metacast
+32 (int (*)(...))QPluginLoader::qt_metacall
+40 (int (*)(...))QPluginLoader::~QPluginLoader
+48 (int (*)(...))QPluginLoader::~QPluginLoader
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QPluginLoader
+ size=32 align=8
+ base size=25 base align=8
+QPluginLoader (0x0x7f884b9bc820) 0
+ vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u)
+ QObject (0x0x7f884ba0e2a0) 0
+ primary-for QPluginLoader (0x0x7f884b9bc820)
+
+Class QProcessEnvironment
+ size=8 align=8
+ base size=8 base align=8
+QProcessEnvironment (0x0x7f884ba0e360) 0
+
+Class QProcess::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QProcess::QPrivateSignal (0x0x7f884ba0ea20) 0 empty
+
+Vtable for QProcess
+QProcess::_ZTV8QProcess: 31u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QProcess)
+16 (int (*)(...))QProcess::metaObject
+24 (int (*)(...))QProcess::qt_metacast
+32 (int (*)(...))QProcess::qt_metacall
+40 (int (*)(...))QProcess::~QProcess
+48 (int (*)(...))QProcess::~QProcess
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QProcess::isSequential
+120 (int (*)(...))QProcess::open
+128 (int (*)(...))QProcess::close
+136 (int (*)(...))QIODevice::pos
+144 (int (*)(...))QIODevice::size
+152 (int (*)(...))QIODevice::seek
+160 (int (*)(...))QProcess::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QProcess::bytesAvailable
+184 (int (*)(...))QProcess::bytesToWrite
+192 (int (*)(...))QProcess::canReadLine
+200 (int (*)(...))QProcess::waitForReadyRead
+208 (int (*)(...))QProcess::waitForBytesWritten
+216 (int (*)(...))QProcess::readData
+224 (int (*)(...))QIODevice::readLineData
+232 (int (*)(...))QProcess::writeData
+240 (int (*)(...))QProcess::setupChildProcess
+
+Class QProcess
+ size=16 align=8
+ base size=16 base align=8
+QProcess (0x0x7f884b9bcea0) 0
+ vptr=((& QProcess::_ZTV8QProcess) + 16u)
+ QIODevice (0x0x7f884b9bcf08) 0
+ primary-for QProcess (0x0x7f884b9bcea0)
+ QObject (0x0x7f884ba0e9c0) 0
+ primary-for QIODevice (0x0x7f884b9bcf08)
+
+Class QVariantAnimation::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QVariantAnimation::QPrivateSignal (0x0x7f884ba0eae0) 0 empty
+
+Vtable for QVariantAnimation
+QVariantAnimation::_ZTV17QVariantAnimation: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QVariantAnimation)
+16 (int (*)(...))QVariantAnimation::metaObject
+24 (int (*)(...))QVariantAnimation::qt_metacast
+32 (int (*)(...))QVariantAnimation::qt_metacall
+40 (int (*)(...))QVariantAnimation::~QVariantAnimation
+48 (int (*)(...))QVariantAnimation::~QVariantAnimation
+56 (int (*)(...))QVariantAnimation::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QVariantAnimation::duration
+120 (int (*)(...))QVariantAnimation::updateCurrentTime
+128 (int (*)(...))QVariantAnimation::updateState
+136 (int (*)(...))QAbstractAnimation::updateDirection
+144 (int (*)(...))QVariantAnimation::updateCurrentValue
+152 (int (*)(...))QVariantAnimation::interpolated
+
+Class QVariantAnimation
+ size=16 align=8
+ base size=16 base align=8
+QVariantAnimation (0x0x7f884b9bcf70) 0
+ vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u)
+ QAbstractAnimation (0x0x7f884ba80000) 0
+ primary-for QVariantAnimation (0x0x7f884b9bcf70)
+ QObject (0x0x7f884ba0ea80) 0
+ primary-for QAbstractAnimation (0x0x7f884ba80000)
+
+Class QPropertyAnimation::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPropertyAnimation::QPrivateSignal (0x0x7f884ba0eba0) 0 empty
+
+Vtable for QPropertyAnimation
+QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QPropertyAnimation)
+16 (int (*)(...))QPropertyAnimation::metaObject
+24 (int (*)(...))QPropertyAnimation::qt_metacast
+32 (int (*)(...))QPropertyAnimation::qt_metacall
+40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation
+48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation
+56 (int (*)(...))QPropertyAnimation::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QVariantAnimation::duration
+120 (int (*)(...))QVariantAnimation::updateCurrentTime
+128 (int (*)(...))QPropertyAnimation::updateState
+136 (int (*)(...))QAbstractAnimation::updateDirection
+144 (int (*)(...))QPropertyAnimation::updateCurrentValue
+152 (int (*)(...))QVariantAnimation::interpolated
+
+Class QPropertyAnimation
+ size=16 align=8
+ base size=16 base align=8
+QPropertyAnimation (0x0x7f884ba800d0) 0
+ vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u)
+ QVariantAnimation (0x0x7f884ba80138) 0
+ primary-for QPropertyAnimation (0x0x7f884ba800d0)
+ QAbstractAnimation (0x0x7f884ba801a0) 0
+ primary-for QVariantAnimation (0x0x7f884ba80138)
+ QObject (0x0x7f884ba0eb40) 0
+ primary-for QAbstractAnimation (0x0x7f884ba801a0)
+
+Class QRandomGenerator::Storage
+ size=2504 align=8
+ base size=2504 base align=8
+QRandomGenerator::Storage (0x0x7f884ba0ecc0) 0
+
+Class QRandomGenerator
+ size=2512 align=8
+ base size=2512 base align=8
+QRandomGenerator (0x0x7f884ba0ec60) 0
+
+Class QRandomGenerator64
+ size=2512 align=8
+ base size=2512 base align=8
+QRandomGenerator64 (0x0x7f884bb35478) 0
+ QRandomGenerator (0x0x7f884bb17c60) 0
+
+Class QReadWriteLock
+ size=8 align=8
+ base size=8 base align=8
+QReadWriteLock (0x0x7f884bb17d20) 0
+
+Class QReadLocker
+ size=8 align=8
+ base size=8 base align=8
+QReadLocker (0x0x7f884b7d6000) 0
+
+Class QWriteLocker
+ size=8 align=8
+ base size=8 base align=8
+QWriteLocker (0x0x7f884b7d60c0) 0
+
+Class QSize
+ size=8 align=4
+ base size=8 base align=4
+QSize (0x0x7f884b7d6180) 0
+
+Class QSizeF
+ size=16 align=8
+ base size=16 base align=8
+QSizeF (0x0x7f884b7d6420) 0
+
+Class QRect
+ size=16 align=4
+ base size=16 base align=4
+QRect (0x0x7f884b7d66c0) 0
+
+Class QRectF
+ size=32 align=8
+ base size=32 base align=8
+QRectF (0x0x7f884b7d6960) 0
+
+Class QRegularExpression
+ size=8 align=8
+ base size=8 base align=8
+QRegularExpression (0x0x7f884b7d6c00) 0
+
+Class QRegularExpressionMatch
+ size=8 align=8
+ base size=8 base align=8
+QRegularExpressionMatch (0x0x7f884b5d8240) 0
+
+Class QRegularExpressionMatchIterator
+ size=8 align=8
+ base size=8 base align=8
+QRegularExpressionMatchIterator (0x0x7f884b5d8540) 0
+
+Class QResource
+ size=8 align=8
+ base size=8 base align=8
+QResource (0x0x7f884b5d8840) 0
+
+Class QSaveFile::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSaveFile::QPrivateSignal (0x0x7f884b5d89c0) 0 empty
+
+Vtable for QSaveFile
+QSaveFile::_ZTV9QSaveFile: 34u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QSaveFile)
+16 (int (*)(...))QSaveFile::metaObject
+24 (int (*)(...))QSaveFile::qt_metacast
+32 (int (*)(...))QSaveFile::qt_metacall
+40 (int (*)(...))QSaveFile::~QSaveFile
+48 (int (*)(...))QSaveFile::~QSaveFile
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QFileDevice::isSequential
+120 (int (*)(...))QSaveFile::open
+128 (int (*)(...))QSaveFile::close
+136 (int (*)(...))QFileDevice::pos
+144 (int (*)(...))QFileDevice::size
+152 (int (*)(...))QFileDevice::seek
+160 (int (*)(...))QFileDevice::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QIODevice::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))QFileDevice::readData
+224 (int (*)(...))QFileDevice::readLineData
+232 (int (*)(...))QSaveFile::writeData
+240 (int (*)(...))QSaveFile::fileName
+248 (int (*)(...))QFileDevice::resize
+256 (int (*)(...))QFileDevice::permissions
+264 (int (*)(...))QFileDevice::setPermissions
+
+Class QSaveFile
+ size=16 align=8
+ base size=16 base align=8
+QSaveFile (0x0x7f884b9aa680) 0
+ vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u)
+ QFileDevice (0x0x7f884b9aa6e8) 0
+ primary-for QSaveFile (0x0x7f884b9aa680)
+ QIODevice (0x0x7f884b9aa750) 0
+ primary-for QFileDevice (0x0x7f884b9aa6e8)
+ QObject (0x0x7f884b5d8960) 0
+ primary-for QIODevice (0x0x7f884b9aa750)
+
+Class QSemaphore
+ size=8 align=8
+ base size=8 base align=8
+QSemaphore (0x0x7f884b5d8a80) 0
+
+Class QSemaphoreReleaser
+ size=16 align=8
+ base size=12 base align=8
+QSemaphoreReleaser (0x0x7f884b5d8ae0) 0
+
+Class QSequentialAnimationGroup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSequentialAnimationGroup::QPrivateSignal (0x0x7f884b759120) 0 empty
+
+Vtable for QSequentialAnimationGroup
+QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup)
+16 (int (*)(...))QSequentialAnimationGroup::metaObject
+24 (int (*)(...))QSequentialAnimationGroup::qt_metacast
+32 (int (*)(...))QSequentialAnimationGroup::qt_metacall
+40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup
+48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup
+56 (int (*)(...))QSequentialAnimationGroup::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QSequentialAnimationGroup::duration
+120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime
+128 (int (*)(...))QSequentialAnimationGroup::updateState
+136 (int (*)(...))QSequentialAnimationGroup::updateDirection
+
+Class QSequentialAnimationGroup
+ size=16 align=8
+ base size=16 base align=8
+QSequentialAnimationGroup (0x0x7f884b73af70) 0
+ vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u)
+ QAnimationGroup (0x0x7f884b75d000) 0
+ primary-for QSequentialAnimationGroup (0x0x7f884b73af70)
+ QAbstractAnimation (0x0x7f884b75d068) 0
+ primary-for QAnimationGroup (0x0x7f884b75d000)
+ QObject (0x0x7f884b7590c0) 0
+ primary-for QAbstractAnimation (0x0x7f884b75d068)
+
+Class QSettings::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSettings::QPrivateSignal (0x0x7f884b7591e0) 0 empty
+
+Vtable for QSettings
+QSettings::_ZTV9QSettings: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QSettings)
+16 (int (*)(...))QSettings::metaObject
+24 (int (*)(...))QSettings::qt_metacast
+32 (int (*)(...))QSettings::qt_metacall
+40 (int (*)(...))QSettings::~QSettings
+48 (int (*)(...))QSettings::~QSettings
+56 (int (*)(...))QSettings::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QSettings
+ size=16 align=8
+ base size=16 base align=8
+QSettings (0x0x7f884b75d0d0) 0
+ vptr=((& QSettings::_ZTV9QSettings) + 16u)
+ QObject (0x0x7f884b759180) 0
+ primary-for QSettings (0x0x7f884b75d0d0)
+
+Class QSharedMemory::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSharedMemory::QPrivateSignal (0x0x7f884b7592a0) 0 empty
+
+Vtable for QSharedMemory
+QSharedMemory::_ZTV13QSharedMemory: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QSharedMemory)
+16 (int (*)(...))QSharedMemory::metaObject
+24 (int (*)(...))QSharedMemory::qt_metacast
+32 (int (*)(...))QSharedMemory::qt_metacall
+40 (int (*)(...))QSharedMemory::~QSharedMemory
+48 (int (*)(...))QSharedMemory::~QSharedMemory
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QSharedMemory
+ size=16 align=8
+ base size=16 base align=8
+QSharedMemory (0x0x7f884b75d138) 0
+ vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u)
+ QObject (0x0x7f884b759240) 0
+ primary-for QSharedMemory (0x0x7f884b75d138)
+
+Class QSignalMapper::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSignalMapper::QPrivateSignal (0x0x7f884b759360) 0 empty
+
+Vtable for QSignalMapper
+QSignalMapper::_ZTV13QSignalMapper: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QSignalMapper)
+16 (int (*)(...))QSignalMapper::metaObject
+24 (int (*)(...))QSignalMapper::qt_metacast
+32 (int (*)(...))QSignalMapper::qt_metacall
+40 (int (*)(...))QSignalMapper::~QSignalMapper
+48 (int (*)(...))QSignalMapper::~QSignalMapper
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QSignalMapper
+ size=16 align=8
+ base size=16 base align=8
+QSignalMapper (0x0x7f884b75d1a0) 0
+ vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u)
+ QObject (0x0x7f884b759300) 0
+ primary-for QSignalMapper (0x0x7f884b75d1a0)
+
+Class QSignalTransition::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSignalTransition::QPrivateSignal (0x0x7f884b759420) 0 empty
+
+Vtable for QSignalTransition
+QSignalTransition::_ZTV17QSignalTransition: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QSignalTransition)
+16 (int (*)(...))QSignalTransition::metaObject
+24 (int (*)(...))QSignalTransition::qt_metacast
+32 (int (*)(...))QSignalTransition::qt_metacall
+40 (int (*)(...))QSignalTransition::~QSignalTransition
+48 (int (*)(...))QSignalTransition::~QSignalTransition
+56 (int (*)(...))QSignalTransition::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QSignalTransition::eventTest
+120 (int (*)(...))QSignalTransition::onTransition
+
+Class QSignalTransition
+ size=16 align=8
+ base size=16 base align=8
+QSignalTransition (0x0x7f884b75d208) 0
+ vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u)
+ QAbstractTransition (0x0x7f884b75d270) 0
+ primary-for QSignalTransition (0x0x7f884b75d208)
+ QObject (0x0x7f884b7593c0) 0
+ primary-for QAbstractTransition (0x0x7f884b75d270)
+
+Class QSocketNotifier::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSocketNotifier::QPrivateSignal (0x0x7f884b7594e0) 0 empty
+
+Vtable for QSocketNotifier
+QSocketNotifier::_ZTV15QSocketNotifier: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QSocketNotifier)
+16 (int (*)(...))QSocketNotifier::metaObject
+24 (int (*)(...))QSocketNotifier::qt_metacast
+32 (int (*)(...))QSocketNotifier::qt_metacall
+40 (int (*)(...))QSocketNotifier::~QSocketNotifier
+48 (int (*)(...))QSocketNotifier::~QSocketNotifier
+56 (int (*)(...))QSocketNotifier::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QSocketNotifier
+ size=16 align=8
+ base size=16 base align=8
+QSocketNotifier (0x0x7f884b75d2d8) 0
+ vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u)
+ QObject (0x0x7f884b759480) 0
+ primary-for QSocketNotifier (0x0x7f884b75d2d8)
+
+Class QSortFilterProxyModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSortFilterProxyModel::QPrivateSignal (0x0x7f884b7595a0) 0 empty
+
+Vtable for QSortFilterProxyModel
+QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QSortFilterProxyModel)
+16 (int (*)(...))QSortFilterProxyModel::metaObject
+24 (int (*)(...))QSortFilterProxyModel::qt_metacast
+32 (int (*)(...))QSortFilterProxyModel::qt_metacall
+40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel
+48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QSortFilterProxyModel::index
+120 (int (*)(...))QSortFilterProxyModel::parent
+128 (int (*)(...))QSortFilterProxyModel::sibling
+136 (int (*)(...))QSortFilterProxyModel::rowCount
+144 (int (*)(...))QSortFilterProxyModel::columnCount
+152 (int (*)(...))QSortFilterProxyModel::hasChildren
+160 (int (*)(...))QSortFilterProxyModel::data
+168 (int (*)(...))QSortFilterProxyModel::setData
+176 (int (*)(...))QSortFilterProxyModel::headerData
+184 (int (*)(...))QSortFilterProxyModel::setHeaderData
+192 (int (*)(...))QAbstractProxyModel::itemData
+200 (int (*)(...))QAbstractProxyModel::setItemData
+208 (int (*)(...))QSortFilterProxyModel::mimeTypes
+216 (int (*)(...))QSortFilterProxyModel::mimeData
+224 (int (*)(...))QAbstractProxyModel::canDropMimeData
+232 (int (*)(...))QSortFilterProxyModel::dropMimeData
+240 (int (*)(...))QSortFilterProxyModel::supportedDropActions
+248 (int (*)(...))QAbstractProxyModel::supportedDragActions
+256 (int (*)(...))QSortFilterProxyModel::insertRows
+264 (int (*)(...))QSortFilterProxyModel::insertColumns
+272 (int (*)(...))QSortFilterProxyModel::removeRows
+280 (int (*)(...))QSortFilterProxyModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QSortFilterProxyModel::fetchMore
+312 (int (*)(...))QSortFilterProxyModel::canFetchMore
+320 (int (*)(...))QSortFilterProxyModel::flags
+328 (int (*)(...))QSortFilterProxyModel::sort
+336 (int (*)(...))QSortFilterProxyModel::buddy
+344 (int (*)(...))QSortFilterProxyModel::match
+352 (int (*)(...))QSortFilterProxyModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractProxyModel::submit
+376 (int (*)(...))QAbstractProxyModel::revert
+384 (int (*)(...))QSortFilterProxyModel::setSourceModel
+392 (int (*)(...))QSortFilterProxyModel::mapToSource
+400 (int (*)(...))QSortFilterProxyModel::mapFromSource
+408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource
+416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource
+424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow
+432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn
+440 (int (*)(...))QSortFilterProxyModel::lessThan
+
+Class QSortFilterProxyModel
+ size=16 align=8
+ base size=16 base align=8
+QSortFilterProxyModel (0x0x7f884b75d340) 0
+ vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u)
+ QAbstractProxyModel (0x0x7f884b75d3a8) 0
+ primary-for QSortFilterProxyModel (0x0x7f884b75d340)
+ QAbstractItemModel (0x0x7f884b75d410) 0
+ primary-for QAbstractProxyModel (0x0x7f884b75d3a8)
+ QObject (0x0x7f884b759540) 0
+ primary-for QAbstractItemModel (0x0x7f884b75d410)
+
+Class QStandardPaths
+ size=1 align=1
+ base size=0 base align=1
+QStandardPaths (0x0x7f884b759660) 0 empty
+
+Class QState::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QState::QPrivateSignal (0x0x7f884b7598a0) 0 empty
+
+Vtable for QState
+QState::_ZTV6QState: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QState)
+16 (int (*)(...))QState::metaObject
+24 (int (*)(...))QState::qt_metacast
+32 (int (*)(...))QState::qt_metacall
+40 (int (*)(...))QState::~QState
+48 (int (*)(...))QState::~QState
+56 (int (*)(...))QState::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QState::onEntry
+120 (int (*)(...))QState::onExit
+
+Class QState
+ size=16 align=8
+ base size=16 base align=8
+QState (0x0x7f884b75d5b0) 0
+ vptr=((& QState::_ZTV6QState) + 16u)
+ QAbstractState (0x0x7f884b75d618) 0
+ primary-for QState (0x0x7f884b75d5b0)
+ QObject (0x0x7f884b759840) 0
+ primary-for QAbstractState (0x0x7f884b75d618)
+
+Class QStateMachine::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QStateMachine::QPrivateSignal (0x0x7f884b7599c0) 0 empty
+
+Vtable for QStateMachine::SignalEvent
+QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE)
+16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent
+24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent
+
+Class QStateMachine::SignalEvent
+ size=48 align=8
+ base size=48 base align=8
+QStateMachine::SignalEvent (0x0x7f884b75d7b8) 0
+ vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u)
+ QEvent (0x0x7f884b759a20) 0
+ primary-for QStateMachine::SignalEvent (0x0x7f884b75d7b8)
+
+Vtable for QStateMachine::WrappedEvent
+QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE)
+16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent
+24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent
+
+Class QStateMachine::WrappedEvent
+ size=40 align=8
+ base size=40 base align=8
+QStateMachine::WrappedEvent (0x0x7f884b75d820) 0
+ vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u)
+ QEvent (0x0x7f884b759a80) 0
+ primary-for QStateMachine::WrappedEvent (0x0x7f884b75d820)
+
+Vtable for QStateMachine
+QStateMachine::_ZTV13QStateMachine: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QStateMachine)
+16 (int (*)(...))QStateMachine::metaObject
+24 (int (*)(...))QStateMachine::qt_metacast
+32 (int (*)(...))QStateMachine::qt_metacall
+40 (int (*)(...))QStateMachine::~QStateMachine
+48 (int (*)(...))QStateMachine::~QStateMachine
+56 (int (*)(...))QStateMachine::event
+64 (int (*)(...))QStateMachine::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QStateMachine::onEntry
+120 (int (*)(...))QStateMachine::onExit
+128 (int (*)(...))QStateMachine::beginSelectTransitions
+136 (int (*)(...))QStateMachine::endSelectTransitions
+144 (int (*)(...))QStateMachine::beginMicrostep
+152 (int (*)(...))QStateMachine::endMicrostep
+
+Class QStateMachine
+ size=16 align=8
+ base size=16 base align=8
+QStateMachine (0x0x7f884b75d680) 0
+ vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u)
+ QState (0x0x7f884b75d6e8) 0
+ primary-for QStateMachine (0x0x7f884b75d680)
+ QAbstractState (0x0x7f884b75d750) 0
+ primary-for QState (0x0x7f884b75d6e8)
+ QObject (0x0x7f884b759960) 0
+ primary-for QAbstractState (0x0x7f884b75d750)
+
+Class QStorageInfo
+ size=8 align=8
+ base size=8 base align=8
+QStorageInfo (0x0x7f884b759ae0) 0
+
+Class QAbstractConcatenable
+ size=1 align=1
+ base size=0 base align=1
+QAbstractConcatenable (0x0x7f884b4a5a20) 0 empty
+
+Class QStringListModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QStringListModel::QPrivateSignal (0x0x7f884b51b540) 0 empty
+
+Vtable for QStringListModel
+QStringListModel::_ZTV16QStringListModel: 48u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QStringListModel)
+16 (int (*)(...))QStringListModel::metaObject
+24 (int (*)(...))QStringListModel::qt_metacast
+32 (int (*)(...))QStringListModel::qt_metacall
+40 (int (*)(...))QStringListModel::~QStringListModel
+48 (int (*)(...))QStringListModel::~QStringListModel
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAbstractListModel::index
+120 (int (*)(...))QAbstractListModel::parent
+128 (int (*)(...))QStringListModel::sibling
+136 (int (*)(...))QStringListModel::rowCount
+144 (int (*)(...))QAbstractListModel::columnCount
+152 (int (*)(...))QAbstractListModel::hasChildren
+160 (int (*)(...))QStringListModel::data
+168 (int (*)(...))QStringListModel::setData
+176 (int (*)(...))QAbstractItemModel::headerData
+184 (int (*)(...))QAbstractItemModel::setHeaderData
+192 (int (*)(...))QAbstractItemModel::itemData
+200 (int (*)(...))QAbstractItemModel::setItemData
+208 (int (*)(...))QAbstractItemModel::mimeTypes
+216 (int (*)(...))QAbstractItemModel::mimeData
+224 (int (*)(...))QAbstractItemModel::canDropMimeData
+232 (int (*)(...))QAbstractListModel::dropMimeData
+240 (int (*)(...))QStringListModel::supportedDropActions
+248 (int (*)(...))QAbstractItemModel::supportedDragActions
+256 (int (*)(...))QStringListModel::insertRows
+264 (int (*)(...))QAbstractItemModel::insertColumns
+272 (int (*)(...))QStringListModel::removeRows
+280 (int (*)(...))QAbstractItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractItemModel::fetchMore
+312 (int (*)(...))QAbstractItemModel::canFetchMore
+320 (int (*)(...))QStringListModel::flags
+328 (int (*)(...))QStringListModel::sort
+336 (int (*)(...))QAbstractItemModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractItemModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractItemModel::submit
+376 (int (*)(...))QAbstractItemModel::revert
+
+Class QStringListModel
+ size=24 align=8
+ base size=24 base align=8
+QStringListModel (0x0x7f884b4c0d00) 0
+ vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u)
+ QAbstractListModel (0x0x7f884b4c0d68) 0
+ primary-for QStringListModel (0x0x7f884b4c0d00)
+ QAbstractItemModel (0x0x7f884b4c0dd0) 0
+ primary-for QAbstractListModel (0x0x7f884b4c0d68)
+ QObject (0x0x7f884b51b4e0) 0
+ primary-for QAbstractItemModel (0x0x7f884b4c0dd0)
+
+Class QSystemSemaphore
+ size=8 align=8
+ base size=8 base align=8
+QSystemSemaphore (0x0x7f884b51b5a0) 0
+
+Class QTemporaryDir
+ size=8 align=8
+ base size=8 base align=8
+QTemporaryDir (0x0x7f884b51b660) 0
+
+Class QTemporaryFile::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTemporaryFile::QPrivateSignal (0x0x7f884b51b780) 0 empty
+
+Vtable for QTemporaryFile
+QTemporaryFile::_ZTV14QTemporaryFile: 34u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QTemporaryFile)
+16 (int (*)(...))QTemporaryFile::metaObject
+24 (int (*)(...))QTemporaryFile::qt_metacast
+32 (int (*)(...))QTemporaryFile::qt_metacall
+40 (int (*)(...))QTemporaryFile::~QTemporaryFile
+48 (int (*)(...))QTemporaryFile::~QTemporaryFile
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QFileDevice::isSequential
+120 (int (*)(...))QTemporaryFile::open
+128 (int (*)(...))QFileDevice::close
+136 (int (*)(...))QFileDevice::pos
+144 (int (*)(...))QFile::size
+152 (int (*)(...))QFileDevice::seek
+160 (int (*)(...))QFileDevice::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QIODevice::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))QFileDevice::readData
+224 (int (*)(...))QFileDevice::readLineData
+232 (int (*)(...))QFileDevice::writeData
+240 (int (*)(...))QTemporaryFile::fileName
+248 (int (*)(...))QFile::resize
+256 (int (*)(...))QFile::permissions
+264 (int (*)(...))QFile::setPermissions
+
+Class QTemporaryFile
+ size=16 align=8
+ base size=16 base align=8
+QTemporaryFile (0x0x7f884b4c0e38) 0
+ vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u)
+ QFile (0x0x7f884b4c0ea0) 0
+ primary-for QTemporaryFile (0x0x7f884b4c0e38)
+ QFileDevice (0x0x7f884b4c0f08) 0
+ primary-for QFile (0x0x7f884b4c0ea0)
+ QIODevice (0x0x7f884b4c0f70) 0
+ primary-for QFileDevice (0x0x7f884b4c0f08)
+ QObject (0x0x7f884b51b720) 0
+ primary-for QIODevice (0x0x7f884b4c0f70)
+
+Class QTextBoundaryFinder
+ size=48 align=8
+ base size=48 base align=8
+QTextBoundaryFinder (0x0x7f884b51b7e0) 0
+
+Class QTextCodec::ConverterState
+ size=32 align=8
+ base size=32 base align=8
+QTextCodec::ConverterState (0x0x7f884b51ba20) 0
+
+Vtable for QTextCodec
+QTextCodec::_ZTV10QTextCodec: 9u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTextCodec)
+16 (int (*)(...))__cxa_pure_virtual
+24 (int (*)(...))QTextCodec::aliases
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 0u
+64 0u
+
+Class QTextCodec
+ size=8 align=8
+ base size=8 base align=8
+QTextCodec (0x0x7f884b51b9c0) 0 nearly-empty
+ vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u)
+
+Class QTextEncoder
+ size=40 align=8
+ base size=40 base align=8
+QTextEncoder (0x0x7f884b51bc00) 0
+
+Class QTextDecoder
+ size=40 align=8
+ base size=40 base align=8
+QTextDecoder (0x0x7f884b51bc60) 0
+
+Class std::__mutex_base
+ size=40 align=8
+ base size=40 base align=8
+std::__mutex_base (0x0x7f884b51bcc0) 0
+
+Class std::__recursive_mutex_base
+ size=40 align=8
+ base size=40 base align=8
+std::__recursive_mutex_base (0x0x7f884b51bd20) 0
+
+Class std::mutex
+ size=40 align=8
+ base size=40 base align=8
+std::mutex (0x0x7f884b59e1a0) 0
+ std::__mutex_base (0x0x7f884b51bd80) 0
+
+Class std::recursive_mutex
+ size=40 align=8
+ base size=40 base align=8
+std::recursive_mutex (0x0x7f884b59e208) 0
+ std::__recursive_mutex_base (0x0x7f884b51bde0) 0
+
+Class std::timed_mutex
+ size=40 align=8
+ base size=40 base align=8
+std::timed_mutex (0x0x7f884b23b380) 0
+ std::__mutex_base (0x0x7f884b51bf00) 0
+ std::__timed_mutex_impl<std::timed_mutex> (0x0x7f884b51bf60) 0 empty
+
+Class std::recursive_timed_mutex
+ size=40 align=8
+ base size=40 base align=8
+std::recursive_timed_mutex (0x0x7f884b257000) 0
+ std::__recursive_mutex_base (0x0x7f884b253060) 0
+ std::__timed_mutex_impl<std::recursive_timed_mutex> (0x0x7f884b2530c0) 0 empty
+
+Class std::defer_lock_t
+ size=1 align=1
+ base size=0 base align=1
+std::defer_lock_t (0x0x7f884b253120) 0 empty
+
+Class std::try_to_lock_t
+ size=1 align=1
+ base size=0 base align=1
+std::try_to_lock_t (0x0x7f884b253180) 0 empty
+
+Class std::adopt_lock_t
+ size=1 align=1
+ base size=0 base align=1
+std::adopt_lock_t (0x0x7f884b2531e0) 0 empty
+
+Class std::once_flag
+ size=4 align=4
+ base size=4 base align=4
+std::once_flag (0x0x7f884b253420) 0
+
+Vtable for __gnu_cxx::__concurrence_lock_error
+__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE)
+16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error
+24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error
+32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what
+
+Class __gnu_cxx::__concurrence_lock_error
+ size=8 align=8
+ base size=8 base align=8
+__gnu_cxx::__concurrence_lock_error (0x0x7f884b59e340) 0 nearly-empty
+ vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16u)
+ std::exception (0x0x7f884b2534e0) 0 nearly-empty
+ primary-for __gnu_cxx::__concurrence_lock_error (0x0x7f884b59e340)
+
+Vtable for __gnu_cxx::__concurrence_unlock_error
+__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE)
+16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error
+24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error
+32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what
+
+Class __gnu_cxx::__concurrence_unlock_error
+ size=8 align=8
+ base size=8 base align=8
+__gnu_cxx::__concurrence_unlock_error (0x0x7f884b59e3a8) 0 nearly-empty
+ vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16u)
+ std::exception (0x0x7f884b2535a0) 0 nearly-empty
+ primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7f884b59e3a8)
+
+Vtable for __gnu_cxx::__concurrence_broadcast_error
+__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE)
+16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error
+24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error
+32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what
+
+Class __gnu_cxx::__concurrence_broadcast_error
+ size=8 align=8
+ base size=8 base align=8
+__gnu_cxx::__concurrence_broadcast_error (0x0x7f884b59e410) 0 nearly-empty
+ vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16u)
+ std::exception (0x0x7f884b253660) 0 nearly-empty
+ primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7f884b59e410)
+
+Vtable for __gnu_cxx::__concurrence_wait_error
+__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE)
+16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error
+24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error
+32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what
+
+Class __gnu_cxx::__concurrence_wait_error
+ size=8 align=8
+ base size=8 base align=8
+__gnu_cxx::__concurrence_wait_error (0x0x7f884b59e4e0) 0 nearly-empty
+ vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16u)
+ std::exception (0x0x7f884b253720) 0 nearly-empty
+ primary-for __gnu_cxx::__concurrence_wait_error (0x0x7f884b59e4e0)
+
+Class __gnu_cxx::__mutex
+ size=40 align=8
+ base size=40 base align=8
+__gnu_cxx::__mutex (0x0x7f884b2537e0) 0
+
+Class __gnu_cxx::__recursive_mutex
+ size=40 align=8
+ base size=40 base align=8
+__gnu_cxx::__recursive_mutex (0x0x7f884b253840) 0
+
+Class __gnu_cxx::__scoped_lock
+ size=8 align=8
+ base size=8 base align=8
+__gnu_cxx::__scoped_lock (0x0x7f884b2538a0) 0
+
+Class __gnu_cxx::__cond
+ size=48 align=8
+ base size=48 base align=8
+__gnu_cxx::__cond (0x0x7f884b253900) 0
+
+Vtable for std::bad_weak_ptr
+std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt12bad_weak_ptr)
+16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr
+24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr
+32 (int (*)(...))std::bad_weak_ptr::what
+
+Class std::bad_weak_ptr
+ size=8 align=8
+ base size=8 base align=8
+std::bad_weak_ptr (0x0x7f884b59e7b8) 0 nearly-empty
+ vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16u)
+ std::exception (0x0x7f884b253c60) 0 nearly-empty
+ primary-for std::bad_weak_ptr (0x0x7f884b59e7b8)
+
+Class std::_Sp_make_shared_tag
+ size=1 align=1
+ base size=0 base align=1
+std::_Sp_make_shared_tag (0x0x7f884b39e4e0) 0 empty
+
+Class std::_Sp_locker
+ size=2 align=1
+ base size=2 base align=1
+std::_Sp_locker (0x0x7f884b39ecc0) 0
+
+Class std::thread::id
+ size=8 align=8
+ base size=8 base align=8
+std::thread::id (0x0x7f884b39eea0) 0
+
+Vtable for std::thread::_Impl_base
+std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt6thread10_Impl_baseE)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class std::thread::_Impl_base
+ size=24 align=8
+ base size=24 base align=8
+std::thread::_Impl_base (0x0x7f884b39ef00) 0
+ vptr=((& std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE) + 16u)
+
+Class std::thread
+ size=8 align=8
+ base size=8 base align=8
+std::thread (0x0x7f884b39ee40) 0
+
+Class std::condition_variable
+ size=48 align=8
+ base size=48 base align=8
+std::condition_variable (0x0x7f884ae4bb40) 0
+
+Class std::__at_thread_exit_elt
+ size=16 align=8
+ base size=16 base align=8
+std::__at_thread_exit_elt (0x0x7f884ae4bc00) 0
+
+Class std::_V2::condition_variable_any
+ size=64 align=8
+ base size=64 base align=8
+std::_V2::condition_variable_any (0x0x7f884ae4bc60) 0
+
+Class std::__atomic_futex_unsigned_base
+ size=1 align=1
+ base size=0 base align=1
+std::__atomic_futex_unsigned_base (0x0x7f884af39300) 0 empty
+
+Vtable for std::future_error
+std::future_error::_ZTVSt12future_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt12future_error)
+16 (int (*)(...))std::future_error::~future_error
+24 (int (*)(...))std::future_error::~future_error
+32 (int (*)(...))std::future_error::what
+
+Class std::future_error
+ size=32 align=8
+ base size=32 base align=8
+std::future_error (0x0x7f884af33af8) 0
+ vptr=((& std::future_error::_ZTVSt12future_error) + 16u)
+ std::logic_error (0x0x7f884af33b60) 0
+ primary-for std::future_error (0x0x7f884af33af8)
+ std::exception (0x0x7f884af39420) 0 nearly-empty
+ primary-for std::logic_error (0x0x7f884af33b60)
+
+Class std::__future_base::_Result_base::_Deleter
+ size=1 align=1
+ base size=0 base align=1
+std::__future_base::_Result_base::_Deleter (0x0x7f884af39540) 0 empty
+
+Vtable for std::__future_base::_Result_base
+std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE)
+16 (int (*)(...))__cxa_pure_virtual
+24 0u
+32 0u
+
+Class std::__future_base::_Result_base
+ size=16 align=8
+ base size=16 base align=8
+std::__future_base::_Result_base (0x0x7f884af394e0) 0
+ vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16u)
+
+Class std::__future_base::_State_baseV2::__exception_ptr_tag
+ size=1 align=1
+ base size=0 base align=1
+std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7f884ac96a80) 0 empty
+
+Class std::__future_base::_State_baseV2::_Make_ready
+ size=32 align=8
+ base size=32 base align=8
+std::__future_base::_State_baseV2::_Make_ready (0x0x7f884acb5138) 0
+ std::__at_thread_exit_elt (0x0x7f884ac96b40) 0
+
+Vtable for std::__future_base::_State_baseV2
+std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E)
+16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2
+24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2
+32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async
+40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future
+
+Class std::__future_base::_State_baseV2
+ size=32 align=8
+ base size=28 base align=8
+std::__future_base::_State_baseV2 (0x0x7f884af396c0) 0
+ vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16u)
+
+Class std::__future_base
+ size=1 align=1
+ base size=0 base align=1
+std::__future_base (0x0x7f884af39480) 0 empty
+
+Vtable for std::__future_base::_Async_state_commonV2
+std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E)
+16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2
+24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2
+32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async
+40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future
+
+Class std::__future_base::_Async_state_commonV2
+ size=48 align=8
+ base size=44 base align=8
+std::__future_base::_Async_state_commonV2 (0x0x7f884a5ded00) 0
+ vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16u)
+ std::__future_base::_State_baseV2 (0x0x7f884a5e0a20) 0
+ primary-for std::__future_base::_Async_state_commonV2 (0x0x7f884a5ded00)
+
+Class QThread::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QThread::QPrivateSignal (0x0x7f884a660180) 0 empty
+
+Vtable for QThread
+QThread::_ZTV7QThread: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QThread)
+16 (int (*)(...))QThread::metaObject
+24 (int (*)(...))QThread::qt_metacast
+32 (int (*)(...))QThread::qt_metacall
+40 (int (*)(...))QThread::~QThread
+48 (int (*)(...))QThread::~QThread
+56 (int (*)(...))QThread::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QThread::run
+
+Class QThread
+ size=16 align=8
+ base size=16 base align=8
+QThread (0x0x7f884a6437b8) 0
+ vptr=((& QThread::_ZTV7QThread) + 16u)
+ QObject (0x0x7f884a660120) 0
+ primary-for QThread (0x0x7f884a6437b8)
+
+Class QThreadPool::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QThreadPool::QPrivateSignal (0x0x7f884a6602a0) 0 empty
+
+Vtable for QThreadPool
+QThreadPool::_ZTV11QThreadPool: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QThreadPool)
+16 (int (*)(...))QThreadPool::metaObject
+24 (int (*)(...))QThreadPool::qt_metacast
+32 (int (*)(...))QThreadPool::qt_metacall
+40 (int (*)(...))QThreadPool::~QThreadPool
+48 (int (*)(...))QThreadPool::~QThreadPool
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QThreadPool
+ size=16 align=8
+ base size=16 base align=8
+QThreadPool (0x0x7f884a643820) 0
+ vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u)
+ QObject (0x0x7f884a660240) 0
+ primary-for QThreadPool (0x0x7f884a643820)
+
+Class QThreadStorageData
+ size=4 align=4
+ base size=4 base align=4
+QThreadStorageData (0x0x7f884a660300) 0
+
+Class QTimeLine::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTimeLine::QPrivateSignal (0x0x7f884a660420) 0 empty
+
+Vtable for QTimeLine
+QTimeLine::_ZTV9QTimeLine: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QTimeLine)
+16 (int (*)(...))QTimeLine::metaObject
+24 (int (*)(...))QTimeLine::qt_metacast
+32 (int (*)(...))QTimeLine::qt_metacall
+40 (int (*)(...))QTimeLine::~QTimeLine
+48 (int (*)(...))QTimeLine::~QTimeLine
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QTimeLine::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QTimeLine::valueForTime
+
+Class QTimeLine
+ size=16 align=8
+ base size=16 base align=8
+QTimeLine (0x0x7f884a643888) 0
+ vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u)
+ QObject (0x0x7f884a6603c0) 0
+ primary-for QTimeLine (0x0x7f884a643888)
+
+Class QTimer::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTimer::QPrivateSignal (0x0x7f884a6604e0) 0 empty
+
+Vtable for QTimer
+QTimer::_ZTV6QTimer: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QTimer)
+16 (int (*)(...))QTimer::metaObject
+24 (int (*)(...))QTimer::qt_metacast
+32 (int (*)(...))QTimer::qt_metacall
+40 (int (*)(...))QTimer::~QTimer
+48 (int (*)(...))QTimer::~QTimer
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QTimer::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QTimer
+ size=32 align=8
+ base size=29 base align=8
+QTimer (0x0x7f884a6438f0) 0
+ vptr=((& QTimer::_ZTV6QTimer) + 16u)
+ QObject (0x0x7f884a660480) 0
+ primary-for QTimer (0x0x7f884a6438f0)
+
+Class QTimeZone::OffsetData
+ size=32 align=8
+ base size=28 base align=8
+QTimeZone::OffsetData (0x0x7f884a660ba0) 0
+
+Class QTimeZone
+ size=8 align=8
+ base size=8 base align=8
+QTimeZone (0x0x7f884a660b40) 0
+
+Class QTranslator::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTranslator::QPrivateSignal (0x0x7f884a730180) 0 empty
+
+Vtable for QTranslator
+QTranslator::_ZTV11QTranslator: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTranslator)
+16 (int (*)(...))QTranslator::metaObject
+24 (int (*)(...))QTranslator::qt_metacast
+32 (int (*)(...))QTranslator::qt_metacall
+40 (int (*)(...))QTranslator::~QTranslator
+48 (int (*)(...))QTranslator::~QTranslator
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QTranslator::translate
+120 (int (*)(...))QTranslator::isEmpty
+
+Class QTranslator
+ size=16 align=8
+ base size=16 base align=8
+QTranslator (0x0x7f884a72b340) 0
+ vptr=((& QTranslator::_ZTV11QTranslator) + 16u)
+ QObject (0x0x7f884a730120) 0
+ primary-for QTranslator (0x0x7f884a72b340)
+
+Class QUrl
+ size=8 align=8
+ base size=8 base align=8
+QUrl (0x0x7f884a7302a0) 0
+
+Class QUrlQuery
+ size=8 align=8
+ base size=8 base align=8
+QUrlQuery (0x0x7f884a444960) 0
+
+Class QUuid
+ size=16 align=4
+ base size=16 base align=4
+QUuid (0x0x7f884a4e8000) 0
+
+Class QWaitCondition
+ size=8 align=8
+ base size=8 base align=8
+QWaitCondition (0x0x7f884a4e8600) 0
+
+Class QXmlStreamStringRef
+ size=16 align=8
+ base size=16 base align=8
+QXmlStreamStringRef (0x0x7f884a4e8660) 0
+
+Class QXmlStreamAttribute
+ size=80 align=8
+ base size=73 base align=8
+QXmlStreamAttribute (0x0x7f884a4e8960) 0
+
+Class QXmlStreamAttributes
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamAttributes (0x0x7f884a4e3e38) 0
+ QVector<QXmlStreamAttribute> (0x0x7f884a4e8d20) 0
+
+Class QXmlStreamNamespaceDeclaration
+ size=40 align=8
+ base size=40 base align=8
+QXmlStreamNamespaceDeclaration (0x0x7f884a4e8d80) 0
+
+Class QXmlStreamNotationDeclaration
+ size=56 align=8
+ base size=56 base align=8
+QXmlStreamNotationDeclaration (0x0x7f884a1d0060) 0
+
+Class QXmlStreamEntityDeclaration
+ size=88 align=8
+ base size=88 base align=8
+QXmlStreamEntityDeclaration (0x0x7f884a1d0300) 0
+
+Vtable for QXmlStreamEntityResolver
+QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver)
+16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity
+40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity
+
+Class QXmlStreamEntityResolver
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamEntityResolver (0x0x7f884a1d05a0) 0 nearly-empty
+ vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u)
+
+Class QXmlStreamReader
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamReader (0x0x7f884a1d0600) 0
+
+Class QXmlStreamWriter
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamWriter (0x0x7f884a280060) 0
+
+Class QTest::QBenchmarkIterationController
+ size=4 align=4
+ base size=4 base align=4
+QTest::QBenchmarkIterationController (0x0x7f884a280180) 0
+
+Class QTestEventLoop::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTestEventLoop::QPrivateSignal (0x0x7f884a280240) 0 empty
+
+Vtable for QTestEventLoop
+QTestEventLoop::_ZTV14QTestEventLoop: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QTestEventLoop)
+16 (int (*)(...))QTestEventLoop::metaObject
+24 (int (*)(...))QTestEventLoop::qt_metacast
+32 (int (*)(...))QTestEventLoop::qt_metacall
+40 (int (*)(...))QTestEventLoop::~QTestEventLoop
+48 (int (*)(...))QTestEventLoop::~QTestEventLoop
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QTestEventLoop::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QTestEventLoop
+ size=32 align=8
+ base size=32 base align=8
+QTestEventLoop (0x0x7f884a1d13a8) 0
+ vptr=((& QTestEventLoop::_ZTV14QTestEventLoop) + 16u)
+ QObject (0x0x7f884a2801e0) 0
+ primary-for QTestEventLoop (0x0x7f884a1d13a8)
+
+Vtable for QSignalSpy
+QSignalSpy::_ZTV10QSignalSpy: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QSignalSpy)
+16 (int (*)(...))QObject::metaObject
+24 (int (*)(...))QObject::qt_metacast
+32 (int (*)(...))QSignalSpy::qt_metacall
+40 (int (*)(...))QSignalSpy::~QSignalSpy
+48 (int (*)(...))QSignalSpy::~QSignalSpy
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QSignalSpy
+ size=80 align=8
+ base size=73 base align=8
+QSignalSpy (0x0x7f884a2ee700) 0
+ vptr=((& QSignalSpy::_ZTV10QSignalSpy) + 16u)
+ QObject (0x0x7f884a2ed180) 0
+ primary-for QSignalSpy (0x0x7f884a2ee700)
+ QList<QList<QVariant> > (0x0x7f884a2b4f70) 16
+ QListSpecialMethods<QList<QVariant> > (0x0x7f884a2ed1e0) 16 empty
+
+Class QTestData
+ size=8 align=8
+ base size=8 base align=8
+QTestData (0x0x7f8849fc22a0) 0
+
+Class QRgba64
+ size=8 align=8
+ base size=8 base align=8
+QRgba64 (0x0x7f884a007720) 0
+
+Class QColor
+ size=16 align=4
+ base size=14 base align=4
+QColor (0x0x7f884a0079c0) 0
+
+Class QRegion::QRegionData
+ size=16 align=8
+ base size=16 base align=8
+QRegion::QRegionData (0x0x7f8849dc23c0) 0
+
+Class QRegion
+ size=8 align=8
+ base size=8 base align=8
+QRegion (0x0x7f8849dc2360) 0
+
+Class QKeySequence
+ size=8 align=8
+ base size=8 base align=8
+QKeySequence (0x0x7f8849e62720) 0
+
+Class QVector2D
+ size=8 align=4
+ base size=8 base align=4
+QVector2D (0x0x7f8849f0fc60) 0
+
+Class QTouchDevice
+ size=8 align=8
+ base size=8 base align=8
+QTouchDevice (0x0x7f8849f0ff00) 0
+
+Vtable for QInputEvent
+QInputEvent::_ZTV11QInputEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QInputEvent)
+16 (int (*)(...))QInputEvent::~QInputEvent
+24 (int (*)(...))QInputEvent::~QInputEvent
+
+Class QInputEvent
+ size=32 align=8
+ base size=32 base align=8
+QInputEvent (0x0x7f8849b8d068) 0
+ vptr=((& QInputEvent::_ZTV11QInputEvent) + 16u)
+ QEvent (0x0x7f8849f89120) 0
+ primary-for QInputEvent (0x0x7f8849b8d068)
+
+Vtable for QEnterEvent
+QEnterEvent::_ZTV11QEnterEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QEnterEvent)
+16 (int (*)(...))QEnterEvent::~QEnterEvent
+24 (int (*)(...))QEnterEvent::~QEnterEvent
+
+Class QEnterEvent
+ size=72 align=8
+ base size=72 base align=8
+QEnterEvent (0x0x7f8849b8d0d0) 0
+ vptr=((& QEnterEvent::_ZTV11QEnterEvent) + 16u)
+ QEvent (0x0x7f8849f89180) 0
+ primary-for QEnterEvent (0x0x7f8849b8d0d0)
+
+Vtable for QMouseEvent
+QMouseEvent::_ZTV11QMouseEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QMouseEvent)
+16 (int (*)(...))QMouseEvent::~QMouseEvent
+24 (int (*)(...))QMouseEvent::~QMouseEvent
+
+Class QMouseEvent
+ size=104 align=8
+ base size=100 base align=8
+QMouseEvent (0x0x7f8849b8d138) 0
+ vptr=((& QMouseEvent::_ZTV11QMouseEvent) + 16u)
+ QInputEvent (0x0x7f8849b8d1a0) 0
+ primary-for QMouseEvent (0x0x7f8849b8d138)
+ QEvent (0x0x7f8849f891e0) 0
+ primary-for QInputEvent (0x0x7f8849b8d1a0)
+
+Vtable for QHoverEvent
+QHoverEvent::_ZTV11QHoverEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QHoverEvent)
+16 (int (*)(...))QHoverEvent::~QHoverEvent
+24 (int (*)(...))QHoverEvent::~QHoverEvent
+
+Class QHoverEvent
+ size=64 align=8
+ base size=64 base align=8
+QHoverEvent (0x0x7f8849b8d208) 0
+ vptr=((& QHoverEvent::_ZTV11QHoverEvent) + 16u)
+ QInputEvent (0x0x7f8849b8d270) 0
+ primary-for QHoverEvent (0x0x7f8849b8d208)
+ QEvent (0x0x7f8849f89240) 0
+ primary-for QInputEvent (0x0x7f8849b8d270)
+
+Vtable for QWheelEvent
+QWheelEvent::_ZTV11QWheelEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QWheelEvent)
+16 (int (*)(...))QWheelEvent::~QWheelEvent
+24 (int (*)(...))QWheelEvent::~QWheelEvent
+
+Class QWheelEvent
+ size=96 align=8
+ base size=96 base align=8
+QWheelEvent (0x0x7f8849b8d2d8) 0
+ vptr=((& QWheelEvent::_ZTV11QWheelEvent) + 16u)
+ QInputEvent (0x0x7f8849b8d340) 0
+ primary-for QWheelEvent (0x0x7f8849b8d2d8)
+ QEvent (0x0x7f8849f892a0) 0
+ primary-for QInputEvent (0x0x7f8849b8d340)
+
+Vtable for QTabletEvent
+QTabletEvent::_ZTV12QTabletEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QTabletEvent)
+16 (int (*)(...))QTabletEvent::~QTabletEvent
+24 (int (*)(...))QTabletEvent::~QTabletEvent
+
+Class QTabletEvent
+ size=128 align=8
+ base size=128 base align=8
+QTabletEvent (0x0x7f8849b8d3a8) 0
+ vptr=((& QTabletEvent::_ZTV12QTabletEvent) + 16u)
+ QInputEvent (0x0x7f8849b8d410) 0
+ primary-for QTabletEvent (0x0x7f8849b8d3a8)
+ QEvent (0x0x7f8849f89300) 0
+ primary-for QInputEvent (0x0x7f8849b8d410)
+
+Vtable for QNativeGestureEvent
+QNativeGestureEvent::_ZTV19QNativeGestureEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QNativeGestureEvent)
+16 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent
+24 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent
+
+Class QNativeGestureEvent
+ size=112 align=8
+ base size=112 base align=8
+QNativeGestureEvent (0x0x7f8849b8d478) 0
+ vptr=((& QNativeGestureEvent::_ZTV19QNativeGestureEvent) + 16u)
+ QInputEvent (0x0x7f8849b8d4e0) 0
+ primary-for QNativeGestureEvent (0x0x7f8849b8d478)
+ QEvent (0x0x7f8849f89360) 0
+ primary-for QInputEvent (0x0x7f8849b8d4e0)
+
+Vtable for QKeyEvent
+QKeyEvent::_ZTV9QKeyEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QKeyEvent)
+16 (int (*)(...))QKeyEvent::~QKeyEvent
+24 (int (*)(...))QKeyEvent::~QKeyEvent
+
+Class QKeyEvent
+ size=64 align=8
+ base size=59 base align=8
+QKeyEvent (0x0x7f8849b8d548) 0
+ vptr=((& QKeyEvent::_ZTV9QKeyEvent) + 16u)
+ QInputEvent (0x0x7f8849b8d5b0) 0
+ primary-for QKeyEvent (0x0x7f8849b8d548)
+ QEvent (0x0x7f8849f893c0) 0
+ primary-for QInputEvent (0x0x7f8849b8d5b0)
+
+Vtable for QFocusEvent
+QFocusEvent::_ZTV11QFocusEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QFocusEvent)
+16 (int (*)(...))QFocusEvent::~QFocusEvent
+24 (int (*)(...))QFocusEvent::~QFocusEvent
+
+Class QFocusEvent
+ size=24 align=8
+ base size=24 base align=8
+QFocusEvent (0x0x7f8849b8d618) 0
+ vptr=((& QFocusEvent::_ZTV11QFocusEvent) + 16u)
+ QEvent (0x0x7f8849f89420) 0
+ primary-for QFocusEvent (0x0x7f8849b8d618)
+
+Vtable for QPaintEvent
+QPaintEvent::_ZTV11QPaintEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QPaintEvent)
+16 (int (*)(...))QPaintEvent::~QPaintEvent
+24 (int (*)(...))QPaintEvent::~QPaintEvent
+
+Class QPaintEvent
+ size=56 align=8
+ base size=49 base align=8
+QPaintEvent (0x0x7f8849b8d680) 0
+ vptr=((& QPaintEvent::_ZTV11QPaintEvent) + 16u)
+ QEvent (0x0x7f8849f89480) 0
+ primary-for QPaintEvent (0x0x7f8849b8d680)
+
+Vtable for QMoveEvent
+QMoveEvent::_ZTV10QMoveEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QMoveEvent)
+16 (int (*)(...))QMoveEvent::~QMoveEvent
+24 (int (*)(...))QMoveEvent::~QMoveEvent
+
+Class QMoveEvent
+ size=40 align=8
+ base size=36 base align=8
+QMoveEvent (0x0x7f8849b8d6e8) 0
+ vptr=((& QMoveEvent::_ZTV10QMoveEvent) + 16u)
+ QEvent (0x0x7f8849f894e0) 0
+ primary-for QMoveEvent (0x0x7f8849b8d6e8)
+
+Vtable for QExposeEvent
+QExposeEvent::_ZTV12QExposeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QExposeEvent)
+16 (int (*)(...))QExposeEvent::~QExposeEvent
+24 (int (*)(...))QExposeEvent::~QExposeEvent
+
+Class QExposeEvent
+ size=32 align=8
+ base size=32 base align=8
+QExposeEvent (0x0x7f8849b8d750) 0
+ vptr=((& QExposeEvent::_ZTV12QExposeEvent) + 16u)
+ QEvent (0x0x7f8849f89540) 0
+ primary-for QExposeEvent (0x0x7f8849b8d750)
+
+Vtable for QPlatformSurfaceEvent
+QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QPlatformSurfaceEvent)
+16 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent
+24 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent
+
+Class QPlatformSurfaceEvent
+ size=24 align=8
+ base size=24 base align=8
+QPlatformSurfaceEvent (0x0x7f8849b8d7b8) 0
+ vptr=((& QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent) + 16u)
+ QEvent (0x0x7f8849f895a0) 0
+ primary-for QPlatformSurfaceEvent (0x0x7f8849b8d7b8)
+
+Vtable for QResizeEvent
+QResizeEvent::_ZTV12QResizeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QResizeEvent)
+16 (int (*)(...))QResizeEvent::~QResizeEvent
+24 (int (*)(...))QResizeEvent::~QResizeEvent
+
+Class QResizeEvent
+ size=40 align=8
+ base size=36 base align=8
+QResizeEvent (0x0x7f8849b8d820) 0
+ vptr=((& QResizeEvent::_ZTV12QResizeEvent) + 16u)
+ QEvent (0x0x7f8849f89600) 0
+ primary-for QResizeEvent (0x0x7f8849b8d820)
+
+Vtable for QCloseEvent
+QCloseEvent::_ZTV11QCloseEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QCloseEvent)
+16 (int (*)(...))QCloseEvent::~QCloseEvent
+24 (int (*)(...))QCloseEvent::~QCloseEvent
+
+Class QCloseEvent
+ size=24 align=8
+ base size=20 base align=8
+QCloseEvent (0x0x7f8849b8d888) 0
+ vptr=((& QCloseEvent::_ZTV11QCloseEvent) + 16u)
+ QEvent (0x0x7f8849f89660) 0
+ primary-for QCloseEvent (0x0x7f8849b8d888)
+
+Vtable for QIconDragEvent
+QIconDragEvent::_ZTV14QIconDragEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QIconDragEvent)
+16 (int (*)(...))QIconDragEvent::~QIconDragEvent
+24 (int (*)(...))QIconDragEvent::~QIconDragEvent
+
+Class QIconDragEvent
+ size=24 align=8
+ base size=20 base align=8
+QIconDragEvent (0x0x7f8849b8d8f0) 0
+ vptr=((& QIconDragEvent::_ZTV14QIconDragEvent) + 16u)
+ QEvent (0x0x7f8849f896c0) 0
+ primary-for QIconDragEvent (0x0x7f8849b8d8f0)
+
+Vtable for QShowEvent
+QShowEvent::_ZTV10QShowEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QShowEvent)
+16 (int (*)(...))QShowEvent::~QShowEvent
+24 (int (*)(...))QShowEvent::~QShowEvent
+
+Class QShowEvent
+ size=24 align=8
+ base size=20 base align=8
+QShowEvent (0x0x7f8849b8d958) 0
+ vptr=((& QShowEvent::_ZTV10QShowEvent) + 16u)
+ QEvent (0x0x7f8849f89720) 0
+ primary-for QShowEvent (0x0x7f8849b8d958)
+
+Vtable for QHideEvent
+QHideEvent::_ZTV10QHideEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QHideEvent)
+16 (int (*)(...))QHideEvent::~QHideEvent
+24 (int (*)(...))QHideEvent::~QHideEvent
+
+Class QHideEvent
+ size=24 align=8
+ base size=20 base align=8
+QHideEvent (0x0x7f8849b8d9c0) 0
+ vptr=((& QHideEvent::_ZTV10QHideEvent) + 16u)
+ QEvent (0x0x7f8849f89780) 0
+ primary-for QHideEvent (0x0x7f8849b8d9c0)
+
+Vtable for QContextMenuEvent
+QContextMenuEvent::_ZTV17QContextMenuEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QContextMenuEvent)
+16 (int (*)(...))QContextMenuEvent::~QContextMenuEvent
+24 (int (*)(...))QContextMenuEvent::~QContextMenuEvent
+
+Class QContextMenuEvent
+ size=56 align=8
+ base size=49 base align=8
+QContextMenuEvent (0x0x7f8849b8da28) 0
+ vptr=((& QContextMenuEvent::_ZTV17QContextMenuEvent) + 16u)
+ QInputEvent (0x0x7f8849b8da90) 0
+ primary-for QContextMenuEvent (0x0x7f8849b8da28)
+ QEvent (0x0x7f8849f897e0) 0
+ primary-for QInputEvent (0x0x7f8849b8da90)
+
+Class QInputMethodEvent::Attribute
+ size=32 align=8
+ base size=32 base align=8
+QInputMethodEvent::Attribute (0x0x7f8849f898a0) 0
+
+Vtable for QInputMethodEvent
+QInputMethodEvent::_ZTV17QInputMethodEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QInputMethodEvent)
+16 (int (*)(...))QInputMethodEvent::~QInputMethodEvent
+24 (int (*)(...))QInputMethodEvent::~QInputMethodEvent
+
+Class QInputMethodEvent
+ size=56 align=8
+ base size=56 base align=8
+QInputMethodEvent (0x0x7f8849b8daf8) 0
+ vptr=((& QInputMethodEvent::_ZTV17QInputMethodEvent) + 16u)
+ QEvent (0x0x7f8849f89840) 0
+ primary-for QInputMethodEvent (0x0x7f8849b8daf8)
+
+Class QInputMethodQueryEvent::QueryPair
+ size=24 align=8
+ base size=24 base align=8
+QInputMethodQueryEvent::QueryPair (0x0x7f8849f89d20) 0
+
+Vtable for QInputMethodQueryEvent
+QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI22QInputMethodQueryEvent)
+16 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent
+24 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent
+
+Class QInputMethodQueryEvent
+ size=32 align=8
+ base size=32 base align=8
+QInputMethodQueryEvent (0x0x7f8849b8de38) 0
+ vptr=((& QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent) + 16u)
+ QEvent (0x0x7f8849f89cc0) 0
+ primary-for QInputMethodQueryEvent (0x0x7f8849b8de38)
+
+Vtable for QDropEvent
+QDropEvent::_ZTV10QDropEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QDropEvent)
+16 (int (*)(...))QDropEvent::~QDropEvent
+24 (int (*)(...))QDropEvent::~QDropEvent
+
+Class QDropEvent
+ size=72 align=8
+ base size=72 base align=8
+QDropEvent (0x0x7f8849cfd138) 0
+ vptr=((& QDropEvent::_ZTV10QDropEvent) + 16u)
+ QEvent (0x0x7f8849cfe0c0) 0
+ primary-for QDropEvent (0x0x7f8849cfd138)
+
+Vtable for QDragMoveEvent
+QDragMoveEvent::_ZTV14QDragMoveEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QDragMoveEvent)
+16 (int (*)(...))QDragMoveEvent::~QDragMoveEvent
+24 (int (*)(...))QDragMoveEvent::~QDragMoveEvent
+
+Class QDragMoveEvent
+ size=88 align=8
+ base size=88 base align=8
+QDragMoveEvent (0x0x7f8849cfd1a0) 0
+ vptr=((& QDragMoveEvent::_ZTV14QDragMoveEvent) + 16u)
+ QDropEvent (0x0x7f8849cfd208) 0
+ primary-for QDragMoveEvent (0x0x7f8849cfd1a0)
+ QEvent (0x0x7f8849cfe120) 0
+ primary-for QDropEvent (0x0x7f8849cfd208)
+
+Vtable for QDragEnterEvent
+QDragEnterEvent::_ZTV15QDragEnterEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QDragEnterEvent)
+16 (int (*)(...))QDragEnterEvent::~QDragEnterEvent
+24 (int (*)(...))QDragEnterEvent::~QDragEnterEvent
+
+Class QDragEnterEvent
+ size=88 align=8
+ base size=88 base align=8
+QDragEnterEvent (0x0x7f8849cfd270) 0
+ vptr=((& QDragEnterEvent::_ZTV15QDragEnterEvent) + 16u)
+ QDragMoveEvent (0x0x7f8849cfd2d8) 0
+ primary-for QDragEnterEvent (0x0x7f8849cfd270)
+ QDropEvent (0x0x7f8849cfd340) 0
+ primary-for QDragMoveEvent (0x0x7f8849cfd2d8)
+ QEvent (0x0x7f8849cfe180) 0
+ primary-for QDropEvent (0x0x7f8849cfd340)
+
+Vtable for QDragLeaveEvent
+QDragLeaveEvent::_ZTV15QDragLeaveEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QDragLeaveEvent)
+16 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent
+24 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent
+
+Class QDragLeaveEvent
+ size=24 align=8
+ base size=20 base align=8
+QDragLeaveEvent (0x0x7f8849cfd3a8) 0
+ vptr=((& QDragLeaveEvent::_ZTV15QDragLeaveEvent) + 16u)
+ QEvent (0x0x7f8849cfe1e0) 0
+ primary-for QDragLeaveEvent (0x0x7f8849cfd3a8)
+
+Vtable for QHelpEvent
+QHelpEvent::_ZTV10QHelpEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QHelpEvent)
+16 (int (*)(...))QHelpEvent::~QHelpEvent
+24 (int (*)(...))QHelpEvent::~QHelpEvent
+
+Class QHelpEvent
+ size=40 align=8
+ base size=36 base align=8
+QHelpEvent (0x0x7f8849cfd410) 0
+ vptr=((& QHelpEvent::_ZTV10QHelpEvent) + 16u)
+ QEvent (0x0x7f8849cfe240) 0
+ primary-for QHelpEvent (0x0x7f8849cfd410)
+
+Vtable for QStatusTipEvent
+QStatusTipEvent::_ZTV15QStatusTipEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QStatusTipEvent)
+16 (int (*)(...))QStatusTipEvent::~QStatusTipEvent
+24 (int (*)(...))QStatusTipEvent::~QStatusTipEvent
+
+Class QStatusTipEvent
+ size=32 align=8
+ base size=32 base align=8
+QStatusTipEvent (0x0x7f8849cfd478) 0
+ vptr=((& QStatusTipEvent::_ZTV15QStatusTipEvent) + 16u)
+ QEvent (0x0x7f8849cfe2a0) 0
+ primary-for QStatusTipEvent (0x0x7f8849cfd478)
+
+Vtable for QWhatsThisClickedEvent
+QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI22QWhatsThisClickedEvent)
+16 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent
+24 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent
+
+Class QWhatsThisClickedEvent
+ size=32 align=8
+ base size=32 base align=8
+QWhatsThisClickedEvent (0x0x7f8849cfd4e0) 0
+ vptr=((& QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent) + 16u)
+ QEvent (0x0x7f8849cfe300) 0
+ primary-for QWhatsThisClickedEvent (0x0x7f8849cfd4e0)
+
+Vtable for QActionEvent
+QActionEvent::_ZTV12QActionEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QActionEvent)
+16 (int (*)(...))QActionEvent::~QActionEvent
+24 (int (*)(...))QActionEvent::~QActionEvent
+
+Class QActionEvent
+ size=40 align=8
+ base size=40 base align=8
+QActionEvent (0x0x7f8849cfd548) 0
+ vptr=((& QActionEvent::_ZTV12QActionEvent) + 16u)
+ QEvent (0x0x7f8849cfe360) 0
+ primary-for QActionEvent (0x0x7f8849cfd548)
+
+Vtable for QFileOpenEvent
+QFileOpenEvent::_ZTV14QFileOpenEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QFileOpenEvent)
+16 (int (*)(...))QFileOpenEvent::~QFileOpenEvent
+24 (int (*)(...))QFileOpenEvent::~QFileOpenEvent
+
+Class QFileOpenEvent
+ size=40 align=8
+ base size=40 base align=8
+QFileOpenEvent (0x0x7f8849cfd5b0) 0
+ vptr=((& QFileOpenEvent::_ZTV14QFileOpenEvent) + 16u)
+ QEvent (0x0x7f8849cfe3c0) 0
+ primary-for QFileOpenEvent (0x0x7f8849cfd5b0)
+
+Vtable for QToolBarChangeEvent
+QToolBarChangeEvent::_ZTV19QToolBarChangeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QToolBarChangeEvent)
+16 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent
+24 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent
+
+Class QToolBarChangeEvent
+ size=24 align=8
+ base size=21 base align=8
+QToolBarChangeEvent (0x0x7f8849cfd618) 0
+ vptr=((& QToolBarChangeEvent::_ZTV19QToolBarChangeEvent) + 16u)
+ QEvent (0x0x7f8849cfe420) 0
+ primary-for QToolBarChangeEvent (0x0x7f8849cfd618)
+
+Vtable for QShortcutEvent
+QShortcutEvent::_ZTV14QShortcutEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QShortcutEvent)
+16 (int (*)(...))QShortcutEvent::~QShortcutEvent
+24 (int (*)(...))QShortcutEvent::~QShortcutEvent
+
+Class QShortcutEvent
+ size=40 align=8
+ base size=40 base align=8
+QShortcutEvent (0x0x7f8849cfd680) 0
+ vptr=((& QShortcutEvent::_ZTV14QShortcutEvent) + 16u)
+ QEvent (0x0x7f8849cfe480) 0
+ primary-for QShortcutEvent (0x0x7f8849cfd680)
+
+Vtable for QWindowStateChangeEvent
+QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QWindowStateChangeEvent)
+16 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent
+24 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent
+
+Class QWindowStateChangeEvent
+ size=32 align=8
+ base size=25 base align=8
+QWindowStateChangeEvent (0x0x7f8849cfd6e8) 0
+ vptr=((& QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent) + 16u)
+ QEvent (0x0x7f8849cfe4e0) 0
+ primary-for QWindowStateChangeEvent (0x0x7f8849cfd6e8)
+
+Class QPointingDeviceUniqueId
+ size=8 align=8
+ base size=8 base align=8
+QPointingDeviceUniqueId (0x0x7f8849cfe540) 0
+
+Class QTouchEvent::TouchPoint
+ size=8 align=8
+ base size=8 base align=8
+QTouchEvent::TouchPoint (0x0x7f8849cfec00) 0
+
+Vtable for QTouchEvent
+QTouchEvent::_ZTV11QTouchEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTouchEvent)
+16 (int (*)(...))QTouchEvent::~QTouchEvent
+24 (int (*)(...))QTouchEvent::~QTouchEvent
+
+Class QTouchEvent
+ size=72 align=8
+ base size=72 base align=8
+QTouchEvent (0x0x7f8849cfdd68) 0
+ vptr=((& QTouchEvent::_ZTV11QTouchEvent) + 16u)
+ QInputEvent (0x0x7f8849cfddd0) 0
+ primary-for QTouchEvent (0x0x7f8849cfdd68)
+ QEvent (0x0x7f8849cfeba0) 0
+ primary-for QInputEvent (0x0x7f8849cfddd0)
+
+Vtable for QScrollPrepareEvent
+QScrollPrepareEvent::_ZTV19QScrollPrepareEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QScrollPrepareEvent)
+16 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent
+24 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent
+
+Class QScrollPrepareEvent
+ size=112 align=8
+ base size=112 base align=8
+QScrollPrepareEvent (0x0x7f8849a25618) 0
+ vptr=((& QScrollPrepareEvent::_ZTV19QScrollPrepareEvent) + 16u)
+ QEvent (0x0x7f8849a362a0) 0
+ primary-for QScrollPrepareEvent (0x0x7f8849a25618)
+
+Vtable for QScrollEvent
+QScrollEvent::_ZTV12QScrollEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QScrollEvent)
+16 (int (*)(...))QScrollEvent::~QScrollEvent
+24 (int (*)(...))QScrollEvent::~QScrollEvent
+
+Class QScrollEvent
+ size=64 align=8
+ base size=60 base align=8
+QScrollEvent (0x0x7f8849a25680) 0
+ vptr=((& QScrollEvent::_ZTV12QScrollEvent) + 16u)
+ QEvent (0x0x7f8849a36300) 0
+ primary-for QScrollEvent (0x0x7f8849a25680)
+
+Vtable for QScreenOrientationChangeEvent
+QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI29QScreenOrientationChangeEvent)
+16 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent
+24 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent
+
+Class QScreenOrientationChangeEvent
+ size=40 align=8
+ base size=36 base align=8
+QScreenOrientationChangeEvent (0x0x7f8849a256e8) 0
+ vptr=((& QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent) + 16u)
+ QEvent (0x0x7f8849a36360) 0
+ primary-for QScreenOrientationChangeEvent (0x0x7f8849a256e8)
+
+Vtable for QApplicationStateChangeEvent
+QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI28QApplicationStateChangeEvent)
+16 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent
+24 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent
+
+Class QApplicationStateChangeEvent
+ size=24 align=8
+ base size=24 base align=8
+QApplicationStateChangeEvent (0x0x7f8849a25750) 0
+ vptr=((& QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent) + 16u)
+ QEvent (0x0x7f8849a363c0) 0
+ primary-for QApplicationStateChangeEvent (0x0x7f8849a25750)
+
+Class QFont
+ size=16 align=8
+ base size=12 base align=8
+QFont (0x0x7f8849a36420) 0
+
+Class QPolygon
+ size=8 align=8
+ base size=8 base align=8
+QPolygon (0x0x7f8849ae84e0) 0
+ QVector<QPoint> (0x0x7f8849aec120) 0
+
+Class QPolygonF
+ size=8 align=8
+ base size=8 base align=8
+QPolygonF (0x0x7f8849ae8888) 0
+ QVector<QPointF> (0x0x7f8849aec5a0) 0
+
+Class QMatrix
+ size=48 align=8
+ base size=48 base align=8
+QMatrix (0x0x7f8849aec960) 0
+
+Class QPainterPath::Element
+ size=24 align=8
+ base size=24 base align=8
+QPainterPath::Element (0x0x7f8849aecc60) 0
+
+Class QPainterPath
+ size=8 align=8
+ base size=8 base align=8
+QPainterPath (0x0x7f8849aecc00) 0
+
+Class QPainterPathStroker
+ size=8 align=8
+ base size=8 base align=8
+QPainterPathStroker (0x0x7f884982b660) 0
+
+Class QTransform
+ size=88 align=8
+ base size=88 base align=8
+QTransform (0x0x7f884982b780) 0
+
+Vtable for QPaintDevice
+QPaintDevice::_ZTV12QPaintDevice: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QPaintDevice)
+16 0u
+24 0u
+32 (int (*)(...))QPaintDevice::devType
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))QPaintDevice::metric
+56 (int (*)(...))QPaintDevice::initPainter
+64 (int (*)(...))QPaintDevice::redirected
+72 (int (*)(...))QPaintDevice::sharedPainter
+
+Class QPaintDevice
+ size=24 align=8
+ base size=24 base align=8
+QPaintDevice (0x0x7f884982bea0) 0
+ vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 16u)
+
+Class QPixelFormat
+ size=8 align=8
+ base size=8 base align=8
+QPixelFormat (0x0x7f884982bf00) 0
+
+Vtable for QImage
+QImage::_ZTV6QImage: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QImage)
+16 (int (*)(...))QImage::~QImage
+24 (int (*)(...))QImage::~QImage
+32 (int (*)(...))QImage::devType
+40 (int (*)(...))QImage::paintEngine
+48 (int (*)(...))QImage::metric
+56 (int (*)(...))QPaintDevice::initPainter
+64 (int (*)(...))QPaintDevice::redirected
+72 (int (*)(...))QPaintDevice::sharedPainter
+
+Class QImage
+ size=32 align=8
+ base size=32 base align=8
+QImage (0x0x7f884996b750) 0
+ vptr=((& QImage::_ZTV6QImage) + 16u)
+ QPaintDevice (0x0x7f88499659c0) 0
+ primary-for QImage (0x0x7f884996b750)
+
+Vtable for QPixmap
+QPixmap::_ZTV7QPixmap: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QPixmap)
+16 (int (*)(...))QPixmap::~QPixmap
+24 (int (*)(...))QPixmap::~QPixmap
+32 (int (*)(...))QPixmap::devType
+40 (int (*)(...))QPixmap::paintEngine
+48 (int (*)(...))QPixmap::metric
+56 (int (*)(...))QPaintDevice::initPainter
+64 (int (*)(...))QPaintDevice::redirected
+72 (int (*)(...))QPaintDevice::sharedPainter
+
+Class QPixmap
+ size=32 align=8
+ base size=32 base align=8
+QPixmap (0x0x7f88496542d8) 0
+ vptr=((& QPixmap::_ZTV7QPixmap) + 16u)
+ QPaintDevice (0x0x7f884963f960) 0
+ primary-for QPixmap (0x0x7f88496542d8)
+
+Class QBrush
+ size=8 align=8
+ base size=8 base align=8
+QBrush (0x0x7f884963fc60) 0
+
+Class QBrushData
+ size=112 align=8
+ base size=112 base align=8
+QBrushData (0x0x7f88496da420) 0
+
+Class QGradient
+ size=64 align=8
+ base size=64 base align=8
+QGradient (0x0x7f88496da480) 0
+
+Class QLinearGradient
+ size=64 align=8
+ base size=64 base align=8
+QLinearGradient (0x0x7f8849654c30) 0
+ QGradient (0x0x7f88496da720) 0
+
+Class QRadialGradient
+ size=64 align=8
+ base size=64 base align=8
+QRadialGradient (0x0x7f8849654c98) 0
+ QGradient (0x0x7f88496da780) 0
+
+Class QConicalGradient
+ size=64 align=8
+ base size=64 base align=8
+QConicalGradient (0x0x7f8849654d00) 0
+ QGradient (0x0x7f88496da7e0) 0
+
+Class QPen
+ size=8 align=8
+ base size=8 base align=8
+QPen (0x0x7f88496da840) 0
+
+Class QTextOption::Tab
+ size=16 align=8
+ base size=14 base align=8
+QTextOption::Tab (0x0x7f88493c1a80) 0
+
+Class QTextOption
+ size=32 align=8
+ base size=32 base align=8
+QTextOption (0x0x7f88493c1a20) 0
+
+Class QTextLength
+ size=16 align=8
+ base size=16 base align=8
+QTextLength (0x0x7f8849403240) 0
+
+Class QTextFormat
+ size=16 align=8
+ base size=12 base align=8
+QTextFormat (0x0x7f8849403960) 0
+
+Class QTextCharFormat
+ size=16 align=8
+ base size=12 base align=8
+QTextCharFormat (0x0x7f88494a4e38) 0
+ QTextFormat (0x0x7f88494c77e0) 0
+
+Class QTextBlockFormat
+ size=16 align=8
+ base size=12 base align=8
+QTextBlockFormat (0x0x7f88494a45b0) 0
+ QTextFormat (0x0x7f88494c7a80) 0
+
+Class QTextListFormat
+ size=16 align=8
+ base size=12 base align=8
+QTextListFormat (0x0x7f88491bc0d0) 0
+ QTextFormat (0x0x7f88494c7d20) 0
+
+Class QTextImageFormat
+ size=16 align=8
+ base size=12 base align=8
+QTextImageFormat (0x0x7f88491bc2d8) 0
+ QTextCharFormat (0x0x7f88491bc340) 0
+ QTextFormat (0x0x7f88491d8000) 0
+
+Class QTextFrameFormat
+ size=16 align=8
+ base size=12 base align=8
+QTextFrameFormat (0x0x7f88491bc548) 0
+ QTextFormat (0x0x7f88491d82a0) 0
+
+Class QTextTableFormat
+ size=16 align=8
+ base size=12 base align=8
+QTextTableFormat (0x0x7f88491bc750) 0
+ QTextFrameFormat (0x0x7f88491bc7b8) 0
+ QTextFormat (0x0x7f88491d8540) 0
+
+Class QTextTableCellFormat
+ size=16 align=8
+ base size=12 base align=8
+QTextTableCellFormat (0x0x7f88491bc9c0) 0
+ QTextCharFormat (0x0x7f88491bca28) 0
+ QTextFormat (0x0x7f88491d8840) 0
+
+Class QFontDatabase
+ size=8 align=8
+ base size=8 base align=8
+QFontDatabase (0x0x7f88491d8ae0) 0
+
+Class QRawFont
+ size=8 align=8
+ base size=8 base align=8
+QRawFont (0x0x7f88491d8b40) 0
+
+Class QGlyphRun
+ size=8 align=8
+ base size=8 base align=8
+QGlyphRun (0x0x7f884929b060) 0
+
+Class QTextCursor
+ size=8 align=8
+ base size=8 base align=8
+QTextCursor (0x0x7f884929b360) 0
+
+Class QTextInlineObject
+ size=16 align=8
+ base size=16 base align=8
+QTextInlineObject (0x0x7f884929b660) 0
+
+Class QTextLayout::FormatRange
+ size=24 align=8
+ base size=24 base align=8
+QTextLayout::FormatRange (0x0x7f884929b720) 0
+
+Class QTextLayout
+ size=8 align=8
+ base size=8 base align=8
+QTextLayout (0x0x7f884929b6c0) 0
+
+Class QTextLine
+ size=16 align=8
+ base size=16 base align=8
+QTextLine (0x0x7f884937d180) 0
+
+Vtable for QAbstractUndoItem
+QAbstractUndoItem::_ZTV17QAbstractUndoItem: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QAbstractUndoItem)
+16 (int (*)(...))__cxa_pure_virtual
+24 (int (*)(...))__cxa_pure_virtual
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+
+Class QAbstractUndoItem
+ size=8 align=8
+ base size=8 base align=8
+QAbstractUndoItem (0x0x7f884937d1e0) 0 nearly-empty
+ vptr=((& QAbstractUndoItem::_ZTV17QAbstractUndoItem) + 16u)
+
+Class QTextDocument::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTextDocument::QPrivateSignal (0x0x7f884937d2a0) 0 empty
+
+Vtable for QTextDocument
+QTextDocument::_ZTV13QTextDocument: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QTextDocument)
+16 (int (*)(...))QTextDocument::metaObject
+24 (int (*)(...))QTextDocument::qt_metacast
+32 (int (*)(...))QTextDocument::qt_metacall
+40 (int (*)(...))QTextDocument::~QTextDocument
+48 (int (*)(...))QTextDocument::~QTextDocument
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QTextDocument::clear
+120 (int (*)(...))QTextDocument::createObject
+128 (int (*)(...))QTextDocument::loadResource
+
+Class QTextDocument
+ size=16 align=8
+ base size=16 base align=8
+QTextDocument (0x0x7f88492dfe38) 0
+ vptr=((& QTextDocument::_ZTV13QTextDocument) + 16u)
+ QObject (0x0x7f884937d240) 0
+ primary-for QTextDocument (0x0x7f88492dfe38)
+
+Class QPalette::Data
+ size=4 align=4
+ base size=4 base align=4
+QPalette::Data (0x0x7f884937d4e0) 0
+
+Class QPalette
+ size=16 align=8
+ base size=12 base align=8
+QPalette (0x0x7f884937d480) 0
+
+Class QAbstractTextDocumentLayout::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractTextDocumentLayout::QPrivateSignal (0x0x7f884909f5a0) 0 empty
+
+Class QAbstractTextDocumentLayout::Selection
+ size=24 align=8
+ base size=24 base align=8
+QAbstractTextDocumentLayout::Selection (0x0x7f884909f600) 0
+
+Class QAbstractTextDocumentLayout::PaintContext
+ size=64 align=8
+ base size=64 base align=8
+QAbstractTextDocumentLayout::PaintContext (0x0x7f884909f660) 0
+
+Vtable for QAbstractTextDocumentLayout
+QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout: 24u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QAbstractTextDocumentLayout)
+16 (int (*)(...))QAbstractTextDocumentLayout::metaObject
+24 (int (*)(...))QAbstractTextDocumentLayout::qt_metacast
+32 (int (*)(...))QAbstractTextDocumentLayout::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))__cxa_pure_virtual
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))QAbstractTextDocumentLayout::resizeInlineObject
+176 (int (*)(...))QAbstractTextDocumentLayout::positionInlineObject
+184 (int (*)(...))QAbstractTextDocumentLayout::drawInlineObject
+
+Class QAbstractTextDocumentLayout
+ size=16 align=8
+ base size=16 base align=8
+QAbstractTextDocumentLayout (0x0x7f884909ca90) 0
+ vptr=((& QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout) + 16u)
+ QObject (0x0x7f884909f540) 0
+ primary-for QAbstractTextDocumentLayout (0x0x7f884909ca90)
+
+Vtable for QTextObjectInterface
+QTextObjectInterface::_ZTV20QTextObjectInterface: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QTextObjectInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+
+Class QTextObjectInterface
+ size=8 align=8
+ base size=8 base align=8
+QTextObjectInterface (0x0x7f884909fc00) 0 nearly-empty
+ vptr=((& QTextObjectInterface::_ZTV20QTextObjectInterface) + 16u)
+
+Class QAccessible::State
+ size=8 align=8
+ base size=5 base align=8
+QAccessible::State (0x0x7f884909fd20) 0
+
+Vtable for QAccessible::ActivationObserver
+QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN11QAccessible18ActivationObserverE)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessible::ActivationObserver
+ size=8 align=8
+ base size=8 base align=8
+QAccessible::ActivationObserver (0x0x7f884909fd80) 0 nearly-empty
+ vptr=((& QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE) + 16u)
+
+Class QAccessible
+ size=1 align=1
+ base size=0 base align=1
+QAccessible (0x0x7f884909fcc0) 0 empty
+
+Vtable for QAccessibleInterface
+QAccessibleInterface::_ZTV20QAccessibleInterface: 23u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QAccessibleInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))QAccessibleInterface::window
+56 (int (*)(...))QAccessibleInterface::relations
+64 (int (*)(...))QAccessibleInterface::focusChild
+72 (int (*)(...))__cxa_pure_virtual
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))__cxa_pure_virtual
+96 (int (*)(...))__cxa_pure_virtual
+104 (int (*)(...))__cxa_pure_virtual
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))QAccessibleInterface::foregroundColor
+160 (int (*)(...))QAccessibleInterface::backgroundColor
+168 (int (*)(...))QAccessibleInterface::virtual_hook
+176 (int (*)(...))QAccessibleInterface::interface_cast
+
+Class QAccessibleInterface
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleInterface (0x0x7f884909ff60) 0 nearly-empty
+ vptr=((& QAccessibleInterface::_ZTV20QAccessibleInterface) + 16u)
+
+Vtable for QAccessibleTextInterface
+QAccessibleTextInterface::_ZTV24QAccessibleTextInterface: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QAccessibleTextInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+72 (int (*)(...))__cxa_pure_virtual
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))__cxa_pure_virtual
+96 (int (*)(...))QAccessibleTextInterface::textBeforeOffset
+104 (int (*)(...))QAccessibleTextInterface::textAfterOffset
+112 (int (*)(...))QAccessibleTextInterface::textAtOffset
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleTextInterface
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleTextInterface (0x0x7f884918a000) 0 nearly-empty
+ vptr=((& QAccessibleTextInterface::_ZTV24QAccessibleTextInterface) + 16u)
+
+Vtable for QAccessibleEditableTextInterface
+QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI32QAccessibleEditableTextInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleEditableTextInterface
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleEditableTextInterface (0x0x7f884918a060) 0 nearly-empty
+ vptr=((& QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface) + 16u)
+
+Vtable for QAccessibleValueInterface
+QAccessibleValueInterface::_ZTV25QAccessibleValueInterface: 9u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI25QAccessibleValueInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleValueInterface
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleValueInterface (0x0x7f884918a0c0) 0 nearly-empty
+ vptr=((& QAccessibleValueInterface::_ZTV25QAccessibleValueInterface) + 16u)
+
+Vtable for QAccessibleTableCellInterface
+QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface: 12u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI29QAccessibleTableCellInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+72 (int (*)(...))__cxa_pure_virtual
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleTableCellInterface
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleTableCellInterface (0x0x7f884918a120) 0 nearly-empty
+ vptr=((& QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface) + 16u)
+
+Vtable for QAccessibleTableInterface
+QAccessibleTableInterface::_ZTV25QAccessibleTableInterface: 24u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI25QAccessibleTableInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+72 (int (*)(...))__cxa_pure_virtual
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))__cxa_pure_virtual
+96 (int (*)(...))__cxa_pure_virtual
+104 (int (*)(...))__cxa_pure_virtual
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))__cxa_pure_virtual
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))__cxa_pure_virtual
+176 (int (*)(...))__cxa_pure_virtual
+184 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleTableInterface
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleTableInterface (0x0x7f884918a180) 0 nearly-empty
+ vptr=((& QAccessibleTableInterface::_ZTV25QAccessibleTableInterface) + 16u)
+
+Vtable for QAccessibleActionInterface
+QAccessibleActionInterface::_ZTV26QAccessibleActionInterface: 9u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QAccessibleActionInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))QAccessibleActionInterface::localizedActionName
+48 (int (*)(...))QAccessibleActionInterface::localizedActionDescription
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleActionInterface
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleActionInterface (0x0x7f884918a1e0) 0 nearly-empty
+ vptr=((& QAccessibleActionInterface::_ZTV26QAccessibleActionInterface) + 16u)
+
+Vtable for QAccessibleImageInterface
+QAccessibleImageInterface::_ZTV25QAccessibleImageInterface: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI25QAccessibleImageInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleImageInterface
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleImageInterface (0x0x7f884918a240) 0 nearly-empty
+ vptr=((& QAccessibleImageInterface::_ZTV25QAccessibleImageInterface) + 16u)
+
+Vtable for QAccessibleEvent
+QAccessibleEvent::_ZTV16QAccessibleEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QAccessibleEvent)
+16 (int (*)(...))QAccessibleEvent::~QAccessibleEvent
+24 (int (*)(...))QAccessibleEvent::~QAccessibleEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleEvent
+ size=32 align=8
+ base size=28 base align=8
+QAccessibleEvent (0x0x7f884918a2a0) 0
+ vptr=((& QAccessibleEvent::_ZTV16QAccessibleEvent) + 16u)
+
+Vtable for QAccessibleStateChangeEvent
+QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QAccessibleStateChangeEvent)
+16 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent
+24 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleStateChangeEvent
+ size=40 align=8
+ base size=40 base align=8
+QAccessibleStateChangeEvent (0x0x7f8848dbd4e0) 0
+ vptr=((& QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent) + 16u)
+ QAccessibleEvent (0x0x7f884918a7e0) 0
+ primary-for QAccessibleStateChangeEvent (0x0x7f8848dbd4e0)
+
+Vtable for QAccessibleTextCursorEvent
+QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QAccessibleTextCursorEvent)
+16 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent
+24 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleTextCursorEvent
+ size=32 align=8
+ base size=32 base align=8
+QAccessibleTextCursorEvent (0x0x7f8848dbd548) 0
+ vptr=((& QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent) + 16u)
+ QAccessibleEvent (0x0x7f884918a840) 0
+ primary-for QAccessibleTextCursorEvent (0x0x7f8848dbd548)
+
+Vtable for QAccessibleTextSelectionEvent
+QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI29QAccessibleTextSelectionEvent)
+16 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent
+24 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleTextSelectionEvent
+ size=40 align=8
+ base size=40 base align=8
+QAccessibleTextSelectionEvent (0x0x7f8848dbd5b0) 0
+ vptr=((& QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent) + 16u)
+ QAccessibleTextCursorEvent (0x0x7f8848dbd618) 0
+ primary-for QAccessibleTextSelectionEvent (0x0x7f8848dbd5b0)
+ QAccessibleEvent (0x0x7f884918a8a0) 0
+ primary-for QAccessibleTextCursorEvent (0x0x7f8848dbd618)
+
+Vtable for QAccessibleTextInsertEvent
+QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QAccessibleTextInsertEvent)
+16 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent
+24 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleTextInsertEvent
+ size=48 align=8
+ base size=48 base align=8
+QAccessibleTextInsertEvent (0x0x7f8848dbd680) 0
+ vptr=((& QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent) + 16u)
+ QAccessibleTextCursorEvent (0x0x7f8848dbd6e8) 0
+ primary-for QAccessibleTextInsertEvent (0x0x7f8848dbd680)
+ QAccessibleEvent (0x0x7f884918a900) 0
+ primary-for QAccessibleTextCursorEvent (0x0x7f8848dbd6e8)
+
+Vtable for QAccessibleTextRemoveEvent
+QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QAccessibleTextRemoveEvent)
+16 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent
+24 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleTextRemoveEvent
+ size=48 align=8
+ base size=48 base align=8
+QAccessibleTextRemoveEvent (0x0x7f8848dbd750) 0
+ vptr=((& QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent) + 16u)
+ QAccessibleTextCursorEvent (0x0x7f8848dbd7b8) 0
+ primary-for QAccessibleTextRemoveEvent (0x0x7f8848dbd750)
+ QAccessibleEvent (0x0x7f884918a960) 0
+ primary-for QAccessibleTextCursorEvent (0x0x7f8848dbd7b8)
+
+Vtable for QAccessibleTextUpdateEvent
+QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QAccessibleTextUpdateEvent)
+16 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent
+24 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleTextUpdateEvent
+ size=56 align=8
+ base size=56 base align=8
+QAccessibleTextUpdateEvent (0x0x7f8848dbd820) 0
+ vptr=((& QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent) + 16u)
+ QAccessibleTextCursorEvent (0x0x7f8848dbd888) 0
+ primary-for QAccessibleTextUpdateEvent (0x0x7f8848dbd820)
+ QAccessibleEvent (0x0x7f884918a9c0) 0
+ primary-for QAccessibleTextCursorEvent (0x0x7f8848dbd888)
+
+Vtable for QAccessibleValueChangeEvent
+QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QAccessibleValueChangeEvent)
+16 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent
+24 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleValueChangeEvent
+ size=48 align=8
+ base size=48 base align=8
+QAccessibleValueChangeEvent (0x0x7f8848dbd8f0) 0
+ vptr=((& QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent) + 16u)
+ QAccessibleEvent (0x0x7f884918aa20) 0
+ primary-for QAccessibleValueChangeEvent (0x0x7f8848dbd8f0)
+
+Vtable for QAccessibleTableModelChangeEvent
+QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI32QAccessibleTableModelChangeEvent)
+16 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent
+24 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleTableModelChangeEvent
+ size=48 align=8
+ base size=48 base align=8
+QAccessibleTableModelChangeEvent (0x0x7f8848dbd958) 0
+ vptr=((& QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent) + 16u)
+ QAccessibleEvent (0x0x7f884918aa80) 0
+ primary-for QAccessibleTableModelChangeEvent (0x0x7f8848dbd958)
+
+Vtable for QAccessibleBridge
+QAccessibleBridge::_ZTV17QAccessibleBridge: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QAccessibleBridge)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleBridge
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleBridge (0x0x7f884918ab40) 0 nearly-empty
+ vptr=((& QAccessibleBridge::_ZTV17QAccessibleBridge) + 16u)
+
+Class QAccessibleBridgePlugin::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAccessibleBridgePlugin::QPrivateSignal (0x0x7f884918ac00) 0 empty
+
+Vtable for QAccessibleBridgePlugin
+QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QAccessibleBridgePlugin)
+16 (int (*)(...))QAccessibleBridgePlugin::metaObject
+24 (int (*)(...))QAccessibleBridgePlugin::qt_metacast
+32 (int (*)(...))QAccessibleBridgePlugin::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleBridgePlugin
+ size=16 align=8
+ base size=16 base align=8
+QAccessibleBridgePlugin (0x0x7f8848dbd9c0) 0
+ vptr=((& QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin) + 16u)
+ QObject (0x0x7f884918aba0) 0
+ primary-for QAccessibleBridgePlugin (0x0x7f8848dbd9c0)
+
+Vtable for QAccessibleObject
+QAccessibleObject::_ZTV17QAccessibleObject: 23u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QAccessibleObject)
+16 0u
+24 0u
+32 (int (*)(...))QAccessibleObject::isValid
+40 (int (*)(...))QAccessibleObject::object
+48 (int (*)(...))QAccessibleInterface::window
+56 (int (*)(...))QAccessibleInterface::relations
+64 (int (*)(...))QAccessibleInterface::focusChild
+72 (int (*)(...))QAccessibleObject::childAt
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))__cxa_pure_virtual
+96 (int (*)(...))__cxa_pure_virtual
+104 (int (*)(...))__cxa_pure_virtual
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))QAccessibleObject::setText
+128 (int (*)(...))QAccessibleObject::rect
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))QAccessibleInterface::foregroundColor
+160 (int (*)(...))QAccessibleInterface::backgroundColor
+168 (int (*)(...))QAccessibleInterface::virtual_hook
+176 (int (*)(...))QAccessibleInterface::interface_cast
+
+Class QAccessibleObject
+ size=16 align=8
+ base size=16 base align=8
+QAccessibleObject (0x0x7f8848dbda28) 0
+ vptr=((& QAccessibleObject::_ZTV17QAccessibleObject) + 16u)
+ QAccessibleInterface (0x0x7f884918ac60) 0 nearly-empty
+ primary-for QAccessibleObject (0x0x7f8848dbda28)
+
+Vtable for QAccessibleApplication
+QAccessibleApplication::_ZTV22QAccessibleApplication: 23u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI22QAccessibleApplication)
+16 (int (*)(...))QAccessibleApplication::~QAccessibleApplication
+24 (int (*)(...))QAccessibleApplication::~QAccessibleApplication
+32 (int (*)(...))QAccessibleObject::isValid
+40 (int (*)(...))QAccessibleObject::object
+48 (int (*)(...))QAccessibleApplication::window
+56 (int (*)(...))QAccessibleInterface::relations
+64 (int (*)(...))QAccessibleApplication::focusChild
+72 (int (*)(...))QAccessibleObject::childAt
+80 (int (*)(...))QAccessibleApplication::parent
+88 (int (*)(...))QAccessibleApplication::child
+96 (int (*)(...))QAccessibleApplication::childCount
+104 (int (*)(...))QAccessibleApplication::indexOfChild
+112 (int (*)(...))QAccessibleApplication::text
+120 (int (*)(...))QAccessibleObject::setText
+128 (int (*)(...))QAccessibleObject::rect
+136 (int (*)(...))QAccessibleApplication::role
+144 (int (*)(...))QAccessibleApplication::state
+152 (int (*)(...))QAccessibleInterface::foregroundColor
+160 (int (*)(...))QAccessibleInterface::backgroundColor
+168 (int (*)(...))QAccessibleInterface::virtual_hook
+176 (int (*)(...))QAccessibleInterface::interface_cast
+
+Class QAccessibleApplication
+ size=16 align=8
+ base size=16 base align=8
+QAccessibleApplication (0x0x7f8848dbda90) 0
+ vptr=((& QAccessibleApplication::_ZTV22QAccessibleApplication) + 16u)
+ QAccessibleObject (0x0x7f8848dbdaf8) 0
+ primary-for QAccessibleApplication (0x0x7f8848dbda90)
+ QAccessibleInterface (0x0x7f884918acc0) 0 nearly-empty
+ primary-for QAccessibleObject (0x0x7f8848dbdaf8)
+
+Class QAccessiblePlugin::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAccessiblePlugin::QPrivateSignal (0x0x7f884918ad80) 0 empty
+
+Vtable for QAccessiblePlugin
+QAccessiblePlugin::_ZTV17QAccessiblePlugin: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QAccessiblePlugin)
+16 (int (*)(...))QAccessiblePlugin::metaObject
+24 (int (*)(...))QAccessiblePlugin::qt_metacast
+32 (int (*)(...))QAccessiblePlugin::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessiblePlugin
+ size=16 align=8
+ base size=16 base align=8
+QAccessiblePlugin (0x0x7f8848dbdb60) 0
+ vptr=((& QAccessiblePlugin::_ZTV17QAccessiblePlugin) + 16u)
+ QObject (0x0x7f884918ad20) 0
+ primary-for QAccessiblePlugin (0x0x7f8848dbdb60)
+
+Class QSurfaceFormat
+ size=8 align=8
+ base size=8 base align=8
+QSurfaceFormat (0x0x7f884918ade0) 0
+
+Vtable for QSurface
+QSurface::_ZTV8QSurface: 8u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QSurface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))__cxa_pure_virtual
+
+Class QSurface
+ size=24 align=8
+ base size=24 base align=8
+QSurface (0x0x7f8848f00000) 0
+ vptr=((& QSurface::_ZTV8QSurface) + 16u)
+
+Class QIcon
+ size=8 align=8
+ base size=8 base align=8
+QIcon (0x0x7f8848f00180) 0
+
+Class QCursor
+ size=8 align=8
+ base size=8 base align=8
+QCursor (0x0x7f8848b97540) 0
+
+Class QWindow::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QWindow::QPrivateSignal (0x0x7f8848c22b40) 0 empty
+
+Vtable for QWindow
+QWindow::_ZTV7QWindow: 45u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QWindow)
+16 (int (*)(...))QWindow::metaObject
+24 (int (*)(...))QWindow::qt_metacast
+32 (int (*)(...))QWindow::qt_metacall
+40 (int (*)(...))QWindow::~QWindow
+48 (int (*)(...))QWindow::~QWindow
+56 (int (*)(...))QWindow::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWindow::surfaceType
+120 (int (*)(...))QWindow::format
+128 (int (*)(...))QWindow::size
+136 (int (*)(...))QWindow::accessibleRoot
+144 (int (*)(...))QWindow::focusObject
+152 (int (*)(...))QWindow::exposeEvent
+160 (int (*)(...))QWindow::resizeEvent
+168 (int (*)(...))QWindow::moveEvent
+176 (int (*)(...))QWindow::focusInEvent
+184 (int (*)(...))QWindow::focusOutEvent
+192 (int (*)(...))QWindow::showEvent
+200 (int (*)(...))QWindow::hideEvent
+208 (int (*)(...))QWindow::keyPressEvent
+216 (int (*)(...))QWindow::keyReleaseEvent
+224 (int (*)(...))QWindow::mousePressEvent
+232 (int (*)(...))QWindow::mouseReleaseEvent
+240 (int (*)(...))QWindow::mouseDoubleClickEvent
+248 (int (*)(...))QWindow::mouseMoveEvent
+256 (int (*)(...))QWindow::wheelEvent
+264 (int (*)(...))QWindow::touchEvent
+272 (int (*)(...))QWindow::tabletEvent
+280 (int (*)(...))QWindow::nativeEvent
+288 (int (*)(...))QWindow::surfaceHandle
+296 (int (*)(...))-16
+304 (int (*)(...))(& _ZTI7QWindow)
+312 (int (*)(...))QWindow::_ZThn16_N7QWindowD1Ev
+320 (int (*)(...))QWindow::_ZThn16_N7QWindowD0Ev
+328 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv
+336 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv
+344 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv
+352 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv
+
+Class QWindow
+ size=40 align=8
+ base size=40 base align=8
+QWindow (0x0x7f8848c338c0) 0
+ vptr=((& QWindow::_ZTV7QWindow) + 16u)
+ QObject (0x0x7f8848c22a80) 0
+ primary-for QWindow (0x0x7f8848c338c0)
+ QSurface (0x0x7f8848c22ae0) 16
+ vptr=((& QWindow::_ZTV7QWindow) + 312u)
+
+Class QBackingStore
+ size=8 align=8
+ base size=8 base align=8
+QBackingStore (0x0x7f8848c22c60) 0
+
+Vtable for QBitmap
+QBitmap::_ZTV7QBitmap: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QBitmap)
+16 (int (*)(...))QBitmap::~QBitmap
+24 (int (*)(...))QBitmap::~QBitmap
+32 (int (*)(...))QPixmap::devType
+40 (int (*)(...))QPixmap::paintEngine
+48 (int (*)(...))QPixmap::metric
+56 (int (*)(...))QPaintDevice::initPainter
+64 (int (*)(...))QPaintDevice::redirected
+72 (int (*)(...))QPaintDevice::sharedPainter
+
+Class QBitmap
+ size=32 align=8
+ base size=32 base align=8
+QBitmap (0x0x7f8848c29bc8) 0
+ vptr=((& QBitmap::_ZTV7QBitmap) + 16u)
+ QPixmap (0x0x7f8848c29c30) 0
+ primary-for QBitmap (0x0x7f8848c29bc8)
+ QPaintDevice (0x0x7f8848c22d20) 0
+ primary-for QPixmap (0x0x7f8848c29c30)
+
+Class QClipboard::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QClipboard::QPrivateSignal (0x0x7f8848cb20c0) 0 empty
+
+Vtable for QClipboard
+QClipboard::_ZTV10QClipboard: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QClipboard)
+16 (int (*)(...))QClipboard::metaObject
+24 (int (*)(...))QClipboard::qt_metacast
+32 (int (*)(...))QClipboard::qt_metacall
+40 (int (*)(...))QClipboard::~QClipboard
+48 (int (*)(...))QClipboard::~QClipboard
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QClipboard
+ size=16 align=8
+ base size=16 base align=8
+QClipboard (0x0x7f8848c29ea0) 0
+ vptr=((& QClipboard::_ZTV10QClipboard) + 16u)
+ QObject (0x0x7f8848cb2060) 0
+ primary-for QClipboard (0x0x7f8848c29ea0)
+
+Class QDesktopServices
+ size=1 align=1
+ base size=0 base align=1
+QDesktopServices (0x0x7f8848cb2120) 0 empty
+
+Class QDrag::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDrag::QPrivateSignal (0x0x7f8848cb21e0) 0 empty
+
+Vtable for QDrag
+QDrag::_ZTV5QDrag: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI5QDrag)
+16 (int (*)(...))QDrag::metaObject
+24 (int (*)(...))QDrag::qt_metacast
+32 (int (*)(...))QDrag::qt_metacall
+40 (int (*)(...))QDrag::~QDrag
+48 (int (*)(...))QDrag::~QDrag
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QDrag
+ size=16 align=8
+ base size=16 base align=8
+QDrag (0x0x7f8848c29f08) 0
+ vptr=((& QDrag::_ZTV5QDrag) + 16u)
+ QObject (0x0x7f8848cb2180) 0
+ primary-for QDrag (0x0x7f8848c29f08)
+
+Class QFontInfo
+ size=8 align=8
+ base size=8 base align=8
+QFontInfo (0x0x7f8848cb2240) 0
+
+Class QFontMetrics
+ size=8 align=8
+ base size=8 base align=8
+QFontMetrics (0x0x7f8848cb24e0) 0
+
+Class QFontMetricsF
+ size=8 align=8
+ base size=8 base align=8
+QFontMetricsF (0x0x7f8848cb27e0) 0
+
+Class QGenericPlugin::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGenericPlugin::QPrivateSignal (0x0x7f8848d8af60) 0 empty
+
+Vtable for QGenericPlugin
+QGenericPlugin::_ZTV14QGenericPlugin: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QGenericPlugin)
+16 (int (*)(...))QGenericPlugin::metaObject
+24 (int (*)(...))QGenericPlugin::qt_metacast
+32 (int (*)(...))QGenericPlugin::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+
+Class QGenericPlugin
+ size=16 align=8
+ base size=16 base align=8
+QGenericPlugin (0x0x7f8848ceca28) 0
+ vptr=((& QGenericPlugin::_ZTV14QGenericPlugin) + 16u)
+ QObject (0x0x7f8848d8af00) 0
+ primary-for QGenericPlugin (0x0x7f8848ceca28)
+
+Class QGenericPluginFactory
+ size=1 align=1
+ base size=0 base align=1
+QGenericPluginFactory (0x0x7f8848a7e000) 0 empty
+
+Class QInputMethod::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QInputMethod::QPrivateSignal (0x0x7f8848a7e0c0) 0 empty
+
+Vtable for QInputMethod
+QInputMethod::_ZTV12QInputMethod: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QInputMethod)
+16 (int (*)(...))QInputMethod::metaObject
+24 (int (*)(...))QInputMethod::qt_metacast
+32 (int (*)(...))QInputMethod::qt_metacall
+40 (int (*)(...))QInputMethod::~QInputMethod
+48 (int (*)(...))QInputMethod::~QInputMethod
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QInputMethod
+ size=16 align=8
+ base size=16 base align=8
+QInputMethod (0x0x7f8848ceca90) 0
+ vptr=((& QInputMethod::_ZTV12QInputMethod) + 16u)
+ QObject (0x0x7f8848a7e060) 0
+ primary-for QInputMethod (0x0x7f8848ceca90)
+
+Class QGuiApplication::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGuiApplication::QPrivateSignal (0x0x7f8848a7e180) 0 empty
+
+Vtable for QGuiApplication
+QGuiApplication::_ZTV15QGuiApplication: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QGuiApplication)
+16 (int (*)(...))QGuiApplication::metaObject
+24 (int (*)(...))QGuiApplication::qt_metacast
+32 (int (*)(...))QGuiApplication::qt_metacall
+40 (int (*)(...))QGuiApplication::~QGuiApplication
+48 (int (*)(...))QGuiApplication::~QGuiApplication
+56 (int (*)(...))QGuiApplication::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGuiApplication::notify
+120 (int (*)(...))QGuiApplication::compressEvent
+
+Class QGuiApplication
+ size=16 align=8
+ base size=16 base align=8
+QGuiApplication (0x0x7f8848cecaf8) 0
+ vptr=((& QGuiApplication::_ZTV15QGuiApplication) + 16u)
+ QCoreApplication (0x0x7f8848cecb60) 0
+ primary-for QGuiApplication (0x0x7f8848cecaf8)
+ QObject (0x0x7f8848a7e120) 0
+ primary-for QCoreApplication (0x0x7f8848cecb60)
+
+Class QIconEngine::AvailableSizesArgument
+ size=16 align=8
+ base size=16 base align=8
+QIconEngine::AvailableSizesArgument (0x0x7f8848a7e6c0) 0
+
+Class QIconEngine::ScaledPixmapArgument
+ size=56 align=8
+ base size=56 base align=8
+QIconEngine::ScaledPixmapArgument (0x0x7f8848a7e840) 0
+
+Vtable for QIconEngine
+QIconEngine::_ZTV11QIconEngine: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QIconEngine)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))QIconEngine::actualSize
+48 (int (*)(...))QIconEngine::pixmap
+56 (int (*)(...))QIconEngine::addPixmap
+64 (int (*)(...))QIconEngine::addFile
+72 (int (*)(...))QIconEngine::key
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))QIconEngine::read
+96 (int (*)(...))QIconEngine::write
+104 (int (*)(...))QIconEngine::availableSizes
+112 (int (*)(...))QIconEngine::iconName
+120 (int (*)(...))QIconEngine::virtual_hook
+
+Class QIconEngine
+ size=8 align=8
+ base size=8 base align=8
+QIconEngine (0x0x7f8848a7e660) 0 nearly-empty
+ vptr=((& QIconEngine::_ZTV11QIconEngine) + 16u)
+
+Class QIconEnginePlugin::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QIconEnginePlugin::QPrivateSignal (0x0x7f8848a7e900) 0 empty
+
+Vtable for QIconEnginePlugin
+QIconEnginePlugin::_ZTV17QIconEnginePlugin: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QIconEnginePlugin)
+16 (int (*)(...))QIconEnginePlugin::metaObject
+24 (int (*)(...))QIconEnginePlugin::qt_metacast
+32 (int (*)(...))QIconEnginePlugin::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+
+Class QIconEnginePlugin
+ size=16 align=8
+ base size=16 base align=8
+QIconEnginePlugin (0x0x7f8848ab6138) 0
+ vptr=((& QIconEnginePlugin::_ZTV17QIconEnginePlugin) + 16u)
+ QObject (0x0x7f8848a7e8a0) 0
+ primary-for QIconEnginePlugin (0x0x7f8848ab6138)
+
+Vtable for QImageIOHandler
+QImageIOHandler::_ZTV15QImageIOHandler: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QImageIOHandler)
+16 0u
+24 0u
+32 (int (*)(...))QImageIOHandler::name
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))QImageIOHandler::write
+64 (int (*)(...))QImageIOHandler::option
+72 (int (*)(...))QImageIOHandler::setOption
+80 (int (*)(...))QImageIOHandler::supportsOption
+88 (int (*)(...))QImageIOHandler::jumpToNextImage
+96 (int (*)(...))QImageIOHandler::jumpToImage
+104 (int (*)(...))QImageIOHandler::loopCount
+112 (int (*)(...))QImageIOHandler::imageCount
+120 (int (*)(...))QImageIOHandler::nextImageDelay
+128 (int (*)(...))QImageIOHandler::currentImageNumber
+136 (int (*)(...))QImageIOHandler::currentImageRect
+
+Class QImageIOHandler
+ size=16 align=8
+ base size=16 base align=8
+QImageIOHandler (0x0x7f8848a7e960) 0
+ vptr=((& QImageIOHandler::_ZTV15QImageIOHandler) + 16u)
+
+Class QImageIOPlugin::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QImageIOPlugin::QPrivateSignal (0x0x7f8848a7eae0) 0 empty
+
+Vtable for QImageIOPlugin
+QImageIOPlugin::_ZTV14QImageIOPlugin: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QImageIOPlugin)
+16 (int (*)(...))QImageIOPlugin::metaObject
+24 (int (*)(...))QImageIOPlugin::qt_metacast
+32 (int (*)(...))QImageIOPlugin::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+
+Class QImageIOPlugin
+ size=16 align=8
+ base size=16 base align=8
+QImageIOPlugin (0x0x7f8848ab61a0) 0
+ vptr=((& QImageIOPlugin::_ZTV14QImageIOPlugin) + 16u)
+ QObject (0x0x7f8848a7ea80) 0
+ primary-for QImageIOPlugin (0x0x7f8848ab61a0)
+
+Class QImageReader
+ size=8 align=8
+ base size=8 base align=8
+QImageReader (0x0x7f8848a7ecc0) 0
+
+Class QImageWriter
+ size=8 align=8
+ base size=8 base align=8
+QImageWriter (0x0x7f8848a7ed20) 0
+
+Class QVector3D
+ size=12 align=4
+ base size=12 base align=4
+QVector3D (0x0x7f8848a7ed80) 0
+
+Class QVector4D
+ size=16 align=4
+ base size=16 base align=4
+QVector4D (0x0x7f8848798060) 0
+
+Class QQuaternion
+ size=16 align=4
+ base size=16 base align=4
+QQuaternion (0x0x7f8848798300) 0
+
+Class QMatrix4x4
+ size=68 align=4
+ base size=68 base align=4
+QMatrix4x4 (0x0x7f8848798900) 0
+
+Class QMovie::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QMovie::QPrivateSignal (0x0x7f88488e30c0) 0 empty
+
+Vtable for QMovie
+QMovie::_ZTV6QMovie: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QMovie)
+16 (int (*)(...))QMovie::metaObject
+24 (int (*)(...))QMovie::qt_metacast
+32 (int (*)(...))QMovie::qt_metacall
+40 (int (*)(...))QMovie::~QMovie
+48 (int (*)(...))QMovie::~QMovie
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QMovie
+ size=16 align=8
+ base size=16 base align=8
+QMovie (0x0x7f88488e13a8) 0
+ vptr=((& QMovie::_ZTV6QMovie) + 16u)
+ QObject (0x0x7f88488e3060) 0
+ primary-for QMovie (0x0x7f88488e13a8)
+
+Class QOffscreenSurface::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOffscreenSurface::QPrivateSignal (0x0x7f88488e31e0) 0 empty
+
+Vtable for QOffscreenSurface
+QOffscreenSurface::_ZTV17QOffscreenSurface: 26u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QOffscreenSurface)
+16 (int (*)(...))QOffscreenSurface::metaObject
+24 (int (*)(...))QOffscreenSurface::qt_metacast
+32 (int (*)(...))QOffscreenSurface::qt_metacall
+40 (int (*)(...))QOffscreenSurface::~QOffscreenSurface
+48 (int (*)(...))QOffscreenSurface::~QOffscreenSurface
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QOffscreenSurface::surfaceType
+120 (int (*)(...))QOffscreenSurface::format
+128 (int (*)(...))QOffscreenSurface::size
+136 (int (*)(...))QOffscreenSurface::surfaceHandle
+144 (int (*)(...))-16
+152 (int (*)(...))(& _ZTI17QOffscreenSurface)
+160 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD1Ev
+168 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD0Ev
+176 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface6formatEv
+184 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface13surfaceHandleEv
+192 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface11surfaceTypeEv
+200 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface4sizeEv
+
+Class QOffscreenSurface
+ size=40 align=8
+ base size=40 base align=8
+QOffscreenSurface (0x0x7f88485d75b0) 0
+ vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 16u)
+ QObject (0x0x7f88488e3120) 0
+ primary-for QOffscreenSurface (0x0x7f88485d75b0)
+ QSurface (0x0x7f88488e3180) 16
+ vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 160u)
+
+Class QOpenGLBuffer
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLBuffer (0x0x7f88488e32a0) 0
+
+Class QOpenGLVersionStatus
+ size=12 align=4
+ base size=12 base align=4
+QOpenGLVersionStatus (0x0x7f88488e3480) 0
+
+Class QOpenGLVersionFunctionsBackend
+ size=16 align=8
+ base size=12 base align=8
+QOpenGLVersionFunctionsBackend (0x0x7f884833ff60) 0
+
+Class QOpenGLVersionFunctionsStorage
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLVersionFunctionsStorage (0x0x7f884837f000) 0
+
+Class QAbstractOpenGLFunctionsPrivate
+ size=16 align=8
+ base size=9 base align=8
+QAbstractOpenGLFunctionsPrivate (0x0x7f884837f060) 0
+
+Vtable for QAbstractOpenGLFunctions
+QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QAbstractOpenGLFunctions)
+16 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions
+24 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions
+32 (int (*)(...))QAbstractOpenGLFunctions::initializeOpenGLFunctions
+
+Class QAbstractOpenGLFunctions
+ size=16 align=8
+ base size=16 base align=8
+QAbstractOpenGLFunctions (0x0x7f884837f0c0) 0
+ vptr=((& QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions) + 16u)
+
+Class QOpenGLFunctions_1_0_CoreBackend::Functions
+ size=384 align=8
+ base size=384 base align=8
+QOpenGLFunctions_1_0_CoreBackend::Functions (0x0x7f884837f180) 0
+
+Class QOpenGLFunctions_1_0_CoreBackend
+ size=400 align=8
+ base size=400 base align=8
+QOpenGLFunctions_1_0_CoreBackend (0x0x7f8848366618) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884837f120) 0
+
+Class QOpenGLFunctions_1_1_CoreBackend::Functions
+ size=128 align=8
+ base size=128 base align=8
+QOpenGLFunctions_1_1_CoreBackend::Functions (0x0x7f884837f2a0) 0
+
+Class QOpenGLFunctions_1_1_CoreBackend
+ size=144 align=8
+ base size=144 base align=8
+QOpenGLFunctions_1_1_CoreBackend (0x0x7f8848366680) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884837f240) 0
+
+Class QOpenGLFunctions_1_2_CoreBackend::Functions
+ size=48 align=8
+ base size=48 base align=8
+QOpenGLFunctions_1_2_CoreBackend::Functions (0x0x7f884837f3c0) 0
+
+Class QOpenGLFunctions_1_2_CoreBackend
+ size=64 align=8
+ base size=64 base align=8
+QOpenGLFunctions_1_2_CoreBackend (0x0x7f88483666e8) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884837f360) 0
+
+Class QOpenGLFunctions_1_3_CoreBackend::Functions
+ size=72 align=8
+ base size=72 base align=8
+QOpenGLFunctions_1_3_CoreBackend::Functions (0x0x7f884837f4e0) 0
+
+Class QOpenGLFunctions_1_3_CoreBackend
+ size=88 align=8
+ base size=88 base align=8
+QOpenGLFunctions_1_3_CoreBackend (0x0x7f8848366750) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884837f480) 0
+
+Class QOpenGLFunctions_1_4_CoreBackend::Functions
+ size=56 align=8
+ base size=56 base align=8
+QOpenGLFunctions_1_4_CoreBackend::Functions (0x0x7f884837f660) 0
+
+Class QOpenGLFunctions_1_4_CoreBackend
+ size=72 align=8
+ base size=72 base align=8
+QOpenGLFunctions_1_4_CoreBackend (0x0x7f88483667b8) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884837f600) 0
+
+Class QOpenGLFunctions_1_5_CoreBackend::Functions
+ size=152 align=8
+ base size=152 base align=8
+QOpenGLFunctions_1_5_CoreBackend::Functions (0x0x7f884837f780) 0
+
+Class QOpenGLFunctions_1_5_CoreBackend
+ size=168 align=8
+ base size=168 base align=8
+QOpenGLFunctions_1_5_CoreBackend (0x0x7f8848366820) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884837f720) 0
+
+Class QOpenGLFunctions_2_0_CoreBackend::Functions
+ size=744 align=8
+ base size=744 base align=8
+QOpenGLFunctions_2_0_CoreBackend::Functions (0x0x7f884837f8a0) 0
+
+Class QOpenGLFunctions_2_0_CoreBackend
+ size=760 align=8
+ base size=760 base align=8
+QOpenGLFunctions_2_0_CoreBackend (0x0x7f8848366888) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884837f840) 0
+
+Class QOpenGLFunctions_2_1_CoreBackend::Functions
+ size=48 align=8
+ base size=48 base align=8
+QOpenGLFunctions_2_1_CoreBackend::Functions (0x0x7f884837f9c0) 0
+
+Class QOpenGLFunctions_2_1_CoreBackend
+ size=64 align=8
+ base size=64 base align=8
+QOpenGLFunctions_2_1_CoreBackend (0x0x7f88483668f0) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884837f960) 0
+
+Class QOpenGLFunctions_3_0_CoreBackend::Functions
+ size=672 align=8
+ base size=672 base align=8
+QOpenGLFunctions_3_0_CoreBackend::Functions (0x0x7f884837fae0) 0
+
+Class QOpenGLFunctions_3_0_CoreBackend
+ size=688 align=8
+ base size=688 base align=8
+QOpenGLFunctions_3_0_CoreBackend (0x0x7f8848366958) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884837fa80) 0
+
+Class QOpenGLFunctions_3_1_CoreBackend::Functions
+ size=96 align=8
+ base size=96 base align=8
+QOpenGLFunctions_3_1_CoreBackend::Functions (0x0x7f884837fc00) 0
+
+Class QOpenGLFunctions_3_1_CoreBackend
+ size=112 align=8
+ base size=112 base align=8
+QOpenGLFunctions_3_1_CoreBackend (0x0x7f88483669c0) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884837fba0) 0
+
+Class QOpenGLFunctions_3_2_CoreBackend::Functions
+ size=152 align=8
+ base size=152 base align=8
+QOpenGLFunctions_3_2_CoreBackend::Functions (0x0x7f884837fd20) 0
+
+Class QOpenGLFunctions_3_2_CoreBackend
+ size=168 align=8
+ base size=168 base align=8
+QOpenGLFunctions_3_2_CoreBackend (0x0x7f8848366a28) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884837fcc0) 0
+
+Class QOpenGLFunctions_3_3_CoreBackend::Functions
+ size=464 align=8
+ base size=464 base align=8
+QOpenGLFunctions_3_3_CoreBackend::Functions (0x0x7f884837fe40) 0
+
+Class QOpenGLFunctions_3_3_CoreBackend
+ size=480 align=8
+ base size=480 base align=8
+QOpenGLFunctions_3_3_CoreBackend (0x0x7f8848366a90) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884837fde0) 0
+
+Class QOpenGLFunctions_4_0_CoreBackend::Functions
+ size=368 align=8
+ base size=368 base align=8
+QOpenGLFunctions_4_0_CoreBackend::Functions (0x0x7f884837ff60) 0
+
+Class QOpenGLFunctions_4_0_CoreBackend
+ size=384 align=8
+ base size=384 base align=8
+QOpenGLFunctions_4_0_CoreBackend (0x0x7f8848366af8) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884837ff00) 0
+
+Class QOpenGLFunctions_4_1_CoreBackend::Functions
+ size=704 align=8
+ base size=704 base align=8
+QOpenGLFunctions_4_1_CoreBackend::Functions (0x0x7f884805a0c0) 0
+
+Class QOpenGLFunctions_4_1_CoreBackend
+ size=720 align=8
+ base size=720 base align=8
+QOpenGLFunctions_4_1_CoreBackend (0x0x7f8848366b60) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884805a060) 0
+
+Class QOpenGLFunctions_4_2_CoreBackend::Functions
+ size=96 align=8
+ base size=96 base align=8
+QOpenGLFunctions_4_2_CoreBackend::Functions (0x0x7f884805a1e0) 0
+
+Class QOpenGLFunctions_4_2_CoreBackend
+ size=112 align=8
+ base size=112 base align=8
+QOpenGLFunctions_4_2_CoreBackend (0x0x7f8848366bc8) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884805a180) 0
+
+Class QOpenGLFunctions_4_3_CoreBackend::Functions
+ size=344 align=8
+ base size=344 base align=8
+QOpenGLFunctions_4_3_CoreBackend::Functions (0x0x7f884805a300) 0
+
+Class QOpenGLFunctions_4_3_CoreBackend
+ size=360 align=8
+ base size=360 base align=8
+QOpenGLFunctions_4_3_CoreBackend (0x0x7f8848366c30) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884805a2a0) 0
+
+Class QOpenGLFunctions_4_4_CoreBackend::Functions
+ size=72 align=8
+ base size=72 base align=8
+QOpenGLFunctions_4_4_CoreBackend::Functions (0x0x7f884805a420) 0
+
+Class QOpenGLFunctions_4_4_CoreBackend
+ size=88 align=8
+ base size=88 base align=8
+QOpenGLFunctions_4_4_CoreBackend (0x0x7f8848366c98) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884805a3c0) 0
+
+Class QOpenGLFunctions_4_5_CoreBackend::Functions
+ size=848 align=8
+ base size=848 base align=8
+QOpenGLFunctions_4_5_CoreBackend::Functions (0x0x7f884805a5a0) 0
+
+Class QOpenGLFunctions_4_5_CoreBackend
+ size=864 align=8
+ base size=864 base align=8
+QOpenGLFunctions_4_5_CoreBackend (0x0x7f8848366d00) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884805a540) 0
+
+Class QOpenGLFunctions_1_0_DeprecatedBackend::Functions
+ size=2064 align=8
+ base size=2064 base align=8
+QOpenGLFunctions_1_0_DeprecatedBackend::Functions (0x0x7f884805a6c0) 0
+
+Class QOpenGLFunctions_1_0_DeprecatedBackend
+ size=2080 align=8
+ base size=2080 base align=8
+QOpenGLFunctions_1_0_DeprecatedBackend (0x0x7f8848366d68) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884805a660) 0
+
+Class QOpenGLFunctions_1_1_DeprecatedBackend::Functions
+ size=136 align=8
+ base size=136 base align=8
+QOpenGLFunctions_1_1_DeprecatedBackend::Functions (0x0x7f884805a7e0) 0
+
+Class QOpenGLFunctions_1_1_DeprecatedBackend
+ size=152 align=8
+ base size=152 base align=8
+QOpenGLFunctions_1_1_DeprecatedBackend (0x0x7f8848366dd0) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884805a780) 0
+
+Class QOpenGLFunctions_1_2_DeprecatedBackend::Functions
+ size=256 align=8
+ base size=256 base align=8
+QOpenGLFunctions_1_2_DeprecatedBackend::Functions (0x0x7f884805a900) 0
+
+Class QOpenGLFunctions_1_2_DeprecatedBackend
+ size=272 align=8
+ base size=272 base align=8
+QOpenGLFunctions_1_2_DeprecatedBackend (0x0x7f8848366e38) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884805a8a0) 0
+
+Class QOpenGLFunctions_1_3_DeprecatedBackend::Functions
+ size=296 align=8
+ base size=296 base align=8
+QOpenGLFunctions_1_3_DeprecatedBackend::Functions (0x0x7f884805aa20) 0
+
+Class QOpenGLFunctions_1_3_DeprecatedBackend
+ size=312 align=8
+ base size=312 base align=8
+QOpenGLFunctions_1_3_DeprecatedBackend (0x0x7f8848366ea0) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884805a9c0) 0
+
+Class QOpenGLFunctions_1_4_DeprecatedBackend::Functions
+ size=304 align=8
+ base size=304 base align=8
+QOpenGLFunctions_1_4_DeprecatedBackend::Functions (0x0x7f884805ab40) 0
+
+Class QOpenGLFunctions_1_4_DeprecatedBackend
+ size=320 align=8
+ base size=320 base align=8
+QOpenGLFunctions_1_4_DeprecatedBackend (0x0x7f8848366f08) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884805aae0) 0
+
+Class QOpenGLFunctions_2_0_DeprecatedBackend::Functions
+ size=288 align=8
+ base size=288 base align=8
+QOpenGLFunctions_2_0_DeprecatedBackend::Functions (0x0x7f884805ac60) 0
+
+Class QOpenGLFunctions_2_0_DeprecatedBackend
+ size=304 align=8
+ base size=304 base align=8
+QOpenGLFunctions_2_0_DeprecatedBackend (0x0x7f8848366f70) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884805ac00) 0
+
+Class QOpenGLFunctions_3_0_DeprecatedBackend::Functions
+ size=160 align=8
+ base size=160 base align=8
+QOpenGLFunctions_3_0_DeprecatedBackend::Functions (0x0x7f884805ad80) 0
+
+Class QOpenGLFunctions_3_0_DeprecatedBackend
+ size=176 align=8
+ base size=176 base align=8
+QOpenGLFunctions_3_0_DeprecatedBackend (0x0x7f884817e000) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884805ad20) 0
+
+Class QOpenGLFunctions_3_3_DeprecatedBackend::Functions
+ size=240 align=8
+ base size=240 base align=8
+QOpenGLFunctions_3_3_DeprecatedBackend::Functions (0x0x7f884805aea0) 0
+
+Class QOpenGLFunctions_3_3_DeprecatedBackend
+ size=256 align=8
+ base size=256 base align=8
+QOpenGLFunctions_3_3_DeprecatedBackend (0x0x7f884817e068) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884805ae40) 0
+
+Class QOpenGLFunctions_4_5_DeprecatedBackend::Functions
+ size=96 align=8
+ base size=96 base align=8
+QOpenGLFunctions_4_5_DeprecatedBackend::Functions (0x0x7f8847d98000) 0
+
+Class QOpenGLFunctions_4_5_DeprecatedBackend
+ size=112 align=8
+ base size=112 base align=8
+QOpenGLFunctions_4_5_DeprecatedBackend (0x0x7f884817e0d0) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f884805af60) 0
+
+Class QOpenGLVersionProfile
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLVersionProfile (0x0x7f8847d980c0) 0
+
+Class QOpenGLContextGroup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLContextGroup::QPrivateSignal (0x0x7f8847d98a80) 0 empty
+
+Vtable for QOpenGLContextGroup
+QOpenGLContextGroup::_ZTV19QOpenGLContextGroup: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QOpenGLContextGroup)
+16 (int (*)(...))QOpenGLContextGroup::metaObject
+24 (int (*)(...))QOpenGLContextGroup::qt_metacast
+32 (int (*)(...))QOpenGLContextGroup::qt_metacall
+40 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup
+48 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QOpenGLContextGroup
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLContextGroup (0x0x7f884817eaf8) 0
+ vptr=((& QOpenGLContextGroup::_ZTV19QOpenGLContextGroup) + 16u)
+ QObject (0x0x7f8847d98a20) 0
+ primary-for QOpenGLContextGroup (0x0x7f884817eaf8)
+
+Class QOpenGLContext::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLContext::QPrivateSignal (0x0x7f8847d98b40) 0 empty
+
+Vtable for QOpenGLContext
+QOpenGLContext::_ZTV14QOpenGLContext: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QOpenGLContext)
+16 (int (*)(...))QOpenGLContext::metaObject
+24 (int (*)(...))QOpenGLContext::qt_metacast
+32 (int (*)(...))QOpenGLContext::qt_metacall
+40 (int (*)(...))QOpenGLContext::~QOpenGLContext
+48 (int (*)(...))QOpenGLContext::~QOpenGLContext
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QOpenGLContext
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLContext (0x0x7f884817eb60) 0
+ vptr=((& QOpenGLContext::_ZTV14QOpenGLContext) + 16u)
+ QObject (0x0x7f8847d98ae0) 0
+ primary-for QOpenGLContext (0x0x7f884817eb60)
+
+Class QOpenGLDebugMessage
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLDebugMessage (0x0x7f8847d98ba0) 0
+
+Class QOpenGLDebugLogger::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLDebugLogger::QPrivateSignal (0x0x7f8847e1b3c0) 0 empty
+
+Vtable for QOpenGLDebugLogger
+QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QOpenGLDebugLogger)
+16 (int (*)(...))QOpenGLDebugLogger::metaObject
+24 (int (*)(...))QOpenGLDebugLogger::qt_metacast
+32 (int (*)(...))QOpenGLDebugLogger::qt_metacall
+40 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger
+48 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QOpenGLDebugLogger
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLDebugLogger (0x0x7f8847e9d000) 0
+ vptr=((& QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger) + 16u)
+ QObject (0x0x7f8847e1b360) 0
+ primary-for QOpenGLDebugLogger (0x0x7f8847e9d000)
+
+Class QOpenGLFunctions
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLFunctions (0x0x7f8847e1b540) 0
+
+Class QOpenGLFunctionsPrivate::Functions
+ size=1152 align=8
+ base size=1152 base align=8
+QOpenGLFunctionsPrivate::Functions (0x0x7f8847e1b780) 0
+
+Class QOpenGLFunctionsPrivate
+ size=1152 align=8
+ base size=1152 base align=8
+QOpenGLFunctionsPrivate (0x0x7f8847e1b720) 0
+
+Class QOpenGLExtraFunctions
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLExtraFunctions (0x0x7f8847e9d270) 0
+ QOpenGLFunctions (0x0x7f8847c16ea0) 0
+
+Class QOpenGLExtraFunctionsPrivate::Functions
+ size=1728 align=8
+ base size=1728 base align=8
+QOpenGLExtraFunctionsPrivate::Functions (0x0x7f8847c16f60) 0
+
+Class QOpenGLExtraFunctionsPrivate
+ size=2880 align=8
+ base size=2880 base align=8
+QOpenGLExtraFunctionsPrivate (0x0x7f8847e9d2d8) 0
+ QOpenGLFunctionsPrivate (0x0x7f8847c16f00) 0
+
+Vtable for QOpenGLFramebufferObject
+QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QOpenGLFramebufferObject)
+16 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject
+24 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject
+
+Class QOpenGLFramebufferObject
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLFramebufferObject (0x0x7f8847a76660) 0
+ vptr=((& QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject) + 16u)
+
+Class QOpenGLFramebufferObjectFormat
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLFramebufferObjectFormat (0x0x7f8847a76780) 0
+
+Vtable for QOpenGLPaintDevice
+QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QOpenGLPaintDevice)
+16 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice
+24 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice
+32 (int (*)(...))QOpenGLPaintDevice::devType
+40 (int (*)(...))QOpenGLPaintDevice::paintEngine
+48 (int (*)(...))QOpenGLPaintDevice::metric
+56 (int (*)(...))QPaintDevice::initPainter
+64 (int (*)(...))QPaintDevice::redirected
+72 (int (*)(...))QPaintDevice::sharedPainter
+80 (int (*)(...))QOpenGLPaintDevice::ensureActiveTarget
+
+Class QOpenGLPaintDevice
+ size=32 align=8
+ base size=32 base align=8
+QOpenGLPaintDevice (0x0x7f8847e9d5b0) 0
+ vptr=((& QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice) + 16u)
+ QPaintDevice (0x0x7f8847a767e0) 0
+ primary-for QOpenGLPaintDevice (0x0x7f8847e9d5b0)
+
+Class QOpenGLPixelTransferOptions
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLPixelTransferOptions (0x0x7f8847a76900) 0
+
+Class QOpenGLShader::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLShader::QPrivateSignal (0x0x7f8847a76c60) 0 empty
+
+Vtable for QOpenGLShader
+QOpenGLShader::_ZTV13QOpenGLShader: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QOpenGLShader)
+16 (int (*)(...))QOpenGLShader::metaObject
+24 (int (*)(...))QOpenGLShader::qt_metacast
+32 (int (*)(...))QOpenGLShader::qt_metacall
+40 (int (*)(...))QOpenGLShader::~QOpenGLShader
+48 (int (*)(...))QOpenGLShader::~QOpenGLShader
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QOpenGLShader
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLShader (0x0x7f8847e9d7b8) 0
+ vptr=((& QOpenGLShader::_ZTV13QOpenGLShader) + 16u)
+ QObject (0x0x7f8847a76c00) 0
+ primary-for QOpenGLShader (0x0x7f8847e9d7b8)
+
+Class QOpenGLShaderProgram::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLShaderProgram::QPrivateSignal (0x0x7f8847a76ea0) 0 empty
+
+Vtable for QOpenGLShaderProgram
+QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QOpenGLShaderProgram)
+16 (int (*)(...))QOpenGLShaderProgram::metaObject
+24 (int (*)(...))QOpenGLShaderProgram::qt_metacast
+32 (int (*)(...))QOpenGLShaderProgram::qt_metacall
+40 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram
+48 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QOpenGLShaderProgram::link
+
+Class QOpenGLShaderProgram
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLShaderProgram (0x0x7f8847e9d8f0) 0
+ vptr=((& QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram) + 16u)
+ QObject (0x0x7f8847a76e40) 0
+ primary-for QOpenGLShaderProgram (0x0x7f8847e9d8f0)
+
+Class QOpenGLTexture
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLTexture (0x0x7f8847a76f00) 0
+
+Class QOpenGLTextureBlitter
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLTextureBlitter (0x0x7f88477ee1e0) 0
+
+Class QOpenGLTimerQuery::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLTimerQuery::QPrivateSignal (0x0x7f88477ee360) 0 empty
+
+Vtable for QOpenGLTimerQuery
+QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QOpenGLTimerQuery)
+16 (int (*)(...))QOpenGLTimerQuery::metaObject
+24 (int (*)(...))QOpenGLTimerQuery::qt_metacast
+32 (int (*)(...))QOpenGLTimerQuery::qt_metacall
+40 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery
+48 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QOpenGLTimerQuery
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLTimerQuery (0x0x7f8847e9da28) 0
+ vptr=((& QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery) + 16u)
+ QObject (0x0x7f88477ee300) 0
+ primary-for QOpenGLTimerQuery (0x0x7f8847e9da28)
+
+Class QOpenGLTimeMonitor::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLTimeMonitor::QPrivateSignal (0x0x7f88477ee420) 0 empty
+
+Vtable for QOpenGLTimeMonitor
+QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QOpenGLTimeMonitor)
+16 (int (*)(...))QOpenGLTimeMonitor::metaObject
+24 (int (*)(...))QOpenGLTimeMonitor::qt_metacast
+32 (int (*)(...))QOpenGLTimeMonitor::qt_metacall
+40 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor
+48 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QOpenGLTimeMonitor
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLTimeMonitor (0x0x7f8847e9da90) 0
+ vptr=((& QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor) + 16u)
+ QObject (0x0x7f88477ee3c0) 0
+ primary-for QOpenGLTimeMonitor (0x0x7f8847e9da90)
+
+Class QOpenGLVertexArrayObject::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLVertexArrayObject::QPrivateSignal (0x0x7f88477ee4e0) 0 empty
+
+Class QOpenGLVertexArrayObject::Binder
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLVertexArrayObject::Binder (0x0x7f88477ee540) 0
+
+Vtable for QOpenGLVertexArrayObject
+QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QOpenGLVertexArrayObject)
+16 (int (*)(...))QOpenGLVertexArrayObject::metaObject
+24 (int (*)(...))QOpenGLVertexArrayObject::qt_metacast
+32 (int (*)(...))QOpenGLVertexArrayObject::qt_metacall
+40 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject
+48 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QOpenGLVertexArrayObject
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLVertexArrayObject (0x0x7f8847e9daf8) 0
+ vptr=((& QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject) + 16u)
+ QObject (0x0x7f88477ee480) 0
+ primary-for QOpenGLVertexArrayObject (0x0x7f8847e9daf8)
+
+Class QPaintDeviceWindow::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPaintDeviceWindow::QPrivateSignal (0x0x7f88477ee6c0) 0 empty
+
+Vtable for QPaintDeviceWindow
+QPaintDeviceWindow::_ZTV18QPaintDeviceWindow: 58u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QPaintDeviceWindow)
+16 (int (*)(...))QPaintDeviceWindow::metaObject
+24 (int (*)(...))QPaintDeviceWindow::qt_metacast
+32 (int (*)(...))QPaintDeviceWindow::qt_metacall
+40 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow
+48 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow
+56 (int (*)(...))QPaintDeviceWindow::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWindow::surfaceType
+120 (int (*)(...))QWindow::format
+128 (int (*)(...))QWindow::size
+136 (int (*)(...))QWindow::accessibleRoot
+144 (int (*)(...))QWindow::focusObject
+152 (int (*)(...))QPaintDeviceWindow::exposeEvent
+160 (int (*)(...))QWindow::resizeEvent
+168 (int (*)(...))QWindow::moveEvent
+176 (int (*)(...))QWindow::focusInEvent
+184 (int (*)(...))QWindow::focusOutEvent
+192 (int (*)(...))QWindow::showEvent
+200 (int (*)(...))QWindow::hideEvent
+208 (int (*)(...))QWindow::keyPressEvent
+216 (int (*)(...))QWindow::keyReleaseEvent
+224 (int (*)(...))QWindow::mousePressEvent
+232 (int (*)(...))QWindow::mouseReleaseEvent
+240 (int (*)(...))QWindow::mouseDoubleClickEvent
+248 (int (*)(...))QWindow::mouseMoveEvent
+256 (int (*)(...))QWindow::wheelEvent
+264 (int (*)(...))QWindow::touchEvent
+272 (int (*)(...))QWindow::tabletEvent
+280 (int (*)(...))QWindow::nativeEvent
+288 (int (*)(...))QWindow::surfaceHandle
+296 (int (*)(...))QPaintDeviceWindow::paintEvent
+304 (int (*)(...))QPaintDeviceWindow::metric
+312 (int (*)(...))QPaintDeviceWindow::paintEngine
+320 (int (*)(...))-16
+328 (int (*)(...))(& _ZTI18QPaintDeviceWindow)
+336 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD1Ev
+344 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD0Ev
+352 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv
+360 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv
+368 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv
+376 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv
+384 (int (*)(...))-40
+392 (int (*)(...))(& _ZTI18QPaintDeviceWindow)
+400 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD1Ev
+408 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD0Ev
+416 (int (*)(...))QPaintDevice::devType
+424 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv
+432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow6metricEN12QPaintDevice17PaintDeviceMetricE
+440 (int (*)(...))QPaintDevice::initPainter
+448 (int (*)(...))QPaintDevice::redirected
+456 (int (*)(...))QPaintDevice::sharedPainter
+
+Class QPaintDeviceWindow
+ size=64 align=8
+ base size=64 base align=8
+QPaintDeviceWindow (0x0x7f8847866000) 0
+ vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 16u)
+ QWindow (0x0x7f8847866070) 0
+ primary-for QPaintDeviceWindow (0x0x7f8847866000)
+ QObject (0x0x7f88477ee5a0) 0
+ primary-for QWindow (0x0x7f8847866070)
+ QSurface (0x0x7f88477ee600) 16
+ vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 336u)
+ QPaintDevice (0x0x7f88477ee660) 40
+ vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 400u)
+
+Class QOpenGLWindow::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLWindow::QPrivateSignal (0x0x7f88477ee840) 0 empty
+
+Vtable for QOpenGLWindow
+QOpenGLWindow::_ZTV13QOpenGLWindow: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QOpenGLWindow)
+16 (int (*)(...))QOpenGLWindow::metaObject
+24 (int (*)(...))QOpenGLWindow::qt_metacast
+32 (int (*)(...))QOpenGLWindow::qt_metacall
+40 (int (*)(...))QOpenGLWindow::~QOpenGLWindow
+48 (int (*)(...))QOpenGLWindow::~QOpenGLWindow
+56 (int (*)(...))QPaintDeviceWindow::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWindow::surfaceType
+120 (int (*)(...))QWindow::format
+128 (int (*)(...))QWindow::size
+136 (int (*)(...))QWindow::accessibleRoot
+144 (int (*)(...))QWindow::focusObject
+152 (int (*)(...))QPaintDeviceWindow::exposeEvent
+160 (int (*)(...))QOpenGLWindow::resizeEvent
+168 (int (*)(...))QWindow::moveEvent
+176 (int (*)(...))QWindow::focusInEvent
+184 (int (*)(...))QWindow::focusOutEvent
+192 (int (*)(...))QWindow::showEvent
+200 (int (*)(...))QWindow::hideEvent
+208 (int (*)(...))QWindow::keyPressEvent
+216 (int (*)(...))QWindow::keyReleaseEvent
+224 (int (*)(...))QWindow::mousePressEvent
+232 (int (*)(...))QWindow::mouseReleaseEvent
+240 (int (*)(...))QWindow::mouseDoubleClickEvent
+248 (int (*)(...))QWindow::mouseMoveEvent
+256 (int (*)(...))QWindow::wheelEvent
+264 (int (*)(...))QWindow::touchEvent
+272 (int (*)(...))QWindow::tabletEvent
+280 (int (*)(...))QWindow::nativeEvent
+288 (int (*)(...))QWindow::surfaceHandle
+296 (int (*)(...))QOpenGLWindow::paintEvent
+304 (int (*)(...))QOpenGLWindow::metric
+312 (int (*)(...))QPaintDeviceWindow::paintEngine
+320 (int (*)(...))QOpenGLWindow::initializeGL
+328 (int (*)(...))QOpenGLWindow::resizeGL
+336 (int (*)(...))QOpenGLWindow::paintGL
+344 (int (*)(...))QOpenGLWindow::paintUnderGL
+352 (int (*)(...))QOpenGLWindow::paintOverGL
+360 (int (*)(...))QOpenGLWindow::redirected
+368 (int (*)(...))-16
+376 (int (*)(...))(& _ZTI13QOpenGLWindow)
+384 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD1Ev
+392 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD0Ev
+400 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv
+408 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv
+416 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv
+424 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv
+432 (int (*)(...))-40
+440 (int (*)(...))(& _ZTI13QOpenGLWindow)
+448 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD1Ev
+456 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD0Ev
+464 (int (*)(...))QPaintDevice::devType
+472 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv
+480 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QPaintDevice::initPainter
+496 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow10redirectedEP6QPoint
+504 (int (*)(...))QPaintDevice::sharedPainter
+
+Class QOpenGLWindow
+ size=64 align=8
+ base size=64 base align=8
+QOpenGLWindow (0x0x7f8847e9dbc8) 0
+ vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 16u)
+ QPaintDeviceWindow (0x0x7f88478665b0) 0
+ primary-for QOpenGLWindow (0x0x7f8847e9dbc8)
+ QWindow (0x0x7f8847866620) 0
+ primary-for QPaintDeviceWindow (0x0x7f88478665b0)
+ QObject (0x0x7f88477ee720) 0
+ primary-for QWindow (0x0x7f8847866620)
+ QSurface (0x0x7f88477ee780) 16
+ vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 384u)
+ QPaintDevice (0x0x7f88477ee7e0) 40
+ vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 448u)
+
+Class QPageSize
+ size=8 align=8
+ base size=8 base align=8
+QPageSize (0x0x7f88477ee8a0) 0
+
+Class QPageLayout
+ size=8 align=8
+ base size=8 base align=8
+QPageLayout (0x0x7f88478cf2a0) 0
+
+Class QPagedPaintDevice::Margins
+ size=32 align=8
+ base size=32 base align=8
+QPagedPaintDevice::Margins (0x0x7f88478cfcc0) 0
+
+Vtable for QPagedPaintDevice
+QPagedPaintDevice::_ZTV17QPagedPaintDevice: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QPagedPaintDevice)
+16 0u
+24 0u
+32 (int (*)(...))QPaintDevice::devType
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))QPaintDevice::metric
+56 (int (*)(...))QPaintDevice::initPainter
+64 (int (*)(...))QPaintDevice::redirected
+72 (int (*)(...))QPaintDevice::sharedPainter
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))QPagedPaintDevice::setPageSize
+96 (int (*)(...))QPagedPaintDevice::setPageSizeMM
+104 (int (*)(...))QPagedPaintDevice::setMargins
+
+Class QPagedPaintDevice
+ size=32 align=8
+ base size=32 base align=8
+QPagedPaintDevice (0x0x7f88478c48f0) 0
+ vptr=((& QPagedPaintDevice::_ZTV17QPagedPaintDevice) + 16u)
+ QPaintDevice (0x0x7f88478cfc60) 0
+ primary-for QPagedPaintDevice (0x0x7f88478c48f0)
+
+Class QPainter::PixmapFragment
+ size=80 align=8
+ base size=80 base align=8
+QPainter::PixmapFragment (0x0x7f88478cfd80) 0
+
+Class QPainter
+ size=8 align=8
+ base size=8 base align=8
+QPainter (0x0x7f88478cfd20) 0
+
+Class QTextItem
+ size=1 align=1
+ base size=0 base align=1
+QTextItem (0x0x7f8847595ba0) 0 empty
+
+Vtable for QPaintEngine
+QPaintEngine::_ZTV12QPaintEngine: 24u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QPaintEngine)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))QPaintEngine::drawRects
+64 (int (*)(...))QPaintEngine::drawRects
+72 (int (*)(...))QPaintEngine::drawLines
+80 (int (*)(...))QPaintEngine::drawLines
+88 (int (*)(...))QPaintEngine::drawEllipse
+96 (int (*)(...))QPaintEngine::drawEllipse
+104 (int (*)(...))QPaintEngine::drawPath
+112 (int (*)(...))QPaintEngine::drawPoints
+120 (int (*)(...))QPaintEngine::drawPoints
+128 (int (*)(...))QPaintEngine::drawPolygon
+136 (int (*)(...))QPaintEngine::drawPolygon
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))QPaintEngine::drawTextItem
+160 (int (*)(...))QPaintEngine::drawTiledPixmap
+168 (int (*)(...))QPaintEngine::drawImage
+176 (int (*)(...))QPaintEngine::coordinateOffset
+184 (int (*)(...))__cxa_pure_virtual
+
+Class QPaintEngine
+ size=32 align=8
+ base size=32 base align=8
+QPaintEngine (0x0x7f8847595e40) 0
+ vptr=((& QPaintEngine::_ZTV12QPaintEngine) + 16u)
+
+Class QPaintEngineState
+ size=4 align=4
+ base size=4 base align=4
+QPaintEngineState (0x0x7f884772f120) 0
+
+Class QPdfWriter::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPdfWriter::QPrivateSignal (0x0x7f884772f540) 0 empty
+
+Vtable for QPdfWriter
+QPdfWriter::_ZTV10QPdfWriter: 34u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QPdfWriter)
+16 (int (*)(...))QPdfWriter::metaObject
+24 (int (*)(...))QPdfWriter::qt_metacast
+32 (int (*)(...))QPdfWriter::qt_metacall
+40 (int (*)(...))QPdfWriter::~QPdfWriter
+48 (int (*)(...))QPdfWriter::~QPdfWriter
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QPdfWriter::newPage
+120 (int (*)(...))QPdfWriter::setPageSize
+128 (int (*)(...))QPdfWriter::setPageSizeMM
+136 (int (*)(...))QPdfWriter::setMargins
+144 (int (*)(...))QPdfWriter::paintEngine
+152 (int (*)(...))QPdfWriter::metric
+160 (int (*)(...))-16
+168 (int (*)(...))(& _ZTI10QPdfWriter)
+176 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD1Ev
+184 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD0Ev
+192 (int (*)(...))QPaintDevice::devType
+200 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter11paintEngineEv
+208 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter6metricEN12QPaintDevice17PaintDeviceMetricE
+216 (int (*)(...))QPaintDevice::initPainter
+224 (int (*)(...))QPaintDevice::redirected
+232 (int (*)(...))QPaintDevice::sharedPainter
+240 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter7newPageEv
+248 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter11setPageSizeEN17QPagedPaintDevice8PageSizeE
+256 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter13setPageSizeMMERK6QSizeF
+264 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter10setMarginsERKN17QPagedPaintDevice7MarginsE
+
+Class QPdfWriter
+ size=48 align=8
+ base size=48 base align=8
+QPdfWriter (0x0x7f88473bc9a0) 0
+ vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 16u)
+ QObject (0x0x7f884772f480) 0
+ primary-for QPdfWriter (0x0x7f88473bc9a0)
+ QPagedPaintDevice (0x0x7f8847685958) 16
+ vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 176u)
+ QPaintDevice (0x0x7f884772f4e0) 16
+ primary-for QPagedPaintDevice (0x0x7f8847685958)
+
+Vtable for QPicture
+QPicture::_ZTV8QPicture: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QPicture)
+16 (int (*)(...))QPicture::~QPicture
+24 (int (*)(...))QPicture::~QPicture
+32 (int (*)(...))QPicture::devType
+40 (int (*)(...))QPicture::paintEngine
+48 (int (*)(...))QPicture::metric
+56 (int (*)(...))QPaintDevice::initPainter
+64 (int (*)(...))QPaintDevice::redirected
+72 (int (*)(...))QPaintDevice::sharedPainter
+80 (int (*)(...))QPicture::setData
+
+Class QPicture
+ size=32 align=8
+ base size=32 base align=8
+QPicture (0x0x7f88476859c0) 0
+ vptr=((& QPicture::_ZTV8QPicture) + 16u)
+ QPaintDevice (0x0x7f884772f6c0) 0
+ primary-for QPicture (0x0x7f88476859c0)
+
+Class QPictureIO
+ size=8 align=8
+ base size=8 base align=8
+QPictureIO (0x0x7f884772f9c0) 0
+
+Class QPictureFormatPlugin::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPictureFormatPlugin::QPrivateSignal (0x0x7f884772fa80) 0 empty
+
+Vtable for QPictureFormatPlugin
+QPictureFormatPlugin::_ZTV20QPictureFormatPlugin: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QPictureFormatPlugin)
+16 (int (*)(...))QPictureFormatPlugin::metaObject
+24 (int (*)(...))QPictureFormatPlugin::qt_metacast
+32 (int (*)(...))QPictureFormatPlugin::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QPictureFormatPlugin::loadPicture
+120 (int (*)(...))QPictureFormatPlugin::savePicture
+128 (int (*)(...))__cxa_pure_virtual
+
+Class QPictureFormatPlugin
+ size=16 align=8
+ base size=16 base align=8
+QPictureFormatPlugin (0x0x7f8847685bc8) 0
+ vptr=((& QPictureFormatPlugin::_ZTV20QPictureFormatPlugin) + 16u)
+ QObject (0x0x7f884772fa20) 0
+ primary-for QPictureFormatPlugin (0x0x7f8847685bc8)
+
+Class QPixmapCache::Key
+ size=8 align=8
+ base size=8 base align=8
+QPixmapCache::Key (0x0x7f884772fb40) 0
+
+Class QPixmapCache
+ size=1 align=1
+ base size=0 base align=1
+QPixmapCache (0x0x7f884772fae0) 0 empty
+
+Class QRasterWindow::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QRasterWindow::QPrivateSignal (0x0x7f88474a4cc0) 0 empty
+
+Vtable for QRasterWindow
+QRasterWindow::_ZTV13QRasterWindow: 59u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QRasterWindow)
+16 (int (*)(...))QRasterWindow::metaObject
+24 (int (*)(...))QRasterWindow::qt_metacast
+32 (int (*)(...))QRasterWindow::qt_metacall
+40 (int (*)(...))QRasterWindow::~QRasterWindow
+48 (int (*)(...))QRasterWindow::~QRasterWindow
+56 (int (*)(...))QPaintDeviceWindow::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWindow::surfaceType
+120 (int (*)(...))QWindow::format
+128 (int (*)(...))QWindow::size
+136 (int (*)(...))QWindow::accessibleRoot
+144 (int (*)(...))QWindow::focusObject
+152 (int (*)(...))QPaintDeviceWindow::exposeEvent
+160 (int (*)(...))QWindow::resizeEvent
+168 (int (*)(...))QWindow::moveEvent
+176 (int (*)(...))QWindow::focusInEvent
+184 (int (*)(...))QWindow::focusOutEvent
+192 (int (*)(...))QWindow::showEvent
+200 (int (*)(...))QWindow::hideEvent
+208 (int (*)(...))QWindow::keyPressEvent
+216 (int (*)(...))QWindow::keyReleaseEvent
+224 (int (*)(...))QWindow::mousePressEvent
+232 (int (*)(...))QWindow::mouseReleaseEvent
+240 (int (*)(...))QWindow::mouseDoubleClickEvent
+248 (int (*)(...))QWindow::mouseMoveEvent
+256 (int (*)(...))QWindow::wheelEvent
+264 (int (*)(...))QWindow::touchEvent
+272 (int (*)(...))QWindow::tabletEvent
+280 (int (*)(...))QWindow::nativeEvent
+288 (int (*)(...))QWindow::surfaceHandle
+296 (int (*)(...))QPaintDeviceWindow::paintEvent
+304 (int (*)(...))QRasterWindow::metric
+312 (int (*)(...))QPaintDeviceWindow::paintEngine
+320 (int (*)(...))QRasterWindow::redirected
+328 (int (*)(...))-16
+336 (int (*)(...))(& _ZTI13QRasterWindow)
+344 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD1Ev
+352 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD0Ev
+360 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv
+368 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv
+376 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv
+384 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv
+392 (int (*)(...))-40
+400 (int (*)(...))(& _ZTI13QRasterWindow)
+408 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD1Ev
+416 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD0Ev
+424 (int (*)(...))QPaintDevice::devType
+432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv
+440 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow6metricEN12QPaintDevice17PaintDeviceMetricE
+448 (int (*)(...))QPaintDevice::initPainter
+456 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow10redirectedEP6QPoint
+464 (int (*)(...))QPaintDevice::sharedPainter
+
+Class QRasterWindow
+ size=64 align=8
+ base size=64 base align=8
+QRasterWindow (0x0x7f88474b22d8) 0
+ vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 16u)
+ QPaintDeviceWindow (0x0x7f88474ba0e0) 0
+ primary-for QRasterWindow (0x0x7f88474b22d8)
+ QWindow (0x0x7f88474ba150) 0
+ primary-for QPaintDeviceWindow (0x0x7f88474ba0e0)
+ QObject (0x0x7f88474a4ba0) 0
+ primary-for QWindow (0x0x7f88474ba150)
+ QSurface (0x0x7f88474a4c00) 16
+ vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 344u)
+ QPaintDevice (0x0x7f88474a4c60) 40
+ vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 408u)
+
+Class QScreen::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QScreen::QPrivateSignal (0x0x7f88474a4d80) 0 empty
+
+Vtable for QScreen
+QScreen::_ZTV7QScreen: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QScreen)
+16 (int (*)(...))QScreen::metaObject
+24 (int (*)(...))QScreen::qt_metacast
+32 (int (*)(...))QScreen::qt_metacall
+40 (int (*)(...))QScreen::~QScreen
+48 (int (*)(...))QScreen::~QScreen
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QScreen
+ size=16 align=8
+ base size=16 base align=8
+QScreen (0x0x7f88474b23a8) 0
+ vptr=((& QScreen::_ZTV7QScreen) + 16u)
+ QObject (0x0x7f88474a4d20) 0
+ primary-for QScreen (0x0x7f88474b23a8)
+
+Class QSessionManager::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSessionManager::QPrivateSignal (0x0x7f88474a4e40) 0 empty
+
+Vtable for QSessionManager
+QSessionManager::_ZTV15QSessionManager: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QSessionManager)
+16 (int (*)(...))QSessionManager::metaObject
+24 (int (*)(...))QSessionManager::qt_metacast
+32 (int (*)(...))QSessionManager::qt_metacall
+40 (int (*)(...))QSessionManager::~QSessionManager
+48 (int (*)(...))QSessionManager::~QSessionManager
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QSessionManager
+ size=16 align=8
+ base size=16 base align=8
+QSessionManager (0x0x7f88474b2410) 0
+ vptr=((& QSessionManager::_ZTV15QSessionManager) + 16u)
+ QObject (0x0x7f88474a4de0) 0
+ primary-for QSessionManager (0x0x7f88474b2410)
+
+Vtable for QStandardItem
+QStandardItem::_ZTV13QStandardItem: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QStandardItem)
+16 (int (*)(...))QStandardItem::~QStandardItem
+24 (int (*)(...))QStandardItem::~QStandardItem
+32 (int (*)(...))QStandardItem::data
+40 (int (*)(...))QStandardItem::setData
+48 (int (*)(...))QStandardItem::clone
+56 (int (*)(...))QStandardItem::type
+64 (int (*)(...))QStandardItem::read
+72 (int (*)(...))QStandardItem::write
+80 (int (*)(...))QStandardItem::operator<
+
+Class QStandardItem
+ size=16 align=8
+ base size=16 base align=8
+QStandardItem (0x0x7f88474a4ea0) 0
+ vptr=((& QStandardItem::_ZTV13QStandardItem) + 16u)
+
+Class QStandardItemModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QStandardItemModel::QPrivateSignal (0x0x7f884753c600) 0 empty
+
+Vtable for QStandardItemModel
+QStandardItemModel::_ZTV18QStandardItemModel: 48u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QStandardItemModel)
+16 (int (*)(...))QStandardItemModel::metaObject
+24 (int (*)(...))QStandardItemModel::qt_metacast
+32 (int (*)(...))QStandardItemModel::qt_metacall
+40 (int (*)(...))QStandardItemModel::~QStandardItemModel
+48 (int (*)(...))QStandardItemModel::~QStandardItemModel
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QStandardItemModel::index
+120 (int (*)(...))QStandardItemModel::parent
+128 (int (*)(...))QStandardItemModel::sibling
+136 (int (*)(...))QStandardItemModel::rowCount
+144 (int (*)(...))QStandardItemModel::columnCount
+152 (int (*)(...))QStandardItemModel::hasChildren
+160 (int (*)(...))QStandardItemModel::data
+168 (int (*)(...))QStandardItemModel::setData
+176 (int (*)(...))QStandardItemModel::headerData
+184 (int (*)(...))QStandardItemModel::setHeaderData
+192 (int (*)(...))QStandardItemModel::itemData
+200 (int (*)(...))QStandardItemModel::setItemData
+208 (int (*)(...))QStandardItemModel::mimeTypes
+216 (int (*)(...))QStandardItemModel::mimeData
+224 (int (*)(...))QAbstractItemModel::canDropMimeData
+232 (int (*)(...))QStandardItemModel::dropMimeData
+240 (int (*)(...))QStandardItemModel::supportedDropActions
+248 (int (*)(...))QAbstractItemModel::supportedDragActions
+256 (int (*)(...))QStandardItemModel::insertRows
+264 (int (*)(...))QStandardItemModel::insertColumns
+272 (int (*)(...))QStandardItemModel::removeRows
+280 (int (*)(...))QStandardItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractItemModel::fetchMore
+312 (int (*)(...))QAbstractItemModel::canFetchMore
+320 (int (*)(...))QStandardItemModel::flags
+328 (int (*)(...))QStandardItemModel::sort
+336 (int (*)(...))QAbstractItemModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractItemModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractItemModel::submit
+376 (int (*)(...))QAbstractItemModel::revert
+
+Class QStandardItemModel
+ size=16 align=8
+ base size=16 base align=8
+QStandardItemModel (0x0x7f88474b2a90) 0
+ vptr=((& QStandardItemModel::_ZTV18QStandardItemModel) + 16u)
+ QAbstractItemModel (0x0x7f88474b2af8) 0
+ primary-for QStandardItemModel (0x0x7f88474b2a90)
+ QObject (0x0x7f884753c5a0) 0
+ primary-for QAbstractItemModel (0x0x7f88474b2af8)
+
+Class QStaticText
+ size=8 align=8
+ base size=8 base align=8
+QStaticText (0x0x7f884753c660) 0
+
+Class QStyleHints::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QStyleHints::QPrivateSignal (0x0x7f884753cae0) 0 empty
+
+Vtable for QStyleHints
+QStyleHints::_ZTV11QStyleHints: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QStyleHints)
+16 (int (*)(...))QStyleHints::metaObject
+24 (int (*)(...))QStyleHints::qt_metacast
+32 (int (*)(...))QStyleHints::qt_metacall
+40 (int (*)(...))QStyleHints::~QStyleHints
+48 (int (*)(...))QStyleHints::~QStyleHints
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QStyleHints
+ size=16 align=8
+ base size=16 base align=8
+QStyleHints (0x0x7f88474b2d00) 0
+ vptr=((& QStyleHints::_ZTV11QStyleHints) + 16u)
+ QObject (0x0x7f884753ca80) 0
+ primary-for QStyleHints (0x0x7f88474b2d00)
+
+Class QTextObject::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTextObject::QPrivateSignal (0x0x7f884753cba0) 0 empty
+
+Vtable for QTextObject
+QTextObject::_ZTV11QTextObject: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTextObject)
+16 (int (*)(...))QTextObject::metaObject
+24 (int (*)(...))QTextObject::qt_metacast
+32 (int (*)(...))QTextObject::qt_metacall
+40 (int (*)(...))QTextObject::~QTextObject
+48 (int (*)(...))QTextObject::~QTextObject
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QTextObject
+ size=16 align=8
+ base size=16 base align=8
+QTextObject (0x0x7f88474b2d68) 0
+ vptr=((& QTextObject::_ZTV11QTextObject) + 16u)
+ QObject (0x0x7f884753cb40) 0
+ primary-for QTextObject (0x0x7f88474b2d68)
+
+Class QTextBlockGroup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTextBlockGroup::QPrivateSignal (0x0x7f884753cc60) 0 empty
+
+Vtable for QTextBlockGroup
+QTextBlockGroup::_ZTV15QTextBlockGroup: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QTextBlockGroup)
+16 (int (*)(...))QTextBlockGroup::metaObject
+24 (int (*)(...))QTextBlockGroup::qt_metacast
+32 (int (*)(...))QTextBlockGroup::qt_metacall
+40 (int (*)(...))QTextBlockGroup::~QTextBlockGroup
+48 (int (*)(...))QTextBlockGroup::~QTextBlockGroup
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QTextBlockGroup::blockInserted
+120 (int (*)(...))QTextBlockGroup::blockRemoved
+128 (int (*)(...))QTextBlockGroup::blockFormatChanged
+
+Class QTextBlockGroup
+ size=16 align=8
+ base size=16 base align=8
+QTextBlockGroup (0x0x7f88474b2dd0) 0
+ vptr=((& QTextBlockGroup::_ZTV15QTextBlockGroup) + 16u)
+ QTextObject (0x0x7f88474b2e38) 0
+ primary-for QTextBlockGroup (0x0x7f88474b2dd0)
+ QObject (0x0x7f884753cc00) 0
+ primary-for QTextObject (0x0x7f88474b2e38)
+
+Vtable for QTextFrameLayoutData
+QTextFrameLayoutData::_ZTV20QTextFrameLayoutData: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QTextFrameLayoutData)
+16 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData
+24 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData
+
+Class QTextFrameLayoutData
+ size=8 align=8
+ base size=8 base align=8
+QTextFrameLayoutData (0x0x7f884753ccc0) 0 nearly-empty
+ vptr=((& QTextFrameLayoutData::_ZTV20QTextFrameLayoutData) + 16u)
+
+Class QTextFrame::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTextFrame::QPrivateSignal (0x0x7f884753cd80) 0 empty
+
+Class QTextFrame::iterator
+ size=32 align=8
+ base size=28 base align=8
+QTextFrame::iterator (0x0x7f884753cde0) 0
+
+Vtable for QTextFrame
+QTextFrame::_ZTV10QTextFrame: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTextFrame)
+16 (int (*)(...))QTextFrame::metaObject
+24 (int (*)(...))QTextFrame::qt_metacast
+32 (int (*)(...))QTextFrame::qt_metacall
+40 (int (*)(...))QTextFrame::~QTextFrame
+48 (int (*)(...))QTextFrame::~QTextFrame
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QTextFrame
+ size=16 align=8
+ base size=16 base align=8
+QTextFrame (0x0x7f88474b2ea0) 0
+ vptr=((& QTextFrame::_ZTV10QTextFrame) + 16u)
+ QTextObject (0x0x7f88474b2f08) 0
+ primary-for QTextFrame (0x0x7f88474b2ea0)
+ QObject (0x0x7f884753cd20) 0
+ primary-for QTextObject (0x0x7f88474b2f08)
+
+Vtable for QTextBlockUserData
+QTextBlockUserData::_ZTV18QTextBlockUserData: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QTextBlockUserData)
+16 (int (*)(...))QTextBlockUserData::~QTextBlockUserData
+24 (int (*)(...))QTextBlockUserData::~QTextBlockUserData
+
+Class QTextBlockUserData
+ size=8 align=8
+ base size=8 base align=8
+QTextBlockUserData (0x0x7f884727c0c0) 0 nearly-empty
+ vptr=((& QTextBlockUserData::_ZTV18QTextBlockUserData) + 16u)
+
+Class QTextBlock::iterator
+ size=24 align=8
+ base size=20 base align=8
+QTextBlock::iterator (0x0x7f884727c180) 0
+
+Class QTextBlock
+ size=16 align=8
+ base size=12 base align=8
+QTextBlock (0x0x7f884727c120) 0
+
+Class QTextFragment
+ size=16 align=8
+ base size=16 base align=8
+QTextFragment (0x0x7f884727c660) 0
+
+Class QSyntaxHighlighter::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSyntaxHighlighter::QPrivateSignal (0x0x7f884727c960) 0 empty
+
+Vtable for QSyntaxHighlighter
+QSyntaxHighlighter::_ZTV18QSyntaxHighlighter: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QSyntaxHighlighter)
+16 (int (*)(...))QSyntaxHighlighter::metaObject
+24 (int (*)(...))QSyntaxHighlighter::qt_metacast
+32 (int (*)(...))QSyntaxHighlighter::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+
+Class QSyntaxHighlighter
+ size=16 align=8
+ base size=16 base align=8
+QSyntaxHighlighter (0x0x7f884727b618) 0
+ vptr=((& QSyntaxHighlighter::_ZTV18QSyntaxHighlighter) + 16u)
+ QObject (0x0x7f884727c900) 0
+ primary-for QSyntaxHighlighter (0x0x7f884727b618)
+
+Class QTextDocumentFragment
+ size=8 align=8
+ base size=8 base align=8
+QTextDocumentFragment (0x0x7f884727c9c0) 0
+
+Class QTextDocumentWriter
+ size=8 align=8
+ base size=8 base align=8
+QTextDocumentWriter (0x0x7f884727ca20) 0
+
+Class QTextList::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTextList::QPrivateSignal (0x0x7f884727cae0) 0 empty
+
+Vtable for QTextList
+QTextList::_ZTV9QTextList: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QTextList)
+16 (int (*)(...))QTextList::metaObject
+24 (int (*)(...))QTextList::qt_metacast
+32 (int (*)(...))QTextList::qt_metacall
+40 (int (*)(...))QTextList::~QTextList
+48 (int (*)(...))QTextList::~QTextList
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QTextBlockGroup::blockInserted
+120 (int (*)(...))QTextBlockGroup::blockRemoved
+128 (int (*)(...))QTextBlockGroup::blockFormatChanged
+
+Class QTextList
+ size=16 align=8
+ base size=16 base align=8
+QTextList (0x0x7f884727b680) 0
+ vptr=((& QTextList::_ZTV9QTextList) + 16u)
+ QTextBlockGroup (0x0x7f884727b6e8) 0
+ primary-for QTextList (0x0x7f884727b680)
+ QTextObject (0x0x7f884727b750) 0
+ primary-for QTextBlockGroup (0x0x7f884727b6e8)
+ QObject (0x0x7f884727ca80) 0
+ primary-for QTextObject (0x0x7f884727b750)
+
+Class QTextTableCell
+ size=16 align=8
+ base size=12 base align=8
+QTextTableCell (0x0x7f884727cb40) 0
+
+Class QTextTable::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTextTable::QPrivateSignal (0x0x7f884727cc00) 0 empty
+
+Vtable for QTextTable
+QTextTable::_ZTV10QTextTable: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTextTable)
+16 (int (*)(...))QTextTable::metaObject
+24 (int (*)(...))QTextTable::qt_metacast
+32 (int (*)(...))QTextTable::qt_metacall
+40 (int (*)(...))QTextTable::~QTextTable
+48 (int (*)(...))QTextTable::~QTextTable
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QTextTable
+ size=16 align=8
+ base size=16 base align=8
+QTextTable (0x0x7f884727b7b8) 0
+ vptr=((& QTextTable::_ZTV10QTextTable) + 16u)
+ QTextFrame (0x0x7f884727b820) 0
+ primary-for QTextTable (0x0x7f884727b7b8)
+ QTextObject (0x0x7f884727b888) 0
+ primary-for QTextFrame (0x0x7f884727b820)
+ QObject (0x0x7f884727cba0) 0
+ primary-for QTextObject (0x0x7f884727b888)
+
+Class QValidator::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QValidator::QPrivateSignal (0x0x7f884727ccc0) 0 empty
+
+Vtable for QValidator
+QValidator::_ZTV10QValidator: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QValidator)
+16 (int (*)(...))QValidator::metaObject
+24 (int (*)(...))QValidator::qt_metacast
+32 (int (*)(...))QValidator::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))QValidator::fixup
+
+Class QValidator
+ size=16 align=8
+ base size=16 base align=8
+QValidator (0x0x7f884727b8f0) 0
+ vptr=((& QValidator::_ZTV10QValidator) + 16u)
+ QObject (0x0x7f884727cc60) 0
+ primary-for QValidator (0x0x7f884727b8f0)
+
+Class QIntValidator::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QIntValidator::QPrivateSignal (0x0x7f884727cd80) 0 empty
+
+Vtable for QIntValidator
+QIntValidator::_ZTV13QIntValidator: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QIntValidator)
+16 (int (*)(...))QIntValidator::metaObject
+24 (int (*)(...))QIntValidator::qt_metacast
+32 (int (*)(...))QIntValidator::qt_metacall
+40 (int (*)(...))QIntValidator::~QIntValidator
+48 (int (*)(...))QIntValidator::~QIntValidator
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QIntValidator::validate
+120 (int (*)(...))QIntValidator::fixup
+128 (int (*)(...))QIntValidator::setRange
+
+Class QIntValidator
+ size=24 align=8
+ base size=24 base align=8
+QIntValidator (0x0x7f884727b958) 0
+ vptr=((& QIntValidator::_ZTV13QIntValidator) + 16u)
+ QValidator (0x0x7f884727b9c0) 0
+ primary-for QIntValidator (0x0x7f884727b958)
+ QObject (0x0x7f884727cd20) 0
+ primary-for QValidator (0x0x7f884727b9c0)
+
+Class QDoubleValidator::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDoubleValidator::QPrivateSignal (0x0x7f884727ce40) 0 empty
+
+Vtable for QDoubleValidator
+QDoubleValidator::_ZTV16QDoubleValidator: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QDoubleValidator)
+16 (int (*)(...))QDoubleValidator::metaObject
+24 (int (*)(...))QDoubleValidator::qt_metacast
+32 (int (*)(...))QDoubleValidator::qt_metacall
+40 (int (*)(...))QDoubleValidator::~QDoubleValidator
+48 (int (*)(...))QDoubleValidator::~QDoubleValidator
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QDoubleValidator::validate
+120 (int (*)(...))QValidator::fixup
+128 (int (*)(...))QDoubleValidator::setRange
+
+Class QDoubleValidator
+ size=40 align=8
+ base size=36 base align=8
+QDoubleValidator (0x0x7f884727ba28) 0
+ vptr=((& QDoubleValidator::_ZTV16QDoubleValidator) + 16u)
+ QValidator (0x0x7f884727ba90) 0
+ primary-for QDoubleValidator (0x0x7f884727ba28)
+ QObject (0x0x7f884727cde0) 0
+ primary-for QValidator (0x0x7f884727ba90)
+
+Class QRegExpValidator::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QRegExpValidator::QPrivateSignal (0x0x7f884727cf60) 0 empty
+
+Vtable for QRegExpValidator
+QRegExpValidator::_ZTV16QRegExpValidator: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QRegExpValidator)
+16 (int (*)(...))QRegExpValidator::metaObject
+24 (int (*)(...))QRegExpValidator::qt_metacast
+32 (int (*)(...))QRegExpValidator::qt_metacall
+40 (int (*)(...))QRegExpValidator::~QRegExpValidator
+48 (int (*)(...))QRegExpValidator::~QRegExpValidator
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QRegExpValidator::validate
+120 (int (*)(...))QValidator::fixup
+
+Class QRegExpValidator
+ size=24 align=8
+ base size=24 base align=8
+QRegExpValidator (0x0x7f884727baf8) 0
+ vptr=((& QRegExpValidator::_ZTV16QRegExpValidator) + 16u)
+ QValidator (0x0x7f884727bb60) 0
+ primary-for QRegExpValidator (0x0x7f884727baf8)
+ QObject (0x0x7f884727cf00) 0
+ primary-for QValidator (0x0x7f884727bb60)
+
+Class QRegularExpressionValidator::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QRegularExpressionValidator::QPrivateSignal (0x0x7f8846f6f060) 0 empty
+
+Vtable for QRegularExpressionValidator
+QRegularExpressionValidator::_ZTV27QRegularExpressionValidator: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QRegularExpressionValidator)
+16 (int (*)(...))QRegularExpressionValidator::metaObject
+24 (int (*)(...))QRegularExpressionValidator::qt_metacast
+32 (int (*)(...))QRegularExpressionValidator::qt_metacall
+40 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator
+48 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QRegularExpressionValidator::validate
+120 (int (*)(...))QValidator::fixup
+
+Class QRegularExpressionValidator
+ size=16 align=8
+ base size=16 base align=8
+QRegularExpressionValidator (0x0x7f884727bbc8) 0
+ vptr=((& QRegularExpressionValidator::_ZTV27QRegularExpressionValidator) + 16u)
+ QValidator (0x0x7f884727bc30) 0
+ primary-for QRegularExpressionValidator (0x0x7f884727bbc8)
+ QObject (0x0x7f8846f6f000) 0
+ primary-for QValidator (0x0x7f884727bc30)
+
+Class QSizePolicy::Bits
+ size=4 align=4
+ base size=4 base align=4
+QSizePolicy::Bits (0x0x7f8846f6f120) 0
+
+Class QSizePolicy
+ size=4 align=4
+ base size=4 base align=4
+QSizePolicy (0x0x7f8846f6f0c0) 0
+
+Class QWidgetData
+ size=88 align=8
+ base size=88 base align=8
+QWidgetData (0x0x7f8846f6fa20) 0
+
+Class QWidget::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QWidget::QPrivateSignal (0x0x7f8846f6fb40) 0 empty
+
+Vtable for QWidget
+QWidget::_ZTV7QWidget: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QWidget)
+16 (int (*)(...))QWidget::metaObject
+24 (int (*)(...))QWidget::qt_metacast
+32 (int (*)(...))QWidget::qt_metacall
+40 (int (*)(...))QWidget::~QWidget
+48 (int (*)(...))QWidget::~QWidget
+56 (int (*)(...))QWidget::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI7QWidget)
+448 (int (*)(...))QWidget::_ZThn16_N7QWidgetD1Ev
+456 (int (*)(...))QWidget::_ZThn16_N7QWidgetD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QWidget
+ size=48 align=8
+ base size=48 base align=8
+QWidget (0x0x7f8847002540) 0
+ vptr=((& QWidget::_ZTV7QWidget) + 16u)
+ QObject (0x0x7f8846f6fa80) 0
+ primary-for QWidget (0x0x7f8847002540)
+ QPaintDevice (0x0x7f8846f6fae0) 16
+ vptr=((& QWidget::_ZTV7QWidget) + 448u)
+
+Class QAbstractButton::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractButton::QPrivateSignal (0x0x7f88470d37e0) 0 empty
+
+Vtable for QAbstractButton
+QAbstractButton::_ZTV15QAbstractButton: 67u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QAbstractButton)
+16 (int (*)(...))QAbstractButton::metaObject
+24 (int (*)(...))QAbstractButton::qt_metacast
+32 (int (*)(...))QAbstractButton::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QAbstractButton::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractButton::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractButton::mousePressEvent
+176 (int (*)(...))QAbstractButton::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractButton::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QAbstractButton::keyPressEvent
+216 (int (*)(...))QAbstractButton::keyReleaseEvent
+224 (int (*)(...))QAbstractButton::focusInEvent
+232 (int (*)(...))QAbstractButton::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))__cxa_pure_virtual
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractButton::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QAbstractButton::hitButton
+440 (int (*)(...))QAbstractButton::checkStateSet
+448 (int (*)(...))QAbstractButton::nextCheckState
+456 (int (*)(...))-16
+464 (int (*)(...))(& _ZTI15QAbstractButton)
+472 0u
+480 0u
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QAbstractButton
+ size=48 align=8
+ base size=48 base align=8
+QAbstractButton (0x0x7f8846fb3f70) 0
+ vptr=((& QAbstractButton::_ZTV15QAbstractButton) + 16u)
+ QWidget (0x0x7f88470fc150) 0
+ primary-for QAbstractButton (0x0x7f8846fb3f70)
+ QObject (0x0x7f88470d3720) 0
+ primary-for QWidget (0x0x7f88470fc150)
+ QPaintDevice (0x0x7f88470d3780) 16
+ vptr=((& QAbstractButton::_ZTV15QAbstractButton) + 472u)
+
+Class QAbstractSpinBox::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractSpinBox::QPrivateSignal (0x0x7f88470d3900) 0 empty
+
+Vtable for QAbstractSpinBox
+QAbstractSpinBox::_ZTV16QAbstractSpinBox: 69u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QAbstractSpinBox)
+16 (int (*)(...))QAbstractSpinBox::metaObject
+24 (int (*)(...))QAbstractSpinBox::qt_metacast
+32 (int (*)(...))QAbstractSpinBox::qt_metacall
+40 (int (*)(...))QAbstractSpinBox::~QAbstractSpinBox
+48 (int (*)(...))QAbstractSpinBox::~QAbstractSpinBox
+56 (int (*)(...))QAbstractSpinBox::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractSpinBox::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractSpinBox::sizeHint
+136 (int (*)(...))QAbstractSpinBox::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractSpinBox::mousePressEvent
+176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent
+200 (int (*)(...))QAbstractSpinBox::wheelEvent
+208 (int (*)(...))QAbstractSpinBox::keyPressEvent
+216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent
+224 (int (*)(...))QAbstractSpinBox::focusInEvent
+232 (int (*)(...))QAbstractSpinBox::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QAbstractSpinBox::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QAbstractSpinBox::resizeEvent
+280 (int (*)(...))QAbstractSpinBox::closeEvent
+288 (int (*)(...))QAbstractSpinBox::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QAbstractSpinBox::showEvent
+352 (int (*)(...))QAbstractSpinBox::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractSpinBox::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QAbstractSpinBox::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QAbstractSpinBox::validate
+440 (int (*)(...))QAbstractSpinBox::fixup
+448 (int (*)(...))QAbstractSpinBox::stepBy
+456 (int (*)(...))QAbstractSpinBox::clear
+464 (int (*)(...))QAbstractSpinBox::stepEnabled
+472 (int (*)(...))-16
+480 (int (*)(...))(& _ZTI16QAbstractSpinBox)
+488 (int (*)(...))QAbstractSpinBox::_ZThn16_N16QAbstractSpinBoxD1Ev
+496 (int (*)(...))QAbstractSpinBox::_ZThn16_N16QAbstractSpinBoxD0Ev
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QAbstractSpinBox
+ size=48 align=8
+ base size=48 base align=8
+QAbstractSpinBox (0x0x7f8847123000) 0
+ vptr=((& QAbstractSpinBox::_ZTV16QAbstractSpinBox) + 16u)
+ QWidget (0x0x7f88470fc620) 0
+ primary-for QAbstractSpinBox (0x0x7f8847123000)
+ QObject (0x0x7f88470d3840) 0
+ primary-for QWidget (0x0x7f88470fc620)
+ QPaintDevice (0x0x7f88470d38a0) 16
+ vptr=((& QAbstractSpinBox::_ZTV16QAbstractSpinBox) + 488u)
+
+Class QAbstractSlider::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractSlider::QPrivateSignal (0x0x7f88470d3ba0) 0 empty
+
+Vtable for QAbstractSlider
+QAbstractSlider::_ZTV15QAbstractSlider: 65u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QAbstractSlider)
+16 (int (*)(...))QAbstractSlider::metaObject
+24 (int (*)(...))QAbstractSlider::qt_metacast
+32 (int (*)(...))QAbstractSlider::qt_metacall
+40 (int (*)(...))QAbstractSlider::~QAbstractSlider
+48 (int (*)(...))QAbstractSlider::~QAbstractSlider
+56 (int (*)(...))QAbstractSlider::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractSlider::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QAbstractSlider::wheelEvent
+208 (int (*)(...))QAbstractSlider::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractSlider::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QAbstractSlider::sliderChange
+440 (int (*)(...))-16
+448 (int (*)(...))(& _ZTI15QAbstractSlider)
+456 (int (*)(...))QAbstractSlider::_ZThn16_N15QAbstractSliderD1Ev
+464 (int (*)(...))QAbstractSlider::_ZThn16_N15QAbstractSliderD0Ev
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QAbstractSlider
+ size=48 align=8
+ base size=48 base align=8
+QAbstractSlider (0x0x7f8847123138) 0
+ vptr=((& QAbstractSlider::_ZTV15QAbstractSlider) + 16u)
+ QWidget (0x0x7f8846d75070) 0
+ primary-for QAbstractSlider (0x0x7f8847123138)
+ QObject (0x0x7f88470d3ae0) 0
+ primary-for QWidget (0x0x7f8846d75070)
+ QPaintDevice (0x0x7f88470d3b40) 16
+ vptr=((& QAbstractSlider::_ZTV15QAbstractSlider) + 456u)
+
+Class QSlider::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSlider::QPrivateSignal (0x0x7f88470d3cc0) 0 empty
+
+Vtable for QSlider
+QSlider::_ZTV7QSlider: 65u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QSlider)
+16 (int (*)(...))QSlider::metaObject
+24 (int (*)(...))QSlider::qt_metacast
+32 (int (*)(...))QSlider::qt_metacall
+40 (int (*)(...))QSlider::~QSlider
+48 (int (*)(...))QSlider::~QSlider
+56 (int (*)(...))QSlider::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractSlider::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QSlider::sizeHint
+136 (int (*)(...))QSlider::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QSlider::mousePressEvent
+176 (int (*)(...))QSlider::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QSlider::mouseMoveEvent
+200 (int (*)(...))QAbstractSlider::wheelEvent
+208 (int (*)(...))QAbstractSlider::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QSlider::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractSlider::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QAbstractSlider::sliderChange
+440 (int (*)(...))-16
+448 (int (*)(...))(& _ZTI7QSlider)
+456 (int (*)(...))QSlider::_ZThn16_N7QSliderD1Ev
+464 (int (*)(...))QSlider::_ZThn16_N7QSliderD0Ev
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QSlider
+ size=48 align=8
+ base size=48 base align=8
+QSlider (0x0x7f88471231a0) 0
+ vptr=((& QSlider::_ZTV7QSlider) + 16u)
+ QAbstractSlider (0x0x7f8847123208) 0
+ primary-for QSlider (0x0x7f88471231a0)
+ QWidget (0x0x7f8846d75a80) 0
+ primary-for QAbstractSlider (0x0x7f8847123208)
+ QObject (0x0x7f88470d3c00) 0
+ primary-for QWidget (0x0x7f8846d75a80)
+ QPaintDevice (0x0x7f88470d3c60) 16
+ vptr=((& QSlider::_ZTV7QSlider) + 456u)
+
+Class QStyle::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QStyle::QPrivateSignal (0x0x7f88470d3d80) 0 empty
+
+Vtable for QStyle
+QStyle::_ZTV6QStyle: 37u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QStyle)
+16 (int (*)(...))QStyle::metaObject
+24 (int (*)(...))QStyle::qt_metacast
+32 (int (*)(...))QStyle::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QStyle::polish
+120 (int (*)(...))QStyle::unpolish
+128 (int (*)(...))QStyle::polish
+136 (int (*)(...))QStyle::unpolish
+144 (int (*)(...))QStyle::polish
+152 (int (*)(...))QStyle::itemTextRect
+160 (int (*)(...))QStyle::itemPixmapRect
+168 (int (*)(...))QStyle::drawItemText
+176 (int (*)(...))QStyle::drawItemPixmap
+184 (int (*)(...))QStyle::standardPalette
+192 (int (*)(...))__cxa_pure_virtual
+200 (int (*)(...))__cxa_pure_virtual
+208 (int (*)(...))__cxa_pure_virtual
+216 (int (*)(...))__cxa_pure_virtual
+224 (int (*)(...))__cxa_pure_virtual
+232 (int (*)(...))__cxa_pure_virtual
+240 (int (*)(...))__cxa_pure_virtual
+248 (int (*)(...))__cxa_pure_virtual
+256 (int (*)(...))__cxa_pure_virtual
+264 (int (*)(...))__cxa_pure_virtual
+272 (int (*)(...))__cxa_pure_virtual
+280 (int (*)(...))__cxa_pure_virtual
+288 (int (*)(...))__cxa_pure_virtual
+
+Class QStyle
+ size=16 align=8
+ base size=16 base align=8
+QStyle (0x0x7f88471232d8) 0
+ vptr=((& QStyle::_ZTV6QStyle) + 16u)
+ QObject (0x0x7f88470d3d20) 0
+ primary-for QStyle (0x0x7f88471232d8)
+
+Class QTabBar::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTabBar::QPrivateSignal (0x0x7f8846e361e0) 0 empty
+
+Vtable for QTabBar
+QTabBar::_ZTV7QTabBar: 69u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QTabBar)
+16 (int (*)(...))QTabBar::metaObject
+24 (int (*)(...))QTabBar::qt_metacast
+32 (int (*)(...))QTabBar::qt_metacall
+40 (int (*)(...))QTabBar::~QTabBar
+48 (int (*)(...))QTabBar::~QTabBar
+56 (int (*)(...))QTabBar::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QTabBar::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QTabBar::sizeHint
+136 (int (*)(...))QTabBar::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QTabBar::mousePressEvent
+176 (int (*)(...))QTabBar::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QTabBar::mouseMoveEvent
+200 (int (*)(...))QTabBar::wheelEvent
+208 (int (*)(...))QTabBar::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QTabBar::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QTabBar::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QTabBar::showEvent
+352 (int (*)(...))QTabBar::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QTabBar::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QTabBar::tabSizeHint
+440 (int (*)(...))QTabBar::minimumTabSizeHint
+448 (int (*)(...))QTabBar::tabInserted
+456 (int (*)(...))QTabBar::tabRemoved
+464 (int (*)(...))QTabBar::tabLayoutChange
+472 (int (*)(...))-16
+480 (int (*)(...))(& _ZTI7QTabBar)
+488 (int (*)(...))QTabBar::_ZThn16_N7QTabBarD1Ev
+496 (int (*)(...))QTabBar::_ZThn16_N7QTabBarD0Ev
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QTabBar
+ size=48 align=8
+ base size=48 base align=8
+QTabBar (0x0x7f88471234e0) 0
+ vptr=((& QTabBar::_ZTV7QTabBar) + 16u)
+ QWidget (0x0x7f8846e67000) 0
+ primary-for QTabBar (0x0x7f88471234e0)
+ QObject (0x0x7f8846e36120) 0
+ primary-for QWidget (0x0x7f8846e67000)
+ QPaintDevice (0x0x7f8846e36180) 16
+ vptr=((& QTabBar::_ZTV7QTabBar) + 488u)
+
+Class QTabWidget::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTabWidget::QPrivateSignal (0x0x7f8846e36300) 0 empty
+
+Vtable for QTabWidget
+QTabWidget::_ZTV10QTabWidget: 66u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTabWidget)
+16 (int (*)(...))QTabWidget::metaObject
+24 (int (*)(...))QTabWidget::qt_metacast
+32 (int (*)(...))QTabWidget::qt_metacall
+40 (int (*)(...))QTabWidget::~QTabWidget
+48 (int (*)(...))QTabWidget::~QTabWidget
+56 (int (*)(...))QTabWidget::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QTabWidget::sizeHint
+136 (int (*)(...))QTabWidget::minimumSizeHint
+144 (int (*)(...))QTabWidget::heightForWidth
+152 (int (*)(...))QTabWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QTabWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QTabWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QTabWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QTabWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QTabWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QTabWidget::tabInserted
+440 (int (*)(...))QTabWidget::tabRemoved
+448 (int (*)(...))-16
+456 (int (*)(...))(& _ZTI10QTabWidget)
+464 (int (*)(...))QTabWidget::_ZThn16_N10QTabWidgetD1Ev
+472 (int (*)(...))QTabWidget::_ZThn16_N10QTabWidgetD0Ev
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QTabWidget
+ size=48 align=8
+ base size=48 base align=8
+QTabWidget (0x0x7f8847123548) 0
+ vptr=((& QTabWidget::_ZTV10QTabWidget) + 16u)
+ QWidget (0x0x7f8846e67c40) 0
+ primary-for QTabWidget (0x0x7f8847123548)
+ QObject (0x0x7f8846e36240) 0
+ primary-for QWidget (0x0x7f8846e67c40)
+ QPaintDevice (0x0x7f8846e362a0) 16
+ vptr=((& QTabWidget::_ZTV10QTabWidget) + 464u)
+
+Class QRubberBand::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QRubberBand::QPrivateSignal (0x0x7f8846e36420) 0 empty
+
+Vtable for QRubberBand
+QRubberBand::_ZTV11QRubberBand: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QRubberBand)
+16 (int (*)(...))QRubberBand::metaObject
+24 (int (*)(...))QRubberBand::qt_metacast
+32 (int (*)(...))QRubberBand::qt_metacall
+40 (int (*)(...))QRubberBand::~QRubberBand
+48 (int (*)(...))QRubberBand::~QRubberBand
+56 (int (*)(...))QRubberBand::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QRubberBand::paintEvent
+264 (int (*)(...))QRubberBand::moveEvent
+272 (int (*)(...))QRubberBand::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QRubberBand::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QRubberBand::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI11QRubberBand)
+448 (int (*)(...))QRubberBand::_ZThn16_N11QRubberBandD1Ev
+456 (int (*)(...))QRubberBand::_ZThn16_N11QRubberBandD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QRubberBand
+ size=48 align=8
+ base size=48 base align=8
+QRubberBand (0x0x7f88471235b0) 0
+ vptr=((& QRubberBand::_ZTV11QRubberBand) + 16u)
+ QWidget (0x0x7f8846ea17e0) 0
+ primary-for QRubberBand (0x0x7f88471235b0)
+ QObject (0x0x7f8846e36360) 0
+ primary-for QWidget (0x0x7f8846ea17e0)
+ QPaintDevice (0x0x7f8846e363c0) 16
+ vptr=((& QRubberBand::_ZTV11QRubberBand) + 448u)
+
+Class QFrame::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFrame::QPrivateSignal (0x0x7f8846e36540) 0 empty
+
+Vtable for QFrame
+QFrame::_ZTV6QFrame: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QFrame)
+16 (int (*)(...))QFrame::metaObject
+24 (int (*)(...))QFrame::qt_metacast
+32 (int (*)(...))QFrame::qt_metacall
+40 (int (*)(...))QFrame::~QFrame
+48 (int (*)(...))QFrame::~QFrame
+56 (int (*)(...))QFrame::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QFrame::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QFrame::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI6QFrame)
+448 (int (*)(...))QFrame::_ZThn16_N6QFrameD1Ev
+456 (int (*)(...))QFrame::_ZThn16_N6QFrameD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QFrame
+ size=48 align=8
+ base size=48 base align=8
+QFrame (0x0x7f8847123618) 0
+ vptr=((& QFrame::_ZTV6QFrame) + 16u)
+ QWidget (0x0x7f8846ed5230) 0
+ primary-for QFrame (0x0x7f8847123618)
+ QObject (0x0x7f8846e36480) 0
+ primary-for QWidget (0x0x7f8846ed5230)
+ QPaintDevice (0x0x7f8846e364e0) 16
+ vptr=((& QFrame::_ZTV6QFrame) + 448u)
+
+Class QStyleOption
+ size=64 align=8
+ base size=64 base align=8
+QStyleOption (0x0x7f8846e365a0) 0
+
+Class QStyleOptionFocusRect
+ size=80 align=8
+ base size=80 base align=8
+QStyleOptionFocusRect (0x0x7f8847123680) 0
+ QStyleOption (0x0x7f8846e36600) 0
+
+Class QStyleOptionFrame
+ size=80 align=8
+ base size=80 base align=8
+QStyleOptionFrame (0x0x7f88471236e8) 0
+ QStyleOption (0x0x7f8846e36660) 0
+
+Class QStyleOptionTabWidgetFrame
+ size=136 align=8
+ base size=132 base align=8
+QStyleOptionTabWidgetFrame (0x0x7f8847123820) 0
+ QStyleOption (0x0x7f8846e36840) 0
+
+Class QStyleOptionTabBarBase
+ size=104 align=8
+ base size=101 base align=8
+QStyleOptionTabBarBase (0x0x7f8847123888) 0
+ QStyleOption (0x0x7f8846e368a0) 0
+
+Class QStyleOptionHeader
+ size=120 align=8
+ base size=116 base align=8
+QStyleOptionHeader (0x0x7f88471238f0) 0
+ QStyleOption (0x0x7f8846e36960) 0
+
+Class QStyleOptionButton
+ size=96 align=8
+ base size=96 base align=8
+QStyleOptionButton (0x0x7f8847123958) 0
+ QStyleOption (0x0x7f8846e369c0) 0
+
+Class QStyleOptionTab
+ size=136 align=8
+ base size=136 base align=8
+QStyleOptionTab (0x0x7f8847123a90) 0
+ QStyleOption (0x0x7f8846e36ba0) 0
+
+Class QStyleOptionToolBar
+ size=88 align=8
+ base size=88 base align=8
+QStyleOptionToolBar (0x0x7f8847123c98) 0
+ QStyleOption (0x0x7f8846e36f00) 0
+
+Class QStyleOptionProgressBar
+ size=104 align=8
+ base size=102 base align=8
+QStyleOptionProgressBar (0x0x7f8847123dd0) 0
+ QStyleOption (0x0x7f8846bd2120) 0
+
+Class QStyleOptionMenuItem
+ size=136 align=8
+ base size=136 base align=8
+QStyleOptionMenuItem (0x0x7f8847123e38) 0
+ QStyleOption (0x0x7f8846bd2180) 0
+
+Class QStyleOptionDockWidget
+ size=80 align=8
+ base size=76 base align=8
+QStyleOptionDockWidget (0x0x7f8847123ea0) 0
+ QStyleOption (0x0x7f8846bd21e0) 0
+
+Class QStyleOptionViewItem
+ size=192 align=8
+ base size=192 base align=8
+QStyleOptionViewItem (0x0x7f8847123f70) 0
+ QStyleOption (0x0x7f8846bd2240) 0
+
+Class QStyleOptionToolBox
+ size=88 align=8
+ base size=88 base align=8
+QStyleOptionToolBox (0x0x7f8846c330d0) 0
+ QStyleOption (0x0x7f8846bd2420) 0
+
+Class QStyleOptionRubberBand
+ size=72 align=8
+ base size=69 base align=8
+QStyleOptionRubberBand (0x0x7f8846c33138) 0
+ QStyleOption (0x0x7f8846bd2480) 0
+
+Class QStyleOptionComplex
+ size=72 align=8
+ base size=72 base align=8
+QStyleOptionComplex (0x0x7f8846c331a0) 0
+ QStyleOption (0x0x7f8846bd24e0) 0
+
+Class QStyleOptionSlider
+ size=128 align=8
+ base size=121 base align=8
+QStyleOptionSlider (0x0x7f8846c33208) 0
+ QStyleOptionComplex (0x0x7f8846c33270) 0
+ QStyleOption (0x0x7f8846bd2540) 0
+
+Class QStyleOptionSpinBox
+ size=88 align=8
+ base size=81 base align=8
+QStyleOptionSpinBox (0x0x7f8846c332d8) 0
+ QStyleOptionComplex (0x0x7f8846c33340) 0
+ QStyleOption (0x0x7f8846bd25a0) 0
+
+Class QStyleOptionToolButton
+ size=136 align=8
+ base size=136 base align=8
+QStyleOptionToolButton (0x0x7f8846c333a8) 0
+ QStyleOptionComplex (0x0x7f8846c33410) 0
+ QStyleOption (0x0x7f8846bd2600) 0
+
+Class QStyleOptionComboBox
+ size=120 align=8
+ base size=120 base align=8
+QStyleOptionComboBox (0x0x7f8846c33548) 0
+ QStyleOptionComplex (0x0x7f8846c335b0) 0
+ QStyleOption (0x0x7f8846bd27e0) 0
+
+Class QStyleOptionTitleBar
+ size=96 align=8
+ base size=96 base align=8
+QStyleOptionTitleBar (0x0x7f8846c33618) 0
+ QStyleOptionComplex (0x0x7f8846c33680) 0
+ QStyleOption (0x0x7f8846bd2840) 0
+
+Class QStyleOptionGroupBox
+ size=120 align=8
+ base size=116 base align=8
+QStyleOptionGroupBox (0x0x7f8846c336e8) 0
+ QStyleOptionComplex (0x0x7f8846c33750) 0
+ QStyleOption (0x0x7f8846bd2900) 0
+
+Class QStyleOptionSizeGrip
+ size=80 align=8
+ base size=76 base align=8
+QStyleOptionSizeGrip (0x0x7f8846c337b8) 0
+ QStyleOptionComplex (0x0x7f8846c33820) 0
+ QStyleOption (0x0x7f8846bd2960) 0
+
+Class QStyleOptionGraphicsItem
+ size=152 align=8
+ base size=152 base align=8
+QStyleOptionGraphicsItem (0x0x7f8846c33888) 0
+ QStyleOption (0x0x7f8846bd29c0) 0
+
+Class QStyleHintReturn
+ size=8 align=4
+ base size=8 base align=4
+QStyleHintReturn (0x0x7f8846bd2ea0) 0
+
+Class QStyleHintReturnMask
+ size=16 align=8
+ base size=16 base align=8
+QStyleHintReturnMask (0x0x7f8846c33e38) 0
+ QStyleHintReturn (0x0x7f8846bd2f00) 0
+
+Class QStyleHintReturnVariant
+ size=24 align=8
+ base size=24 base align=8
+QStyleHintReturnVariant (0x0x7f8846c33ea0) 0
+ QStyleHintReturn (0x0x7f8846bd2f60) 0
+
+Class QAbstractItemDelegate::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractItemDelegate::QPrivateSignal (0x0x7f88469504e0) 0 empty
+
+Vtable for QAbstractItemDelegate
+QAbstractItemDelegate::_ZTV21QAbstractItemDelegate: 24u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QAbstractItemDelegate)
+16 (int (*)(...))QAbstractItemDelegate::metaObject
+24 (int (*)(...))QAbstractItemDelegate::qt_metacast
+32 (int (*)(...))QAbstractItemDelegate::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))QAbstractItemDelegate::createEditor
+136 (int (*)(...))QAbstractItemDelegate::destroyEditor
+144 (int (*)(...))QAbstractItemDelegate::setEditorData
+152 (int (*)(...))QAbstractItemDelegate::setModelData
+160 (int (*)(...))QAbstractItemDelegate::updateEditorGeometry
+168 (int (*)(...))QAbstractItemDelegate::editorEvent
+176 (int (*)(...))QAbstractItemDelegate::helpEvent
+184 (int (*)(...))QAbstractItemDelegate::paintingRoles
+
+Class QAbstractItemDelegate
+ size=16 align=8
+ base size=16 base align=8
+QAbstractItemDelegate (0x0x7f8846955410) 0
+ vptr=((& QAbstractItemDelegate::_ZTV21QAbstractItemDelegate) + 16u)
+ QObject (0x0x7f8846950480) 0
+ primary-for QAbstractItemDelegate (0x0x7f8846955410)
+
+Class QAbstractScrollArea::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractScrollArea::QPrivateSignal (0x0x7f8846950660) 0 empty
+
+Vtable for QAbstractScrollArea
+QAbstractScrollArea::_ZTV19QAbstractScrollArea: 68u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QAbstractScrollArea)
+16 (int (*)(...))QAbstractScrollArea::metaObject
+24 (int (*)(...))QAbstractScrollArea::qt_metacast
+32 (int (*)(...))QAbstractScrollArea::qt_metacall
+40 (int (*)(...))QAbstractScrollArea::~QAbstractScrollArea
+48 (int (*)(...))QAbstractScrollArea::~QAbstractScrollArea
+56 (int (*)(...))QAbstractScrollArea::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractScrollArea::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractScrollArea::mousePressEvent
+176 (int (*)(...))QAbstractScrollArea::mouseReleaseEvent
+184 (int (*)(...))QAbstractScrollArea::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractScrollArea::mouseMoveEvent
+200 (int (*)(...))QAbstractScrollArea::wheelEvent
+208 (int (*)(...))QAbstractScrollArea::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QAbstractScrollArea::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QAbstractScrollArea::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QAbstractScrollArea::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QAbstractScrollArea::dragEnterEvent
+320 (int (*)(...))QAbstractScrollArea::dragMoveEvent
+328 (int (*)(...))QAbstractScrollArea::dragLeaveEvent
+336 (int (*)(...))QAbstractScrollArea::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QAbstractScrollArea::viewportEvent
+448 (int (*)(...))QAbstractScrollArea::scrollContentsBy
+456 (int (*)(...))QAbstractScrollArea::viewportSizeHint
+464 (int (*)(...))-16
+472 (int (*)(...))(& _ZTI19QAbstractScrollArea)
+480 (int (*)(...))QAbstractScrollArea::_ZThn16_N19QAbstractScrollAreaD1Ev
+488 (int (*)(...))QAbstractScrollArea::_ZThn16_N19QAbstractScrollAreaD0Ev
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QAbstractScrollArea
+ size=48 align=8
+ base size=48 base align=8
+QAbstractScrollArea (0x0x7f8846955478) 0
+ vptr=((& QAbstractScrollArea::_ZTV19QAbstractScrollArea) + 16u)
+ QFrame (0x0x7f88469554e0) 0
+ primary-for QAbstractScrollArea (0x0x7f8846955478)
+ QWidget (0x0x7f884695b8c0) 0
+ primary-for QFrame (0x0x7f88469554e0)
+ QObject (0x0x7f88469505a0) 0
+ primary-for QWidget (0x0x7f884695b8c0)
+ QPaintDevice (0x0x7f8846950600) 16
+ vptr=((& QAbstractScrollArea::_ZTV19QAbstractScrollArea) + 480u)
+
+Class QAbstractItemView::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractItemView::QPrivateSignal (0x0x7f8846950780) 0 empty
+
+Vtable for QAbstractItemView
+QAbstractItemView::_ZTV17QAbstractItemView: 106u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QAbstractItemView)
+16 (int (*)(...))QAbstractItemView::metaObject
+24 (int (*)(...))QAbstractItemView::qt_metacast
+32 (int (*)(...))QAbstractItemView::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QAbstractItemView::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QAbstractItemView::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractScrollArea::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractItemView::mousePressEvent
+176 (int (*)(...))QAbstractItemView::mouseReleaseEvent
+184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractItemView::mouseMoveEvent
+200 (int (*)(...))QAbstractScrollArea::wheelEvent
+208 (int (*)(...))QAbstractItemView::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QAbstractItemView::focusInEvent
+232 (int (*)(...))QAbstractItemView::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QAbstractScrollArea::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QAbstractItemView::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QAbstractScrollArea::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QAbstractItemView::dragEnterEvent
+320 (int (*)(...))QAbstractItemView::dragMoveEvent
+328 (int (*)(...))QAbstractItemView::dragLeaveEvent
+336 (int (*)(...))QAbstractItemView::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QAbstractItemView::inputMethodEvent
+416 (int (*)(...))QAbstractItemView::inputMethodQuery
+424 (int (*)(...))QAbstractItemView::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QAbstractItemView::viewportEvent
+448 (int (*)(...))QAbstractScrollArea::scrollContentsBy
+456 (int (*)(...))QAbstractItemView::viewportSizeHint
+464 (int (*)(...))QAbstractItemView::setModel
+472 (int (*)(...))QAbstractItemView::setSelectionModel
+480 (int (*)(...))QAbstractItemView::keyboardSearch
+488 (int (*)(...))__cxa_pure_virtual
+496 (int (*)(...))__cxa_pure_virtual
+504 (int (*)(...))__cxa_pure_virtual
+512 (int (*)(...))QAbstractItemView::sizeHintForRow
+520 (int (*)(...))QAbstractItemView::sizeHintForColumn
+528 (int (*)(...))QAbstractItemView::reset
+536 (int (*)(...))QAbstractItemView::setRootIndex
+544 (int (*)(...))QAbstractItemView::doItemsLayout
+552 (int (*)(...))QAbstractItemView::selectAll
+560 (int (*)(...))QAbstractItemView::dataChanged
+568 (int (*)(...))QAbstractItemView::rowsInserted
+576 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved
+584 (int (*)(...))QAbstractItemView::selectionChanged
+592 (int (*)(...))QAbstractItemView::currentChanged
+600 (int (*)(...))QAbstractItemView::updateEditorData
+608 (int (*)(...))QAbstractItemView::updateEditorGeometries
+616 (int (*)(...))QAbstractItemView::updateGeometries
+624 (int (*)(...))QAbstractItemView::verticalScrollbarAction
+632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction
+640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged
+648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged
+656 (int (*)(...))QAbstractItemView::closeEditor
+664 (int (*)(...))QAbstractItemView::commitData
+672 (int (*)(...))QAbstractItemView::editorDestroyed
+680 (int (*)(...))__cxa_pure_virtual
+688 (int (*)(...))__cxa_pure_virtual
+696 (int (*)(...))__cxa_pure_virtual
+704 (int (*)(...))__cxa_pure_virtual
+712 (int (*)(...))__cxa_pure_virtual
+720 (int (*)(...))__cxa_pure_virtual
+728 (int (*)(...))QAbstractItemView::selectedIndexes
+736 (int (*)(...))QAbstractItemView::edit
+744 (int (*)(...))QAbstractItemView::selectionCommand
+752 (int (*)(...))QAbstractItemView::startDrag
+760 (int (*)(...))QAbstractItemView::viewOptions
+768 (int (*)(...))-16
+776 (int (*)(...))(& _ZTI17QAbstractItemView)
+784 0u
+792 0u
+800 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+808 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+816 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+832 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+840 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QAbstractItemView
+ size=48 align=8
+ base size=48 base align=8
+QAbstractItemView (0x0x7f8846955548) 0
+ vptr=((& QAbstractItemView::_ZTV17QAbstractItemView) + 16u)
+ QAbstractScrollArea (0x0x7f88469555b0) 0
+ primary-for QAbstractItemView (0x0x7f8846955548)
+ QFrame (0x0x7f8846955618) 0
+ primary-for QAbstractScrollArea (0x0x7f88469555b0)
+ QWidget (0x0x7f88469930e0) 0
+ primary-for QFrame (0x0x7f8846955618)
+ QObject (0x0x7f88469506c0) 0
+ primary-for QWidget (0x0x7f88469930e0)
+ QPaintDevice (0x0x7f8846950720) 16
+ vptr=((& QAbstractItemView::_ZTV17QAbstractItemView) + 784u)
+
+Vtable for QAccessibleWidget
+QAccessibleWidget::_ZTV17QAccessibleWidget: 35u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QAccessibleWidget)
+16 (int (*)(...))QAccessibleWidget::~QAccessibleWidget
+24 (int (*)(...))QAccessibleWidget::~QAccessibleWidget
+32 (int (*)(...))QAccessibleWidget::isValid
+40 (int (*)(...))QAccessibleObject::object
+48 (int (*)(...))QAccessibleWidget::window
+56 (int (*)(...))QAccessibleWidget::relations
+64 (int (*)(...))QAccessibleWidget::focusChild
+72 (int (*)(...))QAccessibleObject::childAt
+80 (int (*)(...))QAccessibleWidget::parent
+88 (int (*)(...))QAccessibleWidget::child
+96 (int (*)(...))QAccessibleWidget::childCount
+104 (int (*)(...))QAccessibleWidget::indexOfChild
+112 (int (*)(...))QAccessibleWidget::text
+120 (int (*)(...))QAccessibleObject::setText
+128 (int (*)(...))QAccessibleWidget::rect
+136 (int (*)(...))QAccessibleWidget::role
+144 (int (*)(...))QAccessibleWidget::state
+152 (int (*)(...))QAccessibleWidget::foregroundColor
+160 (int (*)(...))QAccessibleWidget::backgroundColor
+168 (int (*)(...))QAccessibleInterface::virtual_hook
+176 (int (*)(...))QAccessibleWidget::interface_cast
+184 (int (*)(...))QAccessibleWidget::actionNames
+192 (int (*)(...))QAccessibleWidget::doAction
+200 (int (*)(...))QAccessibleWidget::keyBindingsForAction
+208 (int (*)(...))-16
+216 (int (*)(...))(& _ZTI17QAccessibleWidget)
+224 (int (*)(...))QAccessibleWidget::_ZThn16_N17QAccessibleWidgetD1Ev
+232 (int (*)(...))QAccessibleWidget::_ZThn16_N17QAccessibleWidgetD0Ev
+240 (int (*)(...))QAccessibleWidget::_ZThn16_NK17QAccessibleWidget11actionNamesEv
+248 (int (*)(...))QAccessibleActionInterface::localizedActionName
+256 (int (*)(...))QAccessibleActionInterface::localizedActionDescription
+264 (int (*)(...))QAccessibleWidget::_ZThn16_N17QAccessibleWidget8doActionERK7QString
+272 (int (*)(...))QAccessibleWidget::_ZThn16_NK17QAccessibleWidget20keyBindingsForActionERK7QString
+
+Class QAccessibleWidget
+ size=32 align=8
+ base size=32 base align=8
+QAccessibleWidget (0x0x7f8846a0b380) 0
+ vptr=((& QAccessibleWidget::_ZTV17QAccessibleWidget) + 16u)
+ QAccessibleObject (0x0x7f8846955750) 0
+ primary-for QAccessibleWidget (0x0x7f8846a0b380)
+ QAccessibleInterface (0x0x7f8846950960) 0 nearly-empty
+ primary-for QAccessibleObject (0x0x7f8846955750)
+ QAccessibleActionInterface (0x0x7f88469509c0) 16 nearly-empty
+ vptr=((& QAccessibleWidget::_ZTV17QAccessibleWidget) + 224u)
+
+Class QAction::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAction::QPrivateSignal (0x0x7f8846950ae0) 0 empty
+
+Vtable for QAction
+QAction::_ZTV7QAction: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QAction)
+16 (int (*)(...))QAction::metaObject
+24 (int (*)(...))QAction::qt_metacast
+32 (int (*)(...))QAction::qt_metacall
+40 (int (*)(...))QAction::~QAction
+48 (int (*)(...))QAction::~QAction
+56 (int (*)(...))QAction::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QAction
+ size=16 align=8
+ base size=16 base align=8
+QAction (0x0x7f88469557b8) 0
+ vptr=((& QAction::_ZTV7QAction) + 16u)
+ QObject (0x0x7f8846950a80) 0
+ primary-for QAction (0x0x7f88469557b8)
+
+Class QActionGroup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QActionGroup::QPrivateSignal (0x0x7f8846950ba0) 0 empty
+
+Vtable for QActionGroup
+QActionGroup::_ZTV12QActionGroup: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QActionGroup)
+16 (int (*)(...))QActionGroup::metaObject
+24 (int (*)(...))QActionGroup::qt_metacast
+32 (int (*)(...))QActionGroup::qt_metacall
+40 (int (*)(...))QActionGroup::~QActionGroup
+48 (int (*)(...))QActionGroup::~QActionGroup
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QActionGroup
+ size=16 align=8
+ base size=16 base align=8
+QActionGroup (0x0x7f8846955820) 0
+ vptr=((& QActionGroup::_ZTV12QActionGroup) + 16u)
+ QObject (0x0x7f8846950b40) 0
+ primary-for QActionGroup (0x0x7f8846955820)
+
+Class QApplication::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QApplication::QPrivateSignal (0x0x7f8846950c60) 0 empty
+
+Vtable for QApplication
+QApplication::_ZTV12QApplication: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QApplication)
+16 (int (*)(...))QApplication::metaObject
+24 (int (*)(...))QApplication::qt_metacast
+32 (int (*)(...))QApplication::qt_metacall
+40 (int (*)(...))QApplication::~QApplication
+48 (int (*)(...))QApplication::~QApplication
+56 (int (*)(...))QApplication::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QApplication::notify
+120 (int (*)(...))QApplication::compressEvent
+
+Class QApplication
+ size=16 align=8
+ base size=16 base align=8
+QApplication (0x0x7f8846955888) 0
+ vptr=((& QApplication::_ZTV12QApplication) + 16u)
+ QGuiApplication (0x0x7f88469558f0) 0
+ primary-for QApplication (0x0x7f8846955888)
+ QCoreApplication (0x0x7f8846955958) 0
+ primary-for QGuiApplication (0x0x7f88469558f0)
+ QObject (0x0x7f8846950c00) 0
+ primary-for QCoreApplication (0x0x7f8846955958)
+
+Vtable for QLayoutItem
+QLayoutItem::_ZTV11QLayoutItem: 19u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QLayoutItem)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+72 (int (*)(...))__cxa_pure_virtual
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))QLayoutItem::hasHeightForWidth
+96 (int (*)(...))QLayoutItem::heightForWidth
+104 (int (*)(...))QLayoutItem::minimumHeightForWidth
+112 (int (*)(...))QLayoutItem::invalidate
+120 (int (*)(...))QLayoutItem::widget
+128 (int (*)(...))QLayoutItem::layout
+136 (int (*)(...))QLayoutItem::spacerItem
+144 (int (*)(...))QLayoutItem::controlTypes
+
+Class QLayoutItem
+ size=16 align=8
+ base size=12 base align=8
+QLayoutItem (0x0x7f8846950cc0) 0
+ vptr=((& QLayoutItem::_ZTV11QLayoutItem) + 16u)
+
+Vtable for QSpacerItem
+QSpacerItem::_ZTV11QSpacerItem: 19u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QSpacerItem)
+16 (int (*)(...))QSpacerItem::~QSpacerItem
+24 (int (*)(...))QSpacerItem::~QSpacerItem
+32 (int (*)(...))QSpacerItem::sizeHint
+40 (int (*)(...))QSpacerItem::minimumSize
+48 (int (*)(...))QSpacerItem::maximumSize
+56 (int (*)(...))QSpacerItem::expandingDirections
+64 (int (*)(...))QSpacerItem::setGeometry
+72 (int (*)(...))QSpacerItem::geometry
+80 (int (*)(...))QSpacerItem::isEmpty
+88 (int (*)(...))QLayoutItem::hasHeightForWidth
+96 (int (*)(...))QLayoutItem::heightForWidth
+104 (int (*)(...))QLayoutItem::minimumHeightForWidth
+112 (int (*)(...))QLayoutItem::invalidate
+120 (int (*)(...))QLayoutItem::widget
+128 (int (*)(...))QLayoutItem::layout
+136 (int (*)(...))QSpacerItem::spacerItem
+144 (int (*)(...))QLayoutItem::controlTypes
+
+Class QSpacerItem
+ size=40 align=8
+ base size=40 base align=8
+QSpacerItem (0x0x7f88469559c0) 0
+ vptr=((& QSpacerItem::_ZTV11QSpacerItem) + 16u)
+ QLayoutItem (0x0x7f8846950d20) 0
+ primary-for QSpacerItem (0x0x7f88469559c0)
+
+Vtable for QWidgetItem
+QWidgetItem::_ZTV11QWidgetItem: 19u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QWidgetItem)
+16 (int (*)(...))QWidgetItem::~QWidgetItem
+24 (int (*)(...))QWidgetItem::~QWidgetItem
+32 (int (*)(...))QWidgetItem::sizeHint
+40 (int (*)(...))QWidgetItem::minimumSize
+48 (int (*)(...))QWidgetItem::maximumSize
+56 (int (*)(...))QWidgetItem::expandingDirections
+64 (int (*)(...))QWidgetItem::setGeometry
+72 (int (*)(...))QWidgetItem::geometry
+80 (int (*)(...))QWidgetItem::isEmpty
+88 (int (*)(...))QWidgetItem::hasHeightForWidth
+96 (int (*)(...))QWidgetItem::heightForWidth
+104 (int (*)(...))QLayoutItem::minimumHeightForWidth
+112 (int (*)(...))QLayoutItem::invalidate
+120 (int (*)(...))QWidgetItem::widget
+128 (int (*)(...))QLayoutItem::layout
+136 (int (*)(...))QLayoutItem::spacerItem
+144 (int (*)(...))QWidgetItem::controlTypes
+
+Class QWidgetItem
+ size=24 align=8
+ base size=24 base align=8
+QWidgetItem (0x0x7f8846955a28) 0
+ vptr=((& QWidgetItem::_ZTV11QWidgetItem) + 16u)
+ QLayoutItem (0x0x7f8846950d80) 0
+ primary-for QWidgetItem (0x0x7f8846955a28)
+
+Vtable for QWidgetItemV2
+QWidgetItemV2::_ZTV13QWidgetItemV2: 19u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QWidgetItemV2)
+16 (int (*)(...))QWidgetItemV2::~QWidgetItemV2
+24 (int (*)(...))QWidgetItemV2::~QWidgetItemV2
+32 (int (*)(...))QWidgetItemV2::sizeHint
+40 (int (*)(...))QWidgetItemV2::minimumSize
+48 (int (*)(...))QWidgetItemV2::maximumSize
+56 (int (*)(...))QWidgetItem::expandingDirections
+64 (int (*)(...))QWidgetItem::setGeometry
+72 (int (*)(...))QWidgetItem::geometry
+80 (int (*)(...))QWidgetItem::isEmpty
+88 (int (*)(...))QWidgetItem::hasHeightForWidth
+96 (int (*)(...))QWidgetItemV2::heightForWidth
+104 (int (*)(...))QLayoutItem::minimumHeightForWidth
+112 (int (*)(...))QLayoutItem::invalidate
+120 (int (*)(...))QWidgetItem::widget
+128 (int (*)(...))QLayoutItem::layout
+136 (int (*)(...))QLayoutItem::spacerItem
+144 (int (*)(...))QWidgetItem::controlTypes
+
+Class QWidgetItemV2
+ size=88 align=8
+ base size=88 base align=8
+QWidgetItemV2 (0x0x7f8846955a90) 0
+ vptr=((& QWidgetItemV2::_ZTV13QWidgetItemV2) + 16u)
+ QWidgetItem (0x0x7f8846955af8) 0
+ primary-for QWidgetItemV2 (0x0x7f8846955a90)
+ QLayoutItem (0x0x7f8846950de0) 0
+ primary-for QWidgetItem (0x0x7f8846955af8)
+
+Class QLayout::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QLayout::QPrivateSignal (0x0x7f8846950f00) 0 empty
+
+Vtable for QLayout
+QLayout::_ZTV7QLayout: 47u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QLayout)
+16 (int (*)(...))QLayout::metaObject
+24 (int (*)(...))QLayout::qt_metacast
+32 (int (*)(...))QLayout::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QLayout::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QLayout::invalidate
+120 (int (*)(...))QLayout::geometry
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))QLayout::expandingDirections
+144 (int (*)(...))QLayout::minimumSize
+152 (int (*)(...))QLayout::maximumSize
+160 (int (*)(...))QLayout::setGeometry
+168 (int (*)(...))__cxa_pure_virtual
+176 (int (*)(...))__cxa_pure_virtual
+184 (int (*)(...))QLayout::indexOf
+192 (int (*)(...))__cxa_pure_virtual
+200 (int (*)(...))QLayout::isEmpty
+208 (int (*)(...))QLayout::controlTypes
+216 (int (*)(...))QLayout::layout
+224 (int (*)(...))-16
+232 (int (*)(...))(& _ZTI7QLayout)
+240 0u
+248 0u
+256 (int (*)(...))__cxa_pure_virtual
+264 (int (*)(...))QLayout::_ZThn16_NK7QLayout11minimumSizeEv
+272 (int (*)(...))QLayout::_ZThn16_NK7QLayout11maximumSizeEv
+280 (int (*)(...))QLayout::_ZThn16_NK7QLayout19expandingDirectionsEv
+288 (int (*)(...))QLayout::_ZThn16_N7QLayout11setGeometryERK5QRect
+296 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv
+304 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv
+312 (int (*)(...))QLayoutItem::hasHeightForWidth
+320 (int (*)(...))QLayoutItem::heightForWidth
+328 (int (*)(...))QLayoutItem::minimumHeightForWidth
+336 (int (*)(...))QLayout::_ZThn16_N7QLayout10invalidateEv
+344 (int (*)(...))QLayoutItem::widget
+352 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv
+360 (int (*)(...))QLayoutItem::spacerItem
+368 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv
+
+Class QLayout
+ size=32 align=8
+ base size=28 base align=8
+QLayout (0x0x7f8846aa3310) 0
+ vptr=((& QLayout::_ZTV7QLayout) + 16u)
+ QObject (0x0x7f8846950e40) 0
+ primary-for QLayout (0x0x7f8846aa3310)
+ QLayoutItem (0x0x7f8846950ea0) 16
+ vptr=((& QLayout::_ZTV7QLayout) + 240u)
+
+Class QGridLayout::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGridLayout::QPrivateSignal (0x0x7f8846ad0060) 0 empty
+
+Vtable for QGridLayout
+QGridLayout::_ZTV11QGridLayout: 51u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QGridLayout)
+16 (int (*)(...))QGridLayout::metaObject
+24 (int (*)(...))QGridLayout::qt_metacast
+32 (int (*)(...))QGridLayout::qt_metacall
+40 (int (*)(...))QGridLayout::~QGridLayout
+48 (int (*)(...))QGridLayout::~QGridLayout
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QLayout::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGridLayout::invalidate
+120 (int (*)(...))QLayout::geometry
+128 (int (*)(...))QGridLayout::addItem
+136 (int (*)(...))QGridLayout::expandingDirections
+144 (int (*)(...))QGridLayout::minimumSize
+152 (int (*)(...))QGridLayout::maximumSize
+160 (int (*)(...))QGridLayout::setGeometry
+168 (int (*)(...))QGridLayout::itemAt
+176 (int (*)(...))QGridLayout::takeAt
+184 (int (*)(...))QLayout::indexOf
+192 (int (*)(...))QGridLayout::count
+200 (int (*)(...))QLayout::isEmpty
+208 (int (*)(...))QLayout::controlTypes
+216 (int (*)(...))QLayout::layout
+224 (int (*)(...))QGridLayout::sizeHint
+232 (int (*)(...))QGridLayout::hasHeightForWidth
+240 (int (*)(...))QGridLayout::heightForWidth
+248 (int (*)(...))QGridLayout::minimumHeightForWidth
+256 (int (*)(...))-16
+264 (int (*)(...))(& _ZTI11QGridLayout)
+272 (int (*)(...))QGridLayout::_ZThn16_N11QGridLayoutD1Ev
+280 (int (*)(...))QGridLayout::_ZThn16_N11QGridLayoutD0Ev
+288 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout8sizeHintEv
+296 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout11minimumSizeEv
+304 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout11maximumSizeEv
+312 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout19expandingDirectionsEv
+320 (int (*)(...))QGridLayout::_ZThn16_N11QGridLayout11setGeometryERK5QRect
+328 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv
+336 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv
+344 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout17hasHeightForWidthEv
+352 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout14heightForWidthEi
+360 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout21minimumHeightForWidthEi
+368 (int (*)(...))QGridLayout::_ZThn16_N11QGridLayout10invalidateEv
+376 (int (*)(...))QLayoutItem::widget
+384 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv
+392 (int (*)(...))QLayoutItem::spacerItem
+400 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv
+
+Class QGridLayout
+ size=32 align=8
+ base size=28 base align=8
+QGridLayout (0x0x7f8846955b60) 0
+ vptr=((& QGridLayout::_ZTV11QGridLayout) + 16u)
+ QLayout (0x0x7f8846aa3d90) 0
+ primary-for QGridLayout (0x0x7f8846955b60)
+ QObject (0x0x7f8846950f60) 0
+ primary-for QLayout (0x0x7f8846aa3d90)
+ QLayoutItem (0x0x7f8846ad0000) 16
+ vptr=((& QGridLayout::_ZTV11QGridLayout) + 272u)
+
+Class QBoxLayout::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QBoxLayout::QPrivateSignal (0x0x7f8846ad0180) 0 empty
+
+Vtable for QBoxLayout
+QBoxLayout::_ZTV10QBoxLayout: 51u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QBoxLayout)
+16 (int (*)(...))QBoxLayout::metaObject
+24 (int (*)(...))QBoxLayout::qt_metacast
+32 (int (*)(...))QBoxLayout::qt_metacall
+40 (int (*)(...))QBoxLayout::~QBoxLayout
+48 (int (*)(...))QBoxLayout::~QBoxLayout
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QLayout::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QBoxLayout::invalidate
+120 (int (*)(...))QLayout::geometry
+128 (int (*)(...))QBoxLayout::addItem
+136 (int (*)(...))QBoxLayout::expandingDirections
+144 (int (*)(...))QBoxLayout::minimumSize
+152 (int (*)(...))QBoxLayout::maximumSize
+160 (int (*)(...))QBoxLayout::setGeometry
+168 (int (*)(...))QBoxLayout::itemAt
+176 (int (*)(...))QBoxLayout::takeAt
+184 (int (*)(...))QLayout::indexOf
+192 (int (*)(...))QBoxLayout::count
+200 (int (*)(...))QLayout::isEmpty
+208 (int (*)(...))QLayout::controlTypes
+216 (int (*)(...))QLayout::layout
+224 (int (*)(...))QBoxLayout::sizeHint
+232 (int (*)(...))QBoxLayout::hasHeightForWidth
+240 (int (*)(...))QBoxLayout::heightForWidth
+248 (int (*)(...))QBoxLayout::minimumHeightForWidth
+256 (int (*)(...))-16
+264 (int (*)(...))(& _ZTI10QBoxLayout)
+272 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayoutD1Ev
+280 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayoutD0Ev
+288 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout8sizeHintEv
+296 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11minimumSizeEv
+304 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11maximumSizeEv
+312 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout19expandingDirectionsEv
+320 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout11setGeometryERK5QRect
+328 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv
+336 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv
+344 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout17hasHeightForWidthEv
+352 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout14heightForWidthEi
+360 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout21minimumHeightForWidthEi
+368 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout10invalidateEv
+376 (int (*)(...))QLayoutItem::widget
+384 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv
+392 (int (*)(...))QLayoutItem::spacerItem
+400 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv
+
+Class QBoxLayout
+ size=32 align=8
+ base size=28 base align=8
+QBoxLayout (0x0x7f8846955bc8) 0
+ vptr=((& QBoxLayout::_ZTV10QBoxLayout) + 16u)
+ QLayout (0x0x7f8846aeb5b0) 0
+ primary-for QBoxLayout (0x0x7f8846955bc8)
+ QObject (0x0x7f8846ad00c0) 0
+ primary-for QLayout (0x0x7f8846aeb5b0)
+ QLayoutItem (0x0x7f8846ad0120) 16
+ vptr=((& QBoxLayout::_ZTV10QBoxLayout) + 272u)
+
+Class QHBoxLayout::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QHBoxLayout::QPrivateSignal (0x0x7f8846ad02a0) 0 empty
+
+Vtable for QHBoxLayout
+QHBoxLayout::_ZTV11QHBoxLayout: 51u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QHBoxLayout)
+16 (int (*)(...))QHBoxLayout::metaObject
+24 (int (*)(...))QHBoxLayout::qt_metacast
+32 (int (*)(...))QHBoxLayout::qt_metacall
+40 (int (*)(...))QHBoxLayout::~QHBoxLayout
+48 (int (*)(...))QHBoxLayout::~QHBoxLayout
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QLayout::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QBoxLayout::invalidate
+120 (int (*)(...))QLayout::geometry
+128 (int (*)(...))QBoxLayout::addItem
+136 (int (*)(...))QBoxLayout::expandingDirections
+144 (int (*)(...))QBoxLayout::minimumSize
+152 (int (*)(...))QBoxLayout::maximumSize
+160 (int (*)(...))QBoxLayout::setGeometry
+168 (int (*)(...))QBoxLayout::itemAt
+176 (int (*)(...))QBoxLayout::takeAt
+184 (int (*)(...))QLayout::indexOf
+192 (int (*)(...))QBoxLayout::count
+200 (int (*)(...))QLayout::isEmpty
+208 (int (*)(...))QLayout::controlTypes
+216 (int (*)(...))QLayout::layout
+224 (int (*)(...))QBoxLayout::sizeHint
+232 (int (*)(...))QBoxLayout::hasHeightForWidth
+240 (int (*)(...))QBoxLayout::heightForWidth
+248 (int (*)(...))QBoxLayout::minimumHeightForWidth
+256 (int (*)(...))-16
+264 (int (*)(...))(& _ZTI11QHBoxLayout)
+272 (int (*)(...))QHBoxLayout::_ZThn16_N11QHBoxLayoutD1Ev
+280 (int (*)(...))QHBoxLayout::_ZThn16_N11QHBoxLayoutD0Ev
+288 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout8sizeHintEv
+296 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11minimumSizeEv
+304 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11maximumSizeEv
+312 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout19expandingDirectionsEv
+320 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout11setGeometryERK5QRect
+328 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv
+336 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv
+344 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout17hasHeightForWidthEv
+352 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout14heightForWidthEi
+360 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout21minimumHeightForWidthEi
+368 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout10invalidateEv
+376 (int (*)(...))QLayoutItem::widget
+384 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv
+392 (int (*)(...))QLayoutItem::spacerItem
+400 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv
+
+Class QHBoxLayout
+ size=32 align=8
+ base size=28 base align=8
+QHBoxLayout (0x0x7f8846955c98) 0
+ vptr=((& QHBoxLayout::_ZTV11QHBoxLayout) + 16u)
+ QBoxLayout (0x0x7f8846955d00) 0
+ primary-for QHBoxLayout (0x0x7f8846955c98)
+ QLayout (0x0x7f8846aebe00) 0
+ primary-for QBoxLayout (0x0x7f8846955d00)
+ QObject (0x0x7f8846ad01e0) 0
+ primary-for QLayout (0x0x7f8846aebe00)
+ QLayoutItem (0x0x7f8846ad0240) 16
+ vptr=((& QHBoxLayout::_ZTV11QHBoxLayout) + 272u)
+
+Class QVBoxLayout::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QVBoxLayout::QPrivateSignal (0x0x7f8846ad03c0) 0 empty
+
+Vtable for QVBoxLayout
+QVBoxLayout::_ZTV11QVBoxLayout: 51u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QVBoxLayout)
+16 (int (*)(...))QVBoxLayout::metaObject
+24 (int (*)(...))QVBoxLayout::qt_metacast
+32 (int (*)(...))QVBoxLayout::qt_metacall
+40 (int (*)(...))QVBoxLayout::~QVBoxLayout
+48 (int (*)(...))QVBoxLayout::~QVBoxLayout
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QLayout::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QBoxLayout::invalidate
+120 (int (*)(...))QLayout::geometry
+128 (int (*)(...))QBoxLayout::addItem
+136 (int (*)(...))QBoxLayout::expandingDirections
+144 (int (*)(...))QBoxLayout::minimumSize
+152 (int (*)(...))QBoxLayout::maximumSize
+160 (int (*)(...))QBoxLayout::setGeometry
+168 (int (*)(...))QBoxLayout::itemAt
+176 (int (*)(...))QBoxLayout::takeAt
+184 (int (*)(...))QLayout::indexOf
+192 (int (*)(...))QBoxLayout::count
+200 (int (*)(...))QLayout::isEmpty
+208 (int (*)(...))QLayout::controlTypes
+216 (int (*)(...))QLayout::layout
+224 (int (*)(...))QBoxLayout::sizeHint
+232 (int (*)(...))QBoxLayout::hasHeightForWidth
+240 (int (*)(...))QBoxLayout::heightForWidth
+248 (int (*)(...))QBoxLayout::minimumHeightForWidth
+256 (int (*)(...))-16
+264 (int (*)(...))(& _ZTI11QVBoxLayout)
+272 (int (*)(...))QVBoxLayout::_ZThn16_N11QVBoxLayoutD1Ev
+280 (int (*)(...))QVBoxLayout::_ZThn16_N11QVBoxLayoutD0Ev
+288 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout8sizeHintEv
+296 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11minimumSizeEv
+304 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11maximumSizeEv
+312 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout19expandingDirectionsEv
+320 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout11setGeometryERK5QRect
+328 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv
+336 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv
+344 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout17hasHeightForWidthEv
+352 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout14heightForWidthEi
+360 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout21minimumHeightForWidthEi
+368 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout10invalidateEv
+376 (int (*)(...))QLayoutItem::widget
+384 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv
+392 (int (*)(...))QLayoutItem::spacerItem
+400 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv
+
+Class QVBoxLayout
+ size=32 align=8
+ base size=28 base align=8
+QVBoxLayout (0x0x7f8846955d68) 0
+ vptr=((& QVBoxLayout::_ZTV11QVBoxLayout) + 16u)
+ QBoxLayout (0x0x7f8846955dd0) 0
+ primary-for QVBoxLayout (0x0x7f8846955d68)
+ QLayout (0x0x7f8846b18150) 0
+ primary-for QBoxLayout (0x0x7f8846955dd0)
+ QObject (0x0x7f8846ad0300) 0
+ primary-for QLayout (0x0x7f8846b18150)
+ QLayoutItem (0x0x7f8846ad0360) 16
+ vptr=((& QVBoxLayout::_ZTV11QVBoxLayout) + 272u)
+
+Class QButtonGroup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QButtonGroup::QPrivateSignal (0x0x7f8846ad0480) 0 empty
+
+Vtable for QButtonGroup
+QButtonGroup::_ZTV12QButtonGroup: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QButtonGroup)
+16 (int (*)(...))QButtonGroup::metaObject
+24 (int (*)(...))QButtonGroup::qt_metacast
+32 (int (*)(...))QButtonGroup::qt_metacall
+40 (int (*)(...))QButtonGroup::~QButtonGroup
+48 (int (*)(...))QButtonGroup::~QButtonGroup
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QButtonGroup
+ size=16 align=8
+ base size=16 base align=8
+QButtonGroup (0x0x7f8846955e38) 0
+ vptr=((& QButtonGroup::_ZTV12QButtonGroup) + 16u)
+ QObject (0x0x7f8846ad0420) 0
+ primary-for QButtonGroup (0x0x7f8846955e38)
+
+Class QCalendarWidget::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QCalendarWidget::QPrivateSignal (0x0x7f8846ad05a0) 0 empty
+
+Vtable for QCalendarWidget
+QCalendarWidget::_ZTV15QCalendarWidget: 65u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QCalendarWidget)
+16 (int (*)(...))QCalendarWidget::metaObject
+24 (int (*)(...))QCalendarWidget::qt_metacast
+32 (int (*)(...))QCalendarWidget::qt_metacall
+40 (int (*)(...))QCalendarWidget::~QCalendarWidget
+48 (int (*)(...))QCalendarWidget::~QCalendarWidget
+56 (int (*)(...))QCalendarWidget::event
+64 (int (*)(...))QCalendarWidget::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QCalendarWidget::sizeHint
+136 (int (*)(...))QCalendarWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QCalendarWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QCalendarWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QCalendarWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QCalendarWidget::paintCell
+440 (int (*)(...))-16
+448 (int (*)(...))(& _ZTI15QCalendarWidget)
+456 (int (*)(...))QCalendarWidget::_ZThn16_N15QCalendarWidgetD1Ev
+464 (int (*)(...))QCalendarWidget::_ZThn16_N15QCalendarWidgetD0Ev
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QCalendarWidget
+ size=48 align=8
+ base size=48 base align=8
+QCalendarWidget (0x0x7f8846955ea0) 0
+ vptr=((& QCalendarWidget::_ZTV15QCalendarWidget) + 16u)
+ QWidget (0x0x7f8846b188c0) 0
+ primary-for QCalendarWidget (0x0x7f8846955ea0)
+ QObject (0x0x7f8846ad04e0) 0
+ primary-for QWidget (0x0x7f8846b188c0)
+ QPaintDevice (0x0x7f8846ad0540) 16
+ vptr=((& QCalendarWidget::_ZTV15QCalendarWidget) + 456u)
+
+Class QCheckBox::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QCheckBox::QPrivateSignal (0x0x7f8846ad06c0) 0 empty
+
+Vtable for QCheckBox
+QCheckBox::_ZTV9QCheckBox: 67u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QCheckBox)
+16 (int (*)(...))QCheckBox::metaObject
+24 (int (*)(...))QCheckBox::qt_metacast
+32 (int (*)(...))QCheckBox::qt_metacall
+40 (int (*)(...))QCheckBox::~QCheckBox
+48 (int (*)(...))QCheckBox::~QCheckBox
+56 (int (*)(...))QCheckBox::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractButton::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QCheckBox::sizeHint
+136 (int (*)(...))QCheckBox::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractButton::mousePressEvent
+176 (int (*)(...))QAbstractButton::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QCheckBox::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QAbstractButton::keyPressEvent
+216 (int (*)(...))QAbstractButton::keyReleaseEvent
+224 (int (*)(...))QAbstractButton::focusInEvent
+232 (int (*)(...))QAbstractButton::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QCheckBox::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractButton::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QCheckBox::hitButton
+440 (int (*)(...))QCheckBox::checkStateSet
+448 (int (*)(...))QCheckBox::nextCheckState
+456 (int (*)(...))-16
+464 (int (*)(...))(& _ZTI9QCheckBox)
+472 (int (*)(...))QCheckBox::_ZThn16_N9QCheckBoxD1Ev
+480 (int (*)(...))QCheckBox::_ZThn16_N9QCheckBoxD0Ev
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QCheckBox
+ size=48 align=8
+ base size=48 base align=8
+QCheckBox (0x0x7f8846955f08) 0
+ vptr=((& QCheckBox::_ZTV9QCheckBox) + 16u)
+ QAbstractButton (0x0x7f8846955f70) 0
+ primary-for QCheckBox (0x0x7f8846955f08)
+ QWidget (0x0x7f8846759690) 0
+ primary-for QAbstractButton (0x0x7f8846955f70)
+ QObject (0x0x7f8846ad0600) 0
+ primary-for QWidget (0x0x7f8846759690)
+ QPaintDevice (0x0x7f8846ad0660) 16
+ vptr=((& QCheckBox::_ZTV9QCheckBox) + 472u)
+
+Class QDialog::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDialog::QPrivateSignal (0x0x7f8846ad07e0) 0 empty
+
+Vtable for QDialog
+QDialog::_ZTV7QDialog: 69u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QDialog)
+16 (int (*)(...))QDialog::metaObject
+24 (int (*)(...))QDialog::qt_metacast
+32 (int (*)(...))QDialog::qt_metacall
+40 (int (*)(...))QDialog::~QDialog
+48 (int (*)(...))QDialog::~QDialog
+56 (int (*)(...))QWidget::event
+64 (int (*)(...))QDialog::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QDialog::setVisible
+128 (int (*)(...))QDialog::sizeHint
+136 (int (*)(...))QDialog::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QDialog::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QDialog::resizeEvent
+280 (int (*)(...))QDialog::closeEvent
+288 (int (*)(...))QDialog::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QDialog::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QDialog::open
+440 (int (*)(...))QDialog::exec
+448 (int (*)(...))QDialog::done
+456 (int (*)(...))QDialog::accept
+464 (int (*)(...))QDialog::reject
+472 (int (*)(...))-16
+480 (int (*)(...))(& _ZTI7QDialog)
+488 (int (*)(...))QDialog::_ZThn16_N7QDialogD1Ev
+496 (int (*)(...))QDialog::_ZThn16_N7QDialogD0Ev
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QDialog
+ size=48 align=8
+ base size=48 base align=8
+QDialog (0x0x7f884676f000) 0
+ vptr=((& QDialog::_ZTV7QDialog) + 16u)
+ QWidget (0x0x7f8846759b60) 0
+ primary-for QDialog (0x0x7f884676f000)
+ QObject (0x0x7f8846ad0720) 0
+ primary-for QWidget (0x0x7f8846759b60)
+ QPaintDevice (0x0x7f8846ad0780) 16
+ vptr=((& QDialog::_ZTV7QDialog) + 488u)
+
+Class QColorDialog::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QColorDialog::QPrivateSignal (0x0x7f8846ad0900) 0 empty
+
+Vtable for QColorDialog
+QColorDialog::_ZTV12QColorDialog: 69u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QColorDialog)
+16 (int (*)(...))QColorDialog::metaObject
+24 (int (*)(...))QColorDialog::qt_metacast
+32 (int (*)(...))QColorDialog::qt_metacall
+40 (int (*)(...))QColorDialog::~QColorDialog
+48 (int (*)(...))QColorDialog::~QColorDialog
+56 (int (*)(...))QWidget::event
+64 (int (*)(...))QDialog::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QColorDialog::setVisible
+128 (int (*)(...))QDialog::sizeHint
+136 (int (*)(...))QDialog::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QDialog::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QDialog::resizeEvent
+280 (int (*)(...))QDialog::closeEvent
+288 (int (*)(...))QDialog::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QDialog::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QColorDialog::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QDialog::open
+440 (int (*)(...))QDialog::exec
+448 (int (*)(...))QColorDialog::done
+456 (int (*)(...))QDialog::accept
+464 (int (*)(...))QDialog::reject
+472 (int (*)(...))-16
+480 (int (*)(...))(& _ZTI12QColorDialog)
+488 (int (*)(...))QColorDialog::_ZThn16_N12QColorDialogD1Ev
+496 (int (*)(...))QColorDialog::_ZThn16_N12QColorDialogD0Ev
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QColorDialog
+ size=48 align=8
+ base size=48 base align=8
+QColorDialog (0x0x7f884676f068) 0
+ vptr=((& QColorDialog::_ZTV12QColorDialog) + 16u)
+ QDialog (0x0x7f884676f0d0) 0
+ primary-for QColorDialog (0x0x7f884676f068)
+ QWidget (0x0x7f884678c230) 0
+ primary-for QDialog (0x0x7f884676f0d0)
+ QObject (0x0x7f8846ad0840) 0
+ primary-for QWidget (0x0x7f884678c230)
+ QPaintDevice (0x0x7f8846ad08a0) 16
+ vptr=((& QColorDialog::_ZTV12QColorDialog) + 488u)
+
+Class QColormap
+ size=8 align=8
+ base size=8 base align=8
+QColormap (0x0x7f8846ad0b40) 0
+
+Class QColumnView::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QColumnView::QPrivateSignal (0x0x7f8846ad0c60) 0 empty
+
+Vtable for QColumnView
+QColumnView::_ZTV11QColumnView: 107u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QColumnView)
+16 (int (*)(...))QColumnView::metaObject
+24 (int (*)(...))QColumnView::qt_metacast
+32 (int (*)(...))QColumnView::qt_metacall
+40 (int (*)(...))QColumnView::~QColumnView
+48 (int (*)(...))QColumnView::~QColumnView
+56 (int (*)(...))QAbstractItemView::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QAbstractItemView::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QColumnView::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractItemView::mousePressEvent
+176 (int (*)(...))QAbstractItemView::mouseReleaseEvent
+184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractItemView::mouseMoveEvent
+200 (int (*)(...))QAbstractScrollArea::wheelEvent
+208 (int (*)(...))QAbstractItemView::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QAbstractItemView::focusInEvent
+232 (int (*)(...))QAbstractItemView::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QAbstractScrollArea::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QColumnView::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QAbstractScrollArea::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QAbstractItemView::dragEnterEvent
+320 (int (*)(...))QAbstractItemView::dragMoveEvent
+328 (int (*)(...))QAbstractItemView::dragLeaveEvent
+336 (int (*)(...))QAbstractItemView::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QAbstractItemView::inputMethodEvent
+416 (int (*)(...))QAbstractItemView::inputMethodQuery
+424 (int (*)(...))QAbstractItemView::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QAbstractItemView::viewportEvent
+448 (int (*)(...))QColumnView::scrollContentsBy
+456 (int (*)(...))QAbstractItemView::viewportSizeHint
+464 (int (*)(...))QColumnView::setModel
+472 (int (*)(...))QColumnView::setSelectionModel
+480 (int (*)(...))QAbstractItemView::keyboardSearch
+488 (int (*)(...))QColumnView::visualRect
+496 (int (*)(...))QColumnView::scrollTo
+504 (int (*)(...))QColumnView::indexAt
+512 (int (*)(...))QAbstractItemView::sizeHintForRow
+520 (int (*)(...))QAbstractItemView::sizeHintForColumn
+528 (int (*)(...))QAbstractItemView::reset
+536 (int (*)(...))QColumnView::setRootIndex
+544 (int (*)(...))QAbstractItemView::doItemsLayout
+552 (int (*)(...))QColumnView::selectAll
+560 (int (*)(...))QAbstractItemView::dataChanged
+568 (int (*)(...))QColumnView::rowsInserted
+576 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved
+584 (int (*)(...))QAbstractItemView::selectionChanged
+592 (int (*)(...))QColumnView::currentChanged
+600 (int (*)(...))QAbstractItemView::updateEditorData
+608 (int (*)(...))QAbstractItemView::updateEditorGeometries
+616 (int (*)(...))QAbstractItemView::updateGeometries
+624 (int (*)(...))QAbstractItemView::verticalScrollbarAction
+632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction
+640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged
+648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged
+656 (int (*)(...))QAbstractItemView::closeEditor
+664 (int (*)(...))QAbstractItemView::commitData
+672 (int (*)(...))QAbstractItemView::editorDestroyed
+680 (int (*)(...))QColumnView::moveCursor
+688 (int (*)(...))QColumnView::horizontalOffset
+696 (int (*)(...))QColumnView::verticalOffset
+704 (int (*)(...))QColumnView::isIndexHidden
+712 (int (*)(...))QColumnView::setSelection
+720 (int (*)(...))QColumnView::visualRegionForSelection
+728 (int (*)(...))QAbstractItemView::selectedIndexes
+736 (int (*)(...))QAbstractItemView::edit
+744 (int (*)(...))QAbstractItemView::selectionCommand
+752 (int (*)(...))QAbstractItemView::startDrag
+760 (int (*)(...))QAbstractItemView::viewOptions
+768 (int (*)(...))QColumnView::createColumn
+776 (int (*)(...))-16
+784 (int (*)(...))(& _ZTI11QColumnView)
+792 (int (*)(...))QColumnView::_ZThn16_N11QColumnViewD1Ev
+800 (int (*)(...))QColumnView::_ZThn16_N11QColumnViewD0Ev
+808 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+816 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+824 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+832 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+840 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+848 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QColumnView
+ size=48 align=8
+ base size=48 base align=8
+QColumnView (0x0x7f884676f208) 0
+ vptr=((& QColumnView::_ZTV11QColumnView) + 16u)
+ QAbstractItemView (0x0x7f884676f270) 0
+ primary-for QColumnView (0x0x7f884676f208)
+ QAbstractScrollArea (0x0x7f884676f2d8) 0
+ primary-for QAbstractItemView (0x0x7f884676f270)
+ QFrame (0x0x7f884676f340) 0
+ primary-for QAbstractScrollArea (0x0x7f884676f2d8)
+ QWidget (0x0x7f88467beee0) 0
+ primary-for QFrame (0x0x7f884676f340)
+ QObject (0x0x7f8846ad0ba0) 0
+ primary-for QWidget (0x0x7f88467beee0)
+ QPaintDevice (0x0x7f8846ad0c00) 16
+ vptr=((& QColumnView::_ZTV11QColumnView) + 792u)
+
+Class QComboBox::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QComboBox::QPrivateSignal (0x0x7f8846ad0d80) 0 empty
+
+Vtable for QComboBox
+QComboBox::_ZTV9QComboBox: 66u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QComboBox)
+16 (int (*)(...))QComboBox::metaObject
+24 (int (*)(...))QComboBox::qt_metacast
+32 (int (*)(...))QComboBox::qt_metacall
+40 (int (*)(...))QComboBox::~QComboBox
+48 (int (*)(...))QComboBox::~QComboBox
+56 (int (*)(...))QComboBox::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QComboBox::sizeHint
+136 (int (*)(...))QComboBox::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QComboBox::mousePressEvent
+176 (int (*)(...))QComboBox::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QComboBox::wheelEvent
+208 (int (*)(...))QComboBox::keyPressEvent
+216 (int (*)(...))QComboBox::keyReleaseEvent
+224 (int (*)(...))QComboBox::focusInEvent
+232 (int (*)(...))QComboBox::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QComboBox::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QComboBox::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QComboBox::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QComboBox::showEvent
+352 (int (*)(...))QComboBox::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QComboBox::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QComboBox::inputMethodEvent
+416 (int (*)(...))QComboBox::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QComboBox::showPopup
+440 (int (*)(...))QComboBox::hidePopup
+448 (int (*)(...))-16
+456 (int (*)(...))(& _ZTI9QComboBox)
+464 (int (*)(...))QComboBox::_ZThn16_N9QComboBoxD1Ev
+472 (int (*)(...))QComboBox::_ZThn16_N9QComboBoxD0Ev
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QComboBox
+ size=48 align=8
+ base size=48 base align=8
+QComboBox (0x0x7f884676f3a8) 0
+ vptr=((& QComboBox::_ZTV9QComboBox) + 16u)
+ QWidget (0x0x7f88467e83f0) 0
+ primary-for QComboBox (0x0x7f884676f3a8)
+ QObject (0x0x7f8846ad0cc0) 0
+ primary-for QWidget (0x0x7f88467e83f0)
+ QPaintDevice (0x0x7f8846ad0d20) 16
+ vptr=((& QComboBox::_ZTV9QComboBox) + 464u)
+
+Class QPushButton::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPushButton::QPrivateSignal (0x0x7f8846ad0ea0) 0 empty
+
+Vtable for QPushButton
+QPushButton::_ZTV11QPushButton: 67u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QPushButton)
+16 (int (*)(...))QPushButton::metaObject
+24 (int (*)(...))QPushButton::qt_metacast
+32 (int (*)(...))QPushButton::qt_metacall
+40 (int (*)(...))QPushButton::~QPushButton
+48 (int (*)(...))QPushButton::~QPushButton
+56 (int (*)(...))QPushButton::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractButton::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QPushButton::sizeHint
+136 (int (*)(...))QPushButton::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractButton::mousePressEvent
+176 (int (*)(...))QAbstractButton::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractButton::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QPushButton::keyPressEvent
+216 (int (*)(...))QAbstractButton::keyReleaseEvent
+224 (int (*)(...))QPushButton::focusInEvent
+232 (int (*)(...))QPushButton::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QPushButton::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractButton::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QAbstractButton::hitButton
+440 (int (*)(...))QAbstractButton::checkStateSet
+448 (int (*)(...))QAbstractButton::nextCheckState
+456 (int (*)(...))-16
+464 (int (*)(...))(& _ZTI11QPushButton)
+472 (int (*)(...))QPushButton::_ZThn16_N11QPushButtonD1Ev
+480 (int (*)(...))QPushButton::_ZThn16_N11QPushButtonD0Ev
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QPushButton
+ size=48 align=8
+ base size=48 base align=8
+QPushButton (0x0x7f884676f410) 0
+ vptr=((& QPushButton::_ZTV11QPushButton) + 16u)
+ QAbstractButton (0x0x7f884676f478) 0
+ primary-for QPushButton (0x0x7f884676f410)
+ QWidget (0x0x7f88468325b0) 0
+ primary-for QAbstractButton (0x0x7f884676f478)
+ QObject (0x0x7f8846ad0de0) 0
+ primary-for QWidget (0x0x7f88468325b0)
+ QPaintDevice (0x0x7f8846ad0e40) 16
+ vptr=((& QPushButton::_ZTV11QPushButton) + 472u)
+
+Class QCommandLinkButton::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QCommandLinkButton::QPrivateSignal (0x0x7f8846855000) 0 empty
+
+Vtable for QCommandLinkButton
+QCommandLinkButton::_ZTV18QCommandLinkButton: 67u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QCommandLinkButton)
+16 (int (*)(...))QCommandLinkButton::metaObject
+24 (int (*)(...))QCommandLinkButton::qt_metacast
+32 (int (*)(...))QCommandLinkButton::qt_metacall
+40 (int (*)(...))QCommandLinkButton::~QCommandLinkButton
+48 (int (*)(...))QCommandLinkButton::~QCommandLinkButton
+56 (int (*)(...))QCommandLinkButton::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractButton::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QCommandLinkButton::sizeHint
+136 (int (*)(...))QCommandLinkButton::minimumSizeHint
+144 (int (*)(...))QCommandLinkButton::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractButton::mousePressEvent
+176 (int (*)(...))QAbstractButton::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractButton::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QPushButton::keyPressEvent
+216 (int (*)(...))QAbstractButton::keyReleaseEvent
+224 (int (*)(...))QPushButton::focusInEvent
+232 (int (*)(...))QPushButton::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QCommandLinkButton::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractButton::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QAbstractButton::hitButton
+440 (int (*)(...))QAbstractButton::checkStateSet
+448 (int (*)(...))QAbstractButton::nextCheckState
+456 (int (*)(...))-16
+464 (int (*)(...))(& _ZTI18QCommandLinkButton)
+472 (int (*)(...))QCommandLinkButton::_ZThn16_N18QCommandLinkButtonD1Ev
+480 (int (*)(...))QCommandLinkButton::_ZThn16_N18QCommandLinkButtonD0Ev
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QCommandLinkButton
+ size=48 align=8
+ base size=48 base align=8
+QCommandLinkButton (0x0x7f884676f4e0) 0
+ vptr=((& QCommandLinkButton::_ZTV18QCommandLinkButton) + 16u)
+ QPushButton (0x0x7f884676f548) 0
+ primary-for QCommandLinkButton (0x0x7f884676f4e0)
+ QAbstractButton (0x0x7f884676f5b0) 0
+ primary-for QPushButton (0x0x7f884676f548)
+ QWidget (0x0x7f8846832a80) 0
+ primary-for QAbstractButton (0x0x7f884676f5b0)
+ QObject (0x0x7f8846ad0f00) 0
+ primary-for QWidget (0x0x7f8846832a80)
+ QPaintDevice (0x0x7f8846ad0f60) 16
+ vptr=((& QCommandLinkButton::_ZTV18QCommandLinkButton) + 472u)
+
+Class QCommonStyle::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QCommonStyle::QPrivateSignal (0x0x7f88468550c0) 0 empty
+
+Vtable for QCommonStyle
+QCommonStyle::_ZTV12QCommonStyle: 37u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QCommonStyle)
+16 (int (*)(...))QCommonStyle::metaObject
+24 (int (*)(...))QCommonStyle::qt_metacast
+32 (int (*)(...))QCommonStyle::qt_metacall
+40 (int (*)(...))QCommonStyle::~QCommonStyle
+48 (int (*)(...))QCommonStyle::~QCommonStyle
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QCommonStyle::polish
+120 (int (*)(...))QCommonStyle::unpolish
+128 (int (*)(...))QCommonStyle::polish
+136 (int (*)(...))QCommonStyle::unpolish
+144 (int (*)(...))QCommonStyle::polish
+152 (int (*)(...))QStyle::itemTextRect
+160 (int (*)(...))QStyle::itemPixmapRect
+168 (int (*)(...))QStyle::drawItemText
+176 (int (*)(...))QStyle::drawItemPixmap
+184 (int (*)(...))QStyle::standardPalette
+192 (int (*)(...))QCommonStyle::drawPrimitive
+200 (int (*)(...))QCommonStyle::drawControl
+208 (int (*)(...))QCommonStyle::subElementRect
+216 (int (*)(...))QCommonStyle::drawComplexControl
+224 (int (*)(...))QCommonStyle::hitTestComplexControl
+232 (int (*)(...))QCommonStyle::subControlRect
+240 (int (*)(...))QCommonStyle::pixelMetric
+248 (int (*)(...))QCommonStyle::sizeFromContents
+256 (int (*)(...))QCommonStyle::styleHint
+264 (int (*)(...))QCommonStyle::standardPixmap
+272 (int (*)(...))QCommonStyle::standardIcon
+280 (int (*)(...))QCommonStyle::generatedIconPixmap
+288 (int (*)(...))QCommonStyle::layoutSpacing
+
+Class QCommonStyle
+ size=16 align=8
+ base size=16 base align=8
+QCommonStyle (0x0x7f884676f618) 0
+ vptr=((& QCommonStyle::_ZTV12QCommonStyle) + 16u)
+ QStyle (0x0x7f884676f680) 0
+ primary-for QCommonStyle (0x0x7f884676f618)
+ QObject (0x0x7f8846855060) 0
+ primary-for QStyle (0x0x7f884676f680)
+
+Class QCompleter::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QCompleter::QPrivateSignal (0x0x7f8846855180) 0 empty
+
+Vtable for QCompleter
+QCompleter::_ZTV10QCompleter: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QCompleter)
+16 (int (*)(...))QCompleter::metaObject
+24 (int (*)(...))QCompleter::qt_metacast
+32 (int (*)(...))QCompleter::qt_metacall
+40 (int (*)(...))QCompleter::~QCompleter
+48 (int (*)(...))QCompleter::~QCompleter
+56 (int (*)(...))QCompleter::event
+64 (int (*)(...))QCompleter::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QCompleter::pathFromIndex
+120 (int (*)(...))QCompleter::splitPath
+
+Class QCompleter
+ size=16 align=8
+ base size=16 base align=8
+QCompleter (0x0x7f884676f6e8) 0
+ vptr=((& QCompleter::_ZTV10QCompleter) + 16u)
+ QObject (0x0x7f8846855120) 0
+ primary-for QCompleter (0x0x7f884676f6e8)
+
+Class QDataWidgetMapper::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDataWidgetMapper::QPrivateSignal (0x0x7f8846855240) 0 empty
+
+Vtable for QDataWidgetMapper
+QDataWidgetMapper::_ZTV17QDataWidgetMapper: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QDataWidgetMapper)
+16 (int (*)(...))QDataWidgetMapper::metaObject
+24 (int (*)(...))QDataWidgetMapper::qt_metacast
+32 (int (*)(...))QDataWidgetMapper::qt_metacall
+40 (int (*)(...))QDataWidgetMapper::~QDataWidgetMapper
+48 (int (*)(...))QDataWidgetMapper::~QDataWidgetMapper
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QDataWidgetMapper::setCurrentIndex
+
+Class QDataWidgetMapper
+ size=16 align=8
+ base size=16 base align=8
+QDataWidgetMapper (0x0x7f884676f750) 0
+ vptr=((& QDataWidgetMapper::_ZTV17QDataWidgetMapper) + 16u)
+ QObject (0x0x7f88468551e0) 0
+ primary-for QDataWidgetMapper (0x0x7f884676f750)
+
+Class QDateTimeEdit::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDateTimeEdit::QPrivateSignal (0x0x7f8846855360) 0 empty
+
+Vtable for QDateTimeEdit
+QDateTimeEdit::_ZTV13QDateTimeEdit: 71u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QDateTimeEdit)
+16 (int (*)(...))QDateTimeEdit::metaObject
+24 (int (*)(...))QDateTimeEdit::qt_metacast
+32 (int (*)(...))QDateTimeEdit::qt_metacall
+40 (int (*)(...))QDateTimeEdit::~QDateTimeEdit
+48 (int (*)(...))QDateTimeEdit::~QDateTimeEdit
+56 (int (*)(...))QDateTimeEdit::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractSpinBox::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QDateTimeEdit::sizeHint
+136 (int (*)(...))QAbstractSpinBox::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QDateTimeEdit::mousePressEvent
+176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent
+200 (int (*)(...))QDateTimeEdit::wheelEvent
+208 (int (*)(...))QDateTimeEdit::keyPressEvent
+216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent
+224 (int (*)(...))QDateTimeEdit::focusInEvent
+232 (int (*)(...))QAbstractSpinBox::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QDateTimeEdit::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QAbstractSpinBox::resizeEvent
+280 (int (*)(...))QAbstractSpinBox::closeEvent
+288 (int (*)(...))QAbstractSpinBox::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QAbstractSpinBox::showEvent
+352 (int (*)(...))QAbstractSpinBox::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractSpinBox::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QAbstractSpinBox::inputMethodQuery
+424 (int (*)(...))QDateTimeEdit::focusNextPrevChild
+432 (int (*)(...))QDateTimeEdit::validate
+440 (int (*)(...))QDateTimeEdit::fixup
+448 (int (*)(...))QDateTimeEdit::stepBy
+456 (int (*)(...))QDateTimeEdit::clear
+464 (int (*)(...))QDateTimeEdit::stepEnabled
+472 (int (*)(...))QDateTimeEdit::dateTimeFromText
+480 (int (*)(...))QDateTimeEdit::textFromDateTime
+488 (int (*)(...))-16
+496 (int (*)(...))(& _ZTI13QDateTimeEdit)
+504 (int (*)(...))QDateTimeEdit::_ZThn16_N13QDateTimeEditD1Ev
+512 (int (*)(...))QDateTimeEdit::_ZThn16_N13QDateTimeEditD0Ev
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QDateTimeEdit
+ size=48 align=8
+ base size=48 base align=8
+QDateTimeEdit (0x0x7f884676f7b8) 0
+ vptr=((& QDateTimeEdit::_ZTV13QDateTimeEdit) + 16u)
+ QAbstractSpinBox (0x0x7f884676f820) 0
+ primary-for QDateTimeEdit (0x0x7f884676f7b8)
+ QWidget (0x0x7f88468ac2a0) 0
+ primary-for QAbstractSpinBox (0x0x7f884676f820)
+ QObject (0x0x7f88468552a0) 0
+ primary-for QWidget (0x0x7f88468ac2a0)
+ QPaintDevice (0x0x7f8846855300) 16
+ vptr=((& QDateTimeEdit::_ZTV13QDateTimeEdit) + 504u)
+
+Class QTimeEdit::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTimeEdit::QPrivateSignal (0x0x7f8846855600) 0 empty
+
+Vtable for QTimeEdit
+QTimeEdit::_ZTV9QTimeEdit: 71u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QTimeEdit)
+16 (int (*)(...))QTimeEdit::metaObject
+24 (int (*)(...))QTimeEdit::qt_metacast
+32 (int (*)(...))QTimeEdit::qt_metacall
+40 (int (*)(...))QTimeEdit::~QTimeEdit
+48 (int (*)(...))QTimeEdit::~QTimeEdit
+56 (int (*)(...))QDateTimeEdit::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractSpinBox::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QDateTimeEdit::sizeHint
+136 (int (*)(...))QAbstractSpinBox::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QDateTimeEdit::mousePressEvent
+176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent
+200 (int (*)(...))QDateTimeEdit::wheelEvent
+208 (int (*)(...))QDateTimeEdit::keyPressEvent
+216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent
+224 (int (*)(...))QDateTimeEdit::focusInEvent
+232 (int (*)(...))QAbstractSpinBox::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QDateTimeEdit::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QAbstractSpinBox::resizeEvent
+280 (int (*)(...))QAbstractSpinBox::closeEvent
+288 (int (*)(...))QAbstractSpinBox::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QAbstractSpinBox::showEvent
+352 (int (*)(...))QAbstractSpinBox::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractSpinBox::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QAbstractSpinBox::inputMethodQuery
+424 (int (*)(...))QDateTimeEdit::focusNextPrevChild
+432 (int (*)(...))QDateTimeEdit::validate
+440 (int (*)(...))QDateTimeEdit::fixup
+448 (int (*)(...))QDateTimeEdit::stepBy
+456 (int (*)(...))QDateTimeEdit::clear
+464 (int (*)(...))QDateTimeEdit::stepEnabled
+472 (int (*)(...))QDateTimeEdit::dateTimeFromText
+480 (int (*)(...))QDateTimeEdit::textFromDateTime
+488 (int (*)(...))-16
+496 (int (*)(...))(& _ZTI9QTimeEdit)
+504 (int (*)(...))QTimeEdit::_ZThn16_N9QTimeEditD1Ev
+512 (int (*)(...))QTimeEdit::_ZThn16_N9QTimeEditD0Ev
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QTimeEdit
+ size=48 align=8
+ base size=48 base align=8
+QTimeEdit (0x0x7f884676f958) 0
+ vptr=((& QTimeEdit::_ZTV9QTimeEdit) + 16u)
+ QDateTimeEdit (0x0x7f884676f9c0) 0
+ primary-for QTimeEdit (0x0x7f884676f958)
+ QAbstractSpinBox (0x0x7f884676fa28) 0
+ primary-for QDateTimeEdit (0x0x7f884676f9c0)
+ QWidget (0x0x7f88468ed1c0) 0
+ primary-for QAbstractSpinBox (0x0x7f884676fa28)
+ QObject (0x0x7f8846855540) 0
+ primary-for QWidget (0x0x7f88468ed1c0)
+ QPaintDevice (0x0x7f88468555a0) 16
+ vptr=((& QTimeEdit::_ZTV9QTimeEdit) + 504u)
+
+Class QDateEdit::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDateEdit::QPrivateSignal (0x0x7f8846855720) 0 empty
+
+Vtable for QDateEdit
+QDateEdit::_ZTV9QDateEdit: 71u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QDateEdit)
+16 (int (*)(...))QDateEdit::metaObject
+24 (int (*)(...))QDateEdit::qt_metacast
+32 (int (*)(...))QDateEdit::qt_metacall
+40 (int (*)(...))QDateEdit::~QDateEdit
+48 (int (*)(...))QDateEdit::~QDateEdit
+56 (int (*)(...))QDateTimeEdit::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractSpinBox::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QDateTimeEdit::sizeHint
+136 (int (*)(...))QAbstractSpinBox::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QDateTimeEdit::mousePressEvent
+176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent
+200 (int (*)(...))QDateTimeEdit::wheelEvent
+208 (int (*)(...))QDateTimeEdit::keyPressEvent
+216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent
+224 (int (*)(...))QDateTimeEdit::focusInEvent
+232 (int (*)(...))QAbstractSpinBox::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QDateTimeEdit::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QAbstractSpinBox::resizeEvent
+280 (int (*)(...))QAbstractSpinBox::closeEvent
+288 (int (*)(...))QAbstractSpinBox::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QAbstractSpinBox::showEvent
+352 (int (*)(...))QAbstractSpinBox::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractSpinBox::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QAbstractSpinBox::inputMethodQuery
+424 (int (*)(...))QDateTimeEdit::focusNextPrevChild
+432 (int (*)(...))QDateTimeEdit::validate
+440 (int (*)(...))QDateTimeEdit::fixup
+448 (int (*)(...))QDateTimeEdit::stepBy
+456 (int (*)(...))QDateTimeEdit::clear
+464 (int (*)(...))QDateTimeEdit::stepEnabled
+472 (int (*)(...))QDateTimeEdit::dateTimeFromText
+480 (int (*)(...))QDateTimeEdit::textFromDateTime
+488 (int (*)(...))-16
+496 (int (*)(...))(& _ZTI9QDateEdit)
+504 (int (*)(...))QDateEdit::_ZThn16_N9QDateEditD1Ev
+512 (int (*)(...))QDateEdit::_ZThn16_N9QDateEditD0Ev
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QDateEdit
+ size=48 align=8
+ base size=48 base align=8
+QDateEdit (0x0x7f884676fa90) 0
+ vptr=((& QDateEdit::_ZTV9QDateEdit) + 16u)
+ QDateTimeEdit (0x0x7f884676faf8) 0
+ primary-for QDateEdit (0x0x7f884676fa90)
+ QAbstractSpinBox (0x0x7f884676fb60) 0
+ primary-for QDateTimeEdit (0x0x7f884676faf8)
+ QWidget (0x0x7f88468ed4d0) 0
+ primary-for QAbstractSpinBox (0x0x7f884676fb60)
+ QObject (0x0x7f8846855660) 0
+ primary-for QWidget (0x0x7f88468ed4d0)
+ QPaintDevice (0x0x7f88468556c0) 16
+ vptr=((& QDateEdit::_ZTV9QDateEdit) + 504u)
+
+Class QDesktopWidget::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDesktopWidget::QPrivateSignal (0x0x7f8846855840) 0 empty
+
+Vtable for QDesktopWidget
+QDesktopWidget::_ZTV14QDesktopWidget: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QDesktopWidget)
+16 (int (*)(...))QDesktopWidget::metaObject
+24 (int (*)(...))QDesktopWidget::qt_metacast
+32 (int (*)(...))QDesktopWidget::qt_metacall
+40 (int (*)(...))QDesktopWidget::~QDesktopWidget
+48 (int (*)(...))QDesktopWidget::~QDesktopWidget
+56 (int (*)(...))QWidget::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QDesktopWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI14QDesktopWidget)
+448 (int (*)(...))QDesktopWidget::_ZThn16_N14QDesktopWidgetD1Ev
+456 (int (*)(...))QDesktopWidget::_ZThn16_N14QDesktopWidgetD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QDesktopWidget
+ size=48 align=8
+ base size=48 base align=8
+QDesktopWidget (0x0x7f884676fbc8) 0
+ vptr=((& QDesktopWidget::_ZTV14QDesktopWidget) + 16u)
+ QWidget (0x0x7f884651b460) 0
+ primary-for QDesktopWidget (0x0x7f884676fbc8)
+ QObject (0x0x7f8846855780) 0
+ primary-for QWidget (0x0x7f884651b460)
+ QPaintDevice (0x0x7f88468557e0) 16
+ vptr=((& QDesktopWidget::_ZTV14QDesktopWidget) + 448u)
+
+Class QDial::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDial::QPrivateSignal (0x0x7f8846855960) 0 empty
+
+Vtable for QDial
+QDial::_ZTV5QDial: 65u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI5QDial)
+16 (int (*)(...))QDial::metaObject
+24 (int (*)(...))QDial::qt_metacast
+32 (int (*)(...))QDial::qt_metacall
+40 (int (*)(...))QDial::~QDial
+48 (int (*)(...))QDial::~QDial
+56 (int (*)(...))QDial::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractSlider::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QDial::sizeHint
+136 (int (*)(...))QDial::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QDial::mousePressEvent
+176 (int (*)(...))QDial::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QDial::mouseMoveEvent
+200 (int (*)(...))QAbstractSlider::wheelEvent
+208 (int (*)(...))QAbstractSlider::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QDial::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QDial::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractSlider::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QDial::sliderChange
+440 (int (*)(...))-16
+448 (int (*)(...))(& _ZTI5QDial)
+456 (int (*)(...))QDial::_ZThn16_N5QDialD1Ev
+464 (int (*)(...))QDial::_ZThn16_N5QDialD0Ev
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QDial
+ size=48 align=8
+ base size=48 base align=8
+QDial (0x0x7f884676fc30) 0
+ vptr=((& QDial::_ZTV5QDial) + 16u)
+ QAbstractSlider (0x0x7f884676fc98) 0
+ primary-for QDial (0x0x7f884676fc30)
+ QWidget (0x0x7f884651bbd0) 0
+ primary-for QAbstractSlider (0x0x7f884676fc98)
+ QObject (0x0x7f88468558a0) 0
+ primary-for QWidget (0x0x7f884651bbd0)
+ QPaintDevice (0x0x7f8846855900) 16
+ vptr=((& QDial::_ZTV5QDial) + 456u)
+
+Class QDialogButtonBox::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDialogButtonBox::QPrivateSignal (0x0x7f8846855a80) 0 empty
+
+Vtable for QDialogButtonBox
+QDialogButtonBox::_ZTV16QDialogButtonBox: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QDialogButtonBox)
+16 (int (*)(...))QDialogButtonBox::metaObject
+24 (int (*)(...))QDialogButtonBox::qt_metacast
+32 (int (*)(...))QDialogButtonBox::qt_metacall
+40 (int (*)(...))QDialogButtonBox::~QDialogButtonBox
+48 (int (*)(...))QDialogButtonBox::~QDialogButtonBox
+56 (int (*)(...))QDialogButtonBox::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QDialogButtonBox::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI16QDialogButtonBox)
+448 (int (*)(...))QDialogButtonBox::_ZThn16_N16QDialogButtonBoxD1Ev
+456 (int (*)(...))QDialogButtonBox::_ZThn16_N16QDialogButtonBoxD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QDialogButtonBox
+ size=48 align=8
+ base size=48 base align=8
+QDialogButtonBox (0x0x7f884676fd00) 0
+ vptr=((& QDialogButtonBox::_ZTV16QDialogButtonBox) + 16u)
+ QWidget (0x0x7f88465550e0) 0
+ primary-for QDialogButtonBox (0x0x7f884676fd00)
+ QObject (0x0x7f88468559c0) 0
+ primary-for QWidget (0x0x7f88465550e0)
+ QPaintDevice (0x0x7f8846855a20) 16
+ vptr=((& QDialogButtonBox::_ZTV16QDialogButtonBox) + 448u)
+
+Vtable for QFileIconProvider
+QFileIconProvider::_ZTV17QFileIconProvider: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QFileIconProvider)
+16 (int (*)(...))QFileIconProvider::~QFileIconProvider
+24 (int (*)(...))QFileIconProvider::~QFileIconProvider
+32 (int (*)(...))QFileIconProvider::icon
+40 (int (*)(...))QFileIconProvider::icon
+48 (int (*)(...))QFileIconProvider::type
+
+Class QFileIconProvider
+ size=16 align=8
+ base size=16 base align=8
+QFileIconProvider (0x0x7f8846855c60) 0
+ vptr=((& QFileIconProvider::_ZTV17QFileIconProvider) + 16u)
+
+Class QDirModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDirModel::QPrivateSignal (0x0x7f8846855f60) 0 empty
+
+Vtable for QDirModel
+QDirModel::_ZTV9QDirModel: 48u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QDirModel)
+16 (int (*)(...))QDirModel::metaObject
+24 (int (*)(...))QDirModel::qt_metacast
+32 (int (*)(...))QDirModel::qt_metacall
+40 (int (*)(...))QDirModel::~QDirModel
+48 (int (*)(...))QDirModel::~QDirModel
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QDirModel::index
+120 (int (*)(...))QDirModel::parent
+128 (int (*)(...))QAbstractItemModel::sibling
+136 (int (*)(...))QDirModel::rowCount
+144 (int (*)(...))QDirModel::columnCount
+152 (int (*)(...))QDirModel::hasChildren
+160 (int (*)(...))QDirModel::data
+168 (int (*)(...))QDirModel::setData
+176 (int (*)(...))QDirModel::headerData
+184 (int (*)(...))QAbstractItemModel::setHeaderData
+192 (int (*)(...))QAbstractItemModel::itemData
+200 (int (*)(...))QAbstractItemModel::setItemData
+208 (int (*)(...))QDirModel::mimeTypes
+216 (int (*)(...))QDirModel::mimeData
+224 (int (*)(...))QAbstractItemModel::canDropMimeData
+232 (int (*)(...))QDirModel::dropMimeData
+240 (int (*)(...))QDirModel::supportedDropActions
+248 (int (*)(...))QAbstractItemModel::supportedDragActions
+256 (int (*)(...))QAbstractItemModel::insertRows
+264 (int (*)(...))QAbstractItemModel::insertColumns
+272 (int (*)(...))QAbstractItemModel::removeRows
+280 (int (*)(...))QAbstractItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractItemModel::fetchMore
+312 (int (*)(...))QAbstractItemModel::canFetchMore
+320 (int (*)(...))QDirModel::flags
+328 (int (*)(...))QDirModel::sort
+336 (int (*)(...))QAbstractItemModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractItemModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractItemModel::submit
+376 (int (*)(...))QAbstractItemModel::revert
+
+Class QDirModel
+ size=16 align=8
+ base size=16 base align=8
+QDirModel (0x0x7f884676ff08) 0
+ vptr=((& QDirModel::_ZTV9QDirModel) + 16u)
+ QAbstractItemModel (0x0x7f884676ff70) 0
+ primary-for QDirModel (0x0x7f884676ff08)
+ QObject (0x0x7f8846855f00) 0
+ primary-for QAbstractItemModel (0x0x7f884676ff70)
+
+Class QDockWidget::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDockWidget::QPrivateSignal (0x0x7f88466130c0) 0 empty
+
+Vtable for QDockWidget
+QDockWidget::_ZTV11QDockWidget: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QDockWidget)
+16 (int (*)(...))QDockWidget::metaObject
+24 (int (*)(...))QDockWidget::qt_metacast
+32 (int (*)(...))QDockWidget::qt_metacall
+40 (int (*)(...))QDockWidget::~QDockWidget
+48 (int (*)(...))QDockWidget::~QDockWidget
+56 (int (*)(...))QDockWidget::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QDockWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QDockWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QDockWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI11QDockWidget)
+448 (int (*)(...))QDockWidget::_ZThn16_N11QDockWidgetD1Ev
+456 (int (*)(...))QDockWidget::_ZThn16_N11QDockWidgetD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QDockWidget
+ size=48 align=8
+ base size=48 base align=8
+QDockWidget (0x0x7f8846612000) 0
+ vptr=((& QDockWidget::_ZTV11QDockWidget) + 16u)
+ QWidget (0x0x7f884660f0e0) 0
+ primary-for QDockWidget (0x0x7f8846612000)
+ QObject (0x0x7f8846613000) 0
+ primary-for QWidget (0x0x7f884660f0e0)
+ QPaintDevice (0x0x7f8846613060) 16
+ vptr=((& QDockWidget::_ZTV11QDockWidget) + 448u)
+
+Class QTileRules
+ size=8 align=4
+ base size=8 base align=4
+QTileRules (0x0x7f8846613720) 0
+
+Class QErrorMessage::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QErrorMessage::QPrivateSignal (0x0x7f88466139c0) 0 empty
+
+Vtable for QErrorMessage
+QErrorMessage::_ZTV13QErrorMessage: 69u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QErrorMessage)
+16 (int (*)(...))QErrorMessage::metaObject
+24 (int (*)(...))QErrorMessage::qt_metacast
+32 (int (*)(...))QErrorMessage::qt_metacall
+40 (int (*)(...))QErrorMessage::~QErrorMessage
+48 (int (*)(...))QErrorMessage::~QErrorMessage
+56 (int (*)(...))QWidget::event
+64 (int (*)(...))QDialog::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QDialog::setVisible
+128 (int (*)(...))QDialog::sizeHint
+136 (int (*)(...))QDialog::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QDialog::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QDialog::resizeEvent
+280 (int (*)(...))QDialog::closeEvent
+288 (int (*)(...))QDialog::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QDialog::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QErrorMessage::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QDialog::open
+440 (int (*)(...))QDialog::exec
+448 (int (*)(...))QErrorMessage::done
+456 (int (*)(...))QDialog::accept
+464 (int (*)(...))QDialog::reject
+472 (int (*)(...))-16
+480 (int (*)(...))(& _ZTI13QErrorMessage)
+488 (int (*)(...))QErrorMessage::_ZThn16_N13QErrorMessageD1Ev
+496 (int (*)(...))QErrorMessage::_ZThn16_N13QErrorMessageD0Ev
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QErrorMessage
+ size=48 align=8
+ base size=48 base align=8
+QErrorMessage (0x0x7f88466126e8) 0
+ vptr=((& QErrorMessage::_ZTV13QErrorMessage) + 16u)
+ QDialog (0x0x7f8846612750) 0
+ primary-for QErrorMessage (0x0x7f88466126e8)
+ QWidget (0x0x7f8846683850) 0
+ primary-for QDialog (0x0x7f8846612750)
+ QObject (0x0x7f8846613900) 0
+ primary-for QWidget (0x0x7f8846683850)
+ QPaintDevice (0x0x7f8846613960) 16
+ vptr=((& QErrorMessage::_ZTV13QErrorMessage) + 488u)
+
+Class QFileDialog::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFileDialog::QPrivateSignal (0x0x7f8846613ae0) 0 empty
+
+Vtable for QFileDialog
+QFileDialog::_ZTV11QFileDialog: 69u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QFileDialog)
+16 (int (*)(...))QFileDialog::metaObject
+24 (int (*)(...))QFileDialog::qt_metacast
+32 (int (*)(...))QFileDialog::qt_metacall
+40 (int (*)(...))QFileDialog::~QFileDialog
+48 (int (*)(...))QFileDialog::~QFileDialog
+56 (int (*)(...))QWidget::event
+64 (int (*)(...))QDialog::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QFileDialog::setVisible
+128 (int (*)(...))QDialog::sizeHint
+136 (int (*)(...))QDialog::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QDialog::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QDialog::resizeEvent
+280 (int (*)(...))QDialog::closeEvent
+288 (int (*)(...))QDialog::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QDialog::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFileDialog::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QDialog::open
+440 (int (*)(...))QDialog::exec
+448 (int (*)(...))QFileDialog::done
+456 (int (*)(...))QFileDialog::accept
+464 (int (*)(...))QDialog::reject
+472 (int (*)(...))-16
+480 (int (*)(...))(& _ZTI11QFileDialog)
+488 (int (*)(...))QFileDialog::_ZThn16_N11QFileDialogD1Ev
+496 (int (*)(...))QFileDialog::_ZThn16_N11QFileDialogD0Ev
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QFileDialog
+ size=48 align=8
+ base size=48 base align=8
+QFileDialog (0x0x7f88466127b8) 0
+ vptr=((& QFileDialog::_ZTV11QFileDialog) + 16u)
+ QDialog (0x0x7f8846612820) 0
+ primary-for QFileDialog (0x0x7f88466127b8)
+ QWidget (0x0x7f8846683d20) 0
+ primary-for QDialog (0x0x7f8846612820)
+ QObject (0x0x7f8846613a20) 0
+ primary-for QWidget (0x0x7f8846683d20)
+ QPaintDevice (0x0x7f8846613a80) 16
+ vptr=((& QFileDialog::_ZTV11QFileDialog) + 488u)
+
+Class QFileSystemModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFileSystemModel::QPrivateSignal (0x0x7f8846613d20) 0 empty
+
+Vtable for QFileSystemModel
+QFileSystemModel::_ZTV16QFileSystemModel: 48u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QFileSystemModel)
+16 (int (*)(...))QFileSystemModel::metaObject
+24 (int (*)(...))QFileSystemModel::qt_metacast
+32 (int (*)(...))QFileSystemModel::qt_metacall
+40 (int (*)(...))QFileSystemModel::~QFileSystemModel
+48 (int (*)(...))QFileSystemModel::~QFileSystemModel
+56 (int (*)(...))QFileSystemModel::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QFileSystemModel::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QFileSystemModel::index
+120 (int (*)(...))QFileSystemModel::parent
+128 (int (*)(...))QFileSystemModel::sibling
+136 (int (*)(...))QFileSystemModel::rowCount
+144 (int (*)(...))QFileSystemModel::columnCount
+152 (int (*)(...))QFileSystemModel::hasChildren
+160 (int (*)(...))QFileSystemModel::data
+168 (int (*)(...))QFileSystemModel::setData
+176 (int (*)(...))QFileSystemModel::headerData
+184 (int (*)(...))QAbstractItemModel::setHeaderData
+192 (int (*)(...))QAbstractItemModel::itemData
+200 (int (*)(...))QAbstractItemModel::setItemData
+208 (int (*)(...))QFileSystemModel::mimeTypes
+216 (int (*)(...))QFileSystemModel::mimeData
+224 (int (*)(...))QAbstractItemModel::canDropMimeData
+232 (int (*)(...))QFileSystemModel::dropMimeData
+240 (int (*)(...))QFileSystemModel::supportedDropActions
+248 (int (*)(...))QAbstractItemModel::supportedDragActions
+256 (int (*)(...))QAbstractItemModel::insertRows
+264 (int (*)(...))QAbstractItemModel::insertColumns
+272 (int (*)(...))QAbstractItemModel::removeRows
+280 (int (*)(...))QAbstractItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QFileSystemModel::fetchMore
+312 (int (*)(...))QFileSystemModel::canFetchMore
+320 (int (*)(...))QFileSystemModel::flags
+328 (int (*)(...))QFileSystemModel::sort
+336 (int (*)(...))QAbstractItemModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractItemModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractItemModel::submit
+376 (int (*)(...))QAbstractItemModel::revert
+
+Class QFileSystemModel
+ size=16 align=8
+ base size=16 base align=8
+QFileSystemModel (0x0x7f8846612958) 0
+ vptr=((& QFileSystemModel::_ZTV16QFileSystemModel) + 16u)
+ QAbstractItemModel (0x0x7f88466129c0) 0
+ primary-for QFileSystemModel (0x0x7f8846612958)
+ QObject (0x0x7f8846613cc0) 0
+ primary-for QAbstractItemModel (0x0x7f88466129c0)
+
+Class QFocusFrame::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFocusFrame::QPrivateSignal (0x0x7f8846613ea0) 0 empty
+
+Vtable for QFocusFrame
+QFocusFrame::_ZTV11QFocusFrame: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QFocusFrame)
+16 (int (*)(...))QFocusFrame::metaObject
+24 (int (*)(...))QFocusFrame::qt_metacast
+32 (int (*)(...))QFocusFrame::qt_metacall
+40 (int (*)(...))QFocusFrame::~QFocusFrame
+48 (int (*)(...))QFocusFrame::~QFocusFrame
+56 (int (*)(...))QFocusFrame::event
+64 (int (*)(...))QFocusFrame::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QFocusFrame::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI11QFocusFrame)
+448 (int (*)(...))QFocusFrame::_ZThn16_N11QFocusFrameD1Ev
+456 (int (*)(...))QFocusFrame::_ZThn16_N11QFocusFrameD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QFocusFrame
+ size=48 align=8
+ base size=48 base align=8
+QFocusFrame (0x0x7f8846612a28) 0
+ vptr=((& QFocusFrame::_ZTV11QFocusFrame) + 16u)
+ QWidget (0x0x7f8846355310) 0
+ primary-for QFocusFrame (0x0x7f8846612a28)
+ QObject (0x0x7f8846613de0) 0
+ primary-for QWidget (0x0x7f8846355310)
+ QPaintDevice (0x0x7f8846613e40) 16
+ vptr=((& QFocusFrame::_ZTV11QFocusFrame) + 448u)
+
+Class QFontComboBox::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFontComboBox::QPrivateSignal (0x0x7f884636f000) 0 empty
+
+Vtable for QFontComboBox
+QFontComboBox::_ZTV13QFontComboBox: 66u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QFontComboBox)
+16 (int (*)(...))QFontComboBox::metaObject
+24 (int (*)(...))QFontComboBox::qt_metacast
+32 (int (*)(...))QFontComboBox::qt_metacall
+40 (int (*)(...))QFontComboBox::~QFontComboBox
+48 (int (*)(...))QFontComboBox::~QFontComboBox
+56 (int (*)(...))QFontComboBox::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QFontComboBox::sizeHint
+136 (int (*)(...))QComboBox::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QComboBox::mousePressEvent
+176 (int (*)(...))QComboBox::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QComboBox::wheelEvent
+208 (int (*)(...))QComboBox::keyPressEvent
+216 (int (*)(...))QComboBox::keyReleaseEvent
+224 (int (*)(...))QComboBox::focusInEvent
+232 (int (*)(...))QComboBox::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QComboBox::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QComboBox::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QComboBox::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QComboBox::showEvent
+352 (int (*)(...))QComboBox::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QComboBox::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QComboBox::inputMethodEvent
+416 (int (*)(...))QComboBox::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QComboBox::showPopup
+440 (int (*)(...))QComboBox::hidePopup
+448 (int (*)(...))-16
+456 (int (*)(...))(& _ZTI13QFontComboBox)
+464 (int (*)(...))QFontComboBox::_ZThn16_N13QFontComboBoxD1Ev
+472 (int (*)(...))QFontComboBox::_ZThn16_N13QFontComboBoxD0Ev
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QFontComboBox
+ size=48 align=8
+ base size=48 base align=8
+QFontComboBox (0x0x7f8846612a90) 0
+ vptr=((& QFontComboBox::_ZTV13QFontComboBox) + 16u)
+ QComboBox (0x0x7f8846612af8) 0
+ primary-for QFontComboBox (0x0x7f8846612a90)
+ QWidget (0x0x7f88463557e0) 0
+ primary-for QComboBox (0x0x7f8846612af8)
+ QObject (0x0x7f8846613f00) 0
+ primary-for QWidget (0x0x7f88463557e0)
+ QPaintDevice (0x0x7f8846613f60) 16
+ vptr=((& QFontComboBox::_ZTV13QFontComboBox) + 464u)
+
+Class QFontDialog::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFontDialog::QPrivateSignal (0x0x7f884636f2a0) 0 empty
+
+Vtable for QFontDialog
+QFontDialog::_ZTV11QFontDialog: 69u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QFontDialog)
+16 (int (*)(...))QFontDialog::metaObject
+24 (int (*)(...))QFontDialog::qt_metacast
+32 (int (*)(...))QFontDialog::qt_metacall
+40 (int (*)(...))QFontDialog::~QFontDialog
+48 (int (*)(...))QFontDialog::~QFontDialog
+56 (int (*)(...))QWidget::event
+64 (int (*)(...))QFontDialog::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QFontDialog::setVisible
+128 (int (*)(...))QDialog::sizeHint
+136 (int (*)(...))QDialog::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QDialog::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QDialog::resizeEvent
+280 (int (*)(...))QDialog::closeEvent
+288 (int (*)(...))QDialog::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QDialog::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFontDialog::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QDialog::open
+440 (int (*)(...))QDialog::exec
+448 (int (*)(...))QFontDialog::done
+456 (int (*)(...))QDialog::accept
+464 (int (*)(...))QDialog::reject
+472 (int (*)(...))-16
+480 (int (*)(...))(& _ZTI11QFontDialog)
+488 (int (*)(...))QFontDialog::_ZThn16_N11QFontDialogD1Ev
+496 (int (*)(...))QFontDialog::_ZThn16_N11QFontDialogD0Ev
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QFontDialog
+ size=48 align=8
+ base size=48 base align=8
+QFontDialog (0x0x7f8846612c98) 0
+ vptr=((& QFontDialog::_ZTV11QFontDialog) + 16u)
+ QDialog (0x0x7f8846612d00) 0
+ primary-for QFontDialog (0x0x7f8846612c98)
+ QWidget (0x0x7f8846394ee0) 0
+ primary-for QDialog (0x0x7f8846612d00)
+ QObject (0x0x7f884636f1e0) 0
+ primary-for QWidget (0x0x7f8846394ee0)
+ QPaintDevice (0x0x7f884636f240) 16
+ vptr=((& QFontDialog::_ZTV11QFontDialog) + 488u)
+
+Class QFormLayout::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFormLayout::QPrivateSignal (0x0x7f884636f540) 0 empty
+
+Class QFormLayout::TakeRowResult
+ size=16 align=8
+ base size=16 base align=8
+QFormLayout::TakeRowResult (0x0x7f884636f5a0) 0
+
+Vtable for QFormLayout
+QFormLayout::_ZTV11QFormLayout: 50u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QFormLayout)
+16 (int (*)(...))QFormLayout::metaObject
+24 (int (*)(...))QFormLayout::qt_metacast
+32 (int (*)(...))QFormLayout::qt_metacall
+40 (int (*)(...))QFormLayout::~QFormLayout
+48 (int (*)(...))QFormLayout::~QFormLayout
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QLayout::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QFormLayout::invalidate
+120 (int (*)(...))QLayout::geometry
+128 (int (*)(...))QFormLayout::addItem
+136 (int (*)(...))QFormLayout::expandingDirections
+144 (int (*)(...))QFormLayout::minimumSize
+152 (int (*)(...))QLayout::maximumSize
+160 (int (*)(...))QFormLayout::setGeometry
+168 (int (*)(...))QFormLayout::itemAt
+176 (int (*)(...))QFormLayout::takeAt
+184 (int (*)(...))QLayout::indexOf
+192 (int (*)(...))QFormLayout::count
+200 (int (*)(...))QLayout::isEmpty
+208 (int (*)(...))QLayout::controlTypes
+216 (int (*)(...))QLayout::layout
+224 (int (*)(...))QFormLayout::sizeHint
+232 (int (*)(...))QFormLayout::hasHeightForWidth
+240 (int (*)(...))QFormLayout::heightForWidth
+248 (int (*)(...))-16
+256 (int (*)(...))(& _ZTI11QFormLayout)
+264 (int (*)(...))QFormLayout::_ZThn16_N11QFormLayoutD1Ev
+272 (int (*)(...))QFormLayout::_ZThn16_N11QFormLayoutD0Ev
+280 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout8sizeHintEv
+288 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout11minimumSizeEv
+296 (int (*)(...))QLayout::_ZThn16_NK7QLayout11maximumSizeEv
+304 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout19expandingDirectionsEv
+312 (int (*)(...))QFormLayout::_ZThn16_N11QFormLayout11setGeometryERK5QRect
+320 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv
+328 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv
+336 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout17hasHeightForWidthEv
+344 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout14heightForWidthEi
+352 (int (*)(...))QLayoutItem::minimumHeightForWidth
+360 (int (*)(...))QFormLayout::_ZThn16_N11QFormLayout10invalidateEv
+368 (int (*)(...))QLayoutItem::widget
+376 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv
+384 (int (*)(...))QLayoutItem::spacerItem
+392 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv
+
+Class QFormLayout
+ size=32 align=8
+ base size=28 base align=8
+QFormLayout (0x0x7f8846612e38) 0
+ vptr=((& QFormLayout::_ZTV11QFormLayout) + 16u)
+ QLayout (0x0x7f88463e7b60) 0
+ primary-for QFormLayout (0x0x7f8846612e38)
+ QObject (0x0x7f884636f480) 0
+ primary-for QLayout (0x0x7f88463e7b60)
+ QLayoutItem (0x0x7f884636f4e0) 16
+ vptr=((& QFormLayout::_ZTV11QFormLayout) + 264u)
+
+Class QGesture::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGesture::QPrivateSignal (0x0x7f884636fae0) 0 empty
+
+Vtable for QGesture
+QGesture::_ZTV8QGesture: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QGesture)
+16 (int (*)(...))QGesture::metaObject
+24 (int (*)(...))QGesture::qt_metacast
+32 (int (*)(...))QGesture::qt_metacall
+40 (int (*)(...))QGesture::~QGesture
+48 (int (*)(...))QGesture::~QGesture
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QGesture
+ size=16 align=8
+ base size=16 base align=8
+QGesture (0x0x7f8846436068) 0
+ vptr=((& QGesture::_ZTV8QGesture) + 16u)
+ QObject (0x0x7f884636fa80) 0
+ primary-for QGesture (0x0x7f8846436068)
+
+Class QPanGesture::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPanGesture::QPrivateSignal (0x0x7f884636fba0) 0 empty
+
+Vtable for QPanGesture
+QPanGesture::_ZTV11QPanGesture: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QPanGesture)
+16 (int (*)(...))QPanGesture::metaObject
+24 (int (*)(...))QPanGesture::qt_metacast
+32 (int (*)(...))QPanGesture::qt_metacall
+40 (int (*)(...))QPanGesture::~QPanGesture
+48 (int (*)(...))QPanGesture::~QPanGesture
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QPanGesture
+ size=16 align=8
+ base size=16 base align=8
+QPanGesture (0x0x7f88464360d0) 0
+ vptr=((& QPanGesture::_ZTV11QPanGesture) + 16u)
+ QGesture (0x0x7f8846436138) 0
+ primary-for QPanGesture (0x0x7f88464360d0)
+ QObject (0x0x7f884636fb40) 0
+ primary-for QGesture (0x0x7f8846436138)
+
+Class QPinchGesture::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPinchGesture::QPrivateSignal (0x0x7f884636fc60) 0 empty
+
+Vtable for QPinchGesture
+QPinchGesture::_ZTV13QPinchGesture: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QPinchGesture)
+16 (int (*)(...))QPinchGesture::metaObject
+24 (int (*)(...))QPinchGesture::qt_metacast
+32 (int (*)(...))QPinchGesture::qt_metacall
+40 (int (*)(...))QPinchGesture::~QPinchGesture
+48 (int (*)(...))QPinchGesture::~QPinchGesture
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QPinchGesture
+ size=16 align=8
+ base size=16 base align=8
+QPinchGesture (0x0x7f88464361a0) 0
+ vptr=((& QPinchGesture::_ZTV13QPinchGesture) + 16u)
+ QGesture (0x0x7f8846436208) 0
+ primary-for QPinchGesture (0x0x7f88464361a0)
+ QObject (0x0x7f884636fc00) 0
+ primary-for QGesture (0x0x7f8846436208)
+
+Class QSwipeGesture::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSwipeGesture::QPrivateSignal (0x0x7f88464ba000) 0 empty
+
+Vtable for QSwipeGesture
+QSwipeGesture::_ZTV13QSwipeGesture: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QSwipeGesture)
+16 (int (*)(...))QSwipeGesture::metaObject
+24 (int (*)(...))QSwipeGesture::qt_metacast
+32 (int (*)(...))QSwipeGesture::qt_metacall
+40 (int (*)(...))QSwipeGesture::~QSwipeGesture
+48 (int (*)(...))QSwipeGesture::~QSwipeGesture
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QSwipeGesture
+ size=16 align=8
+ base size=16 base align=8
+QSwipeGesture (0x0x7f8846436340) 0
+ vptr=((& QSwipeGesture::_ZTV13QSwipeGesture) + 16u)
+ QGesture (0x0x7f88464363a8) 0
+ primary-for QSwipeGesture (0x0x7f8846436340)
+ QObject (0x0x7f884636ff60) 0
+ primary-for QGesture (0x0x7f88464363a8)
+
+Class QTapGesture::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTapGesture::QPrivateSignal (0x0x7f88464ba120) 0 empty
+
+Vtable for QTapGesture
+QTapGesture::_ZTV11QTapGesture: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTapGesture)
+16 (int (*)(...))QTapGesture::metaObject
+24 (int (*)(...))QTapGesture::qt_metacast
+32 (int (*)(...))QTapGesture::qt_metacall
+40 (int (*)(...))QTapGesture::~QTapGesture
+48 (int (*)(...))QTapGesture::~QTapGesture
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QTapGesture
+ size=16 align=8
+ base size=16 base align=8
+QTapGesture (0x0x7f8846436410) 0
+ vptr=((& QTapGesture::_ZTV11QTapGesture) + 16u)
+ QGesture (0x0x7f8846436478) 0
+ primary-for QTapGesture (0x0x7f8846436410)
+ QObject (0x0x7f88464ba0c0) 0
+ primary-for QGesture (0x0x7f8846436478)
+
+Class QTapAndHoldGesture::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTapAndHoldGesture::QPrivateSignal (0x0x7f88464ba1e0) 0 empty
+
+Vtable for QTapAndHoldGesture
+QTapAndHoldGesture::_ZTV18QTapAndHoldGesture: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QTapAndHoldGesture)
+16 (int (*)(...))QTapAndHoldGesture::metaObject
+24 (int (*)(...))QTapAndHoldGesture::qt_metacast
+32 (int (*)(...))QTapAndHoldGesture::qt_metacall
+40 (int (*)(...))QTapAndHoldGesture::~QTapAndHoldGesture
+48 (int (*)(...))QTapAndHoldGesture::~QTapAndHoldGesture
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QTapAndHoldGesture
+ size=16 align=8
+ base size=16 base align=8
+QTapAndHoldGesture (0x0x7f88464364e0) 0
+ vptr=((& QTapAndHoldGesture::_ZTV18QTapAndHoldGesture) + 16u)
+ QGesture (0x0x7f8846436548) 0
+ primary-for QTapAndHoldGesture (0x0x7f88464364e0)
+ QObject (0x0x7f88464ba180) 0
+ primary-for QGesture (0x0x7f8846436548)
+
+Vtable for QGestureEvent
+QGestureEvent::_ZTV13QGestureEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QGestureEvent)
+16 (int (*)(...))QGestureEvent::~QGestureEvent
+24 (int (*)(...))QGestureEvent::~QGestureEvent
+
+Class QGestureEvent
+ size=56 align=8
+ base size=56 base align=8
+QGestureEvent (0x0x7f88464365b0) 0
+ vptr=((& QGestureEvent::_ZTV13QGestureEvent) + 16u)
+ QEvent (0x0x7f88464ba240) 0
+ primary-for QGestureEvent (0x0x7f88464365b0)
+
+Vtable for QGestureRecognizer
+QGestureRecognizer::_ZTV18QGestureRecognizer: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QGestureRecognizer)
+16 0u
+24 0u
+32 (int (*)(...))QGestureRecognizer::create
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))QGestureRecognizer::reset
+
+Class QGestureRecognizer
+ size=8 align=8
+ base size=8 base align=8
+QGestureRecognizer (0x0x7f88464ba600) 0 nearly-empty
+ vptr=((& QGestureRecognizer::_ZTV18QGestureRecognizer) + 16u)
+
+Vtable for QGraphicsItem
+QGraphicsItem::_ZTV13QGraphicsItem: 39u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QGraphicsItem)
+16 0u
+24 0u
+32 (int (*)(...))QGraphicsItem::advance
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))QGraphicsItem::shape
+56 (int (*)(...))QGraphicsItem::contains
+64 (int (*)(...))QGraphicsItem::collidesWithItem
+72 (int (*)(...))QGraphicsItem::collidesWithPath
+80 (int (*)(...))QGraphicsItem::isObscuredBy
+88 (int (*)(...))QGraphicsItem::opaqueArea
+96 (int (*)(...))__cxa_pure_virtual
+104 (int (*)(...))QGraphicsItem::type
+112 (int (*)(...))QGraphicsItem::sceneEventFilter
+120 (int (*)(...))QGraphicsItem::sceneEvent
+128 (int (*)(...))QGraphicsItem::contextMenuEvent
+136 (int (*)(...))QGraphicsItem::dragEnterEvent
+144 (int (*)(...))QGraphicsItem::dragLeaveEvent
+152 (int (*)(...))QGraphicsItem::dragMoveEvent
+160 (int (*)(...))QGraphicsItem::dropEvent
+168 (int (*)(...))QGraphicsItem::focusInEvent
+176 (int (*)(...))QGraphicsItem::focusOutEvent
+184 (int (*)(...))QGraphicsItem::hoverEnterEvent
+192 (int (*)(...))QGraphicsItem::hoverMoveEvent
+200 (int (*)(...))QGraphicsItem::hoverLeaveEvent
+208 (int (*)(...))QGraphicsItem::keyPressEvent
+216 (int (*)(...))QGraphicsItem::keyReleaseEvent
+224 (int (*)(...))QGraphicsItem::mousePressEvent
+232 (int (*)(...))QGraphicsItem::mouseMoveEvent
+240 (int (*)(...))QGraphicsItem::mouseReleaseEvent
+248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent
+256 (int (*)(...))QGraphicsItem::wheelEvent
+264 (int (*)(...))QGraphicsItem::inputMethodEvent
+272 (int (*)(...))QGraphicsItem::inputMethodQuery
+280 (int (*)(...))QGraphicsItem::itemChange
+288 (int (*)(...))QGraphicsItem::supportsExtension
+296 (int (*)(...))QGraphicsItem::setExtension
+304 (int (*)(...))QGraphicsItem::extension
+
+Class QGraphicsItem
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsItem (0x0x7f88464ba7e0) 0
+ vptr=((& QGraphicsItem::_ZTV13QGraphicsItem) + 16u)
+
+Class QGraphicsObject::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsObject::QPrivateSignal (0x0x7f88464baba0) 0 empty
+
+Vtable for QGraphicsObject
+QGraphicsObject::_ZTV15QGraphicsObject: 53u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QGraphicsObject)
+16 (int (*)(...))QGraphicsObject::metaObject
+24 (int (*)(...))QGraphicsObject::qt_metacast
+32 (int (*)(...))QGraphicsObject::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QGraphicsObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))-16
+120 (int (*)(...))(& _ZTI15QGraphicsObject)
+128 0u
+136 0u
+144 (int (*)(...))QGraphicsItem::advance
+152 (int (*)(...))__cxa_pure_virtual
+160 (int (*)(...))QGraphicsItem::shape
+168 (int (*)(...))QGraphicsItem::contains
+176 (int (*)(...))QGraphicsItem::collidesWithItem
+184 (int (*)(...))QGraphicsItem::collidesWithPath
+192 (int (*)(...))QGraphicsItem::isObscuredBy
+200 (int (*)(...))QGraphicsItem::opaqueArea
+208 (int (*)(...))__cxa_pure_virtual
+216 (int (*)(...))QGraphicsItem::type
+224 (int (*)(...))QGraphicsItem::sceneEventFilter
+232 (int (*)(...))QGraphicsItem::sceneEvent
+240 (int (*)(...))QGraphicsItem::contextMenuEvent
+248 (int (*)(...))QGraphicsItem::dragEnterEvent
+256 (int (*)(...))QGraphicsItem::dragLeaveEvent
+264 (int (*)(...))QGraphicsItem::dragMoveEvent
+272 (int (*)(...))QGraphicsItem::dropEvent
+280 (int (*)(...))QGraphicsItem::focusInEvent
+288 (int (*)(...))QGraphicsItem::focusOutEvent
+296 (int (*)(...))QGraphicsItem::hoverEnterEvent
+304 (int (*)(...))QGraphicsItem::hoverMoveEvent
+312 (int (*)(...))QGraphicsItem::hoverLeaveEvent
+320 (int (*)(...))QGraphicsItem::keyPressEvent
+328 (int (*)(...))QGraphicsItem::keyReleaseEvent
+336 (int (*)(...))QGraphicsItem::mousePressEvent
+344 (int (*)(...))QGraphicsItem::mouseMoveEvent
+352 (int (*)(...))QGraphicsItem::mouseReleaseEvent
+360 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent
+368 (int (*)(...))QGraphicsItem::wheelEvent
+376 (int (*)(...))QGraphicsItem::inputMethodEvent
+384 (int (*)(...))QGraphicsItem::inputMethodQuery
+392 (int (*)(...))QGraphicsItem::itemChange
+400 (int (*)(...))QGraphicsItem::supportsExtension
+408 (int (*)(...))QGraphicsItem::setExtension
+416 (int (*)(...))QGraphicsItem::extension
+
+Class QGraphicsObject
+ size=32 align=8
+ base size=32 base align=8
+QGraphicsObject (0x0x7f8846244b60) 0
+ vptr=((& QGraphicsObject::_ZTV15QGraphicsObject) + 16u)
+ QObject (0x0x7f88464baae0) 0
+ primary-for QGraphicsObject (0x0x7f8846244b60)
+ QGraphicsItem (0x0x7f88464bab40) 16
+ vptr=((& QGraphicsObject::_ZTV15QGraphicsObject) + 128u)
+
+Vtable for QAbstractGraphicsShapeItem
+QAbstractGraphicsShapeItem::_ZTV26QAbstractGraphicsShapeItem: 39u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QAbstractGraphicsShapeItem)
+16 0u
+24 0u
+32 (int (*)(...))QGraphicsItem::advance
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))QGraphicsItem::shape
+56 (int (*)(...))QGraphicsItem::contains
+64 (int (*)(...))QGraphicsItem::collidesWithItem
+72 (int (*)(...))QGraphicsItem::collidesWithPath
+80 (int (*)(...))QAbstractGraphicsShapeItem::isObscuredBy
+88 (int (*)(...))QAbstractGraphicsShapeItem::opaqueArea
+96 (int (*)(...))__cxa_pure_virtual
+104 (int (*)(...))QGraphicsItem::type
+112 (int (*)(...))QGraphicsItem::sceneEventFilter
+120 (int (*)(...))QGraphicsItem::sceneEvent
+128 (int (*)(...))QGraphicsItem::contextMenuEvent
+136 (int (*)(...))QGraphicsItem::dragEnterEvent
+144 (int (*)(...))QGraphicsItem::dragLeaveEvent
+152 (int (*)(...))QGraphicsItem::dragMoveEvent
+160 (int (*)(...))QGraphicsItem::dropEvent
+168 (int (*)(...))QGraphicsItem::focusInEvent
+176 (int (*)(...))QGraphicsItem::focusOutEvent
+184 (int (*)(...))QGraphicsItem::hoverEnterEvent
+192 (int (*)(...))QGraphicsItem::hoverMoveEvent
+200 (int (*)(...))QGraphicsItem::hoverLeaveEvent
+208 (int (*)(...))QGraphicsItem::keyPressEvent
+216 (int (*)(...))QGraphicsItem::keyReleaseEvent
+224 (int (*)(...))QGraphicsItem::mousePressEvent
+232 (int (*)(...))QGraphicsItem::mouseMoveEvent
+240 (int (*)(...))QGraphicsItem::mouseReleaseEvent
+248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent
+256 (int (*)(...))QGraphicsItem::wheelEvent
+264 (int (*)(...))QGraphicsItem::inputMethodEvent
+272 (int (*)(...))QGraphicsItem::inputMethodQuery
+280 (int (*)(...))QGraphicsItem::itemChange
+288 (int (*)(...))QGraphicsItem::supportsExtension
+296 (int (*)(...))QGraphicsItem::setExtension
+304 (int (*)(...))QGraphicsItem::extension
+
+Class QAbstractGraphicsShapeItem
+ size=16 align=8
+ base size=16 base align=8
+QAbstractGraphicsShapeItem (0x0x7f8846436888) 0
+ vptr=((& QAbstractGraphicsShapeItem::_ZTV26QAbstractGraphicsShapeItem) + 16u)
+ QGraphicsItem (0x0x7f88464bac00) 0
+ primary-for QAbstractGraphicsShapeItem (0x0x7f8846436888)
+
+Vtable for QGraphicsPathItem
+QGraphicsPathItem::_ZTV17QGraphicsPathItem: 39u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QGraphicsPathItem)
+16 (int (*)(...))QGraphicsPathItem::~QGraphicsPathItem
+24 (int (*)(...))QGraphicsPathItem::~QGraphicsPathItem
+32 (int (*)(...))QGraphicsItem::advance
+40 (int (*)(...))QGraphicsPathItem::boundingRect
+48 (int (*)(...))QGraphicsPathItem::shape
+56 (int (*)(...))QGraphicsPathItem::contains
+64 (int (*)(...))QGraphicsItem::collidesWithItem
+72 (int (*)(...))QGraphicsItem::collidesWithPath
+80 (int (*)(...))QGraphicsPathItem::isObscuredBy
+88 (int (*)(...))QGraphicsPathItem::opaqueArea
+96 (int (*)(...))QGraphicsPathItem::paint
+104 (int (*)(...))QGraphicsPathItem::type
+112 (int (*)(...))QGraphicsItem::sceneEventFilter
+120 (int (*)(...))QGraphicsItem::sceneEvent
+128 (int (*)(...))QGraphicsItem::contextMenuEvent
+136 (int (*)(...))QGraphicsItem::dragEnterEvent
+144 (int (*)(...))QGraphicsItem::dragLeaveEvent
+152 (int (*)(...))QGraphicsItem::dragMoveEvent
+160 (int (*)(...))QGraphicsItem::dropEvent
+168 (int (*)(...))QGraphicsItem::focusInEvent
+176 (int (*)(...))QGraphicsItem::focusOutEvent
+184 (int (*)(...))QGraphicsItem::hoverEnterEvent
+192 (int (*)(...))QGraphicsItem::hoverMoveEvent
+200 (int (*)(...))QGraphicsItem::hoverLeaveEvent
+208 (int (*)(...))QGraphicsItem::keyPressEvent
+216 (int (*)(...))QGraphicsItem::keyReleaseEvent
+224 (int (*)(...))QGraphicsItem::mousePressEvent
+232 (int (*)(...))QGraphicsItem::mouseMoveEvent
+240 (int (*)(...))QGraphicsItem::mouseReleaseEvent
+248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent
+256 (int (*)(...))QGraphicsItem::wheelEvent
+264 (int (*)(...))QGraphicsItem::inputMethodEvent
+272 (int (*)(...))QGraphicsItem::inputMethodQuery
+280 (int (*)(...))QGraphicsItem::itemChange
+288 (int (*)(...))QGraphicsPathItem::supportsExtension
+296 (int (*)(...))QGraphicsPathItem::setExtension
+304 (int (*)(...))QGraphicsPathItem::extension
+
+Class QGraphicsPathItem
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsPathItem (0x0x7f88464368f0) 0
+ vptr=((& QGraphicsPathItem::_ZTV17QGraphicsPathItem) + 16u)
+ QAbstractGraphicsShapeItem (0x0x7f8846436958) 0
+ primary-for QGraphicsPathItem (0x0x7f88464368f0)
+ QGraphicsItem (0x0x7f88464bac60) 0
+ primary-for QAbstractGraphicsShapeItem (0x0x7f8846436958)
+
+Vtable for QGraphicsRectItem
+QGraphicsRectItem::_ZTV17QGraphicsRectItem: 39u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QGraphicsRectItem)
+16 (int (*)(...))QGraphicsRectItem::~QGraphicsRectItem
+24 (int (*)(...))QGraphicsRectItem::~QGraphicsRectItem
+32 (int (*)(...))QGraphicsItem::advance
+40 (int (*)(...))QGraphicsRectItem::boundingRect
+48 (int (*)(...))QGraphicsRectItem::shape
+56 (int (*)(...))QGraphicsRectItem::contains
+64 (int (*)(...))QGraphicsItem::collidesWithItem
+72 (int (*)(...))QGraphicsItem::collidesWithPath
+80 (int (*)(...))QGraphicsRectItem::isObscuredBy
+88 (int (*)(...))QGraphicsRectItem::opaqueArea
+96 (int (*)(...))QGraphicsRectItem::paint
+104 (int (*)(...))QGraphicsRectItem::type
+112 (int (*)(...))QGraphicsItem::sceneEventFilter
+120 (int (*)(...))QGraphicsItem::sceneEvent
+128 (int (*)(...))QGraphicsItem::contextMenuEvent
+136 (int (*)(...))QGraphicsItem::dragEnterEvent
+144 (int (*)(...))QGraphicsItem::dragLeaveEvent
+152 (int (*)(...))QGraphicsItem::dragMoveEvent
+160 (int (*)(...))QGraphicsItem::dropEvent
+168 (int (*)(...))QGraphicsItem::focusInEvent
+176 (int (*)(...))QGraphicsItem::focusOutEvent
+184 (int (*)(...))QGraphicsItem::hoverEnterEvent
+192 (int (*)(...))QGraphicsItem::hoverMoveEvent
+200 (int (*)(...))QGraphicsItem::hoverLeaveEvent
+208 (int (*)(...))QGraphicsItem::keyPressEvent
+216 (int (*)(...))QGraphicsItem::keyReleaseEvent
+224 (int (*)(...))QGraphicsItem::mousePressEvent
+232 (int (*)(...))QGraphicsItem::mouseMoveEvent
+240 (int (*)(...))QGraphicsItem::mouseReleaseEvent
+248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent
+256 (int (*)(...))QGraphicsItem::wheelEvent
+264 (int (*)(...))QGraphicsItem::inputMethodEvent
+272 (int (*)(...))QGraphicsItem::inputMethodQuery
+280 (int (*)(...))QGraphicsItem::itemChange
+288 (int (*)(...))QGraphicsRectItem::supportsExtension
+296 (int (*)(...))QGraphicsRectItem::setExtension
+304 (int (*)(...))QGraphicsRectItem::extension
+
+Class QGraphicsRectItem
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsRectItem (0x0x7f88464369c0) 0
+ vptr=((& QGraphicsRectItem::_ZTV17QGraphicsRectItem) + 16u)
+ QAbstractGraphicsShapeItem (0x0x7f8846436a28) 0
+ primary-for QGraphicsRectItem (0x0x7f88464369c0)
+ QGraphicsItem (0x0x7f88464bacc0) 0
+ primary-for QAbstractGraphicsShapeItem (0x0x7f8846436a28)
+
+Vtable for QGraphicsEllipseItem
+QGraphicsEllipseItem::_ZTV20QGraphicsEllipseItem: 39u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QGraphicsEllipseItem)
+16 (int (*)(...))QGraphicsEllipseItem::~QGraphicsEllipseItem
+24 (int (*)(...))QGraphicsEllipseItem::~QGraphicsEllipseItem
+32 (int (*)(...))QGraphicsItem::advance
+40 (int (*)(...))QGraphicsEllipseItem::boundingRect
+48 (int (*)(...))QGraphicsEllipseItem::shape
+56 (int (*)(...))QGraphicsEllipseItem::contains
+64 (int (*)(...))QGraphicsItem::collidesWithItem
+72 (int (*)(...))QGraphicsItem::collidesWithPath
+80 (int (*)(...))QGraphicsEllipseItem::isObscuredBy
+88 (int (*)(...))QGraphicsEllipseItem::opaqueArea
+96 (int (*)(...))QGraphicsEllipseItem::paint
+104 (int (*)(...))QGraphicsEllipseItem::type
+112 (int (*)(...))QGraphicsItem::sceneEventFilter
+120 (int (*)(...))QGraphicsItem::sceneEvent
+128 (int (*)(...))QGraphicsItem::contextMenuEvent
+136 (int (*)(...))QGraphicsItem::dragEnterEvent
+144 (int (*)(...))QGraphicsItem::dragLeaveEvent
+152 (int (*)(...))QGraphicsItem::dragMoveEvent
+160 (int (*)(...))QGraphicsItem::dropEvent
+168 (int (*)(...))QGraphicsItem::focusInEvent
+176 (int (*)(...))QGraphicsItem::focusOutEvent
+184 (int (*)(...))QGraphicsItem::hoverEnterEvent
+192 (int (*)(...))QGraphicsItem::hoverMoveEvent
+200 (int (*)(...))QGraphicsItem::hoverLeaveEvent
+208 (int (*)(...))QGraphicsItem::keyPressEvent
+216 (int (*)(...))QGraphicsItem::keyReleaseEvent
+224 (int (*)(...))QGraphicsItem::mousePressEvent
+232 (int (*)(...))QGraphicsItem::mouseMoveEvent
+240 (int (*)(...))QGraphicsItem::mouseReleaseEvent
+248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent
+256 (int (*)(...))QGraphicsItem::wheelEvent
+264 (int (*)(...))QGraphicsItem::inputMethodEvent
+272 (int (*)(...))QGraphicsItem::inputMethodQuery
+280 (int (*)(...))QGraphicsItem::itemChange
+288 (int (*)(...))QGraphicsEllipseItem::supportsExtension
+296 (int (*)(...))QGraphicsEllipseItem::setExtension
+304 (int (*)(...))QGraphicsEllipseItem::extension
+
+Class QGraphicsEllipseItem
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsEllipseItem (0x0x7f8846436a90) 0
+ vptr=((& QGraphicsEllipseItem::_ZTV20QGraphicsEllipseItem) + 16u)
+ QAbstractGraphicsShapeItem (0x0x7f8846436af8) 0
+ primary-for QGraphicsEllipseItem (0x0x7f8846436a90)
+ QGraphicsItem (0x0x7f88464bad20) 0
+ primary-for QAbstractGraphicsShapeItem (0x0x7f8846436af8)
+
+Vtable for QGraphicsPolygonItem
+QGraphicsPolygonItem::_ZTV20QGraphicsPolygonItem: 39u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QGraphicsPolygonItem)
+16 (int (*)(...))QGraphicsPolygonItem::~QGraphicsPolygonItem
+24 (int (*)(...))QGraphicsPolygonItem::~QGraphicsPolygonItem
+32 (int (*)(...))QGraphicsItem::advance
+40 (int (*)(...))QGraphicsPolygonItem::boundingRect
+48 (int (*)(...))QGraphicsPolygonItem::shape
+56 (int (*)(...))QGraphicsPolygonItem::contains
+64 (int (*)(...))QGraphicsItem::collidesWithItem
+72 (int (*)(...))QGraphicsItem::collidesWithPath
+80 (int (*)(...))QGraphicsPolygonItem::isObscuredBy
+88 (int (*)(...))QGraphicsPolygonItem::opaqueArea
+96 (int (*)(...))QGraphicsPolygonItem::paint
+104 (int (*)(...))QGraphicsPolygonItem::type
+112 (int (*)(...))QGraphicsItem::sceneEventFilter
+120 (int (*)(...))QGraphicsItem::sceneEvent
+128 (int (*)(...))QGraphicsItem::contextMenuEvent
+136 (int (*)(...))QGraphicsItem::dragEnterEvent
+144 (int (*)(...))QGraphicsItem::dragLeaveEvent
+152 (int (*)(...))QGraphicsItem::dragMoveEvent
+160 (int (*)(...))QGraphicsItem::dropEvent
+168 (int (*)(...))QGraphicsItem::focusInEvent
+176 (int (*)(...))QGraphicsItem::focusOutEvent
+184 (int (*)(...))QGraphicsItem::hoverEnterEvent
+192 (int (*)(...))QGraphicsItem::hoverMoveEvent
+200 (int (*)(...))QGraphicsItem::hoverLeaveEvent
+208 (int (*)(...))QGraphicsItem::keyPressEvent
+216 (int (*)(...))QGraphicsItem::keyReleaseEvent
+224 (int (*)(...))QGraphicsItem::mousePressEvent
+232 (int (*)(...))QGraphicsItem::mouseMoveEvent
+240 (int (*)(...))QGraphicsItem::mouseReleaseEvent
+248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent
+256 (int (*)(...))QGraphicsItem::wheelEvent
+264 (int (*)(...))QGraphicsItem::inputMethodEvent
+272 (int (*)(...))QGraphicsItem::inputMethodQuery
+280 (int (*)(...))QGraphicsItem::itemChange
+288 (int (*)(...))QGraphicsPolygonItem::supportsExtension
+296 (int (*)(...))QGraphicsPolygonItem::setExtension
+304 (int (*)(...))QGraphicsPolygonItem::extension
+
+Class QGraphicsPolygonItem
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsPolygonItem (0x0x7f8846436b60) 0
+ vptr=((& QGraphicsPolygonItem::_ZTV20QGraphicsPolygonItem) + 16u)
+ QAbstractGraphicsShapeItem (0x0x7f8846436bc8) 0
+ primary-for QGraphicsPolygonItem (0x0x7f8846436b60)
+ QGraphicsItem (0x0x7f88464bad80) 0
+ primary-for QAbstractGraphicsShapeItem (0x0x7f8846436bc8)
+
+Vtable for QGraphicsLineItem
+QGraphicsLineItem::_ZTV17QGraphicsLineItem: 39u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QGraphicsLineItem)
+16 (int (*)(...))QGraphicsLineItem::~QGraphicsLineItem
+24 (int (*)(...))QGraphicsLineItem::~QGraphicsLineItem
+32 (int (*)(...))QGraphicsItem::advance
+40 (int (*)(...))QGraphicsLineItem::boundingRect
+48 (int (*)(...))QGraphicsLineItem::shape
+56 (int (*)(...))QGraphicsLineItem::contains
+64 (int (*)(...))QGraphicsItem::collidesWithItem
+72 (int (*)(...))QGraphicsItem::collidesWithPath
+80 (int (*)(...))QGraphicsLineItem::isObscuredBy
+88 (int (*)(...))QGraphicsLineItem::opaqueArea
+96 (int (*)(...))QGraphicsLineItem::paint
+104 (int (*)(...))QGraphicsLineItem::type
+112 (int (*)(...))QGraphicsItem::sceneEventFilter
+120 (int (*)(...))QGraphicsItem::sceneEvent
+128 (int (*)(...))QGraphicsItem::contextMenuEvent
+136 (int (*)(...))QGraphicsItem::dragEnterEvent
+144 (int (*)(...))QGraphicsItem::dragLeaveEvent
+152 (int (*)(...))QGraphicsItem::dragMoveEvent
+160 (int (*)(...))QGraphicsItem::dropEvent
+168 (int (*)(...))QGraphicsItem::focusInEvent
+176 (int (*)(...))QGraphicsItem::focusOutEvent
+184 (int (*)(...))QGraphicsItem::hoverEnterEvent
+192 (int (*)(...))QGraphicsItem::hoverMoveEvent
+200 (int (*)(...))QGraphicsItem::hoverLeaveEvent
+208 (int (*)(...))QGraphicsItem::keyPressEvent
+216 (int (*)(...))QGraphicsItem::keyReleaseEvent
+224 (int (*)(...))QGraphicsItem::mousePressEvent
+232 (int (*)(...))QGraphicsItem::mouseMoveEvent
+240 (int (*)(...))QGraphicsItem::mouseReleaseEvent
+248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent
+256 (int (*)(...))QGraphicsItem::wheelEvent
+264 (int (*)(...))QGraphicsItem::inputMethodEvent
+272 (int (*)(...))QGraphicsItem::inputMethodQuery
+280 (int (*)(...))QGraphicsItem::itemChange
+288 (int (*)(...))QGraphicsLineItem::supportsExtension
+296 (int (*)(...))QGraphicsLineItem::setExtension
+304 (int (*)(...))QGraphicsLineItem::extension
+
+Class QGraphicsLineItem
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsLineItem (0x0x7f8846436c30) 0
+ vptr=((& QGraphicsLineItem::_ZTV17QGraphicsLineItem) + 16u)
+ QGraphicsItem (0x0x7f88464bade0) 0
+ primary-for QGraphicsLineItem (0x0x7f8846436c30)
+
+Vtable for QGraphicsPixmapItem
+QGraphicsPixmapItem::_ZTV19QGraphicsPixmapItem: 39u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QGraphicsPixmapItem)
+16 (int (*)(...))QGraphicsPixmapItem::~QGraphicsPixmapItem
+24 (int (*)(...))QGraphicsPixmapItem::~QGraphicsPixmapItem
+32 (int (*)(...))QGraphicsItem::advance
+40 (int (*)(...))QGraphicsPixmapItem::boundingRect
+48 (int (*)(...))QGraphicsPixmapItem::shape
+56 (int (*)(...))QGraphicsPixmapItem::contains
+64 (int (*)(...))QGraphicsItem::collidesWithItem
+72 (int (*)(...))QGraphicsItem::collidesWithPath
+80 (int (*)(...))QGraphicsPixmapItem::isObscuredBy
+88 (int (*)(...))QGraphicsPixmapItem::opaqueArea
+96 (int (*)(...))QGraphicsPixmapItem::paint
+104 (int (*)(...))QGraphicsPixmapItem::type
+112 (int (*)(...))QGraphicsItem::sceneEventFilter
+120 (int (*)(...))QGraphicsItem::sceneEvent
+128 (int (*)(...))QGraphicsItem::contextMenuEvent
+136 (int (*)(...))QGraphicsItem::dragEnterEvent
+144 (int (*)(...))QGraphicsItem::dragLeaveEvent
+152 (int (*)(...))QGraphicsItem::dragMoveEvent
+160 (int (*)(...))QGraphicsItem::dropEvent
+168 (int (*)(...))QGraphicsItem::focusInEvent
+176 (int (*)(...))QGraphicsItem::focusOutEvent
+184 (int (*)(...))QGraphicsItem::hoverEnterEvent
+192 (int (*)(...))QGraphicsItem::hoverMoveEvent
+200 (int (*)(...))QGraphicsItem::hoverLeaveEvent
+208 (int (*)(...))QGraphicsItem::keyPressEvent
+216 (int (*)(...))QGraphicsItem::keyReleaseEvent
+224 (int (*)(...))QGraphicsItem::mousePressEvent
+232 (int (*)(...))QGraphicsItem::mouseMoveEvent
+240 (int (*)(...))QGraphicsItem::mouseReleaseEvent
+248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent
+256 (int (*)(...))QGraphicsItem::wheelEvent
+264 (int (*)(...))QGraphicsItem::inputMethodEvent
+272 (int (*)(...))QGraphicsItem::inputMethodQuery
+280 (int (*)(...))QGraphicsItem::itemChange
+288 (int (*)(...))QGraphicsPixmapItem::supportsExtension
+296 (int (*)(...))QGraphicsPixmapItem::setExtension
+304 (int (*)(...))QGraphicsPixmapItem::extension
+
+Class QGraphicsPixmapItem
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsPixmapItem (0x0x7f8846436c98) 0
+ vptr=((& QGraphicsPixmapItem::_ZTV19QGraphicsPixmapItem) + 16u)
+ QGraphicsItem (0x0x7f88464bae40) 0
+ primary-for QGraphicsPixmapItem (0x0x7f8846436c98)
+
+Class QGraphicsTextItem::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsTextItem::QPrivateSignal (0x0x7f88464baf60) 0 empty
+
+Vtable for QGraphicsTextItem
+QGraphicsTextItem::_ZTV17QGraphicsTextItem: 82u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QGraphicsTextItem)
+16 (int (*)(...))QGraphicsTextItem::metaObject
+24 (int (*)(...))QGraphicsTextItem::qt_metacast
+32 (int (*)(...))QGraphicsTextItem::qt_metacall
+40 (int (*)(...))QGraphicsTextItem::~QGraphicsTextItem
+48 (int (*)(...))QGraphicsTextItem::~QGraphicsTextItem
+56 (int (*)(...))QGraphicsObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGraphicsTextItem::boundingRect
+120 (int (*)(...))QGraphicsTextItem::shape
+128 (int (*)(...))QGraphicsTextItem::contains
+136 (int (*)(...))QGraphicsTextItem::paint
+144 (int (*)(...))QGraphicsTextItem::isObscuredBy
+152 (int (*)(...))QGraphicsTextItem::opaqueArea
+160 (int (*)(...))QGraphicsTextItem::type
+168 (int (*)(...))QGraphicsTextItem::sceneEvent
+176 (int (*)(...))QGraphicsTextItem::mousePressEvent
+184 (int (*)(...))QGraphicsTextItem::mouseMoveEvent
+192 (int (*)(...))QGraphicsTextItem::mouseReleaseEvent
+200 (int (*)(...))QGraphicsTextItem::mouseDoubleClickEvent
+208 (int (*)(...))QGraphicsTextItem::contextMenuEvent
+216 (int (*)(...))QGraphicsTextItem::keyPressEvent
+224 (int (*)(...))QGraphicsTextItem::keyReleaseEvent
+232 (int (*)(...))QGraphicsTextItem::focusInEvent
+240 (int (*)(...))QGraphicsTextItem::focusOutEvent
+248 (int (*)(...))QGraphicsTextItem::dragEnterEvent
+256 (int (*)(...))QGraphicsTextItem::dragLeaveEvent
+264 (int (*)(...))QGraphicsTextItem::dragMoveEvent
+272 (int (*)(...))QGraphicsTextItem::dropEvent
+280 (int (*)(...))QGraphicsTextItem::inputMethodEvent
+288 (int (*)(...))QGraphicsTextItem::hoverEnterEvent
+296 (int (*)(...))QGraphicsTextItem::hoverMoveEvent
+304 (int (*)(...))QGraphicsTextItem::hoverLeaveEvent
+312 (int (*)(...))QGraphicsTextItem::inputMethodQuery
+320 (int (*)(...))QGraphicsTextItem::supportsExtension
+328 (int (*)(...))QGraphicsTextItem::setExtension
+336 (int (*)(...))QGraphicsTextItem::extension
+344 (int (*)(...))-16
+352 (int (*)(...))(& _ZTI17QGraphicsTextItem)
+360 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItemD1Ev
+368 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItemD0Ev
+376 (int (*)(...))QGraphicsItem::advance
+384 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem12boundingRectEv
+392 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem5shapeEv
+400 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem8containsERK7QPointF
+408 (int (*)(...))QGraphicsItem::collidesWithItem
+416 (int (*)(...))QGraphicsItem::collidesWithPath
+424 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem12isObscuredByEPK13QGraphicsItem
+432 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem10opaqueAreaEv
+440 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem5paintEP8QPainterPK24QStyleOptionGraphicsItemP7QWidget
+448 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem4typeEv
+456 (int (*)(...))QGraphicsItem::sceneEventFilter
+464 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem10sceneEventEP6QEvent
+472 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem16contextMenuEventEP30QGraphicsSceneContextMenuEvent
+480 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem14dragEnterEventEP27QGraphicsSceneDragDropEvent
+488 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem14dragLeaveEventEP27QGraphicsSceneDragDropEvent
+496 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem13dragMoveEventEP27QGraphicsSceneDragDropEvent
+504 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem9dropEventEP27QGraphicsSceneDragDropEvent
+512 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem12focusInEventEP11QFocusEvent
+520 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem13focusOutEventEP11QFocusEvent
+528 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem15hoverEnterEventEP24QGraphicsSceneHoverEvent
+536 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem14hoverMoveEventEP24QGraphicsSceneHoverEvent
+544 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem15hoverLeaveEventEP24QGraphicsSceneHoverEvent
+552 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem13keyPressEventEP9QKeyEvent
+560 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem15keyReleaseEventEP9QKeyEvent
+568 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem15mousePressEventEP24QGraphicsSceneMouseEvent
+576 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem14mouseMoveEventEP24QGraphicsSceneMouseEvent
+584 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem17mouseReleaseEventEP24QGraphicsSceneMouseEvent
+592 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem21mouseDoubleClickEventEP24QGraphicsSceneMouseEvent
+600 (int (*)(...))QGraphicsItem::wheelEvent
+608 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem16inputMethodEventEP17QInputMethodEvent
+616 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem16inputMethodQueryEN2Qt16InputMethodQueryE
+624 (int (*)(...))QGraphicsItem::itemChange
+632 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem17supportsExtensionEN13QGraphicsItem9ExtensionE
+640 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem12setExtensionEN13QGraphicsItem9ExtensionERK8QVariant
+648 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem9extensionERK8QVariant
+
+Class QGraphicsTextItem
+ size=40 align=8
+ base size=40 base align=8
+QGraphicsTextItem (0x0x7f8846436d00) 0
+ vptr=((& QGraphicsTextItem::_ZTV17QGraphicsTextItem) + 16u)
+ QGraphicsObject (0x0x7f88462c4700) 0
+ primary-for QGraphicsTextItem (0x0x7f8846436d00)
+ QObject (0x0x7f88464baea0) 0
+ primary-for QGraphicsObject (0x0x7f88462c4700)
+ QGraphicsItem (0x0x7f88464baf00) 16
+ vptr=((& QGraphicsTextItem::_ZTV17QGraphicsTextItem) + 360u)
+
+Vtable for QGraphicsSimpleTextItem
+QGraphicsSimpleTextItem::_ZTV23QGraphicsSimpleTextItem: 39u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QGraphicsSimpleTextItem)
+16 (int (*)(...))QGraphicsSimpleTextItem::~QGraphicsSimpleTextItem
+24 (int (*)(...))QGraphicsSimpleTextItem::~QGraphicsSimpleTextItem
+32 (int (*)(...))QGraphicsItem::advance
+40 (int (*)(...))QGraphicsSimpleTextItem::boundingRect
+48 (int (*)(...))QGraphicsSimpleTextItem::shape
+56 (int (*)(...))QGraphicsSimpleTextItem::contains
+64 (int (*)(...))QGraphicsItem::collidesWithItem
+72 (int (*)(...))QGraphicsItem::collidesWithPath
+80 (int (*)(...))QGraphicsSimpleTextItem::isObscuredBy
+88 (int (*)(...))QGraphicsSimpleTextItem::opaqueArea
+96 (int (*)(...))QGraphicsSimpleTextItem::paint
+104 (int (*)(...))QGraphicsSimpleTextItem::type
+112 (int (*)(...))QGraphicsItem::sceneEventFilter
+120 (int (*)(...))QGraphicsItem::sceneEvent
+128 (int (*)(...))QGraphicsItem::contextMenuEvent
+136 (int (*)(...))QGraphicsItem::dragEnterEvent
+144 (int (*)(...))QGraphicsItem::dragLeaveEvent
+152 (int (*)(...))QGraphicsItem::dragMoveEvent
+160 (int (*)(...))QGraphicsItem::dropEvent
+168 (int (*)(...))QGraphicsItem::focusInEvent
+176 (int (*)(...))QGraphicsItem::focusOutEvent
+184 (int (*)(...))QGraphicsItem::hoverEnterEvent
+192 (int (*)(...))QGraphicsItem::hoverMoveEvent
+200 (int (*)(...))QGraphicsItem::hoverLeaveEvent
+208 (int (*)(...))QGraphicsItem::keyPressEvent
+216 (int (*)(...))QGraphicsItem::keyReleaseEvent
+224 (int (*)(...))QGraphicsItem::mousePressEvent
+232 (int (*)(...))QGraphicsItem::mouseMoveEvent
+240 (int (*)(...))QGraphicsItem::mouseReleaseEvent
+248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent
+256 (int (*)(...))QGraphicsItem::wheelEvent
+264 (int (*)(...))QGraphicsItem::inputMethodEvent
+272 (int (*)(...))QGraphicsItem::inputMethodQuery
+280 (int (*)(...))QGraphicsItem::itemChange
+288 (int (*)(...))QGraphicsSimpleTextItem::supportsExtension
+296 (int (*)(...))QGraphicsSimpleTextItem::setExtension
+304 (int (*)(...))QGraphicsSimpleTextItem::extension
+
+Class QGraphicsSimpleTextItem
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsSimpleTextItem (0x0x7f8846436e38) 0
+ vptr=((& QGraphicsSimpleTextItem::_ZTV23QGraphicsSimpleTextItem) + 16u)
+ QAbstractGraphicsShapeItem (0x0x7f8846436ea0) 0
+ primary-for QGraphicsSimpleTextItem (0x0x7f8846436e38)
+ QGraphicsItem (0x0x7f88462f81e0) 0
+ primary-for QAbstractGraphicsShapeItem (0x0x7f8846436ea0)
+
+Vtable for QGraphicsItemGroup
+QGraphicsItemGroup::_ZTV18QGraphicsItemGroup: 39u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QGraphicsItemGroup)
+16 (int (*)(...))QGraphicsItemGroup::~QGraphicsItemGroup
+24 (int (*)(...))QGraphicsItemGroup::~QGraphicsItemGroup
+32 (int (*)(...))QGraphicsItem::advance
+40 (int (*)(...))QGraphicsItemGroup::boundingRect
+48 (int (*)(...))QGraphicsItem::shape
+56 (int (*)(...))QGraphicsItem::contains
+64 (int (*)(...))QGraphicsItem::collidesWithItem
+72 (int (*)(...))QGraphicsItem::collidesWithPath
+80 (int (*)(...))QGraphicsItemGroup::isObscuredBy
+88 (int (*)(...))QGraphicsItemGroup::opaqueArea
+96 (int (*)(...))QGraphicsItemGroup::paint
+104 (int (*)(...))QGraphicsItemGroup::type
+112 (int (*)(...))QGraphicsItem::sceneEventFilter
+120 (int (*)(...))QGraphicsItem::sceneEvent
+128 (int (*)(...))QGraphicsItem::contextMenuEvent
+136 (int (*)(...))QGraphicsItem::dragEnterEvent
+144 (int (*)(...))QGraphicsItem::dragLeaveEvent
+152 (int (*)(...))QGraphicsItem::dragMoveEvent
+160 (int (*)(...))QGraphicsItem::dropEvent
+168 (int (*)(...))QGraphicsItem::focusInEvent
+176 (int (*)(...))QGraphicsItem::focusOutEvent
+184 (int (*)(...))QGraphicsItem::hoverEnterEvent
+192 (int (*)(...))QGraphicsItem::hoverMoveEvent
+200 (int (*)(...))QGraphicsItem::hoverLeaveEvent
+208 (int (*)(...))QGraphicsItem::keyPressEvent
+216 (int (*)(...))QGraphicsItem::keyReleaseEvent
+224 (int (*)(...))QGraphicsItem::mousePressEvent
+232 (int (*)(...))QGraphicsItem::mouseMoveEvent
+240 (int (*)(...))QGraphicsItem::mouseReleaseEvent
+248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent
+256 (int (*)(...))QGraphicsItem::wheelEvent
+264 (int (*)(...))QGraphicsItem::inputMethodEvent
+272 (int (*)(...))QGraphicsItem::inputMethodQuery
+280 (int (*)(...))QGraphicsItem::itemChange
+288 (int (*)(...))QGraphicsItem::supportsExtension
+296 (int (*)(...))QGraphicsItem::setExtension
+304 (int (*)(...))QGraphicsItem::extension
+
+Class QGraphicsItemGroup
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsItemGroup (0x0x7f8846436f08) 0
+ vptr=((& QGraphicsItemGroup::_ZTV18QGraphicsItemGroup) + 16u)
+ QGraphicsItem (0x0x7f88462f8240) 0
+ primary-for QGraphicsItemGroup (0x0x7f8846436f08)
+
+Vtable for QGraphicsLayoutItem
+QGraphicsLayoutItem::_ZTV19QGraphicsLayoutItem: 8u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QGraphicsLayoutItem)
+16 0u
+24 0u
+32 (int (*)(...))QGraphicsLayoutItem::setGeometry
+40 (int (*)(...))QGraphicsLayoutItem::getContentsMargins
+48 (int (*)(...))QGraphicsLayoutItem::updateGeometry
+56 (int (*)(...))__cxa_pure_virtual
+
+Class QGraphicsLayoutItem
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsLayoutItem (0x0x7f88462f83c0) 0
+ vptr=((& QGraphicsLayoutItem::_ZTV19QGraphicsLayoutItem) + 16u)
+
+Vtable for QGraphicsLayout
+QGraphicsLayout::_ZTV15QGraphicsLayout: 13u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QGraphicsLayout)
+16 0u
+24 0u
+32 (int (*)(...))QGraphicsLayoutItem::setGeometry
+40 (int (*)(...))QGraphicsLayout::getContentsMargins
+48 (int (*)(...))QGraphicsLayout::updateGeometry
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))QGraphicsLayout::invalidate
+72 (int (*)(...))QGraphicsLayout::widgetEvent
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))__cxa_pure_virtual
+96 (int (*)(...))__cxa_pure_virtual
+
+Class QGraphicsLayout
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsLayout (0x0x7f8846436f70) 0
+ vptr=((& QGraphicsLayout::_ZTV15QGraphicsLayout) + 16u)
+ QGraphicsLayoutItem (0x0x7f88462f8540) 0
+ primary-for QGraphicsLayout (0x0x7f8846436f70)
+
+Class QGraphicsAnchor::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsAnchor::QPrivateSignal (0x0x7f88462f8660) 0 empty
+
+Vtable for QGraphicsAnchor
+QGraphicsAnchor::_ZTV15QGraphicsAnchor: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QGraphicsAnchor)
+16 (int (*)(...))QGraphicsAnchor::metaObject
+24 (int (*)(...))QGraphicsAnchor::qt_metacast
+32 (int (*)(...))QGraphicsAnchor::qt_metacall
+40 (int (*)(...))QGraphicsAnchor::~QGraphicsAnchor
+48 (int (*)(...))QGraphicsAnchor::~QGraphicsAnchor
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QGraphicsAnchor
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsAnchor (0x0x7f8845f59000) 0
+ vptr=((& QGraphicsAnchor::_ZTV15QGraphicsAnchor) + 16u)
+ QObject (0x0x7f88462f8600) 0
+ primary-for QGraphicsAnchor (0x0x7f8845f59000)
+
+Vtable for QGraphicsAnchorLayout
+QGraphicsAnchorLayout::_ZTV21QGraphicsAnchorLayout: 13u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QGraphicsAnchorLayout)
+16 (int (*)(...))QGraphicsAnchorLayout::~QGraphicsAnchorLayout
+24 (int (*)(...))QGraphicsAnchorLayout::~QGraphicsAnchorLayout
+32 (int (*)(...))QGraphicsAnchorLayout::setGeometry
+40 (int (*)(...))QGraphicsLayout::getContentsMargins
+48 (int (*)(...))QGraphicsLayout::updateGeometry
+56 (int (*)(...))QGraphicsAnchorLayout::sizeHint
+64 (int (*)(...))QGraphicsAnchorLayout::invalidate
+72 (int (*)(...))QGraphicsLayout::widgetEvent
+80 (int (*)(...))QGraphicsAnchorLayout::count
+88 (int (*)(...))QGraphicsAnchorLayout::itemAt
+96 (int (*)(...))QGraphicsAnchorLayout::removeAt
+
+Class QGraphicsAnchorLayout
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsAnchorLayout (0x0x7f8845f59068) 0
+ vptr=((& QGraphicsAnchorLayout::_ZTV21QGraphicsAnchorLayout) + 16u)
+ QGraphicsLayout (0x0x7f8845f590d0) 0
+ primary-for QGraphicsAnchorLayout (0x0x7f8845f59068)
+ QGraphicsLayoutItem (0x0x7f88462f86c0) 0
+ primary-for QGraphicsLayout (0x0x7f8845f590d0)
+
+Class QGraphicsEffect::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsEffect::QPrivateSignal (0x0x7f88462f8780) 0 empty
+
+Vtable for QGraphicsEffect
+QGraphicsEffect::_ZTV15QGraphicsEffect: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QGraphicsEffect)
+16 (int (*)(...))QGraphicsEffect::metaObject
+24 (int (*)(...))QGraphicsEffect::qt_metacast
+32 (int (*)(...))QGraphicsEffect::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGraphicsEffect::boundingRectFor
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))QGraphicsEffect::sourceChanged
+
+Class QGraphicsEffect
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsEffect (0x0x7f8845f59138) 0
+ vptr=((& QGraphicsEffect::_ZTV15QGraphicsEffect) + 16u)
+ QObject (0x0x7f88462f8720) 0
+ primary-for QGraphicsEffect (0x0x7f8845f59138)
+
+Class QGraphicsColorizeEffect::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsColorizeEffect::QPrivateSignal (0x0x7f88462f89c0) 0 empty
+
+Vtable for QGraphicsColorizeEffect
+QGraphicsColorizeEffect::_ZTV23QGraphicsColorizeEffect: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QGraphicsColorizeEffect)
+16 (int (*)(...))QGraphicsColorizeEffect::metaObject
+24 (int (*)(...))QGraphicsColorizeEffect::qt_metacast
+32 (int (*)(...))QGraphicsColorizeEffect::qt_metacall
+40 (int (*)(...))QGraphicsColorizeEffect::~QGraphicsColorizeEffect
+48 (int (*)(...))QGraphicsColorizeEffect::~QGraphicsColorizeEffect
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGraphicsEffect::boundingRectFor
+120 (int (*)(...))QGraphicsColorizeEffect::draw
+128 (int (*)(...))QGraphicsEffect::sourceChanged
+
+Class QGraphicsColorizeEffect
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsColorizeEffect (0x0x7f8845f59270) 0
+ vptr=((& QGraphicsColorizeEffect::_ZTV23QGraphicsColorizeEffect) + 16u)
+ QGraphicsEffect (0x0x7f8845f592d8) 0
+ primary-for QGraphicsColorizeEffect (0x0x7f8845f59270)
+ QObject (0x0x7f88462f8960) 0
+ primary-for QGraphicsEffect (0x0x7f8845f592d8)
+
+Class QGraphicsBlurEffect::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsBlurEffect::QPrivateSignal (0x0x7f88462f8a80) 0 empty
+
+Vtable for QGraphicsBlurEffect
+QGraphicsBlurEffect::_ZTV19QGraphicsBlurEffect: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QGraphicsBlurEffect)
+16 (int (*)(...))QGraphicsBlurEffect::metaObject
+24 (int (*)(...))QGraphicsBlurEffect::qt_metacast
+32 (int (*)(...))QGraphicsBlurEffect::qt_metacall
+40 (int (*)(...))QGraphicsBlurEffect::~QGraphicsBlurEffect
+48 (int (*)(...))QGraphicsBlurEffect::~QGraphicsBlurEffect
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGraphicsBlurEffect::boundingRectFor
+120 (int (*)(...))QGraphicsBlurEffect::draw
+128 (int (*)(...))QGraphicsEffect::sourceChanged
+
+Class QGraphicsBlurEffect
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsBlurEffect (0x0x7f8845f59340) 0
+ vptr=((& QGraphicsBlurEffect::_ZTV19QGraphicsBlurEffect) + 16u)
+ QGraphicsEffect (0x0x7f8845f593a8) 0
+ primary-for QGraphicsBlurEffect (0x0x7f8845f59340)
+ QObject (0x0x7f88462f8a20) 0
+ primary-for QGraphicsEffect (0x0x7f8845f593a8)
+
+Class QGraphicsDropShadowEffect::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsDropShadowEffect::QPrivateSignal (0x0x7f88462f8cc0) 0 empty
+
+Vtable for QGraphicsDropShadowEffect
+QGraphicsDropShadowEffect::_ZTV25QGraphicsDropShadowEffect: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI25QGraphicsDropShadowEffect)
+16 (int (*)(...))QGraphicsDropShadowEffect::metaObject
+24 (int (*)(...))QGraphicsDropShadowEffect::qt_metacast
+32 (int (*)(...))QGraphicsDropShadowEffect::qt_metacall
+40 (int (*)(...))QGraphicsDropShadowEffect::~QGraphicsDropShadowEffect
+48 (int (*)(...))QGraphicsDropShadowEffect::~QGraphicsDropShadowEffect
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGraphicsDropShadowEffect::boundingRectFor
+120 (int (*)(...))QGraphicsDropShadowEffect::draw
+128 (int (*)(...))QGraphicsEffect::sourceChanged
+
+Class QGraphicsDropShadowEffect
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsDropShadowEffect (0x0x7f8845f594e0) 0
+ vptr=((& QGraphicsDropShadowEffect::_ZTV25QGraphicsDropShadowEffect) + 16u)
+ QGraphicsEffect (0x0x7f8845f59548) 0
+ primary-for QGraphicsDropShadowEffect (0x0x7f8845f594e0)
+ QObject (0x0x7f88462f8c60) 0
+ primary-for QGraphicsEffect (0x0x7f8845f59548)
+
+Class QGraphicsOpacityEffect::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsOpacityEffect::QPrivateSignal (0x0x7f88462f8d80) 0 empty
+
+Vtable for QGraphicsOpacityEffect
+QGraphicsOpacityEffect::_ZTV22QGraphicsOpacityEffect: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI22QGraphicsOpacityEffect)
+16 (int (*)(...))QGraphicsOpacityEffect::metaObject
+24 (int (*)(...))QGraphicsOpacityEffect::qt_metacast
+32 (int (*)(...))QGraphicsOpacityEffect::qt_metacall
+40 (int (*)(...))QGraphicsOpacityEffect::~QGraphicsOpacityEffect
+48 (int (*)(...))QGraphicsOpacityEffect::~QGraphicsOpacityEffect
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGraphicsEffect::boundingRectFor
+120 (int (*)(...))QGraphicsOpacityEffect::draw
+128 (int (*)(...))QGraphicsEffect::sourceChanged
+
+Class QGraphicsOpacityEffect
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsOpacityEffect (0x0x7f8845f595b0) 0
+ vptr=((& QGraphicsOpacityEffect::_ZTV22QGraphicsOpacityEffect) + 16u)
+ QGraphicsEffect (0x0x7f8845f59618) 0
+ primary-for QGraphicsOpacityEffect (0x0x7f8845f595b0)
+ QObject (0x0x7f88462f8d20) 0
+ primary-for QGraphicsEffect (0x0x7f8845f59618)
+
+Vtable for QGraphicsGridLayout
+QGraphicsGridLayout::_ZTV19QGraphicsGridLayout: 13u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QGraphicsGridLayout)
+16 (int (*)(...))QGraphicsGridLayout::~QGraphicsGridLayout
+24 (int (*)(...))QGraphicsGridLayout::~QGraphicsGridLayout
+32 (int (*)(...))QGraphicsGridLayout::setGeometry
+40 (int (*)(...))QGraphicsLayout::getContentsMargins
+48 (int (*)(...))QGraphicsLayout::updateGeometry
+56 (int (*)(...))QGraphicsGridLayout::sizeHint
+64 (int (*)(...))QGraphicsGridLayout::invalidate
+72 (int (*)(...))QGraphicsLayout::widgetEvent
+80 (int (*)(...))QGraphicsGridLayout::count
+88 (int (*)(...))QGraphicsGridLayout::itemAt
+96 (int (*)(...))QGraphicsGridLayout::removeAt
+
+Class QGraphicsGridLayout
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsGridLayout (0x0x7f8845f59680) 0
+ vptr=((& QGraphicsGridLayout::_ZTV19QGraphicsGridLayout) + 16u)
+ QGraphicsLayout (0x0x7f8845f596e8) 0
+ primary-for QGraphicsGridLayout (0x0x7f8845f59680)
+ QGraphicsLayoutItem (0x0x7f88462f8de0) 0
+ primary-for QGraphicsLayout (0x0x7f8845f596e8)
+
+Class QGraphicsItemAnimation::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsItemAnimation::QPrivateSignal (0x0x7f88462f8ea0) 0 empty
+
+Vtable for QGraphicsItemAnimation
+QGraphicsItemAnimation::_ZTV22QGraphicsItemAnimation: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI22QGraphicsItemAnimation)
+16 (int (*)(...))QGraphicsItemAnimation::metaObject
+24 (int (*)(...))QGraphicsItemAnimation::qt_metacast
+32 (int (*)(...))QGraphicsItemAnimation::qt_metacall
+40 (int (*)(...))QGraphicsItemAnimation::~QGraphicsItemAnimation
+48 (int (*)(...))QGraphicsItemAnimation::~QGraphicsItemAnimation
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGraphicsItemAnimation::beforeAnimationStep
+120 (int (*)(...))QGraphicsItemAnimation::afterAnimationStep
+
+Class QGraphicsItemAnimation
+ size=24 align=8
+ base size=24 base align=8
+QGraphicsItemAnimation (0x0x7f8845f597b8) 0
+ vptr=((& QGraphicsItemAnimation::_ZTV22QGraphicsItemAnimation) + 16u)
+ QObject (0x0x7f88462f8e40) 0
+ primary-for QGraphicsItemAnimation (0x0x7f8845f597b8)
+
+Vtable for QGraphicsLinearLayout
+QGraphicsLinearLayout::_ZTV21QGraphicsLinearLayout: 13u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QGraphicsLinearLayout)
+16 (int (*)(...))QGraphicsLinearLayout::~QGraphicsLinearLayout
+24 (int (*)(...))QGraphicsLinearLayout::~QGraphicsLinearLayout
+32 (int (*)(...))QGraphicsLinearLayout::setGeometry
+40 (int (*)(...))QGraphicsLayout::getContentsMargins
+48 (int (*)(...))QGraphicsLayout::updateGeometry
+56 (int (*)(...))QGraphicsLinearLayout::sizeHint
+64 (int (*)(...))QGraphicsLinearLayout::invalidate
+72 (int (*)(...))QGraphicsLayout::widgetEvent
+80 (int (*)(...))QGraphicsLinearLayout::count
+88 (int (*)(...))QGraphicsLinearLayout::itemAt
+96 (int (*)(...))QGraphicsLinearLayout::removeAt
+
+Class QGraphicsLinearLayout
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsLinearLayout (0x0x7f8845f59820) 0
+ vptr=((& QGraphicsLinearLayout::_ZTV21QGraphicsLinearLayout) + 16u)
+ QGraphicsLayout (0x0x7f8845f59888) 0
+ primary-for QGraphicsLinearLayout (0x0x7f8845f59820)
+ QGraphicsLayoutItem (0x0x7f88462f8f00) 0
+ primary-for QGraphicsLayout (0x0x7f8845f59888)
+
+Class QGraphicsWidget::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsWidget::QPrivateSignal (0x0x7f884607e0c0) 0 empty
+
+Vtable for QGraphicsWidget
+QGraphicsWidget::_ZTV15QGraphicsWidget: 92u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QGraphicsWidget)
+16 (int (*)(...))QGraphicsWidget::metaObject
+24 (int (*)(...))QGraphicsWidget::qt_metacast
+32 (int (*)(...))QGraphicsWidget::qt_metacall
+40 (int (*)(...))QGraphicsWidget::~QGraphicsWidget
+48 (int (*)(...))QGraphicsWidget::~QGraphicsWidget
+56 (int (*)(...))QGraphicsWidget::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGraphicsWidget::setGeometry
+120 (int (*)(...))QGraphicsWidget::getContentsMargins
+128 (int (*)(...))QGraphicsWidget::type
+136 (int (*)(...))QGraphicsWidget::paint
+144 (int (*)(...))QGraphicsWidget::paintWindowFrame
+152 (int (*)(...))QGraphicsWidget::boundingRect
+160 (int (*)(...))QGraphicsWidget::shape
+168 (int (*)(...))QGraphicsWidget::initStyleOption
+176 (int (*)(...))QGraphicsWidget::sizeHint
+184 (int (*)(...))QGraphicsWidget::updateGeometry
+192 (int (*)(...))QGraphicsWidget::itemChange
+200 (int (*)(...))QGraphicsWidget::propertyChange
+208 (int (*)(...))QGraphicsWidget::sceneEvent
+216 (int (*)(...))QGraphicsWidget::windowFrameEvent
+224 (int (*)(...))QGraphicsWidget::windowFrameSectionAt
+232 (int (*)(...))QGraphicsWidget::changeEvent
+240 (int (*)(...))QGraphicsWidget::closeEvent
+248 (int (*)(...))QGraphicsWidget::focusInEvent
+256 (int (*)(...))QGraphicsWidget::focusNextPrevChild
+264 (int (*)(...))QGraphicsWidget::focusOutEvent
+272 (int (*)(...))QGraphicsWidget::hideEvent
+280 (int (*)(...))QGraphicsWidget::moveEvent
+288 (int (*)(...))QGraphicsWidget::polishEvent
+296 (int (*)(...))QGraphicsWidget::resizeEvent
+304 (int (*)(...))QGraphicsWidget::showEvent
+312 (int (*)(...))QGraphicsWidget::hoverMoveEvent
+320 (int (*)(...))QGraphicsWidget::hoverLeaveEvent
+328 (int (*)(...))QGraphicsWidget::grabMouseEvent
+336 (int (*)(...))QGraphicsWidget::ungrabMouseEvent
+344 (int (*)(...))QGraphicsWidget::grabKeyboardEvent
+352 (int (*)(...))QGraphicsWidget::ungrabKeyboardEvent
+360 (int (*)(...))-16
+368 (int (*)(...))(& _ZTI15QGraphicsWidget)
+376 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidgetD1Ev
+384 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidgetD0Ev
+392 (int (*)(...))QGraphicsItem::advance
+400 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget12boundingRectEv
+408 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget5shapeEv
+416 (int (*)(...))QGraphicsItem::contains
+424 (int (*)(...))QGraphicsItem::collidesWithItem
+432 (int (*)(...))QGraphicsItem::collidesWithPath
+440 (int (*)(...))QGraphicsItem::isObscuredBy
+448 (int (*)(...))QGraphicsItem::opaqueArea
+456 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget5paintEP8QPainterPK24QStyleOptionGraphicsItemP7QWidget
+464 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget4typeEv
+472 (int (*)(...))QGraphicsItem::sceneEventFilter
+480 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget10sceneEventEP6QEvent
+488 (int (*)(...))QGraphicsItem::contextMenuEvent
+496 (int (*)(...))QGraphicsItem::dragEnterEvent
+504 (int (*)(...))QGraphicsItem::dragLeaveEvent
+512 (int (*)(...))QGraphicsItem::dragMoveEvent
+520 (int (*)(...))QGraphicsItem::dropEvent
+528 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget12focusInEventEP11QFocusEvent
+536 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget13focusOutEventEP11QFocusEvent
+544 (int (*)(...))QGraphicsItem::hoverEnterEvent
+552 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget14hoverMoveEventEP24QGraphicsSceneHoverEvent
+560 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget15hoverLeaveEventEP24QGraphicsSceneHoverEvent
+568 (int (*)(...))QGraphicsItem::keyPressEvent
+576 (int (*)(...))QGraphicsItem::keyReleaseEvent
+584 (int (*)(...))QGraphicsItem::mousePressEvent
+592 (int (*)(...))QGraphicsItem::mouseMoveEvent
+600 (int (*)(...))QGraphicsItem::mouseReleaseEvent
+608 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent
+616 (int (*)(...))QGraphicsItem::wheelEvent
+624 (int (*)(...))QGraphicsItem::inputMethodEvent
+632 (int (*)(...))QGraphicsItem::inputMethodQuery
+640 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget10itemChangeEN13QGraphicsItem18GraphicsItemChangeERK8QVariant
+648 (int (*)(...))QGraphicsItem::supportsExtension
+656 (int (*)(...))QGraphicsItem::setExtension
+664 (int (*)(...))QGraphicsItem::extension
+672 (int (*)(...))-32
+680 (int (*)(...))(& _ZTI15QGraphicsWidget)
+688 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidgetD1Ev
+696 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidgetD0Ev
+704 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidget11setGeometryERK6QRectF
+712 (int (*)(...))QGraphicsWidget::_ZThn32_NK15QGraphicsWidget18getContentsMarginsEPdS0_S0_S0_
+720 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidget14updateGeometryEv
+728 (int (*)(...))QGraphicsWidget::_ZThn32_NK15QGraphicsWidget8sizeHintEN2Qt8SizeHintERK6QSizeF
+
+Class QGraphicsWidget
+ size=48 align=8
+ base size=48 base align=8
+QGraphicsWidget (0x0x7f8846057770) 0
+ vptr=((& QGraphicsWidget::_ZTV15QGraphicsWidget) + 16u)
+ QGraphicsObject (0x0x7f88460577e0) 0
+ primary-for QGraphicsWidget (0x0x7f8846057770)
+ QObject (0x0x7f88462f8f60) 0
+ primary-for QGraphicsObject (0x0x7f88460577e0)
+ QGraphicsItem (0x0x7f884607e000) 16
+ vptr=((& QGraphicsWidget::_ZTV15QGraphicsWidget) + 376u)
+ QGraphicsLayoutItem (0x0x7f884607e060) 32
+ vptr=((& QGraphicsWidget::_ZTV15QGraphicsWidget) + 688u)
+
+Class QGraphicsProxyWidget::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsProxyWidget::QPrivateSignal (0x0x7f884607e300) 0 empty
+
+Vtable for QGraphicsProxyWidget
+QGraphicsProxyWidget::_ZTV20QGraphicsProxyWidget: 107u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QGraphicsProxyWidget)
+16 (int (*)(...))QGraphicsProxyWidget::metaObject
+24 (int (*)(...))QGraphicsProxyWidget::qt_metacast
+32 (int (*)(...))QGraphicsProxyWidget::qt_metacall
+40 (int (*)(...))QGraphicsProxyWidget::~QGraphicsProxyWidget
+48 (int (*)(...))QGraphicsProxyWidget::~QGraphicsProxyWidget
+56 (int (*)(...))QGraphicsProxyWidget::event
+64 (int (*)(...))QGraphicsProxyWidget::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGraphicsProxyWidget::setGeometry
+120 (int (*)(...))QGraphicsWidget::getContentsMargins
+128 (int (*)(...))QGraphicsProxyWidget::type
+136 (int (*)(...))QGraphicsProxyWidget::paint
+144 (int (*)(...))QGraphicsWidget::paintWindowFrame
+152 (int (*)(...))QGraphicsWidget::boundingRect
+160 (int (*)(...))QGraphicsWidget::shape
+168 (int (*)(...))QGraphicsWidget::initStyleOption
+176 (int (*)(...))QGraphicsProxyWidget::sizeHint
+184 (int (*)(...))QGraphicsWidget::updateGeometry
+192 (int (*)(...))QGraphicsProxyWidget::itemChange
+200 (int (*)(...))QGraphicsWidget::propertyChange
+208 (int (*)(...))QGraphicsWidget::sceneEvent
+216 (int (*)(...))QGraphicsWidget::windowFrameEvent
+224 (int (*)(...))QGraphicsWidget::windowFrameSectionAt
+232 (int (*)(...))QGraphicsWidget::changeEvent
+240 (int (*)(...))QGraphicsWidget::closeEvent
+248 (int (*)(...))QGraphicsProxyWidget::focusInEvent
+256 (int (*)(...))QGraphicsProxyWidget::focusNextPrevChild
+264 (int (*)(...))QGraphicsProxyWidget::focusOutEvent
+272 (int (*)(...))QGraphicsProxyWidget::hideEvent
+280 (int (*)(...))QGraphicsWidget::moveEvent
+288 (int (*)(...))QGraphicsWidget::polishEvent
+296 (int (*)(...))QGraphicsProxyWidget::resizeEvent
+304 (int (*)(...))QGraphicsProxyWidget::showEvent
+312 (int (*)(...))QGraphicsProxyWidget::hoverMoveEvent
+320 (int (*)(...))QGraphicsProxyWidget::hoverLeaveEvent
+328 (int (*)(...))QGraphicsProxyWidget::grabMouseEvent
+336 (int (*)(...))QGraphicsProxyWidget::ungrabMouseEvent
+344 (int (*)(...))QGraphicsWidget::grabKeyboardEvent
+352 (int (*)(...))QGraphicsWidget::ungrabKeyboardEvent
+360 (int (*)(...))QGraphicsProxyWidget::contextMenuEvent
+368 (int (*)(...))QGraphicsProxyWidget::dragEnterEvent
+376 (int (*)(...))QGraphicsProxyWidget::dragLeaveEvent
+384 (int (*)(...))QGraphicsProxyWidget::dragMoveEvent
+392 (int (*)(...))QGraphicsProxyWidget::dropEvent
+400 (int (*)(...))QGraphicsProxyWidget::hoverEnterEvent
+408 (int (*)(...))QGraphicsProxyWidget::mouseMoveEvent
+416 (int (*)(...))QGraphicsProxyWidget::mousePressEvent
+424 (int (*)(...))QGraphicsProxyWidget::mouseReleaseEvent
+432 (int (*)(...))QGraphicsProxyWidget::mouseDoubleClickEvent
+440 (int (*)(...))QGraphicsProxyWidget::wheelEvent
+448 (int (*)(...))QGraphicsProxyWidget::keyPressEvent
+456 (int (*)(...))QGraphicsProxyWidget::keyReleaseEvent
+464 (int (*)(...))QGraphicsProxyWidget::inputMethodQuery
+472 (int (*)(...))QGraphicsProxyWidget::inputMethodEvent
+480 (int (*)(...))-16
+488 (int (*)(...))(& _ZTI20QGraphicsProxyWidget)
+496 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidgetD1Ev
+504 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidgetD0Ev
+512 (int (*)(...))QGraphicsItem::advance
+520 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget12boundingRectEv
+528 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget5shapeEv
+536 (int (*)(...))QGraphicsItem::contains
+544 (int (*)(...))QGraphicsItem::collidesWithItem
+552 (int (*)(...))QGraphicsItem::collidesWithPath
+560 (int (*)(...))QGraphicsItem::isObscuredBy
+568 (int (*)(...))QGraphicsItem::opaqueArea
+576 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget5paintEP8QPainterPK24QStyleOptionGraphicsItemP7QWidget
+584 (int (*)(...))QGraphicsProxyWidget::_ZThn16_NK20QGraphicsProxyWidget4typeEv
+592 (int (*)(...))QGraphicsItem::sceneEventFilter
+600 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget10sceneEventEP6QEvent
+608 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget16contextMenuEventEP30QGraphicsSceneContextMenuEvent
+616 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget14dragEnterEventEP27QGraphicsSceneDragDropEvent
+624 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget14dragLeaveEventEP27QGraphicsSceneDragDropEvent
+632 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget13dragMoveEventEP27QGraphicsSceneDragDropEvent
+640 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget9dropEventEP27QGraphicsSceneDragDropEvent
+648 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget12focusInEventEP11QFocusEvent
+656 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget13focusOutEventEP11QFocusEvent
+664 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget15hoverEnterEventEP24QGraphicsSceneHoverEvent
+672 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget14hoverMoveEventEP24QGraphicsSceneHoverEvent
+680 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget15hoverLeaveEventEP24QGraphicsSceneHoverEvent
+688 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget13keyPressEventEP9QKeyEvent
+696 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget15keyReleaseEventEP9QKeyEvent
+704 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget15mousePressEventEP24QGraphicsSceneMouseEvent
+712 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget14mouseMoveEventEP24QGraphicsSceneMouseEvent
+720 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget17mouseReleaseEventEP24QGraphicsSceneMouseEvent
+728 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget21mouseDoubleClickEventEP24QGraphicsSceneMouseEvent
+736 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget10wheelEventEP24QGraphicsSceneWheelEvent
+744 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget16inputMethodEventEP17QInputMethodEvent
+752 (int (*)(...))QGraphicsProxyWidget::_ZThn16_NK20QGraphicsProxyWidget16inputMethodQueryEN2Qt16InputMethodQueryE
+760 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget10itemChangeEN13QGraphicsItem18GraphicsItemChangeERK8QVariant
+768 (int (*)(...))QGraphicsItem::supportsExtension
+776 (int (*)(...))QGraphicsItem::setExtension
+784 (int (*)(...))QGraphicsItem::extension
+792 (int (*)(...))-32
+800 (int (*)(...))(& _ZTI20QGraphicsProxyWidget)
+808 (int (*)(...))QGraphicsProxyWidget::_ZThn32_N20QGraphicsProxyWidgetD1Ev
+816 (int (*)(...))QGraphicsProxyWidget::_ZThn32_N20QGraphicsProxyWidgetD0Ev
+824 (int (*)(...))QGraphicsProxyWidget::_ZThn32_N20QGraphicsProxyWidget11setGeometryERK6QRectF
+832 (int (*)(...))QGraphicsWidget::_ZThn32_NK15QGraphicsWidget18getContentsMarginsEPdS0_S0_S0_
+840 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidget14updateGeometryEv
+848 (int (*)(...))QGraphicsProxyWidget::_ZThn32_NK20QGraphicsProxyWidget8sizeHintEN2Qt8SizeHintERK6QSizeF
+
+Class QGraphicsProxyWidget
+ size=48 align=8
+ base size=48 base align=8
+QGraphicsProxyWidget (0x0x7f8845f599c0) 0
+ vptr=((& QGraphicsProxyWidget::_ZTV20QGraphicsProxyWidget) + 16u)
+ QGraphicsWidget (0x0x7f88460b0150) 0
+ primary-for QGraphicsProxyWidget (0x0x7f8845f599c0)
+ QGraphicsObject (0x0x7f88460b01c0) 0
+ primary-for QGraphicsWidget (0x0x7f88460b0150)
+ QObject (0x0x7f884607e1e0) 0
+ primary-for QGraphicsObject (0x0x7f88460b01c0)
+ QGraphicsItem (0x0x7f884607e240) 16
+ vptr=((& QGraphicsProxyWidget::_ZTV20QGraphicsProxyWidget) + 496u)
+ QGraphicsLayoutItem (0x0x7f884607e2a0) 32
+ vptr=((& QGraphicsProxyWidget::_ZTV20QGraphicsProxyWidget) + 808u)
+
+Class QGraphicsScene::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsScene::QPrivateSignal (0x0x7f884607e540) 0 empty
+
+Vtable for QGraphicsScene
+QGraphicsScene::_ZTV14QGraphicsScene: 34u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QGraphicsScene)
+16 (int (*)(...))QGraphicsScene::metaObject
+24 (int (*)(...))QGraphicsScene::qt_metacast
+32 (int (*)(...))QGraphicsScene::qt_metacall
+40 (int (*)(...))QGraphicsScene::~QGraphicsScene
+48 (int (*)(...))QGraphicsScene::~QGraphicsScene
+56 (int (*)(...))QGraphicsScene::event
+64 (int (*)(...))QGraphicsScene::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGraphicsScene::inputMethodQuery
+120 (int (*)(...))QGraphicsScene::contextMenuEvent
+128 (int (*)(...))QGraphicsScene::dragEnterEvent
+136 (int (*)(...))QGraphicsScene::dragMoveEvent
+144 (int (*)(...))QGraphicsScene::dragLeaveEvent
+152 (int (*)(...))QGraphicsScene::dropEvent
+160 (int (*)(...))QGraphicsScene::focusInEvent
+168 (int (*)(...))QGraphicsScene::focusOutEvent
+176 (int (*)(...))QGraphicsScene::helpEvent
+184 (int (*)(...))QGraphicsScene::keyPressEvent
+192 (int (*)(...))QGraphicsScene::keyReleaseEvent
+200 (int (*)(...))QGraphicsScene::mousePressEvent
+208 (int (*)(...))QGraphicsScene::mouseMoveEvent
+216 (int (*)(...))QGraphicsScene::mouseReleaseEvent
+224 (int (*)(...))QGraphicsScene::mouseDoubleClickEvent
+232 (int (*)(...))QGraphicsScene::wheelEvent
+240 (int (*)(...))QGraphicsScene::inputMethodEvent
+248 (int (*)(...))QGraphicsScene::drawBackground
+256 (int (*)(...))QGraphicsScene::drawForeground
+264 (int (*)(...))QGraphicsScene::drawItems
+
+Class QGraphicsScene
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsScene (0x0x7f8845f59bc8) 0
+ vptr=((& QGraphicsScene::_ZTV14QGraphicsScene) + 16u)
+ QObject (0x0x7f884607e4e0) 0
+ primary-for QGraphicsScene (0x0x7f8845f59bc8)
+
+Vtable for QGraphicsSceneEvent
+QGraphicsSceneEvent::_ZTV19QGraphicsSceneEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QGraphicsSceneEvent)
+16 (int (*)(...))QGraphicsSceneEvent::~QGraphicsSceneEvent
+24 (int (*)(...))QGraphicsSceneEvent::~QGraphicsSceneEvent
+
+Class QGraphicsSceneEvent
+ size=32 align=8
+ base size=32 base align=8
+QGraphicsSceneEvent (0x0x7f8845f59dd0) 0
+ vptr=((& QGraphicsSceneEvent::_ZTV19QGraphicsSceneEvent) + 16u)
+ QEvent (0x0x7f884607e8a0) 0
+ primary-for QGraphicsSceneEvent (0x0x7f8845f59dd0)
+
+Vtable for QGraphicsSceneMouseEvent
+QGraphicsSceneMouseEvent::_ZTV24QGraphicsSceneMouseEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QGraphicsSceneMouseEvent)
+16 (int (*)(...))QGraphicsSceneMouseEvent::~QGraphicsSceneMouseEvent
+24 (int (*)(...))QGraphicsSceneMouseEvent::~QGraphicsSceneMouseEvent
+
+Class QGraphicsSceneMouseEvent
+ size=32 align=8
+ base size=32 base align=8
+QGraphicsSceneMouseEvent (0x0x7f8845f59e38) 0
+ vptr=((& QGraphicsSceneMouseEvent::_ZTV24QGraphicsSceneMouseEvent) + 16u)
+ QGraphicsSceneEvent (0x0x7f8845f59ea0) 0
+ primary-for QGraphicsSceneMouseEvent (0x0x7f8845f59e38)
+ QEvent (0x0x7f884607e9c0) 0
+ primary-for QGraphicsSceneEvent (0x0x7f8845f59ea0)
+
+Vtable for QGraphicsSceneWheelEvent
+QGraphicsSceneWheelEvent::_ZTV24QGraphicsSceneWheelEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QGraphicsSceneWheelEvent)
+16 (int (*)(...))QGraphicsSceneWheelEvent::~QGraphicsSceneWheelEvent
+24 (int (*)(...))QGraphicsSceneWheelEvent::~QGraphicsSceneWheelEvent
+
+Class QGraphicsSceneWheelEvent
+ size=32 align=8
+ base size=32 base align=8
+QGraphicsSceneWheelEvent (0x0x7f8845f59f08) 0
+ vptr=((& QGraphicsSceneWheelEvent::_ZTV24QGraphicsSceneWheelEvent) + 16u)
+ QGraphicsSceneEvent (0x0x7f8845f59f70) 0
+ primary-for QGraphicsSceneWheelEvent (0x0x7f8845f59f08)
+ QEvent (0x0x7f884607ea20) 0
+ primary-for QGraphicsSceneEvent (0x0x7f8845f59f70)
+
+Vtable for QGraphicsSceneContextMenuEvent
+QGraphicsSceneContextMenuEvent::_ZTV30QGraphicsSceneContextMenuEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI30QGraphicsSceneContextMenuEvent)
+16 (int (*)(...))QGraphicsSceneContextMenuEvent::~QGraphicsSceneContextMenuEvent
+24 (int (*)(...))QGraphicsSceneContextMenuEvent::~QGraphicsSceneContextMenuEvent
+
+Class QGraphicsSceneContextMenuEvent
+ size=32 align=8
+ base size=32 base align=8
+QGraphicsSceneContextMenuEvent (0x0x7f8845da7000) 0
+ vptr=((& QGraphicsSceneContextMenuEvent::_ZTV30QGraphicsSceneContextMenuEvent) + 16u)
+ QGraphicsSceneEvent (0x0x7f8845da7068) 0
+ primary-for QGraphicsSceneContextMenuEvent (0x0x7f8845da7000)
+ QEvent (0x0x7f884607ea80) 0
+ primary-for QGraphicsSceneEvent (0x0x7f8845da7068)
+
+Vtable for QGraphicsSceneHoverEvent
+QGraphicsSceneHoverEvent::_ZTV24QGraphicsSceneHoverEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QGraphicsSceneHoverEvent)
+16 (int (*)(...))QGraphicsSceneHoverEvent::~QGraphicsSceneHoverEvent
+24 (int (*)(...))QGraphicsSceneHoverEvent::~QGraphicsSceneHoverEvent
+
+Class QGraphicsSceneHoverEvent
+ size=32 align=8
+ base size=32 base align=8
+QGraphicsSceneHoverEvent (0x0x7f8845da70d0) 0
+ vptr=((& QGraphicsSceneHoverEvent::_ZTV24QGraphicsSceneHoverEvent) + 16u)
+ QGraphicsSceneEvent (0x0x7f8845da7138) 0
+ primary-for QGraphicsSceneHoverEvent (0x0x7f8845da70d0)
+ QEvent (0x0x7f884607eae0) 0
+ primary-for QGraphicsSceneEvent (0x0x7f8845da7138)
+
+Vtable for QGraphicsSceneHelpEvent
+QGraphicsSceneHelpEvent::_ZTV23QGraphicsSceneHelpEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QGraphicsSceneHelpEvent)
+16 (int (*)(...))QGraphicsSceneHelpEvent::~QGraphicsSceneHelpEvent
+24 (int (*)(...))QGraphicsSceneHelpEvent::~QGraphicsSceneHelpEvent
+
+Class QGraphicsSceneHelpEvent
+ size=32 align=8
+ base size=32 base align=8
+QGraphicsSceneHelpEvent (0x0x7f8845da71a0) 0
+ vptr=((& QGraphicsSceneHelpEvent::_ZTV23QGraphicsSceneHelpEvent) + 16u)
+ QGraphicsSceneEvent (0x0x7f8845da7208) 0
+ primary-for QGraphicsSceneHelpEvent (0x0x7f8845da71a0)
+ QEvent (0x0x7f884607eb40) 0
+ primary-for QGraphicsSceneEvent (0x0x7f8845da7208)
+
+Vtable for QGraphicsSceneDragDropEvent
+QGraphicsSceneDragDropEvent::_ZTV27QGraphicsSceneDragDropEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QGraphicsSceneDragDropEvent)
+16 (int (*)(...))QGraphicsSceneDragDropEvent::~QGraphicsSceneDragDropEvent
+24 (int (*)(...))QGraphicsSceneDragDropEvent::~QGraphicsSceneDragDropEvent
+
+Class QGraphicsSceneDragDropEvent
+ size=32 align=8
+ base size=32 base align=8
+QGraphicsSceneDragDropEvent (0x0x7f8845da7270) 0
+ vptr=((& QGraphicsSceneDragDropEvent::_ZTV27QGraphicsSceneDragDropEvent) + 16u)
+ QGraphicsSceneEvent (0x0x7f8845da72d8) 0
+ primary-for QGraphicsSceneDragDropEvent (0x0x7f8845da7270)
+ QEvent (0x0x7f884607eba0) 0
+ primary-for QGraphicsSceneEvent (0x0x7f8845da72d8)
+
+Vtable for QGraphicsSceneResizeEvent
+QGraphicsSceneResizeEvent::_ZTV25QGraphicsSceneResizeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI25QGraphicsSceneResizeEvent)
+16 (int (*)(...))QGraphicsSceneResizeEvent::~QGraphicsSceneResizeEvent
+24 (int (*)(...))QGraphicsSceneResizeEvent::~QGraphicsSceneResizeEvent
+
+Class QGraphicsSceneResizeEvent
+ size=32 align=8
+ base size=32 base align=8
+QGraphicsSceneResizeEvent (0x0x7f8845da7340) 0
+ vptr=((& QGraphicsSceneResizeEvent::_ZTV25QGraphicsSceneResizeEvent) + 16u)
+ QGraphicsSceneEvent (0x0x7f8845da73a8) 0
+ primary-for QGraphicsSceneResizeEvent (0x0x7f8845da7340)
+ QEvent (0x0x7f884607ec00) 0
+ primary-for QGraphicsSceneEvent (0x0x7f8845da73a8)
+
+Vtable for QGraphicsSceneMoveEvent
+QGraphicsSceneMoveEvent::_ZTV23QGraphicsSceneMoveEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QGraphicsSceneMoveEvent)
+16 (int (*)(...))QGraphicsSceneMoveEvent::~QGraphicsSceneMoveEvent
+24 (int (*)(...))QGraphicsSceneMoveEvent::~QGraphicsSceneMoveEvent
+
+Class QGraphicsSceneMoveEvent
+ size=32 align=8
+ base size=32 base align=8
+QGraphicsSceneMoveEvent (0x0x7f8845da7410) 0
+ vptr=((& QGraphicsSceneMoveEvent::_ZTV23QGraphicsSceneMoveEvent) + 16u)
+ QGraphicsSceneEvent (0x0x7f8845da7478) 0
+ primary-for QGraphicsSceneMoveEvent (0x0x7f8845da7410)
+ QEvent (0x0x7f884607ec60) 0
+ primary-for QGraphicsSceneEvent (0x0x7f8845da7478)
+
+Class QGraphicsTransform::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsTransform::QPrivateSignal (0x0x7f884607ed20) 0 empty
+
+Vtable for QGraphicsTransform
+QGraphicsTransform::_ZTV18QGraphicsTransform: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QGraphicsTransform)
+16 (int (*)(...))QGraphicsTransform::metaObject
+24 (int (*)(...))QGraphicsTransform::qt_metacast
+32 (int (*)(...))QGraphicsTransform::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+
+Class QGraphicsTransform
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsTransform (0x0x7f8845da74e0) 0
+ vptr=((& QGraphicsTransform::_ZTV18QGraphicsTransform) + 16u)
+ QObject (0x0x7f884607ecc0) 0
+ primary-for QGraphicsTransform (0x0x7f8845da74e0)
+
+Class QGraphicsScale::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsScale::QPrivateSignal (0x0x7f884607ede0) 0 empty
+
+Vtable for QGraphicsScale
+QGraphicsScale::_ZTV14QGraphicsScale: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QGraphicsScale)
+16 (int (*)(...))QGraphicsScale::metaObject
+24 (int (*)(...))QGraphicsScale::qt_metacast
+32 (int (*)(...))QGraphicsScale::qt_metacall
+40 (int (*)(...))QGraphicsScale::~QGraphicsScale
+48 (int (*)(...))QGraphicsScale::~QGraphicsScale
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGraphicsScale::applyTo
+
+Class QGraphicsScale
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsScale (0x0x7f8845da7548) 0
+ vptr=((& QGraphicsScale::_ZTV14QGraphicsScale) + 16u)
+ QGraphicsTransform (0x0x7f8845da75b0) 0
+ primary-for QGraphicsScale (0x0x7f8845da7548)
+ QObject (0x0x7f884607ed80) 0
+ primary-for QGraphicsTransform (0x0x7f8845da75b0)
+
+Class QGraphicsRotation::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsRotation::QPrivateSignal (0x0x7f884607eea0) 0 empty
+
+Vtable for QGraphicsRotation
+QGraphicsRotation::_ZTV17QGraphicsRotation: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QGraphicsRotation)
+16 (int (*)(...))QGraphicsRotation::metaObject
+24 (int (*)(...))QGraphicsRotation::qt_metacast
+32 (int (*)(...))QGraphicsRotation::qt_metacall
+40 (int (*)(...))QGraphicsRotation::~QGraphicsRotation
+48 (int (*)(...))QGraphicsRotation::~QGraphicsRotation
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGraphicsRotation::applyTo
+
+Class QGraphicsRotation
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsRotation (0x0x7f8845da7618) 0
+ vptr=((& QGraphicsRotation::_ZTV17QGraphicsRotation) + 16u)
+ QGraphicsTransform (0x0x7f8845da7680) 0
+ primary-for QGraphicsRotation (0x0x7f8845da7618)
+ QObject (0x0x7f884607ee40) 0
+ primary-for QGraphicsTransform (0x0x7f8845da7680)
+
+Class QScrollArea::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QScrollArea::QPrivateSignal (0x0x7f8845e0c000) 0 empty
+
+Vtable for QScrollArea
+QScrollArea::_ZTV11QScrollArea: 68u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QScrollArea)
+16 (int (*)(...))QScrollArea::metaObject
+24 (int (*)(...))QScrollArea::qt_metacast
+32 (int (*)(...))QScrollArea::qt_metacall
+40 (int (*)(...))QScrollArea::~QScrollArea
+48 (int (*)(...))QScrollArea::~QScrollArea
+56 (int (*)(...))QScrollArea::event
+64 (int (*)(...))QScrollArea::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QScrollArea::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractScrollArea::mousePressEvent
+176 (int (*)(...))QAbstractScrollArea::mouseReleaseEvent
+184 (int (*)(...))QAbstractScrollArea::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractScrollArea::mouseMoveEvent
+200 (int (*)(...))QAbstractScrollArea::wheelEvent
+208 (int (*)(...))QAbstractScrollArea::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QAbstractScrollArea::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QScrollArea::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QAbstractScrollArea::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QAbstractScrollArea::dragEnterEvent
+320 (int (*)(...))QAbstractScrollArea::dragMoveEvent
+328 (int (*)(...))QAbstractScrollArea::dragLeaveEvent
+336 (int (*)(...))QAbstractScrollArea::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QScrollArea::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QAbstractScrollArea::viewportEvent
+448 (int (*)(...))QScrollArea::scrollContentsBy
+456 (int (*)(...))QScrollArea::viewportSizeHint
+464 (int (*)(...))-16
+472 (int (*)(...))(& _ZTI11QScrollArea)
+480 (int (*)(...))QScrollArea::_ZThn16_N11QScrollAreaD1Ev
+488 (int (*)(...))QScrollArea::_ZThn16_N11QScrollAreaD0Ev
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QScrollArea
+ size=48 align=8
+ base size=48 base align=8
+QScrollArea (0x0x7f8845da76e8) 0
+ vptr=((& QScrollArea::_ZTV11QScrollArea) + 16u)
+ QAbstractScrollArea (0x0x7f8845da7750) 0
+ primary-for QScrollArea (0x0x7f8845da76e8)
+ QFrame (0x0x7f8845da77b8) 0
+ primary-for QAbstractScrollArea (0x0x7f8845da7750)
+ QWidget (0x0x7f8845e04230) 0
+ primary-for QFrame (0x0x7f8845da77b8)
+ QObject (0x0x7f884607ef00) 0
+ primary-for QWidget (0x0x7f8845e04230)
+ QPaintDevice (0x0x7f884607ef60) 16
+ vptr=((& QScrollArea::_ZTV11QScrollArea) + 480u)
+
+Class QGraphicsView::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsView::QPrivateSignal (0x0x7f8845e0c120) 0 empty
+
+Vtable for QGraphicsView
+QGraphicsView::_ZTV13QGraphicsView: 71u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QGraphicsView)
+16 (int (*)(...))QGraphicsView::metaObject
+24 (int (*)(...))QGraphicsView::qt_metacast
+32 (int (*)(...))QGraphicsView::qt_metacall
+40 (int (*)(...))QGraphicsView::~QGraphicsView
+48 (int (*)(...))QGraphicsView::~QGraphicsView
+56 (int (*)(...))QGraphicsView::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QGraphicsView::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QGraphicsView::mousePressEvent
+176 (int (*)(...))QGraphicsView::mouseReleaseEvent
+184 (int (*)(...))QGraphicsView::mouseDoubleClickEvent
+192 (int (*)(...))QGraphicsView::mouseMoveEvent
+200 (int (*)(...))QGraphicsView::wheelEvent
+208 (int (*)(...))QGraphicsView::keyPressEvent
+216 (int (*)(...))QGraphicsView::keyReleaseEvent
+224 (int (*)(...))QGraphicsView::focusInEvent
+232 (int (*)(...))QGraphicsView::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QGraphicsView::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QGraphicsView::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QGraphicsView::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QGraphicsView::dragEnterEvent
+320 (int (*)(...))QGraphicsView::dragMoveEvent
+328 (int (*)(...))QGraphicsView::dragLeaveEvent
+336 (int (*)(...))QGraphicsView::dropEvent
+344 (int (*)(...))QGraphicsView::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QGraphicsView::inputMethodEvent
+416 (int (*)(...))QGraphicsView::inputMethodQuery
+424 (int (*)(...))QGraphicsView::focusNextPrevChild
+432 (int (*)(...))QGraphicsView::setupViewport
+440 (int (*)(...))QGraphicsView::viewportEvent
+448 (int (*)(...))QGraphicsView::scrollContentsBy
+456 (int (*)(...))QAbstractScrollArea::viewportSizeHint
+464 (int (*)(...))QGraphicsView::drawBackground
+472 (int (*)(...))QGraphicsView::drawForeground
+480 (int (*)(...))QGraphicsView::drawItems
+488 (int (*)(...))-16
+496 (int (*)(...))(& _ZTI13QGraphicsView)
+504 (int (*)(...))QGraphicsView::_ZThn16_N13QGraphicsViewD1Ev
+512 (int (*)(...))QGraphicsView::_ZThn16_N13QGraphicsViewD0Ev
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QGraphicsView
+ size=48 align=8
+ base size=48 base align=8
+QGraphicsView (0x0x7f8845da7820) 0
+ vptr=((& QGraphicsView::_ZTV13QGraphicsView) + 16u)
+ QAbstractScrollArea (0x0x7f8845da7888) 0
+ primary-for QGraphicsView (0x0x7f8845da7820)
+ QFrame (0x0x7f8845da78f0) 0
+ primary-for QAbstractScrollArea (0x0x7f8845da7888)
+ QWidget (0x0x7f8845e04700) 0
+ primary-for QFrame (0x0x7f8845da78f0)
+ QObject (0x0x7f8845e0c060) 0
+ primary-for QWidget (0x0x7f8845e04700)
+ QPaintDevice (0x0x7f8845e0c0c0) 16
+ vptr=((& QGraphicsView::_ZTV13QGraphicsView) + 504u)
+
+Class QGroupBox::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGroupBox::QPrivateSignal (0x0x7f8845e0c540) 0 empty
+
+Vtable for QGroupBox
+QGroupBox::_ZTV9QGroupBox: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QGroupBox)
+16 (int (*)(...))QGroupBox::metaObject
+24 (int (*)(...))QGroupBox::qt_metacast
+32 (int (*)(...))QGroupBox::qt_metacall
+40 (int (*)(...))QGroupBox::~QGroupBox
+48 (int (*)(...))QGroupBox::~QGroupBox
+56 (int (*)(...))QGroupBox::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QGroupBox::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QGroupBox::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QGroupBox::mousePressEvent
+176 (int (*)(...))QGroupBox::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QGroupBox::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QGroupBox::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QGroupBox::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QGroupBox::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QGroupBox::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI9QGroupBox)
+448 (int (*)(...))QGroupBox::_ZThn16_N9QGroupBoxD1Ev
+456 (int (*)(...))QGroupBox::_ZThn16_N9QGroupBoxD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QGroupBox
+ size=48 align=8
+ base size=48 base align=8
+QGroupBox (0x0x7f8845da7af8) 0
+ vptr=((& QGroupBox::_ZTV9QGroupBox) + 16u)
+ QWidget (0x0x7f8845ec0f50) 0
+ primary-for QGroupBox (0x0x7f8845da7af8)
+ QObject (0x0x7f8845e0c480) 0
+ primary-for QWidget (0x0x7f8845ec0f50)
+ QPaintDevice (0x0x7f8845e0c4e0) 16
+ vptr=((& QGroupBox::_ZTV9QGroupBox) + 448u)
+
+Class QHeaderView::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QHeaderView::QPrivateSignal (0x0x7f8845e0c660) 0 empty
+
+Vtable for QHeaderView
+QHeaderView::_ZTV11QHeaderView: 108u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QHeaderView)
+16 (int (*)(...))QHeaderView::metaObject
+24 (int (*)(...))QHeaderView::qt_metacast
+32 (int (*)(...))QHeaderView::qt_metacall
+40 (int (*)(...))QHeaderView::~QHeaderView
+48 (int (*)(...))QHeaderView::~QHeaderView
+56 (int (*)(...))QHeaderView::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QAbstractItemView::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QHeaderView::setVisible
+128 (int (*)(...))QHeaderView::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QHeaderView::mousePressEvent
+176 (int (*)(...))QHeaderView::mouseReleaseEvent
+184 (int (*)(...))QHeaderView::mouseDoubleClickEvent
+192 (int (*)(...))QHeaderView::mouseMoveEvent
+200 (int (*)(...))QAbstractScrollArea::wheelEvent
+208 (int (*)(...))QAbstractItemView::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QAbstractItemView::focusInEvent
+232 (int (*)(...))QAbstractItemView::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QHeaderView::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QAbstractItemView::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QAbstractScrollArea::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QAbstractItemView::dragEnterEvent
+320 (int (*)(...))QAbstractItemView::dragMoveEvent
+328 (int (*)(...))QAbstractItemView::dragLeaveEvent
+336 (int (*)(...))QAbstractItemView::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QAbstractItemView::inputMethodEvent
+416 (int (*)(...))QAbstractItemView::inputMethodQuery
+424 (int (*)(...))QAbstractItemView::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QHeaderView::viewportEvent
+448 (int (*)(...))QHeaderView::scrollContentsBy
+456 (int (*)(...))QAbstractItemView::viewportSizeHint
+464 (int (*)(...))QHeaderView::setModel
+472 (int (*)(...))QAbstractItemView::setSelectionModel
+480 (int (*)(...))QAbstractItemView::keyboardSearch
+488 (int (*)(...))QHeaderView::visualRect
+496 (int (*)(...))QHeaderView::scrollTo
+504 (int (*)(...))QHeaderView::indexAt
+512 (int (*)(...))QAbstractItemView::sizeHintForRow
+520 (int (*)(...))QAbstractItemView::sizeHintForColumn
+528 (int (*)(...))QHeaderView::reset
+536 (int (*)(...))QAbstractItemView::setRootIndex
+544 (int (*)(...))QHeaderView::doItemsLayout
+552 (int (*)(...))QAbstractItemView::selectAll
+560 (int (*)(...))QHeaderView::dataChanged
+568 (int (*)(...))QHeaderView::rowsInserted
+576 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved
+584 (int (*)(...))QAbstractItemView::selectionChanged
+592 (int (*)(...))QHeaderView::currentChanged
+600 (int (*)(...))QAbstractItemView::updateEditorData
+608 (int (*)(...))QAbstractItemView::updateEditorGeometries
+616 (int (*)(...))QHeaderView::updateGeometries
+624 (int (*)(...))QAbstractItemView::verticalScrollbarAction
+632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction
+640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged
+648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged
+656 (int (*)(...))QAbstractItemView::closeEditor
+664 (int (*)(...))QAbstractItemView::commitData
+672 (int (*)(...))QAbstractItemView::editorDestroyed
+680 (int (*)(...))QHeaderView::moveCursor
+688 (int (*)(...))QHeaderView::horizontalOffset
+696 (int (*)(...))QHeaderView::verticalOffset
+704 (int (*)(...))QHeaderView::isIndexHidden
+712 (int (*)(...))QHeaderView::setSelection
+720 (int (*)(...))QHeaderView::visualRegionForSelection
+728 (int (*)(...))QAbstractItemView::selectedIndexes
+736 (int (*)(...))QAbstractItemView::edit
+744 (int (*)(...))QAbstractItemView::selectionCommand
+752 (int (*)(...))QAbstractItemView::startDrag
+760 (int (*)(...))QAbstractItemView::viewOptions
+768 (int (*)(...))QHeaderView::paintSection
+776 (int (*)(...))QHeaderView::sectionSizeFromContents
+784 (int (*)(...))-16
+792 (int (*)(...))(& _ZTI11QHeaderView)
+800 (int (*)(...))QHeaderView::_ZThn16_N11QHeaderViewD1Ev
+808 (int (*)(...))QHeaderView::_ZThn16_N11QHeaderViewD0Ev
+816 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+832 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+840 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+848 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+856 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QHeaderView
+ size=48 align=8
+ base size=48 base align=8
+QHeaderView (0x0x7f8845da7b60) 0
+ vptr=((& QHeaderView::_ZTV11QHeaderView) + 16u)
+ QAbstractItemView (0x0x7f8845da7bc8) 0
+ primary-for QHeaderView (0x0x7f8845da7b60)
+ QAbstractScrollArea (0x0x7f8845da7c30) 0
+ primary-for QAbstractItemView (0x0x7f8845da7bc8)
+ QFrame (0x0x7f8845da7c98) 0
+ primary-for QAbstractScrollArea (0x0x7f8845da7c30)
+ QWidget (0x0x7f8845edd460) 0
+ primary-for QFrame (0x0x7f8845da7c98)
+ QObject (0x0x7f8845e0c5a0) 0
+ primary-for QWidget (0x0x7f8845edd460)
+ QPaintDevice (0x0x7f8845e0c600) 16
+ vptr=((& QHeaderView::_ZTV11QHeaderView) + 800u)
+
+Class QLineEdit::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QLineEdit::QPrivateSignal (0x0x7f8845e0cc60) 0 empty
+
+Vtable for QLineEdit
+QLineEdit::_ZTV9QLineEdit: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QLineEdit)
+16 (int (*)(...))QLineEdit::metaObject
+24 (int (*)(...))QLineEdit::qt_metacast
+32 (int (*)(...))QLineEdit::qt_metacall
+40 (int (*)(...))QLineEdit::~QLineEdit
+48 (int (*)(...))QLineEdit::~QLineEdit
+56 (int (*)(...))QLineEdit::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QLineEdit::sizeHint
+136 (int (*)(...))QLineEdit::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QLineEdit::mousePressEvent
+176 (int (*)(...))QLineEdit::mouseReleaseEvent
+184 (int (*)(...))QLineEdit::mouseDoubleClickEvent
+192 (int (*)(...))QLineEdit::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QLineEdit::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QLineEdit::focusInEvent
+232 (int (*)(...))QLineEdit::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QLineEdit::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QLineEdit::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QLineEdit::dragEnterEvent
+320 (int (*)(...))QLineEdit::dragMoveEvent
+328 (int (*)(...))QLineEdit::dragLeaveEvent
+336 (int (*)(...))QLineEdit::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QLineEdit::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QLineEdit::inputMethodEvent
+416 (int (*)(...))QLineEdit::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI9QLineEdit)
+448 (int (*)(...))QLineEdit::_ZThn16_N9QLineEditD1Ev
+456 (int (*)(...))QLineEdit::_ZThn16_N9QLineEditD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QLineEdit
+ size=48 align=8
+ base size=48 base align=8
+QLineEdit (0x0x7f8845b33410) 0
+ vptr=((& QLineEdit::_ZTV9QLineEdit) + 16u)
+ QWidget (0x0x7f8845b30620) 0
+ primary-for QLineEdit (0x0x7f8845b33410)
+ QObject (0x0x7f8845e0cba0) 0
+ primary-for QWidget (0x0x7f8845b30620)
+ QPaintDevice (0x0x7f8845e0cc00) 16
+ vptr=((& QLineEdit::_ZTV9QLineEdit) + 448u)
+
+Class QInputDialog::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QInputDialog::QPrivateSignal (0x0x7f8845e0cd80) 0 empty
+
+Vtable for QInputDialog
+QInputDialog::_ZTV12QInputDialog: 69u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QInputDialog)
+16 (int (*)(...))QInputDialog::metaObject
+24 (int (*)(...))QInputDialog::qt_metacast
+32 (int (*)(...))QInputDialog::qt_metacall
+40 (int (*)(...))QInputDialog::~QInputDialog
+48 (int (*)(...))QInputDialog::~QInputDialog
+56 (int (*)(...))QWidget::event
+64 (int (*)(...))QDialog::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QInputDialog::setVisible
+128 (int (*)(...))QInputDialog::sizeHint
+136 (int (*)(...))QInputDialog::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QDialog::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QDialog::resizeEvent
+280 (int (*)(...))QDialog::closeEvent
+288 (int (*)(...))QDialog::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QDialog::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QDialog::open
+440 (int (*)(...))QDialog::exec
+448 (int (*)(...))QInputDialog::done
+456 (int (*)(...))QDialog::accept
+464 (int (*)(...))QDialog::reject
+472 (int (*)(...))-16
+480 (int (*)(...))(& _ZTI12QInputDialog)
+488 (int (*)(...))QInputDialog::_ZThn16_N12QInputDialogD1Ev
+496 (int (*)(...))QInputDialog::_ZThn16_N12QInputDialogD0Ev
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QInputDialog
+ size=48 align=8
+ base size=48 base align=8
+QInputDialog (0x0x7f8845b33478) 0
+ vptr=((& QInputDialog::_ZTV12QInputDialog) + 16u)
+ QDialog (0x0x7f8845b334e0) 0
+ primary-for QInputDialog (0x0x7f8845b33478)
+ QWidget (0x0x7f8845b67150) 0
+ primary-for QDialog (0x0x7f8845b334e0)
+ QObject (0x0x7f8845e0ccc0) 0
+ primary-for QWidget (0x0x7f8845b67150)
+ QPaintDevice (0x0x7f8845e0cd20) 16
+ vptr=((& QInputDialog::_ZTV12QInputDialog) + 488u)
+
+Class QItemDelegate::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QItemDelegate::QPrivateSignal (0x0x7f8845bca000) 0 empty
+
+Vtable for QItemDelegate
+QItemDelegate::_ZTV13QItemDelegate: 28u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QItemDelegate)
+16 (int (*)(...))QItemDelegate::metaObject
+24 (int (*)(...))QItemDelegate::qt_metacast
+32 (int (*)(...))QItemDelegate::qt_metacall
+40 (int (*)(...))QItemDelegate::~QItemDelegate
+48 (int (*)(...))QItemDelegate::~QItemDelegate
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QItemDelegate::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QItemDelegate::paint
+120 (int (*)(...))QItemDelegate::sizeHint
+128 (int (*)(...))QItemDelegate::createEditor
+136 (int (*)(...))QAbstractItemDelegate::destroyEditor
+144 (int (*)(...))QItemDelegate::setEditorData
+152 (int (*)(...))QItemDelegate::setModelData
+160 (int (*)(...))QItemDelegate::updateEditorGeometry
+168 (int (*)(...))QItemDelegate::editorEvent
+176 (int (*)(...))QAbstractItemDelegate::helpEvent
+184 (int (*)(...))QAbstractItemDelegate::paintingRoles
+192 (int (*)(...))QItemDelegate::drawDisplay
+200 (int (*)(...))QItemDelegate::drawDecoration
+208 (int (*)(...))QItemDelegate::drawFocus
+216 (int (*)(...))QItemDelegate::drawCheck
+
+Class QItemDelegate
+ size=16 align=8
+ base size=16 base align=8
+QItemDelegate (0x0x7f8845b33618) 0
+ vptr=((& QItemDelegate::_ZTV13QItemDelegate) + 16u)
+ QAbstractItemDelegate (0x0x7f8845b33680) 0
+ primary-for QItemDelegate (0x0x7f8845b33618)
+ QObject (0x0x7f8845e0cf60) 0
+ primary-for QAbstractItemDelegate (0x0x7f8845b33680)
+
+Vtable for QItemEditorCreatorBase
+QItemEditorCreatorBase::_ZTV22QItemEditorCreatorBase: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI22QItemEditorCreatorBase)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+
+Class QItemEditorCreatorBase
+ size=8 align=8
+ base size=8 base align=8
+QItemEditorCreatorBase (0x0x7f8845bca060) 0 nearly-empty
+ vptr=((& QItemEditorCreatorBase::_ZTV22QItemEditorCreatorBase) + 16u)
+
+Vtable for QItemEditorFactory
+QItemEditorFactory::_ZTV18QItemEditorFactory: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QItemEditorFactory)
+16 (int (*)(...))QItemEditorFactory::~QItemEditorFactory
+24 (int (*)(...))QItemEditorFactory::~QItemEditorFactory
+32 (int (*)(...))QItemEditorFactory::createEditor
+40 (int (*)(...))QItemEditorFactory::valuePropertyName
+
+Class QItemEditorFactory
+ size=16 align=8
+ base size=16 base align=8
+QItemEditorFactory (0x0x7f8845bca180) 0
+ vptr=((& QItemEditorFactory::_ZTV18QItemEditorFactory) + 16u)
+
+Class QKeyEventTransition::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QKeyEventTransition::QPrivateSignal (0x0x7f8845bca300) 0 empty
+
+Vtable for QKeyEventTransition
+QKeyEventTransition::_ZTV19QKeyEventTransition: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QKeyEventTransition)
+16 (int (*)(...))QKeyEventTransition::metaObject
+24 (int (*)(...))QKeyEventTransition::qt_metacast
+32 (int (*)(...))QKeyEventTransition::qt_metacall
+40 (int (*)(...))QKeyEventTransition::~QKeyEventTransition
+48 (int (*)(...))QKeyEventTransition::~QKeyEventTransition
+56 (int (*)(...))QEventTransition::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QKeyEventTransition::eventTest
+120 (int (*)(...))QKeyEventTransition::onTransition
+
+Class QKeyEventTransition
+ size=16 align=8
+ base size=16 base align=8
+QKeyEventTransition (0x0x7f8845b337b8) 0
+ vptr=((& QKeyEventTransition::_ZTV19QKeyEventTransition) + 16u)
+ QEventTransition (0x0x7f8845b33820) 0
+ primary-for QKeyEventTransition (0x0x7f8845b337b8)
+ QAbstractTransition (0x0x7f8845b33888) 0
+ primary-for QEventTransition (0x0x7f8845b33820)
+ QObject (0x0x7f8845bca2a0) 0
+ primary-for QAbstractTransition (0x0x7f8845b33888)
+
+Class QKeySequenceEdit::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QKeySequenceEdit::QPrivateSignal (0x0x7f8845bca420) 0 empty
+
+Vtable for QKeySequenceEdit
+QKeySequenceEdit::_ZTV16QKeySequenceEdit: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QKeySequenceEdit)
+16 (int (*)(...))QKeySequenceEdit::metaObject
+24 (int (*)(...))QKeySequenceEdit::qt_metacast
+32 (int (*)(...))QKeySequenceEdit::qt_metacall
+40 (int (*)(...))QKeySequenceEdit::~QKeySequenceEdit
+48 (int (*)(...))QKeySequenceEdit::~QKeySequenceEdit
+56 (int (*)(...))QKeySequenceEdit::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QKeySequenceEdit::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QKeySequenceEdit::keyPressEvent
+216 (int (*)(...))QKeySequenceEdit::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI16QKeySequenceEdit)
+448 (int (*)(...))QKeySequenceEdit::_ZThn16_N16QKeySequenceEditD1Ev
+456 (int (*)(...))QKeySequenceEdit::_ZThn16_N16QKeySequenceEditD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QKeySequenceEdit
+ size=48 align=8
+ base size=48 base align=8
+QKeySequenceEdit (0x0x7f8845b338f0) 0
+ vptr=((& QKeySequenceEdit::_ZTV16QKeySequenceEdit) + 16u)
+ QWidget (0x0x7f8845c1e0e0) 0
+ primary-for QKeySequenceEdit (0x0x7f8845b338f0)
+ QObject (0x0x7f8845bca360) 0
+ primary-for QWidget (0x0x7f8845c1e0e0)
+ QPaintDevice (0x0x7f8845bca3c0) 16
+ vptr=((& QKeySequenceEdit::_ZTV16QKeySequenceEdit) + 448u)
+
+Class QLabel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QLabel::QPrivateSignal (0x0x7f8845bca540) 0 empty
+
+Vtable for QLabel
+QLabel::_ZTV6QLabel: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QLabel)
+16 (int (*)(...))QLabel::metaObject
+24 (int (*)(...))QLabel::qt_metacast
+32 (int (*)(...))QLabel::qt_metacall
+40 (int (*)(...))QLabel::~QLabel
+48 (int (*)(...))QLabel::~QLabel
+56 (int (*)(...))QLabel::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QLabel::sizeHint
+136 (int (*)(...))QLabel::minimumSizeHint
+144 (int (*)(...))QLabel::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QLabel::mousePressEvent
+176 (int (*)(...))QLabel::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QLabel::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QLabel::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QLabel::focusInEvent
+232 (int (*)(...))QLabel::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QLabel::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QLabel::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QLabel::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QLabel::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI6QLabel)
+448 (int (*)(...))QLabel::_ZThn16_N6QLabelD1Ev
+456 (int (*)(...))QLabel::_ZThn16_N6QLabelD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QLabel
+ size=48 align=8
+ base size=48 base align=8
+QLabel (0x0x7f8845b33958) 0
+ vptr=((& QLabel::_ZTV6QLabel) + 16u)
+ QFrame (0x0x7f8845b339c0) 0
+ primary-for QLabel (0x0x7f8845b33958)
+ QWidget (0x0x7f8845c1e5b0) 0
+ primary-for QFrame (0x0x7f8845b339c0)
+ QObject (0x0x7f8845bca480) 0
+ primary-for QWidget (0x0x7f8845c1e5b0)
+ QPaintDevice (0x0x7f8845bca4e0) 16
+ vptr=((& QLabel::_ZTV6QLabel) + 448u)
+
+Class QLCDNumber::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QLCDNumber::QPrivateSignal (0x0x7f8845bca660) 0 empty
+
+Vtable for QLCDNumber
+QLCDNumber::_ZTV10QLCDNumber: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QLCDNumber)
+16 (int (*)(...))QLCDNumber::metaObject
+24 (int (*)(...))QLCDNumber::qt_metacast
+32 (int (*)(...))QLCDNumber::qt_metacall
+40 (int (*)(...))QLCDNumber::~QLCDNumber
+48 (int (*)(...))QLCDNumber::~QLCDNumber
+56 (int (*)(...))QLCDNumber::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QLCDNumber::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QLCDNumber::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI10QLCDNumber)
+448 (int (*)(...))QLCDNumber::_ZThn16_N10QLCDNumberD1Ev
+456 (int (*)(...))QLCDNumber::_ZThn16_N10QLCDNumberD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QLCDNumber
+ size=48 align=8
+ base size=48 base align=8
+QLCDNumber (0x0x7f8845b33a28) 0
+ vptr=((& QLCDNumber::_ZTV10QLCDNumber) + 16u)
+ QFrame (0x0x7f8845b33a90) 0
+ primary-for QLCDNumber (0x0x7f8845b33a28)
+ QWidget (0x0x7f8845c1eb60) 0
+ primary-for QFrame (0x0x7f8845b33a90)
+ QObject (0x0x7f8845bca5a0) 0
+ primary-for QWidget (0x0x7f8845c1eb60)
+ QPaintDevice (0x0x7f8845bca600) 16
+ vptr=((& QLCDNumber::_ZTV10QLCDNumber) + 448u)
+
+Class QListView::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QListView::QPrivateSignal (0x0x7f8845bca780) 0 empty
+
+Vtable for QListView
+QListView::_ZTV9QListView: 106u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QListView)
+16 (int (*)(...))QListView::metaObject
+24 (int (*)(...))QListView::qt_metacast
+32 (int (*)(...))QListView::qt_metacall
+40 (int (*)(...))QListView::~QListView
+48 (int (*)(...))QListView::~QListView
+56 (int (*)(...))QListView::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QListView::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractScrollArea::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractItemView::mousePressEvent
+176 (int (*)(...))QListView::mouseReleaseEvent
+184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent
+192 (int (*)(...))QListView::mouseMoveEvent
+200 (int (*)(...))QListView::wheelEvent
+208 (int (*)(...))QAbstractItemView::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QAbstractItemView::focusInEvent
+232 (int (*)(...))QAbstractItemView::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QListView::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QListView::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QAbstractScrollArea::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QAbstractItemView::dragEnterEvent
+320 (int (*)(...))QListView::dragMoveEvent
+328 (int (*)(...))QListView::dragLeaveEvent
+336 (int (*)(...))QListView::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QAbstractItemView::inputMethodEvent
+416 (int (*)(...))QAbstractItemView::inputMethodQuery
+424 (int (*)(...))QAbstractItemView::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QAbstractItemView::viewportEvent
+448 (int (*)(...))QListView::scrollContentsBy
+456 (int (*)(...))QListView::viewportSizeHint
+464 (int (*)(...))QAbstractItemView::setModel
+472 (int (*)(...))QAbstractItemView::setSelectionModel
+480 (int (*)(...))QAbstractItemView::keyboardSearch
+488 (int (*)(...))QListView::visualRect
+496 (int (*)(...))QListView::scrollTo
+504 (int (*)(...))QListView::indexAt
+512 (int (*)(...))QAbstractItemView::sizeHintForRow
+520 (int (*)(...))QAbstractItemView::sizeHintForColumn
+528 (int (*)(...))QListView::reset
+536 (int (*)(...))QListView::setRootIndex
+544 (int (*)(...))QListView::doItemsLayout
+552 (int (*)(...))QAbstractItemView::selectAll
+560 (int (*)(...))QListView::dataChanged
+568 (int (*)(...))QListView::rowsInserted
+576 (int (*)(...))QListView::rowsAboutToBeRemoved
+584 (int (*)(...))QListView::selectionChanged
+592 (int (*)(...))QListView::currentChanged
+600 (int (*)(...))QAbstractItemView::updateEditorData
+608 (int (*)(...))QAbstractItemView::updateEditorGeometries
+616 (int (*)(...))QListView::updateGeometries
+624 (int (*)(...))QAbstractItemView::verticalScrollbarAction
+632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction
+640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged
+648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged
+656 (int (*)(...))QAbstractItemView::closeEditor
+664 (int (*)(...))QAbstractItemView::commitData
+672 (int (*)(...))QAbstractItemView::editorDestroyed
+680 (int (*)(...))QListView::moveCursor
+688 (int (*)(...))QListView::horizontalOffset
+696 (int (*)(...))QListView::verticalOffset
+704 (int (*)(...))QListView::isIndexHidden
+712 (int (*)(...))QListView::setSelection
+720 (int (*)(...))QListView::visualRegionForSelection
+728 (int (*)(...))QListView::selectedIndexes
+736 (int (*)(...))QAbstractItemView::edit
+744 (int (*)(...))QAbstractItemView::selectionCommand
+752 (int (*)(...))QListView::startDrag
+760 (int (*)(...))QListView::viewOptions
+768 (int (*)(...))-16
+776 (int (*)(...))(& _ZTI9QListView)
+784 (int (*)(...))QListView::_ZThn16_N9QListViewD1Ev
+792 (int (*)(...))QListView::_ZThn16_N9QListViewD0Ev
+800 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+808 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+816 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+832 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+840 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QListView
+ size=48 align=8
+ base size=48 base align=8
+QListView (0x0x7f8845b33af8) 0
+ vptr=((& QListView::_ZTV9QListView) + 16u)
+ QAbstractItemView (0x0x7f8845b33b60) 0
+ primary-for QListView (0x0x7f8845b33af8)
+ QAbstractScrollArea (0x0x7f8845b33bc8) 0
+ primary-for QAbstractItemView (0x0x7f8845b33b60)
+ QFrame (0x0x7f8845b33c30) 0
+ primary-for QAbstractScrollArea (0x0x7f8845b33bc8)
+ QWidget (0x0x7f8845c68700) 0
+ primary-for QFrame (0x0x7f8845b33c30)
+ QObject (0x0x7f8845bca6c0) 0
+ primary-for QWidget (0x0x7f8845c68700)
+ QPaintDevice (0x0x7f8845bca720) 16
+ vptr=((& QListView::_ZTV9QListView) + 784u)
+
+Vtable for QListWidgetItem
+QListWidgetItem::_ZTV15QListWidgetItem: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QListWidgetItem)
+16 (int (*)(...))QListWidgetItem::~QListWidgetItem
+24 (int (*)(...))QListWidgetItem::~QListWidgetItem
+32 (int (*)(...))QListWidgetItem::clone
+40 (int (*)(...))QListWidgetItem::setBackgroundColor
+48 (int (*)(...))QListWidgetItem::data
+56 (int (*)(...))QListWidgetItem::setData
+64 (int (*)(...))QListWidgetItem::operator<
+72 (int (*)(...))QListWidgetItem::read
+80 (int (*)(...))QListWidgetItem::write
+
+Class QListWidgetItem
+ size=48 align=8
+ base size=44 base align=8
+QListWidgetItem (0x0x7f8845bca7e0) 0
+ vptr=((& QListWidgetItem::_ZTV15QListWidgetItem) + 16u)
+
+Class QListWidget::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QListWidget::QPrivateSignal (0x0x7f8845bcaa20) 0 empty
+
+Vtable for QListWidget
+QListWidget::_ZTV11QListWidget: 110u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QListWidget)
+16 (int (*)(...))QListWidget::metaObject
+24 (int (*)(...))QListWidget::qt_metacast
+32 (int (*)(...))QListWidget::qt_metacall
+40 (int (*)(...))QListWidget::~QListWidget
+48 (int (*)(...))QListWidget::~QListWidget
+56 (int (*)(...))QListWidget::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QListView::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractScrollArea::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractItemView::mousePressEvent
+176 (int (*)(...))QListView::mouseReleaseEvent
+184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent
+192 (int (*)(...))QListView::mouseMoveEvent
+200 (int (*)(...))QListView::wheelEvent
+208 (int (*)(...))QAbstractItemView::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QAbstractItemView::focusInEvent
+232 (int (*)(...))QAbstractItemView::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QListView::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QListView::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QAbstractScrollArea::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QAbstractItemView::dragEnterEvent
+320 (int (*)(...))QListView::dragMoveEvent
+328 (int (*)(...))QListView::dragLeaveEvent
+336 (int (*)(...))QListWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QAbstractItemView::inputMethodEvent
+416 (int (*)(...))QAbstractItemView::inputMethodQuery
+424 (int (*)(...))QAbstractItemView::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QAbstractItemView::viewportEvent
+448 (int (*)(...))QListView::scrollContentsBy
+456 (int (*)(...))QListView::viewportSizeHint
+464 (int (*)(...))QListWidget::setModel
+472 (int (*)(...))QListWidget::setSelectionModel
+480 (int (*)(...))QAbstractItemView::keyboardSearch
+488 (int (*)(...))QListView::visualRect
+496 (int (*)(...))QListView::scrollTo
+504 (int (*)(...))QListView::indexAt
+512 (int (*)(...))QAbstractItemView::sizeHintForRow
+520 (int (*)(...))QAbstractItemView::sizeHintForColumn
+528 (int (*)(...))QListView::reset
+536 (int (*)(...))QListView::setRootIndex
+544 (int (*)(...))QListView::doItemsLayout
+552 (int (*)(...))QAbstractItemView::selectAll
+560 (int (*)(...))QListView::dataChanged
+568 (int (*)(...))QListView::rowsInserted
+576 (int (*)(...))QListView::rowsAboutToBeRemoved
+584 (int (*)(...))QListView::selectionChanged
+592 (int (*)(...))QListView::currentChanged
+600 (int (*)(...))QAbstractItemView::updateEditorData
+608 (int (*)(...))QAbstractItemView::updateEditorGeometries
+616 (int (*)(...))QListView::updateGeometries
+624 (int (*)(...))QAbstractItemView::verticalScrollbarAction
+632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction
+640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged
+648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged
+656 (int (*)(...))QAbstractItemView::closeEditor
+664 (int (*)(...))QAbstractItemView::commitData
+672 (int (*)(...))QAbstractItemView::editorDestroyed
+680 (int (*)(...))QListView::moveCursor
+688 (int (*)(...))QListView::horizontalOffset
+696 (int (*)(...))QListView::verticalOffset
+704 (int (*)(...))QListView::isIndexHidden
+712 (int (*)(...))QListView::setSelection
+720 (int (*)(...))QListView::visualRegionForSelection
+728 (int (*)(...))QListView::selectedIndexes
+736 (int (*)(...))QAbstractItemView::edit
+744 (int (*)(...))QAbstractItemView::selectionCommand
+752 (int (*)(...))QListView::startDrag
+760 (int (*)(...))QListView::viewOptions
+768 (int (*)(...))QListWidget::mimeTypes
+776 (int (*)(...))QListWidget::mimeData
+784 (int (*)(...))QListWidget::dropMimeData
+792 (int (*)(...))QListWidget::supportedDropActions
+800 (int (*)(...))-16
+808 (int (*)(...))(& _ZTI11QListWidget)
+816 (int (*)(...))QListWidget::_ZThn16_N11QListWidgetD1Ev
+824 (int (*)(...))QListWidget::_ZThn16_N11QListWidgetD0Ev
+832 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+840 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+848 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+856 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+864 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+872 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QListWidget
+ size=48 align=8
+ base size=48 base align=8
+QListWidget (0x0x7f8845b33d68) 0
+ vptr=((& QListWidget::_ZTV11QListWidget) + 16u)
+ QListView (0x0x7f8845b33dd0) 0
+ primary-for QListWidget (0x0x7f8845b33d68)
+ QAbstractItemView (0x0x7f8845b33e38) 0
+ primary-for QListView (0x0x7f8845b33dd0)
+ QAbstractScrollArea (0x0x7f8845b33ea0) 0
+ primary-for QAbstractItemView (0x0x7f8845b33e38)
+ QFrame (0x0x7f8845b33f08) 0
+ primary-for QAbstractScrollArea (0x0x7f8845b33ea0)
+ QWidget (0x0x7f8845cfe5b0) 0
+ primary-for QFrame (0x0x7f8845b33f08)
+ QObject (0x0x7f8845bca960) 0
+ primary-for QWidget (0x0x7f8845cfe5b0)
+ QPaintDevice (0x0x7f8845bca9c0) 16
+ vptr=((& QListWidget::_ZTV11QListWidget) + 816u)
+
+Class QMainWindow::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QMainWindow::QPrivateSignal (0x0x7f8845bcab40) 0 empty
+
+Vtable for QMainWindow
+QMainWindow::_ZTV11QMainWindow: 65u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QMainWindow)
+16 (int (*)(...))QMainWindow::metaObject
+24 (int (*)(...))QMainWindow::qt_metacast
+32 (int (*)(...))QMainWindow::qt_metacall
+40 (int (*)(...))QMainWindow::~QMainWindow
+48 (int (*)(...))QMainWindow::~QMainWindow
+56 (int (*)(...))QMainWindow::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QMainWindow::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QMainWindow::createPopupMenu
+440 (int (*)(...))-16
+448 (int (*)(...))(& _ZTI11QMainWindow)
+456 (int (*)(...))QMainWindow::_ZThn16_N11QMainWindowD1Ev
+464 (int (*)(...))QMainWindow::_ZThn16_N11QMainWindowD0Ev
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QMainWindow
+ size=48 align=8
+ base size=48 base align=8
+QMainWindow (0x0x7f8845b33f70) 0
+ vptr=((& QMainWindow::_ZTV11QMainWindow) + 16u)
+ QWidget (0x0x7f88459314d0) 0
+ primary-for QMainWindow (0x0x7f8845b33f70)
+ QObject (0x0x7f8845bcaa80) 0
+ primary-for QWidget (0x0x7f88459314d0)
+ QPaintDevice (0x0x7f8845bcaae0) 16
+ vptr=((& QMainWindow::_ZTV11QMainWindow) + 456u)
+
+Class QMdiArea::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QMdiArea::QPrivateSignal (0x0x7f88572cdde0) 0 empty
+
+Vtable for QMdiArea
+QMdiArea::_ZTV8QMdiArea: 68u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QMdiArea)
+16 (int (*)(...))QMdiArea::metaObject
+24 (int (*)(...))QMdiArea::qt_metacast
+32 (int (*)(...))QMdiArea::qt_metacall
+40 (int (*)(...))QMdiArea::~QMdiArea
+48 (int (*)(...))QMdiArea::~QMdiArea
+56 (int (*)(...))QMdiArea::event
+64 (int (*)(...))QMdiArea::eventFilter
+72 (int (*)(...))QMdiArea::timerEvent
+80 (int (*)(...))QMdiArea::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QMdiArea::sizeHint
+136 (int (*)(...))QMdiArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractScrollArea::mousePressEvent
+176 (int (*)(...))QAbstractScrollArea::mouseReleaseEvent
+184 (int (*)(...))QAbstractScrollArea::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractScrollArea::mouseMoveEvent
+200 (int (*)(...))QAbstractScrollArea::wheelEvent
+208 (int (*)(...))QAbstractScrollArea::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QMdiArea::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QMdiArea::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QAbstractScrollArea::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QAbstractScrollArea::dragEnterEvent
+320 (int (*)(...))QAbstractScrollArea::dragMoveEvent
+328 (int (*)(...))QAbstractScrollArea::dragLeaveEvent
+336 (int (*)(...))QAbstractScrollArea::dropEvent
+344 (int (*)(...))QMdiArea::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QMdiArea::setupViewport
+440 (int (*)(...))QMdiArea::viewportEvent
+448 (int (*)(...))QMdiArea::scrollContentsBy
+456 (int (*)(...))QAbstractScrollArea::viewportSizeHint
+464 (int (*)(...))-16
+472 (int (*)(...))(& _ZTI8QMdiArea)
+480 (int (*)(...))QMdiArea::_ZThn16_N8QMdiAreaD1Ev
+488 (int (*)(...))QMdiArea::_ZThn16_N8QMdiAreaD0Ev
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QMdiArea
+ size=48 align=8
+ base size=48 base align=8
+QMdiArea (0x0x7f8851bc8618) 0
+ vptr=((& QMdiArea::_ZTV8QMdiArea) + 16u)
+ QAbstractScrollArea (0x0x7f8851bc8680) 0
+ primary-for QMdiArea (0x0x7f8851bc8618)
+ QFrame (0x0x7f8851bc8820) 0
+ primary-for QAbstractScrollArea (0x0x7f8851bc8680)
+ QWidget (0x0x7f8852a22150) 0
+ primary-for QFrame (0x0x7f8851bc8820)
+ QObject (0x0x7f88572cd120) 0
+ primary-for QWidget (0x0x7f8852a22150)
+ QPaintDevice (0x0x7f88572cd600) 16
+ vptr=((& QMdiArea::_ZTV8QMdiArea) + 480u)
+
+Class QMdiSubWindow::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QMdiSubWindow::QPrivateSignal (0x0x7f8851c69420) 0 empty
+
+Vtable for QMdiSubWindow
+QMdiSubWindow::_ZTV13QMdiSubWindow: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QMdiSubWindow)
+16 (int (*)(...))QMdiSubWindow::metaObject
+24 (int (*)(...))QMdiSubWindow::qt_metacast
+32 (int (*)(...))QMdiSubWindow::qt_metacall
+40 (int (*)(...))QMdiSubWindow::~QMdiSubWindow
+48 (int (*)(...))QMdiSubWindow::~QMdiSubWindow
+56 (int (*)(...))QMdiSubWindow::event
+64 (int (*)(...))QMdiSubWindow::eventFilter
+72 (int (*)(...))QMdiSubWindow::timerEvent
+80 (int (*)(...))QMdiSubWindow::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QMdiSubWindow::sizeHint
+136 (int (*)(...))QMdiSubWindow::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QMdiSubWindow::mousePressEvent
+176 (int (*)(...))QMdiSubWindow::mouseReleaseEvent
+184 (int (*)(...))QMdiSubWindow::mouseDoubleClickEvent
+192 (int (*)(...))QMdiSubWindow::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QMdiSubWindow::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QMdiSubWindow::focusInEvent
+232 (int (*)(...))QMdiSubWindow::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QMdiSubWindow::leaveEvent
+256 (int (*)(...))QMdiSubWindow::paintEvent
+264 (int (*)(...))QMdiSubWindow::moveEvent
+272 (int (*)(...))QMdiSubWindow::resizeEvent
+280 (int (*)(...))QMdiSubWindow::closeEvent
+288 (int (*)(...))QMdiSubWindow::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QMdiSubWindow::showEvent
+352 (int (*)(...))QMdiSubWindow::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QMdiSubWindow::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI13QMdiSubWindow)
+448 (int (*)(...))QMdiSubWindow::_ZThn16_N13QMdiSubWindowD1Ev
+456 (int (*)(...))QMdiSubWindow::_ZThn16_N13QMdiSubWindowD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QMdiSubWindow
+ size=48 align=8
+ base size=48 base align=8
+QMdiSubWindow (0x0x7f88517d2750) 0
+ vptr=((& QMdiSubWindow::_ZTV13QMdiSubWindow) + 16u)
+ QWidget (0x0x7f8852a42e00) 0
+ primary-for QMdiSubWindow (0x0x7f88517d2750)
+ QObject (0x0x7f88525d5720) 0
+ primary-for QWidget (0x0x7f8852a42e00)
+ QPaintDevice (0x0x7f8851c693c0) 16
+ vptr=((& QMdiSubWindow::_ZTV13QMdiSubWindow) + 448u)
+
+Class QMenu::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QMenu::QPrivateSignal (0x0x7f884fb96a20) 0 empty
+
+Vtable for QMenu
+QMenu::_ZTV5QMenu: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI5QMenu)
+16 (int (*)(...))QMenu::metaObject
+24 (int (*)(...))QMenu::qt_metacast
+32 (int (*)(...))QMenu::qt_metacall
+40 (int (*)(...))QMenu::~QMenu
+48 (int (*)(...))QMenu::~QMenu
+56 (int (*)(...))QMenu::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QMenu::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QMenu::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QMenu::mousePressEvent
+176 (int (*)(...))QMenu::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QMenu::mouseMoveEvent
+200 (int (*)(...))QMenu::wheelEvent
+208 (int (*)(...))QMenu::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QMenu::enterEvent
+248 (int (*)(...))QMenu::leaveEvent
+256 (int (*)(...))QMenu::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QMenu::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QMenu::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QMenu::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QMenu::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI5QMenu)
+448 (int (*)(...))QMenu::_ZThn16_N5QMenuD1Ev
+456 (int (*)(...))QMenu::_ZThn16_N5QMenuD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QMenu
+ size=48 align=8
+ base size=48 base align=8
+QMenu (0x0x7f88509d07b8) 0
+ vptr=((& QMenu::_ZTV5QMenu) + 16u)
+ QWidget (0x0x7f8852a86700) 0
+ primary-for QMenu (0x0x7f88509d07b8)
+ QObject (0x0x7f884fb960c0) 0
+ primary-for QWidget (0x0x7f8852a86700)
+ QPaintDevice (0x0x7f884fb969c0) 16
+ vptr=((& QMenu::_ZTV5QMenu) + 448u)
+
+Class QMenuBar::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QMenuBar::QPrivateSignal (0x0x7f884fbba240) 0 empty
+
+Vtable for QMenuBar
+QMenuBar::_ZTV8QMenuBar: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QMenuBar)
+16 (int (*)(...))QMenuBar::metaObject
+24 (int (*)(...))QMenuBar::qt_metacast
+32 (int (*)(...))QMenuBar::qt_metacall
+40 (int (*)(...))QMenuBar::~QMenuBar
+48 (int (*)(...))QMenuBar::~QMenuBar
+56 (int (*)(...))QMenuBar::event
+64 (int (*)(...))QMenuBar::eventFilter
+72 (int (*)(...))QMenuBar::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QMenuBar::setVisible
+128 (int (*)(...))QMenuBar::sizeHint
+136 (int (*)(...))QMenuBar::minimumSizeHint
+144 (int (*)(...))QMenuBar::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QMenuBar::mousePressEvent
+176 (int (*)(...))QMenuBar::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QMenuBar::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QMenuBar::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QMenuBar::focusInEvent
+232 (int (*)(...))QMenuBar::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QMenuBar::leaveEvent
+256 (int (*)(...))QMenuBar::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QMenuBar::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QMenuBar::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QMenuBar::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI8QMenuBar)
+448 (int (*)(...))QMenuBar::_ZThn16_N8QMenuBarD1Ev
+456 (int (*)(...))QMenuBar::_ZThn16_N8QMenuBarD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QMenuBar
+ size=48 align=8
+ base size=48 base align=8
+QMenuBar (0x0x7f88509d0820) 0
+ vptr=((& QMenuBar::_ZTV8QMenuBar) + 16u)
+ QWidget (0x0x7f8852aa44d0) 0
+ primary-for QMenuBar (0x0x7f88509d0820)
+ QObject (0x0x7f884fbba120) 0
+ primary-for QWidget (0x0x7f8852aa44d0)
+ QPaintDevice (0x0x7f884fbba180) 16
+ vptr=((& QMenuBar::_ZTV8QMenuBar) + 448u)
+
+Class QMessageBox::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QMessageBox::QPrivateSignal (0x0x7f884fbba780) 0 empty
+
+Vtable for QMessageBox
+QMessageBox::_ZTV11QMessageBox: 69u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QMessageBox)
+16 (int (*)(...))QMessageBox::metaObject
+24 (int (*)(...))QMessageBox::qt_metacast
+32 (int (*)(...))QMessageBox::qt_metacall
+40 (int (*)(...))QMessageBox::~QMessageBox
+48 (int (*)(...))QMessageBox::~QMessageBox
+56 (int (*)(...))QMessageBox::event
+64 (int (*)(...))QDialog::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QDialog::setVisible
+128 (int (*)(...))QDialog::sizeHint
+136 (int (*)(...))QDialog::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QMessageBox::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QMessageBox::resizeEvent
+280 (int (*)(...))QMessageBox::closeEvent
+288 (int (*)(...))QDialog::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QMessageBox::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QMessageBox::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QDialog::open
+440 (int (*)(...))QDialog::exec
+448 (int (*)(...))QDialog::done
+456 (int (*)(...))QDialog::accept
+464 (int (*)(...))QDialog::reject
+472 (int (*)(...))-16
+480 (int (*)(...))(& _ZTI11QMessageBox)
+488 (int (*)(...))QMessageBox::_ZThn16_N11QMessageBoxD1Ev
+496 (int (*)(...))QMessageBox::_ZThn16_N11QMessageBoxD0Ev
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QMessageBox
+ size=48 align=8
+ base size=48 base align=8
+QMessageBox (0x0x7f88509d0888) 0
+ vptr=((& QMessageBox::_ZTV11QMessageBox) + 16u)
+ QDialog (0x0x7f88509d08f0) 0
+ primary-for QMessageBox (0x0x7f88509d0888)
+ QWidget (0x0x7f8852aa4a10) 0
+ primary-for QDialog (0x0x7f88509d08f0)
+ QObject (0x0x7f884fbba300) 0
+ primary-for QWidget (0x0x7f8852aa4a10)
+ QPaintDevice (0x0x7f884fbba720) 16
+ vptr=((& QMessageBox::_ZTV11QMessageBox) + 488u)
+
+Class QMouseEventTransition::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QMouseEventTransition::QPrivateSignal (0x0x7f884fbd65a0) 0 empty
+
+Vtable for QMouseEventTransition
+QMouseEventTransition::_ZTV21QMouseEventTransition: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QMouseEventTransition)
+16 (int (*)(...))QMouseEventTransition::metaObject
+24 (int (*)(...))QMouseEventTransition::qt_metacast
+32 (int (*)(...))QMouseEventTransition::qt_metacall
+40 (int (*)(...))QMouseEventTransition::~QMouseEventTransition
+48 (int (*)(...))QMouseEventTransition::~QMouseEventTransition
+56 (int (*)(...))QEventTransition::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QMouseEventTransition::eventTest
+120 (int (*)(...))QMouseEventTransition::onTransition
+
+Class QMouseEventTransition
+ size=16 align=8
+ base size=16 base align=8
+QMouseEventTransition (0x0x7f88509d0a28) 0
+ vptr=((& QMouseEventTransition::_ZTV21QMouseEventTransition) + 16u)
+ QEventTransition (0x0x7f88509d0d00) 0
+ primary-for QMouseEventTransition (0x0x7f88509d0a28)
+ QAbstractTransition (0x0x7f88502074e0) 0
+ primary-for QEventTransition (0x0x7f88509d0d00)
+ QObject (0x0x7f884fbd6540) 0
+ primary-for QAbstractTransition (0x0x7f88502074e0)
+
+Class QOpenGLWidget::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLWidget::QPrivateSignal (0x0x7f884f9c8120) 0 empty
+
+Vtable for QOpenGLWidget
+QOpenGLWidget::_ZTV13QOpenGLWidget: 67u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QOpenGLWidget)
+16 (int (*)(...))QOpenGLWidget::metaObject
+24 (int (*)(...))QOpenGLWidget::qt_metacast
+32 (int (*)(...))QOpenGLWidget::qt_metacall
+40 (int (*)(...))QOpenGLWidget::~QOpenGLWidget
+48 (int (*)(...))QOpenGLWidget::~QOpenGLWidget
+56 (int (*)(...))QOpenGLWidget::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QOpenGLWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QOpenGLWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QOpenGLWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QOpenGLWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QOpenGLWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QOpenGLWidget::initializeGL
+440 (int (*)(...))QOpenGLWidget::resizeGL
+448 (int (*)(...))QOpenGLWidget::paintGL
+456 (int (*)(...))-16
+464 (int (*)(...))(& _ZTI13QOpenGLWidget)
+472 (int (*)(...))QOpenGLWidget::_ZThn16_N13QOpenGLWidgetD1Ev
+480 (int (*)(...))QOpenGLWidget::_ZThn16_N13QOpenGLWidgetD0Ev
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+496 (int (*)(...))QOpenGLWidget::_ZThn16_NK13QOpenGLWidget11paintEngineEv
+504 (int (*)(...))QOpenGLWidget::_ZThn16_NK13QOpenGLWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+520 (int (*)(...))QOpenGLWidget::_ZThn16_NK13QOpenGLWidget10redirectedEP6QPoint
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QOpenGLWidget
+ size=48 align=8
+ base size=48 base align=8
+QOpenGLWidget (0x0x7f8850207548) 0
+ vptr=((& QOpenGLWidget::_ZTV13QOpenGLWidget) + 16u)
+ QWidget (0x0x7f8852b12a10) 0
+ primary-for QOpenGLWidget (0x0x7f8850207548)
+ QObject (0x0x7f884fbd6d80) 0
+ primary-for QWidget (0x0x7f8852b12a10)
+ QPaintDevice (0x0x7f884fbd6de0) 16
+ vptr=((& QOpenGLWidget::_ZTV13QOpenGLWidget) + 472u)
+
+Class QTextEdit::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTextEdit::QPrivateSignal (0x0x7f884f9c8c00) 0 empty
+
+Class QTextEdit::ExtraSelection
+ size=24 align=8
+ base size=24 base align=8
+QTextEdit::ExtraSelection (0x0x7f884f9c8c60) 0
+
+Vtable for QTextEdit
+QTextEdit::_ZTV9QTextEdit: 73u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QTextEdit)
+16 (int (*)(...))QTextEdit::metaObject
+24 (int (*)(...))QTextEdit::qt_metacast
+32 (int (*)(...))QTextEdit::qt_metacall
+40 (int (*)(...))QTextEdit::~QTextEdit
+48 (int (*)(...))QTextEdit::~QTextEdit
+56 (int (*)(...))QTextEdit::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QTextEdit::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractScrollArea::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QTextEdit::mousePressEvent
+176 (int (*)(...))QTextEdit::mouseReleaseEvent
+184 (int (*)(...))QTextEdit::mouseDoubleClickEvent
+192 (int (*)(...))QTextEdit::mouseMoveEvent
+200 (int (*)(...))QTextEdit::wheelEvent
+208 (int (*)(...))QTextEdit::keyPressEvent
+216 (int (*)(...))QTextEdit::keyReleaseEvent
+224 (int (*)(...))QTextEdit::focusInEvent
+232 (int (*)(...))QTextEdit::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QTextEdit::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QTextEdit::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QTextEdit::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QTextEdit::dragEnterEvent
+320 (int (*)(...))QTextEdit::dragMoveEvent
+328 (int (*)(...))QTextEdit::dragLeaveEvent
+336 (int (*)(...))QTextEdit::dropEvent
+344 (int (*)(...))QTextEdit::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QTextEdit::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QTextEdit::inputMethodEvent
+416 (int (*)(...))QTextEdit::inputMethodQuery
+424 (int (*)(...))QTextEdit::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QAbstractScrollArea::viewportEvent
+448 (int (*)(...))QTextEdit::scrollContentsBy
+456 (int (*)(...))QAbstractScrollArea::viewportSizeHint
+464 (int (*)(...))QTextEdit::loadResource
+472 (int (*)(...))QTextEdit::createMimeDataFromSelection
+480 (int (*)(...))QTextEdit::canInsertFromMimeData
+488 (int (*)(...))QTextEdit::insertFromMimeData
+496 (int (*)(...))QTextEdit::doSetTextCursor
+504 (int (*)(...))-16
+512 (int (*)(...))(& _ZTI9QTextEdit)
+520 (int (*)(...))QTextEdit::_ZThn16_N9QTextEditD1Ev
+528 (int (*)(...))QTextEdit::_ZThn16_N9QTextEditD0Ev
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+552 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+560 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+568 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+576 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QTextEdit
+ size=48 align=8
+ base size=48 base align=8
+QTextEdit (0x0x7f884fb95618) 0
+ vptr=((& QTextEdit::_ZTV9QTextEdit) + 16u)
+ QAbstractScrollArea (0x0x7f884fb95bc8) 0
+ primary-for QTextEdit (0x0x7f884fb95618)
+ QFrame (0x0x7f884fb95c30) 0
+ primary-for QAbstractScrollArea (0x0x7f884fb95bc8)
+ QWidget (0x0x7f8852b35150) 0
+ primary-for QFrame (0x0x7f884fb95c30)
+ QObject (0x0x7f884f9c8180) 0
+ primary-for QWidget (0x0x7f8852b35150)
+ QPaintDevice (0x0x7f884f9c8240) 16
+ vptr=((& QTextEdit::_ZTV9QTextEdit) + 520u)
+
+Class QPlainTextEdit::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPlainTextEdit::QPrivateSignal (0x0x7f884f9c8f00) 0 empty
+
+Vtable for QPlainTextEdit
+QPlainTextEdit::_ZTV14QPlainTextEdit: 73u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QPlainTextEdit)
+16 (int (*)(...))QPlainTextEdit::metaObject
+24 (int (*)(...))QPlainTextEdit::qt_metacast
+32 (int (*)(...))QPlainTextEdit::qt_metacall
+40 (int (*)(...))QPlainTextEdit::~QPlainTextEdit
+48 (int (*)(...))QPlainTextEdit::~QPlainTextEdit
+56 (int (*)(...))QPlainTextEdit::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QPlainTextEdit::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractScrollArea::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QPlainTextEdit::mousePressEvent
+176 (int (*)(...))QPlainTextEdit::mouseReleaseEvent
+184 (int (*)(...))QPlainTextEdit::mouseDoubleClickEvent
+192 (int (*)(...))QPlainTextEdit::mouseMoveEvent
+200 (int (*)(...))QPlainTextEdit::wheelEvent
+208 (int (*)(...))QPlainTextEdit::keyPressEvent
+216 (int (*)(...))QPlainTextEdit::keyReleaseEvent
+224 (int (*)(...))QPlainTextEdit::focusInEvent
+232 (int (*)(...))QPlainTextEdit::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QPlainTextEdit::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QPlainTextEdit::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QPlainTextEdit::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QPlainTextEdit::dragEnterEvent
+320 (int (*)(...))QPlainTextEdit::dragMoveEvent
+328 (int (*)(...))QPlainTextEdit::dragLeaveEvent
+336 (int (*)(...))QPlainTextEdit::dropEvent
+344 (int (*)(...))QPlainTextEdit::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QPlainTextEdit::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QPlainTextEdit::inputMethodEvent
+416 (int (*)(...))QPlainTextEdit::inputMethodQuery
+424 (int (*)(...))QPlainTextEdit::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QAbstractScrollArea::viewportEvent
+448 (int (*)(...))QPlainTextEdit::scrollContentsBy
+456 (int (*)(...))QAbstractScrollArea::viewportSizeHint
+464 (int (*)(...))QPlainTextEdit::loadResource
+472 (int (*)(...))QPlainTextEdit::createMimeDataFromSelection
+480 (int (*)(...))QPlainTextEdit::canInsertFromMimeData
+488 (int (*)(...))QPlainTextEdit::insertFromMimeData
+496 (int (*)(...))QPlainTextEdit::doSetTextCursor
+504 (int (*)(...))-16
+512 (int (*)(...))(& _ZTI14QPlainTextEdit)
+520 (int (*)(...))QPlainTextEdit::_ZThn16_N14QPlainTextEditD1Ev
+528 (int (*)(...))QPlainTextEdit::_ZThn16_N14QPlainTextEditD0Ev
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+552 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+560 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+568 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+576 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QPlainTextEdit
+ size=48 align=8
+ base size=48 base align=8
+QPlainTextEdit (0x0x7f884fbd4410) 0
+ vptr=((& QPlainTextEdit::_ZTV14QPlainTextEdit) + 16u)
+ QAbstractScrollArea (0x0x7f884fbd4478) 0
+ primary-for QPlainTextEdit (0x0x7f884fbd4410)
+ QFrame (0x0x7f884fbd4bc8) 0
+ primary-for QAbstractScrollArea (0x0x7f884fbd4478)
+ QWidget (0x0x7f8852b68c40) 0
+ primary-for QFrame (0x0x7f884fbd4bc8)
+ QObject (0x0x7f884f9c8e40) 0
+ primary-for QWidget (0x0x7f8852b68c40)
+ QPaintDevice (0x0x7f884f9c8ea0) 16
+ vptr=((& QPlainTextEdit::_ZTV14QPlainTextEdit) + 520u)
+
+Class QPlainTextDocumentLayout::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPlainTextDocumentLayout::QPrivateSignal (0x0x7f884f6fa000) 0 empty
+
+Vtable for QPlainTextDocumentLayout
+QPlainTextDocumentLayout::_ZTV24QPlainTextDocumentLayout: 24u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QPlainTextDocumentLayout)
+16 (int (*)(...))QPlainTextDocumentLayout::metaObject
+24 (int (*)(...))QPlainTextDocumentLayout::qt_metacast
+32 (int (*)(...))QPlainTextDocumentLayout::qt_metacall
+40 (int (*)(...))QPlainTextDocumentLayout::~QPlainTextDocumentLayout
+48 (int (*)(...))QPlainTextDocumentLayout::~QPlainTextDocumentLayout
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QPlainTextDocumentLayout::draw
+120 (int (*)(...))QPlainTextDocumentLayout::hitTest
+128 (int (*)(...))QPlainTextDocumentLayout::pageCount
+136 (int (*)(...))QPlainTextDocumentLayout::documentSize
+144 (int (*)(...))QPlainTextDocumentLayout::frameBoundingRect
+152 (int (*)(...))QPlainTextDocumentLayout::blockBoundingRect
+160 (int (*)(...))QPlainTextDocumentLayout::documentChanged
+168 (int (*)(...))QAbstractTextDocumentLayout::resizeInlineObject
+176 (int (*)(...))QAbstractTextDocumentLayout::positionInlineObject
+184 (int (*)(...))QAbstractTextDocumentLayout::drawInlineObject
+
+Class QPlainTextDocumentLayout
+ size=16 align=8
+ base size=16 base align=8
+QPlainTextDocumentLayout (0x0x7f884fbd4c30) 0
+ vptr=((& QPlainTextDocumentLayout::_ZTV24QPlainTextDocumentLayout) + 16u)
+ QAbstractTextDocumentLayout (0x0x7f884fbf50d0) 0
+ primary-for QPlainTextDocumentLayout (0x0x7f884fbd4c30)
+ QObject (0x0x7f884f9c8f60) 0
+ primary-for QAbstractTextDocumentLayout (0x0x7f884fbf50d0)
+
+Class QProgressBar::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QProgressBar::QPrivateSignal (0x0x7f884f6fa180) 0 empty
+
+Vtable for QProgressBar
+QProgressBar::_ZTV12QProgressBar: 65u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QProgressBar)
+16 (int (*)(...))QProgressBar::metaObject
+24 (int (*)(...))QProgressBar::qt_metacast
+32 (int (*)(...))QProgressBar::qt_metacall
+40 (int (*)(...))QProgressBar::~QProgressBar
+48 (int (*)(...))QProgressBar::~QProgressBar
+56 (int (*)(...))QProgressBar::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QProgressBar::sizeHint
+136 (int (*)(...))QProgressBar::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QProgressBar::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QProgressBar::text
+440 (int (*)(...))-16
+448 (int (*)(...))(& _ZTI12QProgressBar)
+456 (int (*)(...))QProgressBar::_ZThn16_N12QProgressBarD1Ev
+464 (int (*)(...))QProgressBar::_ZThn16_N12QProgressBarD0Ev
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QProgressBar
+ size=48 align=8
+ base size=48 base align=8
+QProgressBar (0x0x7f884fbf5138) 0
+ vptr=((& QProgressBar::_ZTV12QProgressBar) + 16u)
+ QWidget (0x0x7f8852b7c850) 0
+ primary-for QProgressBar (0x0x7f884fbf5138)
+ QObject (0x0x7f884f6fa060) 0
+ primary-for QWidget (0x0x7f8852b7c850)
+ QPaintDevice (0x0x7f884f6fa120) 16
+ vptr=((& QProgressBar::_ZTV12QProgressBar) + 456u)
+
+Class QProgressDialog::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QProgressDialog::QPrivateSignal (0x0x7f884f49c360) 0 empty
+
+Vtable for QProgressDialog
+QProgressDialog::_ZTV15QProgressDialog: 69u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QProgressDialog)
+16 (int (*)(...))QProgressDialog::metaObject
+24 (int (*)(...))QProgressDialog::qt_metacast
+32 (int (*)(...))QProgressDialog::qt_metacall
+40 (int (*)(...))QProgressDialog::~QProgressDialog
+48 (int (*)(...))QProgressDialog::~QProgressDialog
+56 (int (*)(...))QWidget::event
+64 (int (*)(...))QDialog::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QDialog::setVisible
+128 (int (*)(...))QProgressDialog::sizeHint
+136 (int (*)(...))QDialog::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QDialog::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QProgressDialog::resizeEvent
+280 (int (*)(...))QProgressDialog::closeEvent
+288 (int (*)(...))QDialog::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QProgressDialog::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QProgressDialog::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QDialog::open
+440 (int (*)(...))QDialog::exec
+448 (int (*)(...))QDialog::done
+456 (int (*)(...))QDialog::accept
+464 (int (*)(...))QDialog::reject
+472 (int (*)(...))-16
+480 (int (*)(...))(& _ZTI15QProgressDialog)
+488 (int (*)(...))QProgressDialog::_ZThn16_N15QProgressDialogD1Ev
+496 (int (*)(...))QProgressDialog::_ZThn16_N15QProgressDialogD0Ev
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QProgressDialog
+ size=48 align=8
+ base size=48 base align=8
+QProgressDialog (0x0x7f884f989000) 0
+ vptr=((& QProgressDialog::_ZTV15QProgressDialog) + 16u)
+ QDialog (0x0x7f884f989dd0) 0
+ primary-for QProgressDialog (0x0x7f884f989000)
+ QWidget (0x0x7f88526892a0) 0
+ primary-for QDialog (0x0x7f884f989dd0)
+ QObject (0x0x7f884f6fa1e0) 0
+ primary-for QWidget (0x0x7f88526892a0)
+ QPaintDevice (0x0x7f884f49c2a0) 16
+ vptr=((& QProgressDialog::_ZTV15QProgressDialog) + 488u)
+
+Class QProxyStyle::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QProxyStyle::QPrivateSignal (0x0x7f884f49c600) 0 empty
+
+Vtable for QProxyStyle
+QProxyStyle::_ZTV11QProxyStyle: 37u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QProxyStyle)
+16 (int (*)(...))QProxyStyle::metaObject
+24 (int (*)(...))QProxyStyle::qt_metacast
+32 (int (*)(...))QProxyStyle::qt_metacall
+40 (int (*)(...))QProxyStyle::~QProxyStyle
+48 (int (*)(...))QProxyStyle::~QProxyStyle
+56 (int (*)(...))QProxyStyle::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QProxyStyle::polish
+120 (int (*)(...))QProxyStyle::unpolish
+128 (int (*)(...))QProxyStyle::polish
+136 (int (*)(...))QProxyStyle::unpolish
+144 (int (*)(...))QProxyStyle::polish
+152 (int (*)(...))QProxyStyle::itemTextRect
+160 (int (*)(...))QProxyStyle::itemPixmapRect
+168 (int (*)(...))QProxyStyle::drawItemText
+176 (int (*)(...))QProxyStyle::drawItemPixmap
+184 (int (*)(...))QProxyStyle::standardPalette
+192 (int (*)(...))QProxyStyle::drawPrimitive
+200 (int (*)(...))QProxyStyle::drawControl
+208 (int (*)(...))QProxyStyle::subElementRect
+216 (int (*)(...))QProxyStyle::drawComplexControl
+224 (int (*)(...))QProxyStyle::hitTestComplexControl
+232 (int (*)(...))QProxyStyle::subControlRect
+240 (int (*)(...))QProxyStyle::pixelMetric
+248 (int (*)(...))QProxyStyle::sizeFromContents
+256 (int (*)(...))QProxyStyle::styleHint
+264 (int (*)(...))QProxyStyle::standardPixmap
+272 (int (*)(...))QProxyStyle::standardIcon
+280 (int (*)(...))QProxyStyle::generatedIconPixmap
+288 (int (*)(...))QProxyStyle::layoutSpacing
+
+Class QProxyStyle
+ size=16 align=8
+ base size=16 base align=8
+QProxyStyle (0x0x7f884f989e38) 0
+ vptr=((& QProxyStyle::_ZTV11QProxyStyle) + 16u)
+ QCommonStyle (0x0x7f884f989ea0) 0
+ primary-for QProxyStyle (0x0x7f884f989e38)
+ QStyle (0x0x7f884f989f08) 0
+ primary-for QCommonStyle (0x0x7f884f989ea0)
+ QObject (0x0x7f884f49c420) 0
+ primary-for QStyle (0x0x7f884f989f08)
+
+Class QRadioButton::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QRadioButton::QPrivateSignal (0x0x7f884f49c780) 0 empty
+
+Vtable for QRadioButton
+QRadioButton::_ZTV12QRadioButton: 67u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QRadioButton)
+16 (int (*)(...))QRadioButton::metaObject
+24 (int (*)(...))QRadioButton::qt_metacast
+32 (int (*)(...))QRadioButton::qt_metacall
+40 (int (*)(...))QRadioButton::~QRadioButton
+48 (int (*)(...))QRadioButton::~QRadioButton
+56 (int (*)(...))QRadioButton::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractButton::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QRadioButton::sizeHint
+136 (int (*)(...))QRadioButton::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractButton::mousePressEvent
+176 (int (*)(...))QAbstractButton::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QRadioButton::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QAbstractButton::keyPressEvent
+216 (int (*)(...))QAbstractButton::keyReleaseEvent
+224 (int (*)(...))QAbstractButton::focusInEvent
+232 (int (*)(...))QAbstractButton::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QRadioButton::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractButton::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QRadioButton::hitButton
+440 (int (*)(...))QAbstractButton::checkStateSet
+448 (int (*)(...))QAbstractButton::nextCheckState
+456 (int (*)(...))-16
+464 (int (*)(...))(& _ZTI12QRadioButton)
+472 (int (*)(...))QRadioButton::_ZThn16_N12QRadioButtonD1Ev
+480 (int (*)(...))QRadioButton::_ZThn16_N12QRadioButtonD0Ev
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QRadioButton
+ size=48 align=8
+ base size=48 base align=8
+QRadioButton (0x0x7f884f989f70) 0
+ vptr=((& QRadioButton::_ZTV12QRadioButton) + 16u)
+ QAbstractButton (0x0x7f884fa23000) 0
+ primary-for QRadioButton (0x0x7f884f989f70)
+ QWidget (0x0x7f885269b4d0) 0
+ primary-for QAbstractButton (0x0x7f884fa23000)
+ QObject (0x0x7f884f49c660) 0
+ primary-for QWidget (0x0x7f885269b4d0)
+ QPaintDevice (0x0x7f884f49c720) 16
+ vptr=((& QRadioButton::_ZTV12QRadioButton) + 472u)
+
+Class QScrollBar::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QScrollBar::QPrivateSignal (0x0x7f884f335900) 0 empty
+
+Vtable for QScrollBar
+QScrollBar::_ZTV10QScrollBar: 65u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QScrollBar)
+16 (int (*)(...))QScrollBar::metaObject
+24 (int (*)(...))QScrollBar::qt_metacast
+32 (int (*)(...))QScrollBar::qt_metacall
+40 (int (*)(...))QScrollBar::~QScrollBar
+48 (int (*)(...))QScrollBar::~QScrollBar
+56 (int (*)(...))QScrollBar::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractSlider::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QScrollBar::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QScrollBar::mousePressEvent
+176 (int (*)(...))QScrollBar::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QScrollBar::mouseMoveEvent
+200 (int (*)(...))QScrollBar::wheelEvent
+208 (int (*)(...))QAbstractSlider::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QScrollBar::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QScrollBar::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QScrollBar::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractSlider::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QScrollBar::sliderChange
+440 (int (*)(...))-16
+448 (int (*)(...))(& _ZTI10QScrollBar)
+456 (int (*)(...))QScrollBar::_ZThn16_N10QScrollBarD1Ev
+464 (int (*)(...))QScrollBar::_ZThn16_N10QScrollBarD0Ev
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QScrollBar
+ size=48 align=8
+ base size=48 base align=8
+QScrollBar (0x0x7f884fa23068) 0
+ vptr=((& QScrollBar::_ZTV10QScrollBar) + 16u)
+ QAbstractSlider (0x0x7f884fa230d0) 0
+ primary-for QScrollBar (0x0x7f884fa23068)
+ QWidget (0x0x7f885269be70) 0
+ primary-for QAbstractSlider (0x0x7f884fa230d0)
+ QObject (0x0x7f884f3357e0) 0
+ primary-for QWidget (0x0x7f885269be70)
+ QPaintDevice (0x0x7f884f335840) 16
+ vptr=((& QScrollBar::_ZTV10QScrollBar) + 456u)
+
+Vtable for QScrollerProperties
+QScrollerProperties::_ZTV19QScrollerProperties: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QScrollerProperties)
+16 (int (*)(...))QScrollerProperties::~QScrollerProperties
+24 (int (*)(...))QScrollerProperties::~QScrollerProperties
+
+Class QScrollerProperties
+ size=16 align=8
+ base size=16 base align=8
+QScrollerProperties (0x0x7f884f335ae0) 0
+ vptr=((& QScrollerProperties::_ZTV19QScrollerProperties) + 16u)
+
+Class QScroller::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QScroller::QPrivateSignal (0x0x7f884f40ea20) 0 empty
+
+Vtable for QScroller
+QScroller::_ZTV9QScroller: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QScroller)
+16 (int (*)(...))QScroller::metaObject
+24 (int (*)(...))QScroller::qt_metacast
+32 (int (*)(...))QScroller::qt_metacall
+40 (int (*)(...))QScroller::~QScroller
+48 (int (*)(...))QScroller::~QScroller
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QScroller
+ size=24 align=8
+ base size=24 base align=8
+QScroller (0x0x7f884fa23138) 0
+ vptr=((& QScroller::_ZTV9QScroller) + 16u)
+ QObject (0x0x7f884f40e960) 0
+ primary-for QScroller (0x0x7f884fa23138)
+
+Class QShortcut::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QShortcut::QPrivateSignal (0x0x7f884f4322a0) 0 empty
+
+Vtable for QShortcut
+QShortcut::_ZTV9QShortcut: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QShortcut)
+16 (int (*)(...))QShortcut::metaObject
+24 (int (*)(...))QShortcut::qt_metacast
+32 (int (*)(...))QShortcut::qt_metacall
+40 (int (*)(...))QShortcut::~QShortcut
+48 (int (*)(...))QShortcut::~QShortcut
+56 (int (*)(...))QShortcut::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QShortcut
+ size=16 align=8
+ base size=16 base align=8
+QShortcut (0x0x7f884fa231a0) 0
+ vptr=((& QShortcut::_ZTV9QShortcut) + 16u)
+ QObject (0x0x7f884f432240) 0
+ primary-for QShortcut (0x0x7f884fa231a0)
+
+Class QSizeGrip::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSizeGrip::QPrivateSignal (0x0x7f884f163960) 0 empty
+
+Vtable for QSizeGrip
+QSizeGrip::_ZTV9QSizeGrip: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QSizeGrip)
+16 (int (*)(...))QSizeGrip::metaObject
+24 (int (*)(...))QSizeGrip::qt_metacast
+32 (int (*)(...))QSizeGrip::qt_metacall
+40 (int (*)(...))QSizeGrip::~QSizeGrip
+48 (int (*)(...))QSizeGrip::~QSizeGrip
+56 (int (*)(...))QSizeGrip::event
+64 (int (*)(...))QSizeGrip::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QSizeGrip::setVisible
+128 (int (*)(...))QSizeGrip::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QSizeGrip::mousePressEvent
+176 (int (*)(...))QSizeGrip::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QSizeGrip::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QSizeGrip::paintEvent
+264 (int (*)(...))QSizeGrip::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QSizeGrip::showEvent
+352 (int (*)(...))QSizeGrip::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI9QSizeGrip)
+448 (int (*)(...))QSizeGrip::_ZThn16_N9QSizeGripD1Ev
+456 (int (*)(...))QSizeGrip::_ZThn16_N9QSizeGripD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QSizeGrip
+ size=48 align=8
+ base size=48 base align=8
+QSizeGrip (0x0x7f884fa23208) 0
+ vptr=((& QSizeGrip::_ZTV9QSizeGrip) + 16u)
+ QWidget (0x0x7f88526f9d90) 0
+ primary-for QSizeGrip (0x0x7f884fa23208)
+ QObject (0x0x7f884f432360) 0
+ primary-for QWidget (0x0x7f88526f9d90)
+ QPaintDevice (0x0x7f884f163900) 16
+ vptr=((& QSizeGrip::_ZTV9QSizeGrip) + 448u)
+
+Class QSpinBox::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSpinBox::QPrivateSignal (0x0x7f884ebe2a80) 0 empty
+
+Vtable for QSpinBox
+QSpinBox::_ZTV8QSpinBox: 71u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QSpinBox)
+16 (int (*)(...))QSpinBox::metaObject
+24 (int (*)(...))QSpinBox::qt_metacast
+32 (int (*)(...))QSpinBox::qt_metacall
+40 (int (*)(...))QSpinBox::~QSpinBox
+48 (int (*)(...))QSpinBox::~QSpinBox
+56 (int (*)(...))QSpinBox::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractSpinBox::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractSpinBox::sizeHint
+136 (int (*)(...))QAbstractSpinBox::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractSpinBox::mousePressEvent
+176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent
+200 (int (*)(...))QAbstractSpinBox::wheelEvent
+208 (int (*)(...))QAbstractSpinBox::keyPressEvent
+216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent
+224 (int (*)(...))QAbstractSpinBox::focusInEvent
+232 (int (*)(...))QAbstractSpinBox::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QAbstractSpinBox::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QAbstractSpinBox::resizeEvent
+280 (int (*)(...))QAbstractSpinBox::closeEvent
+288 (int (*)(...))QAbstractSpinBox::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QAbstractSpinBox::showEvent
+352 (int (*)(...))QAbstractSpinBox::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractSpinBox::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QAbstractSpinBox::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QSpinBox::validate
+440 (int (*)(...))QSpinBox::fixup
+448 (int (*)(...))QAbstractSpinBox::stepBy
+456 (int (*)(...))QAbstractSpinBox::clear
+464 (int (*)(...))QAbstractSpinBox::stepEnabled
+472 (int (*)(...))QSpinBox::valueFromText
+480 (int (*)(...))QSpinBox::textFromValue
+488 (int (*)(...))-16
+496 (int (*)(...))(& _ZTI8QSpinBox)
+504 (int (*)(...))QSpinBox::_ZThn16_N8QSpinBoxD1Ev
+512 (int (*)(...))QSpinBox::_ZThn16_N8QSpinBoxD0Ev
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QSpinBox
+ size=48 align=8
+ base size=48 base align=8
+QSpinBox (0x0x7f884fa23270) 0
+ vptr=((& QSpinBox::_ZTV8QSpinBox) + 16u)
+ QAbstractSpinBox (0x0x7f884fa232d8) 0
+ primary-for QSpinBox (0x0x7f884fa23270)
+ QWidget (0x0x7f88527083f0) 0
+ primary-for QAbstractSpinBox (0x0x7f884fa232d8)
+ QObject (0x0x7f884f163a20) 0
+ primary-for QWidget (0x0x7f88527083f0)
+ QPaintDevice (0x0x7f884ebe2a20) 16
+ vptr=((& QSpinBox::_ZTV8QSpinBox) + 504u)
+
+Class QDoubleSpinBox::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDoubleSpinBox::QPrivateSignal (0x0x7f884e936240) 0 empty
+
+Vtable for QDoubleSpinBox
+QDoubleSpinBox::_ZTV14QDoubleSpinBox: 71u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QDoubleSpinBox)
+16 (int (*)(...))QDoubleSpinBox::metaObject
+24 (int (*)(...))QDoubleSpinBox::qt_metacast
+32 (int (*)(...))QDoubleSpinBox::qt_metacall
+40 (int (*)(...))QDoubleSpinBox::~QDoubleSpinBox
+48 (int (*)(...))QDoubleSpinBox::~QDoubleSpinBox
+56 (int (*)(...))QAbstractSpinBox::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractSpinBox::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractSpinBox::sizeHint
+136 (int (*)(...))QAbstractSpinBox::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractSpinBox::mousePressEvent
+176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent
+200 (int (*)(...))QAbstractSpinBox::wheelEvent
+208 (int (*)(...))QAbstractSpinBox::keyPressEvent
+216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent
+224 (int (*)(...))QAbstractSpinBox::focusInEvent
+232 (int (*)(...))QAbstractSpinBox::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QAbstractSpinBox::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QAbstractSpinBox::resizeEvent
+280 (int (*)(...))QAbstractSpinBox::closeEvent
+288 (int (*)(...))QAbstractSpinBox::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QAbstractSpinBox::showEvent
+352 (int (*)(...))QAbstractSpinBox::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractSpinBox::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QAbstractSpinBox::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QDoubleSpinBox::validate
+440 (int (*)(...))QDoubleSpinBox::fixup
+448 (int (*)(...))QAbstractSpinBox::stepBy
+456 (int (*)(...))QAbstractSpinBox::clear
+464 (int (*)(...))QAbstractSpinBox::stepEnabled
+472 (int (*)(...))QDoubleSpinBox::valueFromText
+480 (int (*)(...))QDoubleSpinBox::textFromValue
+488 (int (*)(...))-16
+496 (int (*)(...))(& _ZTI14QDoubleSpinBox)
+504 (int (*)(...))QDoubleSpinBox::_ZThn16_N14QDoubleSpinBoxD1Ev
+512 (int (*)(...))QDoubleSpinBox::_ZThn16_N14QDoubleSpinBoxD0Ev
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QDoubleSpinBox
+ size=48 align=8
+ base size=48 base align=8
+QDoubleSpinBox (0x0x7f884fa23340) 0
+ vptr=((& QDoubleSpinBox::_ZTV14QDoubleSpinBox) + 16u)
+ QAbstractSpinBox (0x0x7f884fa233a8) 0
+ primary-for QDoubleSpinBox (0x0x7f884fa23340)
+ QWidget (0x0x7f88527089a0) 0
+ primary-for QAbstractSpinBox (0x0x7f884fa233a8)
+ QObject (0x0x7f884ebe2ea0) 0
+ primary-for QWidget (0x0x7f88527089a0)
+ QPaintDevice (0x0x7f884ebe2f00) 16
+ vptr=((& QDoubleSpinBox::_ZTV14QDoubleSpinBox) + 504u)
+
+Class QSplashScreen::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSplashScreen::QPrivateSignal (0x0x7f884e936480) 0 empty
+
+Vtable for QSplashScreen
+QSplashScreen::_ZTV13QSplashScreen: 65u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QSplashScreen)
+16 (int (*)(...))QSplashScreen::metaObject
+24 (int (*)(...))QSplashScreen::qt_metacast
+32 (int (*)(...))QSplashScreen::qt_metacall
+40 (int (*)(...))QSplashScreen::~QSplashScreen
+48 (int (*)(...))QSplashScreen::~QSplashScreen
+56 (int (*)(...))QSplashScreen::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QSplashScreen::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QSplashScreen::drawContents
+440 (int (*)(...))-16
+448 (int (*)(...))(& _ZTI13QSplashScreen)
+456 (int (*)(...))QSplashScreen::_ZThn16_N13QSplashScreenD1Ev
+464 (int (*)(...))QSplashScreen::_ZThn16_N13QSplashScreenD0Ev
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QSplashScreen
+ size=48 align=8
+ base size=48 base align=8
+QSplashScreen (0x0x7f884fa23410) 0
+ vptr=((& QSplashScreen::_ZTV13QSplashScreen) + 16u)
+ QWidget (0x0x7f8852728000) 0
+ primary-for QSplashScreen (0x0x7f884fa23410)
+ QObject (0x0x7f884e9362a0) 0
+ primary-for QWidget (0x0x7f8852728000)
+ QPaintDevice (0x0x7f884e936420) 16
+ vptr=((& QSplashScreen::_ZTV13QSplashScreen) + 456u)
+
+Class QSplitter::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSplitter::QPrivateSignal (0x0x7f884e936660) 0 empty
+
+Vtable for QSplitter
+QSplitter::_ZTV9QSplitter: 65u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QSplitter)
+16 (int (*)(...))QSplitter::metaObject
+24 (int (*)(...))QSplitter::qt_metacast
+32 (int (*)(...))QSplitter::qt_metacall
+40 (int (*)(...))QSplitter::~QSplitter
+48 (int (*)(...))QSplitter::~QSplitter
+56 (int (*)(...))QSplitter::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QSplitter::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QSplitter::sizeHint
+136 (int (*)(...))QSplitter::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QFrame::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QSplitter::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QSplitter::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QSplitter::createHandle
+440 (int (*)(...))-16
+448 (int (*)(...))(& _ZTI9QSplitter)
+456 (int (*)(...))QSplitter::_ZThn16_N9QSplitterD1Ev
+464 (int (*)(...))QSplitter::_ZThn16_N9QSplitterD0Ev
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QSplitter
+ size=48 align=8
+ base size=48 base align=8
+QSplitter (0x0x7f884fa23478) 0
+ vptr=((& QSplitter::_ZTV9QSplitter) + 16u)
+ QFrame (0x0x7f884fa234e0) 0
+ primary-for QSplitter (0x0x7f884fa23478)
+ QWidget (0x0x7f8852728a10) 0
+ primary-for QFrame (0x0x7f884fa234e0)
+ QObject (0x0x7f884e936540) 0
+ primary-for QWidget (0x0x7f8852728a10)
+ QPaintDevice (0x0x7f884e936600) 16
+ vptr=((& QSplitter::_ZTV9QSplitter) + 456u)
+
+Class QSplitterHandle::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSplitterHandle::QPrivateSignal (0x0x7f884e964e40) 0 empty
+
+Vtable for QSplitterHandle
+QSplitterHandle::_ZTV15QSplitterHandle: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QSplitterHandle)
+16 (int (*)(...))QSplitterHandle::metaObject
+24 (int (*)(...))QSplitterHandle::qt_metacast
+32 (int (*)(...))QSplitterHandle::qt_metacall
+40 (int (*)(...))QSplitterHandle::~QSplitterHandle
+48 (int (*)(...))QSplitterHandle::~QSplitterHandle
+56 (int (*)(...))QSplitterHandle::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QSplitterHandle::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QSplitterHandle::mousePressEvent
+176 (int (*)(...))QSplitterHandle::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QSplitterHandle::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QSplitterHandle::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QSplitterHandle::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI15QSplitterHandle)
+448 (int (*)(...))QSplitterHandle::_ZThn16_N15QSplitterHandleD1Ev
+456 (int (*)(...))QSplitterHandle::_ZThn16_N15QSplitterHandleD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QSplitterHandle
+ size=48 align=8
+ base size=48 base align=8
+QSplitterHandle (0x0x7f884fa23548) 0
+ vptr=((& QSplitterHandle::_ZTV15QSplitterHandle) + 16u)
+ QWidget (0x0x7f885272c230) 0
+ primary-for QSplitterHandle (0x0x7f884fa23548)
+ QObject (0x0x7f884e964240) 0
+ primary-for QWidget (0x0x7f885272c230)
+ QPaintDevice (0x0x7f884e9642a0) 16
+ vptr=((& QSplitterHandle::_ZTV15QSplitterHandle) + 448u)
+
+Class QStackedLayout::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QStackedLayout::QPrivateSignal (0x0x7f884e989180) 0 empty
+
+Vtable for QStackedLayout
+QStackedLayout::_ZTV14QStackedLayout: 50u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QStackedLayout)
+16 (int (*)(...))QStackedLayout::metaObject
+24 (int (*)(...))QStackedLayout::qt_metacast
+32 (int (*)(...))QStackedLayout::qt_metacall
+40 (int (*)(...))QStackedLayout::~QStackedLayout
+48 (int (*)(...))QStackedLayout::~QStackedLayout
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QLayout::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QLayout::invalidate
+120 (int (*)(...))QLayout::geometry
+128 (int (*)(...))QStackedLayout::addItem
+136 (int (*)(...))QLayout::expandingDirections
+144 (int (*)(...))QStackedLayout::minimumSize
+152 (int (*)(...))QLayout::maximumSize
+160 (int (*)(...))QStackedLayout::setGeometry
+168 (int (*)(...))QStackedLayout::itemAt
+176 (int (*)(...))QStackedLayout::takeAt
+184 (int (*)(...))QLayout::indexOf
+192 (int (*)(...))QStackedLayout::count
+200 (int (*)(...))QLayout::isEmpty
+208 (int (*)(...))QLayout::controlTypes
+216 (int (*)(...))QLayout::layout
+224 (int (*)(...))QStackedLayout::sizeHint
+232 (int (*)(...))QStackedLayout::hasHeightForWidth
+240 (int (*)(...))QStackedLayout::heightForWidth
+248 (int (*)(...))-16
+256 (int (*)(...))(& _ZTI14QStackedLayout)
+264 (int (*)(...))QStackedLayout::_ZThn16_N14QStackedLayoutD1Ev
+272 (int (*)(...))QStackedLayout::_ZThn16_N14QStackedLayoutD0Ev
+280 (int (*)(...))QStackedLayout::_ZThn16_NK14QStackedLayout8sizeHintEv
+288 (int (*)(...))QStackedLayout::_ZThn16_NK14QStackedLayout11minimumSizeEv
+296 (int (*)(...))QLayout::_ZThn16_NK7QLayout11maximumSizeEv
+304 (int (*)(...))QLayout::_ZThn16_NK7QLayout19expandingDirectionsEv
+312 (int (*)(...))QStackedLayout::_ZThn16_N14QStackedLayout11setGeometryERK5QRect
+320 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv
+328 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv
+336 (int (*)(...))QStackedLayout::_ZThn16_NK14QStackedLayout17hasHeightForWidthEv
+344 (int (*)(...))QStackedLayout::_ZThn16_NK14QStackedLayout14heightForWidthEi
+352 (int (*)(...))QLayoutItem::minimumHeightForWidth
+360 (int (*)(...))QLayout::_ZThn16_N7QLayout10invalidateEv
+368 (int (*)(...))QLayoutItem::widget
+376 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv
+384 (int (*)(...))QLayoutItem::spacerItem
+392 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv
+
+Class QStackedLayout
+ size=32 align=8
+ base size=28 base align=8
+QStackedLayout (0x0x7f884fa235b0) 0
+ vptr=((& QStackedLayout::_ZTV14QStackedLayout) + 16u)
+ QLayout (0x0x7f885272c9a0) 0
+ primary-for QStackedLayout (0x0x7f884fa235b0)
+ QObject (0x0x7f884e964ea0) 0
+ primary-for QLayout (0x0x7f885272c9a0)
+ QLayoutItem (0x0x7f884e989120) 16
+ vptr=((& QStackedLayout::_ZTV14QStackedLayout) + 264u)
+
+Class QStackedWidget::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QStackedWidget::QPrivateSignal (0x0x7f884e217600) 0 empty
+
+Vtable for QStackedWidget
+QStackedWidget::_ZTV14QStackedWidget: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QStackedWidget)
+16 (int (*)(...))QStackedWidget::metaObject
+24 (int (*)(...))QStackedWidget::qt_metacast
+32 (int (*)(...))QStackedWidget::qt_metacall
+40 (int (*)(...))QStackedWidget::~QStackedWidget
+48 (int (*)(...))QStackedWidget::~QStackedWidget
+56 (int (*)(...))QStackedWidget::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QFrame::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QFrame::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI14QStackedWidget)
+448 (int (*)(...))QStackedWidget::_ZThn16_N14QStackedWidgetD1Ev
+456 (int (*)(...))QStackedWidget::_ZThn16_N14QStackedWidgetD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QStackedWidget
+ size=48 align=8
+ base size=48 base align=8
+QStackedWidget (0x0x7f884fa23618) 0
+ vptr=((& QStackedWidget::_ZTV14QStackedWidget) + 16u)
+ QFrame (0x0x7f884fa23680) 0
+ primary-for QStackedWidget (0x0x7f884fa23618)
+ QWidget (0x0x7f88527393f0) 0
+ primary-for QFrame (0x0x7f884fa23680)
+ QObject (0x0x7f884e217180) 0
+ primary-for QWidget (0x0x7f88527393f0)
+ QPaintDevice (0x0x7f884e2171e0) 16
+ vptr=((& QStackedWidget::_ZTV14QStackedWidget) + 448u)
+
+Class QStatusBar::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QStatusBar::QPrivateSignal (0x0x7f884e217de0) 0 empty
+
+Vtable for QStatusBar
+QStatusBar::_ZTV10QStatusBar: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QStatusBar)
+16 (int (*)(...))QStatusBar::metaObject
+24 (int (*)(...))QStatusBar::qt_metacast
+32 (int (*)(...))QStatusBar::qt_metacall
+40 (int (*)(...))QStatusBar::~QStatusBar
+48 (int (*)(...))QStatusBar::~QStatusBar
+56 (int (*)(...))QStatusBar::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QStatusBar::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QStatusBar::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QStatusBar::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI10QStatusBar)
+448 (int (*)(...))QStatusBar::_ZThn16_N10QStatusBarD1Ev
+456 (int (*)(...))QStatusBar::_ZThn16_N10QStatusBarD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QStatusBar
+ size=48 align=8
+ base size=48 base align=8
+QStatusBar (0x0x7f884fa23a90) 0
+ vptr=((& QStatusBar::_ZTV10QStatusBar) + 16u)
+ QWidget (0x0x7f8852739bd0) 0
+ primary-for QStatusBar (0x0x7f884fa23a90)
+ QObject (0x0x7f884e217660) 0
+ primary-for QWidget (0x0x7f8852739bd0)
+ QPaintDevice (0x0x7f884e217d80) 16
+ vptr=((& QStatusBar::_ZTV10QStatusBar) + 448u)
+
+Class QStyledItemDelegate::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QStyledItemDelegate::QPrivateSignal (0x0x7f884de3a6c0) 0 empty
+
+Vtable for QStyledItemDelegate
+QStyledItemDelegate::_ZTV19QStyledItemDelegate: 26u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QStyledItemDelegate)
+16 (int (*)(...))QStyledItemDelegate::metaObject
+24 (int (*)(...))QStyledItemDelegate::qt_metacast
+32 (int (*)(...))QStyledItemDelegate::qt_metacall
+40 (int (*)(...))QStyledItemDelegate::~QStyledItemDelegate
+48 (int (*)(...))QStyledItemDelegate::~QStyledItemDelegate
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QStyledItemDelegate::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QStyledItemDelegate::paint
+120 (int (*)(...))QStyledItemDelegate::sizeHint
+128 (int (*)(...))QStyledItemDelegate::createEditor
+136 (int (*)(...))QAbstractItemDelegate::destroyEditor
+144 (int (*)(...))QStyledItemDelegate::setEditorData
+152 (int (*)(...))QStyledItemDelegate::setModelData
+160 (int (*)(...))QStyledItemDelegate::updateEditorGeometry
+168 (int (*)(...))QStyledItemDelegate::editorEvent
+176 (int (*)(...))QAbstractItemDelegate::helpEvent
+184 (int (*)(...))QAbstractItemDelegate::paintingRoles
+192 (int (*)(...))QStyledItemDelegate::displayText
+200 (int (*)(...))QStyledItemDelegate::initStyleOption
+
+Class QStyledItemDelegate
+ size=16 align=8
+ base size=16 base align=8
+QStyledItemDelegate (0x0x7f884fa23af8) 0
+ vptr=((& QStyledItemDelegate::_ZTV19QStyledItemDelegate) + 16u)
+ QAbstractItemDelegate (0x0x7f884fa23b60) 0
+ primary-for QStyledItemDelegate (0x0x7f884fa23af8)
+ QObject (0x0x7f884de3a660) 0
+ primary-for QAbstractItemDelegate (0x0x7f884fa23b60)
+
+Class QStyleFactory
+ size=1 align=1
+ base size=0 base align=1
+QStyleFactory (0x0x7f884de3a7e0) 0 empty
+
+Class QStylePainter
+ size=24 align=8
+ base size=24 base align=8
+QStylePainter (0x0x7f884fa23bc8) 0
+ QPainter (0x0x7f884de3a840) 0
+
+Class QStylePlugin::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QStylePlugin::QPrivateSignal (0x0x7f884de3ade0) 0 empty
+
+Vtable for QStylePlugin
+QStylePlugin::_ZTV12QStylePlugin: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QStylePlugin)
+16 (int (*)(...))QStylePlugin::metaObject
+24 (int (*)(...))QStylePlugin::qt_metacast
+32 (int (*)(...))QStylePlugin::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+
+Class QStylePlugin
+ size=16 align=8
+ base size=16 base align=8
+QStylePlugin (0x0x7f884fa23c98) 0
+ vptr=((& QStylePlugin::_ZTV12QStylePlugin) + 16u)
+ QObject (0x0x7f884de3ad80) 0
+ primary-for QStylePlugin (0x0x7f884fa23c98)
+
+Class QSystemTrayIcon::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSystemTrayIcon::QPrivateSignal (0x0x7f884de3af00) 0 empty
+
+Vtable for QSystemTrayIcon
+QSystemTrayIcon::_ZTV15QSystemTrayIcon: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QSystemTrayIcon)
+16 (int (*)(...))QSystemTrayIcon::metaObject
+24 (int (*)(...))QSystemTrayIcon::qt_metacast
+32 (int (*)(...))QSystemTrayIcon::qt_metacall
+40 (int (*)(...))QSystemTrayIcon::~QSystemTrayIcon
+48 (int (*)(...))QSystemTrayIcon::~QSystemTrayIcon
+56 (int (*)(...))QSystemTrayIcon::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QSystemTrayIcon
+ size=16 align=8
+ base size=16 base align=8
+QSystemTrayIcon (0x0x7f884fa23d00) 0
+ vptr=((& QSystemTrayIcon::_ZTV15QSystemTrayIcon) + 16u)
+ QObject (0x0x7f884de3aea0) 0
+ primary-for QSystemTrayIcon (0x0x7f884fa23d00)
+
+Class QTableView::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTableView::QPrivateSignal (0x0x7f884de646c0) 0 empty
+
+Vtable for QTableView
+QTableView::_ZTV10QTableView: 106u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTableView)
+16 (int (*)(...))QTableView::metaObject
+24 (int (*)(...))QTableView::qt_metacast
+32 (int (*)(...))QTableView::qt_metacall
+40 (int (*)(...))QTableView::~QTableView
+48 (int (*)(...))QTableView::~QTableView
+56 (int (*)(...))QAbstractItemView::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QTableView::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractScrollArea::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractItemView::mousePressEvent
+176 (int (*)(...))QAbstractItemView::mouseReleaseEvent
+184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractItemView::mouseMoveEvent
+200 (int (*)(...))QAbstractScrollArea::wheelEvent
+208 (int (*)(...))QAbstractItemView::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QAbstractItemView::focusInEvent
+232 (int (*)(...))QAbstractItemView::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QTableView::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QAbstractItemView::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QAbstractScrollArea::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QAbstractItemView::dragEnterEvent
+320 (int (*)(...))QAbstractItemView::dragMoveEvent
+328 (int (*)(...))QAbstractItemView::dragLeaveEvent
+336 (int (*)(...))QAbstractItemView::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QAbstractItemView::inputMethodEvent
+416 (int (*)(...))QAbstractItemView::inputMethodQuery
+424 (int (*)(...))QAbstractItemView::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QAbstractItemView::viewportEvent
+448 (int (*)(...))QTableView::scrollContentsBy
+456 (int (*)(...))QTableView::viewportSizeHint
+464 (int (*)(...))QTableView::setModel
+472 (int (*)(...))QTableView::setSelectionModel
+480 (int (*)(...))QAbstractItemView::keyboardSearch
+488 (int (*)(...))QTableView::visualRect
+496 (int (*)(...))QTableView::scrollTo
+504 (int (*)(...))QTableView::indexAt
+512 (int (*)(...))QTableView::sizeHintForRow
+520 (int (*)(...))QTableView::sizeHintForColumn
+528 (int (*)(...))QAbstractItemView::reset
+536 (int (*)(...))QTableView::setRootIndex
+544 (int (*)(...))QTableView::doItemsLayout
+552 (int (*)(...))QAbstractItemView::selectAll
+560 (int (*)(...))QAbstractItemView::dataChanged
+568 (int (*)(...))QAbstractItemView::rowsInserted
+576 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved
+584 (int (*)(...))QTableView::selectionChanged
+592 (int (*)(...))QTableView::currentChanged
+600 (int (*)(...))QAbstractItemView::updateEditorData
+608 (int (*)(...))QAbstractItemView::updateEditorGeometries
+616 (int (*)(...))QTableView::updateGeometries
+624 (int (*)(...))QTableView::verticalScrollbarAction
+632 (int (*)(...))QTableView::horizontalScrollbarAction
+640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged
+648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged
+656 (int (*)(...))QAbstractItemView::closeEditor
+664 (int (*)(...))QAbstractItemView::commitData
+672 (int (*)(...))QAbstractItemView::editorDestroyed
+680 (int (*)(...))QTableView::moveCursor
+688 (int (*)(...))QTableView::horizontalOffset
+696 (int (*)(...))QTableView::verticalOffset
+704 (int (*)(...))QTableView::isIndexHidden
+712 (int (*)(...))QTableView::setSelection
+720 (int (*)(...))QTableView::visualRegionForSelection
+728 (int (*)(...))QTableView::selectedIndexes
+736 (int (*)(...))QAbstractItemView::edit
+744 (int (*)(...))QAbstractItemView::selectionCommand
+752 (int (*)(...))QAbstractItemView::startDrag
+760 (int (*)(...))QTableView::viewOptions
+768 (int (*)(...))-16
+776 (int (*)(...))(& _ZTI10QTableView)
+784 (int (*)(...))QTableView::_ZThn16_N10QTableViewD1Ev
+792 (int (*)(...))QTableView::_ZThn16_N10QTableViewD0Ev
+800 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+808 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+816 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+832 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+840 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QTableView
+ size=48 align=8
+ base size=48 base align=8
+QTableView (0x0x7f884fa23dd0) 0
+ vptr=((& QTableView::_ZTV10QTableView) + 16u)
+ QAbstractItemView (0x0x7f884fa23e38) 0
+ primary-for QTableView (0x0x7f884fa23dd0)
+ QAbstractScrollArea (0x0x7f884fa23ea0) 0
+ primary-for QAbstractItemView (0x0x7f884fa23e38)
+ QFrame (0x0x7f884fa23f08) 0
+ primary-for QAbstractScrollArea (0x0x7f884fa23ea0)
+ QWidget (0x0x7f8852772b60) 0
+ primary-for QFrame (0x0x7f884fa23f08)
+ QObject (0x0x7f884de64000) 0
+ primary-for QWidget (0x0x7f8852772b60)
+ QPaintDevice (0x0x7f884de64060) 16
+ vptr=((& QTableView::_ZTV10QTableView) + 784u)
+
+Class QTableWidgetSelectionRange
+ size=16 align=4
+ base size=16 base align=4
+QTableWidgetSelectionRange (0x0x7f884de64720) 0
+
+Vtable for QTableWidgetItem
+QTableWidgetItem::_ZTV16QTableWidgetItem: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QTableWidgetItem)
+16 (int (*)(...))QTableWidgetItem::~QTableWidgetItem
+24 (int (*)(...))QTableWidgetItem::~QTableWidgetItem
+32 (int (*)(...))QTableWidgetItem::clone
+40 (int (*)(...))QTableWidgetItem::data
+48 (int (*)(...))QTableWidgetItem::setData
+56 (int (*)(...))QTableWidgetItem::operator<
+64 (int (*)(...))QTableWidgetItem::read
+72 (int (*)(...))QTableWidgetItem::write
+
+Class QTableWidgetItem
+ size=48 align=8
+ base size=44 base align=8
+QTableWidgetItem (0x0x7f884dec1300) 0
+ vptr=((& QTableWidgetItem::_ZTV16QTableWidgetItem) + 16u)
+
+Class QTableWidget::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTableWidget::QPrivateSignal (0x0x7f884df8a6c0) 0 empty
+
+Vtable for QTableWidget
+QTableWidget::_ZTV12QTableWidget: 110u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QTableWidget)
+16 (int (*)(...))QTableWidget::metaObject
+24 (int (*)(...))QTableWidget::qt_metacast
+32 (int (*)(...))QTableWidget::qt_metacall
+40 (int (*)(...))QTableWidget::~QTableWidget
+48 (int (*)(...))QTableWidget::~QTableWidget
+56 (int (*)(...))QTableWidget::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QTableView::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractScrollArea::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractItemView::mousePressEvent
+176 (int (*)(...))QAbstractItemView::mouseReleaseEvent
+184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractItemView::mouseMoveEvent
+200 (int (*)(...))QAbstractScrollArea::wheelEvent
+208 (int (*)(...))QAbstractItemView::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QAbstractItemView::focusInEvent
+232 (int (*)(...))QAbstractItemView::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QTableView::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QAbstractItemView::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QAbstractScrollArea::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QAbstractItemView::dragEnterEvent
+320 (int (*)(...))QAbstractItemView::dragMoveEvent
+328 (int (*)(...))QAbstractItemView::dragLeaveEvent
+336 (int (*)(...))QTableWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QAbstractItemView::inputMethodEvent
+416 (int (*)(...))QAbstractItemView::inputMethodQuery
+424 (int (*)(...))QAbstractItemView::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QAbstractItemView::viewportEvent
+448 (int (*)(...))QTableView::scrollContentsBy
+456 (int (*)(...))QTableView::viewportSizeHint
+464 (int (*)(...))QTableWidget::setModel
+472 (int (*)(...))QTableView::setSelectionModel
+480 (int (*)(...))QAbstractItemView::keyboardSearch
+488 (int (*)(...))QTableView::visualRect
+496 (int (*)(...))QTableView::scrollTo
+504 (int (*)(...))QTableView::indexAt
+512 (int (*)(...))QTableView::sizeHintForRow
+520 (int (*)(...))QTableView::sizeHintForColumn
+528 (int (*)(...))QAbstractItemView::reset
+536 (int (*)(...))QTableView::setRootIndex
+544 (int (*)(...))QTableView::doItemsLayout
+552 (int (*)(...))QAbstractItemView::selectAll
+560 (int (*)(...))QAbstractItemView::dataChanged
+568 (int (*)(...))QAbstractItemView::rowsInserted
+576 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved
+584 (int (*)(...))QTableView::selectionChanged
+592 (int (*)(...))QTableView::currentChanged
+600 (int (*)(...))QAbstractItemView::updateEditorData
+608 (int (*)(...))QAbstractItemView::updateEditorGeometries
+616 (int (*)(...))QTableView::updateGeometries
+624 (int (*)(...))QTableView::verticalScrollbarAction
+632 (int (*)(...))QTableView::horizontalScrollbarAction
+640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged
+648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged
+656 (int (*)(...))QAbstractItemView::closeEditor
+664 (int (*)(...))QAbstractItemView::commitData
+672 (int (*)(...))QAbstractItemView::editorDestroyed
+680 (int (*)(...))QTableView::moveCursor
+688 (int (*)(...))QTableView::horizontalOffset
+696 (int (*)(...))QTableView::verticalOffset
+704 (int (*)(...))QTableView::isIndexHidden
+712 (int (*)(...))QTableView::setSelection
+720 (int (*)(...))QTableView::visualRegionForSelection
+728 (int (*)(...))QTableView::selectedIndexes
+736 (int (*)(...))QAbstractItemView::edit
+744 (int (*)(...))QAbstractItemView::selectionCommand
+752 (int (*)(...))QAbstractItemView::startDrag
+760 (int (*)(...))QTableView::viewOptions
+768 (int (*)(...))QTableWidget::mimeTypes
+776 (int (*)(...))QTableWidget::mimeData
+784 (int (*)(...))QTableWidget::dropMimeData
+792 (int (*)(...))QTableWidget::supportedDropActions
+800 (int (*)(...))-16
+808 (int (*)(...))(& _ZTI12QTableWidget)
+816 (int (*)(...))QTableWidget::_ZThn16_N12QTableWidgetD1Ev
+824 (int (*)(...))QTableWidget::_ZThn16_N12QTableWidgetD0Ev
+832 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+840 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+848 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+856 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+864 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+872 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QTableWidget
+ size=48 align=8
+ base size=48 base align=8
+QTableWidget (0x0x7f884f4c5ea0) 0
+ vptr=((& QTableWidget::_ZTV12QTableWidget) + 16u)
+ QTableView (0x0x7f884f4c5270) 0
+ primary-for QTableWidget (0x0x7f884f4c5ea0)
+ QAbstractItemView (0x0x7f884f4c5340) 0
+ primary-for QTableView (0x0x7f884f4c5270)
+ QAbstractScrollArea (0x0x7f884f618068) 0
+ primary-for QAbstractItemView (0x0x7f884f4c5340)
+ QFrame (0x0x7f884f6180d0) 0
+ primary-for QAbstractScrollArea (0x0x7f884f618068)
+ QWidget (0x0x7f88527b1460) 0
+ primary-for QFrame (0x0x7f884f6180d0)
+ QObject (0x0x7f884df8a600) 0
+ primary-for QWidget (0x0x7f88527b1460)
+ QPaintDevice (0x0x7f884df8a660) 16
+ vptr=((& QTableWidget::_ZTV12QTableWidget) + 816u)
+
+Class QTextBrowser::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTextBrowser::QPrivateSignal (0x0x7f884d8cc360) 0 empty
+
+Vtable for QTextBrowser
+QTextBrowser::_ZTV12QTextBrowser: 78u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QTextBrowser)
+16 (int (*)(...))QTextBrowser::metaObject
+24 (int (*)(...))QTextBrowser::qt_metacast
+32 (int (*)(...))QTextBrowser::qt_metacall
+40 (int (*)(...))QTextBrowser::~QTextBrowser
+48 (int (*)(...))QTextBrowser::~QTextBrowser
+56 (int (*)(...))QTextBrowser::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QTextEdit::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractScrollArea::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QTextBrowser::mousePressEvent
+176 (int (*)(...))QTextBrowser::mouseReleaseEvent
+184 (int (*)(...))QTextEdit::mouseDoubleClickEvent
+192 (int (*)(...))QTextBrowser::mouseMoveEvent
+200 (int (*)(...))QTextEdit::wheelEvent
+208 (int (*)(...))QTextBrowser::keyPressEvent
+216 (int (*)(...))QTextEdit::keyReleaseEvent
+224 (int (*)(...))QTextEdit::focusInEvent
+232 (int (*)(...))QTextBrowser::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QTextBrowser::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QTextEdit::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QTextEdit::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QTextEdit::dragEnterEvent
+320 (int (*)(...))QTextEdit::dragMoveEvent
+328 (int (*)(...))QTextEdit::dragLeaveEvent
+336 (int (*)(...))QTextEdit::dropEvent
+344 (int (*)(...))QTextEdit::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QTextEdit::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QTextEdit::inputMethodEvent
+416 (int (*)(...))QTextEdit::inputMethodQuery
+424 (int (*)(...))QTextBrowser::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QAbstractScrollArea::viewportEvent
+448 (int (*)(...))QTextEdit::scrollContentsBy
+456 (int (*)(...))QAbstractScrollArea::viewportSizeHint
+464 (int (*)(...))QTextBrowser::loadResource
+472 (int (*)(...))QTextEdit::createMimeDataFromSelection
+480 (int (*)(...))QTextEdit::canInsertFromMimeData
+488 (int (*)(...))QTextEdit::insertFromMimeData
+496 (int (*)(...))QTextEdit::doSetTextCursor
+504 (int (*)(...))QTextBrowser::setSource
+512 (int (*)(...))QTextBrowser::backward
+520 (int (*)(...))QTextBrowser::forward
+528 (int (*)(...))QTextBrowser::home
+536 (int (*)(...))QTextBrowser::reload
+544 (int (*)(...))-16
+552 (int (*)(...))(& _ZTI12QTextBrowser)
+560 (int (*)(...))QTextBrowser::_ZThn16_N12QTextBrowserD1Ev
+568 (int (*)(...))QTextBrowser::_ZThn16_N12QTextBrowserD0Ev
+576 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+584 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+592 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+600 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+608 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+616 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QTextBrowser
+ size=48 align=8
+ base size=48 base align=8
+QTextBrowser (0x0x7f884f618138) 0
+ vptr=((& QTextBrowser::_ZTV12QTextBrowser) + 16u)
+ QTextEdit (0x0x7f884f6181a0) 0
+ primary-for QTextBrowser (0x0x7f884f618138)
+ QAbstractScrollArea (0x0x7f884f618478) 0
+ primary-for QTextEdit (0x0x7f884f6181a0)
+ QFrame (0x0x7f884f6184e0) 0
+ primary-for QAbstractScrollArea (0x0x7f884f618478)
+ QWidget (0x0x7f88527bb3f0) 0
+ primary-for QFrame (0x0x7f884f6184e0)
+ QObject (0x0x7f884df8a7e0) 0
+ primary-for QWidget (0x0x7f88527bb3f0)
+ QPaintDevice (0x0x7f884df8a840) 16
+ vptr=((& QTextBrowser::_ZTV12QTextBrowser) + 560u)
+
+Class QToolBar::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QToolBar::QPrivateSignal (0x0x7f884d8ccf00) 0 empty
+
+Vtable for QToolBar
+QToolBar::_ZTV8QToolBar: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QToolBar)
+16 (int (*)(...))QToolBar::metaObject
+24 (int (*)(...))QToolBar::qt_metacast
+32 (int (*)(...))QToolBar::qt_metacall
+40 (int (*)(...))QToolBar::~QToolBar
+48 (int (*)(...))QToolBar::~QToolBar
+56 (int (*)(...))QToolBar::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QToolBar::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QToolBar::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QToolBar::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI8QToolBar)
+448 (int (*)(...))QToolBar::_ZThn16_N8QToolBarD1Ev
+456 (int (*)(...))QToolBar::_ZThn16_N8QToolBarD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QToolBar
+ size=48 align=8
+ base size=48 base align=8
+QToolBar (0x0x7f884f6186e8) 0
+ vptr=((& QToolBar::_ZTV8QToolBar) + 16u)
+ QWidget (0x0x7f88527bba80) 0
+ primary-for QToolBar (0x0x7f884f6186e8)
+ QObject (0x0x7f884d8cc3c0) 0
+ primary-for QWidget (0x0x7f88527bba80)
+ QPaintDevice (0x0x7f884d8ccea0) 16
+ vptr=((& QToolBar::_ZTV8QToolBar) + 448u)
+
+Class QToolBox::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QToolBox::QPrivateSignal (0x0x7f884d6e6960) 0 empty
+
+Vtable for QToolBox
+QToolBox::_ZTV8QToolBox: 66u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QToolBox)
+16 (int (*)(...))QToolBox::metaObject
+24 (int (*)(...))QToolBox::qt_metacast
+32 (int (*)(...))QToolBox::qt_metacall
+40 (int (*)(...))QToolBox::~QToolBox
+48 (int (*)(...))QToolBox::~QToolBox
+56 (int (*)(...))QToolBox::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QFrame::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QFrame::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QToolBox::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QToolBox::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QToolBox::itemInserted
+440 (int (*)(...))QToolBox::itemRemoved
+448 (int (*)(...))-16
+456 (int (*)(...))(& _ZTI8QToolBox)
+464 (int (*)(...))QToolBox::_ZThn16_N8QToolBoxD1Ev
+472 (int (*)(...))QToolBox::_ZThn16_N8QToolBoxD0Ev
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QToolBox
+ size=48 align=8
+ base size=48 base align=8
+QToolBox (0x0x7f884f3d59c0) 0
+ vptr=((& QToolBox::_ZTV8QToolBox) + 16u)
+ QFrame (0x0x7f884f3f9548) 0
+ primary-for QToolBox (0x0x7f884f3d59c0)
+ QWidget (0x0x7f88527d48c0) 0
+ primary-for QFrame (0x0x7f884f3f9548)
+ QObject (0x0x7f884d6e6240) 0
+ primary-for QWidget (0x0x7f88527d48c0)
+ QPaintDevice (0x0x7f884d6e6900) 16
+ vptr=((& QToolBox::_ZTV8QToolBox) + 464u)
+
+Class QToolButton::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QToolButton::QPrivateSignal (0x0x7f884d70b8a0) 0 empty
+
+Vtable for QToolButton
+QToolButton::_ZTV11QToolButton: 67u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QToolButton)
+16 (int (*)(...))QToolButton::metaObject
+24 (int (*)(...))QToolButton::qt_metacast
+32 (int (*)(...))QToolButton::qt_metacall
+40 (int (*)(...))QToolButton::~QToolButton
+48 (int (*)(...))QToolButton::~QToolButton
+56 (int (*)(...))QToolButton::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QToolButton::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QToolButton::sizeHint
+136 (int (*)(...))QToolButton::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QToolButton::mousePressEvent
+176 (int (*)(...))QToolButton::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractButton::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QAbstractButton::keyPressEvent
+216 (int (*)(...))QAbstractButton::keyReleaseEvent
+224 (int (*)(...))QAbstractButton::focusInEvent
+232 (int (*)(...))QAbstractButton::focusOutEvent
+240 (int (*)(...))QToolButton::enterEvent
+248 (int (*)(...))QToolButton::leaveEvent
+256 (int (*)(...))QToolButton::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QToolButton::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QToolButton::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QToolButton::hitButton
+440 (int (*)(...))QAbstractButton::checkStateSet
+448 (int (*)(...))QToolButton::nextCheckState
+456 (int (*)(...))-16
+464 (int (*)(...))(& _ZTI11QToolButton)
+472 (int (*)(...))QToolButton::_ZThn16_N11QToolButtonD1Ev
+480 (int (*)(...))QToolButton::_ZThn16_N11QToolButtonD0Ev
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QToolButton
+ size=48 align=8
+ base size=48 base align=8
+QToolButton (0x0x7f884f3f95b0) 0
+ vptr=((& QToolButton::_ZTV11QToolButton) + 16u)
+ QAbstractButton (0x0x7f884f3f9750) 0
+ primary-for QToolButton (0x0x7f884f3f95b0)
+ QWidget (0x0x7f88527dd380) 0
+ primary-for QAbstractButton (0x0x7f884f3f9750)
+ QObject (0x0x7f884d70b120) 0
+ primary-for QWidget (0x0x7f88527dd380)
+ QPaintDevice (0x0x7f884d70b180) 16
+ vptr=((& QToolButton::_ZTV11QToolButton) + 472u)
+
+Class QToolTip
+ size=1 align=1
+ base size=0 base align=1
+QToolTip (0x0x7f884d70b900) 0 empty
+
+Class QTreeView::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTreeView::QPrivateSignal (0x0x7f884d4b9660) 0 empty
+
+Vtable for QTreeView
+QTreeView::_ZTV9QTreeView: 108u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QTreeView)
+16 (int (*)(...))QTreeView::metaObject
+24 (int (*)(...))QTreeView::qt_metacast
+32 (int (*)(...))QTreeView::qt_metacall
+40 (int (*)(...))QTreeView::~QTreeView
+48 (int (*)(...))QTreeView::~QTreeView
+56 (int (*)(...))QAbstractItemView::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QTreeView::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractScrollArea::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QTreeView::mousePressEvent
+176 (int (*)(...))QTreeView::mouseReleaseEvent
+184 (int (*)(...))QTreeView::mouseDoubleClickEvent
+192 (int (*)(...))QTreeView::mouseMoveEvent
+200 (int (*)(...))QAbstractScrollArea::wheelEvent
+208 (int (*)(...))QTreeView::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QAbstractItemView::focusInEvent
+232 (int (*)(...))QAbstractItemView::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QTreeView::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QAbstractItemView::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QAbstractScrollArea::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QAbstractItemView::dragEnterEvent
+320 (int (*)(...))QTreeView::dragMoveEvent
+328 (int (*)(...))QAbstractItemView::dragLeaveEvent
+336 (int (*)(...))QAbstractItemView::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QAbstractItemView::inputMethodEvent
+416 (int (*)(...))QAbstractItemView::inputMethodQuery
+424 (int (*)(...))QAbstractItemView::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QTreeView::viewportEvent
+448 (int (*)(...))QTreeView::scrollContentsBy
+456 (int (*)(...))QTreeView::viewportSizeHint
+464 (int (*)(...))QTreeView::setModel
+472 (int (*)(...))QTreeView::setSelectionModel
+480 (int (*)(...))QTreeView::keyboardSearch
+488 (int (*)(...))QTreeView::visualRect
+496 (int (*)(...))QTreeView::scrollTo
+504 (int (*)(...))QTreeView::indexAt
+512 (int (*)(...))QAbstractItemView::sizeHintForRow
+520 (int (*)(...))QTreeView::sizeHintForColumn
+528 (int (*)(...))QTreeView::reset
+536 (int (*)(...))QTreeView::setRootIndex
+544 (int (*)(...))QTreeView::doItemsLayout
+552 (int (*)(...))QTreeView::selectAll
+560 (int (*)(...))QTreeView::dataChanged
+568 (int (*)(...))QTreeView::rowsInserted
+576 (int (*)(...))QTreeView::rowsAboutToBeRemoved
+584 (int (*)(...))QTreeView::selectionChanged
+592 (int (*)(...))QTreeView::currentChanged
+600 (int (*)(...))QAbstractItemView::updateEditorData
+608 (int (*)(...))QAbstractItemView::updateEditorGeometries
+616 (int (*)(...))QTreeView::updateGeometries
+624 (int (*)(...))QAbstractItemView::verticalScrollbarAction
+632 (int (*)(...))QTreeView::horizontalScrollbarAction
+640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged
+648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged
+656 (int (*)(...))QAbstractItemView::closeEditor
+664 (int (*)(...))QAbstractItemView::commitData
+672 (int (*)(...))QAbstractItemView::editorDestroyed
+680 (int (*)(...))QTreeView::moveCursor
+688 (int (*)(...))QTreeView::horizontalOffset
+696 (int (*)(...))QTreeView::verticalOffset
+704 (int (*)(...))QTreeView::isIndexHidden
+712 (int (*)(...))QTreeView::setSelection
+720 (int (*)(...))QTreeView::visualRegionForSelection
+728 (int (*)(...))QTreeView::selectedIndexes
+736 (int (*)(...))QAbstractItemView::edit
+744 (int (*)(...))QAbstractItemView::selectionCommand
+752 (int (*)(...))QAbstractItemView::startDrag
+760 (int (*)(...))QAbstractItemView::viewOptions
+768 (int (*)(...))QTreeView::drawRow
+776 (int (*)(...))QTreeView::drawBranches
+784 (int (*)(...))-16
+792 (int (*)(...))(& _ZTI9QTreeView)
+800 (int (*)(...))QTreeView::_ZThn16_N9QTreeViewD1Ev
+808 (int (*)(...))QTreeView::_ZThn16_N9QTreeViewD0Ev
+816 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+832 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+840 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+848 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+856 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QTreeView
+ size=48 align=8
+ base size=48 base align=8
+QTreeView (0x0x7f884f3f9958) 0
+ vptr=((& QTreeView::_ZTV9QTreeView) + 16u)
+ QAbstractItemView (0x0x7f884f3f99c0) 0
+ primary-for QTreeView (0x0x7f884f3f9958)
+ QAbstractScrollArea (0x0x7f884f416888) 0
+ primary-for QAbstractItemView (0x0x7f884f3f99c0)
+ QFrame (0x0x7f884f4168f0) 0
+ primary-for QAbstractScrollArea (0x0x7f884f416888)
+ QWidget (0x0x7f88527dde70) 0
+ primary-for QFrame (0x0x7f884f4168f0)
+ QObject (0x0x7f884d70bb40) 0
+ primary-for QWidget (0x0x7f88527dde70)
+ QPaintDevice (0x0x7f884d70bba0) 16
+ vptr=((& QTreeView::_ZTV9QTreeView) + 800u)
+
+Class QTreeWidgetItemIterator
+ size=24 align=8
+ base size=20 base align=8
+QTreeWidgetItemIterator (0x0x7f884d4b96c0) 0
+
+Vtable for QTreeWidgetItem
+QTreeWidgetItem::_ZTV15QTreeWidgetItem: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QTreeWidgetItem)
+16 (int (*)(...))QTreeWidgetItem::~QTreeWidgetItem
+24 (int (*)(...))QTreeWidgetItem::~QTreeWidgetItem
+32 (int (*)(...))QTreeWidgetItem::clone
+40 (int (*)(...))QTreeWidgetItem::data
+48 (int (*)(...))QTreeWidgetItem::setData
+56 (int (*)(...))QTreeWidgetItem::operator<
+64 (int (*)(...))QTreeWidgetItem::read
+72 (int (*)(...))QTreeWidgetItem::write
+
+Class QTreeWidgetItem
+ size=64 align=8
+ base size=60 base align=8
+QTreeWidgetItem (0x0x7f884d4b9c60) 0
+ vptr=((& QTreeWidgetItem::_ZTV15QTreeWidgetItem) + 16u)
+
+Class QTreeWidget::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTreeWidget::QPrivateSignal (0x0x7f884d11aae0) 0 empty
+
+Vtable for QTreeWidget
+QTreeWidget::_ZTV11QTreeWidget: 112u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTreeWidget)
+16 (int (*)(...))QTreeWidget::metaObject
+24 (int (*)(...))QTreeWidget::qt_metacast
+32 (int (*)(...))QTreeWidget::qt_metacall
+40 (int (*)(...))QTreeWidget::~QTreeWidget
+48 (int (*)(...))QTreeWidget::~QTreeWidget
+56 (int (*)(...))QTreeWidget::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QTreeView::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractScrollArea::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QTreeView::mousePressEvent
+176 (int (*)(...))QTreeView::mouseReleaseEvent
+184 (int (*)(...))QTreeView::mouseDoubleClickEvent
+192 (int (*)(...))QTreeView::mouseMoveEvent
+200 (int (*)(...))QAbstractScrollArea::wheelEvent
+208 (int (*)(...))QTreeView::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QAbstractItemView::focusInEvent
+232 (int (*)(...))QAbstractItemView::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QTreeView::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QAbstractItemView::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QAbstractScrollArea::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QAbstractItemView::dragEnterEvent
+320 (int (*)(...))QTreeView::dragMoveEvent
+328 (int (*)(...))QAbstractItemView::dragLeaveEvent
+336 (int (*)(...))QTreeWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QAbstractItemView::inputMethodEvent
+416 (int (*)(...))QAbstractItemView::inputMethodQuery
+424 (int (*)(...))QAbstractItemView::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QTreeView::viewportEvent
+448 (int (*)(...))QTreeView::scrollContentsBy
+456 (int (*)(...))QTreeView::viewportSizeHint
+464 (int (*)(...))QTreeWidget::setModel
+472 (int (*)(...))QTreeWidget::setSelectionModel
+480 (int (*)(...))QTreeView::keyboardSearch
+488 (int (*)(...))QTreeView::visualRect
+496 (int (*)(...))QTreeView::scrollTo
+504 (int (*)(...))QTreeView::indexAt
+512 (int (*)(...))QAbstractItemView::sizeHintForRow
+520 (int (*)(...))QTreeView::sizeHintForColumn
+528 (int (*)(...))QTreeView::reset
+536 (int (*)(...))QTreeView::setRootIndex
+544 (int (*)(...))QTreeView::doItemsLayout
+552 (int (*)(...))QTreeView::selectAll
+560 (int (*)(...))QTreeView::dataChanged
+568 (int (*)(...))QTreeView::rowsInserted
+576 (int (*)(...))QTreeView::rowsAboutToBeRemoved
+584 (int (*)(...))QTreeView::selectionChanged
+592 (int (*)(...))QTreeView::currentChanged
+600 (int (*)(...))QAbstractItemView::updateEditorData
+608 (int (*)(...))QAbstractItemView::updateEditorGeometries
+616 (int (*)(...))QTreeView::updateGeometries
+624 (int (*)(...))QAbstractItemView::verticalScrollbarAction
+632 (int (*)(...))QTreeView::horizontalScrollbarAction
+640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged
+648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged
+656 (int (*)(...))QAbstractItemView::closeEditor
+664 (int (*)(...))QAbstractItemView::commitData
+672 (int (*)(...))QAbstractItemView::editorDestroyed
+680 (int (*)(...))QTreeView::moveCursor
+688 (int (*)(...))QTreeView::horizontalOffset
+696 (int (*)(...))QTreeView::verticalOffset
+704 (int (*)(...))QTreeView::isIndexHidden
+712 (int (*)(...))QTreeView::setSelection
+720 (int (*)(...))QTreeView::visualRegionForSelection
+728 (int (*)(...))QTreeView::selectedIndexes
+736 (int (*)(...))QAbstractItemView::edit
+744 (int (*)(...))QAbstractItemView::selectionCommand
+752 (int (*)(...))QAbstractItemView::startDrag
+760 (int (*)(...))QAbstractItemView::viewOptions
+768 (int (*)(...))QTreeView::drawRow
+776 (int (*)(...))QTreeView::drawBranches
+784 (int (*)(...))QTreeWidget::mimeTypes
+792 (int (*)(...))QTreeWidget::mimeData
+800 (int (*)(...))QTreeWidget::dropMimeData
+808 (int (*)(...))QTreeWidget::supportedDropActions
+816 (int (*)(...))-16
+824 (int (*)(...))(& _ZTI11QTreeWidget)
+832 (int (*)(...))QTreeWidget::_ZThn16_N11QTreeWidgetD1Ev
+840 (int (*)(...))QTreeWidget::_ZThn16_N11QTreeWidgetD0Ev
+848 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+856 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+864 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+872 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+880 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+888 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QTreeWidget
+ size=48 align=8
+ base size=48 base align=8
+QTreeWidget (0x0x7f884ef67068) 0
+ vptr=((& QTreeWidget::_ZTV11QTreeWidget) + 16u)
+ QTreeView (0x0x7f884ef67bc8) 0
+ primary-for QTreeWidget (0x0x7f884ef67068)
+ QAbstractItemView (0x0x7f884ef67c30) 0
+ primary-for QTreeView (0x0x7f884ef67bc8)
+ QAbstractScrollArea (0x0x7f884ef88958) 0
+ primary-for QAbstractItemView (0x0x7f884ef67c30)
+ QFrame (0x0x7f884ef889c0) 0
+ primary-for QAbstractScrollArea (0x0x7f884ef88958)
+ QWidget (0x0x7f88528387e0) 0
+ primary-for QFrame (0x0x7f884ef889c0)
+ QObject (0x0x7f884d0f3ea0) 0
+ primary-for QWidget (0x0x7f88528387e0)
+ QPaintDevice (0x0x7f884d11aa80) 16
+ vptr=((& QTreeWidget::_ZTV11QTreeWidget) + 832u)
+
+Class QUndoGroup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QUndoGroup::QPrivateSignal (0x0x7f884ceeb660) 0 empty
+
+Vtable for QUndoGroup
+QUndoGroup::_ZTV10QUndoGroup: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QUndoGroup)
+16 (int (*)(...))QUndoGroup::metaObject
+24 (int (*)(...))QUndoGroup::qt_metacast
+32 (int (*)(...))QUndoGroup::qt_metacall
+40 (int (*)(...))QUndoGroup::~QUndoGroup
+48 (int (*)(...))QUndoGroup::~QUndoGroup
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QUndoGroup
+ size=16 align=8
+ base size=16 base align=8
+QUndoGroup (0x0x7f884ef88a90) 0
+ vptr=((& QUndoGroup::_ZTV10QUndoGroup) + 16u)
+ QObject (0x0x7f884ceeb600) 0
+ primary-for QUndoGroup (0x0x7f884ef88a90)
+
+Vtable for QUndoCommand
+QUndoCommand::_ZTV12QUndoCommand: 8u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QUndoCommand)
+16 (int (*)(...))QUndoCommand::~QUndoCommand
+24 (int (*)(...))QUndoCommand::~QUndoCommand
+32 (int (*)(...))QUndoCommand::undo
+40 (int (*)(...))QUndoCommand::redo
+48 (int (*)(...))QUndoCommand::id
+56 (int (*)(...))QUndoCommand::mergeWith
+
+Class QUndoCommand
+ size=16 align=8
+ base size=16 base align=8
+QUndoCommand (0x0x7f884cf40180) 0
+ vptr=((& QUndoCommand::_ZTV12QUndoCommand) + 16u)
+
+Class QUndoStack::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QUndoStack::QPrivateSignal (0x0x7f884cf40d80) 0 empty
+
+Vtable for QUndoStack
+QUndoStack::_ZTV10QUndoStack: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QUndoStack)
+16 (int (*)(...))QUndoStack::metaObject
+24 (int (*)(...))QUndoStack::qt_metacast
+32 (int (*)(...))QUndoStack::qt_metacall
+40 (int (*)(...))QUndoStack::~QUndoStack
+48 (int (*)(...))QUndoStack::~QUndoStack
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QUndoStack
+ size=16 align=8
+ base size=16 base align=8
+QUndoStack (0x0x7f884ed18270) 0
+ vptr=((& QUndoStack::_ZTV10QUndoStack) + 16u)
+ QObject (0x0x7f884cf401e0) 0
+ primary-for QUndoStack (0x0x7f884ed18270)
+
+Class QUndoView::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QUndoView::QPrivateSignal (0x0x7f884cf92ba0) 0 empty
+
+Vtable for QUndoView
+QUndoView::_ZTV9QUndoView: 106u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QUndoView)
+16 (int (*)(...))QUndoView::metaObject
+24 (int (*)(...))QUndoView::qt_metacast
+32 (int (*)(...))QUndoView::qt_metacall
+40 (int (*)(...))QUndoView::~QUndoView
+48 (int (*)(...))QUndoView::~QUndoView
+56 (int (*)(...))QListView::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QListView::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractScrollArea::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractItemView::mousePressEvent
+176 (int (*)(...))QListView::mouseReleaseEvent
+184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent
+192 (int (*)(...))QListView::mouseMoveEvent
+200 (int (*)(...))QListView::wheelEvent
+208 (int (*)(...))QAbstractItemView::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QAbstractItemView::focusInEvent
+232 (int (*)(...))QAbstractItemView::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QListView::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QListView::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QAbstractScrollArea::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QAbstractItemView::dragEnterEvent
+320 (int (*)(...))QListView::dragMoveEvent
+328 (int (*)(...))QListView::dragLeaveEvent
+336 (int (*)(...))QListView::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QAbstractItemView::inputMethodEvent
+416 (int (*)(...))QAbstractItemView::inputMethodQuery
+424 (int (*)(...))QAbstractItemView::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QAbstractItemView::viewportEvent
+448 (int (*)(...))QListView::scrollContentsBy
+456 (int (*)(...))QListView::viewportSizeHint
+464 (int (*)(...))QAbstractItemView::setModel
+472 (int (*)(...))QAbstractItemView::setSelectionModel
+480 (int (*)(...))QAbstractItemView::keyboardSearch
+488 (int (*)(...))QListView::visualRect
+496 (int (*)(...))QListView::scrollTo
+504 (int (*)(...))QListView::indexAt
+512 (int (*)(...))QAbstractItemView::sizeHintForRow
+520 (int (*)(...))QAbstractItemView::sizeHintForColumn
+528 (int (*)(...))QListView::reset
+536 (int (*)(...))QListView::setRootIndex
+544 (int (*)(...))QListView::doItemsLayout
+552 (int (*)(...))QAbstractItemView::selectAll
+560 (int (*)(...))QListView::dataChanged
+568 (int (*)(...))QListView::rowsInserted
+576 (int (*)(...))QListView::rowsAboutToBeRemoved
+584 (int (*)(...))QListView::selectionChanged
+592 (int (*)(...))QListView::currentChanged
+600 (int (*)(...))QAbstractItemView::updateEditorData
+608 (int (*)(...))QAbstractItemView::updateEditorGeometries
+616 (int (*)(...))QListView::updateGeometries
+624 (int (*)(...))QAbstractItemView::verticalScrollbarAction
+632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction
+640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged
+648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged
+656 (int (*)(...))QAbstractItemView::closeEditor
+664 (int (*)(...))QAbstractItemView::commitData
+672 (int (*)(...))QAbstractItemView::editorDestroyed
+680 (int (*)(...))QListView::moveCursor
+688 (int (*)(...))QListView::horizontalOffset
+696 (int (*)(...))QListView::verticalOffset
+704 (int (*)(...))QListView::isIndexHidden
+712 (int (*)(...))QListView::setSelection
+720 (int (*)(...))QListView::visualRegionForSelection
+728 (int (*)(...))QListView::selectedIndexes
+736 (int (*)(...))QAbstractItemView::edit
+744 (int (*)(...))QAbstractItemView::selectionCommand
+752 (int (*)(...))QListView::startDrag
+760 (int (*)(...))QListView::viewOptions
+768 (int (*)(...))-16
+776 (int (*)(...))(& _ZTI9QUndoView)
+784 (int (*)(...))QUndoView::_ZThn16_N9QUndoViewD1Ev
+792 (int (*)(...))QUndoView::_ZThn16_N9QUndoViewD0Ev
+800 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+808 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+816 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+832 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+840 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QUndoView
+ size=48 align=8
+ base size=48 base align=8
+QUndoView (0x0x7f884ed182d8) 0
+ vptr=((& QUndoView::_ZTV9QUndoView) + 16u)
+ QListView (0x0x7f884ed18af8) 0
+ primary-for QUndoView (0x0x7f884ed182d8)
+ QAbstractItemView (0x0x7f884eb1a4e0) 0
+ primary-for QListView (0x0x7f884ed18af8)
+ QAbstractScrollArea (0x0x7f884eb1a750) 0
+ primary-for QAbstractItemView (0x0x7f884eb1a4e0)
+ QFrame (0x0x7f884eb1a7b8) 0
+ primary-for QAbstractScrollArea (0x0x7f884eb1a750)
+ QWidget (0x0x7f88524b7cb0) 0
+ primary-for QFrame (0x0x7f884eb1a7b8)
+ QObject (0x0x7f884cf40de0) 0
+ primary-for QWidget (0x0x7f88524b7cb0)
+ QPaintDevice (0x0x7f884cf92b40) 16
+ vptr=((& QUndoView::_ZTV9QUndoView) + 784u)
+
+Class QWhatsThis
+ size=1 align=1
+ base size=0 base align=1
+QWhatsThis (0x0x7f884cf92f60) 0 empty
+
+Class QWidgetAction::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QWidgetAction::QPrivateSignal (0x0x7f884cbf1300) 0 empty
+
+Vtable for QWidgetAction
+QWidgetAction::_ZTV13QWidgetAction: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QWidgetAction)
+16 (int (*)(...))QWidgetAction::metaObject
+24 (int (*)(...))QWidgetAction::qt_metacast
+32 (int (*)(...))QWidgetAction::qt_metacall
+40 (int (*)(...))QWidgetAction::~QWidgetAction
+48 (int (*)(...))QWidgetAction::~QWidgetAction
+56 (int (*)(...))QWidgetAction::event
+64 (int (*)(...))QWidgetAction::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidgetAction::createWidget
+120 (int (*)(...))QWidgetAction::deleteWidget
+
+Class QWidgetAction
+ size=16 align=8
+ base size=16 base align=8
+QWidgetAction (0x0x7f884e946208) 0
+ vptr=((& QWidgetAction::_ZTV13QWidgetAction) + 16u)
+ QAction (0x0x7f884e946270) 0
+ primary-for QWidgetAction (0x0x7f884e946208)
+ QObject (0x0x7f884cbf1000) 0
+ primary-for QAction (0x0x7f884e946270)
+
+Class QWizard::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QWizard::QPrivateSignal (0x0x7f884cbf1540) 0 empty
+
+Vtable for QWizard
+QWizard::_ZTV7QWizard: 73u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QWizard)
+16 (int (*)(...))QWizard::metaObject
+24 (int (*)(...))QWizard::qt_metacast
+32 (int (*)(...))QWizard::qt_metacall
+40 (int (*)(...))QWizard::~QWizard
+48 (int (*)(...))QWizard::~QWizard
+56 (int (*)(...))QWizard::event
+64 (int (*)(...))QDialog::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWizard::setVisible
+128 (int (*)(...))QWizard::sizeHint
+136 (int (*)(...))QDialog::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QDialog::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWizard::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWizard::resizeEvent
+280 (int (*)(...))QDialog::closeEvent
+288 (int (*)(...))QDialog::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QDialog::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QDialog::open
+440 (int (*)(...))QDialog::exec
+448 (int (*)(...))QWizard::done
+456 (int (*)(...))QDialog::accept
+464 (int (*)(...))QDialog::reject
+472 (int (*)(...))QWizard::validateCurrentPage
+480 (int (*)(...))QWizard::nextId
+488 (int (*)(...))QWizard::initializePage
+496 (int (*)(...))QWizard::cleanupPage
+504 (int (*)(...))-16
+512 (int (*)(...))(& _ZTI7QWizard)
+520 (int (*)(...))QWizard::_ZThn16_N7QWizardD1Ev
+528 (int (*)(...))QWizard::_ZThn16_N7QWizardD0Ev
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+552 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+560 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+568 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+576 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QWizard
+ size=48 align=8
+ base size=48 base align=8
+QWizard (0x0x7f884e946e38) 0
+ vptr=((& QWizard::_ZTV7QWizard) + 16u)
+ QDialog (0x0x7f884e946ea0) 0
+ primary-for QWizard (0x0x7f884e946e38)
+ QWidget (0x0x7f88524ef690) 0
+ primary-for QDialog (0x0x7f884e946ea0)
+ QObject (0x0x7f884cbf1360) 0
+ primary-for QWidget (0x0x7f88524ef690)
+ QPaintDevice (0x0x7f884cbf14e0) 16
+ vptr=((& QWizard::_ZTV7QWizard) + 520u)
+
+Class QWizardPage::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QWizardPage::QPrivateSignal (0x0x7f884cc18000) 0 empty
+
+Vtable for QWizardPage
+QWizardPage::_ZTV11QWizardPage: 69u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QWizardPage)
+16 (int (*)(...))QWizardPage::metaObject
+24 (int (*)(...))QWizardPage::qt_metacast
+32 (int (*)(...))QWizardPage::qt_metacall
+40 (int (*)(...))QWizardPage::~QWizardPage
+48 (int (*)(...))QWizardPage::~QWizardPage
+56 (int (*)(...))QWidget::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QWizardPage::initializePage
+440 (int (*)(...))QWizardPage::cleanupPage
+448 (int (*)(...))QWizardPage::validatePage
+456 (int (*)(...))QWizardPage::isComplete
+464 (int (*)(...))QWizardPage::nextId
+472 (int (*)(...))-16
+480 (int (*)(...))(& _ZTI11QWizardPage)
+488 (int (*)(...))QWizardPage::_ZThn16_N11QWizardPageD1Ev
+496 (int (*)(...))QWizardPage::_ZThn16_N11QWizardPageD0Ev
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QWizardPage
+ size=48 align=8
+ base size=48 base align=8
+QWizardPage (0x0x7f884e967e38) 0
+ vptr=((& QWizardPage::_ZTV11QWizardPage) + 16u)
+ QWidget (0x0x7f88525374d0) 0
+ primary-for QWizardPage (0x0x7f884e967e38)
+ QObject (0x0x7f884cbf1840) 0
+ primary-for QWidget (0x0x7f88525374d0)
+ QPaintDevice (0x0x7f884cbf1f60) 16
+ vptr=((& QWizardPage::_ZTV11QWizardPage) + 488u)
+
diff --git a/tests/auto/bic/data/QtQuickWidgets.5.10.0.linux-gcc-amd64.txt b/tests/auto/bic/data/QtQuickWidgets.5.10.0.linux-gcc-amd64.txt
new file mode 100644
index 0000000000..700faa270e
--- /dev/null
+++ b/tests/auto/bic/data/QtQuickWidgets.5.10.0.linux-gcc-amd64.txt
@@ -0,0 +1,21831 @@
+Class std::__failure_type
+ size=1 align=1
+ base size=0 base align=1
+std::__failure_type (0x0x7f21b6846240) 0 empty
+
+Class std::__do_is_destructible_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_is_destructible_impl (0x0x7f21b688d9c0) 0 empty
+
+Class std::__do_is_nt_destructible_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_is_nt_destructible_impl (0x0x7f21b688dc00) 0 empty
+
+Class std::__do_is_default_constructible_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_is_default_constructible_impl (0x0x7f21b688de40) 0 empty
+
+Class std::__do_is_static_castable_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_is_static_castable_impl (0x0x7f21b68b70c0) 0 empty
+
+Class std::__do_is_direct_constructible_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_is_direct_constructible_impl (0x0x7f21b68b7240) 0 empty
+
+Class std::__do_is_nary_constructible_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_is_nary_constructible_impl (0x0x7f21b68b7600) 0 empty
+
+Class std::__do_common_type_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__do_common_type_impl (0x0x7f21b6443d80) 0 empty
+
+Class std::__do_member_type_wrapper
+ size=1 align=1
+ base size=0 base align=1
+std::__do_member_type_wrapper (0x0x7f21b6443e40) 0 empty
+
+Class std::__result_of_memfun_ref_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__result_of_memfun_ref_impl (0x0x7f21b64711e0) 0 empty
+
+Class std::__result_of_memfun_deref_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__result_of_memfun_deref_impl (0x0x7f21b64712a0) 0 empty
+
+Class std::__result_of_memobj_ref_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__result_of_memobj_ref_impl (0x0x7f21b6471360) 0 empty
+
+Class std::__result_of_memobj_deref_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__result_of_memobj_deref_impl (0x0x7f21b6471420) 0 empty
+
+Class std::__result_of_other_impl
+ size=1 align=1
+ base size=0 base align=1
+std::__result_of_other_impl (0x0x7f21b64716c0) 0 empty
+
+Class std::piecewise_construct_t
+ size=1 align=1
+ base size=0 base align=1
+std::piecewise_construct_t (0x0x7f21b64718a0) 0 empty
+
+Class std::__true_type
+ size=1 align=1
+ base size=0 base align=1
+std::__true_type (0x0x7f21b6471d20) 0 empty
+
+Class std::__false_type
+ size=1 align=1
+ base size=0 base align=1
+std::__false_type (0x0x7f21b6471d80) 0 empty
+
+Class std::input_iterator_tag
+ size=1 align=1
+ base size=0 base align=1
+std::input_iterator_tag (0x0x7f21b652aa20) 0 empty
+
+Class std::output_iterator_tag
+ size=1 align=1
+ base size=0 base align=1
+std::output_iterator_tag (0x0x7f21b652aa80) 0 empty
+
+Class std::forward_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::forward_iterator_tag (0x0x7f21b64923a8) 0 empty
+ std::input_iterator_tag (0x0x7f21b652aae0) 0 empty
+
+Class std::bidirectional_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::bidirectional_iterator_tag (0x0x7f21b6492410) 0 empty
+ std::forward_iterator_tag (0x0x7f21b6492478) 0 empty
+ std::input_iterator_tag (0x0x7f21b652ab40) 0 empty
+
+Class std::random_access_iterator_tag
+ size=1 align=1
+ base size=1 base align=1
+std::random_access_iterator_tag (0x0x7f21b64924e0) 0 empty
+ std::bidirectional_iterator_tag (0x0x7f21b6492548) 0 empty
+ std::forward_iterator_tag (0x0x7f21b64925b0) 0 empty
+ std::input_iterator_tag (0x0x7f21b652aba0) 0 empty
+
+Class __gnu_cxx::__ops::_Iter_less_iter
+ size=1 align=1
+ base size=0 base align=1
+__gnu_cxx::__ops::_Iter_less_iter (0x0x7f21b6564840) 0 empty
+
+Class __gnu_cxx::__ops::_Iter_less_val
+ size=1 align=1
+ base size=0 base align=1
+__gnu_cxx::__ops::_Iter_less_val (0x0x7f21b65648a0) 0 empty
+
+Class __gnu_cxx::__ops::_Val_less_iter
+ size=1 align=1
+ base size=0 base align=1
+__gnu_cxx::__ops::_Val_less_iter (0x0x7f21b6564900) 0 empty
+
+Class __gnu_cxx::__ops::_Iter_equal_to_iter
+ size=1 align=1
+ base size=0 base align=1
+__gnu_cxx::__ops::_Iter_equal_to_iter (0x0x7f21b6564960) 0 empty
+
+Class __gnu_cxx::__ops::_Iter_equal_to_val
+ size=1 align=1
+ base size=0 base align=1
+__gnu_cxx::__ops::_Iter_equal_to_val (0x0x7f21b65649c0) 0 empty
+
+Class wait
+ size=4 align=4
+ base size=4 base align=4
+wait (0x0x7f21b66414e0) 0
+
+Class __locale_struct
+ size=232 align=8
+ base size=232 base align=8
+__locale_struct (0x0x7f21b6641720) 0
+
+Class timespec
+ size=16 align=8
+ base size=16 base align=8
+timespec (0x0x7f21b66417e0) 0
+
+Class timeval
+ size=16 align=8
+ base size=16 base align=8
+timeval (0x0x7f21b6641840) 0
+
+Class pthread_attr_t
+ size=56 align=8
+ base size=56 base align=8
+pthread_attr_t (0x0x7f21b6641900) 0
+
+Class __pthread_internal_list
+ size=16 align=8
+ base size=16 base align=8
+__pthread_internal_list (0x0x7f21b6641960) 0
+
+Class random_data
+ size=48 align=8
+ base size=48 base align=8
+random_data (0x0x7f21b6641de0) 0
+
+Class drand48_data
+ size=24 align=8
+ base size=24 base align=8
+drand48_data (0x0x7f21b6641e40) 0
+
+Vtable for std::exception
+std::exception::_ZTVSt9exception: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt9exception)
+16 (int (*)(...))std::exception::~exception
+24 (int (*)(...))std::exception::~exception
+32 (int (*)(...))std::exception::what
+
+Class std::exception
+ size=8 align=8
+ base size=8 base align=8
+std::exception (0x0x7f21b6641ea0) 0 nearly-empty
+ vptr=((& std::exception::_ZTVSt9exception) + 16u)
+
+Vtable for std::bad_exception
+std::bad_exception::_ZTVSt13bad_exception: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt13bad_exception)
+16 (int (*)(...))std::bad_exception::~bad_exception
+24 (int (*)(...))std::bad_exception::~bad_exception
+32 (int (*)(...))std::bad_exception::what
+
+Class std::bad_exception
+ size=8 align=8
+ base size=8 base align=8
+std::bad_exception (0x0x7f21b6492af8) 0 nearly-empty
+ vptr=((& std::bad_exception::_ZTVSt13bad_exception) + 16u)
+ std::exception (0x0x7f21b6641f00) 0 nearly-empty
+ primary-for std::bad_exception (0x0x7f21b6492af8)
+
+Class std::__exception_ptr::exception_ptr
+ size=8 align=8
+ base size=8 base align=8
+std::__exception_ptr::exception_ptr (0x0x7f21b6641f60) 0
+
+Vtable for std::nested_exception
+std::nested_exception::_ZTVSt16nested_exception: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt16nested_exception)
+16 (int (*)(...))std::nested_exception::~nested_exception
+24 (int (*)(...))std::nested_exception::~nested_exception
+
+Class std::nested_exception
+ size=16 align=8
+ base size=16 base align=8
+std::nested_exception (0x0x7f21b6398000) 0
+ vptr=((& std::nested_exception::_ZTVSt16nested_exception) + 16u)
+
+Vtable for std::bad_alloc
+std::bad_alloc::_ZTVSt9bad_alloc: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt9bad_alloc)
+16 (int (*)(...))std::bad_alloc::~bad_alloc
+24 (int (*)(...))std::bad_alloc::~bad_alloc
+32 (int (*)(...))std::bad_alloc::what
+
+Class std::bad_alloc
+ size=8 align=8
+ base size=8 base align=8
+std::bad_alloc (0x0x7f21b6492d00) 0 nearly-empty
+ vptr=((& std::bad_alloc::_ZTVSt9bad_alloc) + 16u)
+ std::exception (0x0x7f21b6398420) 0 nearly-empty
+ primary-for std::bad_alloc (0x0x7f21b6492d00)
+
+Vtable for std::bad_array_new_length
+std::bad_array_new_length::_ZTVSt20bad_array_new_length: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt20bad_array_new_length)
+16 (int (*)(...))std::bad_array_new_length::~bad_array_new_length
+24 (int (*)(...))std::bad_array_new_length::~bad_array_new_length
+32 (int (*)(...))std::bad_array_new_length::what
+
+Class std::bad_array_new_length
+ size=8 align=8
+ base size=8 base align=8
+std::bad_array_new_length (0x0x7f21b6492d68) 0 nearly-empty
+ vptr=((& std::bad_array_new_length::_ZTVSt20bad_array_new_length) + 16u)
+ std::bad_alloc (0x0x7f21b6492dd0) 0 nearly-empty
+ primary-for std::bad_array_new_length (0x0x7f21b6492d68)
+ std::exception (0x0x7f21b6398480) 0 nearly-empty
+ primary-for std::bad_alloc (0x0x7f21b6492dd0)
+
+Class std::nothrow_t
+ size=1 align=1
+ base size=0 base align=1
+std::nothrow_t (0x0x7f21b63984e0) 0 empty
+
+Class __exception
+ size=40 align=8
+ base size=40 base align=8
+__exception (0x0x7f21b6057120) 0
+
+Class lconv
+ size=96 align=8
+ base size=96 base align=8
+lconv (0x0x7f21b6057de0) 0
+
+Vtable for __cxxabiv1::__forced_unwind
+__cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN10__cxxabiv115__forced_unwindE)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class __cxxabiv1::__forced_unwind
+ size=8 align=8
+ base size=8 base align=8
+__cxxabiv1::__forced_unwind (0x0x7f21b6057e40) 0 nearly-empty
+ vptr=((& __cxxabiv1::__forced_unwind::_ZTVN10__cxxabiv115__forced_unwindE) + 16u)
+
+Class sched_param
+ size=4 align=4
+ base size=4 base align=4
+sched_param (0x0x7f21b5e99d20) 0
+
+Class __sched_param
+ size=4 align=4
+ base size=4 base align=4
+__sched_param (0x0x7f21b5e99d80) 0
+
+Class timex
+ size=208 align=8
+ base size=208 base align=8
+timex (0x0x7f21b5e99e40) 0
+
+Class tm
+ size=56 align=8
+ base size=56 base align=8
+tm (0x0x7f21b5e99ea0) 0
+
+Class itimerspec
+ size=32 align=8
+ base size=32 base align=8
+itimerspec (0x0x7f21b5e99f00) 0
+
+Class _pthread_cleanup_buffer
+ size=32 align=8
+ base size=32 base align=8
+_pthread_cleanup_buffer (0x0x7f21b5e99f60) 0
+
+Class __pthread_cleanup_frame
+ size=24 align=8
+ base size=24 base align=8
+__pthread_cleanup_frame (0x0x7f21b5f460c0) 0
+
+Class __pthread_cleanup_class
+ size=24 align=8
+ base size=24 base align=8
+__pthread_cleanup_class (0x0x7f21b5f46120) 0
+
+Class _IO_marker
+ size=24 align=8
+ base size=24 base align=8
+_IO_marker (0x0x7f21b5f46540) 0
+
+Class _IO_FILE
+ size=216 align=8
+ base size=216 base align=8
+_IO_FILE (0x0x7f21b5f465a0) 0
+
+Class std::_Hash_impl
+ size=1 align=1
+ base size=0 base align=1
+std::_Hash_impl (0x0x7f21b5d66d80) 0 empty
+
+Class std::_Fnv_hash_impl
+ size=1 align=1
+ base size=0 base align=1
+std::_Fnv_hash_impl (0x0x7f21b5d66de0) 0 empty
+
+Class std::__numeric_limits_base
+ size=1 align=1
+ base size=0 base align=1
+std::__numeric_limits_base (0x0x7f21b5e29d80) 0 empty
+
+Class std::_Bit_reference
+ size=16 align=8
+ base size=16 base align=8
+std::_Bit_reference (0x0x7f21b5bd2ba0) 0
+
+Class std::_Bit_iterator_base
+ size=16 align=8
+ base size=12 base align=8
+std::_Bit_iterator_base (0x0x7f21b5e2db60) 0
+ std::iterator<std::random_access_iterator_tag, bool> (0x0x7f21b5bd2c60) 0 empty
+
+Class std::_Bit_iterator
+ size=16 align=8
+ base size=12 base align=8
+std::_Bit_iterator (0x0x7f21b5e2dbc8) 0
+ std::_Bit_iterator_base (0x0x7f21b5e2dc30) 0
+ std::iterator<std::random_access_iterator_tag, bool> (0x0x7f21b5bd2cc0) 0 empty
+
+Class std::_Bit_const_iterator
+ size=16 align=8
+ base size=12 base align=8
+std::_Bit_const_iterator (0x0x7f21b5e2dc98) 0
+ std::_Bit_iterator_base (0x0x7f21b5e2dd00) 0
+ std::iterator<std::random_access_iterator_tag, bool> (0x0x7f21b5bd2d20) 0 empty
+
+Class std::random_device
+ size=5000 align=8
+ base size=5000 base align=8
+std::random_device (0x0x7f21b59b7b40) 0
+
+Class std::bernoulli_distribution::param_type
+ size=8 align=8
+ base size=8 base align=8
+std::bernoulli_distribution::param_type (0x0x7f21b56e4900) 0
+
+Class std::bernoulli_distribution
+ size=8 align=8
+ base size=8 base align=8
+std::bernoulli_distribution (0x0x7f21b56e48a0) 0
+
+Class std::seed_seq
+ size=24 align=8
+ base size=24 base align=8
+std::seed_seq (0x0x7f21b54878a0) 0
+
+Class qIsNull(double)::U
+ size=8 align=8
+ base size=8 base align=8
+qIsNull(double)::U (0x0x7f21b40433c0) 0
+
+Class qIsNull(float)::U
+ size=4 align=4
+ base size=4 base align=4
+qIsNull(float)::U (0x0x7f21b4043420) 0
+
+Class QSysInfo
+ size=1 align=1
+ base size=0 base align=1
+QSysInfo (0x0x7f21b40e8ea0) 0 empty
+
+Class QMessageLogContext
+ size=32 align=8
+ base size=32 base align=8
+QMessageLogContext (0x0x7f21b40e8f00) 0
+
+Class QMessageLogger
+ size=32 align=8
+ base size=32 base align=8
+QMessageLogger (0x0x7f21b40e8f60) 0
+
+Class QFlag
+ size=4 align=4
+ base size=4 base align=4
+QFlag (0x0x7f21b4145000) 0
+
+Class QIncompatibleFlag
+ size=4 align=4
+ base size=4 base align=4
+QIncompatibleFlag (0x0x7f21b41452a0) 0
+
+Class std::__atomic_flag_base
+ size=1 align=1
+ base size=1 base align=1
+std::__atomic_flag_base (0x0x7f21b41457e0) 0
+
+Class std::atomic_flag
+ size=1 align=1
+ base size=1 base align=1
+std::atomic_flag (0x0x7f21b40f9a28) 0
+ std::__atomic_flag_base (0x0x7f21b4145840) 0
+
+Class QAtomicInt
+ size=4 align=4
+ base size=4 base align=4
+QAtomicInt (0x0x7f21b3c681a0) 0
+ QAtomicInteger<int> (0x0x7f21b3c68208) 0
+ QBasicAtomicInteger<int> (0x0x7f21b3ecdf60) 0
+
+Class QInternal
+ size=1 align=1
+ base size=0 base align=1
+QInternal (0x0x7f21b3baf540) 0 empty
+
+Class QtPrivate::QSlotObjectBase
+ size=16 align=8
+ base size=16 base align=8
+QtPrivate::QSlotObjectBase (0x0x7f21b39a15a0) 0
+
+Class QGenericArgument
+ size=16 align=8
+ base size=16 base align=8
+QGenericArgument (0x0x7f21b39a16c0) 0
+
+Class QGenericReturnArgument
+ size=16 align=8
+ base size=16 base align=8
+QGenericReturnArgument (0x0x7f21b3b27c30) 0
+ QGenericArgument (0x0x7f21b39a1720) 0
+
+Class QMetaObject
+ size=48 align=8
+ base size=48 base align=8
+QMetaObject (0x0x7f21b39a18a0) 0
+
+Class QMetaObject::Connection
+ size=8 align=8
+ base size=8 base align=8
+QMetaObject::Connection (0x0x7f21b39a1960) 0
+
+Class QLatin1Char
+ size=1 align=1
+ base size=1 base align=1
+QLatin1Char (0x0x7f21b36499c0) 0
+
+Class QChar
+ size=2 align=2
+ base size=2 base align=2
+QChar (0x0x7f21b3649a20) 0
+
+Class QtPrivate::RefCount
+ size=4 align=4
+ base size=4 base align=4
+QtPrivate::RefCount (0x0x7f21b3649cc0) 0
+
+Class QArrayData
+ size=24 align=8
+ base size=24 base align=8
+QArrayData (0x0x7f21b3649d20) 0
+
+Class QtPrivate::QContainerImplHelper
+ size=1 align=1
+ base size=0 base align=1
+QtPrivate::QContainerImplHelper (0x0x7f21b376e0c0) 0 empty
+
+Class std::locale
+ size=8 align=8
+ base size=8 base align=8
+std::locale (0x0x7f21b376e120) 0
+
+Vtable for std::locale::facet
+std::locale::facet::_ZTVNSt6locale5facetE: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt6locale5facetE)
+16 (int (*)(...))std::locale::facet::~facet
+24 (int (*)(...))std::locale::facet::~facet
+
+Class std::locale::facet
+ size=16 align=8
+ base size=12 base align=8
+std::locale::facet (0x0x7f21b376e180) 0
+ vptr=((& std::locale::facet::_ZTVNSt6locale5facetE) + 16u)
+
+Class std::locale::id
+ size=8 align=8
+ base size=8 base align=8
+std::locale::id (0x0x7f21b376e1e0) 0
+
+Class std::locale::_Impl
+ size=40 align=8
+ base size=40 base align=8
+std::locale::_Impl (0x0x7f21b376e240) 0
+
+Class std::__cow_string
+ size=8 align=8
+ base size=8 base align=8
+std::__cow_string (0x0x7f21b376e600) 0
+
+Vtable for std::logic_error
+std::logic_error::_ZTVSt11logic_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt11logic_error)
+16 (int (*)(...))std::logic_error::~logic_error
+24 (int (*)(...))std::logic_error::~logic_error
+32 (int (*)(...))std::logic_error::what
+
+Class std::logic_error
+ size=16 align=8
+ base size=16 base align=8
+std::logic_error (0x0x7f21b37e8208) 0
+ vptr=((& std::logic_error::_ZTVSt11logic_error) + 16u)
+ std::exception (0x0x7f21b376e6c0) 0 nearly-empty
+ primary-for std::logic_error (0x0x7f21b37e8208)
+
+Vtable for std::domain_error
+std::domain_error::_ZTVSt12domain_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt12domain_error)
+16 (int (*)(...))std::domain_error::~domain_error
+24 (int (*)(...))std::domain_error::~domain_error
+32 (int (*)(...))std::logic_error::what
+
+Class std::domain_error
+ size=16 align=8
+ base size=16 base align=8
+std::domain_error (0x0x7f21b37e8270) 0
+ vptr=((& std::domain_error::_ZTVSt12domain_error) + 16u)
+ std::logic_error (0x0x7f21b37e82d8) 0
+ primary-for std::domain_error (0x0x7f21b37e8270)
+ std::exception (0x0x7f21b376e720) 0 nearly-empty
+ primary-for std::logic_error (0x0x7f21b37e82d8)
+
+Vtable for std::invalid_argument
+std::invalid_argument::_ZTVSt16invalid_argument: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt16invalid_argument)
+16 (int (*)(...))std::invalid_argument::~invalid_argument
+24 (int (*)(...))std::invalid_argument::~invalid_argument
+32 (int (*)(...))std::logic_error::what
+
+Class std::invalid_argument
+ size=16 align=8
+ base size=16 base align=8
+std::invalid_argument (0x0x7f21b37e8340) 0
+ vptr=((& std::invalid_argument::_ZTVSt16invalid_argument) + 16u)
+ std::logic_error (0x0x7f21b37e83a8) 0
+ primary-for std::invalid_argument (0x0x7f21b37e8340)
+ std::exception (0x0x7f21b376e780) 0 nearly-empty
+ primary-for std::logic_error (0x0x7f21b37e83a8)
+
+Vtable for std::length_error
+std::length_error::_ZTVSt12length_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt12length_error)
+16 (int (*)(...))std::length_error::~length_error
+24 (int (*)(...))std::length_error::~length_error
+32 (int (*)(...))std::logic_error::what
+
+Class std::length_error
+ size=16 align=8
+ base size=16 base align=8
+std::length_error (0x0x7f21b37e8410) 0
+ vptr=((& std::length_error::_ZTVSt12length_error) + 16u)
+ std::logic_error (0x0x7f21b37e8478) 0
+ primary-for std::length_error (0x0x7f21b37e8410)
+ std::exception (0x0x7f21b376e7e0) 0 nearly-empty
+ primary-for std::logic_error (0x0x7f21b37e8478)
+
+Vtable for std::out_of_range
+std::out_of_range::_ZTVSt12out_of_range: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt12out_of_range)
+16 (int (*)(...))std::out_of_range::~out_of_range
+24 (int (*)(...))std::out_of_range::~out_of_range
+32 (int (*)(...))std::logic_error::what
+
+Class std::out_of_range
+ size=16 align=8
+ base size=16 base align=8
+std::out_of_range (0x0x7f21b37e84e0) 0
+ vptr=((& std::out_of_range::_ZTVSt12out_of_range) + 16u)
+ std::logic_error (0x0x7f21b37e8548) 0
+ primary-for std::out_of_range (0x0x7f21b37e84e0)
+ std::exception (0x0x7f21b376e840) 0 nearly-empty
+ primary-for std::logic_error (0x0x7f21b37e8548)
+
+Vtable for std::runtime_error
+std::runtime_error::_ZTVSt13runtime_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt13runtime_error)
+16 (int (*)(...))std::runtime_error::~runtime_error
+24 (int (*)(...))std::runtime_error::~runtime_error
+32 (int (*)(...))std::runtime_error::what
+
+Class std::runtime_error
+ size=16 align=8
+ base size=16 base align=8
+std::runtime_error (0x0x7f21b37e85b0) 0
+ vptr=((& std::runtime_error::_ZTVSt13runtime_error) + 16u)
+ std::exception (0x0x7f21b376e8a0) 0 nearly-empty
+ primary-for std::runtime_error (0x0x7f21b37e85b0)
+
+Vtable for std::range_error
+std::range_error::_ZTVSt11range_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt11range_error)
+16 (int (*)(...))std::range_error::~range_error
+24 (int (*)(...))std::range_error::~range_error
+32 (int (*)(...))std::runtime_error::what
+
+Class std::range_error
+ size=16 align=8
+ base size=16 base align=8
+std::range_error (0x0x7f21b37e8618) 0
+ vptr=((& std::range_error::_ZTVSt11range_error) + 16u)
+ std::runtime_error (0x0x7f21b37e8680) 0
+ primary-for std::range_error (0x0x7f21b37e8618)
+ std::exception (0x0x7f21b376e900) 0 nearly-empty
+ primary-for std::runtime_error (0x0x7f21b37e8680)
+
+Vtable for std::overflow_error
+std::overflow_error::_ZTVSt14overflow_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt14overflow_error)
+16 (int (*)(...))std::overflow_error::~overflow_error
+24 (int (*)(...))std::overflow_error::~overflow_error
+32 (int (*)(...))std::runtime_error::what
+
+Class std::overflow_error
+ size=16 align=8
+ base size=16 base align=8
+std::overflow_error (0x0x7f21b37e86e8) 0
+ vptr=((& std::overflow_error::_ZTVSt14overflow_error) + 16u)
+ std::runtime_error (0x0x7f21b37e8750) 0
+ primary-for std::overflow_error (0x0x7f21b37e86e8)
+ std::exception (0x0x7f21b376e960) 0 nearly-empty
+ primary-for std::runtime_error (0x0x7f21b37e8750)
+
+Vtable for std::underflow_error
+std::underflow_error::_ZTVSt15underflow_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt15underflow_error)
+16 (int (*)(...))std::underflow_error::~underflow_error
+24 (int (*)(...))std::underflow_error::~underflow_error
+32 (int (*)(...))std::runtime_error::what
+
+Class std::underflow_error
+ size=16 align=8
+ base size=16 base align=8
+std::underflow_error (0x0x7f21b37e87b8) 0
+ vptr=((& std::underflow_error::_ZTVSt15underflow_error) + 16u)
+ std::runtime_error (0x0x7f21b37e8820) 0
+ primary-for std::underflow_error (0x0x7f21b37e87b8)
+ std::exception (0x0x7f21b376e9c0) 0 nearly-empty
+ primary-for std::runtime_error (0x0x7f21b37e8820)
+
+Vtable for std::_V2::error_category
+std::_V2::error_category::_ZTVNSt3_V214error_categoryE: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt3_V214error_categoryE)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))std::_V2::error_category::_M_message
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))std::_V2::error_category::default_error_condition
+64 (int (*)(...))std::_V2::error_category::equivalent
+72 (int (*)(...))std::_V2::error_category::equivalent
+
+Class std::_V2::error_category
+ size=8 align=8
+ base size=8 base align=8
+std::_V2::error_category (0x0x7f21b376eb40) 0 nearly-empty
+ vptr=((& std::_V2::error_category::_ZTVNSt3_V214error_categoryE) + 16u)
+
+Class std::error_code
+ size=16 align=8
+ base size=16 base align=8
+std::error_code (0x0x7f21b376ed80) 0
+
+Class std::error_condition
+ size=16 align=8
+ base size=16 base align=8
+std::error_condition (0x0x7f21b376ef00) 0
+
+Vtable for std::system_error
+std::system_error::_ZTVSt12system_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt12system_error)
+16 (int (*)(...))std::system_error::~system_error
+24 (int (*)(...))std::system_error::~system_error
+32 (int (*)(...))std::runtime_error::what
+
+Class std::system_error
+ size=32 align=8
+ base size=32 base align=8
+std::system_error (0x0x7f21b37e8d00) 0
+ vptr=((& std::system_error::_ZTVSt12system_error) + 16u)
+ std::runtime_error (0x0x7f21b37e8d68) 0
+ primary-for std::system_error (0x0x7f21b37e8d00)
+ std::exception (0x0x7f21b3464180) 0 nearly-empty
+ primary-for std::runtime_error (0x0x7f21b37e8d68)
+
+Vtable for std::ios_base::failure
+std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt8ios_base7failureB5cxx11E)
+16 (int (*)(...))std::ios_base::failure::~failure
+24 (int (*)(...))std::ios_base::failure::~failure
+32 (int (*)(...))std::ios_base::failure::what
+
+Class std::ios_base::failure
+ size=32 align=8
+ base size=32 base align=8
+std::ios_base::failure (0x0x7f21b34838f0) 0
+ vptr=((& std::ios_base::failure::_ZTVNSt8ios_base7failureB5cxx11E) + 16u)
+ std::system_error (0x0x7f21b3483958) 0
+ primary-for std::ios_base::failure (0x0x7f21b34838f0)
+ std::runtime_error (0x0x7f21b34839c0) 0
+ primary-for std::system_error (0x0x7f21b3483958)
+ std::exception (0x0x7f21b3464480) 0 nearly-empty
+ primary-for std::runtime_error (0x0x7f21b34839c0)
+
+Class std::ios_base::_Callback_list
+ size=24 align=8
+ base size=24 base align=8
+std::ios_base::_Callback_list (0x0x7f21b34644e0) 0
+
+Class std::ios_base::_Words
+ size=16 align=8
+ base size=16 base align=8
+std::ios_base::_Words (0x0x7f21b3464540) 0
+
+Class std::ios_base::Init
+ size=1 align=1
+ base size=0 base align=1
+std::ios_base::Init (0x0x7f21b34645a0) 0 empty
+
+Vtable for std::ios_base
+std::ios_base::_ZTVSt8ios_base: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt8ios_base)
+16 (int (*)(...))std::ios_base::~ios_base
+24 (int (*)(...))std::ios_base::~ios_base
+
+Class std::ios_base
+ size=216 align=8
+ base size=216 base align=8
+std::ios_base (0x0x7f21b3464420) 0
+ vptr=((& std::ios_base::_ZTVSt8ios_base) + 16u)
+
+Class std::ctype_base
+ size=1 align=1
+ base size=0 base align=1
+std::ctype_base (0x0x7f21b3464d20) 0 empty
+
+Class std::__num_base
+ size=1 align=1
+ base size=0 base align=1
+std::__num_base (0x0x7f21b35e2420) 0 empty
+
+VTT for std::basic_ostream<char>
+std::basic_ostream<char>::_ZTTSo: 2u entries
+0 ((& std::basic_ostream<char>::_ZTVSo) + 24u)
+8 ((& std::basic_ostream<char>::_ZTVSo) + 64u)
+
+VTT for std::basic_ostream<wchar_t>
+std::basic_ostream<wchar_t>::_ZTTSt13basic_ostreamIwSt11char_traitsIwEE: 2u entries
+0 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 24u)
+8 ((& std::basic_ostream<wchar_t>::_ZTVSt13basic_ostreamIwSt11char_traitsIwEE) + 64u)
+
+VTT for std::basic_istream<char>
+std::basic_istream<char>::_ZTTSi: 2u entries
+0 ((& std::basic_istream<char>::_ZTVSi) + 24u)
+8 ((& std::basic_istream<char>::_ZTVSi) + 64u)
+
+VTT for std::basic_istream<wchar_t>
+std::basic_istream<wchar_t>::_ZTTSt13basic_istreamIwSt11char_traitsIwEE: 2u entries
+0 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 24u)
+8 ((& std::basic_istream<wchar_t>::_ZTVSt13basic_istreamIwSt11char_traitsIwEE) + 64u)
+
+Construction vtable for std::basic_istream<char> (0x0x7f21b3144270 instance) in std::basic_iostream<char>
+std::basic_iostream<char>::_ZTCSd0_Si: 10u entries
+0 24u
+8 (int (*)(...))0
+16 (int (*)(...))(& _ZTISi)
+24 0u
+32 0u
+40 18446744073709551592u
+48 (int (*)(...))-24
+56 (int (*)(...))(& _ZTISi)
+64 0u
+72 0u
+
+Construction vtable for std::basic_ostream<char> (0x0x7f21b3144340 instance) in std::basic_iostream<char>
+std::basic_iostream<char>::_ZTCSd16_So: 10u entries
+0 8u
+8 (int (*)(...))0
+16 (int (*)(...))(& _ZTISo)
+24 0u
+32 0u
+40 18446744073709551608u
+48 (int (*)(...))-8
+56 (int (*)(...))(& _ZTISo)
+64 0u
+72 0u
+
+VTT for std::basic_iostream<char>
+std::basic_iostream<char>::_ZTTSd: 7u entries
+0 ((& std::basic_iostream<char>::_ZTVSd) + 24u)
+8 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 24u)
+16 ((& std::basic_iostream<char>::_ZTCSd0_Si) + 64u)
+24 ((& std::basic_iostream<char>::_ZTCSd16_So) + 24u)
+32 ((& std::basic_iostream<char>::_ZTCSd16_So) + 64u)
+40 ((& std::basic_iostream<char>::_ZTVSd) + 104u)
+48 ((& std::basic_iostream<char>::_ZTVSd) + 64u)
+
+Construction vtable for std::basic_istream<wchar_t> (0x0x7f21b31446e8 instance) in std::basic_iostream<wchar_t>
+std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E: 10u entries
+0 24u
+8 (int (*)(...))0
+16 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE)
+24 0u
+32 0u
+40 18446744073709551592u
+48 (int (*)(...))-24
+56 (int (*)(...))(& _ZTISt13basic_istreamIwSt11char_traitsIwEE)
+64 0u
+72 0u
+
+Construction vtable for std::basic_ostream<wchar_t> (0x0x7f21b31447b8 instance) in std::basic_iostream<wchar_t>
+std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E: 10u entries
+0 8u
+8 (int (*)(...))0
+16 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE)
+24 0u
+32 0u
+40 18446744073709551608u
+48 (int (*)(...))-8
+56 (int (*)(...))(& _ZTISt13basic_ostreamIwSt11char_traitsIwEE)
+64 0u
+72 0u
+
+VTT for std::basic_iostream<wchar_t>
+std::basic_iostream<wchar_t>::_ZTTSt14basic_iostreamIwSt11char_traitsIwEE: 7u entries
+0 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 24u)
+8 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 24u)
+16 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE0_St13basic_istreamIwS1_E) + 64u)
+24 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 24u)
+32 ((& std::basic_iostream<wchar_t>::_ZTCSt14basic_iostreamIwSt11char_traitsIwEE16_St13basic_ostreamIwS1_E) + 64u)
+40 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 104u)
+48 ((& std::basic_iostream<wchar_t>::_ZTVSt14basic_iostreamIwSt11char_traitsIwEE) + 64u)
+
+Class QByteArrayDataPtr
+ size=8 align=8
+ base size=8 base align=8
+QByteArrayDataPtr (0x0x7f21b3376c60) 0
+
+Class QByteArray
+ size=8 align=8
+ base size=8 base align=8
+QByteArray (0x0x7f21b3376cc0) 0
+
+Class QByteRef
+ size=16 align=8
+ base size=12 base align=8
+QByteRef (0x0x7f21b2ed6060) 0
+
+Class QStringDataPtr
+ size=8 align=8
+ base size=8 base align=8
+QStringDataPtr (0x0x7f21b2ed63c0) 0
+
+Class QStringView
+ size=16 align=8
+ base size=16 base align=8
+QStringView (0x0x7f21b2ed6840) 0
+
+Class QLatin1String
+ size=16 align=8
+ base size=16 base align=8
+QLatin1String (0x0x7f21b2fd06c0) 0
+
+Class QString::Null
+ size=1 align=1
+ base size=0 base align=1
+QString::Null (0x0x7f21b2fd0d20) 0 empty
+
+Class QString
+ size=8 align=8
+ base size=8 base align=8
+QString (0x0x7f21b2fd0cc0) 0
+
+Class QCharRef
+ size=16 align=8
+ base size=12 base align=8
+QCharRef (0x0x7f21b2dd5de0) 0
+
+Class QStringRef
+ size=16 align=8
+ base size=16 base align=8
+QStringRef (0x0x7f21b2ae1a20) 0
+
+Class QtPrivate::QHashCombine
+ size=1 align=1
+ base size=0 base align=1
+QtPrivate::QHashCombine (0x0x7f21b2818660) 0 empty
+
+Class QtPrivate::QHashCombineCommutative
+ size=1 align=1
+ base size=0 base align=1
+QtPrivate::QHashCombineCommutative (0x0x7f21b28186c0) 0 empty
+
+Class std::__detail::_List_node_base
+ size=16 align=8
+ base size=16 base align=8
+std::__detail::_List_node_base (0x0x7f21b2818720) 0
+
+Class QListData::NotArrayCompatibleLayout
+ size=1 align=1
+ base size=0 base align=1
+QListData::NotArrayCompatibleLayout (0x0x7f21b2818ae0) 0 empty
+
+Class QListData::NotIndirectLayout
+ size=1 align=1
+ base size=0 base align=1
+QListData::NotIndirectLayout (0x0x7f21b2818b40) 0 empty
+
+Class QListData::ArrayCompatibleLayout
+ size=1 align=1
+ base size=1 base align=1
+QListData::ArrayCompatibleLayout (0x0x7f21b2979208) 0 empty
+ QListData::NotIndirectLayout (0x0x7f21b2818ba0) 0 empty
+
+Class QListData::InlineWithPaddingLayout
+ size=1 align=1
+ base size=1 base align=1
+QListData::InlineWithPaddingLayout (0x0x7f21b2640230) 0 empty
+ QListData::NotArrayCompatibleLayout (0x0x7f21b2818c00) 0 empty
+ QListData::NotIndirectLayout (0x0x7f21b2818c60) 0 empty
+
+Class QListData::IndirectLayout
+ size=1 align=1
+ base size=1 base align=1
+QListData::IndirectLayout (0x0x7f21b2979270) 0 empty
+ QListData::NotArrayCompatibleLayout (0x0x7f21b2818cc0) 0 empty
+
+Class QListData::Data
+ size=24 align=8
+ base size=24 base align=8
+QListData::Data (0x0x7f21b2818d20) 0
+
+Class QListData
+ size=8 align=8
+ base size=8 base align=8
+QListData (0x0x7f21b2818a80) 0
+
+Class QRegExp
+ size=8 align=8
+ base size=8 base align=8
+QRegExp (0x0x7f21b271e1e0) 0
+
+Class QStringMatcher::Data
+ size=272 align=8
+ base size=272 base align=8
+QStringMatcher::Data (0x0x7f21b27f0420) 0
+
+Class QStringMatcher
+ size=1048 align=8
+ base size=1048 base align=8
+QStringMatcher (0x0x7f21b27f03c0) 0
+
+Class QStringList
+ size=8 align=8
+ base size=8 base align=8
+QStringList (0x0x7f21b27e3c98) 0
+ QList<QString> (0x0x7f21b27e3d00) 0
+ QListSpecialMethods<QString> (0x0x7f21b27f0600) 0 empty
+
+Class QScopedPointerPodDeleter
+ size=1 align=1
+ base size=0 base align=1
+QScopedPointerPodDeleter (0x0x7f21b27f0a20) 0 empty
+
+Class std::_Rb_tree_node_base
+ size=32 align=8
+ base size=32 base align=8
+std::_Rb_tree_node_base (0x0x7f21b24f2540) 0
+
+Class std::allocator_arg_t
+ size=1 align=1
+ base size=0 base align=1
+std::allocator_arg_t (0x0x7f21b24f2ba0) 0 empty
+
+Class std::__uses_alloc_base
+ size=1 align=1
+ base size=0 base align=1
+std::__uses_alloc_base (0x0x7f21b24f2d20) 0 empty
+
+Class std::__uses_alloc0::_Sink
+ size=1 align=1
+ base size=0 base align=1
+std::__uses_alloc0::_Sink (0x0x7f21b24f2de0) 0 empty
+
+Class std::__uses_alloc0
+ size=1 align=1
+ base size=1 base align=1
+std::__uses_alloc0 (0x0x7f21b2465618) 0
+ std::__uses_alloc_base (0x0x7f21b24f2d80) 0 empty
+
+Class std::_Swallow_assign
+ size=1 align=1
+ base size=0 base align=1
+std::_Swallow_assign (0x0x7f21b22a3e40) 0 empty
+
+Class QtPrivate::AbstractDebugStreamFunction
+ size=16 align=8
+ base size=16 base align=8
+QtPrivate::AbstractDebugStreamFunction (0x0x7f21b23ec0c0) 0
+
+Class QtPrivate::AbstractComparatorFunction
+ size=24 align=8
+ base size=24 base align=8
+QtPrivate::AbstractComparatorFunction (0x0x7f21b23ec180) 0
+
+Class QtPrivate::AbstractConverterFunction
+ size=8 align=8
+ base size=8 base align=8
+QtPrivate::AbstractConverterFunction (0x0x7f21b23ec2a0) 0
+
+Class QMetaType
+ size=80 align=8
+ base size=80 base align=8
+QMetaType (0x0x7f21b23ec420) 0
+
+Class QtMetaTypePrivate::VariantData
+ size=24 align=8
+ base size=20 base align=8
+QtMetaTypePrivate::VariantData (0x0x7f21b23ec840) 0
+
+Class QtMetaTypePrivate::VectorBoolElements
+ size=1 align=1
+ base size=0 base align=1
+QtMetaTypePrivate::VectorBoolElements (0x0x7f21b23ec960) 0 empty
+
+Class QtMetaTypePrivate::QSequentialIterableImpl
+ size=104 align=8
+ base size=104 base align=8
+QtMetaTypePrivate::QSequentialIterableImpl (0x0x7f21b215c300) 0
+
+Class QtMetaTypePrivate::QAssociativeIterableImpl
+ size=112 align=8
+ base size=112 base align=8
+QtMetaTypePrivate::QAssociativeIterableImpl (0x0x7f21b215c720) 0
+
+Class QtMetaTypePrivate::QPairVariantInterfaceImpl
+ size=40 align=8
+ base size=40 base align=8
+QtMetaTypePrivate::QPairVariantInterfaceImpl (0x0x7f21b215ca20) 0
+
+Class std::chrono::_V2::system_clock
+ size=1 align=1
+ base size=0 base align=1
+std::chrono::_V2::system_clock (0x0x7f21b1bec2a0) 0 empty
+
+Class std::chrono::_V2::steady_clock
+ size=1 align=1
+ base size=0 base align=1
+std::chrono::_V2::steady_clock (0x0x7f21b1d34120) 0 empty
+
+Vtable for QObjectData
+QObjectData::_ZTV11QObjectData: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QObjectData)
+16 (int (*)(...))__cxa_pure_virtual
+24 (int (*)(...))__cxa_pure_virtual
+
+Class QObjectData
+ size=48 align=8
+ base size=48 base align=8
+QObjectData (0x0x7f21b1d34180) 0
+ vptr=((& QObjectData::_ZTV11QObjectData) + 16u)
+
+Class QObject::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QObject::QPrivateSignal (0x0x7f21b1d34360) 0 empty
+
+Vtable for QObject
+QObject::_ZTV7QObject: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QObject)
+16 (int (*)(...))QObject::metaObject
+24 (int (*)(...))QObject::qt_metacast
+32 (int (*)(...))QObject::qt_metacall
+40 (int (*)(...))QObject::~QObject
+48 (int (*)(...))QObject::~QObject
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QObject
+ size=16 align=8
+ base size=16 base align=8
+QObject (0x0x7f21b1d34300) 0
+ vptr=((& QObject::_ZTV7QObject) + 16u)
+
+Vtable for QObjectUserData
+QObjectUserData::_ZTV15QObjectUserData: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QObjectUserData)
+16 (int (*)(...))QObjectUserData::~QObjectUserData
+24 (int (*)(...))QObjectUserData::~QObjectUserData
+
+Class QObjectUserData
+ size=8 align=8
+ base size=8 base align=8
+QObjectUserData (0x0x7f21b1a12600) 0 nearly-empty
+ vptr=((& QObjectUserData::_ZTV15QObjectUserData) + 16u)
+
+Class QSignalBlocker
+ size=16 align=8
+ base size=10 base align=8
+QSignalBlocker (0x0x7f21b1a12660) 0
+
+Class QAbstractAnimation::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractAnimation::QPrivateSignal (0x0x7f21b1a12720) 0 empty
+
+Vtable for QAbstractAnimation
+QAbstractAnimation::_ZTV18QAbstractAnimation: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QAbstractAnimation)
+16 (int (*)(...))QAbstractAnimation::metaObject
+24 (int (*)(...))QAbstractAnimation::qt_metacast
+32 (int (*)(...))QAbstractAnimation::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QAbstractAnimation::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))QAbstractAnimation::updateState
+136 (int (*)(...))QAbstractAnimation::updateDirection
+
+Class QAbstractAnimation
+ size=16 align=8
+ base size=16 base align=8
+QAbstractAnimation (0x0x7f21b1a0e820) 0
+ vptr=((& QAbstractAnimation::_ZTV18QAbstractAnimation) + 16u)
+ QObject (0x0x7f21b1a126c0) 0
+ primary-for QAbstractAnimation (0x0x7f21b1a0e820)
+
+Class QAnimationDriver::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAnimationDriver::QPrivateSignal (0x0x7f21b1a127e0) 0 empty
+
+Vtable for QAnimationDriver
+QAnimationDriver::_ZTV16QAnimationDriver: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QAnimationDriver)
+16 (int (*)(...))QAnimationDriver::metaObject
+24 (int (*)(...))QAnimationDriver::qt_metacast
+32 (int (*)(...))QAnimationDriver::qt_metacall
+40 (int (*)(...))QAnimationDriver::~QAnimationDriver
+48 (int (*)(...))QAnimationDriver::~QAnimationDriver
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAnimationDriver::advance
+120 (int (*)(...))QAnimationDriver::elapsed
+128 (int (*)(...))QAnimationDriver::start
+136 (int (*)(...))QAnimationDriver::stop
+
+Class QAnimationDriver
+ size=16 align=8
+ base size=16 base align=8
+QAnimationDriver (0x0x7f21b1a0e888) 0
+ vptr=((& QAnimationDriver::_ZTV16QAnimationDriver) + 16u)
+ QObject (0x0x7f21b1a12780) 0
+ primary-for QAnimationDriver (0x0x7f21b1a0e888)
+
+Class QEventLoop::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QEventLoop::QPrivateSignal (0x0x7f21b1a128a0) 0 empty
+
+Vtable for QEventLoop
+QEventLoop::_ZTV10QEventLoop: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QEventLoop)
+16 (int (*)(...))QEventLoop::metaObject
+24 (int (*)(...))QEventLoop::qt_metacast
+32 (int (*)(...))QEventLoop::qt_metacall
+40 (int (*)(...))QEventLoop::~QEventLoop
+48 (int (*)(...))QEventLoop::~QEventLoop
+56 (int (*)(...))QEventLoop::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QEventLoop
+ size=16 align=8
+ base size=16 base align=8
+QEventLoop (0x0x7f21b1a0e8f0) 0
+ vptr=((& QEventLoop::_ZTV10QEventLoop) + 16u)
+ QObject (0x0x7f21b1a12840) 0
+ primary-for QEventLoop (0x0x7f21b1a0e8f0)
+
+Class QEventLoopLocker
+ size=8 align=8
+ base size=8 base align=8
+QEventLoopLocker (0x0x7f21b1a12a80) 0
+
+Class QAbstractEventDispatcher::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractEventDispatcher::QPrivateSignal (0x0x7f21b1a12b40) 0 empty
+
+Class QAbstractEventDispatcher::TimerInfo
+ size=12 align=4
+ base size=12 base align=4
+QAbstractEventDispatcher::TimerInfo (0x0x7f21b1a12ba0) 0
+
+Vtable for QAbstractEventDispatcher
+QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher: 28u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QAbstractEventDispatcher)
+16 (int (*)(...))QAbstractEventDispatcher::metaObject
+24 (int (*)(...))QAbstractEventDispatcher::qt_metacast
+32 (int (*)(...))QAbstractEventDispatcher::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))__cxa_pure_virtual
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))__cxa_pure_virtual
+176 (int (*)(...))__cxa_pure_virtual
+184 (int (*)(...))__cxa_pure_virtual
+192 (int (*)(...))__cxa_pure_virtual
+200 (int (*)(...))__cxa_pure_virtual
+208 (int (*)(...))QAbstractEventDispatcher::startingUp
+216 (int (*)(...))QAbstractEventDispatcher::closingDown
+
+Class QAbstractEventDispatcher
+ size=16 align=8
+ base size=16 base align=8
+QAbstractEventDispatcher (0x0x7f21b1a0ea28) 0
+ vptr=((& QAbstractEventDispatcher::_ZTV24QAbstractEventDispatcher) + 16u)
+ QObject (0x0x7f21b1a12ae0) 0
+ primary-for QAbstractEventDispatcher (0x0x7f21b1a0ea28)
+
+Vtable for std::type_info
+std::type_info::_ZTVSt9type_info: 8u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt9type_info)
+16 (int (*)(...))std::type_info::~type_info
+24 (int (*)(...))std::type_info::~type_info
+32 (int (*)(...))std::type_info::__is_pointer_p
+40 (int (*)(...))std::type_info::__is_function_p
+48 (int (*)(...))std::type_info::__do_catch
+56 (int (*)(...))std::type_info::__do_upcast
+
+Class std::type_info
+ size=16 align=8
+ base size=16 base align=8
+std::type_info (0x0x7f21b1a12e40) 0
+ vptr=((& std::type_info::_ZTVSt9type_info) + 16u)
+
+Vtable for std::bad_cast
+std::bad_cast::_ZTVSt8bad_cast: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt8bad_cast)
+16 (int (*)(...))std::bad_cast::~bad_cast
+24 (int (*)(...))std::bad_cast::~bad_cast
+32 (int (*)(...))std::bad_cast::what
+
+Class std::bad_cast
+ size=8 align=8
+ base size=8 base align=8
+std::bad_cast (0x0x7f21b1a0ec30) 0 nearly-empty
+ vptr=((& std::bad_cast::_ZTVSt8bad_cast) + 16u)
+ std::exception (0x0x7f21b1a12ea0) 0 nearly-empty
+ primary-for std::bad_cast (0x0x7f21b1a0ec30)
+
+Vtable for std::bad_typeid
+std::bad_typeid::_ZTVSt10bad_typeid: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt10bad_typeid)
+16 (int (*)(...))std::bad_typeid::~bad_typeid
+24 (int (*)(...))std::bad_typeid::~bad_typeid
+32 (int (*)(...))std::bad_typeid::what
+
+Class std::bad_typeid
+ size=8 align=8
+ base size=8 base align=8
+std::bad_typeid (0x0x7f21b1a0ec98) 0 nearly-empty
+ vptr=((& std::bad_typeid::_ZTVSt10bad_typeid) + 16u)
+ std::exception (0x0x7f21b1a12f00) 0 nearly-empty
+ primary-for std::bad_typeid (0x0x7f21b1a0ec98)
+
+Vtable for std::bad_function_call
+std::bad_function_call::_ZTVSt17bad_function_call: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt17bad_function_call)
+16 (int (*)(...))std::bad_function_call::~bad_function_call
+24 (int (*)(...))std::bad_function_call::~bad_function_call
+32 (int (*)(...))std::bad_function_call::what
+
+Class std::bad_function_call
+ size=8 align=8
+ base size=8 base align=8
+std::bad_function_call (0x0x7f21b1b5bf08) 0 nearly-empty
+ vptr=((& std::bad_function_call::_ZTVSt17bad_function_call) + 16u)
+ std::exception (0x0x7f21b185d000) 0 nearly-empty
+ primary-for std::bad_function_call (0x0x7f21b1b5bf08)
+
+Class std::_Nocopy_types
+ size=16 align=8
+ base size=16 base align=8
+std::_Nocopy_types (0x0x7f21b185d0c0) 0
+
+Class std::_Any_data
+ size=16 align=8
+ base size=16 base align=8
+std::_Any_data (0x0x7f21b185d120) 0
+
+Class std::_Function_base
+ size=24 align=8
+ base size=24 base align=8
+std::_Function_base (0x0x7f21b185d240) 0
+
+Class QMapNodeBase
+ size=24 align=8
+ base size=24 base align=8
+QMapNodeBase (0x0x7f21b185d720) 0
+
+Class QMapDataBase
+ size=40 align=8
+ base size=40 base align=8
+QMapDataBase (0x0x7f21b185dc60) 0
+
+Class QHashData::Node
+ size=16 align=8
+ base size=16 base align=8
+QHashData::Node (0x0x7f21b15f6060) 0
+
+Class QHashData
+ size=48 align=8
+ base size=44 base align=8
+QHashData (0x0x7f21b15f6000) 0
+
+Class QHashDummyValue
+ size=1 align=1
+ base size=0 base align=1
+QHashDummyValue (0x0x7f21b15f60c0) 0 empty
+
+Class QVariant::PrivateShared
+ size=16 align=8
+ base size=12 base align=8
+QVariant::PrivateShared (0x0x7f21b15f6960) 0
+
+Class QVariant::Private::Data
+ size=8 align=8
+ base size=8 base align=8
+QVariant::Private::Data (0x0x7f21b15f6a20) 0
+
+Class QVariant::Private
+ size=16 align=8
+ base size=12 base align=8
+QVariant::Private (0x0x7f21b15f69c0) 0
+
+Class QVariant::Handler
+ size=72 align=8
+ base size=72 base align=8
+QVariant::Handler (0x0x7f21b15f6a80) 0
+
+Class QVariant
+ size=16 align=8
+ base size=16 base align=8
+QVariant (0x0x7f21b15f6900) 0
+
+Class QVariantComparisonHelper
+ size=8 align=8
+ base size=8 base align=8
+QVariantComparisonHelper (0x0x7f21b144c5a0) 0
+
+Class QSequentialIterable::const_iterator
+ size=112 align=8
+ base size=112 base align=8
+QSequentialIterable::const_iterator (0x0x7f21b144cc00) 0
+
+Class QSequentialIterable
+ size=104 align=8
+ base size=104 base align=8
+QSequentialIterable (0x0x7f21b144cba0) 0
+
+Class QAssociativeIterable::const_iterator
+ size=120 align=8
+ base size=120 base align=8
+QAssociativeIterable::const_iterator (0x0x7f21b144ccc0) 0
+
+Class QAssociativeIterable
+ size=112 align=8
+ base size=112 base align=8
+QAssociativeIterable (0x0x7f21b144cc60) 0
+
+Class QModelIndex
+ size=24 align=8
+ base size=24 base align=8
+QModelIndex (0x0x7f21b129b000) 0
+
+Class QPersistentModelIndex
+ size=8 align=8
+ base size=8 base align=8
+QPersistentModelIndex (0x0x7f21b129b6c0) 0
+
+Class QAbstractItemModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractItemModel::QPrivateSignal (0x0x7f21b1342de0) 0 empty
+
+Vtable for QAbstractItemModel
+QAbstractItemModel::_ZTV18QAbstractItemModel: 48u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QAbstractItemModel)
+16 (int (*)(...))QAbstractItemModel::metaObject
+24 (int (*)(...))QAbstractItemModel::qt_metacast
+32 (int (*)(...))QAbstractItemModel::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))QAbstractItemModel::sibling
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))QAbstractItemModel::hasChildren
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))QAbstractItemModel::setData
+176 (int (*)(...))QAbstractItemModel::headerData
+184 (int (*)(...))QAbstractItemModel::setHeaderData
+192 (int (*)(...))QAbstractItemModel::itemData
+200 (int (*)(...))QAbstractItemModel::setItemData
+208 (int (*)(...))QAbstractItemModel::mimeTypes
+216 (int (*)(...))QAbstractItemModel::mimeData
+224 (int (*)(...))QAbstractItemModel::canDropMimeData
+232 (int (*)(...))QAbstractItemModel::dropMimeData
+240 (int (*)(...))QAbstractItemModel::supportedDropActions
+248 (int (*)(...))QAbstractItemModel::supportedDragActions
+256 (int (*)(...))QAbstractItemModel::insertRows
+264 (int (*)(...))QAbstractItemModel::insertColumns
+272 (int (*)(...))QAbstractItemModel::removeRows
+280 (int (*)(...))QAbstractItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractItemModel::fetchMore
+312 (int (*)(...))QAbstractItemModel::canFetchMore
+320 (int (*)(...))QAbstractItemModel::flags
+328 (int (*)(...))QAbstractItemModel::sort
+336 (int (*)(...))QAbstractItemModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractItemModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractItemModel::submit
+376 (int (*)(...))QAbstractItemModel::revert
+
+Class QAbstractItemModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractItemModel (0x0x7f21b1349c98) 0
+ vptr=((& QAbstractItemModel::_ZTV18QAbstractItemModel) + 16u)
+ QObject (0x0x7f21b1342d80) 0
+ primary-for QAbstractItemModel (0x0x7f21b1349c98)
+
+Class QAbstractTableModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractTableModel::QPrivateSignal (0x0x7f21b13d1180) 0 empty
+
+Vtable for QAbstractTableModel
+QAbstractTableModel::_ZTV19QAbstractTableModel: 48u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QAbstractTableModel)
+16 (int (*)(...))QAbstractTableModel::metaObject
+24 (int (*)(...))QAbstractTableModel::qt_metacast
+32 (int (*)(...))QAbstractTableModel::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAbstractTableModel::index
+120 (int (*)(...))QAbstractTableModel::parent
+128 (int (*)(...))QAbstractTableModel::sibling
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))QAbstractTableModel::hasChildren
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))QAbstractItemModel::setData
+176 (int (*)(...))QAbstractItemModel::headerData
+184 (int (*)(...))QAbstractItemModel::setHeaderData
+192 (int (*)(...))QAbstractItemModel::itemData
+200 (int (*)(...))QAbstractItemModel::setItemData
+208 (int (*)(...))QAbstractItemModel::mimeTypes
+216 (int (*)(...))QAbstractItemModel::mimeData
+224 (int (*)(...))QAbstractItemModel::canDropMimeData
+232 (int (*)(...))QAbstractTableModel::dropMimeData
+240 (int (*)(...))QAbstractItemModel::supportedDropActions
+248 (int (*)(...))QAbstractItemModel::supportedDragActions
+256 (int (*)(...))QAbstractItemModel::insertRows
+264 (int (*)(...))QAbstractItemModel::insertColumns
+272 (int (*)(...))QAbstractItemModel::removeRows
+280 (int (*)(...))QAbstractItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractItemModel::fetchMore
+312 (int (*)(...))QAbstractItemModel::canFetchMore
+320 (int (*)(...))QAbstractTableModel::flags
+328 (int (*)(...))QAbstractItemModel::sort
+336 (int (*)(...))QAbstractItemModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractItemModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractItemModel::submit
+376 (int (*)(...))QAbstractItemModel::revert
+
+Class QAbstractTableModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractTableModel (0x0x7f21b1349ea0) 0
+ vptr=((& QAbstractTableModel::_ZTV19QAbstractTableModel) + 16u)
+ QAbstractItemModel (0x0x7f21b1349f08) 0
+ primary-for QAbstractTableModel (0x0x7f21b1349ea0)
+ QObject (0x0x7f21b13d1120) 0
+ primary-for QAbstractItemModel (0x0x7f21b1349f08)
+
+Class QAbstractListModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractListModel::QPrivateSignal (0x0x7f21b13d1240) 0 empty
+
+Vtable for QAbstractListModel
+QAbstractListModel::_ZTV18QAbstractListModel: 48u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QAbstractListModel)
+16 (int (*)(...))QAbstractListModel::metaObject
+24 (int (*)(...))QAbstractListModel::qt_metacast
+32 (int (*)(...))QAbstractListModel::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAbstractListModel::index
+120 (int (*)(...))QAbstractListModel::parent
+128 (int (*)(...))QAbstractListModel::sibling
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))QAbstractListModel::columnCount
+152 (int (*)(...))QAbstractListModel::hasChildren
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))QAbstractItemModel::setData
+176 (int (*)(...))QAbstractItemModel::headerData
+184 (int (*)(...))QAbstractItemModel::setHeaderData
+192 (int (*)(...))QAbstractItemModel::itemData
+200 (int (*)(...))QAbstractItemModel::setItemData
+208 (int (*)(...))QAbstractItemModel::mimeTypes
+216 (int (*)(...))QAbstractItemModel::mimeData
+224 (int (*)(...))QAbstractItemModel::canDropMimeData
+232 (int (*)(...))QAbstractListModel::dropMimeData
+240 (int (*)(...))QAbstractItemModel::supportedDropActions
+248 (int (*)(...))QAbstractItemModel::supportedDragActions
+256 (int (*)(...))QAbstractItemModel::insertRows
+264 (int (*)(...))QAbstractItemModel::insertColumns
+272 (int (*)(...))QAbstractItemModel::removeRows
+280 (int (*)(...))QAbstractItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractItemModel::fetchMore
+312 (int (*)(...))QAbstractItemModel::canFetchMore
+320 (int (*)(...))QAbstractListModel::flags
+328 (int (*)(...))QAbstractItemModel::sort
+336 (int (*)(...))QAbstractItemModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractItemModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractItemModel::submit
+376 (int (*)(...))QAbstractItemModel::revert
+
+Class QAbstractListModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractListModel (0x0x7f21b1349f70) 0
+ vptr=((& QAbstractListModel::_ZTV18QAbstractListModel) + 16u)
+ QAbstractItemModel (0x0x7f21b1015000) 0
+ primary-for QAbstractListModel (0x0x7f21b1349f70)
+ QObject (0x0x7f21b13d11e0) 0
+ primary-for QAbstractItemModel (0x0x7f21b1015000)
+
+Vtable for QAbstractNativeEventFilter
+QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QAbstractNativeEventFilter)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class QAbstractNativeEventFilter
+ size=16 align=8
+ base size=16 base align=8
+QAbstractNativeEventFilter (0x0x7f21b13d14e0) 0
+ vptr=((& QAbstractNativeEventFilter::_ZTV26QAbstractNativeEventFilter) + 16u)
+
+Class QAbstractProxyModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractProxyModel::QPrivateSignal (0x0x7f21b13d15a0) 0 empty
+
+Vtable for QAbstractProxyModel
+QAbstractProxyModel::_ZTV19QAbstractProxyModel: 53u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QAbstractProxyModel)
+16 (int (*)(...))QAbstractProxyModel::metaObject
+24 (int (*)(...))QAbstractProxyModel::qt_metacast
+32 (int (*)(...))QAbstractProxyModel::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))QAbstractProxyModel::sibling
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))QAbstractProxyModel::hasChildren
+160 (int (*)(...))QAbstractProxyModel::data
+168 (int (*)(...))QAbstractProxyModel::setData
+176 (int (*)(...))QAbstractProxyModel::headerData
+184 (int (*)(...))QAbstractProxyModel::setHeaderData
+192 (int (*)(...))QAbstractProxyModel::itemData
+200 (int (*)(...))QAbstractProxyModel::setItemData
+208 (int (*)(...))QAbstractProxyModel::mimeTypes
+216 (int (*)(...))QAbstractProxyModel::mimeData
+224 (int (*)(...))QAbstractProxyModel::canDropMimeData
+232 (int (*)(...))QAbstractProxyModel::dropMimeData
+240 (int (*)(...))QAbstractProxyModel::supportedDropActions
+248 (int (*)(...))QAbstractProxyModel::supportedDragActions
+256 (int (*)(...))QAbstractItemModel::insertRows
+264 (int (*)(...))QAbstractItemModel::insertColumns
+272 (int (*)(...))QAbstractItemModel::removeRows
+280 (int (*)(...))QAbstractItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractProxyModel::fetchMore
+312 (int (*)(...))QAbstractProxyModel::canFetchMore
+320 (int (*)(...))QAbstractProxyModel::flags
+328 (int (*)(...))QAbstractProxyModel::sort
+336 (int (*)(...))QAbstractProxyModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractProxyModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractProxyModel::submit
+376 (int (*)(...))QAbstractProxyModel::revert
+384 (int (*)(...))QAbstractProxyModel::setSourceModel
+392 (int (*)(...))__cxa_pure_virtual
+400 (int (*)(...))__cxa_pure_virtual
+408 (int (*)(...))QAbstractProxyModel::mapSelectionToSource
+416 (int (*)(...))QAbstractProxyModel::mapSelectionFromSource
+
+Class QAbstractProxyModel
+ size=16 align=8
+ base size=16 base align=8
+QAbstractProxyModel (0x0x7f21b1015138) 0
+ vptr=((& QAbstractProxyModel::_ZTV19QAbstractProxyModel) + 16u)
+ QAbstractItemModel (0x0x7f21b10151a0) 0
+ primary-for QAbstractProxyModel (0x0x7f21b1015138)
+ QObject (0x0x7f21b13d1540) 0
+ primary-for QAbstractItemModel (0x0x7f21b10151a0)
+
+Class QAbstractState::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractState::QPrivateSignal (0x0x7f21b13d1660) 0 empty
+
+Vtable for QAbstractState
+QAbstractState::_ZTV14QAbstractState: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QAbstractState)
+16 (int (*)(...))QAbstractState::metaObject
+24 (int (*)(...))QAbstractState::qt_metacast
+32 (int (*)(...))QAbstractState::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QAbstractState::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+
+Class QAbstractState
+ size=16 align=8
+ base size=16 base align=8
+QAbstractState (0x0x7f21b1015208) 0
+ vptr=((& QAbstractState::_ZTV14QAbstractState) + 16u)
+ QObject (0x0x7f21b13d1600) 0
+ primary-for QAbstractState (0x0x7f21b1015208)
+
+Class QAbstractTransition::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractTransition::QPrivateSignal (0x0x7f21b13d1720) 0 empty
+
+Vtable for QAbstractTransition
+QAbstractTransition::_ZTV19QAbstractTransition: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QAbstractTransition)
+16 (int (*)(...))QAbstractTransition::metaObject
+24 (int (*)(...))QAbstractTransition::qt_metacast
+32 (int (*)(...))QAbstractTransition::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QAbstractTransition::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+
+Class QAbstractTransition
+ size=16 align=8
+ base size=16 base align=8
+QAbstractTransition (0x0x7f21b1015270) 0
+ vptr=((& QAbstractTransition::_ZTV19QAbstractTransition) + 16u)
+ QObject (0x0x7f21b13d16c0) 0
+ primary-for QAbstractTransition (0x0x7f21b1015270)
+
+Class QAnimationGroup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAnimationGroup::QPrivateSignal (0x0x7f21b13d17e0) 0 empty
+
+Vtable for QAnimationGroup
+QAnimationGroup::_ZTV15QAnimationGroup: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QAnimationGroup)
+16 (int (*)(...))QAnimationGroup::metaObject
+24 (int (*)(...))QAnimationGroup::qt_metacast
+32 (int (*)(...))QAnimationGroup::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QAnimationGroup::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))QAbstractAnimation::updateState
+136 (int (*)(...))QAbstractAnimation::updateDirection
+
+Class QAnimationGroup
+ size=16 align=8
+ base size=16 base align=8
+QAnimationGroup (0x0x7f21b10152d8) 0
+ vptr=((& QAnimationGroup::_ZTV15QAnimationGroup) + 16u)
+ QAbstractAnimation (0x0x7f21b1015340) 0
+ primary-for QAnimationGroup (0x0x7f21b10152d8)
+ QObject (0x0x7f21b13d1780) 0
+ primary-for QAbstractAnimation (0x0x7f21b1015340)
+
+Class QBasicTimer
+ size=4 align=4
+ base size=4 base align=4
+QBasicTimer (0x0x7f21b10df540) 0
+
+Class QBitArray
+ size=8 align=8
+ base size=8 base align=8
+QBitArray (0x0x7f21b10df7e0) 0
+
+Class QBitRef
+ size=16 align=8
+ base size=12 base align=8
+QBitRef (0x0x7f21b10df8a0) 0
+
+Class QIODevice::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QIODevice::QPrivateSignal (0x0x7f21b10dfba0) 0 empty
+
+Vtable for QIODevice
+QIODevice::_ZTV9QIODevice: 30u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QIODevice)
+16 (int (*)(...))QIODevice::metaObject
+24 (int (*)(...))QIODevice::qt_metacast
+32 (int (*)(...))QIODevice::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QIODevice::isSequential
+120 (int (*)(...))QIODevice::open
+128 (int (*)(...))QIODevice::close
+136 (int (*)(...))QIODevice::pos
+144 (int (*)(...))QIODevice::size
+152 (int (*)(...))QIODevice::seek
+160 (int (*)(...))QIODevice::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QIODevice::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))__cxa_pure_virtual
+224 (int (*)(...))QIODevice::readLineData
+232 (int (*)(...))__cxa_pure_virtual
+
+Class QIODevice
+ size=16 align=8
+ base size=16 base align=8
+QIODevice (0x0x7f21b10159c0) 0
+ vptr=((& QIODevice::_ZTV9QIODevice) + 16u)
+ QObject (0x0x7f21b10dfb40) 0
+ primary-for QIODevice (0x0x7f21b10159c0)
+
+Class QBuffer::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QBuffer::QPrivateSignal (0x0x7f21b10dfde0) 0 empty
+
+Vtable for QBuffer
+QBuffer::_ZTV7QBuffer: 30u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QBuffer)
+16 (int (*)(...))QBuffer::metaObject
+24 (int (*)(...))QBuffer::qt_metacast
+32 (int (*)(...))QBuffer::qt_metacall
+40 (int (*)(...))QBuffer::~QBuffer
+48 (int (*)(...))QBuffer::~QBuffer
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QBuffer::connectNotify
+104 (int (*)(...))QBuffer::disconnectNotify
+112 (int (*)(...))QIODevice::isSequential
+120 (int (*)(...))QBuffer::open
+128 (int (*)(...))QBuffer::close
+136 (int (*)(...))QBuffer::pos
+144 (int (*)(...))QBuffer::size
+152 (int (*)(...))QBuffer::seek
+160 (int (*)(...))QBuffer::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QBuffer::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))QBuffer::readData
+224 (int (*)(...))QIODevice::readLineData
+232 (int (*)(...))QBuffer::writeData
+
+Class QBuffer
+ size=16 align=8
+ base size=16 base align=8
+QBuffer (0x0x7f21b1015af8) 0
+ vptr=((& QBuffer::_ZTV7QBuffer) + 16u)
+ QIODevice (0x0x7f21b1015b60) 0
+ primary-for QBuffer (0x0x7f21b1015af8)
+ QObject (0x0x7f21b10dfd80) 0
+ primary-for QIODevice (0x0x7f21b1015b60)
+
+Class QByteArrayMatcher::Data
+ size=272 align=8
+ base size=272 base align=8
+QByteArrayMatcher::Data (0x0x7f21b10dfea0) 0
+
+Class QByteArrayMatcher
+ size=1040 align=8
+ base size=1040 base align=8
+QByteArrayMatcher (0x0x7f21b10dfe40) 0
+
+Class QStaticByteArrayMatcherBase::Skiptable
+ size=256 align=1
+ base size=256 base align=1
+QStaticByteArrayMatcherBase::Skiptable (0x0x7f21b11d6000) 0
+
+Class QStaticByteArrayMatcherBase
+ size=256 align=16
+ base size=256 base align=16
+QStaticByteArrayMatcherBase (0x0x7f21b10dff60) 0
+
+Class QSharedData
+ size=4 align=4
+ base size=4 base align=4
+QSharedData (0x0x7f21b11d61e0) 0
+
+Class QLocale
+ size=8 align=8
+ base size=8 base align=8
+QLocale (0x0x7f21b11d63c0) 0
+
+Class QCollatorSortKey
+ size=8 align=8
+ base size=8 base align=8
+QCollatorSortKey (0x0x7f21b11d69c0) 0
+
+Class QCollator
+ size=8 align=8
+ base size=8 base align=8
+QCollator (0x0x7f21b11d6a80) 0
+
+Class QCommandLineOption
+ size=8 align=8
+ base size=8 base align=8
+QCommandLineOption (0x0x7f21b0fb5a80) 0
+
+Vtable for QEvent
+QEvent::_ZTV6QEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QEvent)
+16 (int (*)(...))QEvent::~QEvent
+24 (int (*)(...))QEvent::~QEvent
+
+Class QEvent
+ size=24 align=8
+ base size=20 base align=8
+QEvent (0x0x7f21b0fb5f00) 0
+ vptr=((& QEvent::_ZTV6QEvent) + 16u)
+
+Vtable for QTimerEvent
+QTimerEvent::_ZTV11QTimerEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTimerEvent)
+16 (int (*)(...))QTimerEvent::~QTimerEvent
+24 (int (*)(...))QTimerEvent::~QTimerEvent
+
+Class QTimerEvent
+ size=24 align=8
+ base size=24 base align=8
+QTimerEvent (0x0x7f21b0ba4068) 0
+ vptr=((& QTimerEvent::_ZTV11QTimerEvent) + 16u)
+ QEvent (0x0x7f21b0fb5f60) 0
+ primary-for QTimerEvent (0x0x7f21b0ba4068)
+
+Vtable for QChildEvent
+QChildEvent::_ZTV11QChildEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QChildEvent)
+16 (int (*)(...))QChildEvent::~QChildEvent
+24 (int (*)(...))QChildEvent::~QChildEvent
+
+Class QChildEvent
+ size=32 align=8
+ base size=32 base align=8
+QChildEvent (0x0x7f21b0ba40d0) 0
+ vptr=((& QChildEvent::_ZTV11QChildEvent) + 16u)
+ QEvent (0x0x7f21b0be6000) 0
+ primary-for QChildEvent (0x0x7f21b0ba40d0)
+
+Vtable for QDynamicPropertyChangeEvent
+QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QDynamicPropertyChangeEvent)
+16 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+24 (int (*)(...))QDynamicPropertyChangeEvent::~QDynamicPropertyChangeEvent
+
+Class QDynamicPropertyChangeEvent
+ size=32 align=8
+ base size=32 base align=8
+QDynamicPropertyChangeEvent (0x0x7f21b0ba4618) 0
+ vptr=((& QDynamicPropertyChangeEvent::_ZTV27QDynamicPropertyChangeEvent) + 16u)
+ QEvent (0x0x7f21b0be64e0) 0
+ primary-for QDynamicPropertyChangeEvent (0x0x7f21b0ba4618)
+
+Vtable for QDeferredDeleteEvent
+QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QDeferredDeleteEvent)
+16 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent
+24 (int (*)(...))QDeferredDeleteEvent::~QDeferredDeleteEvent
+
+Class QDeferredDeleteEvent
+ size=24 align=8
+ base size=24 base align=8
+QDeferredDeleteEvent (0x0x7f21b0ba4680) 0
+ vptr=((& QDeferredDeleteEvent::_ZTV20QDeferredDeleteEvent) + 16u)
+ QEvent (0x0x7f21b0be6540) 0
+ primary-for QDeferredDeleteEvent (0x0x7f21b0ba4680)
+
+Class QCoreApplication::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QCoreApplication::QPrivateSignal (0x0x7f21b0be6600) 0 empty
+
+Vtable for QCoreApplication
+QCoreApplication::_ZTV16QCoreApplication: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QCoreApplication)
+16 (int (*)(...))QCoreApplication::metaObject
+24 (int (*)(...))QCoreApplication::qt_metacast
+32 (int (*)(...))QCoreApplication::qt_metacall
+40 (int (*)(...))QCoreApplication::~QCoreApplication
+48 (int (*)(...))QCoreApplication::~QCoreApplication
+56 (int (*)(...))QCoreApplication::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QCoreApplication::notify
+120 (int (*)(...))QCoreApplication::compressEvent
+
+Class QCoreApplication
+ size=16 align=8
+ base size=16 base align=8
+QCoreApplication (0x0x7f21b0ba46e8) 0
+ vptr=((& QCoreApplication::_ZTV16QCoreApplication) + 16u)
+ QObject (0x0x7f21b0be65a0) 0
+ primary-for QCoreApplication (0x0x7f21b0ba46e8)
+
+Class QCommandLineParser
+ size=8 align=8
+ base size=8 base align=8
+QCommandLineParser (0x0x7f21b0be6660) 0
+
+Class QContiguousCacheData
+ size=24 align=4
+ base size=24 base align=4
+QContiguousCacheData (0x0x7f21b0be66c0) 0
+
+Class QCryptographicHash
+ size=8 align=8
+ base size=8 base align=8
+QCryptographicHash (0x0x7f21b0be6cc0) 0
+
+Class QDataStream
+ size=32 align=8
+ base size=32 base align=8
+QDataStream (0x0x7f21b0be6d20) 0
+
+Class QtPrivate::StreamStateSaver
+ size=16 align=8
+ base size=12 base align=8
+QtPrivate::StreamStateSaver (0x0x7f21b0be6de0) 0
+
+Class QDate
+ size=8 align=8
+ base size=8 base align=8
+QDate (0x0x7f21b0cc2300) 0
+
+Class QTime
+ size=4 align=4
+ base size=4 base align=4
+QTime (0x0x7f21b0cc25a0) 0
+
+Class QDateTime::ShortData
+ size=8 align=8
+ base size=8 base align=8
+QDateTime::ShortData (0x0x7f21b0cc2d20) 0
+
+Class QDateTime::Data
+ size=8 align=8
+ base size=8 base align=8
+QDateTime::Data (0x0x7f21b0cc2d80) 0
+
+Class QDateTime
+ size=8 align=8
+ base size=8 base align=8
+QDateTime (0x0x7f21b0cc2cc0) 0
+
+Class QElapsedTimer
+ size=16 align=8
+ base size=16 base align=8
+QElapsedTimer (0x0x7f21b09d5ea0) 0
+
+Class QDeadlineTimer
+ size=16 align=8
+ base size=16 base align=8
+QDeadlineTimer (0x0x7f21b0a113c0) 0
+
+Vtable for QTextStream
+QTextStream::_ZTV11QTextStream: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTextStream)
+16 (int (*)(...))QTextStream::~QTextStream
+24 (int (*)(...))QTextStream::~QTextStream
+
+Class QTextStream
+ size=16 align=8
+ base size=16 base align=8
+QTextStream (0x0x7f21b0b3f360) 0
+ vptr=((& QTextStream::_ZTV11QTextStream) + 16u)
+
+Class QTextStreamManipulator
+ size=40 align=8
+ base size=38 base align=8
+QTextStreamManipulator (0x0x7f21b0b3f600) 0
+
+Class QtSharedPointer::NormalDeleter
+ size=1 align=1
+ base size=0 base align=1
+QtSharedPointer::NormalDeleter (0x0x7f21b0b3f840) 0 empty
+
+Class QtSharedPointer::ExternalRefCountData
+ size=16 align=8
+ base size=16 base align=8
+QtSharedPointer::ExternalRefCountData (0x0x7f21b0b3f9c0) 0
+
+Class QDebug::Stream
+ size=80 align=8
+ base size=76 base align=8
+QDebug::Stream (0x0x7f21b0b3ff00) 0
+
+Class QDebug
+ size=8 align=8
+ base size=8 base align=8
+QDebug (0x0x7f21b0b3fea0) 0
+
+Class QDebugStateSaver
+ size=8 align=8
+ base size=8 base align=8
+QDebugStateSaver (0x0x7f21b05c9420) 0
+
+Class QNoDebug
+ size=1 align=1
+ base size=0 base align=1
+QNoDebug (0x0x7f21b05c94e0) 0 empty
+
+Class QFileDevice::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFileDevice::QPrivateSignal (0x0x7f21b068a660) 0 empty
+
+Vtable for QFileDevice
+QFileDevice::_ZTV11QFileDevice: 34u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QFileDevice)
+16 (int (*)(...))QFileDevice::metaObject
+24 (int (*)(...))QFileDevice::qt_metacast
+32 (int (*)(...))QFileDevice::qt_metacall
+40 (int (*)(...))QFileDevice::~QFileDevice
+48 (int (*)(...))QFileDevice::~QFileDevice
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QFileDevice::isSequential
+120 (int (*)(...))QIODevice::open
+128 (int (*)(...))QFileDevice::close
+136 (int (*)(...))QFileDevice::pos
+144 (int (*)(...))QFileDevice::size
+152 (int (*)(...))QFileDevice::seek
+160 (int (*)(...))QFileDevice::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QIODevice::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))QFileDevice::readData
+224 (int (*)(...))QFileDevice::readLineData
+232 (int (*)(...))QFileDevice::writeData
+240 (int (*)(...))QFileDevice::fileName
+248 (int (*)(...))QFileDevice::resize
+256 (int (*)(...))QFileDevice::permissions
+264 (int (*)(...))QFileDevice::setPermissions
+
+Class QFileDevice
+ size=16 align=8
+ base size=16 base align=8
+QFileDevice (0x0x7f21b0691618) 0
+ vptr=((& QFileDevice::_ZTV11QFileDevice) + 16u)
+ QIODevice (0x0x7f21b0691680) 0
+ primary-for QFileDevice (0x0x7f21b0691618)
+ QObject (0x0x7f21b068a600) 0
+ primary-for QIODevice (0x0x7f21b0691680)
+
+Class QFile::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFile::QPrivateSignal (0x0x7f21b068a8a0) 0 empty
+
+Vtable for QFile
+QFile::_ZTV5QFile: 34u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI5QFile)
+16 (int (*)(...))QFile::metaObject
+24 (int (*)(...))QFile::qt_metacast
+32 (int (*)(...))QFile::qt_metacall
+40 (int (*)(...))QFile::~QFile
+48 (int (*)(...))QFile::~QFile
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QFileDevice::isSequential
+120 (int (*)(...))QFile::open
+128 (int (*)(...))QFileDevice::close
+136 (int (*)(...))QFileDevice::pos
+144 (int (*)(...))QFile::size
+152 (int (*)(...))QFileDevice::seek
+160 (int (*)(...))QFileDevice::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QIODevice::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))QFileDevice::readData
+224 (int (*)(...))QFileDevice::readLineData
+232 (int (*)(...))QFileDevice::writeData
+240 (int (*)(...))QFile::fileName
+248 (int (*)(...))QFile::resize
+256 (int (*)(...))QFile::permissions
+264 (int (*)(...))QFile::setPermissions
+
+Class QFile
+ size=16 align=8
+ base size=16 base align=8
+QFile (0x0x7f21b06917b8) 0
+ vptr=((& QFile::_ZTV5QFile) + 16u)
+ QFileDevice (0x0x7f21b0691820) 0
+ primary-for QFile (0x0x7f21b06917b8)
+ QIODevice (0x0x7f21b0691888) 0
+ primary-for QFileDevice (0x0x7f21b0691820)
+ QObject (0x0x7f21b068a840) 0
+ primary-for QIODevice (0x0x7f21b0691888)
+
+Class QFileInfo
+ size=8 align=8
+ base size=8 base align=8
+QFileInfo (0x0x7f21b068aa80) 0
+
+Class QDir
+ size=8 align=8
+ base size=8 base align=8
+QDir (0x0x7f21b068aea0) 0
+
+Class QDirIterator
+ size=8 align=8
+ base size=8 base align=8
+QDirIterator (0x0x7f21b07758a0) 0
+
+Class QEasingCurve
+ size=8 align=8
+ base size=8 base align=8
+QEasingCurve (0x0x7f21b0775ae0) 0
+
+Class QEventTransition::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QEventTransition::QPrivateSignal (0x0x7f21b049cf00) 0 empty
+
+Vtable for QEventTransition
+QEventTransition::_ZTV16QEventTransition: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QEventTransition)
+16 (int (*)(...))QEventTransition::metaObject
+24 (int (*)(...))QEventTransition::qt_metacast
+32 (int (*)(...))QEventTransition::qt_metacall
+40 (int (*)(...))QEventTransition::~QEventTransition
+48 (int (*)(...))QEventTransition::~QEventTransition
+56 (int (*)(...))QEventTransition::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QEventTransition::eventTest
+120 (int (*)(...))QEventTransition::onTransition
+
+Class QEventTransition
+ size=16 align=8
+ base size=16 base align=8
+QEventTransition (0x0x7f21b04a3a90) 0
+ vptr=((& QEventTransition::_ZTV16QEventTransition) + 16u)
+ QAbstractTransition (0x0x7f21b04a3af8) 0
+ primary-for QEventTransition (0x0x7f21b04a3a90)
+ QObject (0x0x7f21b049cea0) 0
+ primary-for QAbstractTransition (0x0x7f21b04a3af8)
+
+Vtable for QException
+QException::_ZTV10QException: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QException)
+16 (int (*)(...))QException::~QException
+24 (int (*)(...))QException::~QException
+32 (int (*)(...))std::exception::what
+40 (int (*)(...))QException::raise
+48 (int (*)(...))QException::clone
+
+Class QException
+ size=8 align=8
+ base size=8 base align=8
+QException (0x0x7f21b04a3b60) 0 nearly-empty
+ vptr=((& QException::_ZTV10QException) + 16u)
+ std::exception (0x0x7f21b049cf60) 0 nearly-empty
+ primary-for QException (0x0x7f21b04a3b60)
+
+Vtable for QUnhandledException
+QUnhandledException::_ZTV19QUnhandledException: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QUnhandledException)
+16 (int (*)(...))QUnhandledException::~QUnhandledException
+24 (int (*)(...))QUnhandledException::~QUnhandledException
+32 (int (*)(...))std::exception::what
+40 (int (*)(...))QUnhandledException::raise
+48 (int (*)(...))QUnhandledException::clone
+
+Class QUnhandledException
+ size=8 align=8
+ base size=8 base align=8
+QUnhandledException (0x0x7f21b04a3bc8) 0 nearly-empty
+ vptr=((& QUnhandledException::_ZTV19QUnhandledException) + 16u)
+ QException (0x0x7f21b04a3c30) 0 nearly-empty
+ primary-for QUnhandledException (0x0x7f21b04a3bc8)
+ std::exception (0x0x7f21b0502000) 0 nearly-empty
+ primary-for QException (0x0x7f21b04a3c30)
+
+Class QtPrivate::ExceptionHolder
+ size=8 align=8
+ base size=8 base align=8
+QtPrivate::ExceptionHolder (0x0x7f21b0502060) 0
+
+Class QtPrivate::ExceptionStore
+ size=8 align=8
+ base size=8 base align=8
+QtPrivate::ExceptionStore (0x0x7f21b0502120) 0
+
+Vtable for QFactoryInterface
+QFactoryInterface::_ZTV17QFactoryInterface: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QFactoryInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class QFactoryInterface
+ size=8 align=8
+ base size=8 base align=8
+QFactoryInterface (0x0x7f21b0502180) 0 nearly-empty
+ vptr=((& QFactoryInterface::_ZTV17QFactoryInterface) + 16u)
+
+Class QFileSelector::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFileSelector::QPrivateSignal (0x0x7f21b05022a0) 0 empty
+
+Vtable for QFileSelector
+QFileSelector::_ZTV13QFileSelector: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QFileSelector)
+16 (int (*)(...))QFileSelector::metaObject
+24 (int (*)(...))QFileSelector::qt_metacast
+32 (int (*)(...))QFileSelector::qt_metacall
+40 (int (*)(...))QFileSelector::~QFileSelector
+48 (int (*)(...))QFileSelector::~QFileSelector
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QFileSelector
+ size=16 align=8
+ base size=16 base align=8
+QFileSelector (0x0x7f21b04a3c98) 0
+ vptr=((& QFileSelector::_ZTV13QFileSelector) + 16u)
+ QObject (0x0x7f21b0502240) 0
+ primary-for QFileSelector (0x0x7f21b04a3c98)
+
+Class QFileSystemWatcher::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFileSystemWatcher::QPrivateSignal (0x0x7f21b0502360) 0 empty
+
+Vtable for QFileSystemWatcher
+QFileSystemWatcher::_ZTV18QFileSystemWatcher: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QFileSystemWatcher)
+16 (int (*)(...))QFileSystemWatcher::metaObject
+24 (int (*)(...))QFileSystemWatcher::qt_metacast
+32 (int (*)(...))QFileSystemWatcher::qt_metacall
+40 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher
+48 (int (*)(...))QFileSystemWatcher::~QFileSystemWatcher
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QFileSystemWatcher
+ size=16 align=8
+ base size=16 base align=8
+QFileSystemWatcher (0x0x7f21b04a3d00) 0
+ vptr=((& QFileSystemWatcher::_ZTV18QFileSystemWatcher) + 16u)
+ QObject (0x0x7f21b0502300) 0
+ primary-for QFileSystemWatcher (0x0x7f21b04a3d00)
+
+Class QFinalState::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFinalState::QPrivateSignal (0x0x7f21b0502420) 0 empty
+
+Vtable for QFinalState
+QFinalState::_ZTV11QFinalState: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QFinalState)
+16 (int (*)(...))QFinalState::metaObject
+24 (int (*)(...))QFinalState::qt_metacast
+32 (int (*)(...))QFinalState::qt_metacall
+40 (int (*)(...))QFinalState::~QFinalState
+48 (int (*)(...))QFinalState::~QFinalState
+56 (int (*)(...))QFinalState::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QFinalState::onEntry
+120 (int (*)(...))QFinalState::onExit
+
+Class QFinalState
+ size=16 align=8
+ base size=16 base align=8
+QFinalState (0x0x7f21b04a3d68) 0
+ vptr=((& QFinalState::_ZTV11QFinalState) + 16u)
+ QAbstractState (0x0x7f21b04a3dd0) 0
+ primary-for QFinalState (0x0x7f21b04a3d68)
+ QObject (0x0x7f21b05023c0) 0
+ primary-for QAbstractState (0x0x7f21b04a3dd0)
+
+Vtable for QRunnable
+QRunnable::_ZTV9QRunnable: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QRunnable)
+16 (int (*)(...))__cxa_pure_virtual
+24 0u
+32 0u
+
+Class QRunnable
+ size=16 align=8
+ base size=12 base align=8
+QRunnable (0x0x7f21b0502480) 0
+ vptr=((& QRunnable::_ZTV9QRunnable) + 16u)
+
+Class QBasicMutex
+ size=8 align=8
+ base size=8 base align=8
+QBasicMutex (0x0x7f21b05024e0) 0
+
+Class QMutex
+ size=8 align=8
+ base size=8 base align=8
+QMutex (0x0x7f21b04a3f08) 0
+ QBasicMutex (0x0x7f21b05026c0) 0
+
+Class QMutexLocker
+ size=8 align=8
+ base size=8 base align=8
+QMutexLocker (0x0x7f21b0502720) 0
+
+Class QtPrivate::ResultItem
+ size=16 align=8
+ base size=16 base align=8
+QtPrivate::ResultItem (0x0x7f21b0502780) 0
+
+Class QtPrivate::ResultIteratorBase
+ size=16 align=8
+ base size=12 base align=8
+QtPrivate::ResultIteratorBase (0x0x7f21b05027e0) 0
+
+Vtable for QtPrivate::ResultStoreBase
+QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN9QtPrivate15ResultStoreBaseE)
+16 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase
+24 (int (*)(...))QtPrivate::ResultStoreBase::~ResultStoreBase
+
+Class QtPrivate::ResultStoreBase
+ size=48 align=8
+ base size=44 base align=8
+QtPrivate::ResultStoreBase (0x0x7f21b0502900) 0
+ vptr=((& QtPrivate::ResultStoreBase::_ZTVN9QtPrivate15ResultStoreBaseE) + 16u)
+
+Vtable for QFutureInterfaceBase
+QFutureInterfaceBase::_ZTV20QFutureInterfaceBase: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QFutureInterfaceBase)
+16 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase
+24 (int (*)(...))QFutureInterfaceBase::~QFutureInterfaceBase
+
+Class QFutureInterfaceBase
+ size=16 align=8
+ base size=16 base align=8
+QFutureInterfaceBase (0x0x7f21b023b180) 0
+ vptr=((& QFutureInterfaceBase::_ZTV20QFutureInterfaceBase) + 16u)
+
+Class QFutureWatcherBase::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFutureWatcherBase::QPrivateSignal (0x0x7f21b023b960) 0 empty
+
+Vtable for QFutureWatcherBase
+QFutureWatcherBase::_ZTV18QFutureWatcherBase: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QFutureWatcherBase)
+16 (int (*)(...))QFutureWatcherBase::metaObject
+24 (int (*)(...))QFutureWatcherBase::qt_metacast
+32 (int (*)(...))QFutureWatcherBase::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QFutureWatcherBase::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QFutureWatcherBase::connectNotify
+104 (int (*)(...))QFutureWatcherBase::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+
+Class QFutureWatcherBase
+ size=16 align=8
+ base size=16 base align=8
+QFutureWatcherBase (0x0x7f21b02bb068) 0
+ vptr=((& QFutureWatcherBase::_ZTV18QFutureWatcherBase) + 16u)
+ QObject (0x0x7f21b023b900) 0
+ primary-for QFutureWatcherBase (0x0x7f21b02bb068)
+
+Class QHistoryState::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QHistoryState::QPrivateSignal (0x0x7f21b023bf60) 0 empty
+
+Vtable for QHistoryState
+QHistoryState::_ZTV13QHistoryState: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QHistoryState)
+16 (int (*)(...))QHistoryState::metaObject
+24 (int (*)(...))QHistoryState::qt_metacast
+32 (int (*)(...))QHistoryState::qt_metacall
+40 (int (*)(...))QHistoryState::~QHistoryState
+48 (int (*)(...))QHistoryState::~QHistoryState
+56 (int (*)(...))QHistoryState::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QHistoryState::onEntry
+120 (int (*)(...))QHistoryState::onExit
+
+Class QHistoryState
+ size=16 align=8
+ base size=16 base align=8
+QHistoryState (0x0x7f21b02bb958) 0
+ vptr=((& QHistoryState::_ZTV13QHistoryState) + 16u)
+ QAbstractState (0x0x7f21b02bb9c0) 0
+ primary-for QHistoryState (0x0x7f21b02bb958)
+ QObject (0x0x7f21b023bf00) 0
+ primary-for QAbstractState (0x0x7f21b02bb9c0)
+
+Class QIdentityProxyModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QIdentityProxyModel::QPrivateSignal (0x0x7f21b032e060) 0 empty
+
+Vtable for QIdentityProxyModel
+QIdentityProxyModel::_ZTV19QIdentityProxyModel: 53u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QIdentityProxyModel)
+16 (int (*)(...))QIdentityProxyModel::metaObject
+24 (int (*)(...))QIdentityProxyModel::qt_metacast
+32 (int (*)(...))QIdentityProxyModel::qt_metacall
+40 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel
+48 (int (*)(...))QIdentityProxyModel::~QIdentityProxyModel
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QIdentityProxyModel::index
+120 (int (*)(...))QIdentityProxyModel::parent
+128 (int (*)(...))QIdentityProxyModel::sibling
+136 (int (*)(...))QIdentityProxyModel::rowCount
+144 (int (*)(...))QIdentityProxyModel::columnCount
+152 (int (*)(...))QAbstractProxyModel::hasChildren
+160 (int (*)(...))QAbstractProxyModel::data
+168 (int (*)(...))QAbstractProxyModel::setData
+176 (int (*)(...))QIdentityProxyModel::headerData
+184 (int (*)(...))QAbstractProxyModel::setHeaderData
+192 (int (*)(...))QAbstractProxyModel::itemData
+200 (int (*)(...))QAbstractProxyModel::setItemData
+208 (int (*)(...))QAbstractProxyModel::mimeTypes
+216 (int (*)(...))QAbstractProxyModel::mimeData
+224 (int (*)(...))QAbstractProxyModel::canDropMimeData
+232 (int (*)(...))QIdentityProxyModel::dropMimeData
+240 (int (*)(...))QAbstractProxyModel::supportedDropActions
+248 (int (*)(...))QAbstractProxyModel::supportedDragActions
+256 (int (*)(...))QIdentityProxyModel::insertRows
+264 (int (*)(...))QIdentityProxyModel::insertColumns
+272 (int (*)(...))QIdentityProxyModel::removeRows
+280 (int (*)(...))QIdentityProxyModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractProxyModel::fetchMore
+312 (int (*)(...))QAbstractProxyModel::canFetchMore
+320 (int (*)(...))QAbstractProxyModel::flags
+328 (int (*)(...))QAbstractProxyModel::sort
+336 (int (*)(...))QAbstractProxyModel::buddy
+344 (int (*)(...))QIdentityProxyModel::match
+352 (int (*)(...))QAbstractProxyModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractProxyModel::submit
+376 (int (*)(...))QAbstractProxyModel::revert
+384 (int (*)(...))QIdentityProxyModel::setSourceModel
+392 (int (*)(...))QIdentityProxyModel::mapToSource
+400 (int (*)(...))QIdentityProxyModel::mapFromSource
+408 (int (*)(...))QIdentityProxyModel::mapSelectionToSource
+416 (int (*)(...))QIdentityProxyModel::mapSelectionFromSource
+
+Class QIdentityProxyModel
+ size=16 align=8
+ base size=16 base align=8
+QIdentityProxyModel (0x0x7f21b02bba28) 0
+ vptr=((& QIdentityProxyModel::_ZTV19QIdentityProxyModel) + 16u)
+ QAbstractProxyModel (0x0x7f21b02bba90) 0
+ primary-for QIdentityProxyModel (0x0x7f21b02bba28)
+ QAbstractItemModel (0x0x7f21b02bbaf8) 0
+ primary-for QAbstractProxyModel (0x0x7f21b02bba90)
+ QObject (0x0x7f21b032e000) 0
+ primary-for QAbstractItemModel (0x0x7f21b02bbaf8)
+
+Class QItemSelectionRange
+ size=16 align=8
+ base size=16 base align=8
+QItemSelectionRange (0x0x7f21b032e0c0) 0
+
+Class QItemSelectionModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QItemSelectionModel::QPrivateSignal (0x0x7f21b032e780) 0 empty
+
+Vtable for QItemSelectionModel
+QItemSelectionModel::_ZTV19QItemSelectionModel: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QItemSelectionModel)
+16 (int (*)(...))QItemSelectionModel::metaObject
+24 (int (*)(...))QItemSelectionModel::qt_metacast
+32 (int (*)(...))QItemSelectionModel::qt_metacall
+40 (int (*)(...))QItemSelectionModel::~QItemSelectionModel
+48 (int (*)(...))QItemSelectionModel::~QItemSelectionModel
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QItemSelectionModel::setCurrentIndex
+120 (int (*)(...))QItemSelectionModel::select
+128 (int (*)(...))QItemSelectionModel::select
+136 (int (*)(...))QItemSelectionModel::clear
+144 (int (*)(...))QItemSelectionModel::reset
+152 (int (*)(...))QItemSelectionModel::clearCurrentIndex
+
+Class QItemSelectionModel
+ size=16 align=8
+ base size=16 base align=8
+QItemSelectionModel (0x0x7f21b0382340) 0
+ vptr=((& QItemSelectionModel::_ZTV19QItemSelectionModel) + 16u)
+ QObject (0x0x7f21b032e720) 0
+ primary-for QItemSelectionModel (0x0x7f21b0382340)
+
+Class QItemSelection
+ size=8 align=8
+ base size=8 base align=8
+QItemSelection (0x0x7f21b0382548) 0
+ QList<QItemSelectionRange> (0x0x7f21b03825b0) 0
+ QListSpecialMethods<QItemSelectionRange> (0x0x7f21b032ea80) 0 empty
+
+Class QJsonValue
+ size=24 align=8
+ base size=20 base align=8
+QJsonValue (0x0x7f21b032ef60) 0
+
+Class QJsonValueRef
+ size=16 align=8
+ base size=12 base align=8
+QJsonValueRef (0x0x7f21b01836c0) 0
+
+Class QJsonValuePtr
+ size=24 align=8
+ base size=24 base align=8
+QJsonValuePtr (0x0x7f21b0183c00) 0
+
+Class QJsonValueRefPtr
+ size=16 align=8
+ base size=16 base align=8
+QJsonValueRefPtr (0x0x7f21b0183c60) 0
+
+Class QJsonArray::iterator
+ size=16 align=8
+ base size=12 base align=8
+QJsonArray::iterator (0x0x7f21b0183e40) 0
+
+Class QJsonArray::const_iterator
+ size=16 align=8
+ base size=12 base align=8
+QJsonArray::const_iterator (0x0x7f21b0183ea0) 0
+
+Class QJsonArray
+ size=16 align=8
+ base size=16 base align=8
+QJsonArray (0x0x7f21b0183de0) 0
+
+Class QJsonParseError
+ size=8 align=4
+ base size=8 base align=4
+QJsonParseError (0x0x7f21afef4120) 0
+
+Class QJsonDocument
+ size=8 align=8
+ base size=8 base align=8
+QJsonDocument (0x0x7f21afef4180) 0
+
+Class QJsonObject::iterator
+ size=16 align=8
+ base size=12 base align=8
+QJsonObject::iterator (0x0x7f21afef47e0) 0
+
+Class QJsonObject::const_iterator
+ size=16 align=8
+ base size=12 base align=8
+QJsonObject::const_iterator (0x0x7f21afef4840) 0
+
+Class QJsonObject
+ size=16 align=8
+ base size=16 base align=8
+QJsonObject (0x0x7f21afef4780) 0
+
+Class QLibrary::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QLibrary::QPrivateSignal (0x0x7f21afba2ae0) 0 empty
+
+Vtable for QLibrary
+QLibrary::_ZTV8QLibrary: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QLibrary)
+16 (int (*)(...))QLibrary::metaObject
+24 (int (*)(...))QLibrary::qt_metacast
+32 (int (*)(...))QLibrary::qt_metacall
+40 (int (*)(...))QLibrary::~QLibrary
+48 (int (*)(...))QLibrary::~QLibrary
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QLibrary
+ size=32 align=8
+ base size=25 base align=8
+QLibrary (0x0x7f21afba68f0) 0
+ vptr=((& QLibrary::_ZTV8QLibrary) + 16u)
+ QObject (0x0x7f21afba2a80) 0
+ primary-for QLibrary (0x0x7f21afba68f0)
+
+Class QVersionNumber::SegmentStorage
+ size=8 align=8
+ base size=8 base align=8
+QVersionNumber::SegmentStorage (0x0x7f21afc311e0) 0
+
+Class QVersionNumber
+ size=8 align=8
+ base size=8 base align=8
+QVersionNumber (0x0x7f21afba2cc0) 0
+
+Class QLibraryInfo
+ size=1 align=1
+ base size=0 base align=1
+QLibraryInfo (0x0x7f21afc316c0) 0 empty
+
+Class QPoint
+ size=8 align=4
+ base size=8 base align=4
+QPoint (0x0x7f21afc31720) 0
+
+Class QPointF
+ size=16 align=8
+ base size=16 base align=8
+QPointF (0x0x7f21afc319c0) 0
+
+Class QLine
+ size=16 align=4
+ base size=16 base align=4
+QLine (0x0x7f21afc31c60) 0
+
+Class QLineF
+ size=32 align=8
+ base size=32 base align=8
+QLineF (0x0x7f21afd26600) 0
+
+Class QLinkedListData
+ size=32 align=8
+ base size=25 base align=8
+QLinkedListData (0x0x7f21afd26f60) 0
+
+Class QLockFile
+ size=8 align=8
+ base size=8 base align=8
+QLockFile (0x0x7f21af9bb300) 0
+
+Class QLoggingCategory::AtomicBools
+ size=4 align=1
+ base size=4 base align=1
+QLoggingCategory::AtomicBools (0x0x7f21af9bb480) 0
+
+Class QLoggingCategory
+ size=24 align=8
+ base size=24 base align=8
+QLoggingCategory (0x0x7f21af9bb420) 0
+
+Class QMargins
+ size=16 align=4
+ base size=16 base align=4
+QMargins (0x0x7f21af9bb600) 0
+
+Class QMarginsF
+ size=32 align=8
+ base size=32 base align=8
+QMarginsF (0x0x7f21af9bb8a0) 0
+
+Class QMessageAuthenticationCode
+ size=8 align=8
+ base size=8 base align=8
+QMessageAuthenticationCode (0x0x7f21af9bbf00) 0
+
+Class QMetaMethod
+ size=16 align=8
+ base size=12 base align=8
+QMetaMethod (0x0x7f21af9bbf60) 0
+
+Class QMetaEnum
+ size=16 align=8
+ base size=12 base align=8
+QMetaEnum (0x0x7f21af7865a0) 0
+
+Class QMetaProperty
+ size=32 align=8
+ base size=32 base align=8
+QMetaProperty (0x0x7f21af7868a0) 0
+
+Class QMetaClassInfo
+ size=16 align=8
+ base size=12 base align=8
+QMetaClassInfo (0x0x7f21af786900) 0
+
+Class QMimeData::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QMimeData::QPrivateSignal (0x0x7f21af786c00) 0 empty
+
+Vtable for QMimeData
+QMimeData::_ZTV9QMimeData: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QMimeData)
+16 (int (*)(...))QMimeData::metaObject
+24 (int (*)(...))QMimeData::qt_metacast
+32 (int (*)(...))QMimeData::qt_metacall
+40 (int (*)(...))QMimeData::~QMimeData
+48 (int (*)(...))QMimeData::~QMimeData
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QMimeData::hasFormat
+120 (int (*)(...))QMimeData::formats
+128 (int (*)(...))QMimeData::retrieveData
+
+Class QMimeData
+ size=16 align=8
+ base size=16 base align=8
+QMimeData (0x0x7f21afb20b60) 0
+ vptr=((& QMimeData::_ZTV9QMimeData) + 16u)
+ QObject (0x0x7f21af786ba0) 0
+ primary-for QMimeData (0x0x7f21afb20b60)
+
+Class QMimeType
+ size=8 align=8
+ base size=8 base align=8
+QMimeType (0x0x7f21af786c60) 0
+
+Class QMimeDatabase
+ size=8 align=8
+ base size=8 base align=8
+QMimeDatabase (0x0x7f21af786f60) 0
+
+Class QObjectCleanupHandler::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QObjectCleanupHandler::QPrivateSignal (0x0x7f21af7f3060) 0 empty
+
+Vtable for QObjectCleanupHandler
+QObjectCleanupHandler::_ZTV21QObjectCleanupHandler: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QObjectCleanupHandler)
+16 (int (*)(...))QObjectCleanupHandler::metaObject
+24 (int (*)(...))QObjectCleanupHandler::qt_metacast
+32 (int (*)(...))QObjectCleanupHandler::qt_metacall
+40 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler
+48 (int (*)(...))QObjectCleanupHandler::~QObjectCleanupHandler
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QObjectCleanupHandler
+ size=24 align=8
+ base size=24 base align=8
+QObjectCleanupHandler (0x0x7f21afb20d68) 0
+ vptr=((& QObjectCleanupHandler::_ZTV21QObjectCleanupHandler) + 16u)
+ QObject (0x0x7f21af7f3000) 0
+ primary-for QObjectCleanupHandler (0x0x7f21afb20d68)
+
+Class QOperatingSystemVersion
+ size=16 align=4
+ base size=16 base align=4
+QOperatingSystemVersion (0x0x7f21af7f30c0) 0
+
+Class QParallelAnimationGroup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QParallelAnimationGroup::QPrivateSignal (0x0x7f21af7f3840) 0 empty
+
+Vtable for QParallelAnimationGroup
+QParallelAnimationGroup::_ZTV23QParallelAnimationGroup: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QParallelAnimationGroup)
+16 (int (*)(...))QParallelAnimationGroup::metaObject
+24 (int (*)(...))QParallelAnimationGroup::qt_metacast
+32 (int (*)(...))QParallelAnimationGroup::qt_metacall
+40 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup
+48 (int (*)(...))QParallelAnimationGroup::~QParallelAnimationGroup
+56 (int (*)(...))QParallelAnimationGroup::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QParallelAnimationGroup::duration
+120 (int (*)(...))QParallelAnimationGroup::updateCurrentTime
+128 (int (*)(...))QParallelAnimationGroup::updateState
+136 (int (*)(...))QParallelAnimationGroup::updateDirection
+
+Class QParallelAnimationGroup
+ size=16 align=8
+ base size=16 base align=8
+QParallelAnimationGroup (0x0x7f21af81d478) 0
+ vptr=((& QParallelAnimationGroup::_ZTV23QParallelAnimationGroup) + 16u)
+ QAnimationGroup (0x0x7f21af81d4e0) 0
+ primary-for QParallelAnimationGroup (0x0x7f21af81d478)
+ QAbstractAnimation (0x0x7f21af81d548) 0
+ primary-for QAnimationGroup (0x0x7f21af81d4e0)
+ QObject (0x0x7f21af7f37e0) 0
+ primary-for QAbstractAnimation (0x0x7f21af81d548)
+
+Class QPauseAnimation::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPauseAnimation::QPrivateSignal (0x0x7f21af7f3900) 0 empty
+
+Vtable for QPauseAnimation
+QPauseAnimation::_ZTV15QPauseAnimation: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QPauseAnimation)
+16 (int (*)(...))QPauseAnimation::metaObject
+24 (int (*)(...))QPauseAnimation::qt_metacast
+32 (int (*)(...))QPauseAnimation::qt_metacall
+40 (int (*)(...))QPauseAnimation::~QPauseAnimation
+48 (int (*)(...))QPauseAnimation::~QPauseAnimation
+56 (int (*)(...))QPauseAnimation::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QPauseAnimation::duration
+120 (int (*)(...))QPauseAnimation::updateCurrentTime
+128 (int (*)(...))QAbstractAnimation::updateState
+136 (int (*)(...))QAbstractAnimation::updateDirection
+
+Class QPauseAnimation
+ size=16 align=8
+ base size=16 base align=8
+QPauseAnimation (0x0x7f21af81d5b0) 0
+ vptr=((& QPauseAnimation::_ZTV15QPauseAnimation) + 16u)
+ QAbstractAnimation (0x0x7f21af81d618) 0
+ primary-for QPauseAnimation (0x0x7f21af81d5b0)
+ QObject (0x0x7f21af7f38a0) 0
+ primary-for QAbstractAnimation (0x0x7f21af81d618)
+
+Class QStaticPlugin
+ size=16 align=8
+ base size=16 base align=8
+QStaticPlugin (0x0x7f21af7f3ae0) 0
+
+Class QPluginLoader::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPluginLoader::QPrivateSignal (0x0x7f21af7f3de0) 0 empty
+
+Vtable for QPluginLoader
+QPluginLoader::_ZTV13QPluginLoader: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QPluginLoader)
+16 (int (*)(...))QPluginLoader::metaObject
+24 (int (*)(...))QPluginLoader::qt_metacast
+32 (int (*)(...))QPluginLoader::qt_metacall
+40 (int (*)(...))QPluginLoader::~QPluginLoader
+48 (int (*)(...))QPluginLoader::~QPluginLoader
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QPluginLoader
+ size=32 align=8
+ base size=25 base align=8
+QPluginLoader (0x0x7f21af81d820) 0
+ vptr=((& QPluginLoader::_ZTV13QPluginLoader) + 16u)
+ QObject (0x0x7f21af7f3d80) 0
+ primary-for QPluginLoader (0x0x7f21af81d820)
+
+Class QProcessEnvironment
+ size=8 align=8
+ base size=8 base align=8
+QProcessEnvironment (0x0x7f21af7f3e40) 0
+
+Class QProcess::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QProcess::QPrivateSignal (0x0x7f21af899540) 0 empty
+
+Vtable for QProcess
+QProcess::_ZTV8QProcess: 31u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QProcess)
+16 (int (*)(...))QProcess::metaObject
+24 (int (*)(...))QProcess::qt_metacast
+32 (int (*)(...))QProcess::qt_metacall
+40 (int (*)(...))QProcess::~QProcess
+48 (int (*)(...))QProcess::~QProcess
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QProcess::isSequential
+120 (int (*)(...))QProcess::open
+128 (int (*)(...))QProcess::close
+136 (int (*)(...))QIODevice::pos
+144 (int (*)(...))QIODevice::size
+152 (int (*)(...))QIODevice::seek
+160 (int (*)(...))QProcess::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QProcess::bytesAvailable
+184 (int (*)(...))QProcess::bytesToWrite
+192 (int (*)(...))QProcess::canReadLine
+200 (int (*)(...))QProcess::waitForReadyRead
+208 (int (*)(...))QProcess::waitForBytesWritten
+216 (int (*)(...))QProcess::readData
+224 (int (*)(...))QIODevice::readLineData
+232 (int (*)(...))QProcess::writeData
+240 (int (*)(...))QProcess::setupChildProcess
+
+Class QProcess
+ size=16 align=8
+ base size=16 base align=8
+QProcess (0x0x7f21af81dea0) 0
+ vptr=((& QProcess::_ZTV8QProcess) + 16u)
+ QIODevice (0x0x7f21af81df08) 0
+ primary-for QProcess (0x0x7f21af81dea0)
+ QObject (0x0x7f21af8994e0) 0
+ primary-for QIODevice (0x0x7f21af81df08)
+
+Class QVariantAnimation::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QVariantAnimation::QPrivateSignal (0x0x7f21af899600) 0 empty
+
+Vtable for QVariantAnimation
+QVariantAnimation::_ZTV17QVariantAnimation: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QVariantAnimation)
+16 (int (*)(...))QVariantAnimation::metaObject
+24 (int (*)(...))QVariantAnimation::qt_metacast
+32 (int (*)(...))QVariantAnimation::qt_metacall
+40 (int (*)(...))QVariantAnimation::~QVariantAnimation
+48 (int (*)(...))QVariantAnimation::~QVariantAnimation
+56 (int (*)(...))QVariantAnimation::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QVariantAnimation::duration
+120 (int (*)(...))QVariantAnimation::updateCurrentTime
+128 (int (*)(...))QVariantAnimation::updateState
+136 (int (*)(...))QAbstractAnimation::updateDirection
+144 (int (*)(...))QVariantAnimation::updateCurrentValue
+152 (int (*)(...))QVariantAnimation::interpolated
+
+Class QVariantAnimation
+ size=16 align=8
+ base size=16 base align=8
+QVariantAnimation (0x0x7f21af81df70) 0
+ vptr=((& QVariantAnimation::_ZTV17QVariantAnimation) + 16u)
+ QAbstractAnimation (0x0x7f21af8dc000) 0
+ primary-for QVariantAnimation (0x0x7f21af81df70)
+ QObject (0x0x7f21af8995a0) 0
+ primary-for QAbstractAnimation (0x0x7f21af8dc000)
+
+Class QPropertyAnimation::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPropertyAnimation::QPrivateSignal (0x0x7f21af8996c0) 0 empty
+
+Vtable for QPropertyAnimation
+QPropertyAnimation::_ZTV18QPropertyAnimation: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QPropertyAnimation)
+16 (int (*)(...))QPropertyAnimation::metaObject
+24 (int (*)(...))QPropertyAnimation::qt_metacast
+32 (int (*)(...))QPropertyAnimation::qt_metacall
+40 (int (*)(...))QPropertyAnimation::~QPropertyAnimation
+48 (int (*)(...))QPropertyAnimation::~QPropertyAnimation
+56 (int (*)(...))QPropertyAnimation::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QVariantAnimation::duration
+120 (int (*)(...))QVariantAnimation::updateCurrentTime
+128 (int (*)(...))QPropertyAnimation::updateState
+136 (int (*)(...))QAbstractAnimation::updateDirection
+144 (int (*)(...))QPropertyAnimation::updateCurrentValue
+152 (int (*)(...))QVariantAnimation::interpolated
+
+Class QPropertyAnimation
+ size=16 align=8
+ base size=16 base align=8
+QPropertyAnimation (0x0x7f21af8dc0d0) 0
+ vptr=((& QPropertyAnimation::_ZTV18QPropertyAnimation) + 16u)
+ QVariantAnimation (0x0x7f21af8dc138) 0
+ primary-for QPropertyAnimation (0x0x7f21af8dc0d0)
+ QAbstractAnimation (0x0x7f21af8dc1a0) 0
+ primary-for QVariantAnimation (0x0x7f21af8dc138)
+ QObject (0x0x7f21af899660) 0
+ primary-for QAbstractAnimation (0x0x7f21af8dc1a0)
+
+Class QRandomGenerator::Storage
+ size=2504 align=8
+ base size=2504 base align=8
+QRandomGenerator::Storage (0x0x7f21af8997e0) 0
+
+Class QRandomGenerator
+ size=2512 align=8
+ base size=2512 base align=8
+QRandomGenerator (0x0x7f21af899780) 0
+
+Class QRandomGenerator64
+ size=2512 align=8
+ base size=2512 base align=8
+QRandomGenerator64 (0x0x7f21af597478) 0
+ QRandomGenerator (0x0x7f21af582780) 0
+
+Class QReadWriteLock
+ size=8 align=8
+ base size=8 base align=8
+QReadWriteLock (0x0x7f21af582840) 0
+
+Class QReadLocker
+ size=8 align=8
+ base size=8 base align=8
+QReadLocker (0x0x7f21af582ae0) 0
+
+Class QWriteLocker
+ size=8 align=8
+ base size=8 base align=8
+QWriteLocker (0x0x7f21af582ba0) 0
+
+Class QSize
+ size=8 align=4
+ base size=8 base align=4
+QSize (0x0x7f21af582c60) 0
+
+Class QSizeF
+ size=16 align=8
+ base size=16 base align=8
+QSizeF (0x0x7f21af582f00) 0
+
+Class QRect
+ size=16 align=4
+ base size=16 base align=4
+QRect (0x0x7f21af69b1e0) 0
+
+Class QRectF
+ size=32 align=8
+ base size=32 base align=8
+QRectF (0x0x7f21af69b480) 0
+
+Class QRegularExpression
+ size=8 align=8
+ base size=8 base align=8
+QRegularExpression (0x0x7f21af69b720) 0
+
+Class QRegularExpressionMatch
+ size=8 align=8
+ base size=8 base align=8
+QRegularExpressionMatch (0x0x7f21af69bd20) 0
+
+Class QRegularExpressionMatchIterator
+ size=8 align=8
+ base size=8 base align=8
+QRegularExpressionMatchIterator (0x0x7f21af484060) 0
+
+Class QResource
+ size=8 align=8
+ base size=8 base align=8
+QResource (0x0x7f21af484360) 0
+
+Class QSaveFile::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSaveFile::QPrivateSignal (0x0x7f21af4844e0) 0 empty
+
+Vtable for QSaveFile
+QSaveFile::_ZTV9QSaveFile: 34u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QSaveFile)
+16 (int (*)(...))QSaveFile::metaObject
+24 (int (*)(...))QSaveFile::qt_metacast
+32 (int (*)(...))QSaveFile::qt_metacall
+40 (int (*)(...))QSaveFile::~QSaveFile
+48 (int (*)(...))QSaveFile::~QSaveFile
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QFileDevice::isSequential
+120 (int (*)(...))QSaveFile::open
+128 (int (*)(...))QSaveFile::close
+136 (int (*)(...))QFileDevice::pos
+144 (int (*)(...))QFileDevice::size
+152 (int (*)(...))QFileDevice::seek
+160 (int (*)(...))QFileDevice::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QIODevice::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))QFileDevice::readData
+224 (int (*)(...))QFileDevice::readLineData
+232 (int (*)(...))QSaveFile::writeData
+240 (int (*)(...))QSaveFile::fileName
+248 (int (*)(...))QFileDevice::resize
+256 (int (*)(...))QFileDevice::permissions
+264 (int (*)(...))QFileDevice::setPermissions
+
+Class QSaveFile
+ size=16 align=8
+ base size=16 base align=8
+QSaveFile (0x0x7f21af409680) 0
+ vptr=((& QSaveFile::_ZTV9QSaveFile) + 16u)
+ QFileDevice (0x0x7f21af4096e8) 0
+ primary-for QSaveFile (0x0x7f21af409680)
+ QIODevice (0x0x7f21af409750) 0
+ primary-for QFileDevice (0x0x7f21af4096e8)
+ QObject (0x0x7f21af484480) 0
+ primary-for QIODevice (0x0x7f21af409750)
+
+Class QSemaphore
+ size=8 align=8
+ base size=8 base align=8
+QSemaphore (0x0x7f21af4845a0) 0
+
+Class QSemaphoreReleaser
+ size=16 align=8
+ base size=12 base align=8
+QSemaphoreReleaser (0x0x7f21af484600) 0
+
+Class QSequentialAnimationGroup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSequentialAnimationGroup::QPrivateSignal (0x0x7f21af19dc00) 0 empty
+
+Vtable for QSequentialAnimationGroup
+QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI25QSequentialAnimationGroup)
+16 (int (*)(...))QSequentialAnimationGroup::metaObject
+24 (int (*)(...))QSequentialAnimationGroup::qt_metacast
+32 (int (*)(...))QSequentialAnimationGroup::qt_metacall
+40 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup
+48 (int (*)(...))QSequentialAnimationGroup::~QSequentialAnimationGroup
+56 (int (*)(...))QSequentialAnimationGroup::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QSequentialAnimationGroup::duration
+120 (int (*)(...))QSequentialAnimationGroup::updateCurrentTime
+128 (int (*)(...))QSequentialAnimationGroup::updateState
+136 (int (*)(...))QSequentialAnimationGroup::updateDirection
+
+Class QSequentialAnimationGroup
+ size=16 align=8
+ base size=16 base align=8
+QSequentialAnimationGroup (0x0x7f21af19bf70) 0
+ vptr=((& QSequentialAnimationGroup::_ZTV25QSequentialAnimationGroup) + 16u)
+ QAnimationGroup (0x0x7f21af1bc000) 0
+ primary-for QSequentialAnimationGroup (0x0x7f21af19bf70)
+ QAbstractAnimation (0x0x7f21af1bc068) 0
+ primary-for QAnimationGroup (0x0x7f21af1bc000)
+ QObject (0x0x7f21af19dba0) 0
+ primary-for QAbstractAnimation (0x0x7f21af1bc068)
+
+Class QSettings::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSettings::QPrivateSignal (0x0x7f21af19dcc0) 0 empty
+
+Vtable for QSettings
+QSettings::_ZTV9QSettings: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QSettings)
+16 (int (*)(...))QSettings::metaObject
+24 (int (*)(...))QSettings::qt_metacast
+32 (int (*)(...))QSettings::qt_metacall
+40 (int (*)(...))QSettings::~QSettings
+48 (int (*)(...))QSettings::~QSettings
+56 (int (*)(...))QSettings::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QSettings
+ size=16 align=8
+ base size=16 base align=8
+QSettings (0x0x7f21af1bc0d0) 0
+ vptr=((& QSettings::_ZTV9QSettings) + 16u)
+ QObject (0x0x7f21af19dc60) 0
+ primary-for QSettings (0x0x7f21af1bc0d0)
+
+Class QSharedMemory::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSharedMemory::QPrivateSignal (0x0x7f21af19dd80) 0 empty
+
+Vtable for QSharedMemory
+QSharedMemory::_ZTV13QSharedMemory: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QSharedMemory)
+16 (int (*)(...))QSharedMemory::metaObject
+24 (int (*)(...))QSharedMemory::qt_metacast
+32 (int (*)(...))QSharedMemory::qt_metacall
+40 (int (*)(...))QSharedMemory::~QSharedMemory
+48 (int (*)(...))QSharedMemory::~QSharedMemory
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QSharedMemory
+ size=16 align=8
+ base size=16 base align=8
+QSharedMemory (0x0x7f21af1bc138) 0
+ vptr=((& QSharedMemory::_ZTV13QSharedMemory) + 16u)
+ QObject (0x0x7f21af19dd20) 0
+ primary-for QSharedMemory (0x0x7f21af1bc138)
+
+Class QSignalMapper::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSignalMapper::QPrivateSignal (0x0x7f21af19de40) 0 empty
+
+Vtable for QSignalMapper
+QSignalMapper::_ZTV13QSignalMapper: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QSignalMapper)
+16 (int (*)(...))QSignalMapper::metaObject
+24 (int (*)(...))QSignalMapper::qt_metacast
+32 (int (*)(...))QSignalMapper::qt_metacall
+40 (int (*)(...))QSignalMapper::~QSignalMapper
+48 (int (*)(...))QSignalMapper::~QSignalMapper
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QSignalMapper
+ size=16 align=8
+ base size=16 base align=8
+QSignalMapper (0x0x7f21af1bc1a0) 0
+ vptr=((& QSignalMapper::_ZTV13QSignalMapper) + 16u)
+ QObject (0x0x7f21af19dde0) 0
+ primary-for QSignalMapper (0x0x7f21af1bc1a0)
+
+Class QSignalTransition::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSignalTransition::QPrivateSignal (0x0x7f21af19df00) 0 empty
+
+Vtable for QSignalTransition
+QSignalTransition::_ZTV17QSignalTransition: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QSignalTransition)
+16 (int (*)(...))QSignalTransition::metaObject
+24 (int (*)(...))QSignalTransition::qt_metacast
+32 (int (*)(...))QSignalTransition::qt_metacall
+40 (int (*)(...))QSignalTransition::~QSignalTransition
+48 (int (*)(...))QSignalTransition::~QSignalTransition
+56 (int (*)(...))QSignalTransition::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QSignalTransition::eventTest
+120 (int (*)(...))QSignalTransition::onTransition
+
+Class QSignalTransition
+ size=16 align=8
+ base size=16 base align=8
+QSignalTransition (0x0x7f21af1bc208) 0
+ vptr=((& QSignalTransition::_ZTV17QSignalTransition) + 16u)
+ QAbstractTransition (0x0x7f21af1bc270) 0
+ primary-for QSignalTransition (0x0x7f21af1bc208)
+ QObject (0x0x7f21af19dea0) 0
+ primary-for QAbstractTransition (0x0x7f21af1bc270)
+
+Class QSocketNotifier::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSocketNotifier::QPrivateSignal (0x0x7f21af22d000) 0 empty
+
+Vtable for QSocketNotifier
+QSocketNotifier::_ZTV15QSocketNotifier: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QSocketNotifier)
+16 (int (*)(...))QSocketNotifier::metaObject
+24 (int (*)(...))QSocketNotifier::qt_metacast
+32 (int (*)(...))QSocketNotifier::qt_metacall
+40 (int (*)(...))QSocketNotifier::~QSocketNotifier
+48 (int (*)(...))QSocketNotifier::~QSocketNotifier
+56 (int (*)(...))QSocketNotifier::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QSocketNotifier
+ size=16 align=8
+ base size=16 base align=8
+QSocketNotifier (0x0x7f21af1bc2d8) 0
+ vptr=((& QSocketNotifier::_ZTV15QSocketNotifier) + 16u)
+ QObject (0x0x7f21af19df60) 0
+ primary-for QSocketNotifier (0x0x7f21af1bc2d8)
+
+Class QSortFilterProxyModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSortFilterProxyModel::QPrivateSignal (0x0x7f21af22d0c0) 0 empty
+
+Vtable for QSortFilterProxyModel
+QSortFilterProxyModel::_ZTV21QSortFilterProxyModel: 56u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QSortFilterProxyModel)
+16 (int (*)(...))QSortFilterProxyModel::metaObject
+24 (int (*)(...))QSortFilterProxyModel::qt_metacast
+32 (int (*)(...))QSortFilterProxyModel::qt_metacall
+40 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel
+48 (int (*)(...))QSortFilterProxyModel::~QSortFilterProxyModel
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QSortFilterProxyModel::index
+120 (int (*)(...))QSortFilterProxyModel::parent
+128 (int (*)(...))QSortFilterProxyModel::sibling
+136 (int (*)(...))QSortFilterProxyModel::rowCount
+144 (int (*)(...))QSortFilterProxyModel::columnCount
+152 (int (*)(...))QSortFilterProxyModel::hasChildren
+160 (int (*)(...))QSortFilterProxyModel::data
+168 (int (*)(...))QSortFilterProxyModel::setData
+176 (int (*)(...))QSortFilterProxyModel::headerData
+184 (int (*)(...))QSortFilterProxyModel::setHeaderData
+192 (int (*)(...))QAbstractProxyModel::itemData
+200 (int (*)(...))QAbstractProxyModel::setItemData
+208 (int (*)(...))QSortFilterProxyModel::mimeTypes
+216 (int (*)(...))QSortFilterProxyModel::mimeData
+224 (int (*)(...))QAbstractProxyModel::canDropMimeData
+232 (int (*)(...))QSortFilterProxyModel::dropMimeData
+240 (int (*)(...))QSortFilterProxyModel::supportedDropActions
+248 (int (*)(...))QAbstractProxyModel::supportedDragActions
+256 (int (*)(...))QSortFilterProxyModel::insertRows
+264 (int (*)(...))QSortFilterProxyModel::insertColumns
+272 (int (*)(...))QSortFilterProxyModel::removeRows
+280 (int (*)(...))QSortFilterProxyModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QSortFilterProxyModel::fetchMore
+312 (int (*)(...))QSortFilterProxyModel::canFetchMore
+320 (int (*)(...))QSortFilterProxyModel::flags
+328 (int (*)(...))QSortFilterProxyModel::sort
+336 (int (*)(...))QSortFilterProxyModel::buddy
+344 (int (*)(...))QSortFilterProxyModel::match
+352 (int (*)(...))QSortFilterProxyModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractProxyModel::submit
+376 (int (*)(...))QAbstractProxyModel::revert
+384 (int (*)(...))QSortFilterProxyModel::setSourceModel
+392 (int (*)(...))QSortFilterProxyModel::mapToSource
+400 (int (*)(...))QSortFilterProxyModel::mapFromSource
+408 (int (*)(...))QSortFilterProxyModel::mapSelectionToSource
+416 (int (*)(...))QSortFilterProxyModel::mapSelectionFromSource
+424 (int (*)(...))QSortFilterProxyModel::filterAcceptsRow
+432 (int (*)(...))QSortFilterProxyModel::filterAcceptsColumn
+440 (int (*)(...))QSortFilterProxyModel::lessThan
+
+Class QSortFilterProxyModel
+ size=16 align=8
+ base size=16 base align=8
+QSortFilterProxyModel (0x0x7f21af1bc340) 0
+ vptr=((& QSortFilterProxyModel::_ZTV21QSortFilterProxyModel) + 16u)
+ QAbstractProxyModel (0x0x7f21af1bc3a8) 0
+ primary-for QSortFilterProxyModel (0x0x7f21af1bc340)
+ QAbstractItemModel (0x0x7f21af1bc410) 0
+ primary-for QAbstractProxyModel (0x0x7f21af1bc3a8)
+ QObject (0x0x7f21af22d060) 0
+ primary-for QAbstractItemModel (0x0x7f21af1bc410)
+
+Class QStandardPaths
+ size=1 align=1
+ base size=0 base align=1
+QStandardPaths (0x0x7f21af22d180) 0 empty
+
+Class QState::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QState::QPrivateSignal (0x0x7f21af22d3c0) 0 empty
+
+Vtable for QState
+QState::_ZTV6QState: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QState)
+16 (int (*)(...))QState::metaObject
+24 (int (*)(...))QState::qt_metacast
+32 (int (*)(...))QState::qt_metacall
+40 (int (*)(...))QState::~QState
+48 (int (*)(...))QState::~QState
+56 (int (*)(...))QState::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QState::onEntry
+120 (int (*)(...))QState::onExit
+
+Class QState
+ size=16 align=8
+ base size=16 base align=8
+QState (0x0x7f21af1bc5b0) 0
+ vptr=((& QState::_ZTV6QState) + 16u)
+ QAbstractState (0x0x7f21af1bc618) 0
+ primary-for QState (0x0x7f21af1bc5b0)
+ QObject (0x0x7f21af22d360) 0
+ primary-for QAbstractState (0x0x7f21af1bc618)
+
+Class QStateMachine::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QStateMachine::QPrivateSignal (0x0x7f21af22d4e0) 0 empty
+
+Vtable for QStateMachine::SignalEvent
+QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN13QStateMachine11SignalEventE)
+16 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent
+24 (int (*)(...))QStateMachine::SignalEvent::~SignalEvent
+
+Class QStateMachine::SignalEvent
+ size=48 align=8
+ base size=48 base align=8
+QStateMachine::SignalEvent (0x0x7f21af1bc7b8) 0
+ vptr=((& QStateMachine::SignalEvent::_ZTVN13QStateMachine11SignalEventE) + 16u)
+ QEvent (0x0x7f21af22d540) 0
+ primary-for QStateMachine::SignalEvent (0x0x7f21af1bc7b8)
+
+Vtable for QStateMachine::WrappedEvent
+QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN13QStateMachine12WrappedEventE)
+16 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent
+24 (int (*)(...))QStateMachine::WrappedEvent::~WrappedEvent
+
+Class QStateMachine::WrappedEvent
+ size=40 align=8
+ base size=40 base align=8
+QStateMachine::WrappedEvent (0x0x7f21af1bc820) 0
+ vptr=((& QStateMachine::WrappedEvent::_ZTVN13QStateMachine12WrappedEventE) + 16u)
+ QEvent (0x0x7f21af22d5a0) 0
+ primary-for QStateMachine::WrappedEvent (0x0x7f21af1bc820)
+
+Vtable for QStateMachine
+QStateMachine::_ZTV13QStateMachine: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QStateMachine)
+16 (int (*)(...))QStateMachine::metaObject
+24 (int (*)(...))QStateMachine::qt_metacast
+32 (int (*)(...))QStateMachine::qt_metacall
+40 (int (*)(...))QStateMachine::~QStateMachine
+48 (int (*)(...))QStateMachine::~QStateMachine
+56 (int (*)(...))QStateMachine::event
+64 (int (*)(...))QStateMachine::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QStateMachine::onEntry
+120 (int (*)(...))QStateMachine::onExit
+128 (int (*)(...))QStateMachine::beginSelectTransitions
+136 (int (*)(...))QStateMachine::endSelectTransitions
+144 (int (*)(...))QStateMachine::beginMicrostep
+152 (int (*)(...))QStateMachine::endMicrostep
+
+Class QStateMachine
+ size=16 align=8
+ base size=16 base align=8
+QStateMachine (0x0x7f21af1bc680) 0
+ vptr=((& QStateMachine::_ZTV13QStateMachine) + 16u)
+ QState (0x0x7f21af1bc6e8) 0
+ primary-for QStateMachine (0x0x7f21af1bc680)
+ QAbstractState (0x0x7f21af1bc750) 0
+ primary-for QState (0x0x7f21af1bc6e8)
+ QObject (0x0x7f21af22d480) 0
+ primary-for QAbstractState (0x0x7f21af1bc750)
+
+Class QStorageInfo
+ size=8 align=8
+ base size=8 base align=8
+QStorageInfo (0x0x7f21af22d600) 0
+
+Class QAbstractConcatenable
+ size=1 align=1
+ base size=0 base align=1
+QAbstractConcatenable (0x0x7f21af31a540) 0 empty
+
+Class QStringListModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QStringListModel::QPrivateSignal (0x0x7f21aefab060) 0 empty
+
+Vtable for QStringListModel
+QStringListModel::_ZTV16QStringListModel: 48u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QStringListModel)
+16 (int (*)(...))QStringListModel::metaObject
+24 (int (*)(...))QStringListModel::qt_metacast
+32 (int (*)(...))QStringListModel::qt_metacall
+40 (int (*)(...))QStringListModel::~QStringListModel
+48 (int (*)(...))QStringListModel::~QStringListModel
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAbstractListModel::index
+120 (int (*)(...))QAbstractListModel::parent
+128 (int (*)(...))QStringListModel::sibling
+136 (int (*)(...))QStringListModel::rowCount
+144 (int (*)(...))QAbstractListModel::columnCount
+152 (int (*)(...))QAbstractListModel::hasChildren
+160 (int (*)(...))QStringListModel::data
+168 (int (*)(...))QStringListModel::setData
+176 (int (*)(...))QAbstractItemModel::headerData
+184 (int (*)(...))QAbstractItemModel::setHeaderData
+192 (int (*)(...))QAbstractItemModel::itemData
+200 (int (*)(...))QAbstractItemModel::setItemData
+208 (int (*)(...))QAbstractItemModel::mimeTypes
+216 (int (*)(...))QAbstractItemModel::mimeData
+224 (int (*)(...))QAbstractItemModel::canDropMimeData
+232 (int (*)(...))QAbstractListModel::dropMimeData
+240 (int (*)(...))QStringListModel::supportedDropActions
+248 (int (*)(...))QAbstractItemModel::supportedDragActions
+256 (int (*)(...))QStringListModel::insertRows
+264 (int (*)(...))QAbstractItemModel::insertColumns
+272 (int (*)(...))QStringListModel::removeRows
+280 (int (*)(...))QAbstractItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractItemModel::fetchMore
+312 (int (*)(...))QAbstractItemModel::canFetchMore
+320 (int (*)(...))QStringListModel::flags
+328 (int (*)(...))QStringListModel::sort
+336 (int (*)(...))QAbstractItemModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractItemModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractItemModel::submit
+376 (int (*)(...))QAbstractItemModel::revert
+
+Class QStringListModel
+ size=24 align=8
+ base size=24 base align=8
+QStringListModel (0x0x7f21af31ed00) 0
+ vptr=((& QStringListModel::_ZTV16QStringListModel) + 16u)
+ QAbstractListModel (0x0x7f21af31ed68) 0
+ primary-for QStringListModel (0x0x7f21af31ed00)
+ QAbstractItemModel (0x0x7f21af31edd0) 0
+ primary-for QAbstractListModel (0x0x7f21af31ed68)
+ QObject (0x0x7f21aefab000) 0
+ primary-for QAbstractItemModel (0x0x7f21af31edd0)
+
+Class QSystemSemaphore
+ size=8 align=8
+ base size=8 base align=8
+QSystemSemaphore (0x0x7f21aefab0c0) 0
+
+Class QTemporaryDir
+ size=8 align=8
+ base size=8 base align=8
+QTemporaryDir (0x0x7f21aefab180) 0
+
+Class QTemporaryFile::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTemporaryFile::QPrivateSignal (0x0x7f21aefab2a0) 0 empty
+
+Vtable for QTemporaryFile
+QTemporaryFile::_ZTV14QTemporaryFile: 34u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QTemporaryFile)
+16 (int (*)(...))QTemporaryFile::metaObject
+24 (int (*)(...))QTemporaryFile::qt_metacast
+32 (int (*)(...))QTemporaryFile::qt_metacall
+40 (int (*)(...))QTemporaryFile::~QTemporaryFile
+48 (int (*)(...))QTemporaryFile::~QTemporaryFile
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QFileDevice::isSequential
+120 (int (*)(...))QTemporaryFile::open
+128 (int (*)(...))QFileDevice::close
+136 (int (*)(...))QFileDevice::pos
+144 (int (*)(...))QFile::size
+152 (int (*)(...))QFileDevice::seek
+160 (int (*)(...))QFileDevice::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QIODevice::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))QFileDevice::readData
+224 (int (*)(...))QFileDevice::readLineData
+232 (int (*)(...))QFileDevice::writeData
+240 (int (*)(...))QTemporaryFile::fileName
+248 (int (*)(...))QFile::resize
+256 (int (*)(...))QFile::permissions
+264 (int (*)(...))QFile::setPermissions
+
+Class QTemporaryFile
+ size=16 align=8
+ base size=16 base align=8
+QTemporaryFile (0x0x7f21af31ee38) 0
+ vptr=((& QTemporaryFile::_ZTV14QTemporaryFile) + 16u)
+ QFile (0x0x7f21af31eea0) 0
+ primary-for QTemporaryFile (0x0x7f21af31ee38)
+ QFileDevice (0x0x7f21af31ef08) 0
+ primary-for QFile (0x0x7f21af31eea0)
+ QIODevice (0x0x7f21af31ef70) 0
+ primary-for QFileDevice (0x0x7f21af31ef08)
+ QObject (0x0x7f21aefab240) 0
+ primary-for QIODevice (0x0x7f21af31ef70)
+
+Class QTextBoundaryFinder
+ size=48 align=8
+ base size=48 base align=8
+QTextBoundaryFinder (0x0x7f21aefab300) 0
+
+Class QTextCodec::ConverterState
+ size=32 align=8
+ base size=32 base align=8
+QTextCodec::ConverterState (0x0x7f21aefab540) 0
+
+Vtable for QTextCodec
+QTextCodec::_ZTV10QTextCodec: 9u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTextCodec)
+16 (int (*)(...))__cxa_pure_virtual
+24 (int (*)(...))QTextCodec::aliases
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 0u
+64 0u
+
+Class QTextCodec
+ size=8 align=8
+ base size=8 base align=8
+QTextCodec (0x0x7f21aefab4e0) 0 nearly-empty
+ vptr=((& QTextCodec::_ZTV10QTextCodec) + 16u)
+
+Class QTextEncoder
+ size=40 align=8
+ base size=40 base align=8
+QTextEncoder (0x0x7f21aefab720) 0
+
+Class QTextDecoder
+ size=40 align=8
+ base size=40 base align=8
+QTextDecoder (0x0x7f21aefab780) 0
+
+Class std::__mutex_base
+ size=40 align=8
+ base size=40 base align=8
+std::__mutex_base (0x0x7f21aefab7e0) 0
+
+Class std::__recursive_mutex_base
+ size=40 align=8
+ base size=40 base align=8
+std::__recursive_mutex_base (0x0x7f21aefab840) 0
+
+Class std::mutex
+ size=40 align=8
+ base size=40 base align=8
+std::mutex (0x0x7f21aeffb1a0) 0
+ std::__mutex_base (0x0x7f21aefab8a0) 0
+
+Class std::recursive_mutex
+ size=40 align=8
+ base size=40 base align=8
+std::recursive_mutex (0x0x7f21aeffb208) 0
+ std::__recursive_mutex_base (0x0x7f21aefab900) 0
+
+Class std::timed_mutex
+ size=40 align=8
+ base size=40 base align=8
+std::timed_mutex (0x0x7f21af09a070) 0
+ std::__mutex_base (0x0x7f21aefaba20) 0
+ std::__timed_mutex_impl<std::timed_mutex> (0x0x7f21aefaba80) 0 empty
+
+Class std::recursive_timed_mutex
+ size=40 align=8
+ base size=40 base align=8
+std::recursive_timed_mutex (0x0x7f21af09acb0) 0
+ std::__recursive_mutex_base (0x0x7f21aefabb40) 0
+ std::__timed_mutex_impl<std::recursive_timed_mutex> (0x0x7f21aefabba0) 0 empty
+
+Class std::defer_lock_t
+ size=1 align=1
+ base size=0 base align=1
+std::defer_lock_t (0x0x7f21aefabc00) 0 empty
+
+Class std::try_to_lock_t
+ size=1 align=1
+ base size=0 base align=1
+std::try_to_lock_t (0x0x7f21aefabc60) 0 empty
+
+Class std::adopt_lock_t
+ size=1 align=1
+ base size=0 base align=1
+std::adopt_lock_t (0x0x7f21aefabcc0) 0 empty
+
+Class std::once_flag
+ size=4 align=4
+ base size=4 base align=4
+std::once_flag (0x0x7f21aefabf00) 0
+
+Vtable for __gnu_cxx::__concurrence_lock_error
+__gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_lock_errorE)
+16 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error
+24 (int (*)(...))__gnu_cxx::__concurrence_lock_error::~__concurrence_lock_error
+32 (int (*)(...))__gnu_cxx::__concurrence_lock_error::what
+
+Class __gnu_cxx::__concurrence_lock_error
+ size=8 align=8
+ base size=8 base align=8
+__gnu_cxx::__concurrence_lock_error (0x0x7f21aeffb340) 0 nearly-empty
+ vptr=((& __gnu_cxx::__concurrence_lock_error::_ZTVN9__gnu_cxx24__concurrence_lock_errorE) + 16u)
+ std::exception (0x0x7f21af101000) 0 nearly-empty
+ primary-for __gnu_cxx::__concurrence_lock_error (0x0x7f21aeffb340)
+
+Vtable for __gnu_cxx::__concurrence_unlock_error
+__gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN9__gnu_cxx26__concurrence_unlock_errorE)
+16 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error
+24 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::~__concurrence_unlock_error
+32 (int (*)(...))__gnu_cxx::__concurrence_unlock_error::what
+
+Class __gnu_cxx::__concurrence_unlock_error
+ size=8 align=8
+ base size=8 base align=8
+__gnu_cxx::__concurrence_unlock_error (0x0x7f21aeffb3a8) 0 nearly-empty
+ vptr=((& __gnu_cxx::__concurrence_unlock_error::_ZTVN9__gnu_cxx26__concurrence_unlock_errorE) + 16u)
+ std::exception (0x0x7f21af1010c0) 0 nearly-empty
+ primary-for __gnu_cxx::__concurrence_unlock_error (0x0x7f21aeffb3a8)
+
+Vtable for __gnu_cxx::__concurrence_broadcast_error
+__gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN9__gnu_cxx29__concurrence_broadcast_errorE)
+16 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error
+24 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::~__concurrence_broadcast_error
+32 (int (*)(...))__gnu_cxx::__concurrence_broadcast_error::what
+
+Class __gnu_cxx::__concurrence_broadcast_error
+ size=8 align=8
+ base size=8 base align=8
+__gnu_cxx::__concurrence_broadcast_error (0x0x7f21aeffb410) 0 nearly-empty
+ vptr=((& __gnu_cxx::__concurrence_broadcast_error::_ZTVN9__gnu_cxx29__concurrence_broadcast_errorE) + 16u)
+ std::exception (0x0x7f21af101180) 0 nearly-empty
+ primary-for __gnu_cxx::__concurrence_broadcast_error (0x0x7f21aeffb410)
+
+Vtable for __gnu_cxx::__concurrence_wait_error
+__gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN9__gnu_cxx24__concurrence_wait_errorE)
+16 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error
+24 (int (*)(...))__gnu_cxx::__concurrence_wait_error::~__concurrence_wait_error
+32 (int (*)(...))__gnu_cxx::__concurrence_wait_error::what
+
+Class __gnu_cxx::__concurrence_wait_error
+ size=8 align=8
+ base size=8 base align=8
+__gnu_cxx::__concurrence_wait_error (0x0x7f21aeffb4e0) 0 nearly-empty
+ vptr=((& __gnu_cxx::__concurrence_wait_error::_ZTVN9__gnu_cxx24__concurrence_wait_errorE) + 16u)
+ std::exception (0x0x7f21af101240) 0 nearly-empty
+ primary-for __gnu_cxx::__concurrence_wait_error (0x0x7f21aeffb4e0)
+
+Class __gnu_cxx::__mutex
+ size=40 align=8
+ base size=40 base align=8
+__gnu_cxx::__mutex (0x0x7f21af101300) 0
+
+Class __gnu_cxx::__recursive_mutex
+ size=40 align=8
+ base size=40 base align=8
+__gnu_cxx::__recursive_mutex (0x0x7f21af101360) 0
+
+Class __gnu_cxx::__scoped_lock
+ size=8 align=8
+ base size=8 base align=8
+__gnu_cxx::__scoped_lock (0x0x7f21af1013c0) 0
+
+Class __gnu_cxx::__cond
+ size=48 align=8
+ base size=48 base align=8
+__gnu_cxx::__cond (0x0x7f21af101420) 0
+
+Vtable for std::bad_weak_ptr
+std::bad_weak_ptr::_ZTVSt12bad_weak_ptr: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt12bad_weak_ptr)
+16 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr
+24 (int (*)(...))std::bad_weak_ptr::~bad_weak_ptr
+32 (int (*)(...))std::bad_weak_ptr::what
+
+Class std::bad_weak_ptr
+ size=8 align=8
+ base size=8 base align=8
+std::bad_weak_ptr (0x0x7f21aeffb7b8) 0 nearly-empty
+ vptr=((& std::bad_weak_ptr::_ZTVSt12bad_weak_ptr) + 16u)
+ std::exception (0x0x7f21af101780) 0 nearly-empty
+ primary-for std::bad_weak_ptr (0x0x7f21aeffb7b8)
+
+Class std::_Sp_make_shared_tag
+ size=1 align=1
+ base size=0 base align=1
+std::_Sp_make_shared_tag (0x0x7f21aee35000) 0 empty
+
+Class std::_Sp_locker
+ size=2 align=1
+ base size=2 base align=1
+std::_Sp_locker (0x0x7f21aee357e0) 0
+
+Class std::thread::id
+ size=8 align=8
+ base size=8 base align=8
+std::thread::id (0x0x7f21aee359c0) 0
+
+Vtable for std::thread::_Impl_base
+std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt6thread10_Impl_baseE)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class std::thread::_Impl_base
+ size=24 align=8
+ base size=24 base align=8
+std::thread::_Impl_base (0x0x7f21aee35a20) 0
+ vptr=((& std::thread::_Impl_base::_ZTVNSt6thread10_Impl_baseE) + 16u)
+
+Class std::thread
+ size=8 align=8
+ base size=8 base align=8
+std::thread (0x0x7f21aee35960) 0
+
+Class std::condition_variable
+ size=48 align=8
+ base size=48 base align=8
+std::condition_variable (0x0x7f21aecb4660) 0
+
+Class std::__at_thread_exit_elt
+ size=16 align=8
+ base size=16 base align=8
+std::__at_thread_exit_elt (0x0x7f21aecb4720) 0
+
+Class std::_V2::condition_variable_any
+ size=64 align=8
+ base size=64 base align=8
+std::_V2::condition_variable_any (0x0x7f21aecb4780) 0
+
+Class std::__atomic_futex_unsigned_base
+ size=1 align=1
+ base size=0 base align=1
+std::__atomic_futex_unsigned_base (0x0x7f21aed40de0) 0 empty
+
+Vtable for std::future_error
+std::future_error::_ZTVSt12future_error: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTISt12future_error)
+16 (int (*)(...))std::future_error::~future_error
+24 (int (*)(...))std::future_error::~future_error
+32 (int (*)(...))std::future_error::what
+
+Class std::future_error
+ size=32 align=8
+ base size=32 base align=8
+std::future_error (0x0x7f21ae991af8) 0
+ vptr=((& std::future_error::_ZTVSt12future_error) + 16u)
+ std::logic_error (0x0x7f21ae991b60) 0
+ primary-for std::future_error (0x0x7f21ae991af8)
+ std::exception (0x0x7f21aed40f00) 0 nearly-empty
+ primary-for std::logic_error (0x0x7f21ae991b60)
+
+Class std::__future_base::_Result_base::_Deleter
+ size=1 align=1
+ base size=0 base align=1
+std::__future_base::_Result_base::_Deleter (0x0x7f21ae9f5060) 0 empty
+
+Vtable for std::__future_base::_Result_base
+std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt13__future_base12_Result_baseE)
+16 (int (*)(...))__cxa_pure_virtual
+24 0u
+32 0u
+
+Class std::__future_base::_Result_base
+ size=16 align=8
+ base size=16 base align=8
+std::__future_base::_Result_base (0x0x7f21ae9f5000) 0
+ vptr=((& std::__future_base::_Result_base::_ZTVNSt13__future_base12_Result_baseE) + 16u)
+
+Class std::__future_base::_State_baseV2::__exception_ptr_tag
+ size=1 align=1
+ base size=0 base align=1
+std::__future_base::_State_baseV2::__exception_ptr_tag (0x0x7f21aeb0d5a0) 0 empty
+
+Class std::__future_base::_State_baseV2::_Make_ready
+ size=32 align=8
+ base size=32 base align=8
+std::__future_base::_State_baseV2::_Make_ready (0x0x7f21aeb13138) 0
+ std::__at_thread_exit_elt (0x0x7f21aeb0d660) 0
+
+Vtable for std::__future_base::_State_baseV2
+std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt13__future_base13_State_baseV2E)
+16 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2
+24 (int (*)(...))std::__future_base::_State_baseV2::~_State_baseV2
+32 (int (*)(...))std::__future_base::_State_baseV2::_M_complete_async
+40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future
+
+Class std::__future_base::_State_baseV2
+ size=32 align=8
+ base size=28 base align=8
+std::__future_base::_State_baseV2 (0x0x7f21ae9f51e0) 0
+ vptr=((& std::__future_base::_State_baseV2::_ZTVNSt13__future_base13_State_baseV2E) + 16u)
+
+Class std::__future_base
+ size=1 align=1
+ base size=0 base align=1
+std::__future_base (0x0x7f21aed40f60) 0 empty
+
+Vtable for std::__future_base::_Async_state_commonV2
+std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTINSt13__future_base21_Async_state_commonV2E)
+16 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2
+24 (int (*)(...))std::__future_base::_Async_state_commonV2::~_Async_state_commonV2
+32 (int (*)(...))std::__future_base::_Async_state_commonV2::_M_complete_async
+40 (int (*)(...))std::__future_base::_State_baseV2::_M_is_deferred_future
+
+Class std::__future_base::_Async_state_commonV2
+ size=48 align=8
+ base size=44 base align=8
+std::__future_base::_Async_state_commonV2 (0x0x7f21ae43fd00) 0
+ vptr=((& std::__future_base::_Async_state_commonV2::_ZTVNSt13__future_base21_Async_state_commonV2E) + 16u)
+ std::__future_base::_State_baseV2 (0x0x7f21ae449540) 0
+ primary-for std::__future_base::_Async_state_commonV2 (0x0x7f21ae43fd00)
+
+Class QThread::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QThread::QPrivateSignal (0x0x7f21ae449c60) 0 empty
+
+Vtable for QThread
+QThread::_ZTV7QThread: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QThread)
+16 (int (*)(...))QThread::metaObject
+24 (int (*)(...))QThread::qt_metacast
+32 (int (*)(...))QThread::qt_metacall
+40 (int (*)(...))QThread::~QThread
+48 (int (*)(...))QThread::~QThread
+56 (int (*)(...))QThread::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QThread::run
+
+Class QThread
+ size=16 align=8
+ base size=16 base align=8
+QThread (0x0x7f21ae49e7b8) 0
+ vptr=((& QThread::_ZTV7QThread) + 16u)
+ QObject (0x0x7f21ae449c00) 0
+ primary-for QThread (0x0x7f21ae49e7b8)
+
+Class QThreadPool::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QThreadPool::QPrivateSignal (0x0x7f21ae449d80) 0 empty
+
+Vtable for QThreadPool
+QThreadPool::_ZTV11QThreadPool: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QThreadPool)
+16 (int (*)(...))QThreadPool::metaObject
+24 (int (*)(...))QThreadPool::qt_metacast
+32 (int (*)(...))QThreadPool::qt_metacall
+40 (int (*)(...))QThreadPool::~QThreadPool
+48 (int (*)(...))QThreadPool::~QThreadPool
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QThreadPool
+ size=16 align=8
+ base size=16 base align=8
+QThreadPool (0x0x7f21ae49e820) 0
+ vptr=((& QThreadPool::_ZTV11QThreadPool) + 16u)
+ QObject (0x0x7f21ae449d20) 0
+ primary-for QThreadPool (0x0x7f21ae49e820)
+
+Class QThreadStorageData
+ size=4 align=4
+ base size=4 base align=4
+QThreadStorageData (0x0x7f21ae449de0) 0
+
+Class QTimeLine::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTimeLine::QPrivateSignal (0x0x7f21ae449f00) 0 empty
+
+Vtable for QTimeLine
+QTimeLine::_ZTV9QTimeLine: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QTimeLine)
+16 (int (*)(...))QTimeLine::metaObject
+24 (int (*)(...))QTimeLine::qt_metacast
+32 (int (*)(...))QTimeLine::qt_metacall
+40 (int (*)(...))QTimeLine::~QTimeLine
+48 (int (*)(...))QTimeLine::~QTimeLine
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QTimeLine::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QTimeLine::valueForTime
+
+Class QTimeLine
+ size=16 align=8
+ base size=16 base align=8
+QTimeLine (0x0x7f21ae49e888) 0
+ vptr=((& QTimeLine::_ZTV9QTimeLine) + 16u)
+ QObject (0x0x7f21ae449ea0) 0
+ primary-for QTimeLine (0x0x7f21ae49e888)
+
+Class QTimer::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTimer::QPrivateSignal (0x0x7f21ae524000) 0 empty
+
+Vtable for QTimer
+QTimer::_ZTV6QTimer: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QTimer)
+16 (int (*)(...))QTimer::metaObject
+24 (int (*)(...))QTimer::qt_metacast
+32 (int (*)(...))QTimer::qt_metacall
+40 (int (*)(...))QTimer::~QTimer
+48 (int (*)(...))QTimer::~QTimer
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QTimer::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QTimer
+ size=32 align=8
+ base size=29 base align=8
+QTimer (0x0x7f21ae49e8f0) 0
+ vptr=((& QTimer::_ZTV6QTimer) + 16u)
+ QObject (0x0x7f21ae449f60) 0
+ primary-for QTimer (0x0x7f21ae49e8f0)
+
+Class QTimeZone::OffsetData
+ size=32 align=8
+ base size=28 base align=8
+QTimeZone::OffsetData (0x0x7f21ae5246c0) 0
+
+Class QTimeZone
+ size=8 align=8
+ base size=8 base align=8
+QTimeZone (0x0x7f21ae524660) 0
+
+Class QTranslator::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTranslator::QPrivateSignal (0x0x7f21ae524c60) 0 empty
+
+Vtable for QTranslator
+QTranslator::_ZTV11QTranslator: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTranslator)
+16 (int (*)(...))QTranslator::metaObject
+24 (int (*)(...))QTranslator::qt_metacast
+32 (int (*)(...))QTranslator::qt_metacall
+40 (int (*)(...))QTranslator::~QTranslator
+48 (int (*)(...))QTranslator::~QTranslator
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QTranslator::translate
+120 (int (*)(...))QTranslator::isEmpty
+
+Class QTranslator
+ size=16 align=8
+ base size=16 base align=8
+QTranslator (0x0x7f21ae186340) 0
+ vptr=((& QTranslator::_ZTV11QTranslator) + 16u)
+ QObject (0x0x7f21ae524c00) 0
+ primary-for QTranslator (0x0x7f21ae186340)
+
+Class QUrl
+ size=8 align=8
+ base size=8 base align=8
+QUrl (0x0x7f21ae524d80) 0
+
+Class QUrlQuery
+ size=8 align=8
+ base size=8 base align=8
+QUrlQuery (0x0x7f21ae2ab480) 0
+
+Class QUuid
+ size=16 align=4
+ base size=16 base align=4
+QUuid (0x0x7f21ae2abae0) 0
+
+Class QWaitCondition
+ size=8 align=8
+ base size=8 base align=8
+QWaitCondition (0x0x7f21adf6b120) 0
+
+Class QXmlStreamStringRef
+ size=16 align=8
+ base size=16 base align=8
+QXmlStreamStringRef (0x0x7f21adf6b180) 0
+
+Class QXmlStreamAttribute
+ size=80 align=8
+ base size=73 base align=8
+QXmlStreamAttribute (0x0x7f21adf6b480) 0
+
+Class QXmlStreamAttributes
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamAttributes (0x0x7f21ae340e38) 0
+ QVector<QXmlStreamAttribute> (0x0x7f21adf6b840) 0
+
+Class QXmlStreamNamespaceDeclaration
+ size=40 align=8
+ base size=40 base align=8
+QXmlStreamNamespaceDeclaration (0x0x7f21adf6b8a0) 0
+
+Class QXmlStreamNotationDeclaration
+ size=56 align=8
+ base size=56 base align=8
+QXmlStreamNotationDeclaration (0x0x7f21adf6bb40) 0
+
+Class QXmlStreamEntityDeclaration
+ size=88 align=8
+ base size=88 base align=8
+QXmlStreamEntityDeclaration (0x0x7f21adf6bde0) 0
+
+Vtable for QXmlStreamEntityResolver
+QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QXmlStreamEntityResolver)
+16 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+24 (int (*)(...))QXmlStreamEntityResolver::~QXmlStreamEntityResolver
+32 (int (*)(...))QXmlStreamEntityResolver::resolveEntity
+40 (int (*)(...))QXmlStreamEntityResolver::resolveUndeclaredEntity
+
+Class QXmlStreamEntityResolver
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamEntityResolver (0x0x7f21ae0800c0) 0 nearly-empty
+ vptr=((& QXmlStreamEntityResolver::_ZTV24QXmlStreamEntityResolver) + 16u)
+
+Class QXmlStreamReader
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamReader (0x0x7f21ae080120) 0
+
+Class QXmlStreamWriter
+ size=8 align=8
+ base size=8 base align=8
+QXmlStreamWriter (0x0x7f21ae080b40) 0
+
+Class QRgba64
+ size=8 align=8
+ base size=8 base align=8
+QRgba64 (0x0x7f21ae080c60) 0
+
+Class QColor
+ size=16 align=4
+ base size=14 base align=4
+QColor (0x0x7f21ae080f00) 0
+
+Class QRegion::QRegionData
+ size=16 align=8
+ base size=16 base align=8
+QRegion::QRegionData (0x0x7f21add9d900) 0
+
+Class QRegion
+ size=8 align=8
+ base size=8 base align=8
+QRegion (0x0x7f21add9d8a0) 0
+
+Class QKeySequence
+ size=8 align=8
+ base size=8 base align=8
+QKeySequence (0x0x7f21ade73c60) 0
+
+Class QVector2D
+ size=8 align=4
+ base size=8 base align=4
+QVector2D (0x0x7f21adf3b1e0) 0
+
+Class QTouchDevice
+ size=8 align=8
+ base size=8 base align=8
+QTouchDevice (0x0x7f21adf3b480) 0
+
+Vtable for QInputEvent
+QInputEvent::_ZTV11QInputEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QInputEvent)
+16 (int (*)(...))QInputEvent::~QInputEvent
+24 (int (*)(...))QInputEvent::~QInputEvent
+
+Class QInputEvent
+ size=32 align=8
+ base size=32 base align=8
+QInputEvent (0x0x7f21adf30c30) 0
+ vptr=((& QInputEvent::_ZTV11QInputEvent) + 16u)
+ QEvent (0x0x7f21adf3b660) 0
+ primary-for QInputEvent (0x0x7f21adf30c30)
+
+Vtable for QEnterEvent
+QEnterEvent::_ZTV11QEnterEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QEnterEvent)
+16 (int (*)(...))QEnterEvent::~QEnterEvent
+24 (int (*)(...))QEnterEvent::~QEnterEvent
+
+Class QEnterEvent
+ size=72 align=8
+ base size=72 base align=8
+QEnterEvent (0x0x7f21adf30c98) 0
+ vptr=((& QEnterEvent::_ZTV11QEnterEvent) + 16u)
+ QEvent (0x0x7f21adf3b6c0) 0
+ primary-for QEnterEvent (0x0x7f21adf30c98)
+
+Vtable for QMouseEvent
+QMouseEvent::_ZTV11QMouseEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QMouseEvent)
+16 (int (*)(...))QMouseEvent::~QMouseEvent
+24 (int (*)(...))QMouseEvent::~QMouseEvent
+
+Class QMouseEvent
+ size=104 align=8
+ base size=100 base align=8
+QMouseEvent (0x0x7f21adf30d00) 0
+ vptr=((& QMouseEvent::_ZTV11QMouseEvent) + 16u)
+ QInputEvent (0x0x7f21adf30d68) 0
+ primary-for QMouseEvent (0x0x7f21adf30d00)
+ QEvent (0x0x7f21adf3b720) 0
+ primary-for QInputEvent (0x0x7f21adf30d68)
+
+Vtable for QHoverEvent
+QHoverEvent::_ZTV11QHoverEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QHoverEvent)
+16 (int (*)(...))QHoverEvent::~QHoverEvent
+24 (int (*)(...))QHoverEvent::~QHoverEvent
+
+Class QHoverEvent
+ size=64 align=8
+ base size=64 base align=8
+QHoverEvent (0x0x7f21adf30dd0) 0
+ vptr=((& QHoverEvent::_ZTV11QHoverEvent) + 16u)
+ QInputEvent (0x0x7f21adf30e38) 0
+ primary-for QHoverEvent (0x0x7f21adf30dd0)
+ QEvent (0x0x7f21adf3b780) 0
+ primary-for QInputEvent (0x0x7f21adf30e38)
+
+Vtable for QWheelEvent
+QWheelEvent::_ZTV11QWheelEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QWheelEvent)
+16 (int (*)(...))QWheelEvent::~QWheelEvent
+24 (int (*)(...))QWheelEvent::~QWheelEvent
+
+Class QWheelEvent
+ size=96 align=8
+ base size=96 base align=8
+QWheelEvent (0x0x7f21adf30ea0) 0
+ vptr=((& QWheelEvent::_ZTV11QWheelEvent) + 16u)
+ QInputEvent (0x0x7f21adf30f08) 0
+ primary-for QWheelEvent (0x0x7f21adf30ea0)
+ QEvent (0x0x7f21adf3b7e0) 0
+ primary-for QInputEvent (0x0x7f21adf30f08)
+
+Vtable for QTabletEvent
+QTabletEvent::_ZTV12QTabletEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QTabletEvent)
+16 (int (*)(...))QTabletEvent::~QTabletEvent
+24 (int (*)(...))QTabletEvent::~QTabletEvent
+
+Class QTabletEvent
+ size=128 align=8
+ base size=128 base align=8
+QTabletEvent (0x0x7f21adf30f70) 0
+ vptr=((& QTabletEvent::_ZTV12QTabletEvent) + 16u)
+ QInputEvent (0x0x7f21adc1e000) 0
+ primary-for QTabletEvent (0x0x7f21adf30f70)
+ QEvent (0x0x7f21adf3b840) 0
+ primary-for QInputEvent (0x0x7f21adc1e000)
+
+Vtable for QNativeGestureEvent
+QNativeGestureEvent::_ZTV19QNativeGestureEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QNativeGestureEvent)
+16 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent
+24 (int (*)(...))QNativeGestureEvent::~QNativeGestureEvent
+
+Class QNativeGestureEvent
+ size=112 align=8
+ base size=112 base align=8
+QNativeGestureEvent (0x0x7f21adc1e068) 0
+ vptr=((& QNativeGestureEvent::_ZTV19QNativeGestureEvent) + 16u)
+ QInputEvent (0x0x7f21adc1e0d0) 0
+ primary-for QNativeGestureEvent (0x0x7f21adc1e068)
+ QEvent (0x0x7f21adf3b8a0) 0
+ primary-for QInputEvent (0x0x7f21adc1e0d0)
+
+Vtable for QKeyEvent
+QKeyEvent::_ZTV9QKeyEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QKeyEvent)
+16 (int (*)(...))QKeyEvent::~QKeyEvent
+24 (int (*)(...))QKeyEvent::~QKeyEvent
+
+Class QKeyEvent
+ size=64 align=8
+ base size=59 base align=8
+QKeyEvent (0x0x7f21adc1e138) 0
+ vptr=((& QKeyEvent::_ZTV9QKeyEvent) + 16u)
+ QInputEvent (0x0x7f21adc1e1a0) 0
+ primary-for QKeyEvent (0x0x7f21adc1e138)
+ QEvent (0x0x7f21adf3b900) 0
+ primary-for QInputEvent (0x0x7f21adc1e1a0)
+
+Vtable for QFocusEvent
+QFocusEvent::_ZTV11QFocusEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QFocusEvent)
+16 (int (*)(...))QFocusEvent::~QFocusEvent
+24 (int (*)(...))QFocusEvent::~QFocusEvent
+
+Class QFocusEvent
+ size=24 align=8
+ base size=24 base align=8
+QFocusEvent (0x0x7f21adc1e208) 0
+ vptr=((& QFocusEvent::_ZTV11QFocusEvent) + 16u)
+ QEvent (0x0x7f21adf3b960) 0
+ primary-for QFocusEvent (0x0x7f21adc1e208)
+
+Vtable for QPaintEvent
+QPaintEvent::_ZTV11QPaintEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QPaintEvent)
+16 (int (*)(...))QPaintEvent::~QPaintEvent
+24 (int (*)(...))QPaintEvent::~QPaintEvent
+
+Class QPaintEvent
+ size=56 align=8
+ base size=49 base align=8
+QPaintEvent (0x0x7f21adc1e270) 0
+ vptr=((& QPaintEvent::_ZTV11QPaintEvent) + 16u)
+ QEvent (0x0x7f21adf3b9c0) 0
+ primary-for QPaintEvent (0x0x7f21adc1e270)
+
+Vtable for QMoveEvent
+QMoveEvent::_ZTV10QMoveEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QMoveEvent)
+16 (int (*)(...))QMoveEvent::~QMoveEvent
+24 (int (*)(...))QMoveEvent::~QMoveEvent
+
+Class QMoveEvent
+ size=40 align=8
+ base size=36 base align=8
+QMoveEvent (0x0x7f21adc1e2d8) 0
+ vptr=((& QMoveEvent::_ZTV10QMoveEvent) + 16u)
+ QEvent (0x0x7f21adf3ba20) 0
+ primary-for QMoveEvent (0x0x7f21adc1e2d8)
+
+Vtable for QExposeEvent
+QExposeEvent::_ZTV12QExposeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QExposeEvent)
+16 (int (*)(...))QExposeEvent::~QExposeEvent
+24 (int (*)(...))QExposeEvent::~QExposeEvent
+
+Class QExposeEvent
+ size=32 align=8
+ base size=32 base align=8
+QExposeEvent (0x0x7f21adc1e340) 0
+ vptr=((& QExposeEvent::_ZTV12QExposeEvent) + 16u)
+ QEvent (0x0x7f21adf3ba80) 0
+ primary-for QExposeEvent (0x0x7f21adc1e340)
+
+Vtable for QPlatformSurfaceEvent
+QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QPlatformSurfaceEvent)
+16 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent
+24 (int (*)(...))QPlatformSurfaceEvent::~QPlatformSurfaceEvent
+
+Class QPlatformSurfaceEvent
+ size=24 align=8
+ base size=24 base align=8
+QPlatformSurfaceEvent (0x0x7f21adc1e3a8) 0
+ vptr=((& QPlatformSurfaceEvent::_ZTV21QPlatformSurfaceEvent) + 16u)
+ QEvent (0x0x7f21adf3bae0) 0
+ primary-for QPlatformSurfaceEvent (0x0x7f21adc1e3a8)
+
+Vtable for QResizeEvent
+QResizeEvent::_ZTV12QResizeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QResizeEvent)
+16 (int (*)(...))QResizeEvent::~QResizeEvent
+24 (int (*)(...))QResizeEvent::~QResizeEvent
+
+Class QResizeEvent
+ size=40 align=8
+ base size=36 base align=8
+QResizeEvent (0x0x7f21adc1e410) 0
+ vptr=((& QResizeEvent::_ZTV12QResizeEvent) + 16u)
+ QEvent (0x0x7f21adf3bb40) 0
+ primary-for QResizeEvent (0x0x7f21adc1e410)
+
+Vtable for QCloseEvent
+QCloseEvent::_ZTV11QCloseEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QCloseEvent)
+16 (int (*)(...))QCloseEvent::~QCloseEvent
+24 (int (*)(...))QCloseEvent::~QCloseEvent
+
+Class QCloseEvent
+ size=24 align=8
+ base size=20 base align=8
+QCloseEvent (0x0x7f21adc1e478) 0
+ vptr=((& QCloseEvent::_ZTV11QCloseEvent) + 16u)
+ QEvent (0x0x7f21adf3bba0) 0
+ primary-for QCloseEvent (0x0x7f21adc1e478)
+
+Vtable for QIconDragEvent
+QIconDragEvent::_ZTV14QIconDragEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QIconDragEvent)
+16 (int (*)(...))QIconDragEvent::~QIconDragEvent
+24 (int (*)(...))QIconDragEvent::~QIconDragEvent
+
+Class QIconDragEvent
+ size=24 align=8
+ base size=20 base align=8
+QIconDragEvent (0x0x7f21adc1e4e0) 0
+ vptr=((& QIconDragEvent::_ZTV14QIconDragEvent) + 16u)
+ QEvent (0x0x7f21adf3bc00) 0
+ primary-for QIconDragEvent (0x0x7f21adc1e4e0)
+
+Vtable for QShowEvent
+QShowEvent::_ZTV10QShowEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QShowEvent)
+16 (int (*)(...))QShowEvent::~QShowEvent
+24 (int (*)(...))QShowEvent::~QShowEvent
+
+Class QShowEvent
+ size=24 align=8
+ base size=20 base align=8
+QShowEvent (0x0x7f21adc1e548) 0
+ vptr=((& QShowEvent::_ZTV10QShowEvent) + 16u)
+ QEvent (0x0x7f21adf3bc60) 0
+ primary-for QShowEvent (0x0x7f21adc1e548)
+
+Vtable for QHideEvent
+QHideEvent::_ZTV10QHideEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QHideEvent)
+16 (int (*)(...))QHideEvent::~QHideEvent
+24 (int (*)(...))QHideEvent::~QHideEvent
+
+Class QHideEvent
+ size=24 align=8
+ base size=20 base align=8
+QHideEvent (0x0x7f21adc1e5b0) 0
+ vptr=((& QHideEvent::_ZTV10QHideEvent) + 16u)
+ QEvent (0x0x7f21adf3bcc0) 0
+ primary-for QHideEvent (0x0x7f21adc1e5b0)
+
+Vtable for QContextMenuEvent
+QContextMenuEvent::_ZTV17QContextMenuEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QContextMenuEvent)
+16 (int (*)(...))QContextMenuEvent::~QContextMenuEvent
+24 (int (*)(...))QContextMenuEvent::~QContextMenuEvent
+
+Class QContextMenuEvent
+ size=56 align=8
+ base size=49 base align=8
+QContextMenuEvent (0x0x7f21adc1e618) 0
+ vptr=((& QContextMenuEvent::_ZTV17QContextMenuEvent) + 16u)
+ QInputEvent (0x0x7f21adc1e680) 0
+ primary-for QContextMenuEvent (0x0x7f21adc1e618)
+ QEvent (0x0x7f21adf3bd20) 0
+ primary-for QInputEvent (0x0x7f21adc1e680)
+
+Class QInputMethodEvent::Attribute
+ size=32 align=8
+ base size=32 base align=8
+QInputMethodEvent::Attribute (0x0x7f21adf3bde0) 0
+
+Vtable for QInputMethodEvent
+QInputMethodEvent::_ZTV17QInputMethodEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QInputMethodEvent)
+16 (int (*)(...))QInputMethodEvent::~QInputMethodEvent
+24 (int (*)(...))QInputMethodEvent::~QInputMethodEvent
+
+Class QInputMethodEvent
+ size=56 align=8
+ base size=56 base align=8
+QInputMethodEvent (0x0x7f21adc1e6e8) 0
+ vptr=((& QInputMethodEvent::_ZTV17QInputMethodEvent) + 16u)
+ QEvent (0x0x7f21adf3bd80) 0
+ primary-for QInputMethodEvent (0x0x7f21adc1e6e8)
+
+Class QInputMethodQueryEvent::QueryPair
+ size=24 align=8
+ base size=24 base align=8
+QInputMethodQueryEvent::QueryPair (0x0x7f21adcd42a0) 0
+
+Vtable for QInputMethodQueryEvent
+QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI22QInputMethodQueryEvent)
+16 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent
+24 (int (*)(...))QInputMethodQueryEvent::~QInputMethodQueryEvent
+
+Class QInputMethodQueryEvent
+ size=32 align=8
+ base size=32 base align=8
+QInputMethodQueryEvent (0x0x7f21adc1ea28) 0
+ vptr=((& QInputMethodQueryEvent::_ZTV22QInputMethodQueryEvent) + 16u)
+ QEvent (0x0x7f21adcd4240) 0
+ primary-for QInputMethodQueryEvent (0x0x7f21adc1ea28)
+
+Vtable for QDropEvent
+QDropEvent::_ZTV10QDropEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QDropEvent)
+16 (int (*)(...))QDropEvent::~QDropEvent
+24 (int (*)(...))QDropEvent::~QDropEvent
+
+Class QDropEvent
+ size=72 align=8
+ base size=72 base align=8
+QDropEvent (0x0x7f21adc1ed00) 0
+ vptr=((& QDropEvent::_ZTV10QDropEvent) + 16u)
+ QEvent (0x0x7f21adcd4600) 0
+ primary-for QDropEvent (0x0x7f21adc1ed00)
+
+Vtable for QDragMoveEvent
+QDragMoveEvent::_ZTV14QDragMoveEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QDragMoveEvent)
+16 (int (*)(...))QDragMoveEvent::~QDragMoveEvent
+24 (int (*)(...))QDragMoveEvent::~QDragMoveEvent
+
+Class QDragMoveEvent
+ size=88 align=8
+ base size=88 base align=8
+QDragMoveEvent (0x0x7f21adc1ed68) 0
+ vptr=((& QDragMoveEvent::_ZTV14QDragMoveEvent) + 16u)
+ QDropEvent (0x0x7f21adc1edd0) 0
+ primary-for QDragMoveEvent (0x0x7f21adc1ed68)
+ QEvent (0x0x7f21adcd4660) 0
+ primary-for QDropEvent (0x0x7f21adc1edd0)
+
+Vtable for QDragEnterEvent
+QDragEnterEvent::_ZTV15QDragEnterEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QDragEnterEvent)
+16 (int (*)(...))QDragEnterEvent::~QDragEnterEvent
+24 (int (*)(...))QDragEnterEvent::~QDragEnterEvent
+
+Class QDragEnterEvent
+ size=88 align=8
+ base size=88 base align=8
+QDragEnterEvent (0x0x7f21adc1ee38) 0
+ vptr=((& QDragEnterEvent::_ZTV15QDragEnterEvent) + 16u)
+ QDragMoveEvent (0x0x7f21adc1eea0) 0
+ primary-for QDragEnterEvent (0x0x7f21adc1ee38)
+ QDropEvent (0x0x7f21adc1ef08) 0
+ primary-for QDragMoveEvent (0x0x7f21adc1eea0)
+ QEvent (0x0x7f21adcd46c0) 0
+ primary-for QDropEvent (0x0x7f21adc1ef08)
+
+Vtable for QDragLeaveEvent
+QDragLeaveEvent::_ZTV15QDragLeaveEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QDragLeaveEvent)
+16 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent
+24 (int (*)(...))QDragLeaveEvent::~QDragLeaveEvent
+
+Class QDragLeaveEvent
+ size=24 align=8
+ base size=20 base align=8
+QDragLeaveEvent (0x0x7f21adc1ef70) 0
+ vptr=((& QDragLeaveEvent::_ZTV15QDragLeaveEvent) + 16u)
+ QEvent (0x0x7f21adcd4720) 0
+ primary-for QDragLeaveEvent (0x0x7f21adc1ef70)
+
+Vtable for QHelpEvent
+QHelpEvent::_ZTV10QHelpEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QHelpEvent)
+16 (int (*)(...))QHelpEvent::~QHelpEvent
+24 (int (*)(...))QHelpEvent::~QHelpEvent
+
+Class QHelpEvent
+ size=40 align=8
+ base size=36 base align=8
+QHelpEvent (0x0x7f21add37000) 0
+ vptr=((& QHelpEvent::_ZTV10QHelpEvent) + 16u)
+ QEvent (0x0x7f21adcd4780) 0
+ primary-for QHelpEvent (0x0x7f21add37000)
+
+Vtable for QStatusTipEvent
+QStatusTipEvent::_ZTV15QStatusTipEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QStatusTipEvent)
+16 (int (*)(...))QStatusTipEvent::~QStatusTipEvent
+24 (int (*)(...))QStatusTipEvent::~QStatusTipEvent
+
+Class QStatusTipEvent
+ size=32 align=8
+ base size=32 base align=8
+QStatusTipEvent (0x0x7f21add37068) 0
+ vptr=((& QStatusTipEvent::_ZTV15QStatusTipEvent) + 16u)
+ QEvent (0x0x7f21adcd47e0) 0
+ primary-for QStatusTipEvent (0x0x7f21add37068)
+
+Vtable for QWhatsThisClickedEvent
+QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI22QWhatsThisClickedEvent)
+16 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent
+24 (int (*)(...))QWhatsThisClickedEvent::~QWhatsThisClickedEvent
+
+Class QWhatsThisClickedEvent
+ size=32 align=8
+ base size=32 base align=8
+QWhatsThisClickedEvent (0x0x7f21add370d0) 0
+ vptr=((& QWhatsThisClickedEvent::_ZTV22QWhatsThisClickedEvent) + 16u)
+ QEvent (0x0x7f21adcd4840) 0
+ primary-for QWhatsThisClickedEvent (0x0x7f21add370d0)
+
+Vtable for QActionEvent
+QActionEvent::_ZTV12QActionEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QActionEvent)
+16 (int (*)(...))QActionEvent::~QActionEvent
+24 (int (*)(...))QActionEvent::~QActionEvent
+
+Class QActionEvent
+ size=40 align=8
+ base size=40 base align=8
+QActionEvent (0x0x7f21add37138) 0
+ vptr=((& QActionEvent::_ZTV12QActionEvent) + 16u)
+ QEvent (0x0x7f21adcd48a0) 0
+ primary-for QActionEvent (0x0x7f21add37138)
+
+Vtable for QFileOpenEvent
+QFileOpenEvent::_ZTV14QFileOpenEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QFileOpenEvent)
+16 (int (*)(...))QFileOpenEvent::~QFileOpenEvent
+24 (int (*)(...))QFileOpenEvent::~QFileOpenEvent
+
+Class QFileOpenEvent
+ size=40 align=8
+ base size=40 base align=8
+QFileOpenEvent (0x0x7f21add371a0) 0
+ vptr=((& QFileOpenEvent::_ZTV14QFileOpenEvent) + 16u)
+ QEvent (0x0x7f21adcd4900) 0
+ primary-for QFileOpenEvent (0x0x7f21add371a0)
+
+Vtable for QToolBarChangeEvent
+QToolBarChangeEvent::_ZTV19QToolBarChangeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QToolBarChangeEvent)
+16 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent
+24 (int (*)(...))QToolBarChangeEvent::~QToolBarChangeEvent
+
+Class QToolBarChangeEvent
+ size=24 align=8
+ base size=21 base align=8
+QToolBarChangeEvent (0x0x7f21add37208) 0
+ vptr=((& QToolBarChangeEvent::_ZTV19QToolBarChangeEvent) + 16u)
+ QEvent (0x0x7f21adcd4960) 0
+ primary-for QToolBarChangeEvent (0x0x7f21add37208)
+
+Vtable for QShortcutEvent
+QShortcutEvent::_ZTV14QShortcutEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QShortcutEvent)
+16 (int (*)(...))QShortcutEvent::~QShortcutEvent
+24 (int (*)(...))QShortcutEvent::~QShortcutEvent
+
+Class QShortcutEvent
+ size=40 align=8
+ base size=40 base align=8
+QShortcutEvent (0x0x7f21add37270) 0
+ vptr=((& QShortcutEvent::_ZTV14QShortcutEvent) + 16u)
+ QEvent (0x0x7f21adcd49c0) 0
+ primary-for QShortcutEvent (0x0x7f21add37270)
+
+Vtable for QWindowStateChangeEvent
+QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QWindowStateChangeEvent)
+16 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent
+24 (int (*)(...))QWindowStateChangeEvent::~QWindowStateChangeEvent
+
+Class QWindowStateChangeEvent
+ size=32 align=8
+ base size=25 base align=8
+QWindowStateChangeEvent (0x0x7f21add372d8) 0
+ vptr=((& QWindowStateChangeEvent::_ZTV23QWindowStateChangeEvent) + 16u)
+ QEvent (0x0x7f21adcd4a20) 0
+ primary-for QWindowStateChangeEvent (0x0x7f21add372d8)
+
+Class QPointingDeviceUniqueId
+ size=8 align=8
+ base size=8 base align=8
+QPointingDeviceUniqueId (0x0x7f21adcd4a80) 0
+
+Class QTouchEvent::TouchPoint
+ size=8 align=8
+ base size=8 base align=8
+QTouchEvent::TouchPoint (0x0x7f21ad977180) 0
+
+Vtable for QTouchEvent
+QTouchEvent::_ZTV11QTouchEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTouchEvent)
+16 (int (*)(...))QTouchEvent::~QTouchEvent
+24 (int (*)(...))QTouchEvent::~QTouchEvent
+
+Class QTouchEvent
+ size=72 align=8
+ base size=72 base align=8
+QTouchEvent (0x0x7f21add37958) 0
+ vptr=((& QTouchEvent::_ZTV11QTouchEvent) + 16u)
+ QInputEvent (0x0x7f21add379c0) 0
+ primary-for QTouchEvent (0x0x7f21add37958)
+ QEvent (0x0x7f21ad977120) 0
+ primary-for QInputEvent (0x0x7f21add379c0)
+
+Vtable for QScrollPrepareEvent
+QScrollPrepareEvent::_ZTV19QScrollPrepareEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QScrollPrepareEvent)
+16 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent
+24 (int (*)(...))QScrollPrepareEvent::~QScrollPrepareEvent
+
+Class QScrollPrepareEvent
+ size=112 align=8
+ base size=112 base align=8
+QScrollPrepareEvent (0x0x7f21ada51208) 0
+ vptr=((& QScrollPrepareEvent::_ZTV19QScrollPrepareEvent) + 16u)
+ QEvent (0x0x7f21ada3e7e0) 0
+ primary-for QScrollPrepareEvent (0x0x7f21ada51208)
+
+Vtable for QScrollEvent
+QScrollEvent::_ZTV12QScrollEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QScrollEvent)
+16 (int (*)(...))QScrollEvent::~QScrollEvent
+24 (int (*)(...))QScrollEvent::~QScrollEvent
+
+Class QScrollEvent
+ size=64 align=8
+ base size=60 base align=8
+QScrollEvent (0x0x7f21ada51270) 0
+ vptr=((& QScrollEvent::_ZTV12QScrollEvent) + 16u)
+ QEvent (0x0x7f21ada3e840) 0
+ primary-for QScrollEvent (0x0x7f21ada51270)
+
+Vtable for QScreenOrientationChangeEvent
+QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI29QScreenOrientationChangeEvent)
+16 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent
+24 (int (*)(...))QScreenOrientationChangeEvent::~QScreenOrientationChangeEvent
+
+Class QScreenOrientationChangeEvent
+ size=40 align=8
+ base size=36 base align=8
+QScreenOrientationChangeEvent (0x0x7f21ada512d8) 0
+ vptr=((& QScreenOrientationChangeEvent::_ZTV29QScreenOrientationChangeEvent) + 16u)
+ QEvent (0x0x7f21ada3e8a0) 0
+ primary-for QScreenOrientationChangeEvent (0x0x7f21ada512d8)
+
+Vtable for QApplicationStateChangeEvent
+QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI28QApplicationStateChangeEvent)
+16 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent
+24 (int (*)(...))QApplicationStateChangeEvent::~QApplicationStateChangeEvent
+
+Class QApplicationStateChangeEvent
+ size=24 align=8
+ base size=24 base align=8
+QApplicationStateChangeEvent (0x0x7f21ada51340) 0
+ vptr=((& QApplicationStateChangeEvent::_ZTV28QApplicationStateChangeEvent) + 16u)
+ QEvent (0x0x7f21ada3e900) 0
+ primary-for QApplicationStateChangeEvent (0x0x7f21ada51340)
+
+Class QFont
+ size=16 align=8
+ base size=12 base align=8
+QFont (0x0x7f21ada3e960) 0
+
+Class QPolygon
+ size=8 align=8
+ base size=8 base align=8
+QPolygon (0x0x7f21adb190d0) 0
+ QVector<QPoint> (0x0x7f21adaf4660) 0
+
+Class QPolygonF
+ size=8 align=8
+ base size=8 base align=8
+QPolygonF (0x0x7f21adb19478) 0
+ QVector<QPointF> (0x0x7f21adaf4ae0) 0
+
+Class QMatrix
+ size=48 align=8
+ base size=48 base align=8
+QMatrix (0x0x7f21adaf4ea0) 0
+
+Class QPainterPath::Element
+ size=24 align=8
+ base size=24 base align=8
+QPainterPath::Element (0x0x7f21ad7f31e0) 0
+
+Class QPainterPath
+ size=8 align=8
+ base size=8 base align=8
+QPainterPath (0x0x7f21ad7f3180) 0
+
+Class QPainterPathStroker
+ size=8 align=8
+ base size=8 base align=8
+QPainterPathStroker (0x0x7f21ad7f3ba0) 0
+
+Class QTransform
+ size=88 align=8
+ base size=88 base align=8
+QTransform (0x0x7f21ad7f3cc0) 0
+
+Vtable for QPaintDevice
+QPaintDevice::_ZTV12QPaintDevice: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QPaintDevice)
+16 0u
+24 0u
+32 (int (*)(...))QPaintDevice::devType
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))QPaintDevice::metric
+56 (int (*)(...))QPaintDevice::initPainter
+64 (int (*)(...))QPaintDevice::redirected
+72 (int (*)(...))QPaintDevice::sharedPainter
+
+Class QPaintDevice
+ size=24 align=8
+ base size=24 base align=8
+QPaintDevice (0x0x7f21ad8d0420) 0
+ vptr=((& QPaintDevice::_ZTV12QPaintDevice) + 16u)
+
+Class QPixelFormat
+ size=8 align=8
+ base size=8 base align=8
+QPixelFormat (0x0x7f21ad8d0480) 0
+
+Vtable for QImage
+QImage::_ZTV6QImage: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QImage)
+16 (int (*)(...))QImage::~QImage
+24 (int (*)(...))QImage::~QImage
+32 (int (*)(...))QImage::devType
+40 (int (*)(...))QImage::paintEngine
+48 (int (*)(...))QImage::metric
+56 (int (*)(...))QPaintDevice::initPainter
+64 (int (*)(...))QPaintDevice::redirected
+72 (int (*)(...))QPaintDevice::sharedPainter
+
+Class QImage
+ size=32 align=8
+ base size=32 base align=8
+QImage (0x0x7f21ad58f340) 0
+ vptr=((& QImage::_ZTV6QImage) + 16u)
+ QPaintDevice (0x0x7f21ad8d0f00) 0
+ primary-for QImage (0x0x7f21ad58f340)
+
+Vtable for QPixmap
+QPixmap::_ZTV7QPixmap: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QPixmap)
+16 (int (*)(...))QPixmap::~QPixmap
+24 (int (*)(...))QPixmap::~QPixmap
+32 (int (*)(...))QPixmap::devType
+40 (int (*)(...))QPixmap::paintEngine
+48 (int (*)(...))QPixmap::metric
+56 (int (*)(...))QPaintDevice::initPainter
+64 (int (*)(...))QPaintDevice::redirected
+72 (int (*)(...))QPaintDevice::sharedPainter
+
+Class QPixmap
+ size=32 align=8
+ base size=32 base align=8
+QPixmap (0x0x7f21ad658ea0) 0
+ vptr=((& QPixmap::_ZTV7QPixmap) + 16u)
+ QPaintDevice (0x0x7f21ad645ea0) 0
+ primary-for QPixmap (0x0x7f21ad658ea0)
+
+Class QBrush
+ size=8 align=8
+ base size=8 base align=8
+QBrush (0x0x7f21ad6bc1e0) 0
+
+Class QBrushData
+ size=112 align=8
+ base size=112 base align=8
+QBrushData (0x0x7f21ad6bc960) 0
+
+Class QGradient
+ size=64 align=8
+ base size=64 base align=8
+QGradient (0x0x7f21ad6bc9c0) 0
+
+Class QLinearGradient
+ size=64 align=8
+ base size=64 base align=8
+QLinearGradient (0x0x7f21ad6bf820) 0
+ QGradient (0x0x7f21ad6bcc60) 0
+
+Class QRadialGradient
+ size=64 align=8
+ base size=64 base align=8
+QRadialGradient (0x0x7f21ad6bf888) 0
+ QGradient (0x0x7f21ad6bccc0) 0
+
+Class QConicalGradient
+ size=64 align=8
+ base size=64 base align=8
+QConicalGradient (0x0x7f21ad6bf8f0) 0
+ QGradient (0x0x7f21ad6bcd20) 0
+
+Class QPen
+ size=8 align=8
+ base size=8 base align=8
+QPen (0x0x7f21ad6bcd80) 0
+
+Class QTextOption::Tab
+ size=16 align=8
+ base size=14 base align=8
+QTextOption::Tab (0x0x7f21ad3f1000) 0
+
+Class QTextOption
+ size=32 align=8
+ base size=32 base align=8
+QTextOption (0x0x7f21ad3c3f60) 0
+
+Class QTextLength
+ size=16 align=8
+ base size=16 base align=8
+QTextLength (0x0x7f21ad3f1780) 0
+
+Class QTextFormat
+ size=16 align=8
+ base size=12 base align=8
+QTextFormat (0x0x7f21ad3f1ea0) 0
+
+Class QTextCharFormat
+ size=16 align=8
+ base size=12 base align=8
+QTextCharFormat (0x0x7f21ad4dc9c0) 0
+ QTextFormat (0x0x7f21ad4b8d20) 0
+
+Class QTextBlockFormat
+ size=16 align=8
+ base size=12 base align=8
+QTextBlockFormat (0x0x7f21ad4dcbc8) 0
+ QTextFormat (0x0x7f21ad1b3000) 0
+
+Class QTextListFormat
+ size=16 align=8
+ base size=12 base align=8
+QTextListFormat (0x0x7f21ad4dce38) 0
+ QTextFormat (0x0x7f21ad1b32a0) 0
+
+Class QTextImageFormat
+ size=16 align=8
+ base size=12 base align=8
+QTextImageFormat (0x0x7f21ad4dc2d8) 0
+ QTextCharFormat (0x0x7f21ad4dc3a8) 0
+ QTextFormat (0x0x7f21ad1b3540) 0
+
+Class QTextFrameFormat
+ size=16 align=8
+ base size=12 base align=8
+QTextFrameFormat (0x0x7f21ad1f9138) 0
+ QTextFormat (0x0x7f21ad1b37e0) 0
+
+Class QTextTableFormat
+ size=16 align=8
+ base size=12 base align=8
+QTextTableFormat (0x0x7f21ad1f9340) 0
+ QTextFrameFormat (0x0x7f21ad1f93a8) 0
+ QTextFormat (0x0x7f21ad1b3a80) 0
+
+Class QTextTableCellFormat
+ size=16 align=8
+ base size=12 base align=8
+QTextTableCellFormat (0x0x7f21ad1f95b0) 0
+ QTextCharFormat (0x0x7f21ad1f9618) 0
+ QTextFormat (0x0x7f21ad1b3d80) 0
+
+Class QFontDatabase
+ size=8 align=8
+ base size=8 base align=8
+QFontDatabase (0x0x7f21ad253060) 0
+
+Class QRawFont
+ size=8 align=8
+ base size=8 base align=8
+QRawFont (0x0x7f21ad2530c0) 0
+
+Class QGlyphRun
+ size=8 align=8
+ base size=8 base align=8
+QGlyphRun (0x0x7f21ad2535a0) 0
+
+Class QTextCursor
+ size=8 align=8
+ base size=8 base align=8
+QTextCursor (0x0x7f21ad2538a0) 0
+
+Class QTextInlineObject
+ size=16 align=8
+ base size=16 base align=8
+QTextInlineObject (0x0x7f21ad253ba0) 0
+
+Class QTextLayout::FormatRange
+ size=24 align=8
+ base size=24 base align=8
+QTextLayout::FormatRange (0x0x7f21ad253c60) 0
+
+Class QTextLayout
+ size=8 align=8
+ base size=8 base align=8
+QTextLayout (0x0x7f21ad253c00) 0
+
+Class QTextLine
+ size=16 align=8
+ base size=16 base align=8
+QTextLine (0x0x7f21acf866c0) 0
+
+Vtable for QAbstractUndoItem
+QAbstractUndoItem::_ZTV17QAbstractUndoItem: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QAbstractUndoItem)
+16 (int (*)(...))__cxa_pure_virtual
+24 (int (*)(...))__cxa_pure_virtual
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+
+Class QAbstractUndoItem
+ size=8 align=8
+ base size=8 base align=8
+QAbstractUndoItem (0x0x7f21acf86720) 0 nearly-empty
+ vptr=((& QAbstractUndoItem::_ZTV17QAbstractUndoItem) + 16u)
+
+Class QTextDocument::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTextDocument::QPrivateSignal (0x0x7f21acf867e0) 0 empty
+
+Vtable for QTextDocument
+QTextDocument::_ZTV13QTextDocument: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QTextDocument)
+16 (int (*)(...))QTextDocument::metaObject
+24 (int (*)(...))QTextDocument::qt_metacast
+32 (int (*)(...))QTextDocument::qt_metacall
+40 (int (*)(...))QTextDocument::~QTextDocument
+48 (int (*)(...))QTextDocument::~QTextDocument
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QTextDocument::clear
+120 (int (*)(...))QTextDocument::createObject
+128 (int (*)(...))QTextDocument::loadResource
+
+Class QTextDocument
+ size=16 align=8
+ base size=16 base align=8
+QTextDocument (0x0x7f21acf84958) 0
+ vptr=((& QTextDocument::_ZTV13QTextDocument) + 16u)
+ QObject (0x0x7f21acf86780) 0
+ primary-for QTextDocument (0x0x7f21acf84958)
+
+Class QPalette::Data
+ size=4 align=4
+ base size=4 base align=4
+QPalette::Data (0x0x7f21acf86a20) 0
+
+Class QPalette
+ size=16 align=8
+ base size=12 base align=8
+QPalette (0x0x7f21acf869c0) 0
+
+Class QAbstractTextDocumentLayout::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractTextDocumentLayout::QPrivateSignal (0x0x7f21ad0acae0) 0 empty
+
+Class QAbstractTextDocumentLayout::Selection
+ size=24 align=8
+ base size=24 base align=8
+QAbstractTextDocumentLayout::Selection (0x0x7f21ad0acb40) 0
+
+Class QAbstractTextDocumentLayout::PaintContext
+ size=64 align=8
+ base size=64 base align=8
+QAbstractTextDocumentLayout::PaintContext (0x0x7f21ad0acba0) 0
+
+Vtable for QAbstractTextDocumentLayout
+QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout: 24u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QAbstractTextDocumentLayout)
+16 (int (*)(...))QAbstractTextDocumentLayout::metaObject
+24 (int (*)(...))QAbstractTextDocumentLayout::qt_metacast
+32 (int (*)(...))QAbstractTextDocumentLayout::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))__cxa_pure_virtual
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))QAbstractTextDocumentLayout::resizeInlineObject
+176 (int (*)(...))QAbstractTextDocumentLayout::positionInlineObject
+184 (int (*)(...))QAbstractTextDocumentLayout::drawInlineObject
+
+Class QAbstractTextDocumentLayout
+ size=16 align=8
+ base size=16 base align=8
+QAbstractTextDocumentLayout (0x0x7f21ad0b8680) 0
+ vptr=((& QAbstractTextDocumentLayout::_ZTV27QAbstractTextDocumentLayout) + 16u)
+ QObject (0x0x7f21ad0aca80) 0
+ primary-for QAbstractTextDocumentLayout (0x0x7f21ad0b8680)
+
+Vtable for QTextObjectInterface
+QTextObjectInterface::_ZTV20QTextObjectInterface: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QTextObjectInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+
+Class QTextObjectInterface
+ size=8 align=8
+ base size=8 base align=8
+QTextObjectInterface (0x0x7f21ad12c180) 0 nearly-empty
+ vptr=((& QTextObjectInterface::_ZTV20QTextObjectInterface) + 16u)
+
+Class QAccessible::State
+ size=8 align=8
+ base size=5 base align=8
+QAccessible::State (0x0x7f21ad12c2a0) 0
+
+Vtable for QAccessible::ActivationObserver
+QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN11QAccessible18ActivationObserverE)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessible::ActivationObserver
+ size=8 align=8
+ base size=8 base align=8
+QAccessible::ActivationObserver (0x0x7f21ad12c300) 0 nearly-empty
+ vptr=((& QAccessible::ActivationObserver::_ZTVN11QAccessible18ActivationObserverE) + 16u)
+
+Class QAccessible
+ size=1 align=1
+ base size=0 base align=1
+QAccessible (0x0x7f21ad12c240) 0 empty
+
+Vtable for QAccessibleInterface
+QAccessibleInterface::_ZTV20QAccessibleInterface: 23u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QAccessibleInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))QAccessibleInterface::window
+56 (int (*)(...))QAccessibleInterface::relations
+64 (int (*)(...))QAccessibleInterface::focusChild
+72 (int (*)(...))__cxa_pure_virtual
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))__cxa_pure_virtual
+96 (int (*)(...))__cxa_pure_virtual
+104 (int (*)(...))__cxa_pure_virtual
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))QAccessibleInterface::foregroundColor
+160 (int (*)(...))QAccessibleInterface::backgroundColor
+168 (int (*)(...))QAccessibleInterface::virtual_hook
+176 (int (*)(...))QAccessibleInterface::interface_cast
+
+Class QAccessibleInterface
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleInterface (0x0x7f21ad12c4e0) 0 nearly-empty
+ vptr=((& QAccessibleInterface::_ZTV20QAccessibleInterface) + 16u)
+
+Vtable for QAccessibleTextInterface
+QAccessibleTextInterface::_ZTV24QAccessibleTextInterface: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QAccessibleTextInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+72 (int (*)(...))__cxa_pure_virtual
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))__cxa_pure_virtual
+96 (int (*)(...))QAccessibleTextInterface::textBeforeOffset
+104 (int (*)(...))QAccessibleTextInterface::textAfterOffset
+112 (int (*)(...))QAccessibleTextInterface::textAtOffset
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleTextInterface
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleTextInterface (0x0x7f21ad12c540) 0 nearly-empty
+ vptr=((& QAccessibleTextInterface::_ZTV24QAccessibleTextInterface) + 16u)
+
+Vtable for QAccessibleEditableTextInterface
+QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI32QAccessibleEditableTextInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleEditableTextInterface
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleEditableTextInterface (0x0x7f21ad12c5a0) 0 nearly-empty
+ vptr=((& QAccessibleEditableTextInterface::_ZTV32QAccessibleEditableTextInterface) + 16u)
+
+Vtable for QAccessibleValueInterface
+QAccessibleValueInterface::_ZTV25QAccessibleValueInterface: 9u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI25QAccessibleValueInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleValueInterface
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleValueInterface (0x0x7f21ad12c600) 0 nearly-empty
+ vptr=((& QAccessibleValueInterface::_ZTV25QAccessibleValueInterface) + 16u)
+
+Vtable for QAccessibleTableCellInterface
+QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface: 12u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI29QAccessibleTableCellInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+72 (int (*)(...))__cxa_pure_virtual
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleTableCellInterface
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleTableCellInterface (0x0x7f21ad12c660) 0 nearly-empty
+ vptr=((& QAccessibleTableCellInterface::_ZTV29QAccessibleTableCellInterface) + 16u)
+
+Vtable for QAccessibleTableInterface
+QAccessibleTableInterface::_ZTV25QAccessibleTableInterface: 24u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI25QAccessibleTableInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+72 (int (*)(...))__cxa_pure_virtual
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))__cxa_pure_virtual
+96 (int (*)(...))__cxa_pure_virtual
+104 (int (*)(...))__cxa_pure_virtual
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))__cxa_pure_virtual
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))__cxa_pure_virtual
+176 (int (*)(...))__cxa_pure_virtual
+184 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleTableInterface
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleTableInterface (0x0x7f21ad12c6c0) 0 nearly-empty
+ vptr=((& QAccessibleTableInterface::_ZTV25QAccessibleTableInterface) + 16u)
+
+Vtable for QAccessibleActionInterface
+QAccessibleActionInterface::_ZTV26QAccessibleActionInterface: 9u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QAccessibleActionInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))QAccessibleActionInterface::localizedActionName
+48 (int (*)(...))QAccessibleActionInterface::localizedActionDescription
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleActionInterface
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleActionInterface (0x0x7f21ad12c720) 0 nearly-empty
+ vptr=((& QAccessibleActionInterface::_ZTV26QAccessibleActionInterface) + 16u)
+
+Vtable for QAccessibleImageInterface
+QAccessibleImageInterface::_ZTV25QAccessibleImageInterface: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI25QAccessibleImageInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleImageInterface
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleImageInterface (0x0x7f21ad12c780) 0 nearly-empty
+ vptr=((& QAccessibleImageInterface::_ZTV25QAccessibleImageInterface) + 16u)
+
+Vtable for QAccessibleEvent
+QAccessibleEvent::_ZTV16QAccessibleEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QAccessibleEvent)
+16 (int (*)(...))QAccessibleEvent::~QAccessibleEvent
+24 (int (*)(...))QAccessibleEvent::~QAccessibleEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleEvent
+ size=32 align=8
+ base size=28 base align=8
+QAccessibleEvent (0x0x7f21ad12c7e0) 0
+ vptr=((& QAccessibleEvent::_ZTV16QAccessibleEvent) + 16u)
+
+Vtable for QAccessibleStateChangeEvent
+QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QAccessibleStateChangeEvent)
+16 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent
+24 (int (*)(...))QAccessibleStateChangeEvent::~QAccessibleStateChangeEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleStateChangeEvent
+ size=40 align=8
+ base size=40 base align=8
+QAccessibleStateChangeEvent (0x0x7f21acddd0d0) 0
+ vptr=((& QAccessibleStateChangeEvent::_ZTV27QAccessibleStateChangeEvent) + 16u)
+ QAccessibleEvent (0x0x7f21ad12cd20) 0
+ primary-for QAccessibleStateChangeEvent (0x0x7f21acddd0d0)
+
+Vtable for QAccessibleTextCursorEvent
+QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QAccessibleTextCursorEvent)
+16 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent
+24 (int (*)(...))QAccessibleTextCursorEvent::~QAccessibleTextCursorEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleTextCursorEvent
+ size=32 align=8
+ base size=32 base align=8
+QAccessibleTextCursorEvent (0x0x7f21acddd138) 0
+ vptr=((& QAccessibleTextCursorEvent::_ZTV26QAccessibleTextCursorEvent) + 16u)
+ QAccessibleEvent (0x0x7f21ad12cd80) 0
+ primary-for QAccessibleTextCursorEvent (0x0x7f21acddd138)
+
+Vtable for QAccessibleTextSelectionEvent
+QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI29QAccessibleTextSelectionEvent)
+16 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent
+24 (int (*)(...))QAccessibleTextSelectionEvent::~QAccessibleTextSelectionEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleTextSelectionEvent
+ size=40 align=8
+ base size=40 base align=8
+QAccessibleTextSelectionEvent (0x0x7f21acddd1a0) 0
+ vptr=((& QAccessibleTextSelectionEvent::_ZTV29QAccessibleTextSelectionEvent) + 16u)
+ QAccessibleTextCursorEvent (0x0x7f21acddd208) 0
+ primary-for QAccessibleTextSelectionEvent (0x0x7f21acddd1a0)
+ QAccessibleEvent (0x0x7f21ad12cde0) 0
+ primary-for QAccessibleTextCursorEvent (0x0x7f21acddd208)
+
+Vtable for QAccessibleTextInsertEvent
+QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QAccessibleTextInsertEvent)
+16 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent
+24 (int (*)(...))QAccessibleTextInsertEvent::~QAccessibleTextInsertEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleTextInsertEvent
+ size=48 align=8
+ base size=48 base align=8
+QAccessibleTextInsertEvent (0x0x7f21acddd270) 0
+ vptr=((& QAccessibleTextInsertEvent::_ZTV26QAccessibleTextInsertEvent) + 16u)
+ QAccessibleTextCursorEvent (0x0x7f21acddd2d8) 0
+ primary-for QAccessibleTextInsertEvent (0x0x7f21acddd270)
+ QAccessibleEvent (0x0x7f21ad12ce40) 0
+ primary-for QAccessibleTextCursorEvent (0x0x7f21acddd2d8)
+
+Vtable for QAccessibleTextRemoveEvent
+QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QAccessibleTextRemoveEvent)
+16 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent
+24 (int (*)(...))QAccessibleTextRemoveEvent::~QAccessibleTextRemoveEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleTextRemoveEvent
+ size=48 align=8
+ base size=48 base align=8
+QAccessibleTextRemoveEvent (0x0x7f21acddd340) 0
+ vptr=((& QAccessibleTextRemoveEvent::_ZTV26QAccessibleTextRemoveEvent) + 16u)
+ QAccessibleTextCursorEvent (0x0x7f21acddd3a8) 0
+ primary-for QAccessibleTextRemoveEvent (0x0x7f21acddd340)
+ QAccessibleEvent (0x0x7f21ad12cea0) 0
+ primary-for QAccessibleTextCursorEvent (0x0x7f21acddd3a8)
+
+Vtable for QAccessibleTextUpdateEvent
+QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QAccessibleTextUpdateEvent)
+16 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent
+24 (int (*)(...))QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleTextUpdateEvent
+ size=56 align=8
+ base size=56 base align=8
+QAccessibleTextUpdateEvent (0x0x7f21acddd410) 0
+ vptr=((& QAccessibleTextUpdateEvent::_ZTV26QAccessibleTextUpdateEvent) + 16u)
+ QAccessibleTextCursorEvent (0x0x7f21acddd478) 0
+ primary-for QAccessibleTextUpdateEvent (0x0x7f21acddd410)
+ QAccessibleEvent (0x0x7f21ad12cf00) 0
+ primary-for QAccessibleTextCursorEvent (0x0x7f21acddd478)
+
+Vtable for QAccessibleValueChangeEvent
+QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QAccessibleValueChangeEvent)
+16 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent
+24 (int (*)(...))QAccessibleValueChangeEvent::~QAccessibleValueChangeEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleValueChangeEvent
+ size=48 align=8
+ base size=48 base align=8
+QAccessibleValueChangeEvent (0x0x7f21acddd4e0) 0
+ vptr=((& QAccessibleValueChangeEvent::_ZTV27QAccessibleValueChangeEvent) + 16u)
+ QAccessibleEvent (0x0x7f21ad12cf60) 0
+ primary-for QAccessibleValueChangeEvent (0x0x7f21acddd4e0)
+
+Vtable for QAccessibleTableModelChangeEvent
+QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI32QAccessibleTableModelChangeEvent)
+16 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent
+24 (int (*)(...))QAccessibleTableModelChangeEvent::~QAccessibleTableModelChangeEvent
+32 (int (*)(...))QAccessibleEvent::accessibleInterface
+
+Class QAccessibleTableModelChangeEvent
+ size=48 align=8
+ base size=48 base align=8
+QAccessibleTableModelChangeEvent (0x0x7f21acddd548) 0
+ vptr=((& QAccessibleTableModelChangeEvent::_ZTV32QAccessibleTableModelChangeEvent) + 16u)
+ QAccessibleEvent (0x0x7f21ace80000) 0
+ primary-for QAccessibleTableModelChangeEvent (0x0x7f21acddd548)
+
+Vtable for QAccessibleBridge
+QAccessibleBridge::_ZTV17QAccessibleBridge: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QAccessibleBridge)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleBridge
+ size=8 align=8
+ base size=8 base align=8
+QAccessibleBridge (0x0x7f21ace800c0) 0 nearly-empty
+ vptr=((& QAccessibleBridge::_ZTV17QAccessibleBridge) + 16u)
+
+Class QAccessibleBridgePlugin::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAccessibleBridgePlugin::QPrivateSignal (0x0x7f21ace80180) 0 empty
+
+Vtable for QAccessibleBridgePlugin
+QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QAccessibleBridgePlugin)
+16 (int (*)(...))QAccessibleBridgePlugin::metaObject
+24 (int (*)(...))QAccessibleBridgePlugin::qt_metacast
+32 (int (*)(...))QAccessibleBridgePlugin::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessibleBridgePlugin
+ size=16 align=8
+ base size=16 base align=8
+QAccessibleBridgePlugin (0x0x7f21acddd5b0) 0
+ vptr=((& QAccessibleBridgePlugin::_ZTV23QAccessibleBridgePlugin) + 16u)
+ QObject (0x0x7f21ace80120) 0
+ primary-for QAccessibleBridgePlugin (0x0x7f21acddd5b0)
+
+Vtable for QAccessibleObject
+QAccessibleObject::_ZTV17QAccessibleObject: 23u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QAccessibleObject)
+16 0u
+24 0u
+32 (int (*)(...))QAccessibleObject::isValid
+40 (int (*)(...))QAccessibleObject::object
+48 (int (*)(...))QAccessibleInterface::window
+56 (int (*)(...))QAccessibleInterface::relations
+64 (int (*)(...))QAccessibleInterface::focusChild
+72 (int (*)(...))QAccessibleObject::childAt
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))__cxa_pure_virtual
+96 (int (*)(...))__cxa_pure_virtual
+104 (int (*)(...))__cxa_pure_virtual
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))QAccessibleObject::setText
+128 (int (*)(...))QAccessibleObject::rect
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))QAccessibleInterface::foregroundColor
+160 (int (*)(...))QAccessibleInterface::backgroundColor
+168 (int (*)(...))QAccessibleInterface::virtual_hook
+176 (int (*)(...))QAccessibleInterface::interface_cast
+
+Class QAccessibleObject
+ size=16 align=8
+ base size=16 base align=8
+QAccessibleObject (0x0x7f21acddd618) 0
+ vptr=((& QAccessibleObject::_ZTV17QAccessibleObject) + 16u)
+ QAccessibleInterface (0x0x7f21ace801e0) 0 nearly-empty
+ primary-for QAccessibleObject (0x0x7f21acddd618)
+
+Vtable for QAccessibleApplication
+QAccessibleApplication::_ZTV22QAccessibleApplication: 23u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI22QAccessibleApplication)
+16 (int (*)(...))QAccessibleApplication::~QAccessibleApplication
+24 (int (*)(...))QAccessibleApplication::~QAccessibleApplication
+32 (int (*)(...))QAccessibleObject::isValid
+40 (int (*)(...))QAccessibleObject::object
+48 (int (*)(...))QAccessibleApplication::window
+56 (int (*)(...))QAccessibleInterface::relations
+64 (int (*)(...))QAccessibleApplication::focusChild
+72 (int (*)(...))QAccessibleObject::childAt
+80 (int (*)(...))QAccessibleApplication::parent
+88 (int (*)(...))QAccessibleApplication::child
+96 (int (*)(...))QAccessibleApplication::childCount
+104 (int (*)(...))QAccessibleApplication::indexOfChild
+112 (int (*)(...))QAccessibleApplication::text
+120 (int (*)(...))QAccessibleObject::setText
+128 (int (*)(...))QAccessibleObject::rect
+136 (int (*)(...))QAccessibleApplication::role
+144 (int (*)(...))QAccessibleApplication::state
+152 (int (*)(...))QAccessibleInterface::foregroundColor
+160 (int (*)(...))QAccessibleInterface::backgroundColor
+168 (int (*)(...))QAccessibleInterface::virtual_hook
+176 (int (*)(...))QAccessibleInterface::interface_cast
+
+Class QAccessibleApplication
+ size=16 align=8
+ base size=16 base align=8
+QAccessibleApplication (0x0x7f21acddd680) 0
+ vptr=((& QAccessibleApplication::_ZTV22QAccessibleApplication) + 16u)
+ QAccessibleObject (0x0x7f21acddd6e8) 0
+ primary-for QAccessibleApplication (0x0x7f21acddd680)
+ QAccessibleInterface (0x0x7f21ace80240) 0 nearly-empty
+ primary-for QAccessibleObject (0x0x7f21acddd6e8)
+
+Class QAccessiblePlugin::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAccessiblePlugin::QPrivateSignal (0x0x7f21ace80300) 0 empty
+
+Vtable for QAccessiblePlugin
+QAccessiblePlugin::_ZTV17QAccessiblePlugin: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QAccessiblePlugin)
+16 (int (*)(...))QAccessiblePlugin::metaObject
+24 (int (*)(...))QAccessiblePlugin::qt_metacast
+32 (int (*)(...))QAccessiblePlugin::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+
+Class QAccessiblePlugin
+ size=16 align=8
+ base size=16 base align=8
+QAccessiblePlugin (0x0x7f21acddd750) 0
+ vptr=((& QAccessiblePlugin::_ZTV17QAccessiblePlugin) + 16u)
+ QObject (0x0x7f21ace802a0) 0
+ primary-for QAccessiblePlugin (0x0x7f21acddd750)
+
+Class QSurfaceFormat
+ size=8 align=8
+ base size=8 base align=8
+QSurfaceFormat (0x0x7f21ace80360) 0
+
+Vtable for QSurface
+QSurface::_ZTV8QSurface: 8u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QSurface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))__cxa_pure_virtual
+
+Class QSurface
+ size=24 align=8
+ base size=24 base align=8
+QSurface (0x0x7f21ace80540) 0
+ vptr=((& QSurface::_ZTV8QSurface) + 16u)
+
+Class QIcon
+ size=8 align=8
+ base size=8 base align=8
+QIcon (0x0x7f21ace806c0) 0
+
+Class QCursor
+ size=8 align=8
+ base size=8 base align=8
+QCursor (0x0x7f21acba7a80) 0
+
+Class QWindow::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QWindow::QPrivateSignal (0x0x7f21acc5b0c0) 0 empty
+
+Vtable for QWindow
+QWindow::_ZTV7QWindow: 45u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QWindow)
+16 (int (*)(...))QWindow::metaObject
+24 (int (*)(...))QWindow::qt_metacast
+32 (int (*)(...))QWindow::qt_metacall
+40 (int (*)(...))QWindow::~QWindow
+48 (int (*)(...))QWindow::~QWindow
+56 (int (*)(...))QWindow::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWindow::surfaceType
+120 (int (*)(...))QWindow::format
+128 (int (*)(...))QWindow::size
+136 (int (*)(...))QWindow::accessibleRoot
+144 (int (*)(...))QWindow::focusObject
+152 (int (*)(...))QWindow::exposeEvent
+160 (int (*)(...))QWindow::resizeEvent
+168 (int (*)(...))QWindow::moveEvent
+176 (int (*)(...))QWindow::focusInEvent
+184 (int (*)(...))QWindow::focusOutEvent
+192 (int (*)(...))QWindow::showEvent
+200 (int (*)(...))QWindow::hideEvent
+208 (int (*)(...))QWindow::keyPressEvent
+216 (int (*)(...))QWindow::keyReleaseEvent
+224 (int (*)(...))QWindow::mousePressEvent
+232 (int (*)(...))QWindow::mouseReleaseEvent
+240 (int (*)(...))QWindow::mouseDoubleClickEvent
+248 (int (*)(...))QWindow::mouseMoveEvent
+256 (int (*)(...))QWindow::wheelEvent
+264 (int (*)(...))QWindow::touchEvent
+272 (int (*)(...))QWindow::tabletEvent
+280 (int (*)(...))QWindow::nativeEvent
+288 (int (*)(...))QWindow::surfaceHandle
+296 (int (*)(...))-16
+304 (int (*)(...))(& _ZTI7QWindow)
+312 (int (*)(...))QWindow::_ZThn16_N7QWindowD1Ev
+320 (int (*)(...))QWindow::_ZThn16_N7QWindowD0Ev
+328 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv
+336 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv
+344 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv
+352 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv
+
+Class QWindow
+ size=40 align=8
+ base size=40 base align=8
+QWindow (0x0x7f21acc4f230) 0
+ vptr=((& QWindow::_ZTV7QWindow) + 16u)
+ QObject (0x0x7f21acc5b000) 0
+ primary-for QWindow (0x0x7f21acc4f230)
+ QSurface (0x0x7f21acc5b060) 16
+ vptr=((& QWindow::_ZTV7QWindow) + 312u)
+
+Class QBackingStore
+ size=8 align=8
+ base size=8 base align=8
+QBackingStore (0x0x7f21acc5b1e0) 0
+
+Vtable for QBitmap
+QBitmap::_ZTV7QBitmap: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QBitmap)
+16 (int (*)(...))QBitmap::~QBitmap
+24 (int (*)(...))QBitmap::~QBitmap
+32 (int (*)(...))QPixmap::devType
+40 (int (*)(...))QPixmap::paintEngine
+48 (int (*)(...))QPixmap::metric
+56 (int (*)(...))QPaintDevice::initPainter
+64 (int (*)(...))QPaintDevice::redirected
+72 (int (*)(...))QPaintDevice::sharedPainter
+
+Class QBitmap
+ size=32 align=8
+ base size=32 base align=8
+QBitmap (0x0x7f21acc427b8) 0
+ vptr=((& QBitmap::_ZTV7QBitmap) + 16u)
+ QPixmap (0x0x7f21acc42820) 0
+ primary-for QBitmap (0x0x7f21acc427b8)
+ QPaintDevice (0x0x7f21acc5b2a0) 0
+ primary-for QPixmap (0x0x7f21acc42820)
+
+Class QClipboard::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QClipboard::QPrivateSignal (0x0x7f21acc5b600) 0 empty
+
+Vtable for QClipboard
+QClipboard::_ZTV10QClipboard: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QClipboard)
+16 (int (*)(...))QClipboard::metaObject
+24 (int (*)(...))QClipboard::qt_metacast
+32 (int (*)(...))QClipboard::qt_metacall
+40 (int (*)(...))QClipboard::~QClipboard
+48 (int (*)(...))QClipboard::~QClipboard
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QClipboard
+ size=16 align=8
+ base size=16 base align=8
+QClipboard (0x0x7f21acc42a90) 0
+ vptr=((& QClipboard::_ZTV10QClipboard) + 16u)
+ QObject (0x0x7f21acc5b5a0) 0
+ primary-for QClipboard (0x0x7f21acc42a90)
+
+Class QDesktopServices
+ size=1 align=1
+ base size=0 base align=1
+QDesktopServices (0x0x7f21acc5b660) 0 empty
+
+Class QDrag::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDrag::QPrivateSignal (0x0x7f21acc5b720) 0 empty
+
+Vtable for QDrag
+QDrag::_ZTV5QDrag: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI5QDrag)
+16 (int (*)(...))QDrag::metaObject
+24 (int (*)(...))QDrag::qt_metacast
+32 (int (*)(...))QDrag::qt_metacall
+40 (int (*)(...))QDrag::~QDrag
+48 (int (*)(...))QDrag::~QDrag
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QDrag
+ size=16 align=8
+ base size=16 base align=8
+QDrag (0x0x7f21acc42af8) 0
+ vptr=((& QDrag::_ZTV5QDrag) + 16u)
+ QObject (0x0x7f21acc5b6c0) 0
+ primary-for QDrag (0x0x7f21acc42af8)
+
+Class QFontInfo
+ size=8 align=8
+ base size=8 base align=8
+QFontInfo (0x0x7f21acc5b780) 0
+
+Class QFontMetrics
+ size=8 align=8
+ base size=8 base align=8
+QFontMetrics (0x0x7f21acc5ba20) 0
+
+Class QFontMetricsF
+ size=8 align=8
+ base size=8 base align=8
+QFontMetricsF (0x0x7f21acc5bd20) 0
+
+Class QGenericPlugin::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGenericPlugin::QPrivateSignal (0x0x7f21aca3a4e0) 0 empty
+
+Vtable for QGenericPlugin
+QGenericPlugin::_ZTV14QGenericPlugin: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QGenericPlugin)
+16 (int (*)(...))QGenericPlugin::metaObject
+24 (int (*)(...))QGenericPlugin::qt_metacast
+32 (int (*)(...))QGenericPlugin::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+
+Class QGenericPlugin
+ size=16 align=8
+ base size=16 base align=8
+QGenericPlugin (0x0x7f21acd38618) 0
+ vptr=((& QGenericPlugin::_ZTV14QGenericPlugin) + 16u)
+ QObject (0x0x7f21aca3a480) 0
+ primary-for QGenericPlugin (0x0x7f21acd38618)
+
+Class QGenericPluginFactory
+ size=1 align=1
+ base size=0 base align=1
+QGenericPluginFactory (0x0x7f21aca3a540) 0 empty
+
+Class QInputMethod::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QInputMethod::QPrivateSignal (0x0x7f21aca3a600) 0 empty
+
+Vtable for QInputMethod
+QInputMethod::_ZTV12QInputMethod: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QInputMethod)
+16 (int (*)(...))QInputMethod::metaObject
+24 (int (*)(...))QInputMethod::qt_metacast
+32 (int (*)(...))QInputMethod::qt_metacall
+40 (int (*)(...))QInputMethod::~QInputMethod
+48 (int (*)(...))QInputMethod::~QInputMethod
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QInputMethod
+ size=16 align=8
+ base size=16 base align=8
+QInputMethod (0x0x7f21acd38680) 0
+ vptr=((& QInputMethod::_ZTV12QInputMethod) + 16u)
+ QObject (0x0x7f21aca3a5a0) 0
+ primary-for QInputMethod (0x0x7f21acd38680)
+
+Class QGuiApplication::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGuiApplication::QPrivateSignal (0x0x7f21aca3a6c0) 0 empty
+
+Vtable for QGuiApplication
+QGuiApplication::_ZTV15QGuiApplication: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QGuiApplication)
+16 (int (*)(...))QGuiApplication::metaObject
+24 (int (*)(...))QGuiApplication::qt_metacast
+32 (int (*)(...))QGuiApplication::qt_metacall
+40 (int (*)(...))QGuiApplication::~QGuiApplication
+48 (int (*)(...))QGuiApplication::~QGuiApplication
+56 (int (*)(...))QGuiApplication::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGuiApplication::notify
+120 (int (*)(...))QGuiApplication::compressEvent
+
+Class QGuiApplication
+ size=16 align=8
+ base size=16 base align=8
+QGuiApplication (0x0x7f21acd386e8) 0
+ vptr=((& QGuiApplication::_ZTV15QGuiApplication) + 16u)
+ QCoreApplication (0x0x7f21acd38750) 0
+ primary-for QGuiApplication (0x0x7f21acd386e8)
+ QObject (0x0x7f21aca3a660) 0
+ primary-for QCoreApplication (0x0x7f21acd38750)
+
+Class QIconEngine::AvailableSizesArgument
+ size=16 align=8
+ base size=16 base align=8
+QIconEngine::AvailableSizesArgument (0x0x7f21aca3ac00) 0
+
+Class QIconEngine::ScaledPixmapArgument
+ size=56 align=8
+ base size=56 base align=8
+QIconEngine::ScaledPixmapArgument (0x0x7f21aca3ad80) 0
+
+Vtable for QIconEngine
+QIconEngine::_ZTV11QIconEngine: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QIconEngine)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))QIconEngine::actualSize
+48 (int (*)(...))QIconEngine::pixmap
+56 (int (*)(...))QIconEngine::addPixmap
+64 (int (*)(...))QIconEngine::addFile
+72 (int (*)(...))QIconEngine::key
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))QIconEngine::read
+96 (int (*)(...))QIconEngine::write
+104 (int (*)(...))QIconEngine::availableSizes
+112 (int (*)(...))QIconEngine::iconName
+120 (int (*)(...))QIconEngine::virtual_hook
+
+Class QIconEngine
+ size=8 align=8
+ base size=8 base align=8
+QIconEngine (0x0x7f21aca3aba0) 0 nearly-empty
+ vptr=((& QIconEngine::_ZTV11QIconEngine) + 16u)
+
+Class QIconEnginePlugin::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QIconEnginePlugin::QPrivateSignal (0x0x7f21aca3ae40) 0 empty
+
+Vtable for QIconEnginePlugin
+QIconEnginePlugin::_ZTV17QIconEnginePlugin: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QIconEnginePlugin)
+16 (int (*)(...))QIconEnginePlugin::metaObject
+24 (int (*)(...))QIconEnginePlugin::qt_metacast
+32 (int (*)(...))QIconEnginePlugin::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+
+Class QIconEnginePlugin
+ size=16 align=8
+ base size=16 base align=8
+QIconEnginePlugin (0x0x7f21acd38d68) 0
+ vptr=((& QIconEnginePlugin::_ZTV17QIconEnginePlugin) + 16u)
+ QObject (0x0x7f21aca3ade0) 0
+ primary-for QIconEnginePlugin (0x0x7f21acd38d68)
+
+Vtable for QImageIOHandler
+QImageIOHandler::_ZTV15QImageIOHandler: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QImageIOHandler)
+16 0u
+24 0u
+32 (int (*)(...))QImageIOHandler::name
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))QImageIOHandler::write
+64 (int (*)(...))QImageIOHandler::option
+72 (int (*)(...))QImageIOHandler::setOption
+80 (int (*)(...))QImageIOHandler::supportsOption
+88 (int (*)(...))QImageIOHandler::jumpToNextImage
+96 (int (*)(...))QImageIOHandler::jumpToImage
+104 (int (*)(...))QImageIOHandler::loopCount
+112 (int (*)(...))QImageIOHandler::imageCount
+120 (int (*)(...))QImageIOHandler::nextImageDelay
+128 (int (*)(...))QImageIOHandler::currentImageNumber
+136 (int (*)(...))QImageIOHandler::currentImageRect
+
+Class QImageIOHandler
+ size=16 align=8
+ base size=16 base align=8
+QImageIOHandler (0x0x7f21aca3aea0) 0
+ vptr=((& QImageIOHandler::_ZTV15QImageIOHandler) + 16u)
+
+Class QImageIOPlugin::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QImageIOPlugin::QPrivateSignal (0x0x7f21acb31060) 0 empty
+
+Vtable for QImageIOPlugin
+QImageIOPlugin::_ZTV14QImageIOPlugin: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QImageIOPlugin)
+16 (int (*)(...))QImageIOPlugin::metaObject
+24 (int (*)(...))QImageIOPlugin::qt_metacast
+32 (int (*)(...))QImageIOPlugin::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+
+Class QImageIOPlugin
+ size=16 align=8
+ base size=16 base align=8
+QImageIOPlugin (0x0x7f21acd38dd0) 0
+ vptr=((& QImageIOPlugin::_ZTV14QImageIOPlugin) + 16u)
+ QObject (0x0x7f21acb31000) 0
+ primary-for QImageIOPlugin (0x0x7f21acd38dd0)
+
+Class QImageReader
+ size=8 align=8
+ base size=8 base align=8
+QImageReader (0x0x7f21acb31240) 0
+
+Class QImageWriter
+ size=8 align=8
+ base size=8 base align=8
+QImageWriter (0x0x7f21acb312a0) 0
+
+Class QVector3D
+ size=12 align=4
+ base size=12 base align=4
+QVector3D (0x0x7f21acb31300) 0
+
+Class QVector4D
+ size=16 align=4
+ base size=16 base align=4
+QVector4D (0x0x7f21acb315a0) 0
+
+Class QQuaternion
+ size=16 align=4
+ base size=16 base align=4
+QQuaternion (0x0x7f21acb31840) 0
+
+Class QMatrix4x4
+ size=68 align=4
+ base size=68 base align=4
+QMatrix4x4 (0x0x7f21acb31e40) 0
+
+Class QMovie::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QMovie::QPrivateSignal (0x0x7f21ac8d2600) 0 empty
+
+Vtable for QMovie
+QMovie::_ZTV6QMovie: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QMovie)
+16 (int (*)(...))QMovie::metaObject
+24 (int (*)(...))QMovie::qt_metacast
+32 (int (*)(...))QMovie::qt_metacall
+40 (int (*)(...))QMovie::~QMovie
+48 (int (*)(...))QMovie::~QMovie
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QMovie
+ size=16 align=8
+ base size=16 base align=8
+QMovie (0x0x7f21ac7b0f70) 0
+ vptr=((& QMovie::_ZTV6QMovie) + 16u)
+ QObject (0x0x7f21ac8d25a0) 0
+ primary-for QMovie (0x0x7f21ac7b0f70)
+
+Class QOffscreenSurface::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOffscreenSurface::QPrivateSignal (0x0x7f21ac8d2720) 0 empty
+
+Vtable for QOffscreenSurface
+QOffscreenSurface::_ZTV17QOffscreenSurface: 26u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QOffscreenSurface)
+16 (int (*)(...))QOffscreenSurface::metaObject
+24 (int (*)(...))QOffscreenSurface::qt_metacast
+32 (int (*)(...))QOffscreenSurface::qt_metacall
+40 (int (*)(...))QOffscreenSurface::~QOffscreenSurface
+48 (int (*)(...))QOffscreenSurface::~QOffscreenSurface
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QOffscreenSurface::surfaceType
+120 (int (*)(...))QOffscreenSurface::format
+128 (int (*)(...))QOffscreenSurface::size
+136 (int (*)(...))QOffscreenSurface::surfaceHandle
+144 (int (*)(...))-16
+152 (int (*)(...))(& _ZTI17QOffscreenSurface)
+160 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD1Ev
+168 (int (*)(...))QOffscreenSurface::_ZThn16_N17QOffscreenSurfaceD0Ev
+176 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface6formatEv
+184 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface13surfaceHandleEv
+192 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface11surfaceTypeEv
+200 (int (*)(...))QOffscreenSurface::_ZThn16_NK17QOffscreenSurface4sizeEv
+
+Class QOffscreenSurface
+ size=40 align=8
+ base size=40 base align=8
+QOffscreenSurface (0x0x7f21ac5bdee0) 0
+ vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 16u)
+ QObject (0x0x7f21ac8d2660) 0
+ primary-for QOffscreenSurface (0x0x7f21ac5bdee0)
+ QSurface (0x0x7f21ac8d26c0) 16
+ vptr=((& QOffscreenSurface::_ZTV17QOffscreenSurface) + 160u)
+
+Class QOpenGLBuffer
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLBuffer (0x0x7f21ac8d27e0) 0
+
+Class QOpenGLVersionStatus
+ size=12 align=4
+ base size=12 base align=4
+QOpenGLVersionStatus (0x0x7f21ac8d29c0) 0
+
+Class QOpenGLVersionFunctionsBackend
+ size=16 align=8
+ base size=12 base align=8
+QOpenGLVersionFunctionsBackend (0x0x7f21abf804e0) 0
+
+Class QOpenGLVersionFunctionsStorage
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLVersionFunctionsStorage (0x0x7f21abf80540) 0
+
+Class QAbstractOpenGLFunctionsPrivate
+ size=16 align=8
+ base size=9 base align=8
+QAbstractOpenGLFunctionsPrivate (0x0x7f21abf805a0) 0
+
+Vtable for QAbstractOpenGLFunctions
+QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QAbstractOpenGLFunctions)
+16 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions
+24 (int (*)(...))QAbstractOpenGLFunctions::~QAbstractOpenGLFunctions
+32 (int (*)(...))QAbstractOpenGLFunctions::initializeOpenGLFunctions
+
+Class QAbstractOpenGLFunctions
+ size=16 align=8
+ base size=16 base align=8
+QAbstractOpenGLFunctions (0x0x7f21abf80600) 0
+ vptr=((& QAbstractOpenGLFunctions::_ZTV24QAbstractOpenGLFunctions) + 16u)
+
+Class QOpenGLFunctions_1_0_CoreBackend::Functions
+ size=384 align=8
+ base size=384 base align=8
+QOpenGLFunctions_1_0_CoreBackend::Functions (0x0x7f21abf806c0) 0
+
+Class QOpenGLFunctions_1_0_CoreBackend
+ size=400 align=8
+ base size=400 base align=8
+QOpenGLFunctions_1_0_CoreBackend (0x0x7f21abf8e208) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21abf80660) 0
+
+Class QOpenGLFunctions_1_1_CoreBackend::Functions
+ size=128 align=8
+ base size=128 base align=8
+QOpenGLFunctions_1_1_CoreBackend::Functions (0x0x7f21abf807e0) 0
+
+Class QOpenGLFunctions_1_1_CoreBackend
+ size=144 align=8
+ base size=144 base align=8
+QOpenGLFunctions_1_1_CoreBackend (0x0x7f21abf8e270) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21abf80780) 0
+
+Class QOpenGLFunctions_1_2_CoreBackend::Functions
+ size=48 align=8
+ base size=48 base align=8
+QOpenGLFunctions_1_2_CoreBackend::Functions (0x0x7f21abf80900) 0
+
+Class QOpenGLFunctions_1_2_CoreBackend
+ size=64 align=8
+ base size=64 base align=8
+QOpenGLFunctions_1_2_CoreBackend (0x0x7f21abf8e2d8) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21abf808a0) 0
+
+Class QOpenGLFunctions_1_3_CoreBackend::Functions
+ size=72 align=8
+ base size=72 base align=8
+QOpenGLFunctions_1_3_CoreBackend::Functions (0x0x7f21abf80a20) 0
+
+Class QOpenGLFunctions_1_3_CoreBackend
+ size=88 align=8
+ base size=88 base align=8
+QOpenGLFunctions_1_3_CoreBackend (0x0x7f21abf8e340) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21abf809c0) 0
+
+Class QOpenGLFunctions_1_4_CoreBackend::Functions
+ size=56 align=8
+ base size=56 base align=8
+QOpenGLFunctions_1_4_CoreBackend::Functions (0x0x7f21abf80ba0) 0
+
+Class QOpenGLFunctions_1_4_CoreBackend
+ size=72 align=8
+ base size=72 base align=8
+QOpenGLFunctions_1_4_CoreBackend (0x0x7f21abf8e3a8) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21abf80b40) 0
+
+Class QOpenGLFunctions_1_5_CoreBackend::Functions
+ size=152 align=8
+ base size=152 base align=8
+QOpenGLFunctions_1_5_CoreBackend::Functions (0x0x7f21abf80cc0) 0
+
+Class QOpenGLFunctions_1_5_CoreBackend
+ size=168 align=8
+ base size=168 base align=8
+QOpenGLFunctions_1_5_CoreBackend (0x0x7f21abf8e410) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21abf80c60) 0
+
+Class QOpenGLFunctions_2_0_CoreBackend::Functions
+ size=744 align=8
+ base size=744 base align=8
+QOpenGLFunctions_2_0_CoreBackend::Functions (0x0x7f21abf80de0) 0
+
+Class QOpenGLFunctions_2_0_CoreBackend
+ size=760 align=8
+ base size=760 base align=8
+QOpenGLFunctions_2_0_CoreBackend (0x0x7f21abf8e478) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21abf80d80) 0
+
+Class QOpenGLFunctions_2_1_CoreBackend::Functions
+ size=48 align=8
+ base size=48 base align=8
+QOpenGLFunctions_2_1_CoreBackend::Functions (0x0x7f21abf80f00) 0
+
+Class QOpenGLFunctions_2_1_CoreBackend
+ size=64 align=8
+ base size=64 base align=8
+QOpenGLFunctions_2_1_CoreBackend (0x0x7f21abf8e4e0) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21abf80ea0) 0
+
+Class QOpenGLFunctions_3_0_CoreBackend::Functions
+ size=672 align=8
+ base size=672 base align=8
+QOpenGLFunctions_3_0_CoreBackend::Functions (0x0x7f21ac017060) 0
+
+Class QOpenGLFunctions_3_0_CoreBackend
+ size=688 align=8
+ base size=688 base align=8
+QOpenGLFunctions_3_0_CoreBackend (0x0x7f21abf8e548) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21ac017000) 0
+
+Class QOpenGLFunctions_3_1_CoreBackend::Functions
+ size=96 align=8
+ base size=96 base align=8
+QOpenGLFunctions_3_1_CoreBackend::Functions (0x0x7f21ac017180) 0
+
+Class QOpenGLFunctions_3_1_CoreBackend
+ size=112 align=8
+ base size=112 base align=8
+QOpenGLFunctions_3_1_CoreBackend (0x0x7f21abf8e5b0) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21ac017120) 0
+
+Class QOpenGLFunctions_3_2_CoreBackend::Functions
+ size=152 align=8
+ base size=152 base align=8
+QOpenGLFunctions_3_2_CoreBackend::Functions (0x0x7f21ac0172a0) 0
+
+Class QOpenGLFunctions_3_2_CoreBackend
+ size=168 align=8
+ base size=168 base align=8
+QOpenGLFunctions_3_2_CoreBackend (0x0x7f21abf8e618) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21ac017240) 0
+
+Class QOpenGLFunctions_3_3_CoreBackend::Functions
+ size=464 align=8
+ base size=464 base align=8
+QOpenGLFunctions_3_3_CoreBackend::Functions (0x0x7f21ac0173c0) 0
+
+Class QOpenGLFunctions_3_3_CoreBackend
+ size=480 align=8
+ base size=480 base align=8
+QOpenGLFunctions_3_3_CoreBackend (0x0x7f21abf8e680) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21ac017360) 0
+
+Class QOpenGLFunctions_4_0_CoreBackend::Functions
+ size=368 align=8
+ base size=368 base align=8
+QOpenGLFunctions_4_0_CoreBackend::Functions (0x0x7f21ac0174e0) 0
+
+Class QOpenGLFunctions_4_0_CoreBackend
+ size=384 align=8
+ base size=384 base align=8
+QOpenGLFunctions_4_0_CoreBackend (0x0x7f21abf8e6e8) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21ac017480) 0
+
+Class QOpenGLFunctions_4_1_CoreBackend::Functions
+ size=704 align=8
+ base size=704 base align=8
+QOpenGLFunctions_4_1_CoreBackend::Functions (0x0x7f21ac017600) 0
+
+Class QOpenGLFunctions_4_1_CoreBackend
+ size=720 align=8
+ base size=720 base align=8
+QOpenGLFunctions_4_1_CoreBackend (0x0x7f21abf8e750) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21ac0175a0) 0
+
+Class QOpenGLFunctions_4_2_CoreBackend::Functions
+ size=96 align=8
+ base size=96 base align=8
+QOpenGLFunctions_4_2_CoreBackend::Functions (0x0x7f21ac017720) 0
+
+Class QOpenGLFunctions_4_2_CoreBackend
+ size=112 align=8
+ base size=112 base align=8
+QOpenGLFunctions_4_2_CoreBackend (0x0x7f21abf8e7b8) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21ac0176c0) 0
+
+Class QOpenGLFunctions_4_3_CoreBackend::Functions
+ size=344 align=8
+ base size=344 base align=8
+QOpenGLFunctions_4_3_CoreBackend::Functions (0x0x7f21ac017840) 0
+
+Class QOpenGLFunctions_4_3_CoreBackend
+ size=360 align=8
+ base size=360 base align=8
+QOpenGLFunctions_4_3_CoreBackend (0x0x7f21abf8e820) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21ac0177e0) 0
+
+Class QOpenGLFunctions_4_4_CoreBackend::Functions
+ size=72 align=8
+ base size=72 base align=8
+QOpenGLFunctions_4_4_CoreBackend::Functions (0x0x7f21ac017960) 0
+
+Class QOpenGLFunctions_4_4_CoreBackend
+ size=88 align=8
+ base size=88 base align=8
+QOpenGLFunctions_4_4_CoreBackend (0x0x7f21abf8e888) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21ac017900) 0
+
+Class QOpenGLFunctions_4_5_CoreBackend::Functions
+ size=848 align=8
+ base size=848 base align=8
+QOpenGLFunctions_4_5_CoreBackend::Functions (0x0x7f21ac017ae0) 0
+
+Class QOpenGLFunctions_4_5_CoreBackend
+ size=864 align=8
+ base size=864 base align=8
+QOpenGLFunctions_4_5_CoreBackend (0x0x7f21abf8e8f0) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21ac017a80) 0
+
+Class QOpenGLFunctions_1_0_DeprecatedBackend::Functions
+ size=2064 align=8
+ base size=2064 base align=8
+QOpenGLFunctions_1_0_DeprecatedBackend::Functions (0x0x7f21ac017c00) 0
+
+Class QOpenGLFunctions_1_0_DeprecatedBackend
+ size=2080 align=8
+ base size=2080 base align=8
+QOpenGLFunctions_1_0_DeprecatedBackend (0x0x7f21abf8e958) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21ac017ba0) 0
+
+Class QOpenGLFunctions_1_1_DeprecatedBackend::Functions
+ size=136 align=8
+ base size=136 base align=8
+QOpenGLFunctions_1_1_DeprecatedBackend::Functions (0x0x7f21ac017d20) 0
+
+Class QOpenGLFunctions_1_1_DeprecatedBackend
+ size=152 align=8
+ base size=152 base align=8
+QOpenGLFunctions_1_1_DeprecatedBackend (0x0x7f21abf8e9c0) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21ac017cc0) 0
+
+Class QOpenGLFunctions_1_2_DeprecatedBackend::Functions
+ size=256 align=8
+ base size=256 base align=8
+QOpenGLFunctions_1_2_DeprecatedBackend::Functions (0x0x7f21ac017e40) 0
+
+Class QOpenGLFunctions_1_2_DeprecatedBackend
+ size=272 align=8
+ base size=272 base align=8
+QOpenGLFunctions_1_2_DeprecatedBackend (0x0x7f21abf8ea28) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21ac017de0) 0
+
+Class QOpenGLFunctions_1_3_DeprecatedBackend::Functions
+ size=296 align=8
+ base size=296 base align=8
+QOpenGLFunctions_1_3_DeprecatedBackend::Functions (0x0x7f21ac017f60) 0
+
+Class QOpenGLFunctions_1_3_DeprecatedBackend
+ size=312 align=8
+ base size=312 base align=8
+QOpenGLFunctions_1_3_DeprecatedBackend (0x0x7f21abf8ea90) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21ac017f00) 0
+
+Class QOpenGLFunctions_1_4_DeprecatedBackend::Functions
+ size=304 align=8
+ base size=304 base align=8
+QOpenGLFunctions_1_4_DeprecatedBackend::Functions (0x0x7f21abd730c0) 0
+
+Class QOpenGLFunctions_1_4_DeprecatedBackend
+ size=320 align=8
+ base size=320 base align=8
+QOpenGLFunctions_1_4_DeprecatedBackend (0x0x7f21abf8eaf8) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21abd73060) 0
+
+Class QOpenGLFunctions_2_0_DeprecatedBackend::Functions
+ size=288 align=8
+ base size=288 base align=8
+QOpenGLFunctions_2_0_DeprecatedBackend::Functions (0x0x7f21abd731e0) 0
+
+Class QOpenGLFunctions_2_0_DeprecatedBackend
+ size=304 align=8
+ base size=304 base align=8
+QOpenGLFunctions_2_0_DeprecatedBackend (0x0x7f21abf8eb60) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21abd73180) 0
+
+Class QOpenGLFunctions_3_0_DeprecatedBackend::Functions
+ size=160 align=8
+ base size=160 base align=8
+QOpenGLFunctions_3_0_DeprecatedBackend::Functions (0x0x7f21abd73300) 0
+
+Class QOpenGLFunctions_3_0_DeprecatedBackend
+ size=176 align=8
+ base size=176 base align=8
+QOpenGLFunctions_3_0_DeprecatedBackend (0x0x7f21abf8ebc8) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21abd732a0) 0
+
+Class QOpenGLFunctions_3_3_DeprecatedBackend::Functions
+ size=240 align=8
+ base size=240 base align=8
+QOpenGLFunctions_3_3_DeprecatedBackend::Functions (0x0x7f21abd73420) 0
+
+Class QOpenGLFunctions_3_3_DeprecatedBackend
+ size=256 align=8
+ base size=256 base align=8
+QOpenGLFunctions_3_3_DeprecatedBackend (0x0x7f21abf8ec30) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21abd733c0) 0
+
+Class QOpenGLFunctions_4_5_DeprecatedBackend::Functions
+ size=96 align=8
+ base size=96 base align=8
+QOpenGLFunctions_4_5_DeprecatedBackend::Functions (0x0x7f21abd73540) 0
+
+Class QOpenGLFunctions_4_5_DeprecatedBackend
+ size=112 align=8
+ base size=112 base align=8
+QOpenGLFunctions_4_5_DeprecatedBackend (0x0x7f21abf8ec98) 0
+ QOpenGLVersionFunctionsBackend (0x0x7f21abd734e0) 0
+
+Class QOpenGLVersionProfile
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLVersionProfile (0x0x7f21abd73600) 0
+
+Class QOpenGLContextGroup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLContextGroup::QPrivateSignal (0x0x7f21abde0000) 0 empty
+
+Vtable for QOpenGLContextGroup
+QOpenGLContextGroup::_ZTV19QOpenGLContextGroup: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QOpenGLContextGroup)
+16 (int (*)(...))QOpenGLContextGroup::metaObject
+24 (int (*)(...))QOpenGLContextGroup::qt_metacast
+32 (int (*)(...))QOpenGLContextGroup::qt_metacall
+40 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup
+48 (int (*)(...))QOpenGLContextGroup::~QOpenGLContextGroup
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QOpenGLContextGroup
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLContextGroup (0x0x7f21abdca6e8) 0
+ vptr=((& QOpenGLContextGroup::_ZTV19QOpenGLContextGroup) + 16u)
+ QObject (0x0x7f21abd73f60) 0
+ primary-for QOpenGLContextGroup (0x0x7f21abdca6e8)
+
+Class QOpenGLContext::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLContext::QPrivateSignal (0x0x7f21abde00c0) 0 empty
+
+Vtable for QOpenGLContext
+QOpenGLContext::_ZTV14QOpenGLContext: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QOpenGLContext)
+16 (int (*)(...))QOpenGLContext::metaObject
+24 (int (*)(...))QOpenGLContext::qt_metacast
+32 (int (*)(...))QOpenGLContext::qt_metacall
+40 (int (*)(...))QOpenGLContext::~QOpenGLContext
+48 (int (*)(...))QOpenGLContext::~QOpenGLContext
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QOpenGLContext
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLContext (0x0x7f21abdca750) 0
+ vptr=((& QOpenGLContext::_ZTV14QOpenGLContext) + 16u)
+ QObject (0x0x7f21abde0060) 0
+ primary-for QOpenGLContext (0x0x7f21abdca750)
+
+Class QOpenGLDebugMessage
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLDebugMessage (0x0x7f21abde0120) 0
+
+Class QOpenGLDebugLogger::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLDebugLogger::QPrivateSignal (0x0x7f21abde0900) 0 empty
+
+Vtable for QOpenGLDebugLogger
+QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QOpenGLDebugLogger)
+16 (int (*)(...))QOpenGLDebugLogger::metaObject
+24 (int (*)(...))QOpenGLDebugLogger::qt_metacast
+32 (int (*)(...))QOpenGLDebugLogger::qt_metacall
+40 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger
+48 (int (*)(...))QOpenGLDebugLogger::~QOpenGLDebugLogger
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QOpenGLDebugLogger
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLDebugLogger (0x0x7f21abdcabc8) 0
+ vptr=((& QOpenGLDebugLogger::_ZTV18QOpenGLDebugLogger) + 16u)
+ QObject (0x0x7f21abde08a0) 0
+ primary-for QOpenGLDebugLogger (0x0x7f21abdcabc8)
+
+Class QOpenGLFunctions
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLFunctions (0x0x7f21abde0a80) 0
+
+Class QOpenGLFunctionsPrivate::Functions
+ size=1152 align=8
+ base size=1152 base align=8
+QOpenGLFunctionsPrivate::Functions (0x0x7f21abde0cc0) 0
+
+Class QOpenGLFunctionsPrivate
+ size=1152 align=8
+ base size=1152 base align=8
+QOpenGLFunctionsPrivate (0x0x7f21abde0c60) 0
+
+Class QOpenGLExtraFunctions
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLExtraFunctions (0x0x7f21abdcae38) 0
+ QOpenGLFunctions (0x0x7f21abc5c420) 0
+
+Class QOpenGLExtraFunctionsPrivate::Functions
+ size=1728 align=8
+ base size=1728 base align=8
+QOpenGLExtraFunctionsPrivate::Functions (0x0x7f21abc5c4e0) 0
+
+Class QOpenGLExtraFunctionsPrivate
+ size=2880 align=8
+ base size=2880 base align=8
+QOpenGLExtraFunctionsPrivate (0x0x7f21abdcaea0) 0
+ QOpenGLFunctionsPrivate (0x0x7f21abc5c480) 0
+
+Vtable for QOpenGLFramebufferObject
+QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QOpenGLFramebufferObject)
+16 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject
+24 (int (*)(...))QOpenGLFramebufferObject::~QOpenGLFramebufferObject
+
+Class QOpenGLFramebufferObject
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLFramebufferObject (0x0x7f21aba79ba0) 0
+ vptr=((& QOpenGLFramebufferObject::_ZTV24QOpenGLFramebufferObject) + 16u)
+
+Class QOpenGLFramebufferObjectFormat
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLFramebufferObjectFormat (0x0x7f21aba79cc0) 0
+
+Vtable for QOpenGLPaintDevice
+QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QOpenGLPaintDevice)
+16 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice
+24 (int (*)(...))QOpenGLPaintDevice::~QOpenGLPaintDevice
+32 (int (*)(...))QOpenGLPaintDevice::devType
+40 (int (*)(...))QOpenGLPaintDevice::paintEngine
+48 (int (*)(...))QOpenGLPaintDevice::metric
+56 (int (*)(...))QPaintDevice::initPainter
+64 (int (*)(...))QPaintDevice::redirected
+72 (int (*)(...))QPaintDevice::sharedPainter
+80 (int (*)(...))QOpenGLPaintDevice::ensureActiveTarget
+
+Class QOpenGLPaintDevice
+ size=32 align=8
+ base size=32 base align=8
+QOpenGLPaintDevice (0x0x7f21ab9f11a0) 0
+ vptr=((& QOpenGLPaintDevice::_ZTV18QOpenGLPaintDevice) + 16u)
+ QPaintDevice (0x0x7f21aba79d20) 0
+ primary-for QOpenGLPaintDevice (0x0x7f21ab9f11a0)
+
+Class QOpenGLPixelTransferOptions
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLPixelTransferOptions (0x0x7f21aba79e40) 0
+
+Class QOpenGLShader::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLShader::QPrivateSignal (0x0x7f21abafe1e0) 0 empty
+
+Vtable for QOpenGLShader
+QOpenGLShader::_ZTV13QOpenGLShader: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QOpenGLShader)
+16 (int (*)(...))QOpenGLShader::metaObject
+24 (int (*)(...))QOpenGLShader::qt_metacast
+32 (int (*)(...))QOpenGLShader::qt_metacall
+40 (int (*)(...))QOpenGLShader::~QOpenGLShader
+48 (int (*)(...))QOpenGLShader::~QOpenGLShader
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QOpenGLShader
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLShader (0x0x7f21ab9f13a8) 0
+ vptr=((& QOpenGLShader::_ZTV13QOpenGLShader) + 16u)
+ QObject (0x0x7f21abafe180) 0
+ primary-for QOpenGLShader (0x0x7f21ab9f13a8)
+
+Class QOpenGLShaderProgram::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLShaderProgram::QPrivateSignal (0x0x7f21abafe420) 0 empty
+
+Vtable for QOpenGLShaderProgram
+QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QOpenGLShaderProgram)
+16 (int (*)(...))QOpenGLShaderProgram::metaObject
+24 (int (*)(...))QOpenGLShaderProgram::qt_metacast
+32 (int (*)(...))QOpenGLShaderProgram::qt_metacall
+40 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram
+48 (int (*)(...))QOpenGLShaderProgram::~QOpenGLShaderProgram
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QOpenGLShaderProgram::link
+
+Class QOpenGLShaderProgram
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLShaderProgram (0x0x7f21ab9f14e0) 0
+ vptr=((& QOpenGLShaderProgram::_ZTV20QOpenGLShaderProgram) + 16u)
+ QObject (0x0x7f21abafe3c0) 0
+ primary-for QOpenGLShaderProgram (0x0x7f21ab9f14e0)
+
+Class QOpenGLTexture
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLTexture (0x0x7f21abafe480) 0
+
+Class QOpenGLTextureBlitter
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLTextureBlitter (0x0x7f21abafe720) 0
+
+Class QOpenGLTimerQuery::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLTimerQuery::QPrivateSignal (0x0x7f21abafe8a0) 0 empty
+
+Vtable for QOpenGLTimerQuery
+QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QOpenGLTimerQuery)
+16 (int (*)(...))QOpenGLTimerQuery::metaObject
+24 (int (*)(...))QOpenGLTimerQuery::qt_metacast
+32 (int (*)(...))QOpenGLTimerQuery::qt_metacall
+40 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery
+48 (int (*)(...))QOpenGLTimerQuery::~QOpenGLTimerQuery
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QOpenGLTimerQuery
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLTimerQuery (0x0x7f21ab9f1618) 0
+ vptr=((& QOpenGLTimerQuery::_ZTV17QOpenGLTimerQuery) + 16u)
+ QObject (0x0x7f21abafe840) 0
+ primary-for QOpenGLTimerQuery (0x0x7f21ab9f1618)
+
+Class QOpenGLTimeMonitor::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLTimeMonitor::QPrivateSignal (0x0x7f21abafe960) 0 empty
+
+Vtable for QOpenGLTimeMonitor
+QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QOpenGLTimeMonitor)
+16 (int (*)(...))QOpenGLTimeMonitor::metaObject
+24 (int (*)(...))QOpenGLTimeMonitor::qt_metacast
+32 (int (*)(...))QOpenGLTimeMonitor::qt_metacall
+40 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor
+48 (int (*)(...))QOpenGLTimeMonitor::~QOpenGLTimeMonitor
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QOpenGLTimeMonitor
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLTimeMonitor (0x0x7f21ab9f1680) 0
+ vptr=((& QOpenGLTimeMonitor::_ZTV18QOpenGLTimeMonitor) + 16u)
+ QObject (0x0x7f21abafe900) 0
+ primary-for QOpenGLTimeMonitor (0x0x7f21ab9f1680)
+
+Class QOpenGLVertexArrayObject::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLVertexArrayObject::QPrivateSignal (0x0x7f21abafea20) 0 empty
+
+Class QOpenGLVertexArrayObject::Binder
+ size=8 align=8
+ base size=8 base align=8
+QOpenGLVertexArrayObject::Binder (0x0x7f21abafea80) 0
+
+Vtable for QOpenGLVertexArrayObject
+QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QOpenGLVertexArrayObject)
+16 (int (*)(...))QOpenGLVertexArrayObject::metaObject
+24 (int (*)(...))QOpenGLVertexArrayObject::qt_metacast
+32 (int (*)(...))QOpenGLVertexArrayObject::qt_metacall
+40 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject
+48 (int (*)(...))QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QOpenGLVertexArrayObject
+ size=16 align=8
+ base size=16 base align=8
+QOpenGLVertexArrayObject (0x0x7f21ab9f16e8) 0
+ vptr=((& QOpenGLVertexArrayObject::_ZTV24QOpenGLVertexArrayObject) + 16u)
+ QObject (0x0x7f21abafe9c0) 0
+ primary-for QOpenGLVertexArrayObject (0x0x7f21ab9f16e8)
+
+Class QPaintDeviceWindow::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPaintDeviceWindow::QPrivateSignal (0x0x7f21abafec00) 0 empty
+
+Vtable for QPaintDeviceWindow
+QPaintDeviceWindow::_ZTV18QPaintDeviceWindow: 58u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QPaintDeviceWindow)
+16 (int (*)(...))QPaintDeviceWindow::metaObject
+24 (int (*)(...))QPaintDeviceWindow::qt_metacast
+32 (int (*)(...))QPaintDeviceWindow::qt_metacall
+40 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow
+48 (int (*)(...))QPaintDeviceWindow::~QPaintDeviceWindow
+56 (int (*)(...))QPaintDeviceWindow::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWindow::surfaceType
+120 (int (*)(...))QWindow::format
+128 (int (*)(...))QWindow::size
+136 (int (*)(...))QWindow::accessibleRoot
+144 (int (*)(...))QWindow::focusObject
+152 (int (*)(...))QPaintDeviceWindow::exposeEvent
+160 (int (*)(...))QWindow::resizeEvent
+168 (int (*)(...))QWindow::moveEvent
+176 (int (*)(...))QWindow::focusInEvent
+184 (int (*)(...))QWindow::focusOutEvent
+192 (int (*)(...))QWindow::showEvent
+200 (int (*)(...))QWindow::hideEvent
+208 (int (*)(...))QWindow::keyPressEvent
+216 (int (*)(...))QWindow::keyReleaseEvent
+224 (int (*)(...))QWindow::mousePressEvent
+232 (int (*)(...))QWindow::mouseReleaseEvent
+240 (int (*)(...))QWindow::mouseDoubleClickEvent
+248 (int (*)(...))QWindow::mouseMoveEvent
+256 (int (*)(...))QWindow::wheelEvent
+264 (int (*)(...))QWindow::touchEvent
+272 (int (*)(...))QWindow::tabletEvent
+280 (int (*)(...))QWindow::nativeEvent
+288 (int (*)(...))QWindow::surfaceHandle
+296 (int (*)(...))QPaintDeviceWindow::paintEvent
+304 (int (*)(...))QPaintDeviceWindow::metric
+312 (int (*)(...))QPaintDeviceWindow::paintEngine
+320 (int (*)(...))-16
+328 (int (*)(...))(& _ZTI18QPaintDeviceWindow)
+336 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD1Ev
+344 (int (*)(...))QPaintDeviceWindow::_ZThn16_N18QPaintDeviceWindowD0Ev
+352 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv
+360 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv
+368 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv
+376 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv
+384 (int (*)(...))-40
+392 (int (*)(...))(& _ZTI18QPaintDeviceWindow)
+400 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD1Ev
+408 (int (*)(...))QPaintDeviceWindow::_ZThn40_N18QPaintDeviceWindowD0Ev
+416 (int (*)(...))QPaintDevice::devType
+424 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv
+432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow6metricEN12QPaintDevice17PaintDeviceMetricE
+440 (int (*)(...))QPaintDevice::initPainter
+448 (int (*)(...))QPaintDevice::redirected
+456 (int (*)(...))QPaintDevice::sharedPainter
+
+Class QPaintDeviceWindow
+ size=64 align=8
+ base size=64 base align=8
+QPaintDeviceWindow (0x0x7f21ab878930) 0
+ vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 16u)
+ QWindow (0x0x7f21ab8789a0) 0
+ primary-for QPaintDeviceWindow (0x0x7f21ab878930)
+ QObject (0x0x7f21abafeae0) 0
+ primary-for QWindow (0x0x7f21ab8789a0)
+ QSurface (0x0x7f21abafeb40) 16
+ vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 336u)
+ QPaintDevice (0x0x7f21abafeba0) 40
+ vptr=((& QPaintDeviceWindow::_ZTV18QPaintDeviceWindow) + 400u)
+
+Class QOpenGLWindow::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLWindow::QPrivateSignal (0x0x7f21abafed80) 0 empty
+
+Vtable for QOpenGLWindow
+QOpenGLWindow::_ZTV13QOpenGLWindow: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QOpenGLWindow)
+16 (int (*)(...))QOpenGLWindow::metaObject
+24 (int (*)(...))QOpenGLWindow::qt_metacast
+32 (int (*)(...))QOpenGLWindow::qt_metacall
+40 (int (*)(...))QOpenGLWindow::~QOpenGLWindow
+48 (int (*)(...))QOpenGLWindow::~QOpenGLWindow
+56 (int (*)(...))QPaintDeviceWindow::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWindow::surfaceType
+120 (int (*)(...))QWindow::format
+128 (int (*)(...))QWindow::size
+136 (int (*)(...))QWindow::accessibleRoot
+144 (int (*)(...))QWindow::focusObject
+152 (int (*)(...))QPaintDeviceWindow::exposeEvent
+160 (int (*)(...))QOpenGLWindow::resizeEvent
+168 (int (*)(...))QWindow::moveEvent
+176 (int (*)(...))QWindow::focusInEvent
+184 (int (*)(...))QWindow::focusOutEvent
+192 (int (*)(...))QWindow::showEvent
+200 (int (*)(...))QWindow::hideEvent
+208 (int (*)(...))QWindow::keyPressEvent
+216 (int (*)(...))QWindow::keyReleaseEvent
+224 (int (*)(...))QWindow::mousePressEvent
+232 (int (*)(...))QWindow::mouseReleaseEvent
+240 (int (*)(...))QWindow::mouseDoubleClickEvent
+248 (int (*)(...))QWindow::mouseMoveEvent
+256 (int (*)(...))QWindow::wheelEvent
+264 (int (*)(...))QWindow::touchEvent
+272 (int (*)(...))QWindow::tabletEvent
+280 (int (*)(...))QWindow::nativeEvent
+288 (int (*)(...))QWindow::surfaceHandle
+296 (int (*)(...))QOpenGLWindow::paintEvent
+304 (int (*)(...))QOpenGLWindow::metric
+312 (int (*)(...))QPaintDeviceWindow::paintEngine
+320 (int (*)(...))QOpenGLWindow::initializeGL
+328 (int (*)(...))QOpenGLWindow::resizeGL
+336 (int (*)(...))QOpenGLWindow::paintGL
+344 (int (*)(...))QOpenGLWindow::paintUnderGL
+352 (int (*)(...))QOpenGLWindow::paintOverGL
+360 (int (*)(...))QOpenGLWindow::redirected
+368 (int (*)(...))-16
+376 (int (*)(...))(& _ZTI13QOpenGLWindow)
+384 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD1Ev
+392 (int (*)(...))QOpenGLWindow::_ZThn16_N13QOpenGLWindowD0Ev
+400 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv
+408 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv
+416 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv
+424 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv
+432 (int (*)(...))-40
+440 (int (*)(...))(& _ZTI13QOpenGLWindow)
+448 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD1Ev
+456 (int (*)(...))QOpenGLWindow::_ZThn40_N13QOpenGLWindowD0Ev
+464 (int (*)(...))QPaintDevice::devType
+472 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv
+480 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QPaintDevice::initPainter
+496 (int (*)(...))QOpenGLWindow::_ZThn40_NK13QOpenGLWindow10redirectedEP6QPoint
+504 (int (*)(...))QPaintDevice::sharedPainter
+
+Class QOpenGLWindow
+ size=64 align=8
+ base size=64 base align=8
+QOpenGLWindow (0x0x7f21ab9f17b8) 0
+ vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 16u)
+ QPaintDeviceWindow (0x0x7f21ab878ee0) 0
+ primary-for QOpenGLWindow (0x0x7f21ab9f17b8)
+ QWindow (0x0x7f21ab878f50) 0
+ primary-for QPaintDeviceWindow (0x0x7f21ab878ee0)
+ QObject (0x0x7f21abafec60) 0
+ primary-for QWindow (0x0x7f21ab878f50)
+ QSurface (0x0x7f21abafecc0) 16
+ vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 384u)
+ QPaintDevice (0x0x7f21abafed20) 40
+ vptr=((& QOpenGLWindow::_ZTV13QOpenGLWindow) + 448u)
+
+Class QPageSize
+ size=8 align=8
+ base size=8 base align=8
+QPageSize (0x0x7f21abafede0) 0
+
+Class QPageLayout
+ size=8 align=8
+ base size=8 base align=8
+QPageLayout (0x0x7f21ab8d27e0) 0
+
+Class QPagedPaintDevice::Margins
+ size=32 align=8
+ base size=32 base align=8
+QPagedPaintDevice::Margins (0x0x7f21ab93c240) 0
+
+Vtable for QPagedPaintDevice
+QPagedPaintDevice::_ZTV17QPagedPaintDevice: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QPagedPaintDevice)
+16 0u
+24 0u
+32 (int (*)(...))QPaintDevice::devType
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))QPaintDevice::metric
+56 (int (*)(...))QPaintDevice::initPainter
+64 (int (*)(...))QPaintDevice::redirected
+72 (int (*)(...))QPaintDevice::sharedPainter
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))QPagedPaintDevice::setPageSize
+96 (int (*)(...))QPagedPaintDevice::setPageSizeMM
+104 (int (*)(...))QPagedPaintDevice::setMargins
+
+Class QPagedPaintDevice
+ size=32 align=8
+ base size=32 base align=8
+QPagedPaintDevice (0x0x7f21ab9254e0) 0
+ vptr=((& QPagedPaintDevice::_ZTV17QPagedPaintDevice) + 16u)
+ QPaintDevice (0x0x7f21ab93c1e0) 0
+ primary-for QPagedPaintDevice (0x0x7f21ab9254e0)
+
+Class QPainter::PixmapFragment
+ size=80 align=8
+ base size=80 base align=8
+QPainter::PixmapFragment (0x0x7f21ab93c300) 0
+
+Class QPainter
+ size=8 align=8
+ base size=8 base align=8
+QPainter (0x0x7f21ab93c2a0) 0
+
+Class QTextItem
+ size=1 align=1
+ base size=0 base align=1
+QTextItem (0x0x7f21ab705120) 0 empty
+
+Vtable for QPaintEngine
+QPaintEngine::_ZTV12QPaintEngine: 24u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QPaintEngine)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))QPaintEngine::drawRects
+64 (int (*)(...))QPaintEngine::drawRects
+72 (int (*)(...))QPaintEngine::drawLines
+80 (int (*)(...))QPaintEngine::drawLines
+88 (int (*)(...))QPaintEngine::drawEllipse
+96 (int (*)(...))QPaintEngine::drawEllipse
+104 (int (*)(...))QPaintEngine::drawPath
+112 (int (*)(...))QPaintEngine::drawPoints
+120 (int (*)(...))QPaintEngine::drawPoints
+128 (int (*)(...))QPaintEngine::drawPolygon
+136 (int (*)(...))QPaintEngine::drawPolygon
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))QPaintEngine::drawTextItem
+160 (int (*)(...))QPaintEngine::drawTiledPixmap
+168 (int (*)(...))QPaintEngine::drawImage
+176 (int (*)(...))QPaintEngine::coordinateOffset
+184 (int (*)(...))__cxa_pure_virtual
+
+Class QPaintEngine
+ size=32 align=8
+ base size=32 base align=8
+QPaintEngine (0x0x7f21ab7053c0) 0
+ vptr=((& QPaintEngine::_ZTV12QPaintEngine) + 16u)
+
+Class QPaintEngineState
+ size=4 align=4
+ base size=4 base align=4
+QPaintEngineState (0x0x7f21ab705660) 0
+
+Class QPdfWriter::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPdfWriter::QPrivateSignal (0x0x7f21ab705a80) 0 empty
+
+Vtable for QPdfWriter
+QPdfWriter::_ZTV10QPdfWriter: 34u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QPdfWriter)
+16 (int (*)(...))QPdfWriter::metaObject
+24 (int (*)(...))QPdfWriter::qt_metacast
+32 (int (*)(...))QPdfWriter::qt_metacall
+40 (int (*)(...))QPdfWriter::~QPdfWriter
+48 (int (*)(...))QPdfWriter::~QPdfWriter
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QPdfWriter::newPage
+120 (int (*)(...))QPdfWriter::setPageSize
+128 (int (*)(...))QPdfWriter::setPageSizeMM
+136 (int (*)(...))QPdfWriter::setMargins
+144 (int (*)(...))QPdfWriter::paintEngine
+152 (int (*)(...))QPdfWriter::metric
+160 (int (*)(...))-16
+168 (int (*)(...))(& _ZTI10QPdfWriter)
+176 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD1Ev
+184 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriterD0Ev
+192 (int (*)(...))QPaintDevice::devType
+200 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter11paintEngineEv
+208 (int (*)(...))QPdfWriter::_ZThn16_NK10QPdfWriter6metricEN12QPaintDevice17PaintDeviceMetricE
+216 (int (*)(...))QPaintDevice::initPainter
+224 (int (*)(...))QPaintDevice::redirected
+232 (int (*)(...))QPaintDevice::sharedPainter
+240 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter7newPageEv
+248 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter11setPageSizeEN17QPagedPaintDevice8PageSizeE
+256 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter13setPageSizeMMERK6QSizeF
+264 (int (*)(...))QPdfWriter::_ZThn16_N10QPdfWriter10setMarginsERKN17QPagedPaintDevice7MarginsE
+
+Class QPdfWriter
+ size=48 align=8
+ base size=48 base align=8
+QPdfWriter (0x0x7f21ab3ea310) 0
+ vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 16u)
+ QObject (0x0x7f21ab7059c0) 0
+ primary-for QPdfWriter (0x0x7f21ab3ea310)
+ QPagedPaintDevice (0x0x7f21ab707548) 16
+ vptr=((& QPdfWriter::_ZTV10QPdfWriter) + 176u)
+ QPaintDevice (0x0x7f21ab705a20) 16
+ primary-for QPagedPaintDevice (0x0x7f21ab707548)
+
+Vtable for QPicture
+QPicture::_ZTV8QPicture: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QPicture)
+16 (int (*)(...))QPicture::~QPicture
+24 (int (*)(...))QPicture::~QPicture
+32 (int (*)(...))QPicture::devType
+40 (int (*)(...))QPicture::paintEngine
+48 (int (*)(...))QPicture::metric
+56 (int (*)(...))QPaintDevice::initPainter
+64 (int (*)(...))QPaintDevice::redirected
+72 (int (*)(...))QPaintDevice::sharedPainter
+80 (int (*)(...))QPicture::setData
+
+Class QPicture
+ size=32 align=8
+ base size=32 base align=8
+QPicture (0x0x7f21ab7075b0) 0
+ vptr=((& QPicture::_ZTV8QPicture) + 16u)
+ QPaintDevice (0x0x7f21ab705c00) 0
+ primary-for QPicture (0x0x7f21ab7075b0)
+
+Class QPictureIO
+ size=8 align=8
+ base size=8 base align=8
+QPictureIO (0x0x7f21ab705f00) 0
+
+Class QPictureFormatPlugin::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPictureFormatPlugin::QPrivateSignal (0x0x7f21ab442000) 0 empty
+
+Vtable for QPictureFormatPlugin
+QPictureFormatPlugin::_ZTV20QPictureFormatPlugin: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QPictureFormatPlugin)
+16 (int (*)(...))QPictureFormatPlugin::metaObject
+24 (int (*)(...))QPictureFormatPlugin::qt_metacast
+32 (int (*)(...))QPictureFormatPlugin::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QPictureFormatPlugin::loadPicture
+120 (int (*)(...))QPictureFormatPlugin::savePicture
+128 (int (*)(...))__cxa_pure_virtual
+
+Class QPictureFormatPlugin
+ size=16 align=8
+ base size=16 base align=8
+QPictureFormatPlugin (0x0x7f21ab7077b8) 0
+ vptr=((& QPictureFormatPlugin::_ZTV20QPictureFormatPlugin) + 16u)
+ QObject (0x0x7f21ab705f60) 0
+ primary-for QPictureFormatPlugin (0x0x7f21ab7077b8)
+
+Class QPixmapCache::Key
+ size=8 align=8
+ base size=8 base align=8
+QPixmapCache::Key (0x0x7f21ab4420c0) 0
+
+Class QPixmapCache
+ size=1 align=1
+ base size=0 base align=1
+QPixmapCache (0x0x7f21ab442060) 0 empty
+
+Class QRasterWindow::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QRasterWindow::QPrivateSignal (0x0x7f21ab4cd240) 0 empty
+
+Vtable for QRasterWindow
+QRasterWindow::_ZTV13QRasterWindow: 59u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QRasterWindow)
+16 (int (*)(...))QRasterWindow::metaObject
+24 (int (*)(...))QRasterWindow::qt_metacast
+32 (int (*)(...))QRasterWindow::qt_metacall
+40 (int (*)(...))QRasterWindow::~QRasterWindow
+48 (int (*)(...))QRasterWindow::~QRasterWindow
+56 (int (*)(...))QPaintDeviceWindow::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWindow::surfaceType
+120 (int (*)(...))QWindow::format
+128 (int (*)(...))QWindow::size
+136 (int (*)(...))QWindow::accessibleRoot
+144 (int (*)(...))QWindow::focusObject
+152 (int (*)(...))QPaintDeviceWindow::exposeEvent
+160 (int (*)(...))QWindow::resizeEvent
+168 (int (*)(...))QWindow::moveEvent
+176 (int (*)(...))QWindow::focusInEvent
+184 (int (*)(...))QWindow::focusOutEvent
+192 (int (*)(...))QWindow::showEvent
+200 (int (*)(...))QWindow::hideEvent
+208 (int (*)(...))QWindow::keyPressEvent
+216 (int (*)(...))QWindow::keyReleaseEvent
+224 (int (*)(...))QWindow::mousePressEvent
+232 (int (*)(...))QWindow::mouseReleaseEvent
+240 (int (*)(...))QWindow::mouseDoubleClickEvent
+248 (int (*)(...))QWindow::mouseMoveEvent
+256 (int (*)(...))QWindow::wheelEvent
+264 (int (*)(...))QWindow::touchEvent
+272 (int (*)(...))QWindow::tabletEvent
+280 (int (*)(...))QWindow::nativeEvent
+288 (int (*)(...))QWindow::surfaceHandle
+296 (int (*)(...))QPaintDeviceWindow::paintEvent
+304 (int (*)(...))QRasterWindow::metric
+312 (int (*)(...))QPaintDeviceWindow::paintEngine
+320 (int (*)(...))QRasterWindow::redirected
+328 (int (*)(...))-16
+336 (int (*)(...))(& _ZTI13QRasterWindow)
+344 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD1Ev
+352 (int (*)(...))QRasterWindow::_ZThn16_N13QRasterWindowD0Ev
+360 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv
+368 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv
+376 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv
+384 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv
+392 (int (*)(...))-40
+400 (int (*)(...))(& _ZTI13QRasterWindow)
+408 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD1Ev
+416 (int (*)(...))QRasterWindow::_ZThn40_N13QRasterWindowD0Ev
+424 (int (*)(...))QPaintDevice::devType
+432 (int (*)(...))QPaintDeviceWindow::_ZThn40_NK18QPaintDeviceWindow11paintEngineEv
+440 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow6metricEN12QPaintDevice17PaintDeviceMetricE
+448 (int (*)(...))QPaintDevice::initPainter
+456 (int (*)(...))QRasterWindow::_ZThn40_NK13QRasterWindow10redirectedEP6QPoint
+464 (int (*)(...))QPaintDevice::sharedPainter
+
+Class QRasterWindow
+ size=64 align=8
+ base size=64 base align=8
+QRasterWindow (0x0x7f21ab4b9ea0) 0
+ vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 16u)
+ QPaintDeviceWindow (0x0x7f21ab4c7a10) 0
+ primary-for QRasterWindow (0x0x7f21ab4b9ea0)
+ QWindow (0x0x7f21ab4c7a80) 0
+ primary-for QPaintDeviceWindow (0x0x7f21ab4c7a10)
+ QObject (0x0x7f21ab4cd120) 0
+ primary-for QWindow (0x0x7f21ab4c7a80)
+ QSurface (0x0x7f21ab4cd180) 16
+ vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 344u)
+ QPaintDevice (0x0x7f21ab4cd1e0) 40
+ vptr=((& QRasterWindow::_ZTV13QRasterWindow) + 408u)
+
+Class QScreen::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QScreen::QPrivateSignal (0x0x7f21ab4cd300) 0 empty
+
+Vtable for QScreen
+QScreen::_ZTV7QScreen: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QScreen)
+16 (int (*)(...))QScreen::metaObject
+24 (int (*)(...))QScreen::qt_metacast
+32 (int (*)(...))QScreen::qt_metacall
+40 (int (*)(...))QScreen::~QScreen
+48 (int (*)(...))QScreen::~QScreen
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QScreen
+ size=16 align=8
+ base size=16 base align=8
+QScreen (0x0x7f21ab4b9f70) 0
+ vptr=((& QScreen::_ZTV7QScreen) + 16u)
+ QObject (0x0x7f21ab4cd2a0) 0
+ primary-for QScreen (0x0x7f21ab4b9f70)
+
+Class QSessionManager::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSessionManager::QPrivateSignal (0x0x7f21ab4cd3c0) 0 empty
+
+Vtable for QSessionManager
+QSessionManager::_ZTV15QSessionManager: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QSessionManager)
+16 (int (*)(...))QSessionManager::metaObject
+24 (int (*)(...))QSessionManager::qt_metacast
+32 (int (*)(...))QSessionManager::qt_metacall
+40 (int (*)(...))QSessionManager::~QSessionManager
+48 (int (*)(...))QSessionManager::~QSessionManager
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QSessionManager
+ size=16 align=8
+ base size=16 base align=8
+QSessionManager (0x0x7f21ab4fd000) 0
+ vptr=((& QSessionManager::_ZTV15QSessionManager) + 16u)
+ QObject (0x0x7f21ab4cd360) 0
+ primary-for QSessionManager (0x0x7f21ab4fd000)
+
+Vtable for QStandardItem
+QStandardItem::_ZTV13QStandardItem: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QStandardItem)
+16 (int (*)(...))QStandardItem::~QStandardItem
+24 (int (*)(...))QStandardItem::~QStandardItem
+32 (int (*)(...))QStandardItem::data
+40 (int (*)(...))QStandardItem::setData
+48 (int (*)(...))QStandardItem::clone
+56 (int (*)(...))QStandardItem::type
+64 (int (*)(...))QStandardItem::read
+72 (int (*)(...))QStandardItem::write
+80 (int (*)(...))QStandardItem::operator<
+
+Class QStandardItem
+ size=16 align=8
+ base size=16 base align=8
+QStandardItem (0x0x7f21ab4cd420) 0
+ vptr=((& QStandardItem::_ZTV13QStandardItem) + 16u)
+
+Class QStandardItemModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QStandardItemModel::QPrivateSignal (0x0x7f21ab4cdb40) 0 empty
+
+Vtable for QStandardItemModel
+QStandardItemModel::_ZTV18QStandardItemModel: 48u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QStandardItemModel)
+16 (int (*)(...))QStandardItemModel::metaObject
+24 (int (*)(...))QStandardItemModel::qt_metacast
+32 (int (*)(...))QStandardItemModel::qt_metacall
+40 (int (*)(...))QStandardItemModel::~QStandardItemModel
+48 (int (*)(...))QStandardItemModel::~QStandardItemModel
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QStandardItemModel::index
+120 (int (*)(...))QStandardItemModel::parent
+128 (int (*)(...))QStandardItemModel::sibling
+136 (int (*)(...))QStandardItemModel::rowCount
+144 (int (*)(...))QStandardItemModel::columnCount
+152 (int (*)(...))QStandardItemModel::hasChildren
+160 (int (*)(...))QStandardItemModel::data
+168 (int (*)(...))QStandardItemModel::setData
+176 (int (*)(...))QStandardItemModel::headerData
+184 (int (*)(...))QStandardItemModel::setHeaderData
+192 (int (*)(...))QStandardItemModel::itemData
+200 (int (*)(...))QStandardItemModel::setItemData
+208 (int (*)(...))QStandardItemModel::mimeTypes
+216 (int (*)(...))QStandardItemModel::mimeData
+224 (int (*)(...))QAbstractItemModel::canDropMimeData
+232 (int (*)(...))QStandardItemModel::dropMimeData
+240 (int (*)(...))QStandardItemModel::supportedDropActions
+248 (int (*)(...))QAbstractItemModel::supportedDragActions
+256 (int (*)(...))QStandardItemModel::insertRows
+264 (int (*)(...))QStandardItemModel::insertColumns
+272 (int (*)(...))QStandardItemModel::removeRows
+280 (int (*)(...))QStandardItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractItemModel::fetchMore
+312 (int (*)(...))QAbstractItemModel::canFetchMore
+320 (int (*)(...))QStandardItemModel::flags
+328 (int (*)(...))QStandardItemModel::sort
+336 (int (*)(...))QAbstractItemModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractItemModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractItemModel::submit
+376 (int (*)(...))QAbstractItemModel::revert
+
+Class QStandardItemModel
+ size=16 align=8
+ base size=16 base align=8
+QStandardItemModel (0x0x7f21ab4fd680) 0
+ vptr=((& QStandardItemModel::_ZTV18QStandardItemModel) + 16u)
+ QAbstractItemModel (0x0x7f21ab4fd6e8) 0
+ primary-for QStandardItemModel (0x0x7f21ab4fd680)
+ QObject (0x0x7f21ab4cdae0) 0
+ primary-for QAbstractItemModel (0x0x7f21ab4fd6e8)
+
+Class QStaticText
+ size=8 align=8
+ base size=8 base align=8
+QStaticText (0x0x7f21ab4cdba0) 0
+
+Class QStyleHints::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QStyleHints::QPrivateSignal (0x0x7f21ab234060) 0 empty
+
+Vtable for QStyleHints
+QStyleHints::_ZTV11QStyleHints: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QStyleHints)
+16 (int (*)(...))QStyleHints::metaObject
+24 (int (*)(...))QStyleHints::qt_metacast
+32 (int (*)(...))QStyleHints::qt_metacall
+40 (int (*)(...))QStyleHints::~QStyleHints
+48 (int (*)(...))QStyleHints::~QStyleHints
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QStyleHints
+ size=16 align=8
+ base size=16 base align=8
+QStyleHints (0x0x7f21ab4fd8f0) 0
+ vptr=((& QStyleHints::_ZTV11QStyleHints) + 16u)
+ QObject (0x0x7f21ab234000) 0
+ primary-for QStyleHints (0x0x7f21ab4fd8f0)
+
+Class QTextObject::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTextObject::QPrivateSignal (0x0x7f21ab234120) 0 empty
+
+Vtable for QTextObject
+QTextObject::_ZTV11QTextObject: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTextObject)
+16 (int (*)(...))QTextObject::metaObject
+24 (int (*)(...))QTextObject::qt_metacast
+32 (int (*)(...))QTextObject::qt_metacall
+40 (int (*)(...))QTextObject::~QTextObject
+48 (int (*)(...))QTextObject::~QTextObject
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QTextObject
+ size=16 align=8
+ base size=16 base align=8
+QTextObject (0x0x7f21ab4fd958) 0
+ vptr=((& QTextObject::_ZTV11QTextObject) + 16u)
+ QObject (0x0x7f21ab2340c0) 0
+ primary-for QTextObject (0x0x7f21ab4fd958)
+
+Class QTextBlockGroup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTextBlockGroup::QPrivateSignal (0x0x7f21ab2341e0) 0 empty
+
+Vtable for QTextBlockGroup
+QTextBlockGroup::_ZTV15QTextBlockGroup: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QTextBlockGroup)
+16 (int (*)(...))QTextBlockGroup::metaObject
+24 (int (*)(...))QTextBlockGroup::qt_metacast
+32 (int (*)(...))QTextBlockGroup::qt_metacall
+40 (int (*)(...))QTextBlockGroup::~QTextBlockGroup
+48 (int (*)(...))QTextBlockGroup::~QTextBlockGroup
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QTextBlockGroup::blockInserted
+120 (int (*)(...))QTextBlockGroup::blockRemoved
+128 (int (*)(...))QTextBlockGroup::blockFormatChanged
+
+Class QTextBlockGroup
+ size=16 align=8
+ base size=16 base align=8
+QTextBlockGroup (0x0x7f21ab4fd9c0) 0
+ vptr=((& QTextBlockGroup::_ZTV15QTextBlockGroup) + 16u)
+ QTextObject (0x0x7f21ab4fda28) 0
+ primary-for QTextBlockGroup (0x0x7f21ab4fd9c0)
+ QObject (0x0x7f21ab234180) 0
+ primary-for QTextObject (0x0x7f21ab4fda28)
+
+Vtable for QTextFrameLayoutData
+QTextFrameLayoutData::_ZTV20QTextFrameLayoutData: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QTextFrameLayoutData)
+16 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData
+24 (int (*)(...))QTextFrameLayoutData::~QTextFrameLayoutData
+
+Class QTextFrameLayoutData
+ size=8 align=8
+ base size=8 base align=8
+QTextFrameLayoutData (0x0x7f21ab234240) 0 nearly-empty
+ vptr=((& QTextFrameLayoutData::_ZTV20QTextFrameLayoutData) + 16u)
+
+Class QTextFrame::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTextFrame::QPrivateSignal (0x0x7f21ab234300) 0 empty
+
+Class QTextFrame::iterator
+ size=32 align=8
+ base size=28 base align=8
+QTextFrame::iterator (0x0x7f21ab234360) 0
+
+Vtable for QTextFrame
+QTextFrame::_ZTV10QTextFrame: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTextFrame)
+16 (int (*)(...))QTextFrame::metaObject
+24 (int (*)(...))QTextFrame::qt_metacast
+32 (int (*)(...))QTextFrame::qt_metacall
+40 (int (*)(...))QTextFrame::~QTextFrame
+48 (int (*)(...))QTextFrame::~QTextFrame
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QTextFrame
+ size=16 align=8
+ base size=16 base align=8
+QTextFrame (0x0x7f21ab4fda90) 0
+ vptr=((& QTextFrame::_ZTV10QTextFrame) + 16u)
+ QTextObject (0x0x7f21ab4fdaf8) 0
+ primary-for QTextFrame (0x0x7f21ab4fda90)
+ QObject (0x0x7f21ab2342a0) 0
+ primary-for QTextObject (0x0x7f21ab4fdaf8)
+
+Vtable for QTextBlockUserData
+QTextBlockUserData::_ZTV18QTextBlockUserData: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QTextBlockUserData)
+16 (int (*)(...))QTextBlockUserData::~QTextBlockUserData
+24 (int (*)(...))QTextBlockUserData::~QTextBlockUserData
+
+Class QTextBlockUserData
+ size=8 align=8
+ base size=8 base align=8
+QTextBlockUserData (0x0x7f21ab234600) 0 nearly-empty
+ vptr=((& QTextBlockUserData::_ZTV18QTextBlockUserData) + 16u)
+
+Class QTextBlock::iterator
+ size=24 align=8
+ base size=20 base align=8
+QTextBlock::iterator (0x0x7f21ab2346c0) 0
+
+Class QTextBlock
+ size=16 align=8
+ base size=12 base align=8
+QTextBlock (0x0x7f21ab234660) 0
+
+Class QTextFragment
+ size=16 align=8
+ base size=16 base align=8
+QTextFragment (0x0x7f21ab234ba0) 0
+
+Class QSyntaxHighlighter::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSyntaxHighlighter::QPrivateSignal (0x0x7f21ab234ea0) 0 empty
+
+Vtable for QSyntaxHighlighter
+QSyntaxHighlighter::_ZTV18QSyntaxHighlighter: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QSyntaxHighlighter)
+16 (int (*)(...))QSyntaxHighlighter::metaObject
+24 (int (*)(...))QSyntaxHighlighter::qt_metacast
+32 (int (*)(...))QSyntaxHighlighter::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+
+Class QSyntaxHighlighter
+ size=16 align=8
+ base size=16 base align=8
+QSyntaxHighlighter (0x0x7f21ab2ce208) 0
+ vptr=((& QSyntaxHighlighter::_ZTV18QSyntaxHighlighter) + 16u)
+ QObject (0x0x7f21ab234e40) 0
+ primary-for QSyntaxHighlighter (0x0x7f21ab2ce208)
+
+Class QTextDocumentFragment
+ size=8 align=8
+ base size=8 base align=8
+QTextDocumentFragment (0x0x7f21ab234f00) 0
+
+Class QTextDocumentWriter
+ size=8 align=8
+ base size=8 base align=8
+QTextDocumentWriter (0x0x7f21ab234f60) 0
+
+Class QTextList::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTextList::QPrivateSignal (0x0x7f21ab301060) 0 empty
+
+Vtable for QTextList
+QTextList::_ZTV9QTextList: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QTextList)
+16 (int (*)(...))QTextList::metaObject
+24 (int (*)(...))QTextList::qt_metacast
+32 (int (*)(...))QTextList::qt_metacall
+40 (int (*)(...))QTextList::~QTextList
+48 (int (*)(...))QTextList::~QTextList
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QTextBlockGroup::blockInserted
+120 (int (*)(...))QTextBlockGroup::blockRemoved
+128 (int (*)(...))QTextBlockGroup::blockFormatChanged
+
+Class QTextList
+ size=16 align=8
+ base size=16 base align=8
+QTextList (0x0x7f21ab2ce270) 0
+ vptr=((& QTextList::_ZTV9QTextList) + 16u)
+ QTextBlockGroup (0x0x7f21ab2ce2d8) 0
+ primary-for QTextList (0x0x7f21ab2ce270)
+ QTextObject (0x0x7f21ab2ce340) 0
+ primary-for QTextBlockGroup (0x0x7f21ab2ce2d8)
+ QObject (0x0x7f21ab301000) 0
+ primary-for QTextObject (0x0x7f21ab2ce340)
+
+Class QTextTableCell
+ size=16 align=8
+ base size=12 base align=8
+QTextTableCell (0x0x7f21ab3010c0) 0
+
+Class QTextTable::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTextTable::QPrivateSignal (0x0x7f21ab301180) 0 empty
+
+Vtable for QTextTable
+QTextTable::_ZTV10QTextTable: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTextTable)
+16 (int (*)(...))QTextTable::metaObject
+24 (int (*)(...))QTextTable::qt_metacast
+32 (int (*)(...))QTextTable::qt_metacall
+40 (int (*)(...))QTextTable::~QTextTable
+48 (int (*)(...))QTextTable::~QTextTable
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QTextTable
+ size=16 align=8
+ base size=16 base align=8
+QTextTable (0x0x7f21ab2ce3a8) 0
+ vptr=((& QTextTable::_ZTV10QTextTable) + 16u)
+ QTextFrame (0x0x7f21ab2ce410) 0
+ primary-for QTextTable (0x0x7f21ab2ce3a8)
+ QTextObject (0x0x7f21ab2ce478) 0
+ primary-for QTextFrame (0x0x7f21ab2ce410)
+ QObject (0x0x7f21ab301120) 0
+ primary-for QTextObject (0x0x7f21ab2ce478)
+
+Class QValidator::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QValidator::QPrivateSignal (0x0x7f21ab301240) 0 empty
+
+Vtable for QValidator
+QValidator::_ZTV10QValidator: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QValidator)
+16 (int (*)(...))QValidator::metaObject
+24 (int (*)(...))QValidator::qt_metacast
+32 (int (*)(...))QValidator::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))QValidator::fixup
+
+Class QValidator
+ size=16 align=8
+ base size=16 base align=8
+QValidator (0x0x7f21ab2ce4e0) 0
+ vptr=((& QValidator::_ZTV10QValidator) + 16u)
+ QObject (0x0x7f21ab3011e0) 0
+ primary-for QValidator (0x0x7f21ab2ce4e0)
+
+Class QIntValidator::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QIntValidator::QPrivateSignal (0x0x7f21ab301300) 0 empty
+
+Vtable for QIntValidator
+QIntValidator::_ZTV13QIntValidator: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QIntValidator)
+16 (int (*)(...))QIntValidator::metaObject
+24 (int (*)(...))QIntValidator::qt_metacast
+32 (int (*)(...))QIntValidator::qt_metacall
+40 (int (*)(...))QIntValidator::~QIntValidator
+48 (int (*)(...))QIntValidator::~QIntValidator
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QIntValidator::validate
+120 (int (*)(...))QIntValidator::fixup
+128 (int (*)(...))QIntValidator::setRange
+
+Class QIntValidator
+ size=24 align=8
+ base size=24 base align=8
+QIntValidator (0x0x7f21ab2ce548) 0
+ vptr=((& QIntValidator::_ZTV13QIntValidator) + 16u)
+ QValidator (0x0x7f21ab2ce5b0) 0
+ primary-for QIntValidator (0x0x7f21ab2ce548)
+ QObject (0x0x7f21ab3012a0) 0
+ primary-for QValidator (0x0x7f21ab2ce5b0)
+
+Class QDoubleValidator::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDoubleValidator::QPrivateSignal (0x0x7f21ab3013c0) 0 empty
+
+Vtable for QDoubleValidator
+QDoubleValidator::_ZTV16QDoubleValidator: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QDoubleValidator)
+16 (int (*)(...))QDoubleValidator::metaObject
+24 (int (*)(...))QDoubleValidator::qt_metacast
+32 (int (*)(...))QDoubleValidator::qt_metacall
+40 (int (*)(...))QDoubleValidator::~QDoubleValidator
+48 (int (*)(...))QDoubleValidator::~QDoubleValidator
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QDoubleValidator::validate
+120 (int (*)(...))QValidator::fixup
+128 (int (*)(...))QDoubleValidator::setRange
+
+Class QDoubleValidator
+ size=40 align=8
+ base size=36 base align=8
+QDoubleValidator (0x0x7f21ab2ce618) 0
+ vptr=((& QDoubleValidator::_ZTV16QDoubleValidator) + 16u)
+ QValidator (0x0x7f21ab2ce680) 0
+ primary-for QDoubleValidator (0x0x7f21ab2ce618)
+ QObject (0x0x7f21ab301360) 0
+ primary-for QValidator (0x0x7f21ab2ce680)
+
+Class QRegExpValidator::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QRegExpValidator::QPrivateSignal (0x0x7f21ab3014e0) 0 empty
+
+Vtable for QRegExpValidator
+QRegExpValidator::_ZTV16QRegExpValidator: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QRegExpValidator)
+16 (int (*)(...))QRegExpValidator::metaObject
+24 (int (*)(...))QRegExpValidator::qt_metacast
+32 (int (*)(...))QRegExpValidator::qt_metacall
+40 (int (*)(...))QRegExpValidator::~QRegExpValidator
+48 (int (*)(...))QRegExpValidator::~QRegExpValidator
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QRegExpValidator::validate
+120 (int (*)(...))QValidator::fixup
+
+Class QRegExpValidator
+ size=24 align=8
+ base size=24 base align=8
+QRegExpValidator (0x0x7f21ab2ce6e8) 0
+ vptr=((& QRegExpValidator::_ZTV16QRegExpValidator) + 16u)
+ QValidator (0x0x7f21ab2ce750) 0
+ primary-for QRegExpValidator (0x0x7f21ab2ce6e8)
+ QObject (0x0x7f21ab301480) 0
+ primary-for QValidator (0x0x7f21ab2ce750)
+
+Class QRegularExpressionValidator::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QRegularExpressionValidator::QPrivateSignal (0x0x7f21ab3015a0) 0 empty
+
+Vtable for QRegularExpressionValidator
+QRegularExpressionValidator::_ZTV27QRegularExpressionValidator: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QRegularExpressionValidator)
+16 (int (*)(...))QRegularExpressionValidator::metaObject
+24 (int (*)(...))QRegularExpressionValidator::qt_metacast
+32 (int (*)(...))QRegularExpressionValidator::qt_metacall
+40 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator
+48 (int (*)(...))QRegularExpressionValidator::~QRegularExpressionValidator
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QRegularExpressionValidator::validate
+120 (int (*)(...))QValidator::fixup
+
+Class QRegularExpressionValidator
+ size=16 align=8
+ base size=16 base align=8
+QRegularExpressionValidator (0x0x7f21ab2ce7b8) 0
+ vptr=((& QRegularExpressionValidator::_ZTV27QRegularExpressionValidator) + 16u)
+ QValidator (0x0x7f21ab2ce820) 0
+ primary-for QRegularExpressionValidator (0x0x7f21ab2ce7b8)
+ QObject (0x0x7f21ab301540) 0
+ primary-for QValidator (0x0x7f21ab2ce820)
+
+Class QNetworkRequest
+ size=8 align=8
+ base size=8 base align=8
+QNetworkRequest (0x0x7f21ab301600) 0
+
+Class QNetworkCacheMetaData
+ size=8 align=8
+ base size=8 base align=8
+QNetworkCacheMetaData (0x0x7f21ab301b40) 0
+
+Class QAbstractNetworkCache::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractNetworkCache::QPrivateSignal (0x0x7f21aafea240) 0 empty
+
+Vtable for QAbstractNetworkCache
+QAbstractNetworkCache::_ZTV21QAbstractNetworkCache: 22u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QAbstractNetworkCache)
+16 (int (*)(...))QAbstractNetworkCache::metaObject
+24 (int (*)(...))QAbstractNetworkCache::qt_metacast
+32 (int (*)(...))QAbstractNetworkCache::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))__cxa_pure_virtual
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))__cxa_pure_virtual
+
+Class QAbstractNetworkCache
+ size=16 align=8
+ base size=16 base align=8
+QAbstractNetworkCache (0x0x7f21aaff2068) 0
+ vptr=((& QAbstractNetworkCache::_ZTV21QAbstractNetworkCache) + 16u)
+ QObject (0x0x7f21aafea1e0) 0
+ primary-for QAbstractNetworkCache (0x0x7f21aaff2068)
+
+Class QAbstractSocket::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractSocket::QPrivateSignal (0x0x7f21aafea300) 0 empty
+
+Vtable for QAbstractSocket
+QAbstractSocket::_ZTV15QAbstractSocket: 41u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QAbstractSocket)
+16 (int (*)(...))QAbstractSocket::metaObject
+24 (int (*)(...))QAbstractSocket::qt_metacast
+32 (int (*)(...))QAbstractSocket::qt_metacall
+40 (int (*)(...))QAbstractSocket::~QAbstractSocket
+48 (int (*)(...))QAbstractSocket::~QAbstractSocket
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAbstractSocket::isSequential
+120 (int (*)(...))QIODevice::open
+128 (int (*)(...))QAbstractSocket::close
+136 (int (*)(...))QIODevice::pos
+144 (int (*)(...))QIODevice::size
+152 (int (*)(...))QIODevice::seek
+160 (int (*)(...))QAbstractSocket::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QAbstractSocket::bytesAvailable
+184 (int (*)(...))QAbstractSocket::bytesToWrite
+192 (int (*)(...))QAbstractSocket::canReadLine
+200 (int (*)(...))QAbstractSocket::waitForReadyRead
+208 (int (*)(...))QAbstractSocket::waitForBytesWritten
+216 (int (*)(...))QAbstractSocket::readData
+224 (int (*)(...))QAbstractSocket::readLineData
+232 (int (*)(...))QAbstractSocket::writeData
+240 (int (*)(...))QAbstractSocket::resume
+248 (int (*)(...))QAbstractSocket::connectToHost
+256 (int (*)(...))QAbstractSocket::connectToHost
+264 (int (*)(...))QAbstractSocket::disconnectFromHost
+272 (int (*)(...))QAbstractSocket::setReadBufferSize
+280 (int (*)(...))QAbstractSocket::socketDescriptor
+288 (int (*)(...))QAbstractSocket::setSocketDescriptor
+296 (int (*)(...))QAbstractSocket::setSocketOption
+304 (int (*)(...))QAbstractSocket::socketOption
+312 (int (*)(...))QAbstractSocket::waitForConnected
+320 (int (*)(...))QAbstractSocket::waitForDisconnected
+
+Class QAbstractSocket
+ size=16 align=8
+ base size=16 base align=8
+QAbstractSocket (0x0x7f21aaff20d0) 0
+ vptr=((& QAbstractSocket::_ZTV15QAbstractSocket) + 16u)
+ QIODevice (0x0x7f21aaff2138) 0
+ primary-for QAbstractSocket (0x0x7f21aaff20d0)
+ QObject (0x0x7f21aafea2a0) 0
+ primary-for QIODevice (0x0x7f21aaff2138)
+
+Class QAuthenticator
+ size=8 align=8
+ base size=8 base align=8
+QAuthenticator (0x0x7f21aafea8a0) 0
+
+Class QDnsDomainNameRecord
+ size=8 align=8
+ base size=8 base align=8
+QDnsDomainNameRecord (0x0x7f21aafea900) 0
+
+Class QDnsHostAddressRecord
+ size=8 align=8
+ base size=8 base align=8
+QDnsHostAddressRecord (0x0x7f21aafeac00) 0
+
+Class QDnsMailExchangeRecord
+ size=8 align=8
+ base size=8 base align=8
+QDnsMailExchangeRecord (0x0x7f21aafeaf00) 0
+
+Class QDnsServiceRecord
+ size=8 align=8
+ base size=8 base align=8
+QDnsServiceRecord (0x0x7f21ab0f9240) 0
+
+Class QDnsTextRecord
+ size=8 align=8
+ base size=8 base align=8
+QDnsTextRecord (0x0x7f21ab0f9540) 0
+
+Class QDnsLookup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDnsLookup::QPrivateSignal (0x0x7f21ab0f98a0) 0 empty
+
+Vtable for QDnsLookup
+QDnsLookup::_ZTV10QDnsLookup: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QDnsLookup)
+16 (int (*)(...))QDnsLookup::metaObject
+24 (int (*)(...))QDnsLookup::qt_metacast
+32 (int (*)(...))QDnsLookup::qt_metacall
+40 (int (*)(...))QDnsLookup::~QDnsLookup
+48 (int (*)(...))QDnsLookup::~QDnsLookup
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QDnsLookup
+ size=16 align=8
+ base size=16 base align=8
+QDnsLookup (0x0x7f21aaff2b60) 0
+ vptr=((& QDnsLookup::_ZTV10QDnsLookup) + 16u)
+ QObject (0x0x7f21ab0f9840) 0
+ primary-for QDnsLookup (0x0x7f21aaff2b60)
+
+Class QIPv6Address
+ size=16 align=1
+ base size=16 base align=1
+QIPv6Address (0x0x7f21ab0f9900) 0
+
+Class QHostAddress
+ size=8 align=8
+ base size=8 base align=8
+QHostAddress (0x0x7f21ab0f9960) 0
+
+Class QHostInfo
+ size=8 align=8
+ base size=8 base align=8
+QHostInfo (0x0x7f21aadb3180) 0
+
+Class QHstsPolicy
+ size=8 align=8
+ base size=8 base align=8
+QHstsPolicy (0x0x7f21aadb3660) 0
+
+Class QHttpPart
+ size=8 align=8
+ base size=8 base align=8
+QHttpPart (0x0x7f21aadb3e40) 0
+
+Class QHttpMultiPart::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QHttpMultiPart::QPrivateSignal (0x0x7f21aae641e0) 0 empty
+
+Vtable for QHttpMultiPart
+QHttpMultiPart::_ZTV14QHttpMultiPart: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QHttpMultiPart)
+16 (int (*)(...))QHttpMultiPart::metaObject
+24 (int (*)(...))QHttpMultiPart::qt_metacast
+32 (int (*)(...))QHttpMultiPart::qt_metacall
+40 (int (*)(...))QHttpMultiPart::~QHttpMultiPart
+48 (int (*)(...))QHttpMultiPart::~QHttpMultiPart
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QHttpMultiPart
+ size=16 align=8
+ base size=16 base align=8
+QHttpMultiPart (0x0x7f21aadb1dd0) 0
+ vptr=((& QHttpMultiPart::_ZTV14QHttpMultiPart) + 16u)
+ QObject (0x0x7f21aae64180) 0
+ primary-for QHttpMultiPart (0x0x7f21aadb1dd0)
+
+Class QLocalServer::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QLocalServer::QPrivateSignal (0x0x7f21aae642a0) 0 empty
+
+Vtable for QLocalServer
+QLocalServer::_ZTV12QLocalServer: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QLocalServer)
+16 (int (*)(...))QLocalServer::metaObject
+24 (int (*)(...))QLocalServer::qt_metacast
+32 (int (*)(...))QLocalServer::qt_metacall
+40 (int (*)(...))QLocalServer::~QLocalServer
+48 (int (*)(...))QLocalServer::~QLocalServer
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QLocalServer::hasPendingConnections
+120 (int (*)(...))QLocalServer::nextPendingConnection
+128 (int (*)(...))QLocalServer::incomingConnection
+
+Class QLocalServer
+ size=16 align=8
+ base size=16 base align=8
+QLocalServer (0x0x7f21aadb1e38) 0
+ vptr=((& QLocalServer::_ZTV12QLocalServer) + 16u)
+ QObject (0x0x7f21aae64240) 0
+ primary-for QLocalServer (0x0x7f21aadb1e38)
+
+Class QLocalSocket::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QLocalSocket::QPrivateSignal (0x0x7f21aae644e0) 0 empty
+
+Vtable for QLocalSocket
+QLocalSocket::_ZTV12QLocalSocket: 30u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QLocalSocket)
+16 (int (*)(...))QLocalSocket::metaObject
+24 (int (*)(...))QLocalSocket::qt_metacast
+32 (int (*)(...))QLocalSocket::qt_metacall
+40 (int (*)(...))QLocalSocket::~QLocalSocket
+48 (int (*)(...))QLocalSocket::~QLocalSocket
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QLocalSocket::isSequential
+120 (int (*)(...))QLocalSocket::open
+128 (int (*)(...))QLocalSocket::close
+136 (int (*)(...))QIODevice::pos
+144 (int (*)(...))QIODevice::size
+152 (int (*)(...))QIODevice::seek
+160 (int (*)(...))QIODevice::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QLocalSocket::bytesAvailable
+184 (int (*)(...))QLocalSocket::bytesToWrite
+192 (int (*)(...))QLocalSocket::canReadLine
+200 (int (*)(...))QLocalSocket::waitForReadyRead
+208 (int (*)(...))QLocalSocket::waitForBytesWritten
+216 (int (*)(...))QLocalSocket::readData
+224 (int (*)(...))QIODevice::readLineData
+232 (int (*)(...))QLocalSocket::writeData
+
+Class QLocalSocket
+ size=16 align=8
+ base size=16 base align=8
+QLocalSocket (0x0x7f21aaebe000) 0
+ vptr=((& QLocalSocket::_ZTV12QLocalSocket) + 16u)
+ QIODevice (0x0x7f21aaebe068) 0
+ primary-for QLocalSocket (0x0x7f21aaebe000)
+ QObject (0x0x7f21aae64480) 0
+ primary-for QIODevice (0x0x7f21aaebe068)
+
+Class QTcpSocket::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTcpSocket::QPrivateSignal (0x0x7f21aae645a0) 0 empty
+
+Vtable for QTcpSocket
+QTcpSocket::_ZTV10QTcpSocket: 41u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTcpSocket)
+16 (int (*)(...))QTcpSocket::metaObject
+24 (int (*)(...))QTcpSocket::qt_metacast
+32 (int (*)(...))QTcpSocket::qt_metacall
+40 (int (*)(...))QTcpSocket::~QTcpSocket
+48 (int (*)(...))QTcpSocket::~QTcpSocket
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAbstractSocket::isSequential
+120 (int (*)(...))QIODevice::open
+128 (int (*)(...))QAbstractSocket::close
+136 (int (*)(...))QIODevice::pos
+144 (int (*)(...))QIODevice::size
+152 (int (*)(...))QIODevice::seek
+160 (int (*)(...))QAbstractSocket::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QAbstractSocket::bytesAvailable
+184 (int (*)(...))QAbstractSocket::bytesToWrite
+192 (int (*)(...))QAbstractSocket::canReadLine
+200 (int (*)(...))QAbstractSocket::waitForReadyRead
+208 (int (*)(...))QAbstractSocket::waitForBytesWritten
+216 (int (*)(...))QAbstractSocket::readData
+224 (int (*)(...))QAbstractSocket::readLineData
+232 (int (*)(...))QAbstractSocket::writeData
+240 (int (*)(...))QAbstractSocket::resume
+248 (int (*)(...))QAbstractSocket::connectToHost
+256 (int (*)(...))QAbstractSocket::connectToHost
+264 (int (*)(...))QAbstractSocket::disconnectFromHost
+272 (int (*)(...))QAbstractSocket::setReadBufferSize
+280 (int (*)(...))QAbstractSocket::socketDescriptor
+288 (int (*)(...))QAbstractSocket::setSocketDescriptor
+296 (int (*)(...))QAbstractSocket::setSocketOption
+304 (int (*)(...))QAbstractSocket::socketOption
+312 (int (*)(...))QAbstractSocket::waitForConnected
+320 (int (*)(...))QAbstractSocket::waitForDisconnected
+
+Class QTcpSocket
+ size=16 align=8
+ base size=16 base align=8
+QTcpSocket (0x0x7f21aaebe0d0) 0
+ vptr=((& QTcpSocket::_ZTV10QTcpSocket) + 16u)
+ QAbstractSocket (0x0x7f21aaebe138) 0
+ primary-for QTcpSocket (0x0x7f21aaebe0d0)
+ QIODevice (0x0x7f21aaebe1a0) 0
+ primary-for QAbstractSocket (0x0x7f21aaebe138)
+ QObject (0x0x7f21aae64540) 0
+ primary-for QIODevice (0x0x7f21aaebe1a0)
+
+Class QSslCertificate
+ size=8 align=8
+ base size=8 base align=8
+QSslCertificate (0x0x7f21aae64780) 0
+
+Class QSslError
+ size=8 align=8
+ base size=8 base align=8
+QSslError (0x0x7f21aae64ba0) 0
+
+Class QSslSocket::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSslSocket::QPrivateSignal (0x0x7f21aab77540) 0 empty
+
+Vtable for QSslSocket
+QSslSocket::_ZTV10QSslSocket: 41u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QSslSocket)
+16 (int (*)(...))QSslSocket::metaObject
+24 (int (*)(...))QSslSocket::qt_metacast
+32 (int (*)(...))QSslSocket::qt_metacall
+40 (int (*)(...))QSslSocket::~QSslSocket
+48 (int (*)(...))QSslSocket::~QSslSocket
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAbstractSocket::isSequential
+120 (int (*)(...))QIODevice::open
+128 (int (*)(...))QSslSocket::close
+136 (int (*)(...))QIODevice::pos
+144 (int (*)(...))QIODevice::size
+152 (int (*)(...))QIODevice::seek
+160 (int (*)(...))QSslSocket::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QSslSocket::bytesAvailable
+184 (int (*)(...))QSslSocket::bytesToWrite
+192 (int (*)(...))QSslSocket::canReadLine
+200 (int (*)(...))QSslSocket::waitForReadyRead
+208 (int (*)(...))QSslSocket::waitForBytesWritten
+216 (int (*)(...))QSslSocket::readData
+224 (int (*)(...))QAbstractSocket::readLineData
+232 (int (*)(...))QSslSocket::writeData
+240 (int (*)(...))QSslSocket::resume
+248 (int (*)(...))QSslSocket::connectToHost
+256 (int (*)(...))QAbstractSocket::connectToHost
+264 (int (*)(...))QSslSocket::disconnectFromHost
+272 (int (*)(...))QSslSocket::setReadBufferSize
+280 (int (*)(...))QAbstractSocket::socketDescriptor
+288 (int (*)(...))QSslSocket::setSocketDescriptor
+296 (int (*)(...))QSslSocket::setSocketOption
+304 (int (*)(...))QSslSocket::socketOption
+312 (int (*)(...))QSslSocket::waitForConnected
+320 (int (*)(...))QSslSocket::waitForDisconnected
+
+Class QSslSocket
+ size=16 align=8
+ base size=16 base align=8
+QSslSocket (0x0x7f21aaebeb60) 0
+ vptr=((& QSslSocket::_ZTV10QSslSocket) + 16u)
+ QTcpSocket (0x0x7f21aaebebc8) 0
+ primary-for QSslSocket (0x0x7f21aaebeb60)
+ QAbstractSocket (0x0x7f21aaebec30) 0
+ primary-for QTcpSocket (0x0x7f21aaebebc8)
+ QIODevice (0x0x7f21aaebec98) 0
+ primary-for QAbstractSocket (0x0x7f21aaebec30)
+ QObject (0x0x7f21aab774e0) 0
+ primary-for QIODevice (0x0x7f21aaebec98)
+
+Class QSslConfiguration
+ size=8 align=8
+ base size=8 base align=8
+QSslConfiguration (0x0x7f21aab775a0) 0
+
+Class QSslPreSharedKeyAuthenticator
+ size=8 align=8
+ base size=8 base align=8
+QSslPreSharedKeyAuthenticator (0x0x7f21aab77d20) 0
+
+Class QNetworkAccessManager::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QNetworkAccessManager::QPrivateSignal (0x0x7f21aac30660) 0 empty
+
+Vtable for QNetworkAccessManager
+QNetworkAccessManager::_ZTV21QNetworkAccessManager: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QNetworkAccessManager)
+16 (int (*)(...))QNetworkAccessManager::metaObject
+24 (int (*)(...))QNetworkAccessManager::qt_metacast
+32 (int (*)(...))QNetworkAccessManager::qt_metacall
+40 (int (*)(...))QNetworkAccessManager::~QNetworkAccessManager
+48 (int (*)(...))QNetworkAccessManager::~QNetworkAccessManager
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QNetworkAccessManager::createRequest
+
+Class QNetworkAccessManager
+ size=16 align=8
+ base size=16 base align=8
+QNetworkAccessManager (0x0x7f21aac02958) 0
+ vptr=((& QNetworkAccessManager::_ZTV21QNetworkAccessManager) + 16u)
+ QObject (0x0x7f21aac30600) 0
+ primary-for QNetworkAccessManager (0x0x7f21aac02958)
+
+Class QNetworkConfiguration
+ size=8 align=8
+ base size=8 base align=8
+QNetworkConfiguration (0x0x7f21aac306c0) 0
+
+Class QNetworkConfigurationManager::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QNetworkConfigurationManager::QPrivateSignal (0x0x7f21aac30b40) 0 empty
+
+Vtable for QNetworkConfigurationManager
+QNetworkConfigurationManager::_ZTV28QNetworkConfigurationManager: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI28QNetworkConfigurationManager)
+16 (int (*)(...))QNetworkConfigurationManager::metaObject
+24 (int (*)(...))QNetworkConfigurationManager::qt_metacast
+32 (int (*)(...))QNetworkConfigurationManager::qt_metacall
+40 (int (*)(...))QNetworkConfigurationManager::~QNetworkConfigurationManager
+48 (int (*)(...))QNetworkConfigurationManager::~QNetworkConfigurationManager
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QNetworkConfigurationManager
+ size=16 align=8
+ base size=16 base align=8
+QNetworkConfigurationManager (0x0x7f21aac02b60) 0
+ vptr=((& QNetworkConfigurationManager::_ZTV28QNetworkConfigurationManager) + 16u)
+ QObject (0x0x7f21aac30ae0) 0
+ primary-for QNetworkConfigurationManager (0x0x7f21aac02b60)
+
+Class QNetworkCookie
+ size=8 align=8
+ base size=8 base align=8
+QNetworkCookie (0x0x7f21aac30ea0) 0
+
+Class QNetworkCookieJar::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QNetworkCookieJar::QPrivateSignal (0x0x7f21aad0b6c0) 0 empty
+
+Vtable for QNetworkCookieJar
+QNetworkCookieJar::_ZTV17QNetworkCookieJar: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QNetworkCookieJar)
+16 (int (*)(...))QNetworkCookieJar::metaObject
+24 (int (*)(...))QNetworkCookieJar::qt_metacast
+32 (int (*)(...))QNetworkCookieJar::qt_metacall
+40 (int (*)(...))QNetworkCookieJar::~QNetworkCookieJar
+48 (int (*)(...))QNetworkCookieJar::~QNetworkCookieJar
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QNetworkCookieJar::cookiesForUrl
+120 (int (*)(...))QNetworkCookieJar::setCookiesFromUrl
+128 (int (*)(...))QNetworkCookieJar::insertCookie
+136 (int (*)(...))QNetworkCookieJar::updateCookie
+144 (int (*)(...))QNetworkCookieJar::deleteCookie
+152 (int (*)(...))QNetworkCookieJar::validateCookie
+
+Class QNetworkCookieJar
+ size=16 align=8
+ base size=16 base align=8
+QNetworkCookieJar (0x0x7f21aad103a8) 0
+ vptr=((& QNetworkCookieJar::_ZTV17QNetworkCookieJar) + 16u)
+ QObject (0x0x7f21aad0b660) 0
+ primary-for QNetworkCookieJar (0x0x7f21aad103a8)
+
+Class QNetworkDatagram
+ size=8 align=8
+ base size=8 base align=8
+QNetworkDatagram (0x0x7f21aad0b720) 0
+
+Class QNetworkDiskCache::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QNetworkDiskCache::QPrivateSignal (0x0x7f21aa9b4720) 0 empty
+
+Vtable for QNetworkDiskCache
+QNetworkDiskCache::_ZTV17QNetworkDiskCache: 23u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QNetworkDiskCache)
+16 (int (*)(...))QNetworkDiskCache::metaObject
+24 (int (*)(...))QNetworkDiskCache::qt_metacast
+32 (int (*)(...))QNetworkDiskCache::qt_metacall
+40 (int (*)(...))QNetworkDiskCache::~QNetworkDiskCache
+48 (int (*)(...))QNetworkDiskCache::~QNetworkDiskCache
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QNetworkDiskCache::metaData
+120 (int (*)(...))QNetworkDiskCache::updateMetaData
+128 (int (*)(...))QNetworkDiskCache::data
+136 (int (*)(...))QNetworkDiskCache::remove
+144 (int (*)(...))QNetworkDiskCache::cacheSize
+152 (int (*)(...))QNetworkDiskCache::prepare
+160 (int (*)(...))QNetworkDiskCache::insert
+168 (int (*)(...))QNetworkDiskCache::clear
+176 (int (*)(...))QNetworkDiskCache::expire
+
+Class QNetworkDiskCache
+ size=16 align=8
+ base size=16 base align=8
+QNetworkDiskCache (0x0x7f21aa9b0dd0) 0
+ vptr=((& QNetworkDiskCache::_ZTV17QNetworkDiskCache) + 16u)
+ QAbstractNetworkCache (0x0x7f21aa9b0e38) 0
+ primary-for QNetworkDiskCache (0x0x7f21aa9b0dd0)
+ QObject (0x0x7f21aa9b46c0) 0
+ primary-for QAbstractNetworkCache (0x0x7f21aa9b0e38)
+
+Class QNetworkAddressEntry
+ size=8 align=8
+ base size=8 base align=8
+QNetworkAddressEntry (0x0x7f21aa9b4780) 0
+
+Class QNetworkInterface
+ size=8 align=8
+ base size=8 base align=8
+QNetworkInterface (0x0x7f21aa9b4e40) 0
+
+Class QNetworkProxyQuery
+ size=8 align=8
+ base size=8 base align=8
+QNetworkProxyQuery (0x0x7f21aaa245a0) 0
+
+Class QNetworkProxy
+ size=8 align=8
+ base size=8 base align=8
+QNetworkProxy (0x0x7f21aaa24c00) 0
+
+Vtable for QNetworkProxyFactory
+QNetworkProxyFactory::_ZTV20QNetworkProxyFactory: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QNetworkProxyFactory)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class QNetworkProxyFactory
+ size=8 align=8
+ base size=8 base align=8
+QNetworkProxyFactory (0x0x7f21aaac3420) 0 nearly-empty
+ vptr=((& QNetworkProxyFactory::_ZTV20QNetworkProxyFactory) + 16u)
+
+Class QNetworkReply::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QNetworkReply::QPrivateSignal (0x0x7f21aaac3600) 0 empty
+
+Vtable for QNetworkReply
+QNetworkReply::_ZTV13QNetworkReply: 36u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QNetworkReply)
+16 (int (*)(...))QNetworkReply::metaObject
+24 (int (*)(...))QNetworkReply::qt_metacast
+32 (int (*)(...))QNetworkReply::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QNetworkReply::isSequential
+120 (int (*)(...))QIODevice::open
+128 (int (*)(...))QNetworkReply::close
+136 (int (*)(...))QIODevice::pos
+144 (int (*)(...))QIODevice::size
+152 (int (*)(...))QIODevice::seek
+160 (int (*)(...))QIODevice::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QIODevice::bytesAvailable
+184 (int (*)(...))QIODevice::bytesToWrite
+192 (int (*)(...))QIODevice::canReadLine
+200 (int (*)(...))QIODevice::waitForReadyRead
+208 (int (*)(...))QIODevice::waitForBytesWritten
+216 (int (*)(...))__cxa_pure_virtual
+224 (int (*)(...))QIODevice::readLineData
+232 (int (*)(...))QNetworkReply::writeData
+240 (int (*)(...))QNetworkReply::setReadBufferSize
+248 (int (*)(...))__cxa_pure_virtual
+256 (int (*)(...))QNetworkReply::ignoreSslErrors
+264 (int (*)(...))QNetworkReply::sslConfigurationImplementation
+272 (int (*)(...))QNetworkReply::setSslConfigurationImplementation
+280 (int (*)(...))QNetworkReply::ignoreSslErrorsImplementation
+
+Class QNetworkReply
+ size=16 align=8
+ base size=16 base align=8
+QNetworkReply (0x0x7f21aaac04e0) 0
+ vptr=((& QNetworkReply::_ZTV13QNetworkReply) + 16u)
+ QIODevice (0x0x7f21aaac0548) 0
+ primary-for QNetworkReply (0x0x7f21aaac04e0)
+ QObject (0x0x7f21aaac35a0) 0
+ primary-for QIODevice (0x0x7f21aaac0548)
+
+Class QNetworkSession::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QNetworkSession::QPrivateSignal (0x0x7f21aaac37e0) 0 empty
+
+Vtable for QNetworkSession
+QNetworkSession::_ZTV15QNetworkSession: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QNetworkSession)
+16 (int (*)(...))QNetworkSession::metaObject
+24 (int (*)(...))QNetworkSession::qt_metacast
+32 (int (*)(...))QNetworkSession::qt_metacall
+40 (int (*)(...))QNetworkSession::~QNetworkSession
+48 (int (*)(...))QNetworkSession::~QNetworkSession
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QNetworkSession::connectNotify
+104 (int (*)(...))QNetworkSession::disconnectNotify
+
+Class QNetworkSession
+ size=24 align=8
+ base size=24 base align=8
+QNetworkSession (0x0x7f21aaac05b0) 0
+ vptr=((& QNetworkSession::_ZTV15QNetworkSession) + 16u)
+ QObject (0x0x7f21aaac3780) 0
+ primary-for QNetworkSession (0x0x7f21aaac05b0)
+
+Class QTcpServer::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTcpServer::QPrivateSignal (0x0x7f21aaac3d80) 0 empty
+
+Vtable for QTcpServer
+QTcpServer::_ZTV10QTcpServer: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTcpServer)
+16 (int (*)(...))QTcpServer::metaObject
+24 (int (*)(...))QTcpServer::qt_metacast
+32 (int (*)(...))QTcpServer::qt_metacall
+40 (int (*)(...))QTcpServer::~QTcpServer
+48 (int (*)(...))QTcpServer::~QTcpServer
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QTcpServer::hasPendingConnections
+120 (int (*)(...))QTcpServer::nextPendingConnection
+128 (int (*)(...))QTcpServer::incomingConnection
+
+Class QTcpServer
+ size=16 align=8
+ base size=16 base align=8
+QTcpServer (0x0x7f21aaac06e8) 0
+ vptr=((& QTcpServer::_ZTV10QTcpServer) + 16u)
+ QObject (0x0x7f21aaac3d20) 0
+ primary-for QTcpServer (0x0x7f21aaac06e8)
+
+Class QSslCertificateExtension
+ size=8 align=8
+ base size=8 base align=8
+QSslCertificateExtension (0x0x7f21aaac3de0) 0
+
+Class QSslCipher
+ size=8 align=8
+ base size=8 base align=8
+QSslCipher (0x0x7f21aa79f120) 0
+
+Class QSslDiffieHellmanParameters
+ size=8 align=8
+ base size=8 base align=8
+QSslDiffieHellmanParameters (0x0x7f21aa79f900) 0
+
+Class QSslEllipticCurve
+ size=4 align=4
+ base size=4 base align=4
+QSslEllipticCurve (0x0x7f21aa855420) 0
+
+Class QSslKey
+ size=8 align=8
+ base size=8 base align=8
+QSslKey (0x0x7f21aa855b40) 0
+
+Class QUdpSocket::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QUdpSocket::QPrivateSignal (0x0x7f21aa855ea0) 0 empty
+
+Vtable for QUdpSocket
+QUdpSocket::_ZTV10QUdpSocket: 41u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QUdpSocket)
+16 (int (*)(...))QUdpSocket::metaObject
+24 (int (*)(...))QUdpSocket::qt_metacast
+32 (int (*)(...))QUdpSocket::qt_metacall
+40 (int (*)(...))QUdpSocket::~QUdpSocket
+48 (int (*)(...))QUdpSocket::~QUdpSocket
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QAbstractSocket::isSequential
+120 (int (*)(...))QIODevice::open
+128 (int (*)(...))QAbstractSocket::close
+136 (int (*)(...))QIODevice::pos
+144 (int (*)(...))QIODevice::size
+152 (int (*)(...))QIODevice::seek
+160 (int (*)(...))QAbstractSocket::atEnd
+168 (int (*)(...))QIODevice::reset
+176 (int (*)(...))QAbstractSocket::bytesAvailable
+184 (int (*)(...))QAbstractSocket::bytesToWrite
+192 (int (*)(...))QAbstractSocket::canReadLine
+200 (int (*)(...))QAbstractSocket::waitForReadyRead
+208 (int (*)(...))QAbstractSocket::waitForBytesWritten
+216 (int (*)(...))QAbstractSocket::readData
+224 (int (*)(...))QAbstractSocket::readLineData
+232 (int (*)(...))QAbstractSocket::writeData
+240 (int (*)(...))QAbstractSocket::resume
+248 (int (*)(...))QAbstractSocket::connectToHost
+256 (int (*)(...))QAbstractSocket::connectToHost
+264 (int (*)(...))QAbstractSocket::disconnectFromHost
+272 (int (*)(...))QAbstractSocket::setReadBufferSize
+280 (int (*)(...))QAbstractSocket::socketDescriptor
+288 (int (*)(...))QAbstractSocket::setSocketDescriptor
+296 (int (*)(...))QAbstractSocket::setSocketOption
+304 (int (*)(...))QAbstractSocket::socketOption
+312 (int (*)(...))QAbstractSocket::waitForConnected
+320 (int (*)(...))QAbstractSocket::waitForDisconnected
+
+Class QUdpSocket
+ size=16 align=8
+ base size=16 base align=8
+QUdpSocket (0x0x7f21aa859c98) 0
+ vptr=((& QUdpSocket::_ZTV10QUdpSocket) + 16u)
+ QAbstractSocket (0x0x7f21aa859d00) 0
+ primary-for QUdpSocket (0x0x7f21aa859c98)
+ QIODevice (0x0x7f21aa859d68) 0
+ primary-for QAbstractSocket (0x0x7f21aa859d00)
+ QObject (0x0x7f21aa855e40) 0
+ primary-for QIODevice (0x0x7f21aa859d68)
+
+Class QJSValue
+ size=8 align=8
+ base size=8 base align=8
+QJSValue (0x0x7f21aa855f00) 0
+
+Class QJSEngine::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QJSEngine::QPrivateSignal (0x0x7f21aa8d1240) 0 empty
+
+Vtable for QJSEngine
+QJSEngine::_ZTV9QJSEngine: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QJSEngine)
+16 (int (*)(...))QJSEngine::metaObject
+24 (int (*)(...))QJSEngine::qt_metacast
+32 (int (*)(...))QJSEngine::qt_metacall
+40 (int (*)(...))QJSEngine::~QJSEngine
+48 (int (*)(...))QJSEngine::~QJSEngine
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QJSEngine
+ size=24 align=8
+ base size=24 base align=8
+QJSEngine (0x0x7f21aa859ea0) 0
+ vptr=((& QJSEngine::_ZTV9QJSEngine) + 16u)
+ QObject (0x0x7f21aa8d11e0) 0
+ primary-for QJSEngine (0x0x7f21aa859ea0)
+
+Class QJSValueIterator
+ size=8 align=8
+ base size=8 base align=8
+QJSValueIterator (0x0x7f21aa8d1420) 0
+
+Class QQmlPrivate::RegisterType
+ size=128 align=8
+ base size=124 base align=8
+QQmlPrivate::RegisterType (0x0x7f21aa8d1900) 0
+
+Class QQmlPrivate::RegisterInterface
+ size=24 align=8
+ base size=24 base align=8
+QQmlPrivate::RegisterInterface (0x0x7f21aa8d1960) 0
+
+Class QQmlPrivate::RegisterAutoParent
+ size=16 align=8
+ base size=16 base align=8
+QQmlPrivate::RegisterAutoParent (0x0x7f21aa8d19c0) 0
+
+Class QQmlPrivate::RegisterSingletonType
+ size=64 align=8
+ base size=64 base align=8
+QQmlPrivate::RegisterSingletonType (0x0x7f21aa8d1a20) 0
+
+Class QQmlPrivate::RegisterCompositeType
+ size=32 align=8
+ base size=32 base align=8
+QQmlPrivate::RegisterCompositeType (0x0x7f21aa8d1a80) 0
+
+Class QQmlPrivate::RegisterCompositeSingletonType
+ size=32 align=8
+ base size=32 base align=8
+QQmlPrivate::RegisterCompositeSingletonType (0x0x7f21aa8d1ae0) 0
+
+Class QQmlPrivate::CachedQmlUnit
+ size=24 align=8
+ base size=24 base align=8
+QQmlPrivate::CachedQmlUnit (0x0x7f21aa8d1b40) 0
+
+Class QQmlPrivate::RegisterQmlUnitCacheHook
+ size=16 align=8
+ base size=16 base align=8
+QQmlPrivate::RegisterQmlUnitCacheHook (0x0x7f21aa8d1ba0) 0
+
+Vtable for QQmlParserStatus
+QQmlParserStatus::_ZTV16QQmlParserStatus: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QQmlParserStatus)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+
+Class QQmlParserStatus
+ size=16 align=8
+ base size=16 base align=8
+QQmlParserStatus (0x0x7f21aa8d1c00) 0
+ vptr=((& QQmlParserStatus::_ZTV16QQmlParserStatus) + 16u)
+
+Vtable for QQmlPropertyValueSource
+QQmlPropertyValueSource::_ZTV23QQmlPropertyValueSource: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QQmlPropertyValueSource)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class QQmlPropertyValueSource
+ size=8 align=8
+ base size=8 base align=8
+QQmlPropertyValueSource (0x0x7f21aa8d1cc0) 0 nearly-empty
+ vptr=((& QQmlPropertyValueSource::_ZTV23QQmlPropertyValueSource) + 16u)
+
+Class QQmlListReference
+ size=8 align=8
+ base size=8 base align=8
+QQmlListReference (0x0x7f21aa8d1de0) 0
+
+Vtable for QQmlAbstractUrlInterceptor
+QQmlAbstractUrlInterceptor::_ZTV26QQmlAbstractUrlInterceptor: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QQmlAbstractUrlInterceptor)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class QQmlAbstractUrlInterceptor
+ size=8 align=8
+ base size=8 base align=8
+QQmlAbstractUrlInterceptor (0x0x7f21aa5cd480) 0 nearly-empty
+ vptr=((& QQmlAbstractUrlInterceptor::_ZTV26QQmlAbstractUrlInterceptor) + 16u)
+
+Class QQmlError
+ size=8 align=8
+ base size=8 base align=8
+QQmlError (0x0x7f21aa5cd4e0) 0
+
+Class QQmlDebuggingEnabler
+ size=1 align=1
+ base size=0 base align=1
+QQmlDebuggingEnabler (0x0x7f21aa5cd780) 0 empty
+
+Vtable for QQmlImageProviderBase
+QQmlImageProviderBase::_ZTV21QQmlImageProviderBase: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QQmlImageProviderBase)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+
+Class QQmlImageProviderBase
+ size=8 align=8
+ base size=8 base align=8
+QQmlImageProviderBase (0x0x7f21aa5cd7e0) 0 nearly-empty
+ vptr=((& QQmlImageProviderBase::_ZTV21QQmlImageProviderBase) + 16u)
+
+Class QQmlEngine::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQmlEngine::QPrivateSignal (0x0x7f21aa5cda20) 0 empty
+
+Vtable for QQmlEngine
+QQmlEngine::_ZTV10QQmlEngine: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QQmlEngine)
+16 (int (*)(...))QQmlEngine::metaObject
+24 (int (*)(...))QQmlEngine::qt_metacast
+32 (int (*)(...))QQmlEngine::qt_metacall
+40 (int (*)(...))QQmlEngine::~QQmlEngine
+48 (int (*)(...))QQmlEngine::~QQmlEngine
+56 (int (*)(...))QQmlEngine::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QQmlEngine
+ size=24 align=8
+ base size=24 base align=8
+QQmlEngine (0x0x7f21aa5254e0) 0
+ vptr=((& QQmlEngine::_ZTV10QQmlEngine) + 16u)
+ QJSEngine (0x0x7f21aa525548) 0
+ primary-for QQmlEngine (0x0x7f21aa5254e0)
+ QObject (0x0x7f21aa5cd9c0) 0
+ primary-for QJSEngine (0x0x7f21aa525548)
+
+Class QQmlApplicationEngine::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQmlApplicationEngine::QPrivateSignal (0x0x7f21aa5cdae0) 0 empty
+
+Vtable for QQmlApplicationEngine
+QQmlApplicationEngine::_ZTV21QQmlApplicationEngine: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QQmlApplicationEngine)
+16 (int (*)(...))QQmlApplicationEngine::metaObject
+24 (int (*)(...))QQmlApplicationEngine::qt_metacast
+32 (int (*)(...))QQmlApplicationEngine::qt_metacall
+40 (int (*)(...))QQmlApplicationEngine::~QQmlApplicationEngine
+48 (int (*)(...))QQmlApplicationEngine::~QQmlApplicationEngine
+56 (int (*)(...))QQmlEngine::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QQmlApplicationEngine
+ size=24 align=8
+ base size=24 base align=8
+QQmlApplicationEngine (0x0x7f21aa5255b0) 0
+ vptr=((& QQmlApplicationEngine::_ZTV21QQmlApplicationEngine) + 16u)
+ QQmlEngine (0x0x7f21aa525618) 0
+ primary-for QQmlApplicationEngine (0x0x7f21aa5255b0)
+ QJSEngine (0x0x7f21aa525680) 0
+ primary-for QQmlEngine (0x0x7f21aa525618)
+ QObject (0x0x7f21aa5cda80) 0
+ primary-for QJSEngine (0x0x7f21aa525680)
+
+Class QQmlComponent::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQmlComponent::QPrivateSignal (0x0x7f21aa5cdba0) 0 empty
+
+Vtable for QQmlComponent
+QQmlComponent::_ZTV13QQmlComponent: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QQmlComponent)
+16 (int (*)(...))QQmlComponent::metaObject
+24 (int (*)(...))QQmlComponent::qt_metacast
+32 (int (*)(...))QQmlComponent::qt_metacall
+40 (int (*)(...))QQmlComponent::~QQmlComponent
+48 (int (*)(...))QQmlComponent::~QQmlComponent
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QQmlComponent::create
+120 (int (*)(...))QQmlComponent::beginCreate
+128 (int (*)(...))QQmlComponent::completeCreate
+
+Class QQmlComponent
+ size=16 align=8
+ base size=16 base align=8
+QQmlComponent (0x0x7f21aa5256e8) 0
+ vptr=((& QQmlComponent::_ZTV13QQmlComponent) + 16u)
+ QObject (0x0x7f21aa5cdb40) 0
+ primary-for QQmlComponent (0x0x7f21aa5256e8)
+
+Class QQmlContext::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQmlContext::QPrivateSignal (0x0x7f21aa328420) 0 empty
+
+Vtable for QQmlContext
+QQmlContext::_ZTV11QQmlContext: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QQmlContext)
+16 (int (*)(...))QQmlContext::metaObject
+24 (int (*)(...))QQmlContext::qt_metacast
+32 (int (*)(...))QQmlContext::qt_metacall
+40 (int (*)(...))QQmlContext::~QQmlContext
+48 (int (*)(...))QQmlContext::~QQmlContext
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QQmlContext
+ size=16 align=8
+ base size=16 base align=8
+QQmlContext (0x0x7f21aa525c30) 0
+ vptr=((& QQmlContext::_ZTV11QQmlContext) + 16u)
+ QObject (0x0x7f21aa3283c0) 0
+ primary-for QQmlContext (0x0x7f21aa525c30)
+
+Class QQmlScriptString
+ size=8 align=8
+ base size=8 base align=8
+QQmlScriptString (0x0x7f21aa3285a0) 0
+
+Class QQmlExpression::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQmlExpression::QPrivateSignal (0x0x7f21aa3287e0) 0 empty
+
+Vtable for QQmlExpression
+QQmlExpression::_ZTV14QQmlExpression: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QQmlExpression)
+16 (int (*)(...))QQmlExpression::metaObject
+24 (int (*)(...))QQmlExpression::qt_metacast
+32 (int (*)(...))QQmlExpression::qt_metacall
+40 (int (*)(...))QQmlExpression::~QQmlExpression
+48 (int (*)(...))QQmlExpression::~QQmlExpression
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QQmlExpression
+ size=16 align=8
+ base size=16 base align=8
+QQmlExpression (0x0x7f21aa525c98) 0
+ vptr=((& QQmlExpression::_ZTV14QQmlExpression) + 16u)
+ QObject (0x0x7f21aa328780) 0
+ primary-for QQmlExpression (0x0x7f21aa525c98)
+
+Vtable for QQmlTypesExtensionInterface
+QQmlTypesExtensionInterface::_ZTV27QQmlTypesExtensionInterface: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QQmlTypesExtensionInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class QQmlTypesExtensionInterface
+ size=8 align=8
+ base size=8 base align=8
+QQmlTypesExtensionInterface (0x0x7f21aa328840) 0 nearly-empty
+ vptr=((& QQmlTypesExtensionInterface::_ZTV27QQmlTypesExtensionInterface) + 16u)
+
+Vtable for QQmlExtensionInterface
+QQmlExtensionInterface::_ZTV22QQmlExtensionInterface: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI22QQmlExtensionInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+
+Class QQmlExtensionInterface
+ size=8 align=8
+ base size=8 base align=8
+QQmlExtensionInterface (0x0x7f21aa525d00) 0 nearly-empty
+ vptr=((& QQmlExtensionInterface::_ZTV22QQmlExtensionInterface) + 16u)
+ QQmlTypesExtensionInterface (0x0x7f21aa3288a0) 0 nearly-empty
+ primary-for QQmlExtensionInterface (0x0x7f21aa525d00)
+
+Class QQmlExtensionPlugin::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQmlExtensionPlugin::QPrivateSignal (0x0x7f21aa328a80) 0 empty
+
+Vtable for QQmlExtensionPlugin
+QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin: 22u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QQmlExtensionPlugin)
+16 (int (*)(...))QQmlExtensionPlugin::metaObject
+24 (int (*)(...))QQmlExtensionPlugin::qt_metacast
+32 (int (*)(...))QQmlExtensionPlugin::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))QQmlExtensionPlugin::initializeEngine
+128 (int (*)(...))-16
+136 (int (*)(...))(& _ZTI19QQmlExtensionPlugin)
+144 0u
+152 0u
+160 (int (*)(...))__cxa_pure_virtual
+168 (int (*)(...))QQmlExtensionPlugin::_ZThn16_N19QQmlExtensionPlugin16initializeEngineEP10QQmlEnginePKc
+
+Class QQmlExtensionPlugin
+ size=24 align=8
+ base size=24 base align=8
+QQmlExtensionPlugin (0x0x7f21aa3858c0) 0
+ vptr=((& QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin) + 16u)
+ QObject (0x0x7f21aa3289c0) 0
+ primary-for QQmlExtensionPlugin (0x0x7f21aa3858c0)
+ QQmlExtensionInterface (0x0x7f21aa525d68) 16 nearly-empty
+ vptr=((& QQmlExtensionPlugin::_ZTV19QQmlExtensionPlugin) + 144u)
+ QQmlTypesExtensionInterface (0x0x7f21aa328a20) 16 nearly-empty
+ primary-for QQmlExtensionInterface (0x0x7f21aa525d68)
+
+Class QQmlFile
+ size=8 align=8
+ base size=8 base align=8
+QQmlFile (0x0x7f21aa328ae0) 0
+
+Class QQmlFileSelector::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQmlFileSelector::QPrivateSignal (0x0x7f21aa328ba0) 0 empty
+
+Vtable for QQmlFileSelector
+QQmlFileSelector::_ZTV16QQmlFileSelector: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QQmlFileSelector)
+16 (int (*)(...))QQmlFileSelector::metaObject
+24 (int (*)(...))QQmlFileSelector::qt_metacast
+32 (int (*)(...))QQmlFileSelector::qt_metacall
+40 (int (*)(...))QQmlFileSelector::~QQmlFileSelector
+48 (int (*)(...))QQmlFileSelector::~QQmlFileSelector
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QQmlFileSelector
+ size=16 align=8
+ base size=16 base align=8
+QQmlFileSelector (0x0x7f21aa525e38) 0
+ vptr=((& QQmlFileSelector::_ZTV16QQmlFileSelector) + 16u)
+ QObject (0x0x7f21aa328b40) 0
+ primary-for QQmlFileSelector (0x0x7f21aa525e38)
+
+Vtable for QQmlIncubator
+QQmlIncubator::_ZTV13QQmlIncubator: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QQmlIncubator)
+16 (int (*)(...))QQmlIncubator::~QQmlIncubator
+24 (int (*)(...))QQmlIncubator::~QQmlIncubator
+32 (int (*)(...))QQmlIncubator::statusChanged
+40 (int (*)(...))QQmlIncubator::setInitialState
+
+Class QQmlIncubator
+ size=16 align=8
+ base size=16 base align=8
+QQmlIncubator (0x0x7f21aa328c00) 0
+ vptr=((& QQmlIncubator::_ZTV13QQmlIncubator) + 16u)
+
+Vtable for QQmlIncubationController
+QQmlIncubationController::_ZTV24QQmlIncubationController: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QQmlIncubationController)
+16 (int (*)(...))QQmlIncubationController::~QQmlIncubationController
+24 (int (*)(...))QQmlIncubationController::~QQmlIncubationController
+32 (int (*)(...))QQmlIncubationController::incubatingObjectCountChanged
+
+Class QQmlIncubationController
+ size=16 align=8
+ base size=16 base align=8
+QQmlIncubationController (0x0x7f21aa328c60) 0
+ vptr=((& QQmlIncubationController::_ZTV24QQmlIncubationController) + 16u)
+
+Class QQmlInfo
+ size=16 align=8
+ base size=16 base align=8
+QQmlInfo (0x0x7f21aa525ea0) 0
+ QDebug (0x0x7f21aa328cc0) 0
+
+Vtable for QQmlNetworkAccessManagerFactory
+QQmlNetworkAccessManagerFactory::_ZTV31QQmlNetworkAccessManagerFactory: 5u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI31QQmlNetworkAccessManagerFactory)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+
+Class QQmlNetworkAccessManagerFactory
+ size=8 align=8
+ base size=8 base align=8
+QQmlNetworkAccessManagerFactory (0x0x7f21aa435ba0) 0 nearly-empty
+ vptr=((& QQmlNetworkAccessManagerFactory::_ZTV31QQmlNetworkAccessManagerFactory) + 16u)
+
+Class QQmlProperty
+ size=8 align=8
+ base size=8 base align=8
+QQmlProperty (0x0x7f21aa435c00) 0
+
+Class QQmlPropertyMap::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQmlPropertyMap::QPrivateSignal (0x0x7f21aa46f780) 0 empty
+
+Vtable for QQmlPropertyMap
+QQmlPropertyMap::_ZTV15QQmlPropertyMap: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QQmlPropertyMap)
+16 (int (*)(...))QQmlPropertyMap::metaObject
+24 (int (*)(...))QQmlPropertyMap::qt_metacast
+32 (int (*)(...))QQmlPropertyMap::qt_metacall
+40 (int (*)(...))QQmlPropertyMap::~QQmlPropertyMap
+48 (int (*)(...))QQmlPropertyMap::~QQmlPropertyMap
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QQmlPropertyMap::updateValue
+
+Class QQmlPropertyMap
+ size=16 align=8
+ base size=16 base align=8
+QQmlPropertyMap (0x0x7f21aa4736e8) 0
+ vptr=((& QQmlPropertyMap::_ZTV15QQmlPropertyMap) + 16u)
+ QObject (0x0x7f21aa46f720) 0
+ primary-for QQmlPropertyMap (0x0x7f21aa4736e8)
+
+Class QQuickTransform::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQuickTransform::QPrivateSignal (0x0x7f21aa46f840) 0 empty
+
+Vtable for QQuickTransform
+QQuickTransform::_ZTV15QQuickTransform: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QQuickTransform)
+16 (int (*)(...))QQuickTransform::metaObject
+24 (int (*)(...))QQuickTransform::qt_metacast
+32 (int (*)(...))QQuickTransform::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+
+Class QQuickTransform
+ size=16 align=8
+ base size=16 base align=8
+QQuickTransform (0x0x7f21aa473750) 0
+ vptr=((& QQuickTransform::_ZTV15QQuickTransform) + 16u)
+ QObject (0x0x7f21aa46f7e0) 0
+ primary-for QQuickTransform (0x0x7f21aa473750)
+
+Class QQuickItem::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQuickItem::QPrivateSignal (0x0x7f21aa46f960) 0 empty
+
+Class QQuickItem::ItemChangeData
+ size=8 align=8
+ base size=8 base align=8
+QQuickItem::ItemChangeData (0x0x7f21aa46f9c0) 0
+
+Class QQuickItem::UpdatePaintNodeData
+ size=8 align=8
+ base size=8 base align=8
+QQuickItem::UpdatePaintNodeData (0x0x7f21aa46fa20) 0
+
+Vtable for QQuickItem
+QQuickItem::_ZTV10QQuickItem: 55u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QQuickItem)
+16 (int (*)(...))QQuickItem::metaObject
+24 (int (*)(...))QQuickItem::qt_metacast
+32 (int (*)(...))QQuickItem::qt_metacall
+40 (int (*)(...))QQuickItem::~QQuickItem
+48 (int (*)(...))QQuickItem::~QQuickItem
+56 (int (*)(...))QQuickItem::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QQuickItem::boundingRect
+120 (int (*)(...))QQuickItem::clipRect
+128 (int (*)(...))QQuickItem::contains
+136 (int (*)(...))QQuickItem::inputMethodQuery
+144 (int (*)(...))QQuickItem::isTextureProvider
+152 (int (*)(...))QQuickItem::textureProvider
+160 (int (*)(...))QQuickItem::itemChange
+168 (int (*)(...))QQuickItem::classBegin
+176 (int (*)(...))QQuickItem::componentComplete
+184 (int (*)(...))QQuickItem::keyPressEvent
+192 (int (*)(...))QQuickItem::keyReleaseEvent
+200 (int (*)(...))QQuickItem::inputMethodEvent
+208 (int (*)(...))QQuickItem::focusInEvent
+216 (int (*)(...))QQuickItem::focusOutEvent
+224 (int (*)(...))QQuickItem::mousePressEvent
+232 (int (*)(...))QQuickItem::mouseMoveEvent
+240 (int (*)(...))QQuickItem::mouseReleaseEvent
+248 (int (*)(...))QQuickItem::mouseDoubleClickEvent
+256 (int (*)(...))QQuickItem::mouseUngrabEvent
+264 (int (*)(...))QQuickItem::touchUngrabEvent
+272 (int (*)(...))QQuickItem::wheelEvent
+280 (int (*)(...))QQuickItem::touchEvent
+288 (int (*)(...))QQuickItem::hoverEnterEvent
+296 (int (*)(...))QQuickItem::hoverMoveEvent
+304 (int (*)(...))QQuickItem::hoverLeaveEvent
+312 (int (*)(...))QQuickItem::dragEnterEvent
+320 (int (*)(...))QQuickItem::dragMoveEvent
+328 (int (*)(...))QQuickItem::dragLeaveEvent
+336 (int (*)(...))QQuickItem::dropEvent
+344 (int (*)(...))QQuickItem::childMouseEventFilter
+352 (int (*)(...))QQuickItem::windowDeactivateEvent
+360 (int (*)(...))QQuickItem::geometryChanged
+368 (int (*)(...))QQuickItem::updatePaintNode
+376 (int (*)(...))QQuickItem::releaseResources
+384 (int (*)(...))QQuickItem::updatePolish
+392 (int (*)(...))-16
+400 (int (*)(...))(& _ZTI10QQuickItem)
+408 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItemD1Ev
+416 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItemD0Ev
+424 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv
+432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv
+
+Class QQuickItem
+ size=32 align=8
+ base size=32 base align=8
+QQuickItem (0x0x7f21aa491690) 0
+ vptr=((& QQuickItem::_ZTV10QQuickItem) + 16u)
+ QObject (0x0x7f21aa46f8a0) 0
+ primary-for QQuickItem (0x0x7f21aa491690)
+ QQmlParserStatus (0x0x7f21aa46f900) 16
+ vptr=((& QQuickItem::_ZTV10QQuickItem) + 408u)
+
+Class QQuickFramebufferObject::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQuickFramebufferObject::QPrivateSignal (0x0x7f21aa149240) 0 empty
+
+Vtable for QQuickFramebufferObject::Renderer
+QQuickFramebufferObject::Renderer::_ZTVN23QQuickFramebufferObject8RendererE: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN23QQuickFramebufferObject8RendererE)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))QQuickFramebufferObject::Renderer::createFramebufferObject
+48 (int (*)(...))QQuickFramebufferObject::Renderer::synchronize
+
+Class QQuickFramebufferObject::Renderer
+ size=16 align=8
+ base size=16 base align=8
+QQuickFramebufferObject::Renderer (0x0x7f21aa1492a0) 0
+ vptr=((& QQuickFramebufferObject::Renderer::_ZTVN23QQuickFramebufferObject8RendererE) + 16u)
+
+Vtable for QQuickFramebufferObject
+QQuickFramebufferObject::_ZTV23QQuickFramebufferObject: 56u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QQuickFramebufferObject)
+16 (int (*)(...))QQuickFramebufferObject::metaObject
+24 (int (*)(...))QQuickFramebufferObject::qt_metacast
+32 (int (*)(...))QQuickFramebufferObject::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QQuickItem::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QQuickItem::boundingRect
+120 (int (*)(...))QQuickItem::clipRect
+128 (int (*)(...))QQuickItem::contains
+136 (int (*)(...))QQuickItem::inputMethodQuery
+144 (int (*)(...))QQuickFramebufferObject::isTextureProvider
+152 (int (*)(...))QQuickFramebufferObject::textureProvider
+160 (int (*)(...))QQuickItem::itemChange
+168 (int (*)(...))QQuickItem::classBegin
+176 (int (*)(...))QQuickItem::componentComplete
+184 (int (*)(...))QQuickItem::keyPressEvent
+192 (int (*)(...))QQuickItem::keyReleaseEvent
+200 (int (*)(...))QQuickItem::inputMethodEvent
+208 (int (*)(...))QQuickItem::focusInEvent
+216 (int (*)(...))QQuickItem::focusOutEvent
+224 (int (*)(...))QQuickItem::mousePressEvent
+232 (int (*)(...))QQuickItem::mouseMoveEvent
+240 (int (*)(...))QQuickItem::mouseReleaseEvent
+248 (int (*)(...))QQuickItem::mouseDoubleClickEvent
+256 (int (*)(...))QQuickItem::mouseUngrabEvent
+264 (int (*)(...))QQuickItem::touchUngrabEvent
+272 (int (*)(...))QQuickItem::wheelEvent
+280 (int (*)(...))QQuickItem::touchEvent
+288 (int (*)(...))QQuickItem::hoverEnterEvent
+296 (int (*)(...))QQuickItem::hoverMoveEvent
+304 (int (*)(...))QQuickItem::hoverLeaveEvent
+312 (int (*)(...))QQuickItem::dragEnterEvent
+320 (int (*)(...))QQuickItem::dragMoveEvent
+328 (int (*)(...))QQuickItem::dragLeaveEvent
+336 (int (*)(...))QQuickItem::dropEvent
+344 (int (*)(...))QQuickItem::childMouseEventFilter
+352 (int (*)(...))QQuickItem::windowDeactivateEvent
+360 (int (*)(...))QQuickFramebufferObject::geometryChanged
+368 (int (*)(...))QQuickFramebufferObject::updatePaintNode
+376 (int (*)(...))QQuickFramebufferObject::releaseResources
+384 (int (*)(...))QQuickItem::updatePolish
+392 (int (*)(...))__cxa_pure_virtual
+400 (int (*)(...))-16
+408 (int (*)(...))(& _ZTI23QQuickFramebufferObject)
+416 0u
+424 0u
+432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv
+440 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv
+
+Class QQuickFramebufferObject
+ size=32 align=8
+ base size=32 base align=8
+QQuickFramebufferObject (0x0x7f21aa473888) 0
+ vptr=((& QQuickFramebufferObject::_ZTV23QQuickFramebufferObject) + 16u)
+ QQuickItem (0x0x7f21aa134cb0) 0
+ primary-for QQuickFramebufferObject (0x0x7f21aa473888)
+ QObject (0x0x7f21aa149180) 0
+ primary-for QQuickItem (0x0x7f21aa134cb0)
+ QQmlParserStatus (0x0x7f21aa1491e0) 16
+ vptr=((& QQuickFramebufferObject::_ZTV23QQuickFramebufferObject) + 416u)
+
+Vtable for QQuickTextureFactory
+QQuickTextureFactory::_ZTV20QQuickTextureFactory: 18u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QQuickTextureFactory)
+16 (int (*)(...))QObject::metaObject
+24 (int (*)(...))QObject::qt_metacast
+32 (int (*)(...))QObject::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))QQuickTextureFactory::image
+
+Class QQuickTextureFactory
+ size=16 align=8
+ base size=16 base align=8
+QQuickTextureFactory (0x0x7f21aa4738f0) 0
+ vptr=((& QQuickTextureFactory::_ZTV20QQuickTextureFactory) + 16u)
+ QObject (0x0x7f21aa149300) 0
+ primary-for QQuickTextureFactory (0x0x7f21aa4738f0)
+
+Class QQuickImageResponse::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQuickImageResponse::QPrivateSignal (0x0x7f21aa1493c0) 0 empty
+
+Vtable for QQuickImageResponse
+QQuickImageResponse::_ZTV19QQuickImageResponse: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QQuickImageResponse)
+16 (int (*)(...))QQuickImageResponse::metaObject
+24 (int (*)(...))QQuickImageResponse::qt_metacast
+32 (int (*)(...))QQuickImageResponse::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))QQuickImageResponse::errorString
+128 (int (*)(...))QQuickImageResponse::cancel
+
+Class QQuickImageResponse
+ size=16 align=8
+ base size=16 base align=8
+QQuickImageResponse (0x0x7f21aa473958) 0
+ vptr=((& QQuickImageResponse::_ZTV19QQuickImageResponse) + 16u)
+ QObject (0x0x7f21aa149360) 0
+ primary-for QQuickImageResponse (0x0x7f21aa473958)
+
+Vtable for QQuickImageProvider
+QQuickImageProvider::_ZTV19QQuickImageProvider: 9u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QQuickImageProvider)
+16 (int (*)(...))QQuickImageProvider::~QQuickImageProvider
+24 (int (*)(...))QQuickImageProvider::~QQuickImageProvider
+32 (int (*)(...))QQuickImageProvider::imageType
+40 (int (*)(...))QQuickImageProvider::flags
+48 (int (*)(...))QQuickImageProvider::requestImage
+56 (int (*)(...))QQuickImageProvider::requestPixmap
+64 (int (*)(...))QQuickImageProvider::requestTexture
+
+Class QQuickImageProvider
+ size=16 align=8
+ base size=16 base align=8
+QQuickImageProvider (0x0x7f21aa4739c0) 0
+ vptr=((& QQuickImageProvider::_ZTV19QQuickImageProvider) + 16u)
+ QQmlImageProviderBase (0x0x7f21aa149420) 0 nearly-empty
+ primary-for QQuickImageProvider (0x0x7f21aa4739c0)
+
+Vtable for QQuickAsyncImageProvider
+QQuickAsyncImageProvider::_ZTV24QQuickAsyncImageProvider: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QQuickAsyncImageProvider)
+16 0u
+24 0u
+32 (int (*)(...))QQuickImageProvider::imageType
+40 (int (*)(...))QQuickImageProvider::flags
+48 (int (*)(...))QQuickImageProvider::requestImage
+56 (int (*)(...))QQuickImageProvider::requestPixmap
+64 (int (*)(...))QQuickImageProvider::requestTexture
+72 (int (*)(...))__cxa_pure_virtual
+
+Class QQuickAsyncImageProvider
+ size=24 align=8
+ base size=24 base align=8
+QQuickAsyncImageProvider (0x0x7f21aa473a28) 0
+ vptr=((& QQuickAsyncImageProvider::_ZTV24QQuickAsyncImageProvider) + 16u)
+ QQuickImageProvider (0x0x7f21aa473a90) 0
+ primary-for QQuickAsyncImageProvider (0x0x7f21aa473a28)
+ QQmlImageProviderBase (0x0x7f21aa149480) 0 nearly-empty
+ primary-for QQuickImageProvider (0x0x7f21aa473a90)
+
+Class QQuickItemGrabResult::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQuickItemGrabResult::QPrivateSignal (0x0x7f21aa149540) 0 empty
+
+Vtable for QQuickItemGrabResult
+QQuickItemGrabResult::_ZTV20QQuickItemGrabResult: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QQuickItemGrabResult)
+16 (int (*)(...))QQuickItemGrabResult::metaObject
+24 (int (*)(...))QQuickItemGrabResult::qt_metacast
+32 (int (*)(...))QQuickItemGrabResult::qt_metacall
+40 (int (*)(...))QQuickItemGrabResult::~QQuickItemGrabResult
+48 (int (*)(...))QQuickItemGrabResult::~QQuickItemGrabResult
+56 (int (*)(...))QQuickItemGrabResult::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QQuickItemGrabResult
+ size=16 align=8
+ base size=16 base align=8
+QQuickItemGrabResult (0x0x7f21aa473af8) 0
+ vptr=((& QQuickItemGrabResult::_ZTV20QQuickItemGrabResult) + 16u)
+ QObject (0x0x7f21aa1494e0) 0
+ primary-for QQuickItemGrabResult (0x0x7f21aa473af8)
+
+Class QQuickPaintedItem::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQuickPaintedItem::QPrivateSignal (0x0x7f21aa149660) 0 empty
+
+Vtable for QQuickPaintedItem
+QQuickPaintedItem::_ZTV17QQuickPaintedItem: 56u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QQuickPaintedItem)
+16 (int (*)(...))QQuickPaintedItem::metaObject
+24 (int (*)(...))QQuickPaintedItem::qt_metacast
+32 (int (*)(...))QQuickPaintedItem::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QQuickItem::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QQuickItem::boundingRect
+120 (int (*)(...))QQuickItem::clipRect
+128 (int (*)(...))QQuickItem::contains
+136 (int (*)(...))QQuickItem::inputMethodQuery
+144 (int (*)(...))QQuickPaintedItem::isTextureProvider
+152 (int (*)(...))QQuickPaintedItem::textureProvider
+160 (int (*)(...))QQuickPaintedItem::itemChange
+168 (int (*)(...))QQuickItem::classBegin
+176 (int (*)(...))QQuickItem::componentComplete
+184 (int (*)(...))QQuickItem::keyPressEvent
+192 (int (*)(...))QQuickItem::keyReleaseEvent
+200 (int (*)(...))QQuickItem::inputMethodEvent
+208 (int (*)(...))QQuickItem::focusInEvent
+216 (int (*)(...))QQuickItem::focusOutEvent
+224 (int (*)(...))QQuickItem::mousePressEvent
+232 (int (*)(...))QQuickItem::mouseMoveEvent
+240 (int (*)(...))QQuickItem::mouseReleaseEvent
+248 (int (*)(...))QQuickItem::mouseDoubleClickEvent
+256 (int (*)(...))QQuickItem::mouseUngrabEvent
+264 (int (*)(...))QQuickItem::touchUngrabEvent
+272 (int (*)(...))QQuickItem::wheelEvent
+280 (int (*)(...))QQuickItem::touchEvent
+288 (int (*)(...))QQuickItem::hoverEnterEvent
+296 (int (*)(...))QQuickItem::hoverMoveEvent
+304 (int (*)(...))QQuickItem::hoverLeaveEvent
+312 (int (*)(...))QQuickItem::dragEnterEvent
+320 (int (*)(...))QQuickItem::dragMoveEvent
+328 (int (*)(...))QQuickItem::dragLeaveEvent
+336 (int (*)(...))QQuickItem::dropEvent
+344 (int (*)(...))QQuickItem::childMouseEventFilter
+352 (int (*)(...))QQuickItem::windowDeactivateEvent
+360 (int (*)(...))QQuickItem::geometryChanged
+368 (int (*)(...))QQuickPaintedItem::updatePaintNode
+376 (int (*)(...))QQuickPaintedItem::releaseResources
+384 (int (*)(...))QQuickItem::updatePolish
+392 (int (*)(...))__cxa_pure_virtual
+400 (int (*)(...))-16
+408 (int (*)(...))(& _ZTI17QQuickPaintedItem)
+416 0u
+424 0u
+432 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem10classBeginEv
+440 (int (*)(...))QQuickItem::_ZThn16_N10QQuickItem17componentCompleteEv
+
+Class QQuickPaintedItem
+ size=32 align=8
+ base size=32 base align=8
+QQuickPaintedItem (0x0x7f21aa473b60) 0
+ vptr=((& QQuickPaintedItem::_ZTV17QQuickPaintedItem) + 16u)
+ QQuickItem (0x0x7f21aa16eee0) 0
+ primary-for QQuickPaintedItem (0x0x7f21aa473b60)
+ QObject (0x0x7f21aa1495a0) 0
+ primary-for QQuickItem (0x0x7f21aa16eee0)
+ QQmlParserStatus (0x0x7f21aa149600) 16
+ vptr=((& QQuickPaintedItem::_ZTV17QQuickPaintedItem) + 416u)
+
+Class QQuickRenderControl::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQuickRenderControl::QPrivateSignal (0x0x7f21aa1498a0) 0 empty
+
+Vtable for QQuickRenderControl
+QQuickRenderControl::_ZTV19QQuickRenderControl: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QQuickRenderControl)
+16 (int (*)(...))QQuickRenderControl::metaObject
+24 (int (*)(...))QQuickRenderControl::qt_metacast
+32 (int (*)(...))QQuickRenderControl::qt_metacall
+40 (int (*)(...))QQuickRenderControl::~QQuickRenderControl
+48 (int (*)(...))QQuickRenderControl::~QQuickRenderControl
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QQuickRenderControl::renderWindow
+
+Class QQuickRenderControl
+ size=16 align=8
+ base size=16 base align=8
+QQuickRenderControl (0x0x7f21aa473d00) 0
+ vptr=((& QQuickRenderControl::_ZTV19QQuickRenderControl) + 16u)
+ QObject (0x0x7f21aa149840) 0
+ primary-for QQuickRenderControl (0x0x7f21aa473d00)
+
+Class QQuickTextDocument::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQuickTextDocument::QPrivateSignal (0x0x7f21aa149960) 0 empty
+
+Vtable for QQuickTextDocument
+QQuickTextDocument::_ZTV18QQuickTextDocument: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QQuickTextDocument)
+16 (int (*)(...))QQuickTextDocument::metaObject
+24 (int (*)(...))QQuickTextDocument::qt_metacast
+32 (int (*)(...))QQuickTextDocument::qt_metacall
+40 (int (*)(...))QQuickTextDocument::~QQuickTextDocument
+48 (int (*)(...))QQuickTextDocument::~QQuickTextDocument
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QQuickTextDocument
+ size=16 align=8
+ base size=16 base align=8
+QQuickTextDocument (0x0x7f21aa473d68) 0
+ vptr=((& QQuickTextDocument::_ZTV18QQuickTextDocument) + 16u)
+ QObject (0x0x7f21aa149900) 0
+ primary-for QQuickTextDocument (0x0x7f21aa473d68)
+
+Class QSGGeometry::Attribute
+ size=16 align=4
+ base size=16 base align=4
+QSGGeometry::Attribute (0x0x7f21aa149cc0) 0
+
+Class QSGGeometry::AttributeSet
+ size=16 align=8
+ base size=16 base align=8
+QSGGeometry::AttributeSet (0x0x7f21aa149d20) 0
+
+Class QSGGeometry::Point2D
+ size=8 align=4
+ base size=8 base align=4
+QSGGeometry::Point2D (0x0x7f21aa149d80) 0
+
+Class QSGGeometry::TexturedPoint2D
+ size=16 align=4
+ base size=16 base align=4
+QSGGeometry::TexturedPoint2D (0x0x7f21aa149de0) 0
+
+Class QSGGeometry::ColoredPoint2D
+ size=12 align=4
+ base size=12 base align=4
+QSGGeometry::ColoredPoint2D (0x0x7f21aa149e40) 0
+
+Vtable for QSGGeometry
+QSGGeometry::_ZTV11QSGGeometry: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QSGGeometry)
+16 (int (*)(...))QSGGeometry::~QSGGeometry
+24 (int (*)(...))QSGGeometry::~QSGGeometry
+
+Class QSGGeometry
+ size=128 align=8
+ base size=128 base align=8
+QSGGeometry (0x0x7f21aa149c60) 0
+ vptr=((& QSGGeometry::_ZTV11QSGGeometry) + 16u)
+
+Vtable for QSGNode
+QSGNode::_ZTV7QSGNode: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QSGNode)
+16 (int (*)(...))QSGNode::~QSGNode
+24 (int (*)(...))QSGNode::~QSGNode
+32 (int (*)(...))QSGNode::isSubtreeBlocked
+40 (int (*)(...))QSGNode::preprocess
+
+Class QSGNode
+ size=80 align=8
+ base size=80 base align=8
+QSGNode (0x0x7f21aa246360) 0
+ vptr=((& QSGNode::_ZTV7QSGNode) + 16u)
+
+Vtable for QSGBasicGeometryNode
+QSGBasicGeometryNode::_ZTV20QSGBasicGeometryNode: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QSGBasicGeometryNode)
+16 (int (*)(...))QSGBasicGeometryNode::~QSGBasicGeometryNode
+24 (int (*)(...))QSGBasicGeometryNode::~QSGBasicGeometryNode
+32 (int (*)(...))QSGNode::isSubtreeBlocked
+40 (int (*)(...))QSGNode::preprocess
+
+Class QSGBasicGeometryNode
+ size=112 align=8
+ base size=112 base align=8
+QSGBasicGeometryNode (0x0x7f21aa248478) 0
+ vptr=((& QSGBasicGeometryNode::_ZTV20QSGBasicGeometryNode) + 16u)
+ QSGNode (0x0x7f21aa246720) 0
+ primary-for QSGBasicGeometryNode (0x0x7f21aa248478)
+
+Vtable for QSGGeometryNode
+QSGGeometryNode::_ZTV15QSGGeometryNode: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QSGGeometryNode)
+16 (int (*)(...))QSGGeometryNode::~QSGGeometryNode
+24 (int (*)(...))QSGGeometryNode::~QSGGeometryNode
+32 (int (*)(...))QSGNode::isSubtreeBlocked
+40 (int (*)(...))QSGNode::preprocess
+
+Class QSGGeometryNode
+ size=144 align=8
+ base size=144 base align=8
+QSGGeometryNode (0x0x7f21aa2484e0) 0
+ vptr=((& QSGGeometryNode::_ZTV15QSGGeometryNode) + 16u)
+ QSGBasicGeometryNode (0x0x7f21aa248548) 0
+ primary-for QSGGeometryNode (0x0x7f21aa2484e0)
+ QSGNode (0x0x7f21aa246780) 0
+ primary-for QSGBasicGeometryNode (0x0x7f21aa248548)
+
+Vtable for QSGClipNode
+QSGClipNode::_ZTV11QSGClipNode: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QSGClipNode)
+16 (int (*)(...))QSGClipNode::~QSGClipNode
+24 (int (*)(...))QSGClipNode::~QSGClipNode
+32 (int (*)(...))QSGNode::isSubtreeBlocked
+40 (int (*)(...))QSGNode::preprocess
+
+Class QSGClipNode
+ size=152 align=8
+ base size=152 base align=8
+QSGClipNode (0x0x7f21aa2485b0) 0
+ vptr=((& QSGClipNode::_ZTV11QSGClipNode) + 16u)
+ QSGBasicGeometryNode (0x0x7f21aa248618) 0
+ primary-for QSGClipNode (0x0x7f21aa2485b0)
+ QSGNode (0x0x7f21aa2467e0) 0
+ primary-for QSGBasicGeometryNode (0x0x7f21aa248618)
+
+Vtable for QSGTransformNode
+QSGTransformNode::_ZTV16QSGTransformNode: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QSGTransformNode)
+16 (int (*)(...))QSGTransformNode::~QSGTransformNode
+24 (int (*)(...))QSGTransformNode::~QSGTransformNode
+32 (int (*)(...))QSGNode::isSubtreeBlocked
+40 (int (*)(...))QSGNode::preprocess
+
+Class QSGTransformNode
+ size=216 align=8
+ base size=216 base align=8
+QSGTransformNode (0x0x7f21aa248680) 0
+ vptr=((& QSGTransformNode::_ZTV16QSGTransformNode) + 16u)
+ QSGNode (0x0x7f21aa246840) 0
+ primary-for QSGTransformNode (0x0x7f21aa248680)
+
+Vtable for QSGRootNode
+QSGRootNode::_ZTV11QSGRootNode: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QSGRootNode)
+16 (int (*)(...))QSGRootNode::~QSGRootNode
+24 (int (*)(...))QSGRootNode::~QSGRootNode
+32 (int (*)(...))QSGNode::isSubtreeBlocked
+40 (int (*)(...))QSGNode::preprocess
+
+Class QSGRootNode
+ size=88 align=8
+ base size=88 base align=8
+QSGRootNode (0x0x7f21aa2486e8) 0
+ vptr=((& QSGRootNode::_ZTV11QSGRootNode) + 16u)
+ QSGNode (0x0x7f21aa2468a0) 0
+ primary-for QSGRootNode (0x0x7f21aa2486e8)
+
+Vtable for QSGOpacityNode
+QSGOpacityNode::_ZTV14QSGOpacityNode: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QSGOpacityNode)
+16 (int (*)(...))QSGOpacityNode::~QSGOpacityNode
+24 (int (*)(...))QSGOpacityNode::~QSGOpacityNode
+32 (int (*)(...))QSGOpacityNode::isSubtreeBlocked
+40 (int (*)(...))QSGNode::preprocess
+
+Class QSGOpacityNode
+ size=96 align=8
+ base size=96 base align=8
+QSGOpacityNode (0x0x7f21aa248888) 0
+ vptr=((& QSGOpacityNode::_ZTV14QSGOpacityNode) + 16u)
+ QSGNode (0x0x7f21aa246a20) 0
+ primary-for QSGOpacityNode (0x0x7f21aa248888)
+
+Vtable for QSGNodeVisitor
+QSGNodeVisitor::_ZTV14QSGNodeVisitor: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QSGNodeVisitor)
+16 (int (*)(...))QSGNodeVisitor::~QSGNodeVisitor
+24 (int (*)(...))QSGNodeVisitor::~QSGNodeVisitor
+32 (int (*)(...))QSGNodeVisitor::enterTransformNode
+40 (int (*)(...))QSGNodeVisitor::leaveTransformNode
+48 (int (*)(...))QSGNodeVisitor::enterClipNode
+56 (int (*)(...))QSGNodeVisitor::leaveClipNode
+64 (int (*)(...))QSGNodeVisitor::enterGeometryNode
+72 (int (*)(...))QSGNodeVisitor::leaveGeometryNode
+80 (int (*)(...))QSGNodeVisitor::enterOpacityNode
+88 (int (*)(...))QSGNodeVisitor::leaveOpacityNode
+96 (int (*)(...))QSGNodeVisitor::visitNode
+104 (int (*)(...))QSGNodeVisitor::visitChildren
+
+Class QSGNodeVisitor
+ size=8 align=8
+ base size=8 base align=8
+QSGNodeVisitor (0x0x7f21aa246a80) 0 nearly-empty
+ vptr=((& QSGNodeVisitor::_ZTV14QSGNodeVisitor) + 16u)
+
+Vtable for QSGRendererInterface
+QSGRendererInterface::_ZTV20QSGRendererInterface: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QSGRendererInterface)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))QSGRendererInterface::getResource
+48 (int (*)(...))QSGRendererInterface::getResource
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+72 (int (*)(...))__cxa_pure_virtual
+
+Class QSGRendererInterface
+ size=8 align=8
+ base size=8 base align=8
+QSGRendererInterface (0x0x7f21aa246ae0) 0 nearly-empty
+ vptr=((& QSGRendererInterface::_ZTV20QSGRendererInterface) + 16u)
+
+Class QQuickWindow::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQuickWindow::QPrivateSignal (0x0x7f21aa246f00) 0 empty
+
+Vtable for QQuickWindow
+QQuickWindow::_ZTV12QQuickWindow: 45u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QQuickWindow)
+16 (int (*)(...))QQuickWindow::metaObject
+24 (int (*)(...))QQuickWindow::qt_metacast
+32 (int (*)(...))QQuickWindow::qt_metacall
+40 (int (*)(...))QQuickWindow::~QQuickWindow
+48 (int (*)(...))QQuickWindow::~QQuickWindow
+56 (int (*)(...))QQuickWindow::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWindow::surfaceType
+120 (int (*)(...))QWindow::format
+128 (int (*)(...))QWindow::size
+136 (int (*)(...))QQuickWindow::accessibleRoot
+144 (int (*)(...))QQuickWindow::focusObject
+152 (int (*)(...))QQuickWindow::exposeEvent
+160 (int (*)(...))QQuickWindow::resizeEvent
+168 (int (*)(...))QWindow::moveEvent
+176 (int (*)(...))QQuickWindow::focusInEvent
+184 (int (*)(...))QQuickWindow::focusOutEvent
+192 (int (*)(...))QQuickWindow::showEvent
+200 (int (*)(...))QQuickWindow::hideEvent
+208 (int (*)(...))QQuickWindow::keyPressEvent
+216 (int (*)(...))QQuickWindow::keyReleaseEvent
+224 (int (*)(...))QQuickWindow::mousePressEvent
+232 (int (*)(...))QQuickWindow::mouseReleaseEvent
+240 (int (*)(...))QQuickWindow::mouseDoubleClickEvent
+248 (int (*)(...))QQuickWindow::mouseMoveEvent
+256 (int (*)(...))QQuickWindow::wheelEvent
+264 (int (*)(...))QWindow::touchEvent
+272 (int (*)(...))QWindow::tabletEvent
+280 (int (*)(...))QWindow::nativeEvent
+288 (int (*)(...))QWindow::surfaceHandle
+296 (int (*)(...))-16
+304 (int (*)(...))(& _ZTI12QQuickWindow)
+312 (int (*)(...))QQuickWindow::_ZThn16_N12QQuickWindowD1Ev
+320 (int (*)(...))QQuickWindow::_ZThn16_N12QQuickWindowD0Ev
+328 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv
+336 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv
+344 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv
+352 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv
+
+Class QQuickWindow
+ size=40 align=8
+ base size=40 base align=8
+QQuickWindow (0x0x7f21aa248a90) 0
+ vptr=((& QQuickWindow::_ZTV12QQuickWindow) + 16u)
+ QWindow (0x0x7f21a9fd1ee0) 0
+ primary-for QQuickWindow (0x0x7f21aa248a90)
+ QObject (0x0x7f21aa246e40) 0
+ primary-for QWindow (0x0x7f21a9fd1ee0)
+ QSurface (0x0x7f21aa246ea0) 16
+ vptr=((& QQuickWindow::_ZTV12QQuickWindow) + 312u)
+
+Class QQuickView::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQuickView::QPrivateSignal (0x0x7f21aa02d300) 0 empty
+
+Vtable for QQuickView
+QQuickView::_ZTV10QQuickView: 45u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QQuickView)
+16 (int (*)(...))QQuickView::metaObject
+24 (int (*)(...))QQuickView::qt_metacast
+32 (int (*)(...))QQuickView::qt_metacall
+40 (int (*)(...))QQuickView::~QQuickView
+48 (int (*)(...))QQuickView::~QQuickView
+56 (int (*)(...))QQuickWindow::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QQuickView::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWindow::surfaceType
+120 (int (*)(...))QWindow::format
+128 (int (*)(...))QWindow::size
+136 (int (*)(...))QQuickWindow::accessibleRoot
+144 (int (*)(...))QQuickWindow::focusObject
+152 (int (*)(...))QQuickWindow::exposeEvent
+160 (int (*)(...))QQuickView::resizeEvent
+168 (int (*)(...))QWindow::moveEvent
+176 (int (*)(...))QQuickWindow::focusInEvent
+184 (int (*)(...))QQuickWindow::focusOutEvent
+192 (int (*)(...))QQuickWindow::showEvent
+200 (int (*)(...))QQuickWindow::hideEvent
+208 (int (*)(...))QQuickView::keyPressEvent
+216 (int (*)(...))QQuickView::keyReleaseEvent
+224 (int (*)(...))QQuickView::mousePressEvent
+232 (int (*)(...))QQuickView::mouseReleaseEvent
+240 (int (*)(...))QQuickWindow::mouseDoubleClickEvent
+248 (int (*)(...))QQuickView::mouseMoveEvent
+256 (int (*)(...))QQuickWindow::wheelEvent
+264 (int (*)(...))QWindow::touchEvent
+272 (int (*)(...))QWindow::tabletEvent
+280 (int (*)(...))QWindow::nativeEvent
+288 (int (*)(...))QWindow::surfaceHandle
+296 (int (*)(...))-16
+304 (int (*)(...))(& _ZTI10QQuickView)
+312 (int (*)(...))QQuickView::_ZThn16_N10QQuickViewD1Ev
+320 (int (*)(...))QQuickView::_ZThn16_N10QQuickViewD0Ev
+328 (int (*)(...))QWindow::_ZThn16_NK7QWindow6formatEv
+336 (int (*)(...))QWindow::_ZThn16_NK7QWindow13surfaceHandleEv
+344 (int (*)(...))QWindow::_ZThn16_NK7QWindow11surfaceTypeEv
+352 (int (*)(...))QWindow::_ZThn16_NK7QWindow4sizeEv
+
+Class QQuickView
+ size=40 align=8
+ base size=40 base align=8
+QQuickView (0x0x7f21aa248bc8) 0
+ vptr=((& QQuickView::_ZTV10QQuickView) + 16u)
+ QQuickWindow (0x0x7f21aa248c30) 0
+ primary-for QQuickView (0x0x7f21aa248bc8)
+ QWindow (0x0x7f21aa0495b0) 0
+ primary-for QQuickWindow (0x0x7f21aa248c30)
+ QObject (0x0x7f21aa02d240) 0
+ primary-for QWindow (0x0x7f21aa0495b0)
+ QSurface (0x0x7f21aa02d2a0) 16
+ vptr=((& QQuickView::_ZTV10QQuickView) + 312u)
+
+Class QSGAbstractRenderer::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSGAbstractRenderer::QPrivateSignal (0x0x7f21aa02d3c0) 0 empty
+
+Vtable for QSGAbstractRenderer
+QSGAbstractRenderer::_ZTV19QSGAbstractRenderer: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QSGAbstractRenderer)
+16 (int (*)(...))QSGAbstractRenderer::metaObject
+24 (int (*)(...))QSGAbstractRenderer::qt_metacast
+32 (int (*)(...))QSGAbstractRenderer::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+
+Class QSGAbstractRenderer
+ size=16 align=8
+ base size=16 base align=8
+QSGAbstractRenderer (0x0x7f21aa248c98) 0
+ vptr=((& QSGAbstractRenderer::_ZTV19QSGAbstractRenderer) + 16u)
+ QObject (0x0x7f21aa02d360) 0
+ primary-for QSGAbstractRenderer (0x0x7f21aa248c98)
+
+Class QSGEngine::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSGEngine::QPrivateSignal (0x0x7f21aa02d600) 0 empty
+
+Vtable for QSGEngine
+QSGEngine::_ZTV9QSGEngine: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QSGEngine)
+16 (int (*)(...))QSGEngine::metaObject
+24 (int (*)(...))QSGEngine::qt_metacast
+32 (int (*)(...))QSGEngine::qt_metacall
+40 (int (*)(...))QSGEngine::~QSGEngine
+48 (int (*)(...))QSGEngine::~QSGEngine
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QSGEngine
+ size=16 align=8
+ base size=16 base align=8
+QSGEngine (0x0x7f21aa248dd0) 0
+ vptr=((& QSGEngine::_ZTV9QSGEngine) + 16u)
+ QObject (0x0x7f21aa02d5a0) 0
+ primary-for QSGEngine (0x0x7f21aa248dd0)
+
+Class QSGMaterialShader::RenderState
+ size=16 align=8
+ base size=16 base align=8
+QSGMaterialShader::RenderState (0x0x7f21aa02d8a0) 0
+
+Vtable for QSGMaterialShader
+QSGMaterialShader::_ZTV17QSGMaterialShader: 12u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QSGMaterialShader)
+16 0u
+24 0u
+32 (int (*)(...))QSGMaterialShader::activate
+40 (int (*)(...))QSGMaterialShader::deactivate
+48 (int (*)(...))QSGMaterialShader::updateState
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))QSGMaterialShader::compile
+72 (int (*)(...))QSGMaterialShader::initialize
+80 (int (*)(...))QSGMaterialShader::vertexShader
+88 (int (*)(...))QSGMaterialShader::fragmentShader
+
+Class QSGMaterialShader
+ size=32 align=8
+ base size=32 base align=8
+QSGMaterialShader (0x0x7f21aa02d840) 0
+ vptr=((& QSGMaterialShader::_ZTV17QSGMaterialShader) + 16u)
+
+Class QSGMaterialType
+ size=1 align=1
+ base size=0 base align=1
+QSGMaterialType (0x0x7f21aa02db40) 0 empty
+
+Vtable for QSGMaterial
+QSGMaterial::_ZTV11QSGMaterial: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QSGMaterial)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))QSGMaterial::compare
+
+Class QSGMaterial
+ size=24 align=8
+ base size=24 base align=8
+QSGMaterial (0x0x7f21aa02dba0) 0
+ vptr=((& QSGMaterial::_ZTV11QSGMaterial) + 16u)
+
+Vtable for QSGFlatColorMaterial
+QSGFlatColorMaterial::_ZTV20QSGFlatColorMaterial: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QSGFlatColorMaterial)
+16 (int (*)(...))QSGFlatColorMaterial::~QSGFlatColorMaterial
+24 (int (*)(...))QSGFlatColorMaterial::~QSGFlatColorMaterial
+32 (int (*)(...))QSGFlatColorMaterial::type
+40 (int (*)(...))QSGFlatColorMaterial::createShader
+48 (int (*)(...))QSGFlatColorMaterial::compare
+
+Class QSGFlatColorMaterial
+ size=40 align=8
+ base size=40 base align=8
+QSGFlatColorMaterial (0x0x7f21aa110138) 0
+ vptr=((& QSGFlatColorMaterial::_ZTV20QSGFlatColorMaterial) + 16u)
+ QSGMaterial (0x0x7f21aa02dd80) 0
+ primary-for QSGFlatColorMaterial (0x0x7f21aa110138)
+
+Class QSGTexture::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSGTexture::QPrivateSignal (0x0x7f21aa02de40) 0 empty
+
+Vtable for QSGTexture
+QSGTexture::_ZTV10QSGTexture: 22u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QSGTexture)
+16 (int (*)(...))QSGTexture::metaObject
+24 (int (*)(...))QSGTexture::qt_metacast
+32 (int (*)(...))QSGTexture::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))QSGTexture::normalizedTextureSubRect
+152 (int (*)(...))QSGTexture::isAtlasTexture
+160 (int (*)(...))QSGTexture::removedFromAtlas
+168 (int (*)(...))__cxa_pure_virtual
+
+Class QSGTexture
+ size=16 align=8
+ base size=16 base align=8
+QSGTexture (0x0x7f21aa1101a0) 0
+ vptr=((& QSGTexture::_ZTV10QSGTexture) + 16u)
+ QObject (0x0x7f21aa02dde0) 0
+ primary-for QSGTexture (0x0x7f21aa1101a0)
+
+Class QSGDynamicTexture::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSGDynamicTexture::QPrivateSignal (0x0x7f21aa02df00) 0 empty
+
+Vtable for QSGDynamicTexture
+QSGDynamicTexture::_ZTV17QSGDynamicTexture: 23u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QSGDynamicTexture)
+16 (int (*)(...))QSGDynamicTexture::metaObject
+24 (int (*)(...))QSGDynamicTexture::qt_metacast
+32 (int (*)(...))QSGDynamicTexture::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))QSGTexture::normalizedTextureSubRect
+152 (int (*)(...))QSGTexture::isAtlasTexture
+160 (int (*)(...))QSGTexture::removedFromAtlas
+168 (int (*)(...))__cxa_pure_virtual
+176 (int (*)(...))__cxa_pure_virtual
+
+Class QSGDynamicTexture
+ size=16 align=8
+ base size=16 base align=8
+QSGDynamicTexture (0x0x7f21aa110208) 0
+ vptr=((& QSGDynamicTexture::_ZTV17QSGDynamicTexture) + 16u)
+ QSGTexture (0x0x7f21aa110270) 0
+ primary-for QSGDynamicTexture (0x0x7f21aa110208)
+ QObject (0x0x7f21aa02dea0) 0
+ primary-for QSGTexture (0x0x7f21aa110270)
+
+Vtable for QSGImageNode
+QSGImageNode::_ZTV12QSGImageNode: 20u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QSGImageNode)
+16 0u
+24 0u
+32 (int (*)(...))QSGNode::isSubtreeBlocked
+40 (int (*)(...))QSGNode::preprocess
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+72 (int (*)(...))__cxa_pure_virtual
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))__cxa_pure_virtual
+96 (int (*)(...))__cxa_pure_virtual
+104 (int (*)(...))__cxa_pure_virtual
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))__cxa_pure_virtual
+144 (int (*)(...))__cxa_pure_virtual
+152 (int (*)(...))__cxa_pure_virtual
+
+Class QSGImageNode
+ size=144 align=8
+ base size=144 base align=8
+QSGImageNode (0x0x7f21aa1102d8) 0
+ vptr=((& QSGImageNode::_ZTV12QSGImageNode) + 16u)
+ QSGGeometryNode (0x0x7f21aa110340) 0
+ primary-for QSGImageNode (0x0x7f21aa1102d8)
+ QSGBasicGeometryNode (0x0x7f21aa1103a8) 0
+ primary-for QSGGeometryNode (0x0x7f21aa110340)
+ QSGNode (0x0x7f21aa02df60) 0
+ primary-for QSGBasicGeometryNode (0x0x7f21aa1103a8)
+
+Vtable for QSGNinePatchNode
+QSGNinePatchNode::_ZTV16QSGNinePatchNode: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QSGNinePatchNode)
+16 0u
+24 0u
+32 (int (*)(...))QSGNode::isSubtreeBlocked
+40 (int (*)(...))QSGNode::preprocess
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+72 (int (*)(...))__cxa_pure_virtual
+80 (int (*)(...))__cxa_pure_virtual
+
+Class QSGNinePatchNode
+ size=144 align=8
+ base size=144 base align=8
+QSGNinePatchNode (0x0x7f21aa1104e0) 0
+ vptr=((& QSGNinePatchNode::_ZTV16QSGNinePatchNode) + 16u)
+ QSGGeometryNode (0x0x7f21aa110548) 0
+ primary-for QSGNinePatchNode (0x0x7f21aa1104e0)
+ QSGBasicGeometryNode (0x0x7f21aa1105b0) 0
+ primary-for QSGGeometryNode (0x0x7f21aa110548)
+ QSGNode (0x0x7f21a9da1180) 0
+ primary-for QSGBasicGeometryNode (0x0x7f21aa1105b0)
+
+Vtable for QSGRectangleNode
+QSGRectangleNode::_ZTV16QSGRectangleNode: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QSGRectangleNode)
+16 0u
+24 0u
+32 (int (*)(...))QSGNode::isSubtreeBlocked
+40 (int (*)(...))QSGNode::preprocess
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+72 (int (*)(...))__cxa_pure_virtual
+
+Class QSGRectangleNode
+ size=144 align=8
+ base size=144 base align=8
+QSGRectangleNode (0x0x7f21aa110618) 0
+ vptr=((& QSGRectangleNode::_ZTV16QSGRectangleNode) + 16u)
+ QSGGeometryNode (0x0x7f21aa110680) 0
+ primary-for QSGRectangleNode (0x0x7f21aa110618)
+ QSGBasicGeometryNode (0x0x7f21aa1106e8) 0
+ primary-for QSGGeometryNode (0x0x7f21aa110680)
+ QSGNode (0x0x7f21a9da11e0) 0
+ primary-for QSGBasicGeometryNode (0x0x7f21aa1106e8)
+
+Vtable for QSGRenderNode::RenderState
+QSGRenderNode::RenderState::_ZTVN13QSGRenderNode11RenderStateE: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTIN13QSGRenderNode11RenderStateE)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+72 (int (*)(...))__cxa_pure_virtual
+80 (int (*)(...))QSGRenderNode::RenderState::get
+
+Class QSGRenderNode::RenderState
+ size=8 align=8
+ base size=8 base align=8
+QSGRenderNode::RenderState (0x0x7f21a9da12a0) 0 nearly-empty
+ vptr=((& QSGRenderNode::RenderState::_ZTVN13QSGRenderNode11RenderStateE) + 16u)
+
+Vtable for QSGRenderNode
+QSGRenderNode::_ZTV13QSGRenderNode: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QSGRenderNode)
+16 0u
+24 0u
+32 (int (*)(...))QSGNode::isSubtreeBlocked
+40 (int (*)(...))QSGNode::preprocess
+48 (int (*)(...))QSGRenderNode::changedStates
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))QSGRenderNode::releaseResources
+72 (int (*)(...))QSGRenderNode::flags
+80 (int (*)(...))QSGRenderNode::rect
+
+Class QSGRenderNode
+ size=88 align=8
+ base size=88 base align=8
+QSGRenderNode (0x0x7f21aa110750) 0
+ vptr=((& QSGRenderNode::_ZTV13QSGRenderNode) + 16u)
+ QSGNode (0x0x7f21a9da1240) 0
+ primary-for QSGRenderNode (0x0x7f21aa110750)
+
+Vtable for QSGSimpleRectNode
+QSGSimpleRectNode::_ZTV17QSGSimpleRectNode: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QSGSimpleRectNode)
+16 (int (*)(...))QSGSimpleRectNode::~QSGSimpleRectNode
+24 (int (*)(...))QSGSimpleRectNode::~QSGSimpleRectNode
+32 (int (*)(...))QSGNode::isSubtreeBlocked
+40 (int (*)(...))QSGNode::preprocess
+
+Class QSGSimpleRectNode
+ size=320 align=8
+ base size=320 base align=8
+QSGSimpleRectNode (0x0x7f21aa110bc8) 0
+ vptr=((& QSGSimpleRectNode::_ZTV17QSGSimpleRectNode) + 16u)
+ QSGGeometryNode (0x0x7f21aa110c30) 0
+ primary-for QSGSimpleRectNode (0x0x7f21aa110bc8)
+ QSGBasicGeometryNode (0x0x7f21aa110c98) 0
+ primary-for QSGGeometryNode (0x0x7f21aa110c30)
+ QSGNode (0x0x7f21a9da18a0) 0
+ primary-for QSGBasicGeometryNode (0x0x7f21aa110c98)
+
+Vtable for QSGOpaqueTextureMaterial
+QSGOpaqueTextureMaterial::_ZTV24QSGOpaqueTextureMaterial: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QSGOpaqueTextureMaterial)
+16 (int (*)(...))QSGOpaqueTextureMaterial::~QSGOpaqueTextureMaterial
+24 (int (*)(...))QSGOpaqueTextureMaterial::~QSGOpaqueTextureMaterial
+32 (int (*)(...))QSGOpaqueTextureMaterial::type
+40 (int (*)(...))QSGOpaqueTextureMaterial::createShader
+48 (int (*)(...))QSGOpaqueTextureMaterial::compare
+
+Class QSGOpaqueTextureMaterial
+ size=40 align=8
+ base size=36 base align=8
+QSGOpaqueTextureMaterial (0x0x7f21aa110d00) 0
+ vptr=((& QSGOpaqueTextureMaterial::_ZTV24QSGOpaqueTextureMaterial) + 16u)
+ QSGMaterial (0x0x7f21a9da1900) 0
+ primary-for QSGOpaqueTextureMaterial (0x0x7f21aa110d00)
+
+Vtable for QSGTextureMaterial
+QSGTextureMaterial::_ZTV18QSGTextureMaterial: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QSGTextureMaterial)
+16 (int (*)(...))QSGTextureMaterial::~QSGTextureMaterial
+24 (int (*)(...))QSGTextureMaterial::~QSGTextureMaterial
+32 (int (*)(...))QSGTextureMaterial::type
+40 (int (*)(...))QSGTextureMaterial::createShader
+48 (int (*)(...))QSGOpaqueTextureMaterial::compare
+
+Class QSGTextureMaterial
+ size=40 align=8
+ base size=36 base align=8
+QSGTextureMaterial (0x0x7f21aa110d68) 0
+ vptr=((& QSGTextureMaterial::_ZTV18QSGTextureMaterial) + 16u)
+ QSGOpaqueTextureMaterial (0x0x7f21aa110dd0) 0
+ primary-for QSGTextureMaterial (0x0x7f21aa110d68)
+ QSGMaterial (0x0x7f21a9da1960) 0
+ primary-for QSGOpaqueTextureMaterial (0x0x7f21aa110dd0)
+
+Vtable for QSGSimpleTextureNode
+QSGSimpleTextureNode::_ZTV20QSGSimpleTextureNode: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QSGSimpleTextureNode)
+16 (int (*)(...))QSGSimpleTextureNode::~QSGSimpleTextureNode
+24 (int (*)(...))QSGSimpleTextureNode::~QSGSimpleTextureNode
+32 (int (*)(...))QSGNode::isSubtreeBlocked
+40 (int (*)(...))QSGNode::preprocess
+
+Class QSGSimpleTextureNode
+ size=384 align=8
+ base size=384 base align=8
+QSGSimpleTextureNode (0x0x7f21aa110e38) 0
+ vptr=((& QSGSimpleTextureNode::_ZTV20QSGSimpleTextureNode) + 16u)
+ QSGGeometryNode (0x0x7f21aa110ea0) 0
+ primary-for QSGSimpleTextureNode (0x0x7f21aa110e38)
+ QSGBasicGeometryNode (0x0x7f21aa110f08) 0
+ primary-for QSGGeometryNode (0x0x7f21aa110ea0)
+ QSGNode (0x0x7f21a9da19c0) 0
+ primary-for QSGBasicGeometryNode (0x0x7f21aa110f08)
+
+Class QSGTextureProvider::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSGTextureProvider::QPrivateSignal (0x0x7f21a9da1c60) 0 empty
+
+Vtable for QSGTextureProvider
+QSGTextureProvider::_ZTV18QSGTextureProvider: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QSGTextureProvider)
+16 (int (*)(...))QSGTextureProvider::metaObject
+24 (int (*)(...))QSGTextureProvider::qt_metacast
+32 (int (*)(...))QSGTextureProvider::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+
+Class QSGTextureProvider
+ size=16 align=8
+ base size=16 base align=8
+QSGTextureProvider (0x0x7f21a9ed10d0) 0
+ vptr=((& QSGTextureProvider::_ZTV18QSGTextureProvider) + 16u)
+ QObject (0x0x7f21a9da1c00) 0
+ primary-for QSGTextureProvider (0x0x7f21a9ed10d0)
+
+Vtable for QSGVertexColorMaterial
+QSGVertexColorMaterial::_ZTV22QSGVertexColorMaterial: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI22QSGVertexColorMaterial)
+16 (int (*)(...))QSGVertexColorMaterial::~QSGVertexColorMaterial
+24 (int (*)(...))QSGVertexColorMaterial::~QSGVertexColorMaterial
+32 (int (*)(...))QSGVertexColorMaterial::type
+40 (int (*)(...))QSGVertexColorMaterial::createShader
+48 (int (*)(...))QSGVertexColorMaterial::compare
+
+Class QSGVertexColorMaterial
+ size=24 align=8
+ base size=24 base align=8
+QSGVertexColorMaterial (0x0x7f21a9ed1138) 0
+ vptr=((& QSGVertexColorMaterial::_ZTV22QSGVertexColorMaterial) + 16u)
+ QSGMaterial (0x0x7f21a9da1cc0) 0
+ primary-for QSGVertexColorMaterial (0x0x7f21a9ed1138)
+
+Class QSizePolicy::Bits
+ size=4 align=4
+ base size=4 base align=4
+QSizePolicy::Bits (0x0x7f21a9da1d80) 0
+
+Class QSizePolicy
+ size=4 align=4
+ base size=4 base align=4
+QSizePolicy (0x0x7f21a9da1d20) 0
+
+Class QWidgetData
+ size=88 align=8
+ base size=88 base align=8
+QWidgetData (0x0x7f21a9b466c0) 0
+
+Class QWidget::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QWidget::QPrivateSignal (0x0x7f21a9b467e0) 0 empty
+
+Vtable for QWidget
+QWidget::_ZTV7QWidget: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QWidget)
+16 (int (*)(...))QWidget::metaObject
+24 (int (*)(...))QWidget::qt_metacast
+32 (int (*)(...))QWidget::qt_metacall
+40 (int (*)(...))QWidget::~QWidget
+48 (int (*)(...))QWidget::~QWidget
+56 (int (*)(...))QWidget::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI7QWidget)
+448 (int (*)(...))QWidget::_ZThn16_N7QWidgetD1Ev
+456 (int (*)(...))QWidget::_ZThn16_N7QWidgetD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QWidget
+ size=48 align=8
+ base size=48 base align=8
+QWidget (0x0x7f21a9ba6230) 0
+ vptr=((& QWidget::_ZTV7QWidget) + 16u)
+ QObject (0x0x7f21a9b46720) 0
+ primary-for QWidget (0x0x7f21a9ba6230)
+ QPaintDevice (0x0x7f21a9b46780) 16
+ vptr=((& QWidget::_ZTV7QWidget) + 448u)
+
+Class QAbstractButton::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractButton::QPrivateSignal (0x0x7f21a9c9c480) 0 empty
+
+Vtable for QAbstractButton
+QAbstractButton::_ZTV15QAbstractButton: 67u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QAbstractButton)
+16 (int (*)(...))QAbstractButton::metaObject
+24 (int (*)(...))QAbstractButton::qt_metacast
+32 (int (*)(...))QAbstractButton::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QAbstractButton::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractButton::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractButton::mousePressEvent
+176 (int (*)(...))QAbstractButton::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractButton::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QAbstractButton::keyPressEvent
+216 (int (*)(...))QAbstractButton::keyReleaseEvent
+224 (int (*)(...))QAbstractButton::focusInEvent
+232 (int (*)(...))QAbstractButton::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))__cxa_pure_virtual
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractButton::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QAbstractButton::hitButton
+440 (int (*)(...))QAbstractButton::checkStateSet
+448 (int (*)(...))QAbstractButton::nextCheckState
+456 (int (*)(...))-16
+464 (int (*)(...))(& _ZTI15QAbstractButton)
+472 0u
+480 0u
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QAbstractButton
+ size=48 align=8
+ base size=48 base align=8
+QAbstractButton (0x0x7f21a9c9e478) 0
+ vptr=((& QAbstractButton::_ZTV15QAbstractButton) + 16u)
+ QWidget (0x0x7f21a9c91e00) 0
+ primary-for QAbstractButton (0x0x7f21a9c9e478)
+ QObject (0x0x7f21a9c9c3c0) 0
+ primary-for QWidget (0x0x7f21a9c91e00)
+ QPaintDevice (0x0x7f21a9c9c420) 16
+ vptr=((& QAbstractButton::_ZTV15QAbstractButton) + 472u)
+
+Class QAbstractSpinBox::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractSpinBox::QPrivateSignal (0x0x7f21a9c9c5a0) 0 empty
+
+Vtable for QAbstractSpinBox
+QAbstractSpinBox::_ZTV16QAbstractSpinBox: 69u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QAbstractSpinBox)
+16 (int (*)(...))QAbstractSpinBox::metaObject
+24 (int (*)(...))QAbstractSpinBox::qt_metacast
+32 (int (*)(...))QAbstractSpinBox::qt_metacall
+40 (int (*)(...))QAbstractSpinBox::~QAbstractSpinBox
+48 (int (*)(...))QAbstractSpinBox::~QAbstractSpinBox
+56 (int (*)(...))QAbstractSpinBox::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractSpinBox::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractSpinBox::sizeHint
+136 (int (*)(...))QAbstractSpinBox::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractSpinBox::mousePressEvent
+176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent
+200 (int (*)(...))QAbstractSpinBox::wheelEvent
+208 (int (*)(...))QAbstractSpinBox::keyPressEvent
+216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent
+224 (int (*)(...))QAbstractSpinBox::focusInEvent
+232 (int (*)(...))QAbstractSpinBox::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QAbstractSpinBox::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QAbstractSpinBox::resizeEvent
+280 (int (*)(...))QAbstractSpinBox::closeEvent
+288 (int (*)(...))QAbstractSpinBox::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QAbstractSpinBox::showEvent
+352 (int (*)(...))QAbstractSpinBox::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractSpinBox::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QAbstractSpinBox::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QAbstractSpinBox::validate
+440 (int (*)(...))QAbstractSpinBox::fixup
+448 (int (*)(...))QAbstractSpinBox::stepBy
+456 (int (*)(...))QAbstractSpinBox::clear
+464 (int (*)(...))QAbstractSpinBox::stepEnabled
+472 (int (*)(...))-16
+480 (int (*)(...))(& _ZTI16QAbstractSpinBox)
+488 (int (*)(...))QAbstractSpinBox::_ZThn16_N16QAbstractSpinBoxD1Ev
+496 (int (*)(...))QAbstractSpinBox::_ZThn16_N16QAbstractSpinBoxD0Ev
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QAbstractSpinBox
+ size=48 align=8
+ base size=48 base align=8
+QAbstractSpinBox (0x0x7f21a9c9e4e0) 0
+ vptr=((& QAbstractSpinBox::_ZTV16QAbstractSpinBox) + 16u)
+ QWidget (0x0x7f21a9cc6310) 0
+ primary-for QAbstractSpinBox (0x0x7f21a9c9e4e0)
+ QObject (0x0x7f21a9c9c4e0) 0
+ primary-for QWidget (0x0x7f21a9cc6310)
+ QPaintDevice (0x0x7f21a9c9c540) 16
+ vptr=((& QAbstractSpinBox::_ZTV16QAbstractSpinBox) + 488u)
+
+Class QAbstractSlider::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractSlider::QPrivateSignal (0x0x7f21a9c9c840) 0 empty
+
+Vtable for QAbstractSlider
+QAbstractSlider::_ZTV15QAbstractSlider: 65u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QAbstractSlider)
+16 (int (*)(...))QAbstractSlider::metaObject
+24 (int (*)(...))QAbstractSlider::qt_metacast
+32 (int (*)(...))QAbstractSlider::qt_metacall
+40 (int (*)(...))QAbstractSlider::~QAbstractSlider
+48 (int (*)(...))QAbstractSlider::~QAbstractSlider
+56 (int (*)(...))QAbstractSlider::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractSlider::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QAbstractSlider::wheelEvent
+208 (int (*)(...))QAbstractSlider::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractSlider::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QAbstractSlider::sliderChange
+440 (int (*)(...))-16
+448 (int (*)(...))(& _ZTI15QAbstractSlider)
+456 (int (*)(...))QAbstractSlider::_ZThn16_N15QAbstractSliderD1Ev
+464 (int (*)(...))QAbstractSlider::_ZThn16_N15QAbstractSliderD0Ev
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QAbstractSlider
+ size=48 align=8
+ base size=48 base align=8
+QAbstractSlider (0x0x7f21a9c9e618) 0
+ vptr=((& QAbstractSlider::_ZTV15QAbstractSlider) + 16u)
+ QWidget (0x0x7f21a9d01d20) 0
+ primary-for QAbstractSlider (0x0x7f21a9c9e618)
+ QObject (0x0x7f21a9c9c780) 0
+ primary-for QWidget (0x0x7f21a9d01d20)
+ QPaintDevice (0x0x7f21a9c9c7e0) 16
+ vptr=((& QAbstractSlider::_ZTV15QAbstractSlider) + 456u)
+
+Class QSlider::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSlider::QPrivateSignal (0x0x7f21a9c9c960) 0 empty
+
+Vtable for QSlider
+QSlider::_ZTV7QSlider: 65u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QSlider)
+16 (int (*)(...))QSlider::metaObject
+24 (int (*)(...))QSlider::qt_metacast
+32 (int (*)(...))QSlider::qt_metacall
+40 (int (*)(...))QSlider::~QSlider
+48 (int (*)(...))QSlider::~QSlider
+56 (int (*)(...))QSlider::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractSlider::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QSlider::sizeHint
+136 (int (*)(...))QSlider::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QSlider::mousePressEvent
+176 (int (*)(...))QSlider::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QSlider::mouseMoveEvent
+200 (int (*)(...))QAbstractSlider::wheelEvent
+208 (int (*)(...))QAbstractSlider::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QSlider::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractSlider::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QAbstractSlider::sliderChange
+440 (int (*)(...))-16
+448 (int (*)(...))(& _ZTI7QSlider)
+456 (int (*)(...))QSlider::_ZThn16_N7QSliderD1Ev
+464 (int (*)(...))QSlider::_ZThn16_N7QSliderD0Ev
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QSlider
+ size=48 align=8
+ base size=48 base align=8
+QSlider (0x0x7f21a9c9e680) 0
+ vptr=((& QSlider::_ZTV7QSlider) + 16u)
+ QAbstractSlider (0x0x7f21a9c9e6e8) 0
+ primary-for QSlider (0x0x7f21a9c9e680)
+ QWidget (0x0x7f21a9928770) 0
+ primary-for QAbstractSlider (0x0x7f21a9c9e6e8)
+ QObject (0x0x7f21a9c9c8a0) 0
+ primary-for QWidget (0x0x7f21a9928770)
+ QPaintDevice (0x0x7f21a9c9c900) 16
+ vptr=((& QSlider::_ZTV7QSlider) + 456u)
+
+Class QStyle::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QStyle::QPrivateSignal (0x0x7f21a9c9ca20) 0 empty
+
+Vtable for QStyle
+QStyle::_ZTV6QStyle: 37u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QStyle)
+16 (int (*)(...))QStyle::metaObject
+24 (int (*)(...))QStyle::qt_metacast
+32 (int (*)(...))QStyle::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QStyle::polish
+120 (int (*)(...))QStyle::unpolish
+128 (int (*)(...))QStyle::polish
+136 (int (*)(...))QStyle::unpolish
+144 (int (*)(...))QStyle::polish
+152 (int (*)(...))QStyle::itemTextRect
+160 (int (*)(...))QStyle::itemPixmapRect
+168 (int (*)(...))QStyle::drawItemText
+176 (int (*)(...))QStyle::drawItemPixmap
+184 (int (*)(...))QStyle::standardPalette
+192 (int (*)(...))__cxa_pure_virtual
+200 (int (*)(...))__cxa_pure_virtual
+208 (int (*)(...))__cxa_pure_virtual
+216 (int (*)(...))__cxa_pure_virtual
+224 (int (*)(...))__cxa_pure_virtual
+232 (int (*)(...))__cxa_pure_virtual
+240 (int (*)(...))__cxa_pure_virtual
+248 (int (*)(...))__cxa_pure_virtual
+256 (int (*)(...))__cxa_pure_virtual
+264 (int (*)(...))__cxa_pure_virtual
+272 (int (*)(...))__cxa_pure_virtual
+280 (int (*)(...))__cxa_pure_virtual
+288 (int (*)(...))__cxa_pure_virtual
+
+Class QStyle
+ size=16 align=8
+ base size=16 base align=8
+QStyle (0x0x7f21a9c9e7b8) 0
+ vptr=((& QStyle::_ZTV6QStyle) + 16u)
+ QObject (0x0x7f21a9c9c9c0) 0
+ primary-for QStyle (0x0x7f21a9c9e7b8)
+
+Class QTabBar::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTabBar::QPrivateSignal (0x0x7f21a9c9ce40) 0 empty
+
+Vtable for QTabBar
+QTabBar::_ZTV7QTabBar: 69u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QTabBar)
+16 (int (*)(...))QTabBar::metaObject
+24 (int (*)(...))QTabBar::qt_metacast
+32 (int (*)(...))QTabBar::qt_metacall
+40 (int (*)(...))QTabBar::~QTabBar
+48 (int (*)(...))QTabBar::~QTabBar
+56 (int (*)(...))QTabBar::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QTabBar::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QTabBar::sizeHint
+136 (int (*)(...))QTabBar::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QTabBar::mousePressEvent
+176 (int (*)(...))QTabBar::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QTabBar::mouseMoveEvent
+200 (int (*)(...))QTabBar::wheelEvent
+208 (int (*)(...))QTabBar::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QTabBar::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QTabBar::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QTabBar::showEvent
+352 (int (*)(...))QTabBar::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QTabBar::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QTabBar::tabSizeHint
+440 (int (*)(...))QTabBar::minimumTabSizeHint
+448 (int (*)(...))QTabBar::tabInserted
+456 (int (*)(...))QTabBar::tabRemoved
+464 (int (*)(...))QTabBar::tabLayoutChange
+472 (int (*)(...))-16
+480 (int (*)(...))(& _ZTI7QTabBar)
+488 (int (*)(...))QTabBar::_ZThn16_N7QTabBarD1Ev
+496 (int (*)(...))QTabBar::_ZThn16_N7QTabBarD0Ev
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QTabBar
+ size=48 align=8
+ base size=48 base align=8
+QTabBar (0x0x7f21a9c9e9c0) 0
+ vptr=((& QTabBar::_ZTV7QTabBar) + 16u)
+ QWidget (0x0x7f21a99facb0) 0
+ primary-for QTabBar (0x0x7f21a9c9e9c0)
+ QObject (0x0x7f21a9c9cd80) 0
+ primary-for QWidget (0x0x7f21a99facb0)
+ QPaintDevice (0x0x7f21a9c9cde0) 16
+ vptr=((& QTabBar::_ZTV7QTabBar) + 488u)
+
+Class QTabWidget::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTabWidget::QPrivateSignal (0x0x7f21a9c9cf60) 0 empty
+
+Vtable for QTabWidget
+QTabWidget::_ZTV10QTabWidget: 66u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTabWidget)
+16 (int (*)(...))QTabWidget::metaObject
+24 (int (*)(...))QTabWidget::qt_metacast
+32 (int (*)(...))QTabWidget::qt_metacall
+40 (int (*)(...))QTabWidget::~QTabWidget
+48 (int (*)(...))QTabWidget::~QTabWidget
+56 (int (*)(...))QTabWidget::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QTabWidget::sizeHint
+136 (int (*)(...))QTabWidget::minimumSizeHint
+144 (int (*)(...))QTabWidget::heightForWidth
+152 (int (*)(...))QTabWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QTabWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QTabWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QTabWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QTabWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QTabWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QTabWidget::tabInserted
+440 (int (*)(...))QTabWidget::tabRemoved
+448 (int (*)(...))-16
+456 (int (*)(...))(& _ZTI10QTabWidget)
+464 (int (*)(...))QTabWidget::_ZThn16_N10QTabWidgetD1Ev
+472 (int (*)(...))QTabWidget::_ZThn16_N10QTabWidgetD0Ev
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QTabWidget
+ size=48 align=8
+ base size=48 base align=8
+QTabWidget (0x0x7f21a9c9ea28) 0
+ vptr=((& QTabWidget::_ZTV10QTabWidget) + 16u)
+ QWidget (0x0x7f21a9a21930) 0
+ primary-for QTabWidget (0x0x7f21a9c9ea28)
+ QObject (0x0x7f21a9c9cea0) 0
+ primary-for QWidget (0x0x7f21a9a21930)
+ QPaintDevice (0x0x7f21a9c9cf00) 16
+ vptr=((& QTabWidget::_ZTV10QTabWidget) + 464u)
+
+Class QRubberBand::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QRubberBand::QPrivateSignal (0x0x7f21a9a710c0) 0 empty
+
+Vtable for QRubberBand
+QRubberBand::_ZTV11QRubberBand: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QRubberBand)
+16 (int (*)(...))QRubberBand::metaObject
+24 (int (*)(...))QRubberBand::qt_metacast
+32 (int (*)(...))QRubberBand::qt_metacall
+40 (int (*)(...))QRubberBand::~QRubberBand
+48 (int (*)(...))QRubberBand::~QRubberBand
+56 (int (*)(...))QRubberBand::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QRubberBand::paintEvent
+264 (int (*)(...))QRubberBand::moveEvent
+272 (int (*)(...))QRubberBand::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QRubberBand::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QRubberBand::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI11QRubberBand)
+448 (int (*)(...))QRubberBand::_ZThn16_N11QRubberBandD1Ev
+456 (int (*)(...))QRubberBand::_ZThn16_N11QRubberBandD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QRubberBand
+ size=48 align=8
+ base size=48 base align=8
+QRubberBand (0x0x7f21a9c9ea90) 0
+ vptr=((& QRubberBand::_ZTV11QRubberBand) + 16u)
+ QWidget (0x0x7f21a9a6b4d0) 0
+ primary-for QRubberBand (0x0x7f21a9c9ea90)
+ QObject (0x0x7f21a9a71000) 0
+ primary-for QWidget (0x0x7f21a9a6b4d0)
+ QPaintDevice (0x0x7f21a9a71060) 16
+ vptr=((& QRubberBand::_ZTV11QRubberBand) + 448u)
+
+Class QFrame::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFrame::QPrivateSignal (0x0x7f21a9a711e0) 0 empty
+
+Vtable for QFrame
+QFrame::_ZTV6QFrame: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QFrame)
+16 (int (*)(...))QFrame::metaObject
+24 (int (*)(...))QFrame::qt_metacast
+32 (int (*)(...))QFrame::qt_metacall
+40 (int (*)(...))QFrame::~QFrame
+48 (int (*)(...))QFrame::~QFrame
+56 (int (*)(...))QFrame::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QFrame::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QFrame::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI6QFrame)
+448 (int (*)(...))QFrame::_ZThn16_N6QFrameD1Ev
+456 (int (*)(...))QFrame::_ZThn16_N6QFrameD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QFrame
+ size=48 align=8
+ base size=48 base align=8
+QFrame (0x0x7f21a9c9eaf8) 0
+ vptr=((& QFrame::_ZTV6QFrame) + 16u)
+ QWidget (0x0x7f21a9a6bee0) 0
+ primary-for QFrame (0x0x7f21a9c9eaf8)
+ QObject (0x0x7f21a9a71120) 0
+ primary-for QWidget (0x0x7f21a9a6bee0)
+ QPaintDevice (0x0x7f21a9a71180) 16
+ vptr=((& QFrame::_ZTV6QFrame) + 448u)
+
+Class QStyleOption
+ size=64 align=8
+ base size=64 base align=8
+QStyleOption (0x0x7f21a9a71240) 0
+
+Class QStyleOptionFocusRect
+ size=80 align=8
+ base size=80 base align=8
+QStyleOptionFocusRect (0x0x7f21a9c9eb60) 0
+ QStyleOption (0x0x7f21a9a712a0) 0
+
+Class QStyleOptionFrame
+ size=80 align=8
+ base size=80 base align=8
+QStyleOptionFrame (0x0x7f21a9c9ebc8) 0
+ QStyleOption (0x0x7f21a9a71300) 0
+
+Class QStyleOptionTabWidgetFrame
+ size=136 align=8
+ base size=132 base align=8
+QStyleOptionTabWidgetFrame (0x0x7f21a9c9ed00) 0
+ QStyleOption (0x0x7f21a9a714e0) 0
+
+Class QStyleOptionTabBarBase
+ size=104 align=8
+ base size=101 base align=8
+QStyleOptionTabBarBase (0x0x7f21a9c9ed68) 0
+ QStyleOption (0x0x7f21a9a71540) 0
+
+Class QStyleOptionHeader
+ size=120 align=8
+ base size=116 base align=8
+QStyleOptionHeader (0x0x7f21a9c9edd0) 0
+ QStyleOption (0x0x7f21a9a71600) 0
+
+Class QStyleOptionButton
+ size=96 align=8
+ base size=96 base align=8
+QStyleOptionButton (0x0x7f21a9c9ee38) 0
+ QStyleOption (0x0x7f21a9a71660) 0
+
+Class QStyleOptionTab
+ size=136 align=8
+ base size=136 base align=8
+QStyleOptionTab (0x0x7f21b5a2a208) 0
+ QStyleOption (0x0x7f21bb49d600) 0
+
+Class QStyleOptionToolBar
+ size=88 align=8
+ base size=88 base align=8
+QStyleOptionToolBar (0x0x7f21b5a2a888) 0
+ QStyleOption (0x0x7f21b6057180) 0
+
+Class QStyleOptionProgressBar
+ size=104 align=8
+ base size=102 base align=8
+QStyleOptionProgressBar (0x0x7f21b56328f0) 0
+ QStyleOption (0x0x7f21b3d82300) 0
+
+Class QStyleOptionMenuItem
+ size=136 align=8
+ base size=136 base align=8
+QStyleOptionMenuItem (0x0x7f21b5632958) 0
+ QStyleOption (0x0x7f21b3d82360) 0
+
+Class QStyleOptionDockWidget
+ size=80 align=8
+ base size=76 base align=8
+QStyleOptionDockWidget (0x0x7f21b48317b8) 0
+ QStyleOption (0x0x7f21b3d82660) 0
+
+Class QStyleOptionViewItem
+ size=192 align=8
+ base size=192 base align=8
+QStyleOptionViewItem (0x0x7f21b4831888) 0
+ QStyleOption (0x0x7f21b3d826c0) 0
+
+Class QStyleOptionToolBox
+ size=88 align=8
+ base size=88 base align=8
+QStyleOptionToolBox (0x0x7f21b48319c0) 0
+ QStyleOption (0x0x7f21b3a3ac00) 0
+
+Class QStyleOptionRubberBand
+ size=72 align=8
+ base size=69 base align=8
+QStyleOptionRubberBand (0x0x7f21b4831a28) 0
+ QStyleOption (0x0x7f21b3a3ac60) 0
+
+Class QStyleOptionComplex
+ size=72 align=8
+ base size=72 base align=8
+QStyleOptionComplex (0x0x7f21b4831d00) 0
+ QStyleOption (0x0x7f21b3a3ad20) 0
+
+Class QStyleOptionSlider
+ size=128 align=8
+ base size=121 base align=8
+QStyleOptionSlider (0x0x7f21b3c684e0) 0
+ QStyleOptionComplex (0x0x7f21b3c68548) 0
+ QStyleOption (0x0x7f21b3a3ade0) 0
+
+Class QStyleOptionSpinBox
+ size=88 align=8
+ base size=81 base align=8
+QStyleOptionSpinBox (0x0x7f21b3a335b0) 0
+ QStyleOptionComplex (0x0x7f21b3a33618) 0
+ QStyleOption (0x0x7f21b3620240) 0
+
+Class QStyleOptionToolButton
+ size=136 align=8
+ base size=136 base align=8
+QStyleOptionToolButton (0x0x7f21b3a33bc8) 0
+ QStyleOptionComplex (0x0x7f21b3a33c30) 0
+ QStyleOption (0x0x7f21b36202a0) 0
+
+Class QStyleOptionComboBox
+ size=120 align=8
+ base size=120 base align=8
+QStyleOptionComboBox (0x0x7f21b3634410) 0
+ QStyleOptionComplex (0x0x7f21b3634478) 0
+ QStyleOption (0x0x7f21b3649060) 0
+
+Class QStyleOptionTitleBar
+ size=96 align=8
+ base size=96 base align=8
+QStyleOptionTitleBar (0x0x7f21b3634bc8) 0
+ QStyleOptionComplex (0x0x7f21b3634c30) 0
+ QStyleOption (0x0x7f21b36490c0) 0
+
+Class QStyleOptionGroupBox
+ size=120 align=8
+ base size=116 base align=8
+QStyleOptionGroupBox (0x0x7f21b36560d0) 0
+ QStyleOptionComplex (0x0x7f21b3656138) 0
+ QStyleOption (0x0x7f21b3649900) 0
+
+Class QStyleOptionSizeGrip
+ size=80 align=8
+ base size=76 base align=8
+QStyleOptionSizeGrip (0x0x7f21b37e8000) 0
+ QStyleOptionComplex (0x0x7f21b37e8dd0) 0
+ QStyleOption (0x0x7f21b376ec00) 0
+
+Class QStyleOptionGraphicsItem
+ size=152 align=8
+ base size=152 base align=8
+QStyleOptionGraphicsItem (0x0x7f21b37e8e38) 0
+ QStyleOption (0x0x7f21b376ec60) 0
+
+Class QStyleHintReturn
+ size=8 align=4
+ base size=8 base align=4
+QStyleHintReturn (0x0x7f21b3464b40) 0
+
+Class QStyleHintReturnMask
+ size=16 align=8
+ base size=16 base align=8
+QStyleHintReturnMask (0x0x7f21b3483410) 0
+ QStyleHintReturn (0x0x7f21b3464c00) 0
+
+Class QStyleHintReturnVariant
+ size=24 align=8
+ base size=24 base align=8
+QStyleHintReturnVariant (0x0x7f21b3483478) 0
+ QStyleHintReturn (0x0x7f21b3464c60) 0
+
+Class QAbstractItemDelegate::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractItemDelegate::QPrivateSignal (0x0x7f21b2e541e0) 0 empty
+
+Vtable for QAbstractItemDelegate
+QAbstractItemDelegate::_ZTV21QAbstractItemDelegate: 24u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QAbstractItemDelegate)
+16 (int (*)(...))QAbstractItemDelegate::metaObject
+24 (int (*)(...))QAbstractItemDelegate::qt_metacast
+32 (int (*)(...))QAbstractItemDelegate::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))QAbstractItemDelegate::createEditor
+136 (int (*)(...))QAbstractItemDelegate::destroyEditor
+144 (int (*)(...))QAbstractItemDelegate::setEditorData
+152 (int (*)(...))QAbstractItemDelegate::setModelData
+160 (int (*)(...))QAbstractItemDelegate::updateEditorGeometry
+168 (int (*)(...))QAbstractItemDelegate::editorEvent
+176 (int (*)(...))QAbstractItemDelegate::helpEvent
+184 (int (*)(...))QAbstractItemDelegate::paintingRoles
+
+Class QAbstractItemDelegate
+ size=16 align=8
+ base size=16 base align=8
+QAbstractItemDelegate (0x0x7f21b3483e38) 0
+ vptr=((& QAbstractItemDelegate::_ZTV21QAbstractItemDelegate) + 16u)
+ QObject (0x0x7f21b2e2d660) 0
+ primary-for QAbstractItemDelegate (0x0x7f21b3483e38)
+
+Class QAbstractScrollArea::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractScrollArea::QPrivateSignal (0x0x7f21b2e54c60) 0 empty
+
+Vtable for QAbstractScrollArea
+QAbstractScrollArea::_ZTV19QAbstractScrollArea: 68u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QAbstractScrollArea)
+16 (int (*)(...))QAbstractScrollArea::metaObject
+24 (int (*)(...))QAbstractScrollArea::qt_metacast
+32 (int (*)(...))QAbstractScrollArea::qt_metacall
+40 (int (*)(...))QAbstractScrollArea::~QAbstractScrollArea
+48 (int (*)(...))QAbstractScrollArea::~QAbstractScrollArea
+56 (int (*)(...))QAbstractScrollArea::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractScrollArea::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractScrollArea::mousePressEvent
+176 (int (*)(...))QAbstractScrollArea::mouseReleaseEvent
+184 (int (*)(...))QAbstractScrollArea::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractScrollArea::mouseMoveEvent
+200 (int (*)(...))QAbstractScrollArea::wheelEvent
+208 (int (*)(...))QAbstractScrollArea::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QAbstractScrollArea::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QAbstractScrollArea::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QAbstractScrollArea::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QAbstractScrollArea::dragEnterEvent
+320 (int (*)(...))QAbstractScrollArea::dragMoveEvent
+328 (int (*)(...))QAbstractScrollArea::dragLeaveEvent
+336 (int (*)(...))QAbstractScrollArea::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QAbstractScrollArea::viewportEvent
+448 (int (*)(...))QAbstractScrollArea::scrollContentsBy
+456 (int (*)(...))QAbstractScrollArea::viewportSizeHint
+464 (int (*)(...))-16
+472 (int (*)(...))(& _ZTI19QAbstractScrollArea)
+480 (int (*)(...))QAbstractScrollArea::_ZThn16_N19QAbstractScrollAreaD1Ev
+488 (int (*)(...))QAbstractScrollArea::_ZThn16_N19QAbstractScrollAreaD0Ev
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QAbstractScrollArea
+ size=48 align=8
+ base size=48 base align=8
+QAbstractScrollArea (0x0x7f21b3483ea0) 0
+ vptr=((& QAbstractScrollArea::_ZTV19QAbstractScrollArea) + 16u)
+ QFrame (0x0x7f21b3483f08) 0
+ primary-for QAbstractScrollArea (0x0x7f21b3483ea0)
+ QWidget (0x0x7f21b6587bd0) 0
+ primary-for QFrame (0x0x7f21b3483f08)
+ QObject (0x0x7f21b2e54b40) 0
+ primary-for QWidget (0x0x7f21b6587bd0)
+ QPaintDevice (0x0x7f21b2e54ba0) 16
+ vptr=((& QAbstractScrollArea::_ZTV19QAbstractScrollArea) + 480u)
+
+Class QAbstractItemView::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAbstractItemView::QPrivateSignal (0x0x7f21b2e74540) 0 empty
+
+Vtable for QAbstractItemView
+QAbstractItemView::_ZTV17QAbstractItemView: 106u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QAbstractItemView)
+16 (int (*)(...))QAbstractItemView::metaObject
+24 (int (*)(...))QAbstractItemView::qt_metacast
+32 (int (*)(...))QAbstractItemView::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QAbstractItemView::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QAbstractItemView::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractScrollArea::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractItemView::mousePressEvent
+176 (int (*)(...))QAbstractItemView::mouseReleaseEvent
+184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractItemView::mouseMoveEvent
+200 (int (*)(...))QAbstractScrollArea::wheelEvent
+208 (int (*)(...))QAbstractItemView::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QAbstractItemView::focusInEvent
+232 (int (*)(...))QAbstractItemView::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QAbstractScrollArea::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QAbstractItemView::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QAbstractScrollArea::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QAbstractItemView::dragEnterEvent
+320 (int (*)(...))QAbstractItemView::dragMoveEvent
+328 (int (*)(...))QAbstractItemView::dragLeaveEvent
+336 (int (*)(...))QAbstractItemView::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QAbstractItemView::inputMethodEvent
+416 (int (*)(...))QAbstractItemView::inputMethodQuery
+424 (int (*)(...))QAbstractItemView::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QAbstractItemView::viewportEvent
+448 (int (*)(...))QAbstractScrollArea::scrollContentsBy
+456 (int (*)(...))QAbstractItemView::viewportSizeHint
+464 (int (*)(...))QAbstractItemView::setModel
+472 (int (*)(...))QAbstractItemView::setSelectionModel
+480 (int (*)(...))QAbstractItemView::keyboardSearch
+488 (int (*)(...))__cxa_pure_virtual
+496 (int (*)(...))__cxa_pure_virtual
+504 (int (*)(...))__cxa_pure_virtual
+512 (int (*)(...))QAbstractItemView::sizeHintForRow
+520 (int (*)(...))QAbstractItemView::sizeHintForColumn
+528 (int (*)(...))QAbstractItemView::reset
+536 (int (*)(...))QAbstractItemView::setRootIndex
+544 (int (*)(...))QAbstractItemView::doItemsLayout
+552 (int (*)(...))QAbstractItemView::selectAll
+560 (int (*)(...))QAbstractItemView::dataChanged
+568 (int (*)(...))QAbstractItemView::rowsInserted
+576 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved
+584 (int (*)(...))QAbstractItemView::selectionChanged
+592 (int (*)(...))QAbstractItemView::currentChanged
+600 (int (*)(...))QAbstractItemView::updateEditorData
+608 (int (*)(...))QAbstractItemView::updateEditorGeometries
+616 (int (*)(...))QAbstractItemView::updateGeometries
+624 (int (*)(...))QAbstractItemView::verticalScrollbarAction
+632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction
+640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged
+648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged
+656 (int (*)(...))QAbstractItemView::closeEditor
+664 (int (*)(...))QAbstractItemView::commitData
+672 (int (*)(...))QAbstractItemView::editorDestroyed
+680 (int (*)(...))__cxa_pure_virtual
+688 (int (*)(...))__cxa_pure_virtual
+696 (int (*)(...))__cxa_pure_virtual
+704 (int (*)(...))__cxa_pure_virtual
+712 (int (*)(...))__cxa_pure_virtual
+720 (int (*)(...))__cxa_pure_virtual
+728 (int (*)(...))QAbstractItemView::selectedIndexes
+736 (int (*)(...))QAbstractItemView::edit
+744 (int (*)(...))QAbstractItemView::selectionCommand
+752 (int (*)(...))QAbstractItemView::startDrag
+760 (int (*)(...))QAbstractItemView::viewOptions
+768 (int (*)(...))-16
+776 (int (*)(...))(& _ZTI17QAbstractItemView)
+784 0u
+792 0u
+800 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+808 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+816 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+832 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+840 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QAbstractItemView
+ size=48 align=8
+ base size=48 base align=8
+QAbstractItemView (0x0x7f21b3483f70) 0
+ vptr=((& QAbstractItemView::_ZTV17QAbstractItemView) + 16u)
+ QAbstractScrollArea (0x0x7f21b3323e38) 0
+ primary-for QAbstractItemView (0x0x7f21b3483f70)
+ QFrame (0x0x7f21b3323ea0) 0
+ primary-for QAbstractScrollArea (0x0x7f21b3323e38)
+ QWidget (0x0x7f21b658e7e0) 0
+ primary-for QFrame (0x0x7f21b3323ea0)
+ QObject (0x0x7f21b2e74420) 0
+ primary-for QWidget (0x0x7f21b658e7e0)
+ QPaintDevice (0x0x7f21b2e74480) 16
+ vptr=((& QAbstractItemView::_ZTV17QAbstractItemView) + 784u)
+
+Vtable for QAccessibleWidget
+QAccessibleWidget::_ZTV17QAccessibleWidget: 35u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QAccessibleWidget)
+16 (int (*)(...))QAccessibleWidget::~QAccessibleWidget
+24 (int (*)(...))QAccessibleWidget::~QAccessibleWidget
+32 (int (*)(...))QAccessibleWidget::isValid
+40 (int (*)(...))QAccessibleObject::object
+48 (int (*)(...))QAccessibleWidget::window
+56 (int (*)(...))QAccessibleWidget::relations
+64 (int (*)(...))QAccessibleWidget::focusChild
+72 (int (*)(...))QAccessibleObject::childAt
+80 (int (*)(...))QAccessibleWidget::parent
+88 (int (*)(...))QAccessibleWidget::child
+96 (int (*)(...))QAccessibleWidget::childCount
+104 (int (*)(...))QAccessibleWidget::indexOfChild
+112 (int (*)(...))QAccessibleWidget::text
+120 (int (*)(...))QAccessibleObject::setText
+128 (int (*)(...))QAccessibleWidget::rect
+136 (int (*)(...))QAccessibleWidget::role
+144 (int (*)(...))QAccessibleWidget::state
+152 (int (*)(...))QAccessibleWidget::foregroundColor
+160 (int (*)(...))QAccessibleWidget::backgroundColor
+168 (int (*)(...))QAccessibleInterface::virtual_hook
+176 (int (*)(...))QAccessibleWidget::interface_cast
+184 (int (*)(...))QAccessibleWidget::actionNames
+192 (int (*)(...))QAccessibleWidget::doAction
+200 (int (*)(...))QAccessibleWidget::keyBindingsForAction
+208 (int (*)(...))-16
+216 (int (*)(...))(& _ZTI17QAccessibleWidget)
+224 (int (*)(...))QAccessibleWidget::_ZThn16_N17QAccessibleWidgetD1Ev
+232 (int (*)(...))QAccessibleWidget::_ZThn16_N17QAccessibleWidgetD0Ev
+240 (int (*)(...))QAccessibleWidget::_ZThn16_NK17QAccessibleWidget11actionNamesEv
+248 (int (*)(...))QAccessibleActionInterface::localizedActionName
+256 (int (*)(...))QAccessibleActionInterface::localizedActionDescription
+264 (int (*)(...))QAccessibleWidget::_ZThn16_N17QAccessibleWidget8doActionERK7QString
+272 (int (*)(...))QAccessibleWidget::_ZThn16_NK17QAccessibleWidget20keyBindingsForActionERK7QString
+
+Class QAccessibleWidget
+ size=32 align=8
+ base size=32 base align=8
+QAccessibleWidget (0x0x7f21b65d9770) 0
+ vptr=((& QAccessibleWidget::_ZTV17QAccessibleWidget) + 16u)
+ QAccessibleObject (0x0x7f21b3075068) 0
+ primary-for QAccessibleWidget (0x0x7f21b65d9770)
+ QAccessibleInterface (0x0x7f21b2fd0480) 0 nearly-empty
+ primary-for QAccessibleObject (0x0x7f21b3075068)
+ QAccessibleActionInterface (0x0x7f21b2fd0540) 16 nearly-empty
+ vptr=((& QAccessibleWidget::_ZTV17QAccessibleWidget) + 224u)
+
+Class QAction::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QAction::QPrivateSignal (0x0x7f21b271e9c0) 0 empty
+
+Vtable for QAction
+QAction::_ZTV7QAction: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QAction)
+16 (int (*)(...))QAction::metaObject
+24 (int (*)(...))QAction::qt_metacast
+32 (int (*)(...))QAction::qt_metacall
+40 (int (*)(...))QAction::~QAction
+48 (int (*)(...))QAction::~QAction
+56 (int (*)(...))QAction::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QAction
+ size=16 align=8
+ base size=16 base align=8
+QAction (0x0x7f21b30750d0) 0
+ vptr=((& QAction::_ZTV7QAction) + 16u)
+ QObject (0x0x7f21b271e5a0) 0
+ primary-for QAction (0x0x7f21b30750d0)
+
+Class QActionGroup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QActionGroup::QPrivateSignal (0x0x7f21b271ed20) 0 empty
+
+Vtable for QActionGroup
+QActionGroup::_ZTV12QActionGroup: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QActionGroup)
+16 (int (*)(...))QActionGroup::metaObject
+24 (int (*)(...))QActionGroup::qt_metacast
+32 (int (*)(...))QActionGroup::qt_metacall
+40 (int (*)(...))QActionGroup::~QActionGroup
+48 (int (*)(...))QActionGroup::~QActionGroup
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QActionGroup
+ size=16 align=8
+ base size=16 base align=8
+QActionGroup (0x0x7f21b3075138) 0
+ vptr=((& QActionGroup::_ZTV12QActionGroup) + 16u)
+ QObject (0x0x7f21b271ea20) 0
+ primary-for QActionGroup (0x0x7f21b3075138)
+
+Class QApplication::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QApplication::QPrivateSignal (0x0x7f21b271ef00) 0 empty
+
+Vtable for QApplication
+QApplication::_ZTV12QApplication: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QApplication)
+16 (int (*)(...))QApplication::metaObject
+24 (int (*)(...))QApplication::qt_metacast
+32 (int (*)(...))QApplication::qt_metacall
+40 (int (*)(...))QApplication::~QApplication
+48 (int (*)(...))QApplication::~QApplication
+56 (int (*)(...))QApplication::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QApplication::notify
+120 (int (*)(...))QApplication::compressEvent
+
+Class QApplication
+ size=16 align=8
+ base size=16 base align=8
+QApplication (0x0x7f21b30751a0) 0
+ vptr=((& QApplication::_ZTV12QApplication) + 16u)
+ QGuiApplication (0x0x7f21b3075478) 0
+ primary-for QApplication (0x0x7f21b30751a0)
+ QCoreApplication (0x0x7f21b30754e0) 0
+ primary-for QGuiApplication (0x0x7f21b3075478)
+ QObject (0x0x7f21b271ed80) 0
+ primary-for QCoreApplication (0x0x7f21b30754e0)
+
+Vtable for QLayoutItem
+QLayoutItem::_ZTV11QLayoutItem: 19u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QLayoutItem)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))__cxa_pure_virtual
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))__cxa_pure_virtual
+72 (int (*)(...))__cxa_pure_virtual
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))QLayoutItem::hasHeightForWidth
+96 (int (*)(...))QLayoutItem::heightForWidth
+104 (int (*)(...))QLayoutItem::minimumHeightForWidth
+112 (int (*)(...))QLayoutItem::invalidate
+120 (int (*)(...))QLayoutItem::widget
+128 (int (*)(...))QLayoutItem::layout
+136 (int (*)(...))QLayoutItem::spacerItem
+144 (int (*)(...))QLayoutItem::controlTypes
+
+Class QLayoutItem
+ size=16 align=8
+ base size=12 base align=8
+QLayoutItem (0x0x7f21b271ef60) 0
+ vptr=((& QLayoutItem::_ZTV11QLayoutItem) + 16u)
+
+Vtable for QSpacerItem
+QSpacerItem::_ZTV11QSpacerItem: 19u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QSpacerItem)
+16 (int (*)(...))QSpacerItem::~QSpacerItem
+24 (int (*)(...))QSpacerItem::~QSpacerItem
+32 (int (*)(...))QSpacerItem::sizeHint
+40 (int (*)(...))QSpacerItem::minimumSize
+48 (int (*)(...))QSpacerItem::maximumSize
+56 (int (*)(...))QSpacerItem::expandingDirections
+64 (int (*)(...))QSpacerItem::setGeometry
+72 (int (*)(...))QSpacerItem::geometry
+80 (int (*)(...))QSpacerItem::isEmpty
+88 (int (*)(...))QLayoutItem::hasHeightForWidth
+96 (int (*)(...))QLayoutItem::heightForWidth
+104 (int (*)(...))QLayoutItem::minimumHeightForWidth
+112 (int (*)(...))QLayoutItem::invalidate
+120 (int (*)(...))QLayoutItem::widget
+128 (int (*)(...))QLayoutItem::layout
+136 (int (*)(...))QSpacerItem::spacerItem
+144 (int (*)(...))QLayoutItem::controlTypes
+
+Class QSpacerItem
+ size=40 align=8
+ base size=40 base align=8
+QSpacerItem (0x0x7f21b30756e8) 0
+ vptr=((& QSpacerItem::_ZTV11QSpacerItem) + 16u)
+ QLayoutItem (0x0x7f21b27a4060) 0
+ primary-for QSpacerItem (0x0x7f21b30756e8)
+
+Vtable for QWidgetItem
+QWidgetItem::_ZTV11QWidgetItem: 19u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QWidgetItem)
+16 (int (*)(...))QWidgetItem::~QWidgetItem
+24 (int (*)(...))QWidgetItem::~QWidgetItem
+32 (int (*)(...))QWidgetItem::sizeHint
+40 (int (*)(...))QWidgetItem::minimumSize
+48 (int (*)(...))QWidgetItem::maximumSize
+56 (int (*)(...))QWidgetItem::expandingDirections
+64 (int (*)(...))QWidgetItem::setGeometry
+72 (int (*)(...))QWidgetItem::geometry
+80 (int (*)(...))QWidgetItem::isEmpty
+88 (int (*)(...))QWidgetItem::hasHeightForWidth
+96 (int (*)(...))QWidgetItem::heightForWidth
+104 (int (*)(...))QLayoutItem::minimumHeightForWidth
+112 (int (*)(...))QLayoutItem::invalidate
+120 (int (*)(...))QWidgetItem::widget
+128 (int (*)(...))QLayoutItem::layout
+136 (int (*)(...))QLayoutItem::spacerItem
+144 (int (*)(...))QWidgetItem::controlTypes
+
+Class QWidgetItem
+ size=24 align=8
+ base size=24 base align=8
+QWidgetItem (0x0x7f21b3075750) 0
+ vptr=((& QWidgetItem::_ZTV11QWidgetItem) + 16u)
+ QLayoutItem (0x0x7f21b27a4120) 0
+ primary-for QWidgetItem (0x0x7f21b3075750)
+
+Vtable for QWidgetItemV2
+QWidgetItemV2::_ZTV13QWidgetItemV2: 19u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QWidgetItemV2)
+16 (int (*)(...))QWidgetItemV2::~QWidgetItemV2
+24 (int (*)(...))QWidgetItemV2::~QWidgetItemV2
+32 (int (*)(...))QWidgetItemV2::sizeHint
+40 (int (*)(...))QWidgetItemV2::minimumSize
+48 (int (*)(...))QWidgetItemV2::maximumSize
+56 (int (*)(...))QWidgetItem::expandingDirections
+64 (int (*)(...))QWidgetItem::setGeometry
+72 (int (*)(...))QWidgetItem::geometry
+80 (int (*)(...))QWidgetItem::isEmpty
+88 (int (*)(...))QWidgetItem::hasHeightForWidth
+96 (int (*)(...))QWidgetItemV2::heightForWidth
+104 (int (*)(...))QLayoutItem::minimumHeightForWidth
+112 (int (*)(...))QLayoutItem::invalidate
+120 (int (*)(...))QWidgetItem::widget
+128 (int (*)(...))QLayoutItem::layout
+136 (int (*)(...))QLayoutItem::spacerItem
+144 (int (*)(...))QWidgetItem::controlTypes
+
+Class QWidgetItemV2
+ size=88 align=8
+ base size=88 base align=8
+QWidgetItemV2 (0x0x7f21b30757b8) 0
+ vptr=((& QWidgetItemV2::_ZTV13QWidgetItemV2) + 16u)
+ QWidgetItem (0x0x7f21b3075820) 0
+ primary-for QWidgetItemV2 (0x0x7f21b30757b8)
+ QLayoutItem (0x0x7f21b27a4180) 0
+ primary-for QWidgetItem (0x0x7f21b3075820)
+
+Class QLayout::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QLayout::QPrivateSignal (0x0x7f21b27c8960) 0 empty
+
+Vtable for QLayout
+QLayout::_ZTV7QLayout: 47u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QLayout)
+16 (int (*)(...))QLayout::metaObject
+24 (int (*)(...))QLayout::qt_metacast
+32 (int (*)(...))QLayout::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QLayout::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QLayout::invalidate
+120 (int (*)(...))QLayout::geometry
+128 (int (*)(...))__cxa_pure_virtual
+136 (int (*)(...))QLayout::expandingDirections
+144 (int (*)(...))QLayout::minimumSize
+152 (int (*)(...))QLayout::maximumSize
+160 (int (*)(...))QLayout::setGeometry
+168 (int (*)(...))__cxa_pure_virtual
+176 (int (*)(...))__cxa_pure_virtual
+184 (int (*)(...))QLayout::indexOf
+192 (int (*)(...))__cxa_pure_virtual
+200 (int (*)(...))QLayout::isEmpty
+208 (int (*)(...))QLayout::controlTypes
+216 (int (*)(...))QLayout::layout
+224 (int (*)(...))-16
+232 (int (*)(...))(& _ZTI7QLayout)
+240 0u
+248 0u
+256 (int (*)(...))__cxa_pure_virtual
+264 (int (*)(...))QLayout::_ZThn16_NK7QLayout11minimumSizeEv
+272 (int (*)(...))QLayout::_ZThn16_NK7QLayout11maximumSizeEv
+280 (int (*)(...))QLayout::_ZThn16_NK7QLayout19expandingDirectionsEv
+288 (int (*)(...))QLayout::_ZThn16_N7QLayout11setGeometryERK5QRect
+296 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv
+304 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv
+312 (int (*)(...))QLayoutItem::hasHeightForWidth
+320 (int (*)(...))QLayoutItem::heightForWidth
+328 (int (*)(...))QLayoutItem::minimumHeightForWidth
+336 (int (*)(...))QLayout::_ZThn16_N7QLayout10invalidateEv
+344 (int (*)(...))QLayoutItem::widget
+352 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv
+360 (int (*)(...))QLayoutItem::spacerItem
+368 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv
+
+Class QLayout
+ size=32 align=8
+ base size=28 base align=8
+QLayout (0x0x7f21b6612cb0) 0
+ vptr=((& QLayout::_ZTV7QLayout) + 16u)
+ QObject (0x0x7f21b27a4d20) 0
+ primary-for QLayout (0x0x7f21b6612cb0)
+ QLayoutItem (0x0x7f21b27a4d80) 16
+ vptr=((& QLayout::_ZTV7QLayout) + 240u)
+
+Class QGridLayout::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGridLayout::QPrivateSignal (0x0x7f21b27c8c60) 0 empty
+
+Vtable for QGridLayout
+QGridLayout::_ZTV11QGridLayout: 51u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QGridLayout)
+16 (int (*)(...))QGridLayout::metaObject
+24 (int (*)(...))QGridLayout::qt_metacast
+32 (int (*)(...))QGridLayout::qt_metacall
+40 (int (*)(...))QGridLayout::~QGridLayout
+48 (int (*)(...))QGridLayout::~QGridLayout
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QLayout::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGridLayout::invalidate
+120 (int (*)(...))QLayout::geometry
+128 (int (*)(...))QGridLayout::addItem
+136 (int (*)(...))QGridLayout::expandingDirections
+144 (int (*)(...))QGridLayout::minimumSize
+152 (int (*)(...))QGridLayout::maximumSize
+160 (int (*)(...))QGridLayout::setGeometry
+168 (int (*)(...))QGridLayout::itemAt
+176 (int (*)(...))QGridLayout::takeAt
+184 (int (*)(...))QLayout::indexOf
+192 (int (*)(...))QGridLayout::count
+200 (int (*)(...))QLayout::isEmpty
+208 (int (*)(...))QLayout::controlTypes
+216 (int (*)(...))QLayout::layout
+224 (int (*)(...))QGridLayout::sizeHint
+232 (int (*)(...))QGridLayout::hasHeightForWidth
+240 (int (*)(...))QGridLayout::heightForWidth
+248 (int (*)(...))QGridLayout::minimumHeightForWidth
+256 (int (*)(...))-16
+264 (int (*)(...))(& _ZTI11QGridLayout)
+272 (int (*)(...))QGridLayout::_ZThn16_N11QGridLayoutD1Ev
+280 (int (*)(...))QGridLayout::_ZThn16_N11QGridLayoutD0Ev
+288 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout8sizeHintEv
+296 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout11minimumSizeEv
+304 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout11maximumSizeEv
+312 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout19expandingDirectionsEv
+320 (int (*)(...))QGridLayout::_ZThn16_N11QGridLayout11setGeometryERK5QRect
+328 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv
+336 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv
+344 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout17hasHeightForWidthEv
+352 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout14heightForWidthEi
+360 (int (*)(...))QGridLayout::_ZThn16_NK11QGridLayout21minimumHeightForWidthEi
+368 (int (*)(...))QGridLayout::_ZThn16_N11QGridLayout10invalidateEv
+376 (int (*)(...))QLayoutItem::widget
+384 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv
+392 (int (*)(...))QLayoutItem::spacerItem
+400 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv
+
+Class QGridLayout
+ size=32 align=8
+ base size=28 base align=8
+QGridLayout (0x0x7f21b3144c30) 0
+ vptr=((& QGridLayout::_ZTV11QGridLayout) + 16u)
+ QLayout (0x0x7f21b661daf0) 0
+ primary-for QGridLayout (0x0x7f21b3144c30)
+ QObject (0x0x7f21b27c89c0) 0
+ primary-for QLayout (0x0x7f21b661daf0)
+ QLayoutItem (0x0x7f21b27c8c00) 16
+ vptr=((& QGridLayout::_ZTV11QGridLayout) + 272u)
+
+Class QBoxLayout::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QBoxLayout::QPrivateSignal (0x0x7f21b1c74120) 0 empty
+
+Vtable for QBoxLayout
+QBoxLayout::_ZTV10QBoxLayout: 51u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QBoxLayout)
+16 (int (*)(...))QBoxLayout::metaObject
+24 (int (*)(...))QBoxLayout::qt_metacast
+32 (int (*)(...))QBoxLayout::qt_metacall
+40 (int (*)(...))QBoxLayout::~QBoxLayout
+48 (int (*)(...))QBoxLayout::~QBoxLayout
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QLayout::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QBoxLayout::invalidate
+120 (int (*)(...))QLayout::geometry
+128 (int (*)(...))QBoxLayout::addItem
+136 (int (*)(...))QBoxLayout::expandingDirections
+144 (int (*)(...))QBoxLayout::minimumSize
+152 (int (*)(...))QBoxLayout::maximumSize
+160 (int (*)(...))QBoxLayout::setGeometry
+168 (int (*)(...))QBoxLayout::itemAt
+176 (int (*)(...))QBoxLayout::takeAt
+184 (int (*)(...))QLayout::indexOf
+192 (int (*)(...))QBoxLayout::count
+200 (int (*)(...))QLayout::isEmpty
+208 (int (*)(...))QLayout::controlTypes
+216 (int (*)(...))QLayout::layout
+224 (int (*)(...))QBoxLayout::sizeHint
+232 (int (*)(...))QBoxLayout::hasHeightForWidth
+240 (int (*)(...))QBoxLayout::heightForWidth
+248 (int (*)(...))QBoxLayout::minimumHeightForWidth
+256 (int (*)(...))-16
+264 (int (*)(...))(& _ZTI10QBoxLayout)
+272 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayoutD1Ev
+280 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayoutD0Ev
+288 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout8sizeHintEv
+296 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11minimumSizeEv
+304 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11maximumSizeEv
+312 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout19expandingDirectionsEv
+320 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout11setGeometryERK5QRect
+328 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv
+336 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv
+344 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout17hasHeightForWidthEv
+352 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout14heightForWidthEi
+360 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout21minimumHeightForWidthEi
+368 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout10invalidateEv
+376 (int (*)(...))QLayoutItem::widget
+384 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv
+392 (int (*)(...))QLayoutItem::spacerItem
+400 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv
+
+Class QBoxLayout
+ size=32 align=8
+ base size=28 base align=8
+QBoxLayout (0x0x7f21b31444e0) 0
+ vptr=((& QBoxLayout::_ZTV10QBoxLayout) + 16u)
+ QLayout (0x0x7f21b66295b0) 0
+ primary-for QBoxLayout (0x0x7f21b31444e0)
+ QObject (0x0x7f21b1becc60) 0
+ primary-for QLayout (0x0x7f21b66295b0)
+ QLayoutItem (0x0x7f21b1beccc0) 16
+ vptr=((& QBoxLayout::_ZTV10QBoxLayout) + 272u)
+
+Class QHBoxLayout::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QHBoxLayout::QPrivateSignal (0x0x7f21b1c74900) 0 empty
+
+Vtable for QHBoxLayout
+QHBoxLayout::_ZTV11QHBoxLayout: 51u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QHBoxLayout)
+16 (int (*)(...))QHBoxLayout::metaObject
+24 (int (*)(...))QHBoxLayout::qt_metacast
+32 (int (*)(...))QHBoxLayout::qt_metacall
+40 (int (*)(...))QHBoxLayout::~QHBoxLayout
+48 (int (*)(...))QHBoxLayout::~QHBoxLayout
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QLayout::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QBoxLayout::invalidate
+120 (int (*)(...))QLayout::geometry
+128 (int (*)(...))QBoxLayout::addItem
+136 (int (*)(...))QBoxLayout::expandingDirections
+144 (int (*)(...))QBoxLayout::minimumSize
+152 (int (*)(...))QBoxLayout::maximumSize
+160 (int (*)(...))QBoxLayout::setGeometry
+168 (int (*)(...))QBoxLayout::itemAt
+176 (int (*)(...))QBoxLayout::takeAt
+184 (int (*)(...))QLayout::indexOf
+192 (int (*)(...))QBoxLayout::count
+200 (int (*)(...))QLayout::isEmpty
+208 (int (*)(...))QLayout::controlTypes
+216 (int (*)(...))QLayout::layout
+224 (int (*)(...))QBoxLayout::sizeHint
+232 (int (*)(...))QBoxLayout::hasHeightForWidth
+240 (int (*)(...))QBoxLayout::heightForWidth
+248 (int (*)(...))QBoxLayout::minimumHeightForWidth
+256 (int (*)(...))-16
+264 (int (*)(...))(& _ZTI11QHBoxLayout)
+272 (int (*)(...))QHBoxLayout::_ZThn16_N11QHBoxLayoutD1Ev
+280 (int (*)(...))QHBoxLayout::_ZThn16_N11QHBoxLayoutD0Ev
+288 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout8sizeHintEv
+296 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11minimumSizeEv
+304 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11maximumSizeEv
+312 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout19expandingDirectionsEv
+320 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout11setGeometryERK5QRect
+328 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv
+336 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv
+344 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout17hasHeightForWidthEv
+352 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout14heightForWidthEi
+360 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout21minimumHeightForWidthEi
+368 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout10invalidateEv
+376 (int (*)(...))QLayoutItem::widget
+384 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv
+392 (int (*)(...))QLayoutItem::spacerItem
+400 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv
+
+Class QHBoxLayout
+ size=32 align=8
+ base size=28 base align=8
+QHBoxLayout (0x0x7f21b3144958) 0
+ vptr=((& QHBoxLayout::_ZTV11QHBoxLayout) + 16u)
+ QBoxLayout (0x0x7f21b31449c0) 0
+ primary-for QHBoxLayout (0x0x7f21b3144958)
+ QLayout (0x0x7f21b66320e0) 0
+ primary-for QBoxLayout (0x0x7f21b31449c0)
+ QObject (0x0x7f21b1c74180) 0
+ primary-for QLayout (0x0x7f21b66320e0)
+ QLayoutItem (0x0x7f21b1c748a0) 16
+ vptr=((& QHBoxLayout::_ZTV11QHBoxLayout) + 272u)
+
+Class QVBoxLayout::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QVBoxLayout::QPrivateSignal (0x0x7f21b1ca9300) 0 empty
+
+Vtable for QVBoxLayout
+QVBoxLayout::_ZTV11QVBoxLayout: 51u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QVBoxLayout)
+16 (int (*)(...))QVBoxLayout::metaObject
+24 (int (*)(...))QVBoxLayout::qt_metacast
+32 (int (*)(...))QVBoxLayout::qt_metacall
+40 (int (*)(...))QVBoxLayout::~QVBoxLayout
+48 (int (*)(...))QVBoxLayout::~QVBoxLayout
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QLayout::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QBoxLayout::invalidate
+120 (int (*)(...))QLayout::geometry
+128 (int (*)(...))QBoxLayout::addItem
+136 (int (*)(...))QBoxLayout::expandingDirections
+144 (int (*)(...))QBoxLayout::minimumSize
+152 (int (*)(...))QBoxLayout::maximumSize
+160 (int (*)(...))QBoxLayout::setGeometry
+168 (int (*)(...))QBoxLayout::itemAt
+176 (int (*)(...))QBoxLayout::takeAt
+184 (int (*)(...))QLayout::indexOf
+192 (int (*)(...))QBoxLayout::count
+200 (int (*)(...))QLayout::isEmpty
+208 (int (*)(...))QLayout::controlTypes
+216 (int (*)(...))QLayout::layout
+224 (int (*)(...))QBoxLayout::sizeHint
+232 (int (*)(...))QBoxLayout::hasHeightForWidth
+240 (int (*)(...))QBoxLayout::heightForWidth
+248 (int (*)(...))QBoxLayout::minimumHeightForWidth
+256 (int (*)(...))-16
+264 (int (*)(...))(& _ZTI11QVBoxLayout)
+272 (int (*)(...))QVBoxLayout::_ZThn16_N11QVBoxLayoutD1Ev
+280 (int (*)(...))QVBoxLayout::_ZThn16_N11QVBoxLayoutD0Ev
+288 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout8sizeHintEv
+296 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11minimumSizeEv
+304 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout11maximumSizeEv
+312 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout19expandingDirectionsEv
+320 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout11setGeometryERK5QRect
+328 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv
+336 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv
+344 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout17hasHeightForWidthEv
+352 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout14heightForWidthEi
+360 (int (*)(...))QBoxLayout::_ZThn16_NK10QBoxLayout21minimumHeightForWidthEi
+368 (int (*)(...))QBoxLayout::_ZThn16_N10QBoxLayout10invalidateEv
+376 (int (*)(...))QLayoutItem::widget
+384 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv
+392 (int (*)(...))QLayoutItem::spacerItem
+400 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv
+
+Class QVBoxLayout
+ size=32 align=8
+ base size=28 base align=8
+QVBoxLayout (0x0x7f21b3144a28) 0
+ vptr=((& QVBoxLayout::_ZTV11QVBoxLayout) + 16u)
+ QBoxLayout (0x0x7f21b3144a90) 0
+ primary-for QVBoxLayout (0x0x7f21b3144a28)
+ QLayout (0x0x7f21b66324d0) 0
+ primary-for QBoxLayout (0x0x7f21b3144a90)
+ QObject (0x0x7f21b1ca9180) 0
+ primary-for QLayout (0x0x7f21b66324d0)
+ QLayoutItem (0x0x7f21b1ca91e0) 16
+ vptr=((& QVBoxLayout::_ZTV11QVBoxLayout) + 272u)
+
+Class QButtonGroup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QButtonGroup::QPrivateSignal (0x0x7f21b1ca9420) 0 empty
+
+Vtable for QButtonGroup
+QButtonGroup::_ZTV12QButtonGroup: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QButtonGroup)
+16 (int (*)(...))QButtonGroup::metaObject
+24 (int (*)(...))QButtonGroup::qt_metacast
+32 (int (*)(...))QButtonGroup::qt_metacall
+40 (int (*)(...))QButtonGroup::~QButtonGroup
+48 (int (*)(...))QButtonGroup::~QButtonGroup
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QButtonGroup
+ size=16 align=8
+ base size=16 base align=8
+QButtonGroup (0x0x7f21b3144b60) 0
+ vptr=((& QButtonGroup::_ZTV12QButtonGroup) + 16u)
+ QObject (0x0x7f21b1ca9360) 0
+ primary-for QButtonGroup (0x0x7f21b3144b60)
+
+Class QCalendarWidget::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QCalendarWidget::QPrivateSignal (0x0x7f21b1ca99c0) 0 empty
+
+Vtable for QCalendarWidget
+QCalendarWidget::_ZTV15QCalendarWidget: 65u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QCalendarWidget)
+16 (int (*)(...))QCalendarWidget::metaObject
+24 (int (*)(...))QCalendarWidget::qt_metacast
+32 (int (*)(...))QCalendarWidget::qt_metacall
+40 (int (*)(...))QCalendarWidget::~QCalendarWidget
+48 (int (*)(...))QCalendarWidget::~QCalendarWidget
+56 (int (*)(...))QCalendarWidget::event
+64 (int (*)(...))QCalendarWidget::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QCalendarWidget::sizeHint
+136 (int (*)(...))QCalendarWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QCalendarWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QCalendarWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QCalendarWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QCalendarWidget::paintCell
+440 (int (*)(...))-16
+448 (int (*)(...))(& _ZTI15QCalendarWidget)
+456 (int (*)(...))QCalendarWidget::_ZThn16_N15QCalendarWidgetD1Ev
+464 (int (*)(...))QCalendarWidget::_ZThn16_N15QCalendarWidgetD0Ev
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QCalendarWidget
+ size=48 align=8
+ base size=48 base align=8
+QCalendarWidget (0x0x7f21b2e32958) 0
+ vptr=((& QCalendarWidget::_ZTV15QCalendarWidget) + 16u)
+ QWidget (0x0x7f21b6632e70) 0
+ primary-for QCalendarWidget (0x0x7f21b2e32958)
+ QObject (0x0x7f21b1ca98a0) 0
+ primary-for QWidget (0x0x7f21b6632e70)
+ QPaintDevice (0x0x7f21b1ca9900) 16
+ vptr=((& QCalendarWidget::_ZTV15QCalendarWidget) + 456u)
+
+Class QCheckBox::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QCheckBox::QPrivateSignal (0x0x7f21b1ca9b40) 0 empty
+
+Vtable for QCheckBox
+QCheckBox::_ZTV9QCheckBox: 67u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QCheckBox)
+16 (int (*)(...))QCheckBox::metaObject
+24 (int (*)(...))QCheckBox::qt_metacast
+32 (int (*)(...))QCheckBox::qt_metacall
+40 (int (*)(...))QCheckBox::~QCheckBox
+48 (int (*)(...))QCheckBox::~QCheckBox
+56 (int (*)(...))QCheckBox::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractButton::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QCheckBox::sizeHint
+136 (int (*)(...))QCheckBox::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractButton::mousePressEvent
+176 (int (*)(...))QAbstractButton::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QCheckBox::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QAbstractButton::keyPressEvent
+216 (int (*)(...))QAbstractButton::keyReleaseEvent
+224 (int (*)(...))QAbstractButton::focusInEvent
+232 (int (*)(...))QAbstractButton::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QCheckBox::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractButton::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QCheckBox::hitButton
+440 (int (*)(...))QCheckBox::checkStateSet
+448 (int (*)(...))QCheckBox::nextCheckState
+456 (int (*)(...))-16
+464 (int (*)(...))(& _ZTI9QCheckBox)
+472 (int (*)(...))QCheckBox::_ZThn16_N9QCheckBoxD1Ev
+480 (int (*)(...))QCheckBox::_ZThn16_N9QCheckBoxD0Ev
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QCheckBox
+ size=48 align=8
+ base size=48 base align=8
+QCheckBox (0x0x7f21b2e329c0) 0
+ vptr=((& QCheckBox::_ZTV9QCheckBox) + 16u)
+ QAbstractButton (0x0x7f21b2e58548) 0
+ primary-for QCheckBox (0x0x7f21b2e329c0)
+ QWidget (0x0x7f21b624c150) 0
+ primary-for QAbstractButton (0x0x7f21b2e58548)
+ QObject (0x0x7f21b1ca9a20) 0
+ primary-for QWidget (0x0x7f21b624c150)
+ QPaintDevice (0x0x7f21b1ca9ae0) 16
+ vptr=((& QCheckBox::_ZTV9QCheckBox) + 472u)
+
+Class QDialog::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDialog::QPrivateSignal (0x0x7f21b1cf0de0) 0 empty
+
+Vtable for QDialog
+QDialog::_ZTV7QDialog: 69u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QDialog)
+16 (int (*)(...))QDialog::metaObject
+24 (int (*)(...))QDialog::qt_metacast
+32 (int (*)(...))QDialog::qt_metacall
+40 (int (*)(...))QDialog::~QDialog
+48 (int (*)(...))QDialog::~QDialog
+56 (int (*)(...))QWidget::event
+64 (int (*)(...))QDialog::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QDialog::setVisible
+128 (int (*)(...))QDialog::sizeHint
+136 (int (*)(...))QDialog::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QDialog::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QDialog::resizeEvent
+280 (int (*)(...))QDialog::closeEvent
+288 (int (*)(...))QDialog::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QDialog::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QDialog::open
+440 (int (*)(...))QDialog::exec
+448 (int (*)(...))QDialog::done
+456 (int (*)(...))QDialog::accept
+464 (int (*)(...))QDialog::reject
+472 (int (*)(...))-16
+480 (int (*)(...))(& _ZTI7QDialog)
+488 (int (*)(...))QDialog::_ZThn16_N7QDialogD1Ev
+496 (int (*)(...))QDialog::_ZThn16_N7QDialogD0Ev
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QDialog
+ size=48 align=8
+ base size=48 base align=8
+QDialog (0x0x7f21b2e585b0) 0
+ vptr=((& QDialog::_ZTV7QDialog) + 16u)
+ QWidget (0x0x7f21b624c8c0) 0
+ primary-for QDialog (0x0x7f21b2e585b0)
+ QObject (0x0x7f21b1cf01e0) 0
+ primary-for QWidget (0x0x7f21b624c8c0)
+ QPaintDevice (0x0x7f21b1cf0240) 16
+ vptr=((& QDialog::_ZTV7QDialog) + 488u)
+
+Class QColorDialog::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QColorDialog::QPrivateSignal (0x0x7f21b1a12060) 0 empty
+
+Vtable for QColorDialog
+QColorDialog::_ZTV12QColorDialog: 69u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QColorDialog)
+16 (int (*)(...))QColorDialog::metaObject
+24 (int (*)(...))QColorDialog::qt_metacast
+32 (int (*)(...))QColorDialog::qt_metacall
+40 (int (*)(...))QColorDialog::~QColorDialog
+48 (int (*)(...))QColorDialog::~QColorDialog
+56 (int (*)(...))QWidget::event
+64 (int (*)(...))QDialog::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QColorDialog::setVisible
+128 (int (*)(...))QDialog::sizeHint
+136 (int (*)(...))QDialog::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QDialog::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QDialog::resizeEvent
+280 (int (*)(...))QDialog::closeEvent
+288 (int (*)(...))QDialog::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QDialog::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QColorDialog::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QDialog::open
+440 (int (*)(...))QDialog::exec
+448 (int (*)(...))QColorDialog::done
+456 (int (*)(...))QDialog::accept
+464 (int (*)(...))QDialog::reject
+472 (int (*)(...))-16
+480 (int (*)(...))(& _ZTI12QColorDialog)
+488 (int (*)(...))QColorDialog::_ZThn16_N12QColorDialogD1Ev
+496 (int (*)(...))QColorDialog::_ZThn16_N12QColorDialogD0Ev
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QColorDialog
+ size=48 align=8
+ base size=48 base align=8
+QColorDialog (0x0x7f21b2e58750) 0
+ vptr=((& QColorDialog::_ZTV12QColorDialog) + 16u)
+ QDialog (0x0x7f21b2e58958) 0
+ primary-for QColorDialog (0x0x7f21b2e58750)
+ QWidget (0x0x7f21b6258070) 0
+ primary-for QDialog (0x0x7f21b2e58958)
+ QObject (0x0x7f21b1cf0e40) 0
+ primary-for QWidget (0x0x7f21b6258070)
+ QPaintDevice (0x0x7f21b1a12000) 16
+ vptr=((& QColorDialog::_ZTV12QColorDialog) + 488u)
+
+Class QColormap
+ size=8 align=8
+ base size=8 base align=8
+QColormap (0x0x7f21b15f6e40) 0
+
+Class QColumnView::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QColumnView::QPrivateSignal (0x0x7f21b175da20) 0 empty
+
+Vtable for QColumnView
+QColumnView::_ZTV11QColumnView: 107u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QColumnView)
+16 (int (*)(...))QColumnView::metaObject
+24 (int (*)(...))QColumnView::qt_metacast
+32 (int (*)(...))QColumnView::qt_metacall
+40 (int (*)(...))QColumnView::~QColumnView
+48 (int (*)(...))QColumnView::~QColumnView
+56 (int (*)(...))QAbstractItemView::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QAbstractItemView::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QColumnView::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractItemView::mousePressEvent
+176 (int (*)(...))QAbstractItemView::mouseReleaseEvent
+184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractItemView::mouseMoveEvent
+200 (int (*)(...))QAbstractScrollArea::wheelEvent
+208 (int (*)(...))QAbstractItemView::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QAbstractItemView::focusInEvent
+232 (int (*)(...))QAbstractItemView::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QAbstractScrollArea::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QColumnView::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QAbstractScrollArea::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QAbstractItemView::dragEnterEvent
+320 (int (*)(...))QAbstractItemView::dragMoveEvent
+328 (int (*)(...))QAbstractItemView::dragLeaveEvent
+336 (int (*)(...))QAbstractItemView::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QAbstractItemView::inputMethodEvent
+416 (int (*)(...))QAbstractItemView::inputMethodQuery
+424 (int (*)(...))QAbstractItemView::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QAbstractItemView::viewportEvent
+448 (int (*)(...))QColumnView::scrollContentsBy
+456 (int (*)(...))QAbstractItemView::viewportSizeHint
+464 (int (*)(...))QColumnView::setModel
+472 (int (*)(...))QColumnView::setSelectionModel
+480 (int (*)(...))QAbstractItemView::keyboardSearch
+488 (int (*)(...))QColumnView::visualRect
+496 (int (*)(...))QColumnView::scrollTo
+504 (int (*)(...))QColumnView::indexAt
+512 (int (*)(...))QAbstractItemView::sizeHintForRow
+520 (int (*)(...))QAbstractItemView::sizeHintForColumn
+528 (int (*)(...))QAbstractItemView::reset
+536 (int (*)(...))QColumnView::setRootIndex
+544 (int (*)(...))QAbstractItemView::doItemsLayout
+552 (int (*)(...))QColumnView::selectAll
+560 (int (*)(...))QAbstractItemView::dataChanged
+568 (int (*)(...))QColumnView::rowsInserted
+576 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved
+584 (int (*)(...))QAbstractItemView::selectionChanged
+592 (int (*)(...))QColumnView::currentChanged
+600 (int (*)(...))QAbstractItemView::updateEditorData
+608 (int (*)(...))QAbstractItemView::updateEditorGeometries
+616 (int (*)(...))QAbstractItemView::updateGeometries
+624 (int (*)(...))QAbstractItemView::verticalScrollbarAction
+632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction
+640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged
+648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged
+656 (int (*)(...))QAbstractItemView::closeEditor
+664 (int (*)(...))QAbstractItemView::commitData
+672 (int (*)(...))QAbstractItemView::editorDestroyed
+680 (int (*)(...))QColumnView::moveCursor
+688 (int (*)(...))QColumnView::horizontalOffset
+696 (int (*)(...))QColumnView::verticalOffset
+704 (int (*)(...))QColumnView::isIndexHidden
+712 (int (*)(...))QColumnView::setSelection
+720 (int (*)(...))QColumnView::visualRegionForSelection
+728 (int (*)(...))QAbstractItemView::selectedIndexes
+736 (int (*)(...))QAbstractItemView::edit
+744 (int (*)(...))QAbstractItemView::selectionCommand
+752 (int (*)(...))QAbstractItemView::startDrag
+760 (int (*)(...))QAbstractItemView::viewOptions
+768 (int (*)(...))QColumnView::createColumn
+776 (int (*)(...))-16
+784 (int (*)(...))(& _ZTI11QColumnView)
+792 (int (*)(...))QColumnView::_ZThn16_N11QColumnViewD1Ev
+800 (int (*)(...))QColumnView::_ZThn16_N11QColumnViewD0Ev
+808 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+816 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+824 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+832 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+840 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+848 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QColumnView
+ size=48 align=8
+ base size=48 base align=8
+QColumnView (0x0x7f21b2e728f0) 0
+ vptr=((& QColumnView::_ZTV11QColumnView) + 16u)
+ QAbstractItemView (0x0x7f21b2e932d8) 0
+ primary-for QColumnView (0x0x7f21b2e728f0)
+ QAbstractScrollArea (0x0x7f21b2fcf270) 0
+ primary-for QAbstractItemView (0x0x7f21b2e932d8)
+ QFrame (0x0x7f21b2fcf5b0) 0
+ primary-for QAbstractScrollArea (0x0x7f21b2fcf270)
+ QWidget (0x0x7f21b6272690) 0
+ primary-for QFrame (0x0x7f21b2fcf5b0)
+ QObject (0x0x7f21b15f6ea0) 0
+ primary-for QWidget (0x0x7f21b6272690)
+ QPaintDevice (0x0x7f21b175d9c0) 16
+ vptr=((& QColumnView::_ZTV11QColumnView) + 792u)
+
+Class QComboBox::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QComboBox::QPrivateSignal (0x0x7f21b17850c0) 0 empty
+
+Vtable for QComboBox
+QComboBox::_ZTV9QComboBox: 66u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QComboBox)
+16 (int (*)(...))QComboBox::metaObject
+24 (int (*)(...))QComboBox::qt_metacast
+32 (int (*)(...))QComboBox::qt_metacall
+40 (int (*)(...))QComboBox::~QComboBox
+48 (int (*)(...))QComboBox::~QComboBox
+56 (int (*)(...))QComboBox::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QComboBox::sizeHint
+136 (int (*)(...))QComboBox::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QComboBox::mousePressEvent
+176 (int (*)(...))QComboBox::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QComboBox::wheelEvent
+208 (int (*)(...))QComboBox::keyPressEvent
+216 (int (*)(...))QComboBox::keyReleaseEvent
+224 (int (*)(...))QComboBox::focusInEvent
+232 (int (*)(...))QComboBox::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QComboBox::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QComboBox::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QComboBox::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QComboBox::showEvent
+352 (int (*)(...))QComboBox::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QComboBox::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QComboBox::inputMethodEvent
+416 (int (*)(...))QComboBox::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QComboBox::showPopup
+440 (int (*)(...))QComboBox::hidePopup
+448 (int (*)(...))-16
+456 (int (*)(...))(& _ZTI9QComboBox)
+464 (int (*)(...))QComboBox::_ZThn16_N9QComboBoxD1Ev
+472 (int (*)(...))QComboBox::_ZThn16_N9QComboBoxD0Ev
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QComboBox
+ size=48 align=8
+ base size=48 base align=8
+QComboBox (0x0x7f21b2fcf618) 0
+ vptr=((& QComboBox::_ZTV9QComboBox) + 16u)
+ QWidget (0x0x7f21b6272c40) 0
+ primary-for QComboBox (0x0x7f21b2fcf618)
+ QObject (0x0x7f21b175df60) 0
+ primary-for QWidget (0x0x7f21b6272c40)
+ QPaintDevice (0x0x7f21b1785000) 16
+ vptr=((& QComboBox::_ZTV9QComboBox) + 464u)
+
+Class QPushButton::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPushButton::QPrivateSignal (0x0x7f21b17ac120) 0 empty
+
+Vtable for QPushButton
+QPushButton::_ZTV11QPushButton: 67u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QPushButton)
+16 (int (*)(...))QPushButton::metaObject
+24 (int (*)(...))QPushButton::qt_metacast
+32 (int (*)(...))QPushButton::qt_metacall
+40 (int (*)(...))QPushButton::~QPushButton
+48 (int (*)(...))QPushButton::~QPushButton
+56 (int (*)(...))QPushButton::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractButton::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QPushButton::sizeHint
+136 (int (*)(...))QPushButton::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractButton::mousePressEvent
+176 (int (*)(...))QAbstractButton::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractButton::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QPushButton::keyPressEvent
+216 (int (*)(...))QAbstractButton::keyReleaseEvent
+224 (int (*)(...))QPushButton::focusInEvent
+232 (int (*)(...))QPushButton::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QPushButton::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractButton::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QAbstractButton::hitButton
+440 (int (*)(...))QAbstractButton::checkStateSet
+448 (int (*)(...))QAbstractButton::nextCheckState
+456 (int (*)(...))-16
+464 (int (*)(...))(& _ZTI11QPushButton)
+472 (int (*)(...))QPushButton::_ZThn16_N11QPushButtonD1Ev
+480 (int (*)(...))QPushButton::_ZThn16_N11QPushButtonD0Ev
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QPushButton
+ size=48 align=8
+ base size=48 base align=8
+QPushButton (0x0x7f21b2fcff70) 0
+ vptr=((& QPushButton::_ZTV11QPushButton) + 16u)
+ QAbstractButton (0x0x7f21b2dc3000) 0
+ primary-for QPushButton (0x0x7f21b2fcff70)
+ QWidget (0x0x7f21b62894d0) 0
+ primary-for QAbstractButton (0x0x7f21b2dc3000)
+ QObject (0x0x7f21b1785180) 0
+ primary-for QWidget (0x0x7f21b62894d0)
+ QPaintDevice (0x0x7f21b1785240) 16
+ vptr=((& QPushButton::_ZTV11QPushButton) + 472u)
+
+Class QCommandLinkButton::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QCommandLinkButton::QPrivateSignal (0x0x7f21b150d720) 0 empty
+
+Vtable for QCommandLinkButton
+QCommandLinkButton::_ZTV18QCommandLinkButton: 67u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QCommandLinkButton)
+16 (int (*)(...))QCommandLinkButton::metaObject
+24 (int (*)(...))QCommandLinkButton::qt_metacast
+32 (int (*)(...))QCommandLinkButton::qt_metacall
+40 (int (*)(...))QCommandLinkButton::~QCommandLinkButton
+48 (int (*)(...))QCommandLinkButton::~QCommandLinkButton
+56 (int (*)(...))QCommandLinkButton::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractButton::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QCommandLinkButton::sizeHint
+136 (int (*)(...))QCommandLinkButton::minimumSizeHint
+144 (int (*)(...))QCommandLinkButton::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractButton::mousePressEvent
+176 (int (*)(...))QAbstractButton::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractButton::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QPushButton::keyPressEvent
+216 (int (*)(...))QAbstractButton::keyReleaseEvent
+224 (int (*)(...))QPushButton::focusInEvent
+232 (int (*)(...))QPushButton::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QCommandLinkButton::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractButton::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QAbstractButton::hitButton
+440 (int (*)(...))QAbstractButton::checkStateSet
+448 (int (*)(...))QAbstractButton::nextCheckState
+456 (int (*)(...))-16
+464 (int (*)(...))(& _ZTI18QCommandLinkButton)
+472 (int (*)(...))QCommandLinkButton::_ZThn16_N18QCommandLinkButtonD1Ev
+480 (int (*)(...))QCommandLinkButton::_ZThn16_N18QCommandLinkButtonD0Ev
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QCommandLinkButton
+ size=48 align=8
+ base size=48 base align=8
+QCommandLinkButton (0x0x7f21b2dc3068) 0
+ vptr=((& QCommandLinkButton::_ZTV18QCommandLinkButton) + 16u)
+ QPushButton (0x0x7f21b2dc3bc8) 0
+ primary-for QCommandLinkButton (0x0x7f21b2dc3068)
+ QAbstractButton (0x0x7f21b2dc3c30) 0
+ primary-for QPushButton (0x0x7f21b2dc3bc8)
+ QWidget (0x0x7f21b6289b60) 0
+ primary-for QAbstractButton (0x0x7f21b2dc3c30)
+ QObject (0x0x7f21b17ac180) 0
+ primary-for QWidget (0x0x7f21b6289b60)
+ QPaintDevice (0x0x7f21b150d6c0) 16
+ vptr=((& QCommandLinkButton::_ZTV18QCommandLinkButton) + 472u)
+
+Class QCommonStyle::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QCommonStyle::QPrivateSignal (0x0x7f21b150db40) 0 empty
+
+Vtable for QCommonStyle
+QCommonStyle::_ZTV12QCommonStyle: 37u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QCommonStyle)
+16 (int (*)(...))QCommonStyle::metaObject
+24 (int (*)(...))QCommonStyle::qt_metacast
+32 (int (*)(...))QCommonStyle::qt_metacall
+40 (int (*)(...))QCommonStyle::~QCommonStyle
+48 (int (*)(...))QCommonStyle::~QCommonStyle
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QCommonStyle::polish
+120 (int (*)(...))QCommonStyle::unpolish
+128 (int (*)(...))QCommonStyle::polish
+136 (int (*)(...))QCommonStyle::unpolish
+144 (int (*)(...))QCommonStyle::polish
+152 (int (*)(...))QStyle::itemTextRect
+160 (int (*)(...))QStyle::itemPixmapRect
+168 (int (*)(...))QStyle::drawItemText
+176 (int (*)(...))QStyle::drawItemPixmap
+184 (int (*)(...))QStyle::standardPalette
+192 (int (*)(...))QCommonStyle::drawPrimitive
+200 (int (*)(...))QCommonStyle::drawControl
+208 (int (*)(...))QCommonStyle::subElementRect
+216 (int (*)(...))QCommonStyle::drawComplexControl
+224 (int (*)(...))QCommonStyle::hitTestComplexControl
+232 (int (*)(...))QCommonStyle::subControlRect
+240 (int (*)(...))QCommonStyle::pixelMetric
+248 (int (*)(...))QCommonStyle::sizeFromContents
+256 (int (*)(...))QCommonStyle::styleHint
+264 (int (*)(...))QCommonStyle::standardPixmap
+272 (int (*)(...))QCommonStyle::standardIcon
+280 (int (*)(...))QCommonStyle::generatedIconPixmap
+288 (int (*)(...))QCommonStyle::layoutSpacing
+
+Class QCommonStyle
+ size=16 align=8
+ base size=16 base align=8
+QCommonStyle (0x0x7f21b2de3958) 0
+ vptr=((& QCommonStyle::_ZTV12QCommonStyle) + 16u)
+ QStyle (0x0x7f21b2de39c0) 0
+ primary-for QCommonStyle (0x0x7f21b2de3958)
+ QObject (0x0x7f21b150dae0) 0
+ primary-for QStyle (0x0x7f21b2de39c0)
+
+Class QCompleter::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QCompleter::QPrivateSignal (0x0x7f21b150dd20) 0 empty
+
+Vtable for QCompleter
+QCompleter::_ZTV10QCompleter: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QCompleter)
+16 (int (*)(...))QCompleter::metaObject
+24 (int (*)(...))QCompleter::qt_metacast
+32 (int (*)(...))QCompleter::qt_metacall
+40 (int (*)(...))QCompleter::~QCompleter
+48 (int (*)(...))QCompleter::~QCompleter
+56 (int (*)(...))QCompleter::event
+64 (int (*)(...))QCompleter::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QCompleter::pathFromIndex
+120 (int (*)(...))QCompleter::splitPath
+
+Class QCompleter
+ size=16 align=8
+ base size=16 base align=8
+QCompleter (0x0x7f21b2de3a28) 0
+ vptr=((& QCompleter::_ZTV10QCompleter) + 16u)
+ QObject (0x0x7f21b150dcc0) 0
+ primary-for QCompleter (0x0x7f21b2de3a28)
+
+Class QDataWidgetMapper::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDataWidgetMapper::QPrivateSignal (0x0x7f21b154d480) 0 empty
+
+Vtable for QDataWidgetMapper
+QDataWidgetMapper::_ZTV17QDataWidgetMapper: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QDataWidgetMapper)
+16 (int (*)(...))QDataWidgetMapper::metaObject
+24 (int (*)(...))QDataWidgetMapper::qt_metacast
+32 (int (*)(...))QDataWidgetMapper::qt_metacall
+40 (int (*)(...))QDataWidgetMapper::~QDataWidgetMapper
+48 (int (*)(...))QDataWidgetMapper::~QDataWidgetMapper
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QDataWidgetMapper::setCurrentIndex
+
+Class QDataWidgetMapper
+ size=16 align=8
+ base size=16 base align=8
+QDataWidgetMapper (0x0x7f21b2de3a90) 0
+ vptr=((& QDataWidgetMapper::_ZTV17QDataWidgetMapper) + 16u)
+ QObject (0x0x7f21b154d420) 0
+ primary-for QDataWidgetMapper (0x0x7f21b2de3a90)
+
+Class QDateTimeEdit::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDateTimeEdit::QPrivateSignal (0x0x7f21b15743c0) 0 empty
+
+Vtable for QDateTimeEdit
+QDateTimeEdit::_ZTV13QDateTimeEdit: 71u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QDateTimeEdit)
+16 (int (*)(...))QDateTimeEdit::metaObject
+24 (int (*)(...))QDateTimeEdit::qt_metacast
+32 (int (*)(...))QDateTimeEdit::qt_metacall
+40 (int (*)(...))QDateTimeEdit::~QDateTimeEdit
+48 (int (*)(...))QDateTimeEdit::~QDateTimeEdit
+56 (int (*)(...))QDateTimeEdit::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractSpinBox::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QDateTimeEdit::sizeHint
+136 (int (*)(...))QAbstractSpinBox::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QDateTimeEdit::mousePressEvent
+176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent
+200 (int (*)(...))QDateTimeEdit::wheelEvent
+208 (int (*)(...))QDateTimeEdit::keyPressEvent
+216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent
+224 (int (*)(...))QDateTimeEdit::focusInEvent
+232 (int (*)(...))QAbstractSpinBox::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QDateTimeEdit::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QAbstractSpinBox::resizeEvent
+280 (int (*)(...))QAbstractSpinBox::closeEvent
+288 (int (*)(...))QAbstractSpinBox::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QAbstractSpinBox::showEvent
+352 (int (*)(...))QAbstractSpinBox::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractSpinBox::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QAbstractSpinBox::inputMethodQuery
+424 (int (*)(...))QDateTimeEdit::focusNextPrevChild
+432 (int (*)(...))QDateTimeEdit::validate
+440 (int (*)(...))QDateTimeEdit::fixup
+448 (int (*)(...))QDateTimeEdit::stepBy
+456 (int (*)(...))QDateTimeEdit::clear
+464 (int (*)(...))QDateTimeEdit::stepEnabled
+472 (int (*)(...))QDateTimeEdit::dateTimeFromText
+480 (int (*)(...))QDateTimeEdit::textFromDateTime
+488 (int (*)(...))-16
+496 (int (*)(...))(& _ZTI13QDateTimeEdit)
+504 (int (*)(...))QDateTimeEdit::_ZThn16_N13QDateTimeEditD1Ev
+512 (int (*)(...))QDateTimeEdit::_ZThn16_N13QDateTimeEditD0Ev
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QDateTimeEdit
+ size=48 align=8
+ base size=48 base align=8
+QDateTimeEdit (0x0x7f21b2b7b270) 0
+ vptr=((& QDateTimeEdit::_ZTV13QDateTimeEdit) + 16u)
+ QAbstractSpinBox (0x0x7f21b2b7b2d8) 0
+ primary-for QDateTimeEdit (0x0x7f21b2b7b270)
+ QWidget (0x0x7f21b62c09a0) 0
+ primary-for QAbstractSpinBox (0x0x7f21b2b7b2d8)
+ QObject (0x0x7f21b154dc00) 0
+ primary-for QWidget (0x0x7f21b62c09a0)
+ QPaintDevice (0x0x7f21b154dc60) 16
+ vptr=((& QDateTimeEdit::_ZTV13QDateTimeEdit) + 504u)
+
+Class QTimeEdit::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTimeEdit::QPrivateSignal (0x0x7f21b13203c0) 0 empty
+
+Vtable for QTimeEdit
+QTimeEdit::_ZTV9QTimeEdit: 71u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QTimeEdit)
+16 (int (*)(...))QTimeEdit::metaObject
+24 (int (*)(...))QTimeEdit::qt_metacast
+32 (int (*)(...))QTimeEdit::qt_metacall
+40 (int (*)(...))QTimeEdit::~QTimeEdit
+48 (int (*)(...))QTimeEdit::~QTimeEdit
+56 (int (*)(...))QDateTimeEdit::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractSpinBox::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QDateTimeEdit::sizeHint
+136 (int (*)(...))QAbstractSpinBox::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QDateTimeEdit::mousePressEvent
+176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent
+200 (int (*)(...))QDateTimeEdit::wheelEvent
+208 (int (*)(...))QDateTimeEdit::keyPressEvent
+216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent
+224 (int (*)(...))QDateTimeEdit::focusInEvent
+232 (int (*)(...))QAbstractSpinBox::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QDateTimeEdit::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QAbstractSpinBox::resizeEvent
+280 (int (*)(...))QAbstractSpinBox::closeEvent
+288 (int (*)(...))QAbstractSpinBox::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QAbstractSpinBox::showEvent
+352 (int (*)(...))QAbstractSpinBox::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractSpinBox::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QAbstractSpinBox::inputMethodQuery
+424 (int (*)(...))QDateTimeEdit::focusNextPrevChild
+432 (int (*)(...))QDateTimeEdit::validate
+440 (int (*)(...))QDateTimeEdit::fixup
+448 (int (*)(...))QDateTimeEdit::stepBy
+456 (int (*)(...))QDateTimeEdit::clear
+464 (int (*)(...))QDateTimeEdit::stepEnabled
+472 (int (*)(...))QDateTimeEdit::dateTimeFromText
+480 (int (*)(...))QDateTimeEdit::textFromDateTime
+488 (int (*)(...))-16
+496 (int (*)(...))(& _ZTI9QTimeEdit)
+504 (int (*)(...))QTimeEdit::_ZThn16_N9QTimeEditD1Ev
+512 (int (*)(...))QTimeEdit::_ZThn16_N9QTimeEditD0Ev
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QTimeEdit
+ size=48 align=8
+ base size=48 base align=8
+QTimeEdit (0x0x7f21b2979750) 0
+ vptr=((& QTimeEdit::_ZTV9QTimeEdit) + 16u)
+ QDateTimeEdit (0x0x7f21b29797b8) 0
+ primary-for QTimeEdit (0x0x7f21b2979750)
+ QAbstractSpinBox (0x0x7f21b27a3208) 0
+ primary-for QDateTimeEdit (0x0x7f21b29797b8)
+ QWidget (0x0x7f21b631a8c0) 0
+ primary-for QAbstractSpinBox (0x0x7f21b27a3208)
+ QObject (0x0x7f21b13201e0) 0
+ primary-for QWidget (0x0x7f21b631a8c0)
+ QPaintDevice (0x0x7f21b13202a0) 16
+ vptr=((& QTimeEdit::_ZTV9QTimeEdit) + 504u)
+
+Class QDateEdit::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDateEdit::QPrivateSignal (0x0x7f21b1320540) 0 empty
+
+Vtable for QDateEdit
+QDateEdit::_ZTV9QDateEdit: 71u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QDateEdit)
+16 (int (*)(...))QDateEdit::metaObject
+24 (int (*)(...))QDateEdit::qt_metacast
+32 (int (*)(...))QDateEdit::qt_metacall
+40 (int (*)(...))QDateEdit::~QDateEdit
+48 (int (*)(...))QDateEdit::~QDateEdit
+56 (int (*)(...))QDateTimeEdit::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractSpinBox::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QDateTimeEdit::sizeHint
+136 (int (*)(...))QAbstractSpinBox::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QDateTimeEdit::mousePressEvent
+176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent
+200 (int (*)(...))QDateTimeEdit::wheelEvent
+208 (int (*)(...))QDateTimeEdit::keyPressEvent
+216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent
+224 (int (*)(...))QDateTimeEdit::focusInEvent
+232 (int (*)(...))QAbstractSpinBox::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QDateTimeEdit::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QAbstractSpinBox::resizeEvent
+280 (int (*)(...))QAbstractSpinBox::closeEvent
+288 (int (*)(...))QAbstractSpinBox::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QAbstractSpinBox::showEvent
+352 (int (*)(...))QAbstractSpinBox::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractSpinBox::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QAbstractSpinBox::inputMethodQuery
+424 (int (*)(...))QDateTimeEdit::focusNextPrevChild
+432 (int (*)(...))QDateTimeEdit::validate
+440 (int (*)(...))QDateTimeEdit::fixup
+448 (int (*)(...))QDateTimeEdit::stepBy
+456 (int (*)(...))QDateTimeEdit::clear
+464 (int (*)(...))QDateTimeEdit::stepEnabled
+472 (int (*)(...))QDateTimeEdit::dateTimeFromText
+480 (int (*)(...))QDateTimeEdit::textFromDateTime
+488 (int (*)(...))-16
+496 (int (*)(...))(& _ZTI9QDateEdit)
+504 (int (*)(...))QDateEdit::_ZThn16_N9QDateEditD1Ev
+512 (int (*)(...))QDateEdit::_ZThn16_N9QDateEditD0Ev
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QDateEdit
+ size=48 align=8
+ base size=48 base align=8
+QDateEdit (0x0x7f21b27a3270) 0
+ vptr=((& QDateEdit::_ZTV9QDateEdit) + 16u)
+ QDateTimeEdit (0x0x7f21b27a3e38) 0
+ primary-for QDateEdit (0x0x7f21b27a3270)
+ QAbstractSpinBox (0x0x7f21b27a3ea0) 0
+ primary-for QDateTimeEdit (0x0x7f21b27a3e38)
+ QWidget (0x0x7f21b631ac40) 0
+ primary-for QAbstractSpinBox (0x0x7f21b27a3ea0)
+ QObject (0x0x7f21b1320420) 0
+ primary-for QWidget (0x0x7f21b631ac40)
+ QPaintDevice (0x0x7f21b13204e0) 16
+ vptr=((& QDateEdit::_ZTV9QDateEdit) + 504u)
+
+Class QDesktopWidget::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDesktopWidget::QPrivateSignal (0x0x7f21b13207e0) 0 empty
+
+Vtable for QDesktopWidget
+QDesktopWidget::_ZTV14QDesktopWidget: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QDesktopWidget)
+16 (int (*)(...))QDesktopWidget::metaObject
+24 (int (*)(...))QDesktopWidget::qt_metacast
+32 (int (*)(...))QDesktopWidget::qt_metacall
+40 (int (*)(...))QDesktopWidget::~QDesktopWidget
+48 (int (*)(...))QDesktopWidget::~QDesktopWidget
+56 (int (*)(...))QWidget::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QDesktopWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI14QDesktopWidget)
+448 (int (*)(...))QDesktopWidget::_ZThn16_N14QDesktopWidgetD1Ev
+456 (int (*)(...))QDesktopWidget::_ZThn16_N14QDesktopWidgetD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QDesktopWidget
+ size=48 align=8
+ base size=48 base align=8
+QDesktopWidget (0x0x7f21b27c4270) 0
+ vptr=((& QDesktopWidget::_ZTV14QDesktopWidget) + 16u)
+ QWidget (0x0x7f21b6355e70) 0
+ primary-for QDesktopWidget (0x0x7f21b27c4270)
+ QObject (0x0x7f21b1320600) 0
+ primary-for QWidget (0x0x7f21b6355e70)
+ QPaintDevice (0x0x7f21b1320780) 16
+ vptr=((& QDesktopWidget::_ZTV14QDesktopWidget) + 448u)
+
+Class QDial::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDial::QPrivateSignal (0x0x7f21b11d6e40) 0 empty
+
+Vtable for QDial
+QDial::_ZTV5QDial: 65u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI5QDial)
+16 (int (*)(...))QDial::metaObject
+24 (int (*)(...))QDial::qt_metacast
+32 (int (*)(...))QDial::qt_metacall
+40 (int (*)(...))QDial::~QDial
+48 (int (*)(...))QDial::~QDial
+56 (int (*)(...))QDial::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractSlider::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QDial::sizeHint
+136 (int (*)(...))QDial::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QDial::mousePressEvent
+176 (int (*)(...))QDial::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QDial::mouseMoveEvent
+200 (int (*)(...))QAbstractSlider::wheelEvent
+208 (int (*)(...))QAbstractSlider::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QDial::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QDial::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractSlider::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QDial::sliderChange
+440 (int (*)(...))-16
+448 (int (*)(...))(& _ZTI5QDial)
+456 (int (*)(...))QDial::_ZThn16_N5QDialD1Ev
+464 (int (*)(...))QDial::_ZThn16_N5QDialD0Ev
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QDial
+ size=48 align=8
+ base size=48 base align=8
+QDial (0x0x7f21b27c42d8) 0
+ vptr=((& QDial::_ZTV5QDial) + 16u)
+ QAbstractSlider (0x0x7f21b27c4e38) 0
+ primary-for QDial (0x0x7f21b27c42d8)
+ QWidget (0x0x7f21b63638c0) 0
+ primary-for QAbstractSlider (0x0x7f21b27c4e38)
+ QObject (0x0x7f21b13208a0) 0
+ primary-for QWidget (0x0x7f21b63638c0)
+ QPaintDevice (0x0x7f21b11d6de0) 16
+ vptr=((& QDial::_ZTV5QDial) + 456u)
+
+Class QDialogButtonBox::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDialogButtonBox::QPrivateSignal (0x0x7f21b0f865a0) 0 empty
+
+Vtable for QDialogButtonBox
+QDialogButtonBox::_ZTV16QDialogButtonBox: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QDialogButtonBox)
+16 (int (*)(...))QDialogButtonBox::metaObject
+24 (int (*)(...))QDialogButtonBox::qt_metacast
+32 (int (*)(...))QDialogButtonBox::qt_metacall
+40 (int (*)(...))QDialogButtonBox::~QDialogButtonBox
+48 (int (*)(...))QDialogButtonBox::~QDialogButtonBox
+56 (int (*)(...))QDialogButtonBox::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QDialogButtonBox::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI16QDialogButtonBox)
+448 (int (*)(...))QDialogButtonBox::_ZThn16_N16QDialogButtonBoxD1Ev
+456 (int (*)(...))QDialogButtonBox::_ZThn16_N16QDialogButtonBoxD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QDialogButtonBox
+ size=48 align=8
+ base size=48 base align=8
+QDialogButtonBox (0x0x7f21b27c4ea0) 0
+ vptr=((& QDialogButtonBox::_ZTV16QDialogButtonBox) + 16u)
+ QWidget (0x0x7f21b6363e70) 0
+ primary-for QDialogButtonBox (0x0x7f21b27c4ea0)
+ QObject (0x0x7f21b0f5c960) 0
+ primary-for QWidget (0x0x7f21b6363e70)
+ QPaintDevice (0x0x7f21b0f5c9c0) 16
+ vptr=((& QDialogButtonBox::_ZTV16QDialogButtonBox) + 448u)
+
+Vtable for QFileIconProvider
+QFileIconProvider::_ZTV17QFileIconProvider: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QFileIconProvider)
+16 (int (*)(...))QFileIconProvider::~QFileIconProvider
+24 (int (*)(...))QFileIconProvider::~QFileIconProvider
+32 (int (*)(...))QFileIconProvider::icon
+40 (int (*)(...))QFileIconProvider::icon
+48 (int (*)(...))QFileIconProvider::type
+
+Class QFileIconProvider
+ size=16 align=8
+ base size=16 base align=8
+QFileIconProvider (0x0x7f21b0d85cc0) 0
+ vptr=((& QFileIconProvider::_ZTV17QFileIconProvider) + 16u)
+
+Class QDirModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDirModel::QPrivateSignal (0x0x7f21b0a11e40) 0 empty
+
+Vtable for QDirModel
+QDirModel::_ZTV9QDirModel: 48u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QDirModel)
+16 (int (*)(...))QDirModel::metaObject
+24 (int (*)(...))QDirModel::qt_metacast
+32 (int (*)(...))QDirModel::qt_metacall
+40 (int (*)(...))QDirModel::~QDirModel
+48 (int (*)(...))QDirModel::~QDirModel
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QDirModel::index
+120 (int (*)(...))QDirModel::parent
+128 (int (*)(...))QAbstractItemModel::sibling
+136 (int (*)(...))QDirModel::rowCount
+144 (int (*)(...))QDirModel::columnCount
+152 (int (*)(...))QDirModel::hasChildren
+160 (int (*)(...))QDirModel::data
+168 (int (*)(...))QDirModel::setData
+176 (int (*)(...))QDirModel::headerData
+184 (int (*)(...))QAbstractItemModel::setHeaderData
+192 (int (*)(...))QAbstractItemModel::itemData
+200 (int (*)(...))QAbstractItemModel::setItemData
+208 (int (*)(...))QDirModel::mimeTypes
+216 (int (*)(...))QDirModel::mimeData
+224 (int (*)(...))QAbstractItemModel::canDropMimeData
+232 (int (*)(...))QDirModel::dropMimeData
+240 (int (*)(...))QDirModel::supportedDropActions
+248 (int (*)(...))QAbstractItemModel::supportedDragActions
+256 (int (*)(...))QAbstractItemModel::insertRows
+264 (int (*)(...))QAbstractItemModel::insertColumns
+272 (int (*)(...))QAbstractItemModel::removeRows
+280 (int (*)(...))QAbstractItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QAbstractItemModel::fetchMore
+312 (int (*)(...))QAbstractItemModel::canFetchMore
+320 (int (*)(...))QDirModel::flags
+328 (int (*)(...))QDirModel::sort
+336 (int (*)(...))QAbstractItemModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractItemModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractItemModel::submit
+376 (int (*)(...))QAbstractItemModel::revert
+
+Class QDirModel
+ size=16 align=8
+ base size=16 base align=8
+QDirModel (0x0x7f21b23eeea0) 0
+ vptr=((& QDirModel::_ZTV9QDirModel) + 16u)
+ QAbstractItemModel (0x0x7f21b2164a90) 0
+ primary-for QDirModel (0x0x7f21b23eeea0)
+ QObject (0x0x7f21b0a11de0) 0
+ primary-for QAbstractItemModel (0x0x7f21b2164a90)
+
+Class QDockWidget::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDockWidget::QPrivateSignal (0x0x7f21b0a5e120) 0 empty
+
+Vtable for QDockWidget
+QDockWidget::_ZTV11QDockWidget: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QDockWidget)
+16 (int (*)(...))QDockWidget::metaObject
+24 (int (*)(...))QDockWidget::qt_metacast
+32 (int (*)(...))QDockWidget::qt_metacall
+40 (int (*)(...))QDockWidget::~QDockWidget
+48 (int (*)(...))QDockWidget::~QDockWidget
+56 (int (*)(...))QDockWidget::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QDockWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QDockWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QDockWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI11QDockWidget)
+448 (int (*)(...))QDockWidget::_ZThn16_N11QDockWidgetD1Ev
+456 (int (*)(...))QDockWidget::_ZThn16_N11QDockWidgetD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QDockWidget
+ size=48 align=8
+ base size=48 base align=8
+QDockWidget (0x0x7f21b2164c30) 0
+ vptr=((& QDockWidget::_ZTV11QDockWidget) + 16u)
+ QWidget (0x0x7f21b63e8690) 0
+ primary-for QDockWidget (0x0x7f21b2164c30)
+ QObject (0x0x7f21b0a5e000) 0
+ primary-for QWidget (0x0x7f21b63e8690)
+ QPaintDevice (0x0x7f21b0a5e060) 16
+ vptr=((& QDockWidget::_ZTV11QDockWidget) + 448u)
+
+Class QTileRules
+ size=8 align=4
+ base size=8 base align=4
+QTileRules (0x0x7f21b0aa2a80) 0
+
+Class QErrorMessage::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QErrorMessage::QPrivateSignal (0x0x7f21b0ad3600) 0 empty
+
+Vtable for QErrorMessage
+QErrorMessage::_ZTV13QErrorMessage: 69u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QErrorMessage)
+16 (int (*)(...))QErrorMessage::metaObject
+24 (int (*)(...))QErrorMessage::qt_metacast
+32 (int (*)(...))QErrorMessage::qt_metacall
+40 (int (*)(...))QErrorMessage::~QErrorMessage
+48 (int (*)(...))QErrorMessage::~QErrorMessage
+56 (int (*)(...))QWidget::event
+64 (int (*)(...))QDialog::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QDialog::setVisible
+128 (int (*)(...))QDialog::sizeHint
+136 (int (*)(...))QDialog::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QDialog::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QDialog::resizeEvent
+280 (int (*)(...))QDialog::closeEvent
+288 (int (*)(...))QDialog::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QDialog::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QErrorMessage::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QDialog::open
+440 (int (*)(...))QDialog::exec
+448 (int (*)(...))QErrorMessage::done
+456 (int (*)(...))QDialog::accept
+464 (int (*)(...))QDialog::reject
+472 (int (*)(...))-16
+480 (int (*)(...))(& _ZTI13QErrorMessage)
+488 (int (*)(...))QErrorMessage::_ZThn16_N13QErrorMessageD1Ev
+496 (int (*)(...))QErrorMessage::_ZThn16_N13QErrorMessageD0Ev
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QErrorMessage
+ size=48 align=8
+ base size=48 base align=8
+QErrorMessage (0x0x7f21b1a0e270) 0
+ vptr=((& QErrorMessage::_ZTV13QErrorMessage) + 16u)
+ QDialog (0x0x7f21b1a0e3a8) 0
+ primary-for QErrorMessage (0x0x7f21b1a0e270)
+ QWidget (0x0x7f21b6048380) 0
+ primary-for QDialog (0x0x7f21b1a0e3a8)
+ QObject (0x0x7f21b0ad3360) 0
+ primary-for QWidget (0x0x7f21b6048380)
+ QPaintDevice (0x0x7f21b0ad33c0) 16
+ vptr=((& QErrorMessage::_ZTV13QErrorMessage) + 488u)
+
+Class QFileDialog::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFileDialog::QPrivateSignal (0x0x7f21b0af9000) 0 empty
+
+Vtable for QFileDialog
+QFileDialog::_ZTV11QFileDialog: 69u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QFileDialog)
+16 (int (*)(...))QFileDialog::metaObject
+24 (int (*)(...))QFileDialog::qt_metacast
+32 (int (*)(...))QFileDialog::qt_metacall
+40 (int (*)(...))QFileDialog::~QFileDialog
+48 (int (*)(...))QFileDialog::~QFileDialog
+56 (int (*)(...))QWidget::event
+64 (int (*)(...))QDialog::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QFileDialog::setVisible
+128 (int (*)(...))QDialog::sizeHint
+136 (int (*)(...))QDialog::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QDialog::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QDialog::resizeEvent
+280 (int (*)(...))QDialog::closeEvent
+288 (int (*)(...))QDialog::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QDialog::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFileDialog::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QDialog::open
+440 (int (*)(...))QDialog::exec
+448 (int (*)(...))QFileDialog::done
+456 (int (*)(...))QFileDialog::accept
+464 (int (*)(...))QDialog::reject
+472 (int (*)(...))-16
+480 (int (*)(...))(& _ZTI11QFileDialog)
+488 (int (*)(...))QFileDialog::_ZThn16_N11QFileDialogD1Ev
+496 (int (*)(...))QFileDialog::_ZThn16_N11QFileDialogD0Ev
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QFileDialog
+ size=48 align=8
+ base size=48 base align=8
+QFileDialog (0x0x7f21b1a0e548) 0
+ vptr=((& QFileDialog::_ZTV11QFileDialog) + 16u)
+ QDialog (0x0x7f21b1a0e5b0) 0
+ primary-for QFileDialog (0x0x7f21b1a0e548)
+ QWidget (0x0x7f21b60489a0) 0
+ primary-for QDialog (0x0x7f21b1a0e5b0)
+ QObject (0x0x7f21b0ad3660) 0
+ primary-for QWidget (0x0x7f21b60489a0)
+ QPaintDevice (0x0x7f21b0ad3f60) 16
+ vptr=((& QFileDialog::_ZTV11QFileDialog) + 488u)
+
+Class QFileSystemModel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFileSystemModel::QPrivateSignal (0x0x7f21b0948300) 0 empty
+
+Vtable for QFileSystemModel
+QFileSystemModel::_ZTV16QFileSystemModel: 48u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QFileSystemModel)
+16 (int (*)(...))QFileSystemModel::metaObject
+24 (int (*)(...))QFileSystemModel::qt_metacast
+32 (int (*)(...))QFileSystemModel::qt_metacall
+40 (int (*)(...))QFileSystemModel::~QFileSystemModel
+48 (int (*)(...))QFileSystemModel::~QFileSystemModel
+56 (int (*)(...))QFileSystemModel::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QFileSystemModel::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QFileSystemModel::index
+120 (int (*)(...))QFileSystemModel::parent
+128 (int (*)(...))QFileSystemModel::sibling
+136 (int (*)(...))QFileSystemModel::rowCount
+144 (int (*)(...))QFileSystemModel::columnCount
+152 (int (*)(...))QFileSystemModel::hasChildren
+160 (int (*)(...))QFileSystemModel::data
+168 (int (*)(...))QFileSystemModel::setData
+176 (int (*)(...))QFileSystemModel::headerData
+184 (int (*)(...))QAbstractItemModel::setHeaderData
+192 (int (*)(...))QAbstractItemModel::itemData
+200 (int (*)(...))QAbstractItemModel::setItemData
+208 (int (*)(...))QFileSystemModel::mimeTypes
+216 (int (*)(...))QFileSystemModel::mimeData
+224 (int (*)(...))QAbstractItemModel::canDropMimeData
+232 (int (*)(...))QFileSystemModel::dropMimeData
+240 (int (*)(...))QFileSystemModel::supportedDropActions
+248 (int (*)(...))QAbstractItemModel::supportedDragActions
+256 (int (*)(...))QAbstractItemModel::insertRows
+264 (int (*)(...))QAbstractItemModel::insertColumns
+272 (int (*)(...))QAbstractItemModel::removeRows
+280 (int (*)(...))QAbstractItemModel::removeColumns
+288 (int (*)(...))QAbstractItemModel::moveRows
+296 (int (*)(...))QAbstractItemModel::moveColumns
+304 (int (*)(...))QFileSystemModel::fetchMore
+312 (int (*)(...))QFileSystemModel::canFetchMore
+320 (int (*)(...))QFileSystemModel::flags
+328 (int (*)(...))QFileSystemModel::sort
+336 (int (*)(...))QAbstractItemModel::buddy
+344 (int (*)(...))QAbstractItemModel::match
+352 (int (*)(...))QAbstractItemModel::span
+360 (int (*)(...))QAbstractItemModel::roleNames
+368 (int (*)(...))QAbstractItemModel::submit
+376 (int (*)(...))QAbstractItemModel::revert
+
+Class QFileSystemModel
+ size=16 align=8
+ base size=16 base align=8
+QFileSystemModel (0x0x7f21b1a0e7b8) 0
+ vptr=((& QFileSystemModel::_ZTV16QFileSystemModel) + 16u)
+ QAbstractItemModel (0x0x7f21b186c0d0) 0
+ primary-for QFileSystemModel (0x0x7f21b1a0e7b8)
+ QObject (0x0x7f21b09482a0) 0
+ primary-for QAbstractItemModel (0x0x7f21b186c0d0)
+
+Class QFocusFrame::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFocusFrame::QPrivateSignal (0x0x7f21b0948ae0) 0 empty
+
+Vtable for QFocusFrame
+QFocusFrame::_ZTV11QFocusFrame: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QFocusFrame)
+16 (int (*)(...))QFocusFrame::metaObject
+24 (int (*)(...))QFocusFrame::qt_metacast
+32 (int (*)(...))QFocusFrame::qt_metacall
+40 (int (*)(...))QFocusFrame::~QFocusFrame
+48 (int (*)(...))QFocusFrame::~QFocusFrame
+56 (int (*)(...))QFocusFrame::event
+64 (int (*)(...))QFocusFrame::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QFocusFrame::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI11QFocusFrame)
+448 (int (*)(...))QFocusFrame::_ZThn16_N11QFocusFrameD1Ev
+456 (int (*)(...))QFocusFrame::_ZThn16_N11QFocusFrameD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QFocusFrame
+ size=48 align=8
+ base size=48 base align=8
+QFocusFrame (0x0x7f21b186c138) 0
+ vptr=((& QFocusFrame::_ZTV11QFocusFrame) + 16u)
+ QWidget (0x0x7f21b60df1c0) 0
+ primary-for QFocusFrame (0x0x7f21b186c138)
+ QObject (0x0x7f21b0948780) 0
+ primary-for QWidget (0x0x7f21b60df1c0)
+ QPaintDevice (0x0x7f21b0948a80) 16
+ vptr=((& QFocusFrame::_ZTV11QFocusFrame) + 448u)
+
+Class QFontComboBox::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFontComboBox::QPrivateSignal (0x0x7f21b0948d80) 0 empty
+
+Vtable for QFontComboBox
+QFontComboBox::_ZTV13QFontComboBox: 66u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QFontComboBox)
+16 (int (*)(...))QFontComboBox::metaObject
+24 (int (*)(...))QFontComboBox::qt_metacast
+32 (int (*)(...))QFontComboBox::qt_metacall
+40 (int (*)(...))QFontComboBox::~QFontComboBox
+48 (int (*)(...))QFontComboBox::~QFontComboBox
+56 (int (*)(...))QFontComboBox::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QFontComboBox::sizeHint
+136 (int (*)(...))QComboBox::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QComboBox::mousePressEvent
+176 (int (*)(...))QComboBox::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QComboBox::wheelEvent
+208 (int (*)(...))QComboBox::keyPressEvent
+216 (int (*)(...))QComboBox::keyReleaseEvent
+224 (int (*)(...))QComboBox::focusInEvent
+232 (int (*)(...))QComboBox::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QComboBox::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QComboBox::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QComboBox::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QComboBox::showEvent
+352 (int (*)(...))QComboBox::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QComboBox::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QComboBox::inputMethodEvent
+416 (int (*)(...))QComboBox::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QComboBox::showPopup
+440 (int (*)(...))QComboBox::hidePopup
+448 (int (*)(...))-16
+456 (int (*)(...))(& _ZTI13QFontComboBox)
+464 (int (*)(...))QFontComboBox::_ZThn16_N13QFontComboBoxD1Ev
+472 (int (*)(...))QFontComboBox::_ZThn16_N13QFontComboBoxD0Ev
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QFontComboBox
+ size=48 align=8
+ base size=48 base align=8
+QFontComboBox (0x0x7f21b186cea0) 0
+ vptr=((& QFontComboBox::_ZTV13QFontComboBox) + 16u)
+ QComboBox (0x0x7f21b1608138) 0
+ primary-for QFontComboBox (0x0x7f21b186cea0)
+ QWidget (0x0x7f21b60dfa10) 0
+ primary-for QComboBox (0x0x7f21b1608138)
+ QObject (0x0x7f21b0948c60) 0
+ primary-for QWidget (0x0x7f21b60dfa10)
+ QPaintDevice (0x0x7f21b0948cc0) 16
+ vptr=((& QFontComboBox::_ZTV13QFontComboBox) + 464u)
+
+Class QFontDialog::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFontDialog::QPrivateSignal (0x0x7f21b098d960) 0 empty
+
+Vtable for QFontDialog
+QFontDialog::_ZTV11QFontDialog: 69u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QFontDialog)
+16 (int (*)(...))QFontDialog::metaObject
+24 (int (*)(...))QFontDialog::qt_metacast
+32 (int (*)(...))QFontDialog::qt_metacall
+40 (int (*)(...))QFontDialog::~QFontDialog
+48 (int (*)(...))QFontDialog::~QFontDialog
+56 (int (*)(...))QWidget::event
+64 (int (*)(...))QFontDialog::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QFontDialog::setVisible
+128 (int (*)(...))QDialog::sizeHint
+136 (int (*)(...))QDialog::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QDialog::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QDialog::resizeEvent
+280 (int (*)(...))QDialog::closeEvent
+288 (int (*)(...))QDialog::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QDialog::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFontDialog::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QDialog::open
+440 (int (*)(...))QDialog::exec
+448 (int (*)(...))QFontDialog::done
+456 (int (*)(...))QDialog::accept
+464 (int (*)(...))QDialog::reject
+472 (int (*)(...))-16
+480 (int (*)(...))(& _ZTI11QFontDialog)
+488 (int (*)(...))QFontDialog::_ZThn16_N11QFontDialogD1Ev
+496 (int (*)(...))QFontDialog::_ZThn16_N11QFontDialogD0Ev
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QFontDialog
+ size=48 align=8
+ base size=48 base align=8
+QFontDialog (0x0x7f21b1608a90) 0
+ vptr=((& QFontDialog::_ZTV11QFontDialog) + 16u)
+ QDialog (0x0x7f21b1608af8) 0
+ primary-for QFontDialog (0x0x7f21b1608a90)
+ QWidget (0x0x7f21b61033f0) 0
+ primary-for QDialog (0x0x7f21b1608af8)
+ QObject (0x0x7f21b098d6c0) 0
+ primary-for QWidget (0x0x7f21b61033f0)
+ QPaintDevice (0x0x7f21b098d720) 16
+ vptr=((& QFontDialog::_ZTV11QFontDialog) + 488u)
+
+Class QFormLayout::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QFormLayout::QPrivateSignal (0x0x7f21b044bf60) 0 empty
+
+Class QFormLayout::TakeRowResult
+ size=16 align=8
+ base size=16 base align=8
+QFormLayout::TakeRowResult (0x0x7f21b0471000) 0
+
+Vtable for QFormLayout
+QFormLayout::_ZTV11QFormLayout: 50u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QFormLayout)
+16 (int (*)(...))QFormLayout::metaObject
+24 (int (*)(...))QFormLayout::qt_metacast
+32 (int (*)(...))QFormLayout::qt_metacall
+40 (int (*)(...))QFormLayout::~QFormLayout
+48 (int (*)(...))QFormLayout::~QFormLayout
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QLayout::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QFormLayout::invalidate
+120 (int (*)(...))QLayout::geometry
+128 (int (*)(...))QFormLayout::addItem
+136 (int (*)(...))QFormLayout::expandingDirections
+144 (int (*)(...))QFormLayout::minimumSize
+152 (int (*)(...))QLayout::maximumSize
+160 (int (*)(...))QFormLayout::setGeometry
+168 (int (*)(...))QFormLayout::itemAt
+176 (int (*)(...))QFormLayout::takeAt
+184 (int (*)(...))QLayout::indexOf
+192 (int (*)(...))QFormLayout::count
+200 (int (*)(...))QLayout::isEmpty
+208 (int (*)(...))QLayout::controlTypes
+216 (int (*)(...))QLayout::layout
+224 (int (*)(...))QFormLayout::sizeHint
+232 (int (*)(...))QFormLayout::hasHeightForWidth
+240 (int (*)(...))QFormLayout::heightForWidth
+248 (int (*)(...))-16
+256 (int (*)(...))(& _ZTI11QFormLayout)
+264 (int (*)(...))QFormLayout::_ZThn16_N11QFormLayoutD1Ev
+272 (int (*)(...))QFormLayout::_ZThn16_N11QFormLayoutD0Ev
+280 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout8sizeHintEv
+288 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout11minimumSizeEv
+296 (int (*)(...))QLayout::_ZThn16_NK7QLayout11maximumSizeEv
+304 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout19expandingDirectionsEv
+312 (int (*)(...))QFormLayout::_ZThn16_N11QFormLayout11setGeometryERK5QRect
+320 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv
+328 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv
+336 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout17hasHeightForWidthEv
+344 (int (*)(...))QFormLayout::_ZThn16_NK11QFormLayout14heightForWidthEi
+352 (int (*)(...))QLayoutItem::minimumHeightForWidth
+360 (int (*)(...))QFormLayout::_ZThn16_N11QFormLayout10invalidateEv
+368 (int (*)(...))QLayoutItem::widget
+376 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv
+384 (int (*)(...))QLayoutItem::spacerItem
+392 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv
+
+Class QFormLayout
+ size=32 align=8
+ base size=28 base align=8
+QFormLayout (0x0x7f21b176f000) 0
+ vptr=((& QFormLayout::_ZTV11QFormLayout) + 16u)
+ QLayout (0x0x7f21b61305b0) 0
+ primary-for QFormLayout (0x0x7f21b176f000)
+ QObject (0x0x7f21b044b3c0) 0
+ primary-for QLayout (0x0x7f21b61305b0)
+ QLayoutItem (0x0x7f21b044b420) 16
+ vptr=((& QFormLayout::_ZTV11QFormLayout) + 264u)
+
+Class QGesture::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGesture::QPrivateSignal (0x0x7f21b0031480) 0 empty
+
+Vtable for QGesture
+QGesture::_ZTV8QGesture: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QGesture)
+16 (int (*)(...))QGesture::metaObject
+24 (int (*)(...))QGesture::qt_metacast
+32 (int (*)(...))QGesture::qt_metacall
+40 (int (*)(...))QGesture::~QGesture
+48 (int (*)(...))QGesture::~QGesture
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QGesture
+ size=16 align=8
+ base size=16 base align=8
+QGesture (0x0x7f21b178f208) 0
+ vptr=((& QGesture::_ZTV8QGesture) + 16u)
+ QObject (0x0x7f21b0502ea0) 0
+ primary-for QGesture (0x0x7f21b178f208)
+
+Class QPanGesture::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPanGesture::QPrivateSignal (0x0x7f21b00315a0) 0 empty
+
+Vtable for QPanGesture
+QPanGesture::_ZTV11QPanGesture: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QPanGesture)
+16 (int (*)(...))QPanGesture::metaObject
+24 (int (*)(...))QPanGesture::qt_metacast
+32 (int (*)(...))QPanGesture::qt_metacall
+40 (int (*)(...))QPanGesture::~QPanGesture
+48 (int (*)(...))QPanGesture::~QPanGesture
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QPanGesture
+ size=16 align=8
+ base size=16 base align=8
+QPanGesture (0x0x7f21b178f2d8) 0
+ vptr=((& QPanGesture::_ZTV11QPanGesture) + 16u)
+ QGesture (0x0x7f21b178f340) 0
+ primary-for QPanGesture (0x0x7f21b178f2d8)
+ QObject (0x0x7f21b00314e0) 0
+ primary-for QGesture (0x0x7f21b178f340)
+
+Class QPinchGesture::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPinchGesture::QPrivateSignal (0x0x7f21b00317e0) 0 empty
+
+Vtable for QPinchGesture
+QPinchGesture::_ZTV13QPinchGesture: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QPinchGesture)
+16 (int (*)(...))QPinchGesture::metaObject
+24 (int (*)(...))QPinchGesture::qt_metacast
+32 (int (*)(...))QPinchGesture::qt_metacall
+40 (int (*)(...))QPinchGesture::~QPinchGesture
+48 (int (*)(...))QPinchGesture::~QPinchGesture
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QPinchGesture
+ size=16 align=8
+ base size=16 base align=8
+QPinchGesture (0x0x7f21b178f680) 0
+ vptr=((& QPinchGesture::_ZTV13QPinchGesture) + 16u)
+ QGesture (0x0x7f21b178f6e8) 0
+ primary-for QPinchGesture (0x0x7f21b178f680)
+ QObject (0x0x7f21b0031780) 0
+ primary-for QGesture (0x0x7f21b178f6e8)
+
+Class QSwipeGesture::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSwipeGesture::QPrivateSignal (0x0x7f21b00bd000) 0 empty
+
+Vtable for QSwipeGesture
+QSwipeGesture::_ZTV13QSwipeGesture: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QSwipeGesture)
+16 (int (*)(...))QSwipeGesture::metaObject
+24 (int (*)(...))QSwipeGesture::qt_metacast
+32 (int (*)(...))QSwipeGesture::qt_metacall
+40 (int (*)(...))QSwipeGesture::~QSwipeGesture
+48 (int (*)(...))QSwipeGesture::~QSwipeGesture
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QSwipeGesture
+ size=16 align=8
+ base size=16 base align=8
+QSwipeGesture (0x0x7f21b17aa0d0) 0
+ vptr=((& QSwipeGesture::_ZTV13QSwipeGesture) + 16u)
+ QGesture (0x0x7f21b17aa138) 0
+ primary-for QSwipeGesture (0x0x7f21b17aa0d0)
+ QObject (0x0x7f21b00972a0) 0
+ primary-for QGesture (0x0x7f21b17aa138)
+
+Class QTapGesture::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTapGesture::QPrivateSignal (0x0x7f21b00bd780) 0 empty
+
+Vtable for QTapGesture
+QTapGesture::_ZTV11QTapGesture: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTapGesture)
+16 (int (*)(...))QTapGesture::metaObject
+24 (int (*)(...))QTapGesture::qt_metacast
+32 (int (*)(...))QTapGesture::qt_metacall
+40 (int (*)(...))QTapGesture::~QTapGesture
+48 (int (*)(...))QTapGesture::~QTapGesture
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QTapGesture
+ size=16 align=8
+ base size=16 base align=8
+QTapGesture (0x0x7f21b17c61a0) 0
+ vptr=((& QTapGesture::_ZTV11QTapGesture) + 16u)
+ QGesture (0x0x7f21b15143a8) 0
+ primary-for QTapGesture (0x0x7f21b17c61a0)
+ QObject (0x0x7f21b00bd720) 0
+ primary-for QGesture (0x0x7f21b15143a8)
+
+Class QTapAndHoldGesture::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTapAndHoldGesture::QPrivateSignal (0x0x7f21b00bdcc0) 0 empty
+
+Vtable for QTapAndHoldGesture
+QTapAndHoldGesture::_ZTV18QTapAndHoldGesture: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QTapAndHoldGesture)
+16 (int (*)(...))QTapAndHoldGesture::metaObject
+24 (int (*)(...))QTapAndHoldGesture::qt_metacast
+32 (int (*)(...))QTapAndHoldGesture::qt_metacall
+40 (int (*)(...))QTapAndHoldGesture::~QTapAndHoldGesture
+48 (int (*)(...))QTapAndHoldGesture::~QTapAndHoldGesture
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QTapAndHoldGesture
+ size=16 align=8
+ base size=16 base align=8
+QTapAndHoldGesture (0x0x7f21b1514410) 0
+ vptr=((& QTapAndHoldGesture::_ZTV18QTapAndHoldGesture) + 16u)
+ QGesture (0x0x7f21b1555a28) 0
+ primary-for QTapAndHoldGesture (0x0x7f21b1514410)
+ QObject (0x0x7f21b00bdc60) 0
+ primary-for QGesture (0x0x7f21b1555a28)
+
+Vtable for QGestureEvent
+QGestureEvent::_ZTV13QGestureEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QGestureEvent)
+16 (int (*)(...))QGestureEvent::~QGestureEvent
+24 (int (*)(...))QGestureEvent::~QGestureEvent
+
+Class QGestureEvent
+ size=56 align=8
+ base size=56 base align=8
+QGestureEvent (0x0x7f21b1555a90) 0
+ vptr=((& QGestureEvent::_ZTV13QGestureEvent) + 16u)
+ QEvent (0x0x7f21b00ec240) 0
+ primary-for QGestureEvent (0x0x7f21b1555a90)
+
+Vtable for QGestureRecognizer
+QGestureRecognizer::_ZTV18QGestureRecognizer: 7u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QGestureRecognizer)
+16 0u
+24 0u
+32 (int (*)(...))QGestureRecognizer::create
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))QGestureRecognizer::reset
+
+Class QGestureRecognizer
+ size=8 align=8
+ base size=8 base align=8
+QGestureRecognizer (0x0x7f21b0112a80) 0 nearly-empty
+ vptr=((& QGestureRecognizer::_ZTV18QGestureRecognizer) + 16u)
+
+Vtable for QGraphicsItem
+QGraphicsItem::_ZTV13QGraphicsItem: 39u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QGraphicsItem)
+16 0u
+24 0u
+32 (int (*)(...))QGraphicsItem::advance
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))QGraphicsItem::shape
+56 (int (*)(...))QGraphicsItem::contains
+64 (int (*)(...))QGraphicsItem::collidesWithItem
+72 (int (*)(...))QGraphicsItem::collidesWithPath
+80 (int (*)(...))QGraphicsItem::isObscuredBy
+88 (int (*)(...))QGraphicsItem::opaqueArea
+96 (int (*)(...))__cxa_pure_virtual
+104 (int (*)(...))QGraphicsItem::type
+112 (int (*)(...))QGraphicsItem::sceneEventFilter
+120 (int (*)(...))QGraphicsItem::sceneEvent
+128 (int (*)(...))QGraphicsItem::contextMenuEvent
+136 (int (*)(...))QGraphicsItem::dragEnterEvent
+144 (int (*)(...))QGraphicsItem::dragLeaveEvent
+152 (int (*)(...))QGraphicsItem::dragMoveEvent
+160 (int (*)(...))QGraphicsItem::dropEvent
+168 (int (*)(...))QGraphicsItem::focusInEvent
+176 (int (*)(...))QGraphicsItem::focusOutEvent
+184 (int (*)(...))QGraphicsItem::hoverEnterEvent
+192 (int (*)(...))QGraphicsItem::hoverMoveEvent
+200 (int (*)(...))QGraphicsItem::hoverLeaveEvent
+208 (int (*)(...))QGraphicsItem::keyPressEvent
+216 (int (*)(...))QGraphicsItem::keyReleaseEvent
+224 (int (*)(...))QGraphicsItem::mousePressEvent
+232 (int (*)(...))QGraphicsItem::mouseMoveEvent
+240 (int (*)(...))QGraphicsItem::mouseReleaseEvent
+248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent
+256 (int (*)(...))QGraphicsItem::wheelEvent
+264 (int (*)(...))QGraphicsItem::inputMethodEvent
+272 (int (*)(...))QGraphicsItem::inputMethodQuery
+280 (int (*)(...))QGraphicsItem::itemChange
+288 (int (*)(...))QGraphicsItem::supportsExtension
+296 (int (*)(...))QGraphicsItem::setExtension
+304 (int (*)(...))QGraphicsItem::extension
+
+Class QGraphicsItem
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsItem (0x0x7f21b0133300) 0
+ vptr=((& QGraphicsItem::_ZTV13QGraphicsItem) + 16u)
+
+Class QGraphicsObject::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsObject::QPrivateSignal (0x0x7f21afe3e7e0) 0 empty
+
+Vtable for QGraphicsObject
+QGraphicsObject::_ZTV15QGraphicsObject: 53u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QGraphicsObject)
+16 (int (*)(...))QGraphicsObject::metaObject
+24 (int (*)(...))QGraphicsObject::qt_metacast
+32 (int (*)(...))QGraphicsObject::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QGraphicsObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))-16
+120 (int (*)(...))(& _ZTI15QGraphicsObject)
+128 0u
+136 0u
+144 (int (*)(...))QGraphicsItem::advance
+152 (int (*)(...))__cxa_pure_virtual
+160 (int (*)(...))QGraphicsItem::shape
+168 (int (*)(...))QGraphicsItem::contains
+176 (int (*)(...))QGraphicsItem::collidesWithItem
+184 (int (*)(...))QGraphicsItem::collidesWithPath
+192 (int (*)(...))QGraphicsItem::isObscuredBy
+200 (int (*)(...))QGraphicsItem::opaqueArea
+208 (int (*)(...))__cxa_pure_virtual
+216 (int (*)(...))QGraphicsItem::type
+224 (int (*)(...))QGraphicsItem::sceneEventFilter
+232 (int (*)(...))QGraphicsItem::sceneEvent
+240 (int (*)(...))QGraphicsItem::contextMenuEvent
+248 (int (*)(...))QGraphicsItem::dragEnterEvent
+256 (int (*)(...))QGraphicsItem::dragLeaveEvent
+264 (int (*)(...))QGraphicsItem::dragMoveEvent
+272 (int (*)(...))QGraphicsItem::dropEvent
+280 (int (*)(...))QGraphicsItem::focusInEvent
+288 (int (*)(...))QGraphicsItem::focusOutEvent
+296 (int (*)(...))QGraphicsItem::hoverEnterEvent
+304 (int (*)(...))QGraphicsItem::hoverMoveEvent
+312 (int (*)(...))QGraphicsItem::hoverLeaveEvent
+320 (int (*)(...))QGraphicsItem::keyPressEvent
+328 (int (*)(...))QGraphicsItem::keyReleaseEvent
+336 (int (*)(...))QGraphicsItem::mousePressEvent
+344 (int (*)(...))QGraphicsItem::mouseMoveEvent
+352 (int (*)(...))QGraphicsItem::mouseReleaseEvent
+360 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent
+368 (int (*)(...))QGraphicsItem::wheelEvent
+376 (int (*)(...))QGraphicsItem::inputMethodEvent
+384 (int (*)(...))QGraphicsItem::inputMethodQuery
+392 (int (*)(...))QGraphicsItem::itemChange
+400 (int (*)(...))QGraphicsItem::supportsExtension
+408 (int (*)(...))QGraphicsItem::setExtension
+416 (int (*)(...))QGraphicsItem::extension
+
+Class QGraphicsObject
+ size=32 align=8
+ base size=32 base align=8
+QGraphicsObject (0x0x7f21b5ead380) 0
+ vptr=((& QGraphicsObject::_ZTV15QGraphicsObject) + 16u)
+ QObject (0x0x7f21afe3e540) 0
+ primary-for QGraphicsObject (0x0x7f21b5ead380)
+ QGraphicsItem (0x0x7f21afe3e600) 16
+ vptr=((& QGraphicsObject::_ZTV15QGraphicsObject) + 128u)
+
+Vtable for QAbstractGraphicsShapeItem
+QAbstractGraphicsShapeItem::_ZTV26QAbstractGraphicsShapeItem: 39u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI26QAbstractGraphicsShapeItem)
+16 0u
+24 0u
+32 (int (*)(...))QGraphicsItem::advance
+40 (int (*)(...))__cxa_pure_virtual
+48 (int (*)(...))QGraphicsItem::shape
+56 (int (*)(...))QGraphicsItem::contains
+64 (int (*)(...))QGraphicsItem::collidesWithItem
+72 (int (*)(...))QGraphicsItem::collidesWithPath
+80 (int (*)(...))QAbstractGraphicsShapeItem::isObscuredBy
+88 (int (*)(...))QAbstractGraphicsShapeItem::opaqueArea
+96 (int (*)(...))__cxa_pure_virtual
+104 (int (*)(...))QGraphicsItem::type
+112 (int (*)(...))QGraphicsItem::sceneEventFilter
+120 (int (*)(...))QGraphicsItem::sceneEvent
+128 (int (*)(...))QGraphicsItem::contextMenuEvent
+136 (int (*)(...))QGraphicsItem::dragEnterEvent
+144 (int (*)(...))QGraphicsItem::dragLeaveEvent
+152 (int (*)(...))QGraphicsItem::dragMoveEvent
+160 (int (*)(...))QGraphicsItem::dropEvent
+168 (int (*)(...))QGraphicsItem::focusInEvent
+176 (int (*)(...))QGraphicsItem::focusOutEvent
+184 (int (*)(...))QGraphicsItem::hoverEnterEvent
+192 (int (*)(...))QGraphicsItem::hoverMoveEvent
+200 (int (*)(...))QGraphicsItem::hoverLeaveEvent
+208 (int (*)(...))QGraphicsItem::keyPressEvent
+216 (int (*)(...))QGraphicsItem::keyReleaseEvent
+224 (int (*)(...))QGraphicsItem::mousePressEvent
+232 (int (*)(...))QGraphicsItem::mouseMoveEvent
+240 (int (*)(...))QGraphicsItem::mouseReleaseEvent
+248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent
+256 (int (*)(...))QGraphicsItem::wheelEvent
+264 (int (*)(...))QGraphicsItem::inputMethodEvent
+272 (int (*)(...))QGraphicsItem::inputMethodQuery
+280 (int (*)(...))QGraphicsItem::itemChange
+288 (int (*)(...))QGraphicsItem::supportsExtension
+296 (int (*)(...))QGraphicsItem::setExtension
+304 (int (*)(...))QGraphicsItem::extension
+
+Class QAbstractGraphicsShapeItem
+ size=16 align=8
+ base size=16 base align=8
+QAbstractGraphicsShapeItem (0x0x7f21b12e8410) 0
+ vptr=((& QAbstractGraphicsShapeItem::_ZTV26QAbstractGraphicsShapeItem) + 16u)
+ QGraphicsItem (0x0x7f21afe3e840) 0
+ primary-for QAbstractGraphicsShapeItem (0x0x7f21b12e8410)
+
+Vtable for QGraphicsPathItem
+QGraphicsPathItem::_ZTV17QGraphicsPathItem: 39u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QGraphicsPathItem)
+16 (int (*)(...))QGraphicsPathItem::~QGraphicsPathItem
+24 (int (*)(...))QGraphicsPathItem::~QGraphicsPathItem
+32 (int (*)(...))QGraphicsItem::advance
+40 (int (*)(...))QGraphicsPathItem::boundingRect
+48 (int (*)(...))QGraphicsPathItem::shape
+56 (int (*)(...))QGraphicsPathItem::contains
+64 (int (*)(...))QGraphicsItem::collidesWithItem
+72 (int (*)(...))QGraphicsItem::collidesWithPath
+80 (int (*)(...))QGraphicsPathItem::isObscuredBy
+88 (int (*)(...))QGraphicsPathItem::opaqueArea
+96 (int (*)(...))QGraphicsPathItem::paint
+104 (int (*)(...))QGraphicsPathItem::type
+112 (int (*)(...))QGraphicsItem::sceneEventFilter
+120 (int (*)(...))QGraphicsItem::sceneEvent
+128 (int (*)(...))QGraphicsItem::contextMenuEvent
+136 (int (*)(...))QGraphicsItem::dragEnterEvent
+144 (int (*)(...))QGraphicsItem::dragLeaveEvent
+152 (int (*)(...))QGraphicsItem::dragMoveEvent
+160 (int (*)(...))QGraphicsItem::dropEvent
+168 (int (*)(...))QGraphicsItem::focusInEvent
+176 (int (*)(...))QGraphicsItem::focusOutEvent
+184 (int (*)(...))QGraphicsItem::hoverEnterEvent
+192 (int (*)(...))QGraphicsItem::hoverMoveEvent
+200 (int (*)(...))QGraphicsItem::hoverLeaveEvent
+208 (int (*)(...))QGraphicsItem::keyPressEvent
+216 (int (*)(...))QGraphicsItem::keyReleaseEvent
+224 (int (*)(...))QGraphicsItem::mousePressEvent
+232 (int (*)(...))QGraphicsItem::mouseMoveEvent
+240 (int (*)(...))QGraphicsItem::mouseReleaseEvent
+248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent
+256 (int (*)(...))QGraphicsItem::wheelEvent
+264 (int (*)(...))QGraphicsItem::inputMethodEvent
+272 (int (*)(...))QGraphicsItem::inputMethodQuery
+280 (int (*)(...))QGraphicsItem::itemChange
+288 (int (*)(...))QGraphicsPathItem::supportsExtension
+296 (int (*)(...))QGraphicsPathItem::setExtension
+304 (int (*)(...))QGraphicsPathItem::extension
+
+Class QGraphicsPathItem
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsPathItem (0x0x7f21b130c1a0) 0
+ vptr=((& QGraphicsPathItem::_ZTV17QGraphicsPathItem) + 16u)
+ QAbstractGraphicsShapeItem (0x0x7f21b130c208) 0
+ primary-for QGraphicsPathItem (0x0x7f21b130c1a0)
+ QGraphicsItem (0x0x7f21afe643c0) 0
+ primary-for QAbstractGraphicsShapeItem (0x0x7f21b130c208)
+
+Vtable for QGraphicsRectItem
+QGraphicsRectItem::_ZTV17QGraphicsRectItem: 39u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QGraphicsRectItem)
+16 (int (*)(...))QGraphicsRectItem::~QGraphicsRectItem
+24 (int (*)(...))QGraphicsRectItem::~QGraphicsRectItem
+32 (int (*)(...))QGraphicsItem::advance
+40 (int (*)(...))QGraphicsRectItem::boundingRect
+48 (int (*)(...))QGraphicsRectItem::shape
+56 (int (*)(...))QGraphicsRectItem::contains
+64 (int (*)(...))QGraphicsItem::collidesWithItem
+72 (int (*)(...))QGraphicsItem::collidesWithPath
+80 (int (*)(...))QGraphicsRectItem::isObscuredBy
+88 (int (*)(...))QGraphicsRectItem::opaqueArea
+96 (int (*)(...))QGraphicsRectItem::paint
+104 (int (*)(...))QGraphicsRectItem::type
+112 (int (*)(...))QGraphicsItem::sceneEventFilter
+120 (int (*)(...))QGraphicsItem::sceneEvent
+128 (int (*)(...))QGraphicsItem::contextMenuEvent
+136 (int (*)(...))QGraphicsItem::dragEnterEvent
+144 (int (*)(...))QGraphicsItem::dragLeaveEvent
+152 (int (*)(...))QGraphicsItem::dragMoveEvent
+160 (int (*)(...))QGraphicsItem::dropEvent
+168 (int (*)(...))QGraphicsItem::focusInEvent
+176 (int (*)(...))QGraphicsItem::focusOutEvent
+184 (int (*)(...))QGraphicsItem::hoverEnterEvent
+192 (int (*)(...))QGraphicsItem::hoverMoveEvent
+200 (int (*)(...))QGraphicsItem::hoverLeaveEvent
+208 (int (*)(...))QGraphicsItem::keyPressEvent
+216 (int (*)(...))QGraphicsItem::keyReleaseEvent
+224 (int (*)(...))QGraphicsItem::mousePressEvent
+232 (int (*)(...))QGraphicsItem::mouseMoveEvent
+240 (int (*)(...))QGraphicsItem::mouseReleaseEvent
+248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent
+256 (int (*)(...))QGraphicsItem::wheelEvent
+264 (int (*)(...))QGraphicsItem::inputMethodEvent
+272 (int (*)(...))QGraphicsItem::inputMethodQuery
+280 (int (*)(...))QGraphicsItem::itemChange
+288 (int (*)(...))QGraphicsRectItem::supportsExtension
+296 (int (*)(...))QGraphicsRectItem::setExtension
+304 (int (*)(...))QGraphicsRectItem::extension
+
+Class QGraphicsRectItem
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsRectItem (0x0x7f21b130cc30) 0
+ vptr=((& QGraphicsRectItem::_ZTV17QGraphicsRectItem) + 16u)
+ QAbstractGraphicsShapeItem (0x0x7f21b130cc98) 0
+ primary-for QGraphicsRectItem (0x0x7f21b130cc30)
+ QGraphicsItem (0x0x7f21afe64420) 0
+ primary-for QAbstractGraphicsShapeItem (0x0x7f21b130cc98)
+
+Vtable for QGraphicsEllipseItem
+QGraphicsEllipseItem::_ZTV20QGraphicsEllipseItem: 39u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QGraphicsEllipseItem)
+16 (int (*)(...))QGraphicsEllipseItem::~QGraphicsEllipseItem
+24 (int (*)(...))QGraphicsEllipseItem::~QGraphicsEllipseItem
+32 (int (*)(...))QGraphicsItem::advance
+40 (int (*)(...))QGraphicsEllipseItem::boundingRect
+48 (int (*)(...))QGraphicsEllipseItem::shape
+56 (int (*)(...))QGraphicsEllipseItem::contains
+64 (int (*)(...))QGraphicsItem::collidesWithItem
+72 (int (*)(...))QGraphicsItem::collidesWithPath
+80 (int (*)(...))QGraphicsEllipseItem::isObscuredBy
+88 (int (*)(...))QGraphicsEllipseItem::opaqueArea
+96 (int (*)(...))QGraphicsEllipseItem::paint
+104 (int (*)(...))QGraphicsEllipseItem::type
+112 (int (*)(...))QGraphicsItem::sceneEventFilter
+120 (int (*)(...))QGraphicsItem::sceneEvent
+128 (int (*)(...))QGraphicsItem::contextMenuEvent
+136 (int (*)(...))QGraphicsItem::dragEnterEvent
+144 (int (*)(...))QGraphicsItem::dragLeaveEvent
+152 (int (*)(...))QGraphicsItem::dragMoveEvent
+160 (int (*)(...))QGraphicsItem::dropEvent
+168 (int (*)(...))QGraphicsItem::focusInEvent
+176 (int (*)(...))QGraphicsItem::focusOutEvent
+184 (int (*)(...))QGraphicsItem::hoverEnterEvent
+192 (int (*)(...))QGraphicsItem::hoverMoveEvent
+200 (int (*)(...))QGraphicsItem::hoverLeaveEvent
+208 (int (*)(...))QGraphicsItem::keyPressEvent
+216 (int (*)(...))QGraphicsItem::keyReleaseEvent
+224 (int (*)(...))QGraphicsItem::mousePressEvent
+232 (int (*)(...))QGraphicsItem::mouseMoveEvent
+240 (int (*)(...))QGraphicsItem::mouseReleaseEvent
+248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent
+256 (int (*)(...))QGraphicsItem::wheelEvent
+264 (int (*)(...))QGraphicsItem::inputMethodEvent
+272 (int (*)(...))QGraphicsItem::inputMethodQuery
+280 (int (*)(...))QGraphicsItem::itemChange
+288 (int (*)(...))QGraphicsEllipseItem::supportsExtension
+296 (int (*)(...))QGraphicsEllipseItem::setExtension
+304 (int (*)(...))QGraphicsEllipseItem::extension
+
+Class QGraphicsEllipseItem
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsEllipseItem (0x0x7f21b130cdd0) 0
+ vptr=((& QGraphicsEllipseItem::_ZTV20QGraphicsEllipseItem) + 16u)
+ QAbstractGraphicsShapeItem (0x0x7f21b1328680) 0
+ primary-for QGraphicsEllipseItem (0x0x7f21b130cdd0)
+ QGraphicsItem (0x0x7f21afe64960) 0
+ primary-for QAbstractGraphicsShapeItem (0x0x7f21b1328680)
+
+Vtable for QGraphicsPolygonItem
+QGraphicsPolygonItem::_ZTV20QGraphicsPolygonItem: 39u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QGraphicsPolygonItem)
+16 (int (*)(...))QGraphicsPolygonItem::~QGraphicsPolygonItem
+24 (int (*)(...))QGraphicsPolygonItem::~QGraphicsPolygonItem
+32 (int (*)(...))QGraphicsItem::advance
+40 (int (*)(...))QGraphicsPolygonItem::boundingRect
+48 (int (*)(...))QGraphicsPolygonItem::shape
+56 (int (*)(...))QGraphicsPolygonItem::contains
+64 (int (*)(...))QGraphicsItem::collidesWithItem
+72 (int (*)(...))QGraphicsItem::collidesWithPath
+80 (int (*)(...))QGraphicsPolygonItem::isObscuredBy
+88 (int (*)(...))QGraphicsPolygonItem::opaqueArea
+96 (int (*)(...))QGraphicsPolygonItem::paint
+104 (int (*)(...))QGraphicsPolygonItem::type
+112 (int (*)(...))QGraphicsItem::sceneEventFilter
+120 (int (*)(...))QGraphicsItem::sceneEvent
+128 (int (*)(...))QGraphicsItem::contextMenuEvent
+136 (int (*)(...))QGraphicsItem::dragEnterEvent
+144 (int (*)(...))QGraphicsItem::dragLeaveEvent
+152 (int (*)(...))QGraphicsItem::dragMoveEvent
+160 (int (*)(...))QGraphicsItem::dropEvent
+168 (int (*)(...))QGraphicsItem::focusInEvent
+176 (int (*)(...))QGraphicsItem::focusOutEvent
+184 (int (*)(...))QGraphicsItem::hoverEnterEvent
+192 (int (*)(...))QGraphicsItem::hoverMoveEvent
+200 (int (*)(...))QGraphicsItem::hoverLeaveEvent
+208 (int (*)(...))QGraphicsItem::keyPressEvent
+216 (int (*)(...))QGraphicsItem::keyReleaseEvent
+224 (int (*)(...))QGraphicsItem::mousePressEvent
+232 (int (*)(...))QGraphicsItem::mouseMoveEvent
+240 (int (*)(...))QGraphicsItem::mouseReleaseEvent
+248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent
+256 (int (*)(...))QGraphicsItem::wheelEvent
+264 (int (*)(...))QGraphicsItem::inputMethodEvent
+272 (int (*)(...))QGraphicsItem::inputMethodQuery
+280 (int (*)(...))QGraphicsItem::itemChange
+288 (int (*)(...))QGraphicsPolygonItem::supportsExtension
+296 (int (*)(...))QGraphicsPolygonItem::setExtension
+304 (int (*)(...))QGraphicsPolygonItem::extension
+
+Class QGraphicsPolygonItem
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsPolygonItem (0x0x7f21b13286e8) 0
+ vptr=((& QGraphicsPolygonItem::_ZTV20QGraphicsPolygonItem) + 16u)
+ QAbstractGraphicsShapeItem (0x0x7f21b1328888) 0
+ primary-for QGraphicsPolygonItem (0x0x7f21b13286e8)
+ QGraphicsItem (0x0x7f21afe649c0) 0
+ primary-for QAbstractGraphicsShapeItem (0x0x7f21b1328888)
+
+Vtable for QGraphicsLineItem
+QGraphicsLineItem::_ZTV17QGraphicsLineItem: 39u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QGraphicsLineItem)
+16 (int (*)(...))QGraphicsLineItem::~QGraphicsLineItem
+24 (int (*)(...))QGraphicsLineItem::~QGraphicsLineItem
+32 (int (*)(...))QGraphicsItem::advance
+40 (int (*)(...))QGraphicsLineItem::boundingRect
+48 (int (*)(...))QGraphicsLineItem::shape
+56 (int (*)(...))QGraphicsLineItem::contains
+64 (int (*)(...))QGraphicsItem::collidesWithItem
+72 (int (*)(...))QGraphicsItem::collidesWithPath
+80 (int (*)(...))QGraphicsLineItem::isObscuredBy
+88 (int (*)(...))QGraphicsLineItem::opaqueArea
+96 (int (*)(...))QGraphicsLineItem::paint
+104 (int (*)(...))QGraphicsLineItem::type
+112 (int (*)(...))QGraphicsItem::sceneEventFilter
+120 (int (*)(...))QGraphicsItem::sceneEvent
+128 (int (*)(...))QGraphicsItem::contextMenuEvent
+136 (int (*)(...))QGraphicsItem::dragEnterEvent
+144 (int (*)(...))QGraphicsItem::dragLeaveEvent
+152 (int (*)(...))QGraphicsItem::dragMoveEvent
+160 (int (*)(...))QGraphicsItem::dropEvent
+168 (int (*)(...))QGraphicsItem::focusInEvent
+176 (int (*)(...))QGraphicsItem::focusOutEvent
+184 (int (*)(...))QGraphicsItem::hoverEnterEvent
+192 (int (*)(...))QGraphicsItem::hoverMoveEvent
+200 (int (*)(...))QGraphicsItem::hoverLeaveEvent
+208 (int (*)(...))QGraphicsItem::keyPressEvent
+216 (int (*)(...))QGraphicsItem::keyReleaseEvent
+224 (int (*)(...))QGraphicsItem::mousePressEvent
+232 (int (*)(...))QGraphicsItem::mouseMoveEvent
+240 (int (*)(...))QGraphicsItem::mouseReleaseEvent
+248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent
+256 (int (*)(...))QGraphicsItem::wheelEvent
+264 (int (*)(...))QGraphicsItem::inputMethodEvent
+272 (int (*)(...))QGraphicsItem::inputMethodQuery
+280 (int (*)(...))QGraphicsItem::itemChange
+288 (int (*)(...))QGraphicsLineItem::supportsExtension
+296 (int (*)(...))QGraphicsLineItem::setExtension
+304 (int (*)(...))QGraphicsLineItem::extension
+
+Class QGraphicsLineItem
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsLineItem (0x0x7f21b1349e38) 0
+ vptr=((& QGraphicsLineItem::_ZTV17QGraphicsLineItem) + 16u)
+ QGraphicsItem (0x0x7f21afe64a80) 0
+ primary-for QGraphicsLineItem (0x0x7f21b1349e38)
+
+Vtable for QGraphicsPixmapItem
+QGraphicsPixmapItem::_ZTV19QGraphicsPixmapItem: 39u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QGraphicsPixmapItem)
+16 (int (*)(...))QGraphicsPixmapItem::~QGraphicsPixmapItem
+24 (int (*)(...))QGraphicsPixmapItem::~QGraphicsPixmapItem
+32 (int (*)(...))QGraphicsItem::advance
+40 (int (*)(...))QGraphicsPixmapItem::boundingRect
+48 (int (*)(...))QGraphicsPixmapItem::shape
+56 (int (*)(...))QGraphicsPixmapItem::contains
+64 (int (*)(...))QGraphicsItem::collidesWithItem
+72 (int (*)(...))QGraphicsItem::collidesWithPath
+80 (int (*)(...))QGraphicsPixmapItem::isObscuredBy
+88 (int (*)(...))QGraphicsPixmapItem::opaqueArea
+96 (int (*)(...))QGraphicsPixmapItem::paint
+104 (int (*)(...))QGraphicsPixmapItem::type
+112 (int (*)(...))QGraphicsItem::sceneEventFilter
+120 (int (*)(...))QGraphicsItem::sceneEvent
+128 (int (*)(...))QGraphicsItem::contextMenuEvent
+136 (int (*)(...))QGraphicsItem::dragEnterEvent
+144 (int (*)(...))QGraphicsItem::dragLeaveEvent
+152 (int (*)(...))QGraphicsItem::dragMoveEvent
+160 (int (*)(...))QGraphicsItem::dropEvent
+168 (int (*)(...))QGraphicsItem::focusInEvent
+176 (int (*)(...))QGraphicsItem::focusOutEvent
+184 (int (*)(...))QGraphicsItem::hoverEnterEvent
+192 (int (*)(...))QGraphicsItem::hoverMoveEvent
+200 (int (*)(...))QGraphicsItem::hoverLeaveEvent
+208 (int (*)(...))QGraphicsItem::keyPressEvent
+216 (int (*)(...))QGraphicsItem::keyReleaseEvent
+224 (int (*)(...))QGraphicsItem::mousePressEvent
+232 (int (*)(...))QGraphicsItem::mouseMoveEvent
+240 (int (*)(...))QGraphicsItem::mouseReleaseEvent
+248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent
+256 (int (*)(...))QGraphicsItem::wheelEvent
+264 (int (*)(...))QGraphicsItem::inputMethodEvent
+272 (int (*)(...))QGraphicsItem::inputMethodQuery
+280 (int (*)(...))QGraphicsItem::itemChange
+288 (int (*)(...))QGraphicsPixmapItem::supportsExtension
+296 (int (*)(...))QGraphicsPixmapItem::setExtension
+304 (int (*)(...))QGraphicsPixmapItem::extension
+
+Class QGraphicsPixmapItem
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsPixmapItem (0x0x7f21b10150d0) 0
+ vptr=((& QGraphicsPixmapItem::_ZTV19QGraphicsPixmapItem) + 16u)
+ QGraphicsItem (0x0x7f21afe64c60) 0
+ primary-for QGraphicsPixmapItem (0x0x7f21b10150d0)
+
+Class QGraphicsTextItem::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsTextItem::QPrivateSignal (0x0x7f21afe83720) 0 empty
+
+Vtable for QGraphicsTextItem
+QGraphicsTextItem::_ZTV17QGraphicsTextItem: 82u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QGraphicsTextItem)
+16 (int (*)(...))QGraphicsTextItem::metaObject
+24 (int (*)(...))QGraphicsTextItem::qt_metacast
+32 (int (*)(...))QGraphicsTextItem::qt_metacall
+40 (int (*)(...))QGraphicsTextItem::~QGraphicsTextItem
+48 (int (*)(...))QGraphicsTextItem::~QGraphicsTextItem
+56 (int (*)(...))QGraphicsObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGraphicsTextItem::boundingRect
+120 (int (*)(...))QGraphicsTextItem::shape
+128 (int (*)(...))QGraphicsTextItem::contains
+136 (int (*)(...))QGraphicsTextItem::paint
+144 (int (*)(...))QGraphicsTextItem::isObscuredBy
+152 (int (*)(...))QGraphicsTextItem::opaqueArea
+160 (int (*)(...))QGraphicsTextItem::type
+168 (int (*)(...))QGraphicsTextItem::sceneEvent
+176 (int (*)(...))QGraphicsTextItem::mousePressEvent
+184 (int (*)(...))QGraphicsTextItem::mouseMoveEvent
+192 (int (*)(...))QGraphicsTextItem::mouseReleaseEvent
+200 (int (*)(...))QGraphicsTextItem::mouseDoubleClickEvent
+208 (int (*)(...))QGraphicsTextItem::contextMenuEvent
+216 (int (*)(...))QGraphicsTextItem::keyPressEvent
+224 (int (*)(...))QGraphicsTextItem::keyReleaseEvent
+232 (int (*)(...))QGraphicsTextItem::focusInEvent
+240 (int (*)(...))QGraphicsTextItem::focusOutEvent
+248 (int (*)(...))QGraphicsTextItem::dragEnterEvent
+256 (int (*)(...))QGraphicsTextItem::dragLeaveEvent
+264 (int (*)(...))QGraphicsTextItem::dragMoveEvent
+272 (int (*)(...))QGraphicsTextItem::dropEvent
+280 (int (*)(...))QGraphicsTextItem::inputMethodEvent
+288 (int (*)(...))QGraphicsTextItem::hoverEnterEvent
+296 (int (*)(...))QGraphicsTextItem::hoverMoveEvent
+304 (int (*)(...))QGraphicsTextItem::hoverLeaveEvent
+312 (int (*)(...))QGraphicsTextItem::inputMethodQuery
+320 (int (*)(...))QGraphicsTextItem::supportsExtension
+328 (int (*)(...))QGraphicsTextItem::setExtension
+336 (int (*)(...))QGraphicsTextItem::extension
+344 (int (*)(...))-16
+352 (int (*)(...))(& _ZTI17QGraphicsTextItem)
+360 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItemD1Ev
+368 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItemD0Ev
+376 (int (*)(...))QGraphicsItem::advance
+384 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem12boundingRectEv
+392 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem5shapeEv
+400 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem8containsERK7QPointF
+408 (int (*)(...))QGraphicsItem::collidesWithItem
+416 (int (*)(...))QGraphicsItem::collidesWithPath
+424 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem12isObscuredByEPK13QGraphicsItem
+432 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem10opaqueAreaEv
+440 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem5paintEP8QPainterPK24QStyleOptionGraphicsItemP7QWidget
+448 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem4typeEv
+456 (int (*)(...))QGraphicsItem::sceneEventFilter
+464 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem10sceneEventEP6QEvent
+472 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem16contextMenuEventEP30QGraphicsSceneContextMenuEvent
+480 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem14dragEnterEventEP27QGraphicsSceneDragDropEvent
+488 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem14dragLeaveEventEP27QGraphicsSceneDragDropEvent
+496 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem13dragMoveEventEP27QGraphicsSceneDragDropEvent
+504 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem9dropEventEP27QGraphicsSceneDragDropEvent
+512 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem12focusInEventEP11QFocusEvent
+520 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem13focusOutEventEP11QFocusEvent
+528 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem15hoverEnterEventEP24QGraphicsSceneHoverEvent
+536 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem14hoverMoveEventEP24QGraphicsSceneHoverEvent
+544 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem15hoverLeaveEventEP24QGraphicsSceneHoverEvent
+552 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem13keyPressEventEP9QKeyEvent
+560 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem15keyReleaseEventEP9QKeyEvent
+568 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem15mousePressEventEP24QGraphicsSceneMouseEvent
+576 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem14mouseMoveEventEP24QGraphicsSceneMouseEvent
+584 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem17mouseReleaseEventEP24QGraphicsSceneMouseEvent
+592 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem21mouseDoubleClickEventEP24QGraphicsSceneMouseEvent
+600 (int (*)(...))QGraphicsItem::wheelEvent
+608 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem16inputMethodEventEP17QInputMethodEvent
+616 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem16inputMethodQueryEN2Qt16InputMethodQueryE
+624 (int (*)(...))QGraphicsItem::itemChange
+632 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem17supportsExtensionEN13QGraphicsItem9ExtensionE
+640 (int (*)(...))QGraphicsTextItem::_ZThn16_N17QGraphicsTextItem12setExtensionEN13QGraphicsItem9ExtensionERK8QVariant
+648 (int (*)(...))QGraphicsTextItem::_ZThn16_NK17QGraphicsTextItem9extensionERK8QVariant
+
+Class QGraphicsTextItem
+ size=40 align=8
+ base size=40 base align=8
+QGraphicsTextItem (0x0x7f21b10157b8) 0
+ vptr=((& QGraphicsTextItem::_ZTV17QGraphicsTextItem) + 16u)
+ QGraphicsObject (0x0x7f21b5ec89a0) 0
+ primary-for QGraphicsTextItem (0x0x7f21b10157b8)
+ QObject (0x0x7f21afe64cc0) 0
+ primary-for QGraphicsObject (0x0x7f21b5ec89a0)
+ QGraphicsItem (0x0x7f21afe836c0) 16
+ vptr=((& QGraphicsTextItem::_ZTV17QGraphicsTextItem) + 360u)
+
+Vtable for QGraphicsSimpleTextItem
+QGraphicsSimpleTextItem::_ZTV23QGraphicsSimpleTextItem: 39u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QGraphicsSimpleTextItem)
+16 (int (*)(...))QGraphicsSimpleTextItem::~QGraphicsSimpleTextItem
+24 (int (*)(...))QGraphicsSimpleTextItem::~QGraphicsSimpleTextItem
+32 (int (*)(...))QGraphicsItem::advance
+40 (int (*)(...))QGraphicsSimpleTextItem::boundingRect
+48 (int (*)(...))QGraphicsSimpleTextItem::shape
+56 (int (*)(...))QGraphicsSimpleTextItem::contains
+64 (int (*)(...))QGraphicsItem::collidesWithItem
+72 (int (*)(...))QGraphicsItem::collidesWithPath
+80 (int (*)(...))QGraphicsSimpleTextItem::isObscuredBy
+88 (int (*)(...))QGraphicsSimpleTextItem::opaqueArea
+96 (int (*)(...))QGraphicsSimpleTextItem::paint
+104 (int (*)(...))QGraphicsSimpleTextItem::type
+112 (int (*)(...))QGraphicsItem::sceneEventFilter
+120 (int (*)(...))QGraphicsItem::sceneEvent
+128 (int (*)(...))QGraphicsItem::contextMenuEvent
+136 (int (*)(...))QGraphicsItem::dragEnterEvent
+144 (int (*)(...))QGraphicsItem::dragLeaveEvent
+152 (int (*)(...))QGraphicsItem::dragMoveEvent
+160 (int (*)(...))QGraphicsItem::dropEvent
+168 (int (*)(...))QGraphicsItem::focusInEvent
+176 (int (*)(...))QGraphicsItem::focusOutEvent
+184 (int (*)(...))QGraphicsItem::hoverEnterEvent
+192 (int (*)(...))QGraphicsItem::hoverMoveEvent
+200 (int (*)(...))QGraphicsItem::hoverLeaveEvent
+208 (int (*)(...))QGraphicsItem::keyPressEvent
+216 (int (*)(...))QGraphicsItem::keyReleaseEvent
+224 (int (*)(...))QGraphicsItem::mousePressEvent
+232 (int (*)(...))QGraphicsItem::mouseMoveEvent
+240 (int (*)(...))QGraphicsItem::mouseReleaseEvent
+248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent
+256 (int (*)(...))QGraphicsItem::wheelEvent
+264 (int (*)(...))QGraphicsItem::inputMethodEvent
+272 (int (*)(...))QGraphicsItem::inputMethodQuery
+280 (int (*)(...))QGraphicsItem::itemChange
+288 (int (*)(...))QGraphicsSimpleTextItem::supportsExtension
+296 (int (*)(...))QGraphicsSimpleTextItem::setExtension
+304 (int (*)(...))QGraphicsSimpleTextItem::extension
+
+Class QGraphicsSimpleTextItem
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsSimpleTextItem (0x0x7f21b0ef92d8) 0
+ vptr=((& QGraphicsSimpleTextItem::_ZTV23QGraphicsSimpleTextItem) + 16u)
+ QAbstractGraphicsShapeItem (0x0x7f21b0ef9340) 0
+ primary-for QGraphicsSimpleTextItem (0x0x7f21b0ef92d8)
+ QGraphicsItem (0x0x7f21aff6f060) 0
+ primary-for QAbstractGraphicsShapeItem (0x0x7f21b0ef9340)
+
+Vtable for QGraphicsItemGroup
+QGraphicsItemGroup::_ZTV18QGraphicsItemGroup: 39u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QGraphicsItemGroup)
+16 (int (*)(...))QGraphicsItemGroup::~QGraphicsItemGroup
+24 (int (*)(...))QGraphicsItemGroup::~QGraphicsItemGroup
+32 (int (*)(...))QGraphicsItem::advance
+40 (int (*)(...))QGraphicsItemGroup::boundingRect
+48 (int (*)(...))QGraphicsItem::shape
+56 (int (*)(...))QGraphicsItem::contains
+64 (int (*)(...))QGraphicsItem::collidesWithItem
+72 (int (*)(...))QGraphicsItem::collidesWithPath
+80 (int (*)(...))QGraphicsItemGroup::isObscuredBy
+88 (int (*)(...))QGraphicsItemGroup::opaqueArea
+96 (int (*)(...))QGraphicsItemGroup::paint
+104 (int (*)(...))QGraphicsItemGroup::type
+112 (int (*)(...))QGraphicsItem::sceneEventFilter
+120 (int (*)(...))QGraphicsItem::sceneEvent
+128 (int (*)(...))QGraphicsItem::contextMenuEvent
+136 (int (*)(...))QGraphicsItem::dragEnterEvent
+144 (int (*)(...))QGraphicsItem::dragLeaveEvent
+152 (int (*)(...))QGraphicsItem::dragMoveEvent
+160 (int (*)(...))QGraphicsItem::dropEvent
+168 (int (*)(...))QGraphicsItem::focusInEvent
+176 (int (*)(...))QGraphicsItem::focusOutEvent
+184 (int (*)(...))QGraphicsItem::hoverEnterEvent
+192 (int (*)(...))QGraphicsItem::hoverMoveEvent
+200 (int (*)(...))QGraphicsItem::hoverLeaveEvent
+208 (int (*)(...))QGraphicsItem::keyPressEvent
+216 (int (*)(...))QGraphicsItem::keyReleaseEvent
+224 (int (*)(...))QGraphicsItem::mousePressEvent
+232 (int (*)(...))QGraphicsItem::mouseMoveEvent
+240 (int (*)(...))QGraphicsItem::mouseReleaseEvent
+248 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent
+256 (int (*)(...))QGraphicsItem::wheelEvent
+264 (int (*)(...))QGraphicsItem::inputMethodEvent
+272 (int (*)(...))QGraphicsItem::inputMethodQuery
+280 (int (*)(...))QGraphicsItem::itemChange
+288 (int (*)(...))QGraphicsItem::supportsExtension
+296 (int (*)(...))QGraphicsItem::setExtension
+304 (int (*)(...))QGraphicsItem::extension
+
+Class QGraphicsItemGroup
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsItemGroup (0x0x7f21b0ef9820) 0
+ vptr=((& QGraphicsItemGroup::_ZTV18QGraphicsItemGroup) + 16u)
+ QGraphicsItem (0x0x7f21aff6f240) 0
+ primary-for QGraphicsItemGroup (0x0x7f21b0ef9820)
+
+Vtable for QGraphicsLayoutItem
+QGraphicsLayoutItem::_ZTV19QGraphicsLayoutItem: 8u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QGraphicsLayoutItem)
+16 0u
+24 0u
+32 (int (*)(...))QGraphicsLayoutItem::setGeometry
+40 (int (*)(...))QGraphicsLayoutItem::getContentsMargins
+48 (int (*)(...))QGraphicsLayoutItem::updateGeometry
+56 (int (*)(...))__cxa_pure_virtual
+
+Class QGraphicsLayoutItem
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsLayoutItem (0x0x7f21afb753c0) 0
+ vptr=((& QGraphicsLayoutItem::_ZTV19QGraphicsLayoutItem) + 16u)
+
+Vtable for QGraphicsLayout
+QGraphicsLayout::_ZTV15QGraphicsLayout: 13u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QGraphicsLayout)
+16 0u
+24 0u
+32 (int (*)(...))QGraphicsLayoutItem::setGeometry
+40 (int (*)(...))QGraphicsLayout::getContentsMargins
+48 (int (*)(...))QGraphicsLayout::updateGeometry
+56 (int (*)(...))__cxa_pure_virtual
+64 (int (*)(...))QGraphicsLayout::invalidate
+72 (int (*)(...))QGraphicsLayout::widgetEvent
+80 (int (*)(...))__cxa_pure_virtual
+88 (int (*)(...))__cxa_pure_virtual
+96 (int (*)(...))__cxa_pure_virtual
+
+Class QGraphicsLayout
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsLayout (0x0x7f21b0ef9888) 0
+ vptr=((& QGraphicsLayout::_ZTV15QGraphicsLayout) + 16u)
+ QGraphicsLayoutItem (0x0x7f21afba20c0) 0
+ primary-for QGraphicsLayout (0x0x7f21b0ef9888)
+
+Class QGraphicsAnchor::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsAnchor::QPrivateSignal (0x0x7f21afba23c0) 0 empty
+
+Vtable for QGraphicsAnchor
+QGraphicsAnchor::_ZTV15QGraphicsAnchor: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QGraphicsAnchor)
+16 (int (*)(...))QGraphicsAnchor::metaObject
+24 (int (*)(...))QGraphicsAnchor::qt_metacast
+32 (int (*)(...))QGraphicsAnchor::qt_metacall
+40 (int (*)(...))QGraphicsAnchor::~QGraphicsAnchor
+48 (int (*)(...))QGraphicsAnchor::~QGraphicsAnchor
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QGraphicsAnchor
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsAnchor (0x0x7f21b0ef9b60) 0
+ vptr=((& QGraphicsAnchor::_ZTV15QGraphicsAnchor) + 16u)
+ QObject (0x0x7f21afba2360) 0
+ primary-for QGraphicsAnchor (0x0x7f21b0ef9b60)
+
+Vtable for QGraphicsAnchorLayout
+QGraphicsAnchorLayout::_ZTV21QGraphicsAnchorLayout: 13u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QGraphicsAnchorLayout)
+16 (int (*)(...))QGraphicsAnchorLayout::~QGraphicsAnchorLayout
+24 (int (*)(...))QGraphicsAnchorLayout::~QGraphicsAnchorLayout
+32 (int (*)(...))QGraphicsAnchorLayout::setGeometry
+40 (int (*)(...))QGraphicsLayout::getContentsMargins
+48 (int (*)(...))QGraphicsLayout::updateGeometry
+56 (int (*)(...))QGraphicsAnchorLayout::sizeHint
+64 (int (*)(...))QGraphicsAnchorLayout::invalidate
+72 (int (*)(...))QGraphicsLayout::widgetEvent
+80 (int (*)(...))QGraphicsAnchorLayout::count
+88 (int (*)(...))QGraphicsAnchorLayout::itemAt
+96 (int (*)(...))QGraphicsAnchorLayout::removeAt
+
+Class QGraphicsAnchorLayout
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsAnchorLayout (0x0x7f21b0ef9bc8) 0
+ vptr=((& QGraphicsAnchorLayout::_ZTV21QGraphicsAnchorLayout) + 16u)
+ QGraphicsLayout (0x0x7f21b0ef9d68) 0
+ primary-for QGraphicsAnchorLayout (0x0x7f21b0ef9bc8)
+ QGraphicsLayoutItem (0x0x7f21af484900) 0
+ primary-for QGraphicsLayout (0x0x7f21b0ef9d68)
+
+Class QGraphicsEffect::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsEffect::QPrivateSignal (0x0x7f21af504420) 0 empty
+
+Vtable for QGraphicsEffect
+QGraphicsEffect::_ZTV15QGraphicsEffect: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QGraphicsEffect)
+16 (int (*)(...))QGraphicsEffect::metaObject
+24 (int (*)(...))QGraphicsEffect::qt_metacast
+32 (int (*)(...))QGraphicsEffect::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGraphicsEffect::boundingRectFor
+120 (int (*)(...))__cxa_pure_virtual
+128 (int (*)(...))QGraphicsEffect::sourceChanged
+
+Class QGraphicsEffect
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsEffect (0x0x7f21b0ef9dd0) 0
+ vptr=((& QGraphicsEffect::_ZTV15QGraphicsEffect) + 16u)
+ QObject (0x0x7f21af484960) 0
+ primary-for QGraphicsEffect (0x0x7f21b0ef9dd0)
+
+Class QGraphicsColorizeEffect::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsColorizeEffect::QPrivateSignal (0x0x7f21af529b40) 0 empty
+
+Vtable for QGraphicsColorizeEffect
+QGraphicsColorizeEffect::_ZTV23QGraphicsColorizeEffect: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QGraphicsColorizeEffect)
+16 (int (*)(...))QGraphicsColorizeEffect::metaObject
+24 (int (*)(...))QGraphicsColorizeEffect::qt_metacast
+32 (int (*)(...))QGraphicsColorizeEffect::qt_metacall
+40 (int (*)(...))QGraphicsColorizeEffect::~QGraphicsColorizeEffect
+48 (int (*)(...))QGraphicsColorizeEffect::~QGraphicsColorizeEffect
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGraphicsEffect::boundingRectFor
+120 (int (*)(...))QGraphicsColorizeEffect::draw
+128 (int (*)(...))QGraphicsEffect::sourceChanged
+
+Class QGraphicsColorizeEffect
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsColorizeEffect (0x0x7f21b0f70068) 0
+ vptr=((& QGraphicsColorizeEffect::_ZTV23QGraphicsColorizeEffect) + 16u)
+ QGraphicsEffect (0x0x7f21b0f70d68) 0
+ primary-for QGraphicsColorizeEffect (0x0x7f21b0f70068)
+ QObject (0x0x7f21af529240) 0
+ primary-for QGraphicsEffect (0x0x7f21b0f70d68)
+
+Class QGraphicsBlurEffect::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsBlurEffect::QPrivateSignal (0x0x7f21af54f840) 0 empty
+
+Vtable for QGraphicsBlurEffect
+QGraphicsBlurEffect::_ZTV19QGraphicsBlurEffect: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QGraphicsBlurEffect)
+16 (int (*)(...))QGraphicsBlurEffect::metaObject
+24 (int (*)(...))QGraphicsBlurEffect::qt_metacast
+32 (int (*)(...))QGraphicsBlurEffect::qt_metacall
+40 (int (*)(...))QGraphicsBlurEffect::~QGraphicsBlurEffect
+48 (int (*)(...))QGraphicsBlurEffect::~QGraphicsBlurEffect
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGraphicsBlurEffect::boundingRectFor
+120 (int (*)(...))QGraphicsBlurEffect::draw
+128 (int (*)(...))QGraphicsEffect::sourceChanged
+
+Class QGraphicsBlurEffect
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsBlurEffect (0x0x7f21b0f70dd0) 0
+ vptr=((& QGraphicsBlurEffect::_ZTV19QGraphicsBlurEffect) + 16u)
+ QGraphicsEffect (0x0x7f21b0f92138) 0
+ primary-for QGraphicsBlurEffect (0x0x7f21b0f70dd0)
+ QObject (0x0x7f21af529ba0) 0
+ primary-for QGraphicsEffect (0x0x7f21b0f92138)
+
+Class QGraphicsDropShadowEffect::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsDropShadowEffect::QPrivateSignal (0x0x7f21af17e9c0) 0 empty
+
+Vtable for QGraphicsDropShadowEffect
+QGraphicsDropShadowEffect::_ZTV25QGraphicsDropShadowEffect: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI25QGraphicsDropShadowEffect)
+16 (int (*)(...))QGraphicsDropShadowEffect::metaObject
+24 (int (*)(...))QGraphicsDropShadowEffect::qt_metacast
+32 (int (*)(...))QGraphicsDropShadowEffect::qt_metacall
+40 (int (*)(...))QGraphicsDropShadowEffect::~QGraphicsDropShadowEffect
+48 (int (*)(...))QGraphicsDropShadowEffect::~QGraphicsDropShadowEffect
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGraphicsDropShadowEffect::boundingRectFor
+120 (int (*)(...))QGraphicsDropShadowEffect::draw
+128 (int (*)(...))QGraphicsEffect::sourceChanged
+
+Class QGraphicsDropShadowEffect
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsDropShadowEffect (0x0x7f21b0f92d68) 0
+ vptr=((& QGraphicsDropShadowEffect::_ZTV25QGraphicsDropShadowEffect) + 16u)
+ QGraphicsEffect (0x0x7f21b0f92e38) 0
+ primary-for QGraphicsDropShadowEffect (0x0x7f21b0f92d68)
+ QObject (0x0x7f21af17e420) 0
+ primary-for QGraphicsEffect (0x0x7f21b0f92e38)
+
+Class QGraphicsOpacityEffect::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsOpacityEffect::QPrivateSignal (0x0x7f21af17ed80) 0 empty
+
+Vtable for QGraphicsOpacityEffect
+QGraphicsOpacityEffect::_ZTV22QGraphicsOpacityEffect: 17u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI22QGraphicsOpacityEffect)
+16 (int (*)(...))QGraphicsOpacityEffect::metaObject
+24 (int (*)(...))QGraphicsOpacityEffect::qt_metacast
+32 (int (*)(...))QGraphicsOpacityEffect::qt_metacall
+40 (int (*)(...))QGraphicsOpacityEffect::~QGraphicsOpacityEffect
+48 (int (*)(...))QGraphicsOpacityEffect::~QGraphicsOpacityEffect
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGraphicsEffect::boundingRectFor
+120 (int (*)(...))QGraphicsOpacityEffect::draw
+128 (int (*)(...))QGraphicsEffect::sourceChanged
+
+Class QGraphicsOpacityEffect
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsOpacityEffect (0x0x7f21b0f92ea0) 0
+ vptr=((& QGraphicsOpacityEffect::_ZTV22QGraphicsOpacityEffect) + 16u)
+ QGraphicsEffect (0x0x7f21b0fb4208) 0
+ primary-for QGraphicsOpacityEffect (0x0x7f21b0f92ea0)
+ QObject (0x0x7f21af17ea20) 0
+ primary-for QGraphicsEffect (0x0x7f21b0fb4208)
+
+Vtable for QGraphicsGridLayout
+QGraphicsGridLayout::_ZTV19QGraphicsGridLayout: 13u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QGraphicsGridLayout)
+16 (int (*)(...))QGraphicsGridLayout::~QGraphicsGridLayout
+24 (int (*)(...))QGraphicsGridLayout::~QGraphicsGridLayout
+32 (int (*)(...))QGraphicsGridLayout::setGeometry
+40 (int (*)(...))QGraphicsLayout::getContentsMargins
+48 (int (*)(...))QGraphicsLayout::updateGeometry
+56 (int (*)(...))QGraphicsGridLayout::sizeHint
+64 (int (*)(...))QGraphicsGridLayout::invalidate
+72 (int (*)(...))QGraphicsLayout::widgetEvent
+80 (int (*)(...))QGraphicsGridLayout::count
+88 (int (*)(...))QGraphicsGridLayout::itemAt
+96 (int (*)(...))QGraphicsGridLayout::removeAt
+
+Class QGraphicsGridLayout
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsGridLayout (0x0x7f21b0fb4270) 0
+ vptr=((& QGraphicsGridLayout::_ZTV19QGraphicsGridLayout) + 16u)
+ QGraphicsLayout (0x0x7f21b0d38750) 0
+ primary-for QGraphicsGridLayout (0x0x7f21b0fb4270)
+ QGraphicsLayoutItem (0x0x7f21af17ede0) 0
+ primary-for QGraphicsLayout (0x0x7f21b0d38750)
+
+Class QGraphicsItemAnimation::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsItemAnimation::QPrivateSignal (0x0x7f21af19d480) 0 empty
+
+Vtable for QGraphicsItemAnimation
+QGraphicsItemAnimation::_ZTV22QGraphicsItemAnimation: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI22QGraphicsItemAnimation)
+16 (int (*)(...))QGraphicsItemAnimation::metaObject
+24 (int (*)(...))QGraphicsItemAnimation::qt_metacast
+32 (int (*)(...))QGraphicsItemAnimation::qt_metacall
+40 (int (*)(...))QGraphicsItemAnimation::~QGraphicsItemAnimation
+48 (int (*)(...))QGraphicsItemAnimation::~QGraphicsItemAnimation
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGraphicsItemAnimation::beforeAnimationStep
+120 (int (*)(...))QGraphicsItemAnimation::afterAnimationStep
+
+Class QGraphicsItemAnimation
+ size=24 align=8
+ base size=24 base align=8
+QGraphicsItemAnimation (0x0x7f21b0d38c98) 0
+ vptr=((& QGraphicsItemAnimation::_ZTV22QGraphicsItemAnimation) + 16u)
+ QObject (0x0x7f21af19d420) 0
+ primary-for QGraphicsItemAnimation (0x0x7f21b0d38c98)
+
+Vtable for QGraphicsLinearLayout
+QGraphicsLinearLayout::_ZTV21QGraphicsLinearLayout: 13u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QGraphicsLinearLayout)
+16 (int (*)(...))QGraphicsLinearLayout::~QGraphicsLinearLayout
+24 (int (*)(...))QGraphicsLinearLayout::~QGraphicsLinearLayout
+32 (int (*)(...))QGraphicsLinearLayout::setGeometry
+40 (int (*)(...))QGraphicsLayout::getContentsMargins
+48 (int (*)(...))QGraphicsLayout::updateGeometry
+56 (int (*)(...))QGraphicsLinearLayout::sizeHint
+64 (int (*)(...))QGraphicsLinearLayout::invalidate
+72 (int (*)(...))QGraphicsLayout::widgetEvent
+80 (int (*)(...))QGraphicsLinearLayout::count
+88 (int (*)(...))QGraphicsLinearLayout::itemAt
+96 (int (*)(...))QGraphicsLinearLayout::removeAt
+
+Class QGraphicsLinearLayout
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsLinearLayout (0x0x7f21b0d38d00) 0
+ vptr=((& QGraphicsLinearLayout::_ZTV21QGraphicsLinearLayout) + 16u)
+ QGraphicsLayout (0x0x7f21b0995000) 0
+ primary-for QGraphicsLinearLayout (0x0x7f21b0d38d00)
+ QGraphicsLayoutItem (0x0x7f21af19d8a0) 0
+ primary-for QGraphicsLayout (0x0x7f21b0995000)
+
+Class QGraphicsWidget::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsWidget::QPrivateSignal (0x0x7f21af22d960) 0 empty
+
+Vtable for QGraphicsWidget
+QGraphicsWidget::_ZTV15QGraphicsWidget: 92u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QGraphicsWidget)
+16 (int (*)(...))QGraphicsWidget::metaObject
+24 (int (*)(...))QGraphicsWidget::qt_metacast
+32 (int (*)(...))QGraphicsWidget::qt_metacall
+40 (int (*)(...))QGraphicsWidget::~QGraphicsWidget
+48 (int (*)(...))QGraphicsWidget::~QGraphicsWidget
+56 (int (*)(...))QGraphicsWidget::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGraphicsWidget::setGeometry
+120 (int (*)(...))QGraphicsWidget::getContentsMargins
+128 (int (*)(...))QGraphicsWidget::type
+136 (int (*)(...))QGraphicsWidget::paint
+144 (int (*)(...))QGraphicsWidget::paintWindowFrame
+152 (int (*)(...))QGraphicsWidget::boundingRect
+160 (int (*)(...))QGraphicsWidget::shape
+168 (int (*)(...))QGraphicsWidget::initStyleOption
+176 (int (*)(...))QGraphicsWidget::sizeHint
+184 (int (*)(...))QGraphicsWidget::updateGeometry
+192 (int (*)(...))QGraphicsWidget::itemChange
+200 (int (*)(...))QGraphicsWidget::propertyChange
+208 (int (*)(...))QGraphicsWidget::sceneEvent
+216 (int (*)(...))QGraphicsWidget::windowFrameEvent
+224 (int (*)(...))QGraphicsWidget::windowFrameSectionAt
+232 (int (*)(...))QGraphicsWidget::changeEvent
+240 (int (*)(...))QGraphicsWidget::closeEvent
+248 (int (*)(...))QGraphicsWidget::focusInEvent
+256 (int (*)(...))QGraphicsWidget::focusNextPrevChild
+264 (int (*)(...))QGraphicsWidget::focusOutEvent
+272 (int (*)(...))QGraphicsWidget::hideEvent
+280 (int (*)(...))QGraphicsWidget::moveEvent
+288 (int (*)(...))QGraphicsWidget::polishEvent
+296 (int (*)(...))QGraphicsWidget::resizeEvent
+304 (int (*)(...))QGraphicsWidget::showEvent
+312 (int (*)(...))QGraphicsWidget::hoverMoveEvent
+320 (int (*)(...))QGraphicsWidget::hoverLeaveEvent
+328 (int (*)(...))QGraphicsWidget::grabMouseEvent
+336 (int (*)(...))QGraphicsWidget::ungrabMouseEvent
+344 (int (*)(...))QGraphicsWidget::grabKeyboardEvent
+352 (int (*)(...))QGraphicsWidget::ungrabKeyboardEvent
+360 (int (*)(...))-16
+368 (int (*)(...))(& _ZTI15QGraphicsWidget)
+376 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidgetD1Ev
+384 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidgetD0Ev
+392 (int (*)(...))QGraphicsItem::advance
+400 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget12boundingRectEv
+408 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget5shapeEv
+416 (int (*)(...))QGraphicsItem::contains
+424 (int (*)(...))QGraphicsItem::collidesWithItem
+432 (int (*)(...))QGraphicsItem::collidesWithPath
+440 (int (*)(...))QGraphicsItem::isObscuredBy
+448 (int (*)(...))QGraphicsItem::opaqueArea
+456 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget5paintEP8QPainterPK24QStyleOptionGraphicsItemP7QWidget
+464 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget4typeEv
+472 (int (*)(...))QGraphicsItem::sceneEventFilter
+480 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget10sceneEventEP6QEvent
+488 (int (*)(...))QGraphicsItem::contextMenuEvent
+496 (int (*)(...))QGraphicsItem::dragEnterEvent
+504 (int (*)(...))QGraphicsItem::dragLeaveEvent
+512 (int (*)(...))QGraphicsItem::dragMoveEvent
+520 (int (*)(...))QGraphicsItem::dropEvent
+528 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget12focusInEventEP11QFocusEvent
+536 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget13focusOutEventEP11QFocusEvent
+544 (int (*)(...))QGraphicsItem::hoverEnterEvent
+552 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget14hoverMoveEventEP24QGraphicsSceneHoverEvent
+560 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget15hoverLeaveEventEP24QGraphicsSceneHoverEvent
+568 (int (*)(...))QGraphicsItem::keyPressEvent
+576 (int (*)(...))QGraphicsItem::keyReleaseEvent
+584 (int (*)(...))QGraphicsItem::mousePressEvent
+592 (int (*)(...))QGraphicsItem::mouseMoveEvent
+600 (int (*)(...))QGraphicsItem::mouseReleaseEvent
+608 (int (*)(...))QGraphicsItem::mouseDoubleClickEvent
+616 (int (*)(...))QGraphicsItem::wheelEvent
+624 (int (*)(...))QGraphicsItem::inputMethodEvent
+632 (int (*)(...))QGraphicsItem::inputMethodQuery
+640 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget10itemChangeEN13QGraphicsItem18GraphicsItemChangeERK8QVariant
+648 (int (*)(...))QGraphicsItem::supportsExtension
+656 (int (*)(...))QGraphicsItem::setExtension
+664 (int (*)(...))QGraphicsItem::extension
+672 (int (*)(...))-32
+680 (int (*)(...))(& _ZTI15QGraphicsWidget)
+688 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidgetD1Ev
+696 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidgetD0Ev
+704 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidget11setGeometryERK6QRectF
+712 (int (*)(...))QGraphicsWidget::_ZThn32_NK15QGraphicsWidget18getContentsMarginsEPdS0_S0_S0_
+720 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidget14updateGeometryEv
+728 (int (*)(...))QGraphicsWidget::_ZThn32_NK15QGraphicsWidget8sizeHintEN2Qt8SizeHintERK6QSizeF
+
+Class QGraphicsWidget
+ size=48 align=8
+ base size=48 base align=8
+QGraphicsWidget (0x0x7f21b5fff0e0) 0
+ vptr=((& QGraphicsWidget::_ZTV15QGraphicsWidget) + 16u)
+ QGraphicsObject (0x0x7f21b5fff1c0) 0
+ primary-for QGraphicsWidget (0x0x7f21b5fff0e0)
+ QObject (0x0x7f21af19d900) 0
+ primary-for QGraphicsObject (0x0x7f21b5fff1c0)
+ QGraphicsItem (0x0x7f21af19dae0) 16
+ vptr=((& QGraphicsWidget::_ZTV15QGraphicsWidget) + 376u)
+ QGraphicsLayoutItem (0x0x7f21af19db40) 32
+ vptr=((& QGraphicsWidget::_ZTV15QGraphicsWidget) + 688u)
+
+Class QGraphicsProxyWidget::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsProxyWidget::QPrivateSignal (0x0x7f21af22dd80) 0 empty
+
+Vtable for QGraphicsProxyWidget
+QGraphicsProxyWidget::_ZTV20QGraphicsProxyWidget: 107u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI20QGraphicsProxyWidget)
+16 (int (*)(...))QGraphicsProxyWidget::metaObject
+24 (int (*)(...))QGraphicsProxyWidget::qt_metacast
+32 (int (*)(...))QGraphicsProxyWidget::qt_metacall
+40 (int (*)(...))QGraphicsProxyWidget::~QGraphicsProxyWidget
+48 (int (*)(...))QGraphicsProxyWidget::~QGraphicsProxyWidget
+56 (int (*)(...))QGraphicsProxyWidget::event
+64 (int (*)(...))QGraphicsProxyWidget::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGraphicsProxyWidget::setGeometry
+120 (int (*)(...))QGraphicsWidget::getContentsMargins
+128 (int (*)(...))QGraphicsProxyWidget::type
+136 (int (*)(...))QGraphicsProxyWidget::paint
+144 (int (*)(...))QGraphicsWidget::paintWindowFrame
+152 (int (*)(...))QGraphicsWidget::boundingRect
+160 (int (*)(...))QGraphicsWidget::shape
+168 (int (*)(...))QGraphicsWidget::initStyleOption
+176 (int (*)(...))QGraphicsProxyWidget::sizeHint
+184 (int (*)(...))QGraphicsWidget::updateGeometry
+192 (int (*)(...))QGraphicsProxyWidget::itemChange
+200 (int (*)(...))QGraphicsWidget::propertyChange
+208 (int (*)(...))QGraphicsWidget::sceneEvent
+216 (int (*)(...))QGraphicsWidget::windowFrameEvent
+224 (int (*)(...))QGraphicsWidget::windowFrameSectionAt
+232 (int (*)(...))QGraphicsWidget::changeEvent
+240 (int (*)(...))QGraphicsWidget::closeEvent
+248 (int (*)(...))QGraphicsProxyWidget::focusInEvent
+256 (int (*)(...))QGraphicsProxyWidget::focusNextPrevChild
+264 (int (*)(...))QGraphicsProxyWidget::focusOutEvent
+272 (int (*)(...))QGraphicsProxyWidget::hideEvent
+280 (int (*)(...))QGraphicsWidget::moveEvent
+288 (int (*)(...))QGraphicsWidget::polishEvent
+296 (int (*)(...))QGraphicsProxyWidget::resizeEvent
+304 (int (*)(...))QGraphicsProxyWidget::showEvent
+312 (int (*)(...))QGraphicsProxyWidget::hoverMoveEvent
+320 (int (*)(...))QGraphicsProxyWidget::hoverLeaveEvent
+328 (int (*)(...))QGraphicsProxyWidget::grabMouseEvent
+336 (int (*)(...))QGraphicsProxyWidget::ungrabMouseEvent
+344 (int (*)(...))QGraphicsWidget::grabKeyboardEvent
+352 (int (*)(...))QGraphicsWidget::ungrabKeyboardEvent
+360 (int (*)(...))QGraphicsProxyWidget::contextMenuEvent
+368 (int (*)(...))QGraphicsProxyWidget::dragEnterEvent
+376 (int (*)(...))QGraphicsProxyWidget::dragLeaveEvent
+384 (int (*)(...))QGraphicsProxyWidget::dragMoveEvent
+392 (int (*)(...))QGraphicsProxyWidget::dropEvent
+400 (int (*)(...))QGraphicsProxyWidget::hoverEnterEvent
+408 (int (*)(...))QGraphicsProxyWidget::mouseMoveEvent
+416 (int (*)(...))QGraphicsProxyWidget::mousePressEvent
+424 (int (*)(...))QGraphicsProxyWidget::mouseReleaseEvent
+432 (int (*)(...))QGraphicsProxyWidget::mouseDoubleClickEvent
+440 (int (*)(...))QGraphicsProxyWidget::wheelEvent
+448 (int (*)(...))QGraphicsProxyWidget::keyPressEvent
+456 (int (*)(...))QGraphicsProxyWidget::keyReleaseEvent
+464 (int (*)(...))QGraphicsProxyWidget::inputMethodQuery
+472 (int (*)(...))QGraphicsProxyWidget::inputMethodEvent
+480 (int (*)(...))-16
+488 (int (*)(...))(& _ZTI20QGraphicsProxyWidget)
+496 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidgetD1Ev
+504 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidgetD0Ev
+512 (int (*)(...))QGraphicsItem::advance
+520 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget12boundingRectEv
+528 (int (*)(...))QGraphicsWidget::_ZThn16_NK15QGraphicsWidget5shapeEv
+536 (int (*)(...))QGraphicsItem::contains
+544 (int (*)(...))QGraphicsItem::collidesWithItem
+552 (int (*)(...))QGraphicsItem::collidesWithPath
+560 (int (*)(...))QGraphicsItem::isObscuredBy
+568 (int (*)(...))QGraphicsItem::opaqueArea
+576 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget5paintEP8QPainterPK24QStyleOptionGraphicsItemP7QWidget
+584 (int (*)(...))QGraphicsProxyWidget::_ZThn16_NK20QGraphicsProxyWidget4typeEv
+592 (int (*)(...))QGraphicsItem::sceneEventFilter
+600 (int (*)(...))QGraphicsWidget::_ZThn16_N15QGraphicsWidget10sceneEventEP6QEvent
+608 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget16contextMenuEventEP30QGraphicsSceneContextMenuEvent
+616 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget14dragEnterEventEP27QGraphicsSceneDragDropEvent
+624 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget14dragLeaveEventEP27QGraphicsSceneDragDropEvent
+632 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget13dragMoveEventEP27QGraphicsSceneDragDropEvent
+640 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget9dropEventEP27QGraphicsSceneDragDropEvent
+648 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget12focusInEventEP11QFocusEvent
+656 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget13focusOutEventEP11QFocusEvent
+664 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget15hoverEnterEventEP24QGraphicsSceneHoverEvent
+672 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget14hoverMoveEventEP24QGraphicsSceneHoverEvent
+680 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget15hoverLeaveEventEP24QGraphicsSceneHoverEvent
+688 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget13keyPressEventEP9QKeyEvent
+696 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget15keyReleaseEventEP9QKeyEvent
+704 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget15mousePressEventEP24QGraphicsSceneMouseEvent
+712 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget14mouseMoveEventEP24QGraphicsSceneMouseEvent
+720 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget17mouseReleaseEventEP24QGraphicsSceneMouseEvent
+728 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget21mouseDoubleClickEventEP24QGraphicsSceneMouseEvent
+736 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget10wheelEventEP24QGraphicsSceneWheelEvent
+744 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget16inputMethodEventEP17QInputMethodEvent
+752 (int (*)(...))QGraphicsProxyWidget::_ZThn16_NK20QGraphicsProxyWidget16inputMethodQueryEN2Qt16InputMethodQueryE
+760 (int (*)(...))QGraphicsProxyWidget::_ZThn16_N20QGraphicsProxyWidget10itemChangeEN13QGraphicsItem18GraphicsItemChangeERK8QVariant
+768 (int (*)(...))QGraphicsItem::supportsExtension
+776 (int (*)(...))QGraphicsItem::setExtension
+784 (int (*)(...))QGraphicsItem::extension
+792 (int (*)(...))-32
+800 (int (*)(...))(& _ZTI20QGraphicsProxyWidget)
+808 (int (*)(...))QGraphicsProxyWidget::_ZThn32_N20QGraphicsProxyWidgetD1Ev
+816 (int (*)(...))QGraphicsProxyWidget::_ZThn32_N20QGraphicsProxyWidgetD0Ev
+824 (int (*)(...))QGraphicsProxyWidget::_ZThn32_N20QGraphicsProxyWidget11setGeometryERK6QRectF
+832 (int (*)(...))QGraphicsWidget::_ZThn32_NK15QGraphicsWidget18getContentsMarginsEPdS0_S0_S0_
+840 (int (*)(...))QGraphicsWidget::_ZThn32_N15QGraphicsWidget14updateGeometryEv
+848 (int (*)(...))QGraphicsProxyWidget::_ZThn32_NK20QGraphicsProxyWidget8sizeHintEN2Qt8SizeHintERK6QSizeF
+
+Class QGraphicsProxyWidget
+ size=48 align=8
+ base size=48 base align=8
+QGraphicsProxyWidget (0x0x7f21b0995270) 0
+ vptr=((& QGraphicsProxyWidget::_ZTV20QGraphicsProxyWidget) + 16u)
+ QGraphicsWidget (0x0x7f21b5ffff50) 0
+ primary-for QGraphicsProxyWidget (0x0x7f21b0995270)
+ QGraphicsObject (0x0x7f21b6004070) 0
+ primary-for QGraphicsWidget (0x0x7f21b5ffff50)
+ QObject (0x0x7f21af22dc00) 0
+ primary-for QGraphicsObject (0x0x7f21b6004070)
+ QGraphicsItem (0x0x7f21af22dc60) 16
+ vptr=((& QGraphicsProxyWidget::_ZTV20QGraphicsProxyWidget) + 496u)
+ QGraphicsLayoutItem (0x0x7f21af22dd20) 32
+ vptr=((& QGraphicsProxyWidget::_ZTV20QGraphicsProxyWidget) + 808u)
+
+Class QGraphicsScene::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsScene::QPrivateSignal (0x0x7f21aeba7060) 0 empty
+
+Vtable for QGraphicsScene
+QGraphicsScene::_ZTV14QGraphicsScene: 34u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QGraphicsScene)
+16 (int (*)(...))QGraphicsScene::metaObject
+24 (int (*)(...))QGraphicsScene::qt_metacast
+32 (int (*)(...))QGraphicsScene::qt_metacall
+40 (int (*)(...))QGraphicsScene::~QGraphicsScene
+48 (int (*)(...))QGraphicsScene::~QGraphicsScene
+56 (int (*)(...))QGraphicsScene::event
+64 (int (*)(...))QGraphicsScene::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGraphicsScene::inputMethodQuery
+120 (int (*)(...))QGraphicsScene::contextMenuEvent
+128 (int (*)(...))QGraphicsScene::dragEnterEvent
+136 (int (*)(...))QGraphicsScene::dragMoveEvent
+144 (int (*)(...))QGraphicsScene::dragLeaveEvent
+152 (int (*)(...))QGraphicsScene::dropEvent
+160 (int (*)(...))QGraphicsScene::focusInEvent
+168 (int (*)(...))QGraphicsScene::focusOutEvent
+176 (int (*)(...))QGraphicsScene::helpEvent
+184 (int (*)(...))QGraphicsScene::keyPressEvent
+192 (int (*)(...))QGraphicsScene::keyReleaseEvent
+200 (int (*)(...))QGraphicsScene::mousePressEvent
+208 (int (*)(...))QGraphicsScene::mouseMoveEvent
+216 (int (*)(...))QGraphicsScene::mouseReleaseEvent
+224 (int (*)(...))QGraphicsScene::mouseDoubleClickEvent
+232 (int (*)(...))QGraphicsScene::wheelEvent
+240 (int (*)(...))QGraphicsScene::inputMethodEvent
+248 (int (*)(...))QGraphicsScene::drawBackground
+256 (int (*)(...))QGraphicsScene::drawForeground
+264 (int (*)(...))QGraphicsScene::drawItems
+
+Class QGraphicsScene
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsScene (0x0x7f21b09b6270) 0
+ vptr=((& QGraphicsScene::_ZTV14QGraphicsScene) + 16u)
+ QObject (0x0x7f21af1012a0) 0
+ primary-for QGraphicsScene (0x0x7f21b09b6270)
+
+Vtable for QGraphicsSceneEvent
+QGraphicsSceneEvent::_ZTV19QGraphicsSceneEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QGraphicsSceneEvent)
+16 (int (*)(...))QGraphicsSceneEvent::~QGraphicsSceneEvent
+24 (int (*)(...))QGraphicsSceneEvent::~QGraphicsSceneEvent
+
+Class QGraphicsSceneEvent
+ size=32 align=8
+ base size=32 base align=8
+QGraphicsSceneEvent (0x0x7f21b09d42d8) 0
+ vptr=((& QGraphicsSceneEvent::_ZTV19QGraphicsSceneEvent) + 16u)
+ QEvent (0x0x7f21aec23d80) 0
+ primary-for QGraphicsSceneEvent (0x0x7f21b09d42d8)
+
+Vtable for QGraphicsSceneMouseEvent
+QGraphicsSceneMouseEvent::_ZTV24QGraphicsSceneMouseEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QGraphicsSceneMouseEvent)
+16 (int (*)(...))QGraphicsSceneMouseEvent::~QGraphicsSceneMouseEvent
+24 (int (*)(...))QGraphicsSceneMouseEvent::~QGraphicsSceneMouseEvent
+
+Class QGraphicsSceneMouseEvent
+ size=32 align=8
+ base size=32 base align=8
+QGraphicsSceneMouseEvent (0x0x7f21b09d4340) 0
+ vptr=((& QGraphicsSceneMouseEvent::_ZTV24QGraphicsSceneMouseEvent) + 16u)
+ QGraphicsSceneEvent (0x0x7f21b09d4680) 0
+ primary-for QGraphicsSceneMouseEvent (0x0x7f21b09d4340)
+ QEvent (0x0x7f21aec23f60) 0
+ primary-for QGraphicsSceneEvent (0x0x7f21b09d4680)
+
+Vtable for QGraphicsSceneWheelEvent
+QGraphicsSceneWheelEvent::_ZTV24QGraphicsSceneWheelEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QGraphicsSceneWheelEvent)
+16 (int (*)(...))QGraphicsSceneWheelEvent::~QGraphicsSceneWheelEvent
+24 (int (*)(...))QGraphicsSceneWheelEvent::~QGraphicsSceneWheelEvent
+
+Class QGraphicsSceneWheelEvent
+ size=32 align=8
+ base size=32 base align=8
+QGraphicsSceneWheelEvent (0x0x7f21b09d46e8) 0
+ vptr=((& QGraphicsSceneWheelEvent::_ZTV24QGraphicsSceneWheelEvent) + 16u)
+ QGraphicsSceneEvent (0x0x7f21b0a4d208) 0
+ primary-for QGraphicsSceneWheelEvent (0x0x7f21b09d46e8)
+ QEvent (0x0x7f21aec6e000) 0
+ primary-for QGraphicsSceneEvent (0x0x7f21b0a4d208)
+
+Vtable for QGraphicsSceneContextMenuEvent
+QGraphicsSceneContextMenuEvent::_ZTV30QGraphicsSceneContextMenuEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI30QGraphicsSceneContextMenuEvent)
+16 (int (*)(...))QGraphicsSceneContextMenuEvent::~QGraphicsSceneContextMenuEvent
+24 (int (*)(...))QGraphicsSceneContextMenuEvent::~QGraphicsSceneContextMenuEvent
+
+Class QGraphicsSceneContextMenuEvent
+ size=32 align=8
+ base size=32 base align=8
+QGraphicsSceneContextMenuEvent (0x0x7f21b0a4d270) 0
+ vptr=((& QGraphicsSceneContextMenuEvent::_ZTV30QGraphicsSceneContextMenuEvent) + 16u)
+ QGraphicsSceneEvent (0x0x7f21b0a4dc98) 0
+ primary-for QGraphicsSceneContextMenuEvent (0x0x7f21b0a4d270)
+ QEvent (0x0x7f21aec6e780) 0
+ primary-for QGraphicsSceneEvent (0x0x7f21b0a4dc98)
+
+Vtable for QGraphicsSceneHoverEvent
+QGraphicsSceneHoverEvent::_ZTV24QGraphicsSceneHoverEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QGraphicsSceneHoverEvent)
+16 (int (*)(...))QGraphicsSceneHoverEvent::~QGraphicsSceneHoverEvent
+24 (int (*)(...))QGraphicsSceneHoverEvent::~QGraphicsSceneHoverEvent
+
+Class QGraphicsSceneHoverEvent
+ size=32 align=8
+ base size=32 base align=8
+QGraphicsSceneHoverEvent (0x0x7f21b0a4dd00) 0
+ vptr=((& QGraphicsSceneHoverEvent::_ZTV24QGraphicsSceneHoverEvent) + 16u)
+ QGraphicsSceneEvent (0x0x7f21b0a996e8) 0
+ primary-for QGraphicsSceneHoverEvent (0x0x7f21b0a4dd00)
+ QEvent (0x0x7f21aec6e7e0) 0
+ primary-for QGraphicsSceneEvent (0x0x7f21b0a996e8)
+
+Vtable for QGraphicsSceneHelpEvent
+QGraphicsSceneHelpEvent::_ZTV23QGraphicsSceneHelpEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QGraphicsSceneHelpEvent)
+16 (int (*)(...))QGraphicsSceneHelpEvent::~QGraphicsSceneHelpEvent
+24 (int (*)(...))QGraphicsSceneHelpEvent::~QGraphicsSceneHelpEvent
+
+Class QGraphicsSceneHelpEvent
+ size=32 align=8
+ base size=32 base align=8
+QGraphicsSceneHelpEvent (0x0x7f21b0a99750) 0
+ vptr=((& QGraphicsSceneHelpEvent::_ZTV23QGraphicsSceneHelpEvent) + 16u)
+ QGraphicsSceneEvent (0x0x7f21b0a997b8) 0
+ primary-for QGraphicsSceneHelpEvent (0x0x7f21b0a99750)
+ QEvent (0x0x7f21aec6e8a0) 0
+ primary-for QGraphicsSceneEvent (0x0x7f21b0a997b8)
+
+Vtable for QGraphicsSceneDragDropEvent
+QGraphicsSceneDragDropEvent::_ZTV27QGraphicsSceneDragDropEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI27QGraphicsSceneDragDropEvent)
+16 (int (*)(...))QGraphicsSceneDragDropEvent::~QGraphicsSceneDragDropEvent
+24 (int (*)(...))QGraphicsSceneDragDropEvent::~QGraphicsSceneDragDropEvent
+
+Class QGraphicsSceneDragDropEvent
+ size=32 align=8
+ base size=32 base align=8
+QGraphicsSceneDragDropEvent (0x0x7f21b0a99820) 0
+ vptr=((& QGraphicsSceneDragDropEvent::_ZTV27QGraphicsSceneDragDropEvent) + 16u)
+ QGraphicsSceneEvent (0x0x7f21b0abe068) 0
+ primary-for QGraphicsSceneDragDropEvent (0x0x7f21b0a99820)
+ QEvent (0x0x7f21aec6e960) 0
+ primary-for QGraphicsSceneEvent (0x0x7f21b0abe068)
+
+Vtable for QGraphicsSceneResizeEvent
+QGraphicsSceneResizeEvent::_ZTV25QGraphicsSceneResizeEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI25QGraphicsSceneResizeEvent)
+16 (int (*)(...))QGraphicsSceneResizeEvent::~QGraphicsSceneResizeEvent
+24 (int (*)(...))QGraphicsSceneResizeEvent::~QGraphicsSceneResizeEvent
+
+Class QGraphicsSceneResizeEvent
+ size=32 align=8
+ base size=32 base align=8
+QGraphicsSceneResizeEvent (0x0x7f21b0abe0d0) 0
+ vptr=((& QGraphicsSceneResizeEvent::_ZTV25QGraphicsSceneResizeEvent) + 16u)
+ QGraphicsSceneEvent (0x0x7f21b0abe270) 0
+ primary-for QGraphicsSceneResizeEvent (0x0x7f21b0abe0d0)
+ QEvent (0x0x7f21aec6ea20) 0
+ primary-for QGraphicsSceneEvent (0x0x7f21b0abe270)
+
+Vtable for QGraphicsSceneMoveEvent
+QGraphicsSceneMoveEvent::_ZTV23QGraphicsSceneMoveEvent: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI23QGraphicsSceneMoveEvent)
+16 (int (*)(...))QGraphicsSceneMoveEvent::~QGraphicsSceneMoveEvent
+24 (int (*)(...))QGraphicsSceneMoveEvent::~QGraphicsSceneMoveEvent
+
+Class QGraphicsSceneMoveEvent
+ size=32 align=8
+ base size=32 base align=8
+QGraphicsSceneMoveEvent (0x0x7f21b0abe2d8) 0
+ vptr=((& QGraphicsSceneMoveEvent::_ZTV23QGraphicsSceneMoveEvent) + 16u)
+ QGraphicsSceneEvent (0x0x7f21b0b05958) 0
+ primary-for QGraphicsSceneMoveEvent (0x0x7f21b0abe2d8)
+ QEvent (0x0x7f21aec6eea0) 0
+ primary-for QGraphicsSceneEvent (0x0x7f21b0b05958)
+
+Class QGraphicsTransform::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsTransform::QPrivateSignal (0x0x7f21aec94180) 0 empty
+
+Vtable for QGraphicsTransform
+QGraphicsTransform::_ZTV18QGraphicsTransform: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QGraphicsTransform)
+16 (int (*)(...))QGraphicsTransform::metaObject
+24 (int (*)(...))QGraphicsTransform::qt_metacast
+32 (int (*)(...))QGraphicsTransform::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+
+Class QGraphicsTransform
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsTransform (0x0x7f21b0b05c30) 0
+ vptr=((& QGraphicsTransform::_ZTV18QGraphicsTransform) + 16u)
+ QObject (0x0x7f21aec6ef00) 0
+ primary-for QGraphicsTransform (0x0x7f21b0b05c30)
+
+Class QGraphicsScale::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsScale::QPrivateSignal (0x0x7f21aec94840) 0 empty
+
+Vtable for QGraphicsScale
+QGraphicsScale::_ZTV14QGraphicsScale: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QGraphicsScale)
+16 (int (*)(...))QGraphicsScale::metaObject
+24 (int (*)(...))QGraphicsScale::qt_metacast
+32 (int (*)(...))QGraphicsScale::qt_metacall
+40 (int (*)(...))QGraphicsScale::~QGraphicsScale
+48 (int (*)(...))QGraphicsScale::~QGraphicsScale
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGraphicsScale::applyTo
+
+Class QGraphicsScale
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsScale (0x0x7f21b0b05e38) 0
+ vptr=((& QGraphicsScale::_ZTV14QGraphicsScale) + 16u)
+ QGraphicsTransform (0x0x7f21b0b05ea0) 0
+ primary-for QGraphicsScale (0x0x7f21b0b05e38)
+ QObject (0x0x7f21aec941e0) 0
+ primary-for QGraphicsTransform (0x0x7f21b0b05ea0)
+
+Class QGraphicsRotation::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsRotation::QPrivateSignal (0x0x7f21aed40780) 0 empty
+
+Vtable for QGraphicsRotation
+QGraphicsRotation::_ZTV17QGraphicsRotation: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI17QGraphicsRotation)
+16 (int (*)(...))QGraphicsRotation::metaObject
+24 (int (*)(...))QGraphicsRotation::qt_metacast
+32 (int (*)(...))QGraphicsRotation::qt_metacall
+40 (int (*)(...))QGraphicsRotation::~QGraphicsRotation
+48 (int (*)(...))QGraphicsRotation::~QGraphicsRotation
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QGraphicsRotation::applyTo
+
+Class QGraphicsRotation
+ size=16 align=8
+ base size=16 base align=8
+QGraphicsRotation (0x0x7f21b0b49618) 0
+ vptr=((& QGraphicsRotation::_ZTV17QGraphicsRotation) + 16u)
+ QGraphicsTransform (0x0x7f21b0b49680) 0
+ primary-for QGraphicsRotation (0x0x7f21b0b49618)
+ QObject (0x0x7f21aec948a0) 0
+ primary-for QGraphicsTransform (0x0x7f21b0b49680)
+
+Class QScrollArea::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QScrollArea::QPrivateSignal (0x0x7f21ae9f58a0) 0 empty
+
+Vtable for QScrollArea
+QScrollArea::_ZTV11QScrollArea: 68u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QScrollArea)
+16 (int (*)(...))QScrollArea::metaObject
+24 (int (*)(...))QScrollArea::qt_metacast
+32 (int (*)(...))QScrollArea::qt_metacall
+40 (int (*)(...))QScrollArea::~QScrollArea
+48 (int (*)(...))QScrollArea::~QScrollArea
+56 (int (*)(...))QScrollArea::event
+64 (int (*)(...))QScrollArea::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QScrollArea::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractScrollArea::mousePressEvent
+176 (int (*)(...))QAbstractScrollArea::mouseReleaseEvent
+184 (int (*)(...))QAbstractScrollArea::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractScrollArea::mouseMoveEvent
+200 (int (*)(...))QAbstractScrollArea::wheelEvent
+208 (int (*)(...))QAbstractScrollArea::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QAbstractScrollArea::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QScrollArea::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QAbstractScrollArea::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QAbstractScrollArea::dragEnterEvent
+320 (int (*)(...))QAbstractScrollArea::dragMoveEvent
+328 (int (*)(...))QAbstractScrollArea::dragLeaveEvent
+336 (int (*)(...))QAbstractScrollArea::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QScrollArea::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QAbstractScrollArea::viewportEvent
+448 (int (*)(...))QScrollArea::scrollContentsBy
+456 (int (*)(...))QScrollArea::viewportSizeHint
+464 (int (*)(...))-16
+472 (int (*)(...))(& _ZTI11QScrollArea)
+480 (int (*)(...))QScrollArea::_ZThn16_N11QScrollAreaD1Ev
+488 (int (*)(...))QScrollArea::_ZThn16_N11QScrollAreaD0Ev
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QScrollArea
+ size=48 align=8
+ base size=48 base align=8
+QScrollArea (0x0x7f21b096a000) 0
+ vptr=((& QScrollArea::_ZTV11QScrollArea) + 16u)
+ QAbstractScrollArea (0x0x7f21b096a068) 0
+ primary-for QScrollArea (0x0x7f21b096a000)
+ QFrame (0x0x7f21b096ac30) 0
+ primary-for QAbstractScrollArea (0x0x7f21b096a068)
+ QWidget (0x0x7f21b5c528c0) 0
+ primary-for QFrame (0x0x7f21b096ac30)
+ QObject (0x0x7f21aed407e0) 0
+ primary-for QWidget (0x0x7f21b5c528c0)
+ QPaintDevice (0x0x7f21ae9f5840) 16
+ vptr=((& QScrollArea::_ZTV11QScrollArea) + 480u)
+
+Class QGraphicsView::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGraphicsView::QPrivateSignal (0x0x7f21ae75c300) 0 empty
+
+Vtable for QGraphicsView
+QGraphicsView::_ZTV13QGraphicsView: 71u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QGraphicsView)
+16 (int (*)(...))QGraphicsView::metaObject
+24 (int (*)(...))QGraphicsView::qt_metacast
+32 (int (*)(...))QGraphicsView::qt_metacall
+40 (int (*)(...))QGraphicsView::~QGraphicsView
+48 (int (*)(...))QGraphicsView::~QGraphicsView
+56 (int (*)(...))QGraphicsView::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QGraphicsView::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QGraphicsView::mousePressEvent
+176 (int (*)(...))QGraphicsView::mouseReleaseEvent
+184 (int (*)(...))QGraphicsView::mouseDoubleClickEvent
+192 (int (*)(...))QGraphicsView::mouseMoveEvent
+200 (int (*)(...))QGraphicsView::wheelEvent
+208 (int (*)(...))QGraphicsView::keyPressEvent
+216 (int (*)(...))QGraphicsView::keyReleaseEvent
+224 (int (*)(...))QGraphicsView::focusInEvent
+232 (int (*)(...))QGraphicsView::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QGraphicsView::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QGraphicsView::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QGraphicsView::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QGraphicsView::dragEnterEvent
+320 (int (*)(...))QGraphicsView::dragMoveEvent
+328 (int (*)(...))QGraphicsView::dragLeaveEvent
+336 (int (*)(...))QGraphicsView::dropEvent
+344 (int (*)(...))QGraphicsView::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QGraphicsView::inputMethodEvent
+416 (int (*)(...))QGraphicsView::inputMethodQuery
+424 (int (*)(...))QGraphicsView::focusNextPrevChild
+432 (int (*)(...))QGraphicsView::setupViewport
+440 (int (*)(...))QGraphicsView::viewportEvent
+448 (int (*)(...))QGraphicsView::scrollContentsBy
+456 (int (*)(...))QAbstractScrollArea::viewportSizeHint
+464 (int (*)(...))QGraphicsView::drawBackground
+472 (int (*)(...))QGraphicsView::drawForeground
+480 (int (*)(...))QGraphicsView::drawItems
+488 (int (*)(...))-16
+496 (int (*)(...))(& _ZTI13QGraphicsView)
+504 (int (*)(...))QGraphicsView::_ZThn16_N13QGraphicsViewD1Ev
+512 (int (*)(...))QGraphicsView::_ZThn16_N13QGraphicsViewD0Ev
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QGraphicsView
+ size=48 align=8
+ base size=48 base align=8
+QGraphicsView (0x0x7f21b096ac98) 0
+ vptr=((& QGraphicsView::_ZTV13QGraphicsView) + 16u)
+ QAbstractScrollArea (0x0x7f21b0988068) 0
+ primary-for QGraphicsView (0x0x7f21b096ac98)
+ QFrame (0x0x7f21b09880d0) 0
+ primary-for QAbstractScrollArea (0x0x7f21b0988068)
+ QWidget (0x0x7f21b5c52ee0) 0
+ primary-for QFrame (0x0x7f21b09880d0)
+ QObject (0x0x7f21aeb0d3c0) 0
+ primary-for QWidget (0x0x7f21b5c52ee0)
+ QPaintDevice (0x0x7f21aeb0d420) 16
+ vptr=((& QGraphicsView::_ZTV13QGraphicsView) + 504u)
+
+Class QGroupBox::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QGroupBox::QPrivateSignal (0x0x7f21ae7f1a80) 0 empty
+
+Vtable for QGroupBox
+QGroupBox::_ZTV9QGroupBox: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QGroupBox)
+16 (int (*)(...))QGroupBox::metaObject
+24 (int (*)(...))QGroupBox::qt_metacast
+32 (int (*)(...))QGroupBox::qt_metacall
+40 (int (*)(...))QGroupBox::~QGroupBox
+48 (int (*)(...))QGroupBox::~QGroupBox
+56 (int (*)(...))QGroupBox::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QGroupBox::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QGroupBox::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QGroupBox::mousePressEvent
+176 (int (*)(...))QGroupBox::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QGroupBox::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QGroupBox::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QGroupBox::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QGroupBox::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QGroupBox::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI9QGroupBox)
+448 (int (*)(...))QGroupBox::_ZThn16_N9QGroupBoxD1Ev
+456 (int (*)(...))QGroupBox::_ZThn16_N9QGroupBoxD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QGroupBox
+ size=48 align=8
+ base size=48 base align=8
+QGroupBox (0x0x7f21b064ed00) 0
+ vptr=((& QGroupBox::_ZTV9QGroupBox) + 16u)
+ QWidget (0x0x7f21b5df1ee0) 0
+ primary-for QGroupBox (0x0x7f21b064ed00)
+ QObject (0x0x7f21ae7f1960) 0
+ primary-for QWidget (0x0x7f21b5df1ee0)
+ QPaintDevice (0x0x7f21ae7f19c0) 16
+ vptr=((& QGroupBox::_ZTV9QGroupBox) + 448u)
+
+Class QHeaderView::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QHeaderView::QPrivateSignal (0x0x7f21ae7f1cc0) 0 empty
+
+Vtable for QHeaderView
+QHeaderView::_ZTV11QHeaderView: 108u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QHeaderView)
+16 (int (*)(...))QHeaderView::metaObject
+24 (int (*)(...))QHeaderView::qt_metacast
+32 (int (*)(...))QHeaderView::qt_metacall
+40 (int (*)(...))QHeaderView::~QHeaderView
+48 (int (*)(...))QHeaderView::~QHeaderView
+56 (int (*)(...))QHeaderView::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QAbstractItemView::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QHeaderView::setVisible
+128 (int (*)(...))QHeaderView::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QHeaderView::mousePressEvent
+176 (int (*)(...))QHeaderView::mouseReleaseEvent
+184 (int (*)(...))QHeaderView::mouseDoubleClickEvent
+192 (int (*)(...))QHeaderView::mouseMoveEvent
+200 (int (*)(...))QAbstractScrollArea::wheelEvent
+208 (int (*)(...))QAbstractItemView::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QAbstractItemView::focusInEvent
+232 (int (*)(...))QAbstractItemView::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QHeaderView::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QAbstractItemView::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QAbstractScrollArea::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QAbstractItemView::dragEnterEvent
+320 (int (*)(...))QAbstractItemView::dragMoveEvent
+328 (int (*)(...))QAbstractItemView::dragLeaveEvent
+336 (int (*)(...))QAbstractItemView::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QAbstractItemView::inputMethodEvent
+416 (int (*)(...))QAbstractItemView::inputMethodQuery
+424 (int (*)(...))QAbstractItemView::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QHeaderView::viewportEvent
+448 (int (*)(...))QHeaderView::scrollContentsBy
+456 (int (*)(...))QAbstractItemView::viewportSizeHint
+464 (int (*)(...))QHeaderView::setModel
+472 (int (*)(...))QAbstractItemView::setSelectionModel
+480 (int (*)(...))QAbstractItemView::keyboardSearch
+488 (int (*)(...))QHeaderView::visualRect
+496 (int (*)(...))QHeaderView::scrollTo
+504 (int (*)(...))QHeaderView::indexAt
+512 (int (*)(...))QAbstractItemView::sizeHintForRow
+520 (int (*)(...))QAbstractItemView::sizeHintForColumn
+528 (int (*)(...))QHeaderView::reset
+536 (int (*)(...))QAbstractItemView::setRootIndex
+544 (int (*)(...))QHeaderView::doItemsLayout
+552 (int (*)(...))QAbstractItemView::selectAll
+560 (int (*)(...))QHeaderView::dataChanged
+568 (int (*)(...))QHeaderView::rowsInserted
+576 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved
+584 (int (*)(...))QAbstractItemView::selectionChanged
+592 (int (*)(...))QHeaderView::currentChanged
+600 (int (*)(...))QAbstractItemView::updateEditorData
+608 (int (*)(...))QAbstractItemView::updateEditorGeometries
+616 (int (*)(...))QHeaderView::updateGeometries
+624 (int (*)(...))QAbstractItemView::verticalScrollbarAction
+632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction
+640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged
+648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged
+656 (int (*)(...))QAbstractItemView::closeEditor
+664 (int (*)(...))QAbstractItemView::commitData
+672 (int (*)(...))QAbstractItemView::editorDestroyed
+680 (int (*)(...))QHeaderView::moveCursor
+688 (int (*)(...))QHeaderView::horizontalOffset
+696 (int (*)(...))QHeaderView::verticalOffset
+704 (int (*)(...))QHeaderView::isIndexHidden
+712 (int (*)(...))QHeaderView::setSelection
+720 (int (*)(...))QHeaderView::visualRegionForSelection
+728 (int (*)(...))QAbstractItemView::selectedIndexes
+736 (int (*)(...))QAbstractItemView::edit
+744 (int (*)(...))QAbstractItemView::selectionCommand
+752 (int (*)(...))QAbstractItemView::startDrag
+760 (int (*)(...))QAbstractItemView::viewOptions
+768 (int (*)(...))QHeaderView::paintSection
+776 (int (*)(...))QHeaderView::sectionSizeFromContents
+784 (int (*)(...))-16
+792 (int (*)(...))(& _ZTI11QHeaderView)
+800 (int (*)(...))QHeaderView::_ZThn16_N11QHeaderViewD1Ev
+808 (int (*)(...))QHeaderView::_ZThn16_N11QHeaderViewD0Ev
+816 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+832 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+840 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+848 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+856 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QHeaderView
+ size=48 align=8
+ base size=48 base align=8
+QHeaderView (0x0x7f21b064edd0) 0
+ vptr=((& QHeaderView::_ZTV11QHeaderView) + 16u)
+ QAbstractItemView (0x0x7f21b064eea0) 0
+ primary-for QHeaderView (0x0x7f21b064edd0)
+ QAbstractScrollArea (0x0x7f21b0670068) 0
+ primary-for QAbstractItemView (0x0x7f21b064eea0)
+ QFrame (0x0x7f21b0670410) 0
+ primary-for QAbstractScrollArea (0x0x7f21b0670068)
+ QWidget (0x0x7f21b5e05540) 0
+ primary-for QFrame (0x0x7f21b0670410)
+ QObject (0x0x7f21ae7f1ae0) 0
+ primary-for QWidget (0x0x7f21b5e05540)
+ QPaintDevice (0x0x7f21ae7f1b40) 16
+ vptr=((& QHeaderView::_ZTV11QHeaderView) + 800u)
+
+Class QLineEdit::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QLineEdit::QPrivateSignal (0x0x7f21ae74b3c0) 0 empty
+
+Vtable for QLineEdit
+QLineEdit::_ZTV9QLineEdit: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QLineEdit)
+16 (int (*)(...))QLineEdit::metaObject
+24 (int (*)(...))QLineEdit::qt_metacast
+32 (int (*)(...))QLineEdit::qt_metacall
+40 (int (*)(...))QLineEdit::~QLineEdit
+48 (int (*)(...))QLineEdit::~QLineEdit
+56 (int (*)(...))QLineEdit::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QLineEdit::sizeHint
+136 (int (*)(...))QLineEdit::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QLineEdit::mousePressEvent
+176 (int (*)(...))QLineEdit::mouseReleaseEvent
+184 (int (*)(...))QLineEdit::mouseDoubleClickEvent
+192 (int (*)(...))QLineEdit::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QLineEdit::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QLineEdit::focusInEvent
+232 (int (*)(...))QLineEdit::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QLineEdit::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QLineEdit::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QLineEdit::dragEnterEvent
+320 (int (*)(...))QLineEdit::dragMoveEvent
+328 (int (*)(...))QLineEdit::dragLeaveEvent
+336 (int (*)(...))QLineEdit::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QLineEdit::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QLineEdit::inputMethodEvent
+416 (int (*)(...))QLineEdit::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI9QLineEdit)
+448 (int (*)(...))QLineEdit::_ZThn16_N9QLineEditD1Ev
+456 (int (*)(...))QLineEdit::_ZThn16_N9QLineEditD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QLineEdit
+ size=48 align=8
+ base size=48 base align=8
+QLineEdit (0x0x7f21b04a3f70) 0
+ vptr=((& QLineEdit::_ZTV9QLineEdit) + 16u)
+ QWidget (0x0x7f21b5e17bd0) 0
+ primary-for QLineEdit (0x0x7f21b04a3f70)
+ QObject (0x0x7f21ae604a80) 0
+ primary-for QWidget (0x0x7f21b5e17bd0)
+ QPaintDevice (0x0x7f21ae604ae0) 16
+ vptr=((& QLineEdit::_ZTV9QLineEdit) + 448u)
+
+Class QInputDialog::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QInputDialog::QPrivateSignal (0x0x7f21ae3960c0) 0 empty
+
+Vtable for QInputDialog
+QInputDialog::_ZTV12QInputDialog: 69u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QInputDialog)
+16 (int (*)(...))QInputDialog::metaObject
+24 (int (*)(...))QInputDialog::qt_metacast
+32 (int (*)(...))QInputDialog::qt_metacall
+40 (int (*)(...))QInputDialog::~QInputDialog
+48 (int (*)(...))QInputDialog::~QInputDialog
+56 (int (*)(...))QWidget::event
+64 (int (*)(...))QDialog::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QInputDialog::setVisible
+128 (int (*)(...))QInputDialog::sizeHint
+136 (int (*)(...))QInputDialog::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QDialog::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QDialog::resizeEvent
+280 (int (*)(...))QDialog::closeEvent
+288 (int (*)(...))QDialog::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QDialog::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QDialog::open
+440 (int (*)(...))QDialog::exec
+448 (int (*)(...))QInputDialog::done
+456 (int (*)(...))QDialog::accept
+464 (int (*)(...))QDialog::reject
+472 (int (*)(...))-16
+480 (int (*)(...))(& _ZTI12QInputDialog)
+488 (int (*)(...))QInputDialog::_ZThn16_N12QInputDialogD1Ev
+496 (int (*)(...))QInputDialog::_ZThn16_N12QInputDialogD0Ev
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QInputDialog
+ size=48 align=8
+ base size=48 base align=8
+QInputDialog (0x0x7f21b02321a0) 0
+ vptr=((& QInputDialog::_ZTV12QInputDialog) + 16u)
+ QDialog (0x0x7f21b0232340) 0
+ primary-for QInputDialog (0x0x7f21b02321a0)
+ QWidget (0x0x7f21b5e23930) 0
+ primary-for QDialog (0x0x7f21b0232340)
+ QObject (0x0x7f21ae74b420) 0
+ primary-for QWidget (0x0x7f21b5e23930)
+ QPaintDevice (0x0x7f21ae396060) 16
+ vptr=((& QInputDialog::_ZTV12QInputDialog) + 488u)
+
+Class QItemDelegate::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QItemDelegate::QPrivateSignal (0x0x7f21ae40c7e0) 0 empty
+
+Vtable for QItemDelegate
+QItemDelegate::_ZTV13QItemDelegate: 28u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QItemDelegate)
+16 (int (*)(...))QItemDelegate::metaObject
+24 (int (*)(...))QItemDelegate::qt_metacast
+32 (int (*)(...))QItemDelegate::qt_metacall
+40 (int (*)(...))QItemDelegate::~QItemDelegate
+48 (int (*)(...))QItemDelegate::~QItemDelegate
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QItemDelegate::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QItemDelegate::paint
+120 (int (*)(...))QItemDelegate::sizeHint
+128 (int (*)(...))QItemDelegate::createEditor
+136 (int (*)(...))QAbstractItemDelegate::destroyEditor
+144 (int (*)(...))QItemDelegate::setEditorData
+152 (int (*)(...))QItemDelegate::setModelData
+160 (int (*)(...))QItemDelegate::updateEditorGeometry
+168 (int (*)(...))QItemDelegate::editorEvent
+176 (int (*)(...))QAbstractItemDelegate::helpEvent
+184 (int (*)(...))QAbstractItemDelegate::paintingRoles
+192 (int (*)(...))QItemDelegate::drawDisplay
+200 (int (*)(...))QItemDelegate::drawDecoration
+208 (int (*)(...))QItemDelegate::drawFocus
+216 (int (*)(...))QItemDelegate::drawCheck
+
+Class QItemDelegate
+ size=16 align=8
+ base size=16 base align=8
+QItemDelegate (0x0x7f21b02bb888) 0
+ vptr=((& QItemDelegate::_ZTV13QItemDelegate) + 16u)
+ QAbstractItemDelegate (0x0x7f21b02bb8f0) 0
+ primary-for QItemDelegate (0x0x7f21b02bb888)
+ QObject (0x0x7f21ae40c780) 0
+ primary-for QAbstractItemDelegate (0x0x7f21b02bb8f0)
+
+Vtable for QItemEditorCreatorBase
+QItemEditorCreatorBase::_ZTV22QItemEditorCreatorBase: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI22QItemEditorCreatorBase)
+16 0u
+24 0u
+32 (int (*)(...))__cxa_pure_virtual
+40 (int (*)(...))__cxa_pure_virtual
+
+Class QItemEditorCreatorBase
+ size=8 align=8
+ base size=8 base align=8
+QItemEditorCreatorBase (0x0x7f21ae449000) 0 nearly-empty
+ vptr=((& QItemEditorCreatorBase::_ZTV22QItemEditorCreatorBase) + 16u)
+
+Vtable for QItemEditorFactory
+QItemEditorFactory::_ZTV18QItemEditorFactory: 6u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI18QItemEditorFactory)
+16 (int (*)(...))QItemEditorFactory::~QItemEditorFactory
+24 (int (*)(...))QItemEditorFactory::~QItemEditorFactory
+32 (int (*)(...))QItemEditorFactory::createEditor
+40 (int (*)(...))QItemEditorFactory::valuePropertyName
+
+Class QItemEditorFactory
+ size=16 align=8
+ base size=16 base align=8
+QItemEditorFactory (0x0x7f21ae206540) 0
+ vptr=((& QItemEditorFactory::_ZTV18QItemEditorFactory) + 16u)
+
+Class QKeyEventTransition::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QKeyEventTransition::QPrivateSignal (0x0x7f21ae206f60) 0 empty
+
+Vtable for QKeyEventTransition
+QKeyEventTransition::_ZTV19QKeyEventTransition: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QKeyEventTransition)
+16 (int (*)(...))QKeyEventTransition::metaObject
+24 (int (*)(...))QKeyEventTransition::qt_metacast
+32 (int (*)(...))QKeyEventTransition::qt_metacall
+40 (int (*)(...))QKeyEventTransition::~QKeyEventTransition
+48 (int (*)(...))QKeyEventTransition::~QKeyEventTransition
+56 (int (*)(...))QEventTransition::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QKeyEventTransition::eventTest
+120 (int (*)(...))QKeyEventTransition::onTransition
+
+Class QKeyEventTransition
+ size=16 align=8
+ base size=16 base align=8
+QKeyEventTransition (0x0x7f21b02bbc98) 0
+ vptr=((& QKeyEventTransition::_ZTV19QKeyEventTransition) + 16u)
+ QEventTransition (0x0x7f21b03824e0) 0
+ primary-for QKeyEventTransition (0x0x7f21b02bbc98)
+ QAbstractTransition (0x0x7f21b005e3a8) 0
+ primary-for QEventTransition (0x0x7f21b03824e0)
+ QObject (0x0x7f21ae206ea0) 0
+ primary-for QAbstractTransition (0x0x7f21b005e3a8)
+
+Class QKeySequenceEdit::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QKeySequenceEdit::QPrivateSignal (0x0x7f21ae262ba0) 0 empty
+
+Vtable for QKeySequenceEdit
+QKeySequenceEdit::_ZTV16QKeySequenceEdit: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QKeySequenceEdit)
+16 (int (*)(...))QKeySequenceEdit::metaObject
+24 (int (*)(...))QKeySequenceEdit::qt_metacast
+32 (int (*)(...))QKeySequenceEdit::qt_metacall
+40 (int (*)(...))QKeySequenceEdit::~QKeySequenceEdit
+48 (int (*)(...))QKeySequenceEdit::~QKeySequenceEdit
+56 (int (*)(...))QKeySequenceEdit::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QKeySequenceEdit::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QKeySequenceEdit::keyPressEvent
+216 (int (*)(...))QKeySequenceEdit::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI16QKeySequenceEdit)
+448 (int (*)(...))QKeySequenceEdit::_ZThn16_N16QKeySequenceEditD1Ev
+456 (int (*)(...))QKeySequenceEdit::_ZThn16_N16QKeySequenceEditD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QKeySequenceEdit
+ size=48 align=8
+ base size=48 base align=8
+QKeySequenceEdit (0x0x7f21b005e410) 0
+ vptr=((& QKeySequenceEdit::_ZTV16QKeySequenceEdit) + 16u)
+ QWidget (0x0x7f21b5b66e70) 0
+ primary-for QKeySequenceEdit (0x0x7f21b005e410)
+ QObject (0x0x7f21ae262180) 0
+ primary-for QWidget (0x0x7f21b5b66e70)
+ QPaintDevice (0x0x7f21ae2621e0) 16
+ vptr=((& QKeySequenceEdit::_ZTV16QKeySequenceEdit) + 448u)
+
+Class QLabel::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QLabel::QPrivateSignal (0x0x7f21ae262d80) 0 empty
+
+Vtable for QLabel
+QLabel::_ZTV6QLabel: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI6QLabel)
+16 (int (*)(...))QLabel::metaObject
+24 (int (*)(...))QLabel::qt_metacast
+32 (int (*)(...))QLabel::qt_metacall
+40 (int (*)(...))QLabel::~QLabel
+48 (int (*)(...))QLabel::~QLabel
+56 (int (*)(...))QLabel::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QLabel::sizeHint
+136 (int (*)(...))QLabel::minimumSizeHint
+144 (int (*)(...))QLabel::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QLabel::mousePressEvent
+176 (int (*)(...))QLabel::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QLabel::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QLabel::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QLabel::focusInEvent
+232 (int (*)(...))QLabel::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QLabel::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QLabel::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QLabel::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QLabel::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI6QLabel)
+448 (int (*)(...))QLabel::_ZThn16_N6QLabelD1Ev
+456 (int (*)(...))QLabel::_ZThn16_N6QLabelD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QLabel
+ size=48 align=8
+ base size=48 base align=8
+QLabel (0x0x7f21b005eb60) 0
+ vptr=((& QLabel::_ZTV6QLabel) + 16u)
+ QFrame (0x0x7f21b005ebc8) 0
+ primary-for QLabel (0x0x7f21b005eb60)
+ QWidget (0x0x7f21b5b72460) 0
+ primary-for QFrame (0x0x7f21b005ebc8)
+ QObject (0x0x7f21ae262c00) 0
+ primary-for QWidget (0x0x7f21b5b72460)
+ QPaintDevice (0x0x7f21ae262d20) 16
+ vptr=((& QLabel::_ZTV6QLabel) + 448u)
+
+Class QLCDNumber::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QLCDNumber::QPrivateSignal (0x0x7f21ae285960) 0 empty
+
+Vtable for QLCDNumber
+QLCDNumber::_ZTV10QLCDNumber: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QLCDNumber)
+16 (int (*)(...))QLCDNumber::metaObject
+24 (int (*)(...))QLCDNumber::qt_metacast
+32 (int (*)(...))QLCDNumber::qt_metacall
+40 (int (*)(...))QLCDNumber::~QLCDNumber
+48 (int (*)(...))QLCDNumber::~QLCDNumber
+56 (int (*)(...))QLCDNumber::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QLCDNumber::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QLCDNumber::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI10QLCDNumber)
+448 (int (*)(...))QLCDNumber::_ZThn16_N10QLCDNumberD1Ev
+456 (int (*)(...))QLCDNumber::_ZThn16_N10QLCDNumberD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QLCDNumber
+ size=48 align=8
+ base size=48 base align=8
+QLCDNumber (0x0x7f21b005ed68) 0
+ vptr=((& QLCDNumber::_ZTV10QLCDNumber) + 16u)
+ QFrame (0x0x7f21b005ef70) 0
+ primary-for QLCDNumber (0x0x7f21b005ed68)
+ QWidget (0x0x7f21b5b72af0) 0
+ primary-for QFrame (0x0x7f21b005ef70)
+ QObject (0x0x7f21ae285000) 0
+ primary-for QWidget (0x0x7f21b5b72af0)
+ QPaintDevice (0x0x7f21ae285060) 16
+ vptr=((& QLCDNumber::_ZTV10QLCDNumber) + 448u)
+
+Class QListView::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QListView::QPrivateSignal (0x0x7f21ae285d20) 0 empty
+
+Vtable for QListView
+QListView::_ZTV9QListView: 106u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QListView)
+16 (int (*)(...))QListView::metaObject
+24 (int (*)(...))QListView::qt_metacast
+32 (int (*)(...))QListView::qt_metacall
+40 (int (*)(...))QListView::~QListView
+48 (int (*)(...))QListView::~QListView
+56 (int (*)(...))QListView::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QListView::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractScrollArea::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractItemView::mousePressEvent
+176 (int (*)(...))QListView::mouseReleaseEvent
+184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent
+192 (int (*)(...))QListView::mouseMoveEvent
+200 (int (*)(...))QListView::wheelEvent
+208 (int (*)(...))QAbstractItemView::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QAbstractItemView::focusInEvent
+232 (int (*)(...))QAbstractItemView::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QListView::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QListView::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QAbstractScrollArea::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QAbstractItemView::dragEnterEvent
+320 (int (*)(...))QListView::dragMoveEvent
+328 (int (*)(...))QListView::dragLeaveEvent
+336 (int (*)(...))QListView::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QAbstractItemView::inputMethodEvent
+416 (int (*)(...))QAbstractItemView::inputMethodQuery
+424 (int (*)(...))QAbstractItemView::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QAbstractItemView::viewportEvent
+448 (int (*)(...))QListView::scrollContentsBy
+456 (int (*)(...))QListView::viewportSizeHint
+464 (int (*)(...))QAbstractItemView::setModel
+472 (int (*)(...))QAbstractItemView::setSelectionModel
+480 (int (*)(...))QAbstractItemView::keyboardSearch
+488 (int (*)(...))QListView::visualRect
+496 (int (*)(...))QListView::scrollTo
+504 (int (*)(...))QListView::indexAt
+512 (int (*)(...))QAbstractItemView::sizeHintForRow
+520 (int (*)(...))QAbstractItemView::sizeHintForColumn
+528 (int (*)(...))QListView::reset
+536 (int (*)(...))QListView::setRootIndex
+544 (int (*)(...))QListView::doItemsLayout
+552 (int (*)(...))QAbstractItemView::selectAll
+560 (int (*)(...))QListView::dataChanged
+568 (int (*)(...))QListView::rowsInserted
+576 (int (*)(...))QListView::rowsAboutToBeRemoved
+584 (int (*)(...))QListView::selectionChanged
+592 (int (*)(...))QListView::currentChanged
+600 (int (*)(...))QAbstractItemView::updateEditorData
+608 (int (*)(...))QAbstractItemView::updateEditorGeometries
+616 (int (*)(...))QListView::updateGeometries
+624 (int (*)(...))QAbstractItemView::verticalScrollbarAction
+632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction
+640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged
+648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged
+656 (int (*)(...))QAbstractItemView::closeEditor
+664 (int (*)(...))QAbstractItemView::commitData
+672 (int (*)(...))QAbstractItemView::editorDestroyed
+680 (int (*)(...))QListView::moveCursor
+688 (int (*)(...))QListView::horizontalOffset
+696 (int (*)(...))QListView::verticalOffset
+704 (int (*)(...))QListView::isIndexHidden
+712 (int (*)(...))QListView::setSelection
+720 (int (*)(...))QListView::visualRegionForSelection
+728 (int (*)(...))QListView::selectedIndexes
+736 (int (*)(...))QAbstractItemView::edit
+744 (int (*)(...))QAbstractItemView::selectionCommand
+752 (int (*)(...))QListView::startDrag
+760 (int (*)(...))QListView::viewOptions
+768 (int (*)(...))-16
+776 (int (*)(...))(& _ZTI9QListView)
+784 (int (*)(...))QListView::_ZThn16_N9QListViewD1Ev
+792 (int (*)(...))QListView::_ZThn16_N9QListViewD0Ev
+800 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+808 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+816 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+832 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+840 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QListView
+ size=48 align=8
+ base size=48 base align=8
+QListView (0x0x7f21b007e000) 0
+ vptr=((& QListView::_ZTV9QListView) + 16u)
+ QAbstractItemView (0x0x7f21b007eea0) 0
+ primary-for QListView (0x0x7f21b007e000)
+ QAbstractScrollArea (0x0x7f21b007ef08) 0
+ primary-for QAbstractItemView (0x0x7f21b007eea0)
+ QFrame (0x0x7f21b009e680) 0
+ primary-for QAbstractScrollArea (0x0x7f21b007ef08)
+ QWidget (0x0x7f21b5b7e7e0) 0
+ primary-for QFrame (0x0x7f21b009e680)
+ QObject (0x0x7f21ae2859c0) 0
+ primary-for QWidget (0x0x7f21b5b7e7e0)
+ QPaintDevice (0x0x7f21ae285cc0) 16
+ vptr=((& QListView::_ZTV9QListView) + 784u)
+
+Vtable for QListWidgetItem
+QListWidgetItem::_ZTV15QListWidgetItem: 11u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QListWidgetItem)
+16 (int (*)(...))QListWidgetItem::~QListWidgetItem
+24 (int (*)(...))QListWidgetItem::~QListWidgetItem
+32 (int (*)(...))QListWidgetItem::clone
+40 (int (*)(...))QListWidgetItem::setBackgroundColor
+48 (int (*)(...))QListWidgetItem::data
+56 (int (*)(...))QListWidgetItem::setData
+64 (int (*)(...))QListWidgetItem::operator<
+72 (int (*)(...))QListWidgetItem::read
+80 (int (*)(...))QListWidgetItem::write
+
+Class QListWidgetItem
+ size=48 align=8
+ base size=44 base align=8
+QListWidgetItem (0x0x7f21add9dea0) 0
+ vptr=((& QListWidgetItem::_ZTV15QListWidgetItem) + 16u)
+
+Class QListWidget::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QListWidget::QPrivateSignal (0x0x7f21ade1ede0) 0 empty
+
+Vtable for QListWidget
+QListWidget::_ZTV11QListWidget: 110u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QListWidget)
+16 (int (*)(...))QListWidget::metaObject
+24 (int (*)(...))QListWidget::qt_metacast
+32 (int (*)(...))QListWidget::qt_metacall
+40 (int (*)(...))QListWidget::~QListWidget
+48 (int (*)(...))QListWidget::~QListWidget
+56 (int (*)(...))QListWidget::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QListView::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractScrollArea::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractItemView::mousePressEvent
+176 (int (*)(...))QListView::mouseReleaseEvent
+184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent
+192 (int (*)(...))QListView::mouseMoveEvent
+200 (int (*)(...))QListView::wheelEvent
+208 (int (*)(...))QAbstractItemView::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QAbstractItemView::focusInEvent
+232 (int (*)(...))QAbstractItemView::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QListView::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QListView::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QAbstractScrollArea::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QAbstractItemView::dragEnterEvent
+320 (int (*)(...))QListView::dragMoveEvent
+328 (int (*)(...))QListView::dragLeaveEvent
+336 (int (*)(...))QListWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QAbstractItemView::inputMethodEvent
+416 (int (*)(...))QAbstractItemView::inputMethodQuery
+424 (int (*)(...))QAbstractItemView::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QAbstractItemView::viewportEvent
+448 (int (*)(...))QListView::scrollContentsBy
+456 (int (*)(...))QListView::viewportSizeHint
+464 (int (*)(...))QListWidget::setModel
+472 (int (*)(...))QListWidget::setSelectionModel
+480 (int (*)(...))QAbstractItemView::keyboardSearch
+488 (int (*)(...))QListView::visualRect
+496 (int (*)(...))QListView::scrollTo
+504 (int (*)(...))QListView::indexAt
+512 (int (*)(...))QAbstractItemView::sizeHintForRow
+520 (int (*)(...))QAbstractItemView::sizeHintForColumn
+528 (int (*)(...))QListView::reset
+536 (int (*)(...))QListView::setRootIndex
+544 (int (*)(...))QListView::doItemsLayout
+552 (int (*)(...))QAbstractItemView::selectAll
+560 (int (*)(...))QListView::dataChanged
+568 (int (*)(...))QListView::rowsInserted
+576 (int (*)(...))QListView::rowsAboutToBeRemoved
+584 (int (*)(...))QListView::selectionChanged
+592 (int (*)(...))QListView::currentChanged
+600 (int (*)(...))QAbstractItemView::updateEditorData
+608 (int (*)(...))QAbstractItemView::updateEditorGeometries
+616 (int (*)(...))QListView::updateGeometries
+624 (int (*)(...))QAbstractItemView::verticalScrollbarAction
+632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction
+640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged
+648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged
+656 (int (*)(...))QAbstractItemView::closeEditor
+664 (int (*)(...))QAbstractItemView::commitData
+672 (int (*)(...))QAbstractItemView::editorDestroyed
+680 (int (*)(...))QListView::moveCursor
+688 (int (*)(...))QListView::horizontalOffset
+696 (int (*)(...))QListView::verticalOffset
+704 (int (*)(...))QListView::isIndexHidden
+712 (int (*)(...))QListView::setSelection
+720 (int (*)(...))QListView::visualRegionForSelection
+728 (int (*)(...))QListView::selectedIndexes
+736 (int (*)(...))QAbstractItemView::edit
+744 (int (*)(...))QAbstractItemView::selectionCommand
+752 (int (*)(...))QListView::startDrag
+760 (int (*)(...))QListView::viewOptions
+768 (int (*)(...))QListWidget::mimeTypes
+776 (int (*)(...))QListWidget::mimeData
+784 (int (*)(...))QListWidget::dropMimeData
+792 (int (*)(...))QListWidget::supportedDropActions
+800 (int (*)(...))-16
+808 (int (*)(...))(& _ZTI11QListWidget)
+816 (int (*)(...))QListWidget::_ZThn16_N11QListWidgetD1Ev
+824 (int (*)(...))QListWidget::_ZThn16_N11QListWidgetD0Ev
+832 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+840 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+848 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+856 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+864 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+872 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QListWidget
+ size=48 align=8
+ base size=48 base align=8
+QListWidget (0x0x7f21b009e7b8) 0
+ vptr=((& QListWidget::_ZTV11QListWidget) + 16u)
+ QListView (0x0x7f21b009ea90) 0
+ primary-for QListWidget (0x0x7f21b009e7b8)
+ QAbstractItemView (0x0x7f21b009eaf8) 0
+ primary-for QListView (0x0x7f21b009ea90)
+ QAbstractScrollArea (0x0x7f21b009ef70) 0
+ primary-for QAbstractItemView (0x0x7f21b009eaf8)
+ QFrame (0x0x7f21b00bc000) 0
+ primary-for QAbstractScrollArea (0x0x7f21b009ef70)
+ QWidget (0x0x7f21b5b9fee0) 0
+ primary-for QFrame (0x0x7f21b00bc000)
+ QObject (0x0x7f21ade1e240) 0
+ primary-for QWidget (0x0x7f21b5b9fee0)
+ QPaintDevice (0x0x7f21ade1ed80) 16
+ vptr=((& QListWidget::_ZTV11QListWidget) + 816u)
+
+Class QMainWindow::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QMainWindow::QPrivateSignal (0x0x7f21ade49480) 0 empty
+
+Vtable for QMainWindow
+QMainWindow::_ZTV11QMainWindow: 65u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QMainWindow)
+16 (int (*)(...))QMainWindow::metaObject
+24 (int (*)(...))QMainWindow::qt_metacast
+32 (int (*)(...))QMainWindow::qt_metacall
+40 (int (*)(...))QMainWindow::~QMainWindow
+48 (int (*)(...))QMainWindow::~QMainWindow
+56 (int (*)(...))QMainWindow::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QMainWindow::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QMainWindow::createPopupMenu
+440 (int (*)(...))-16
+448 (int (*)(...))(& _ZTI11QMainWindow)
+456 (int (*)(...))QMainWindow::_ZThn16_N11QMainWindowD1Ev
+464 (int (*)(...))QMainWindow::_ZThn16_N11QMainWindowD0Ev
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QMainWindow
+ size=48 align=8
+ base size=48 base align=8
+QMainWindow (0x0x7f21b00bc2d8) 0
+ vptr=((& QMainWindow::_ZTV11QMainWindow) + 16u)
+ QWidget (0x0x7f21b5bc3620) 0
+ primary-for QMainWindow (0x0x7f21b00bc2d8)
+ QObject (0x0x7f21ade49360) 0
+ primary-for QWidget (0x0x7f21b5bc3620)
+ QPaintDevice (0x0x7f21ade493c0) 16
+ vptr=((& QMainWindow::_ZTV11QMainWindow) + 456u)
+
+Class QMdiArea::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QMdiArea::QPrivateSignal (0x0x7f21ade73900) 0 empty
+
+Vtable for QMdiArea
+QMdiArea::_ZTV8QMdiArea: 68u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QMdiArea)
+16 (int (*)(...))QMdiArea::metaObject
+24 (int (*)(...))QMdiArea::qt_metacast
+32 (int (*)(...))QMdiArea::qt_metacall
+40 (int (*)(...))QMdiArea::~QMdiArea
+48 (int (*)(...))QMdiArea::~QMdiArea
+56 (int (*)(...))QMdiArea::event
+64 (int (*)(...))QMdiArea::eventFilter
+72 (int (*)(...))QMdiArea::timerEvent
+80 (int (*)(...))QMdiArea::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QMdiArea::sizeHint
+136 (int (*)(...))QMdiArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractScrollArea::mousePressEvent
+176 (int (*)(...))QAbstractScrollArea::mouseReleaseEvent
+184 (int (*)(...))QAbstractScrollArea::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractScrollArea::mouseMoveEvent
+200 (int (*)(...))QAbstractScrollArea::wheelEvent
+208 (int (*)(...))QAbstractScrollArea::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QMdiArea::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QMdiArea::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QAbstractScrollArea::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QAbstractScrollArea::dragEnterEvent
+320 (int (*)(...))QAbstractScrollArea::dragMoveEvent
+328 (int (*)(...))QAbstractScrollArea::dragLeaveEvent
+336 (int (*)(...))QAbstractScrollArea::dropEvent
+344 (int (*)(...))QMdiArea::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QMdiArea::setupViewport
+440 (int (*)(...))QMdiArea::viewportEvent
+448 (int (*)(...))QMdiArea::scrollContentsBy
+456 (int (*)(...))QAbstractScrollArea::viewportSizeHint
+464 (int (*)(...))-16
+472 (int (*)(...))(& _ZTI8QMdiArea)
+480 (int (*)(...))QMdiArea::_ZThn16_N8QMdiAreaD1Ev
+488 (int (*)(...))QMdiArea::_ZThn16_N8QMdiAreaD0Ev
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QMdiArea
+ size=48 align=8
+ base size=48 base align=8
+QMdiArea (0x0x7f21b00bc548) 0
+ vptr=((& QMdiArea::_ZTV8QMdiArea) + 16u)
+ QAbstractScrollArea (0x0x7f21b00bc6e8) 0
+ primary-for QMdiArea (0x0x7f21b00bc548)
+ QFrame (0x0x7f21b00bc750) 0
+ primary-for QAbstractScrollArea (0x0x7f21b00bc6e8)
+ QWidget (0x0x7f21b5bee460) 0
+ primary-for QFrame (0x0x7f21b00bc750)
+ QObject (0x0x7f21ade73360) 0
+ primary-for QWidget (0x0x7f21b5bee460)
+ QPaintDevice (0x0x7f21ade738a0) 16
+ vptr=((& QMdiArea::_ZTV8QMdiArea) + 480u)
+
+Class QMdiSubWindow::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QMdiSubWindow::QPrivateSignal (0x0x7f21adef5120) 0 empty
+
+Vtable for QMdiSubWindow
+QMdiSubWindow::_ZTV13QMdiSubWindow: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QMdiSubWindow)
+16 (int (*)(...))QMdiSubWindow::metaObject
+24 (int (*)(...))QMdiSubWindow::qt_metacast
+32 (int (*)(...))QMdiSubWindow::qt_metacall
+40 (int (*)(...))QMdiSubWindow::~QMdiSubWindow
+48 (int (*)(...))QMdiSubWindow::~QMdiSubWindow
+56 (int (*)(...))QMdiSubWindow::event
+64 (int (*)(...))QMdiSubWindow::eventFilter
+72 (int (*)(...))QMdiSubWindow::timerEvent
+80 (int (*)(...))QMdiSubWindow::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QMdiSubWindow::sizeHint
+136 (int (*)(...))QMdiSubWindow::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QMdiSubWindow::mousePressEvent
+176 (int (*)(...))QMdiSubWindow::mouseReleaseEvent
+184 (int (*)(...))QMdiSubWindow::mouseDoubleClickEvent
+192 (int (*)(...))QMdiSubWindow::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QMdiSubWindow::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QMdiSubWindow::focusInEvent
+232 (int (*)(...))QMdiSubWindow::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QMdiSubWindow::leaveEvent
+256 (int (*)(...))QMdiSubWindow::paintEvent
+264 (int (*)(...))QMdiSubWindow::moveEvent
+272 (int (*)(...))QMdiSubWindow::resizeEvent
+280 (int (*)(...))QMdiSubWindow::closeEvent
+288 (int (*)(...))QMdiSubWindow::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QMdiSubWindow::showEvent
+352 (int (*)(...))QMdiSubWindow::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QMdiSubWindow::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI13QMdiSubWindow)
+448 (int (*)(...))QMdiSubWindow::_ZThn16_N13QMdiSubWindowD1Ev
+456 (int (*)(...))QMdiSubWindow::_ZThn16_N13QMdiSubWindowD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QMdiSubWindow
+ size=48 align=8
+ base size=48 base align=8
+QMdiSubWindow (0x0x7f21b00dd548) 0
+ vptr=((& QMdiSubWindow::_ZTV13QMdiSubWindow) + 16u)
+ QWidget (0x0x7f21b5c163f0) 0
+ primary-for QMdiSubWindow (0x0x7f21b00dd548)
+ QObject (0x0x7f21adecd540) 0
+ primary-for QWidget (0x0x7f21b5c163f0)
+ QPaintDevice (0x0x7f21adecd5a0) 16
+ vptr=((& QMdiSubWindow::_ZTV13QMdiSubWindow) + 448u)
+
+Class QMenu::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QMenu::QPrivateSignal (0x0x7f21adf13480) 0 empty
+
+Vtable for QMenu
+QMenu::_ZTV5QMenu: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI5QMenu)
+16 (int (*)(...))QMenu::metaObject
+24 (int (*)(...))QMenu::qt_metacast
+32 (int (*)(...))QMenu::qt_metacall
+40 (int (*)(...))QMenu::~QMenu
+48 (int (*)(...))QMenu::~QMenu
+56 (int (*)(...))QMenu::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QMenu::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QMenu::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QMenu::mousePressEvent
+176 (int (*)(...))QMenu::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QMenu::mouseMoveEvent
+200 (int (*)(...))QMenu::wheelEvent
+208 (int (*)(...))QMenu::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QMenu::enterEvent
+248 (int (*)(...))QMenu::leaveEvent
+256 (int (*)(...))QMenu::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QMenu::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QMenu::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QMenu::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QMenu::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI5QMenu)
+448 (int (*)(...))QMenu::_ZThn16_N5QMenuD1Ev
+456 (int (*)(...))QMenu::_ZThn16_N5QMenuD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QMenu
+ size=48 align=8
+ base size=48 base align=8
+QMenu (0x0x7f21b00ff7b8) 0
+ vptr=((& QMenu::_ZTV5QMenu) + 16u)
+ QWidget (0x0x7f21b5c33af0) 0
+ primary-for QMenu (0x0x7f21b00ff7b8)
+ QObject (0x0x7f21adef5a20) 0
+ primary-for QWidget (0x0x7f21b5c33af0)
+ QPaintDevice (0x0x7f21adf13420) 16
+ vptr=((& QMenu::_ZTV5QMenu) + 448u)
+
+Class QMenuBar::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QMenuBar::QPrivateSignal (0x0x7f21adf13780) 0 empty
+
+Vtable for QMenuBar
+QMenuBar::_ZTV8QMenuBar: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QMenuBar)
+16 (int (*)(...))QMenuBar::metaObject
+24 (int (*)(...))QMenuBar::qt_metacast
+32 (int (*)(...))QMenuBar::qt_metacall
+40 (int (*)(...))QMenuBar::~QMenuBar
+48 (int (*)(...))QMenuBar::~QMenuBar
+56 (int (*)(...))QMenuBar::event
+64 (int (*)(...))QMenuBar::eventFilter
+72 (int (*)(...))QMenuBar::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QMenuBar::setVisible
+128 (int (*)(...))QMenuBar::sizeHint
+136 (int (*)(...))QMenuBar::minimumSizeHint
+144 (int (*)(...))QMenuBar::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QMenuBar::mousePressEvent
+176 (int (*)(...))QMenuBar::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QMenuBar::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QMenuBar::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QMenuBar::focusInEvent
+232 (int (*)(...))QMenuBar::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QMenuBar::leaveEvent
+256 (int (*)(...))QMenuBar::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QMenuBar::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QMenuBar::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QMenuBar::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI8QMenuBar)
+448 (int (*)(...))QMenuBar::_ZThn16_N8QMenuBarD1Ev
+456 (int (*)(...))QMenuBar::_ZThn16_N8QMenuBarD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QMenuBar
+ size=48 align=8
+ base size=48 base align=8
+QMenuBar (0x0x7f21b00ff820) 0
+ vptr=((& QMenuBar::_ZTV8QMenuBar) + 16u)
+ QWidget (0x0x7f21b584f070) 0
+ primary-for QMenuBar (0x0x7f21b00ff820)
+ QObject (0x0x7f21adf13540) 0
+ primary-for QWidget (0x0x7f21b584f070)
+ QPaintDevice (0x0x7f21adf13720) 16
+ vptr=((& QMenuBar::_ZTV8QMenuBar) + 448u)
+
+Class QMessageBox::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QMessageBox::QPrivateSignal (0x0x7f21ada1b000) 0 empty
+
+Vtable for QMessageBox
+QMessageBox::_ZTV11QMessageBox: 69u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QMessageBox)
+16 (int (*)(...))QMessageBox::metaObject
+24 (int (*)(...))QMessageBox::qt_metacast
+32 (int (*)(...))QMessageBox::qt_metacall
+40 (int (*)(...))QMessageBox::~QMessageBox
+48 (int (*)(...))QMessageBox::~QMessageBox
+56 (int (*)(...))QMessageBox::event
+64 (int (*)(...))QDialog::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QDialog::setVisible
+128 (int (*)(...))QDialog::sizeHint
+136 (int (*)(...))QDialog::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QMessageBox::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QMessageBox::resizeEvent
+280 (int (*)(...))QMessageBox::closeEvent
+288 (int (*)(...))QDialog::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QMessageBox::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QMessageBox::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QDialog::open
+440 (int (*)(...))QDialog::exec
+448 (int (*)(...))QDialog::done
+456 (int (*)(...))QDialog::accept
+464 (int (*)(...))QDialog::reject
+472 (int (*)(...))-16
+480 (int (*)(...))(& _ZTI11QMessageBox)
+488 (int (*)(...))QMessageBox::_ZThn16_N11QMessageBoxD1Ev
+496 (int (*)(...))QMessageBox::_ZThn16_N11QMessageBoxD0Ev
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QMessageBox
+ size=48 align=8
+ base size=48 base align=8
+QMessageBox (0x0x7f21b011b270) 0
+ vptr=((& QMessageBox::_ZTV11QMessageBox) + 16u)
+ QDialog (0x0x7f21b011b2d8) 0
+ primary-for QMessageBox (0x0x7f21b011b270)
+ QWidget (0x0x7f21b584f930) 0
+ primary-for QDialog (0x0x7f21b011b2d8)
+ QObject (0x0x7f21ad9f7ea0) 0
+ primary-for QWidget (0x0x7f21b584f930)
+ QPaintDevice (0x0x7f21ad9f7f00) 16
+ vptr=((& QMessageBox::_ZTV11QMessageBox) + 488u)
+
+Class QMouseEventTransition::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QMouseEventTransition::QPrivateSignal (0x0x7f21ada1b420) 0 empty
+
+Vtable for QMouseEventTransition
+QMouseEventTransition::_ZTV21QMouseEventTransition: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI21QMouseEventTransition)
+16 (int (*)(...))QMouseEventTransition::metaObject
+24 (int (*)(...))QMouseEventTransition::qt_metacast
+32 (int (*)(...))QMouseEventTransition::qt_metacall
+40 (int (*)(...))QMouseEventTransition::~QMouseEventTransition
+48 (int (*)(...))QMouseEventTransition::~QMouseEventTransition
+56 (int (*)(...))QEventTransition::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QMouseEventTransition::eventTest
+120 (int (*)(...))QMouseEventTransition::onTransition
+
+Class QMouseEventTransition
+ size=16 align=8
+ base size=16 base align=8
+QMouseEventTransition (0x0x7f21b011bd68) 0
+ vptr=((& QMouseEventTransition::_ZTV21QMouseEventTransition) + 16u)
+ QEventTransition (0x0x7f21b011bea0) 0
+ primary-for QMouseEventTransition (0x0x7f21b011bd68)
+ QAbstractTransition (0x0x7f21b011bf08) 0
+ primary-for QEventTransition (0x0x7f21b011bea0)
+ QObject (0x0x7f21ada1b360) 0
+ primary-for QAbstractTransition (0x0x7f21b011bf08)
+
+Class QOpenGLWidget::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QOpenGLWidget::QPrivateSignal (0x0x7f21ada1b600) 0 empty
+
+Vtable for QOpenGLWidget
+QOpenGLWidget::_ZTV13QOpenGLWidget: 67u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QOpenGLWidget)
+16 (int (*)(...))QOpenGLWidget::metaObject
+24 (int (*)(...))QOpenGLWidget::qt_metacast
+32 (int (*)(...))QOpenGLWidget::qt_metacall
+40 (int (*)(...))QOpenGLWidget::~QOpenGLWidget
+48 (int (*)(...))QOpenGLWidget::~QOpenGLWidget
+56 (int (*)(...))QOpenGLWidget::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QOpenGLWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QOpenGLWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QOpenGLWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QOpenGLWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QOpenGLWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QOpenGLWidget::initializeGL
+440 (int (*)(...))QOpenGLWidget::resizeGL
+448 (int (*)(...))QOpenGLWidget::paintGL
+456 (int (*)(...))-16
+464 (int (*)(...))(& _ZTI13QOpenGLWidget)
+472 (int (*)(...))QOpenGLWidget::_ZThn16_N13QOpenGLWidgetD1Ev
+480 (int (*)(...))QOpenGLWidget::_ZThn16_N13QOpenGLWidgetD0Ev
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+496 (int (*)(...))QOpenGLWidget::_ZThn16_NK13QOpenGLWidget11paintEngineEv
+504 (int (*)(...))QOpenGLWidget::_ZThn16_NK13QOpenGLWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+520 (int (*)(...))QOpenGLWidget::_ZThn16_NK13QOpenGLWidget10redirectedEP6QPoint
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QOpenGLWidget
+ size=48 align=8
+ base size=48 base align=8
+QOpenGLWidget (0x0x7f21b014a888) 0
+ vptr=((& QOpenGLWidget::_ZTV13QOpenGLWidget) + 16u)
+ QWidget (0x0x7f21b587d9a0) 0
+ primary-for QOpenGLWidget (0x0x7f21b014a888)
+ QObject (0x0x7f21ada1b480) 0
+ primary-for QWidget (0x0x7f21b587d9a0)
+ QPaintDevice (0x0x7f21ada1b540) 16
+ vptr=((& QOpenGLWidget::_ZTV13QOpenGLWidget) + 472u)
+
+Class QTextEdit::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTextEdit::QPrivateSignal (0x0x7f21ada1bf00) 0 empty
+
+Class QTextEdit::ExtraSelection
+ size=24 align=8
+ base size=24 base align=8
+QTextEdit::ExtraSelection (0x0x7f21ada1bf60) 0
+
+Vtable for QTextEdit
+QTextEdit::_ZTV9QTextEdit: 73u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QTextEdit)
+16 (int (*)(...))QTextEdit::metaObject
+24 (int (*)(...))QTextEdit::qt_metacast
+32 (int (*)(...))QTextEdit::qt_metacall
+40 (int (*)(...))QTextEdit::~QTextEdit
+48 (int (*)(...))QTextEdit::~QTextEdit
+56 (int (*)(...))QTextEdit::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QTextEdit::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractScrollArea::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QTextEdit::mousePressEvent
+176 (int (*)(...))QTextEdit::mouseReleaseEvent
+184 (int (*)(...))QTextEdit::mouseDoubleClickEvent
+192 (int (*)(...))QTextEdit::mouseMoveEvent
+200 (int (*)(...))QTextEdit::wheelEvent
+208 (int (*)(...))QTextEdit::keyPressEvent
+216 (int (*)(...))QTextEdit::keyReleaseEvent
+224 (int (*)(...))QTextEdit::focusInEvent
+232 (int (*)(...))QTextEdit::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QTextEdit::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QTextEdit::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QTextEdit::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QTextEdit::dragEnterEvent
+320 (int (*)(...))QTextEdit::dragMoveEvent
+328 (int (*)(...))QTextEdit::dragLeaveEvent
+336 (int (*)(...))QTextEdit::dropEvent
+344 (int (*)(...))QTextEdit::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QTextEdit::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QTextEdit::inputMethodEvent
+416 (int (*)(...))QTextEdit::inputMethodQuery
+424 (int (*)(...))QTextEdit::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QAbstractScrollArea::viewportEvent
+448 (int (*)(...))QTextEdit::scrollContentsBy
+456 (int (*)(...))QAbstractScrollArea::viewportSizeHint
+464 (int (*)(...))QTextEdit::loadResource
+472 (int (*)(...))QTextEdit::createMimeDataFromSelection
+480 (int (*)(...))QTextEdit::canInsertFromMimeData
+488 (int (*)(...))QTextEdit::insertFromMimeData
+496 (int (*)(...))QTextEdit::doSetTextCursor
+504 (int (*)(...))-16
+512 (int (*)(...))(& _ZTI9QTextEdit)
+520 (int (*)(...))QTextEdit::_ZThn16_N9QTextEditD1Ev
+528 (int (*)(...))QTextEdit::_ZThn16_N9QTextEditD0Ev
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+552 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+560 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+568 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+576 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QTextEdit
+ size=48 align=8
+ base size=48 base align=8
+QTextEdit (0x0x7f21b014a9c0) 0
+ vptr=((& QTextEdit::_ZTV9QTextEdit) + 16u)
+ QAbstractScrollArea (0x0x7f21b014aa28) 0
+ primary-for QTextEdit (0x0x7f21b014a9c0)
+ QFrame (0x0x7f21b014ad68) 0
+ primary-for QAbstractScrollArea (0x0x7f21b014aa28)
+ QWidget (0x0x7f21b58891c0) 0
+ primary-for QFrame (0x0x7f21b014ad68)
+ QObject (0x0x7f21ada1bd20) 0
+ primary-for QWidget (0x0x7f21b58891c0)
+ QPaintDevice (0x0x7f21ada1bd80) 16
+ vptr=((& QTextEdit::_ZTV9QTextEdit) + 520u)
+
+Class QPlainTextEdit::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPlainTextEdit::QPrivateSignal (0x0x7f21ad5fb1e0) 0 empty
+
+Vtable for QPlainTextEdit
+QPlainTextEdit::_ZTV14QPlainTextEdit: 73u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QPlainTextEdit)
+16 (int (*)(...))QPlainTextEdit::metaObject
+24 (int (*)(...))QPlainTextEdit::qt_metacast
+32 (int (*)(...))QPlainTextEdit::qt_metacall
+40 (int (*)(...))QPlainTextEdit::~QPlainTextEdit
+48 (int (*)(...))QPlainTextEdit::~QPlainTextEdit
+56 (int (*)(...))QPlainTextEdit::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QPlainTextEdit::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractScrollArea::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QPlainTextEdit::mousePressEvent
+176 (int (*)(...))QPlainTextEdit::mouseReleaseEvent
+184 (int (*)(...))QPlainTextEdit::mouseDoubleClickEvent
+192 (int (*)(...))QPlainTextEdit::mouseMoveEvent
+200 (int (*)(...))QPlainTextEdit::wheelEvent
+208 (int (*)(...))QPlainTextEdit::keyPressEvent
+216 (int (*)(...))QPlainTextEdit::keyReleaseEvent
+224 (int (*)(...))QPlainTextEdit::focusInEvent
+232 (int (*)(...))QPlainTextEdit::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QPlainTextEdit::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QPlainTextEdit::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QPlainTextEdit::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QPlainTextEdit::dragEnterEvent
+320 (int (*)(...))QPlainTextEdit::dragMoveEvent
+328 (int (*)(...))QPlainTextEdit::dragLeaveEvent
+336 (int (*)(...))QPlainTextEdit::dropEvent
+344 (int (*)(...))QPlainTextEdit::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QPlainTextEdit::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QPlainTextEdit::inputMethodEvent
+416 (int (*)(...))QPlainTextEdit::inputMethodQuery
+424 (int (*)(...))QPlainTextEdit::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QAbstractScrollArea::viewportEvent
+448 (int (*)(...))QPlainTextEdit::scrollContentsBy
+456 (int (*)(...))QAbstractScrollArea::viewportSizeHint
+464 (int (*)(...))QPlainTextEdit::loadResource
+472 (int (*)(...))QPlainTextEdit::createMimeDataFromSelection
+480 (int (*)(...))QPlainTextEdit::canInsertFromMimeData
+488 (int (*)(...))QPlainTextEdit::insertFromMimeData
+496 (int (*)(...))QPlainTextEdit::doSetTextCursor
+504 (int (*)(...))-16
+512 (int (*)(...))(& _ZTI14QPlainTextEdit)
+520 (int (*)(...))QPlainTextEdit::_ZThn16_N14QPlainTextEditD1Ev
+528 (int (*)(...))QPlainTextEdit::_ZThn16_N14QPlainTextEditD0Ev
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+552 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+560 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+568 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+576 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QPlainTextEdit
+ size=48 align=8
+ base size=48 base align=8
+QPlainTextEdit (0x0x7f21b01669c0) 0
+ vptr=((& QPlainTextEdit::_ZTV14QPlainTextEdit) + 16u)
+ QAbstractScrollArea (0x0x7f21b0166d68) 0
+ primary-for QPlainTextEdit (0x0x7f21b01669c0)
+ QFrame (0x0x7f21b0166dd0) 0
+ primary-for QAbstractScrollArea (0x0x7f21b0166d68)
+ QWidget (0x0x7f21b58a0a80) 0
+ primary-for QFrame (0x0x7f21b0166dd0)
+ QObject (0x0x7f21ada3e300) 0
+ primary-for QWidget (0x0x7f21b58a0a80)
+ QPaintDevice (0x0x7f21ada3e3c0) 16
+ vptr=((& QPlainTextEdit::_ZTV14QPlainTextEdit) + 520u)
+
+Class QPlainTextDocumentLayout::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QPlainTextDocumentLayout::QPrivateSignal (0x0x7f21ad5fbcc0) 0 empty
+
+Vtable for QPlainTextDocumentLayout
+QPlainTextDocumentLayout::_ZTV24QPlainTextDocumentLayout: 24u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI24QPlainTextDocumentLayout)
+16 (int (*)(...))QPlainTextDocumentLayout::metaObject
+24 (int (*)(...))QPlainTextDocumentLayout::qt_metacast
+32 (int (*)(...))QPlainTextDocumentLayout::qt_metacall
+40 (int (*)(...))QPlainTextDocumentLayout::~QPlainTextDocumentLayout
+48 (int (*)(...))QPlainTextDocumentLayout::~QPlainTextDocumentLayout
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QPlainTextDocumentLayout::draw
+120 (int (*)(...))QPlainTextDocumentLayout::hitTest
+128 (int (*)(...))QPlainTextDocumentLayout::pageCount
+136 (int (*)(...))QPlainTextDocumentLayout::documentSize
+144 (int (*)(...))QPlainTextDocumentLayout::frameBoundingRect
+152 (int (*)(...))QPlainTextDocumentLayout::blockBoundingRect
+160 (int (*)(...))QPlainTextDocumentLayout::documentChanged
+168 (int (*)(...))QAbstractTextDocumentLayout::resizeInlineObject
+176 (int (*)(...))QAbstractTextDocumentLayout::positionInlineObject
+184 (int (*)(...))QAbstractTextDocumentLayout::drawInlineObject
+
+Class QPlainTextDocumentLayout
+ size=16 align=8
+ base size=16 base align=8
+QPlainTextDocumentLayout (0x0x7f21afdf80d0) 0
+ vptr=((& QPlainTextDocumentLayout::_ZTV24QPlainTextDocumentLayout) + 16u)
+ QAbstractTextDocumentLayout (0x0x7f21afdf8138) 0
+ primary-for QPlainTextDocumentLayout (0x0x7f21afdf80d0)
+ QObject (0x0x7f21ad5fb240) 0
+ primary-for QAbstractTextDocumentLayout (0x0x7f21afdf8138)
+
+Class QProgressBar::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QProgressBar::QPrivateSignal (0x0x7f21ad620780) 0 empty
+
+Vtable for QProgressBar
+QProgressBar::_ZTV12QProgressBar: 65u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QProgressBar)
+16 (int (*)(...))QProgressBar::metaObject
+24 (int (*)(...))QProgressBar::qt_metacast
+32 (int (*)(...))QProgressBar::qt_metacall
+40 (int (*)(...))QProgressBar::~QProgressBar
+48 (int (*)(...))QProgressBar::~QProgressBar
+56 (int (*)(...))QProgressBar::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QProgressBar::sizeHint
+136 (int (*)(...))QProgressBar::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QProgressBar::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QProgressBar::text
+440 (int (*)(...))-16
+448 (int (*)(...))(& _ZTI12QProgressBar)
+456 (int (*)(...))QProgressBar::_ZThn16_N12QProgressBarD1Ev
+464 (int (*)(...))QProgressBar::_ZThn16_N12QProgressBarD0Ev
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QProgressBar
+ size=48 align=8
+ base size=48 base align=8
+QProgressBar (0x0x7f21afdf81a0) 0
+ vptr=((& QProgressBar::_ZTV12QProgressBar) + 16u)
+ QWidget (0x0x7f21b58db460) 0
+ primary-for QProgressBar (0x0x7f21afdf81a0)
+ QObject (0x0x7f21ad5fbd20) 0
+ primary-for QWidget (0x0x7f21b58db460)
+ QPaintDevice (0x0x7f21ad620720) 16
+ vptr=((& QProgressBar::_ZTV12QProgressBar) + 456u)
+
+Class QProgressDialog::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QProgressDialog::QPrivateSignal (0x0x7f21ad645420) 0 empty
+
+Vtable for QProgressDialog
+QProgressDialog::_ZTV15QProgressDialog: 69u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QProgressDialog)
+16 (int (*)(...))QProgressDialog::metaObject
+24 (int (*)(...))QProgressDialog::qt_metacast
+32 (int (*)(...))QProgressDialog::qt_metacall
+40 (int (*)(...))QProgressDialog::~QProgressDialog
+48 (int (*)(...))QProgressDialog::~QProgressDialog
+56 (int (*)(...))QWidget::event
+64 (int (*)(...))QDialog::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QDialog::setVisible
+128 (int (*)(...))QProgressDialog::sizeHint
+136 (int (*)(...))QDialog::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QDialog::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QProgressDialog::resizeEvent
+280 (int (*)(...))QProgressDialog::closeEvent
+288 (int (*)(...))QDialog::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QProgressDialog::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QProgressDialog::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QDialog::open
+440 (int (*)(...))QDialog::exec
+448 (int (*)(...))QDialog::done
+456 (int (*)(...))QDialog::accept
+464 (int (*)(...))QDialog::reject
+472 (int (*)(...))-16
+480 (int (*)(...))(& _ZTI15QProgressDialog)
+488 (int (*)(...))QProgressDialog::_ZThn16_N15QProgressDialogD1Ev
+496 (int (*)(...))QProgressDialog::_ZThn16_N15QProgressDialogD0Ev
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QProgressDialog
+ size=48 align=8
+ base size=48 base align=8
+QProgressDialog (0x0x7f21afdf8208) 0
+ vptr=((& QProgressDialog::_ZTV15QProgressDialog) + 16u)
+ QDialog (0x0x7f21afdf8270) 0
+ primary-for QProgressDialog (0x0x7f21afdf8208)
+ QWidget (0x0x7f21b58e2310) 0
+ primary-for QDialog (0x0x7f21afdf8270)
+ QObject (0x0x7f21ad620a80) 0
+ primary-for QWidget (0x0x7f21b58e2310)
+ QPaintDevice (0x0x7f21ad620ae0) 16
+ vptr=((& QProgressDialog::_ZTV15QProgressDialog) + 488u)
+
+Class QProxyStyle::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QProxyStyle::QPrivateSignal (0x0x7f21ad37d060) 0 empty
+
+Vtable for QProxyStyle
+QProxyStyle::_ZTV11QProxyStyle: 37u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QProxyStyle)
+16 (int (*)(...))QProxyStyle::metaObject
+24 (int (*)(...))QProxyStyle::qt_metacast
+32 (int (*)(...))QProxyStyle::qt_metacall
+40 (int (*)(...))QProxyStyle::~QProxyStyle
+48 (int (*)(...))QProxyStyle::~QProxyStyle
+56 (int (*)(...))QProxyStyle::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QProxyStyle::polish
+120 (int (*)(...))QProxyStyle::unpolish
+128 (int (*)(...))QProxyStyle::polish
+136 (int (*)(...))QProxyStyle::unpolish
+144 (int (*)(...))QProxyStyle::polish
+152 (int (*)(...))QProxyStyle::itemTextRect
+160 (int (*)(...))QProxyStyle::itemPixmapRect
+168 (int (*)(...))QProxyStyle::drawItemText
+176 (int (*)(...))QProxyStyle::drawItemPixmap
+184 (int (*)(...))QProxyStyle::standardPalette
+192 (int (*)(...))QProxyStyle::drawPrimitive
+200 (int (*)(...))QProxyStyle::drawControl
+208 (int (*)(...))QProxyStyle::subElementRect
+216 (int (*)(...))QProxyStyle::drawComplexControl
+224 (int (*)(...))QProxyStyle::hitTestComplexControl
+232 (int (*)(...))QProxyStyle::subControlRect
+240 (int (*)(...))QProxyStyle::pixelMetric
+248 (int (*)(...))QProxyStyle::sizeFromContents
+256 (int (*)(...))QProxyStyle::styleHint
+264 (int (*)(...))QProxyStyle::standardPixmap
+272 (int (*)(...))QProxyStyle::standardIcon
+280 (int (*)(...))QProxyStyle::generatedIconPixmap
+288 (int (*)(...))QProxyStyle::layoutSpacing
+
+Class QProxyStyle
+ size=16 align=8
+ base size=16 base align=8
+QProxyStyle (0x0x7f21afdf82d8) 0
+ vptr=((& QProxyStyle::_ZTV11QProxyStyle) + 16u)
+ QCommonStyle (0x0x7f21afdf85b0) 0
+ primary-for QProxyStyle (0x0x7f21afdf82d8)
+ QStyle (0x0x7f21afdf8618) 0
+ primary-for QCommonStyle (0x0x7f21afdf85b0)
+ QObject (0x0x7f21ad645480) 0
+ primary-for QStyle (0x0x7f21afdf8618)
+
+Class QRadioButton::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QRadioButton::QPrivateSignal (0x0x7f21ad37d9c0) 0 empty
+
+Vtable for QRadioButton
+QRadioButton::_ZTV12QRadioButton: 67u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QRadioButton)
+16 (int (*)(...))QRadioButton::metaObject
+24 (int (*)(...))QRadioButton::qt_metacast
+32 (int (*)(...))QRadioButton::qt_metacall
+40 (int (*)(...))QRadioButton::~QRadioButton
+48 (int (*)(...))QRadioButton::~QRadioButton
+56 (int (*)(...))QRadioButton::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractButton::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QRadioButton::sizeHint
+136 (int (*)(...))QRadioButton::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractButton::mousePressEvent
+176 (int (*)(...))QAbstractButton::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QRadioButton::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QAbstractButton::keyPressEvent
+216 (int (*)(...))QAbstractButton::keyReleaseEvent
+224 (int (*)(...))QAbstractButton::focusInEvent
+232 (int (*)(...))QAbstractButton::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QRadioButton::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractButton::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QRadioButton::hitButton
+440 (int (*)(...))QAbstractButton::checkStateSet
+448 (int (*)(...))QAbstractButton::nextCheckState
+456 (int (*)(...))-16
+464 (int (*)(...))(& _ZTI12QRadioButton)
+472 (int (*)(...))QRadioButton::_ZThn16_N12QRadioButtonD1Ev
+480 (int (*)(...))QRadioButton::_ZThn16_N12QRadioButtonD0Ev
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QRadioButton
+ size=48 align=8
+ base size=48 base align=8
+QRadioButton (0x0x7f21afdf8a90) 0
+ vptr=((& QRadioButton::_ZTV12QRadioButton) + 16u)
+ QAbstractButton (0x0x7f21afdf8af8) 0
+ primary-for QRadioButton (0x0x7f21afdf8a90)
+ QWidget (0x0x7f21b58e9380) 0
+ primary-for QAbstractButton (0x0x7f21afdf8af8)
+ QObject (0x0x7f21ad37d0c0) 0
+ primary-for QWidget (0x0x7f21b58e9380)
+ QPaintDevice (0x0x7f21ad37d960) 16
+ vptr=((& QRadioButton::_ZTV12QRadioButton) + 472u)
+
+Class QScrollBar::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QScrollBar::QPrivateSignal (0x0x7f21ad37dcc0) 0 empty
+
+Vtable for QScrollBar
+QScrollBar::_ZTV10QScrollBar: 65u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QScrollBar)
+16 (int (*)(...))QScrollBar::metaObject
+24 (int (*)(...))QScrollBar::qt_metacast
+32 (int (*)(...))QScrollBar::qt_metacall
+40 (int (*)(...))QScrollBar::~QScrollBar
+48 (int (*)(...))QScrollBar::~QScrollBar
+56 (int (*)(...))QScrollBar::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractSlider::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QScrollBar::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QScrollBar::mousePressEvent
+176 (int (*)(...))QScrollBar::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QScrollBar::mouseMoveEvent
+200 (int (*)(...))QScrollBar::wheelEvent
+208 (int (*)(...))QAbstractSlider::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QScrollBar::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QScrollBar::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QScrollBar::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractSlider::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QScrollBar::sliderChange
+440 (int (*)(...))-16
+448 (int (*)(...))(& _ZTI10QScrollBar)
+456 (int (*)(...))QScrollBar::_ZThn16_N10QScrollBarD1Ev
+464 (int (*)(...))QScrollBar::_ZThn16_N10QScrollBarD0Ev
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QScrollBar
+ size=48 align=8
+ base size=48 base align=8
+QScrollBar (0x0x7f21afdf8dd0) 0
+ vptr=((& QScrollBar::_ZTV10QScrollBar) + 16u)
+ QAbstractSlider (0x0x7f21afdf8e38) 0
+ primary-for QScrollBar (0x0x7f21afdf8dd0)
+ QWidget (0x0x7f21b58e9bd0) 0
+ primary-for QAbstractSlider (0x0x7f21afdf8e38)
+ QObject (0x0x7f21ad37da80) 0
+ primary-for QWidget (0x0x7f21b58e9bd0)
+ QPaintDevice (0x0x7f21ad37dc60) 16
+ vptr=((& QScrollBar::_ZTV10QScrollBar) + 456u)
+
+Vtable for QScrollerProperties
+QScrollerProperties::_ZTV19QScrollerProperties: 4u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QScrollerProperties)
+16 (int (*)(...))QScrollerProperties::~QScrollerProperties
+24 (int (*)(...))QScrollerProperties::~QScrollerProperties
+
+Class QScrollerProperties
+ size=16 align=8
+ base size=16 base align=8
+QScrollerProperties (0x0x7f21ad3a16c0) 0
+ vptr=((& QScrollerProperties::_ZTV19QScrollerProperties) + 16u)
+
+Class QScroller::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QScroller::QPrivateSignal (0x0x7f21ad3c3840) 0 empty
+
+Vtable for QScroller
+QScroller::_ZTV9QScroller: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QScroller)
+16 (int (*)(...))QScroller::metaObject
+24 (int (*)(...))QScroller::qt_metacast
+32 (int (*)(...))QScroller::qt_metacall
+40 (int (*)(...))QScroller::~QScroller
+48 (int (*)(...))QScroller::~QScroller
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QScroller
+ size=24 align=8
+ base size=24 base align=8
+QScroller (0x0x7f21afe5a138) 0
+ vptr=((& QScroller::_ZTV9QScroller) + 16u)
+ QObject (0x0x7f21ad3c37e0) 0
+ primary-for QScroller (0x0x7f21afe5a138)
+
+Class QShortcut::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QShortcut::QPrivateSignal (0x0x7f21acf86e40) 0 empty
+
+Vtable for QShortcut
+QShortcut::_ZTV9QShortcut: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QShortcut)
+16 (int (*)(...))QShortcut::metaObject
+24 (int (*)(...))QShortcut::qt_metacast
+32 (int (*)(...))QShortcut::qt_metacall
+40 (int (*)(...))QShortcut::~QShortcut
+48 (int (*)(...))QShortcut::~QShortcut
+56 (int (*)(...))QShortcut::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QShortcut
+ size=16 align=8
+ base size=16 base align=8
+QShortcut (0x0x7f21afe5a1a0) 0
+ vptr=((& QShortcut::_ZTV9QShortcut) + 16u)
+ QObject (0x0x7f21acf86de0) 0
+ primary-for QShortcut (0x0x7f21afe5a1a0)
+
+Class QSizeGrip::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSizeGrip::QPrivateSignal (0x0x7f21ad05b600) 0 empty
+
+Vtable for QSizeGrip
+QSizeGrip::_ZTV9QSizeGrip: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QSizeGrip)
+16 (int (*)(...))QSizeGrip::metaObject
+24 (int (*)(...))QSizeGrip::qt_metacast
+32 (int (*)(...))QSizeGrip::qt_metacall
+40 (int (*)(...))QSizeGrip::~QSizeGrip
+48 (int (*)(...))QSizeGrip::~QSizeGrip
+56 (int (*)(...))QSizeGrip::event
+64 (int (*)(...))QSizeGrip::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QSizeGrip::setVisible
+128 (int (*)(...))QSizeGrip::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QSizeGrip::mousePressEvent
+176 (int (*)(...))QSizeGrip::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QSizeGrip::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QSizeGrip::paintEvent
+264 (int (*)(...))QSizeGrip::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QSizeGrip::showEvent
+352 (int (*)(...))QSizeGrip::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI9QSizeGrip)
+448 (int (*)(...))QSizeGrip::_ZThn16_N9QSizeGripD1Ev
+456 (int (*)(...))QSizeGrip::_ZThn16_N9QSizeGripD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QSizeGrip
+ size=48 align=8
+ base size=48 base align=8
+QSizeGrip (0x0x7f21afe5a478) 0
+ vptr=((& QSizeGrip::_ZTV9QSizeGrip) + 16u)
+ QWidget (0x0x7f21b59210e0) 0
+ primary-for QSizeGrip (0x0x7f21afe5a478)
+ QObject (0x0x7f21ad05b2a0) 0
+ primary-for QWidget (0x0x7f21b59210e0)
+ QPaintDevice (0x0x7f21ad05b300) 16
+ vptr=((& QSizeGrip::_ZTV9QSizeGrip) + 448u)
+
+Class QSpinBox::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSpinBox::QPrivateSignal (0x0x7f21ad05b900) 0 empty
+
+Vtable for QSpinBox
+QSpinBox::_ZTV8QSpinBox: 71u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QSpinBox)
+16 (int (*)(...))QSpinBox::metaObject
+24 (int (*)(...))QSpinBox::qt_metacast
+32 (int (*)(...))QSpinBox::qt_metacall
+40 (int (*)(...))QSpinBox::~QSpinBox
+48 (int (*)(...))QSpinBox::~QSpinBox
+56 (int (*)(...))QSpinBox::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractSpinBox::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractSpinBox::sizeHint
+136 (int (*)(...))QAbstractSpinBox::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractSpinBox::mousePressEvent
+176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent
+200 (int (*)(...))QAbstractSpinBox::wheelEvent
+208 (int (*)(...))QAbstractSpinBox::keyPressEvent
+216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent
+224 (int (*)(...))QAbstractSpinBox::focusInEvent
+232 (int (*)(...))QAbstractSpinBox::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QAbstractSpinBox::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QAbstractSpinBox::resizeEvent
+280 (int (*)(...))QAbstractSpinBox::closeEvent
+288 (int (*)(...))QAbstractSpinBox::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QAbstractSpinBox::showEvent
+352 (int (*)(...))QAbstractSpinBox::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractSpinBox::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QAbstractSpinBox::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QSpinBox::validate
+440 (int (*)(...))QSpinBox::fixup
+448 (int (*)(...))QAbstractSpinBox::stepBy
+456 (int (*)(...))QAbstractSpinBox::clear
+464 (int (*)(...))QAbstractSpinBox::stepEnabled
+472 (int (*)(...))QSpinBox::valueFromText
+480 (int (*)(...))QSpinBox::textFromValue
+488 (int (*)(...))-16
+496 (int (*)(...))(& _ZTI8QSpinBox)
+504 (int (*)(...))QSpinBox::_ZThn16_N8QSpinBoxD1Ev
+512 (int (*)(...))QSpinBox::_ZThn16_N8QSpinBoxD0Ev
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QSpinBox
+ size=48 align=8
+ base size=48 base align=8
+QSpinBox (0x0x7f21afe5a4e0) 0
+ vptr=((& QSpinBox::_ZTV8QSpinBox) + 16u)
+ QAbstractSpinBox (0x0x7f21afe7add0) 0
+ primary-for QSpinBox (0x0x7f21afe5a4e0)
+ QWidget (0x0x7f21b5921850) 0
+ primary-for QAbstractSpinBox (0x0x7f21afe7add0)
+ QObject (0x0x7f21ad05b660) 0
+ primary-for QWidget (0x0x7f21b5921850)
+ QPaintDevice (0x0x7f21ad05b8a0) 16
+ vptr=((& QSpinBox::_ZTV8QSpinBox) + 504u)
+
+Class QDoubleSpinBox::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QDoubleSpinBox::QPrivateSignal (0x0x7f21ad0ac120) 0 empty
+
+Vtable for QDoubleSpinBox
+QDoubleSpinBox::_ZTV14QDoubleSpinBox: 71u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QDoubleSpinBox)
+16 (int (*)(...))QDoubleSpinBox::metaObject
+24 (int (*)(...))QDoubleSpinBox::qt_metacast
+32 (int (*)(...))QDoubleSpinBox::qt_metacall
+40 (int (*)(...))QDoubleSpinBox::~QDoubleSpinBox
+48 (int (*)(...))QDoubleSpinBox::~QDoubleSpinBox
+56 (int (*)(...))QAbstractSpinBox::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QAbstractSpinBox::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractSpinBox::sizeHint
+136 (int (*)(...))QAbstractSpinBox::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractSpinBox::mousePressEvent
+176 (int (*)(...))QAbstractSpinBox::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractSpinBox::mouseMoveEvent
+200 (int (*)(...))QAbstractSpinBox::wheelEvent
+208 (int (*)(...))QAbstractSpinBox::keyPressEvent
+216 (int (*)(...))QAbstractSpinBox::keyReleaseEvent
+224 (int (*)(...))QAbstractSpinBox::focusInEvent
+232 (int (*)(...))QAbstractSpinBox::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QAbstractSpinBox::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QAbstractSpinBox::resizeEvent
+280 (int (*)(...))QAbstractSpinBox::closeEvent
+288 (int (*)(...))QAbstractSpinBox::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QAbstractSpinBox::showEvent
+352 (int (*)(...))QAbstractSpinBox::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QAbstractSpinBox::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QAbstractSpinBox::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QDoubleSpinBox::validate
+440 (int (*)(...))QDoubleSpinBox::fixup
+448 (int (*)(...))QAbstractSpinBox::stepBy
+456 (int (*)(...))QAbstractSpinBox::clear
+464 (int (*)(...))QAbstractSpinBox::stepEnabled
+472 (int (*)(...))QDoubleSpinBox::valueFromText
+480 (int (*)(...))QDoubleSpinBox::textFromValue
+488 (int (*)(...))-16
+496 (int (*)(...))(& _ZTI14QDoubleSpinBox)
+504 (int (*)(...))QDoubleSpinBox::_ZThn16_N14QDoubleSpinBoxD1Ev
+512 (int (*)(...))QDoubleSpinBox::_ZThn16_N14QDoubleSpinBoxD0Ev
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+552 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+560 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QDoubleSpinBox
+ size=48 align=8
+ base size=48 base align=8
+QDoubleSpinBox (0x0x7f21afe7ae38) 0
+ vptr=((& QDoubleSpinBox::_ZTV14QDoubleSpinBox) + 16u)
+ QAbstractSpinBox (0x0x7f21aff15138) 0
+ primary-for QDoubleSpinBox (0x0x7f21afe7ae38)
+ QWidget (0x0x7f21b59390e0) 0
+ primary-for QAbstractSpinBox (0x0x7f21aff15138)
+ QObject (0x0x7f21ad05bba0) 0
+ primary-for QWidget (0x0x7f21b59390e0)
+ QPaintDevice (0x0x7f21ad05bc00) 16
+ vptr=((& QDoubleSpinBox::_ZTV14QDoubleSpinBox) + 504u)
+
+Class QSplashScreen::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSplashScreen::QPrivateSignal (0x0x7f21ace809c0) 0 empty
+
+Vtable for QSplashScreen
+QSplashScreen::_ZTV13QSplashScreen: 65u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QSplashScreen)
+16 (int (*)(...))QSplashScreen::metaObject
+24 (int (*)(...))QSplashScreen::qt_metacast
+32 (int (*)(...))QSplashScreen::qt_metacall
+40 (int (*)(...))QSplashScreen::~QSplashScreen
+48 (int (*)(...))QSplashScreen::~QSplashScreen
+56 (int (*)(...))QSplashScreen::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QSplashScreen::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QSplashScreen::drawContents
+440 (int (*)(...))-16
+448 (int (*)(...))(& _ZTI13QSplashScreen)
+456 (int (*)(...))QSplashScreen::_ZThn16_N13QSplashScreenD1Ev
+464 (int (*)(...))QSplashScreen::_ZThn16_N13QSplashScreenD0Ev
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QSplashScreen
+ size=48 align=8
+ base size=48 base align=8
+QSplashScreen (0x0x7f21aff151a0) 0
+ vptr=((& QSplashScreen::_ZTV13QSplashScreen) + 16u)
+ QWidget (0x0x7f21b5939a10) 0
+ primary-for QSplashScreen (0x0x7f21aff151a0)
+ QObject (0x0x7f21ad0ac180) 0
+ primary-for QWidget (0x0x7f21b5939a10)
+ QPaintDevice (0x0x7f21ace80960) 16
+ vptr=((& QSplashScreen::_ZTV13QSplashScreen) + 456u)
+
+Class QSplitter::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSplitter::QPrivateSignal (0x0x7f21acb55240) 0 empty
+
+Vtable for QSplitter
+QSplitter::_ZTV9QSplitter: 65u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QSplitter)
+16 (int (*)(...))QSplitter::metaObject
+24 (int (*)(...))QSplitter::qt_metacast
+32 (int (*)(...))QSplitter::qt_metacall
+40 (int (*)(...))QSplitter::~QSplitter
+48 (int (*)(...))QSplitter::~QSplitter
+56 (int (*)(...))QSplitter::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QSplitter::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QSplitter::sizeHint
+136 (int (*)(...))QSplitter::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QFrame::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QSplitter::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QSplitter::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QSplitter::createHandle
+440 (int (*)(...))-16
+448 (int (*)(...))(& _ZTI9QSplitter)
+456 (int (*)(...))QSplitter::_ZThn16_N9QSplitterD1Ev
+464 (int (*)(...))QSplitter::_ZThn16_N9QSplitterD0Ev
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QSplitter
+ size=48 align=8
+ base size=48 base align=8
+QSplitter (0x0x7f21aff15208) 0
+ vptr=((& QSplitter::_ZTV9QSplitter) + 16u)
+ QFrame (0x0x7f21aff15270) 0
+ primary-for QSplitter (0x0x7f21aff15208)
+ QWidget (0x0x7f21b59505b0) 0
+ primary-for QFrame (0x0x7f21aff15270)
+ QObject (0x0x7f21ace80ea0) 0
+ primary-for QWidget (0x0x7f21b59505b0)
+ QPaintDevice (0x0x7f21ace80f00) 16
+ vptr=((& QSplitter::_ZTV9QSplitter) + 456u)
+
+Class QSplitterHandle::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSplitterHandle::QPrivateSignal (0x0x7f21acb55480) 0 empty
+
+Vtable for QSplitterHandle
+QSplitterHandle::_ZTV15QSplitterHandle: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QSplitterHandle)
+16 (int (*)(...))QSplitterHandle::metaObject
+24 (int (*)(...))QSplitterHandle::qt_metacast
+32 (int (*)(...))QSplitterHandle::qt_metacall
+40 (int (*)(...))QSplitterHandle::~QSplitterHandle
+48 (int (*)(...))QSplitterHandle::~QSplitterHandle
+56 (int (*)(...))QSplitterHandle::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QSplitterHandle::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QSplitterHandle::mousePressEvent
+176 (int (*)(...))QSplitterHandle::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QSplitterHandle::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QSplitterHandle::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QSplitterHandle::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI15QSplitterHandle)
+448 (int (*)(...))QSplitterHandle::_ZThn16_N15QSplitterHandleD1Ev
+456 (int (*)(...))QSplitterHandle::_ZThn16_N15QSplitterHandleD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QSplitterHandle
+ size=48 align=8
+ base size=48 base align=8
+QSplitterHandle (0x0x7f21aff152d8) 0
+ vptr=((& QSplitterHandle::_ZTV15QSplitterHandle) + 16u)
+ QWidget (0x0x7f21b5950e70) 0
+ primary-for QSplitterHandle (0x0x7f21aff152d8)
+ QObject (0x0x7f21acb552a0) 0
+ primary-for QWidget (0x0x7f21b5950e70)
+ QPaintDevice (0x0x7f21acb55420) 16
+ vptr=((& QSplitterHandle::_ZTV15QSplitterHandle) + 448u)
+
+Class QStackedLayout::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QStackedLayout::QPrivateSignal (0x0x7f21acb55660) 0 empty
+
+Vtable for QStackedLayout
+QStackedLayout::_ZTV14QStackedLayout: 50u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QStackedLayout)
+16 (int (*)(...))QStackedLayout::metaObject
+24 (int (*)(...))QStackedLayout::qt_metacast
+32 (int (*)(...))QStackedLayout::qt_metacall
+40 (int (*)(...))QStackedLayout::~QStackedLayout
+48 (int (*)(...))QStackedLayout::~QStackedLayout
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QLayout::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QLayout::invalidate
+120 (int (*)(...))QLayout::geometry
+128 (int (*)(...))QStackedLayout::addItem
+136 (int (*)(...))QLayout::expandingDirections
+144 (int (*)(...))QStackedLayout::minimumSize
+152 (int (*)(...))QLayout::maximumSize
+160 (int (*)(...))QStackedLayout::setGeometry
+168 (int (*)(...))QStackedLayout::itemAt
+176 (int (*)(...))QStackedLayout::takeAt
+184 (int (*)(...))QLayout::indexOf
+192 (int (*)(...))QStackedLayout::count
+200 (int (*)(...))QLayout::isEmpty
+208 (int (*)(...))QLayout::controlTypes
+216 (int (*)(...))QLayout::layout
+224 (int (*)(...))QStackedLayout::sizeHint
+232 (int (*)(...))QStackedLayout::hasHeightForWidth
+240 (int (*)(...))QStackedLayout::heightForWidth
+248 (int (*)(...))-16
+256 (int (*)(...))(& _ZTI14QStackedLayout)
+264 (int (*)(...))QStackedLayout::_ZThn16_N14QStackedLayoutD1Ev
+272 (int (*)(...))QStackedLayout::_ZThn16_N14QStackedLayoutD0Ev
+280 (int (*)(...))QStackedLayout::_ZThn16_NK14QStackedLayout8sizeHintEv
+288 (int (*)(...))QStackedLayout::_ZThn16_NK14QStackedLayout11minimumSizeEv
+296 (int (*)(...))QLayout::_ZThn16_NK7QLayout11maximumSizeEv
+304 (int (*)(...))QLayout::_ZThn16_NK7QLayout19expandingDirectionsEv
+312 (int (*)(...))QStackedLayout::_ZThn16_N14QStackedLayout11setGeometryERK5QRect
+320 (int (*)(...))QLayout::_ZThn16_NK7QLayout8geometryEv
+328 (int (*)(...))QLayout::_ZThn16_NK7QLayout7isEmptyEv
+336 (int (*)(...))QStackedLayout::_ZThn16_NK14QStackedLayout17hasHeightForWidthEv
+344 (int (*)(...))QStackedLayout::_ZThn16_NK14QStackedLayout14heightForWidthEi
+352 (int (*)(...))QLayoutItem::minimumHeightForWidth
+360 (int (*)(...))QLayout::_ZThn16_N7QLayout10invalidateEv
+368 (int (*)(...))QLayoutItem::widget
+376 (int (*)(...))QLayout::_ZThn16_N7QLayout6layoutEv
+384 (int (*)(...))QLayoutItem::spacerItem
+392 (int (*)(...))QLayout::_ZThn16_NK7QLayout12controlTypesEv
+
+Class QStackedLayout
+ size=32 align=8
+ base size=28 base align=8
+QStackedLayout (0x0x7f21aff15340) 0
+ vptr=((& QStackedLayout::_ZTV14QStackedLayout) + 16u)
+ QLayout (0x0x7f21b5961460) 0
+ primary-for QStackedLayout (0x0x7f21aff15340)
+ QObject (0x0x7f21acb55540) 0
+ primary-for QLayout (0x0x7f21b5961460)
+ QLayoutItem (0x0x7f21acb55600) 16
+ vptr=((& QStackedLayout::_ZTV14QStackedLayout) + 264u)
+
+Class QStackedWidget::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QStackedWidget::QPrivateSignal (0x0x7f21acb844e0) 0 empty
+
+Vtable for QStackedWidget
+QStackedWidget::_ZTV14QStackedWidget: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI14QStackedWidget)
+16 (int (*)(...))QStackedWidget::metaObject
+24 (int (*)(...))QStackedWidget::qt_metacast
+32 (int (*)(...))QStackedWidget::qt_metacall
+40 (int (*)(...))QStackedWidget::~QStackedWidget
+48 (int (*)(...))QStackedWidget::~QStackedWidget
+56 (int (*)(...))QStackedWidget::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QFrame::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QFrame::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI14QStackedWidget)
+448 (int (*)(...))QStackedWidget::_ZThn16_N14QStackedWidgetD1Ev
+456 (int (*)(...))QStackedWidget::_ZThn16_N14QStackedWidgetD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QStackedWidget
+ size=48 align=8
+ base size=48 base align=8
+QStackedWidget (0x0x7f21aff15618) 0
+ vptr=((& QStackedWidget::_ZTV14QStackedWidget) + 16u)
+ QFrame (0x0x7f21aff15680) 0
+ primary-for QStackedWidget (0x0x7f21aff15618)
+ QWidget (0x0x7f21b5961f50) 0
+ primary-for QFrame (0x0x7f21aff15680)
+ QObject (0x0x7f21acb84240) 0
+ primary-for QWidget (0x0x7f21b5961f50)
+ QPaintDevice (0x0x7f21acb842a0) 16
+ vptr=((& QStackedWidget::_ZTV14QStackedWidget) + 448u)
+
+Class QStatusBar::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QStatusBar::QPrivateSignal (0x0x7f21acb84ea0) 0 empty
+
+Vtable for QStatusBar
+QStatusBar::_ZTV10QStatusBar: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QStatusBar)
+16 (int (*)(...))QStatusBar::metaObject
+24 (int (*)(...))QStatusBar::qt_metacast
+32 (int (*)(...))QStatusBar::qt_metacall
+40 (int (*)(...))QStatusBar::~QStatusBar
+48 (int (*)(...))QStatusBar::~QStatusBar
+56 (int (*)(...))QStatusBar::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QStatusBar::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QStatusBar::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QStatusBar::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI10QStatusBar)
+448 (int (*)(...))QStatusBar::_ZThn16_N10QStatusBarD1Ev
+456 (int (*)(...))QStatusBar::_ZThn16_N10QStatusBarD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QStatusBar
+ size=48 align=8
+ base size=48 base align=8
+QStatusBar (0x0x7f21aff86270) 0
+ vptr=((& QStatusBar::_ZTV10QStatusBar) + 16u)
+ QWidget (0x0x7f21b596f690) 0
+ primary-for QStatusBar (0x0x7f21aff86270)
+ QObject (0x0x7f21acb84540) 0
+ primary-for QWidget (0x0x7f21b596f690)
+ QPaintDevice (0x0x7f21acb84e40) 16
+ vptr=((& QStatusBar::_ZTV10QStatusBar) + 448u)
+
+Class QStyledItemDelegate::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QStyledItemDelegate::QPrivateSignal (0x0x7f21acba7060) 0 empty
+
+Vtable for QStyledItemDelegate
+QStyledItemDelegate::_ZTV19QStyledItemDelegate: 26u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI19QStyledItemDelegate)
+16 (int (*)(...))QStyledItemDelegate::metaObject
+24 (int (*)(...))QStyledItemDelegate::qt_metacast
+32 (int (*)(...))QStyledItemDelegate::qt_metacall
+40 (int (*)(...))QStyledItemDelegate::~QStyledItemDelegate
+48 (int (*)(...))QStyledItemDelegate::~QStyledItemDelegate
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QStyledItemDelegate::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QStyledItemDelegate::paint
+120 (int (*)(...))QStyledItemDelegate::sizeHint
+128 (int (*)(...))QStyledItemDelegate::createEditor
+136 (int (*)(...))QAbstractItemDelegate::destroyEditor
+144 (int (*)(...))QStyledItemDelegate::setEditorData
+152 (int (*)(...))QStyledItemDelegate::setModelData
+160 (int (*)(...))QStyledItemDelegate::updateEditorGeometry
+168 (int (*)(...))QStyledItemDelegate::editorEvent
+176 (int (*)(...))QAbstractItemDelegate::helpEvent
+184 (int (*)(...))QAbstractItemDelegate::paintingRoles
+192 (int (*)(...))QStyledItemDelegate::displayText
+200 (int (*)(...))QStyledItemDelegate::initStyleOption
+
+Class QStyledItemDelegate
+ size=16 align=8
+ base size=16 base align=8
+QStyledItemDelegate (0x0x7f21aff862d8) 0
+ vptr=((& QStyledItemDelegate::_ZTV19QStyledItemDelegate) + 16u)
+ QAbstractItemDelegate (0x0x7f21afb83138) 0
+ primary-for QStyledItemDelegate (0x0x7f21aff862d8)
+ QObject (0x0x7f21acba7000) 0
+ primary-for QAbstractItemDelegate (0x0x7f21afb83138)
+
+Class QStyleFactory
+ size=1 align=1
+ base size=0 base align=1
+QStyleFactory (0x0x7f21acba72a0) 0 empty
+
+Class QStylePainter
+ size=24 align=8
+ base size=24 base align=8
+QStylePainter (0x0x7f21afb831a0) 0
+ QPainter (0x0x7f21acba7300) 0
+
+Class QStylePlugin::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QStylePlugin::QPrivateSignal (0x0x7f21acbe3660) 0 empty
+
+Vtable for QStylePlugin
+QStylePlugin::_ZTV12QStylePlugin: 15u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QStylePlugin)
+16 (int (*)(...))QStylePlugin::metaObject
+24 (int (*)(...))QStylePlugin::qt_metacast
+32 (int (*)(...))QStylePlugin::qt_metacall
+40 0u
+48 0u
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))__cxa_pure_virtual
+
+Class QStylePlugin
+ size=16 align=8
+ base size=16 base align=8
+QStylePlugin (0x0x7f21af5975b0) 0
+ vptr=((& QStylePlugin::_ZTV12QStylePlugin) + 16u)
+ QObject (0x0x7f21acba7d80) 0
+ primary-for QStylePlugin (0x0x7f21af5975b0)
+
+Class QSystemTrayIcon::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QSystemTrayIcon::QPrivateSignal (0x0x7f21acbe3780) 0 empty
+
+Vtable for QSystemTrayIcon
+QSystemTrayIcon::_ZTV15QSystemTrayIcon: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QSystemTrayIcon)
+16 (int (*)(...))QSystemTrayIcon::metaObject
+24 (int (*)(...))QSystemTrayIcon::qt_metacast
+32 (int (*)(...))QSystemTrayIcon::qt_metacall
+40 (int (*)(...))QSystemTrayIcon::~QSystemTrayIcon
+48 (int (*)(...))QSystemTrayIcon::~QSystemTrayIcon
+56 (int (*)(...))QSystemTrayIcon::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QSystemTrayIcon
+ size=16 align=8
+ base size=16 base align=8
+QSystemTrayIcon (0x0x7f21af597820) 0
+ vptr=((& QSystemTrayIcon::_ZTV15QSystemTrayIcon) + 16u)
+ QObject (0x0x7f21acbe36c0) 0
+ primary-for QSystemTrayIcon (0x0x7f21af597820)
+
+Class QTableView::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTableView::QPrivateSignal (0x0x7f21acc053c0) 0 empty
+
+Vtable for QTableView
+QTableView::_ZTV10QTableView: 106u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QTableView)
+16 (int (*)(...))QTableView::metaObject
+24 (int (*)(...))QTableView::qt_metacast
+32 (int (*)(...))QTableView::qt_metacall
+40 (int (*)(...))QTableView::~QTableView
+48 (int (*)(...))QTableView::~QTableView
+56 (int (*)(...))QAbstractItemView::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QTableView::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractScrollArea::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractItemView::mousePressEvent
+176 (int (*)(...))QAbstractItemView::mouseReleaseEvent
+184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractItemView::mouseMoveEvent
+200 (int (*)(...))QAbstractScrollArea::wheelEvent
+208 (int (*)(...))QAbstractItemView::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QAbstractItemView::focusInEvent
+232 (int (*)(...))QAbstractItemView::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QTableView::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QAbstractItemView::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QAbstractScrollArea::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QAbstractItemView::dragEnterEvent
+320 (int (*)(...))QAbstractItemView::dragMoveEvent
+328 (int (*)(...))QAbstractItemView::dragLeaveEvent
+336 (int (*)(...))QAbstractItemView::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QAbstractItemView::inputMethodEvent
+416 (int (*)(...))QAbstractItemView::inputMethodQuery
+424 (int (*)(...))QAbstractItemView::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QAbstractItemView::viewportEvent
+448 (int (*)(...))QTableView::scrollContentsBy
+456 (int (*)(...))QTableView::viewportSizeHint
+464 (int (*)(...))QTableView::setModel
+472 (int (*)(...))QTableView::setSelectionModel
+480 (int (*)(...))QAbstractItemView::keyboardSearch
+488 (int (*)(...))QTableView::visualRect
+496 (int (*)(...))QTableView::scrollTo
+504 (int (*)(...))QTableView::indexAt
+512 (int (*)(...))QTableView::sizeHintForRow
+520 (int (*)(...))QTableView::sizeHintForColumn
+528 (int (*)(...))QAbstractItemView::reset
+536 (int (*)(...))QTableView::setRootIndex
+544 (int (*)(...))QTableView::doItemsLayout
+552 (int (*)(...))QAbstractItemView::selectAll
+560 (int (*)(...))QAbstractItemView::dataChanged
+568 (int (*)(...))QAbstractItemView::rowsInserted
+576 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved
+584 (int (*)(...))QTableView::selectionChanged
+592 (int (*)(...))QTableView::currentChanged
+600 (int (*)(...))QAbstractItemView::updateEditorData
+608 (int (*)(...))QAbstractItemView::updateEditorGeometries
+616 (int (*)(...))QTableView::updateGeometries
+624 (int (*)(...))QTableView::verticalScrollbarAction
+632 (int (*)(...))QTableView::horizontalScrollbarAction
+640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged
+648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged
+656 (int (*)(...))QAbstractItemView::closeEditor
+664 (int (*)(...))QAbstractItemView::commitData
+672 (int (*)(...))QAbstractItemView::editorDestroyed
+680 (int (*)(...))QTableView::moveCursor
+688 (int (*)(...))QTableView::horizontalOffset
+696 (int (*)(...))QTableView::verticalOffset
+704 (int (*)(...))QTableView::isIndexHidden
+712 (int (*)(...))QTableView::setSelection
+720 (int (*)(...))QTableView::visualRegionForSelection
+728 (int (*)(...))QTableView::selectedIndexes
+736 (int (*)(...))QAbstractItemView::edit
+744 (int (*)(...))QAbstractItemView::selectionCommand
+752 (int (*)(...))QAbstractItemView::startDrag
+760 (int (*)(...))QTableView::viewOptions
+768 (int (*)(...))-16
+776 (int (*)(...))(& _ZTI10QTableView)
+784 (int (*)(...))QTableView::_ZThn16_N10QTableViewD1Ev
+792 (int (*)(...))QTableView::_ZThn16_N10QTableViewD0Ev
+800 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+808 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+816 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+832 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+840 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QTableView
+ size=48 align=8
+ base size=48 base align=8
+QTableView (0x0x7f21af597888) 0
+ vptr=((& QTableView::_ZTV10QTableView) + 16u)
+ QAbstractItemView (0x0x7f21af597a90) 0
+ primary-for QTableView (0x0x7f21af597888)
+ QAbstractScrollArea (0x0x7f21af597af8) 0
+ primary-for QAbstractItemView (0x0x7f21af597a90)
+ QFrame (0x0x7f21af597b60) 0
+ primary-for QAbstractScrollArea (0x0x7f21af597af8)
+ QWidget (0x0x7f21b59c1d90) 0
+ primary-for QFrame (0x0x7f21af597b60)
+ QObject (0x0x7f21acbe3960) 0
+ primary-for QWidget (0x0x7f21b59c1d90)
+ QPaintDevice (0x0x7f21acbe39c0) 16
+ vptr=((& QTableView::_ZTV10QTableView) + 784u)
+
+Class QTableWidgetSelectionRange
+ size=16 align=4
+ base size=16 base align=4
+QTableWidgetSelectionRange (0x0x7f21acc05420) 0
+
+Vtable for QTableWidgetItem
+QTableWidgetItem::_ZTV16QTableWidgetItem: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI16QTableWidgetItem)
+16 (int (*)(...))QTableWidgetItem::~QTableWidgetItem
+24 (int (*)(...))QTableWidgetItem::~QTableWidgetItem
+32 (int (*)(...))QTableWidgetItem::clone
+40 (int (*)(...))QTableWidgetItem::data
+48 (int (*)(...))QTableWidgetItem::setData
+56 (int (*)(...))QTableWidgetItem::operator<
+64 (int (*)(...))QTableWidgetItem::read
+72 (int (*)(...))QTableWidgetItem::write
+
+Class QTableWidgetItem
+ size=48 align=8
+ base size=44 base align=8
+QTableWidgetItem (0x0x7f21acc05540) 0
+ vptr=((& QTableWidgetItem::_ZTV16QTableWidgetItem) + 16u)
+
+Class QTableWidget::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTableWidget::QPrivateSignal (0x0x7f21acc304e0) 0 empty
+
+Vtable for QTableWidget
+QTableWidget::_ZTV12QTableWidget: 110u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QTableWidget)
+16 (int (*)(...))QTableWidget::metaObject
+24 (int (*)(...))QTableWidget::qt_metacast
+32 (int (*)(...))QTableWidget::qt_metacall
+40 (int (*)(...))QTableWidget::~QTableWidget
+48 (int (*)(...))QTableWidget::~QTableWidget
+56 (int (*)(...))QTableWidget::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QTableView::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractScrollArea::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractItemView::mousePressEvent
+176 (int (*)(...))QAbstractItemView::mouseReleaseEvent
+184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractItemView::mouseMoveEvent
+200 (int (*)(...))QAbstractScrollArea::wheelEvent
+208 (int (*)(...))QAbstractItemView::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QAbstractItemView::focusInEvent
+232 (int (*)(...))QAbstractItemView::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QTableView::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QAbstractItemView::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QAbstractScrollArea::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QAbstractItemView::dragEnterEvent
+320 (int (*)(...))QAbstractItemView::dragMoveEvent
+328 (int (*)(...))QAbstractItemView::dragLeaveEvent
+336 (int (*)(...))QTableWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QAbstractItemView::inputMethodEvent
+416 (int (*)(...))QAbstractItemView::inputMethodQuery
+424 (int (*)(...))QAbstractItemView::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QAbstractItemView::viewportEvent
+448 (int (*)(...))QTableView::scrollContentsBy
+456 (int (*)(...))QTableView::viewportSizeHint
+464 (int (*)(...))QTableWidget::setModel
+472 (int (*)(...))QTableView::setSelectionModel
+480 (int (*)(...))QAbstractItemView::keyboardSearch
+488 (int (*)(...))QTableView::visualRect
+496 (int (*)(...))QTableView::scrollTo
+504 (int (*)(...))QTableView::indexAt
+512 (int (*)(...))QTableView::sizeHintForRow
+520 (int (*)(...))QTableView::sizeHintForColumn
+528 (int (*)(...))QAbstractItemView::reset
+536 (int (*)(...))QTableView::setRootIndex
+544 (int (*)(...))QTableView::doItemsLayout
+552 (int (*)(...))QAbstractItemView::selectAll
+560 (int (*)(...))QAbstractItemView::dataChanged
+568 (int (*)(...))QAbstractItemView::rowsInserted
+576 (int (*)(...))QAbstractItemView::rowsAboutToBeRemoved
+584 (int (*)(...))QTableView::selectionChanged
+592 (int (*)(...))QTableView::currentChanged
+600 (int (*)(...))QAbstractItemView::updateEditorData
+608 (int (*)(...))QAbstractItemView::updateEditorGeometries
+616 (int (*)(...))QTableView::updateGeometries
+624 (int (*)(...))QTableView::verticalScrollbarAction
+632 (int (*)(...))QTableView::horizontalScrollbarAction
+640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged
+648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged
+656 (int (*)(...))QAbstractItemView::closeEditor
+664 (int (*)(...))QAbstractItemView::commitData
+672 (int (*)(...))QAbstractItemView::editorDestroyed
+680 (int (*)(...))QTableView::moveCursor
+688 (int (*)(...))QTableView::horizontalOffset
+696 (int (*)(...))QTableView::verticalOffset
+704 (int (*)(...))QTableView::isIndexHidden
+712 (int (*)(...))QTableView::setSelection
+720 (int (*)(...))QTableView::visualRegionForSelection
+728 (int (*)(...))QTableView::selectedIndexes
+736 (int (*)(...))QAbstractItemView::edit
+744 (int (*)(...))QAbstractItemView::selectionCommand
+752 (int (*)(...))QAbstractItemView::startDrag
+760 (int (*)(...))QTableView::viewOptions
+768 (int (*)(...))QTableWidget::mimeTypes
+776 (int (*)(...))QTableWidget::mimeData
+784 (int (*)(...))QTableWidget::dropMimeData
+792 (int (*)(...))QTableWidget::supportedDropActions
+800 (int (*)(...))-16
+808 (int (*)(...))(& _ZTI12QTableWidget)
+816 (int (*)(...))QTableWidget::_ZThn16_N12QTableWidgetD1Ev
+824 (int (*)(...))QTableWidget::_ZThn16_N12QTableWidgetD0Ev
+832 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+840 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+848 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+856 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+864 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+872 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QTableWidget
+ size=48 align=8
+ base size=48 base align=8
+QTableWidget (0x0x7f21af4097b8) 0
+ vptr=((& QTableWidget::_ZTV12QTableWidget) + 16u)
+ QTableView (0x0x7f21af409820) 0
+ primary-for QTableWidget (0x0x7f21af4097b8)
+ QAbstractItemView (0x0x7f21af409888) 0
+ primary-for QTableView (0x0x7f21af409820)
+ QAbstractScrollArea (0x0x7f21af4098f0) 0
+ primary-for QAbstractItemView (0x0x7f21af409888)
+ QFrame (0x0x7f21af409a90) 0
+ primary-for QAbstractScrollArea (0x0x7f21af4098f0)
+ QWidget (0x0x7f21b59ee770) 0
+ primary-for QFrame (0x0x7f21af409a90)
+ QObject (0x0x7f21acc30180) 0
+ primary-for QWidget (0x0x7f21b59ee770)
+ QPaintDevice (0x0x7f21acc301e0) 16
+ vptr=((& QTableWidget::_ZTV12QTableWidget) + 816u)
+
+Class QTextBrowser::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTextBrowser::QPrivateSignal (0x0x7f21abf4e2a0) 0 empty
+
+Vtable for QTextBrowser
+QTextBrowser::_ZTV12QTextBrowser: 78u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QTextBrowser)
+16 (int (*)(...))QTextBrowser::metaObject
+24 (int (*)(...))QTextBrowser::qt_metacast
+32 (int (*)(...))QTextBrowser::qt_metacall
+40 (int (*)(...))QTextBrowser::~QTextBrowser
+48 (int (*)(...))QTextBrowser::~QTextBrowser
+56 (int (*)(...))QTextBrowser::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QTextEdit::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractScrollArea::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QTextBrowser::mousePressEvent
+176 (int (*)(...))QTextBrowser::mouseReleaseEvent
+184 (int (*)(...))QTextEdit::mouseDoubleClickEvent
+192 (int (*)(...))QTextBrowser::mouseMoveEvent
+200 (int (*)(...))QTextEdit::wheelEvent
+208 (int (*)(...))QTextBrowser::keyPressEvent
+216 (int (*)(...))QTextEdit::keyReleaseEvent
+224 (int (*)(...))QTextEdit::focusInEvent
+232 (int (*)(...))QTextBrowser::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QTextBrowser::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QTextEdit::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QTextEdit::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QTextEdit::dragEnterEvent
+320 (int (*)(...))QTextEdit::dragMoveEvent
+328 (int (*)(...))QTextEdit::dragLeaveEvent
+336 (int (*)(...))QTextEdit::dropEvent
+344 (int (*)(...))QTextEdit::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QTextEdit::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QTextEdit::inputMethodEvent
+416 (int (*)(...))QTextEdit::inputMethodQuery
+424 (int (*)(...))QTextBrowser::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QAbstractScrollArea::viewportEvent
+448 (int (*)(...))QTextEdit::scrollContentsBy
+456 (int (*)(...))QAbstractScrollArea::viewportSizeHint
+464 (int (*)(...))QTextBrowser::loadResource
+472 (int (*)(...))QTextEdit::createMimeDataFromSelection
+480 (int (*)(...))QTextEdit::canInsertFromMimeData
+488 (int (*)(...))QTextEdit::insertFromMimeData
+496 (int (*)(...))QTextEdit::doSetTextCursor
+504 (int (*)(...))QTextBrowser::setSource
+512 (int (*)(...))QTextBrowser::backward
+520 (int (*)(...))QTextBrowser::forward
+528 (int (*)(...))QTextBrowser::home
+536 (int (*)(...))QTextBrowser::reload
+544 (int (*)(...))-16
+552 (int (*)(...))(& _ZTI12QTextBrowser)
+560 (int (*)(...))QTextBrowser::_ZThn16_N12QTextBrowserD1Ev
+568 (int (*)(...))QTextBrowser::_ZThn16_N12QTextBrowserD0Ev
+576 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+584 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+592 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+600 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+608 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+616 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QTextBrowser
+ size=48 align=8
+ base size=48 base align=8
+QTextBrowser (0x0x7f21af409af8) 0
+ vptr=((& QTextBrowser::_ZTV12QTextBrowser) + 16u)
+ QTextEdit (0x0x7f21af4f6068) 0
+ primary-for QTextBrowser (0x0x7f21af409af8)
+ QAbstractScrollArea (0x0x7f21af4f60d0) 0
+ primary-for QTextEdit (0x0x7f21af4f6068)
+ QFrame (0x0x7f21af4f63a8) 0
+ primary-for QAbstractScrollArea (0x0x7f21af4f60d0)
+ QWidget (0x0x7f21b59f9540) 0
+ primary-for QFrame (0x0x7f21af4f63a8)
+ QObject (0x0x7f21acc30540) 0
+ primary-for QWidget (0x0x7f21b59f9540)
+ QPaintDevice (0x0x7f21abf4e240) 16
+ vptr=((& QTextBrowser::_ZTV12QTextBrowser) + 560u)
+
+Class QToolBar::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QToolBar::QPrivateSignal (0x0x7f21ab705ba0) 0 empty
+
+Vtable for QToolBar
+QToolBar::_ZTV8QToolBar: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QToolBar)
+16 (int (*)(...))QToolBar::metaObject
+24 (int (*)(...))QToolBar::qt_metacast
+32 (int (*)(...))QToolBar::qt_metacall
+40 (int (*)(...))QToolBar::~QToolBar
+48 (int (*)(...))QToolBar::~QToolBar
+56 (int (*)(...))QToolBar::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QToolBar::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QToolBar::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QToolBar::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI8QToolBar)
+448 (int (*)(...))QToolBar::_ZThn16_N8QToolBarD1Ev
+456 (int (*)(...))QToolBar::_ZThn16_N8QToolBarD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QToolBar
+ size=48 align=8
+ base size=48 base align=8
+QToolBar (0x0x7f21af4f6410) 0
+ vptr=((& QToolBar::_ZTV8QToolBar) + 16u)
+ QWidget (0x0x7f21b59f9a80) 0
+ primary-for QToolBar (0x0x7f21af4f6410)
+ QObject (0x0x7f21ab705ae0) 0
+ primary-for QWidget (0x0x7f21b59f9a80)
+ QPaintDevice (0x0x7f21ab705b40) 16
+ vptr=((& QToolBar::_ZTV8QToolBar) + 448u)
+
+Class QToolBox::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QToolBox::QPrivateSignal (0x0x7f21aa991240) 0 empty
+
+Vtable for QToolBox
+QToolBox::_ZTV8QToolBox: 66u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI8QToolBox)
+16 (int (*)(...))QToolBox::metaObject
+24 (int (*)(...))QToolBox::qt_metacast
+32 (int (*)(...))QToolBox::qt_metacall
+40 (int (*)(...))QToolBox::~QToolBox
+48 (int (*)(...))QToolBox::~QToolBox
+56 (int (*)(...))QToolBox::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QFrame::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QFrame::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QToolBox::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QToolBox::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QToolBox::itemInserted
+440 (int (*)(...))QToolBox::itemRemoved
+448 (int (*)(...))-16
+456 (int (*)(...))(& _ZTI8QToolBox)
+464 (int (*)(...))QToolBox::_ZThn16_N8QToolBoxD1Ev
+472 (int (*)(...))QToolBox::_ZThn16_N8QToolBoxD0Ev
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QToolBox
+ size=48 align=8
+ base size=48 base align=8
+QToolBox (0x0x7f21af1825b0) 0
+ vptr=((& QToolBox::_ZTV8QToolBox) + 16u)
+ QFrame (0x0x7f21af182618) 0
+ primary-for QToolBox (0x0x7f21af1825b0)
+ QWidget (0x0x7f21b5a15460) 0
+ primary-for QFrame (0x0x7f21af182618)
+ QObject (0x0x7f21ab4a48a0) 0
+ primary-for QWidget (0x0x7f21b5a15460)
+ QPaintDevice (0x0x7f21aa9911e0) 16
+ vptr=((& QToolBox::_ZTV8QToolBox) + 464u)
+
+Class QToolButton::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QToolButton::QPrivateSignal (0x0x7f21aa991420) 0 empty
+
+Vtable for QToolButton
+QToolButton::_ZTV11QToolButton: 67u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QToolButton)
+16 (int (*)(...))QToolButton::metaObject
+24 (int (*)(...))QToolButton::qt_metacast
+32 (int (*)(...))QToolButton::qt_metacall
+40 (int (*)(...))QToolButton::~QToolButton
+48 (int (*)(...))QToolButton::~QToolButton
+56 (int (*)(...))QToolButton::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QToolButton::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QToolButton::sizeHint
+136 (int (*)(...))QToolButton::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QToolButton::mousePressEvent
+176 (int (*)(...))QToolButton::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QAbstractButton::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QAbstractButton::keyPressEvent
+216 (int (*)(...))QAbstractButton::keyReleaseEvent
+224 (int (*)(...))QAbstractButton::focusInEvent
+232 (int (*)(...))QAbstractButton::focusOutEvent
+240 (int (*)(...))QToolButton::enterEvent
+248 (int (*)(...))QToolButton::leaveEvent
+256 (int (*)(...))QToolButton::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QToolButton::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QToolButton::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QToolButton::hitButton
+440 (int (*)(...))QAbstractButton::checkStateSet
+448 (int (*)(...))QToolButton::nextCheckState
+456 (int (*)(...))-16
+464 (int (*)(...))(& _ZTI11QToolButton)
+472 (int (*)(...))QToolButton::_ZThn16_N11QToolButtonD1Ev
+480 (int (*)(...))QToolButton::_ZThn16_N11QToolButtonD0Ev
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QToolButton
+ size=48 align=8
+ base size=48 base align=8
+QToolButton (0x0x7f21af182c98) 0
+ vptr=((& QToolButton::_ZTV11QToolButton) + 16u)
+ QAbstractButton (0x0x7f21af182d00) 0
+ primary-for QToolButton (0x0x7f21af182c98)
+ QWidget (0x0x7f21b5a15d90) 0
+ primary-for QAbstractButton (0x0x7f21af182d00)
+ QObject (0x0x7f21aa991300) 0
+ primary-for QWidget (0x0x7f21b5a15d90)
+ QPaintDevice (0x0x7f21aa9913c0) 16
+ vptr=((& QToolButton::_ZTV11QToolButton) + 472u)
+
+Class QToolTip
+ size=1 align=1
+ base size=0 base align=1
+QToolTip (0x0x7f21aa9914e0) 0 empty
+
+Class QTreeView::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTreeView::QPrivateSignal (0x0x7f21aa82cf60) 0 empty
+
+Vtable for QTreeView
+QTreeView::_ZTV9QTreeView: 108u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QTreeView)
+16 (int (*)(...))QTreeView::metaObject
+24 (int (*)(...))QTreeView::qt_metacast
+32 (int (*)(...))QTreeView::qt_metacall
+40 (int (*)(...))QTreeView::~QTreeView
+48 (int (*)(...))QTreeView::~QTreeView
+56 (int (*)(...))QAbstractItemView::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QTreeView::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractScrollArea::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QTreeView::mousePressEvent
+176 (int (*)(...))QTreeView::mouseReleaseEvent
+184 (int (*)(...))QTreeView::mouseDoubleClickEvent
+192 (int (*)(...))QTreeView::mouseMoveEvent
+200 (int (*)(...))QAbstractScrollArea::wheelEvent
+208 (int (*)(...))QTreeView::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QAbstractItemView::focusInEvent
+232 (int (*)(...))QAbstractItemView::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QTreeView::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QAbstractItemView::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QAbstractScrollArea::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QAbstractItemView::dragEnterEvent
+320 (int (*)(...))QTreeView::dragMoveEvent
+328 (int (*)(...))QAbstractItemView::dragLeaveEvent
+336 (int (*)(...))QAbstractItemView::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QAbstractItemView::inputMethodEvent
+416 (int (*)(...))QAbstractItemView::inputMethodQuery
+424 (int (*)(...))QAbstractItemView::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QTreeView::viewportEvent
+448 (int (*)(...))QTreeView::scrollContentsBy
+456 (int (*)(...))QTreeView::viewportSizeHint
+464 (int (*)(...))QTreeView::setModel
+472 (int (*)(...))QTreeView::setSelectionModel
+480 (int (*)(...))QTreeView::keyboardSearch
+488 (int (*)(...))QTreeView::visualRect
+496 (int (*)(...))QTreeView::scrollTo
+504 (int (*)(...))QTreeView::indexAt
+512 (int (*)(...))QAbstractItemView::sizeHintForRow
+520 (int (*)(...))QTreeView::sizeHintForColumn
+528 (int (*)(...))QTreeView::reset
+536 (int (*)(...))QTreeView::setRootIndex
+544 (int (*)(...))QTreeView::doItemsLayout
+552 (int (*)(...))QTreeView::selectAll
+560 (int (*)(...))QTreeView::dataChanged
+568 (int (*)(...))QTreeView::rowsInserted
+576 (int (*)(...))QTreeView::rowsAboutToBeRemoved
+584 (int (*)(...))QTreeView::selectionChanged
+592 (int (*)(...))QTreeView::currentChanged
+600 (int (*)(...))QAbstractItemView::updateEditorData
+608 (int (*)(...))QAbstractItemView::updateEditorGeometries
+616 (int (*)(...))QTreeView::updateGeometries
+624 (int (*)(...))QAbstractItemView::verticalScrollbarAction
+632 (int (*)(...))QTreeView::horizontalScrollbarAction
+640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged
+648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged
+656 (int (*)(...))QAbstractItemView::closeEditor
+664 (int (*)(...))QAbstractItemView::commitData
+672 (int (*)(...))QAbstractItemView::editorDestroyed
+680 (int (*)(...))QTreeView::moveCursor
+688 (int (*)(...))QTreeView::horizontalOffset
+696 (int (*)(...))QTreeView::verticalOffset
+704 (int (*)(...))QTreeView::isIndexHidden
+712 (int (*)(...))QTreeView::setSelection
+720 (int (*)(...))QTreeView::visualRegionForSelection
+728 (int (*)(...))QTreeView::selectedIndexes
+736 (int (*)(...))QAbstractItemView::edit
+744 (int (*)(...))QAbstractItemView::selectionCommand
+752 (int (*)(...))QAbstractItemView::startDrag
+760 (int (*)(...))QAbstractItemView::viewOptions
+768 (int (*)(...))QTreeView::drawRow
+776 (int (*)(...))QTreeView::drawBranches
+784 (int (*)(...))-16
+792 (int (*)(...))(& _ZTI9QTreeView)
+800 (int (*)(...))QTreeView::_ZThn16_N9QTreeViewD1Ev
+808 (int (*)(...))QTreeView::_ZThn16_N9QTreeViewD0Ev
+816 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+832 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+840 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+848 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+856 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QTreeView
+ size=48 align=8
+ base size=48 base align=8
+QTreeView (0x0x7f21af19b138) 0
+ vptr=((& QTreeView::_ZTV9QTreeView) + 16u)
+ QAbstractItemView (0x0x7f21af19b1a0) 0
+ primary-for QTreeView (0x0x7f21af19b138)
+ QAbstractScrollArea (0x0x7f21af19b958) 0
+ primary-for QAbstractItemView (0x0x7f21af19b1a0)
+ QFrame (0x0x7f21af19b9c0) 0
+ primary-for QAbstractScrollArea (0x0x7f21af19b958)
+ QWidget (0x0x7f21b5a20850) 0
+ primary-for QFrame (0x0x7f21af19b9c0)
+ QObject (0x0x7f21aa991540) 0
+ primary-for QWidget (0x0x7f21b5a20850)
+ QPaintDevice (0x0x7f21aa9915a0) 16
+ vptr=((& QTreeView::_ZTV9QTreeView) + 800u)
+
+Class QTreeWidgetItemIterator
+ size=24 align=8
+ base size=20 base align=8
+QTreeWidgetItemIterator (0x0x7f21aa855000) 0
+
+Vtable for QTreeWidgetItem
+QTreeWidgetItem::_ZTV15QTreeWidgetItem: 10u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI15QTreeWidgetItem)
+16 (int (*)(...))QTreeWidgetItem::~QTreeWidgetItem
+24 (int (*)(...))QTreeWidgetItem::~QTreeWidgetItem
+32 (int (*)(...))QTreeWidgetItem::clone
+40 (int (*)(...))QTreeWidgetItem::data
+48 (int (*)(...))QTreeWidgetItem::setData
+56 (int (*)(...))QTreeWidgetItem::operator<
+64 (int (*)(...))QTreeWidgetItem::read
+72 (int (*)(...))QTreeWidgetItem::write
+
+Class QTreeWidgetItem
+ size=64 align=8
+ base size=60 base align=8
+QTreeWidgetItem (0x0x7f21a9a71a80) 0
+ vptr=((& QTreeWidgetItem::_ZTV15QTreeWidgetItem) + 16u)
+
+Class QTreeWidget::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QTreeWidget::QPrivateSignal (0x0x7f21a9a71d80) 0 empty
+
+Vtable for QTreeWidget
+QTreeWidget::_ZTV11QTreeWidget: 112u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QTreeWidget)
+16 (int (*)(...))QTreeWidget::metaObject
+24 (int (*)(...))QTreeWidget::qt_metacast
+32 (int (*)(...))QTreeWidget::qt_metacall
+40 (int (*)(...))QTreeWidget::~QTreeWidget
+48 (int (*)(...))QTreeWidget::~QTreeWidget
+56 (int (*)(...))QTreeWidget::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QTreeView::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractScrollArea::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QTreeView::mousePressEvent
+176 (int (*)(...))QTreeView::mouseReleaseEvent
+184 (int (*)(...))QTreeView::mouseDoubleClickEvent
+192 (int (*)(...))QTreeView::mouseMoveEvent
+200 (int (*)(...))QAbstractScrollArea::wheelEvent
+208 (int (*)(...))QTreeView::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QAbstractItemView::focusInEvent
+232 (int (*)(...))QAbstractItemView::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QTreeView::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QAbstractItemView::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QAbstractScrollArea::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QAbstractItemView::dragEnterEvent
+320 (int (*)(...))QTreeView::dragMoveEvent
+328 (int (*)(...))QAbstractItemView::dragLeaveEvent
+336 (int (*)(...))QTreeWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QAbstractItemView::inputMethodEvent
+416 (int (*)(...))QAbstractItemView::inputMethodQuery
+424 (int (*)(...))QAbstractItemView::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QTreeView::viewportEvent
+448 (int (*)(...))QTreeView::scrollContentsBy
+456 (int (*)(...))QTreeView::viewportSizeHint
+464 (int (*)(...))QTreeWidget::setModel
+472 (int (*)(...))QTreeWidget::setSelectionModel
+480 (int (*)(...))QTreeView::keyboardSearch
+488 (int (*)(...))QTreeView::visualRect
+496 (int (*)(...))QTreeView::scrollTo
+504 (int (*)(...))QTreeView::indexAt
+512 (int (*)(...))QAbstractItemView::sizeHintForRow
+520 (int (*)(...))QTreeView::sizeHintForColumn
+528 (int (*)(...))QTreeView::reset
+536 (int (*)(...))QTreeView::setRootIndex
+544 (int (*)(...))QTreeView::doItemsLayout
+552 (int (*)(...))QTreeView::selectAll
+560 (int (*)(...))QTreeView::dataChanged
+568 (int (*)(...))QTreeView::rowsInserted
+576 (int (*)(...))QTreeView::rowsAboutToBeRemoved
+584 (int (*)(...))QTreeView::selectionChanged
+592 (int (*)(...))QTreeView::currentChanged
+600 (int (*)(...))QAbstractItemView::updateEditorData
+608 (int (*)(...))QAbstractItemView::updateEditorGeometries
+616 (int (*)(...))QTreeView::updateGeometries
+624 (int (*)(...))QAbstractItemView::verticalScrollbarAction
+632 (int (*)(...))QTreeView::horizontalScrollbarAction
+640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged
+648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged
+656 (int (*)(...))QAbstractItemView::closeEditor
+664 (int (*)(...))QAbstractItemView::commitData
+672 (int (*)(...))QAbstractItemView::editorDestroyed
+680 (int (*)(...))QTreeView::moveCursor
+688 (int (*)(...))QTreeView::horizontalOffset
+696 (int (*)(...))QTreeView::verticalOffset
+704 (int (*)(...))QTreeView::isIndexHidden
+712 (int (*)(...))QTreeView::setSelection
+720 (int (*)(...))QTreeView::visualRegionForSelection
+728 (int (*)(...))QTreeView::selectedIndexes
+736 (int (*)(...))QAbstractItemView::edit
+744 (int (*)(...))QAbstractItemView::selectionCommand
+752 (int (*)(...))QAbstractItemView::startDrag
+760 (int (*)(...))QAbstractItemView::viewOptions
+768 (int (*)(...))QTreeView::drawRow
+776 (int (*)(...))QTreeView::drawBranches
+784 (int (*)(...))QTreeWidget::mimeTypes
+792 (int (*)(...))QTreeWidget::mimeData
+800 (int (*)(...))QTreeWidget::dropMimeData
+808 (int (*)(...))QTreeWidget::supportedDropActions
+816 (int (*)(...))-16
+824 (int (*)(...))(& _ZTI11QTreeWidget)
+832 (int (*)(...))QTreeWidget::_ZThn16_N11QTreeWidgetD1Ev
+840 (int (*)(...))QTreeWidget::_ZThn16_N11QTreeWidgetD0Ev
+848 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+856 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+864 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+872 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+880 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+888 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QTreeWidget
+ size=48 align=8
+ base size=48 base align=8
+QTreeWidget (0x0x7f21aeffbc98) 0
+ vptr=((& QTreeWidget::_ZTV11QTreeWidget) + 16u)
+ QTreeView (0x0x7f21aeffbd00) 0
+ primary-for QTreeWidget (0x0x7f21aeffbc98)
+ QAbstractItemView (0x0x7f21aeffbea0) 0
+ primary-for QTreeView (0x0x7f21aeffbd00)
+ QAbstractScrollArea (0x0x7f21aeffbf08) 0
+ primary-for QAbstractItemView (0x0x7f21aeffbea0)
+ QFrame (0x0x7f21aeffbf70) 0
+ primary-for QAbstractScrollArea (0x0x7f21aeffbf08)
+ QWidget (0x0x7f21b569a4d0) 0
+ primary-for QFrame (0x0x7f21aeffbf70)
+ QObject (0x0x7f21a9a71cc0) 0
+ primary-for QWidget (0x0x7f21b569a4d0)
+ QPaintDevice (0x0x7f21a9a71d20) 16
+ vptr=((& QTreeWidget::_ZTV11QTreeWidget) + 832u)
+
+Class QUndoGroup::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QUndoGroup::QPrivateSignal (0x0x7f21a9a71e40) 0 empty
+
+Vtable for QUndoGroup
+QUndoGroup::_ZTV10QUndoGroup: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QUndoGroup)
+16 (int (*)(...))QUndoGroup::metaObject
+24 (int (*)(...))QUndoGroup::qt_metacast
+32 (int (*)(...))QUndoGroup::qt_metacall
+40 (int (*)(...))QUndoGroup::~QUndoGroup
+48 (int (*)(...))QUndoGroup::~QUndoGroup
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QUndoGroup
+ size=16 align=8
+ base size=16 base align=8
+QUndoGroup (0x0x7f21aee20068) 0
+ vptr=((& QUndoGroup::_ZTV10QUndoGroup) + 16u)
+ QObject (0x0x7f21a9a71de0) 0
+ primary-for QUndoGroup (0x0x7f21aee20068)
+
+Vtable for QUndoCommand
+QUndoCommand::_ZTV12QUndoCommand: 8u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QUndoCommand)
+16 (int (*)(...))QUndoCommand::~QUndoCommand
+24 (int (*)(...))QUndoCommand::~QUndoCommand
+32 (int (*)(...))QUndoCommand::undo
+40 (int (*)(...))QUndoCommand::redo
+48 (int (*)(...))QUndoCommand::id
+56 (int (*)(...))QUndoCommand::mergeWith
+
+Class QUndoCommand
+ size=16 align=8
+ base size=16 base align=8
+QUndoCommand (0x0x7f21a9a71ea0) 0
+ vptr=((& QUndoCommand::_ZTV12QUndoCommand) + 16u)
+
+Class QUndoStack::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QUndoStack::QPrivateSignal (0x0x7f21a9a71f60) 0 empty
+
+Vtable for QUndoStack
+QUndoStack::_ZTV10QUndoStack: 14u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI10QUndoStack)
+16 (int (*)(...))QUndoStack::metaObject
+24 (int (*)(...))QUndoStack::qt_metacast
+32 (int (*)(...))QUndoStack::qt_metacall
+40 (int (*)(...))QUndoStack::~QUndoStack
+48 (int (*)(...))QUndoStack::~QUndoStack
+56 (int (*)(...))QObject::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+
+Class QUndoStack
+ size=16 align=8
+ base size=16 base align=8
+QUndoStack (0x0x7f21aee200d0) 0
+ vptr=((& QUndoStack::_ZTV10QUndoStack) + 16u)
+ QObject (0x0x7f21a9a71f00) 0
+ primary-for QUndoStack (0x0x7f21aee200d0)
+
+Class QUndoView::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QUndoView::QPrivateSignal (0x0x7f21ac3f80c0) 0 empty
+
+Vtable for QUndoView
+QUndoView::_ZTV9QUndoView: 106u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI9QUndoView)
+16 (int (*)(...))QUndoView::metaObject
+24 (int (*)(...))QUndoView::qt_metacast
+32 (int (*)(...))QUndoView::qt_metacall
+40 (int (*)(...))QUndoView::~QUndoView
+48 (int (*)(...))QUndoView::~QUndoView
+56 (int (*)(...))QListView::event
+64 (int (*)(...))QAbstractScrollArea::eventFilter
+72 (int (*)(...))QListView::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QAbstractScrollArea::sizeHint
+136 (int (*)(...))QAbstractScrollArea::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QAbstractItemView::mousePressEvent
+176 (int (*)(...))QListView::mouseReleaseEvent
+184 (int (*)(...))QAbstractItemView::mouseDoubleClickEvent
+192 (int (*)(...))QListView::mouseMoveEvent
+200 (int (*)(...))QListView::wheelEvent
+208 (int (*)(...))QAbstractItemView::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QAbstractItemView::focusInEvent
+232 (int (*)(...))QAbstractItemView::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QListView::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QListView::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QAbstractScrollArea::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QAbstractItemView::dragEnterEvent
+320 (int (*)(...))QListView::dragMoveEvent
+328 (int (*)(...))QListView::dragLeaveEvent
+336 (int (*)(...))QListView::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QFrame::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QAbstractItemView::inputMethodEvent
+416 (int (*)(...))QAbstractItemView::inputMethodQuery
+424 (int (*)(...))QAbstractItemView::focusNextPrevChild
+432 (int (*)(...))QAbstractScrollArea::setupViewport
+440 (int (*)(...))QAbstractItemView::viewportEvent
+448 (int (*)(...))QListView::scrollContentsBy
+456 (int (*)(...))QListView::viewportSizeHint
+464 (int (*)(...))QAbstractItemView::setModel
+472 (int (*)(...))QAbstractItemView::setSelectionModel
+480 (int (*)(...))QAbstractItemView::keyboardSearch
+488 (int (*)(...))QListView::visualRect
+496 (int (*)(...))QListView::scrollTo
+504 (int (*)(...))QListView::indexAt
+512 (int (*)(...))QAbstractItemView::sizeHintForRow
+520 (int (*)(...))QAbstractItemView::sizeHintForColumn
+528 (int (*)(...))QListView::reset
+536 (int (*)(...))QListView::setRootIndex
+544 (int (*)(...))QListView::doItemsLayout
+552 (int (*)(...))QAbstractItemView::selectAll
+560 (int (*)(...))QListView::dataChanged
+568 (int (*)(...))QListView::rowsInserted
+576 (int (*)(...))QListView::rowsAboutToBeRemoved
+584 (int (*)(...))QListView::selectionChanged
+592 (int (*)(...))QListView::currentChanged
+600 (int (*)(...))QAbstractItemView::updateEditorData
+608 (int (*)(...))QAbstractItemView::updateEditorGeometries
+616 (int (*)(...))QListView::updateGeometries
+624 (int (*)(...))QAbstractItemView::verticalScrollbarAction
+632 (int (*)(...))QAbstractItemView::horizontalScrollbarAction
+640 (int (*)(...))QAbstractItemView::verticalScrollbarValueChanged
+648 (int (*)(...))QAbstractItemView::horizontalScrollbarValueChanged
+656 (int (*)(...))QAbstractItemView::closeEditor
+664 (int (*)(...))QAbstractItemView::commitData
+672 (int (*)(...))QAbstractItemView::editorDestroyed
+680 (int (*)(...))QListView::moveCursor
+688 (int (*)(...))QListView::horizontalOffset
+696 (int (*)(...))QListView::verticalOffset
+704 (int (*)(...))QListView::isIndexHidden
+712 (int (*)(...))QListView::setSelection
+720 (int (*)(...))QListView::visualRegionForSelection
+728 (int (*)(...))QListView::selectedIndexes
+736 (int (*)(...))QAbstractItemView::edit
+744 (int (*)(...))QAbstractItemView::selectionCommand
+752 (int (*)(...))QListView::startDrag
+760 (int (*)(...))QListView::viewOptions
+768 (int (*)(...))-16
+776 (int (*)(...))(& _ZTI9QUndoView)
+784 (int (*)(...))QUndoView::_ZThn16_N9QUndoViewD1Ev
+792 (int (*)(...))QUndoView::_ZThn16_N9QUndoViewD0Ev
+800 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+808 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+816 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+824 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+832 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+840 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QUndoView
+ size=48 align=8
+ base size=48 base align=8
+QUndoView (0x0x7f21aee20138) 0
+ vptr=((& QUndoView::_ZTV9QUndoView) + 16u)
+ QListView (0x0x7f21aee20750) 0
+ primary-for QUndoView (0x0x7f21aee20138)
+ QAbstractItemView (0x0x7f21aee208f0) 0
+ primary-for QListView (0x0x7f21aee20750)
+ QAbstractScrollArea (0x0x7f21aee20a90) 0
+ primary-for QAbstractItemView (0x0x7f21aee208f0)
+ QFrame (0x0x7f21aee20af8) 0
+ primary-for QAbstractScrollArea (0x0x7f21aee20a90)
+ QWidget (0x0x7f21b56c4230) 0
+ primary-for QFrame (0x0x7f21aee20af8)
+ QObject (0x0x7f21ac3f8000) 0
+ primary-for QWidget (0x0x7f21b56c4230)
+ QPaintDevice (0x0x7f21ac3f8060) 16
+ vptr=((& QUndoView::_ZTV9QUndoView) + 784u)
+
+Class QWhatsThis
+ size=1 align=1
+ base size=0 base align=1
+QWhatsThis (0x0x7f21ac3f8120) 0 empty
+
+Class QWidgetAction::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QWidgetAction::QPrivateSignal (0x0x7f21ac3f81e0) 0 empty
+
+Vtable for QWidgetAction
+QWidgetAction::_ZTV13QWidgetAction: 16u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI13QWidgetAction)
+16 (int (*)(...))QWidgetAction::metaObject
+24 (int (*)(...))QWidgetAction::qt_metacast
+32 (int (*)(...))QWidgetAction::qt_metacall
+40 (int (*)(...))QWidgetAction::~QWidgetAction
+48 (int (*)(...))QWidgetAction::~QWidgetAction
+56 (int (*)(...))QWidgetAction::event
+64 (int (*)(...))QWidgetAction::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidgetAction::createWidget
+120 (int (*)(...))QWidgetAction::deleteWidget
+
+Class QWidgetAction
+ size=16 align=8
+ base size=16 base align=8
+QWidgetAction (0x0x7f21aeba8208) 0
+ vptr=((& QWidgetAction::_ZTV13QWidgetAction) + 16u)
+ QAction (0x0x7f21aeba8270) 0
+ primary-for QWidgetAction (0x0x7f21aeba8208)
+ QObject (0x0x7f21ac3f8180) 0
+ primary-for QAction (0x0x7f21aeba8270)
+
+Class QWizard::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QWizard::QPrivateSignal (0x0x7f21ac3f8300) 0 empty
+
+Vtable for QWizard
+QWizard::_ZTV7QWizard: 73u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI7QWizard)
+16 (int (*)(...))QWizard::metaObject
+24 (int (*)(...))QWizard::qt_metacast
+32 (int (*)(...))QWizard::qt_metacall
+40 (int (*)(...))QWizard::~QWizard
+48 (int (*)(...))QWizard::~QWizard
+56 (int (*)(...))QWizard::event
+64 (int (*)(...))QDialog::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWizard::setVisible
+128 (int (*)(...))QWizard::sizeHint
+136 (int (*)(...))QDialog::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QDialog::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWizard::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWizard::resizeEvent
+280 (int (*)(...))QDialog::closeEvent
+288 (int (*)(...))QDialog::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QDialog::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QDialog::open
+440 (int (*)(...))QDialog::exec
+448 (int (*)(...))QWizard::done
+456 (int (*)(...))QDialog::accept
+464 (int (*)(...))QDialog::reject
+472 (int (*)(...))QWizard::validateCurrentPage
+480 (int (*)(...))QWizard::nextId
+488 (int (*)(...))QWizard::initializePage
+496 (int (*)(...))QWizard::cleanupPage
+504 (int (*)(...))-16
+512 (int (*)(...))(& _ZTI7QWizard)
+520 (int (*)(...))QWizard::_ZThn16_N7QWizardD1Ev
+528 (int (*)(...))QWizard::_ZThn16_N7QWizardD0Ev
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+552 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+560 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+568 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+576 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QWizard
+ size=48 align=8
+ base size=48 base align=8
+QWizard (0x0x7f21aeba8750) 0
+ vptr=((& QWizard::_ZTV7QWizard) + 16u)
+ QDialog (0x0x7f21aeba87b8) 0
+ primary-for QWizard (0x0x7f21aeba8750)
+ QWidget (0x0x7f21b56d31c0) 0
+ primary-for QDialog (0x0x7f21aeba87b8)
+ QObject (0x0x7f21ac3f8240) 0
+ primary-for QWidget (0x0x7f21b56d31c0)
+ QPaintDevice (0x0x7f21ac3f82a0) 16
+ vptr=((& QWizard::_ZTV7QWizard) + 520u)
+
+Class QWizardPage::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QWizardPage::QPrivateSignal (0x0x7f21ac3f85a0) 0 empty
+
+Vtable for QWizardPage
+QWizardPage::_ZTV11QWizardPage: 69u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI11QWizardPage)
+16 (int (*)(...))QWizardPage::metaObject
+24 (int (*)(...))QWizardPage::qt_metacast
+32 (int (*)(...))QWizardPage::qt_metacall
+40 (int (*)(...))QWizardPage::~QWizardPage
+48 (int (*)(...))QWizardPage::~QWizardPage
+56 (int (*)(...))QWidget::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QObject::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QWidget::mousePressEvent
+176 (int (*)(...))QWidget::mouseReleaseEvent
+184 (int (*)(...))QWidget::mouseDoubleClickEvent
+192 (int (*)(...))QWidget::mouseMoveEvent
+200 (int (*)(...))QWidget::wheelEvent
+208 (int (*)(...))QWidget::keyPressEvent
+216 (int (*)(...))QWidget::keyReleaseEvent
+224 (int (*)(...))QWidget::focusInEvent
+232 (int (*)(...))QWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QWidget::dragEnterEvent
+320 (int (*)(...))QWidget::dragMoveEvent
+328 (int (*)(...))QWidget::dragLeaveEvent
+336 (int (*)(...))QWidget::dropEvent
+344 (int (*)(...))QWidget::showEvent
+352 (int (*)(...))QWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))QWizardPage::initializePage
+440 (int (*)(...))QWizardPage::cleanupPage
+448 (int (*)(...))QWizardPage::validatePage
+456 (int (*)(...))QWizardPage::isComplete
+464 (int (*)(...))QWizardPage::nextId
+472 (int (*)(...))-16
+480 (int (*)(...))(& _ZTI11QWizardPage)
+488 (int (*)(...))QWizardPage::_ZThn16_N11QWizardPageD1Ev
+496 (int (*)(...))QWizardPage::_ZThn16_N11QWizardPageD0Ev
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+512 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+520 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+528 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+536 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+544 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QWizardPage
+ size=48 align=8
+ base size=48 base align=8
+QWizardPage (0x0x7f21aeba8d00) 0
+ vptr=((& QWizardPage::_ZTV11QWizardPage) + 16u)
+ QWidget (0x0x7f21b5728850) 0
+ primary-for QWizardPage (0x0x7f21aeba8d00)
+ QObject (0x0x7f21ac3f84e0) 0
+ primary-for QWidget (0x0x7f21b5728850)
+ QPaintDevice (0x0x7f21ac3f8540) 16
+ vptr=((& QWizardPage::_ZTV11QWizardPage) + 488u)
+
+Class QQuickWidget::QPrivateSignal
+ size=1 align=1
+ base size=0 base align=1
+QQuickWidget::QPrivateSignal (0x0x7f21ac3f86c0) 0 empty
+
+Vtable for QQuickWidget
+QQuickWidget::_ZTV12QQuickWidget: 64u entries
+0 (int (*)(...))0
+8 (int (*)(...))(& _ZTI12QQuickWidget)
+16 (int (*)(...))QQuickWidget::metaObject
+24 (int (*)(...))QQuickWidget::qt_metacast
+32 (int (*)(...))QQuickWidget::qt_metacall
+40 (int (*)(...))QQuickWidget::~QQuickWidget
+48 (int (*)(...))QQuickWidget::~QQuickWidget
+56 (int (*)(...))QQuickWidget::event
+64 (int (*)(...))QObject::eventFilter
+72 (int (*)(...))QQuickWidget::timerEvent
+80 (int (*)(...))QObject::childEvent
+88 (int (*)(...))QObject::customEvent
+96 (int (*)(...))QObject::connectNotify
+104 (int (*)(...))QObject::disconnectNotify
+112 (int (*)(...))QWidget::devType
+120 (int (*)(...))QWidget::setVisible
+128 (int (*)(...))QQuickWidget::sizeHint
+136 (int (*)(...))QWidget::minimumSizeHint
+144 (int (*)(...))QWidget::heightForWidth
+152 (int (*)(...))QWidget::hasHeightForWidth
+160 (int (*)(...))QWidget::paintEngine
+168 (int (*)(...))QQuickWidget::mousePressEvent
+176 (int (*)(...))QQuickWidget::mouseReleaseEvent
+184 (int (*)(...))QQuickWidget::mouseDoubleClickEvent
+192 (int (*)(...))QQuickWidget::mouseMoveEvent
+200 (int (*)(...))QQuickWidget::wheelEvent
+208 (int (*)(...))QQuickWidget::keyPressEvent
+216 (int (*)(...))QQuickWidget::keyReleaseEvent
+224 (int (*)(...))QQuickWidget::focusInEvent
+232 (int (*)(...))QQuickWidget::focusOutEvent
+240 (int (*)(...))QWidget::enterEvent
+248 (int (*)(...))QWidget::leaveEvent
+256 (int (*)(...))QQuickWidget::paintEvent
+264 (int (*)(...))QWidget::moveEvent
+272 (int (*)(...))QQuickWidget::resizeEvent
+280 (int (*)(...))QWidget::closeEvent
+288 (int (*)(...))QWidget::contextMenuEvent
+296 (int (*)(...))QWidget::tabletEvent
+304 (int (*)(...))QWidget::actionEvent
+312 (int (*)(...))QQuickWidget::dragEnterEvent
+320 (int (*)(...))QQuickWidget::dragMoveEvent
+328 (int (*)(...))QQuickWidget::dragLeaveEvent
+336 (int (*)(...))QQuickWidget::dropEvent
+344 (int (*)(...))QQuickWidget::showEvent
+352 (int (*)(...))QQuickWidget::hideEvent
+360 (int (*)(...))QWidget::nativeEvent
+368 (int (*)(...))QWidget::changeEvent
+376 (int (*)(...))QWidget::metric
+384 (int (*)(...))QWidget::initPainter
+392 (int (*)(...))QWidget::redirected
+400 (int (*)(...))QWidget::sharedPainter
+408 (int (*)(...))QWidget::inputMethodEvent
+416 (int (*)(...))QWidget::inputMethodQuery
+424 (int (*)(...))QWidget::focusNextPrevChild
+432 (int (*)(...))-16
+440 (int (*)(...))(& _ZTI12QQuickWidget)
+448 (int (*)(...))QQuickWidget::_ZThn16_N12QQuickWidgetD1Ev
+456 (int (*)(...))QQuickWidget::_ZThn16_N12QQuickWidgetD0Ev
+464 (int (*)(...))QWidget::_ZThn16_NK7QWidget7devTypeEv
+472 (int (*)(...))QWidget::_ZThn16_NK7QWidget11paintEngineEv
+480 (int (*)(...))QWidget::_ZThn16_NK7QWidget6metricEN12QPaintDevice17PaintDeviceMetricE
+488 (int (*)(...))QWidget::_ZThn16_NK7QWidget11initPainterEP8QPainter
+496 (int (*)(...))QWidget::_ZThn16_NK7QWidget10redirectedEP6QPoint
+504 (int (*)(...))QWidget::_ZThn16_NK7QWidget13sharedPainterEv
+
+Class QQuickWidget
+ size=48 align=8
+ base size=48 base align=8
+QQuickWidget (0x0x7f21aeba8ea0) 0
+ vptr=((& QQuickWidget::_ZTV12QQuickWidget) + 16u)
+ QWidget (0x0x7f21b5728d20) 0
+ primary-for QQuickWidget (0x0x7f21aeba8ea0)
+ QObject (0x0x7f21ac3f8600) 0
+ primary-for QWidget (0x0x7f21b5728d20)
+ QPaintDevice (0x0x7f21ac3f8660) 16
+ vptr=((& QQuickWidget::_ZTV12QQuickWidget) + 448u)
+
diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt
index 4b9fbe75ac..4d4d8e3db7 100644
--- a/tests/auto/cmake/CMakeLists.txt
+++ b/tests/auto/cmake/CMakeLists.txt
@@ -15,3 +15,14 @@ test_module_includes(
)
expect_pass(test_plugins)
+
+add_test(qtquickcompiler ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMAKE_CURRENT_SOURCE_DIR}/qtquickcompiler/"
+ "${CMAKE_CURRENT_BINARY_DIR}/qtquickcompiler"
+ --build-config "${CMAKE_BUILD_TYPE}"
+ --build-generator ${CMAKE_GENERATOR}
+ --build-makeprogram ${CMAKE_MAKE_PROGRAM}
+ --build-project qqc_test
+ --build-options "-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}" ${BUILD_OPTIONS_LIST}
+)
diff --git a/tests/auto/cmake/qtquickcompiler/CMakeLists.txt b/tests/auto/cmake/qtquickcompiler/CMakeLists.txt
new file mode 100644
index 0000000000..6dee1e25dc
--- /dev/null
+++ b/tests/auto/cmake/qtquickcompiler/CMakeLists.txt
@@ -0,0 +1,14 @@
+
+cmake_minimum_required(VERSION 2.8)
+project(qqc_test)
+
+find_package(Qt5Qml 5.0.0 REQUIRED)
+find_package(Qt5Gui 5.0.0 REQUIRED)
+find_package(Qt5QuickCompiler)
+
+set(CMAKE_CXXFLAGS "${CMAKE_CXXFLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}")
+
+qtquick_compiler_add_resources(RESOURCES qqc_test.qrc)
+
+add_executable(qqc_test "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" ${RESOURCES})
+target_link_libraries(qqc_test Qt5::Gui Qt5::Qml)
diff --git a/tests/auto/cmake/qtquickcompiler/main.cpp b/tests/auto/cmake/qtquickcompiler/main.cpp
new file mode 100644
index 0000000000..47fc709c0a
--- /dev/null
+++ b/tests/auto/cmake/qtquickcompiler/main.cpp
@@ -0,0 +1,9 @@
+
+#include <QtGui>
+#include <QtQml>
+
+int main(int argc, char **argv)
+{
+ QGuiApplication app(argc, argv);
+ return app.exec();
+}
diff --git a/tests/auto/cmake/qtquickcompiler/main.qml b/tests/auto/cmake/qtquickcompiler/main.qml
new file mode 100644
index 0000000000..1f146d89c3
--- /dev/null
+++ b/tests/auto/cmake/qtquickcompiler/main.qml
@@ -0,0 +1,4 @@
+import QtQml 2.0
+QtObject {
+ property bool success: 42
+}
diff --git a/tests/auto/cmake/qtquickcompiler/qqc_test.qrc b/tests/auto/cmake/qtquickcompiler/qqc_test.qrc
new file mode 100644
index 0000000000..f128b7004b
--- /dev/null
+++ b/tests/auto/cmake/qtquickcompiler/qqc_test.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+<file>./main.qml</file>
+<file>./main.cpp</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/particles/qquickimageparticle/BLACKLIST b/tests/auto/particles/qquickimageparticle/BLACKLIST
new file mode 100644
index 0000000000..a615dcd6e6
--- /dev/null
+++ b/tests/auto/particles/qquickimageparticle/BLACKLIST
@@ -0,0 +1,16 @@
+# QTBUG-63055
+[test_colored]
+b2qt
+
+# QTBUG-63055
+[test_colorVariance]
+b2qt
+
+# QTBUG-63055
+[test_deformed]
+b2qt
+
+# QTBUG-63055
+[test_sprite]
+b2qt
+
diff --git a/tests/auto/particles/qquickspritegoal/BLACKLIST b/tests/auto/particles/qquickspritegoal/BLACKLIST
new file mode 100644
index 0000000000..bd64621f77
--- /dev/null
+++ b/tests/auto/particles/qquickspritegoal/BLACKLIST
@@ -0,0 +1,3 @@
+# QTBUG-63057
+[test_instantTransition]
+b2qt
diff --git a/tests/auto/qml/bindingdependencyapi/bindingdependencyapi.pro b/tests/auto/qml/bindingdependencyapi/bindingdependencyapi.pro
new file mode 100644
index 0000000000..430d87ab5b
--- /dev/null
+++ b/tests/auto/qml/bindingdependencyapi/bindingdependencyapi.pro
@@ -0,0 +1,11 @@
+CONFIG += testcase
+TARGET = tst_bindingdependencyapi
+macos:CONFIG -= app_bundle
+
+SOURCES += tst_bindingdependencyapi.cpp
+
+include (../../shared/util.pri)
+
+TESTDATA = data/*
+
+QT += core-private gui-private qml-private quick-private testlib
diff --git a/tests/auto/qml/bindingdependencyapi/tst_bindingdependencyapi.cpp b/tests/auto/qml/bindingdependencyapi/tst_bindingdependencyapi.cpp
new file mode 100644
index 0000000000..6f24f85f6d
--- /dev/null
+++ b/tests/auto/qml/bindingdependencyapi/tst_bindingdependencyapi.cpp
@@ -0,0 +1,360 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <qtest.h>
+#include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlcomponent.h>
+#include <private/qqmldata_p.h>
+#include <private/qqmlbinding_p.h>
+#include <QtQuick/private/qquicktext_p.h>
+#include <QtQuick/private/qquickrectangle_p.h>
+#include "../../shared/util.h"
+#include <qqmlcontext.h>
+
+class tst_bindingdependencyapi : public QObject
+{
+ Q_OBJECT
+public:
+ tst_bindingdependencyapi();
+
+private slots:
+ void testSingleDep_data();
+ void testSingleDep();
+ void testManyDeps_data();
+ void testManyDeps();
+ void testConditionalDependencies_data();
+ void testConditionalDependencies();
+ void testBindingLoop();
+
+private:
+ bool findProperties(const QVector<QQmlProperty> &properties, QObject *obj, const QString &propertyName, const QVariant &value);
+};
+
+tst_bindingdependencyapi::tst_bindingdependencyapi()
+{
+}
+
+
+void tst_bindingdependencyapi::testSingleDep_data()
+{
+ QTest::addColumn<QByteArray>("code");
+ QTest::addColumn<QString>("referencedObjectName");
+
+ QTest::addRow("context property")
+ << QByteArray("import QtQuick 2.0\n"
+ "Rectangle {\n"
+ "objectName: \"rect\"\n"
+ "property string labelText: \"Hello world!\"\n"
+ "Text { text: labelText }\n"
+ "}") << "rect";
+
+ QTest::addRow("scope property")
+ << QByteArray("import QtQuick 2.0\n"
+ "Rectangle {\n"
+ "property string labelText: \"I am wrong!\"\n"
+ "Text {\n"
+ "objectName: \"text\"\n"
+ "property string labelText: \"Hello world!\"\n"
+ "text: labelText\n"
+ "}\n"
+ "}") << "text";
+
+ QTest::addRow("id object property")
+ << QByteArray("import QtQuick 2.0\n"
+ "Rectangle {\n"
+ "id: rect\n"
+ "objectName: \"rect\"\n"
+ "property string labelText: \"Hello world!\"\n"
+ "Text { text: rect.labelText }\n"
+ "}") << "rect";
+
+ QTest::addRow("dynamic context property")
+ << QByteArray("import QtQuick 2.0\n"
+ "Rectangle {\n"
+ "objectName: \"rect\"\n"
+ "property string labelText: \"Hello world!\"\n"
+ "Text { Component.onCompleted: text = Qt.binding(function() { return labelText; }); }\n"
+ "}") << "rect";
+
+ QTest::addRow("dynamic scope property")
+ << QByteArray("import QtQuick 2.0\n"
+ "Rectangle {\n"
+ "property string labelText: \"I am wrong!\"\n"
+ "Text {\n"
+ "objectName: \"text\"\n"
+ "property string labelText: \"Hello world!\"\n"
+ "Component.onCompleted: text = Qt.binding(function() { return labelText; });\n"
+ "}\n"
+ "}") << "text";
+
+ QTest::addRow("dynamic id object property")
+ << QByteArray("import QtQuick 2.0\n"
+ "Rectangle {\n"
+ "id: rect\n"
+ "objectName: \"rect\"\n"
+ "property string labelText: \"Hello world!\"\n"
+ "Text { Component.onCompleted: text = Qt.binding(function() { return rect.labelText; }); }\n"
+ "}") << "rect";
+}
+
+void tst_bindingdependencyapi::testSingleDep()
+{
+ QFETCH(QByteArray, code);
+ QFETCH(QString, referencedObjectName);
+
+ QQmlEngine engine;
+ QQmlComponent c(&engine);
+ c.setData(code, QUrl());
+ QObject *rect = c.create();
+ QTest::qWait(10);
+ QVERIFY(rect != 0);
+ QObject *text = rect->findChildren<QQuickText *>().front();
+
+ QObject *referencedObject = rect->objectName() == referencedObjectName ? rect : rect->findChild<QObject *>(referencedObjectName);
+
+ auto data = QQmlData::get(text);
+ QVERIFY(data);
+ auto b = data->bindings;
+ QVERIFY(b);
+ auto binding = dynamic_cast<QQmlBinding*>(b);
+ QVERIFY(binding);
+ auto dependencies = binding->dependencies();
+ QCOMPARE(dependencies.size(), 1);
+ auto dependency = dependencies.front();
+ QVERIFY(dependency.isValid());
+ QCOMPARE(quintptr(dependency.object()), quintptr(referencedObject));
+ QCOMPARE(dependency.property().name(), "labelText");
+ QCOMPARE(dependency.read().toString(), QStringLiteral("Hello world!"));
+ QCOMPARE(dependency, QQmlProperty(referencedObject, "labelText"));
+
+ delete rect;
+}
+
+bool tst_bindingdependencyapi::findProperties(const QVector<QQmlProperty> &properties, QObject *obj, const QString &propertyName, const QVariant &value)
+{
+ auto dep = std::find_if(properties.cbegin(), properties.cend(), [&](const QQmlProperty &dep) {
+ return dep.object() == obj
+ && dep.property().name() == propertyName
+ && dep.read() == value;
+ });
+ if (dep == properties.cend()) {
+ qWarning() << "Searched for property with:" << "{ object:" << obj << ", propertyName:" << propertyName << ", value:" << value << "}" << "but only found:";
+ for (auto dep : properties) {
+ qWarning() << "{ object:" << dep.object() << ", propertyName:" << dep.property().name() << ", value:" << dep.read() << "}";
+ }
+ return false;
+ }
+ return true;
+}
+
+void tst_bindingdependencyapi::testManyDeps_data()
+{
+ QTest::addColumn<QByteArray>("code");
+
+ QTest::addRow("permanent binding")
+ << QByteArray("import QtQuick 2.0\n"
+ "Rectangle {\n"
+ "id: rect\n"
+ "objectName: 'rect'\n"
+ "property string name: 'world'\n"
+ "Text {\n"
+ "text: config.helloWorldTemplate.arg(greeting).arg(rect.name) \n"
+ "property string greeting: 'Hello'\n"
+ "}\n"
+ "QtObject { id: config; objectName: 'config'; property string helloWorldTemplate: '%1 %2!' }\n"
+ "}");
+
+ QTest::addRow("dynamic binding")
+ << QByteArray("import QtQuick 2.0\n"
+ "Rectangle {\n"
+ "id: rect\n"
+ "objectName: 'rect'\n"
+ "property string name: 'world'\n"
+ "Text {\n"
+ "Component.onCompleted: text = Qt.binding(function() { return config.helloWorldTemplate.arg(greeting).arg(rect.name); }); \n"
+ "property string greeting: 'Hello'\n"
+ "}\n"
+ "QtObject { id: config; objectName: 'config'; property string helloWorldTemplate: '%1 %2!' }\n"
+ "}");
+}
+
+void tst_bindingdependencyapi::testManyDeps()
+{
+ QFETCH(QByteArray, code);
+ QQmlEngine engine;
+ QQmlComponent c(&engine);
+ c.setData(code, QUrl());
+ QObject *rect = c.create();
+ if (c.isError()) {
+ qWarning() << c.errorString();
+ }
+ QTest::qWait(100);
+ QVERIFY(rect != 0);
+ QObject *text = rect->findChildren<QQuickText *>().front();
+ QObject *configObj = rect->findChild<QObject *>("config");
+
+ auto data = QQmlData::get(text);
+ QVERIFY(data);
+ auto b = data->bindings;
+ QVERIFY(b);
+ auto binding = dynamic_cast<QQmlBinding*>(b);
+ QVERIFY(binding);
+ auto dependencies = binding->dependencies();
+ QCOMPARE(dependencies.size(), 3);
+
+ QVERIFY(findProperties(dependencies, rect, "name", "world"));
+ QVERIFY(findProperties(dependencies, text, "greeting", "Hello"));
+ QVERIFY(findProperties(dependencies, configObj, "helloWorldTemplate", "%1 %2!"));
+
+ delete rect;
+}
+
+void tst_bindingdependencyapi::testConditionalDependencies_data()
+{
+ QTest::addColumn<QByteArray>("code");
+ QTest::addColumn<QString>("referencedObjectName");
+
+ QTest::addRow("id object property")
+ << QByteArray("import QtQuick 2.0\n"
+ "Rectangle {\n"
+ "id: rect\n"
+ "objectName: \"rect\"\n"
+ "property bool haveDep: false\n"
+ "property string labelText: \"Hello world!\"\n"
+ "Text { text: rect.haveDep ? rect.labelText : '' }\n"
+ "}") << "rect";
+
+ QTest::addRow("dynamic context property")
+ << QByteArray("import QtQuick 2.0\n"
+ "Rectangle {\n"
+ "objectName: \"rect\"\n"
+ "property bool haveDep: false\n"
+ "property string labelText: \"Hello world!\"\n"
+ "Text { Component.onCompleted: text = Qt.binding(function() { return haveDep ? labelText : ''; }); }\n"
+ "}") << "rect";
+
+ QTest::addRow("dynamic scope property")
+ << QByteArray("import QtQuick 2.0\n"
+ "Rectangle {\n"
+ "property string labelText: \"I am wrong!\"\n"
+ "Text {\n"
+ "objectName: \"text\"\n"
+ "property bool haveDep: false\n"
+ "property string labelText: \"Hello world!\"\n"
+ "Component.onCompleted: text = Qt.binding(function() { return haveDep ? labelText : ''; });\n"
+ "}\n"
+ "}") << "text";
+
+ QTest::addRow("dynamic id object property")
+ << QByteArray("import QtQuick 2.0\n"
+ "Rectangle {\n"
+ "id: rect\n"
+ "objectName: \"rect\"\n"
+ "property bool haveDep: false\n"
+ "property string labelText: \"Hello world!\"\n"
+ "Text { Component.onCompleted: text = Qt.binding(function() { return rect.haveDep ? rect.labelText : ''; }); }\n"
+ "}") << "rect";
+}
+
+void tst_bindingdependencyapi::testConditionalDependencies()
+{
+ QFETCH(QByteArray, code);
+ QFETCH(QString, referencedObjectName);
+
+ QQmlEngine engine;
+ QQmlComponent c(&engine);
+ c.setData(code, QUrl());
+ QObject *rect = c.create();
+ QTest::qWait(10);
+ QVERIFY(rect != 0);
+ QObject *text = rect->findChildren<QQuickText *>().front();
+
+ QObject *referencedObject = rect->objectName() == referencedObjectName ? rect : rect->findChild<QObject *>(referencedObjectName);
+
+ auto data = QQmlData::get(text);
+ QVERIFY(data);
+ auto b = data->bindings;
+ QVERIFY(b);
+ auto binding = dynamic_cast<QQmlBinding*>(b);
+ QVERIFY(binding);
+ auto dependencies = binding->dependencies();
+ QCOMPARE(dependencies.size(), 1);
+ QVERIFY(findProperties(dependencies, referencedObject, "haveDep", false));
+
+ referencedObject->setProperty("haveDep", true);
+ dependencies = binding->dependencies();
+ QCOMPARE(dependencies.size(), 2);
+ QVERIFY(findProperties(dependencies, referencedObject, "haveDep", true));
+ QVERIFY(findProperties(dependencies, referencedObject, "labelText", "Hello world!"));
+
+ referencedObject->setProperty("haveDep", false);
+ dependencies = binding->dependencies();
+ QCOMPARE(dependencies.size(), 1);
+ QVERIFY(findProperties(dependencies, referencedObject, "haveDep", false));
+
+ delete rect;
+}
+
+void tst_bindingdependencyapi::testBindingLoop()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine);
+ c.setData(QByteArray("import QtQuick 2.0\n"
+ "Rectangle {\n"
+ "property string labelText: label.text\n"
+ "Text {\n"
+ "id: label\n"
+ "text: labelText\n"
+ "}\n"
+ "}"), QUrl());
+ QObject *rect = c.create();
+ if (c.isError()) {
+ qWarning() << c.errorString();
+ }
+ QTest::qWait(100);
+ QVERIFY(rect != 0);
+ QObject *text = rect->findChildren<QQuickText *>().front();
+
+ auto data = QQmlData::get(text);
+ QVERIFY(data);
+ auto b = data->bindings;
+ QVERIFY(b);
+ auto binding = dynamic_cast<QQmlBinding*>(b);
+ QVERIFY(binding);
+ auto dependencies = binding->dependencies();
+ QCOMPARE(dependencies.size(), 1);
+ auto dependency = dependencies.front();
+ QVERIFY(dependency.isValid());
+ QCOMPARE(quintptr(dependency.object()), quintptr(rect));
+ QCOMPARE(dependency.property().name(), "labelText");
+
+ delete rect;
+}
+
+QTEST_MAIN(tst_bindingdependencyapi)
+
+#include "tst_bindingdependencyapi.moc"
diff --git a/tests/auto/qml/debugger/debugger.pro b/tests/auto/qml/debugger/debugger.pro
index a50411e18b..63721cc575 100644
--- a/tests/auto/qml/debugger/debugger.pro
+++ b/tests/auto/qml/debugger/debugger.pro
@@ -10,7 +10,8 @@ PUBLICTESTS += \
qqmlenginedebuginspectorintegrationtest \
qqmlenginecontrol \
qqmldebuggingenabler \
- qqmlnativeconnector
+ qqmlnativeconnector \
+ qqmldebugprocess
PRIVATETESTS += \
qqmldebugclient \
diff --git a/tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro b/tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro
index 6c729ab235..9cf323ba36 100644
--- a/tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro
+++ b/tests/auto/qml/debugger/qdebugmessageservice/qdebugmessageservice.pro
@@ -5,8 +5,6 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qdebugmessageservice.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
include(../shared/debugutil.pri)
TESTDATA = data/*
diff --git a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp
index f193d3928a..f851688b5e 100644
--- a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp
+++ b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp
@@ -28,7 +28,6 @@
//QQmlDebugTest
#include "debugutil_p.h"
-#include "../../../shared/util.h"
#include <private/qqmldebugclient_p.h>
#include <private/qqmldebugconnection_p.h>
@@ -38,31 +37,19 @@
#include <QtCore/qlibraryinfo.h>
#include <QtTest/qtest.h>
-const char *NORMALMODE = "-qmljsdebugger=port:3777,3787,block";
const char *QMLFILE = "test.qml";
class QQmlDebugMsgClient;
-class tst_QDebugMessageService : public QQmlDataTest
+class tst_QDebugMessageService : public QQmlDebugTest
{
Q_OBJECT
-public:
- tst_QDebugMessageService();
-
- void init();
-
private slots:
- void initTestCase();
- void cleanupTestCase();
-
- void cleanup();
-
void retrieveDebugOutput();
private:
- QQmlDebugProcess *m_process;
- QQmlDebugMsgClient *m_client;
- QQmlDebugConnection *m_connection;
+ QList<QQmlDebugClient *> createClients() override;
+ QPointer<QQmlDebugMsgClient> m_client;
};
struct LogEntry {
@@ -150,73 +137,16 @@ void QQmlDebugMsgClient::messageReceived(const QByteArray &data)
}
}
-tst_QDebugMessageService::tst_QDebugMessageService()
-{
-}
-
-void tst_QDebugMessageService::initTestCase()
-{
- QQmlDataTest::initTestCase();
- m_process = 0;
- m_client = 0;
- m_connection = 0;
-}
-
-void tst_QDebugMessageService::cleanupTestCase()
+QList<QQmlDebugClient *> tst_QDebugMessageService::createClients()
{
- if (m_process)
- delete m_process;
-
- if (m_client)
- delete m_client;
-
- if (m_connection)
- delete m_connection;
-}
-
-void tst_QDebugMessageService::init()
-{
- m_connection = new QQmlDebugConnection();
- m_process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml", this);
m_client = new QQmlDebugMsgClient(m_connection);
-
- m_process->start(QStringList() << QLatin1String(NORMALMODE) << QQmlDataTest::instance()->testFile(QMLFILE));
- QVERIFY2(m_process->waitForSessionStart(),
- "Could not launch application, or did not get 'Waiting for connection'.");
-
- const int port = m_process->debugPort();
- m_connection->connectToHost("127.0.0.1", port);
- QVERIFY(m_connection->waitForConnected());
-
- if (m_client->state() != QQmlDebugClient::Enabled)
- QQmlDebugTest::waitForSignal(m_client, SIGNAL(enabled()));
-
- QCOMPARE(m_client->state(), QQmlDebugClient::Enabled);
-}
-
-void tst_QDebugMessageService::cleanup()
-{
- if (QTest::currentTestFailed()) {
- qDebug() << "Process State:" << m_process->state();
- qDebug() << "Application Output:" << m_process->output();
- }
- if (m_process)
- delete m_process;
-
- if (m_client)
- delete m_client;
-
- if (m_connection)
- delete m_connection;
-
- m_process = 0;
- m_client = 0;
- m_connection = 0;
+ return QList<QQmlDebugClient *>({m_client});
}
void tst_QDebugMessageService::retrieveDebugOutput()
{
- init();
+ QCOMPARE(QQmlDebugTest::connect(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml",
+ QString(), testFile(QMLFILE), true), ConnectSuccess);
QTRY_VERIFY(m_client->logBuffer.size() >= 2);
diff --git a/tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro b/tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro
index a7c0fa7f8e..b1e3835844 100644
--- a/tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro
+++ b/tests/auto/qml/debugger/qpacketprotocol/qpacketprotocol.pro
@@ -4,7 +4,6 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qpacketprotocol.cpp
-INCLUDEPATH += ../shared
include(../shared/debugutil.pri)
QT += qml network testlib gui-private core-private
diff --git a/tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro b/tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro
index 622b373692..673330a3cf 100644
--- a/tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro
+++ b/tests/auto/qml/debugger/qqmldebugclient/qqmldebugclient.pro
@@ -7,7 +7,6 @@ HEADERS += ../shared/qqmldebugtestservice.h
SOURCES += tst_qqmldebugclient.cpp \
../shared/qqmldebugtestservice.cpp
-INCLUDEPATH += ../shared
include(../shared/debugutil.pri)
DEFINES += QT_QML_DEBUG_NO_WARNING
diff --git a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/qqmldebuggingenabler.pro b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/qqmldebuggingenabler.pro
index f8014f04f4..bd382ebaab 100644
--- a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/qqmldebuggingenabler.pro
+++ b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/qqmldebuggingenabler.pro
@@ -6,8 +6,6 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qqmldebuggingenabler.cpp
-INCLUDEPATH += ../../shared
-include(../../../../shared/util.pri)
include(../../shared/debugutil.pri)
OTHER_FILES += data/test.qml
diff --git a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp
index 3aa3a5c87e..a76740a3f9 100644
--- a/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp
+++ b/tests/auto/qml/debugger/qqmldebuggingenabler/qqmldebuggingenabler/tst_qqmldebuggingenabler.cpp
@@ -27,11 +27,14 @@
****************************************************************************/
#include "debugutil_p.h"
+#include "qqmldebugprocess_p.h"
#include "../../../shared/util.h"
#include <private/qqmldebugclient_p.h>
#include <private/qqmldebugconnection_p.h>
+#include <QtQml/qqmldebug.h>
+
#include <QtTest/qtest.h>
#include <QtCore/qprocess.h>
#include <QtCore/qtimer.h>
@@ -40,17 +43,11 @@
#include <QtCore/qmutex.h>
#include <QtCore/qlibraryinfo.h>
-class tst_QQmlDebuggingEnabler : public QQmlDataTest
+class tst_QQmlDebuggingEnabler : public QQmlDebugTest
{
Q_OBJECT
- bool init(bool blockMode, bool qmlscene, int portFrom, int portTo);
-
private slots:
- void initTestCase();
- void cleanupTestCase();
- void cleanup();
-
void qmlscene_data();
void qmlscene();
void custom_data();
@@ -58,88 +55,8 @@ private slots:
private:
void data();
- QQmlDebugProcess *process;
- QQmlDebugConnection *connection;
- QTime t;
};
-void tst_QQmlDebuggingEnabler::initTestCase()
-{
- QQmlDataTest::initTestCase();
- t.start();
- process = 0;
- connection = 0;
-}
-
-void tst_QQmlDebuggingEnabler::cleanupTestCase()
-{
- if (process) {
- process->stop();
- delete process;
- }
-
- if (connection)
- delete connection;
-}
-
-bool tst_QQmlDebuggingEnabler::init(bool blockMode, bool qmlscene, int portFrom, int portTo)
-{
- connection = new QQmlDebugConnection();
-
- if (qmlscene) {
- process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this);
- process->setMaximumBindErrors(1);
- } else {
- process = new QQmlDebugProcess(QCoreApplication::applicationDirPath() + QLatin1String("/qqmldebuggingenablerserver"), this);
- process->setMaximumBindErrors(portTo - portFrom);
- }
-
- if (qmlscene) {
- process->start(QStringList() << QLatin1String("-qmljsdebugger=port:") +
- QString::number(portFrom) + QLatin1Char(',') + QString::number(portTo) +
- QLatin1String(blockMode ? ",block": "") <<
- testFile(QLatin1String("test.qml")));
- } else {
- QStringList args;
- if (blockMode)
- args << QLatin1String("-block");
- args << QString::number(portFrom) << QString::number(portTo);
- process->start(args);
- }
-
- if (!process->waitForSessionStart()) {
- return false;
- }
-
- const int port = process->debugPort();
- connection->connectToHost("127.0.0.1", port);
- if (!connection->waitForConnected()) {
- qDebug() << "could not connect to host!";
- return false;
- }
- return true;
-}
-
-void tst_QQmlDebuggingEnabler::cleanup()
-{
- if (QTest::currentTestFailed()) {
- qDebug() << "Process State:" << process->state();
- qDebug() << "Application Output:" << process->output();
- }
-
- if (process) {
- process->stop();
- delete process;
- }
-
-
- if (connection)
- delete connection;
-
- process = 0;
- connection = 0;
-}
-
void tst_QQmlDebuggingEnabler::data()
{
QTest::addColumn<QString>("connector");
@@ -185,32 +102,32 @@ void tst_QQmlDebuggingEnabler::qmlscene()
QFETCH(bool, blockMode);
QFETCH(QStringList, services);
- process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene",
- this);
- process->setMaximumBindErrors(1);
- process->start(QStringList()
- << QString::fromLatin1("-qmljsdebugger=connector:%1%2%3%4")
- .arg(connector + (connector == QLatin1String("QQmlDebugServer") ?
- QLatin1String(",port:5555,5565") : QString()))
- .arg(blockMode ? QLatin1String(",block") : QString())
- .arg(services.isEmpty() ? QString() : QString::fromLatin1(",services:"))
- .arg(services.isEmpty() ? QString() : services.join(","))
- << testFile(QLatin1String("test.qml")));
+ m_process = new QQmlDebugProcess(
+ QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this);
+ m_process->setMaximumBindErrors(1);
+ m_process->start(QStringList()
+ << QString::fromLatin1("-qmljsdebugger=connector:%1%2%3%4")
+ .arg(connector + (connector == QLatin1String("QQmlDebugServer")
+ ? QLatin1String(",port:5555,5565") : QString()))
+ .arg(blockMode ? QLatin1String(",block") : QString())
+ .arg(services.isEmpty() ? QString() : QString::fromLatin1(",services:"))
+ .arg(services.isEmpty() ? QString() : services.join(","))
+ << testFile(QLatin1String("test.qml")));
if (connector == QLatin1String("QQmlDebugServer")) {
- QVERIFY(process->waitForSessionStart());
- connection = new QQmlDebugConnection();
- QList<QQmlDebugClient *> clients = QQmlDebugTest::createOtherClients(connection);
- connection->connectToHost("127.0.0.1", process->debugPort());
- QVERIFY(connection->waitForConnected());
- foreach (QQmlDebugClient *client, clients)
+ QVERIFY(m_process->waitForSessionStart());
+ m_connection = new QQmlDebugConnection();
+ m_clients = QQmlDebugTest::createOtherClients(m_connection);
+ m_connection->connectToHost("127.0.0.1", m_process->debugPort());
+ QVERIFY(m_connection->waitForConnected());
+ foreach (QQmlDebugClient *client, m_clients)
QCOMPARE(client->state(), (services.isEmpty() || services.contains(client->name())) ?
QQmlDebugClient::Enabled : QQmlDebugClient::Unavailable);
}
- QCOMPARE(process->state(), QLatin1String("running"));
+ QCOMPARE(m_process->state(), QLatin1String("running"));
if (!blockMode)
- QTRY_VERIFY(process->output().contains(QLatin1String("qml: Component.onCompleted")));
+ QTRY_VERIFY(m_process->output().contains(QLatin1String("qml: Component.onCompleted")));
}
void tst_QQmlDebuggingEnabler::custom_data()
@@ -226,9 +143,9 @@ void tst_QQmlDebuggingEnabler::custom()
const int portFrom = 5555;
const int portTo = 5565;
- process = new QQmlDebugProcess(QCoreApplication::applicationDirPath() +
- QLatin1String("/qqmldebuggingenablerserver"), this);
- process->setMaximumBindErrors(portTo - portFrom);
+ m_process = new QQmlDebugProcess(QCoreApplication::applicationDirPath() +
+ QLatin1String("/qqmldebuggingenablerserver"), this);
+ m_process->setMaximumBindErrors(portTo - portFrom);
QStringList args;
if (blockMode)
@@ -240,22 +157,22 @@ void tst_QQmlDebuggingEnabler::custom()
if (!services.isEmpty())
args << QLatin1String("-services") << services;
- process->start(args);
+ m_process->start(args);
if (connector == QLatin1String("QQmlDebugServer")) {
- QVERIFY(process->waitForSessionStart());
- connection = new QQmlDebugConnection();
- QList<QQmlDebugClient *> clients = QQmlDebugTest::createOtherClients(connection);
- connection->connectToHost("127.0.0.1", process->debugPort());
- QVERIFY(connection->waitForConnected());
- foreach (QQmlDebugClient *client, clients)
+ QVERIFY(m_process->waitForSessionStart());
+ m_connection = new QQmlDebugConnection();
+ m_clients = QQmlDebugTest::createOtherClients(m_connection);
+ m_connection->connectToHost("127.0.0.1", m_process->debugPort());
+ QVERIFY(m_connection->waitForConnected());
+ for (QQmlDebugClient *client : qAsConst(m_clients))
QCOMPARE(client->state(), (services.isEmpty() || services.contains(client->name())) ?
QQmlDebugClient::Enabled : QQmlDebugClient::Unavailable);
}
- QCOMPARE(process->state(), QLatin1String("running"));
+ QCOMPARE(m_process->state(), QLatin1String("running"));
if (!blockMode)
- QTRY_VERIFY(process->output().contains(QLatin1String("QQmlEngine created")));
+ QTRY_VERIFY(m_process->output().contains(QLatin1String("QQmlEngine created")));
}
QTEST_MAIN(tst_QQmlDebuggingEnabler)
diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro
index cbaf3b5309..90623c75a6 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro
+++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro
@@ -6,8 +6,6 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qqmldebugjs.cpp
-INCLUDEPATH += ../../shared
-include(../../../../shared/util.pri)
include(../../shared/debugutil.pri)
include(../../shared/qqmlenginedebugclient.pri)
diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp
index d248cf9708..3cd359cf48 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp
+++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp
@@ -27,6 +27,7 @@
****************************************************************************/
#include "debugutil_p.h"
+#include "qqmldebugprocess_p.h"
#include "../../shared/qqmlenginedebugclient.h"
#include "../../../../shared/util.h"
@@ -136,7 +137,7 @@ const char *BREAKPOINTRELOCATION_QMLFILE = "breakpointRelocation.qml";
do {\
if (!QTest::qVerify((statement), #statement, "", __FILE__, __LINE__)) {\
if (QTest::currentTestFailed()) \
- qDebug().nospace() << "\nDEBUGGEE OUTPUT:\n" << process->output();\
+ qDebug().nospace() << "\nDEBUGGEE OUTPUT:\n" << m_process->output();\
return;\
}\
} while (0)
@@ -144,18 +145,12 @@ do {\
class QJSDebugClient;
-class tst_QQmlDebugJS : public QQmlDataTest
+class tst_QQmlDebugJS : public QQmlDebugTest
{
Q_OBJECT
- void init(bool qmlscene, const QString &qmlFile = QString(TEST_QMLFILE), bool blockMode = true,
- bool restrictServices = false);
-
private slots:
- void initTestCase();
- void cleanupTestCase();
-
- void cleanup();
+ void initTestCase() override;
void connect_data();
void connect();
@@ -223,11 +218,12 @@ private slots:
void getScripts();
private:
- void targetData();
+ ConnectResult init(bool qmlscene, const QString &qmlFile = QString(TEST_QMLFILE),
+ bool blockMode = true, bool restrictServices = false);
+ QList<QQmlDebugClient *> createClients() override;
+ QPointer<QJSDebugClient> m_client;
- QQmlDebugProcess *process;
- QJSDebugClient *client;
- QQmlDebugConnection *connection;
+ void targetData();
QTime t;
};
@@ -280,7 +276,6 @@ protected:
void messageReceived(const QByteArray &data);
signals:
- void enabled();
void connected();
void interruptRequested();
void result();
@@ -667,10 +662,8 @@ void QJSDebugClient::disconnect()
void QJSDebugClient::stateChanged(State state)
{
- if (state == Enabled) {
+ if (state == Enabled)
flushSendBuffer();
- emit enabled();
- }
}
void QJSDebugClient::messageReceived(const QByteArray &data)
@@ -763,85 +756,19 @@ QByteArray QJSDebugClient::packMessage(const QByteArray &type, const QByteArray
void tst_QQmlDebugJS::initTestCase()
{
- QQmlDataTest::initTestCase();
+ QQmlDebugTest::initTestCase();
t.start();
- process = 0;
- client = 0;
- connection = 0;
}
-void tst_QQmlDebugJS::cleanupTestCase()
+QQmlDebugTest::ConnectResult tst_QQmlDebugJS::init(bool qmlscene, const QString &qmlFile,
+ bool blockMode, bool restrictServices)
{
- if (process) {
- process->stop();
- delete process;
- }
-
- if (client)
- delete client;
-
- if (connection)
- delete connection;
-}
-
-void tst_QQmlDebugJS::init(bool qmlscene, const QString &qmlFile, bool blockMode,
- bool restrictServices)
-{
- connection = new QQmlDebugConnection();
- if (qmlscene)
- process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) +
- "/qmlscene", this);
- else
- process = new QQmlDebugProcess(QCoreApplication::applicationDirPath() +
- QLatin1String("/qqmldebugjsserver"), this);
- client = new QJSDebugClient(connection);
- QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(connection);
-
- const char *args = 0;
- if (blockMode)
- args = restrictServices ? BLOCKRESTRICTEDMODE : BLOCKMODE;
- else
- args = restrictServices ? NORMALRESTRICTEDMODE : NORMALMODE;
-
- process->start(QStringList() << QLatin1String(args) << testFile(qmlFile));
-
- QVERIFY(process->waitForSessionStart());
-
- const int port = process->debugPort();
- connection->connectToHost("127.0.0.1", port);
- QVERIFY(connection->waitForConnected());
-
-
- if (client->state() != QQmlDebugClient::Enabled)
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(enabled())));
-
- foreach (QQmlDebugClient *otherClient, others)
- QCOMPARE(otherClient->state(), restrictServices ? QQmlDebugClient::Unavailable :
- QQmlDebugClient::Enabled);
- qDeleteAll(others);
-}
-
-void tst_QQmlDebugJS::cleanup()
-{
- if (QTest::currentTestFailed()) {
- qDebug() << "Process State:" << process->state();
- qDebug() << "Application Output:" << process->output();
- }
-
- if (process) {
- process->stop();
- delete process;
- }
-
- if (client)
- delete client;
-
- if (connection)
- delete connection;
-
- process = 0;
- client = 0;
- connection = 0;
+ const QString executable = qmlscene
+ ? QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene"
+ : QCoreApplication::applicationDirPath() + QLatin1String("/qqmldebugjsserver");
+ return QQmlDebugTest::connect(
+ executable, restrictServices ? QStringLiteral("V8Debugger") : QString(),
+ testFile(qmlFile), blockMode);
}
void tst_QQmlDebugJS::connect_data()
@@ -864,9 +791,9 @@ void tst_QQmlDebugJS::connect()
QFETCH(bool, blockMode);
QFETCH(bool, restrictMode);
QFETCH(bool, qmlscene);
- init(qmlscene, QString(TEST_QMLFILE), blockMode, restrictMode);
- client->connect();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(connected())));
+ QCOMPARE(init(qmlscene, QString(TEST_QMLFILE), blockMode, restrictMode), ConnectSuccess);
+ m_client->connect();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(connected())));
}
void tst_QQmlDebugJS::interrupt()
@@ -876,11 +803,11 @@ void tst_QQmlDebugJS::interrupt()
QFETCH(bool, qmlscene);
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
- init(qmlscene);
- client->connect(redundantRefs, namesAsObjects);
+ QCOMPARE(init(qmlscene), ConnectSuccess);
+ m_client->connect(redundantRefs, namesAsObjects);
- client->interrupt();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(interruptRequested())));
+ m_client->interrupt();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(interruptRequested())));
}
void tst_QQmlDebugJS::getVersion()
@@ -890,12 +817,12 @@ void tst_QQmlDebugJS::getVersion()
QFETCH(bool, qmlscene);
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
- init(qmlscene);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(connected())));
+ QCOMPARE(init(qmlscene), ConnectSuccess);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(connected())));
- client->version();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->version();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
}
void tst_QQmlDebugJS::getVersionWhenAttaching()
@@ -905,11 +832,11 @@ void tst_QQmlDebugJS::getVersionWhenAttaching()
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
- init(qmlscene, QLatin1String(TIMER_QMLFILE), false);
- client->connect(redundantRefs, namesAsObjects);
+ QCOMPARE(init(qmlscene, QLatin1String(TIMER_QMLFILE), false), ConnectSuccess);
+ m_client->connect(redundantRefs, namesAsObjects);
- client->version();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->version();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
}
void tst_QQmlDebugJS::disconnect()
@@ -919,11 +846,11 @@ void tst_QQmlDebugJS::disconnect()
QFETCH(bool, qmlscene);
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
- init(qmlscene);
- client->connect(redundantRefs, namesAsObjects);
+ QCOMPARE(init(qmlscene), ConnectSuccess);
+ m_client->connect(redundantRefs, namesAsObjects);
- client->disconnect();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->disconnect();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
}
void tst_QQmlDebugJS::setBreakpointInScriptOnCompleted()
@@ -934,14 +861,14 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnCompleted()
QFETCH(bool, namesAsObjects);
int sourceLine = 34;
- init(qmlscene, ONCOMPLETED_QMLFILE);
+ QCOMPARE(init(qmlscene, ONCOMPLETED_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -957,14 +884,14 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnComponentCreated()
QFETCH(bool, namesAsObjects);
int sourceLine = 34;
- init(qmlscene, CREATECOMPONENT_QMLFILE);
+ QCOMPARE(init(qmlscene, CREATECOMPONENT_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -978,16 +905,16 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnTimerCallback()
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
int sourceLine = 35;
- init(qmlscene, TIMER_QMLFILE);
+ QCOMPARE(init(qmlscene, TIMER_QMLFILE), ConnectSuccess);
- client->connect(redundantRefs, namesAsObjects);
+ m_client->connect(redundantRefs, namesAsObjects);
//We can set the breakpoint after connect() here because the timer is repeating and if we miss
//its first iteration we can still catch the second one.
- client->setBreakpoint(QLatin1String(TIMER_QMLFILE), sourceLine, -1, true);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(TIMER_QMLFILE), sourceLine, -1, true);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -1003,14 +930,14 @@ void tst_QQmlDebugJS::setBreakpointInScriptInDifferentFile()
QFETCH(bool, namesAsObjects);
int sourceLine = 31;
- init(qmlscene, LOADJSFILE_QMLFILE);
+ QCOMPARE(init(qmlscene, LOADJSFILE_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(TEST_JSFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(TEST_JSFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -1027,15 +954,15 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnComment()
int sourceLine = 34;
int actualLine = 36;
- init(qmlscene, BREAKPOINTRELOCATION_QMLFILE);
+ QCOMPARE(init(qmlscene, BREAKPOINTRELOCATION_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
+ m_client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()), 1));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()), 1));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -1052,15 +979,15 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnEmptyLine()
int sourceLine = 35;
int actualLine = 36;
- init(qmlscene, BREAKPOINTRELOCATION_QMLFILE);
+ QCOMPARE(init(qmlscene, BREAKPOINTRELOCATION_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
+ m_client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()), 1));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()), 1));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -1076,14 +1003,14 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnOptimizedBinding()
QFETCH(bool, namesAsObjects);
int sourceLine = 39;
- init(qmlscene, BREAKPOINTRELOCATION_QMLFILE);
+ QCOMPARE(init(qmlscene, BREAKPOINTRELOCATION_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -1098,28 +1025,28 @@ void tst_QQmlDebugJS::setBreakpointInScriptWithCondition()
QFETCH(bool, namesAsObjects);
int out = 10;
int sourceLine = 37;
- init(qmlscene, CONDITION_QMLFILE);
+ QCOMPARE(init(qmlscene, CONDITION_QMLFILE), ConnectSuccess);
- client->connect(redundantRefs, namesAsObjects);
+ m_client->connect(redundantRefs, namesAsObjects);
//The breakpoint is in a timer loop so we can set it after connect().
- client->setBreakpoint(QLatin1String(CONDITION_QMLFILE), sourceLine, 1, true, QLatin1String("a > 10"));
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(CONDITION_QMLFILE), sourceLine, 1, true, QLatin1String("a > 10"));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
//Get the frame index
- QString jsonString = client->response;
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString = m_client->response;
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
{
QVariantMap body = value.value("body").toMap();
int frameIndex = body.value("index").toInt();
//Verify the value of 'result'
- client->evaluate(QLatin1String("a"),frameIndex);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->evaluate(QLatin1String("a"),frameIndex);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
}
- jsonString = client->response;
- QJSValue val = client->parser.call(QJSValueList() << QJSValue(jsonString));
+ jsonString = m_client->response;
+ QJSValue val = m_client->parser.call(QJSValueList() << QJSValue(jsonString));
QVERIFY(val.isObject());
QJSValue body = val.property(QStringLiteral("body"));
QVERIFY(body.isObject());
@@ -1135,42 +1062,42 @@ void tst_QQmlDebugJS::setBreakpointInScriptThatQuits()
QFETCH(bool, qmlscene);
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
- init(qmlscene, QUIT_QMLFILE);
+ QCOMPARE(init(qmlscene, QUIT_QMLFILE), ConnectSuccess);
int sourceLine = 36;
- client->setBreakpoint(QLatin1String(QUIT_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(QUIT_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
QCOMPARE(body.value("sourceLine").toInt(), sourceLine);
QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QUIT_QMLFILE));
- client->continueDebugging(QJSDebugClient::Continue);
- QVERIFY(process->waitForFinished());
- QCOMPARE(process->exitStatus(), QProcess::NormalExit);
+ m_client->continueDebugging(QJSDebugClient::Continue);
+ QVERIFY(m_process->waitForFinished());
+ QCOMPARE(m_process->exitStatus(), QProcess::NormalExit);
}
void tst_QQmlDebugJS::setBreakpointWhenAttaching()
{
int sourceLine = 35;
- init(true, QLatin1String(TIMER_QMLFILE), false);
+ QCOMPARE(init(true, QLatin1String(TIMER_QMLFILE), false), ConnectSuccess);
- client->connect();
+ m_client->connect();
QSKIP("\nThe breakpoint may not hit because the engine may run in JIT mode or not have debug\n"
"instructions, as we've connected in non-blocking mode above. That means we may have\n"
"connected after the engine was already running, with all the QML already compiled.");
//The breakpoint is in a timer loop so we can set it after connect().
- client->setBreakpoint(QLatin1String(TIMER_QMLFILE), sourceLine);
+ m_client->setBreakpoint(QLatin1String(TIMER_QMLFILE), sourceLine);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
}
void tst_QQmlDebugJS::clearBreakpoint()
@@ -1182,41 +1109,41 @@ void tst_QQmlDebugJS::clearBreakpoint()
int sourceLine1 = 37;
int sourceLine2 = 38;
- init(qmlscene, CHANGEBREAKPOINT_QMLFILE);
+ QCOMPARE(init(qmlscene, CHANGEBREAKPOINT_QMLFILE), ConnectSuccess);
- client->connect(redundantRefs, namesAsObjects);
+ m_client->connect(redundantRefs, namesAsObjects);
//The breakpoints are in a timer loop so we can set them after connect().
//Furthermore the breakpoints should be hit in the right order because setting of breakpoints
//can only occur in the QML event loop. (see QCOMPARE for sourceLine2 below)
- client->setBreakpoint(QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine1, -1, true);
- client->setBreakpoint(QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine2, -1, true);
+ m_client->setBreakpoint(QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine1, -1, true);
+ m_client->setBreakpoint(QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine2, -1, true);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
//Will hit 1st brakpoint, change this breakpoint enable = false
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
QList<QVariant> breakpointsHit = body.value("breakpoints").toList();
int breakpoint = breakpointsHit.at(0).toInt();
- client->clearBreakpoint(breakpoint);
+ m_client->clearBreakpoint(breakpoint);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
//Continue with debugging
- client->continueDebugging(QJSDebugClient::Continue);
+ m_client->continueDebugging(QJSDebugClient::Continue);
//Hit 2nd breakpoint
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
//Continue with debugging
- client->continueDebugging(QJSDebugClient::Continue);
+ m_client->continueDebugging(QJSDebugClient::Continue);
//Should stop at 2nd breakpoint
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- jsonString = client->response;
- value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ jsonString = m_client->response;
+ value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
body = value.value("body").toMap();
@@ -1230,10 +1157,10 @@ void tst_QQmlDebugJS::setExceptionBreak()
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
- init(qmlscene, EXCEPTION_QMLFILE);
- client->setExceptionBreak(QJSDebugClient::All,true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ QCOMPARE(init(qmlscene, EXCEPTION_QMLFILE), ConnectSuccess);
+ m_client->setExceptionBreak(QJSDebugClient::All,true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
}
void tst_QQmlDebugJS::stepNext()
@@ -1244,17 +1171,17 @@ void tst_QQmlDebugJS::stepNext()
QFETCH(bool, namesAsObjects);
int sourceLine = 37;
- init(qmlscene, STEPACTION_QMLFILE);
+ QCOMPARE(init(qmlscene, STEPACTION_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- client->continueDebugging(QJSDebugClient::Next);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->continueDebugging(QJSDebugClient::Next);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -1262,6 +1189,14 @@ void tst_QQmlDebugJS::stepNext()
QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
}
+static QVariantMap responseBody(QJSDebugClient *client)
+{
+ const QString jsonString(client->response);
+ const QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString))
+ .toVariant().toMap();
+ return value.value("body").toMap();
+}
+
void tst_QQmlDebugJS::stepIn()
{
//void continueDebugging(StepAction stepAction, int stepCount = 1);
@@ -1270,21 +1205,18 @@ void tst_QQmlDebugJS::stepIn()
QFETCH(bool, namesAsObjects);
int sourceLine = 41;
- int actualLine = 37;
- init(qmlscene, STEPACTION_QMLFILE);
-
- client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, 1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- client->continueDebugging(QJSDebugClient::In);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ int actualLine = 36;
+ QCOMPARE(init(qmlscene, STEPACTION_QMLFILE), ConnectSuccess);
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ m_client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, 1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
+ QCOMPARE(responseBody(m_client).value("sourceLine").toInt(), sourceLine);
- QVariantMap body = value.value("body").toMap();
+ m_client->continueDebugging(QJSDebugClient::In);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
+ const QVariantMap body = responseBody(m_client);
QCOMPARE(body.value("sourceLine").toInt(), actualLine);
QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
}
@@ -1298,20 +1230,17 @@ void tst_QQmlDebugJS::stepOut()
int sourceLine = 37;
int actualLine = 41;
- init(qmlscene, STEPACTION_QMLFILE);
+ QCOMPARE(init(qmlscene, STEPACTION_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
+ QCOMPARE(responseBody(m_client).value("sourceLine").toInt(), sourceLine);
- client->continueDebugging(QJSDebugClient::Out);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
-
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
-
- QVariantMap body = value.value("body").toMap();
+ m_client->continueDebugging(QJSDebugClient::Out);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
+ const QVariantMap body = responseBody(m_client);
QCOMPARE(body.value("sourceLine").toInt(), actualLine);
QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE));
}
@@ -1325,18 +1254,18 @@ void tst_QQmlDebugJS::continueDebugging()
int sourceLine1 = 41;
int sourceLine2 = 38;
- init(qmlscene, STEPACTION_QMLFILE);
+ QCOMPARE(init(qmlscene, STEPACTION_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine1, -1, true);
- client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine2, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine1, -1, true);
+ m_client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine2, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- client->continueDebugging(QJSDebugClient::Continue);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->continueDebugging(QJSDebugClient::Continue);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
@@ -1352,14 +1281,14 @@ void tst_QQmlDebugJS::backtrace()
QFETCH(bool, namesAsObjects);
int sourceLine = 34;
- init(qmlscene, ONCOMPLETED_QMLFILE);
+ QCOMPARE(init(qmlscene, ONCOMPLETED_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- client->backtrace();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->backtrace();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
}
void tst_QQmlDebugJS::getFrameDetails()
@@ -1370,14 +1299,14 @@ void tst_QQmlDebugJS::getFrameDetails()
QFETCH(bool, namesAsObjects);
int sourceLine = 34;
- init(qmlscene, ONCOMPLETED_QMLFILE);
+ QCOMPARE(init(qmlscene, ONCOMPLETED_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- client->frame();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->frame();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
}
void tst_QQmlDebugJS::getScopeDetails()
@@ -1388,33 +1317,32 @@ void tst_QQmlDebugJS::getScopeDetails()
QFETCH(bool, namesAsObjects);
int sourceLine = 34;
- init(qmlscene, ONCOMPLETED_QMLFILE);
+ QCOMPARE(init(qmlscene, ONCOMPLETED_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- client->scope();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->scope();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
}
void tst_QQmlDebugJS::evaluateInGlobalScope()
{
//void evaluate(QString expr, int frame = -1);
- init(true);
+ QCOMPARE(init(true), ConnectSuccess);
- client->connect();
+ m_client->connect();
- do {
+ for (int i = 0; i < 10; ++i) {
// The engine might not be initialized, yet. We just try until it shows up.
- client->evaluate(QLatin1String("console.log('Hello World')"));
- } while (!QQmlDebugTest::waitForSignal(client, SIGNAL(result()), 500));
+ m_client->evaluate(QLatin1String("console.log('Hello World')"));
+ if (QQmlDebugTest::waitForSignal(m_client, SIGNAL(result()), 500))
+ break;
+ }
//Verify the return value of 'console.log()', which is "undefined"
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
- QVariantMap body = value.value("body").toMap();
- QCOMPARE(body.value("type").toString(),QLatin1String("undefined"));
+ QCOMPARE(responseBody(m_client).value("type").toString(), QLatin1String("undefined"));
}
void tst_QQmlDebugJS::evaluateInLocalScope()
@@ -1425,29 +1353,29 @@ void tst_QQmlDebugJS::evaluateInLocalScope()
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
int sourceLine = 34;
- init(qmlscene, ONCOMPLETED_QMLFILE);
+ QCOMPARE(init(qmlscene, ONCOMPLETED_QMLFILE), ConnectSuccess);
- client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- client->frame();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->frame();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
//Get the frame index
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
QVariantMap body = value.value("body").toMap();
int frameIndex = body.value("index").toInt();
- client->evaluate(QLatin1String("root.a"), frameIndex);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
+ m_client->evaluate(QLatin1String("root.a"), frameIndex);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
//Verify the value of 'timer.interval'
- jsonString = client->response;
- value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ jsonString = m_client->response;
+ value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
body = value.value("body").toMap();
@@ -1456,25 +1384,25 @@ void tst_QQmlDebugJS::evaluateInLocalScope()
void tst_QQmlDebugJS::evaluateInContext()
{
- connection = new QQmlDebugConnection();
- process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath)
+ m_connection = new QQmlDebugConnection();
+ m_process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath)
+ "/qmlscene", this);
- client = new QJSDebugClient(connection);
- QScopedPointer<QQmlEngineDebugClient> engineClient(new QQmlEngineDebugClient(connection));
- process->start(QStringList() << QLatin1String(BLOCKMODE) << testFile(ONCOMPLETED_QMLFILE));
+ m_client = new QJSDebugClient(m_connection);
+ QScopedPointer<QQmlEngineDebugClient> engineClient(new QQmlEngineDebugClient(m_connection));
+ m_process->start(QStringList() << QLatin1String(BLOCKMODE) << testFile(ONCOMPLETED_QMLFILE));
- QVERIFY(process->waitForSessionStart());
+ QVERIFY(m_process->waitForSessionStart());
- connection->connectToHost("127.0.0.1", process->debugPort());
- QVERIFY(connection->waitForConnected());
+ m_connection->connectToHost("127.0.0.1", m_process->debugPort());
+ QVERIFY(m_connection->waitForConnected());
- QTRY_COMPARE(client->state(), QQmlEngineDebugClient::Enabled);
+ QTRY_COMPARE(m_client->state(), QQmlEngineDebugClient::Enabled);
QTRY_COMPARE(engineClient->state(), QQmlEngineDebugClient::Enabled);
- client->connect();
+ m_client->connect();
// "a" not accessible without extra context
- client->evaluate(QLatin1String("a + 10"), -1, -1);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(failure())));
+ m_client->evaluate(QLatin1String("a + 10"), -1, -1);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(failure())));
bool success = false;
engineClient->queryAvailableEngines(&success);
@@ -1496,14 +1424,10 @@ void tst_QQmlDebugJS::evaluateInContext()
auto object = engineClient->object();
// "a" accessible in context of surrounding object
- client->evaluate(QLatin1String("a + 10"), -1, object.debugId);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
-
- QString jsonString = client->response;
- QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap();
+ m_client->evaluate(QLatin1String("a + 10"), -1, object.debugId);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
- QVariantMap body = value.value("body").toMap();
- QTRY_COMPARE(body.value("value").toInt(), 20);
+ QTRY_COMPARE(responseBody(m_client).value("value").toInt(), 20);
}
void tst_QQmlDebugJS::getScripts()
@@ -1513,16 +1437,16 @@ void tst_QQmlDebugJS::getScripts()
QFETCH(bool, qmlscene);
QFETCH(bool, redundantRefs);
QFETCH(bool, namesAsObjects);
- init(qmlscene);
+ QCOMPARE(init(qmlscene), ConnectSuccess);
- client->setBreakpoint(QString(TEST_QMLFILE), 35, -1, true);
- client->connect(redundantRefs, namesAsObjects);
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped())));
+ m_client->setBreakpoint(QString(TEST_QMLFILE), 35, -1, true);
+ m_client->connect(redundantRefs, namesAsObjects);
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped())));
- client->scripts();
- QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result())));
- QString jsonString(client->response);
- QVariantMap value = client->parser.call(QJSValueList()
+ m_client->scripts();
+ QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result())));
+ QString jsonString(m_client->response);
+ QVariantMap value = m_client->parser.call(QJSValueList()
<< QJSValue(jsonString)).toVariant().toMap();
QList<QVariant> scripts = value.value("body").toList();
@@ -1531,6 +1455,12 @@ void tst_QQmlDebugJS::getScripts()
QVERIFY(scripts.first().toMap()[QStringLiteral("name")].toString().endsWith(QStringLiteral("data/test.qml")));
}
+QList<QQmlDebugClient *> tst_QQmlDebugJS::createClients()
+{
+ m_client = new QJSDebugClient(m_connection);
+ return QList<QQmlDebugClient *>({m_client});
+}
+
void tst_QQmlDebugJS::targetData()
{
QTest::addColumn<bool>("qmlscene");
diff --git a/tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro b/tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro
index 860d39cca4..1dc9de8f34 100644
--- a/tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro
+++ b/tests/auto/qml/debugger/qqmldebuglocal/qqmldebuglocal.pro
@@ -7,7 +7,6 @@ HEADERS += ../shared/qqmldebugtestservice.h
SOURCES += tst_qqmldebuglocal.cpp \
../shared/qqmldebugtestservice.cpp
-INCLUDEPATH += ../shared
include(../shared/debugutil.pri)
QT += qml-private testlib gui-private core-private
diff --git a/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp b/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp
index 8d21a8a45a..4b28857fc0 100644
--- a/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp
+++ b/tests/auto/qml/debugger/qqmldebuglocal/tst_qqmldebuglocal.cpp
@@ -32,6 +32,9 @@
#include <private/qqmldebugconnector_p.h>
#include <private/qqmldebugconnection_p.h>
+#include <QtQml/qqmldebug.h>
+#include <QtQml/qqmlengine.h>
+
#include <QtTest/qtest.h>
#include <QtTest/qsignalspy.h>
#include <QtNetwork/qhostaddress.h>
diff --git a/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess.pro b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess.pro
new file mode 100644
index 0000000000..331d87b9f1
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess.pro
@@ -0,0 +1,4 @@
+TEMPLATE = subdirs
+SUBDIRS = qqmldebugprocess qqmldebugprocessprocess
+
+qqmldebugprocess.depends = qqmldebugprocessprocess
diff --git a/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/qqmldebugprocess.pro b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/qqmldebugprocess.pro
new file mode 100644
index 0000000000..9bea2d222c
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/qqmldebugprocess.pro
@@ -0,0 +1,14 @@
+CONFIG += testcase
+TARGET = tst_qqmldebugprocess
+QT = core testlib
+CONFIG -= debug_and_release_target
+macos:CONFIG -= app_bundle
+
+SOURCES += \
+ ../../shared/qqmldebugprocess.cpp \
+ tst_qqmldebugprocess.cpp
+
+HEADERS += \
+ ../../shared/qqmldebugprocess_p.h
+
+INCLUDEPATH += ../../shared
diff --git a/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/tst_qqmldebugprocess.cpp b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/tst_qqmldebugprocess.cpp
new file mode 100644
index 0000000000..993a1d5f63
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocess/tst_qqmldebugprocess.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qqmldebugprocess_p.h>
+#include <QtTest>
+
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qscopedpointer.h>
+
+class tst_QQmlDebugProcess : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void sessionStart_data();
+ void sessionStart();
+};
+
+void tst_QQmlDebugProcess::sessionStart_data()
+{
+ QTest::addColumn<int>("delay");
+ QTest::addColumn<QString>("arg");
+ QTest::addColumn<bool>("sessionExpected");
+ QTest::addColumn<bool>("outputExpected");
+
+ QTest::addRow("synchronous / waiting") << -1
+ << "QML Debugger: Waiting for connection on port 2423..."
+ << true << false;
+ QTest::addRow("synchronous / failed") << -1 << "QML Debugger: Unable to listen to port 242."
+ << false << false;
+ QTest::addRow("synchronous / unknown") << -1 << "QML Debugger: You don't know this string."
+ << false << true;
+ QTest::addRow("synchronous / appout") << -1 << "Output from app itself."
+ << false << true;
+
+ QTest::addRow("no delay / waiting") << 0
+ << "QML Debugger: Waiting for connection on port 2423..."
+ << true << false;
+ QTest::addRow("no delay / failed") << 0 << "QML Debugger: Unable to listen to port 242."
+ << false << false;
+ QTest::addRow("no delay / unknown") << 0 << "QML Debugger: You don't know this string."
+ << false << true;
+ QTest::addRow("no delay / appout") << 0 << "Output from app itself."
+ << false << true;
+
+ QTest::addRow("delay / waiting") << 1000
+ << "QML Debugger: Waiting for connection on port 2423..."
+ << true << false;
+ QTest::addRow("delay / failed") << 1000 << "QML Debugger: Unable to listen to port 242."
+ << false << false;
+ QTest::addRow("delay / unknown") << 1000 << "QML Debugger: You don't know this string."
+ << false << true;
+ QTest::addRow("delay / appout") << 1000 << "Output from app itself."
+ << false << true;
+}
+
+void tst_QQmlDebugProcess::sessionStart()
+{
+ QFETCH(int, delay);
+ QFETCH(QString, arg);
+ QFETCH(bool, sessionExpected);
+ QFETCH(bool, outputExpected);
+
+ QScopedPointer<QQmlDebugProcess> process(
+ new QQmlDebugProcess(QCoreApplication::applicationDirPath()
+ + QLatin1String("/qqmldebugprocessprocess"), this));
+ QVERIFY(process);
+
+ bool outputReceived = false;
+ connect(process.data(), &QQmlDebugProcess::readyReadStandardOutput, this, [&]() {
+ QVERIFY(outputExpected);
+ QVERIFY(!outputReceived);
+ QCOMPARE(process->output().trimmed(), arg);
+ outputReceived = true;
+ QTimer::singleShot(qMax(delay, 0), process.data(), &QQmlDebugProcess::stop);
+ });
+
+ if (!outputExpected && !sessionExpected)
+ QTest::ignoreMessage(QtWarningMsg, "App was unable to bind to port!");
+ process->start(QStringList({arg}));
+
+ bool done = false;
+ auto wait = [&](){
+ QCOMPARE(process->waitForSessionStart(), sessionExpected);
+ QCOMPARE(outputReceived, outputExpected);
+ process->stop();
+ done = true;
+ };
+
+ if (delay < 0)
+ wait();
+ else
+ QTimer::singleShot(delay, process.data(), wait);
+
+ QTRY_VERIFY(done);
+ QVERIFY(process->state().startsWith("not running"));
+}
+
+QTEST_MAIN(tst_QQmlDebugProcess)
+
+#include "tst_qqmldebugprocess.moc"
diff --git a/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.cpp b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.cpp
new file mode 100644
index 0000000000..21cce53fc3
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.cpp
@@ -0,0 +1,39 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qcoreapplication.h>
+
+// Process that just outputs a fake "Waiting" message.
+int main(int argc, char **argv)
+{
+ QCoreApplication app(argc, argv);
+ if (argc > 1)
+ qDebug() << argv[1];
+ return app.exec();
+}
diff --git a/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.pro b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.pro
new file mode 100644
index 0000000000..a8eb4885d4
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugprocess/qqmldebugprocessprocess/qqmldebugprocessprocess.pro
@@ -0,0 +1,11 @@
+QT = core
+macos:CONFIG -= app_bundle
+CONFIG -= debug_and_release_target
+CONFIG += console
+SOURCES += qqmldebugprocessprocess.cpp
+
+DESTDIR = ../qqmldebugprocess
+
+target.path = $$[QT_INSTALL_TESTS]/tst_qqmldebugprocess
+INSTALLS += target
+
diff --git a/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro b/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro
index 79cbe52331..3101d09ea5 100644
--- a/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro
+++ b/tests/auto/qml/debugger/qqmldebugservice/qqmldebugservice.pro
@@ -7,8 +7,6 @@ HEADERS += ../shared/qqmldebugtestservice.h
SOURCES += tst_qqmldebugservice.cpp \
../shared/qqmldebugtestservice.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
include(../shared/debugutil.pri)
TESTDATA = data/*
diff --git a/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp b/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp
index 8092faba04..4e103e9a65 100644
--- a/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp
+++ b/tests/auto/qml/debugger/qqmldebugservice/tst_qqmldebugservice.cpp
@@ -29,6 +29,7 @@
#include "qqmldebugtestservice.h"
#include "debugutil_p.h"
+#include "qqmldebugprocess_p.h"
#include "../../../shared/util.h"
#include <private/qqmldebugclient_p.h>
@@ -105,10 +106,13 @@ void tst_QQmlDebugService::initTestCase()
void tst_QQmlDebugService::checkPortRange()
{
- QQmlDebugConnection *connection1 = new QQmlDebugConnection();
- QQmlDebugProcess *process1 = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this);
+ QScopedPointer<QQmlDebugConnection> connection1(new QQmlDebugConnection());
+ QScopedPointer<QQmlDebugProcess> process1(
+ new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath)
+ + "/qmlscene", this));
- process1->start(QStringList() << QLatin1String("-qmljsdebugger=port:3782,3792") << testFile("test.qml"));
+ process1->start(QStringList() << QLatin1String("-qmljsdebugger=port:3782,3792")
+ << testFile("test.qml"));
if (!process1->waitForSessionStart())
QFAIL("could not launch application, or did not get 'Waiting for connection'.");
@@ -119,10 +123,13 @@ void tst_QQmlDebugService::checkPortRange()
QFAIL("could not connect to host!");
// Second instance
- QQmlDebugConnection *connection2 = new QQmlDebugConnection();
- QQmlDebugProcess *process2 = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this);
+ QScopedPointer<QQmlDebugConnection> connection2(new QQmlDebugConnection());
+ QScopedPointer<QQmlDebugProcess> process2(
+ new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath)
+ + "/qmlscene", this));
- process2->start(QStringList() << QLatin1String("-qmljsdebugger=port:3782,3792") << testFile("test.qml"));
+ process2->start(QStringList() << QLatin1String("-qmljsdebugger=port:3782,3792")
+ << testFile("test.qml"));
if (!process2->waitForSessionStart())
QFAIL("could not launch application, or did not get 'Waiting for connection'.");
@@ -131,11 +138,6 @@ void tst_QQmlDebugService::checkPortRange()
connection2->connectToHost("127.0.0.1", port2);
if (!connection2->waitForConnected())
QFAIL("could not connect to host!");
-
- delete connection1;
- delete process1;
- delete connection2;
- delete process2;
}
void tst_QQmlDebugService::name()
diff --git a/tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro b/tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro
index 40ec1230d6..73455bd903 100644
--- a/tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro
+++ b/tests/auto/qml/debugger/qqmlenginecontrol/qqmlenginecontrol.pro
@@ -4,13 +4,11 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qqmlenginecontrol.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
include(../shared/debugutil.pri)
TESTDATA = data/*
-QT += core qml testlib testlib-private gui-private core-private
+QT += core qml testlib gui-private core-private
OTHER_FILES += \
data/test.qml \
diff --git a/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp b/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp
index 2c515d7cf5..a8c43b1c75 100644
--- a/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp
+++ b/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp
@@ -35,12 +35,8 @@
#include <private/qqmlenginecontrolclient_p.h>
#include <QtTest/qtest.h>
-#include <private/qtestresult_p.h>
#include <QtCore/qlibraryinfo.h>
-#define STR_PORT_FROM "13773"
-#define STR_PORT_TO "13783"
-
class QQmlEngineBlocker : public QObject
{
Q_OBJECT
@@ -65,77 +61,37 @@ void QQmlEngineBlocker::blockEngine(int engineId, const QString &name)
static_cast<QQmlEngineControlClient *>(parent())->blockEngine(engineId);
}
-class tst_QQmlEngineControl : public QQmlDataTest
+class tst_QQmlEngineControl : public QQmlDebugTest
{
Q_OBJECT
-public:
- tst_QQmlEngineControl()
- : m_process(0)
- , m_connection(0)
- , m_client(0)
- {}
-
private:
- QQmlDebugProcess *m_process;
- QQmlDebugConnection *m_connection;
- QQmlEngineControlClient *m_client;
+ ConnectResult connect(const QString &testFile, bool restrictServices);
+ QList<QQmlDebugClient *> createClients() override;
- void connect(const QString &testFile, bool restrictServices);
void engine_data();
+ QPointer<QQmlEngineControlClient> m_client;
private slots:
- void cleanup();
-
void startEngine_data();
void startEngine();
void stopEngine_data();
void stopEngine();
};
-void tst_QQmlEngineControl::connect(const QString &testFile, bool restrictServices)
+QQmlDebugTest::ConnectResult tst_QQmlEngineControl::connect(const QString &file,
+ bool restrictServices)
{
- const QString executable = QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene";
- QStringList arguments;
- arguments << QString::fromLatin1("-qmljsdebugger=port:%1,%2,block%3")
- .arg(STR_PORT_FROM).arg(STR_PORT_TO)
- .arg(restrictServices ? QStringLiteral(",services:EngineControl") : QString());
-
- arguments << QQmlDataTest::instance()->testFile(testFile);
-
- m_process = new QQmlDebugProcess(executable, this);
- m_process->start(QStringList() << arguments);
- QVERIFY2(m_process->waitForSessionStart(), "Could not launch application, or did not get 'Waiting for connection'.");
-
- m_connection = new QQmlDebugConnection();
- m_client = new QQmlEngineControlClient(m_connection);
- new QQmlEngineBlocker(m_client);
- QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(m_connection);
-
- const int port = m_process->debugPort();
- m_connection->connectToHost(QLatin1String("127.0.0.1"), port);
-
- QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
- foreach (QQmlDebugClient *other, others)
- QCOMPARE(other->state(), restrictServices ? QQmlDebugClient::Unavailable :
- QQmlDebugClient::Enabled);
- qDeleteAll(others);
+ return QQmlDebugTest::connect(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene",
+ restrictServices ? QStringLiteral("EngineControl") : QString(),
+ testFile(file), true);
}
-void tst_QQmlEngineControl::cleanup()
+QList<QQmlDebugClient *> tst_QQmlEngineControl::createClients()
{
- if (QTest::currentTestFailed()) {
- qDebug() << "Process State:" << (m_process ? m_process->state() : QLatin1String("null"));
- qDebug() << "Application Output:" << (m_process ? m_process->output() : QLatin1String("null"));
- qDebug() << "Connection State:" << QQmlDebugTest::connectionStateString(m_connection);
- qDebug() << "Client State:" << QQmlDebugTest::clientStateString(m_client);
- }
- delete m_process;
- m_process = 0;
- delete m_client;
- m_client = 0;
- delete m_connection;
- m_connection = 0;
+ m_client = new QQmlEngineControlClient(m_connection);
+ new QQmlEngineBlocker(m_client);
+ return QList<QQmlDebugClient *>({m_client});
}
void tst_QQmlEngineControl::engine_data()
@@ -153,16 +109,16 @@ void tst_QQmlEngineControl::startEngine_data()
void tst_QQmlEngineControl::startEngine()
{
QFETCH(bool, restrictMode);
-
- connect("test.qml", restrictMode);
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(connect("test.qml", restrictMode), ConnectSuccess);
QTRY_VERIFY(!m_client->blockedEngines().empty());
m_client->releaseEngine(m_client->blockedEngines().last());
+ QVERIFY(m_client->blockedEngines().isEmpty());
QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineAdded(int,QString))),
"No engine start message received in time.");
+
+ QVERIFY(m_client->blockedEngines().isEmpty());
}
void tst_QQmlEngineControl::stopEngine_data()
@@ -174,21 +130,23 @@ void tst_QQmlEngineControl::stopEngine()
{
QFETCH(bool, restrictMode);
- connect("exit.qml", restrictMode);
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(connect("exit.qml", restrictMode), ConnectSuccess);
QTRY_VERIFY(!m_client->blockedEngines().empty());
m_client->releaseEngine(m_client->blockedEngines().last());
+ QVERIFY(m_client->blockedEngines().isEmpty());
QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineAdded(int,QString))),
"No engine start message received in time.");
+ QVERIFY(m_client->blockedEngines().isEmpty());
QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineAboutToBeRemoved(int,QString))),
"No engine about to stop message received in time.");
m_client->releaseEngine(m_client->blockedEngines().last());
+ QVERIFY(m_client->blockedEngines().isEmpty());
QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(engineRemoved(int,QString))),
"No engine stop message received in time.");
+ QVERIFY(m_client->blockedEngines().isEmpty());
}
QTEST_MAIN(tst_QQmlEngineControl)
diff --git a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro
index b8b4c3fc8b..5f58e5ec7f 100644
--- a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro
+++ b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/qqmlenginedebuginspectorintegrationtest.pro
@@ -1,13 +1,11 @@
CONFIG += testcase
TARGET = tst_qqmlenginedebuginspectorintegration
-QT += qml testlib testlib-private gui-private core-private
+QT += qml testlib gui-private core-private
osx:CONFIG -= app_bundle
SOURCES += tst_qqmlenginedebuginspectorintegration.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
include(../shared/qqmlinspectorclient.pri)
include(../shared/qqmlenginedebugclient.pri)
include(../shared/debugutil.pri)
diff --git a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp
index aba9eb39ab..249416a3b9 100644
--- a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp
+++ b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp
@@ -34,7 +34,6 @@
#include <private/qqmldebugconnection_p.h>
#include <QtTest/qtest.h>
-#include <private/qtestresult_p.h>
#include <QtTest/qsignalspy.h>
#include <QtNetwork/qhostaddress.h>
#include <QtCore/qtimer.h>
@@ -42,35 +41,21 @@
#include <QtCore/qthread.h>
#include <QtCore/qlibraryinfo.h>
-#define STR_PORT_FROM "3776"
-#define STR_PORT_TO "3786"
-
-class tst_QQmlEngineDebugInspectorIntegration : public QQmlDataTest
+class tst_QQmlEngineDebugInspectorIntegration : public QQmlDebugTest
{
Q_OBJECT
-public:
- tst_QQmlEngineDebugInspectorIntegration()
- : m_process(0)
- , m_inspectorClient(0)
- , m_engineDebugClient(0)
- , m_recipient(0)
- {
- }
-
-
private:
- void init(bool restrictServices);
+ ConnectResult init(bool restrictServices);
+ QList<QQmlDebugClient *> createClients() override;
+
QmlDebugObjectReference findRootObject();
- QQmlDebugProcess *m_process;
- QQmlInspectorClient *m_inspectorClient;
- QQmlEngineDebugClient *m_engineDebugClient;
- QQmlInspectorResultRecipient *m_recipient;
+ QPointer<QQmlInspectorClient> m_inspectorClient;
+ QPointer<QQmlEngineDebugClient> m_engineDebugClient;
+ QPointer<QQmlInspectorResultRecipient> m_recipient;
private slots:
- void cleanup();
-
void connect_data();
void connect();
void objectLocationLookup();
@@ -100,53 +85,22 @@ QmlDebugObjectReference tst_QQmlEngineDebugInspectorIntegration::findRootObject(
return m_engineDebugClient->object();
}
-void tst_QQmlEngineDebugInspectorIntegration::init(bool restrictServices)
+QQmlDebugTest::ConnectResult tst_QQmlEngineDebugInspectorIntegration::init(bool restrictServices)
{
- const QString argument = QString::fromLatin1("-qmljsdebugger=port:%1,%2,block%3")
- .arg(STR_PORT_FROM).arg(STR_PORT_TO)
- .arg(restrictServices ? QStringLiteral(",services:QmlDebugger,QmlInspector") :
- QString());
-
- m_process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml",
- this);
- m_process->start(QStringList() << argument << testFile("qtquick2.qml"));
- QVERIFY2(m_process->waitForSessionStart(),
- "Could not launch application, or did not get 'Waiting for connection'.");
-
- QQmlDebugConnection *m_connection = new QQmlDebugConnection(this);
- m_inspectorClient = new QQmlInspectorClient(m_connection);
- m_engineDebugClient = new QQmlEngineDebugClient(m_connection);
- m_recipient = new QQmlInspectorResultRecipient(this);
- QObject::connect(m_inspectorClient, &QQmlInspectorClient::responseReceived,
- m_recipient, &QQmlInspectorResultRecipient::recordResponse);
-
- QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(m_connection);
-
- m_connection->connectToHost(QLatin1String("127.0.0.1"), m_process->debugPort());
- QVERIFY(m_connection->waitForConnected());
- foreach (QQmlDebugClient *other, others)
- QCOMPARE(other->state(), restrictServices ? QQmlDebugClient::Unavailable :
- QQmlDebugClient::Enabled);
- qDeleteAll(others);
-
- QTRY_COMPARE(m_inspectorClient->state(), QQmlDebugClient::Enabled);
- QTRY_COMPARE(m_engineDebugClient->state(), QQmlDebugClient::Enabled);
+ return QQmlDebugTest::connect(
+ QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml",
+ restrictServices ? QStringLiteral("QmlDebugger,QmlInspector") : QString(),
+ testFile("qtquick2.qml"), true);
}
-void tst_QQmlEngineDebugInspectorIntegration::cleanup()
+QList<QQmlDebugClient *> tst_QQmlEngineDebugInspectorIntegration::createClients()
{
- if (QTest::currentTestFailed()) {
- qDebug() << "Process State:" << m_process->state();
- qDebug() << "Application Output:" << m_process->output();
- }
- delete m_process;
- m_process = 0;
- delete m_engineDebugClient;
- m_engineDebugClient = 0;
- delete m_inspectorClient;
- m_inspectorClient = 0;
- delete m_recipient;
- m_recipient = 0;
+ m_inspectorClient = new QQmlInspectorClient(m_connection);
+ m_engineDebugClient = new QQmlEngineDebugClient(m_connection);
+ m_recipient = new QQmlInspectorResultRecipient(m_inspectorClient);
+ QObject::connect(m_inspectorClient.data(), &QQmlInspectorClient::responseReceived,
+ m_recipient.data(), &QQmlInspectorResultRecipient::recordResponse);
+ return QList<QQmlDebugClient *>({m_inspectorClient, m_engineDebugClient});
}
void tst_QQmlEngineDebugInspectorIntegration::connect_data()
@@ -159,14 +113,12 @@ void tst_QQmlEngineDebugInspectorIntegration::connect_data()
void tst_QQmlEngineDebugInspectorIntegration::connect()
{
QFETCH(bool, restrictMode);
- init(restrictMode);
+ QCOMPARE(init(restrictMode), ConnectSuccess);
}
void tst_QQmlEngineDebugInspectorIntegration::objectLocationLookup()
{
- init(true);
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(init(true), ConnectSuccess);
bool success = false;
QmlDebugObjectReference rootObject = findRootObject();
@@ -192,9 +144,7 @@ void tst_QQmlEngineDebugInspectorIntegration::objectLocationLookup()
void tst_QQmlEngineDebugInspectorIntegration::select()
{
- init(true);
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(init(true), ConnectSuccess);
QmlDebugObjectReference rootObject = findRootObject();
QList<int> childIds;
@@ -212,9 +162,7 @@ void tst_QQmlEngineDebugInspectorIntegration::select()
void tst_QQmlEngineDebugInspectorIntegration::createObject()
{
- init(true);
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(init(true), ConnectSuccess);
QString qml = QLatin1String("Rectangle {\n"
" id: xxxyxxx\n"
@@ -241,9 +189,7 @@ void tst_QQmlEngineDebugInspectorIntegration::createObject()
void tst_QQmlEngineDebugInspectorIntegration::moveObject()
{
- init(true);
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(init(true), ConnectSuccess);
QCOMPARE(m_inspectorClient->state(), QQmlDebugClient::Enabled);
QmlDebugObjectReference rootObject = findRootObject();
@@ -268,9 +214,7 @@ void tst_QQmlEngineDebugInspectorIntegration::moveObject()
void tst_QQmlEngineDebugInspectorIntegration::destroyObject()
{
- init(true);
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(init(true), ConnectSuccess);
QCOMPARE(m_inspectorClient->state(), QQmlDebugClient::Enabled);
QmlDebugObjectReference rootObject = findRootObject();
diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro b/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro
index 06250d9940..33ee023c06 100644
--- a/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro
+++ b/tests/auto/qml/debugger/qqmlenginedebugservice/qqmlenginedebugservice.pro
@@ -5,8 +5,6 @@ osx:CONFIG -= app_bundle
SOURCES += \
tst_qqmlenginedebugservice.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
include(../shared/qqmlenginedebugclient.pri)
include(../shared/debugutil.pri)
diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
index 6d31ff9219..8993ce7cf4 100644
--- a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
+++ b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
@@ -229,9 +229,23 @@ void tst_QQmlEngineDebugService::recursiveObjectTest(
QCOMPARE(p.name, QString::fromUtf8(pmeta.name()));
- if (pmeta.type() < QVariant::UserType && pmeta.userType() !=
- QMetaType::QVariant) // TODO test complex types
- QCOMPARE(p.value , pmeta.read(o));
+ if (pmeta.userType() == QMetaType::QObjectStar) {
+ const QmlDebugObjectReference ref = qvariant_cast<QmlDebugObjectReference>(p.value);
+ QObject *pobj = qvariant_cast<QObject *>(pmeta.read(o));
+ if (pobj) {
+ if (pobj->objectName().isEmpty())
+ QCOMPARE(ref.name, QString("<unnamed object>"));
+ else
+ QCOMPARE(ref.name, pobj->objectName());
+ } else {
+ QCOMPARE(ref.name, QString("<unknown value>"));
+ }
+ } else if (pmeta.type() < QVariant::UserType && pmeta.userType() != QMetaType::QVariant) {
+ const QVariant expected = pmeta.read(o);
+ QVERIFY2(p.value == expected, QString::fromLatin1("%1 != %2. Details: %3/%4/%5/%6")
+ .arg(QTest::toString(p.value)).arg(QTest::toString(expected)).arg(p.name)
+ .arg(p.valueTypeName).arg(pmeta.type()).arg(pmeta.userType()).toUtf8());
+ }
if (p.name == "parent")
QVERIFY(p.valueTypeName == "QGraphicsObject*" ||
@@ -1259,7 +1273,8 @@ void tst_QQmlEngineDebugService::queryObjectTree()
QmlDebugObjectReference targetReference = qvariant_cast<QmlDebugObjectReference>(propertyChangeTarget.value);
QVERIFY(!targetReference.className.isEmpty());
- QVERIFY(targetReference.debugId != -1);
+ QCOMPARE(targetReference.debugId, -1);
+ QCOMPARE(targetReference.name, QString("<unnamed object>"));
// check transition
QmlDebugObjectReference transition = obj.children[0];
@@ -1277,7 +1292,8 @@ void tst_QQmlEngineDebugService::queryObjectTree()
targetReference = qvariant_cast<QmlDebugObjectReference>(animationTarget.value);
QVERIFY(!targetReference.className.isEmpty());
- QVERIFY(targetReference.debugId != -1);
+ QCOMPARE(targetReference.debugId, -1);
+ QCOMPARE(targetReference.name, QString("<unnamed object>"));
QCOMPARE(findProperty(animation.properties,"property").value.toString(), QString("width"));
QCOMPARE(findProperty(animation.properties,"duration").value.toInt(), 100);
diff --git a/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro b/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro
index ee5f3c708a..fd07255ae5 100644
--- a/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro
+++ b/tests/auto/qml/debugger/qqmlinspector/qqmlinspector.pro
@@ -6,8 +6,6 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qqmlinspector.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
include(../shared/qqmlinspectorclient.pri)
include(../shared/debugutil.pri)
diff --git a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
index 9461922eff..5c9506eb21 100644
--- a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
+++ b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
@@ -28,6 +28,7 @@
#include "qqmlinspectorclient.h"
#include "../shared/debugutil_p.h"
+#include "../shared/qqmldebugprocess_p.h"
#include "../../../shared/util.h"
#include <private/qqmldebugconnection_p.h>
@@ -40,64 +41,32 @@
#include <QtCore/qlibraryinfo.h>
#include <QtNetwork/qhostaddress.h>
-#define STR_PORT_FROM "3772"
-#define STR_PORT_TO "3782"
-
-
-class tst_QQmlInspector : public QQmlDataTest
+class tst_QQmlInspector : public QQmlDebugTest
{
Q_OBJECT
private:
- void startQmlProcess(const QString &qmlFile, bool restrictMode = true);
+ ConnectResult startQmlProcess(const QString &qmlFile, bool restrictMode = true);
void checkAnimationSpeed(int targetMillisPerDegree);
+ QList<QQmlDebugClient *> createClients() override;
+ QQmlDebugProcess *createProcess(const QString &executable) override;
-private:
- QScopedPointer<QQmlDebugProcess> m_process;
- QScopedPointer<QQmlDebugConnection> m_connection;
- QScopedPointer<QQmlInspectorClient> m_client;
- QScopedPointer<QQmlInspectorResultRecipient> m_recipient;
+ QPointer<QQmlInspectorClient> m_client;
+ QPointer<QQmlInspectorResultRecipient> m_recipient;
private slots:
- void cleanup();
-
void connect_data();
void connect();
void setAnimationSpeed();
void showAppOnTop();
};
-void tst_QQmlInspector::startQmlProcess(const QString &qmlFile, bool restrictServices)
+QQmlDebugTest::ConnectResult tst_QQmlInspector::startQmlProcess(const QString &qmlFile,
+ bool restrictServices)
{
- const QString argument = QString::fromLatin1("-qmljsdebugger=port:%1,%2,block%3")
- .arg(STR_PORT_FROM).arg(STR_PORT_TO)
- .arg(restrictServices ? QStringLiteral(",services:QmlInspector") : QString());
-
- m_process.reset(new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) +
- "/qml"));
- // Make sure the animation timing is exact
- m_process->addEnvironment(QLatin1String("QSG_RENDER_LOOP=basic"));
- m_process->start(QStringList() << argument << testFile(qmlFile));
- QVERIFY2(m_process->waitForSessionStart(),
- "Could not launch application, or did not get 'Waiting for connection'.");
-
- m_client.reset();
- m_connection.reset(new QQmlDebugConnection);
- m_client.reset(new QQmlInspectorClient(m_connection.data()));
-
- m_recipient.reset(new QQmlInspectorResultRecipient);
- QObject::connect(m_client.data(), &QQmlInspectorClient::responseReceived,
- m_recipient.data(), &QQmlInspectorResultRecipient::recordResponse);
-
- QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(m_connection.data());
-
- m_connection->connectToHost(QLatin1String("127.0.0.1"), m_process->debugPort());
- QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
-
- foreach (QQmlDebugClient *other, others)
- QCOMPARE(other->state(), restrictServices ? QQmlDebugClient::Unavailable :
- QQmlDebugClient::Enabled);
- qDeleteAll(others);
+ return QQmlDebugTest::connect(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml",
+ restrictServices ? QStringLiteral("QmlInspector") : QString(),
+ testFile(qmlFile), true);
}
void tst_QQmlInspector::checkAnimationSpeed(int targetMillisPerDegree)
@@ -114,8 +83,7 @@ void tst_QQmlInspector::checkAnimationSpeed(int targetMillisPerDegree)
QString output = m_process->output();
int position = output.length();
do {
- QVERIFY(QQmlDebugTest::waitForSignal(m_process.data(),
- SIGNAL(readyReadStandardOutput())));
+ QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
output = m_process->output();
} while (!output.mid(position).contains(markerString));
@@ -144,12 +112,21 @@ void tst_QQmlInspector::checkAnimationSpeed(int targetMillisPerDegree)
.arg(targetMillisPerDegree).toLocal8Bit().constData());
}
-void tst_QQmlInspector::cleanup()
+QList<QQmlDebugClient *> tst_QQmlInspector::createClients()
{
- if (QTest::currentTestFailed()) {
- qDebug() << "Process State:" << m_process->state();
- qDebug() << "Application Output:" << m_process->output();
- }
+ m_client = new QQmlInspectorClient(m_connection);
+ m_recipient = new QQmlInspectorResultRecipient(m_client);
+ QObject::connect(m_client.data(), &QQmlInspectorClient::responseReceived,
+ m_recipient.data(), &QQmlInspectorResultRecipient::recordResponse);
+ return QList<QQmlDebugClient *>({m_client});
+}
+
+QQmlDebugProcess *tst_QQmlInspector::createProcess(const QString &executable)
+{
+ QQmlDebugProcess *process = QQmlDebugTest::createProcess(executable);
+ // Make sure the animation timing is exact
+ process->addEnvironment(QLatin1String("QSG_RENDER_LOOP=basic"));
+ return process;
}
void tst_QQmlInspector::connect_data()
@@ -166,7 +143,7 @@ void tst_QQmlInspector::connect()
{
QFETCH(QString, file);
QFETCH(bool, restrictMode);
- startQmlProcess(file, restrictMode);
+ QCOMPARE(startQmlProcess(file, restrictMode), ConnectSuccess);
QVERIFY(m_client);
QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
@@ -181,7 +158,7 @@ void tst_QQmlInspector::connect()
void tst_QQmlInspector::showAppOnTop()
{
- startQmlProcess("qtquick2.qml");
+ QCOMPARE(startQmlProcess("qtquick2.qml"), ConnectSuccess);
QVERIFY(m_client);
QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
@@ -196,7 +173,7 @@ void tst_QQmlInspector::showAppOnTop()
void tst_QQmlInspector::setAnimationSpeed()
{
- startQmlProcess("qtquick2.qml");
+ QCOMPARE(startQmlProcess("qtquick2.qml"), ConnectSuccess);
QVERIFY(m_client);
QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
checkAnimationSpeed(10);
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/data/controlFromJS.qml b/tests/auto/qml/debugger/qqmlprofilerservice/data/controlFromJS.qml
index dd7cb2055d..4235a2d55f 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/data/controlFromJS.qml
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/data/controlFromJS.qml
@@ -43,13 +43,6 @@ QtObject {
interval: 1000
onTriggered: {
console.profileEnd();
- endTimer.start();
}
}
-
- property var endTimer: Timer {
- id: endTimer
- interval: 1000
- onTriggered: Qt.quit();
- }
}
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/data/exit.qml b/tests/auto/qml/debugger/qqmlprofilerservice/data/exit.qml
index 4236d70ea3..3b28e65174 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/data/exit.qml
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/data/exit.qml
@@ -1,7 +1,7 @@
import QtQml 2.0
QtObject {
- Timer {
+ property Timer timer: Timer {
running: true
interval: 1
onTriggered: Qt.quit();
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/data/qstr.qml b/tests/auto/qml/debugger/qqmlprofilerservice/data/qstr.qml
new file mode 100644
index 0000000000..09dcd34b5c
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/data/qstr.qml
@@ -0,0 +1,9 @@
+import QtQml 2.0
+
+Timer {
+ property string stuff: qsTr("foo")
+
+ running: true
+ interval: 1
+ onTriggered: Qt.quit();
+}
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro b/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro
index 56840d5c8f..7c78b5fcb3 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro
@@ -4,8 +4,6 @@ osx:CONFIG -= app_bundle
SOURCES += tst_qqmlprofilerservice.cpp
-INCLUDEPATH += ../shared
-include(../../../shared/util.pri)
include(../shared/debugutil.pri)
TESTDATA = data/*
@@ -22,4 +20,5 @@ OTHER_FILES += \
data/signalSourceLocation.qml \
data/javascript.qml \
data/timer.qml \
+ data/qstr.qml \
data/memory.qml
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
index bc6c51707a..db28d3202d 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
@@ -27,6 +27,7 @@
****************************************************************************/
#include "debugutil_p.h"
+#include "qqmldebugprocess_p.h"
#include "../../../shared/util.h"
#include <private/qqmlprofilerclient_p.h>
@@ -36,246 +37,144 @@
#include <private/qtestresult_p.h>
#include <QtCore/qlibraryinfo.h>
-#define STR_PORT_FROM "13773"
-#define STR_PORT_TO "13783"
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/qpa/qplatformintegration.h>
-struct QQmlProfilerData
-{
- QQmlProfilerData(qint64 time = -2, int messageType = -1, int detailType = -1,
- const QString &detailData = QString()) :
- time(time), messageType(messageType), detailType(detailType), detailData(detailData),
- line(-1), column(-1), framerate(-1), animationcount(-1), amount(-1)
- {}
-
- qint64 time;
- int messageType;
- int detailType;
-
- //###
- QString detailData; //used by RangeData and RangeLocation
- int line; //used by RangeLocation
- int column; //used by RangeLocation
- int framerate; //used by animation events
- int animationcount; //used by animation events
- qint64 amount; //used by heap events
-};
-
-class QQmlProfilerTestClient : public QQmlProfilerClient
+class QQmlProfilerTestClient : public QQmlProfilerEventReceiver, public QQmlProfilerDefinitions
{
Q_OBJECT
public:
- QQmlProfilerTestClient(QQmlDebugConnection *connection) : QQmlProfilerClient(connection),
- lastTimestamp(-1) {}
+ QQmlProfilerTestClient(QQmlDebugConnection *connection) :
+ client(new QQmlProfilerClient(connection, this))
+ {
+ connect(client.data(), &QQmlProfilerClient::traceStarted,
+ this, &QQmlProfilerTestClient::startTrace);
+ connect(client.data(), &QQmlProfilerClient::traceFinished,
+ this, &QQmlProfilerTestClient::endTrace);
+ }
- QVector<QQmlProfilerData> qmlMessages;
- QVector<QQmlProfilerData> javascriptMessages;
- QVector<QQmlProfilerData> jsHeapMessages;
- QVector<QQmlProfilerData> asynchronousMessages;
- QVector<QQmlProfilerData> pixmapMessages;
+ void startTrace(qint64 timestamp, const QList<int> &engineIds);
+ void endTrace(qint64 timestamp, const QList<int> &engineIds);
- qint64 lastTimestamp;
+ QPointer<QQmlProfilerClient> client; // Owned by QQmlDebugTest
+ QVector<QQmlProfilerEventType> types;
-signals:
- void recordingFinished();
+ QVector<QQmlProfilerEvent> qmlMessages;
+ QVector<QQmlProfilerEvent> javascriptMessages;
+ QVector<QQmlProfilerEvent> jsHeapMessages;
+ QVector<QQmlProfilerEvent> asynchronousMessages;
+ QVector<QQmlProfilerEvent> pixmapMessages;
-private:
- void traceStarted(qint64 time, int engineId);
- void traceFinished(qint64 time, int engineId);
- void rangeStart(QQmlProfilerDefinitions::RangeType type, qint64 startTime);
- void rangeData(QQmlProfilerDefinitions::RangeType type, qint64 time, const QString &data);
- void rangeLocation(QQmlProfilerDefinitions::RangeType type, qint64 time,
- const QQmlEventLocation &location);
- void rangeEnd(QQmlProfilerDefinitions::RangeType type, qint64 endTime);
- void animationFrame(qint64 time, int frameRate, int animationCount, int threadId);
- void sceneGraphEvent(QQmlProfilerDefinitions::SceneGraphFrameType type, qint64 time,
- qint64 numericData1, qint64 numericData2, qint64 numericData3,
- qint64 numericData4, qint64 numericData5);
- void pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type, qint64 time,
- const QString &url, int numericData1, int numericData2);
- void memoryAllocation(QQmlProfilerDefinitions::MemoryType type, qint64 time, qint64 amount);
- void inputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time, int a, int b);
- void complete();
-
- void unknownEvent(QQmlProfilerDefinitions::Message messageType, qint64 time, int detailType);
- void unknownData(QPacket &stream);
+ int numLoadedEventTypes() const override;
+ void addEventType(const QQmlProfilerEventType &type) override;
+ void addEvent(const QQmlProfilerEvent &event) override;
};
-void QQmlProfilerTestClient::traceStarted(qint64 time, int engineId)
-{
- asynchronousMessages.append(QQmlProfilerData(time, QQmlProfilerDefinitions::Event,
- QQmlProfilerDefinitions::StartTrace,
- QString::number(engineId)));
-}
-
-void QQmlProfilerTestClient::traceFinished(qint64 time, int engineId)
+void QQmlProfilerTestClient::startTrace(qint64 timestamp, const QList<int> &engineIds)
{
- asynchronousMessages.append(QQmlProfilerData(time, QQmlProfilerDefinitions::Event,
- QQmlProfilerDefinitions::EndTrace,
- QString::number(engineId)));
+ types.append(QQmlProfilerEventType(Event, MaximumRangeType, StartTrace));
+ asynchronousMessages.append(QQmlProfilerEvent(timestamp, types.length() - 1,
+ engineIds.toVector()));
}
-void QQmlProfilerTestClient::rangeStart(QQmlProfilerDefinitions::RangeType type, qint64 startTime)
+void QQmlProfilerTestClient::endTrace(qint64 timestamp, const QList<int> &engineIds)
{
- QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType);
- QVERIFY(lastTimestamp <= startTime);
- lastTimestamp = startTime;
- QQmlProfilerData data(startTime, QQmlProfilerDefinitions::RangeStart, type);
- if (type == QQmlProfilerDefinitions::Javascript)
- javascriptMessages.append(data);
- else
- qmlMessages.append(data);
+ types.append(QQmlProfilerEventType(Event, MaximumRangeType, EndTrace));
+ asynchronousMessages.append(QQmlProfilerEvent(timestamp, types.length() - 1,
+ engineIds.toVector()));
}
-void QQmlProfilerTestClient::rangeData(QQmlProfilerDefinitions::RangeType type, qint64 time,
- const QString &string)
+int QQmlProfilerTestClient::numLoadedEventTypes() const
{
- QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType);
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- QQmlProfilerData data(time, QQmlProfilerDefinitions::RangeData, type, string);
- if (type == QQmlProfilerDefinitions::Javascript)
- javascriptMessages.append(data);
- else
- qmlMessages.append(data);
+ return types.length();
}
-void QQmlProfilerTestClient::rangeLocation(QQmlProfilerDefinitions::RangeType type, qint64 time,
- const QQmlEventLocation &location)
+void QQmlProfilerTestClient::addEventType(const QQmlProfilerEventType &type)
{
- QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType);
- QVERIFY(location.line >= -2);
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- QQmlProfilerData data(time, QQmlProfilerDefinitions::RangeLocation, type, location.filename);
- data.line = location.line;
- data.column = location.column;
- if (type == QQmlProfilerDefinitions::Javascript)
- javascriptMessages.append(data);
- else
- qmlMessages.append(data);
+ types.append(type);
}
-void QQmlProfilerTestClient::rangeEnd(QQmlProfilerDefinitions::RangeType type, qint64 endTime)
+void QQmlProfilerTestClient::addEvent(const QQmlProfilerEvent &event)
{
- QVERIFY(type >= 0 && type < QQmlProfilerDefinitions::MaximumRangeType);
- QVERIFY(lastTimestamp <= endTime);
- lastTimestamp = endTime;
- QQmlProfilerData data(endTime, QQmlProfilerDefinitions::RangeEnd, type);
- if (type == QQmlProfilerDefinitions::Javascript)
- javascriptMessages.append(data);
- else
- qmlMessages.append(data);
-}
+ const int typeIndex = event.typeIndex();
+ QVERIFY(typeIndex < types.length());
-void QQmlProfilerTestClient::animationFrame(qint64 time, int frameRate, int animationCount, int threadId)
-{
- QVERIFY(threadId >= 0);
- QVERIFY(frameRate != -1);
- QVERIFY(animationCount != -1);
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- QQmlProfilerData data(time, QQmlProfilerDefinitions::Event,
- QQmlProfilerDefinitions::AnimationFrame);
- data.framerate = frameRate;
- data.animationcount = animationCount;
- asynchronousMessages.append(data);
-}
-
-void QQmlProfilerTestClient::sceneGraphEvent(QQmlProfilerDefinitions::SceneGraphFrameType type,
- qint64 time, qint64 numericData1, qint64 numericData2,
- qint64 numericData3, qint64 numericData4,
- qint64 numericData5)
-{
- Q_UNUSED(numericData1);
- Q_UNUSED(numericData2);
- Q_UNUSED(numericData3);
- Q_UNUSED(numericData4);
- Q_UNUSED(numericData5);
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- asynchronousMessages.append(QQmlProfilerData(time, QQmlProfilerDefinitions::SceneGraphFrame,
- type));
-}
+ const QQmlProfilerEventType &type = types[typeIndex];
-void QQmlProfilerTestClient::pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type,
- qint64 time, const QString &url, int numericData1,
- int numericData2)
-{
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- QQmlProfilerData data(time, QQmlProfilerDefinitions::PixmapCacheEvent, type, url);
- switch (type) {
- case QQmlProfilerDefinitions::PixmapSizeKnown:
- data.line = numericData1;
- data.column = numericData2;
+ switch (type.message()) {
+ case Event: {
+ switch (type.detailType()) {
+ case StartTrace:
+ QFAIL("StartTrace should not be passed on as event");
+ break;
+ case EndTrace:
+ QFAIL("EndTrace should not be passed on as event");
+ break;
+ case AnimationFrame:
+ asynchronousMessages.append(event);
+ break;
+ case Mouse:
+ case Key:
+ qmlMessages.append(event);
+ break;
+ default:
+ QFAIL(qPrintable(QString::fromLatin1("Event with unknown detailType %1 received at %2.")
+ .arg(type.detailType()).arg(event.timestamp())));
+ break;
+ }
+ break;
+ }
+ case RangeStart:
+ case RangeData:
+ case RangeLocation:
+ case RangeEnd:
+ QFAIL("Range stages are transmitted as part of events");
+ break;
+ case Complete:
+ QFAIL("Complete should not be passed on as event");
+ break;
+ case PixmapCacheEvent:
+ pixmapMessages.append(event);
+ break;
+ case SceneGraphFrame:
+ asynchronousMessages.append(event);
break;
- case QQmlProfilerDefinitions::PixmapReferenceCountChanged:
- case QQmlProfilerDefinitions::PixmapCacheCountChanged:
- data.animationcount = numericData1;
+ case MemoryAllocation:
+ jsHeapMessages.append(event);
break;
- default:
+ case DebugMessage:
+ // Unhandled
+ break;
+ case MaximumMessage:
+ switch (type.rangeType()) {
+ case Painting:
+ QFAIL("QtQuick1 paint message received.");
+ break;
+ case Compiling:
+ case Creating:
+ case Binding:
+ case HandlingSignal:
+ qmlMessages.append(event);
+ break;
+ case Javascript:
+ javascriptMessages.append(event);
+ break;
+ default:
+ QFAIL(qPrintable(
+ QString::fromLatin1("Unknown range event %1 received at %2.")
+ .arg(type.rangeType()).arg(event.timestamp())));
+ break;
+ }
break;
}
- pixmapMessages.append(data);
-}
-
-void QQmlProfilerTestClient::memoryAllocation(QQmlProfilerDefinitions::MemoryType type, qint64 time,
- qint64 amount)
-{
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- QQmlProfilerData data(time, QQmlProfilerDefinitions::MemoryAllocation, type);
- data.amount = amount;
- jsHeapMessages.append(data);
}
-void QQmlProfilerTestClient::inputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time,
- int a, int b)
-{
- QVERIFY(lastTimestamp <= time);
- lastTimestamp = time;
- qmlMessages.append(QQmlProfilerData(time, QQmlProfilerDefinitions::Event, type,
- QString::number(a) + QLatin1Char('x') +
- QString::number(b)));
-}
-
-void QQmlProfilerTestClient::unknownEvent(QQmlProfilerDefinitions::Message messageType, qint64 time,
- int detailType)
-{
- QFAIL(qPrintable(QString::fromLatin1("Unknown event %1 with detail type %2 received at %3.")
- .arg(messageType).arg(detailType).arg(time)));
-}
-
-void QQmlProfilerTestClient::unknownData(QPacket &stream)
-{
- QFAIL(qPrintable(QString::fromLatin1("%1 bytes of extra data after receiving message.")
- .arg(stream.device()->bytesAvailable())));
-}
-
-void QQmlProfilerTestClient::complete()
-{
- emit recordingFinished();
-}
-
-class tst_QQmlProfilerService : public QQmlDataTest
+class tst_QQmlProfilerService : public QQmlDebugTest
{
Q_OBJECT
-public:
- tst_QQmlProfilerService()
- : m_process(0)
- , m_connection(0)
- , m_client(0)
- {
- }
-
-
private:
- QQmlDebugProcess *m_process;
- QQmlDebugConnection *m_connection;
- QQmlProfilerTestClient *m_client;
-
enum MessageListType {
MessageListQML,
MessageListJavaScript,
@@ -290,18 +189,26 @@ private:
CheckLine = 1 << 2,
CheckColumn = 1 << 3,
CheckDataEndsWith = 1 << 4,
+ CheckFileEndsWith = 1 << 5,
+ CheckNumbers = 1 << 6,
- CheckAll = CheckMessageType | CheckDetailType | CheckLine | CheckColumn | CheckDataEndsWith
+ CheckType = CheckMessageType | CheckDetailType | CheckLine | CheckColumn | CheckFileEndsWith
};
- void connect(bool block, const QString &testFile, bool restrictServices = true);
+ ConnectResult connect(bool block, const QString &testFile, bool recordFromStart = true,
+ uint flushInterval = 0, bool restrictServices = true);
+ void checkProcessTerminated();
void checkTraceReceived();
void checkJsHeap();
- bool verify(MessageListType type, int expectedPosition, const QQmlProfilerData &expected,
- quint32 checks);
+ bool verify(MessageListType type, int expectedPosition,
+ const QQmlProfilerEventType &expectedType, quint32 checks,
+ const QVector<qint64> &numbers);
+
+ QList<QQmlDebugClient *> createClients() override;
+ QScopedPointer<QQmlProfilerTestClient> m_client;
private slots:
- void cleanup();
+ void cleanup() override;
void connect_data();
void connect();
@@ -312,55 +219,69 @@ private slots:
void signalSourceLocation();
void javascript();
void flushInterval();
+ void translationBinding();
void memory();
+
+private:
+ bool m_recordFromStart = true;
+ bool m_flushInterval = 0;
+ bool m_isComplete = false;
+
+ // Don't use ({...}) here as MSVC will interpret that as the "QVector(int size)" ctor.
+ const QVector<qint64> m_rangeStart = (QVector<qint64>() << QQmlProfilerDefinitions::RangeStart);
+ const QVector<qint64> m_rangeEnd = (QVector<qint64>() << QQmlProfilerDefinitions::RangeEnd);
};
-#define VERIFY(type, position, expected, checks) QVERIFY(verify(type, position, expected, checks))
+#define VERIFY(type, position, expected, checks, numbers) \
+ QVERIFY(verify(type, position, expected, checks, numbers))
-void tst_QQmlProfilerService::connect(bool block, const QString &testFile, bool restrictServices)
+QQmlDebugTest::ConnectResult tst_QQmlProfilerService::connect(
+ bool block, const QString &file, bool recordFromStart, uint flushInterval,
+ bool restrictServices)
{
+ m_recordFromStart = recordFromStart;
+ m_flushInterval = flushInterval;
+ m_isComplete = false;
+
// ### Still using qmlscene due to QTBUG-33377
- const QString executable = QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene";
- QStringList arguments;
- arguments << QString::fromLatin1("-qmljsdebugger=port:%1,%2%3%4")
- .arg(STR_PORT_FROM).arg(STR_PORT_TO)
- .arg(block ? QStringLiteral(",block") : QString())
- .arg(restrictServices ? QStringLiteral(",services:CanvasFrameRate") : QString())
- << QQmlDataTest::instance()->testFile(testFile);
-
- m_process = new QQmlDebugProcess(executable, this);
- m_process->start(QStringList() << arguments);
- QVERIFY2(m_process->waitForSessionStart(), "Could not launch application, or did not get 'Waiting for connection'.");
-
- m_connection = new QQmlDebugConnection();
- m_client = new QQmlProfilerTestClient(m_connection);
- QList<QQmlDebugClient *> others = QQmlDebugTest::createOtherClients(m_connection);
-
- const int port = m_process->debugPort();
- m_connection->connectToHost(QLatin1String("127.0.0.1"), port);
- QVERIFY(m_client);
- QTRY_COMPARE(m_client->state(), QQmlDebugClient::Enabled);
+ return QQmlDebugTest::connect(
+ QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene",
+ restrictServices ? QQmlDebuggingEnabler::profilerServices().join(',') : QString(),
+ testFile(file), block);
+}
- foreach (QQmlDebugClient *other, others)
- QCOMPARE(other->state(), restrictServices ? QQmlDebugClient::Unavailable :
- QQmlDebugClient::Enabled);
- qDeleteAll(others);
+void tst_QQmlProfilerService::checkProcessTerminated()
+{
+ // If the process ends before connect(), we get a non-success value from connect()
+ // That's not a problem as we will still receive the trace. We check that process has terminated
+ // cleanly here.
+
+ // Wait for the process to finish by itself, if that hasn't happened already
+ QVERIFY(m_client);
+ QVERIFY(m_client->client);
+ QTRY_COMPARE(m_client->client->state(), QQmlDebugClient::NotConnected);
+ QVERIFY(m_process);
+ QTRY_COMPARE(m_process->exitStatus(), QProcess::NormalExit);
}
void tst_QQmlProfilerService::checkTraceReceived()
{
- QVERIFY2(QQmlDebugTest::waitForSignal(m_client, SIGNAL(recordingFinished())),
- "No trace received in time.");
+ QTRY_VERIFY2(m_isComplete, "No trace received in time.");
+
+ QVector<qint64> numbers;
// must start with "StartTrace"
- QQmlProfilerData expected(0, QQmlProfilerDefinitions::Event,
- QQmlProfilerDefinitions::StartTrace);
- VERIFY(MessageListAsynchronous, 0, expected, CheckMessageType | CheckDetailType);
+ QQmlProfilerEventType expected(QQmlProfilerDefinitions::Event,
+ QQmlProfilerDefinitions::MaximumRangeType,
+ QQmlProfilerDefinitions::StartTrace);
+ VERIFY(MessageListAsynchronous, 0, expected, CheckMessageType | CheckDetailType, numbers);
// must end with "EndTrace"
- expected.detailType = QQmlProfilerDefinitions::EndTrace;
+ expected = QQmlProfilerEventType(QQmlProfilerDefinitions::Event,
+ QQmlProfilerDefinitions::MaximumRangeType,
+ QQmlProfilerDefinitions::EndTrace);
VERIFY(MessageListAsynchronous, m_client->asynchronousMessages.length() - 1, expected,
- CheckMessageType | CheckDetailType);
+ CheckMessageType | CheckDetailType, numbers);
}
void tst_QQmlProfilerService::checkJsHeap()
@@ -373,33 +294,35 @@ void tst_QQmlProfilerService::checkJsHeap()
qint64 allocated = 0;
qint64 used = 0;
qint64 lastTimestamp = -1;
- foreach (const QQmlProfilerData &message, m_client->jsHeapMessages) {
- switch (message.detailType) {
+ foreach (const QQmlProfilerEvent &message, m_client->jsHeapMessages) {
+ const qint64 amount = message.number<qint64>(0);
+ const QQmlProfilerEventType &type = m_client->types.at(message.typeIndex());
+ switch (type.detailType()) {
case QV4::Profiling::HeapPage:
- allocated += message.amount;
+ allocated += amount;
seen_alloc = true;
break;
case QV4::Profiling::SmallItem:
- used += message.amount;
+ used += amount;
seen_small = true;
break;
case QV4::Profiling::LargeItem:
- allocated += message.amount;
- used += message.amount;
+ allocated += amount;
+ used += amount;
seen_large = true;
break;
}
- QVERIFY(message.time >= lastTimestamp);
+ QVERIFY(message.timestamp() >= lastTimestamp);
// The heap will only be consistent after all events of the same timestamp are processed.
if (lastTimestamp == -1) {
- lastTimestamp = message.time;
+ lastTimestamp = message.timestamp();
continue;
- } else if (message.time == lastTimestamp) {
+ } else if (message.timestamp() == lastTimestamp) {
continue;
}
- lastTimestamp = message.time;
+ lastTimestamp = message.timestamp();
QVERIFY2(used >= 0, QString::fromLatin1("Negative memory usage seen: %1")
.arg(used).toUtf8().constData());
@@ -418,10 +341,10 @@ void tst_QQmlProfilerService::checkJsHeap()
}
bool tst_QQmlProfilerService::verify(tst_QQmlProfilerService::MessageListType type,
- int expectedPosition, const QQmlProfilerData &expected,
- quint32 checks)
+ int expectedPosition, const QQmlProfilerEventType &expected,
+ quint32 checks, const QVector<qint64> &expectedNumbers)
{
- QVector<QQmlProfilerData> *target = 0;
+ const QVector<QQmlProfilerEvent> *target = 0;
switch (type) {
case MessageListQML: target = &(m_client->qmlMessages); break;
case MessageListJavaScript: target = &(m_client->javascriptMessages); break;
@@ -437,41 +360,81 @@ bool tst_QQmlProfilerService::verify(tst_QQmlProfilerService::MessageListType ty
}
uint position = expectedPosition;
- qint64 timestamp = target->at(expectedPosition).time;
- while (position > 0 && target->at(position - 1).time == timestamp)
+ qint64 timestamp = target->at(expectedPosition).timestamp();
+ while (position > 0 && target->at(position - 1).timestamp() == timestamp)
--position;
QStringList warnings;
do {
- const QQmlProfilerData &actual = target->at(position);
- if ((checks & CheckMessageType) && actual.messageType != expected.messageType) {
- warnings << QString::fromLatin1("%1: unexpected messageType. actual: %2 - expected: %3")
- .arg(position).arg(actual.messageType).arg(expected.messageType);
+ const QQmlProfilerEvent &event = target->at(position);
+ const QQmlProfilerEventType &actual = m_client->types.at(event.typeIndex());
+ if ((checks & CheckMessageType) &&
+ (actual.message() != expected.message()
+ || actual.rangeType() != expected.rangeType())) {
+ warnings << QString::fromLatin1("%1: unexpected messageType or rangeType. "
+ "actual: %2, %3 - expected: %4, %5")
+ .arg(position).arg(actual.message()).arg(actual.rangeType())
+ .arg(expected.message()).arg(expected.rangeType());
continue;
}
- if ((checks & CheckDetailType) && actual.detailType != expected.detailType) {
+ if ((checks & CheckDetailType) && actual.detailType() != expected.detailType()) {
warnings << QString::fromLatin1("%1: unexpected detailType. actual: %2 - expected: %3")
- .arg(position).arg(actual.detailType).arg(expected.detailType);
+ .arg(position).arg(actual.detailType()).arg(expected.detailType());
continue;
}
- if ((checks & CheckLine) && actual.line != expected.line) {
+
+ const QQmlProfilerEventLocation expectedLocation = expected.location();
+ const QQmlProfilerEventLocation actualLocation = actual.location();
+
+ if ((checks & CheckLine) && actualLocation.line() != expectedLocation.line()) {
warnings << QString::fromLatin1("%1: unexpected line. actual: %2 - expected: %3")
- .arg(position).arg(actual.line).arg(expected.line);
+ .arg(position).arg(actualLocation.line())
+ .arg(expectedLocation.line());
continue;
}
- if ((checks & CheckColumn) && actual.column != expected.column) {
+ if ((checks & CheckColumn) && actualLocation.column() != expectedLocation.column()) {
warnings << QString::fromLatin1("%1: unexpected column. actual: %2 - expected: %3")
- .arg(position).arg(actual.column).arg(expected.column);
+ .arg(position).arg(actualLocation.column())
+ .arg(expectedLocation.column());
+ continue;
+ }
+ if ((checks & CheckFileEndsWith) &&
+ !actualLocation.filename().endsWith(expectedLocation.filename())) {
+ warnings << QString::fromLatin1("%1: unexpected fileName. actual: %2 - expected: %3")
+ .arg(position).arg(actualLocation.filename())
+ .arg(expectedLocation.filename());
continue;
}
- if ((checks & CheckDataEndsWith) && !actual.detailData.endsWith(expected.detailData)) {
+
+ if ((checks & CheckDataEndsWith) && !actual.data().endsWith(expected.data())) {
warnings << QString::fromLatin1("%1: unexpected detailData. actual: %2 - expected: %3")
- .arg(position).arg(actual.detailData).arg(expected.detailData);
+ .arg(position).arg(actual.data()).arg(expected.data());
continue;
}
+
+ if (checks & CheckNumbers) {
+ const QVector<qint64> actualNumbers = event.numbers<QVector<qint64>>();
+ if (actualNumbers != expectedNumbers) {
+
+ QStringList expectedList;
+ for (qint64 number : expectedNumbers)
+ expectedList.append(QString::number(number));
+ QStringList actualList;
+ for (qint64 number : actualNumbers)
+ actualList.append(QString::number(number));
+
+ warnings << QString::fromLatin1(
+ "%1: unexpected numbers. actual [%2] - expected: [%3]")
+ .arg(position)
+ .arg(actualList.join(QLatin1String(", ")))
+ .arg(expectedList.join(QLatin1String(", ")));
+ continue;
+ }
+ }
+
return true;
- } while (target->at(++position).time == timestamp);
+ } while (target->at(++position).timestamp() == timestamp);
foreach (const QString &message, warnings)
qWarning() << message.toLocal8Bit().constData();
@@ -479,54 +442,62 @@ bool tst_QQmlProfilerService::verify(tst_QQmlProfilerService::MessageListType ty
return false;
}
+QList<QQmlDebugClient *> tst_QQmlProfilerService::createClients()
+{
+ m_client.reset(new QQmlProfilerTestClient(m_connection));
+ m_client->client->setRecording(m_recordFromStart);
+ m_client->client->setFlushInterval(m_flushInterval);
+ QObject::connect(m_client->client, &QQmlProfilerClient::complete,
+ this, [this](){ m_isComplete = true; });
+ return QList<QQmlDebugClient *>({m_client->client});
+}
+
void tst_QQmlProfilerService::cleanup()
{
+ auto log = [this](const QQmlProfilerEvent &data, int i) {
+ const QQmlProfilerEventType &type = m_client->types.at(data.typeIndex());
+ const QQmlProfilerEventLocation location = type.location();
+ qDebug() << i << data.timestamp() << type.message() << type.rangeType() << type.detailType()
+ << location.filename() << location.line() << location.column()
+ << data.numbers<QVector<qint64>>();
+ };
+
if (m_client && QTest::currentTestFailed()) {
qDebug() << "QML Messages:" << m_client->qmlMessages.count();
int i = 0;
- foreach (const QQmlProfilerData &data, m_client->qmlMessages) {
- qDebug() << i++ << data.time << data.messageType << data.detailType << data.detailData
- << data.line << data.column;
- }
+ for (const QQmlProfilerEvent &data : qAsConst(m_client->qmlMessages))
+ log(data, i++);
+
qDebug() << " ";
qDebug() << "JavaScript Messages:" << m_client->javascriptMessages.count();
i = 0;
- foreach (const QQmlProfilerData &data, m_client->javascriptMessages) {
- qDebug() << i++ << data.time << data.messageType << data.detailType << data.detailData
- << data.line << data.column;
- }
+
+ for (const QQmlProfilerEvent &data : qAsConst(m_client->javascriptMessages))
+ log(data, i++);
+
qDebug() << " ";
qDebug() << "Asynchronous Messages:" << m_client->asynchronousMessages.count();
i = 0;
- foreach (const QQmlProfilerData &data, m_client->asynchronousMessages) {
- qDebug() << i++ << data.time << data.messageType << data.detailType << data.detailData
- << data.framerate << data.animationcount << data.line << data.column;
- }
+ for (const QQmlProfilerEvent &data : qAsConst(m_client->asynchronousMessages))
+ log(data, i++);
+
qDebug() << " ";
qDebug() << "Pixmap Cache Messages:" << m_client->pixmapMessages.count();
i = 0;
- foreach (const QQmlProfilerData &data, m_client->pixmapMessages) {
- qDebug() << i++ << data.time << data.messageType << data.detailType << data.detailData
- << data.line << data.column;
- }
+ for (const QQmlProfilerEvent &data : qAsConst(m_client->pixmapMessages))
+ log(data, i++);
+
qDebug() << " ";
qDebug() << "Javascript Heap Messages:" << m_client->jsHeapMessages.count();
i = 0;
- foreach (const QQmlProfilerData &data, m_client->jsHeapMessages) {
- qDebug() << i++ << data.time << data.messageType << data.detailType;
- }
+ for (const QQmlProfilerEvent &data : qAsConst(m_client->jsHeapMessages))
+ log(data, i++);
+
qDebug() << " ";
- qDebug() << "Process State:" << (m_process ? m_process->state() : QLatin1String("null"));
- qDebug() << "Application Output:" << (m_process ? m_process->output() : QLatin1String("null"));
- qDebug() << "Connection State:" << QQmlDebugTest::connectionStateString(m_connection);
- qDebug() << "Client State:" << QQmlDebugTest::clientStateString(m_client);
}
- delete m_process;
- m_process = 0;
- delete m_client;
- m_client = 0;
- delete m_connection;
- m_connection = 0;
+
+ m_client.reset();
+ QQmlDebugTest::cleanup();
}
void tst_QQmlProfilerService::connect_data()
@@ -550,67 +521,62 @@ void tst_QQmlProfilerService::connect()
QFETCH(bool, restrictMode);
QFETCH(bool, traceEnabled);
- connect(blockMode, "test.qml", restrictMode);
+ QCOMPARE(connect(blockMode, "test.qml", traceEnabled, 0, restrictMode), ConnectSuccess);
- // if the engine is waiting, then the first message determines if it starts with trace enabled
if (!traceEnabled)
- m_client->sendRecordingStatus(false);
- m_client->sendRecordingStatus(true);
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(true);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
}
void tst_QQmlProfilerService::pixmapCacheData()
{
- connect(true, "pixmapCacheTest.qml");
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
- m_client->sendRecordingStatus(true);
- QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
+ QCOMPARE(connect(true, "pixmapCacheTest.qml"), ConnectSuccess);
+ // Don't wait for readyReadStandardOutput before the loop. It may have already arrived.
while (m_process->output().indexOf(QLatin1String("image loaded")) == -1 &&
m_process->output().indexOf(QLatin1String("image error")) == -1)
QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
- QQmlProfilerData expected(0, QQmlProfilerDefinitions::PixmapCacheEvent);
+ auto createType = [](QQmlProfilerDefinitions::PixmapEventType type) {
+ return QQmlProfilerEventType(QQmlProfilerDefinitions::PixmapCacheEvent,
+ QQmlProfilerDefinitions::MaximumRangeType, type);
+ };
+
+ QVector<qint64> numbers;
// image starting to load
- expected.detailType = QQmlProfilerDefinitions::PixmapLoadingStarted;
- VERIFY(MessageListPixmap, 0, expected, CheckMessageType | CheckDetailType);
+ VERIFY(MessageListPixmap, 0, createType(QQmlProfilerDefinitions::PixmapLoadingStarted),
+ CheckMessageType | CheckDetailType, numbers);
// image size
- expected.detailType = QQmlProfilerDefinitions::PixmapSizeKnown;
- expected.line = expected.column = 2; // width and height, in fact
- VERIFY(MessageListPixmap, 1, expected,
- CheckMessageType | CheckDetailType | CheckLine | CheckColumn);
+ numbers = QVector<qint64>({2, 2, 1});
+ VERIFY(MessageListPixmap, 1, createType(QQmlProfilerDefinitions::PixmapSizeKnown),
+ CheckMessageType | CheckDetailType | CheckNumbers, numbers);
// image loaded
- expected.detailType = QQmlProfilerDefinitions::PixmapLoadingFinished;
- VERIFY(MessageListPixmap, 2, expected, CheckMessageType | CheckDetailType);
+ VERIFY(MessageListPixmap, 2, createType(QQmlProfilerDefinitions::PixmapLoadingFinished),
+ CheckMessageType | CheckDetailType, numbers);
// cache size
- expected.detailType = QQmlProfilerDefinitions::PixmapCacheCountChanged;
- VERIFY(MessageListPixmap, 3, expected, CheckMessageType | CheckDetailType);
+ VERIFY(MessageListPixmap, 3, createType(QQmlProfilerDefinitions::PixmapCacheCountChanged),
+ CheckMessageType | CheckDetailType, numbers);
}
void tst_QQmlProfilerService::scenegraphData()
{
- connect(true, "scenegraphTest.qml");
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
-
- m_client->sendRecordingStatus(true);
+ QCOMPARE(connect(true, "scenegraphTest.qml"), ConnectSuccess);
while (!m_process->output().contains(QLatin1String("tick")))
QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
@@ -625,34 +591,39 @@ void tst_QQmlProfilerService::scenegraphData()
qint64 contextFrameTime = -1;
qint64 renderFrameTime = -1;
#if QT_CONFIG(opengl) //Software renderer doesn't have context frames
- foreach (const QQmlProfilerData &msg, m_client->asynchronousMessages) {
- if (msg.messageType == QQmlProfilerDefinitions::SceneGraphFrame) {
- if (msg.detailType == QQmlProfilerDefinitions::SceneGraphContextFrame) {
- contextFrameTime = msg.time;
- break;
+ if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) {
+ foreach (const QQmlProfilerEvent &msg, m_client->asynchronousMessages) {
+ const QQmlProfilerEventType &type = m_client->types.at(msg.typeIndex());
+ if (type.message() == QQmlProfilerDefinitions::SceneGraphFrame) {
+ if (type.detailType() == QQmlProfilerDefinitions::SceneGraphContextFrame) {
+ contextFrameTime = msg.timestamp();
+ break;
+ }
}
}
- }
- QVERIFY(contextFrameTime != -1);
+ QVERIFY(contextFrameTime != -1);
+ }
#endif
- foreach (const QQmlProfilerData &msg, m_client->asynchronousMessages) {
- if (msg.detailType == QQmlProfilerDefinitions::SceneGraphRendererFrame) {
- QVERIFY(msg.time >= contextFrameTime);
- renderFrameTime = msg.time;
+ foreach (const QQmlProfilerEvent &msg, m_client->asynchronousMessages) {
+ const QQmlProfilerEventType &type = m_client->types.at(msg.typeIndex());
+ if (type.detailType() == QQmlProfilerDefinitions::SceneGraphRendererFrame) {
+ QVERIFY(msg.timestamp() >= contextFrameTime);
+ renderFrameTime = msg.timestamp();
break;
}
}
QVERIFY(renderFrameTime != -1);
- foreach (const QQmlProfilerData &msg, m_client->asynchronousMessages) {
- if (msg.detailType == QQmlProfilerDefinitions::SceneGraphRenderLoopFrame) {
- if (msg.time >= contextFrameTime) {
+ foreach (const QQmlProfilerEvent &msg, m_client->asynchronousMessages) {
+ const QQmlProfilerEventType &type = m_client->types.at(msg.typeIndex());
+ if (type.detailType() == QQmlProfilerDefinitions::SceneGraphRenderLoopFrame) {
+ if (msg.timestamp() >= contextFrameTime) {
// Make sure SceneGraphRenderLoopFrame is not between SceneGraphContextFrame and
// SceneGraphRendererFrame. A SceneGraphRenderLoopFrame before everything else is
// OK as the scene graph might decide to do an initial rendering.
- QVERIFY(msg.time >= renderFrameTime);
+ QVERIFY(msg.timestamp() >= renderFrameTime);
break;
}
}
@@ -662,10 +633,7 @@ void tst_QQmlProfilerService::scenegraphData()
void tst_QQmlProfilerService::profileOnExit()
{
connect(true, "exit.qml");
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
-
- m_client->sendRecordingStatus(true);
+ checkProcessTerminated();
checkTraceReceived();
checkJsHeap();
@@ -673,104 +641,108 @@ void tst_QQmlProfilerService::profileOnExit()
void tst_QQmlProfilerService::controlFromJS()
{
- connect(true, "controlFromJS.qml");
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(connect(true, "controlFromJS.qml", false), ConnectSuccess);
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
}
void tst_QQmlProfilerService::signalSourceLocation()
{
- connect(true, "signalSourceLocation.qml");
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(connect(true, "signalSourceLocation.qml"), ConnectSuccess);
- m_client->sendRecordingStatus(true);
while (!(m_process->output().contains(QLatin1String("500"))))
QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
- QQmlProfilerData expected(0, QQmlProfilerDefinitions::RangeLocation,
- QQmlProfilerDefinitions::HandlingSignal,
- QLatin1String("signalSourceLocation.qml"));
- expected.line = 8;
- expected.column = 28;
- VERIFY(MessageListQML, 9, expected, CheckAll);
+ auto createType = [](int line, int column) {
+ return QQmlProfilerEventType(
+ QQmlProfilerDefinitions::MaximumMessage,
+ QQmlProfilerDefinitions::HandlingSignal, -1,
+ QQmlProfilerEventLocation(QLatin1String("signalSourceLocation.qml"), line,
+ column));
+ };
- expected.line = 7;
- expected.column = 21;
- VERIFY(MessageListQML, 11, expected, CheckAll);
+ VERIFY(MessageListQML, 4, createType(8, 28), CheckType | CheckNumbers, m_rangeStart);
+ VERIFY(MessageListQML, 6, createType(7, 21), CheckType | CheckNumbers, m_rangeEnd);
}
void tst_QQmlProfilerService::javascript()
{
- connect(true, "javascript.qml");
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
+ QCOMPARE(connect(true, "javascript.qml"), ConnectSuccess);
- m_client->sendRecordingStatus(true);
while (!(m_process->output().contains(QLatin1String("done"))))
QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
- QQmlProfilerData expected(0, QQmlProfilerDefinitions::RangeStart,
- QQmlProfilerDefinitions::Javascript);
- VERIFY(MessageListJavaScript, 6, expected, CheckMessageType | CheckDetailType);
+ VERIFY(MessageListJavaScript, 2, QQmlProfilerEventType(QQmlProfilerDefinitions::MaximumMessage,
+ QQmlProfilerDefinitions::Javascript),
+ CheckMessageType | CheckDetailType | CheckNumbers, m_rangeStart);
- expected.messageType = QQmlProfilerDefinitions::RangeLocation;
- expected.detailData = QLatin1String("javascript.qml");
- expected.line = 4;
- expected.column = 5;
- VERIFY(MessageListJavaScript, 7, expected, CheckAll);
+ VERIFY(MessageListJavaScript, 3,
+ QQmlProfilerEventType(QQmlProfilerDefinitions::MaximumMessage,
+ QQmlProfilerDefinitions::Javascript, -1,
+ QQmlProfilerEventLocation(QLatin1String("javascript.qml"), 4, 5)),
+ CheckType | CheckNumbers, m_rangeStart);
- expected.messageType = QQmlProfilerDefinitions::RangeData;
- expected.detailData = QLatin1String("something");
- VERIFY(MessageListJavaScript, 8, expected,
- CheckMessageType | CheckDetailType | CheckDataEndsWith);
+ VERIFY(MessageListJavaScript, 4, QQmlProfilerEventType(
+ QQmlProfilerDefinitions::MaximumMessage, QQmlProfilerDefinitions::Javascript, -1,
+ QQmlProfilerEventLocation(), QLatin1String("something")),
+ CheckMessageType | CheckDetailType | CheckDataEndsWith | CheckNumbers, m_rangeStart);
- expected.messageType = QQmlProfilerDefinitions::RangeEnd;
- VERIFY(MessageListJavaScript, 21, expected, CheckMessageType | CheckDetailType);
+ VERIFY(MessageListJavaScript, 10, QQmlProfilerEventType(QQmlProfilerDefinitions::MaximumMessage,
+ QQmlProfilerDefinitions::Javascript),
+ CheckMessageType | CheckDetailType | CheckNumbers, m_rangeEnd);
}
void tst_QQmlProfilerService::flushInterval()
{
- connect(true, "timer.qml");
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
-
- m_client->sendRecordingStatus(true, -1, 1);
+ QCOMPARE(connect(true, "timer.qml", true, 1), ConnectSuccess);
// Make sure we get multiple messages
QTRY_VERIFY(m_client->qmlMessages.length() > 0);
QVERIFY(m_client->qmlMessages.length() < 100);
QTRY_VERIFY(m_client->qmlMessages.length() > 100);
- m_client->sendRecordingStatus(false);
+ m_client->client->setRecording(false);
checkTraceReceived();
checkJsHeap();
}
+void tst_QQmlProfilerService::translationBinding()
+{
+ connect(true, "qstr.qml");
+ checkProcessTerminated();
+
+ checkTraceReceived();
+ checkJsHeap();
+
+ const QQmlProfilerEventType type(QQmlProfilerDefinitions::MaximumMessage,
+ QQmlProfilerDefinitions::Binding);
+
+ VERIFY(MessageListQML, 4, type, CheckDetailType | CheckMessageType | CheckNumbers,
+ m_rangeStart);
+ VERIFY(MessageListQML, 5, type, CheckDetailType | CheckMessageType | CheckNumbers,
+ m_rangeEnd);
+}
+
void tst_QQmlProfilerService::memory()
{
connect(true, "memory.qml");
- if (QTest::currentTestFailed() || QTestResult::skipCurrentTest())
- return;
-
- m_client->sendRecordingStatus(true);
+ checkProcessTerminated();
checkTraceReceived();
checkJsHeap();
int smallItems = 0;
for (auto message : m_client->jsHeapMessages) {
- if (message.detailType == QV4::Profiling::SmallItem)
+ const QQmlProfilerEventType &type = m_client->types[message.typeIndex()];
+ if (type.detailType() == QV4::Profiling::SmallItem)
++smallItems;
}
diff --git a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
index 441f8c113f..b569ad6b3c 100644
--- a/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
+++ b/tests/auto/qml/debugger/qv4debugger/tst_qv4debugger.cpp
@@ -38,7 +38,6 @@
#include <private/qv4debugging_p.h>
#include <private/qv8engine_p.h>
#include <private/qv4objectiterator_p.h>
-#include <private/qv4isel_moth_p.h>
#include <private/qv4string_p.h>
#include <private/qqmlbuiltinfunctions_p.h>
#include <private/qqmldebugservice_p.h>
@@ -46,7 +45,7 @@
using namespace QV4;
using namespace QV4::Debugging;
-typedef void (*InjectedFunction)(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+typedef QV4::ReturnedValue (*InjectedFunction)(const FunctionObject *b, const QV4::Value *, const QV4::Value *, int);
Q_DECLARE_METATYPE(InjectedFunction)
static bool waitForSignal(QObject* obj, const char* signal, int timeout = 10000)
@@ -79,7 +78,7 @@ public:
emit evaluateFinished();
}
- QV4::ExecutionEngine *v4Engine() { return QV8Engine::getV4(this); }
+ QV4::ExecutionEngine *v4Engine() { return handle(); }
Q_INVOKABLE void injectFunction(const QString &functionName, InjectedFunction injectedFunction)
{
@@ -88,7 +87,7 @@ public:
QV4::ScopedString name(scope, v4->newString(functionName));
QV4::ScopedContext ctx(scope, v4->rootContext());
- QV4::ScopedValue function(scope, BuiltinFunction::create(ctx, name, injectedFunction));
+ QV4::ScopedValue function(scope, FunctionObject::createBuiltinFunction(ctx, name, injectedFunction));
v4->globalObject->put(name, function);
}
@@ -343,7 +342,6 @@ void tst_qv4debugger::init()
m_javaScriptThread = new QThread;
m_engine = new TestEngine;
m_v4 = m_engine->v4Engine();
- m_v4->iselFactory.reset(new QV4::Moth::ISelFactory);
m_v4->setDebugger(new QV4Debugger(m_v4));
m_engine->moveToThread(m_javaScriptThread);
m_javaScriptThread->start();
@@ -438,9 +436,9 @@ void tst_qv4debugger::addBreakPointWhilePaused()
QCOMPARE(state.lineNumber, 2);
}
-static void someCall(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *)
+static QV4::ReturnedValue someCall(const FunctionObject *function, const QV4::Value *, const QV4::Value *, int)
{
- static_cast<QV4Debugger *>(scope.engine->debugger())
+ static_cast<QV4Debugger *>(function->engine()->debugger())
->removeBreakPoint("removeBreakPointForNextInstruction", 2);
RETURN_UNDEFINED();
}
@@ -464,7 +462,7 @@ void tst_qv4debugger::conditionalBreakPoint()
{
m_debuggerAgent->m_captureContextInfo = true;
QString script =
- "function test() {\n"
+ "var test = function() {\n"
" for (var i = 0; i < 15; ++i) {\n"
" var x = i;\n"
" }\n"
@@ -489,9 +487,8 @@ void tst_qv4debugger::conditionalBreakPoint()
void tst_qv4debugger::conditionalBreakPointInQml()
{
QQmlEngine engine;
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine);
+ QV4::ExecutionEngine *v4 = engine.handle();
QV4Debugger *v4Debugger = new QV4Debugger(v4);
- v4->iselFactory.reset(new QV4::Moth::ISelFactory);
v4->setDebugger(v4Debugger);
QScopedPointer<QThread> debugThread(new QThread);
@@ -531,7 +528,7 @@ void tst_qv4debugger::readArguments()
m_debuggerAgent->m_captureContextInfo = true;
QString script =
- "function f(a, b, c, d) {\n"
+ "var f = function(a, b, c, d) {\n"
" return a === b\n"
"}\n"
"var four;\n"
@@ -557,7 +554,7 @@ void tst_qv4debugger::readLocals()
m_debuggerAgent->m_captureContextInfo = true;
QString script =
- "function f(a, b) {\n"
+ "var f = function(a, b) {\n"
" var c = a + b\n"
" var d = a - b\n" // breakpoint, c should be set, d should be undefined
" return c === d\n"
@@ -583,7 +580,7 @@ void tst_qv4debugger::readObject()
m_debuggerAgent->m_captureContextInfo = true;
QString script =
- "function f(a) {\n"
+ "var f = function(a) {\n"
" var b = a\n"
" return b\n"
"}\n"
@@ -630,7 +627,7 @@ void tst_qv4debugger::readObject()
QCOMPARE(b_tail_head.value("value").toString(), QStringLiteral("asdf"));
QJsonObject b_tail_tail = b_tail_props.at(1).toObject();
QCOMPARE(b_tail_tail.value("name").toString(), QStringLiteral("tail"));
- QCOMPARE(b_tail_tail.value("type").toString(), QStringLiteral("null"));
+ QCOMPARE(b_tail_tail.value("type").toString(), QStringLiteral("object"));
QVERIFY(b_tail_tail.value("value").isNull());
}
@@ -641,7 +638,7 @@ void tst_qv4debugger::readContextInAllFrames()
m_debuggerAgent->m_captureContextInfo = true;
QString script =
- "function fact(n) {\n"
+ "var fact = function(n) {\n"
" if (n > 1) {\n"
" var n_1 = n - 1;\n"
" n_1 = fact(n_1);\n"
@@ -814,13 +811,13 @@ void tst_qv4debugger::lastLineOfConditional_data()
QTest::newRow("do..while {block}") << "do {\n" << "} while (ret < 10);" << 4 << 7;
QTest::newRow("if true {block}") << "if (true) {\n" << "}"
- << 4 << 7;
+ << 4 << 8;
QTest::newRow("if false {block}") << "if (false) {\n" << "}"
<< 2 << 8;
QTest::newRow("if true else {block}") << "if (true) {\n" << "} else {\n ret += 8;\n}"
- << 4 << 7;
+ << 4 << 10;
QTest::newRow("if false else {block}") << "if (false) {\n" << "} else {\n ret += 8;\n}"
- << 8 << 9;
+ << 8 << 10;
QTest::newRow("for statement") << "for (var i = 0; i < 10; ++i)\n" << "" << 4 << 2;
QTest::newRow("for..in statement") << "for (var i in [0, 1, 2, 3, 4])\n" << "" << 4 << 2;
@@ -829,11 +826,11 @@ void tst_qv4debugger::lastLineOfConditional_data()
// For two nested if statements without blocks, we need to map the jump from the inner to the
// outer one on the outer "if". There is just no better place.
- QTest::newRow("if true statement") << "if (true)\n" << "" << 4 << 2;
+ QTest::newRow("if true statement") << "if (true)\n" << "" << 4 << 8;
QTest::newRow("if false statement") << "if (false)\n" << "" << 2 << 8;
// Also two nested ifs without blocks.
- QTest::newRow("if true else statement") << "if (true)\n" << "else\n ret += 8;" << 4 << 2;
+ QTest::newRow("if true else statement") << "if (true)\n" << "else\n ret += 8;" << 4 << 9;
QTest::newRow("if false else statement") << "if (false)\n" << "else\n ret += 8;" << 8 << 9;
}
diff --git a/tests/auto/qml/debugger/shared/debugutil.cpp b/tests/auto/qml/debugger/shared/debugutil.cpp
index d31efc84cf..8ecbe53822 100644
--- a/tests/auto/qml/debugger/shared/debugutil.cpp
+++ b/tests/auto/qml/debugger/shared/debugutil.cpp
@@ -27,13 +27,14 @@
****************************************************************************/
#include "debugutil_p.h"
+#include "qqmldebugprocess_p.h"
#include <private/qqmldebugconnection_p.h>
+#include <QtQml/qqmldebug.h>
+
#include <QtCore/qeventloop.h>
#include <QtCore/qtimer.h>
-#include <QtCore/qfileinfo.h>
-#include <QtCore/qdir.h>
bool QQmlDebugTest::waitForSignal(QObject *receiver, const char *member, int timeout) {
QEventLoop loop;
@@ -116,192 +117,114 @@ void QQmlDebugTestClient::messageReceived(const QByteArray &ba)
emit serverMessage(ba);
}
-QQmlDebugProcess::QQmlDebugProcess(const QString &executable, QObject *parent)
- : QObject(parent)
- , m_executable(executable)
- , m_started(false)
- , m_port(0)
- , m_maximumBindErrors(0)
- , m_receivedBindErrors(0)
-{
- m_process.setProcessChannelMode(QProcess::MergedChannels);
- m_timer.setSingleShot(true);
- m_timer.setInterval(15000);
- connect(&m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(processAppOutput()));
- connect(&m_process, SIGNAL(errorOccurred(QProcess::ProcessError)),
- this, SLOT(processError(QProcess::ProcessError)));
- connect(&m_timer, SIGNAL(timeout()), SLOT(timeout()));
-}
+template<typename F>
+struct Finalizer {
+ F m_lambda;
+ Finalizer(F &&lambda) : m_lambda(std::forward<F>(lambda)) {}
+ ~Finalizer() { m_lambda(); }
+};
-QQmlDebugProcess::~QQmlDebugProcess()
+template<typename F>
+static Finalizer<F> defer(F &&lambda)
{
- stop();
+ return Finalizer<F>(std::forward<F>(lambda));
}
-QString QQmlDebugProcess::state()
+QQmlDebugTest::ConnectResult QQmlDebugTest::connect(
+ const QString &executable, const QString &services, const QString &extraArgs,
+ bool block)
{
- QString stateStr;
- switch (m_process.state()) {
- case QProcess::NotRunning: {
- stateStr = "not running";
- if (m_process.exitStatus() == QProcess::CrashExit)
- stateStr += " (crashed!)";
- else
- stateStr += ", return value " + QString::number(m_process.exitCode());
- break;
- }
- case QProcess::Starting: stateStr = "starting"; break;
- case QProcess::Running: stateStr = "running"; break;
- }
- return stateStr;
-}
+ QStringList arguments;
+ arguments << QString::fromLatin1("-qmljsdebugger=port:13773,13783%3%4")
+ .arg(block ? QStringLiteral(",block") : QString())
+ .arg(services.isEmpty() ? services : (QStringLiteral(",services:") + services))
+ << extraArgs;
-void QQmlDebugProcess::start(const QStringList &arguments)
-{
-#ifdef Q_OS_MAC
- // make sure m_executable points to the actual binary even if it's inside an app bundle
- QFileInfo binFile(m_executable);
- if (!binFile.isExecutable()) {
- QDir bundleDir(m_executable + ".app");
- if (bundleDir.exists()) {
- m_executable = bundleDir.absoluteFilePath("Contents/MacOS/" + binFile.baseName());
- //qDebug() << Q_FUNC_INFO << "found bundled binary" << m_executable;
- }
- }
-#endif
- m_mutex.lock();
- m_port = 0;
- m_process.setEnvironment(QProcess::systemEnvironment() + m_environment);
- m_process.start(m_executable, arguments);
- if (!m_process.waitForStarted()) {
- qWarning() << "QML Debug Client: Could not launch app " << m_executable
- << ": " << m_process.errorString();
- m_eventLoop.quit();
- } else {
- m_timer.start();
- }
- m_mutex.unlock();
-}
+ m_process = createProcess(executable);
+ if (!m_process)
+ return ProcessFailed;
-void QQmlDebugProcess::stop()
-{
- if (m_process.state() != QProcess::NotRunning) {
- m_process.kill();
- m_process.waitForFinished(5000);
- }
-}
+ m_process->start(QStringList() << arguments);
+ if (!m_process->waitForSessionStart())
+ return SessionFailed;
-void QQmlDebugProcess::setMaximumBindErrors(int ignore)
-{
- m_maximumBindErrors = ignore;
-}
+ m_connection = createConnection();
+ if (!m_connection)
+ return ConnectionFailed;
-void QQmlDebugProcess::timeout()
-{
- qWarning() << "Timeout while waiting for QML debugging messages "
- "in application output. Process is in state" << m_process.state() << ", Output:" << m_output << ".";
- m_eventLoop.quit();
-}
+ m_clients = createClients();
+ if (m_clients.contains(nullptr))
+ return ClientsFailed;
-bool QQmlDebugProcess::waitForSessionStart()
-{
- if (m_process.state() != QProcess::Running) {
- qWarning() << "Could not start up " << m_executable;
- return false;
- } else if (m_started) {
+ auto allEnabled = [this]() {
+ for (QQmlDebugClient *client : m_clients) {
+ if (client->state() != QQmlDebugClient::Enabled)
+ return false;
+ }
return true;
+ };
+
+ QList<QQmlDebugClient *> others = createOtherClients(m_connection);
+ auto deleter = defer([&others]() { qDeleteAll(others); });
+ Q_UNUSED(deleter);
+
+ const int port = m_process->debugPort();
+ m_connection->connectToHost(QLatin1String("127.0.0.1"), port);
+ for (int tries = 0; tries < 100 && !allEnabled(); ++tries)
+ QTest::qWait(50);
+ if (!allEnabled())
+ return EnableFailed;
+
+ const QQmlDebugClient::State expectedState = services.isEmpty() ? QQmlDebugClient::Enabled
+ : QQmlDebugClient::Unavailable;
+ for (QQmlDebugClient *other : others) {
+ if (other->state() != expectedState)
+ return RestrictFailed;
}
- m_eventLoop.exec();
-
- return m_started;
+ return ConnectSuccess;
}
-int QQmlDebugProcess::debugPort() const
+QList<QQmlDebugClient *> QQmlDebugTest::createClients()
{
- return m_port;
+ return QList<QQmlDebugClient *>();
}
-bool QQmlDebugProcess::waitForFinished()
+QQmlDebugProcess *QQmlDebugTest::createProcess(const QString &executable)
{
- return m_process.waitForFinished();
+ return new QQmlDebugProcess(executable, this);
}
-QProcess::ExitStatus QQmlDebugProcess::exitStatus() const
+QQmlDebugConnection *QQmlDebugTest::createConnection()
{
- return m_process.exitStatus();
+ return new QQmlDebugConnection(this);
}
-void QQmlDebugProcess::addEnvironment(const QString &environment)
+void QQmlDebugTest::cleanup()
{
- m_environment.append(environment);
-}
+ if (QTest::currentTestFailed()) {
+ const QString null = QStringLiteral("null");
-QString QQmlDebugProcess::output() const
-{
- return m_output;
-}
-
-void QQmlDebugProcess::processAppOutput()
-{
- m_mutex.lock();
-
- bool outputFromAppItself = false;
-
- QString newOutput = m_process.readAll();
- m_output.append(newOutput);
- m_outputBuffer.append(newOutput);
-
- while (true) {
- const int nlIndex = m_outputBuffer.indexOf(QLatin1Char('\n'));
- if (nlIndex < 0) // no further complete lines
- break;
- const QString line = m_outputBuffer.left(nlIndex);
- m_outputBuffer = m_outputBuffer.right(m_outputBuffer.size() - nlIndex - 1);
-
- if (line.contains("QML Debugger:")) {
- const QRegExp portRx("Waiting for connection on port (\\d+)");
- if (portRx.indexIn(line) != -1) {
- m_port = portRx.cap(1).toInt();
- m_timer.stop();
- m_started = true;
- m_eventLoop.quit();
- continue;
- }
- if (line.contains("Unable to listen")) {
- if (++m_receivedBindErrors >= m_maximumBindErrors) {
- if (m_maximumBindErrors == 0)
- qWarning() << "App was unable to bind to port!";
- m_timer.stop();
- m_eventLoop.quit();
- }
- continue;
- }
- } else {
- // set to true if there is output not coming from the debugger
- outputFromAppItself = true;
+ qDebug() << "Process State:" << (m_process ? m_process->state() : null);
+ qDebug() << "Application Output:" << (m_process ? m_process->output() : null);
+ qDebug() << "Connection State:" << QQmlDebugTest::connectionStateString(m_connection);
+ for (QQmlDebugClient *client : m_clients) {
+ if (client)
+ qDebug() << client->name() << "State:" << QQmlDebugTest::clientStateString(client);
+ else
+ qDebug() << "Failed Client:" << null;
}
}
- m_mutex.unlock();
- if (outputFromAppItself)
- emit readyReadStandardOutput();
-}
+ qDeleteAll(m_clients);
+ m_clients.clear();
-void QQmlDebugProcess::processError(QProcess::ProcessError error)
-{
- if (!m_eventLoop.isRunning())
- return;
-
- qDebug() << "An error occurred while waiting for debug process to become available:";
- switch (error) {
- case QProcess::FailedToStart: qDebug() << "Process failed to start."; break;
- case QProcess::Crashed: qDebug() << "Process crashed."; break;
- case QProcess::Timedout: qDebug() << "Process timed out."; break;
- case QProcess::WriteError: qDebug() << "Error while writing to process."; break;
- case QProcess::ReadError: qDebug() << "Error while reading from process."; break;
- case QProcess::UnknownError: qDebug() << "Unknown process error."; break;
- }
+ delete m_connection;
+ m_connection = nullptr;
- m_eventLoop.exit();
+ if (m_process) {
+ m_process->stop();
+ delete m_process;
+ m_process = nullptr;
+ }
}
diff --git a/tests/auto/qml/debugger/shared/debugutil.pri b/tests/auto/qml/debugger/shared/debugutil.pri
index 1983f3583e..13dcdb91d8 100644
--- a/tests/auto/qml/debugger/shared/debugutil.pri
+++ b/tests/auto/qml/debugger/shared/debugutil.pri
@@ -1,4 +1,11 @@
QT += qmldebug-private
-HEADERS += $$PWD/debugutil_p.h
-SOURCES += $$PWD/debugutil.cpp
+INCLUDEPATH += $$PWD
+include($$PWD/../../../shared/util.pri)
+
+HEADERS += \
+ $$PWD/debugutil_p.h \
+ $$PWD/qqmldebugprocess_p.h
+SOURCES += \
+ $$PWD/debugutil.cpp \
+ $$PWD/qqmldebugprocess.cpp
diff --git a/tests/auto/qml/debugger/shared/debugutil_p.h b/tests/auto/qml/debugger/shared/debugutil_p.h
index 1ec0a6513d..94ad83bfce 100644
--- a/tests/auto/qml/debugger/shared/debugutil_p.h
+++ b/tests/auto/qml/debugger/shared/debugutil_p.h
@@ -1,4 +1,3 @@
-
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
@@ -41,23 +40,43 @@
// We mean it.
//
+#include <../../../shared/util.h>
#include <private/qqmldebugclient_p.h>
-#include <QtCore/qeventloop.h>
-#include <QtCore/qtimer.h>
-#include <QtCore/qthread.h>
-#include <QtCore/qprocess.h>
-#include <QtCore/qmutex.h>
-#include <QtTest/qtest.h>
-#include <QtQml/qqmlengine.h>
-
-class QQmlDebugTest
+class QQmlDebugProcess;
+class QQmlDebugTest : public QQmlDataTest
{
+ Q_OBJECT
public:
static bool waitForSignal(QObject *receiver, const char *member, int timeout = 5000);
static QList<QQmlDebugClient *> createOtherClients(QQmlDebugConnection *connection);
static QString clientStateString(const QQmlDebugClient *client);
static QString connectionStateString(const QQmlDebugConnection *connection);
+
+protected:
+ enum ConnectResult {
+ ConnectSuccess,
+ ProcessFailed,
+ SessionFailed,
+ ConnectionFailed,
+ ClientsFailed,
+ EnableFailed,
+ RestrictFailed
+ };
+
+ ConnectResult connect(const QString &executable, const QString &services,
+ const QString &extraArgs, bool block);
+
+ virtual QQmlDebugProcess *createProcess(const QString &executable);
+ virtual QQmlDebugConnection *createConnection();
+ virtual QList<QQmlDebugClient *> createClients();
+
+ QQmlDebugProcess *m_process = nullptr;
+ QQmlDebugConnection *m_connection = nullptr;
+ QList<QQmlDebugClient *> m_clients;
+
+protected slots:
+ virtual void cleanup();
};
class QQmlDebugTestClient : public QQmlDebugClient
@@ -80,51 +99,6 @@ private:
QByteArray lastMsg;
};
-class QQmlDebugProcess : public QObject
-{
- Q_OBJECT
-public:
- QQmlDebugProcess(const QString &executable, QObject *parent = 0);
- ~QQmlDebugProcess();
-
- QString state();
-
- void addEnvironment(const QString &environment);
-
- void start(const QStringList &arguments);
- bool waitForSessionStart();
- int debugPort() const;
-
- bool waitForFinished();
- QProcess::ExitStatus exitStatus() const;
-
- QString output() const;
- void stop();
- void setMaximumBindErrors(int numErrors);
-
-signals:
- void readyReadStandardOutput();
-
-private slots:
- void timeout();
- void processAppOutput();
- void processError(QProcess::ProcessError error);
-
-private:
- QString m_executable;
- QProcess m_process;
- QString m_outputBuffer;
- QString m_output;
- QTimer m_timer;
- QEventLoop m_eventLoop;
- QMutex m_mutex;
- bool m_started;
- QStringList m_environment;
- int m_port;
- int m_maximumBindErrors;
- int m_receivedBindErrors;
-};
-
class QQmlInspectorResultRecipient : public QObject
{
Q_OBJECT
diff --git a/tests/auto/qml/debugger/shared/qqmldebugprocess.cpp b/tests/auto/qml/debugger/shared/qqmldebugprocess.cpp
new file mode 100644
index 0000000000..201a6b1a76
--- /dev/null
+++ b/tests/auto/qml/debugger/shared/qqmldebugprocess.cpp
@@ -0,0 +1,245 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qqmldebugprocess_p.h"
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qfileinfo.h>
+#include <QtCore/qdir.h>
+
+QQmlDebugProcess::QQmlDebugProcess(const QString &executable, QObject *parent)
+ : QObject(parent)
+ , m_executable(executable)
+ , m_state(SessionUnknown)
+ , m_port(0)
+ , m_maximumBindErrors(0)
+ , m_receivedBindErrors(0)
+{
+ m_process.setProcessChannelMode(QProcess::MergedChannels);
+ m_timer.setSingleShot(true);
+ m_timer.setInterval(15000);
+ connect(&m_process, &QProcess::readyReadStandardOutput,
+ this, &QQmlDebugProcess::processAppOutput);
+ connect(&m_process, &QProcess::errorOccurred,
+ this, &QQmlDebugProcess::processError);
+ connect(&m_process, QOverload<int>::of(&QProcess::finished),
+ this, [this]() {
+ m_timer.stop();
+ m_eventLoop.quit();
+ });
+ connect(&m_timer, &QTimer::timeout,
+ this, &QQmlDebugProcess::timeout);
+}
+
+QQmlDebugProcess::~QQmlDebugProcess()
+{
+ stop();
+}
+
+QString QQmlDebugProcess::state()
+{
+ QString stateStr;
+ switch (m_process.state()) {
+ case QProcess::NotRunning: {
+ stateStr = "not running";
+ if (m_process.exitStatus() == QProcess::CrashExit)
+ stateStr += " (crashed!)";
+ else
+ stateStr += ", return value " + QString::number(m_process.exitCode());
+ break;
+ }
+ case QProcess::Starting:
+ stateStr = "starting";
+ break;
+ case QProcess::Running:
+ stateStr = "running";
+ break;
+ }
+ return stateStr;
+}
+
+void QQmlDebugProcess::start(const QStringList &arguments)
+{
+#ifdef Q_OS_MAC
+ // make sure m_executable points to the actual binary even if it's inside an app bundle
+ QFileInfo binFile(m_executable);
+ if (!binFile.isExecutable()) {
+ QDir bundleDir(m_executable + ".app");
+ if (bundleDir.exists()) {
+ m_executable = bundleDir.absoluteFilePath("Contents/MacOS/" + binFile.baseName());
+ //qDebug() << Q_FUNC_INFO << "found bundled binary" << m_executable;
+ }
+ }
+#endif
+ m_mutex.lock();
+ m_port = 0;
+ m_process.setEnvironment(QProcess::systemEnvironment() + m_environment);
+ m_process.start(m_executable, arguments);
+ if (!m_process.waitForStarted()) {
+ qWarning() << "QML Debug Client: Could not launch app " << m_executable
+ << ": " << m_process.errorString();
+ m_eventLoop.quit();
+ }
+ m_mutex.unlock();
+}
+
+void QQmlDebugProcess::stop()
+{
+ if (m_process.state() != QProcess::NotRunning) {
+ disconnect(&m_process, &QProcess::errorOccurred, this, &QQmlDebugProcess::processError);
+ m_process.kill();
+ m_process.waitForFinished(5000);
+ }
+}
+
+void QQmlDebugProcess::setMaximumBindErrors(int ignore)
+{
+ m_maximumBindErrors = ignore;
+}
+
+void QQmlDebugProcess::timeout()
+{
+ qWarning() << "Timeout while waiting for QML debugging messages "
+ "in application output. Process is in state" << m_process.state()
+ << ", Output:" << m_output << ".";
+ m_eventLoop.quit();
+}
+
+bool QQmlDebugProcess::waitForSessionStart()
+{
+ if (m_process.state() != QProcess::Running) {
+ qWarning() << "Could not start up " << m_executable;
+ return false;
+ } else if (m_state == SessionStarted) {
+ return true;
+ } else if (m_state == SessionFailed) {
+ return false;
+ }
+
+ m_timer.start();
+ m_eventLoop.exec();
+
+ return m_state == SessionStarted;
+}
+
+int QQmlDebugProcess::debugPort() const
+{
+ return m_port;
+}
+
+bool QQmlDebugProcess::waitForFinished()
+{
+ return m_process.waitForFinished();
+}
+
+QProcess::ExitStatus QQmlDebugProcess::exitStatus() const
+{
+ return m_process.exitStatus();
+}
+
+void QQmlDebugProcess::addEnvironment(const QString &environment)
+{
+ m_environment.append(environment);
+}
+
+QString QQmlDebugProcess::output() const
+{
+ return m_output;
+}
+
+void QQmlDebugProcess::processAppOutput()
+{
+ m_mutex.lock();
+
+ bool outputFromAppItself = false;
+
+ QString newOutput = m_process.readAll();
+ m_output.append(newOutput);
+ m_outputBuffer.append(newOutput);
+
+ while (true) {
+ const int nlIndex = m_outputBuffer.indexOf(QLatin1Char('\n'));
+ if (nlIndex < 0) // no further complete lines
+ break;
+ const QString line = m_outputBuffer.left(nlIndex);
+ m_outputBuffer = m_outputBuffer.right(m_outputBuffer.size() - nlIndex - 1);
+
+ if (line.contains("QML Debugger:")) {
+ const QRegExp portRx("Waiting for connection on port (\\d+)");
+ if (portRx.indexIn(line) != -1) {
+ m_port = portRx.cap(1).toInt();
+ m_timer.stop();
+ m_state = SessionStarted;
+ m_eventLoop.quit();
+ continue;
+ }
+ if (line.contains("Unable to listen")) {
+ if (++m_receivedBindErrors >= m_maximumBindErrors) {
+ if (m_maximumBindErrors == 0)
+ qWarning() << "App was unable to bind to port!";
+ m_timer.stop();
+ m_state = SessionFailed;
+ m_eventLoop.quit();
+ }
+ continue;
+ }
+ }
+
+ // set to true if there is output not coming from the debugger or we don't understand it
+ outputFromAppItself = true;
+ }
+ m_mutex.unlock();
+
+ if (outputFromAppItself)
+ emit readyReadStandardOutput();
+}
+
+void QQmlDebugProcess::processError(QProcess::ProcessError error)
+{
+ qDebug() << "An error occurred while waiting for debug process to become available:";
+ switch (error) {
+ case QProcess::FailedToStart:
+ qDebug() << "Process failed to start.";
+ break;
+ case QProcess::Crashed:
+ qDebug() << "Process crashed.";
+ break;
+ case QProcess::Timedout:
+ qDebug() << "Process timed out.";
+ break;
+ case QProcess::WriteError:
+ qDebug() << "Error while writing to process.";
+ break;
+ case QProcess::ReadError:
+ qDebug() << "Error while reading from process.";
+ break;
+ case QProcess::UnknownError:
+ qDebug() << "Unknown process error.";
+ break;
+ }
+}
diff --git a/tests/auto/qml/debugger/shared/qqmldebugprocess_p.h b/tests/auto/qml/debugger/shared/qqmldebugprocess_p.h
new file mode 100644
index 0000000000..fd2c89bb41
--- /dev/null
+++ b/tests/auto/qml/debugger/shared/qqmldebugprocess_p.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QQMLDEBUGPROCESS_P_H
+#define QQMLDEBUGPROCESS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qprocess.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qeventloop.h>
+#include <QtCore/qmutex.h>
+
+class QQmlDebugProcess : public QObject
+{
+ Q_OBJECT
+public:
+ QQmlDebugProcess(const QString &executable, QObject *parent = 0);
+ ~QQmlDebugProcess();
+
+ QString state();
+
+ void addEnvironment(const QString &environment);
+
+ void start(const QStringList &arguments);
+ bool waitForSessionStart();
+ int debugPort() const;
+
+ bool waitForFinished();
+ QProcess::ExitStatus exitStatus() const;
+
+ QString output() const;
+ void stop();
+ void setMaximumBindErrors(int numErrors);
+
+signals:
+ void readyReadStandardOutput();
+
+private slots:
+ void timeout();
+ void processAppOutput();
+ void processError(QProcess::ProcessError error);
+
+private:
+ enum SessionState {
+ SessionUnknown,
+ SessionStarted,
+ SessionFailed
+ };
+
+ QString m_executable;
+ QProcess m_process;
+ QString m_outputBuffer;
+ QString m_output;
+ QTimer m_timer;
+ QEventLoop m_eventLoop;
+ QMutex m_mutex;
+ SessionState m_state;
+ QStringList m_environment;
+ int m_port;
+ int m_maximumBindErrors;
+ int m_receivedBindErrors;
+};
+
+#endif // QQMLDEBUGPROCESS_P_H
diff --git a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp
index c0252a0290..7e736ec400 100644
--- a/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp
+++ b/tests/auto/qml/debugger/shared/qqmlenginedebugclient.cpp
@@ -385,7 +385,7 @@ void QQmlEngineDebugClient::decode(QPacket &ds,
case QmlObjectProperty::Object:
{
QmlDebugObjectReference obj;
- obj.debugId = prop.value.toInt();
+ obj.name = data.value.toString();
obj.className = prop.valueTypeName;
prop.value = qVariantFromValue(obj);
break;
diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations
index 49f107452a..589f25d174 100644
--- a/tests/auto/qml/ecmascripttests/TestExpectations
+++ b/tests/auto/qml/ecmascripttests/TestExpectations
@@ -15,7 +15,6 @@ S15.1.2.3_A2_T10
15.5.4.20-3-5
15.5.4.20-3-6
-10.4.3-1-106 failing
11.2.3-3_3 failing
S13_A15_T4 failing
S15.4.4.3_A1_T1 failing
@@ -29,3 +28,150 @@ Sbp_12.5_A9_T3 failing
Sbp_12.6.1_A13_T3 failing
Sbp_12.6.2_A13_T3 failing
Sbp_12.6.4_A13_T3 failing
+
+# es6: function length attributes are configurable, wasn't in es5
+S15.1.2.2_A9.2 failing
+S15.1.3.1_A5.2 failing
+S15.1.3.2_A5.2 failing
+S15.1.3.3_A5.2 failing
+S15.1.2.3_A7.2 failing
+S15.1.2.4_A2.2 failing
+S15.1.2.5_A2.2 failing
+S15.1.3.4_A5.2 failing
+15.2.3.3-4-186 failing
+S15.2.4.2_A9 failing
+S15.2.4.3_A9 failing
+S15.2.4.4_A9 failing
+S15.2.4.5_A9 failing
+S15.2.4.6_A9 failing
+S15.2.4.7_A9 failing
+15.3.3.2-1 failing
+15.4.4.2_A4.2
+S15.3.4.2_A9 failing
+S15.3.4.3_A9 failing
+S15.3.4.4_A9 failing
+15.3.4.5-15-2 failing
+S15.4.4.2_A4.2 failing
+S15.4.4.3_A4.2 failing
+S15.4.4.4_A4.2 failing
+S15.4.4.5_A6.2 failing
+S15.4.4.6_A5.2 failing
+S15.4.4.7_A6.2 failing
+S15.4.4.8_A5.2 failing
+S15.4.4.9_A5.2 failing
+S15.4.4.10_A5.2 failing
+S15.4.4.11_A7.2 failing
+S15.4.4.12_A5.2 failing
+S15.4.4.13_A5.2 failing
+S15.5.4.10_A9 failing
+S15.5.4.11_A9 failing
+S15.5.4.12_A9 failing
+S15.5.4.13_A9 failing
+S15.5.4.14_A9 failing
+S15.5.4.15_A9 failing
+S15.5.4.16_A9 failing
+S15.5.4.17_A9 failing
+S15.5.4.18_A9 failing
+S15.5.4.19_A9 failing
+S15.5.4.4_A9 failing
+S15.5.4.5_A9 failing
+S15.5.4.6_A9 failing
+S15.5.4.7_A9 failing
+S15.5.4.8_A9 failing
+S15.5.4.9_A9 failing
+S15.9.4.2_A3_T2 failing
+S15.9.4.3_A3_T2 failing
+S15.9.5.2_A3_T2 failing
+S15.9.5.3_A3_T2 failing
+S15.9.5.4_A3_T2 failing
+S15.9.5.5_A3_T2 failing
+S15.9.5.1_A3_T2 failing
+S15.9.5.10_A3_T2 failing
+S15.9.5.11_A3_T2 failing
+S15.9.5.12_A3_T2 failing
+S15.9.5.13_A3_T2 failing
+S15.9.5.14_A3_T2 failing
+S15.9.5.15_A3_T2 failing
+S15.9.5.16_A3_T2 failing
+S15.9.5.17_A3_T2 failing
+S15.9.5.18_A3_T2 failing
+S15.9.5.19_A3_T2 failing
+S15.9.5.20_A3_T2 failing
+S15.9.5.21_A3_T2 failing
+S15.9.5.22_A3_T2 failing
+S15.9.5.23_A3_T2 failing
+S15.9.5.24_A3_T2 failing
+S15.9.5.25_A3_T2 failing
+S15.9.5.26_A3_T2 failing
+S15.9.5.27_A3_T2 failing
+S15.9.5.28_A3_T2 failing
+S15.9.5.29_A3_T2 failing
+S15.9.5.30_A3_T2 failing
+S15.9.5.31_A3_T2 failing
+S15.9.5.32_A3_T2 failing
+S15.9.5.33_A3_T2 failing
+S15.9.5.34_A3_T2 failing
+S15.9.5.35_A3_T2 failing
+S15.9.5.36_A3_T2 failing
+S15.9.5.37_A3_T2 failing
+S15.9.5.38_A3_T2 failing
+S15.9.5.39_A3_T2 failing
+S15.9.5.40_A3_T2 failing
+S15.9.5.41_A3_T2 failing
+S15.9.5.42_A3_T2 failing
+S15.9.5.6_A3_T2 failing
+S15.9.5.7_A3_T2 failing
+S15.9.5.8_A3_T2 failing
+S15.9.5.9_A3_T2 failing
+S15.10.6.2_A9 failing
+S15.10.6.3_A9 failing
+S15.10.6.4_A9 failing
+
+# es6: Object.freeze(v) on a non-object returns v, no longer TypeError
+15.2.3.9-1 failing
+15.2.3.9-1-1 failing
+15.2.3.9-1-2 failing
+15.2.3.9-1-3 failing
+15.2.3.9-1-4 failing
+# es6: Object.preventExtensions(O) on a non-object, no longer TypeError
+15.2.3.10-1 failing
+15.2.3.10-1-3 failing
+15.2.3.10-1-4 failing
+# es6: Object.isSealed(O) on a non-object, no longer TypeError
+15.2.3.11-1
+# es6: Object.isFrozen(O) on a non-object, no longer TypeError
+15.2.3.12-1
+15.2.3.12-1-3
+15.2.3.12-1-4
+# es6: Object.isExtensible(O) on a non-object, no longer TypeError
+15.2.3.13-1
+15.2.3.13-1-3
+15.2.3.13-1-4
+# es6: Object.keys(O) on a non-object, no longer TypeError
+15.2.3.14-1-1
+15.2.3.14-1-2
+15.2.3.14-1-3
+15.2.3.14-1
+15.2.3.14-2
+15.2.3.14-3
+# es6: Object.getOwnPropertyDescriptor(O) on a non-object, no longer TypeError
+15.2.3.3-1
+15.2.3.3-1-3
+15.2.3.3-1-4
+# es6: Object.getPrototypeOf(O) on a non-object, no longer TypeError
+15.2.3.2-1
+15.2.3.2-1-3
+15.2.3.2-1-4
+# es6: Object.getOwnPropertyNames(O) on a non-object, no longer TypeError
+15.2.3.4-1
+15.2.3.4-1-4
+15.2.3.4-1-5
+# es6: Object.seal(O) on a non-object, no longer TypeError
+15.2.3.8-1
+15.2.3.8-1-1
+15.2.3.8-1-2
+15.2.3.8-1-3
+15.2.3.8-1-4
+
+# es6: Date.prototype is no longer a DateObject
+15.9.5.40_1 failing
diff --git a/tests/auto/qml/ecmascripttests/test262 b/tests/auto/qml/ecmascripttests/test262
-Subproject fe58b18c13d1ea5d42951e5b698efc3bfab6dc8
+Subproject d60c4ed97e69639bc5bc1db43a98828debf80c8
diff --git a/tests/auto/qml/ecmascripttests/test262.py b/tests/auto/qml/ecmascripttests/test262.py
index 437cd1b27d..ae4c54df9d 100755
--- a/tests/auto/qml/ecmascripttests/test262.py
+++ b/tests/auto/qml/ecmascripttests/test262.py
@@ -552,10 +552,10 @@ class TestSuite(object):
def Main():
- # Some date tests rely on being run in pacific time.
# Uncomment the next line for more logging info.
#logging.basicConfig(level=logging.DEBUG)
- os.environ["TZ"] = "PST8PDT"
+ # Some date tests rely on being run in pacific time and the USA's locale:
+ os.environ["TZ"] = "America/Vancouver"
os.environ["LANG"] = "en_US.UTF-8"
os.environ["LC_TIME"] = "en_US.UTF-8"
parser = BuildOptions()
diff --git a/tests/auto/qml/ecmascripttests/tst_ecmascripttests.cpp b/tests/auto/qml/ecmascripttests/tst_ecmascripttests.cpp
index 880e254543..0d58d045b9 100644
--- a/tests/auto/qml/ecmascripttests/tst_ecmascripttests.cpp
+++ b/tests/auto/qml/ecmascripttests/tst_ecmascripttests.cpp
@@ -34,29 +34,29 @@
class tst_EcmaScriptTests : public QObject
{
Q_OBJECT
-private slots:
- void runTests_data();
- void runTests();
-};
-void tst_EcmaScriptTests::runTests_data()
-{
- QTest::addColumn<QString>("qmljsParameter");
+ void runTests(bool interpret);
- QTest::newRow("jit") << QStringLiteral("--jit");
- QTest::newRow("interpreter") << QStringLiteral("--interpret");
-}
+private slots:
+ void runInterpreted();
+ void runJitted();
+};
-void tst_EcmaScriptTests::runTests()
+void tst_EcmaScriptTests::runTests(bool interpret)
{
#if defined(Q_OS_LINUX) && defined(Q_PROCESSOR_X86_64)
- QFETCH(QString, qmljsParameter);
+ QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
+ if (interpret)
+ env.insert("QV4_FORCE_INTERPRETER", "1");
+ else
+ env.insert("QV4_JIT_CALL_THRESHOLD", "0");
QProcess process;
process.setProcessChannelMode(QProcess::ForwardedChannels);
process.setWorkingDirectory(QLatin1String(SRCDIR));
process.setProgram("python");
- process.setArguments(QStringList() << "test262.py" << "--command=" + QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmljs " + qmljsParameter << "--parallel" << "--with-test-expectations");
+ process.setProcessEnvironment(env);
+ process.setArguments(QStringList() << "test262.py" << "--command=" + QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmljs" << "--parallel" << "--with-test-expectations");
qDebug() << "Going to run" << process.program() << process.arguments() << "in" << process.workingDirectory();
@@ -71,6 +71,16 @@ void tst_EcmaScriptTests::runTests()
#endif
}
+void tst_EcmaScriptTests::runInterpreted()
+{
+ runTests(true);
+}
+
+void tst_EcmaScriptTests::runJitted()
+{
+ runTests(false);
+}
+
QTEST_GUILESS_MAIN(tst_EcmaScriptTests)
#include "tst_ecmascripttests.moc"
diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
index 8b815f7a06..519c57efb2 100644
--- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
@@ -201,6 +201,8 @@ private slots:
void malformedExpression();
+ void scriptScopes();
+
signals:
void testSignal();
};
@@ -569,10 +571,6 @@ void tst_QJSEngine::newDate()
QCOMPARE(date.isDate(), true);
QCOMPARE(date.isObject(), true);
QVERIFY(!date.isCallable());
- // prototype should be Date.prototype
- QVERIFY(!date.prototype().isUndefined());
- QCOMPARE(date.prototype().isDate(), true);
- QCOMPARE(date.prototype().strictlyEquals(eng.evaluate("Date.prototype")), true);
}
{
@@ -581,10 +579,6 @@ void tst_QJSEngine::newDate()
QVERIFY(!date.isUndefined());
QCOMPARE(date.isDate(), true);
QCOMPARE(date.isObject(), true);
- // prototype should be Date.prototype
- QVERIFY(!date.prototype().isUndefined());
- QCOMPARE(date.prototype().isDate(), true);
- QCOMPARE(date.prototype().strictlyEquals(eng.evaluate("Date.prototype")), true);
QCOMPARE(date.toDateTime(), dt);
}
@@ -1115,7 +1109,7 @@ void tst_QJSEngine::builtinFunctionNames_data()
QTest::newRow("Date.prototype.setFullYear") << QString("Date.prototype.setFullYear") << QString("setFullYear");
QTest::newRow("Date.prototype.setUTCFullYear") << QString("Date.prototype.setUTCFullYear") << QString("setUTCFullYear");
QTest::newRow("Date.prototype.toUTCString") << QString("Date.prototype.toUTCString") << QString("toUTCString");
- QTest::newRow("Date.prototype.toGMTString") << QString("Date.prototype.toGMTString") << QString("toGMTString");
+ QTest::newRow("Date.prototype.toGMTString") << QString("Date.prototype.toGMTString") << QString("toUTCString"); // yes, this is per spec
QTest::newRow("Error") << QString("Error") << QString("Error");
// QTest::newRow("Error.prototype.backtrace") << QString("Error.prototype.backtrace") << QString("backtrace");
@@ -1193,6 +1187,7 @@ void tst_QJSEngine::builtinFunctionNames_data()
QTest::newRow("String.prototype.lastIndexOf") << QString("String.prototype.lastIndexOf") << QString("lastIndexOf");
QTest::newRow("String.prototype.localeCompare") << QString("String.prototype.localeCompare") << QString("localeCompare");
QTest::newRow("String.prototype.match") << QString("String.prototype.match") << QString("match");
+ QTest::newRow("String.prototype.repeat") << QString("String.prototype.repeat") << QString("repeat");
QTest::newRow("String.prototype.replace") << QString("String.prototype.replace") << QString("replace");
QTest::newRow("String.prototype.search") << QString("String.prototype.search") << QString("search");
QTest::newRow("String.prototype.slice") << QString("String.prototype.slice") << QString("slice");
@@ -4125,6 +4120,22 @@ void tst_QJSEngine::malformedExpression()
engine.evaluate("5%55555&&5555555\n7-0");
}
+void tst_QJSEngine::scriptScopes()
+{
+ QJSEngine engine;
+
+ QJSValue def = engine.evaluate("'use strict'; function foo() { return 42 }");
+ QVERIFY(!def.isError());
+ QJSValue globalObject = engine.globalObject();
+ QJSValue foo = globalObject.property("foo");
+ QVERIFY(foo.isObject());
+ QVERIFY(foo.isCallable());
+
+ QJSValue use = engine.evaluate("'use strict'; foo()");
+ QVERIFY(use.isNumber());
+ QCOMPARE(use.toInt(), 42);
+}
+
QTEST_MAIN(tst_QJSEngine)
#include "tst_qjsengine.moc"
diff --git a/tests/auto/qml/qjsonbinding/qjsonbinding.pro b/tests/auto/qml/qjsonbinding/qjsonbinding.pro
index 75b48aa854..f7a185d27a 100644
--- a/tests/auto/qml/qjsonbinding/qjsonbinding.pro
+++ b/tests/auto/qml/qjsonbinding/qjsonbinding.pro
@@ -3,7 +3,6 @@ TARGET = tst_qjsonbinding
macx:CONFIG -= app_bundle
SOURCES += tst_qjsonbinding.cpp
-INCLUDEPATH += ../../shared
include (../../shared/util.pri)
diff --git a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
index 12c33909cf..db99c44261 100644
--- a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
+++ b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
@@ -970,10 +970,6 @@ void tst_QJSValue::toUInt()
QCOMPARE(qjsvalue_cast<quint32>(inv), quint32(0));
}
-#if defined Q_CC_MSVC && _MSC_VER < 1300
-Q_DECLARE_METATYPE(QVariant)
-#endif
-
void tst_QJSValue::toVariant()
{
QJSEngine eng;
diff --git a/tests/auto/qml/qml.pro b/tests/auto/qml/qml.pro
index 42a5400dc1..9557393a2e 100644
--- a/tests/auto/qml/qml.pro
+++ b/tests/auto/qml/qml.pro
@@ -1,4 +1,5 @@
TEMPLATE = subdirs
+QT_FOR_CONFIG += qml
METATYPETESTS += \
qqmlmetatype
@@ -10,7 +11,6 @@ PUBLICTESTS += \
qqmlfile \
qqmlfileselector
-!boot2qt {
PUBLICTESTS += \
qmlmin \
qqmlcomponent \
@@ -32,15 +32,12 @@ PUBLICTESTS += \
qqmlsettings \
qqmlstatemachine \
qmldiskcache
-}
PRIVATETESTS += \
qqmlcpputils \
qqmldirparser \
- v4misc \
qmlcachegen
-!boot2qt {
PRIVATETESTS += \
animation \
qqmlecmascript \
@@ -73,20 +70,23 @@ PRIVATETESTS += \
qqmlimport \
qqmlobjectmodel \
qv4mm \
- ecmascripttests
-}
+ ecmascripttests \
+ bindingdependencyapi
qtHaveModule(widgets) {
PUBLICTESTS += \
qjsengine \
- qjsvalue
+ qjsvalue \
+# qwidgetsinqml
}
SUBDIRS += $$PUBLICTESTS
SUBDIRS += $$METATYPETESTS
-qtConfig(process):!boot2qt {
- !contains(QT_CONFIG, no-qml-debug): SUBDIRS += debugger
- SUBDIRS += qmllint qmlplugindump
+qtConfig(process) {
+ qtConfig(qml-debug): SUBDIRS += debugger
+ !boot2qt {
+ SUBDIRS += qmllint qmlplugindump
+ }
}
qtConfig(library) {
diff --git a/tests/auto/qml/qmlcachegen/qmlcachegen.pro b/tests/auto/qml/qmlcachegen/qmlcachegen.pro
index 8d8b37be15..a8b72224ba 100644
--- a/tests/auto/qml/qmlcachegen/qmlcachegen.pro
+++ b/tests/auto/qml/qmlcachegen/qmlcachegen.pro
@@ -1,7 +1,11 @@
-CONFIG += testcase
+CONFIG += testcase qtquickcompiler
TARGET = tst_qmlcachegen
macos:CONFIG -= app_bundle
SOURCES += tst_qmlcachegen.cpp
+workerscripts_test.files = worker.js worker.qml
+workerscripts_test.prefix = /workerscripts
+RESOURCES += workerscripts_test
+
QT += core-private qml-private testlib
diff --git a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
index 98a3a9d6ef..2f5ff0022e 100644
--- a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
+++ b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
@@ -44,7 +44,11 @@ private slots:
void loadGeneratedFile();
void translationExpressionSupport();
+ void signalHandlerParameters();
void errorOnArgumentsInSignalHandler();
+ void aheadOfTimeCompilation();
+
+ void workerScripts();
};
// A wrapper around QQmlComponent to ensure the temporary reference counts
@@ -75,7 +79,7 @@ static bool generateCache(const QString &qmlFileName, QByteArray *capturedStderr
if (capturedStderr == nullptr)
proc.setProcessChannelMode(QProcess::ForwardedChannels);
proc.setProgram(QLibraryInfo::location(QLibraryInfo::BinariesPath) + QDir::separator() + QLatin1String("qmlcachegen"));
- proc.setArguments(QStringList() << (QLatin1String("--target-architecture=") + QSysInfo::buildCpuArchitecture()) << (QLatin1String("--target-abi=") + QSysInfo::buildAbi()) << qmlFileName);
+ proc.setArguments(QStringList() << qmlFileName);
proc.start();
if (!proc.waitForFinished())
return false;
@@ -182,6 +186,41 @@ void tst_qmlcachegen::translationExpressionSupport()
QCOMPARE(obj->property("text").toString(), QString("All Ok"));
}
+void tst_qmlcachegen::signalHandlerParameters()
+{
+ QTemporaryDir tempDir;
+ QVERIFY(tempDir.isValid());
+
+ const auto writeTempFile = [&tempDir](const QString &fileName, const char *contents) {
+ QFile f(tempDir.path() + '/' + fileName);
+ const bool ok = f.open(QIODevice::WriteOnly | QIODevice::Truncate);
+ Q_ASSERT(ok);
+ f.write(contents);
+ return f.fileName();
+ };
+
+ const QString testFilePath = writeTempFile("test.qml", "import QtQml 2.0\n"
+ "QtObject {\n"
+ " property real result: 0\n"
+ " signal testMe(real value);\n"
+ " onTestMe: result = value;\n"
+ " function runTest() { testMe(42); }\n"
+ "}");
+
+ QVERIFY(generateCache(testFilePath));
+
+ const QString cacheFilePath = testFilePath + QLatin1Char('c');
+ QVERIFY(QFile::exists(cacheFilePath));
+ QVERIFY(QFile::remove(testFilePath));
+
+ QQmlEngine engine;
+ CleanlyLoadingComponent component(&engine, QUrl::fromLocalFile(testFilePath));
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+ QMetaObject::invokeMethod(obj.data(), "runTest");
+ QCOMPARE(obj->property("result").toInt(), 42);
+}
+
void tst_qmlcachegen::errorOnArgumentsInSignalHandler()
{
QTemporaryDir tempDir;
@@ -207,6 +246,52 @@ void tst_qmlcachegen::errorOnArgumentsInSignalHandler()
QVERIFY2(errorOutput.contains("error: The use of the arguments object in signal handlers is"), errorOutput);
}
+void tst_qmlcachegen::aheadOfTimeCompilation()
+{
+ QTemporaryDir tempDir;
+ QVERIFY(tempDir.isValid());
+
+ const auto writeTempFile = [&tempDir](const QString &fileName, const char *contents) {
+ QFile f(tempDir.path() + '/' + fileName);
+ const bool ok = f.open(QIODevice::WriteOnly | QIODevice::Truncate);
+ Q_ASSERT(ok);
+ f.write(contents);
+ return f.fileName();
+ };
+
+ const QString testFilePath = writeTempFile("test.qml", "import QtQml 2.0\n"
+ "QtObject {\n"
+ " function runTest() { var x = 0; while (x < 42) { ++x }; return x; }\n"
+ "}");
+
+ QVERIFY(generateCache(testFilePath));
+
+ const QString cacheFilePath = testFilePath + QLatin1Char('c');
+ QVERIFY(QFile::exists(cacheFilePath));
+ QVERIFY(QFile::remove(testFilePath));
+
+ QQmlEngine engine;
+ CleanlyLoadingComponent component(&engine, QUrl::fromLocalFile(testFilePath));
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+ QVariant result;
+ QMetaObject::invokeMethod(obj.data(), "runTest", Q_RETURN_ARG(QVariant, result));
+ QCOMPARE(result.toInt(), 42);
+}
+
+void tst_qmlcachegen::workerScripts()
+{
+ QVERIFY(QFile::exists(":/workerscripts/worker.js"));
+ QVERIFY(QFile::exists(":/workerscripts/worker.qml"));
+ QCOMPARE(QFileInfo(":/workerscripts/worker.js").size(), 0);
+
+ QQmlEngine engine;
+ CleanlyLoadingComponent component(&engine, QUrl("qrc:///workerscripts/worker.qml"));
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+ QTRY_VERIFY(obj->property("success").toBool());
+}
+
QTEST_GUILESS_MAIN(tst_qmlcachegen)
#include "tst_qmlcachegen.moc"
diff --git a/tests/auto/qml/qmlcachegen/worker.js b/tests/auto/qml/qmlcachegen/worker.js
new file mode 100644
index 0000000000..dd2d0b843d
--- /dev/null
+++ b/tests/auto/qml/qmlcachegen/worker.js
@@ -0,0 +1,3 @@
+WorkerScript.onMessage = function(message) {
+ WorkerScript.sendMessage({ reply: message });
+}
diff --git a/tests/auto/qml/qmlcachegen/worker.qml b/tests/auto/qml/qmlcachegen/worker.qml
new file mode 100644
index 0000000000..1f1c9d1ac7
--- /dev/null
+++ b/tests/auto/qml/qmlcachegen/worker.qml
@@ -0,0 +1,12 @@
+import QtQml 2.0
+import QtQuick 2.0
+QtObject {
+ property bool success: false
+ property WorkerScript worker: WorkerScript {
+ source: "worker.js"
+ onMessage: {
+ success = true
+ }
+ }
+ Component.onCompleted: worker.sendMessage("Hello")
+}
diff --git a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
index e75e51ed29..f5905758f3 100644
--- a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
+++ b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
@@ -30,10 +30,9 @@
#include <private/qv4compileddata_p.h>
#include <private/qv4compiler_p.h>
-#include <private/qv4jsir_p.h>
-#include <private/qv4isel_p.h>
#include <private/qv8engine_p.h>
#include <private/qv4engine_p.h>
+#include <private/qv4codegen_p.h>
#include <QQmlComponent>
#include <QQmlEngine>
#include <QQmlFileSelector>
@@ -174,9 +173,8 @@ struct TestCompiler
bool verify()
{
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
- QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = v4->iselFactory->createUnitForLoading();
- return unit->loadFromDisk(QUrl::fromLocalFile(testFilePath), QFileInfo(testFilePath).lastModified(), v4->iselFactory.data(), &lastErrorString);
+ QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = QV4::Compiler::Codegen::createUnitForLoading();
+ return unit->loadFromDisk(QUrl::fromLocalFile(testFilePath), QFileInfo(testFilePath).lastModified(), &lastErrorString);
}
void closeMapping()
@@ -231,12 +229,14 @@ void tst_qmldiskcache::regenerateAfterChange()
const QV4::CompiledData::Object *obj = testUnit->objectAt(0);
QCOMPARE(quint32(obj->nBindings), quint32(1));
QCOMPARE(quint32(obj->bindingTable()->type), quint32(QV4::CompiledData::Binding::Type_Script));
- QCOMPARE(quint32(obj->bindingTable()->value.compiledScriptIndex), quint32(1));
+ QCOMPARE(quint32(obj->bindingTable()->value.compiledScriptIndex), quint32(0));
- QCOMPARE(quint32(testUnit->functionTableSize), quint32(2));
+ QCOMPARE(quint32(testUnit->functionTableSize), quint32(1));
- const QV4::CompiledData::Function *bindingFunction = testUnit->functionAt(1);
- QVERIFY(bindingFunction->codeOffset > testUnit->unitSize);
+ const QV4::CompiledData::Function *bindingFunction = testUnit->functionAt(0);
+ QCOMPARE(testUnit->stringAt(bindingFunction->nameIndex), QString("expression for blah")); // check if we have the correct function
+ QVERIFY(bindingFunction->codeSize > 0);
+ QVERIFY(bindingFunction->codeOffset < testUnit->unitSize);
}
{
@@ -257,10 +257,12 @@ void tst_qmldiskcache::regenerateAfterChange()
QCOMPARE(quint32(obj->bindingTable()->type), quint32(QV4::CompiledData::Binding::Type_Number));
QCOMPARE(obj->bindingTable()->valueAsNumber(), double(42));
- QCOMPARE(quint32(testUnit->functionTableSize), quint32(2));
+ QCOMPARE(quint32(testUnit->functionTableSize), quint32(1));
- const QV4::CompiledData::Function *bindingFunction = testUnit->functionAt(1);
- QVERIFY(bindingFunction->codeOffset > testUnit->unitSize);
+ const QV4::CompiledData::Function *bindingFunction = testUnit->functionAt(0);
+ QCOMPARE(testUnit->stringAt(bindingFunction->nameIndex), QString("expression for blah")); // check if we have the correct function
+ QVERIFY(bindingFunction->codeSize > 0);
+ QVERIFY(bindingFunction->codeOffset < testUnit->unitSize);
}
}
@@ -342,30 +344,6 @@ void tst_qmldiskcache::basicVersionChecks()
QVERIFY(!testCompiler.verify());
QCOMPARE(testCompiler.lastErrorString, QString::fromUtf8("V4 data structure version mismatch. Found 0 expected %1").arg(QV4_DATA_STRUCTURE_VERSION, 0, 16));
}
-
- {
- testCompiler.clearCache();
- QVERIFY2(testCompiler.compile(contents), qPrintable(testCompiler.lastErrorString));
-
- testCompiler.tweakHeader([](QV4::CompiledData::Unit *header) {
- header->architectureIndex = 0;
- });
-
- QVERIFY(!testCompiler.verify());
- QCOMPARE(testCompiler.lastErrorString, QString::fromUtf8("Architecture mismatch. Found expected %1").arg(QSysInfo::buildAbi()));
- }
-
- {
- testCompiler.clearCache();
- QVERIFY2(testCompiler.compile(contents), qPrintable(testCompiler.lastErrorString));
-
- testCompiler.tweakHeader([](QV4::CompiledData::Unit *header) {
- header->codeGeneratorIndex = 0;
- });
-
- QVERIFY(!testCompiler.verify());
- QCOMPARE(testCompiler.lastErrorString, QString::fromUtf8("Code generator mismatch. Found code generated by but expected %1").arg(QV8Engine::getV4(&engine)->iselFactory->codeGeneratorName));
- }
}
class TypeVersion1 : public QObject
diff --git a/tests/auto/qml/qmlmin/qmlmin.pro b/tests/auto/qml/qmlmin/qmlmin.pro
index 6af6653270..93e5caabcf 100644
--- a/tests/auto/qml/qmlmin/qmlmin.pro
+++ b/tests/auto/qml/qmlmin/qmlmin.pro
@@ -6,5 +6,7 @@ macx:CONFIG -= app_bundle
SOURCES += tst_qmlmin.cpp
DEFINES += SRCDIR=\\\"$$PWD\\\"
-
-cross_compile: DEFINES += QTEST_CROSS_COMPILED
+# Boot2qt is cross compiled but it has sources available
+!boot2qt {
+ cross_compile: DEFINES += QTEST_CROSS_COMPILED
+}
diff --git a/tests/auto/qml/qmlmin/tst_qmlmin.cpp b/tests/auto/qml/qmlmin/tst_qmlmin.cpp
index 171c2bda8a..5941385c80 100644
--- a/tests/auto/qml/qmlmin/tst_qmlmin.cpp
+++ b/tests/auto/qml/qmlmin/tst_qmlmin.cpp
@@ -98,6 +98,8 @@ void tst_qmlmin::initTestCase()
invalidFiles << "tests/auto/qml/qqmllanguage/data/insertedSemicolon.1.qml";
invalidFiles << "tests/auto/qml/qqmllanguage/data/nonexistantProperty.5.qml";
invalidFiles << "tests/auto/qml/qqmllanguage/data/invalidRoot.1.qml";
+ invalidFiles << "tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.1.qml";
+ invalidFiles << "tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.2.qml";
invalidFiles << "tests/auto/qml/qquickfolderlistmodel/data/dummy.qml";
invalidFiles << "tests/auto/qml/qqmlecmascript/data/qtbug_22843.js";
invalidFiles << "tests/auto/qml/qqmlecmascript/data/qtbug_22843.library.js";
diff --git a/tests/auto/qml/qmlplugindump/tests/dumper/CompositeSingleton/Singleton.qml b/tests/auto/qml/qmlplugindump/data/dumper/CompositeSingleton/Singleton.qml
index b47d2e98f4..b47d2e98f4 100644
--- a/tests/auto/qml/qmlplugindump/tests/dumper/CompositeSingleton/Singleton.qml
+++ b/tests/auto/qml/qmlplugindump/data/dumper/CompositeSingleton/Singleton.qml
diff --git a/tests/auto/qml/qmlplugindump/tests/dumper/CompositeSingleton/qmldir b/tests/auto/qml/qmlplugindump/data/dumper/CompositeSingleton/qmldir
index 8df57f6d47..8df57f6d47 100644
--- a/tests/auto/qml/qmlplugindump/tests/dumper/CompositeSingleton/qmldir
+++ b/tests/auto/qml/qmlplugindump/data/dumper/CompositeSingleton/qmldir
diff --git a/tests/auto/qml/qmlplugindump/qmlplugindump.pro b/tests/auto/qml/qmlplugindump/qmlplugindump.pro
index 9327beffa6..ab915c819c 100644
--- a/tests/auto/qml/qmlplugindump/qmlplugindump.pro
+++ b/tests/auto/qml/qmlplugindump/qmlplugindump.pro
@@ -1,7 +1,7 @@
-CONFIG += testcase
-TARGET = tst_qmlplugindump
-QT += testlib gui-private
+QT += testlib gui-private qml
macx:CONFIG -= app_bundle
+include(../../shared/util.pri)
+
DEFINES += QT_QMLTEST_DIR=\\\"$${_PRO_FILE_PWD_}\\\"
SOURCES += tst_qmlplugindump.cpp
diff --git a/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp b/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp
index 235cf6fac9..ffddc52f9c 100644
--- a/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp
+++ b/tests/auto/qml/qmlplugindump/tst_qmlplugindump.cpp
@@ -26,6 +26,8 @@
**
****************************************************************************/
+#include "util.h"
+
#include <qtest.h>
#include <QLibraryInfo>
#include <QDir>
@@ -33,7 +35,7 @@
#include <QDebug>
#include <cstdlib>
-class tst_qmlplugindump : public QObject
+class tst_qmlplugindump : public QQmlDataTest
{
Q_OBJECT
public:
@@ -54,6 +56,7 @@ tst_qmlplugindump::tst_qmlplugindump()
void tst_qmlplugindump::initTestCase()
{
+ QQmlDataTest::initTestCase();
qmlplugindumpPath = QLibraryInfo::location(QLibraryInfo::BinariesPath);
#if defined(Q_OS_WIN)
@@ -105,12 +108,12 @@ void tst_qmlplugindump::singleton()
args << QLatin1String("tests.dumper.CompositeSingleton") << QLatin1String("1.0")
<< QLatin1String(QT_QMLTEST_DIR);
dumper.start(qmlplugindumpPath, args);
- dumper.waitForFinished();
+ QVERIFY2(dumper.waitForStarted(), qPrintable(dumper.errorString()));
+ QVERIFY2(dumper.waitForFinished(), qPrintable(dumper.errorString()));
const QString &result = dumper.readAllStandardOutput();
- qDebug() << "result: " << result;
- QVERIFY(result.contains(QLatin1String("exports: [\"Singleton 1.0\"]")));
- QVERIFY(result.contains(QLatin1String("exportMetaObjectRevisions: [0]")));
+ QVERIFY2(result.contains(QLatin1String("exports: [\"Singleton 1.0\"]")), qPrintable(result));
+ QVERIFY2(result.contains(QLatin1String("exportMetaObjectRevisions: [0]")), qPrintable(result));
}
QTEST_MAIN(tst_qmlplugindump)
diff --git a/tests/auto/qml/qqmlapplicationengine/qqmlapplicationengine.pro b/tests/auto/qml/qqmlapplicationengine/qqmlapplicationengine.pro
index 4a2dde7c47..3adad3759b 100644
--- a/tests/auto/qml/qqmlapplicationengine/qqmlapplicationengine.pro
+++ b/tests/auto/qml/qqmlapplicationengine/qqmlapplicationengine.pro
@@ -1,3 +1,5 @@
TEMPLATE = subdirs
-SUBDIRS = tst_qqmlapplicationengine.pro \
- testapp
+SUBDIRS = testapp \
+ tst_qqmlapplicationengine.pro
+
+CONFIG += ordered
diff --git a/tests/auto/qml/qqmlbinding/data/bindingOverwriting.qml b/tests/auto/qml/qqmlbinding/data/bindingOverwriting.qml
new file mode 100644
index 0000000000..767ca0c719
--- /dev/null
+++ b/tests/auto/qml/qqmlbinding/data/bindingOverwriting.qml
@@ -0,0 +1,13 @@
+import QtQuick 2.9
+
+Text {
+ visible: text && enabled
+ enabled: font.pixelSize === 25
+ font: enabled ? Qt.font({ "pixelSize": 25 }) : Qt.font({ "pixelSize": 50 })
+
+ Component.onCompleted: {
+ enabled = Qt.binding(function() { return visible; }); // replacement binding, not breaking
+ visible = true; // breaks visible binding
+ font.bold = true; // breaks font binding
+ }
+}
diff --git a/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp b/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp
index 6f1d82eca5..4b485d2ce8 100644
--- a/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp
+++ b/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp
@@ -50,6 +50,7 @@ private slots:
void disabledOnUnknownProperty();
void disabledOnReadonlyProperty();
void delayed();
+ void bindingOverwriting();
private:
QQmlEngine engine;
@@ -303,6 +304,21 @@ void tst_qqmlbinding::delayed()
delete item;
}
+void tst_qqmlbinding::bindingOverwriting()
+{
+ QQmlTestMessageHandler messageHandler;
+ QLoggingCategory::setFilterRules(QStringLiteral("qt.qml.binding.removal.info=true"));
+
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("bindingOverwriting.qml"));
+ QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
+ QVERIFY(item);
+ delete item;
+
+ QLoggingCategory::setFilterRules(QString());
+ QCOMPARE(messageHandler.messages().count(), 2);
+}
+
QTEST_MAIN(tst_qqmlbinding)
#include "tst_qqmlbinding.moc"
diff --git a/tests/auto/qml/qqmlchangeset/tst_qqmlchangeset.cpp b/tests/auto/qml/qqmlchangeset/tst_qqmlchangeset.cpp
index da7956a5fb..f12c3432c2 100644
--- a/tests/auto/qml/qqmlchangeset/tst_qqmlchangeset.cpp
+++ b/tests/auto/qml/qqmlchangeset/tst_qqmlchangeset.cpp
@@ -26,6 +26,7 @@
**
****************************************************************************/
#include <qtest.h>
+#include <qrandom.h>
#include <private/qqmlchangeset_p.h>
class tst_qqmlchangeset : public QObject
@@ -1462,23 +1463,19 @@ void tst_qqmlchangeset::debug()
void tst_qqmlchangeset::random_data()
{
- QTest::addColumn<int>("seed");
QTest::addColumn<int>("combinations");
QTest::addColumn<int>("depth");
- QTest::newRow("1*5") << 32 << 1 << 5;
- QTest::newRow("2*2") << 32 << 2 << 2;
- QTest::newRow("3*2") << 32 << 3 << 2;
- QTest::newRow("3*5") << 32 << 3 << 5;
+ QTest::newRow("1*5") << 1 << 5;
+ QTest::newRow("2*2") << 2 << 2;
+ QTest::newRow("3*2") << 3 << 2;
+ QTest::newRow("3*5") << 3 << 5;
}
void tst_qqmlchangeset::random()
{
- QFETCH(int, seed);
QFETCH(int, combinations);
QFETCH(int, depth);
- qsrand(seed);
-
int failures = 0;
for (int i = 0; i < 20000; ++i) {
QQmlChangeSet accumulatedSet;
@@ -1490,27 +1487,27 @@ void tst_qqmlchangeset::random()
for (int j = 0; j < combinations; ++j) {
QQmlChangeSet set;
for (int k = 0; k < depth; ++k) {
- switch (-(qrand() % 3)) {
+ switch (-QRandomGenerator::global()->bounded(3)) {
case InsertOp: {
- int index = qrand() % (modelCount + 1);
- int count = qrand() % 5 + 1;
+ int index = QRandomGenerator::global()->bounded(modelCount + 1);
+ int count = QRandomGenerator::global()->bounded(5) + 1;
set.insert(index, count);
input.append(Insert(index, count));
modelCount += count;
break;
}
case RemoveOp: {
- const int index = qrand() % (modelCount + 1);
- const int count = qrand() % (modelCount - index + 1);
+ const int index = QRandomGenerator::global()->bounded(modelCount + 1);
+ const int count = QRandomGenerator::global()->bounded(modelCount - index + 1);
set.remove(index, count);
input.append(Remove(index, count));
modelCount -= count;
break;
}
case MoveOp: {
- const int from = qrand() % (modelCount + 1);
- const int count = qrand() % (modelCount - from + 1);
- const int to = qrand() % (modelCount - count + 1);
+ const int from = QRandomGenerator::global()->bounded(modelCount + 1);
+ const int count = QRandomGenerator::global()->bounded(modelCount - from + 1);
+ const int to = QRandomGenerator::global()->bounded(modelCount - count + 1);
const int moveId = moveCount++;
set.move(from, to, count, moveId);
input.append(Move(from, to, count, moveId));
diff --git a/tests/auto/qml/qqmlcomponent/qqmlcomponent.pro b/tests/auto/qml/qqmlcomponent/qqmlcomponent.pro
index 0d501ebefd..54012e050c 100644
--- a/tests/auto/qml/qqmlcomponent/qqmlcomponent.pro
+++ b/tests/auto/qml/qqmlcomponent/qqmlcomponent.pro
@@ -2,7 +2,6 @@ CONFIG += testcase
TARGET = tst_qqmlcomponent
macx:CONFIG -= app_bundle
-INCLUDEPATH += ../../shared/
SOURCES += tst_qqmlcomponent.cpp \
../../shared/testhttpserver.cpp
diff --git a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp
index 3c78f6601e..105469fbcf 100644
--- a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp
+++ b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp
@@ -544,7 +544,7 @@ public:
QJSEngine *jsEngine = qjsEngine(this);
if (!jsEngine)
return;
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(jsEngine);
+ QV4::ExecutionEngine *v4 = jsEngine->handle();
if (!v4)
return;
QV4::Scope scope(v4);
diff --git a/tests/auto/qml/qqmlconnections/data/connection-no-signal-name.qml b/tests/auto/qml/qqmlconnections/data/connection-no-signal-name.qml
new file mode 100644
index 0000000000..462a9577ff
--- /dev/null
+++ b/tests/auto/qml/qqmlconnections/data/connection-no-signal-name.qml
@@ -0,0 +1,15 @@
+import QtQuick 2.4
+
+Item {
+ id: blaBlaBla
+ function hint() {
+ }
+
+ Connections {
+ //target: blaBlaBla
+ //onHint: hint();
+ on: true
+ }
+}
+
+
diff --git a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp
index fe45495f74..22e9724c61 100644
--- a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp
+++ b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp
@@ -54,6 +54,7 @@ private slots:
void enableDisable_QTBUG_36350();
void disabledAtStart();
void clearImplicitTarget();
+ void onWithoutASignal();
private:
QQmlEngine engine;
@@ -397,6 +398,15 @@ void tst_qqmlconnections::clearImplicitTarget()
delete item;
}
+void tst_qqmlconnections::onWithoutASignal()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("connection-no-signal-name.qml"));
+ QVERIFY(c.isError()); // Cannot assign to non-existent property "on" expected
+ QScopedPointer<QQuickItem> item(qobject_cast<QQuickItem*>(c.create()));
+ QVERIFY(item == nullptr); // should parse error, and not give us an item (or crash).
+}
+
QTEST_MAIN(tst_qqmlconnections)
#include "tst_qqmlconnections.moc"
diff --git a/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp b/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp
index 574e6e2834..783b5cb786 100644
--- a/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp
+++ b/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp
@@ -49,6 +49,7 @@ private slots:
void engineMethod();
void parentContext();
void setContextProperty();
+ void setContextProperties();
void setContextObject();
void destruction();
void idAsContextProperty();
@@ -366,6 +367,32 @@ void tst_qqmlcontext::setContextProperty()
}
}
+void tst_qqmlcontext::setContextProperties()
+{
+ QQmlContext ctxt(&engine);
+
+ TestObject obj1;
+ obj1.setA(3345);
+ TestObject obj2;
+ obj2.setA(-19);
+
+ QVector<QQmlContext::PropertyPair> properties;
+
+ properties.append({QString("a"), QVariant(10)});
+ properties.append({QString("b"), QVariant(19)});
+ properties.append({QString("d"), QVariant::fromValue<TestObject*>(&obj2)});
+ properties.append({QString("c"), QVariant(QString("Hello World!"))});
+ properties.append({QString("e"), QVariant::fromValue<TestObject*>(&obj1)});
+
+ ctxt.setContextProperties(properties);
+
+ TEST_CONTEXT_PROPERTY(&ctxt, a, QVariant(10));
+ TEST_CONTEXT_PROPERTY(&ctxt, b, QVariant(19));
+ TEST_CONTEXT_PROPERTY(&ctxt, c, QVariant(QString("Hello World!")));
+ TEST_CONTEXT_PROPERTY(&ctxt, d.a, QVariant(-19));
+ TEST_CONTEXT_PROPERTY(&ctxt, e.a, QVariant(3345));
+}
+
void tst_qqmlcontext::setContextObject()
{
QQmlContext ctxt(&engine);
@@ -777,7 +804,7 @@ void tst_qqmlcontext::contextLeak()
QV4::Scope scope(ddata->jsWrapper.engine());
QV4::ScopedValue scriptContextWrapper(scope);
scriptContextWrapper = context->importedScripts.valueRef()->as<QV4::Object>()->getIndexed(0);
- scriptContext = scriptContextWrapper->as<QV4::QmlContextWrapper>()->getContext();
+ scriptContext = scriptContextWrapper->as<QV4::QQmlContextWrapper>()->getContext();
}
}
diff --git a/tests/auto/qml/qqmlecmascript/data/assignDate.1.qml b/tests/auto/qml/qqmlecmascript/data/assignDate.1.qml
index efca6cdb80..8912d2a314 100644
--- a/tests/auto/qml/qqmlecmascript/data/assignDate.1.qml
+++ b/tests/auto/qml/qqmlecmascript/data/assignDate.1.qml
@@ -11,25 +11,26 @@ MyTypeObject {
dateTimeProperty = dateTimeVar
dateTimeProperty2 = dateTimeVar2
- // Commented properties do not currently test true:
- boolProperty = //(dateProperty.getTime() == dateVar.getTime()) &&
+ boolProperty = (dateProperty.getTime() == dateVar.getTime()) &&
(dateProperty.getFullYear() == 2009) &&
(dateProperty.getMonth() == 5-1) &&
- //(dateProperty.getDate() == 12) &&
- (dateProperty.getHours() == 0) &&
+ (dateProperty.getUTCDate() == 12) &&
+ (dateProperty.getUTCHours() == 0) &&
+ (dateProperty.getUTCMinutes() == 0) &&
+ (dateProperty.getUTCSeconds() == 0) &&
(dateTimeProperty.getTime() == dateTimeVar.getTime()) &&
(dateTimeProperty.getFullYear() == 2009) &&
(dateTimeProperty.getMonth() == 5-1) &&
- //(dateTimeProperty.getDate() == 12) &&
- //(dateTimeProperty.getHours() == 0) &&
- (dateTimeProperty.getMinutes() == 0) &&
- (dateTimeProperty.getSeconds() == 1) &&
+ (dateTimeProperty.getUTCDate() == 12) &&
+ (dateTimeProperty.getUTCHours() == 0) &&
+ (dateTimeProperty.getUTCMinutes() == 0) &&
+ (dateTimeProperty.getUTCSeconds() == 1) &&
(dateTimeProperty2.getTime() == dateTimeVar2.getTime()) &&
(dateTimeProperty2.getFullYear() == 2009) &&
(dateTimeProperty2.getMonth() == 5-1) &&
- //(dateTimeProperty2.getDate() == 12) &&
- //(dateTimeProperty2.getHours() == 23) &&
- (dateTimeProperty2.getMinutes() == 59) &&
- (dateTimeProperty2.getSeconds() == 59)
+ (dateTimeProperty2.getUTCDate() == 12) &&
+ (dateTimeProperty2.getUTCHours() == 23) &&
+ (dateTimeProperty2.getUTCMinutes() == 59) &&
+ (dateTimeProperty2.getUTCSeconds() == 59)
}
}
diff --git a/tests/auto/qml/qqmlecmascript/data/assignDate.2.qml b/tests/auto/qml/qqmlecmascript/data/assignDate.2.qml
index 71dd188f05..f8c1f6eb8f 100644
--- a/tests/auto/qml/qqmlecmascript/data/assignDate.2.qml
+++ b/tests/auto/qml/qqmlecmascript/data/assignDate.2.qml
@@ -12,24 +12,25 @@ MyTypeObject {
var dateTimeVar = new Date("2009-05-12T00:00:01")
var dateTimeVar2 = new Date("2009-05-12T23:59:59")
- // Commented properties do not currently test true:
- boolProperty = //(dateProperty.getTime() == dateVar.getTime()) &&
+ boolProperty = (dateProperty.getTime() == dateVar.getTime()) &&
(dateProperty.getFullYear() == 2009) &&
(dateProperty.getMonth() == 5-1) &&
- //(dateProperty.getDate() == 12) &&
- (dateProperty.getHours() == 0) &&
+ (dateProperty.getUTCDate() == 12) &&
+ (dateProperty.getUTCHours() == 0) &&
+ (dateProperty.getUTCMinutes() == 0) &&
+ (dateProperty.getUTCSeconds() == 0) &&
(dateTimeProperty.getTime() == dateTimeVar.getTime()) &&
(dateTimeProperty.getFullYear() == 2009) &&
(dateTimeProperty.getMonth() == 5-1) &&
- //(dateTimeProperty.getDate() == 12) &&
- //(dateTimeProperty.getHours() == 0) &&
+ (dateTimeProperty.getDate() == 12) &&
+ (dateTimeProperty.getHours() == 0) &&
(dateTimeProperty.getMinutes() == 0) &&
(dateTimeProperty.getSeconds() == 1) &&
(dateTimeProperty2.getTime() == dateTimeVar2.getTime()) &&
(dateTimeProperty2.getFullYear() == 2009) &&
(dateTimeProperty2.getMonth() == 5-1) &&
- //(dateTimeProperty2.getDate() == 12) &&
- //(dateTimeProperty2.getHours() == 23) &&
+ (dateTimeProperty2.getDate() == 12) &&
+ (dateTimeProperty2.getHours() == 23) &&
(dateTimeProperty2.getMinutes() == 59) &&
(dateTimeProperty2.getSeconds() == 59)
}
diff --git a/tests/auto/qml/qqmlecmascript/data/assignDate.3.qml b/tests/auto/qml/qqmlecmascript/data/assignDate.3.qml
index 2cf740645c..e960eef193 100644
--- a/tests/auto/qml/qqmlecmascript/data/assignDate.3.qml
+++ b/tests/auto/qml/qqmlecmascript/data/assignDate.3.qml
@@ -2,35 +2,36 @@ import Qt.test 1.0
import QtQuick 2.0
MyTypeObject {
- dateProperty: if (1) "2009-05-12Z"
+ dateProperty: if (1) "2009-05-12"
dateTimeProperty: if (1) "2009-05-12T00:00:01Z"
dateTimeProperty2: if (1) "2009-05-12T23:59:59Z"
boolProperty: false
Component.onCompleted: {
- var dateVar = new Date("2009-05-12Z")
+ var dateVar = new Date("2009-05-12")
var dateTimeVar = new Date("2009-05-12T00:00:01Z")
var dateTimeVar2 = new Date("2009-05-12T23:59:59Z")
- // Commented properties do not currently test true:
- boolProperty = //(dateProperty.getTime() == dateVar.getTime()) &&
+ boolProperty = (dateProperty.getTime() == dateVar.getTime()) &&
(dateProperty.getFullYear() == 2009) &&
(dateProperty.getMonth() == 5-1) &&
- //(dateProperty.getDate() == 12) &&
- (dateProperty.getHours() == 0) &&
+ (dateProperty.getUTCDate() == 12) &&
+ (dateProperty.getUTCHours() == 0) &&
+ (dateProperty.getUTCMinutes() == 0) &&
+ (dateProperty.getUTCSeconds() == 0) &&
(dateTimeProperty.getTime() == dateTimeVar.getTime()) &&
(dateTimeProperty.getFullYear() == 2009) &&
(dateTimeProperty.getMonth() == 5-1) &&
- //(dateTimeProperty.getDate() == 12) &&
- //(dateTimeProperty.getHours() == 0) &&
- (dateTimeProperty.getMinutes() == 0) &&
- (dateTimeProperty.getSeconds() == 1) &&
+ (dateTimeProperty.getUTCDate() == 12) &&
+ (dateTimeProperty.getUTCHours() == 0) &&
+ (dateTimeProperty.getUTCMinutes() == 0) &&
+ (dateTimeProperty.getUTCSeconds() == 1) &&
(dateTimeProperty2.getTime() == dateTimeVar2.getTime()) &&
(dateTimeProperty2.getFullYear() == 2009) &&
(dateTimeProperty2.getMonth() == 5-1) &&
- //(dateTimeProperty2.getDate() == 12) &&
- //(dateTimeProperty2.getHours() == 23) &&
- (dateTimeProperty2.getMinutes() == 59) &&
- (dateTimeProperty2.getSeconds() == 59)
+ (dateTimeProperty2.getUTCDate() == 12) &&
+ (dateTimeProperty2.getUTCHours() == 23) &&
+ (dateTimeProperty2.getUTCMinutes() == 59) &&
+ (dateTimeProperty2.getUTCSeconds() == 59)
}
}
diff --git a/tests/auto/qml/qqmlecmascript/data/assignDate.4.qml b/tests/auto/qml/qqmlecmascript/data/assignDate.4.qml
index 9b4975c833..6dd29afbc9 100644
--- a/tests/auto/qml/qqmlecmascript/data/assignDate.4.qml
+++ b/tests/auto/qml/qqmlecmascript/data/assignDate.4.qml
@@ -2,35 +2,36 @@ import Qt.test 1.0
import QtQuick 2.0
MyTypeObject {
- dateProperty: if (1) new Date("2009-05-12Z")
+ dateProperty: if (1) new Date("2009-05-12")
dateTimeProperty: if (1) new Date("2009-05-12T00:00:01Z")
dateTimeProperty2: if (1) new Date("2009-05-12T23:59:59Z")
boolProperty: false
Component.onCompleted: {
- var dateVar = new Date("2009-05-12Z")
+ var dateVar = new Date("2009-05-12")
var dateTimeVar = new Date("2009-05-12T00:00:01Z")
var dateTimeVar2 = new Date("2009-05-12T23:59:59Z")
- // Commented properties do not currently test true:
- boolProperty = //(dateProperty.getTime() == dateVar.getTime()) &&
+ boolProperty = (dateProperty.getTime() == dateVar.getTime()) &&
(dateProperty.getFullYear() == 2009) &&
(dateProperty.getMonth() == 5-1) &&
- //(dateProperty.getDate() == 12) &&
- (dateProperty.getHours() == 0) &&
+ (dateProperty.getUTCDate() == 12) &&
+ (dateProperty.getUTCHours() == 0) &&
+ (dateProperty.getUTCMinutes() == 0) &&
+ (dateProperty.getUTCSeconds() == 0) &&
(dateTimeProperty.getTime() == dateTimeVar.getTime()) &&
(dateTimeProperty.getFullYear() == 2009) &&
(dateTimeProperty.getMonth() == 5-1) &&
- //(dateTimeProperty.getDate() == 12) &&
- //(dateTimeProperty.getHours() == 0) &&
- (dateTimeProperty.getMinutes() == 0) &&
- (dateTimeProperty.getSeconds() == 1) &&
+ (dateTimeProperty.getUTCDate() == 12) &&
+ (dateTimeProperty.getUTCHours() == 0) &&
+ (dateTimeProperty.getUTCMinutes() == 0) &&
+ (dateTimeProperty.getUTCSeconds() == 1) &&
(dateTimeProperty2.getTime() == dateTimeVar2.getTime()) &&
(dateTimeProperty2.getFullYear() == 2009) &&
(dateTimeProperty2.getMonth() == 5-1) &&
- //(dateTimeProperty2.getDate() == 12) &&
- //(dateTimeProperty2.getHours() == 23) &&
- (dateTimeProperty2.getMinutes() == 59) &&
- (dateTimeProperty2.getSeconds() == 59)
+ (dateTimeProperty2.getUTCDate() == 12) &&
+ (dateTimeProperty2.getUTCHours() == 23) &&
+ (dateTimeProperty2.getUTCMinutes() == 59) &&
+ (dateTimeProperty2.getUTCSeconds() == 59)
}
}
diff --git a/tests/auto/qml/qqmlecmascript/data/assignDate.5.qml b/tests/auto/qml/qqmlecmascript/data/assignDate.5.qml
index 2cf740645c..cfadaafc54 100644
--- a/tests/auto/qml/qqmlecmascript/data/assignDate.5.qml
+++ b/tests/auto/qml/qqmlecmascript/data/assignDate.5.qml
@@ -2,35 +2,36 @@ import Qt.test 1.0
import QtQuick 2.0
MyTypeObject {
- dateProperty: if (1) "2009-05-12Z"
- dateTimeProperty: if (1) "2009-05-12T00:00:01Z"
- dateTimeProperty2: if (1) "2009-05-12T23:59:59Z"
+ dateProperty: if (1) "2009-05-12"
+ dateTimeProperty: if (1) "2009-05-12T00:00:01+02:00"
+ dateTimeProperty2: if (1) "2009-05-12T23:59:59+02:00"
boolProperty: false
Component.onCompleted: {
- var dateVar = new Date("2009-05-12Z")
- var dateTimeVar = new Date("2009-05-12T00:00:01Z")
- var dateTimeVar2 = new Date("2009-05-12T23:59:59Z")
+ var dateVar = new Date("2009-05-12")
+ var dateTimeVar = new Date("2009-05-12T00:00:01+02:00")
+ var dateTimeVar2 = new Date("2009-05-12T23:59:59+02:00")
- // Commented properties do not currently test true:
- boolProperty = //(dateProperty.getTime() == dateVar.getTime()) &&
+ boolProperty = (dateProperty.getTime() == dateVar.getTime()) &&
(dateProperty.getFullYear() == 2009) &&
(dateProperty.getMonth() == 5-1) &&
- //(dateProperty.getDate() == 12) &&
- (dateProperty.getHours() == 0) &&
+ (dateProperty.getUTCDate() == 12) &&
+ (dateProperty.getUTCHours() == 0) &&
+ (dateProperty.getUTCMinutes() == 0) &&
+ (dateProperty.getUTCSeconds() == 0) &&
(dateTimeProperty.getTime() == dateTimeVar.getTime()) &&
(dateTimeProperty.getFullYear() == 2009) &&
(dateTimeProperty.getMonth() == 5-1) &&
- //(dateTimeProperty.getDate() == 12) &&
- //(dateTimeProperty.getHours() == 0) &&
- (dateTimeProperty.getMinutes() == 0) &&
- (dateTimeProperty.getSeconds() == 1) &&
+ (dateTimeProperty.getUTCDate() == 11) &&
+ (dateTimeProperty.getUTCHours() == 22) &&
+ (dateTimeProperty.getUTCMinutes() == 0) &&
+ (dateTimeProperty.getUTCSeconds() == 1) &&
(dateTimeProperty2.getTime() == dateTimeVar2.getTime()) &&
(dateTimeProperty2.getFullYear() == 2009) &&
(dateTimeProperty2.getMonth() == 5-1) &&
- //(dateTimeProperty2.getDate() == 12) &&
- //(dateTimeProperty2.getHours() == 23) &&
- (dateTimeProperty2.getMinutes() == 59) &&
- (dateTimeProperty2.getSeconds() == 59)
+ (dateTimeProperty2.getUTCDate() == 12) &&
+ (dateTimeProperty2.getUTCHours() == 21) &&
+ (dateTimeProperty2.getUTCMinutes() == 59) &&
+ (dateTimeProperty2.getUTCSeconds() == 59)
}
}
diff --git a/tests/auto/qml/qqmlecmascript/data/assignDate.6.qml b/tests/auto/qml/qqmlecmascript/data/assignDate.6.qml
index 73e26db0c8..97cd0d1e60 100644
--- a/tests/auto/qml/qqmlecmascript/data/assignDate.6.qml
+++ b/tests/auto/qml/qqmlecmascript/data/assignDate.6.qml
@@ -3,34 +3,35 @@ import QtQuick 2.0
MyTypeObject {
dateProperty: if (1) new Date("2009-05-12")
- dateTimeProperty: if (1) new Date("2009-05-12T02:00:01+02:00")
- dateTimeProperty2: if (1) new Date("2009-05-13T01:59:59+02:00")
+ dateTimeProperty: if (1) new Date("2009-05-12T00:00:01+02:00")
+ dateTimeProperty2: if (1) new Date("2009-05-12T23:59:59+02:00")
boolProperty: false
Component.onCompleted: {
var dateVar = new Date("2009-05-12")
- var dateTimeVar = new Date("2009-05-12T02:00:01+02:00")
- var dateTimeVar2 = new Date("2009-05-13T01:59:59+02:00")
+ var dateTimeVar = new Date("2009-05-12T00:00:01+02:00")
+ var dateTimeVar2 = new Date("2009-05-12T23:59:59+02:00")
- // Commented properties do not currently test true:
- boolProperty = //(dateProperty.getTime() == dateVar.getTime()) &&
+ boolProperty = (dateProperty.getTime() == dateVar.getTime()) &&
(dateProperty.getFullYear() == 2009) &&
(dateProperty.getMonth() == 5-1) &&
- //(dateProperty.getDate() == 12) &&
- (dateProperty.getHours() == 0) &&
+ (dateProperty.getUTCDate() == 12) &&
+ (dateProperty.getUTCHours() == 0) &&
+ (dateProperty.getUTCMinutes() == 0) &&
+ (dateProperty.getUTCSeconds() == 0) &&
(dateTimeProperty.getTime() == dateTimeVar.getTime()) &&
(dateTimeProperty.getFullYear() == 2009) &&
(dateTimeProperty.getMonth() == 5-1) &&
- //(dateTimeProperty.getDate() == 12) &&
- //(dateTimeProperty.getHours() == 0) &&
- (dateTimeProperty.getMinutes() == 0) &&
- (dateTimeProperty.getSeconds() == 1) &&
+ (dateTimeProperty.getUTCDate() == 11) &&
+ (dateTimeProperty.getUTCHours() == 22) &&
+ (dateTimeProperty.getUTCMinutes() == 0) &&
+ (dateTimeProperty.getUTCSeconds() == 1) &&
(dateTimeProperty2.getTime() == dateTimeVar2.getTime()) &&
(dateTimeProperty2.getFullYear() == 2009) &&
(dateTimeProperty2.getMonth() == 5-1) &&
- //(dateTimeProperty2.getDate() == 12) &&
- //(dateTimeProperty2.getHours() == 23) &&
- (dateTimeProperty2.getMinutes() == 59) &&
- (dateTimeProperty2.getSeconds() == 59)
+ (dateTimeProperty2.getUTCDate() == 12) &&
+ (dateTimeProperty2.getUTCHours() == 21) &&
+ (dateTimeProperty2.getUTCMinutes() == 59) &&
+ (dateTimeProperty2.getUTCSeconds() == 59)
}
}
diff --git a/tests/auto/qml/qqmlecmascript/data/assignDate.qml b/tests/auto/qml/qqmlecmascript/data/assignDate.qml
index 14fe20787b..73677e99f1 100644
--- a/tests/auto/qml/qqmlecmascript/data/assignDate.qml
+++ b/tests/auto/qml/qqmlecmascript/data/assignDate.qml
@@ -7,28 +7,31 @@ MyTypeObject {
var dateTimeVar = new Date("2009-05-12T00:00:01")
var dateTimeVar2 = new Date("2009-05-12T23:59:59")
+ // Date, with no zone specified, is implicitly UTC
dateProperty = dateVar
+ // Date-time, with no zone, is implicitly local-time
dateTimeProperty = dateTimeVar
dateTimeProperty2 = dateTimeVar2
- // Commented properties do not currently test true:
- boolProperty = //(dateProperty.getTime() == dateVar.getTime()) &&
+ boolProperty = (dateProperty.getTime() == dateVar.getTime()) &&
(dateProperty.getFullYear() == 2009) &&
(dateProperty.getMonth() == 5-1) &&
- //(dateProperty.getDate() == 12) &&
- (dateProperty.getHours() == 0) &&
+ (dateProperty.getDate() == 12) &&
+ (dateProperty.getUTCHours() == 0) &&
+ (dateProperty.getUTCMinutes() == 0) &&
+ (dateProperty.getUTCSeconds() == 0) &&
(dateTimeProperty.getTime() == dateTimeVar.getTime()) &&
(dateTimeProperty.getFullYear() == 2009) &&
(dateTimeProperty.getMonth() == 5-1) &&
- //(dateTimeProperty.getDate() == 12) &&
- //(dateTimeProperty.getHours() == 0) &&
+ (dateTimeProperty.getDate() == 12) &&
+ (dateTimeProperty.getHours() == 0) &&
(dateTimeProperty.getMinutes() == 0) &&
(dateTimeProperty.getSeconds() == 1) &&
(dateTimeProperty2.getTime() == dateTimeVar2.getTime()) &&
(dateTimeProperty2.getFullYear() == 2009) &&
(dateTimeProperty2.getMonth() == 5-1) &&
- //(dateTimeProperty2.getDate() == 12) &&
- //(dateTimeProperty2.getHours() == 23) &&
+ (dateTimeProperty2.getDate() == 12) &&
+ (dateTimeProperty2.getHours() == 23) &&
(dateTimeProperty2.getMinutes() == 59) &&
(dateTimeProperty2.getSeconds() == 59)
}
diff --git a/tests/auto/qml/qqmlecmascript/data/dynamicString.qml b/tests/auto/qml/qqmlecmascript/data/dynamicString.qml
index 5693794c71..c704161eb5 100644
--- a/tests/auto/qml/qqmlecmascript/data/dynamicString.qml
+++ b/tests/auto/qml/qqmlecmascript/data/dynamicString.qml
@@ -11,6 +11,6 @@ MyTypeObject {
date.setHours(5);
date.setMinutes(30);
date.setSeconds(50);
- stringProperty = stringProperty.arg("Hello World").arg(false).arg(true).arg(100).arg(-100).arg(3.1415926).arg(Qt.formatDateTime(date, "yyyy-MM-dd hh::mm:ss"));
+ stringProperty = stringProperty.arg("Hello World").arg(false).arg(true).arg(100).arg(-100).arg(Math.PI).arg(Qt.formatDateTime(date, "yyyy-MM-dd hh::mm:ss"));
}
}
diff --git a/tests/auto/qml/qqmlecmascript/data/nonNotifyableConstant.qml b/tests/auto/qml/qqmlecmascript/data/nonNotifyableConstant.qml
new file mode 100644
index 0000000000..424b3e8b07
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/nonNotifyableConstant.qml
@@ -0,0 +1,5 @@
+import Qt.test 1.0
+
+MyQmlObject {
+ objectName: trueProperty ? "foo" : "bar"
+}
diff --git a/tests/auto/qml/qqmlecmascript/data/sequenceSort.qml b/tests/auto/qml/qqmlecmascript/data/sequenceSort.qml
index 74c7cda9a3..c6732efc05 100644
--- a/tests/auto/qml/qqmlecmascript/data/sequenceSort.qml
+++ b/tests/auto/qml/qqmlecmascript/data/sequenceSort.qml
@@ -52,7 +52,11 @@ Item {
function doStringTest(stringList, fn) {
var expected = createExpected(stringList, fn);
var actual = msc.strings(stringList);
- return checkResults(expected, actual, fn);
+ var actual2 = msc.stringsVector(stringList);
+ var actual3 = msc.stringsStdVector(stringList);
+ return checkResults(expected, actual, fn)
+ && checkResults(expected, actual2, fn)
+ && checkResults(expected, actual3, fn)
}
function doIntTest(intList, fn) {
var expected = createExpected(intList, fn);
@@ -67,12 +71,16 @@ Item {
function doIntVectorTest(intList, fn) {
var expected = createExpected(intList, fn);
var actual = msc.integerVector(intList);
- return checkResults(expected, actual, fn);
+ var actual2 = msc.integerStdVector(intList);
+ return checkResults(expected, actual, fn)
+ && checkResults(expected, actual2, fn)
}
function doRealVectorTest(realList, fn) {
var expected = createExpected(realList, fn);
var actual = msc.realVector(realList);
- return checkResults(expected, actual, fn);
+ var actual2 = msc.realStdVector(realList);
+ return checkResults(expected, actual, fn)
+ && checkResults(expected, actual2, fn)
}
function test_qtbug_25269(useCustomCompare) {
diff --git a/tests/auto/qml/qqmlecmascript/qqmlecmascript.pro b/tests/auto/qml/qqmlecmascript/qqmlecmascript.pro
index 101181bba0..0dd9365366 100644
--- a/tests/auto/qml/qqmlecmascript/qqmlecmascript.pro
+++ b/tests/auto/qml/qqmlecmascript/qqmlecmascript.pro
@@ -7,7 +7,6 @@ SOURCES += tst_qqmlecmascript.cpp \
../../shared/testhttpserver.cpp
HEADERS += testtypes.h \
../../shared/testhttpserver.h
-INCLUDEPATH += ../../shared
RESOURCES += qqmlecmascript.qrc
diff --git a/tests/auto/qml/qqmlecmascript/testtypes.cpp b/tests/auto/qml/qqmlecmascript/testtypes.cpp
index 13bb0435cd..80da5d7e52 100644
--- a/tests/auto/qml/qqmlecmascript/testtypes.cpp
+++ b/tests/auto/qml/qqmlecmascript/testtypes.cpp
@@ -290,6 +290,15 @@ public:
{
return stringList;
}
+ Q_INVOKABLE QVector<QString> stringsVector(const QStringList& stringList) const
+ {
+ return stringList.toVector();
+ }
+ Q_INVOKABLE
+ std::vector<QString> stringsStdVector(const QStringList& stringList) const
+ {
+ return std::vector<QString>(stringList.begin(), stringList.end());
+ }
Q_INVOKABLE QList<int> integers(QList<int> v) const
{
return v;
@@ -306,14 +315,29 @@ public:
{
return v;
}
+ Q_INVOKABLE
+ std::vector<int> integerStdVector(std::vector<int> v) const
+ {
+ return v;
+ }
Q_INVOKABLE QVector<qreal> realVector(QVector<qreal> v) const
{
return v;
}
+ Q_INVOKABLE
+ std::vector<qreal> realStdVector(std::vector<qreal> v) const
+ {
+ return v;
+ }
Q_INVOKABLE QVector<bool> boolVector(QVector<bool> v) const
{
return v;
}
+ Q_INVOKABLE
+ std::vector<bool> boolStdVector(std::vector<bool> v) const
+ {
+ return v;
+ }
};
static MyInheritedQmlObject *theSingletonObject = 0;
diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h
index ec20714c51..8d89df31db 100644
--- a/tests/auto/qml/qqmlecmascript/testtypes.h
+++ b/tests/auto/qml/qqmlecmascript/testtypes.h
@@ -1262,7 +1262,6 @@ public:
{
CircularReferenceObject *retn = new CircularReferenceObject(parent);
retn->m_dtorCount = m_dtorCount;
- retn->m_engine = m_engine;
return retn;
}
@@ -1283,14 +1282,8 @@ public:
thisObject->defineDefaultProperty(QStringLiteral("autoTestStrongRef"), v);
}
- void setEngine(QQmlEngine* declarativeEngine)
- {
- m_engine = QQmlEnginePrivate::get(declarativeEngine)->v8engine();
- }
-
private:
int *m_dtorCount;
- QV8Engine* m_engine;
};
Q_DECLARE_METATYPE(CircularReferenceObject*)
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index 14447383c1..5e752d124b 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2017 Crimson AS <info@crimson.no>
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
@@ -42,6 +43,7 @@
#include "../../shared/util.h"
#include <private/qv4functionobject_p.h>
#include <private/qv4scopedvalue_p.h>
+#include <private/qv4jscall_p.h>
#include <private/qv4alloca_p.h>
#include <private/qv4runtime_p.h>
#include <private/qv4object_p.h>
@@ -259,6 +261,7 @@ private slots:
void doubleEvaluate();
void forInLoop();
void nonNotifyable();
+ void nonNotifyableConstant();
void deleteWhileBindingRunning();
void callQtInvokables();
void resolveClashingProperties();
@@ -335,9 +338,17 @@ private slots:
void stringify_qtbug_50592();
void instanceof_data();
void instanceof();
+ void constkw_data();
+ void constkw();
+ void redefineGlobalProp();
void freeze_empty_object();
void singleBlockLoops();
void qtbug_60547();
+ void delayLoadingArgs();
+ void manyArguments();
+ void forInIterator();
+ void localForInIterator();
+ void shadowedFunctionName();
void anotherNaN();
private:
@@ -440,29 +451,37 @@ void tst_qqmlecmascript::assignBasicTypes()
void tst_qqmlecmascript::assignDate_data()
{
QTest::addColumn<QUrl>("source");
+ QTest::addColumn<int>("timeOffset"); // -1 for local-time, else minutes from UTC
- QTest::newRow("Component.onComplete JS Parse") << testFileUrl("assignDate.qml");
- QTest::newRow("Component.onComplete JS") << testFileUrl("assignDate.1.qml");
- QTest::newRow("Binding JS") << testFileUrl("assignDate.2.qml");
- QTest::newRow("Binding UTC") << testFileUrl("assignDate.3.qml");
- QTest::newRow("Binding JS UTC") << testFileUrl("assignDate.4.qml");
- QTest::newRow("Binding UTC+2") << testFileUrl("assignDate.5.qml");
- QTest::newRow("Binding JS UTC+2 ") << testFileUrl("assignDate.6.qml");
+ QTest::newRow("Component.onComplete JS Parse") << testFileUrl("assignDate.qml") << -1;
+ QTest::newRow("Component.onComplete JS") << testFileUrl("assignDate.1.qml") << 0;
+ QTest::newRow("Binding JS") << testFileUrl("assignDate.2.qml") << -1;
+ QTest::newRow("Binding UTC") << testFileUrl("assignDate.3.qml") << 0;
+ QTest::newRow("Binding JS UTC") << testFileUrl("assignDate.4.qml") << 0;
+ QTest::newRow("Binding UTC+2") << testFileUrl("assignDate.5.qml") << 120;
+ QTest::newRow("Binding JS UTC+2 ") << testFileUrl("assignDate.6.qml") << 120;
}
void tst_qqmlecmascript::assignDate()
{
QFETCH(QUrl, source);
+ QFETCH(int, timeOffset);
QQmlComponent component(&engine, source);
QScopedPointer<QObject> obj(component.create());
MyTypeObject *object = qobject_cast<MyTypeObject *>(obj.data());
QVERIFY(object != 0);
- // Dates received from JS are automatically converted to local time
- QDate expectedDate(QDateTime(QDate(2009, 5, 12), QTime(0, 0, 0), Qt::UTC).toLocalTime().date());
- QDateTime expectedDateTime(QDateTime(QDate(2009, 5, 12), QTime(0, 0, 1), Qt::UTC).toLocalTime());
- QDateTime expectedDateTime2(QDateTime(QDate(2009, 5, 12), QTime(23, 59, 59), Qt::UTC).toLocalTime());
+ QDate expectedDate(2009, 5, 12);
+ QDateTime expectedDateTime;
+ QDateTime expectedDateTime2;
+ if (timeOffset == -1) {
+ expectedDateTime = QDateTime(QDate(2009, 5, 12), QTime(0, 0, 1), Qt::LocalTime);
+ expectedDateTime2 = QDateTime(QDate(2009, 5, 12), QTime(23, 59, 59), Qt::LocalTime);
+ } else {
+ expectedDateTime = QDateTime(QDate(2009, 5, 12), QTime(0, 0, 1), Qt::OffsetFromUTC, timeOffset * 60);
+ expectedDateTime2 = QDateTime(QDate(2009, 5, 12), QTime(23, 59, 59), Qt::OffsetFromUTC, timeOffset * 60);
+ }
QCOMPARE(object->dateProperty(), expectedDate);
QCOMPARE(object->dateTimeProperty(), expectedDateTime);
@@ -2329,13 +2348,13 @@ void tst_qqmlecmascript::regExpBug()
}
}
-static inline bool evaluate_error(QV8Engine *engine, const QV4::Value &o, const char *source)
+static inline bool evaluate_error(QV4::ExecutionEngine *v4, const QV4::Value &o, const char *source)
{
QString functionSource = QLatin1String("(function(object) { return ") +
QLatin1String(source) + QLatin1String(" })");
- QV4::Scope scope(QV8Engine::getV4(engine));
- QV4::Script program(QV4::ScopedContext(scope, scope.engine->rootContext()), functionSource);
+ QV4::Scope scope(v4);
+ QV4::Script program(QV4::ScopedContext(scope, scope.engine->rootContext()), QV4::Compiler::EvalCode, functionSource);
program.inheritContext = true;
QV4::ScopedFunctionObject function(scope, program.run());
@@ -2343,10 +2362,10 @@ static inline bool evaluate_error(QV8Engine *engine, const QV4::Value &o, const
scope.engine->catchException();
return true;
}
- QV4::ScopedCallData d(scope, 1);
- d->args[0] = o;
- d->thisObject = engine->global();
- function->call(scope, d);
+ QV4::JSCallData jsCallData(scope, 1);
+ jsCallData->args[0] = o;
+ *jsCallData->thisObject = v4->global();
+ function->call(jsCallData);
if (scope.engine->hasException) {
scope.engine->catchException();
return true;
@@ -2354,14 +2373,14 @@ static inline bool evaluate_error(QV8Engine *engine, const QV4::Value &o, const
return false;
}
-static inline bool evaluate_value(QV8Engine *engine, const QV4::Value &o,
+static inline bool evaluate_value(QV4::ExecutionEngine *v4, const QV4::Value &o,
const char *source, const QV4::Value &result)
{
QString functionSource = QLatin1String("(function(object) { return ") +
QLatin1String(source) + QLatin1String(" })");
- QV4::Scope scope(QV8Engine::getV4(engine));
- QV4::Script program(QV4::ScopedContext(scope, scope.engine->rootContext()), functionSource);
+ QV4::Scope scope(v4);
+ QV4::Script program(QV4::ScopedContext(scope, scope.engine->rootContext()), QV4::Compiler::EvalCode, functionSource);
program.inheritContext = true;
QV4::ScopedFunctionObject function(scope, program.run());
@@ -2372,26 +2391,27 @@ static inline bool evaluate_value(QV8Engine *engine, const QV4::Value &o,
if (!function)
return false;
- QV4::ScopedCallData d(scope, 1);
- d->args[0] = o;
- d->thisObject = engine->global();
- function->call(scope, d);
+ QV4::ScopedValue value(scope);
+ QV4::JSCallData jsCallData(scope, 1);
+ jsCallData->args[0] = o;
+ *jsCallData->thisObject = v4->global();
+ value = function->call(jsCallData);
if (scope.engine->hasException) {
scope.engine->catchException();
return false;
}
- return QV4::Runtime::method_strictEqual(scope.result, result);
+ return QV4::Runtime::method_strictEqual(value, result);
}
-static inline QV4::ReturnedValue evaluate(QV8Engine *engine, const QV4::Value &o,
- const char *source)
+static inline QV4::ReturnedValue evaluate(QV4::ExecutionEngine *v4, const QV4::Value &o,
+ const char *source)
{
QString functionSource = QLatin1String("(function(object) { return ") +
QLatin1String(source) + QLatin1String(" })");
- QV4::Scope scope(QV8Engine::getV4(engine));
+ QV4::Scope scope(v4);
- QV4::Script program(QV4::ScopedContext(scope, scope.engine->rootContext()), functionSource);
+ QV4::Script program(QV4::ScopedContext(scope, scope.engine->rootContext()), QV4::Compiler::EvalCode, functionSource);
program.inheritContext = true;
QV4::ScopedFunctionObject function(scope, program.run());
@@ -2401,15 +2421,15 @@ static inline QV4::ReturnedValue evaluate(QV8Engine *engine, const QV4::Value &o
}
if (!function)
return QV4::Encode::undefined();
- QV4::ScopedCallData d(scope, 1);
- d->args[0] = o;
- d->thisObject = engine->global();
- function->call(scope, d);
+ QV4::JSCallData jsCallData(scope, 1);
+ jsCallData->args[0] = o;
+ *jsCallData->thisObject = v4->global();
+ QV4::ScopedValue result(scope, function->call(jsCallData));
if (scope.engine->hasException) {
scope.engine->catchException();
return QV4::Encode::undefined();
}
- return scope.result.asReturnedValue();
+ return result->asReturnedValue();
}
#define EVALUATE_ERROR(source) evaluate_error(engine, object, source)
@@ -2423,12 +2443,11 @@ void tst_qqmlecmascript::callQtInvokables()
MyInvokableObject *o = new MyInvokableObject();
QQmlEngine qmlengine;
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(&qmlengine);
- QV8Engine *engine = ep->v8engine();
- QV4::Scope scope(QV8Engine::getV4(engine));
+ QV4::ExecutionEngine *engine = qmlengine.handle();
+ QV4::Scope scope(engine);
- QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(QV8Engine::getV4(engine), o));
+ QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(engine, o));
// Non-existent methods
o->reset();
@@ -2996,9 +3015,8 @@ void tst_qqmlecmascript::resolveClashingProperties()
{
ClashingNames *o = new ClashingNames();
QQmlEngine qmlengine;
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(&qmlengine);
- QV4::ExecutionEngine *engine = QV8Engine::getV4(ep->v8engine());
+ QV4::ExecutionEngine *engine = qmlengine.handle();
QV4::Scope scope(engine);
QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(engine, o));
@@ -4028,11 +4046,10 @@ void tst_qqmlecmascript::verifyContextLifetime(QQmlContextData *ctxt) {
QQmlContextData *childCtxt = ctxt->childContexts;
if (!ctxt->importedScripts.isNullOrUndefined()) {
- QV8Engine *engine = QV8Engine::get(ctxt->engine);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
+ QV4::ExecutionEngine *v4 = ctxt->engine->handle();
QV4::Scope scope(v4);
QV4::ScopedArrayObject scripts(scope, ctxt->importedScripts.value());
- QV4::Scoped<QV4::QmlContextWrapper> qml(scope);
+ QV4::Scoped<QV4::QQmlContextWrapper> qml(scope);
for (quint32 i = 0; i < scripts->getLength(); ++i) {
QQmlContextData *scriptContext, *newContext;
qml = scripts->getIndexed(i);
@@ -4041,7 +4058,7 @@ void tst_qqmlecmascript::verifyContextLifetime(QQmlContextData *ctxt) {
qml = QV4::Encode::undefined();
{
- QV4::Scope scope(QV8Engine::getV4((engine)));
+ QV4::Scope scope(v4);
QV4::ScopedContext temporaryScope(scope, QV4::QmlContext::create(scope.engine->rootContext(), scriptContext, 0));
Q_UNUSED(temporaryScope)
}
@@ -4358,8 +4375,7 @@ void tst_qqmlecmascript::scarceResources_other()
QPixmap origPixmap(100, 100);
origPixmap.fill(Qt::blue);
QString srp_name, expectedWarning;
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(&engine);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(ep->v8engine());
+ QV4::ExecutionEngine *v4 = engine.handle();
ScarceResourceObject *eo = 0;
QObject *srsc = 0;
QObject *object = 0;
@@ -4730,8 +4746,7 @@ void tst_qqmlecmascript::scarceResources()
QFETCH(QVariantList, expectedValues);
QFETCH(QStringList, expectedErrors);
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(&engine);
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(ep->v8engine());
+ QV4::ExecutionEngine *v4 = engine.handle();
ScarceResourceObject *eo = 0;
QObject *object = 0;
@@ -5171,9 +5186,9 @@ void tst_qqmlecmascript::propertyVarInheritance()
// XXX NOTE: this is very implementation dependent. QDVMEMO->vmeProperty() is the only
// public function which can return us a handle to something in the varProperties array.
QV4::ReturnedValue tmp = icovmemo->vmeProperty(ico5->metaObject()->indexOfProperty("circ"));
- icoCanaryHandle.set(QQmlEnginePrivate::getV4Engine(&engine), tmp);
+ icoCanaryHandle.set(engine.handle(), tmp);
tmp = ccovmemo->vmeProperty(cco5->metaObject()->indexOfProperty("circ"));
- ccoCanaryHandle.set(QQmlEnginePrivate::getV4Engine(&engine), tmp);
+ ccoCanaryHandle.set(engine.handle(), tmp);
tmp = QV4::Encode::null();
QVERIFY(!icoCanaryHandle.isUndefined());
QVERIFY(!ccoCanaryHandle.isUndefined());
@@ -5211,7 +5226,7 @@ void tst_qqmlecmascript::propertyVarInheritance2()
QCOMPARE(childObject->property("textCanary").toInt(), 10);
QV4::WeakValue childObjectVarArrayValueHandle;
{
- childObjectVarArrayValueHandle.set(QQmlEnginePrivate::getV4Engine(&engine),
+ childObjectVarArrayValueHandle.set(engine.handle(),
QQmlVMEMetaObject::get(childObject)->vmeProperty(childObject->metaObject()->indexOfProperty("vp")));
QVERIFY(!childObjectVarArrayValueHandle.isUndefined());
gc(engine);
@@ -5299,7 +5314,6 @@ void tst_qqmlecmascript::handleReferenceManagement()
QObject *object = component.create();
QVERIFY(object != 0);
CircularReferenceObject *cro = object->findChild<CircularReferenceObject*>("cro");
- cro->setEngine(&hrmEngine);
cro->setDtorCount(&dtorCount);
QMetaObject::invokeMethod(object, "createReference");
gc(hrmEngine);
@@ -5319,7 +5333,6 @@ void tst_qqmlecmascript::handleReferenceManagement()
QObject *object = component.create();
QVERIFY(object != 0);
CircularReferenceObject *cro = object->findChild<CircularReferenceObject*>("cro");
- cro->setEngine(&hrmEngine);
cro->setDtorCount(&dtorCount);
QMetaObject::invokeMethod(object, "circularReference");
gc(hrmEngine);
@@ -6232,10 +6245,6 @@ void tst_qqmlecmascript::include()
void tst_qqmlecmascript::includeRemoteSuccess()
{
-#if defined(Q_CC_MSVC) && _MSC_VER == 1700
- QSKIP("This test does not work reliably with MSVC2012 on Win8 64-bit in release mode.");
-#endif
-
// Remote - success
TestHTTPServer server;
QVERIFY2(server.listen(), qPrintable(server.errorString()));
@@ -6881,6 +6890,18 @@ void tst_qqmlecmascript::nonNotifyable()
delete object;
}
+void tst_qqmlecmascript::nonNotifyableConstant()
+{
+ QQmlComponent component(&engine, testFileUrl("nonNotifyableConstant.qml"));
+ QQmlTestMessageHandler messageHandler;
+
+ // Shouldn't produce an error message about non-NOTIFYable properties,
+ // as the property has the CONSTANT attribute.
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(object);
+ QCOMPARE(messageHandler.messages().size(), 0);
+}
+
void tst_qqmlecmascript::forInLoop()
{
QQmlComponent component(&engine, testFileUrl("forInLoop.qml"));
@@ -7278,8 +7299,8 @@ class WeakReferenceMutator : public QObject
Q_OBJECT
public:
WeakReferenceMutator()
- : resultPtr(Q_NULLPTR)
- , weakRef(Q_NULLPTR)
+ : resultPtr(nullptr)
+ , weakRef(nullptr)
{}
void init(QV4::ExecutionEngine *v4, QV4::WeakValue *weakRef, bool *resultPtr)
@@ -7298,7 +7319,7 @@ private slots:
*resultPtr = weakRef->valueRef() && weakRef->isNullOrUndefined();
if (!*resultPtr)
return;
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(qmlEngine(this));
+ QV4::ExecutionEngine *v4 = qmlEngine(this)->handle();
weakRef->set(v4, v4->newObject());
*resultPtr = weakRef->valueRef() && !weakRef->isNullOrUndefined();
}
@@ -7348,7 +7369,7 @@ void tst_qqmlecmascript::onDestructionViaGC()
qmlRegisterType<WeakReferenceMutator>("Test", 1, 0, "WeakReferenceMutator");
QQmlEngine engine;
- QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine);
+ QV4::ExecutionEngine *v4 =engine.handle();
QQmlComponent component(&engine, testFileUrl("DestructionHelper.qml"));
@@ -8174,6 +8195,8 @@ void tst_qqmlecmascript::stringify_qtbug_50592()
QCOMPARE(obj->property("source").toString(), QString::fromLatin1("http://example.org/some_nonexistant_image.png"));
}
+// Tests for the JS-only instanceof. Tests for the QML extensions for
+// instanceof belong in tst_qqmllanguage!
void tst_qqmlecmascript::instanceof_data()
{
QTest::addColumn<QString>("setupCode");
@@ -8226,7 +8249,7 @@ void tst_qqmlecmascript::instanceof()
QJSEngine engine;
QJSValue ret = engine.evaluate(setupCode + ";\n" + QTest::currentDataTag());
- if (expectedValue.type() == QMetaType::Bool) {
+ if (expectedValue.type() == QVariant::Bool) {
bool returnValue = ret.toBool();
QVERIFY2(!ret.isError(), qPrintable(ret.toString()));
QCOMPARE(returnValue, expectedValue.toBool());
@@ -8236,6 +8259,108 @@ void tst_qqmlecmascript::instanceof()
}
}
+void tst_qqmlecmascript::constkw_data()
+{
+ QTest::addColumn<QString>("sourceCode");
+ QTest::addColumn<bool>("exceptionExpected");
+ QTest::addColumn<QVariant>("expectedValue");
+
+ QTest::newRow("simpleconst")
+ << "const v = 5\n"
+ "v\n"
+ << false
+ << QVariant(5);
+ QTest::newRow("twoconst")
+ << "const v = 5, i = 10\n"
+ "v + i\n"
+ << false
+ << QVariant(15);
+ QTest::newRow("constandvar")
+ << "const v = 5\n"
+ "var i = 20\n"
+ "v + i\n"
+ << false
+ << QVariant(25);
+ QTest::newRow("const-multiple-scopes-same-var")
+ << "const v = 3\n"
+ "function f() { const v = 1; return v; }\n"
+ "v + f()\n"
+ << false
+ << QVariant(4);
+
+ // error cases
+ QTest::newRow("const-no-initializer")
+ << "const v\n"
+ << true
+ << QVariant("SyntaxError: Missing initializer in const declaration");
+ QTest::newRow("const-no-initializer-comma")
+ << "const v = 1, i\n"
+ << true
+ << QVariant("SyntaxError: Missing initializer in const declaration");
+ QTest::newRow("const-no-duplicate")
+ << "const v = 1, v = 2\n"
+ << true
+ << QVariant("SyntaxError: Identifier v has already been declared");
+ QTest::newRow("const-no-duplicate-2")
+ << "const v = 1\n"
+ "const v = 2\n"
+ << true
+ << QVariant("SyntaxError: Identifier v has already been declared");
+ QTest::newRow("const-no-duplicate-var")
+ << "const v = 1\n"
+ "var v = 1\n"
+ << true
+ << QVariant("SyntaxError: Identifier v has already been declared");
+ QTest::newRow("var-no-duplicate-const")
+ << "var v = 1\n"
+ "const v = 1\n"
+ << true
+ << QVariant("SyntaxError: Identifier v has already been declared");
+ QTest::newRow("const-no-duplicate-let")
+ << "const v = 1\n"
+ "let v = 1\n"
+ << true
+ << QVariant("SyntaxError: Identifier v has already been declared");
+ QTest::newRow("let-no-duplicate-const")
+ << "let v = 1\n"
+ "const v = 1\n"
+ << true
+ << QVariant("SyntaxError: Identifier v has already been declared");
+}
+
+void tst_qqmlecmascript::constkw()
+{
+ QFETCH(QString, sourceCode);
+ QFETCH(bool, exceptionExpected);
+ QFETCH(QVariant, expectedValue);
+
+ QJSEngine engine;
+ QJSValue ret = engine.evaluate(sourceCode);
+
+ if (!exceptionExpected) {
+ QVERIFY2(!ret.isError(), qPrintable(ret.toString()));
+ QCOMPARE(ret.toVariant(), expectedValue);
+ } else {
+ QVERIFY2(ret.isError(), qPrintable(ret.toString()));
+ QCOMPARE(ret.toString(), expectedValue.toString());
+ }
+}
+
+// Redefine a property found on the global object. It shouldn't throw.
+void tst_qqmlecmascript::redefineGlobalProp()
+{
+ {
+ QJSEngine engine;
+ QJSValue ret = engine.evaluate("\"use strict\"\n var toString = 1;");
+ QVERIFY2(!ret.isError(), qPrintable(ret.toString()));
+ }
+ {
+ QJSEngine engine;
+ QJSValue ret = engine.evaluate("var toString = 1;");
+ QVERIFY2(!ret.isError(), qPrintable(ret.toString()));
+ }
+}
+
void tst_qqmlecmascript::freeze_empty_object()
{
// this shouldn't crash
@@ -8281,6 +8406,69 @@ void tst_qqmlecmascript::anotherNaN()
object->setProperty("prop", d); // don't crash
}
+void tst_qqmlecmascript::delayLoadingArgs()
+{
+ QJSEngine engine;
+ QJSValue ret = engine.evaluate("(function(x){return x + (x+=2)})(20)");
+ QCOMPARE(ret.toInt(), 42); // esp. not 44.
+}
+
+void tst_qqmlecmascript::manyArguments()
+{
+ const char *testCase =
+ "function x() { var sum; for (var i = 0; i < arguments.length; ++i) sum += arguments[i][0]; }"
+ "x([0],[1],[2],[3],[4],[5],[6],[7],[8],[9], [0],[1],[2],[3],[4],[5],[6],[7],[8],[9], [0],[1],[2],[3],[4],[5],[6],[7],[8],[9])";
+
+ QJSEngine engine;
+ engine.evaluate(testCase);
+}
+
+void tst_qqmlecmascript::forInIterator()
+{
+ auto testCase =
+ "(function(){\n"
+ "var x = 'yoyo'\n"
+ "var i\n"
+ "for (i in x) {\n"
+ "}\n"
+ "return i\n"
+ "})()";
+ QJSEngine engine;
+ QJSValue ret = engine.evaluate(testCase);
+ QVERIFY(ret.isString());
+ QCOMPARE(ret.toString(), QStringLiteral("3"));
+}
+
+void tst_qqmlecmascript::localForInIterator()
+{
+ auto testCase =
+ "(function(){\n"
+ "var x = 'yoyo'\n"
+ "for (var i in x) {\n"
+ "}\n"
+ "return i\n"
+ "})()";
+ QJSEngine engine;
+ QJSValue ret = engine.evaluate(testCase);
+ QVERIFY(ret.isString());
+ QCOMPARE(ret.toString(), QStringLiteral("3"));
+}
+
+void tst_qqmlecmascript::shadowedFunctionName()
+{
+ // verify that arguments shadow the function name
+ QJSEngine engine;
+ QJSValue v = engine.evaluate(QString::fromLatin1(
+ "function f(f) { return f; }\n"
+ "f(true)\n"
+ ));
+ QVERIFY(!v.isError());
+ QVERIFY(v.isBool());
+ QCOMPARE(v.toBool(), true);
+}
+
+
+
QTEST_MAIN(tst_qqmlecmascript)
#include "tst_qqmlecmascript.moc"
diff --git a/tests/auto/qml/qqmlengine/data/GroupedPropertiesRevisionComponent1.qml b/tests/auto/qml/qqmlengine/data/GroupedPropertiesRevisionComponent1.qml
new file mode 100644
index 0000000000..1047926750
--- /dev/null
+++ b/tests/auto/qml/qqmlengine/data/GroupedPropertiesRevisionComponent1.qml
@@ -0,0 +1,10 @@
+import QtQuick 2.8
+
+Item {
+ property alias textEdit: textEdit
+
+ TextEdit {
+ id: textEdit
+
+ }
+}
diff --git a/tests/auto/qml/qqmlengine/data/GroupedPropertiesRevisionComponent2.qml b/tests/auto/qml/qqmlengine/data/GroupedPropertiesRevisionComponent2.qml
new file mode 100644
index 0000000000..552c6c3791
--- /dev/null
+++ b/tests/auto/qml/qqmlengine/data/GroupedPropertiesRevisionComponent2.qml
@@ -0,0 +1,10 @@
+import QtQuick 2.0
+
+Item {
+ property alias textEdit: textEdit
+
+ TextEdit {
+ id: textEdit
+
+ }
+}
diff --git a/tests/auto/qml/qqmlengine/data/testGroupedPropertiesRevision.1.qml b/tests/auto/qml/qqmlengine/data/testGroupedPropertiesRevision.1.qml
new file mode 100644
index 0000000000..39bd01fe40
--- /dev/null
+++ b/tests/auto/qml/qqmlengine/data/testGroupedPropertiesRevision.1.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.8
+
+Item {
+ GroupedPropertiesRevisionComponent1 {
+ textEdit.onEditingFinished: console.log("test")
+ }
+}
diff --git a/tests/auto/qml/qqmlengine/data/testGroupedPropertiesRevision.2.qml b/tests/auto/qml/qqmlengine/data/testGroupedPropertiesRevision.2.qml
new file mode 100644
index 0000000000..bb9ba79b01
--- /dev/null
+++ b/tests/auto/qml/qqmlengine/data/testGroupedPropertiesRevision.2.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.8
+
+Item {
+ GroupedPropertiesRevisionComponent2 {
+ textEdit.onEditingFinished: console.log("test")
+ }
+}
diff --git a/tests/auto/qml/qqmlengine/qqmlengine.pro b/tests/auto/qml/qqmlengine/qqmlengine.pro
index e7952d8e3a..8d1e149d62 100644
--- a/tests/auto/qml/qqmlengine/qqmlengine.pro
+++ b/tests/auto/qml/qqmlengine/qqmlengine.pro
@@ -7,3 +7,8 @@ include (../../shared/util.pri)
SOURCES += tst_qqmlengine.cpp
QT += core-private gui-private qml-private network testlib
+
+boot2qt: {
+ # GC corruption test is too heavy for qemu-arm
+ DEFINES += SKIP_GCCORRUPTION_TEST
+}
diff --git a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
index dac6ddaebd..d6d7506c48 100644
--- a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
+++ b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
@@ -75,6 +75,7 @@ private slots:
void urlInterceptor();
void qmlContextProperties();
void testGCCorruption();
+ void testGroupedPropertyRevisions();
public slots:
QObject *createAQObjectForOwnershipTest ()
@@ -741,6 +742,9 @@ public:
if (url.path().endsWith("Test.2/qmldir"))//Special case
return QUrl::fromLocalFile(m_base.path() + "interception/module/intercepted/qmldir");
+ // Special case: with 5.10 we always add the implicit import, so we need to explicitly handle this case now
+ if (url.path().endsWith("intercepted/qmldir"))
+ return url;
QString alteredPath = url.path();
int a = alteredPath.lastIndexOf('/');
@@ -859,6 +863,10 @@ void tst_qqmlengine::qmlContextProperties()
void tst_qqmlengine::testGCCorruption()
{
+#ifdef SKIP_GCCORRUPTION_TEST
+ QSKIP("Test too heavy for qemu");
+#endif
+
QQmlEngine e;
QQmlComponent c(&e, testFileUrl("testGCCorruption.qml"));
@@ -866,6 +874,17 @@ void tst_qqmlengine::testGCCorruption()
QVERIFY2(o, qPrintable(c.errorString()));
}
+void tst_qqmlengine::testGroupedPropertyRevisions()
+{
+ QQmlEngine e;
+
+ QQmlComponent c(&e, testFileUrl("testGroupedPropertiesRevision.1.qml"));
+ QScopedPointer<QObject> object(c.create());
+ QVERIFY2(object.data(), qPrintable(c.errorString()));
+ QQmlComponent c2(&e, testFileUrl("testGroupedPropertiesRevision.2.qml"));
+ QVERIFY(!c2.errorString().isEmpty());
+}
+
QTEST_MAIN(tst_qqmlengine)
#include "tst_qqmlengine.moc"
diff --git a/tests/auto/qml/qqmlextensionplugin/tst_qqmlextensionplugin.cpp b/tests/auto/qml/qqmlextensionplugin/tst_qqmlextensionplugin.cpp
index 268010ead8..2511eebefe 100644
--- a/tests/auto/qml/qqmlextensionplugin/tst_qqmlextensionplugin.cpp
+++ b/tests/auto/qml/qqmlextensionplugin/tst_qqmlextensionplugin.cpp
@@ -105,7 +105,7 @@ void tst_qqmlextensionplugin::iidCheck()
QPluginLoader loader(filePath);
QVERIFY2(loader.load(), qPrintable(loader.errorString()));
- QVERIFY(loader.instance() != Q_NULLPTR);
+ QVERIFY(loader.instance() != nullptr);
if (qobject_cast<QQmlExtensionPlugin *>(loader.instance())) {
QString iid = loader.metaData().value(QStringLiteral("IID")).toString();
diff --git a/tests/auto/qml/qqmlinstantiator/qqmlinstantiator.pro b/tests/auto/qml/qqmlinstantiator/qqmlinstantiator.pro
index 719fd6c350..542ec44736 100644
--- a/tests/auto/qml/qqmlinstantiator/qqmlinstantiator.pro
+++ b/tests/auto/qml/qqmlinstantiator/qqmlinstantiator.pro
@@ -2,7 +2,6 @@ CONFIG += testcase
TARGET = tst_qqmlinstantiator
macx:CONFIG -= app_bundle
-INCLUDEPATH += ../../shared/
SOURCES += tst_qqmlinstantiator.cpp
HEADERS += stringmodel.h
diff --git a/tests/auto/qml/qqmlinstantiator/stringmodel.h b/tests/auto/qml/qqmlinstantiator/stringmodel.h
index 0bd4ada55e..b01817375a 100644
--- a/tests/auto/qml/qqmlinstantiator/stringmodel.h
+++ b/tests/auto/qml/qqmlinstantiator/stringmodel.h
@@ -65,7 +65,7 @@ public:
return items.count();
}
- virtual QHash<int, QByteArray> roleNames() const Q_DECL_OVERRIDE
+ QHash<int, QByteArray> roleNames() const override
{
return roles;
}
@@ -75,7 +75,7 @@ public:
return 1;
}
- virtual bool hasChildren(const QModelIndex &) const Q_DECL_OVERRIDE
+ bool hasChildren(const QModelIndex &) const override
{
return rowCount(QModelIndex()) > 0;
}
diff --git a/tests/auto/qml/qqmlitemmodels/qtestmodel.h b/tests/auto/qml/qqmlitemmodels/qtestmodel.h
index 8724ef927f..6a022b3135 100644
--- a/tests/auto/qml/qqmlitemmodels/qtestmodel.h
+++ b/tests/auto/qml/qqmlitemmodels/qtestmodel.h
@@ -91,8 +91,6 @@ public:
}
int rowCount(const QModelIndex& parent = QModelIndex()) const {
- if (!fetched)
- qFatal("%s: rowCount should not be called before fetching", Q_FUNC_INFO);
if ((parent.column() > 0) || (level(parent) > levels)
|| (alternateChildlessRows && parent.row() > 0 && (parent.row() & 1)))
return 0;
diff --git a/tests/auto/qml/qqmllanguage/data/TypeWithEnum.qml b/tests/auto/qml/qqmllanguage/data/TypeWithEnum.qml
new file mode 100644
index 0000000000..c6788f787a
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/TypeWithEnum.qml
@@ -0,0 +1,28 @@
+import QtQuick 2.0
+
+QtObject {
+ enum MyEnum {
+ EnumValue1,
+ EnumValue2,
+ EnumValue3
+ }
+
+ enum MyOtherEnum {
+ OtherEnumValue1 = 24,
+ OtherEnumValue2,
+ OtherEnumValue3 = 24,
+ OtherEnumValue4,
+ OtherEnumValue5 = 1
+ }
+
+ property int enumValue: TypeWithEnum.EnumValue2
+ property int enumValue2
+ property int scopedEnumValue: TypeWithEnum.MyEnum.EnumValue2
+ Component.onCompleted: enumValue2 = TypeWithEnum.EnumValue3
+
+ property int otherEnumValue1: TypeWithEnum.OtherEnumValue1
+ property int otherEnumValue2: TypeWithEnum.OtherEnumValue2
+ property int otherEnumValue3: TypeWithEnum.OtherEnumValue3
+ property int otherEnumValue4: TypeWithEnum.OtherEnumValue4
+ property int otherEnumValue5: TypeWithEnum.OtherEnumValue5
+}
diff --git a/tests/auto/qml/qqmllanguage/data/circularSingleton.qml b/tests/auto/qml/qqmllanguage/data/circularSingleton.qml
new file mode 100644
index 0000000000..e569111956
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/circularSingleton.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.10
+import "singleton/circular"
+
+QtObject {
+ property int value: MySingleton.value
+}
diff --git a/tests/auto/qml/qqmllanguage/data/cppnamespace.qml b/tests/auto/qml/qqmllanguage/data/cppnamespace.qml
index efedf2b14a..48f7eb6715 100644
--- a/tests/auto/qml/qqmllanguage/data/cppnamespace.qml
+++ b/tests/auto/qml/qqmllanguage/data/cppnamespace.qml
@@ -2,4 +2,5 @@ import Test 1.0
MyNamespacedType {
myEnum: MyNamespace.Key5
+ property int intProperty: MyNamespace.MyOtherNSEnum.OtherKey2
}
diff --git a/tests/auto/qml/qqmllanguage/data/instanceOf/CustomMouseArea.qml b/tests/auto/qml/qqmllanguage/data/instanceOf/CustomMouseArea.qml
new file mode 100644
index 0000000000..f6ec5848c1
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/instanceOf/CustomMouseArea.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.6
+
+MouseArea {
+
+}
+
diff --git a/tests/auto/qml/qqmllanguage/data/instanceOf/CustomRectangle.qml b/tests/auto/qml/qqmllanguage/data/instanceOf/CustomRectangle.qml
new file mode 100644
index 0000000000..b3fa43a671
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/instanceOf/CustomRectangle.qml
@@ -0,0 +1,4 @@
+import QtQuick 2.6
+
+Rectangle {
+}
diff --git a/tests/auto/qml/qqmllanguage/data/instanceOf/CustomRectangleWithProp.qml b/tests/auto/qml/qqmllanguage/data/instanceOf/CustomRectangleWithProp.qml
new file mode 100644
index 0000000000..cf566b9315
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/instanceOf/CustomRectangleWithProp.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.6
+
+Rectangle {
+ property int somethingCustom: 0
+}
+
diff --git a/tests/auto/qml/qqmllanguage/data/instanceOf/qmldir b/tests/auto/qml/qqmllanguage/data/instanceOf/qmldir
new file mode 100644
index 0000000000..144c93d8e3
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/instanceOf/qmldir
@@ -0,0 +1,2 @@
+CustomRectangle 1.0 CustomRectangle.qml
+CustomMouseArea 1.0 CustomMouseArea.qml
diff --git a/tests/auto/qml/qqmllanguage/data/instanceof_qtqml.qml b/tests/auto/qml/qqmllanguage/data/instanceof_qtqml.qml
new file mode 100644
index 0000000000..d74b172cf8
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/instanceof_qtqml.qml
@@ -0,0 +1,13 @@
+import QtQml 2.0
+
+QtObject {
+ id: qtobjectInstance
+
+ property Timer aTimer: Timer {
+ id: timerInstance
+ }
+
+ property Connections aConnections: Connections {
+ id: connectionsInstance
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/instanceof_qtqml_qualified.qml b/tests/auto/qml/qqmllanguage/data/instanceof_qtqml_qualified.qml
new file mode 100644
index 0000000000..a8e303363e
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/instanceof_qtqml_qualified.qml
@@ -0,0 +1,13 @@
+import QtQml 2.0 as QmlImport
+
+QmlImport.QtObject {
+ id: qtobjectInstance
+
+ property QmlImport.Timer aTimer: QmlImport.Timer {
+ id: timerInstance
+ }
+
+ property QmlImport.Connections aConnections: QmlImport.Connections {
+ id: connectionsInstance
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/instanceof_qtquick.qml b/tests/auto/qml/qqmllanguage/data/instanceof_qtquick.qml
new file mode 100644
index 0000000000..9c1808d515
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/instanceof_qtquick.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.0
+
+Item {
+ id: itemInstance
+
+ Rectangle {
+ id: rectangleInstance
+ }
+
+ MouseArea {
+ id: mouseAreaInstance
+ }
+}
+
diff --git a/tests/auto/qml/qqmllanguage/data/instanceof_qtquick_composite.qml b/tests/auto/qml/qqmllanguage/data/instanceof_qtquick_composite.qml
new file mode 100644
index 0000000000..78fc112805
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/instanceof_qtquick_composite.qml
@@ -0,0 +1,26 @@
+import QtQuick 2.0
+import "instanceOf"
+
+Item {
+ id: itemInstance
+
+ Rectangle {
+ id: rectangleInstance
+ }
+
+ MouseArea {
+ id: mouseAreaInstance
+ }
+
+ CustomRectangle {
+ id: customRectangleInstance
+ }
+ CustomRectangleWithProp {
+ id: customRectangleWithPropInstance
+ }
+ CustomMouseArea {
+ id: customMouseAreaInstance
+ }
+}
+
+
diff --git a/tests/auto/qml/qqmllanguage/data/instanceof_qtquick_composite_qualified.qml b/tests/auto/qml/qqmllanguage/data/instanceof_qtquick_composite_qualified.qml
new file mode 100644
index 0000000000..97361b7334
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/instanceof_qtquick_composite_qualified.qml
@@ -0,0 +1,27 @@
+import QtQuick 2.0 as QuickImport
+import "instanceOf" as CustomImport
+
+QuickImport.Item {
+ id: itemInstance
+
+ QuickImport.Rectangle {
+ id: rectangleInstance
+ }
+
+ QuickImport.MouseArea {
+ id: mouseAreaInstance
+ }
+
+ CustomImport.CustomRectangle {
+ id: customRectangleInstance
+ }
+ CustomImport.CustomRectangleWithProp {
+ id: customRectangleWithPropInstance
+ }
+ CustomImport.CustomMouseArea {
+ id: customMouseAreaInstance
+ }
+}
+
+
+
diff --git a/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.1.errors.txt b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.1.errors.txt
new file mode 100644
index 0000000000..a96fe376aa
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.1.errors.txt
@@ -0,0 +1 @@
+6:22:Expected token `numeric literal'
diff --git a/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.1.qml b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.1.qml
new file mode 100644
index 0000000000..fef23ecbef
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.1.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.0
+
+QtObject {
+ enum MyEnum {
+ EnumValue1,
+ EnumValue2 = "hello",
+ EnumValue3
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.2.errors.txt b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.2.errors.txt
new file mode 100644
index 0000000000..a96fe376aa
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.2.errors.txt
@@ -0,0 +1 @@
+6:22:Expected token `numeric literal'
diff --git a/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.2.qml b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.2.qml
new file mode 100644
index 0000000000..9892fcd19c
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.2.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.0
+
+QtObject {
+ enum MyEnum {
+ EnumValue1,
+ EnumValue2 = hello,
+ EnumValue3
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.3.errors.txt b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.3.errors.txt
new file mode 100644
index 0000000000..43465c60ec
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.3.errors.txt
@@ -0,0 +1 @@
+7:22:Enum value out of range
diff --git a/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.3.qml b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.3.qml
new file mode 100644
index 0000000000..654bc0e626
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.3.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.0
+
+QtObject {
+ enum MyEnum {
+ EnumValue1,
+ EnumValue2,
+ EnumValue3 = 2147483648
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.4.errors.txt b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.4.errors.txt
new file mode 100644
index 0000000000..12756dc593
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.4.errors.txt
@@ -0,0 +1 @@
+7:22:Enum value must be an integer
diff --git a/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.4.qml b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.4.qml
new file mode 100644
index 0000000000..4a0aafba5e
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.4.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.0
+
+QtObject {
+ enum MyEnum {
+ EnumValue1,
+ EnumValue2,
+ EnumValue3 = 17.5
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/NonSingletonType.qml b/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/NonSingletonType.qml
new file mode 100644
index 0000000000..ec7c76c055
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/NonSingletonType.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.0
+import org.qtproject.MixedModule 1.0
+
+Item {
+}
diff --git a/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/SingletonType.qml b/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/SingletonType.qml
new file mode 100644
index 0000000000..7763c783f1
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/SingletonType.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.0
+pragma Singleton
+
+Item {
+}
diff --git a/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/qmldir b/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/qmldir
new file mode 100644
index 0000000000..cd03a5f941
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/qmldir
@@ -0,0 +1,4 @@
+module org.qtproject.MixedModule
+singleton SingletonType 1.0 SingletonType.qml
+NonSingletonType 1.0 NonSingletonType.qml
+Test 1.0 test.js
diff --git a/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/test.js b/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/test.js
new file mode 100644
index 0000000000..6a53b53b02
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/lib/org/qtproject/MixedModule/test.js
@@ -0,0 +1 @@
+var foo = 1
diff --git a/tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.1.errors.txt b/tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.1.errors.txt
new file mode 100644
index 0000000000..d1bd2bcff4
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.1.errors.txt
@@ -0,0 +1 @@
+6:9:Enum names must begin with an upper case letter
diff --git a/tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.1.qml b/tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.1.qml
new file mode 100644
index 0000000000..0b50820128
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.1.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.0
+
+QtObject {
+ enum MyEnum {
+ EnumValue1,
+ enumValue2,
+ EnumValue3
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.2.errors.txt b/tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.2.errors.txt
new file mode 100644
index 0000000000..3e051c416e
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.2.errors.txt
@@ -0,0 +1 @@
+4:5:Scoped enum names must begin with an upper case letter
diff --git a/tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.2.qml b/tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.2.qml
new file mode 100644
index 0000000000..bb7aea6aa4
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/lowercaseQmlEnum.2.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.0
+
+QtObject {
+ enum myEnum {
+ EnumValue1,
+ EnumValue2,
+ EnumValue3
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/mixedModuleWithSelfImport.qml b/tests/auto/qml/qqmllanguage/data/mixedModuleWithSelfImport.qml
new file mode 100644
index 0000000000..7768a6aedf
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/mixedModuleWithSelfImport.qml
@@ -0,0 +1,3 @@
+import org.qtproject.MixedModule 1.0
+
+NonSingletonType {}
diff --git a/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyInternalType.qml b/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyInternalType.qml
new file mode 100644
index 0000000000..0e69012662
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyInternalType.qml
@@ -0,0 +1,2 @@
+import QtQml 2.0
+QtObject {}
diff --git a/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyPublicType.qml b/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyPublicType.qml
new file mode 100644
index 0000000000..c6b38d51a9
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyPublicType.qml
@@ -0,0 +1,4 @@
+import QtQml 2.0
+QtObject {
+ property InternalType myInternalType: InternalType {}
+}
diff --git a/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyPublicTypeWithExplicitImport.qml b/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyPublicTypeWithExplicitImport.qml
new file mode 100644
index 0000000000..9b488f92da
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyPublicTypeWithExplicitImport.qml
@@ -0,0 +1,5 @@
+import QtQml 2.0
+import modulewithinternaltypes 1.0
+QtObject {
+ property InternalType myInternalType: InternalType {}
+}
diff --git a/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/qmldir b/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/qmldir
new file mode 100644
index 0000000000..3593845329
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/qmldir
@@ -0,0 +1,3 @@
+PublicType 1.0 MyPublicType.qml
+PublicTypeWithExplicitImport 1.0 MyPublicTypeWithExplicitImport.qml
+internal InternalType MyInternalType.qml
diff --git a/tests/auto/qml/qqmllanguage/data/registeredCompositeTypeWithEnum.qml b/tests/auto/qml/qqmllanguage/data/registeredCompositeTypeWithEnum.qml
index 5f8c11e5f6..b6a07693f2 100644
--- a/tests/auto/qml/qqmllanguage/data/registeredCompositeTypeWithEnum.qml
+++ b/tests/auto/qml/qqmllanguage/data/registeredCompositeTypeWithEnum.qml
@@ -3,4 +3,5 @@ import Test 1.0
RegisteredCompositeTypeWithEnum {
property int enumValue0: RegisteredCompositeTypeWithEnum.EnumValue0
property int enumValue42: RegisteredCompositeTypeWithEnum.EnumValue42
+ property int enumValue15: RegisteredCompositeTypeWithEnum.ScopedCompositeEnum.EnumValue15
}
diff --git a/tests/auto/qml/qqmllanguage/data/scopedEnum.qml b/tests/auto/qml/qqmllanguage/data/scopedEnum.qml
new file mode 100644
index 0000000000..7f4177af76
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/scopedEnum.qml
@@ -0,0 +1,21 @@
+import QtQuick 2.0
+import Test 1.0
+
+MyTypeObject {
+ id: obj
+ scopedEnum: MyTypeObject.MyScopedEnum.ScopedVal1
+ intProperty: MyTypeObject.MyScopedEnum.ScopedVal2
+ property int listValue: myModel.get(0).myData
+ property int noScope: MyTypeObject.ScopedVal1
+
+ function assignNewValue() {
+ scopedEnum = MyTypeObject.MyScopedEnum.ScopedVal2
+ noScope = MyTypeObject.ScopedVal2
+ }
+
+ property ListModel myModel: ListModel {
+ ListElement {
+ myData: MyTypeObject.MyScopedEnum.ScopedVal3
+ }
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/scopedEnumList.errors.txt b/tests/auto/qml/qqmllanguage/data/scopedEnumList.errors.txt
new file mode 100644
index 0000000000..67576dfd8d
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/scopedEnumList.errors.txt
@@ -0,0 +1 @@
+7:13:ListElement: cannot use script for property value
diff --git a/tests/auto/qml/qqmllanguage/data/scopedEnumList.qml b/tests/auto/qml/qqmllanguage/data/scopedEnumList.qml
new file mode 100644
index 0000000000..8655139683
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/scopedEnumList.qml
@@ -0,0 +1,10 @@
+import QtQuick 2.0
+import Test 1.0
+
+MyTypeObject {
+ property ListModel myModel: ListModel {
+ ListElement {
+ myData: MyTypeObject.MyScopedEnum
+ }
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/singleton/circular/MySingleton.qml b/tests/auto/qml/qqmllanguage/data/singleton/circular/MySingleton.qml
new file mode 100644
index 0000000000..1253018789
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/singleton/circular/MySingleton.qml
@@ -0,0 +1,12 @@
+pragma Singleton
+import QtQuick 2.10
+
+QtObject {
+ enum MyEnum {
+ Value0,
+ Value1,
+ Value2
+ }
+
+ property int value: MySingleton.Value2
+}
diff --git a/tests/auto/qml/qqmllanguage/data/singleton/circular/qmldir b/tests/auto/qml/qqmllanguage/data/singleton/circular/qmldir
new file mode 100644
index 0000000000..3bc50738dd
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/singleton/circular/qmldir
@@ -0,0 +1 @@
+singleton MySingleton MySingleton.qml
diff --git a/tests/auto/qml/qqmllanguage/data/usingTypeWithEnum.qml b/tests/auto/qml/qqmllanguage/data/usingTypeWithEnum.qml
new file mode 100644
index 0000000000..2509fc0df1
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/usingTypeWithEnum.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.0
+
+QtObject {
+ property int enumValue: TypeWithEnum.EnumValue2
+ property int enumValue2: -1
+ property int scopedEnumValue: TypeWithEnum.MyEnum.EnumValue3
+ Component.onCompleted: enumValue2 = TypeWithEnum.EnumValue1
+}
diff --git a/tests/auto/qml/qqmllanguage/qqmllanguage.pro b/tests/auto/qml/qqmllanguage/qqmllanguage.pro
index 99c0c3e823..3e88f3f0db 100644
--- a/tests/auto/qml/qqmllanguage/qqmllanguage.pro
+++ b/tests/auto/qml/qqmllanguage/qqmllanguage.pro
@@ -6,7 +6,6 @@ SOURCES += tst_qqmllanguage.cpp \
testtypes.cpp
HEADERS += testtypes.h
-INCLUDEPATH += ../../shared/
HEADERS += ../../shared/testhttpserver.h
SOURCES += ../../shared/testhttpserver.cpp
diff --git a/tests/auto/qml/qqmllanguage/testtypes.cpp b/tests/auto/qml/qqmllanguage/testtypes.cpp
index d2240d25a9..1a81528bc4 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.cpp
+++ b/tests/auto/qml/qqmllanguage/testtypes.cpp
@@ -136,7 +136,7 @@ void CustomBinding::componentComplete()
QQmlContextData *context = QQmlContextData::get(qmlContext(this));
QQmlProperty property(m_target, name, qmlContext(this));
- QV4::Scope scope(QQmlEnginePrivate::getV4Engine(qmlEngine(this)));
+ QV4::Scope scope(qmlEngine(this)->handle());
QV4::Scoped<QV4::QmlContext> qmlContext(scope, QV4::QmlContext::create(scope.engine->rootContext(), context, m_target));
QQmlBinding *qmlBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core,
compilationUnit->runtimeFunctions[bindingId], m_target, context, qmlContext);
diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h
index d9ddff20a7..5025a6e7f2 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.h
+++ b/tests/auto/qml/qqmllanguage/testtypes.h
@@ -223,6 +223,7 @@ class MyTypeObject : public QObject
Q_PROPERTY(Qt::TextFormat qtEnumProperty READ qtEnumProperty WRITE setQtEnumProperty NOTIFY qtEnumPropertyChanged)
Q_PROPERTY(MyMirroredEnum mirroredEnumProperty READ mirroredEnumProperty WRITE setMirroredEnumProperty NOTIFY mirroredEnumPropertyChanged)
Q_PROPERTY(MyEnumContainer::RelatedEnum relatedEnumProperty READ relatedEnumProperty WRITE setRelatedEnumProperty)
+ Q_PROPERTY(MyScopedEnum scopedEnum READ scopedEnum WRITE setScopedEnum)
Q_PROPERTY(QString stringProperty READ stringProperty WRITE setStringProperty NOTIFY stringPropertyChanged)
Q_PROPERTY(QByteArray byteArrayProperty READ byteArrayProperty WRITE setByteArrayProperty NOTIFY byteArrayPropertyChanged)
Q_PROPERTY(uint uintProperty READ uintProperty WRITE setUintProperty NOTIFY uintPropertyChanged)
@@ -339,6 +340,14 @@ public:
relatedEnumPropertyValue = v;
}
+ enum class MyScopedEnum : int { ScopedVal1, ScopedVal2, ScopedVal3 };
+ Q_ENUM(MyScopedEnum)
+ MyScopedEnum scopedEnumPropertyValue;
+ MyScopedEnum scopedEnum() const { return scopedEnumPropertyValue; }
+ void setScopedEnum(MyScopedEnum v) {
+ scopedEnumPropertyValue = v;
+ }
+
QString stringPropertyValue;
QString stringProperty() const {
return stringPropertyValue;
@@ -738,6 +747,13 @@ namespace MyNamespace {
};
Q_ENUM_NS(MyNSEnum);
+ enum class MyOtherNSEnum {
+ OtherKey1 = 1,
+ OtherKey2
+ };
+ Q_ENUM_NS(MyOtherNSEnum);
+
+
class MyNamespacedType : public QObject
{
Q_OBJECT
@@ -1171,9 +1187,11 @@ class MyCompositeBaseType : public QObject
{
Q_OBJECT
Q_ENUMS(CompositeEnum)
+ Q_ENUMS(ScopedCompositeEnum)
public:
enum CompositeEnum { EnumValue0, EnumValue42 = 42 };
+ enum class ScopedCompositeEnum : int { EnumValue15 = 15 };
static QObject *qmlAttachedProperties(QObject *parent) { return new QObject(parent); }
};
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index 83151fb6e2..03d53b755d 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -179,6 +179,8 @@ private slots:
void importIncorrectCase();
void importJs_data();
void importJs();
+ void explicitSelfImport();
+ void importInternalType();
void qmlAttachedPropertiesObjectMethod();
void customOnProperty();
@@ -209,6 +211,8 @@ private slots:
void lowercaseEnumRuntime();
void lowercaseEnumCompileTime_data();
void lowercaseEnumCompileTime();
+ void scopedEnum();
+ void qmlEnums();
void literals_data();
void literals();
@@ -237,6 +241,7 @@ private slots:
void compositeSingletonJavaScriptPragma();
void compositeSingletonSelectors();
void compositeSingletonRegistered();
+ void compositeSingletonCircular();
void customParserBindingScopes();
void customParserEvaluateEnum();
@@ -267,6 +272,9 @@ private slots:
void qmlTypeCanBeResolvedByName_data();
void qmlTypeCanBeResolvedByName();
+ void instanceof_data();
+ void instanceof();
+
void concurrentLoadQmlDir();
void accessDeletedObject();
@@ -319,7 +327,7 @@ private:
if (!errorfile) { \
if (qgetenv("DEBUG") != "" && !component.errors().isEmpty()) \
qWarning() << "Unexpected Errors:" << component.errors(); \
- QVERIFY(!component.isError()); \
+ QVERIFY2(!component.isError(), qPrintable(component.errorString())); \
QVERIFY(component.errors().isEmpty()); \
} else { \
DETERMINE_ERRORS(errorfile,expected,actual);\
@@ -550,6 +558,14 @@ void tst_qqmllanguage::errors_data()
QTest::newRow("singularProperty") << "singularProperty.qml" << "singularProperty.errors.txt" << false;
QTest::newRow("singularProperty.2") << "singularProperty.2.qml" << "singularProperty.2.errors.txt" << false;
+ QTest::newRow("scopedEnumList") << "scopedEnumList.qml" << "scopedEnumList.errors.txt" << false;
+ QTest::newRow("lowercase enum value") << "lowercaseQmlEnum.1.qml" << "lowercaseQmlEnum.1.errors.txt" << false;
+ QTest::newRow("lowercase enum type") << "lowercaseQmlEnum.2.qml" << "lowercaseQmlEnum.2.errors.txt" << false;
+ QTest::newRow("string enum value") << "invalidQmlEnumValue.1.qml" << "invalidQmlEnumValue.1.errors.txt" << false;
+ QTest::newRow("identifier enum type") << "invalidQmlEnumValue.2.qml" << "invalidQmlEnumValue.2.errors.txt" << false;
+ QTest::newRow("enum value too large") << "invalidQmlEnumValue.3.qml" << "invalidQmlEnumValue.3.errors.txt" << false;
+ QTest::newRow("non-integer enum value") << "invalidQmlEnumValue.4.qml" << "invalidQmlEnumValue.4.errors.txt" << false;
+
const QString expectedError = isCaseSensitiveFileSystem(dataDirectory()) ?
QStringLiteral("incorrectCase.errors.sensitive.txt") :
QStringLiteral("incorrectCase.errors.insensitive.txt");
@@ -1610,6 +1626,9 @@ void tst_qqmllanguage::cppnamespace()
VERIFY_ERRORS(0);
QObject *object = component.create();
QVERIFY(object != 0);
+
+ QCOMPARE(object->property("intProperty").toInt(), (int)MyNamespace::MyOtherNSEnum::OtherKey2);
+
delete object;
}
@@ -3068,12 +3087,45 @@ void tst_qqmllanguage::importJs()
engine.setImportPathList(defaultImportPathList);
}
+void tst_qqmllanguage::explicitSelfImport()
+{
+ engine.setImportPathList(QStringList(defaultImportPathList) << testFile("lib"));
+
+ QQmlComponent component(&engine, testFileUrl("mixedModuleWithSelfImport.qml"));
+ QVERIFY(component.errors().count() == 0);
+
+ engine.setImportPathList(defaultImportPathList);
+}
+
+void tst_qqmllanguage::importInternalType()
+{
+ QQmlEngine engine;
+ engine.addImportPath(dataDirectory());
+
+ {
+ QQmlComponent component(&engine);
+ component.setData("import modulewithinternaltypes 1.0\nPublicType{}", QUrl());
+ VERIFY_ERRORS(0);
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+ QVERIFY(obj->property("myInternalType").value<QObject*>() != 0);
+ }
+ {
+ QQmlComponent component(&engine);
+ component.setData("import modulewithinternaltypes 1.0\nPublicTypeWithExplicitImport{}", QUrl());
+ VERIFY_ERRORS(0);
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+ QVERIFY(obj->property("myInternalType").value<QObject*>() != 0);
+ }
+}
+
void tst_qqmllanguage::qmlAttachedPropertiesObjectMethod()
{
QObject object;
QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(&object, false), (QObject *)0);
- QCOMPARE(qmlAttachedPropertiesObject<MyQmlObject>(&object, true), (QObject *)0);
+ QVERIFY(qmlAttachedPropertiesObject<MyQmlObject>(&object, true));
{
QQmlComponent component(&engine, testFileUrl("qmlAttachedPropertiesObjectMethod.1.qml"));
@@ -3510,6 +3562,7 @@ void tst_qqmllanguage::registeredCompositeTypeWithEnum()
QCOMPARE(o->property("enumValue0").toInt(), static_cast<int>(MyCompositeBaseType::EnumValue0));
QCOMPARE(o->property("enumValue42").toInt(), static_cast<int>(MyCompositeBaseType::EnumValue42));
+ QCOMPARE(o->property("enumValue15").toInt(), static_cast<int>(MyCompositeBaseType::ScopedCompositeEnum::EnumValue15));
delete o;
}
@@ -3690,6 +3743,50 @@ void tst_qqmllanguage::lowercaseEnumCompileTime()
VERIFY_ERRORS(qPrintable(errorFile));
}
+void tst_qqmllanguage::scopedEnum()
+{
+ QQmlComponent component(&engine, testFileUrl("scopedEnum.qml"));
+
+ MyTypeObject *o = qobject_cast<MyTypeObject *>(component.create());
+ QVERIFY(o != 0);
+
+ QCOMPARE(o->scopedEnum(), MyTypeObject::MyScopedEnum::ScopedVal1);
+ QCOMPARE(o->intProperty(), (int)MyTypeObject::MyScopedEnum::ScopedVal2);
+ QCOMPARE(o->property("listValue").toInt(), (int)MyTypeObject::MyScopedEnum::ScopedVal3);
+ QCOMPARE(o->property("noScope").toInt(), (int)MyTypeObject::MyScopedEnum::ScopedVal1);
+
+ QMetaObject::invokeMethod(o, "assignNewValue");
+ QCOMPARE(o->scopedEnum(), MyTypeObject::MyScopedEnum::ScopedVal2);
+ QCOMPARE(o->property("noScope").toInt(), (int)MyTypeObject::MyScopedEnum::ScopedVal2);
+}
+
+void tst_qqmllanguage::qmlEnums()
+{
+ {
+ QQmlComponent component(&engine, testFileUrl("TypeWithEnum.qml"));
+ QObject *o = component.create();
+ QVERIFY(o);
+ QCOMPARE(o->property("enumValue").toInt(), 1);
+ QCOMPARE(o->property("enumValue2").toInt(), 2);
+ QCOMPARE(o->property("scopedEnumValue").toInt(), 1);
+
+ QCOMPARE(o->property("otherEnumValue1").toInt(), 24);
+ QCOMPARE(o->property("otherEnumValue2").toInt(), 25);
+ QCOMPARE(o->property("otherEnumValue3").toInt(), 24);
+ QCOMPARE(o->property("otherEnumValue4").toInt(), 25);
+ QCOMPARE(o->property("otherEnumValue5").toInt(), 1);
+ }
+
+ {
+ QQmlComponent component(&engine, testFileUrl("usingTypeWithEnum.qml"));
+ QObject *o = component.create();
+ QVERIFY(o);
+ QCOMPARE(o->property("enumValue").toInt(), 1);
+ QCOMPARE(o->property("enumValue2").toInt(), 0);
+ QCOMPARE(o->property("scopedEnumValue").toInt(), 2);
+ }
+}
+
void tst_qqmllanguage::literals_data()
{
QTest::addColumn<QString>("property");
@@ -4123,6 +4220,22 @@ void tst_qqmllanguage::compositeSingletonRegistered()
verifyCompositeSingletonPropertyValues(o, "value1", 925, "value2", 755);
}
+void tst_qqmllanguage::compositeSingletonCircular()
+{
+ QQmlComponent component(&engine, testFile("circularSingleton.qml"));
+ VERIFY_ERRORS(0);
+
+ QQmlTestMessageHandler messageHandler;
+
+ QObject *o = component.create();
+ QVERIFY(o != 0);
+
+ // ensure we aren't hitting the recursion warning
+ QVERIFY2(messageHandler.messages().isEmpty(), qPrintable(messageHandler.messageString()));
+
+ QCOMPARE(o->property("value").toInt(), 2);
+}
+
void tst_qqmllanguage::customParserBindingScopes()
{
QQmlComponent component(&engine, testFile("customParserBindingScopes.qml"));
@@ -4562,6 +4675,200 @@ void tst_qqmllanguage::qmlTypeCanBeResolvedByName()
QVERIFY(!o.isNull());
}
+// Tests for the QML-only extensions of instanceof. Tests for the regular JS
+// instanceof belong in tst_qqmlecmascript!
+void tst_qqmllanguage::instanceof_data()
+{
+ QTest::addColumn<QUrl>("documentToTestIn");
+ QTest::addColumn<QVariant>("expectedValue");
+
+ // so the way this works is that the name of the test tag defines the test
+ // to run.
+ //
+ // the expectedValue is either a boolean true or false for whether the two
+ // operands are indeed an instanceof each other, or a string for the
+ // expected error message.
+
+ // assert that basic types don't convert to QObject
+ QTest::newRow("1 instanceof QtObject")
+ << testFileUrl("instanceof_qtqml.qml")
+ << QVariant("TypeError: Type error");
+ QTest::newRow("true instanceof QtObject")
+ << testFileUrl("instanceof_qtqml.qml")
+ << QVariant("TypeError: Type error");
+ QTest::newRow("\"foobar\" instanceof QtObject")
+ << testFileUrl("instanceof_qtqml.qml")
+ << QVariant("TypeError: Type error");
+
+ // assert that Managed don't either
+ QTest::newRow("new String(\"foobar\") instanceof QtObject")
+ << testFileUrl("instanceof_qtqml.qml")
+ << QVariant("TypeError: Type error");
+ QTest::newRow("new Object() instanceof QtObject")
+ << testFileUrl("instanceof_qtqml.qml")
+ << QVariant("TypeError: Type error");
+ QTest::newRow("new Date() instanceof QtObject")
+ << testFileUrl("instanceof_qtqml.qml")
+ << QVariant("TypeError: Type error");
+
+ // test that simple QtQml comparisons work
+ QTest::newRow("qtobjectInstance instanceof QtObject")
+ << testFileUrl("instanceof_qtqml.qml")
+ << QVariant(true);
+ QTest::newRow("qtobjectInstance instanceof Timer")
+ << testFileUrl("instanceof_qtqml.qml")
+ << QVariant(false);
+ QTest::newRow("timerInstance instanceof QtObject")
+ << testFileUrl("instanceof_qtqml.qml")
+ << QVariant(true);
+ QTest::newRow("timerInstance instanceof Timer")
+ << testFileUrl("instanceof_qtqml.qml")
+ << QVariant(true);
+ QTest::newRow("connectionsInstance instanceof QtObject")
+ << testFileUrl("instanceof_qtqml.qml")
+ << QVariant(true);
+ QTest::newRow("connectionsInstance instanceof Timer")
+ << testFileUrl("instanceof_qtqml.qml")
+ << QVariant(false);
+ QTest::newRow("connectionsInstance instanceof Connections")
+ << testFileUrl("instanceof_qtqml.qml")
+ << QVariant(true);
+
+ // make sure they still work when imported with a qualifier
+ QTest::newRow("qtobjectInstance instanceof QmlImport.QtObject")
+ << testFileUrl("instanceof_qtqml_qualified.qml")
+ << QVariant(true);
+ QTest::newRow("qtobjectInstance instanceof QmlImport.Timer")
+ << testFileUrl("instanceof_qtqml_qualified.qml")
+ << QVariant(false);
+ QTest::newRow("timerInstance instanceof QmlImport.QtObject")
+ << testFileUrl("instanceof_qtqml_qualified.qml")
+ << QVariant(true);
+ QTest::newRow("timerInstance instanceof QmlImport.Timer")
+ << testFileUrl("instanceof_qtqml_qualified.qml")
+ << QVariant(true);
+ QTest::newRow("connectionsInstance instanceof QmlImport.QtObject")
+ << testFileUrl("instanceof_qtqml_qualified.qml")
+ << QVariant(true);
+ QTest::newRow("connectionsInstance instanceof QmlImport.Timer")
+ << testFileUrl("instanceof_qtqml_qualified.qml")
+ << QVariant(false);
+ QTest::newRow("connectionsInstance instanceof QmlImport.Connections")
+ << testFileUrl("instanceof_qtqml_qualified.qml")
+ << QVariant(true);
+
+ // test that Quick C++ types work ok
+ QTest::newRow("itemInstance instanceof QtObject")
+ << testFileUrl("instanceof_qtquick.qml")
+ << QVariant(true);
+ QTest::newRow("itemInstance instanceof Timer")
+ << testFileUrl("instanceof_qtquick.qml")
+ << QVariant(false);
+ QTest::newRow("itemInstance instanceof Rectangle")
+ << testFileUrl("instanceof_qtquick.qml")
+ << QVariant(false);
+ QTest::newRow("rectangleInstance instanceof Item")
+ << testFileUrl("instanceof_qtquick.qml")
+ << QVariant(true);
+ QTest::newRow("rectangleInstance instanceof Rectangle")
+ << testFileUrl("instanceof_qtquick.qml")
+ << QVariant(true);
+ QTest::newRow("rectangleInstance instanceof MouseArea")
+ << testFileUrl("instanceof_qtquick.qml")
+ << QVariant(false);
+ QTest::newRow("mouseAreaInstance instanceof Item")
+ << testFileUrl("instanceof_qtquick.qml")
+ << QVariant(true);
+ QTest::newRow("mouseAreaInstance instanceof Rectangle")
+ << testFileUrl("instanceof_qtquick.qml")
+ << QVariant(false);
+ QTest::newRow("mouseAreaInstance instanceof MouseArea")
+ << testFileUrl("instanceof_qtquick.qml")
+ << QVariant(true);
+
+ // test that unqualified quick composite types work ok
+ QTest::newRow("rectangleInstance instanceof CustomRectangle")
+ << testFileUrl("instanceof_qtquick_composite.qml")
+ << QVariant(false);
+ QTest::newRow("customRectangleInstance instanceof Rectangle")
+ << testFileUrl("instanceof_qtquick_composite.qml")
+ << QVariant(true);
+ QTest::newRow("customRectangleInstance instanceof Item")
+ << testFileUrl("instanceof_qtquick_composite.qml")
+ << QVariant(true);
+ QTest::newRow("customRectangleWithPropInstance instanceof CustomRectangleWithProp")
+ << testFileUrl("instanceof_qtquick_composite.qml")
+ << QVariant(true);
+ QTest::newRow("customRectangleWithPropInstance instanceof CustomRectangle")
+ << testFileUrl("instanceof_qtquick_composite.qml")
+ << QVariant(false); // ### XXX: QTBUG-58477
+ QTest::newRow("customRectangleWithPropInstance instanceof Rectangle")
+ << testFileUrl("instanceof_qtquick_composite.qml")
+ << QVariant(true);
+ QTest::newRow("customRectangleInstance instanceof MouseArea")
+ << testFileUrl("instanceof_qtquick_composite.qml")
+ << QVariant(false);
+ QTest::newRow("customMouseAreaInstance instanceof MouseArea")
+ << testFileUrl("instanceof_qtquick_composite.qml")
+ << QVariant(true);
+
+ // test that they still work when qualified
+ QTest::newRow("rectangleInstance instanceof CustomImport.CustomRectangle")
+ << testFileUrl("instanceof_qtquick_composite_qualified.qml")
+ << QVariant(false);
+ QTest::newRow("customRectangleInstance instanceof QuickImport.Rectangle")
+ << testFileUrl("instanceof_qtquick_composite_qualified.qml")
+ << QVariant(true);
+ QTest::newRow("customRectangleInstance instanceof QuickImport.Item")
+ << testFileUrl("instanceof_qtquick_composite_qualified.qml")
+ << QVariant(true);
+ QTest::newRow("customRectangleWithPropInstance instanceof CustomImport.CustomRectangleWithProp")
+ << testFileUrl("instanceof_qtquick_composite_qualified.qml")
+ << QVariant(true);
+ QTest::newRow("customRectangleWithPropInstance instanceof CustomImport.CustomRectangle")
+ << testFileUrl("instanceof_qtquick_composite_qualified.qml")
+ << QVariant(false); // ### XXX: QTBUG-58477
+ QTest::newRow("customRectangleWithPropInstance instanceof QuickImport.Rectangle")
+ << testFileUrl("instanceof_qtquick_composite_qualified.qml")
+ << QVariant(true);
+ QTest::newRow("customRectangleInstance instanceof QuickImport.MouseArea")
+ << testFileUrl("instanceof_qtquick_composite_qualified.qml")
+ << QVariant(false);
+ QTest::newRow("customMouseAreaInstance instanceof QuickImport.MouseArea")
+ << testFileUrl("instanceof_qtquick_composite_qualified.qml")
+ << QVariant(true);
+}
+
+void tst_qqmllanguage::instanceof()
+{
+ QFETCH(QUrl, documentToTestIn);
+ QFETCH(QVariant, expectedValue);
+
+ QQmlEngine engine;
+ QQmlComponent component(&engine, documentToTestIn);
+ VERIFY_ERRORS(0);
+
+ QScopedPointer<QObject> o(component.create());
+ QVERIFY(o != 0);
+
+ QQmlExpression expr(engine.contextForObject(o.data()), 0, QString::fromLatin1(QTest::currentDataTag()));
+ QVariant ret = expr.evaluate();
+
+ if (expectedValue.type() == QVariant::Bool) {
+ // no error expected
+ QVERIFY2(!expr.hasError(), qPrintable(expr.error().description()));
+ bool returnValue = ret.toBool();
+
+ if (QTest::currentDataTag() == QLatin1String("customRectangleWithPropInstance instanceof CustomRectangle") ||
+ QTest::currentDataTag() == QLatin1String("customRectangleWithPropInstance instanceof CustomImport.CustomRectangle"))
+ QEXPECT_FAIL("", "QTBUG-58477: QML type rules are a little lax", Continue);
+ QCOMPARE(returnValue, expectedValue.toBool());
+ } else {
+ QVERIFY(expr.hasError());
+ QCOMPARE(expr.error().description(), expectedValue.toString());
+ }
+}
+
void tst_qqmllanguage::concurrentLoadQmlDir()
{
ThreadedTestHTTPServer server(dataDirectory());
diff --git a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
index f5c0e5ddf7..73aec7c55b 100644
--- a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
+++ b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
@@ -124,6 +124,7 @@ private slots:
void modify_through_delegate();
void bindingsOnGetResult();
void stringifyModelEntry();
+ void qobjectTrackerForDynamicModelObjects();
};
bool tst_qqmllistmodel::compareVariantList(const QVariantList &testList, QVariant object)
@@ -1205,8 +1206,8 @@ void tst_qqmllistmodel::role_mode_data()
QTest::newRow("default1") << "{append({'a':1});dynamicRoles}" << 0 << "";
QTest::newRow("enableDynamic0") << "{dynamicRoles=true;dynamicRoles}" << 1 << "";
- QTest::newRow("enableDynamic1") << "{append({'a':1});dynamicRoles=true;dynamicRoles}" << 0 << "<Unknown File>: QML ListModel: unable to enable dynamic roles as this model is not empty!";
- QTest::newRow("enableDynamic2") << "{dynamicRoles=true;append({'a':1});dynamicRoles=false;dynamicRoles}" << 1 << "<Unknown File>: QML ListModel: unable to enable static roles as this model is not empty!";
+ QTest::newRow("enableDynamic1") << "{append({'a':1});dynamicRoles=true;dynamicRoles}" << 0 << "<Unknown File>: QML ListModel: unable to enable dynamic roles as this model is not empty";
+ QTest::newRow("enableDynamic2") << "{dynamicRoles=true;append({'a':1});dynamicRoles=false;dynamicRoles}" << 1 << "<Unknown File>: QML ListModel: unable to enable static roles as this model is not empty";
}
void tst_qqmllistmodel::role_mode()
@@ -1505,6 +1506,33 @@ void tst_qqmllistmodel::stringifyModelEntry()
QCOMPARE(v.toString(), expectedString);
}
+void tst_qqmllistmodel::qobjectTrackerForDynamicModelObjects()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData(
+ "import QtQuick 2.0\n"
+ "Item {\n"
+ " ListModel {\n"
+ " id: testModel\n"
+ " objectName: \"testModel\"\n"
+ " ListElement { name: \"Joe\"; age: 22 }\n"
+ " }\n"
+ "}\n", QUrl());
+ QScopedPointer<QObject> scene(component.create());
+ QQmlListModel *model = scene->findChild<QQmlListModel*>("testModel");
+ QQmlExpression expr(engine.rootContext(), model, "get(0);");
+ QVariant v = expr.evaluate();
+ QVERIFY2(!expr.hasError(), QTest::toString(expr.error().toString()));
+
+ QObject *obj = v.value<QObject*>();
+ QVERIFY(obj);
+
+ QQmlData *ddata = QQmlData::get(obj, /*create*/false);
+ QVERIFY(ddata);
+ QVERIFY(!ddata->jsWrapper.isNullOrUndefined());
+}
+
QTEST_MAIN(tst_qqmllistmodel)
#include "tst_qqmllistmodel.moc"
diff --git a/tests/auto/qml/qqmllistmodelworkerscript/tst_qqmllistmodelworkerscript.cpp b/tests/auto/qml/qqmllistmodelworkerscript/tst_qqmllistmodelworkerscript.cpp
index 9564d6a8b2..6301c35676 100644
--- a/tests/auto/qml/qqmllistmodelworkerscript/tst_qqmllistmodelworkerscript.cpp
+++ b/tests/auto/qml/qqmllistmodelworkerscript/tst_qqmllistmodelworkerscript.cpp
@@ -192,7 +192,7 @@ void tst_qqmllistmodelworkerscript::dynamic_data()
QTest::addColumn<QString>("warning");
QTest::addColumn<bool>("dynamicRoles");
- for (int i=0 ; i < 2 ; ++i) {
+ for (int i = 0; i < 2; ++i) {
bool dr = (i != 0);
// Simple flat model
@@ -434,7 +434,7 @@ void tst_qqmllistmodelworkerscript::get_data()
QTest::addColumn<QVariant>("roleValue");
QTest::addColumn<bool>("dynamicRoles");
- for (int i=0 ; i < 2 ; ++i) {
+ for (int i =0; i < 2; ++i) {
bool dr = (i != 0);
QTest::newRow("simple value") << "get(0).roleA = 500" << 0 << "roleA" << QVariant(500) << dr;
@@ -515,7 +515,7 @@ void tst_qqmllistmodelworkerscript::property_changes_data()
QTest::addColumn<QString>("testExpression");
QTest::addColumn<bool>("dynamicRoles");
- for (int i=0 ; i < 2 ; ++i) {
+ for (int i=1 ; i < 2 ; ++i) {
bool dr = (i != 0);
QTest::newRow("set: plain") << "append({'a':123, 'b':456, 'c':789});" << "set(0,{'b':123});"
@@ -574,7 +574,7 @@ void tst_qqmllistmodelworkerscript::property_changes_data()
<< "b" << 0 << true << "get(0).b.get(0).a == 1 && get(0).b.get(1).a == 2 && get(0).b.get(2).a == 3" << dr;
QTest::newRow("nested-set: list, no changes, empty") << "append({'a':123, 'b':[], 'c':789});" << "set(0,{'b':[]});"
- << "b" << 0 << true << "get(0).b.count == 0" << dr;
+ << "b" << 0 << false << "get(0).b.count == 0" << dr;
}
}
diff --git a/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp b/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp
index d0ce83b997..4f4deaafe5 100644
--- a/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp
+++ b/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp
@@ -1268,8 +1268,8 @@ void tst_qqmllocale::timeZoneUpdated()
{
QByteArray original(qgetenv("TZ"));
- // Set the timezone to Brisbane time
- setTimeZone(QByteArray("AEST-10:00"));
+ // Set the timezone to Brisbane time, AEST-10:00
+ setTimeZone(QByteArray("Australia/Brisbane"));
DateFormatter formatter;
@@ -1281,8 +1281,8 @@ void tst_qqmllocale::timeZoneUpdated()
QVERIFY(obj);
QVERIFY(obj->property("success").toBool());
- // Change to Indian time
- setTimeZone(QByteArray("IST-05:30"));
+ // Change to Indian time, IST-05:30
+ setTimeZone(QByteArray("Asia/Kolkata"));
QMetaObject::invokeMethod(obj.data(), "check");
diff --git a/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/invalidStrictModule.pro b/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/invalidStrictModule.pro
deleted file mode 100644
index 150f2f08d3..0000000000
--- a/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/invalidStrictModule.pro
+++ /dev/null
@@ -1,12 +0,0 @@
-TEMPLATE = lib
-CONFIG += plugin
-SOURCES = plugin.cpp
-QT = core qml
-DESTDIR = ../imports/org/qtproject/InvalidStrictModule
-
-QT += core-private gui-private qml-private
-
-IMPORT_FILES = \
- qmldir
-
-include (../../../shared/imports.pri)
diff --git a/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/qmldir b/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/qmldir
deleted file mode 100644
index 20716dc9f9..0000000000
--- a/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/qmldir
+++ /dev/null
@@ -1,2 +0,0 @@
-module org.qtproject.InvalidStrictModule
-plugin invalidStrictModule
diff --git a/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro b/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro
index 0f548aa6f8..ae13a041cc 100644
--- a/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro
+++ b/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro
@@ -11,7 +11,6 @@ SUBDIRS =\
nestedPlugin\
strictModule\
strictModule.2\
- invalidStrictModule\
nonstrictModule\
preemptiveModule\
preemptedStrictModule\
diff --git a/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp b/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp
index 9abff7b2f6..85e4918b61 100644
--- a/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp
+++ b/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp
@@ -580,12 +580,6 @@ void tst_qqmlmoduleplugin::importStrictModule_data()
<< QString()
<< QString();
- QTest::newRow("wrong target")
- << "import org.qtproject.InvalidStrictModule 1.0\n"
- "MyPluginType {}"
- << QString()
- << ":1:1: plugin cannot be loaded for module \"org.qtproject.InvalidStrictModule\": Cannot install element 'MyPluginType' into unregistered namespace 'org.qtproject.SomeOtherModule'";
-
QTest::newRow("non-strict clash")
<< "import org.qtproject.NonstrictModule 1.0\n"
"MyPluginType {}"
diff --git a/tests/auto/qml/qqmlnotifier/tst_qqmlnotifier.cpp b/tests/auto/qml/qqmlnotifier/tst_qqmlnotifier.cpp
index beb60925bb..88a5d41975 100644
--- a/tests/auto/qml/qqmlnotifier/tst_qqmlnotifier.cpp
+++ b/tests/auto/qml/qqmlnotifier/tst_qqmlnotifier.cpp
@@ -98,7 +98,7 @@ public:
}
protected:
- void connectNotify(const QMetaMethod &signal) Q_DECL_OVERRIDE {
+ void connectNotify(const QMetaMethod &signal) override {
if (signal.name() == "qmlObjectPropChanged") qmlObjectPropConnections++;
if (signal.name() == "cppObjectPropChanged") cppObjectPropConnections++;
if (signal.name() == "unboundPropChanged") unboundPropConnections++;
@@ -112,7 +112,7 @@ protected:
//qDebug() << Q_FUNC_INFO << this << signal.name();
}
- void disconnectNotify(const QMetaMethod &signal) Q_DECL_OVERRIDE {
+ void disconnectNotify(const QMetaMethod &signal) override {
if (signal.name() == "qmlObjectPropChanged") qmlObjectPropConnections--;
if (signal.name() == "cppObjectPropChanged") cppObjectPropConnections--;
if (signal.name() == "unboundPropChanged") unboundPropConnections--;
@@ -146,7 +146,7 @@ public:
{}
private slots:
- void initTestCase() Q_DECL_OVERRIDE;
+ void initTestCase() override;
void cleanupTestCase();
void testConnectNotify();
diff --git a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp
index 0576650d01..0bc1127069 100644
--- a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp
+++ b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp
@@ -888,7 +888,8 @@ void tst_qqmlqt::dateTimeFormattingVariants_data()
QTest::newRow("formatTime, qtime") << "formatTime" << QVariant::fromValue(time) << (QStringList() << temporary.time().toString(Qt::DefaultLocaleShortDate) << temporary.time().toString(Qt::DefaultLocaleLongDate) << temporary.time().toString("H:m:s a") << temporary.time().toString("hh:mm:ss.zzz"));
QDate date(2011,5,31);
- temporary = QDateTime(date);
+ // V4 reads the date in UTC but DateObject::toQDateTime() gives it back in local time:
+ temporary = QDateTime(date, QTime(0, 0, 0), Qt::UTC).toLocalTime();
QTest::newRow("formatDate, qdate") << "formatDate" << QVariant::fromValue(date) << (QStringList() << temporary.date().toString(Qt::DefaultLocaleShortDate) << temporary.date().toString(Qt::DefaultLocaleLongDate) << temporary.date().toString("ddd MMMM d yy"));
QTest::newRow("formatDateTime, qdate") << "formatDateTime" << QVariant::fromValue(date) << (QStringList() << temporary.toString(Qt::DefaultLocaleShortDate) << temporary.toString(Qt::DefaultLocaleLongDate) << temporary.toString("M/d/yy H:m:s a"));
QTest::newRow("formatTime, qdate") << "formatTime" << QVariant::fromValue(date) << (QStringList() << temporary.time().toString(Qt::DefaultLocaleShortDate) << temporary.time().toString(Qt::DefaultLocaleLongDate) << temporary.time().toString("H:m:s a") << temporary.time().toString("hh:mm:ss.zzz"));
@@ -997,7 +998,7 @@ void tst_qqmlqt::exit()
QSignalSpy spy(&engine, &QQmlEngine::exit);
QObject *object = component.create();
- QVERIFY(object != Q_NULLPTR);
+ QVERIFY(object != nullptr);
QCOMPARE(spy.count(), 1);
QList<QVariant> arguments = spy.takeFirst();
QVERIFY(arguments.at(0).toInt() == object->property("returnCode").toInt());
diff --git a/tests/auto/qml/qqmltranslation/data/TranslationChangeBase.qml b/tests/auto/qml/qqmltranslation/data/TranslationChangeBase.qml
new file mode 100644
index 0000000000..c447c84987
--- /dev/null
+++ b/tests/auto/qml/qqmltranslation/data/TranslationChangeBase.qml
@@ -0,0 +1,5 @@
+import QtQml 2.0
+
+QtObject {
+ property string baseProperty: qsTr("translate me");
+}
diff --git a/tests/auto/qml/qqmltranslation/data/translationChange.qml b/tests/auto/qml/qqmltranslation/data/translationChange.qml
new file mode 100644
index 0000000000..23b87c2493
--- /dev/null
+++ b/tests/auto/qml/qqmltranslation/data/translationChange.qml
@@ -0,0 +1,10 @@
+import QtQml 2.0
+
+TranslationChangeBase {
+ baseProperty: "do not translate"
+ property string text1: qsTr("translate me")
+ function weDoTranslations() {
+ return qsTr("translate me")
+ }
+ property string text2: weDoTranslations()
+}
diff --git a/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp b/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp
index dd4edeb97d..80c54bdf8e 100644
--- a/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp
+++ b/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp
@@ -44,6 +44,7 @@ private slots:
void translation_data();
void translation();
void idTranslation();
+ void translationChange();
};
void tst_qqmltranslation::translation_data()
@@ -162,6 +163,51 @@ void tst_qqmltranslation::idTranslation()
delete object;
}
+class DummyTranslator : public QTranslator
+{
+ Q_OBJECT
+
+ QString translate(const char *context, const char *sourceText, const char *disambiguation, int n) const override
+ {
+ Q_UNUSED(context);
+ Q_UNUSED(disambiguation);
+ Q_UNUSED(n);
+ if (!qstrcmp(sourceText, "translate me"))
+ return QString::fromUtf8("xxx");
+ return QString();
+ }
+
+ bool isEmpty() const override
+ {
+ return false;
+ }
+};
+
+void tst_qqmltranslation::translationChange()
+{
+ QQmlEngine engine;
+
+ QQmlComponent component(&engine, testFileUrl("translationChange.qml"));
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+
+ QCOMPARE(object->property("baseProperty").toString(), QString::fromUtf8("do not translate"));
+ QCOMPARE(object->property("text1").toString(), QString::fromUtf8("translate me"));
+ QCOMPARE(object->property("text2").toString(), QString::fromUtf8("translate me"));
+
+ DummyTranslator translator;
+ QCoreApplication::installTranslator(&translator);
+
+ QEvent ev(QEvent::LanguageChange);
+ QCoreApplication::sendEvent(&engine, &ev);
+
+ QCOMPARE(object->property("baseProperty").toString(), QString::fromUtf8("do not translate"));
+ QCOMPARE(object->property("text1").toString(), QString::fromUtf8("xxx"));
+ QCOMPARE(object->property("text2").toString(), QString::fromUtf8("xxx"));
+
+ QCoreApplication::removeTranslator(&translator);
+}
+
QTEST_MAIN(tst_qqmltranslation)
#include "tst_qqmltranslation.moc"
diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/send_data.11.expect b/tests/auto/qml/qqmlxmlhttprequest/data/send_data.11.expect
new file mode 100644
index 0000000000..6d34e1d2bb
--- /dev/null
+++ b/tests/auto/qml/qqmlxmlhttprequest/data/send_data.11.expect
Binary files differ
diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/send_data.11.qml b/tests/auto/qml/qqmlxmlhttprequest/data/send_data.11.qml
new file mode 100644
index 0000000000..ba9761201e
--- /dev/null
+++ b/tests/auto/qml/qqmlxmlhttprequest/data/send_data.11.qml
@@ -0,0 +1,23 @@
+import QtQuick 2.0
+
+QtObject {
+ property string url
+
+ property bool dataOK: false
+
+ Component.onCompleted: {
+ var x = new XMLHttpRequest;
+ x.open("POST", url);
+ x.setRequestHeader("Accept-Language","en-US");
+
+ // Test to the end
+ x.onreadystatechange = function() {
+ if (x.readyState == XMLHttpRequest.DONE) {
+ dataOK = (x.responseText == "QML Rocks!\n");
+ }
+ }
+
+ var data = new Uint8Array([1, 2, 3, 0, 3, 2, 1])
+ x.send(data.buffer);
+ }
+}
diff --git a/tests/auto/qml/qqmlxmlhttprequest/qqmlxmlhttprequest.pro b/tests/auto/qml/qqmlxmlhttprequest/qqmlxmlhttprequest.pro
index 44b2963918..572ab1d572 100644
--- a/tests/auto/qml/qqmlxmlhttprequest/qqmlxmlhttprequest.pro
+++ b/tests/auto/qml/qqmlxmlhttprequest/qqmlxmlhttprequest.pro
@@ -2,7 +2,6 @@ CONFIG += testcase
TARGET = tst_qqmlxmlhttprequest
macx:CONFIG -= app_bundle
-INCLUDEPATH += ../../shared/
HEADERS += ../../shared/testhttpserver.h
SOURCES += tst_qqmlxmlhttprequest.cpp \
diff --git a/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp b/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp
index 1ce07ecdab..59716acc0d 100644
--- a/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp
+++ b/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp
@@ -291,7 +291,7 @@ class TestThreadedHTTPServer : public QObject
Q_OBJECT
public:
TestThreadedHTTPServer(const QUrl &expectUrl, const QUrl &replyUrl, const QUrl &bodyUrl)
- : m_server(Q_NULLPTR) {
+ : m_server(nullptr) {
QMutexLocker locker(&m_lock);
moveToThread(&m_thread);
m_thread.start();
@@ -597,6 +597,7 @@ void tst_qqmlxmlhttprequest::send_withdata_data()
QTest::newRow("Incorrect content-type - out of order") << "send_data.4.expect" << "send_data.5.qml";
QTest::newRow("PUT") << "send_data.6.expect" << "send_data.6.qml";
QTest::newRow("Correct content-type - no charset") << "send_data.1.expect" << "send_data.7.qml";
+ QTest::newRow("ArrayBuffer") << "send_data.11.expect" << "send_data.11.qml";
}
void tst_qqmlxmlhttprequest::send_options()
diff --git a/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp b/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp
index f19e82032a..1a23286ede 100644
--- a/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp
+++ b/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp
@@ -42,6 +42,7 @@
// From qquickfolderlistmodel.h
const int FileNameRole = Qt::UserRole+1;
enum SortField { Unsorted, Name, Time, Size, Type };
+enum Status { Null, Ready, Loading };
class tst_qquickfolderlistmodel : public QQmlDataTest
{
@@ -58,6 +59,7 @@ public slots:
private slots:
void initTestCase();
void basicProperties();
+ void status();
void showFiles();
void resetFiltering();
void nameFilters();
@@ -141,6 +143,20 @@ void tst_qquickfolderlistmodel::basicProperties()
QCOMPARE(flm->property("folder").toUrl(), QUrl::fromLocalFile(""));
}
+void tst_qquickfolderlistmodel::status()
+{
+ QQmlComponent component(&engine, testFileUrl("basic.qml"));
+ checkNoErrors(component);
+
+ QAbstractListModel *flm = qobject_cast<QAbstractListModel*>(component.create());
+ QVERIFY(flm != 0);
+ QTRY_COMPARE(flm->property("status").toInt(), int(Ready));
+ flm->setProperty("folder", QUrl::fromLocalFile(""));
+ QTRY_COMPARE(flm->property("status").toInt(), int(Null));
+ flm->setProperty("folder", QUrl::fromLocalFile(QDir::currentPath()));
+ QTRY_COMPARE(flm->property("status").toInt(), int(Ready));
+}
+
void tst_qquickfolderlistmodel::showFiles()
{
QQmlComponent component(&engine, testFileUrl("basic.qml"));
diff --git a/tests/auto/qml/qwidgetsinqml/qwidgetsinqml.pro b/tests/auto/qml/qwidgetsinqml/qwidgetsinqml.pro
new file mode 100644
index 0000000000..c86365d5ea
--- /dev/null
+++ b/tests/auto/qml/qwidgetsinqml/qwidgetsinqml.pro
@@ -0,0 +1,7 @@
+CONFIG += testcase
+CONFIG += parallel_test
+TARGET = tst_qwidgetsinqml
+macos:CONFIG -= app_bundle
+QT += qml widgets testlib gui-private
+SOURCES += tst_qwidgetsinqml.cpp
+DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qml/qwidgetsinqml/tst_qwidgetsinqml.cpp b/tests/auto/qml/qwidgetsinqml/tst_qwidgetsinqml.cpp
new file mode 100644
index 0000000000..c7bbb55474
--- /dev/null
+++ b/tests/auto/qml/qwidgetsinqml/tst_qwidgetsinqml.cpp
@@ -0,0 +1,283 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QQmlEngine>
+#include <QtQml>
+#include <QWidget>
+
+class tst_QWidgetsInQml : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QWidgetsInQml();
+
+private slots:
+ void instantiateWidget();
+ void instantiateWidgetWithoutParentWidget();
+ void widgetAsDefaultPropertyCollected();
+ void widgetAsDefaultPropertyKept();
+ void widgetAsDefaultPropertyKeptDuringCreation();
+};
+
+static void gc(QQmlEngine &engine)
+{
+ engine.collectGarbage();
+ QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+ QCoreApplication::processEvents();
+}
+
+// Like QtObject, but with default property
+class QObjectContainer : public QObject
+{
+ Q_OBJECT
+ Q_CLASSINFO("DefaultProperty", "data");
+ Q_PROPERTY(QQmlListProperty<QObject> data READ data DESIGNABLE false);
+public:
+ QObjectContainer()
+ : widgetParent(0)
+ , gcOnAppend(false)
+ {}
+
+ QQmlListProperty<QObject> data() {
+ return QQmlListProperty<QObject>(this, 0, children_append, children_count, children_at, children_clear);
+ }
+
+ static void children_append(QQmlListProperty<QObject> *prop, QObject *o)
+ {
+ QObjectContainer *that = static_cast<QObjectContainer*>(prop->object);
+ that->dataChildren.append(o);
+ QObject::connect(o, SIGNAL(destroyed(QObject*)), prop->object, SLOT(childDestroyed(QObject*)));
+ QWidget *widget = qobject_cast<QWidget*>(o);
+ if (widget && that->widgetParent)
+ widget->setParent(that->widgetParent);
+
+ if (that->gcOnAppend) {
+ QQmlEngine *engine = qmlEngine(that);
+ gc(*engine);
+ }
+ }
+
+ static int children_count(QQmlListProperty<QObject> *prop)
+ {
+ return static_cast<QObjectContainer*>(prop->object)->dataChildren.count();
+ }
+
+ static QObject *children_at(QQmlListProperty<QObject> *prop, int index)
+ {
+ return static_cast<QObjectContainer*>(prop->object)->dataChildren.at(index);
+ }
+
+ static void children_clear(QQmlListProperty<QObject> *prop)
+ {
+ QObjectContainer *that = static_cast<QObjectContainer*>(prop->object);
+ foreach (QObject *c, that->dataChildren)
+ QObject::disconnect(c, SIGNAL(destroyed(QObject*)), that, SLOT(childDestroyed(QObject*)));
+ that->dataChildren.clear();
+ }
+
+ QList<QObject*> dataChildren;
+ QWidget *widgetParent;
+ bool gcOnAppend;
+
+protected slots:
+ void childDestroyed(QObject *child) {
+ dataChildren.removeAll(child);
+ }
+};
+
+class QWidgetContainer : public QObjectContainer
+{
+ Q_OBJECT
+public:
+ QWidgetContainer()
+ {
+ widgetParent = new QWidget;
+ QQmlEngine::setObjectOwnership(widgetParent, QQmlEngine::CppOwnership);
+ }
+ virtual ~QWidgetContainer()
+ {
+ delete widgetParent;
+ widgetParent = 0;
+ }
+};
+
+class QObjectContainerWithGCOnAppend : public QObjectContainer
+{
+ Q_OBJECT
+public:
+ QObjectContainerWithGCOnAppend()
+ {
+ gcOnAppend = true;
+ }
+};
+
+tst_QWidgetsInQml::tst_QWidgetsInQml()
+{
+ qmlRegisterType<QWidget>("Qt.Widgets", 1, 0, "QWidget");
+ qmlRegisterType<QObjectContainer>("Qt.Widgets", 1, 0, "QObjectContainer");
+ qmlRegisterType<QWidgetContainer>("Qt.Widgets", 1, 0, "QWidgetContainer");
+ qmlRegisterType<QObjectContainerWithGCOnAppend>("Qt.Widgets", 1, 0, "QObjectContainerWithGCOnAppend");
+}
+
+void tst_QWidgetsInQml::instantiateWidget()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData("import Qt.Widgets 1.0;\nQWidget { property QWidget child: QWidget { objectName: 'child' } }", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+ QWidget *rootWidget = qobject_cast<QWidget*>(object.data());
+ QVERIFY(rootWidget != 0);
+ QCOMPARE(rootWidget->children().count(), 1);
+ QWidget *firstChildWidget = qobject_cast<QWidget*>(rootWidget->children().first());
+ QVERIFY(firstChildWidget != 0);
+
+ QWidget *widgetProperty = qvariant_cast<QWidget*>(object->property("child"));
+ QVERIFY(widgetProperty != 0);
+ QCOMPARE(firstChildWidget, widgetProperty);
+ QCOMPARE(firstChildWidget->objectName(), QString("child"));
+}
+
+void tst_QWidgetsInQml::instantiateWidgetWithoutParentWidget()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData("import Qt.Widgets 1.0;\n"
+ "import QtQml 2.0;\n"
+ "QtObject { property QtObject child: QWidget { objectName: 'child' } }", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+
+ QPointer<QWidget> widgetProperty = qvariant_cast<QWidget*>(object->property("child"));
+ QVERIFY(!widgetProperty.isNull());
+ QCOMPARE(widgetProperty->objectName(), QString("child"));
+
+ QVERIFY(!widgetProperty->parent());
+ gc(engine);
+ // Don't collect, the property reference should keep it alive
+ QVERIFY(!widgetProperty.isNull());
+}
+
+void tst_QWidgetsInQml::widgetAsDefaultPropertyCollected()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData("import Qt.Widgets 1.0;\n"
+ "import QtQml 2.0;\n"
+ "QObjectContainer {\n"
+ " QWidget {\n"
+ " id: parentLessChild;\n"
+ " objectName: 'child'\n"
+ " }\n"
+ " property var widgetHolder;\n"
+ " Component.onCompleted: {\n"
+ " widgetHolder = parentLessChild;\n"
+ " }\n"
+ "}", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+
+ QObjectContainer *container = qobject_cast<QObjectContainer*>(object.data());
+ QCOMPARE(container->dataChildren.count(), 1);
+
+ QJSValue holder = qvariant_cast<QJSValue>(object->property("widgetHolder"));
+ QVERIFY(!holder.isNull());
+ gc(engine);
+ QCOMPARE(container->dataChildren.count(), 1);
+
+ holder = QJSValue();
+ object->setProperty("widgetHolder", QVariant::fromValue(holder));
+
+ gc(engine);
+ // The QWidget is without a parent and nobody is referencing it anymore (the children
+ // list in QObjectContainer is weak!), so it should get collected.
+ QCOMPARE(container->dataChildren.count(), 0);
+}
+
+void tst_QWidgetsInQml::widgetAsDefaultPropertyKept()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData("import Qt.Widgets 1.0;\n"
+ "import QtQml 2.0;\n"
+ "QWidgetContainer {\n"
+ " QWidget {\n"
+ " id: parentLessChild;\n"
+ " objectName: 'child'\n"
+ " }\n"
+ " property var widgetHolder;\n"
+ " Component.onCompleted: {\n"
+ " widgetHolder = parentLessChild;\n"
+ " }\n"
+ "}", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+
+ QWidgetContainer *container = qobject_cast<QWidgetContainer*>(object.data());
+ QCOMPARE(container->dataChildren.count(), 1);
+
+ QJSValue holder = qvariant_cast<QJSValue>(object->property("widgetHolder"));
+ QVERIFY(!holder.isNull());
+ gc(engine);
+ QCOMPARE(container->dataChildren.count(), 1);
+
+ holder = QJSValue();
+ object->setProperty("widgetHolder", QVariant::fromValue(holder));
+
+ gc(engine);
+ QCOMPARE(container->dataChildren.count(), 1);
+}
+
+void tst_QWidgetsInQml::widgetAsDefaultPropertyKeptDuringCreation()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData("import Qt.Widgets 1.0;\n"
+ "import QtQml 2.0;\n"
+ "QObjectContainerWithGCOnAppend {\n"
+ " QWidget {\n"
+ " id: parentLessChild;\n"
+ " objectName: 'child'\n"
+ " property var blah;\n" // Ensures that we have a JS wrapper
+ " }\n"
+ "}", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+
+ QObjectContainer *container = qobject_cast<QObjectContainer*>(object.data());
+ QCOMPARE(container->dataChildren.count(), 1);
+
+ gc(engine);
+ QCOMPARE(container->dataChildren.count(), 0);
+
+}
+
+QTEST_MAIN(tst_QWidgetsInQml)
+
+#include "tst_qwidgetsinqml.moc"
diff --git a/tests/auto/qmltest-blacklist/shortcut/shortcut.pro b/tests/auto/qmltest-blacklist/shortcut/shortcut.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest-blacklist/shortcut/shortcut.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest-blacklist/shortcut/tst_shortcut.qml b/tests/auto/qmltest-blacklist/shortcut/tst_shortcut.qml
new file mode 100644
index 0000000000..bc433761e2
--- /dev/null
+++ b/tests/auto/qmltest-blacklist/shortcut/tst_shortcut.qml
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import QtQuick.Window 2.2
+import QtTest 1.2
+
+TestCase {
+ name: "ShortCut"
+ when: windowShown
+
+ Shortcut {
+ id: shortcut
+ property bool everActivated: false
+ sequence: StandardKey.NextChild
+ onActivated: everActivated = true
+ }
+
+ Shortcut {
+ id: shortcut2
+ property bool everActivated: false
+ sequence: "Ctrl+E,Ctrl+W"
+ onActivated: everActivated = true
+ }
+
+ function test_shortcut() {
+ keySequence(StandardKey.NextChild)
+ verify(shortcut.everActivated);
+
+ keySequence("Ctrl+E,Ctrl+W")
+ verify(shortcut2.everActivated);
+ }
+}
diff --git a/tests/auto/qmltest/BLACKLIST b/tests/auto/qmltest/BLACKLIST
deleted file mode 100644
index 9b39f87219..0000000000
--- a/tests/auto/qmltest/BLACKLIST
+++ /dev/null
@@ -1,16 +0,0 @@
-# Blacklist for testing
-[SelfTests::test_blacklisted_fail]
-*
-[SelfTests::test_blacklistWithData:test2]
-*
-[shadersource-dynamic-sourceobject::test_endresult]
-linux
-[tst_grabImage::test_equals]
-linux
-[ListView::test_listInteractiveCurrentIndexEnforce]
-linux
-osx-10.12
-[TextEdit::test_textentry]
-osx-10.12
-[TextEdit::test_textentry_char]
-osx-10.12
diff --git a/tests/auto/qmltest/animatedimage/animatedimage.pro b/tests/auto/qmltest/animatedimage/animatedimage.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/animatedimage/animatedimage.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/animations/animations.pro b/tests/auto/qmltest/animations/animations.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/animations/animations.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/borderimage/borderimage.pro b/tests/auto/qmltest/borderimage/borderimage.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/borderimage/borderimage.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/buttonclick/buttonclick.pro b/tests/auto/qmltest/buttonclick/buttonclick.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/buttonclick/buttonclick.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/createbenchmark/createbenchmark.pro b/tests/auto/qmltest/createbenchmark/createbenchmark.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/createbenchmark/createbenchmark.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/events/events.pro b/tests/auto/qmltest/events/events.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/events/events.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/events/tst_touch.qml b/tests/auto/qmltest/events/tst_touch.qml
index 5b209a6d0b..b7fa701429 100644
--- a/tests/auto/qmltest/events/tst_touch.qml
+++ b/tests/auto/qmltest/events/tst_touch.qml
@@ -35,6 +35,16 @@ MultiPointTouchArea {
width: 100
height: 100
+ // touchUpdatedSpy stores the QQuickTouchPoint, and in some cases
+ // MultiPointTouchArea can delete it out from under us.
+ // (test_simpleChain was failing because touchUpdatedSpy.signalArguments[0][0][0]
+ // ended up as an empty object somehow.) If we declare
+ // all the touchpoints that this test will use, that won't happen.
+ touchPoints: [
+ TouchPoint { },
+ TouchPoint { }
+ ]
+
SignalSpy {
id: touchUpdatedSpy
target: touchArea
@@ -173,10 +183,10 @@ MultiPointTouchArea {
function test_simpleChain() {
var first = 1;
- touchEvent(touchArea).press(first).commit().release(first).commit();
- compare(touchUpdatedSpy.count, 2);
- var touchPoint = touchUpdatedSpy.signalArguments[0][0][0];
- verify(comparePoint(touchPoint, first, touchArea.width / 2, touchArea.height / 2));
+ touchEvent(interior).press(first).commit().release(first).commit();
+ compare(interiorSpy.count, 2);
+ var touchPoint = interiorSpy.signalArguments[0][0][0];
+ verify(comparePoint(touchPoint, first, interior.width / 2, interior.height / 2));
}
}
}
diff --git a/tests/auto/qmltest/fontloader/fontloader.pro b/tests/auto/qmltest/fontloader/fontloader.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/fontloader/fontloader.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/gradient/gradient.pro b/tests/auto/qmltest/gradient/gradient.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/gradient/gradient.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/image/car.ktx b/tests/auto/qmltest/image/car.ktx
new file mode 100644
index 0000000000..2aefdd306b
--- /dev/null
+++ b/tests/auto/qmltest/image/car.ktx
Binary files differ
diff --git a/tests/auto/qmltest/image/image.pro b/tests/auto/qmltest/image/image.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/image/image.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/image/logo.pkm b/tests/auto/qmltest/image/logo.pkm
new file mode 100644
index 0000000000..c0987c5c36
--- /dev/null
+++ b/tests/auto/qmltest/image/logo.pkm
Binary files differ
diff --git a/tests/auto/qmltest/image/tst_image.qml b/tests/auto/qmltest/image/tst_image.qml
index 1c36e2a7c3..346bee6969 100644
--- a/tests/auto/qmltest/image/tst_image.qml
+++ b/tests/auto/qmltest/image/tst_image.qml
@@ -122,6 +122,16 @@ Item {
fillMode: Image.TileHorizontally
}
+ Image {
+ id: pkmImage
+ source: "logo.pkm"
+ }
+
+ Image {
+ id: ktxImage
+ source: "car.ktx"
+ }
+
TestCase {
name: "Image"
@@ -222,5 +232,14 @@ Item {
compare(tileModes3.fillMode, Image.TileHorizontally)
}
+ function test_pkmImage() {
+ compare(pkmImage.width, 256)
+ compare(pkmImage.height, 256)
+ }
+
+ function test_ktxImage() {
+ compare(ktxImage.width, 146)
+ compare(ktxImage.height, 80)
+ }
}
}
diff --git a/tests/auto/qmltest/itemgrabber/itemgrabber.pro b/tests/auto/qmltest/itemgrabber/itemgrabber.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/itemgrabber/itemgrabber.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/itemgrabber/tst_itemgrabber.qml b/tests/auto/qmltest/itemgrabber/tst_itemgrabber.qml
index a80814d6de..af1b4db0e0 100644
--- a/tests/auto/qmltest/itemgrabber/tst_itemgrabber.qml
+++ b/tests/auto/qmltest/itemgrabber/tst_itemgrabber.qml
@@ -40,6 +40,10 @@ Item {
when: imageOnDisk.ready && imageOnDiskSmall.ready
function test_endresult_disk() {
+ if ((Qt.platform.pluginName === "offscreen")
+ || (Qt.platform.pluginName === "minimal"))
+ skip("grabImage does not work on offscreen/minimal platforms");
+
var image = grabImage(root);
// imageOnDisk at (0, 0) - (100x100)
@@ -73,6 +77,10 @@ Item {
}
function test_endresult_cache(data) {
+ if ((Qt.platform.pluginName === "offscreen")
+ || (Qt.platform.pluginName === "minimal"))
+ skip("grabImage does not work on offscreen/minimal platforms");
+
imageInCache.cache = data.cache;
imageInCache.sourceSize = data.sourceSize;
imageInCache.fillMode = data.fillMode;
@@ -135,7 +143,7 @@ Item {
property int callCount: 0;
property bool ready: false;
function handleGrab(result) {
- if (!result.saveToFile("itemgrabber/image.png"))
+ if (!result.saveToFile("image.png"))
print("Error: Failed to save image to disk...");
source = "image.png";
ready = true;
@@ -149,7 +157,7 @@ Item {
y: 0
property bool ready: false;
function handleGrab(result) {
- if (!result.saveToFile("itemgrabber/image_small.png"))
+ if (!result.saveToFile("image_small.png"))
print("Error: Failed to save image to disk...");
source = "image_small.png";
ready = true;
diff --git a/tests/auto/qmltest/layout/layout.pro b/tests/auto/qmltest/layout/layout.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/layout/layout.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/listmodel/listmodel.pro b/tests/auto/qmltest/listmodel/listmodel.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/listmodel/listmodel.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/listmodel/tst_listmodel.qml b/tests/auto/qmltest/listmodel/tst_listmodel.qml
index 11f2019e08..2867897b0c 100644
--- a/tests/auto/qmltest/listmodel/tst_listmodel.qml
+++ b/tests/auto/qmltest/listmodel/tst_listmodel.qml
@@ -61,6 +61,16 @@ Item {
ListModel { id: secondmodel; ListElement { name: "SecondModelElement0" } ListElement { name: "SecondModelElement1" } }
ListModel { id: altermodel; ListElement { name: "AlterModelElement0" } ListElement { name: "AlterModelElement1" } }
+ property string funcResult
+ ListModel {
+ id: funcModel
+ property string modelProp
+ ListElement { friendlyText: "one"; action: function(obj) { funcResult = obj.friendlyText } }
+ ListElement { friendlyText: "two"; action: function() {} }
+ ListElement { friendlyText: "three"; action: function() { modelProp = "fail" } }
+ ListElement { friendlyText: "four"; action: function() { funcResult = friendlyText } }
+ }
+
TestCase {
name: "ListModel"
@@ -138,5 +148,51 @@ Item {
tryCompare(altermodel, 'count', 0)
compare(altermodel.get(0), undefined)
}
+
+ function test_functions() {
+ // test different ways of calling
+ funcModel.get(0).action(funcModel.get(0))
+ compare(funcResult, "one")
+ funcModel.get(0).action.call(this, { friendlyText: "seven" })
+ compare(funcResult, "seven")
+
+ // test different ways of setting
+ funcResult = ""
+ funcModel.get(1).action()
+ compare(funcResult, "")
+
+ funcModel.set(1, { friendlyText: "two", action: function() { funcResult = "set" } })
+ funcModel.get(1).action()
+ compare(funcResult, "set")
+
+ funcModel.setProperty(1, "action", function() { top.funcResult = "setProperty" })
+ funcModel.get(1).action()
+ compare(funcResult, "setProperty")
+
+ funcModel.get(1).action = function() { funcResult = "jsSet" }
+ funcModel.get(1).action()
+ compare(funcResult, "jsSet")
+
+ // test unsupported features
+ var didThrow = false
+ try {
+ funcModel.get(2).action()
+ } catch(ex) {
+ verify(ex.toString().includes("Error: Invalid write to global property"))
+ didThrow = true
+ }
+ verify(didThrow)
+
+ didThrow = false
+ try {
+ funcModel.get(3).action()
+ } catch(ex) {
+ verify(ex.toString().includes("ReferenceError: friendlyText is not defined"))
+ didThrow = true
+ }
+ verify(didThrow)
+
+
+ }
}
}
diff --git a/tests/auto/qmltest/listview/BLACKLIST b/tests/auto/qmltest/listview/BLACKLIST
new file mode 100644
index 0000000000..62bf89128d
--- /dev/null
+++ b/tests/auto/qmltest/listview/BLACKLIST
@@ -0,0 +1,3 @@
+# Blacklist for testing
+[ListView::test_listInteractiveCurrentIndexEnforce]
+*
diff --git a/tests/auto/qmltest/listview/listview.pro b/tests/auto/qmltest/listview/listview.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/listview/listview.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/listview/tst_listview.qml b/tests/auto/qmltest/listview/tst_listview.qml
index 2b5246b116..f7a34cbce2 100644
--- a/tests/auto/qmltest/listview/tst_listview.qml
+++ b/tests/auto/qmltest/listview/tst_listview.qml
@@ -161,6 +161,15 @@ Item {
}
}
+ ListView {
+ id: viewWithActionModel
+ property string funcResult
+ model: ListModel { ListElement { friendlyText: "one"; action: function(text) { viewWithActionModel.funcResult = text } } }
+ delegate: Item {
+ Component.onCompleted: action(model.friendlyText)
+ }
+ }
+
Component {
id: delegateModelAfterCreateComponent
Rectangle {
@@ -350,5 +359,9 @@ Item {
singleElementList.heightForDelegate = 200;
compare(singleElementList.contentHeightOnDelegateResize, 200);
}
+
+ function test_viewWithAction() {
+ compare(viewWithActionModel.funcResult, "one")
+ }
}
}
diff --git a/tests/auto/qmltest/objectmodel/objectmodel.pro b/tests/auto/qmltest/objectmodel/objectmodel.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/objectmodel/objectmodel.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/pathview/pathview.pro b/tests/auto/qmltest/pathview/pathview.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/pathview/pathview.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/pixel/pixel.pro b/tests/auto/qmltest/pixel/pixel.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/pixel/pixel.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/positioners/positioners.pro b/tests/auto/qmltest/positioners/positioners.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/positioners/positioners.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/qmltest.pro b/tests/auto/qmltest/qmltest.pro
index 52fd6bf9de..8ad1541cbc 100644
--- a/tests/auto/qmltest/qmltest.pro
+++ b/tests/auto/qmltest/qmltest.pro
@@ -1,14 +1,30 @@
-TEMPLATE=app
-TARGET=tst_qmltest
-CONFIG += qmltestcase
-CONFIG += console
-SOURCES += tst_qmltest.cpp
-
-
-importFiles.files = borderimage buttonclick createbenchmark events qqmlbinding selftests
-
-importFiles.path = .
-DEPLOYMENT += importFiles
-
-# Please do not make this test insignificant again, thanks.
-# Just skip those unstable ones. See also QTBUG-33723.
+TEMPLATE = subdirs
+SUBDIRS += \
+ animatedimage \
+ animations \
+ borderimage \
+ buttonclick \
+ createbenchmark \
+ events \
+ fontloader \
+ gradient \
+ image \
+ itemgrabber \
+ layout \
+ listmodel \
+ listview \
+ objectmodel \
+ pathview \
+ pixel \
+ positioners \
+ qqmlbinding \
+ qtbug46798 \
+ rectangle \
+ selftests \
+ shadersource \
+ stability \
+ statemachine \
+ text \
+ textedit \
+ textinput \
+ window
diff --git a/tests/auto/qmltest/qqmlbinding/qqmlbinding.pro b/tests/auto/qmltest/qqmlbinding/qqmlbinding.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/qqmlbinding/qqmlbinding.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/qtbug46798/qtbug46798.pro b/tests/auto/qmltest/qtbug46798/qtbug46798.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/qtbug46798/qtbug46798.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/rectangle/rectangle.pro b/tests/auto/qmltest/rectangle/rectangle.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/rectangle/rectangle.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/selftests/BLACKLIST b/tests/auto/qmltest/selftests/BLACKLIST
new file mode 100644
index 0000000000..ffce42e4c0
--- /dev/null
+++ b/tests/auto/qmltest/selftests/BLACKLIST
@@ -0,0 +1,13 @@
+# Blacklist for testing
+[SelfTests::test_blacklisted_fail]
+*
+[SelfTests::test_blacklistWithData:test2]
+*
+# QTBUG-53793: seems to be failing on Linux a little too often...
+[tst_grabImage::test_equals]
+linux
+[tst_grabImage::test_sizeProps]
+linux
+[tst_grabImage::test_save]
+linux
+
diff --git a/tests/auto/qmltest/selftests/selftests.pro b/tests/auto/qmltest/selftests/selftests.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/selftests/selftests.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/selftests/tst_grabImage.qml b/tests/auto/qmltest/selftests/tst_grabImage.qml
index 1748030f14..7ce7e93a07 100644
--- a/tests/auto/qmltest/selftests/tst_grabImage.qml
+++ b/tests/auto/qmltest/selftests/tst_grabImage.qml
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2017 Crimson AS <info@crimson.no>
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
@@ -35,7 +36,7 @@ TestCase {
when: windowShown
function test_equals() {
- var rect = Qt.createQmlObject("import QtQuick 2.0; Rectangle { color: 'red'; width: 10; height: 10; }", testCase);
+ var rect = createTemporaryQmlObject("import QtQuick 2.0; Rectangle { color: 'red'; width: 10; height: 10; }", testCase);
verify(rect);
var oldImage = grabImage(rect);
rect.width += 10;
@@ -45,9 +46,66 @@ TestCase {
oldImage = grabImage(rect);
// Don't change anything...
newImage = grabImage(rect);
- verify(newImage.equals(oldImage));
+ try {
+ compare(newImage.size, oldImage.size);
+ verify(newImage.equals(oldImage));
+ } catch (ex) {
+ oldImage.save("tst_grabImage_test_equals_oldImage.png")
+ newImage.save("tst_grabImage_test_equals_newImage.png")
+ throw ex;
+ }
verify(!newImage.equals(null));
verify(!newImage.equals(undefined));
}
+
+ function test_sizeProps() {
+ var rect = createTemporaryQmlObject("import QtQuick 2.0; Rectangle { color: 'red'; width: 10; height: 20; }", testCase);
+ var image = grabImage(rect);
+
+ try {
+ compare(image.width, 10)
+ compare(image.height, 20)
+ compare(image.size, Qt.size(10, 20))
+ } catch (ex) {
+ image.save("tst_grabImage_test_sizeProps.png")
+ throw ex;
+ }
+ }
+
+ function test_save() {
+ var rect = createTemporaryQmlObject("import QtQuick 2.0; Rectangle { color: 'red'; width: 10; height: 20; }", testCase);
+ var grabbedImage = grabImage(rect);
+ grabbedImage.save("tst_grabImage_test_save.png")
+
+ // Now try to load it
+ var url = Qt.resolvedUrl("tst_grabImage_test_save.png")
+ var image = createTemporaryQmlObject("import QtQuick 2.0; Image { source: \"" + url + "\" }", testCase);
+ tryCompare(image, "status", Image.Ready)
+ var grabbedImage2 = grabImage(image);
+
+ try {
+ verify(grabbedImage2.equals(grabbedImage))
+ } catch (ex) {
+ grabbedImage2.save("tst_grabImage_test_save2.png")
+ throw ex;
+ }
+ }
+
+ function test_saveThrowsWhenFailing() {
+ var rect = createTemporaryQmlObject("import QtQuick 2.0; Rectangle { color: 'red'; width: 10; height: 20; }", testCase);
+ var grabbedImage = grabImage(rect);
+ var didThrow = false;
+
+ try {
+ // Format doesn't exist, so this will throw
+ grabbedImage.save("tst_grabImage_test_saveThrowsWhenFailing.never-gonna-give-you-up");
+ } catch (ex) {
+ didThrow = true;
+ }
+
+ if (!didThrow) {
+ fail("save() should have thrown, but didn't!")
+ }
+ }
}
diff --git a/tests/auto/qmltest/selftests/tst_selftests.qml b/tests/auto/qmltest/selftests/tst_selftests.qml
index 439ea7a70d..5555876014 100644
--- a/tests/auto/qmltest/selftests/tst_selftests.qml
+++ b/tests/auto/qmltest/selftests/tst_selftests.qml
@@ -167,6 +167,16 @@ TestCase {
caught = true
}
verify(caught)
+
+ caught = false;
+ try {
+ testCase.verify(true, "foo", "bar")
+ } catch (e) {
+ compare(e.message, "QtQuickTest::fail")
+ compare(functions.failmsg, "More than two arguments given to verify(). Did you mean tryVerify() or tryCompare()?")
+ caught = true
+ }
+ verify(caught)
}
function test_compare() {
diff --git a/tests/auto/qmltest/shadersource/BLACKLIST b/tests/auto/qmltest/shadersource/BLACKLIST
new file mode 100644
index 0000000000..cc1e110153
--- /dev/null
+++ b/tests/auto/qmltest/shadersource/BLACKLIST
@@ -0,0 +1,3 @@
+# Blacklist for testing
+[shadersource-dynamic-sourceobject::test_endresult]
+linux
diff --git a/tests/auto/qmltest/shadersource/shadersource.pro b/tests/auto/qmltest/shadersource/shadersource.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/shadersource/shadersource.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/shadersource/tst_DynamicallyCreatedSource.qml b/tests/auto/qmltest/shadersource/tst_DynamicallyCreatedSource.qml
index 2c6d4cc28f..74dc63a972 100644
--- a/tests/auto/qmltest/shadersource/tst_DynamicallyCreatedSource.qml
+++ b/tests/auto/qmltest/shadersource/tst_DynamicallyCreatedSource.qml
@@ -67,6 +67,10 @@ Item {
when: root.source != undefined
function test_endresult() {
+ if ((Qt.platform.pluginName === "offscreen")
+ || (Qt.platform.pluginName === "minimal"))
+ skip("grabImage does not work on offscreen/minimal platforms");
+
var image = grabImage(root);
compare(image.red(0,0), 255);
compare(image.green(0,0), 0);
diff --git a/tests/auto/qmltest/stability/stability.pro b/tests/auto/qmltest/stability/stability.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/stability/stability.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/statemachine/statemachine.pro b/tests/auto/qmltest/statemachine/statemachine.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/statemachine/statemachine.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/text/text.pro b/tests/auto/qmltest/text/text.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/text/text.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/textedit/BLACKLIST b/tests/auto/qmltest/textedit/BLACKLIST
new file mode 100644
index 0000000000..e06cba3e8f
--- /dev/null
+++ b/tests/auto/qmltest/textedit/BLACKLIST
@@ -0,0 +1,6 @@
+# Blacklist for testing
+[TextEdit::test_textentry]
+osx-10.12
+[TextEdit::test_textentry_char]
+osx-10.12
+
diff --git a/tests/auto/qmltest/textedit/textedit.pro b/tests/auto/qmltest/textedit/textedit.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/textedit/textedit.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/textinput/textinput.pro b/tests/auto/qmltest/textinput/textinput.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/textinput/textinput.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/qmltest/window/window.pro b/tests/auto/qmltest/window/window.pro
new file mode 100644
index 0000000000..a7938e7003
--- /dev/null
+++ b/tests/auto/qmltest/window/window.pro
@@ -0,0 +1 @@
+CONFIG += qmltestcase
diff --git a/tests/auto/quick/drawingmodes/tst_drawingmodes.cpp b/tests/auto/quick/drawingmodes/tst_drawingmodes.cpp
index d4065e3d38..fe794cf952 100644
--- a/tests/auto/quick/drawingmodes/tst_drawingmodes.cpp
+++ b/tests/auto/quick/drawingmodes/tst_drawingmodes.cpp
@@ -149,6 +149,10 @@ void tst_drawingmodes::points()
if (QGuiApplication::primaryScreen()->depth() < 24)
QSKIP("This test does not work at display depths < 24");
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+
#ifdef Q_OS_WIN
if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES)
QSKIP("ANGLE cannot draw GL_POINTS.");
@@ -187,6 +191,11 @@ void tst_drawingmodes::lines()
DrawingModeItem::drawingMode = GL_LINES;
if (QGuiApplication::primaryScreen()->depth() < 24)
QSKIP("This test does not work at display depths < 24");
+
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+
QImage fb = runTest("DrawingModes.qml");
QCOMPARE(fb.width(), 200);
@@ -213,6 +222,11 @@ void tst_drawingmodes::lineStrip()
DrawingModeItem::drawingMode = GL_LINE_STRIP;
if (QGuiApplication::primaryScreen()->depth() < 24)
QSKIP("This test does not work at display depths < 24");
+
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+
QImage fb = runTest("DrawingModes.qml");
QCOMPARE(fb.width(), 200);
@@ -241,6 +255,11 @@ void tst_drawingmodes::lineLoop()
DrawingModeItem::drawingMode = GL_LINE_LOOP;
if (QGuiApplication::primaryScreen()->depth() < 24)
QSKIP("This test does not work at display depths < 24");
+
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+
QImage fb = runTest("DrawingModes.qml");
QCOMPARE(fb.width(), 200);
@@ -269,6 +288,11 @@ void tst_drawingmodes::triangles()
DrawingModeItem::drawingMode = GL_TRIANGLES;
if (QGuiApplication::primaryScreen()->depth() < 24)
QSKIP("This test does not work at display depths < 24");
+
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+
QImage fb = runTest("DrawingModes.qml");
QCOMPARE(fb.width(), 200);
@@ -293,6 +317,11 @@ void tst_drawingmodes::triangleStrip()
DrawingModeItem::drawingMode = GL_TRIANGLE_STRIP;
if (QGuiApplication::primaryScreen()->depth() < 24)
QSKIP("This test does not work at display depths < 24");
+
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+
QImage fb = runTest("DrawingModes.qml");
QCOMPARE(fb.width(), 200);
@@ -316,6 +345,11 @@ void tst_drawingmodes::triangleFan()
DrawingModeItem::drawingMode = GL_TRIANGLE_FAN;
if (QGuiApplication::primaryScreen()->depth() < 24)
QSKIP("This test does not work at display depths < 24");
+
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+
QImage fb = runTest("DrawingModes.qml");
QCOMPARE(fb.width(), 200);
diff --git a/tests/auto/quick/examples/tst_examples.cpp b/tests/auto/quick/examples/tst_examples.cpp
index b6742b9efe..2dc5a8ed23 100644
--- a/tests/auto/quick/examples/tst_examples.cpp
+++ b/tests/auto/quick/examples/tst_examples.cpp
@@ -86,6 +86,8 @@ tst_examples::tst_examples()
excludedDirs << "snippets/qml/visualdatamodel_rootindex";
excludedDirs << "snippets/qml/qtbinding";
excludedDirs << "snippets/qml/imports";
+ excludedFiles << "examples/quick/shapes/content/main.qml"; // relies on resources
+ excludedFiles << "examples/quick/shapes/content/interactive.qml"; // relies on resources
#ifdef QT_NO_XMLPATTERNS
excludedDirs << "demos/twitter";
diff --git a/tests/auto/quick/nodes/tst_nodestest.cpp b/tests/auto/quick/nodes/tst_nodestest.cpp
index 63e0aeb324..e7303604b4 100644
--- a/tests/auto/quick/nodes/tst_nodestest.cpp
+++ b/tests/auto/quick/nodes/tst_nodestest.cpp
@@ -41,6 +41,9 @@
#include <QtQuick/qsgsimpletexturenode.h>
#include <QtQuick/private/qsgtexture_p.h>
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/qpa/qplatformintegration.h>
+
QT_BEGIN_NAMESPACE
inline bool operator==(const QSGGeometry::TexturedPoint2D& l, const QSGGeometry::TexturedPoint2D& r)
{
@@ -80,6 +83,9 @@ private:
void NodesTest::initTestCase()
{
+ if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL))
+ QSKIP("OpenGL not supported by the platform");
+
QSGRenderLoop *renderLoop = QSGRenderLoop::instance();
surface = new QOffscreenSurface;
@@ -141,9 +147,9 @@ public:
int DummyRenderer::globalRendereringOrder;
NodesTest::NodesTest()
- : surface(Q_NULLPTR)
- , context(Q_NULLPTR)
- , renderContext(Q_NULLPTR)
+ : surface(nullptr)
+ , context(nullptr)
+ , renderContext(nullptr)
{
}
diff --git a/tests/auto/quick/nokeywords/tst_nokeywords.cpp b/tests/auto/quick/nokeywords/tst_nokeywords.cpp
index ad77743ddd..e6655589a3 100644
--- a/tests/auto/quick/nokeywords/tst_nokeywords.cpp
+++ b/tests/auto/quick/nokeywords/tst_nokeywords.cpp
@@ -55,7 +55,6 @@
#include <QtQuick/private/qsgdefaultinternalrectanglenode_p.h>
#include <QtQuick/private/qsgdepthstencilbuffer_p.h>
#include <QtQuick/private/qsgdistancefieldglyphnode_p.h>
-#include <QtQuick/private/qsgdistancefieldutil_p.h>
#endif
#include <QtQuick/private/qsggeometry_p.h>
#include <QtQuick/private/qsgnode_p.h>
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/FlashAnimation.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/FlashAnimation.qml
new file mode 100644
index 0000000000..4b2935b52e
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/FlashAnimation.qml
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+SequentialAnimation {
+ id: tapFlash
+ running: false
+ PropertyAction { value: false }
+ PauseAnimation { duration: 100 }
+ PropertyAction { value: true }
+ PauseAnimation { duration: 100 }
+ PropertyAction { value: false }
+ PauseAnimation { duration: 100 }
+ PropertyAction { value: true }
+ PauseAnimation { duration: 100 }
+ PropertyAction { value: false }
+ PauseAnimation { duration: 100 }
+ PropertyAction { value: true }
+}
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/Slider.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/Slider.qml
new file mode 100644
index 0000000000..f6acd53615
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/Slider.qml
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+
+Item {
+ id: root
+ property int value: 50
+ property int maximumValue: 99
+ property alias label: label.text
+ property alias tapEnabled: tap.enabled
+ property alias pressed: tap.pressed
+ signal tapped
+
+ Rectangle {
+ id: slot
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ anchors.margins: 10
+ anchors.topMargin: 30
+ anchors.bottomMargin: 30
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: 10
+ color: "black"
+ radius: width / 2
+ smooth: true
+ }
+
+ Rectangle {
+ id: glow
+ anchors.fill: knob
+ anchors.margins: -5
+ anchors.leftMargin: -2
+ anchors.horizontalCenterOffset: 1
+ radius: 5
+ color: "#4400FFFF"
+ opacity: tap.pressed || tapFlash.running ? 1 : 0
+ FlashAnimation on visible {
+ id: tapFlash
+ }
+ }
+ Rectangle {
+ id: knob
+ objectName: "Slider Knob"
+ width: parent.width - 2
+ height: 20
+ radius: 5
+ color: "darkgray"
+ border.color: "black"
+ property bool programmatic: false
+ property real multiplier: root.maximumValue / (dragHandler.yAxis.maximum - dragHandler.yAxis.minimum)
+ onYChanged: if (!programmatic) root.value = root.maximumValue - (knob.y - dragHandler.yAxis.minimum) * multiplier
+ transformOrigin: Item.Center
+ function setValue(value) { knob.y = dragHandler.yAxis.maximum - value / knob.multiplier }
+ DragHandler {
+ id: dragHandler
+ objectName: label.text + " DragHandler"
+ xAxis.enabled: false
+ yAxis.minimum: slot.y
+ yAxis.maximum: slot.height + slot.y - knob.height
+ }
+ TapHandler {
+ id: tap
+ objectName: label.text + " TapHandler"
+ gesturePolicy: TapHandler.DragThreshold
+ onTapped: {
+ tapFlash.start()
+ root.tapped
+ }
+ }
+ }
+
+ Text {
+ font.pointSize: 16
+ color: "red"
+ anchors.bottom: parent.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ text: root.value
+ }
+
+ Text {
+ id: label
+ font.pointSize: 12
+ color: "red"
+ anchors.top: parent.top
+ anchors.topMargin: 5
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+
+ Component.onCompleted: {
+ knob.programmatic = true
+ knob.setValue(root.value)
+ knob.programmatic = false
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/TapHandlerButton.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/TapHandlerButton.qml
new file mode 100644
index 0000000000..55f77460f1
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/TapHandlerButton.qml
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+
+Rectangle {
+ id: root
+ property alias label: label.text
+ property alias pressed: tap.pressed
+ property bool checked: false
+ property alias gesturePolicy: tap.gesturePolicy
+ property alias enabled: tap.enabled
+ signal tapped
+
+ width: label.implicitWidth * 1.5; height: label.implicitHeight * 2.0
+ border.color: "#9f9d9a"; border.width: 1; radius: height / 4; antialiasing: true
+
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: tap.pressed ? "#b8b5b2" : "#efebe7" }
+ GradientStop { position: 1.0; color: "#b8b5b2" }
+ }
+
+ TapHandler {
+ id: tap
+ objectName: label.text
+ longPressThreshold: 100 // CI can be insanely slow, so don't demand a timely release to generate onTapped
+ onTapped: {
+ tapFlash.start()
+ root.tapped()
+ }
+ }
+
+ Text {
+ id: label
+ font.pointSize: 14
+ text: "Button"
+ anchors.centerIn: parent
+ }
+
+ Rectangle {
+ anchors.fill: parent; anchors.margins: -5
+ color: "transparent"; border.color: "#4400FFFF"
+ border.width: 5; radius: root.radius; antialiasing: true
+ opacity: tapFlash.running ? 1 : 0
+ FlashAnimation on visible { id: tapFlash }
+ }
+
+ Rectangle {
+ objectName: "expandingCircle"
+ radius: tap.timeHeld * 100
+ visible: radius > 0 && tap.pressed
+ border.width: 3
+ border.color: "cyan"
+ color: "transparent"
+ width: radius * 2
+ height: radius * 2
+ x: tap.point.scenePressPosition.x - radius
+ y: tap.point.scenePressPosition.y - radius
+ opacity: 0.25
+ Component.onCompleted: {
+ // get on top of all the buttons
+ var par = root.parent;
+ while (par.parent)
+ par = par.parent;
+ parent = par;
+ }
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/data/flickableWithHandlers.qml b/tests/auto/quick/pointerhandlers/flickableinterop/data/flickableWithHandlers.qml
new file mode 100644
index 0000000000..7d7f53dd15
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/data/flickableWithHandlers.qml
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+
+Rectangle {
+ id: root
+ width: 800
+ height: 480
+ objectName: "root"
+ color: "#222222"
+
+ Flickable {
+ anchors.fill: parent
+ anchors.margins: 10
+ anchors.topMargin: 40
+ contentHeight: 600
+ contentWidth: 1000
+// pressDelay: TODO
+
+ Row {
+ spacing: 6
+ Slider {
+ label: "DragHandler"
+ objectName: "Slider"
+ value: 49; width: 100; height: 400
+ }
+ Column {
+ spacing: 6
+ TapHandlerButton {
+ objectName: "DragThreshold"
+ label: "DragThreshold"
+ gesturePolicy: TapHandler.DragThreshold
+ }
+ TapHandlerButton {
+ objectName: "WithinBounds"
+ label: "WithinBounds"
+ gesturePolicy: TapHandler.WithinBounds
+ }
+ TapHandlerButton {
+ objectName: "ReleaseWithinBounds"
+ label: "ReleaseWithinBounds"
+ gesturePolicy: TapHandler.ReleaseWithinBounds // the default
+ }
+ }
+ Column {
+ spacing: 6
+ Rectangle {
+ width: 50
+ height: 50
+ color: "aqua"
+ border.color: drag1.active ? "darkgreen" : "transparent"
+ border.width: 3
+ objectName: "drag"
+ DragHandler {
+ id: drag1
+ }
+ Text {
+ anchors.centerIn: parent
+ enabled: false
+ text: "drag"
+ }
+ }
+ Rectangle {
+ width: 50
+ height: 50
+ color: "aqua"
+ objectName: "tap"
+ border.color: tap1.isPressed ? "red" : "transparent"
+ border.width: 3
+ TapHandler {
+ id: tap1
+ gesturePolicy: TapHandler.DragThreshold
+ }
+ Text {
+ anchors.centerIn: parent
+ enabled: false
+ text: "tap"
+ }
+ }
+ Rectangle {
+ width: 50
+ height: 50
+ color: "aqua"
+ border.color: tap2.isPressed ? "red" : drag2.active ? "darkgreen" : "transparent"
+ border.width: 3
+ objectName: "dragAndTap"
+ DragHandler {
+ id: drag2
+ }
+ TapHandler {
+ id: tap2
+ gesturePolicy: TapHandler.DragThreshold
+ }
+ Text {
+ anchors.centerIn: parent
+ enabled: false
+ text: "drag\nand\ntap"
+ }
+ }
+ Rectangle {
+ width: 50
+ height: 50
+ color: "aqua"
+ border.color: tap3.isPressed ? "red" : drag3.active ? "darkgreen" : "transparent"
+ border.width: 3
+ objectName: "tapAndDrag"
+ TapHandler {
+ id: tap3
+ gesturePolicy: TapHandler.DragThreshold
+ }
+ DragHandler {
+ id: drag3
+ }
+ Text {
+ anchors.centerIn: parent
+ enabled: false
+ text: "tap\nand\ndrag"
+ }
+ }
+ }
+ }
+ }
+}
+
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/flickableinterop.pro b/tests/auto/quick/pointerhandlers/flickableinterop/flickableinterop.pro
new file mode 100644
index 0000000000..9075044bd3
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/flickableinterop.pro
@@ -0,0 +1,15 @@
+CONFIG += testcase
+
+TARGET = tst_flickableinterop
+QT += core-private gui-private qml-private quick-private testlib
+
+macos:CONFIG -= app_bundle
+
+SOURCES += tst_flickableinterop.cpp
+
+include (../../../shared/util.pri)
+include (../../shared/util.pri)
+
+TESTDATA = data/*
+
+OTHER_FILES += data/flickableWithHandlers.qml data/Slider.qml
diff --git a/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp b/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp
new file mode 100644
index 0000000000..c0b34f8246
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/flickableinterop/tst_flickableinterop.cpp
@@ -0,0 +1,566 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+#include <QtGui/qstylehints.h>
+#include <QtQuick/qquickview.h>
+#include <QtQuick/qquickitem.h>
+#include <QtQuick/private/qquickflickable_p.h>
+#include <QtQuick/private/qquickpointerhandler_p.h>
+#include <QtQuick/private/qquickdraghandler_p.h>
+#include <QtQuick/private/qquicktaphandler_p.h>
+#include <qpa/qwindowsysteminterface.h>
+
+#include <private/qquickwindow_p.h>
+
+#include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlproperty.h>
+
+#include "../../../shared/util.h"
+#include "../../shared/viewtestutil.h"
+
+Q_LOGGING_CATEGORY(lcPointerTests, "qt.quick.pointer.tests")
+
+class tst_FlickableInterop : public QQmlDataTest
+{
+ Q_OBJECT
+public:
+ tst_FlickableInterop()
+ :touchDevice(QTest::createTouchDevice())
+ {}
+
+private slots:
+ void initTestCase();
+
+ void touchTapButton_data();
+ void touchTapButton();
+ void touchDragFlickableBehindButton_data();
+ void touchDragFlickableBehindButton();
+ void mouseClickButton_data();
+ void mouseClickButton();
+ void mouseDragFlickableBehindButton_data();
+ void mouseDragFlickableBehindButton();
+ void touchDragSlider();
+ void touchDragFlickableBehindSlider();
+ void mouseDragSlider();
+ void mouseDragFlickableBehindSlider();
+ void touchDragFlickableBehindItemWithHandlers_data();
+ void touchDragFlickableBehindItemWithHandlers();
+ void mouseDragFlickableBehindItemWithHandlers_data();
+ void mouseDragFlickableBehindItemWithHandlers();
+
+private:
+ void createView(QScopedPointer<QQuickView> &window, const char *fileName);
+ QTouchDevice *touchDevice;
+};
+
+void tst_FlickableInterop::createView(QScopedPointer<QQuickView> &window, const char *fileName)
+{
+ window.reset(new QQuickView);
+ window->setSource(testFileUrl(fileName));
+ QTRY_COMPARE(window->status(), QQuickView::Ready);
+ QQuickViewTestUtil::centerOnScreen(window.data());
+ QQuickViewTestUtil::moveMouseAway(window.data());
+
+ window->show();
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
+ QVERIFY(window->rootObject() != 0);
+}
+
+void tst_FlickableInterop::initTestCase()
+{
+ // This test assumes that we don't get synthesized mouse events from QGuiApplication
+ qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, false);
+
+ QQmlDataTest::initTestCase();
+}
+
+void tst_FlickableInterop::touchTapButton_data()
+{
+ QTest::addColumn<QString>("buttonName");
+ QTest::newRow("DragThreshold") << QStringLiteral("DragThreshold");
+ QTest::newRow("WithinBounds") << QStringLiteral("WithinBounds");
+ QTest::newRow("ReleaseWithinBounds") << QStringLiteral("ReleaseWithinBounds");
+}
+
+void tst_FlickableInterop::touchTapButton()
+{
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "flickableWithHandlers.qml");
+ QQuickView * window = windowPtr.data();
+
+ QFETCH(QString, buttonName);
+
+ QQuickItem *button = window->rootObject()->findChild<QQuickItem*>(buttonName);
+ QVERIFY(button);
+ QSignalSpy tappedSpy(button, SIGNAL(tapped()));
+
+ // Button changes pressed state and emits tapped on release
+ QPoint p1 = button->mapToScene(QPointF(20, 20)).toPoint();
+ QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(button->property("pressed").toBool());
+ QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(!button->property("pressed").toBool());
+ QCOMPARE(tappedSpy.count(), 1);
+
+ // We can drag <= dragThreshold and the button still acts normal, Flickable doesn't grab
+ p1 = button->mapToScene(QPointF(20, 20)).toPoint();
+ QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(button->property("pressed").toBool());
+ p1 += QPoint(dragThreshold, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QVERIFY(button->property("pressed").toBool());
+ QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(!button->property("pressed").toBool());
+ QCOMPARE(tappedSpy.count(), 2);
+}
+
+void tst_FlickableInterop::touchDragFlickableBehindButton_data()
+{
+ QTest::addColumn<QString>("buttonName");
+ QTest::newRow("DragThreshold") << QStringLiteral("DragThreshold");
+ QTest::newRow("WithinBounds") << QStringLiteral("WithinBounds");
+ QTest::newRow("ReleaseWithinBounds") << QStringLiteral("ReleaseWithinBounds");
+}
+
+void tst_FlickableInterop::touchDragFlickableBehindButton()
+{
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "flickableWithHandlers.qml");
+ QQuickView * window = windowPtr.data();
+
+ QFETCH(QString, buttonName);
+
+ QQuickItem *button = window->rootObject()->findChild<QQuickItem*>(buttonName);
+ QVERIFY(button);
+ QQuickFlickable *flickable = window->rootObject()->findChild<QQuickFlickable*>();
+ QVERIFY(flickable);
+ QSignalSpy tappedSpy(button, SIGNAL(tapped()));
+
+ tappedSpy.clear();
+ QPoint p1 = button->mapToScene(QPointF(20, 20)).toPoint();
+ QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(button->property("pressed").toBool());
+ p1 += QPoint(dragThreshold, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QVERIFY(button->property("pressed").toBool());
+ int i = 0;
+ // Start dragging; eventually when the touchpoint goes beyond dragThreshold,
+ // Button is no longer pressed because Flickable steals the grab
+ for (; i < 100 && !flickable->isMoving(); ++i) {
+ p1 += QPoint(1, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ }
+ QVERIFY(flickable->isMoving());
+ qDebug() << "flickable started moving after" << i << "moves, when we got to" << p1;
+ QCOMPARE(i, 2);
+ QVERIFY(!button->property("pressed").toBool());
+ QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QVERIFY(!button->property("pressed").toBool());
+ QCOMPARE(tappedSpy.count(), 0);
+}
+
+void tst_FlickableInterop::mouseClickButton_data()
+{
+ QTest::addColumn<QString>("buttonName");
+ QTest::newRow("DragThreshold") << QStringLiteral("DragThreshold");
+ QTest::newRow("WithinBounds") << QStringLiteral("WithinBounds");
+ QTest::newRow("ReleaseWithinBounds") << QStringLiteral("ReleaseWithinBounds");
+}
+
+void tst_FlickableInterop::mouseClickButton()
+{
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "flickableWithHandlers.qml");
+ QQuickView * window = windowPtr.data();
+
+ QFETCH(QString, buttonName);
+
+ QQuickItem *button = window->rootObject()->findChild<QQuickItem*>(buttonName);
+ QVERIFY(button);
+ QSignalSpy tappedSpy(button, SIGNAL(tapped()));
+
+ // Button changes pressed state and emits tapped on release
+ QPoint p1 = button->mapToScene(QPointF(20, 20)).toPoint();
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(button->property("pressed").toBool());
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(!button->property("pressed").toBool());
+ QCOMPARE(tappedSpy.count(), 1);
+
+ // We can drag <= dragThreshold and the button still acts normal, Flickable doesn't grab
+ p1 = button->mapToScene(QPointF(20, 20)).toPoint();
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(button->property("pressed").toBool());
+ p1 += QPoint(dragThreshold, 0);
+ QTest::mouseMove(window, p1);
+ QVERIFY(button->property("pressed").toBool());
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(!button->property("pressed").toBool());
+ QCOMPARE(tappedSpy.count(), 2);
+}
+
+void tst_FlickableInterop::mouseDragFlickableBehindButton_data()
+{
+ QTest::addColumn<QString>("buttonName");
+ QTest::newRow("DragThreshold") << QStringLiteral("DragThreshold");
+ QTest::newRow("WithinBounds") << QStringLiteral("WithinBounds");
+ QTest::newRow("ReleaseWithinBounds") << QStringLiteral("ReleaseWithinBounds");
+}
+
+void tst_FlickableInterop::mouseDragFlickableBehindButton()
+{
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "flickableWithHandlers.qml");
+ QQuickView * window = windowPtr.data();
+
+ QFETCH(QString, buttonName);
+
+ QQuickItem *button = window->rootObject()->findChild<QQuickItem*>(buttonName);
+ QVERIFY(button);
+ QQuickFlickable *flickable = window->rootObject()->findChild<QQuickFlickable*>();
+ QVERIFY(flickable);
+ QSignalSpy tappedSpy(button, SIGNAL(tapped()));
+
+ // Button is no longer pressed if touchpoint goes beyond dragThreshold,
+ // because Flickable steals the grab
+ tappedSpy.clear();
+ QPoint p1 = button->mapToScene(QPointF(20, 20)).toPoint();
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(button->property("pressed").toBool());
+ p1 += QPoint(dragThreshold, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QVERIFY(button->property("pressed").toBool());
+ int i = 0;
+ for (; i < 100 && !flickable->isMoving(); ++i) {
+ p1 += QPoint(1, 0);
+ QTest::mouseMove(window, p1);
+ }
+ qDebug() << "flickable started moving after" << i << "moves, when we got to" << p1;
+ QVERIFY(flickable->isMoving());
+ QCOMPARE(i, 2);
+ QVERIFY(!button->property("pressed").toBool());
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QVERIFY(!button->property("pressed").toBool());
+ QCOMPARE(tappedSpy.count(), 0);
+}
+
+void tst_FlickableInterop::touchDragSlider()
+{
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "flickableWithHandlers.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickItem *slider = window->rootObject()->findChild<QQuickItem*>("Slider");
+ QVERIFY(slider);
+ QQuickDragHandler *drag = slider->findChild<QQuickDragHandler*>();
+ QVERIFY(drag);
+ QQuickItem *knob = slider->findChild<QQuickItem*>("Slider Knob");
+ QVERIFY(knob);
+ QQuickFlickable *flickable = window->rootObject()->findChild<QQuickFlickable*>();
+ QVERIFY(flickable);
+ QSignalSpy tappedSpy(knob->parent(), SIGNAL(tapped()));
+ QSignalSpy translationChangedSpy(drag, SIGNAL(translationChanged()));
+
+ // Drag the slider in the allowed (vertical) direction
+ tappedSpy.clear();
+ QPoint p1 = knob->mapToScene(knob->clipRect().center()).toPoint();
+ QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(slider->property("pressed").toBool());
+ p1 += QPoint(0, dragThreshold);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QVERIFY(slider->property("pressed").toBool());
+ QCOMPARE(slider->property("value").toInt(), 49);
+ p1 += QPoint(0, 1);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ p1 += QPoint(0, 10);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QVERIFY(slider->property("value").toInt() < 49);
+ QVERIFY(!flickable->isMoving());
+ QVERIFY(!slider->property("pressed").toBool());
+
+ // Now that the DragHandler is active, the Flickable will not steal the grab
+ // even if we move a large distance horizontally
+ p1 += QPoint(dragThreshold * 2, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QVERIFY(!flickable->isMoving());
+
+ // Release, and do not expect the tapped signal
+ QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QCOMPARE(tappedSpy.count(), 0);
+ QCOMPARE(translationChangedSpy.count(), 1);
+}
+
+void tst_FlickableInterop::mouseDragSlider()
+{
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "flickableWithHandlers.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickItem *slider = window->rootObject()->findChild<QQuickItem*>("Slider");
+ QVERIFY(slider);
+ QQuickDragHandler *drag = slider->findChild<QQuickDragHandler*>();
+ QVERIFY(drag);
+ QQuickItem *knob = slider->findChild<QQuickItem*>("Slider Knob");
+ QVERIFY(knob);
+ QQuickFlickable *flickable = window->rootObject()->findChild<QQuickFlickable*>();
+ QVERIFY(flickable);
+ QSignalSpy tappedSpy(knob->parent(), SIGNAL(tapped()));
+ QSignalSpy translationChangedSpy(drag, SIGNAL(translationChanged()));
+
+ // Drag the slider in the allowed (vertical) direction
+ tappedSpy.clear();
+ QPoint p1 = knob->mapToScene(knob->clipRect().center()).toPoint();
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(slider->property("pressed").toBool());
+ p1 += QPoint(0, dragThreshold);
+ QTest::mouseMove(window, p1);
+ QVERIFY(slider->property("pressed").toBool());
+ QCOMPARE(slider->property("value").toInt(), 49);
+ p1 += QPoint(0, 1);
+ QTest::mouseMove(window, p1);
+ p1 += QPoint(0, 10);
+ QTest::mouseMove(window, p1);
+ QVERIFY(slider->property("value").toInt() < 49);
+ QVERIFY(!flickable->isMoving());
+ QVERIFY(!slider->property("pressed").toBool());
+
+ // Now that the DragHandler is active, the Flickable will not steal the grab
+ // even if we move a large distance horizontally
+ p1 += QPoint(dragThreshold * 2, 0);
+ QTest::mouseMove(window, p1);
+ QVERIFY(!flickable->isMoving());
+
+ // Release, and do not expect the tapped signal
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QCOMPARE(tappedSpy.count(), 0);
+ QCOMPARE(translationChangedSpy.count(), 1);
+}
+
+void tst_FlickableInterop::touchDragFlickableBehindSlider()
+{
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "flickableWithHandlers.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickItem *slider = window->rootObject()->findChild<QQuickItem*>("Slider");
+ QVERIFY(slider);
+ QQuickDragHandler *drag = slider->findChild<QQuickDragHandler*>();
+ QVERIFY(drag);
+ QQuickItem *knob = slider->findChild<QQuickItem*>("Slider Knob");
+ QVERIFY(knob);
+ QQuickFlickable *flickable = window->rootObject()->findChild<QQuickFlickable*>();
+ QVERIFY(flickable);
+ QSignalSpy tappedSpy(knob->parent(), SIGNAL(tapped()));
+ QSignalSpy translationChangedSpy(drag, SIGNAL(translationChanged()));
+
+ // Button is no longer pressed if touchpoint goes beyond dragThreshold,
+ // because Flickable steals the grab
+ tappedSpy.clear();
+ QPoint p1 = knob->mapToScene(knob->clipRect().center()).toPoint();
+ QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(slider->property("pressed").toBool());
+ p1 += QPoint(dragThreshold, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QVERIFY(slider->property("pressed").toBool());
+ int i = 0;
+ for (; i < 100 && !flickable->isMoving(); ++i) {
+ p1 += QPoint(1, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ }
+ qDebug() << "flickable started moving after" << i << "moves, when we got to" << p1;
+ QVERIFY(flickable->isMoving());
+ QCOMPARE(i, 2);
+ QVERIFY(!slider->property("pressed").toBool());
+ QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QVERIFY(!slider->property("pressed").toBool());
+ QCOMPARE(tappedSpy.count(), 0);
+ QCOMPARE(translationChangedSpy.count(), 0);
+}
+
+void tst_FlickableInterop::mouseDragFlickableBehindSlider()
+{
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "flickableWithHandlers.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickItem *slider = window->rootObject()->findChild<QQuickItem*>("Slider");
+ QVERIFY(slider);
+ QQuickDragHandler *drag = slider->findChild<QQuickDragHandler*>();
+ QVERIFY(drag);
+ QQuickItem *knob = slider->findChild<QQuickItem*>("Slider Knob");
+ QVERIFY(knob);
+ QQuickFlickable *flickable = window->rootObject()->findChild<QQuickFlickable*>();
+ QVERIFY(flickable);
+ QSignalSpy tappedSpy(knob->parent(), SIGNAL(tapped()));
+ QSignalSpy translationChangedSpy(drag, SIGNAL(translationChanged()));
+
+ // Button is no longer pressed if touchpoint goes beyond dragThreshold,
+ // because Flickable steals the grab
+ tappedSpy.clear();
+ QPoint p1 = knob->mapToScene(knob->clipRect().center()).toPoint();
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(slider->property("pressed").toBool());
+ p1 += QPoint(dragThreshold, 0);
+ QTest::mouseMove(window, p1);
+ QQuickTouchUtils::flush(window);
+ QVERIFY(slider->property("pressed").toBool());
+ int i = 0;
+ for (; i < 100 && !flickable->isMoving(); ++i) {
+ p1 += QPoint(1, 0);
+ QTest::mouseMove(window, p1);
+ }
+ qDebug() << "flickable started moving after" << i << "moves, when we got to" << p1;
+ QVERIFY(flickable->isMoving());
+ QCOMPARE(i, 2);
+ QVERIFY(!slider->property("pressed").toBool());
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QCOMPARE(tappedSpy.count(), 0);
+ QCOMPARE(translationChangedSpy.count(), 0);
+}
+
+void tst_FlickableInterop::touchDragFlickableBehindItemWithHandlers_data()
+{
+ QTest::addColumn<QByteArray>("nameOfRectangleToDrag");
+ QTest::addColumn<bool>("expectedFlickableMoving");
+ QTest::newRow("drag") << QByteArray("drag") << false;
+ QTest::newRow("tap") << QByteArray("tap") << true;
+ QTest::newRow("dragAndTap") << QByteArray("dragAndTap") << false;
+ QTest::newRow("tapAndDrag") << QByteArray("tapAndDrag") << false;
+}
+
+void tst_FlickableInterop::touchDragFlickableBehindItemWithHandlers()
+{
+ QFETCH(bool, expectedFlickableMoving);
+ QFETCH(QByteArray, nameOfRectangleToDrag);
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "flickableWithHandlers.qml");
+ QQuickView * window = windowPtr.data();
+ QQuickItem *rect = window->rootObject()->findChild<QQuickItem*>(nameOfRectangleToDrag);
+ QVERIFY(rect);
+ QQuickFlickable *flickable = window->rootObject()->findChild<QQuickFlickable*>();
+ QVERIFY(flickable);
+ QPoint p1 = rect->mapToScene(rect->clipRect().center()).toPoint();
+ QPoint originP1 = p1;
+
+ QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ for (int i = 0; i < dragThreshold * 3; ++i) {
+ p1 = originP1;
+ p1.rx() += i;
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ }
+ QCOMPARE(flickable->isMoving(), expectedFlickableMoving);
+ if (!expectedFlickableMoving) {
+ QVERIFY(rect->mapToScene(rect->clipRect().center()).toPoint().x() > originP1.x());
+ }
+ QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QQuickTouchUtils::flush(window);
+}
+
+void tst_FlickableInterop::mouseDragFlickableBehindItemWithHandlers_data()
+{
+ touchDragFlickableBehindItemWithHandlers_data();
+}
+
+void tst_FlickableInterop::mouseDragFlickableBehindItemWithHandlers()
+{
+ QFETCH(bool, expectedFlickableMoving);
+ QFETCH(QByteArray, nameOfRectangleToDrag);
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "flickableWithHandlers.qml");
+ QQuickView * window = windowPtr.data();
+ QQuickItem *rect = window->rootObject()->findChild<QQuickItem*>(nameOfRectangleToDrag);
+ QVERIFY(rect);
+ QQuickFlickable *flickable = window->rootObject()->findChild<QQuickFlickable*>();
+ QVERIFY(flickable);
+ QPoint p1 = rect->mapToScene(rect->clipRect().center()).toPoint();
+ QPoint originP1 = p1;
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ for (int i = 0; i < 3; ++i) {
+ p1 += QPoint(dragThreshold, 0);
+ QTest::mouseMove(window, p1);
+ QQuickTouchUtils::flush(window);
+ }
+ QCOMPARE(flickable->isMoving(), expectedFlickableMoving);
+ if (!expectedFlickableMoving) {
+ QCOMPARE(originP1 + QPoint(3*dragThreshold, 0), p1);
+ }
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1);
+ // wait until flickable stops
+ QTRY_COMPARE(flickable->isMoving(), false);
+
+ // After the mouse button has been released, move the mouse and ensure that nothing is moving
+ // because of that (this tests if all grabs are released when the mouse button is released).
+ p1 = rect->mapToScene(rect->clipRect().center()).toPoint();
+ originP1 = p1;
+ for (int i = 0; i < 3; ++i) {
+ p1 += QPoint(dragThreshold, 0);
+ QTest::mouseMove(window, p1);
+ QQuickTouchUtils::flush(window);
+ }
+ QCOMPARE(flickable->isMoving(), false);
+ QCOMPARE(originP1, rect->mapToScene(rect->clipRect().center()).toPoint());
+}
+
+QTEST_MAIN(tst_FlickableInterop)
+
+#include "tst_flickableinterop.moc"
+
diff --git a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/data/pinchDragMPTA.qml b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/data/pinchDragMPTA.qml
new file mode 100644
index 0000000000..084cc25414
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/data/pinchDragMPTA.qml
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+
+Rectangle {
+ width: 1024; height: 600
+ color: "beige"
+ objectName: "beige root"
+
+ Rectangle {
+ id: container
+ objectName: "container rect"
+ width: 600
+ height: 500
+ color: "black"
+ border.color: pinch3.active ? "red" : "black"
+ border.width: 3
+ antialiasing: true
+
+ MultiPointTouchArea {
+ id: mpta
+ anchors.fill: parent
+ //onGestureStarted: gesture.grab() // in case this is embedded in something that might steal
+ touchPoints: [
+ TouchPoint { property color color: "red" },
+ TouchPoint { property color color: "orange" },
+ TouchPoint { property color color: "lightsteelblue" },
+ TouchPoint { property color color: "green" }
+ ] }
+
+ Repeater {
+ model: 4
+
+ Item {
+ id: crosshairs
+ property TouchPoint touchPoint
+ x: touchPoint.x - width / 2
+ y: touchPoint.y - height / 2
+ width: 300; height: 300
+ visible: touchPoint.pressed
+ rotation: touchPoint.rotation
+
+ Rectangle {
+ color: touchPoint.color
+ anchors.centerIn: parent
+ width: 2; height: parent.height
+ antialiasing: true
+ }
+ Rectangle {
+ color: touchPoint.color
+ anchors.centerIn: parent
+ width: parent.width; height: 2
+ antialiasing: true
+ }
+ Component.onCompleted: touchPoint = mpta.touchPoints[index]
+ }
+ }
+
+ Item {
+ objectName: "pinch and drag"
+ anchors.fill: parent
+ // In order for PinchHandler to get a chance to take a passive grab, it has to get the touchpoints first.
+ // In order to get the touchpoints first, it has to be on top of the Z order: i.e. come last in paintOrderChildItems().
+ // This is the opposite situation as with filtersChildMouseEvents: e.g. PinchArea would have wanted to be the parent,
+ // if it even knew that trick (which it doesn't).
+ DragHandler {
+ id: dragHandler
+ objectName: "DragHandler"
+ target: container
+ }
+ PinchHandler {
+ id: pinch3
+ objectName: "3-finger pinch"
+ target: container
+ minimumPointCount: 3
+ minimumScale: 0.1
+ maximumScale: 10
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/multipointtoucharea_interop.pro b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/multipointtoucharea_interop.pro
new file mode 100644
index 0000000000..10d0ff8018
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/multipointtoucharea_interop.pro
@@ -0,0 +1,15 @@
+CONFIG += testcase
+
+TARGET = tst_multipointtoucharea_interop
+QT += core-private gui-private qml-private quick-private testlib
+
+macos:CONFIG -= app_bundle
+
+SOURCES += tst_multipointtoucharea_interop.cpp
+
+include (../../../shared/util.pri)
+include (../../shared/util.pri)
+
+TESTDATA = data/*
+
+OTHER_FILES += data/pinchDragMPTA.qml
diff --git a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp
new file mode 100644
index 0000000000..a2934eee32
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp
@@ -0,0 +1,287 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+
+#include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlproperty.h>
+#include <QtQuick/private/qquickdraghandler_p.h>
+#include <QtQuick/private/qquickmultipointtoucharea_p.h>
+#include <QtQuick/private/qquickpinchhandler_p.h>
+#include <QtQuick/qquickitem.h>
+#include <QtQuick/qquickview.h>
+
+#include "../../../shared/util.h"
+#include "../../shared/viewtestutil.h"
+
+Q_LOGGING_CATEGORY(lcPointerTests, "qt.quick.pointer.tests")
+
+class tst_MptaInterop : public QQmlDataTest
+{
+ Q_OBJECT
+public:
+ tst_MptaInterop()
+ : touchDevice(QTest::createTouchDevice())
+ , touchPointerDevice(QQuickPointerDevice::touchDevice(touchDevice))
+ {}
+
+private slots:
+ void initTestCase();
+
+ void touchDrag();
+ void touchesThenPinch();
+
+private:
+ void createView(QScopedPointer<QQuickView> &window, const char *fileName);
+ QTouchDevice *touchDevice;
+ QQuickPointerDevice *touchPointerDevice;
+};
+
+void tst_MptaInterop::createView(QScopedPointer<QQuickView> &window, const char *fileName)
+{
+ window.reset(new QQuickView);
+ window->setSource(testFileUrl(fileName));
+ QTRY_COMPARE(window->status(), QQuickView::Ready);
+ QQuickViewTestUtil::centerOnScreen(window.data());
+ QQuickViewTestUtil::moveMouseAway(window.data());
+
+ window->show();
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
+ QVERIFY(window->rootObject() != 0);
+}
+
+void tst_MptaInterop::initTestCase()
+{
+ // This test assumes that we don't get synthesized mouse events from QGuiApplication
+ qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, false);
+
+ QQmlDataTest::initTestCase();
+}
+
+void tst_MptaInterop::touchDrag()
+{
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "pinchDragMPTA.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickMultiPointTouchArea *mpta = window->rootObject()->findChild<QQuickMultiPointTouchArea*>();
+ QVERIFY(mpta);
+ QQuickPinchHandler *pinch = window->rootObject()->findChild<QQuickPinchHandler*>();
+ QVERIFY(pinch);
+ QQuickDragHandler *drag = window->rootObject()->findChild<QQuickDragHandler*>();
+ QVERIFY(drag);
+ QQmlListReference tp(mpta, "touchPoints");
+ QVERIFY(tp.at(3)); // the QML declares four touchpoints
+ QSignalSpy mptaPressedSpy(mpta, SIGNAL(pressed(QList<QObject*>)));
+ QSignalSpy mptaReleasedSpy(mpta, SIGNAL(released(QList<QObject*>)));
+ QTest::QTouchEventSequence touch = QTest::touchEvent(window, touchDevice);
+
+ // Press one touchpoint:
+ // DragHandler gets a passive grab
+ // PinchHandler declines, because it wants 3 touchpoints
+ // MPTA doesn't get a chance, because DragHandler accepted the single EventPoint
+ QPoint p1 = mpta->mapToScene(QPointF(20, 20)).toPoint();
+ touch.press(1, p1).commit();
+ QQuickTouchUtils::flush(window);
+ auto pointerEvent = QQuickWindowPrivate::get(window)->pointerEventInstance(touchPointerDevice);
+ QCOMPARE(tp.at(0)->property("pressed").toBool(), false);
+ QTRY_VERIFY(pointerEvent->point(0)->passiveGrabbers().contains(drag));
+
+ // Start moving
+ // DragHandler keeps monitoring, due to its passive grab,
+ // and eventually steals the exclusive grab from MPTA
+ int dragStoleGrab = 0;
+ for (int i = 0; i < 4; ++i) {
+ p1 += QPoint(dragThreshold / 2, 0);
+ touch.move(1, p1).commit();
+ QQuickTouchUtils::flush(window);
+ if (!dragStoleGrab && pointerEvent->point(0)->exclusiveGrabber() == drag)
+ dragStoleGrab = i;
+ }
+ if (dragStoleGrab)
+ qCDebug(lcPointerTests, "DragHandler stole the grab after %d events", dragStoleGrab);
+ QVERIFY(dragStoleGrab > 1);
+
+ touch.release(1, p1).commit();
+ QQuickTouchUtils::flush(window);
+}
+
+// TODO touchesThenPinch_data with press/release sequences somehow: vectors of touchpoint IDs? or a string representation?
+void tst_MptaInterop::touchesThenPinch()
+{
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "pinchDragMPTA.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickMultiPointTouchArea *mpta = window->rootObject()->findChild<QQuickMultiPointTouchArea*>();
+ QVERIFY(mpta);
+ QQuickPinchHandler *pinch = window->rootObject()->findChild<QQuickPinchHandler*>();
+ QVERIFY(pinch);
+ QQuickDragHandler *drag = window->rootObject()->findChild<QQuickDragHandler*>();
+ QVERIFY(drag);
+ QQmlListReference tp(mpta, "touchPoints");
+ QVERIFY(tp.at(3)); // the QML declares four touchpoints
+ QSignalSpy mptaPressedSpy(mpta, SIGNAL(pressed(QList<QObject*>)));
+ QSignalSpy mptaReleasedSpy(mpta, SIGNAL(released(QList<QObject*>)));
+ QSignalSpy mptaCanceledSpy(mpta, SIGNAL(canceled(QList<QObject*>)));
+ QTest::QTouchEventSequence touch = QTest::touchEvent(window, touchDevice);
+ auto pointerEvent = QQuickWindowPrivate::get(window)->pointerEventInstance(touchPointerDevice);
+
+ // Press one touchpoint:
+ // DragHandler gets a passive grab
+ // PinchHandler declines, because it wants 3 touchpoints
+ // MPTA doesn't get a chance, because DragHandler accepted the single EventPoint
+ QPoint p1 = mpta->mapToScene(QPointF(20, 20)).toPoint();
+ touch.press(1, p1).commit();
+ QQuickTouchUtils::flush(window);
+ QTRY_COMPARE(pointerEvent->point(0)->exclusiveGrabber(), nullptr);
+ QTRY_COMPARE(pointerEvent->point(0)->passiveGrabbers().first(), drag);
+
+ // Press a second touchpoint: MPTA grabs it
+ QPoint p2 = mpta->mapToScene(QPointF(200, 30)).toPoint();
+ touch.stationary(1).press(2, p2).commit();
+ QQuickTouchUtils::flush(window);
+ QVERIFY(tp.at(0)->property("pressed").toBool());
+ QTRY_VERIFY(tp.at(1)->property("pressed").toBool());
+ QCOMPARE(mptaPressedSpy.count(), 1);
+
+ // ATM it's required that when PinchHandler sees the third touchpoint,
+ // the pre-existing points must have moved far enough to exceed the drag threshold.
+ // If MPTA is allowed to grab that third point, then PinchHandler won't steal.
+ // TODO should we change that? make sure that if PH has a passive grab, it always gets updated even though MPTA has the grab?
+ for (int i = 0; i < 2; ++i) {
+ p1 += QPoint(dragThreshold, dragThreshold);
+ p2 += QPoint(dragThreshold, dragThreshold);
+ touch.move(1, p1).move(2, p2).commit();
+ }
+
+ // Press a third touchpoint: PinchHandler grabs, MPTA loses its grabs
+ QPoint p3 = mpta->mapToScene(QPointF(110, 200)).toPoint();
+ touch.stationary(1).stationary(2).press(3, p3).commit();
+ QQuickTouchUtils::flush(window);
+ QCOMPARE(tp.at(0)->property("pressed").toBool(), false);
+ QCOMPARE(tp.at(1)->property("pressed").toBool(), false);
+ QCOMPARE(tp.at(2)->property("pressed").toBool(), false);
+ QCOMPARE(mptaPressedSpy.count(), 1);
+ QCOMPARE(mptaCanceledSpy.count(), 1);
+ QTRY_COMPARE(pointerEvent->point(0)->exclusiveGrabber(), pinch);
+ QTRY_COMPARE(pointerEvent->point(1)->exclusiveGrabber(), pinch);
+ QTRY_COMPARE(pointerEvent->point(2)->exclusiveGrabber(), pinch);
+ QVERIFY(pinch->active());
+
+ // Start moving: PinchHandler steals the exclusive grab from MPTA as soon as dragThreshold is exceeded
+ int pinchStoleGrab = 0;
+ for (int i = 0; i < 8; ++i) {
+ p1 += QPoint(dragThreshold / 2, dragThreshold / 2);
+ p2 += QPoint(dragThreshold / 2, dragThreshold / 2);
+ p3 += QPoint(-dragThreshold / 2, dragThreshold / 2);
+ touch.move(1, p1).move(2, p2).move(3, p3).commit();
+ QQuickTouchUtils::flush(window);
+ QTRY_COMPARE(tp.at(0)->property("pressed").toBool(), false);
+ QCOMPARE(tp.at(1)->property("pressed").toBool(), false);
+ QCOMPARE(tp.at(2)->property("pressed").toBool(), false);
+ if (!pinchStoleGrab && pointerEvent->point(0)->exclusiveGrabber() == pinch)
+ pinchStoleGrab = i;
+ }
+ qCDebug(lcPointerTests) << "pinch started after" << pinchStoleGrab << "moves; ended with scale" << pinch->scale() << "rot" << pinch->rotation();
+ QTRY_VERIFY(pinch->rotation() > 8);
+ QVERIFY(pinch->scale() > 1);
+
+ // Press one more point (pinkie finger)
+ QPoint p4 = mpta->mapToScene(QPointF(300, 200)).toPoint();
+ touch.move(1, p1).move(2, p2).move(3, p3).press(4, p4).commit();
+ // PinchHandler gives up its grabs (only on non-stationary points at this time: see QQuickPointerHandler::handlePointerEvent())
+ // because it has minimum touch points 3, maximum touch points 3, and now there are 4 points.
+ // MPTA grabs all points which are not already grabbed
+ QTRY_COMPARE(pointerEvent->point(0)->exclusiveGrabber(), mpta);
+ QCOMPARE(pointerEvent->point(1)->exclusiveGrabber(), mpta);
+ QCOMPARE(pointerEvent->point(2)->exclusiveGrabber(), mpta);
+ QCOMPARE(pointerEvent->point(3)->exclusiveGrabber(), mpta);
+ // Move some more... MPTA keeps reacting
+ for (int i = 0; i < 8; ++i) {
+ p1 += QPoint(4, 4);
+ p2 += QPoint(4, 4);
+ p3 += QPoint(-4, 4);
+ p4 += QPoint(-4, -4);
+ touch.move(1, p1).move(2, p2).move(3, p3).move(4, p4).commit();
+ QCOMPARE(pointerEvent->point(0)->exclusiveGrabber(), mpta);
+ QCOMPARE(pointerEvent->point(1)->exclusiveGrabber(), mpta);
+ QCOMPARE(pointerEvent->point(2)->exclusiveGrabber(), mpta);
+ QCOMPARE(pointerEvent->point(3)->exclusiveGrabber(), mpta);
+ QCOMPARE(tp.at(0)->property("pressed").toBool(), true);
+ QCOMPARE(tp.at(1)->property("pressed").toBool(), true);
+ QCOMPARE(tp.at(2)->property("pressed").toBool(), true);
+ QCOMPARE(tp.at(3)->property("pressed").toBool(), true);
+ }
+
+ // Release the pinkie: PinchHandler acquires passive grabs on the 3 remaining points
+ touch.move(1, p1).move(2, p2).move(3, p3).release(4, p4).commit();
+ // Move some more: PinchHander grabs again, and reacts
+ for (int i = 0; i < 8; ++i) {
+ p1 -= QPoint(4, 4);
+ p2 += QPoint(4, 4);
+ p3 -= QPoint(-4, 4);
+ touch.move(1, p1).move(2, p2).move(3, p3).commit();
+ QTRY_COMPARE(pointerEvent->point(0)->exclusiveGrabber(), pinch);
+ QCOMPARE(pointerEvent->point(1)->exclusiveGrabber(), pinch);
+ QCOMPARE(pointerEvent->point(2)->exclusiveGrabber(), pinch);
+ }
+
+ // Release the first finger
+ touch.stationary(2).stationary(3).release(1, p1).commit();
+ // Move some more: PinchHander isn't interested in a mere 2 points.
+ // MPTA could maybe react; but QQuickWindowPrivate::deliverTouchEvent() calls
+ // deliverPressOrReleaseEvent() in a way which "starts over" with event delivery
+ // only for handlers, not for Items; therefore MPTA is not visited at this time.
+ for (int i = 0; i < 8; ++i) {
+ p2 -= QPoint(4, 4);
+ p3 += QPoint(4, 4);
+ touch.move(2, p2).move(3, p3).commit();
+ QQuickTouchUtils::flush(window);
+ }
+
+ // Release another finger
+ touch.stationary(2).release(3, p3).commit();
+ // Move some more: DragHandler reacts.
+ // It had a passive grab this whole time; now it activates and gets an exclusive grab.
+ for (int i = 0; i < 8; ++i) {
+ p2 += QPoint(8, -8);
+ touch.move(2, p2).commit();
+ QTRY_COMPARE(pointerEvent->point(0)->exclusiveGrabber(), drag);
+ }
+
+ touch.release(2, p2).commit();
+ QQuickTouchUtils::flush(window);
+ QTRY_COMPARE(mptaReleasedSpy.count(), 1);
+}
+
+QTEST_MAIN(tst_MptaInterop)
+
+#include "tst_multipointtoucharea_interop.moc"
diff --git a/tests/auto/quick/pointerhandlers/pointerhandlers.pro b/tests/auto/quick/pointerhandlers/pointerhandlers.pro
new file mode 100644
index 0000000000..2492924944
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/pointerhandlers.pro
@@ -0,0 +1,11 @@
+TEMPLATE = subdirs
+
+qtConfig(private_tests) {
+ SUBDIRS += \
+ flickableinterop \
+ multipointtoucharea_interop \
+ qquickpointerhandler \
+ qquickdraghandler \
+ qquicktaphandler \
+}
+
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/DragAnywhereSlider.qml b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/DragAnywhereSlider.qml
new file mode 100644
index 0000000000..fe5f74743d
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/DragAnywhereSlider.qml
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+
+Item {
+ id: root
+ objectName: label
+ property int value: 50
+ property int maximumValue: 99
+ property alias label: label.text
+ property alias tapEnabled: tap.enabled
+ property alias pressed: tap.pressed
+ signal tapped
+ width: 140
+ height: 400
+
+ DragHandler {
+ id: dragHandler
+ objectName: label.text + " DragHandler"
+ target: knob
+ xAxis.enabled: false
+ yAxis.minimum: slot.y
+ yAxis.maximum: slot.height + slot.y - knob.height
+ }
+
+ Rectangle {
+ id: slot
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ anchors.margins: 10
+ anchors.topMargin: 30
+ anchors.bottomMargin: 30
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: 10
+ color: "black"
+ radius: width / 2
+ smooth: true
+ }
+
+ Rectangle {
+ id: glow
+ anchors.fill: knob
+ anchors.margins: -5
+ anchors.leftMargin: -2
+ anchors.horizontalCenterOffset: 1
+ radius: 5
+ color: "#4400FFFF"
+ opacity: tap.pressed || tapFlash.running ? 1 : 0
+ FlashAnimation on visible {
+ id: tapFlash
+ }
+ }
+ Rectangle {
+ id: knob
+ objectName: "Slider Knob"
+ width: parent.width - 2
+ height: 30
+ radius: 5
+ color: "darkgray"
+ border.color: "black"
+ property bool programmatic: false
+ property real multiplier: root.maximumValue / (dragHandler.yAxis.maximum - dragHandler.yAxis.minimum)
+ onYChanged: if (!programmatic) root.value = root.maximumValue - (knob.y - dragHandler.yAxis.minimum) * multiplier
+ transformOrigin: Item.Center
+ function setValue(value) { knob.y = dragHandler.yAxis.maximum - value / knob.multiplier }
+ TapHandler {
+ id: tap
+ objectName: label.text + " TapHandler"
+ gesturePolicy: TapHandler.DragThreshold
+ onTapped: {
+ tapFlash.start()
+ root.tapped
+ }
+ }
+ }
+
+ Text {
+ font.pointSize: 16
+ color: "red"
+ anchors.bottom: parent.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ text: root.value
+ }
+
+ Text {
+ id: label
+ font.pointSize: 12
+ color: "red"
+ anchors.top: parent.top
+ anchors.topMargin: 5
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+
+ Component.onCompleted: {
+ knob.programmatic = true
+ knob.setValue(root.value)
+ knob.programmatic = false
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/FlashAnimation.qml b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/FlashAnimation.qml
new file mode 100644
index 0000000000..158a02b7a6
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/FlashAnimation.qml
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+SequentialAnimation {
+ id: tapFlash
+ running: false
+ PropertyAction { value: false }
+ PauseAnimation { duration: 100 }
+ PropertyAction { value: true }
+ PauseAnimation { duration: 100 }
+ PropertyAction { value: false }
+ PauseAnimation { duration: 100 }
+ PropertyAction { value: true }
+ PauseAnimation { duration: 100 }
+ PropertyAction { value: false }
+ PauseAnimation { duration: 100 }
+ PropertyAction { value: true }
+}
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/Slider.qml b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/Slider.qml
new file mode 100644
index 0000000000..a41a8285b6
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/Slider.qml
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+
+Item {
+ id: root
+ objectName: label
+ property int value: 50
+ property int maximumValue: 99
+ property alias label: label.text
+ property alias tapEnabled: tap.enabled
+ property alias pressed: tap.pressed
+ signal tapped
+ width: 140
+ height: 400
+
+ Rectangle {
+ id: slot
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ anchors.margins: 10
+ anchors.topMargin: 30
+ anchors.bottomMargin: 30
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: 10
+ color: "black"
+ radius: width / 2
+ smooth: true
+ }
+
+ Rectangle {
+ id: glow
+ anchors.fill: knob
+ anchors.margins: -5
+ anchors.leftMargin: -2
+ anchors.horizontalCenterOffset: 1
+ radius: 5
+ color: "#4400FFFF"
+ opacity: tap.pressed || tapFlash.running ? 1 : 0
+ FlashAnimation on visible {
+ id: tapFlash
+ }
+ }
+ Rectangle {
+ id: knob
+ objectName: root.label + " Knob"
+ width: parent.width - 2
+ height: 30
+ radius: 5
+ color: "darkgray"
+ border.color: "black"
+ property bool programmatic: false
+ property real multiplier: root.maximumValue / (dragHandler.yAxis.maximum - dragHandler.yAxis.minimum)
+ onYChanged: if (!programmatic) root.value = root.maximumValue - (knob.y - dragHandler.yAxis.minimum) * multiplier
+ transformOrigin: Item.Center
+ function setValue(value) { knob.y = dragHandler.yAxis.maximum - value / knob.multiplier }
+ function flash() { tapFlash.start() }
+ DragHandler {
+ id: dragHandler
+ objectName: label.text + " DragHandler"
+ xAxis.enabled: false
+ yAxis.minimum: slot.y
+ yAxis.maximum: slot.height + slot.y - knob.height
+ }
+ TapHandler {
+ id: tap
+ objectName: label.text + " TapHandler"
+ gesturePolicy: TapHandler.DragThreshold
+ onTapped: {
+ tapFlash.start()
+ root.tapped
+ }
+ }
+ }
+
+ Text {
+ font.pointSize: 16
+ color: "red"
+ anchors.bottom: parent.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ text: root.value
+ }
+
+ Text {
+ id: label
+ font.pointSize: 12
+ color: "red"
+ anchors.top: parent.top
+ anchors.topMargin: 5
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+
+ Component.onCompleted: {
+ knob.programmatic = true
+ knob.setValue(root.value)
+ knob.programmatic = false
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/draggables.qml b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/draggables.qml
new file mode 100644
index 0000000000..5b701b4033
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/draggables.qml
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+
+Item {
+ id: root
+ objectName: "Draggables"
+ width: 640
+ height: 480
+
+ Repeater {
+ model: 2
+
+ Rectangle {
+ id: ball
+ objectName: "Ball " + index
+ color: dragHandler.active ? "blue" : "lightsteelblue"
+ width: 80; height: 80; x: 200 + index * 200; y: 200; radius: width / 2
+ onParentChanged: console.log(this + " parent " + parent)
+
+ DragHandler {
+ id: dragHandler
+ objectName: "DragHandler " + index
+ }
+
+ Text {
+ color: "white"
+ anchors.centerIn: parent
+ text: dragHandler.point.position.x.toFixed(1) + "," + dragHandler.point.position.y.toFixed(1)
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/multipleSliders.qml b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/multipleSliders.qml
new file mode 100644
index 0000000000..ba6e2d00a8
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/multipleSliders.qml
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+
+Rectangle {
+ id: root
+ width: 900
+ height: 850
+ objectName: "root"
+ color: "#222222"
+
+ Grid {
+ objectName: "grid"
+ anchors.fill: parent
+ spacing: 10
+ columns: 6
+ Repeater {
+ id: top
+ objectName: "top"
+ model: 6
+
+ delegate: Slider {
+ objectName: label
+ label: "Drag Knob " + index
+ width: 140
+ }
+ }
+ Repeater {
+ id: bottom
+ objectName: "bottom"
+ model: 6
+
+ delegate: DragAnywhereSlider {
+ objectName: label
+ label: "Drag Anywhere " + index
+ width: 140
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/reparenting.qml b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/reparenting.qml
new file mode 100644
index 0000000000..3545badd86
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/reparenting.qml
@@ -0,0 +1,60 @@
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+
+Grid {
+ id: root
+ objectName: "root"
+ property bool reparentOnDrag: true
+ width: 200; height: 200
+ columns: 3
+ spacing: 10
+ Repeater {
+ model: 9
+ anchors.fill: parent
+ Item {
+ id: gridPlaceholder
+ objectName: "gridPlaceholder" + index
+ width: 60
+ height: 60
+ Rectangle {
+ id: icon
+ border.color: "black"
+ color: "beige"
+ radius: 3
+ width: 60
+ height: 60
+ onParentChanged :console.log("parent " + parent)
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ verticalCenter: parent.verticalCenter
+ }
+ DragHandler {
+ id: dragArea
+ }
+ Text {
+ anchors.centerIn: parent
+ text: index + "@" + Math.round(icon.x) + "," + Math.round(icon.y)
+ font.pointSize: 8
+ }
+ states: [
+ State {
+ when: dragArea.dragging
+ AnchorChanges {
+ target: icon
+ anchors.horizontalCenter: undefined
+ anchors.verticalCenter: undefined
+ }
+ ParentChange {
+ target: root.reparentOnDrag ? icon : null
+ parent: root
+ }
+ PropertyChanges {
+ target: icon
+ color: "yellow"
+ }
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/simpleTapAndDragHandlers.qml b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/simpleTapAndDragHandlers.qml
new file mode 100644
index 0000000000..adb8332213
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/simpleTapAndDragHandlers.qml
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+
+Rectangle {
+ id: root
+ width: 900
+ height: 850
+ objectName: "root"
+ color: "#222222"
+
+ Row {
+ objectName: "row"
+ anchors.fill: parent
+ spacing: 10
+ Rectangle {
+ width: 50
+ height: 50
+ color: "aqua"
+ objectName: "dragAndTap"
+ DragHandler {
+ objectName: "drag"
+ }
+ TapHandler {
+ objectName: "tap"
+ gesturePolicy: TapHandler.DragThreshold
+ }
+ }
+ Rectangle {
+ width: 50
+ height: 50
+ color: "aqua"
+ objectName: "tapAndDrag"
+ TapHandler {
+ objectName: "tap"
+ gesturePolicy: TapHandler.DragThreshold
+ }
+ DragHandler {
+ objectName: "drag"
+ }
+ }
+
+ Rectangle {
+ color: "aqua"
+ width: 50
+ height: 50
+ objectName: "dragAndTapNotSiblings"
+ DragHandler {
+ objectName: "drag"
+ }
+ Rectangle {
+ color: "blue"
+ width: 30
+ height: 30
+ anchors.centerIn: parent
+ TapHandler {
+ objectName: "tap"
+ gesturePolicy: TapHandler.DragThreshold
+ }
+ }
+ }
+ Rectangle {
+ color: "aqua"
+ width: 50
+ height: 50
+ objectName: "tapAndDragNotSiblings"
+ TapHandler {
+ objectName: "tap"
+ gesturePolicy: TapHandler.DragThreshold
+ }
+ Rectangle {
+ color: "blue"
+ x: 10
+ y: 10
+ width: 30
+ height: 30
+ DragHandler {
+ objectName: "drag"
+ }
+ }
+ }
+
+
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/qquickdraghandler.pro b/tests/auto/quick/pointerhandlers/qquickdraghandler/qquickdraghandler.pro
new file mode 100644
index 0000000000..42c4e46c4f
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/qquickdraghandler.pro
@@ -0,0 +1,21 @@
+CONFIG += testcase
+
+TARGET = tst_qquickdraghandler
+QT += core-private gui-private qml-private quick-private testlib
+
+macos:CONFIG -= app_bundle
+
+SOURCES += tst_qquickdraghandler.cpp
+
+include (../../../shared/util.pri)
+include (../../shared/util.pri)
+
+TESTDATA = data/*
+
+OTHER_FILES += data/DragAnywhereSlider.qml \
+ data/FlashAnimation.qml \
+ data/Slider.qml \
+ data/draggables.qml \
+ data/grabberstate.qml \
+ data/multipleSliders.qml \
+ data/reparenting.qml \
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp b/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
new file mode 100644
index 0000000000..f827b82205
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
@@ -0,0 +1,487 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+
+#include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlproperty.h>
+#include <QtQuick/private/qquickdraghandler_p.h>
+#include <QtQuick/private/qquickrepeater_p.h>
+#include <QtQuick/private/qquicktaphandler_p.h>
+#include <QtQuick/qquickitem.h>
+#include <QtQuick/qquickview.h>
+
+#include "../../../shared/util.h"
+#include "../../shared/viewtestutil.h"
+
+Q_LOGGING_CATEGORY(lcPointerTests, "qt.quick.pointer.tests")
+
+class tst_DragHandler : public QQmlDataTest
+{
+ Q_OBJECT
+public:
+ tst_DragHandler()
+ :touchDevice(QTest::createTouchDevice())
+ {}
+
+private slots:
+ void initTestCase();
+
+ void defaultPropertyValues();
+ void touchDrag();
+ void mouseDrag();
+ void touchDragMulti();
+ void touchDragMultiSliders_data();
+ void touchDragMultiSliders();
+ void touchPassiveGrabbers_data();
+ void touchPassiveGrabbers();
+
+private:
+ void createView(QScopedPointer<QQuickView> &window, const char *fileName);
+ QSet<QQuickPointerHandler *> passiveGrabbers(QQuickWindow *window, int pointId = 0);
+ QTouchDevice *touchDevice;
+};
+
+void tst_DragHandler::createView(QScopedPointer<QQuickView> &window, const char *fileName)
+{
+ window.reset(new QQuickView);
+ window->setSource(testFileUrl(fileName));
+ QTRY_COMPARE(window->status(), QQuickView::Ready);
+ QQuickViewTestUtil::centerOnScreen(window.data());
+ QQuickViewTestUtil::moveMouseAway(window.data());
+
+ window->show();
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
+ QVERIFY(window->rootObject() != 0);
+}
+
+QSet<QQuickPointerHandler*> tst_DragHandler::passiveGrabbers(QQuickWindow *window, int pointId /*= 0*/)
+{
+ QSet<QQuickPointerHandler*> result;
+ QQuickWindowPrivate *winp = QQuickWindowPrivate::get(window);
+ if (QQuickPointerDevice* device = QQuickPointerDevice::touchDevice(touchDevice)) {
+ QQuickPointerEvent *pointerEvent = winp->pointerEventInstance(device);
+ for (int i = 0; i < pointerEvent->pointCount(); ++i) {
+ QQuickEventPoint *eventPoint = pointerEvent->point(i);
+ QVector<QPointer <QQuickPointerHandler> > passives = eventPoint->passiveGrabbers();
+ if (!pointId || eventPoint->pointId() == pointId) {
+ for (auto it = passives.constBegin(); it != passives.constEnd(); ++it)
+ result << it->data();
+ }
+ }
+ }
+ return result;
+}
+
+void tst_DragHandler::initTestCase()
+{
+ // This test assumes that we don't get synthesized mouse events from QGuiApplication
+ qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, false);
+
+ QQmlDataTest::initTestCase();
+}
+
+void tst_DragHandler::defaultPropertyValues()
+{
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "draggables.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickItem *ball = window->rootObject()->childItems().first();
+ QVERIFY(ball);
+ QQuickDragHandler *dragHandler = ball->findChild<QQuickDragHandler*>();
+ QVERIFY(dragHandler);
+
+ QCOMPARE(dragHandler->acceptedButtons(), Qt::LeftButton);
+ QCOMPARE(dragHandler->translation(), QVector2D());
+ QCOMPARE(dragHandler->point().position(), QPointF());
+ QCOMPARE(dragHandler->point().scenePosition(), QPointF());
+ QCOMPARE(dragHandler->point().pressPosition(), QPointF());
+ QCOMPARE(dragHandler->point().scenePressPosition(), QPointF());
+ QCOMPARE(dragHandler->point().sceneGrabPosition(), QPointF());
+}
+
+void tst_DragHandler::touchDrag()
+{
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "draggables.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickItem *ball = window->rootObject()->childItems().first();
+ QVERIFY(ball);
+ QQuickDragHandler *dragHandler = ball->findChild<QQuickDragHandler*>();
+ QVERIFY(dragHandler);
+
+ QSignalSpy translationChangedSpy(dragHandler, SIGNAL(translationChanged()));
+
+ QPointF ballCenter = ball->clipRect().center();
+ QPointF scenePressPos = ball->mapToScene(ballCenter);
+ QPoint p1 = scenePressPos.toPoint();
+ QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QVERIFY(!dragHandler->active());
+ QCOMPARE(dragHandler->point().position(), ballCenter);
+ QCOMPARE(dragHandler->point().pressPosition(), ballCenter);
+ QCOMPARE(dragHandler->point().scenePosition(), scenePressPos);
+ QCOMPARE(dragHandler->point().scenePressPosition(), scenePressPos);
+ p1 += QPoint(dragThreshold, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QVERIFY(!dragHandler->active());
+ p1 += QPoint(1, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(dragHandler->active());
+ QCOMPARE(translationChangedSpy.count(), 0);
+ QCOMPARE(dragHandler->translation().x(), 0.0);
+ QPointF sceneGrabPos = p1;
+ QCOMPARE(dragHandler->point().sceneGrabPosition(), sceneGrabPos);
+ p1 += QPoint(19, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(dragHandler->active());
+ QCOMPARE(dragHandler->point().position(), ballCenter);
+ QCOMPARE(dragHandler->point().pressPosition(), ballCenter);
+ QCOMPARE(dragHandler->point().scenePosition(), ball->mapToScene(ballCenter));
+ QCOMPARE(dragHandler->point().scenePressPosition(), scenePressPos);
+ QCOMPARE(dragHandler->point().sceneGrabPosition(), sceneGrabPos);
+ QCOMPARE(dragHandler->translation().x(), dragThreshold + 20.0);
+ QCOMPARE(dragHandler->translation().y(), 0.0);
+ QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(!dragHandler->active());
+ QCOMPARE(dragHandler->point().pressedButtons(), Qt::NoButton);
+ QCOMPARE(ball->mapToScene(ballCenter).toPoint(), p1);
+ QCOMPARE(translationChangedSpy.count(), 1);
+}
+
+void tst_DragHandler::mouseDrag()
+{
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "draggables.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickItem *ball = window->rootObject()->childItems().first();
+ QVERIFY(ball);
+ QQuickDragHandler *dragHandler = ball->findChild<QQuickDragHandler*>();
+ QVERIFY(dragHandler);
+
+ QSignalSpy translationChangedSpy(dragHandler, SIGNAL(translationChanged()));
+
+ QPointF ballCenter = ball->clipRect().center();
+ QPointF scenePressPos = ball->mapToScene(ballCenter);
+ QPoint p1 = scenePressPos.toPoint();
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QVERIFY(!dragHandler->active());
+ QCOMPARE(dragHandler->point().position(), ballCenter);
+ QCOMPARE(dragHandler->point().pressPosition(), ballCenter);
+ QCOMPARE(dragHandler->point().scenePosition(), scenePressPos);
+ QCOMPARE(dragHandler->point().scenePressPosition(), scenePressPos);
+ p1 += QPoint(dragThreshold, 0);
+ QTest::mouseMove(window, p1);
+ QVERIFY(!dragHandler->active());
+ p1 += QPoint(1, 0);
+ QTest::mouseMove(window, p1);
+ QTRY_VERIFY(dragHandler->active());
+ QCOMPARE(translationChangedSpy.count(), 0);
+ QCOMPARE(dragHandler->translation().x(), 0.0);
+ QPointF sceneGrabPos = p1;
+ QCOMPARE(dragHandler->point().sceneGrabPosition(), sceneGrabPos);
+ p1 += QPoint(19, 0);
+ QTest::mouseMove(window, p1);
+ QTRY_VERIFY(dragHandler->active());
+ QCOMPARE(dragHandler->point().position(), ballCenter);
+ QCOMPARE(dragHandler->point().pressPosition(), ballCenter);
+ QCOMPARE(dragHandler->point().scenePosition(), ball->mapToScene(ballCenter));
+ QCOMPARE(dragHandler->point().scenePressPosition(), scenePressPos);
+ QCOMPARE(dragHandler->point().sceneGrabPosition(), sceneGrabPos);
+ QCOMPARE(dragHandler->translation().x(), dragThreshold + 20.0);
+ QCOMPARE(dragHandler->translation().y(), 0.0);
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(!dragHandler->active());
+ QCOMPARE(dragHandler->point().pressedButtons(), Qt::NoButton);
+ QCOMPARE(ball->mapToScene(ballCenter).toPoint(), p1);
+ QCOMPARE(translationChangedSpy.count(), 1);
+}
+
+void tst_DragHandler::touchDragMulti()
+{
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "draggables.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickItem *ball1 = window->rootObject()->childItems().first();
+ QVERIFY(ball1);
+ QQuickDragHandler *dragHandler1 = ball1->findChild<QQuickDragHandler*>();
+ QVERIFY(dragHandler1);
+ QSignalSpy translationChangedSpy1(dragHandler1, SIGNAL(translationChanged()));
+
+ QQuickItem *ball2 = window->rootObject()->childItems().at(1);
+ QVERIFY(ball2);
+ QQuickDragHandler *dragHandler2 = ball2->findChild<QQuickDragHandler*>();
+ QVERIFY(dragHandler2);
+ QSignalSpy translationChangedSpy2(dragHandler2, SIGNAL(translationChanged()));
+
+ QPointF ball1Center = ball1->clipRect().center();
+ QPointF scenePressPos1 = ball1->mapToScene(ball1Center);
+ QPoint p1 = scenePressPos1.toPoint();
+ QPointF ball2Center = ball2->clipRect().center();
+ QPointF scenePressPos2 = ball2->mapToScene(ball2Center);
+ QPoint p2 = scenePressPos2.toPoint();
+
+ QTest::touchEvent(window, touchDevice).press(1, p1, window).press(2, p2, window);
+ QQuickTouchUtils::flush(window);
+ QVERIFY(!dragHandler1->active());
+ QCOMPARE(dragHandler1->point().position(), ball1Center);
+ QCOMPARE(dragHandler1->point().pressPosition(), ball1Center);
+ QCOMPARE(dragHandler1->point().scenePosition(), scenePressPos1);
+ QCOMPARE(dragHandler1->point().scenePressPosition(), scenePressPos1);
+ QVERIFY(!dragHandler2->active());
+ QCOMPARE(dragHandler2->point().position(), ball2Center);
+ QCOMPARE(dragHandler2->point().pressPosition(), ball2Center);
+ QCOMPARE(dragHandler2->point().scenePosition(), scenePressPos2);
+ QCOMPARE(dragHandler2->point().scenePressPosition(), scenePressPos2);
+ p1 += QPoint(dragThreshold, 0);
+ p2 += QPoint(0, dragThreshold);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window).move(2, p2, window);
+ QQuickTouchUtils::flush(window);
+ QVERIFY(!dragHandler1->active());
+ p1 += QPoint(1, 0);
+ p2 += QPoint(0, 1);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window).move(2, p2, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(dragHandler1->active());
+ QVERIFY(dragHandler2->active());
+ QCOMPARE(translationChangedSpy1.count(), 0);
+ QCOMPARE(dragHandler1->translation().x(), 0.0);
+ QPointF sceneGrabPos1 = p1;
+ QPointF sceneGrabPos2 = p2;
+ QCOMPARE(dragHandler1->point().sceneGrabPosition(), sceneGrabPos1);
+ QCOMPARE(dragHandler2->point().sceneGrabPosition(), sceneGrabPos2);
+ p1 += QPoint(19, 0);
+ p2 += QPoint(0, 19);
+ QVERIFY(dragHandler2->active());
+ QCOMPARE(translationChangedSpy2.count(), 0);
+ QCOMPARE(dragHandler2->translation().x(), 0.0);
+ QCOMPARE(dragHandler2->point().sceneGrabPosition(), sceneGrabPos2);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window).move(2, p2, window);
+ QQuickTouchUtils::flush(window);
+ QVERIFY(dragHandler1->active());
+ QVERIFY(dragHandler2->active());
+ QCOMPARE(dragHandler1->point().position(), ball1Center);
+ QCOMPARE(dragHandler1->point().pressPosition(), ball1Center);
+ QCOMPARE(dragHandler1->point().scenePosition(), ball1->mapToScene(ball1Center));
+ QCOMPARE(dragHandler1->point().scenePressPosition(), scenePressPos1);
+ QCOMPARE(dragHandler1->point().sceneGrabPosition(), sceneGrabPos1);
+ QCOMPARE(dragHandler1->translation().x(), dragThreshold + 20.0);
+ QCOMPARE(dragHandler1->translation().y(), 0.0);
+ QCOMPARE(dragHandler2->point().position(), ball2Center);
+ QCOMPARE(dragHandler2->point().pressPosition(), ball2Center);
+ QCOMPARE(dragHandler2->point().scenePosition(), ball2->mapToScene(ball2Center));
+ QCOMPARE(dragHandler2->point().scenePressPosition(), scenePressPos2);
+ QCOMPARE(dragHandler2->point().sceneGrabPosition(), sceneGrabPos2);
+ QCOMPARE(dragHandler2->translation().x(), 0.0);
+ QCOMPARE(dragHandler2->translation().y(), dragThreshold + 20.0);
+ QTest::touchEvent(window, touchDevice).release(1, p1, window).stationary(2);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(!dragHandler1->active());
+ QVERIFY(dragHandler2->active());
+ QCOMPARE(dragHandler1->point().pressedButtons(), Qt::NoButton);
+ QCOMPARE(ball1->mapToScene(ball1Center).toPoint(), p1);
+ QCOMPARE(translationChangedSpy1.count(), 1);
+ QTest::touchEvent(window, touchDevice).release(2, p2, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(!dragHandler2->active());
+ QCOMPARE(ball2->mapToScene(ball2Center).toPoint(), p2);
+ QCOMPARE(translationChangedSpy2.count(), 1);
+}
+
+void tst_DragHandler::touchDragMultiSliders_data()
+{
+ QTest::addColumn<int>("sliderRow");
+ QTest::addColumn<QVector<int> >("whichSliders");
+ QTest::addColumn<QVector<int> >("startingCenterOffsets");
+ QTest::addColumn<QVector<QVector2D> >("movements");
+
+ QTest::newRow("Drag Knob: start on the knobs, drag down") <<
+ 0 << QVector<int> { 0, 1, 2 } << QVector<int> { 0, 0, 0 } << QVector<QVector2D> { {0, 60}, {0, 60}, {0, 60} };
+ QTest::newRow("Drag Knob: start on the knobs, drag diagonally downward") <<
+ 0 << QVector<int> { 0, 1, 2 } << QVector<int> { 0, 0, 0 } << QVector<QVector2D> { {20, 40}, {20, 60}, {20, 80} };
+ QTest::newRow("Drag Anywhere: start on the knobs, drag down") <<
+ 1 << QVector<int> { 0, 1, 2 } << QVector<int> { 0, 0, 0 } << QVector<QVector2D> { {0, 60}, {0, 60}, {0, 60} };
+ QTest::newRow("Drag Anywhere: start on the knobs, drag diagonally downward") <<
+ 1 << QVector<int> { 0, 1, 2 } << QVector<int> { 0, 0, 0 } << QVector<QVector2D> { {20, 40}, {20, 60}, {20, 80} };
+ // TODO these next two fail because the DragHandler grabs when a finger
+ // drags across it from outside, but should rather start only if it is pressed inside
+// QTest::newRow("Drag Knob: start above the knobs, drag down") <<
+// 0 << QVector<int> { 0, 1, 2 } << QVector<int> { -30, -30, -30 } << QVector<QVector2D> { {0, 40}, {0, 60}, {0, 80} };
+// QTest::newRow("Drag Knob: start above the knobs, drag diagonally downward") <<
+// 0 << QVector<int> { 0, 1, 2 } << QVector<int> { -30, -30, -30 } << QVector<QVector2D> { {20, 40}, {20, 60}, {20, 80} };
+ QTest::newRow("Drag Anywhere: start above the knobs, drag down") <<
+ 1 << QVector<int> { 0, 1, 2 } << QVector<int> { -20, -30, -40 } << QVector<QVector2D> { {0, 60}, {0, 60}, {0, 60} };
+ QTest::newRow("Drag Anywhere: start above the knobs, drag diagonally downward") <<
+ 1 << QVector<int> { 0, 1, 2 } << QVector<int> { -20, -30, -40 } << QVector<QVector2D> { {20, 40}, {20, 60}, {20, 80} };
+}
+
+void tst_DragHandler::touchDragMultiSliders()
+{
+ QFETCH(int, sliderRow);
+ QFETCH(QVector<int>, whichSliders);
+ QFETCH(QVector<int>, startingCenterOffsets);
+ QFETCH(QVector<QVector2D>, movements);
+ const int moveCount = 8;
+
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "multipleSliders.qml");
+ QQuickView * window = windowPtr.data();
+ QTest::QTouchEventSequence touch = QTest::touchEvent(window, touchDevice);
+
+ QQuickRepeater *rowRepeater = window->rootObject()->findChildren<QQuickRepeater *>()[sliderRow];
+ QVector<QQuickItem *> knobs;
+ QVector<QQuickDragHandler *> dragHandlers;
+ QVector<QQuickTapHandler *> tapHandlers;
+ QVector<QPointF> startPoints;
+ for (int sli : whichSliders) {
+ QQuickItem *slider = rowRepeater->itemAt(sli);
+ QVERIFY(slider);
+ dragHandlers << slider->findChild<QQuickDragHandler*>();
+ QVERIFY(dragHandlers[sli]);
+ tapHandlers << slider->findChild<QQuickTapHandler*>();
+ QVERIFY(tapHandlers[sli]);
+ knobs << tapHandlers[sli]->parentItem();
+ QPointF startPoint = knobs[sli]->mapToScene(knobs[sli]->clipRect().center());
+ startPoint.setY(startPoint.y() + startingCenterOffsets[sli]);
+ startPoints << startPoint;
+ qCDebug(lcPointerTests) << "row" << sliderRow << "slider" << sli << slider->objectName() <<
+ "start" << startingCenterOffsets[sli] << startPoints[sli];
+ }
+ QVector<QPointF> touchPoints = startPoints;
+
+ // Press
+ for (int sli : whichSliders)
+ touch.press(sli, touchPoints[sli].toPoint());
+ touch.commit();
+
+ // Moves
+ for (int m = 0; m < moveCount; ++m) {
+ for (int sli : whichSliders) {
+ QVector2D incr = movements[sli] / moveCount;
+ touchPoints[sli] += incr.toPointF();
+ touch.move(sli, touchPoints[sli].toPoint());
+ }
+ touch.commit();
+ QQuickTouchUtils::flush(window);
+ }
+
+ // Check that they moved to where they should: since the slider is constrained,
+ // only the y component should have an effect; knobs should not come out of their "grooves"
+ for (int sli : whichSliders) {
+ QPoint endPosition = knobs[sli]->mapToScene(knobs[sli]->clipRect().center()).toPoint();
+ QPoint expectedEndPosition(startPoints[sli].x(), startPoints[sli].y() + movements[sli].y());
+ if (sliderRow == 0 && qAbs(startingCenterOffsets[sli]) > knobs[sli]->height() / 2)
+ expectedEndPosition = startPoints[sli].toPoint();
+ qCDebug(lcPointerTests) << "slider " << knobs[sli]->objectName() << "started @" << startPoints[sli]
+ << "tried to move by" << movements[sli] << "ended up @" << endPosition << "expected" << expectedEndPosition;
+ QTRY_COMPARE(endPosition, expectedEndPosition);
+ }
+
+ // Release
+ for (int sli : whichSliders)
+ touch.release(sli, touchPoints[sli].toPoint());
+ touch.commit();
+}
+
+void tst_DragHandler::touchPassiveGrabbers_data()
+{
+ QTest::addColumn<QString>("itemName");
+ QTest::addColumn<QStringList>("expectedPassiveGrabberNames");
+
+ QTest::newRow("Drag And Tap") << "dragAndTap" << QStringList({"drag", "tap"});
+ QTest::newRow("Tap And Drag") << "tapAndDrag" << QStringList({"tap", "drag"});
+ QTest::newRow("Drag And Tap (not siblings)") << "dragAndTapNotSiblings" << QStringList({"drag", "tap"});
+ QTest::newRow("Tap And Drag (not siblings)") << "tapAndDragNotSiblings" << QStringList({"tap", "drag"});
+}
+
+void tst_DragHandler::touchPassiveGrabbers()
+{
+ QFETCH(QString, itemName);
+ QFETCH(QStringList, expectedPassiveGrabberNames);
+
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "simpleTapAndDragHandlers.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickItem *row2 = window->rootObject()->findChild<QQuickItem*>(itemName);
+ QSet<QQuickPointerHandler *> expectedPassiveGrabbers;
+ for (QString objectName : expectedPassiveGrabberNames)
+ expectedPassiveGrabbers << row2->findChild<QQuickPointerHandler*>(objectName);
+
+ QPointF p1 = row2->mapToScene(row2->clipRect().center());
+ QTest::QTouchEventSequence touch = QTest::touchEvent(window, touchDevice);
+ touch.press(1, p1.toPoint()).commit();
+ QQuickTouchUtils::flush(window);
+
+ QCOMPARE(passiveGrabbers(window), expectedPassiveGrabbers);
+
+ QQuickDragHandler *dragHandler = nullptr;
+ for (QQuickPointerHandler *handler: expectedPassiveGrabbers) {
+ QCOMPARE(static_cast<QQuickSinglePointHandler *>(handler)->point().scenePressPosition(), p1);
+ QQuickDragHandler *dh = qmlobject_cast<QQuickDragHandler *>(handler);
+ if (dh)
+ dragHandler = dh;
+ }
+ QVERIFY(dragHandler);
+ QPointF initialPos = dragHandler->target()->position();
+
+ p1 += QPointF(50, 50);
+ touch.move(1, p1.toPoint()).commit();
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(dragHandler->active());
+
+ p1 += QPointF(50, 50);
+ touch.move(1, p1.toPoint()).commit();
+ QQuickTouchUtils::flush(window);
+ QPointF movementDelta = dragHandler->target()->position() - initialPos;
+ qCDebug(lcPointerTests) << "DragHandler moved the target by" << movementDelta;
+ QVERIFY(movementDelta.x() >= 100);
+ QVERIFY(movementDelta.y() >= 100);
+
+ QTest::qWait(500);
+
+ touch.release(1, p1.toPoint());
+ touch.commit();
+ QQuickTouchUtils::flush(window);
+}
+
+QTEST_MAIN(tst_DragHandler)
+
+#include "tst_qquickdraghandler.moc"
+
diff --git a/tests/auto/quick/pointerhandlers/qquickpointerhandler/data/singleitem.qml b/tests/auto/quick/pointerhandlers/qquickpointerhandler/data/singleitem.qml
new file mode 100644
index 0000000000..126cf3ff2b
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquickpointerhandler/data/singleitem.qml
@@ -0,0 +1,28 @@
+import QtQuick 2.8
+import Qt.test 1.0
+
+Item {
+ id: root
+ objectName: "root Item"
+ width: 320
+ height: 480
+
+ Rectangle {
+ objectName: "eventItem's bounds"
+ anchors.fill: eventItem
+ color: "lightsteelblue"
+ }
+
+ EventItem {
+ id: eventItem
+ objectName: "eventItem1"
+ x: 5
+ y: 5
+ height: 30
+ width: 30
+
+ EventHandler {
+ objectName: "eventHandler"
+ }
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/qquickpointerhandler/qquickpointerhandler.pro b/tests/auto/quick/pointerhandlers/qquickpointerhandler/qquickpointerhandler.pro
new file mode 100644
index 0000000000..c386969206
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquickpointerhandler/qquickpointerhandler.pro
@@ -0,0 +1,16 @@
+CONFIG += testcase
+
+TARGET = tst_qquickpointerhandler
+QT += core-private gui-private qml-private quick-private testlib
+
+macos:CONFIG -= app_bundle
+
+SOURCES += tst_qquickpointerhandler.cpp
+
+include (../../../shared/util.pri)
+include (../../shared/util.pri)
+
+TESTDATA = data/*
+
+# OTHER_FILES += data/foo.qml
+
diff --git a/tests/auto/quick/pointerhandlers/qquickpointerhandler/tst_qquickpointerhandler.cpp b/tests/auto/quick/pointerhandlers/qquickpointerhandler/tst_qquickpointerhandler.cpp
new file mode 100644
index 0000000000..d38ae3190e
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquickpointerhandler/tst_qquickpointerhandler.cpp
@@ -0,0 +1,580 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+
+#include <private/qdebug_p.h>
+#include <QtGui/qstylehints.h>
+#include <QtQuick/private/qquickpointerhandler_p.h>
+#include <QtQuick/qquickitem.h>
+#include <QtQuick/qquickview.h>
+
+#include "../../../shared/util.h"
+#include "../../shared/viewtestutil.h"
+
+Q_LOGGING_CATEGORY(lcPointerTests, "qt.quick.pointer.tests")
+
+class Event
+{
+ Q_GADGET
+public:
+ enum Destination {
+ FilterDestination,
+ MouseDestination,
+ TouchDestination,
+ HandlerDestination
+ };
+ Q_ENUM(Destination)
+
+ Event(Destination d, QEvent::Type t, Qt::TouchPointState s, int grabState, QPointF item, QPointF scene)
+ : destination(d), type(t), state(s), grabState(grabState), posWrtItem(item), posWrtScene(scene)
+ {}
+
+ Destination destination;
+ QEvent::Type type; // if this represents a QEvent that was received
+ Qt::TouchPointState state; // if this represents an event (pointer, touch or mouse)
+ int grabState; // if this represents an onGrabChanged() notification (QQuickEventPoint::GrabState)
+ QPointF posWrtItem;
+ QPointF posWrtScene;
+};
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const class Event &event) {
+ QDebugStateSaver saver(dbg);
+ dbg.nospace();
+ dbg << "Event(";
+ QtDebugUtils::formatQEnum(dbg, event.destination);
+ dbg << ' ';
+ QtDebugUtils::formatQEnum(dbg, event.type);
+ dbg << ' ';
+ QtDebugUtils::formatQEnum(dbg, event.state);
+ if (event.grabState) {
+ dbg << ' ';
+ QtDebugUtils::formatQEnum(dbg, QQuickEventPoint::GrabState(event.grabState));
+ }
+ dbg << " @ ";
+ QtDebugUtils::formatQPoint(dbg, event.posWrtItem);
+ dbg << " S ";
+ QtDebugUtils::formatQPoint(dbg, event.posWrtScene);
+ dbg << ')';
+ return dbg;
+}
+#endif
+
+enum {
+ NoGrab = 0,
+};
+
+class EventItem : public QQuickItem
+{
+ Q_OBJECT
+public:
+ EventItem(QQuickItem *parent = 0)
+ : QQuickItem(parent), acceptPointer(false), grabPointer(false), acceptMouse(false), acceptTouch(false), filterTouch(false)
+ {}
+
+ inline int grabState(bool accept, Qt::TouchPointState state) {
+ return (accept && (state != Qt::TouchPointReleased)) ? (int)QQuickEventPoint::GrabExclusive : (int)NoGrab;
+ }
+
+ void touchEvent(QTouchEvent *event)
+ {
+ qCDebug(lcPointerTests) << event << "will accept?" << acceptTouch;
+ for (const QTouchEvent::TouchPoint &tp : event->touchPoints())
+ eventList.append(Event(Event::TouchDestination, event->type(), tp.state(), grabState(acceptTouch, tp.state()), tp.pos(), tp.scenePos()));
+ event->setAccepted(acceptTouch);
+ }
+ void mousePressEvent(QMouseEvent *event)
+ {
+ qCDebug(lcPointerTests) << event;
+ eventList.append(Event(Event::MouseDestination, event->type(), Qt::TouchPointPressed, grabState(acceptMouse, Qt::TouchPointPressed), event->pos(), event->windowPos()));
+ event->setAccepted(acceptMouse);
+ }
+ void mouseMoveEvent(QMouseEvent *event)
+ {
+ qCDebug(lcPointerTests) << event;
+ eventList.append(Event(Event::MouseDestination, event->type(), Qt::TouchPointMoved, grabState(acceptMouse, Qt::TouchPointMoved), event->pos(), event->windowPos()));
+ event->setAccepted(acceptMouse);
+ }
+ void mouseReleaseEvent(QMouseEvent *event)
+ {
+ qCDebug(lcPointerTests) << event;
+ eventList.append(Event(Event::MouseDestination, event->type(), Qt::TouchPointReleased, grabState(acceptMouse, Qt::TouchPointReleased), event->pos(), event->windowPos()));
+ event->setAccepted(acceptMouse);
+ }
+ void mouseDoubleClickEvent(QMouseEvent *event)
+ {
+ qCDebug(lcPointerTests) << event;
+ eventList.append(Event(Event::MouseDestination, event->type(), Qt::TouchPointPressed, grabState(acceptMouse, Qt::TouchPointPressed), event->pos(), event->windowPos()));
+ event->setAccepted(acceptMouse);
+ }
+
+ void mouseUngrabEvent()
+ {
+ qCDebug(lcPointerTests);
+ eventList.append(Event(Event::MouseDestination, QEvent::UngrabMouse, Qt::TouchPointReleased, QQuickEventPoint::UngrabExclusive, QPoint(0,0), QPoint(0,0)));
+ }
+
+ bool event(QEvent *event)
+ {
+ qCDebug(lcPointerTests) << event;
+ return QQuickItem::event(event);
+ }
+
+ QList<Event> eventList;
+ bool acceptPointer;
+ bool grabPointer;
+ bool acceptMouse;
+ bool acceptTouch;
+ bool filterTouch; // when used as event filter
+
+ bool eventFilter(QObject *o, QEvent *event)
+ {
+ qCDebug(lcPointerTests) << event << o;
+ if (event->type() == QEvent::TouchBegin ||
+ event->type() == QEvent::TouchUpdate ||
+ event->type() == QEvent::TouchCancel ||
+ event->type() == QEvent::TouchEnd) {
+ QTouchEvent *touch = static_cast<QTouchEvent*>(event);
+ for (const QTouchEvent::TouchPoint &tp : touch->touchPoints())
+ eventList.append(Event(Event::FilterDestination, event->type(), tp.state(), QQuickEventPoint::GrabExclusive, tp.pos(), tp.scenePos()));
+ if (filterTouch)
+ event->accept();
+ return true;
+ }
+ return false;
+ }
+};
+
+#define QCOMPARE_EVENT(i, d, t, s, g) \
+ {\
+ const Event &event = eventItem1->eventList.at(i);\
+ QCOMPARE(event.destination, d);\
+ QCOMPARE(event.type, t);\
+ QCOMPARE(event.state, s);\
+ QCOMPARE(event.grabState, g);\
+ }\
+
+class EventHandler : public QQuickPointerHandler
+{
+ void handlePointerEventImpl(QQuickPointerEvent *event) override
+ {
+ QQuickPointerHandler::handlePointerEventImpl(event);
+ if (!enabled())
+ return;
+ EventItem *item = static_cast<EventItem *>(target());
+ qCDebug(lcPointerTests) << item->objectName() << event;
+ int c = event->pointCount();
+ for (int i = 0; i < c; ++i) {
+ QQuickEventPoint *point = event->point(i);
+ if (item->acceptPointer)
+ point->setAccepted(item->acceptPointer); // does NOT imply a grab
+ if (item->grabPointer)
+ setExclusiveGrab(point, true);
+ qCDebug(lcPointerTests) << " " << i << ":" << point << "accepted?" << item->acceptPointer << "grabbed?" << (point->exclusiveGrabber() == this);
+ item->eventList.append(Event(Event::HandlerDestination, QEvent::Pointer,
+ static_cast<Qt::TouchPointState>(point->state()),
+ item->grabPointer ? (int)QQuickEventPoint::GrabExclusive : (int)NoGrab,
+ eventPos(point), point->scenePosition()));
+ }
+ }
+
+ void onGrabChanged(QQuickPointerHandler *, QQuickEventPoint::GrabState stateChange, QQuickEventPoint *point) override
+ {
+ EventItem *item = static_cast<EventItem *>(target());
+ item->eventList.append(Event(Event::HandlerDestination, QEvent::None,
+ static_cast<Qt::TouchPointState>(point->state()), stateChange, eventPos(point), point->scenePosition()));
+ }
+};
+
+class tst_PointerHandlers : public QQmlDataTest
+{
+ Q_OBJECT
+public:
+ tst_PointerHandlers()
+ :touchDevice(QTest::createTouchDevice())
+ {}
+
+private slots:
+ void initTestCase();
+
+ void touchEventDelivery();
+ void mouseEventDelivery();
+ void touchReleaseOutside_data();
+ void touchReleaseOutside();
+
+protected:
+ bool eventFilter(QObject *, QEvent *event)
+ {
+ Qt::TouchPointState tpState;
+ switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ tpState = Qt::TouchPointPressed;
+ break;
+ case QEvent::MouseMove:
+ tpState = Qt::TouchPointMoved;
+ break;
+ case QEvent::MouseButtonRelease:
+ tpState = Qt::TouchPointReleased;
+ break;
+ default:
+ // So far we aren't recording filtered touch events here - they would be quite numerous in some cases
+ return false;
+ }
+ QMouseEvent *me = static_cast<QMouseEvent*>(event);
+ filteredEventList.append(Event(Event::FilterDestination, event->type(), tpState,
+ 0, me->pos(), me->globalPos()));
+ return false;
+ }
+
+private:
+ void createView(QScopedPointer<QQuickView> &window, const char *fileName);
+ QTouchDevice *touchDevice;
+ QList<Event> filteredEventList;
+};
+
+void tst_PointerHandlers::createView(QScopedPointer<QQuickView> &window, const char *fileName)
+{
+ window.reset(new QQuickView);
+// window->setGeometry(0,0,240,320);
+ window->setSource(testFileUrl(fileName));
+ QTRY_COMPARE(window->status(), QQuickView::Ready);
+ QQuickViewTestUtil::centerOnScreen(window.data());
+ QQuickViewTestUtil::moveMouseAway(window.data());
+
+ window->show();
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
+ QVERIFY(window->rootObject() != 0);
+}
+
+void tst_PointerHandlers::initTestCase()
+{
+ // This test assumes that we don't get synthesized mouse events from QGuiApplication
+ qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, false);
+
+ QQmlDataTest::initTestCase();
+ qmlRegisterType<EventItem>("Qt.test", 1, 0, "EventItem");
+ qmlRegisterType<EventHandler>("Qt.test", 1, 0, "EventHandler");
+}
+
+void tst_PointerHandlers::touchEventDelivery()
+{
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "singleitem.qml");
+ QQuickView * window = windowPtr.data();
+
+ EventItem *eventItem1 = window->rootObject()->findChild<EventItem*>("eventItem1");
+ QVERIFY(eventItem1);
+
+ // Do not accept anything
+ QPoint p1 = QPoint(20, 20);
+ QTest::touchEvent(window, touchDevice).press(0, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_COMPARE(eventItem1->eventList.size(), 3);
+ QCOMPARE_EVENT(0, Event::HandlerDestination, QEvent::Pointer, Qt::TouchPointPressed, NoGrab);
+ QCOMPARE_EVENT(1, Event::TouchDestination, QEvent::TouchBegin, Qt::TouchPointPressed, NoGrab);
+ QCOMPARE_EVENT(2, Event::MouseDestination, QEvent::MouseButtonPress, Qt::TouchPointPressed, NoGrab);
+ p1 += QPoint(10, 0);
+ QTest::touchEvent(window, touchDevice).move(0, p1, window);
+ QQuickTouchUtils::flush(window);
+ QCOMPARE(eventItem1->eventList.size(), 4);
+ QCOMPARE_EVENT(3, Event::HandlerDestination, QEvent::Pointer, Qt::TouchPointMoved, NoGrab);
+ QTest::touchEvent(window, touchDevice).release(0, p1, window);
+ QQuickTouchUtils::flush(window);
+ QCOMPARE(eventItem1->eventList.size(), 5);
+ QCOMPARE_EVENT(4, Event::HandlerDestination, QEvent::Pointer, Qt::TouchPointReleased, NoGrab);
+ eventItem1->eventList.clear();
+
+ // Accept touch
+ eventItem1->acceptTouch = true;
+ p1 = QPoint(20, 20);
+ QTest::touchEvent(window, touchDevice).press(0, p1, window);
+ QQuickTouchUtils::flush(window);
+ QCOMPARE(eventItem1->eventList.size(), 2);
+ QCOMPARE_EVENT(0, Event::HandlerDestination, QEvent::Pointer, Qt::TouchPointPressed, NoGrab);
+ QCOMPARE_EVENT(1, Event::TouchDestination, QEvent::TouchBegin, Qt::TouchPointPressed, QQuickEventPoint::GrabExclusive);
+ auto pointerEvent = QQuickWindowPrivate::get(window)->pointerEventInstance(QQuickPointerDevice::touchDevices().at(0));
+ QCOMPARE(pointerEvent->point(0)->exclusiveGrabber(), eventItem1);
+ p1 += QPoint(10, 0);
+ QTest::touchEvent(window, touchDevice).move(0, p1, window);
+ QQuickTouchUtils::flush(window);
+ QCOMPARE(eventItem1->eventList.size(), 4);
+ QCOMPARE_EVENT(2, Event::HandlerDestination, QEvent::Pointer, Qt::TouchPointMoved, NoGrab);
+ QCOMPARE_EVENT(3, Event::TouchDestination, QEvent::TouchUpdate, Qt::TouchPointMoved, QQuickEventPoint::GrabExclusive);
+ QTest::touchEvent(window, touchDevice).release(0, p1, window);
+ QQuickTouchUtils::flush(window);
+ QCOMPARE(eventItem1->eventList.size(), 6);
+ QCOMPARE_EVENT(4, Event::HandlerDestination, QEvent::Pointer, Qt::TouchPointReleased, NoGrab);
+ QCOMPARE_EVENT(5, Event::TouchDestination, QEvent::TouchEnd, Qt::TouchPointReleased, NoGrab);
+ eventItem1->eventList.clear();
+
+ // wait to avoid getting a double click event
+ QTest::qWait(qApp->styleHints()->mouseDoubleClickInterval() + 10);
+
+ // Accept mouse
+ eventItem1->acceptTouch = false;
+ eventItem1->acceptMouse = true;
+ eventItem1->setAcceptedMouseButtons(Qt::LeftButton);
+ p1 = QPoint(20, 20);
+ QTest::touchEvent(window, touchDevice).press(0, p1, window);
+ QQuickTouchUtils::flush(window);
+ QCOMPARE(eventItem1->eventList.size(), 3);
+ QCOMPARE_EVENT(0, Event::HandlerDestination, QEvent::Pointer, Qt::TouchPointPressed, NoGrab);
+ QCOMPARE_EVENT(1, Event::TouchDestination, QEvent::TouchBegin, Qt::TouchPointPressed, NoGrab);
+ QCOMPARE_EVENT(2, Event::MouseDestination, QEvent::MouseButtonPress, Qt::TouchPointPressed, QQuickEventPoint::GrabExclusive);
+ QCOMPARE(window->mouseGrabberItem(), eventItem1);
+
+ QPointF localPos = eventItem1->mapFromScene(p1);
+ QPointF scenePos = p1; // item is at 0,0
+ QCOMPARE(eventItem1->eventList.at(1).posWrtItem, localPos);
+ QCOMPARE(eventItem1->eventList.at(1).posWrtScene, scenePos);
+ QCOMPARE(eventItem1->eventList.at(2).posWrtItem, localPos);
+ QCOMPARE(eventItem1->eventList.at(2).posWrtScene, scenePos);
+
+ p1 += QPoint(10, 0);
+ QTest::touchEvent(window, touchDevice).move(0, p1, window);
+ QQuickTouchUtils::flush(window);
+ QCOMPARE(eventItem1->eventList.size(), 6);
+ QCOMPARE_EVENT(3, Event::HandlerDestination, QEvent::Pointer, Qt::TouchPointMoved, NoGrab);
+ QCOMPARE_EVENT(4, Event::TouchDestination, QEvent::TouchUpdate, Qt::TouchPointMoved, NoGrab);
+ QCOMPARE_EVENT(5, Event::MouseDestination, QEvent::MouseMove, Qt::TouchPointMoved, QQuickEventPoint::GrabExclusive);
+ QTest::touchEvent(window, touchDevice).release(0, p1, window);
+ QQuickTouchUtils::flush(window);
+ QCOMPARE(eventItem1->eventList.size(), 10);
+ QCOMPARE_EVENT(6, Event::HandlerDestination, QEvent::Pointer, Qt::TouchPointReleased, NoGrab);
+ QCOMPARE_EVENT(7, Event::TouchDestination, QEvent::TouchEnd, Qt::TouchPointReleased, NoGrab);
+ QCOMPARE_EVENT(8, Event::MouseDestination, QEvent::MouseButtonRelease, Qt::TouchPointReleased, NoGrab);
+ QCOMPARE_EVENT(9, Event::MouseDestination, QEvent::UngrabMouse, Qt::TouchPointReleased, QQuickEventPoint::UngrabExclusive);
+ eventItem1->eventList.clear();
+
+ // wait to avoid getting a double click event
+ QTest::qWait(qApp->styleHints()->mouseDoubleClickInterval() + 10);
+
+ // Accept mouse buttons but not the touch event
+ eventItem1->acceptTouch = false;
+ eventItem1->acceptMouse = false;
+ eventItem1->setAcceptedMouseButtons(Qt::LeftButton);
+ p1 = QPoint(20, 20);
+ QTest::touchEvent(window, touchDevice).press(0, p1, window);
+ QQuickTouchUtils::flush(window);
+ QCOMPARE(eventItem1->eventList.size(), 3);
+ QCOMPARE_EVENT(0, Event::HandlerDestination, QEvent::Pointer, Qt::TouchPointPressed, NoGrab);
+ QCOMPARE_EVENT(1, Event::TouchDestination, QEvent::TouchBegin, Qt::TouchPointPressed, NoGrab);
+ QCOMPARE_EVENT(2, Event::MouseDestination, QEvent::MouseButtonPress, Qt::TouchPointPressed, NoGrab);
+ QCOMPARE(pointerEvent->point(0)->exclusiveGrabber(), nullptr);
+ p1 += QPoint(10, 0);
+ QTest::touchEvent(window, touchDevice).move(0, p1, window);
+ QQuickTouchUtils::flush(window);
+ QCOMPARE(eventItem1->eventList.size(), 4);
+ QTest::touchEvent(window, touchDevice).release(0, p1, window);
+ QQuickTouchUtils::flush(window);
+ QCOMPARE(eventItem1->eventList.size(), 5);
+ eventItem1->eventList.clear();
+
+ // wait to avoid getting a double click event
+ QTest::qWait(qApp->styleHints()->mouseDoubleClickInterval() + 10);
+
+ // Accept touch
+ eventItem1->acceptTouch = true;
+ eventItem1->setAcceptedMouseButtons(Qt::LeftButton);
+ p1 = QPoint(20, 20);
+ QTest::touchEvent(window, touchDevice).press(0, p1, window);
+ QQuickTouchUtils::flush(window);
+ QCOMPARE(eventItem1->eventList.size(), 2);
+ QCOMPARE_EVENT(0, Event::HandlerDestination, QEvent::Pointer, Qt::TouchPointPressed, NoGrab);
+ QCOMPARE_EVENT(1, Event::TouchDestination, QEvent::TouchBegin, Qt::TouchPointPressed, QQuickEventPoint::GrabExclusive);
+ p1 += QPoint(10, 0);
+ QTest::touchEvent(window, touchDevice).move(0, p1, window);
+ QQuickTouchUtils::flush(window);
+ QCOMPARE(eventItem1->eventList.size(), 4);
+ QCOMPARE_EVENT(2, Event::HandlerDestination, QEvent::Pointer, Qt::TouchPointMoved, NoGrab);
+ QCOMPARE_EVENT(3, Event::TouchDestination, QEvent::TouchUpdate, Qt::TouchPointMoved, QQuickEventPoint::GrabExclusive);
+ QTest::touchEvent(window, touchDevice).release(0, p1, window);
+ QQuickTouchUtils::flush(window);
+ QCOMPARE(eventItem1->eventList.size(), 6);
+ QCOMPARE_EVENT(4, Event::HandlerDestination, QEvent::Pointer, Qt::TouchPointReleased, NoGrab);
+ QCOMPARE_EVENT(5, Event::TouchDestination, QEvent::TouchEnd, Qt::TouchPointReleased, NoGrab);
+ eventItem1->eventList.clear();
+
+ // Accept pointer events
+ eventItem1->acceptPointer = true;
+ eventItem1->grabPointer = true;
+ p1 = QPoint(20, 20);
+ QTest::touchEvent(window, touchDevice).press(0, p1, window);
+ QQuickTouchUtils::flush(window);
+ QCOMPARE(eventItem1->eventList.size(), 2);
+ QCOMPARE_EVENT(0, Event::HandlerDestination, QEvent::None, Qt::TouchPointPressed, QQuickEventPoint::GrabExclusive);
+ QCOMPARE_EVENT(1, Event::HandlerDestination, QEvent::Pointer, Qt::TouchPointPressed, QQuickEventPoint::GrabExclusive);
+ p1 += QPoint(10, 0);
+ QTest::touchEvent(window, touchDevice).move(0, p1, window);
+ QQuickTouchUtils::flush(window);
+ QCOMPARE(eventItem1->eventList.size(), 3);
+ QCOMPARE_EVENT(2, Event::HandlerDestination, QEvent::Pointer, Qt::TouchPointMoved, QQuickEventPoint::GrabExclusive);
+ QTest::touchEvent(window, touchDevice).release(0, p1, window);
+ QQuickTouchUtils::flush(window);
+ QCOMPARE(eventItem1->eventList.size(), 5);
+ qCDebug(lcPointerTests) << eventItem1->eventList;
+ QCOMPARE_EVENT(3, Event::HandlerDestination, QEvent::Pointer, Qt::TouchPointReleased, QQuickEventPoint::GrabExclusive);
+ QCOMPARE_EVENT(4, Event::HandlerDestination, QEvent::None, Qt::TouchPointReleased, QQuickEventPoint::UngrabExclusive);
+ eventItem1->eventList.clear();
+}
+
+void tst_PointerHandlers::mouseEventDelivery()
+{
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "singleitem.qml");
+ QQuickView * window = windowPtr.data();
+
+ EventItem *eventItem1 = window->rootObject()->findChild<EventItem*>("eventItem1");
+ QVERIFY(eventItem1);
+
+ // Do not accept anything
+ QPoint p1 = QPoint(20, 20);
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QCOMPARE(eventItem1->eventList.size(), 2);
+ p1 += QPoint(10, 0);
+ QTest::mouseMove(window, p1);
+ QCOMPARE(eventItem1->eventList.size(), 3);
+ QTest::mouseRelease(window, Qt::LeftButton);
+ QCOMPARE(eventItem1->eventList.size(), 3);
+ eventItem1->eventList.clear();
+
+ // wait to avoid getting a double click event
+ QTest::qWait(qApp->styleHints()->mouseDoubleClickInterval() + 10);
+
+ // Accept mouse
+ eventItem1->acceptTouch = false;
+ eventItem1->acceptMouse = true;
+ eventItem1->setAcceptedMouseButtons(Qt::LeftButton);
+ p1 = QPoint(20, 20);
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QCOMPARE(eventItem1->eventList.size(), 2);
+ QCOMPARE_EVENT(0, Event::HandlerDestination, QEvent::Pointer, Qt::TouchPointPressed, NoGrab);
+ QCOMPARE_EVENT(1, Event::MouseDestination, QEvent::MouseButtonPress, Qt::TouchPointPressed, QQuickEventPoint::GrabExclusive);
+ QCOMPARE(window->mouseGrabberItem(), eventItem1);
+
+ QPointF localPos = eventItem1->mapFromScene(p1);
+ QPointF scenePos = p1; // item is at 0,0
+ QCOMPARE(eventItem1->eventList.at(0).posWrtItem, localPos);
+ QCOMPARE(eventItem1->eventList.at(0).posWrtScene, scenePos);
+ QCOMPARE(eventItem1->eventList.at(1).posWrtItem, localPos);
+ QCOMPARE(eventItem1->eventList.at(1).posWrtScene, scenePos);
+
+ p1 += QPoint(10, 0);
+ QTest::mouseMove(window, p1);
+ QCOMPARE(eventItem1->eventList.size(), 3);
+ QCOMPARE_EVENT(2, Event::MouseDestination, QEvent::MouseMove, Qt::TouchPointMoved, QQuickEventPoint::GrabExclusive);
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QCOMPARE(eventItem1->eventList.size(), 5);
+ QCOMPARE_EVENT(3, Event::MouseDestination, QEvent::MouseButtonRelease, Qt::TouchPointReleased, NoGrab);
+ QCOMPARE_EVENT(4, Event::MouseDestination, QEvent::UngrabMouse, Qt::TouchPointReleased, QQuickEventPoint::UngrabExclusive);
+ eventItem1->eventList.clear();
+
+ // wait to avoid getting a double click event
+ QTest::qWait(qApp->styleHints()->mouseDoubleClickInterval() + 10);
+
+ // Grab pointer events
+ eventItem1->acceptMouse = false;
+ eventItem1->acceptPointer = true;
+ eventItem1->grabPointer = true;
+ p1 = QPoint(20, 20);
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_COMPARE(eventItem1->eventList.size(), 3);
+ QCOMPARE_EVENT(0, Event::HandlerDestination, QEvent::None, Qt::TouchPointPressed, QQuickEventPoint::GrabExclusive);
+ QCOMPARE_EVENT(1, Event::HandlerDestination, QEvent::Pointer, Qt::TouchPointPressed, QQuickEventPoint::GrabExclusive);
+ QCOMPARE_EVENT(2, Event::MouseDestination, QEvent::MouseButtonPress, Qt::TouchPointPressed, 0);
+ p1 += QPoint(10, 0);
+ QTest::mouseMove(window, p1);
+ QCOMPARE(eventItem1->eventList.size(), 4);
+ QCOMPARE_EVENT(3, Event::HandlerDestination, QEvent::Pointer, Qt::TouchPointMoved, QQuickEventPoint::GrabExclusive);
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QCOMPARE(eventItem1->eventList.size(), 6);
+ QCOMPARE_EVENT(4, Event::HandlerDestination, QEvent::Pointer, Qt::TouchPointReleased, QQuickEventPoint::GrabExclusive);
+ QCOMPARE_EVENT(5, Event::HandlerDestination, QEvent::None, Qt::TouchPointReleased, QQuickEventPoint::UngrabExclusive);
+ eventItem1->eventList.clear();
+}
+
+void tst_PointerHandlers::touchReleaseOutside_data()
+{
+ QTest::addColumn<bool>("acceptPointer");
+ QTest::addColumn<bool>("grabPointer");
+ QTest::addColumn<int>("eventCount");
+ QTest::addColumn<int>("endIndexToTest");
+ QTest::addColumn<int>("endDestination"); // Event::Destination
+ QTest::addColumn<int>("endType"); // QEvent::Type
+ QTest::addColumn<int>("endState"); // Qt::TouchPointState
+ QTest::addColumn<int>("endGrabState"); // Qt::TouchPointState
+
+ QTest::newRow("reject and ignore") << false << false << 6 << 5 << (int)Event::TouchDestination
+ << (int)QEvent::TouchEnd << (int)Qt::TouchPointReleased << (int)NoGrab;
+ QTest::newRow("reject and grab") << false << true << 5 << 4 << (int)Event::HandlerDestination
+ << (int)QEvent::None << (int)Qt::TouchPointReleased << (int)QQuickEventPoint::UngrabExclusive;
+ QTest::newRow("accept and ignore") << true << false << 1 << 0 << (int)Event::HandlerDestination
+ << (int)QEvent::Pointer << (int)Qt::TouchPointPressed << (int)NoGrab;
+ QTest::newRow("accept and grab") << true << true << 5 << 4 << (int)Event::HandlerDestination
+ << (int)QEvent::None << (int)Qt::TouchPointReleased << (int)QQuickEventPoint::UngrabExclusive;
+}
+
+void tst_PointerHandlers::touchReleaseOutside()
+{
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "singleitem.qml");
+ QQuickView * window = windowPtr.data();
+
+ QFETCH(bool, acceptPointer);
+ QFETCH(bool, grabPointer);
+ QFETCH(int, eventCount);
+ QFETCH(int, endIndexToTest);
+ QFETCH(int, endDestination);
+ QFETCH(int, endType);
+ QFETCH(int, endState);
+ QFETCH(int, endGrabState);
+
+ EventItem *eventItem1 = window->rootObject()->findChild<EventItem*>("eventItem1");
+ QVERIFY(eventItem1);
+
+ eventItem1->acceptTouch = true;
+ eventItem1->acceptPointer = acceptPointer;
+ eventItem1->grabPointer = grabPointer;
+
+ QPoint p1 = QPoint(20, 20);
+ QTest::touchEvent(window, touchDevice).press(0, p1, window);
+ QQuickTouchUtils::flush(window);
+ p1.setX(eventItem1->mapToScene(eventItem1->clipRect().bottomRight()).x() + 10);
+ QTest::touchEvent(window, touchDevice).move(0, p1, window);
+ QTest::touchEvent(window, touchDevice).release(0, p1, window);
+ QQuickTouchUtils::flush(window);
+ qCDebug(lcPointerTests) << eventItem1->eventList;
+ QCOMPARE(eventItem1->eventList.size(), eventCount);
+ QCOMPARE_EVENT(endIndexToTest, endDestination, endType, endState, endGrabState);
+}
+
+QTEST_MAIN(tst_PointerHandlers)
+
+#include "tst_qquickpointerhandler.moc"
+
diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/Button.qml b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/Button.qml
new file mode 100644
index 0000000000..0b7713bd13
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/Button.qml
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+
+Rectangle {
+ id: root
+ property alias label: label.text
+ property alias pressed: tap.pressed
+ property bool checked: false
+ property alias gesturePolicy: tap.gesturePolicy
+ signal tapped
+
+ width: label.implicitWidth * 1.5; height: label.implicitHeight * 2.0
+ border.color: "#9f9d9a"; border.width: 1; radius: height / 4; antialiasing: true
+
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: tap.pressed ? "#b8b5b2" : "#efebe7" }
+ GradientStop { position: 1.0; color: "#b8b5b2" }
+ }
+
+ TapHandler {
+ id: tap
+ objectName: label.text
+ longPressThreshold: 100 // CI can be insanely slow, so don't demand a timely release to generate onTapped
+ onTapped: {
+ tapFlash.start()
+ root.tapped()
+ }
+ }
+
+ Text {
+ id: label
+ font.pointSize: 14
+ text: "Button"
+ anchors.centerIn: parent
+ }
+
+ Rectangle {
+ anchors.fill: parent
+ color: "transparent"
+ border.width: 2; radius: root.radius; antialiasing: true
+ opacity: tapFlash.running ? 1 : 0
+ FlashAnimation on visible { id: tapFlash }
+ }
+
+ Rectangle {
+ objectName: "expandingCircle"
+ radius: tap.timeHeld * 100
+ visible: radius > 0 && tap.pressed
+ border.width: 3
+ border.color: "blue"
+ color: "transparent"
+ width: radius * 2
+ height: radius * 2
+ x: tap.point.scenePressPosition.x - radius
+ y: tap.point.scenePressPosition.y - radius
+ opacity: 0.25
+ Component.onCompleted: parent = root.parent
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/FlashAnimation.qml b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/FlashAnimation.qml
new file mode 100644
index 0000000000..158a02b7a6
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/FlashAnimation.qml
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+SequentialAnimation {
+ id: tapFlash
+ running: false
+ PropertyAction { value: false }
+ PauseAnimation { duration: 100 }
+ PropertyAction { value: true }
+ PauseAnimation { duration: 100 }
+ PropertyAction { value: false }
+ PauseAnimation { duration: 100 }
+ PropertyAction { value: true }
+ PauseAnimation { duration: 100 }
+ PropertyAction { value: false }
+ PauseAnimation { duration: 100 }
+ PropertyAction { value: true }
+}
diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/buttonOverrideHandler.qml b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/buttonOverrideHandler.qml
new file mode 100644
index 0000000000..219d4a70a8
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/buttonOverrideHandler.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import Qt.labs.handlers 1.0
+
+Item {
+ width: 320
+ height: 240
+ Button {
+ id: button
+ objectName: "Overridden"
+ label: "Overridden"
+ x: 10; y: 10; width: parent.width - 20; height: 40
+ TapHandler {
+ gesturePolicy: TapHandler.ReleaseWithinBounds
+ objectName: "override"
+ onTapped: button.tapped()
+ }
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/data/buttons.qml b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/buttons.qml
new file mode 100644
index 0000000000..1df9bb9b96
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/data/buttons.qml
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import Qt.labs.handlers 1.0
+
+Item {
+ width: 320
+ height: 240
+ Button {
+ objectName: "DragThreshold"
+ label: "DragThreshold"
+ x: 10; y: 10; width: parent.width - 20; height: 40
+ gesturePolicy: TapHandler.DragThreshold
+ }
+ Button {
+ objectName: "WithinBounds"
+ label: "WithinBounds"
+ x: 10; y: 60; width: parent.width - 20; height: 40
+ gesturePolicy: TapHandler.WithinBounds
+ }
+ Button {
+ objectName: "ReleaseWithinBounds"
+ label: "ReleaseWithinBounds"
+ x: 10; y: 110; width: parent.width - 20; height: 40
+ gesturePolicy: TapHandler.ReleaseWithinBounds
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/qquicktaphandler.pro b/tests/auto/quick/pointerhandlers/qquicktaphandler/qquicktaphandler.pro
new file mode 100644
index 0000000000..b41a94b55e
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/qquicktaphandler.pro
@@ -0,0 +1,16 @@
+CONFIG += testcase
+
+TARGET = tst_qquicktaphandler
+QT += core-private gui-private qml-private quick-private testlib
+
+macos:CONFIG -= app_bundle
+
+SOURCES += tst_qquicktaphandler.cpp
+
+include (../../../shared/util.pri)
+include (../../shared/util.pri)
+
+TESTDATA = data/*
+
+# OTHER_FILES += data/foo.qml
+
diff --git a/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp b/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp
new file mode 100644
index 0000000000..9e3261f7b2
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquicktaphandler/tst_qquicktaphandler.cpp
@@ -0,0 +1,627 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+#include <QtGui/qstylehints.h>
+#include <QtQuick/qquickview.h>
+#include <QtQuick/qquickitem.h>
+#include <QtQuick/private/qquickpointerhandler_p.h>
+#include <QtQuick/private/qquicktaphandler_p.h>
+#include <qpa/qwindowsysteminterface.h>
+
+#include <private/qquickwindow_p.h>
+
+#include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlproperty.h>
+
+#include "../../../shared/util.h"
+#include "../../shared/viewtestutil.h"
+
+Q_LOGGING_CATEGORY(lcPointerTests, "qt.quick.pointer.tests")
+
+class tst_TapHandler : public QQmlDataTest
+{
+ Q_OBJECT
+public:
+ tst_TapHandler()
+ :touchDevice(QTest::createTouchDevice())
+ {}
+
+private slots:
+ void initTestCase();
+
+ void touchGesturePolicyDragThreshold();
+ void mouseGesturePolicyDragThreshold();
+ void touchGesturePolicyWithinBounds();
+ void mouseGesturePolicyWithinBounds();
+ void touchGesturePolicyReleaseWithinBounds();
+ void mouseGesturePolicyReleaseWithinBounds();
+ void touchMultiTap();
+ void mouseMultiTap();
+ void touchLongPress();
+ void mouseLongPress();
+ void buttonsMultiTouch();
+ void componentUserBehavioralOverride();
+
+private:
+ void createView(QScopedPointer<QQuickView> &window, const char *fileName);
+ QTouchDevice *touchDevice;
+};
+
+void tst_TapHandler::createView(QScopedPointer<QQuickView> &window, const char *fileName)
+{
+ window.reset(new QQuickView);
+ window->setSource(testFileUrl(fileName));
+ QTRY_COMPARE(window->status(), QQuickView::Ready);
+ QQuickViewTestUtil::centerOnScreen(window.data());
+ QQuickViewTestUtil::moveMouseAway(window.data());
+
+ window->show();
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
+ QVERIFY(window->rootObject() != 0);
+}
+
+void tst_TapHandler::initTestCase()
+{
+ // This test assumes that we don't get synthesized mouse events from QGuiApplication
+ qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents, false);
+
+ QQmlDataTest::initTestCase();
+}
+
+void tst_TapHandler::touchGesturePolicyDragThreshold()
+{
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "buttons.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickItem *buttonDragThreshold = window->rootObject()->findChild<QQuickItem*>("DragThreshold");
+ QVERIFY(buttonDragThreshold);
+ QSignalSpy dragThresholdTappedSpy(buttonDragThreshold, SIGNAL(tapped()));
+
+ // DragThreshold button stays pressed while touchpoint stays within dragThreshold, emits tapped on release
+ QPoint p1 = buttonDragThreshold->mapToScene(QPointF(20, 20)).toPoint();
+ QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(buttonDragThreshold->property("pressed").toBool());
+ p1 += QPoint(dragThreshold, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QVERIFY(buttonDragThreshold->property("pressed").toBool());
+ QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(!buttonDragThreshold->property("pressed").toBool());
+ QCOMPARE(dragThresholdTappedSpy.count(), 1);
+
+ // DragThreshold button is no longer pressed if touchpoint goes beyond dragThreshold
+ dragThresholdTappedSpy.clear();
+ p1 = buttonDragThreshold->mapToScene(QPointF(20, 20)).toPoint();
+ QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(buttonDragThreshold->property("pressed").toBool());
+ p1 += QPoint(dragThreshold, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QVERIFY(buttonDragThreshold->property("pressed").toBool());
+ p1 += QPoint(1, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(!buttonDragThreshold->property("pressed").toBool());
+ QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QVERIFY(!buttonDragThreshold->property("pressed").toBool());
+ QCOMPARE(dragThresholdTappedSpy.count(), 0);
+}
+
+void tst_TapHandler::mouseGesturePolicyDragThreshold()
+{
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "buttons.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickItem *buttonDragThreshold = window->rootObject()->findChild<QQuickItem*>("DragThreshold");
+ QVERIFY(buttonDragThreshold);
+ QSignalSpy dragThresholdTappedSpy(buttonDragThreshold, SIGNAL(tapped()));
+
+ // DragThreshold button stays pressed while mouse stays within dragThreshold, emits tapped on release
+ QPoint p1 = buttonDragThreshold->mapToScene(QPointF(20, 20)).toPoint();
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(buttonDragThreshold->property("pressed").toBool());
+ p1 += QPoint(dragThreshold, 0);
+ QTest::mouseMove(window, p1);
+ QVERIFY(buttonDragThreshold->property("pressed").toBool());
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(!buttonDragThreshold->property("pressed").toBool());
+ QTRY_COMPARE(dragThresholdTappedSpy.count(), 1);
+
+ // DragThreshold button is no longer pressed if mouse goes beyond dragThreshold
+ dragThresholdTappedSpy.clear();
+ p1 = buttonDragThreshold->mapToScene(QPointF(20, 20)).toPoint();
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(buttonDragThreshold->property("pressed").toBool());
+ p1 += QPoint(dragThreshold, 0);
+ QTest::mouseMove(window, p1);
+ QVERIFY(buttonDragThreshold->property("pressed").toBool());
+ p1 += QPoint(1, 0);
+ QTest::mouseMove(window, p1);
+ QTRY_VERIFY(!buttonDragThreshold->property("pressed").toBool());
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QVERIFY(!buttonDragThreshold->property("pressed").toBool());
+ QCOMPARE(dragThresholdTappedSpy.count(), 0);
+}
+
+void tst_TapHandler::touchGesturePolicyWithinBounds()
+{
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "buttons.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickItem *buttonWithinBounds = window->rootObject()->findChild<QQuickItem*>("WithinBounds");
+ QVERIFY(buttonWithinBounds);
+ QSignalSpy withinBoundsTappedSpy(buttonWithinBounds, SIGNAL(tapped()));
+
+ // WithinBounds button stays pressed while touchpoint stays within bounds, emits tapped on release
+ QPoint p1 = buttonWithinBounds->mapToScene(QPointF(20, 20)).toPoint();
+ QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(buttonWithinBounds->property("pressed").toBool());
+ p1 += QPoint(50, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QVERIFY(buttonWithinBounds->property("pressed").toBool());
+ QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(!buttonWithinBounds->property("pressed").toBool());
+ QCOMPARE(withinBoundsTappedSpy.count(), 1);
+
+ // WithinBounds button is no longer pressed if touchpoint leaves bounds
+ withinBoundsTappedSpy.clear();
+ p1 = buttonWithinBounds->mapToScene(QPointF(20, 20)).toPoint();
+ QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(buttonWithinBounds->property("pressed").toBool());
+ p1 += QPoint(0, 100);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(!buttonWithinBounds->property("pressed").toBool());
+ QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QVERIFY(!buttonWithinBounds->property("pressed").toBool());
+ QCOMPARE(withinBoundsTappedSpy.count(), 0);
+}
+
+void tst_TapHandler::mouseGesturePolicyWithinBounds()
+{
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "buttons.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickItem *buttonWithinBounds = window->rootObject()->findChild<QQuickItem*>("WithinBounds");
+ QVERIFY(buttonWithinBounds);
+ QSignalSpy withinBoundsTappedSpy(buttonWithinBounds, SIGNAL(tapped()));
+
+ // WithinBounds button stays pressed while touchpoint stays within bounds, emits tapped on release
+ QPoint p1 = buttonWithinBounds->mapToScene(QPointF(20, 20)).toPoint();
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(buttonWithinBounds->property("pressed").toBool());
+ p1 += QPoint(50, 0);
+ QTest::mouseMove(window, p1);
+ QVERIFY(buttonWithinBounds->property("pressed").toBool());
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(!buttonWithinBounds->property("pressed").toBool());
+ QCOMPARE(withinBoundsTappedSpy.count(), 1);
+
+ // WithinBounds button is no longer pressed if touchpoint leaves bounds
+ withinBoundsTappedSpy.clear();
+ p1 = buttonWithinBounds->mapToScene(QPointF(20, 20)).toPoint();
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(buttonWithinBounds->property("pressed").toBool());
+ p1 += QPoint(0, 100);
+ QTest::mouseMove(window, p1);
+ QTRY_VERIFY(!buttonWithinBounds->property("pressed").toBool());
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QVERIFY(!buttonWithinBounds->property("pressed").toBool());
+ QCOMPARE(withinBoundsTappedSpy.count(), 0);
+}
+
+void tst_TapHandler::touchGesturePolicyReleaseWithinBounds()
+{
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "buttons.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickItem *buttonReleaseWithinBounds = window->rootObject()->findChild<QQuickItem*>("ReleaseWithinBounds");
+ QVERIFY(buttonReleaseWithinBounds);
+ QSignalSpy releaseWithinBoundsTappedSpy(buttonReleaseWithinBounds, SIGNAL(tapped()));
+
+ // ReleaseWithinBounds button stays pressed while touchpoint wanders anywhere,
+ // then if it comes back within bounds, emits tapped on release
+ QPoint p1 = buttonReleaseWithinBounds->mapToScene(QPointF(20, 20)).toPoint();
+ QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(buttonReleaseWithinBounds->property("pressed").toBool());
+ p1 += QPoint(50, 0);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QVERIFY(buttonReleaseWithinBounds->property("pressed").toBool());
+ p1 += QPoint(250, 100);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QVERIFY(buttonReleaseWithinBounds->property("pressed").toBool());
+ p1 = buttonReleaseWithinBounds->mapToScene(QPointF(25, 15)).toPoint();
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QVERIFY(buttonReleaseWithinBounds->property("pressed").toBool());
+ QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(!buttonReleaseWithinBounds->property("pressed").toBool());
+ QCOMPARE(releaseWithinBoundsTappedSpy.count(), 1);
+
+ // ReleaseWithinBounds button does not emit tapped if released out of bounds
+ releaseWithinBoundsTappedSpy.clear();
+ p1 = buttonReleaseWithinBounds->mapToScene(QPointF(20, 20)).toPoint();
+ QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(buttonReleaseWithinBounds->property("pressed").toBool());
+ p1 += QPoint(0, 100);
+ QTest::touchEvent(window, touchDevice).move(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QVERIFY(buttonReleaseWithinBounds->property("pressed").toBool());
+ QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(!buttonReleaseWithinBounds->property("pressed").toBool());
+ QCOMPARE(releaseWithinBoundsTappedSpy.count(), 0);
+}
+
+void tst_TapHandler::mouseGesturePolicyReleaseWithinBounds()
+{
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "buttons.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickItem *buttonReleaseWithinBounds = window->rootObject()->findChild<QQuickItem*>("ReleaseWithinBounds");
+ QVERIFY(buttonReleaseWithinBounds);
+ QSignalSpy releaseWithinBoundsTappedSpy(buttonReleaseWithinBounds, SIGNAL(tapped()));
+
+ // ReleaseWithinBounds button stays pressed while touchpoint wanders anywhere,
+ // then if it comes back within bounds, emits tapped on release
+ QPoint p1 = buttonReleaseWithinBounds->mapToScene(QPointF(20, 20)).toPoint();
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(buttonReleaseWithinBounds->property("pressed").toBool());
+ p1 += QPoint(50, 0);
+ QTest::mouseMove(window, p1);
+ QVERIFY(buttonReleaseWithinBounds->property("pressed").toBool());
+ p1 += QPoint(250, 100);
+ QTest::mouseMove(window, p1);
+ QVERIFY(buttonReleaseWithinBounds->property("pressed").toBool());
+ p1 = buttonReleaseWithinBounds->mapToScene(QPointF(25, 15)).toPoint();
+ QTest::mouseMove(window, p1);
+ QVERIFY(buttonReleaseWithinBounds->property("pressed").toBool());
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(!buttonReleaseWithinBounds->property("pressed").toBool());
+ QCOMPARE(releaseWithinBoundsTappedSpy.count(), 1);
+
+ // ReleaseWithinBounds button does not emit tapped if released out of bounds
+ releaseWithinBoundsTappedSpy.clear();
+ p1 = buttonReleaseWithinBounds->mapToScene(QPointF(20, 20)).toPoint();
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(buttonReleaseWithinBounds->property("pressed").toBool());
+ p1 += QPoint(0, 100);
+ QTest::mouseMove(window, p1);
+ QVERIFY(buttonReleaseWithinBounds->property("pressed").toBool());
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(!buttonReleaseWithinBounds->property("pressed").toBool());
+ QCOMPARE(releaseWithinBoundsTappedSpy.count(), 0);
+}
+
+void tst_TapHandler::touchMultiTap()
+{
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "buttons.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickItem *button = window->rootObject()->findChild<QQuickItem*>("DragThreshold");
+ QVERIFY(button);
+ QSignalSpy tappedSpy(button, SIGNAL(tapped()));
+
+ // Tap once
+ QPoint p1 = button->mapToScene(QPointF(2, 2)).toPoint();
+ QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(button->property("pressed").toBool());
+ QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(!button->property("pressed").toBool());
+ QCOMPARE(tappedSpy.count(), 1);
+
+ // Tap again in exactly the same place (not likely with touch in the real world)
+ QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(button->property("pressed").toBool());
+ QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(!button->property("pressed").toBool());
+ QCOMPARE(tappedSpy.count(), 2);
+
+ // Tap a third time, nearby
+ p1 += QPoint(dragThreshold, dragThreshold);
+ QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(button->property("pressed").toBool());
+ QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(!button->property("pressed").toBool());
+ QCOMPARE(tappedSpy.count(), 3);
+
+ // Tap a fourth time, drifting farther away
+ p1 += QPoint(dragThreshold, dragThreshold);
+ QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(button->property("pressed").toBool());
+ QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(!button->property("pressed").toBool());
+ QCOMPARE(tappedSpy.count(), 4);
+}
+
+void tst_TapHandler::mouseMultiTap()
+{
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "buttons.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickItem *button = window->rootObject()->findChild<QQuickItem*>("DragThreshold");
+ QVERIFY(button);
+ QSignalSpy tappedSpy(button, SIGNAL(tapped()));
+
+ // Tap once
+ QPoint p1 = button->mapToScene(QPointF(2, 2)).toPoint();
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(button->property("pressed").toBool());
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(!button->property("pressed").toBool());
+ QCOMPARE(tappedSpy.count(), 1);
+
+ // Tap again in exactly the same place (not likely with touch in the real world)
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(button->property("pressed").toBool());
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(!button->property("pressed").toBool());
+ QCOMPARE(tappedSpy.count(), 2);
+
+ // Tap a third time, nearby
+ p1 += QPoint(dragThreshold, dragThreshold);
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(button->property("pressed").toBool());
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(!button->property("pressed").toBool());
+ QCOMPARE(tappedSpy.count(), 3);
+
+ // Tap a fourth time, drifting farther away
+ p1 += QPoint(dragThreshold, dragThreshold);
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(button->property("pressed").toBool());
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(!button->property("pressed").toBool());
+ QCOMPARE(tappedSpy.count(), 4);
+}
+
+void tst_TapHandler::touchLongPress()
+{
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "buttons.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickItem *button = window->rootObject()->findChild<QQuickItem*>("DragThreshold");
+ QVERIFY(button);
+ QQuickTapHandler *tapHandler = button->findChild<QQuickTapHandler*>("DragThreshold");
+ QVERIFY(tapHandler);
+ QSignalSpy tappedSpy(button, SIGNAL(tapped()));
+ QSignalSpy longPressThresholdChangedSpy(tapHandler, SIGNAL(longPressThresholdChanged()));
+ QSignalSpy timeHeldSpy(tapHandler, SIGNAL(timeHeldChanged()));
+ QSignalSpy longPressedSpy(tapHandler, SIGNAL(longPressed()));
+
+ // Reduce the threshold so that we can get a long press quickly
+ tapHandler->setLongPressThreshold(0.5);
+ QCOMPARE(longPressThresholdChangedSpy.count(), 1);
+
+ // Press and hold
+ QPoint p1 = button->mapToScene(button->clipRect().center()).toPoint();
+ QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(button->property("pressed").toBool());
+ QTRY_COMPARE(longPressedSpy.count(), 1);
+ timeHeldSpy.wait(); // the longer we hold it, the more this will occur
+ qDebug() << "held" << tapHandler->timeHeld() << "secs; timeHeld updated" << timeHeldSpy.count() << "times";
+ QVERIFY(timeHeldSpy.count() > 0);
+ QVERIFY(tapHandler->timeHeld() > 0.4); // Should be > 0.5 but slow CI and timer granularity can interfere
+
+ // Release and verify that tapped was not emitted
+ QTest::touchEvent(window, touchDevice).release(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(!button->property("pressed").toBool());
+ QCOMPARE(tappedSpy.count(), 0);
+}
+
+void tst_TapHandler::mouseLongPress()
+{
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "buttons.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickItem *button = window->rootObject()->findChild<QQuickItem*>("DragThreshold");
+ QVERIFY(button);
+ QQuickTapHandler *tapHandler = button->findChild<QQuickTapHandler*>("DragThreshold");
+ QVERIFY(tapHandler);
+ QSignalSpy tappedSpy(button, SIGNAL(tapped()));
+ QSignalSpy longPressThresholdChangedSpy(tapHandler, SIGNAL(longPressThresholdChanged()));
+ QSignalSpy timeHeldSpy(tapHandler, SIGNAL(timeHeldChanged()));
+ QSignalSpy longPressedSpy(tapHandler, SIGNAL(longPressed()));
+
+ // Reduce the threshold so that we can get a long press quickly
+ tapHandler->setLongPressThreshold(0.5);
+ QCOMPARE(longPressThresholdChangedSpy.count(), 1);
+
+ // Press and hold
+ QPoint p1 = button->mapToScene(button->clipRect().center()).toPoint();
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(button->property("pressed").toBool());
+ QTRY_COMPARE(longPressedSpy.count(), 1);
+ timeHeldSpy.wait(); // the longer we hold it, the more this will occur
+ qDebug() << "held" << tapHandler->timeHeld() << "secs; timeHeld updated" << timeHeldSpy.count() << "times";
+ QVERIFY(timeHeldSpy.count() > 0);
+ QVERIFY(tapHandler->timeHeld() > 0.4); // Should be > 0.5 but slow CI and timer granularity can interfere
+
+ // Release and verify that tapped was not emitted
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1, 500);
+ QTRY_VERIFY(!button->property("pressed").toBool());
+ QCOMPARE(tappedSpy.count(), 0);
+}
+
+void tst_TapHandler::buttonsMultiTouch()
+{
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "buttons.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickItem *buttonDragThreshold = window->rootObject()->findChild<QQuickItem*>("DragThreshold");
+ QVERIFY(buttonDragThreshold);
+ QSignalSpy dragThresholdTappedSpy(buttonDragThreshold, SIGNAL(tapped()));
+
+ QQuickItem *buttonWithinBounds = window->rootObject()->findChild<QQuickItem*>("WithinBounds");
+ QVERIFY(buttonWithinBounds);
+ QSignalSpy withinBoundsTappedSpy(buttonWithinBounds, SIGNAL(tapped()));
+
+ QQuickItem *buttonReleaseWithinBounds = window->rootObject()->findChild<QQuickItem*>("ReleaseWithinBounds");
+ QVERIFY(buttonReleaseWithinBounds);
+ QSignalSpy releaseWithinBoundsTappedSpy(buttonReleaseWithinBounds, SIGNAL(tapped()));
+
+ // can press multiple buttons at the same time
+ QPoint p1 = buttonDragThreshold->mapToScene(QPointF(20, 20)).toPoint();
+ QTest::touchEvent(window, touchDevice).press(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(buttonDragThreshold->property("pressed").toBool());
+ QPoint p2 = buttonWithinBounds->mapToScene(QPointF(20, 20)).toPoint();
+ QTest::touchEvent(window, touchDevice).stationary(1).press(2, p2, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(buttonWithinBounds->property("pressed").toBool());
+ QPoint p3 = buttonReleaseWithinBounds->mapToScene(QPointF(20, 20)).toPoint();
+ QTest::touchEvent(window, touchDevice).stationary(1).stationary(2).press(3, p3, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(buttonReleaseWithinBounds->property("pressed").toBool());
+
+ // can release top button and press again: others stay pressed the whole time
+ QTest::touchEvent(window, touchDevice).stationary(2).stationary(3).release(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(!buttonDragThreshold->property("pressed").toBool());
+ QCOMPARE(dragThresholdTappedSpy.count(), 1);
+ QVERIFY(buttonWithinBounds->property("pressed").toBool());
+ QCOMPARE(withinBoundsTappedSpy.count(), 0);
+ QVERIFY(buttonReleaseWithinBounds->property("pressed").toBool());
+ QCOMPARE(releaseWithinBoundsTappedSpy.count(), 0);
+ QTest::touchEvent(window, touchDevice).stationary(2).stationary(3).press(1, p1, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(buttonDragThreshold->property("pressed").toBool());
+ QVERIFY(buttonWithinBounds->property("pressed").toBool());
+ QVERIFY(buttonReleaseWithinBounds->property("pressed").toBool());
+
+ // can release middle button and press again: others stay pressed the whole time
+ QTest::touchEvent(window, touchDevice).stationary(1).stationary(3).release(2, p2, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(!buttonWithinBounds->property("pressed").toBool());
+ QCOMPARE(withinBoundsTappedSpy.count(), 1);
+ QVERIFY(buttonDragThreshold->property("pressed").toBool());
+ QCOMPARE(dragThresholdTappedSpy.count(), 1);
+ QVERIFY(buttonReleaseWithinBounds->property("pressed").toBool());
+ QCOMPARE(releaseWithinBoundsTappedSpy.count(), 0);
+ QTest::touchEvent(window, touchDevice).stationary(1).stationary(3).press(2, p2, window);
+ QQuickTouchUtils::flush(window);
+ QVERIFY(buttonDragThreshold->property("pressed").toBool());
+ QVERIFY(buttonWithinBounds->property("pressed").toBool());
+ QVERIFY(buttonReleaseWithinBounds->property("pressed").toBool());
+
+ // can release bottom button and press again: others stay pressed the whole time
+ QTest::touchEvent(window, touchDevice).stationary(1).stationary(2).release(3, p3, window);
+ QQuickTouchUtils::flush(window);
+ QCOMPARE(releaseWithinBoundsTappedSpy.count(), 1);
+ QVERIFY(buttonWithinBounds->property("pressed").toBool());
+ QCOMPARE(withinBoundsTappedSpy.count(), 1);
+ QVERIFY(!buttonReleaseWithinBounds->property("pressed").toBool());
+ QCOMPARE(dragThresholdTappedSpy.count(), 1);
+ QTest::touchEvent(window, touchDevice).stationary(1).stationary(2).press(3, p3, window);
+ QQuickTouchUtils::flush(window);
+ QTRY_VERIFY(buttonDragThreshold->property("pressed").toBool());
+ QVERIFY(buttonWithinBounds->property("pressed").toBool());
+ QVERIFY(buttonReleaseWithinBounds->property("pressed").toBool());
+}
+
+void tst_TapHandler::componentUserBehavioralOverride()
+{
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "buttonOverrideHandler.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickItem *button = window->rootObject()->findChild<QQuickItem*>("Overridden");
+ QVERIFY(button);
+ QQuickTapHandler *innerTapHandler = button->findChild<QQuickTapHandler*>("Overridden");
+ QVERIFY(innerTapHandler);
+ QQuickTapHandler *userTapHandler = button->findChild<QQuickTapHandler*>("override");
+ QVERIFY(userTapHandler);
+ QSignalSpy tappedSpy(button, SIGNAL(tapped()));
+ QSignalSpy innerGrabChangedSpy(innerTapHandler, SIGNAL(grabChanged(QQuickEventPoint *)));
+ QSignalSpy userGrabChangedSpy(userTapHandler, SIGNAL(grabChanged(QQuickEventPoint *)));
+ QSignalSpy innerPressedChangedSpy(innerTapHandler, SIGNAL(pressedChanged()));
+ QSignalSpy userPressedChangedSpy(userTapHandler, SIGNAL(pressedChanged()));
+
+ // Press
+ QPoint p1 = button->mapToScene(button->clipRect().center()).toPoint();
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_COMPARE(userPressedChangedSpy.count(), 1);
+ QCOMPARE(innerPressedChangedSpy.count(), 0);
+ QCOMPARE(innerGrabChangedSpy.count(), 0);
+ QCOMPARE(userGrabChangedSpy.count(), 1);
+
+ // Release
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_COMPARE(userPressedChangedSpy.count(), 2);
+ QCOMPARE(innerPressedChangedSpy.count(), 0);
+ QCOMPARE(tappedSpy.count(), 1); // only because the override handler makes that happen
+ QCOMPARE(innerGrabChangedSpy.count(), 0);
+ QCOMPARE(userGrabChangedSpy.count(), 2);
+}
+
+QTEST_MAIN(tst_TapHandler)
+
+#include "tst_qquicktaphandler.moc"
+
diff --git a/tests/auto/quick/qquickanimatedsprite/BLACKLIST b/tests/auto/quick/qquickanimatedsprite/BLACKLIST
new file mode 100644
index 0000000000..7eb242876a
--- /dev/null
+++ b/tests/auto/quick/qquickanimatedsprite/BLACKLIST
@@ -0,0 +1,3 @@
+# QTBUG-65613
+[test_largeAnimation]
+b2qt
diff --git a/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp b/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp
index 820c804065..dcb0e01b5d 100644
--- a/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp
+++ b/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp
@@ -292,7 +292,7 @@ class KillerThread : public QThread
{
Q_OBJECT
protected:
- void run() Q_DECL_OVERRIDE {
+ void run() override {
sleep(3);
qFatal("Either the GUI or the render thread is stuck in an infinite loop.");
}
diff --git a/tests/auto/quick/qquickanimations/BLACKLIST b/tests/auto/quick/qquickanimations/BLACKLIST
index e45c141d17..e011db46b7 100644
--- a/tests/auto/quick/qquickanimations/BLACKLIST
+++ b/tests/auto/quick/qquickanimations/BLACKLIST
@@ -1,40 +1,6 @@
# QTBUG-45466 QTBUG-29062
[simpleProperty]
osx-10.9 developer-build
-[badTypes]
-windows msvc-2010 32bit developer-build
-[mixedTypes]
-windows msvc-2010 32bit developer-build
-[properties]
-windows msvc-2010 32bit developer-build
-[propertiesTransition]
-windows msvc-2010 32bit developer-build
-[pathTransition]
-windows msvc-2010 32bit developer-build
-[disabledTransition]
-windows msvc-2010 32bit developer-build
-[rotation]
-windows msvc-2010 32bit developer-build
-[startStopSignals]
-windows msvc-2010 32bit developer-build
-[runningTrueBug]
-windows msvc-2010 32bit developer-build
-[nonTransitionBug]
-windows msvc-2010 32bit developer-build
-[registrationBug]
-windows msvc-2010 32bit developer-build
-[alwaysRunToEndRestartBug]
-windows msvc-2010 32bit developer-build
-[loopingBug]
-windows msvc-2010 32bit developer-build
-[pathAnimationInOutBackBug]
-windows msvc-2010 32bit developer-build
-[reparent]
-windows msvc-2012 64bit developer-build
-windows msvc-2010 32bit developer-build
-[simpleAnchor]
-windows msvc-2010 32bit developer-build
[simplePath]
windows gcc developer-build
-windows msvc-2010 32bit developer-build
diff --git a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
index 4a7a77416a..d28d065d17 100644
--- a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
+++ b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
@@ -120,12 +120,16 @@ void tst_qquickanimations::simpleProperty()
{
QQuickRectangle rect;
QQuickPropertyAnimation animation;
+ QSignalSpy fromChangedSpy(&animation, &QQuickPropertyAnimation::fromChanged);
+ QSignalSpy toChangedSpy(&animation, &QQuickPropertyAnimation::toChanged);
animation.setTargetObject(&rect);
animation.setProperty("x");
animation.setTo(200);
QCOMPARE(animation.target(), &rect);
QCOMPARE(animation.property(), QLatin1String("x"));
QCOMPARE(animation.to().toReal(), 200.0);
+ QCOMPARE(fromChangedSpy.count(), 0);
+ QCOMPARE(toChangedSpy.count(), 1);
animation.start();
QVERIFY(animation.isRunning());
QTest::qWait(animation.duration());
@@ -139,18 +143,25 @@ void tst_qquickanimations::simpleProperty()
animation.setCurrentTime(125);
QCOMPARE(animation.currentTime(), 125);
QCOMPARE(rect.x(),100.0);
+ animation.setFrom(100);
+ QCOMPARE(fromChangedSpy.count(), 1);
+ QCOMPARE(toChangedSpy.count(), 1);
}
void tst_qquickanimations::simpleNumber()
{
QQuickRectangle rect;
QQuickNumberAnimation animation;
+ QSignalSpy fromChangedSpy(&animation, &QQuickNumberAnimation::fromChanged);
+ QSignalSpy toChangedSpy(&animation, &QQuickNumberAnimation::toChanged);
animation.setTargetObject(&rect);
animation.setProperty("x");
animation.setTo(200);
QCOMPARE(animation.target(), &rect);
QCOMPARE(animation.property(), QLatin1String("x"));
QCOMPARE(animation.to(), qreal(200));
+ QCOMPARE(fromChangedSpy.count(), 0);
+ QCOMPARE(toChangedSpy.count(), 1);
animation.start();
QVERIFY(animation.isRunning());
QTest::qWait(animation.duration());
@@ -164,18 +175,25 @@ void tst_qquickanimations::simpleNumber()
animation.setCurrentTime(125);
QCOMPARE(animation.currentTime(), 125);
QCOMPARE(rect.x(), qreal(100));
+ animation.setFrom(100);
+ QCOMPARE(fromChangedSpy.count(), 1);
+ QCOMPARE(toChangedSpy.count(), 1);
}
void tst_qquickanimations::simpleColor()
{
QQuickRectangle rect;
QQuickColorAnimation animation;
+ QSignalSpy fromChangedSpy(&animation, &QQuickColorAnimation::fromChanged);
+ QSignalSpy toChangedSpy(&animation, &QQuickColorAnimation::toChanged);
animation.setTargetObject(&rect);
animation.setProperty("color");
animation.setTo(QColor("red"));
QCOMPARE(animation.target(), &rect);
QCOMPARE(animation.property(), QLatin1String("color"));
QCOMPARE(animation.to(), QColor("red"));
+ QCOMPARE(fromChangedSpy.count(), 0);
+ QCOMPARE(toChangedSpy.count(), 1);
animation.start();
QVERIFY(animation.isRunning());
QTest::qWait(animation.duration());
@@ -193,6 +211,8 @@ void tst_qquickanimations::simpleColor()
rect.setColor(QColor("green"));
animation.setFrom(QColor("blue"));
QCOMPARE(animation.from(), QColor("blue"));
+ QCOMPARE(fromChangedSpy.count(), 1);
+ QCOMPARE(toChangedSpy.count(), 1);
animation.restart();
QCOMPARE(rect.color(), QColor("blue"));
QVERIFY(animation.isRunning());
@@ -204,6 +224,8 @@ void tst_qquickanimations::simpleRotation()
{
QQuickRectangle rect;
QQuickRotationAnimation animation;
+ QSignalSpy fromChangedSpy(&animation, &QQuickRotationAnimation::fromChanged);
+ QSignalSpy toChangedSpy(&animation, &QQuickRotationAnimation::toChanged);
animation.setTargetObject(&rect);
animation.setProperty("rotation");
animation.setTo(270);
@@ -211,6 +233,8 @@ void tst_qquickanimations::simpleRotation()
QCOMPARE(animation.property(), QLatin1String("rotation"));
QCOMPARE(animation.to(), qreal(270));
QCOMPARE(animation.direction(), QQuickRotationAnimation::Numerical);
+ QCOMPARE(fromChangedSpy.count(), 0);
+ QCOMPARE(toChangedSpy.count(), 1);
animation.start();
QVERIFY(animation.isRunning());
QTest::qWait(animation.duration());
@@ -224,6 +248,9 @@ void tst_qquickanimations::simpleRotation()
animation.setCurrentTime(125);
QCOMPARE(animation.currentTime(), 125);
QCOMPARE(rect.rotation(), qreal(135));
+ animation.setFrom(90);
+ QCOMPARE(fromChangedSpy.count(), 1);
+ QCOMPARE(toChangedSpy.count(), 1);
}
void tst_qquickanimations::simplePath()
diff --git a/tests/auto/quick/qquickapplication/data/tst_platformname.qml b/tests/auto/quick/qquickapplication/data/tst_platformname.qml
new file mode 100644
index 0000000000..1bcd66ac8d
--- /dev/null
+++ b/tests/auto/quick/qquickapplication/data/tst_platformname.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.0;
+
+Item {
+ id: root;
+ property string platformName: Qt.platform.pluginName
+}
diff --git a/tests/auto/quick/qquickapplication/qquickapplication.pro b/tests/auto/quick/qquickapplication/qquickapplication.pro
index c47f5472b7..00b5bb3a18 100644
--- a/tests/auto/quick/qquickapplication/qquickapplication.pro
+++ b/tests/auto/quick/qquickapplication/qquickapplication.pro
@@ -3,7 +3,8 @@ TARGET = tst_qquickapplication
macx:CONFIG -= app_bundle
SOURCES += tst_qquickapplication.cpp
-OTHER_FILES += data/tst_displayname.qml
+OTHER_FILES += data/tst_displayname.qml \
+ data/tst_platformname.qml
include (../../shared/util.pri)
diff --git a/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp b/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp
index d780b91260..89b7924618 100644
--- a/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp
+++ b/tests/auto/quick/qquickapplication/tst_qquickapplication.cpp
@@ -53,6 +53,7 @@ private slots:
void styleHints();
void cleanup();
void displayName();
+ void platformName();
private:
QQmlEngine engine;
@@ -66,7 +67,7 @@ void tst_qquickapplication::cleanup()
{
if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ApplicationState)) {
QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive);
- QTest::waitForEvents();
+ QCoreApplication::processEvents();
}
}
@@ -264,6 +265,24 @@ void tst_qquickapplication::displayName()
QCOMPARE(QGuiApplication::applicationDisplayName(), name[2]);
}
+void tst_qquickapplication::platformName()
+{
+ // Set up QML component
+ QQmlComponent component(&engine, testFileUrl("tst_platformname.qml"));
+ QQuickItem *item = qobject_cast<QQuickItem *>(component.create());
+ QVERIFY(item);
+ QQuickView view;
+ item->setParentItem(view.rootObject());
+
+ // Get native platform name
+ QString guiApplicationPlatformName = QGuiApplication::platformName();
+ QVERIFY(!guiApplicationPlatformName.isEmpty());
+
+ // Get platform name from QML component and verify it's same
+ QString qmlPlatformName = qvariant_cast<QString>(item->property("platformName"));
+ QCOMPARE(qmlPlatformName, guiApplicationPlatformName);
+}
+
QTEST_MAIN(tst_qquickapplication)
#include "tst_qquickapplication.moc"
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml b/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml
index 565f906fb1..8238d87313 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml
@@ -151,9 +151,11 @@ CanvasTestCase {
{mimeType:"image/bmp"},
{mimeType:"image/jpeg"},
{mimeType:"image/x-portable-pixmap"},
- //{mimeType:"image/tiff"}, QTBUG-23980
{mimeType:"image/xpm"},
];
+ if (hasImageFormats)
+ imageTypes.push({ mimeType: "image/tiff" });
+
for (var i = 0; i < imageTypes.length; i++) {
ctx.fillStyle = "red";
ctx.fillRect(0, 0, c.width, c.height);
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_imagedata.qml b/tests/auto/quick/qquickcanvasitem/data/tst_imagedata.qml
index 7095602ea2..76b99a765e 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_imagedata.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_imagedata.qml
@@ -6,6 +6,10 @@ CanvasTestCase {
name: "imagedata"
function init_data() { return testData("2d"); }
function test_rounding(row) {
+ if ((Qt.platform.pluginName === "offscreen")
+ || (Qt.platform.pluginName === "minimal"))
+ skip("ctx.getImageData crashes on offscreen/minimal platforms");
+
var canvas = createCanvasObject(row);
var ctx = canvas.getContext('2d');
var size = 17
diff --git a/tests/auto/quick/qquickcanvasitem/qquickcanvasitem.pro b/tests/auto/quick/qquickcanvasitem/qquickcanvasitem.pro
index c6d2a69f8c..845128f9de 100644
--- a/tests/auto/quick/qquickcanvasitem/qquickcanvasitem.pro
+++ b/tests/auto/quick/qquickcanvasitem/qquickcanvasitem.pro
@@ -5,6 +5,8 @@ TARGET=tst_qquickcanvasitem
CONFIG += qmltestcase
SOURCES += tst_qquickcanvasitem.cpp
+exists($$[QT_INSTALL_PLUGINS]/imageformats): DEFINES += HAS_IMAGE_FORMATS
+
TESTDATA = data/*
OTHER_FILES += \
diff --git a/tests/auto/quick/qquickcanvasitem/tst_qquickcanvasitem.cpp b/tests/auto/quick/qquickcanvasitem/tst_qquickcanvasitem.cpp
index bde2b4809b..dad8df0682 100644
--- a/tests/auto/quick/qquickcanvasitem/tst_qquickcanvasitem.cpp
+++ b/tests/auto/quick/qquickcanvasitem/tst_qquickcanvasitem.cpp
@@ -26,4 +26,29 @@
**
****************************************************************************/
#include <QtQuickTest/quicktest.h>
-QUICK_TEST_MAIN(qquickcanvasitem)
+#include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlcontext.h>
+
+class Setup : public QObject
+{
+ Q_OBJECT
+
+public:
+ Setup() {}
+
+public slots:
+ void qmlEngineAvailable(QQmlEngine *engine)
+ {
+ engine->rootContext()->setContextProperty("hasImageFormats", QVariant(
+#ifdef HAS_IMAGE_FORMATS
+ true
+#else
+ false
+#endif
+ ));
+ }
+};
+
+QUICK_TEST_MAIN_WITH_SETUP(qquickcanvasitem, Setup)
+
+#include "tst_qquickcanvasitem.moc"
diff --git a/tests/auto/quick/qquickflickable/BLACKLIST b/tests/auto/quick/qquickflickable/BLACKLIST
index f35397f119..826c024732 100644
--- a/tests/auto/quick/qquickflickable/BLACKLIST
+++ b/tests/auto/quick/qquickflickable/BLACKLIST
@@ -1,7 +1,8 @@
# QTBUG-36804
osx-10.10
+# QTBUG-26696
[rebound]
-osx-10.10
+osx
[movingAndFlicking:vertical]
osx-10.10
[movingAndFlicking:both]
diff --git a/tests/auto/quick/qquickflickable/data/nestedStopAtBounds.qml b/tests/auto/quick/qquickflickable/data/nestedStopAtBounds.qml
index 81187f3c2f..902920babc 100644
--- a/tests/auto/quick/qquickflickable/data/nestedStopAtBounds.qml
+++ b/tests/auto/quick/qquickflickable/data/nestedStopAtBounds.qml
@@ -18,6 +18,8 @@ Flickable {
height: 300
color: "yellow"
+ objectName: "yellowRect"
+
Flickable {
id: inner
objectName: "innerFlickable"
@@ -30,6 +32,7 @@ Flickable {
Rectangle {
anchors.fill: parent
anchors.margins: 100
+ objectName: "blueRect"
color: "blue"
}
MouseArea {
diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
index c080dd9ac4..bdf7d3dcfd 100644
--- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
+++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
@@ -64,7 +64,13 @@ public:
, touchReleases(0)
, ungrabs(0)
, m_active(false)
- { }
+ {
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ setAcceptTouchEvents(true);
+#else
+ setAcceptedMouseButtons(Qt::LeftButton); // not really, but we want touch events
+#endif
+ }
QPointF pos() const { return m_pos; }
@@ -1340,11 +1346,6 @@ void tst_qquickflickable::flickOnRelease()
// wait for any motion to end
QTRY_VERIFY(!flickable->isMoving());
-#ifdef Q_OS_MAC
-# if QT_CONFIG(opengl)
- QEXPECT_FAIL("", "QTBUG-26094 stopping on a full pixel doesn't work on OS X", Continue);
-# endif
-#endif
// Stop on a full pixel after user interaction
QCOMPARE(flickable->contentY(), (qreal)qRound(flickable->contentY()));
}
@@ -2224,6 +2225,7 @@ Q_DECLARE_METATYPE(QQuickFlickable::BoundsBehavior)
void tst_qquickflickable::overshoot()
{
QFETCH(QQuickFlickable::BoundsBehavior, boundsBehavior);
+ QFETCH(int, boundsMovement);
QScopedPointer<QQuickView> window(new QQuickView);
window->setSource(testFileUrl("overshoot.qml"));
@@ -2240,6 +2242,7 @@ void tst_qquickflickable::overshoot()
QCOMPARE(flickable->contentHeight(), 400.0);
flickable->setBoundsBehavior(boundsBehavior);
+ flickable->setBoundsMovement(QQuickFlickable::BoundsMovement(boundsMovement));
// drag past the beginning
QTest::mousePress(window.data(), Qt::LeftButton, 0, QPoint(10, 10));
@@ -2248,23 +2251,30 @@ void tst_qquickflickable::overshoot()
QTest::mouseMove(window.data(), QPoint(40, 40));
QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(50, 50));
+ if ((boundsMovement == QQuickFlickable::FollowBoundsBehavior) && (boundsBehavior & QQuickFlickable::DragOverBounds)) {
+ QVERIFY(flickable->property("minContentX").toReal() < 0.0);
+ QVERIFY(flickable->property("minContentY").toReal() < 0.0);
+ } else {
+ QCOMPARE(flickable->property("minContentX").toReal(), 0.0);
+ QCOMPARE(flickable->property("minContentY").toReal(), 0.0);
+ }
if (boundsBehavior & QQuickFlickable::DragOverBounds) {
- QVERIFY(flickable->property("minVerticalOvershoot").toReal() < 0.0);
QVERIFY(flickable->property("minHorizontalOvershoot").toReal() < 0.0);
- QCOMPARE(flickable->property("minContentY").toReal(),
- flickable->property("minVerticalOvershoot").toReal());
- QCOMPARE(flickable->property("minContentX").toReal(),
- flickable->property("minHorizontalOvershoot").toReal());
+ QVERIFY(flickable->property("minVerticalOvershoot").toReal() < 0.0);
} else {
- QCOMPARE(flickable->property("minContentY").toReal(), 0.0);
- QCOMPARE(flickable->property("minContentX").toReal(), 0.0);
- QCOMPARE(flickable->property("minVerticalOvershoot").toReal(), 0.0);
QCOMPARE(flickable->property("minHorizontalOvershoot").toReal(), 0.0);
+ QCOMPARE(flickable->property("minVerticalOvershoot").toReal(), 0.0);
+ }
+ if (bool(boundsMovement == QQuickFlickable::FollowBoundsBehavior) == bool(boundsBehavior & QQuickFlickable::DragOverBounds)) {
+ QCOMPARE(flickable->property("minContentX").toReal(),
+ flickable->property("minHorizontalOvershoot").toReal());
+ QCOMPARE(flickable->property("minContentY").toReal(),
+ flickable->property("minVerticalOvershoot").toReal());
}
- QCOMPARE(flickable->property("maxContentY").toReal(), 0.0);
QCOMPARE(flickable->property("maxContentX").toReal(), 0.0);
- QCOMPARE(flickable->property("maxVerticalOvershoot").toReal(), 0.0);
+ QCOMPARE(flickable->property("maxContentY").toReal(), 0.0);
QCOMPARE(flickable->property("maxHorizontalOvershoot").toReal(), 0.0);
+ QCOMPARE(flickable->property("maxVerticalOvershoot").toReal(), 0.0);
flickable->setContentX(20.0);
flickable->setContentY(20.0);
@@ -2274,23 +2284,30 @@ void tst_qquickflickable::overshoot()
flick(window.data(), QPoint(10, 10), QPoint(50, 50), 100);
QTRY_VERIFY(!flickable->property("flicking").toBool());
+ if ((boundsMovement == QQuickFlickable::FollowBoundsBehavior) && (boundsBehavior & QQuickFlickable::OvershootBounds)) {
+ QVERIFY(flickable->property("minContentX").toReal() < 0.0);
+ QVERIFY(flickable->property("minContentY").toReal() < 0.0);
+ } else {
+ QCOMPARE(flickable->property("minContentX").toReal(), 0.0);
+ QCOMPARE(flickable->property("minContentY").toReal(), 0.0);
+ }
if (boundsBehavior & QQuickFlickable::OvershootBounds) {
- QVERIFY(flickable->property("minVerticalOvershoot").toReal() < 0.0);
QVERIFY(flickable->property("minHorizontalOvershoot").toReal() < 0.0);
- QCOMPARE(flickable->property("minContentY").toReal(),
- flickable->property("minVerticalOvershoot").toReal());
- QCOMPARE(flickable->property("minContentX").toReal(),
- flickable->property("minHorizontalOvershoot").toReal());
+ QVERIFY(flickable->property("minVerticalOvershoot").toReal() < 0.0);
} else {
- QCOMPARE(flickable->property("minContentY").toReal(), 0.0);
- QCOMPARE(flickable->property("minContentX").toReal(), 0.0);
- QCOMPARE(flickable->property("minVerticalOvershoot").toReal(), 0.0);
QCOMPARE(flickable->property("minHorizontalOvershoot").toReal(), 0.0);
+ QCOMPARE(flickable->property("minVerticalOvershoot").toReal(), 0.0);
+ }
+ if ((boundsMovement == QQuickFlickable::FollowBoundsBehavior) == (boundsBehavior & QQuickFlickable::OvershootBounds)) {
+ QCOMPARE(flickable->property("minContentX").toReal(),
+ flickable->property("minHorizontalOvershoot").toReal());
+ QCOMPARE(flickable->property("minContentY").toReal(),
+ flickable->property("minVerticalOvershoot").toReal());
}
- QCOMPARE(flickable->property("maxContentY").toReal(), 20.0);
QCOMPARE(flickable->property("maxContentX").toReal(), 20.0);
- QCOMPARE(flickable->property("maxVerticalOvershoot").toReal(), 0.0);
+ QCOMPARE(flickable->property("maxContentY").toReal(), 20.0);
QCOMPARE(flickable->property("maxHorizontalOvershoot").toReal(), 0.0);
+ QCOMPARE(flickable->property("maxVerticalOvershoot").toReal(), 0.0);
flickable->setContentX(200.0);
flickable->setContentY(200.0);
@@ -2303,23 +2320,30 @@ void tst_qquickflickable::overshoot()
QTest::mouseMove(window.data(), QPoint(20, 20));
QTest::mouseRelease(window.data(), Qt::LeftButton, 0, QPoint(10, 10));
+ if ((boundsMovement == QQuickFlickable::FollowBoundsBehavior) && (boundsBehavior & QQuickFlickable::DragOverBounds)) {
+ QVERIFY(flickable->property("maxContentX").toReal() > 200.0);
+ QVERIFY(flickable->property("maxContentX").toReal() > 200.0);
+ } else {
+ QCOMPARE(flickable->property("maxContentX").toReal(), 200.0);
+ QCOMPARE(flickable->property("maxContentY").toReal(), 200.0);
+ }
if (boundsBehavior & QQuickFlickable::DragOverBounds) {
- QVERIFY(flickable->property("maxVerticalOvershoot").toReal() > 0.0);
QVERIFY(flickable->property("maxHorizontalOvershoot").toReal() > 0.0);
- QCOMPARE(flickable->property("maxContentY").toReal() - 200.0,
- flickable->property("maxVerticalOvershoot").toReal());
- QCOMPARE(flickable->property("maxContentX").toReal() - 200.0,
- flickable->property("maxHorizontalOvershoot").toReal());
+ QVERIFY(flickable->property("maxVerticalOvershoot").toReal() > 0.0);
} else {
- QCOMPARE(flickable->property("maxContentY").toReal(), 200.0);
- QCOMPARE(flickable->property("maxContentX").toReal(), 200.0);
- QCOMPARE(flickable->property("maxVerticalOvershoot").toReal(), 0.0);
QCOMPARE(flickable->property("maxHorizontalOvershoot").toReal(), 0.0);
+ QCOMPARE(flickable->property("maxVerticalOvershoot").toReal(), 0.0);
+ }
+ if ((boundsMovement == QQuickFlickable::FollowBoundsBehavior) == (boundsBehavior & QQuickFlickable::DragOverBounds)) {
+ QCOMPARE(flickable->property("maxContentX").toReal() - 200.0,
+ flickable->property("maxHorizontalOvershoot").toReal());
+ QCOMPARE(flickable->property("maxContentY").toReal() - 200.0,
+ flickable->property("maxVerticalOvershoot").toReal());
}
- QCOMPARE(flickable->property("minContentY").toReal(), 200.0);
QCOMPARE(flickable->property("minContentX").toReal(), 200.0);
- QCOMPARE(flickable->property("minVerticalOvershoot").toReal(), 0.0);
+ QCOMPARE(flickable->property("minContentY").toReal(), 200.0);
QCOMPARE(flickable->property("minHorizontalOvershoot").toReal(), 0.0);
+ QCOMPARE(flickable->property("minVerticalOvershoot").toReal(), 0.0);
flickable->setContentX(180.0);
flickable->setContentY(180.0);
@@ -2329,37 +2353,59 @@ void tst_qquickflickable::overshoot()
flick(window.data(), QPoint(50, 50), QPoint(10, 10), 100);
QTRY_VERIFY(!flickable->property("flicking").toBool());
+ if ((boundsMovement == QQuickFlickable::FollowBoundsBehavior) && (boundsBehavior & QQuickFlickable::OvershootBounds)) {
+ QVERIFY(flickable->property("maxContentX").toReal() > 200.0);
+ QVERIFY(flickable->property("maxContentY").toReal() > 200.0);
+ } else {
+ QCOMPARE(flickable->property("maxContentX").toReal(), 200.0);
+ QCOMPARE(flickable->property("maxContentY").toReal(), 200.0);
+ }
if (boundsBehavior & QQuickFlickable::OvershootBounds) {
- QVERIFY(flickable->property("maxVerticalOvershoot").toReal() > 0.0);
QVERIFY(flickable->property("maxHorizontalOvershoot").toReal() > 0.0);
- QCOMPARE(flickable->property("maxContentY").toReal() - 200.0,
- flickable->property("maxVerticalOvershoot").toReal());
- QCOMPARE(flickable->property("maxContentX").toReal() - 200.0,
- flickable->property("maxHorizontalOvershoot").toReal());
+ QVERIFY(flickable->property("maxVerticalOvershoot").toReal() > 0.0);
} else {
- QCOMPARE(flickable->property("maxContentY").toReal(), 200.0);
- QCOMPARE(flickable->property("maxContentX").toReal(), 200.0);
- QCOMPARE(flickable->property("maxVerticalOvershoot").toReal(), 0.0);
QCOMPARE(flickable->property("maxHorizontalOvershoot").toReal(), 0.0);
+ QCOMPARE(flickable->property("maxVerticalOvershoot").toReal(), 0.0);
+ }
+ if ((boundsMovement == QQuickFlickable::FollowBoundsBehavior) == (boundsBehavior & QQuickFlickable::OvershootBounds)) {
+ QCOMPARE(flickable->property("maxContentX").toReal() - 200.0,
+ flickable->property("maxHorizontalOvershoot").toReal());
+ QCOMPARE(flickable->property("maxContentY").toReal() - 200.0,
+ flickable->property("maxVerticalOvershoot").toReal());
}
- QCOMPARE(flickable->property("minContentY").toReal(), 180.0);
QCOMPARE(flickable->property("minContentX").toReal(), 180.0);
- QCOMPARE(flickable->property("minVerticalOvershoot").toReal(), 0.0);
+ QCOMPARE(flickable->property("minContentY").toReal(), 180.0);
QCOMPARE(flickable->property("minHorizontalOvershoot").toReal(), 0.0);
+ QCOMPARE(flickable->property("minVerticalOvershoot").toReal(), 0.0);
}
void tst_qquickflickable::overshoot_data()
{
QTest::addColumn<QQuickFlickable::BoundsBehavior>("boundsBehavior");
-
- QTest::newRow("StopAtBounds")
- << QQuickFlickable::BoundsBehavior(QQuickFlickable::StopAtBounds);
- QTest::newRow("DragOverBounds")
- << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragOverBounds);
- QTest::newRow("OvershootBounds")
- << QQuickFlickable::BoundsBehavior(QQuickFlickable::OvershootBounds);
- QTest::newRow("DragAndOvershootBounds")
- << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragAndOvershootBounds);
+ QTest::addColumn<int>("boundsMovement");
+
+ QTest::newRow("StopAtBounds,FollowBoundsBehavior")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::StopAtBounds)
+ << int(QQuickFlickable::FollowBoundsBehavior);
+ QTest::newRow("DragOverBounds,FollowBoundsBehavior")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragOverBounds)
+ << int(QQuickFlickable::FollowBoundsBehavior);
+ QTest::newRow("OvershootBounds,FollowBoundsBehavior")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::OvershootBounds)
+ << int(QQuickFlickable::FollowBoundsBehavior);
+ QTest::newRow("DragAndOvershootBounds,FollowBoundsBehavior")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragAndOvershootBounds)
+ << int(QQuickFlickable::FollowBoundsBehavior);
+
+ QTest::newRow("DragOverBounds,StopAtBounds")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragOverBounds)
+ << int(QQuickFlickable::StopAtBounds);
+ QTest::newRow("OvershootBounds,StopAtBounds")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::OvershootBounds)
+ << int(QQuickFlickable::StopAtBounds);
+ QTest::newRow("DragAndOvershootBounds,StopAtBounds")
+ << QQuickFlickable::BoundsBehavior(QQuickFlickable::DragAndOvershootBounds)
+ << int(QQuickFlickable::StopAtBounds);
}
void tst_qquickflickable::overshoot_reentrant()
diff --git a/tests/auto/quick/qquickframebufferobject/BLACKLIST b/tests/auto/quick/qquickframebufferobject/BLACKLIST
new file mode 100644
index 0000000000..8a3d7df480
--- /dev/null
+++ b/tests/auto/quick/qquickframebufferobject/BLACKLIST
@@ -0,0 +1,7 @@
+# QTBUG-64470
+[testInvalidate)
+osx
+# QTBUG-65614
+b2qt
+[testThatStuffWorks]
+b2qt
diff --git a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
index e271cc1d7b..ce04dc3c80 100644
--- a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
+++ b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
@@ -1144,7 +1144,7 @@ void tst_QQuickGridView::removed_defaultLayout_data()
QTest::newRow("remove multiple, after visible, content not at start")
<< 2.0 // show 6-23
<< 16+4 << 5
- << 15+10 << 7
+ << 15 << 7
<< 0.0 << "Item6" << "Item10";
QTest::newRow("remove multiple, mix of items from within and after visible items")
@@ -6742,7 +6742,7 @@ void tst_QQuickGridView::QTBUG_48870_fastModelUpdates()
QQuickItemViewPrivate *priv = QQuickItemViewPrivate::get(view);
bool nonUnique;
- FxViewItem *item = Q_NULLPTR;
+ FxViewItem *item = nullptr;
int expectedIdx;
QVERIFY(testVisibleItems(priv, &nonUnique, &item, &expectedIdx));
diff --git a/tests/auto/quick/qquickimage/BLACKLIST b/tests/auto/quick/qquickimage/BLACKLIST
new file mode 100644
index 0000000000..d15fae1b67
--- /dev/null
+++ b/tests/auto/quick/qquickimage/BLACKLIST
@@ -0,0 +1,4 @@
+# QTBUG-65978
+[nullPixmapPaint]
+b2qt
+
diff --git a/tests/auto/quick/qquickimage/data/pattern.pkm b/tests/auto/quick/qquickimage/data/pattern.pkm
new file mode 100644
index 0000000000..d986e89b2d
--- /dev/null
+++ b/tests/auto/quick/qquickimage/data/pattern.pkm
Binary files differ
diff --git a/tests/auto/quick/qquickimage/tst_qquickimage.cpp b/tests/auto/quick/qquickimage/tst_qquickimage.cpp
index 115fe53430..783e4aab4c 100644
--- a/tests/auto/quick/qquickimage/tst_qquickimage.cpp
+++ b/tests/auto/quick/qquickimage/tst_qquickimage.cpp
@@ -91,6 +91,8 @@ private slots:
void sourceSizeChanges();
void correctStatus();
void highdpi();
+ void highDpiFillModesAndSizes_data();
+ void highDpiFillModesAndSizes();
void hugeImages();
private:
@@ -150,6 +152,14 @@ void tst_qquickimage::imageSource_data()
QTest::newRow("remote svgz") << "/heart.svgz" << 595.0 << 841.0 << true << false << false << "";
QTest::newRow("remote not found") << "/no-such-file.png" << 0.0 << 0.0 << true
<< false << true << "<Unknown File>:2:1: QML Image: Error transferring {{ServerBaseUrl}}/no-such-file.png - server replied: Not found";
+ QTest::newRow("extless") << testFileUrl("colors").toString() << 120.0 << 120.0 << false << false << true << "";
+ QTest::newRow("extless no cache") << testFileUrl("colors").toString() << 120.0 << 120.0 << false << false << false << "";
+ QTest::newRow("extless async") << testFileUrl("colors1").toString() << 120.0 << 120.0 << false << true << true << "";
+ QTest::newRow("extless not found") << testFileUrl("no-such-file").toString() << 0.0 << 0.0 << false
+ << false << true << "<Unknown File>:2:1: QML Image: Cannot open: " + testFileUrl("no-such-file").toString();
+ // Test that pkm is preferred over png. As pattern.pkm has different size than pattern.png, these tests verify that the right file has been loaded
+ QTest::newRow("extless prefer-tex") << testFileUrl("pattern").toString() << 64.0 << 64.0 << false << false << true << "";
+ QTest::newRow("extless prefer-tex async") << testFileUrl("pattern").toString() << 64.0 << 64.0 << false << true << true << "";
}
@@ -299,6 +309,10 @@ void tst_qquickimage::smooth()
void tst_qquickimage::mirror()
{
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+
QMap<QQuickImage::FillMode, QImage> screenshots;
QList<QQuickImage::FillMode> fillModes;
fillModes << QQuickImage::Stretch << QQuickImage::PreserveAspectFit << QQuickImage::PreserveAspectCrop
@@ -398,11 +412,11 @@ void tst_qquickimage::svg()
component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
QVERIFY(obj != 0);
- QCOMPARE(int(obj->width()), 212); // round down: highdpi can give back fractional values
+ QCOMPARE(obj->width(), 300.0);
QCOMPARE(obj->height(), 300.0);
obj->setSourceSize(QSize(200,200));
- QCOMPARE(int(obj->width()), 141); // round down: highdpi can give back fractional values
+ QCOMPARE(obj->width(), 200.0);
QCOMPARE(obj->height(), 200.0);
delete obj;
}
@@ -499,6 +513,10 @@ void tst_qquickimage::big()
void tst_qquickimage::tiling_QTBUG_6716()
{
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+
QFETCH(QString, source);
QQuickView view(testFileUrl(source));
@@ -971,8 +989,71 @@ void tst_qquickimage::highdpi()
delete obj;
}
+void tst_qquickimage::highDpiFillModesAndSizes_data()
+{
+ QTest::addColumn<QQuickImage::FillMode>("fillMode");
+ QTest::addColumn<qreal>("expectedHeightAfterSettingWidthTo100");
+ QTest::addColumn<qreal>("expectedImplicitHeightAfterSettingWidthTo100");
+ QTest::addColumn<qreal>("expectedPaintedWidthAfterSettingWidthTo100");
+ QTest::addColumn<qreal>("expectedPaintedHeightAfterSettingWidthTo100");
+
+ QTest::addRow("Stretch") << QQuickImage::Stretch << 150.0 << 150.0 << 100.0 << 150.0;
+ QTest::addRow("PreserveAspectFit") << QQuickImage::PreserveAspectFit << 100.0 << 100.0 << 100.0 << 100.0;
+ QTest::addRow("PreserveAspectCrop") << QQuickImage::PreserveAspectCrop << 150.0 << 150.0 << 150.0 << 150.0;
+ QTest::addRow("Tile") << QQuickImage::Tile << 150.0 << 150.0 << 100.0 << 150.0;
+ QTest::addRow("TileVertically") << QQuickImage::TileVertically << 150.0 << 150.0 << 100.0 << 150.0;
+ QTest::addRow("TileHorizontally") << QQuickImage::TileHorizontally << 150.0 << 150.0 << 100.0 << 150.0;
+ QTest::addRow("Pad") << QQuickImage::Pad << 150.0 << 150.0 << 150.0 << 150.0;
+}
+
+void tst_qquickimage::highDpiFillModesAndSizes()
+{
+ QFETCH(QQuickImage::FillMode, fillMode);
+ QFETCH(qreal, expectedHeightAfterSettingWidthTo100);
+ QFETCH(qreal, expectedImplicitHeightAfterSettingWidthTo100);
+ QFETCH(qreal, expectedPaintedWidthAfterSettingWidthTo100);
+ QFETCH(qreal, expectedPaintedHeightAfterSettingWidthTo100);
+
+ QString componentStr = "import QtQuick 2.0\nImage { source: srcImage; }";
+ QQmlComponent component(&engine);
+ component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+
+ engine.rootContext()->setContextProperty("srcImage", testFileUrl("heart-highdpi@2x.png"));
+
+ QScopedPointer<QQuickImage> image(qobject_cast<QQuickImage*>(component.create()));
+ QVERIFY(image);
+ QCOMPARE(image->width(), 150.0);
+ QCOMPARE(image->height(), 150.0);
+ QCOMPARE(image->paintedWidth(), 150.0);
+ QCOMPARE(image->paintedHeight(), 150.0);
+ QCOMPARE(image->implicitWidth(), 150.0);
+ QCOMPARE(image->implicitHeight(), 150.0);
+ QCOMPARE(image->paintedWidth(), 150.0);
+ QCOMPARE(image->paintedHeight(), 150.0);
+
+ // The implicit size should not change when setting any fillMode here.
+ image->setFillMode(fillMode);
+ QCOMPARE(image->fillMode(), fillMode);
+ QCOMPARE(image->implicitWidth(), 150.0);
+ QCOMPARE(image->implicitHeight(), 150.0);
+ QCOMPARE(image->paintedWidth(), 150.0);
+ QCOMPARE(image->paintedHeight(), 150.0);
+
+ image->setWidth(100.0);
+ QCOMPARE(image->width(), 100.0);
+ QCOMPARE(image->height(), expectedHeightAfterSettingWidthTo100);
+ QCOMPARE(image->implicitWidth(), 150.0);
+ QCOMPARE(image->implicitHeight(), expectedImplicitHeightAfterSettingWidthTo100);
+ QCOMPARE(image->paintedWidth(), expectedPaintedWidthAfterSettingWidthTo100);
+ QCOMPARE(image->paintedHeight(), expectedPaintedHeightAfterSettingWidthTo100);
+}
+
void tst_qquickimage::hugeImages()
{
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+
QQuickView view;
view.setSource(testFileUrl("hugeImages.qml"));
view.setGeometry(0, 0, 200, 200);
diff --git a/tests/auto/quick/qquickitem/BLACKLIST b/tests/auto/quick/qquickitem/BLACKLIST
index d94a3ef102..f00b061356 100644
--- a/tests/auto/quick/qquickitem/BLACKLIST
+++ b/tests/auto/quick/qquickitem/BLACKLIST
@@ -1,2 +1,4 @@
[contains:hollow square: testing points inside]
xcb
+[ignoreButtonPressNotInAcceptedMouseButtons]
+*
diff --git a/tests/auto/quick/qquickitem/tst_qquickitem.cpp b/tests/auto/quick/qquickitem/tst_qquickitem.cpp
index 10a3a0bfa8..f4434d9d3f 100644
--- a/tests/auto/quick/qquickitem/tst_qquickitem.cpp
+++ b/tests/auto/quick/qquickitem/tst_qquickitem.cpp
@@ -49,7 +49,12 @@ public:
: QQuickItem(parent), focused(false), pressCount(0), releaseCount(0)
, wheelCount(0), acceptIncomingTouchEvents(true)
, touchEventReached(false), timestamp(0)
- , lastWheelEventPos(0, 0), lastWheelEventGlobalPos(0, 0) {}
+ , lastWheelEventPos(0, 0), lastWheelEventGlobalPos(0, 0)
+ {
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ setAcceptTouchEvents(true);
+#endif
+ }
bool focused;
int pressCount;
diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
index 09e89ff85f..b66dc1708f 100644
--- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
@@ -301,7 +301,7 @@ class TabFenceItem : public QQuickItem
Q_OBJECT
public:
- TabFenceItem(QQuickItem *parent = Q_NULLPTR)
+ TabFenceItem(QQuickItem *parent = nullptr)
: QQuickItem(parent)
{
QQuickItemPrivate *d = QQuickItemPrivate::get(this);
@@ -316,7 +316,7 @@ class TabFenceItem2 : public QQuickItem
Q_OBJECT
public:
- TabFenceItem2(QQuickItem *parent = Q_NULLPTR)
+ TabFenceItem2(QQuickItem *parent = nullptr)
: QQuickItem(parent)
{
QQuickItemPrivate *d = QQuickItemPrivate::get(this);
@@ -1188,12 +1188,12 @@ void tst_QQuickItem::tabFence()
QVERIFY(window->rootObject()->hasActiveFocus());
const char *rootTabFocusChain[] = {
- "input1", "input2", "input3", "input1", Q_NULLPTR
+ "input1", "input2", "input3", "input1", nullptr
};
verifyTabFocusChain(window, rootTabFocusChain, true /* forward */);
const char *rootBacktabFocusChain[] = {
- "input3", "input2", "input1", "input3", Q_NULLPTR
+ "input3", "input2", "input1", "input3", nullptr
};
verifyTabFocusChain(window, rootBacktabFocusChain, false /* forward */);
@@ -1204,12 +1204,12 @@ void tst_QQuickItem::tabFence()
QVERIFY(item->hasActiveFocus());
const char *fence1TabFocusChain[] = {
- "input12", "input13", "input11", "input12", Q_NULLPTR
+ "input12", "input13", "input11", "input12", nullptr
};
verifyTabFocusChain(window, fence1TabFocusChain, true /* forward */);
const char *fence1BacktabFocusChain[] = {
- "input11", "input13", "input12", "input11", Q_NULLPTR
+ "input11", "input13", "input12", "input11", nullptr
};
verifyTabFocusChain(window, fence1BacktabFocusChain, false /* forward */);
}
@@ -3305,6 +3305,10 @@ void tst_QQuickItem::childAt()
void tst_QQuickItem::grab()
{
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabToImage not functional on offscreen/minimimal platforms");
+
QQuickView view;
view.setSource(testFileUrl("grabToImage.qml"));
view.show();
diff --git a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp
index 5419778cfc..a8a00b51e9 100644
--- a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp
+++ b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp
@@ -36,6 +36,9 @@
#include "../../shared/util.h"
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/qpa/qplatformintegration.h>
+
class tst_QQuickItemLayer: public QQmlDataTest
{
Q_OBJECT
@@ -54,7 +57,7 @@ public:
}
private slots:
- void initTestCase() Q_DECL_OVERRIDE;
+ void initTestCase() override;
void layerEnabled();
void layerSmooth();
#if QT_CONFIG(opengl)
@@ -102,35 +105,37 @@ void tst_QQuickItemLayer::initTestCase()
{
QQmlDataTest::initTestCase();
#if QT_CONFIG(opengl)
- QWindow window;
- QOpenGLContext context;
- window.setSurfaceType(QWindow::OpenGLSurface);
- window.create();
- QVERIFY(context.create());
- QVERIFY(context.makeCurrent(&window));
- const char *vendor = (const char *)context.functions()->glGetString(GL_VENDOR);
- const char *renderer = (const char *)context.functions()->glGetString(GL_RENDERER);
- m_isMesaSoftwareRasterizer = strcmp(vendor, "Mesa Project") == 0
- && strcmp(renderer, "Software Rasterizer") == 0;
- if (m_isMesaSoftwareRasterizer) {
- // Expects format: <OpenGL version> Mesa <Mesa version>[-devel] [...]
- const char *version = (const char *)context.functions()->glGetString(GL_VERSION);
- QList<QByteArray> list = QByteArray(version).split(' ');
- if (list.size() >= 3) {
- list = list.at(2).split('-').at(0).split('.');
- int major = 0;
- int minor = 0;
- int patch = 0;
- if (list.size() >= 1)
- major = list.at(0).toInt();
- if (list.size() >= 2)
- minor = list.at(1).toInt();
- if (list.size() >= 3)
- patch = list.at(2).toInt();
- m_mesaVersion = QT_VERSION_CHECK(major, minor, patch);
+ if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) {
+ QWindow window;
+ QOpenGLContext context;
+ window.setSurfaceType(QWindow::OpenGLSurface);
+ window.create();
+ QVERIFY(context.create());
+ QVERIFY(context.makeCurrent(&window));
+ const char *vendor = (const char *)context.functions()->glGetString(GL_VENDOR);
+ const char *renderer = (const char *)context.functions()->glGetString(GL_RENDERER);
+ m_isMesaSoftwareRasterizer = strcmp(vendor, "Mesa Project") == 0
+ && strcmp(renderer, "Software Rasterizer") == 0;
+ if (m_isMesaSoftwareRasterizer) {
+ // Expects format: <OpenGL version> Mesa <Mesa version>[-devel] [...]
+ const char *version = (const char *)context.functions()->glGetString(GL_VERSION);
+ QList<QByteArray> list = QByteArray(version).split(' ');
+ if (list.size() >= 3) {
+ list = list.at(2).split('-').at(0).split('.');
+ int major = 0;
+ int minor = 0;
+ int patch = 0;
+ if (list.size() >= 1)
+ major = list.at(0).toInt();
+ if (list.size() >= 2)
+ minor = list.at(1).toInt();
+ if (list.size() >= 3)
+ patch = list.at(2).toInt();
+ m_mesaVersion = QT_VERSION_CHECK(major, minor, patch);
+ }
}
+ window.create();
}
- window.create();
#endif
QQuickView view;
view.showNormal();
@@ -147,6 +152,11 @@ void tst_QQuickItemLayer::layerSmooth()
{
if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
+
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+
QImage fb = runTest("Smooth.qml");
QCOMPARE(fb.pixel(0, 0), qRgb(0xff, 0, 0));
QCOMPARE(fb.pixel(fb.width() - 1, 0), qRgb(0, 0, 0xff));
@@ -166,6 +176,11 @@ void tst_QQuickItemLayer::layerEnabled()
{
if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
+
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+
QImage fb = runTest("Enabled.qml");
// Verify the banding
QCOMPARE(fb.pixel(0, 0), fb.pixel(0, 1));
@@ -181,6 +196,7 @@ void tst_QQuickItemLayer::layerMipmap()
{
if (m_isMesaSoftwareRasterizer)
QSKIP("Mipmapping does not work with the Mesa Software Rasterizer.");
+
QImage fb = runTest("Mipmap.qml");
QVERIFY(fb.pixel(0, 0) != 0xff000000);
QVERIFY(fb.pixel(0, 0) != 0xffffffff);
@@ -195,6 +211,11 @@ void tst_QQuickItemLayer::layerEffect()
{
if (m_isMesaSoftwareRasterizer && m_mesaVersion < QT_VERSION_CHECK(7, 11, 0))
QSKIP("Mesa Software Rasterizer below version 7.11 does not render this test correctly.");
+
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+
QImage fb = runTest("Effect.qml");
QCOMPARE(fb.pixel(0, 0), qRgb(0xff, 0, 0));
QCOMPARE(fb.pixel(fb.width() - 1, 0), qRgb(0, 0xff, 0));
@@ -451,6 +472,10 @@ void tst_QQuickItemLayer::itemEffect()
void tst_QQuickItemLayer::rectangleEffect()
{
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+
QImage fb = runTest("RectangleEffect.qml");
QCOMPARE(fb.pixel(0, 0), qRgb(0, 0xff, 0));
QCOMPARE(fb.pixel(199, 0), qRgb(0, 0xff, 0));
diff --git a/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml b/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml
index 4346c5283e..4ff1017116 100644
--- a/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml
+++ b/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml
@@ -263,6 +263,41 @@ Item {
col.destroy()
}
+ function test_dynamicSizeAdaptationsForInitiallyInvisibleItemsInLayout() {
+ var test_layoutStr =
+ 'import QtQuick 2.2; \
+ import QtQuick.Layouts 1.0; \
+ RowLayout { \
+ id: row; \
+ width: 10; \
+ spacing: 0; \
+ property alias r1: _r1; \
+ Rectangle { \
+ id: _r1; \
+ visible: false; \
+ height: 10; \
+ Layout.fillWidth: true; \
+ color: "#8080ff"; \
+ } \
+ property alias r2: _r2; \
+ Rectangle { \
+ id: _r2; \
+ height: 10; \
+ Layout.fillWidth: true; \
+ color: "#c0c0ff"; \
+ } \
+ } '
+
+ var lay = Qt.createQmlObject(test_layoutStr, container, '');
+ compare(lay.r1.width, 0)
+ compare(lay.r2.width, 10)
+ lay.r1.visible = true;
+ waitForRendering(lay)
+ compare(lay.r1.width, 5)
+ compare(lay.r2.width, 5)
+ lay.destroy()
+ }
+
Component {
id: layoutItem_Component
Rectangle {
diff --git a/tests/auto/quick/qquicklistview/BLACKLIST b/tests/auto/quick/qquicklistview/BLACKLIST
index d259c11219..8cf8a57eee 100644
--- a/tests/auto/quick/qquicklistview/BLACKLIST
+++ b/tests/auto/quick/qquicklistview/BLACKLIST
@@ -5,3 +5,6 @@ osx
#QTBUG-53863
[populateTransitions]
opensuse-42.1
+#QTBUG-65964
+[QTBUG_34576_velocityZero]
+osx-10.11 ci
diff --git a/tests/auto/quick/qquicklistview/data/flickBothDirections.qml b/tests/auto/quick/qquicklistview/data/flickBothDirections.qml
index 754e91a732..b491981edb 100644
--- a/tests/auto/quick/qquicklistview/data/flickBothDirections.qml
+++ b/tests/auto/quick/qquicklistview/data/flickBothDirections.qml
@@ -63,6 +63,7 @@ Rectangle {
contentWidth: initialContentWidth
contentHeight: initialContentHeight
flickableDirection: initialFlickableDirection
+ pixelAligned: true
delegate: Rectangle {
width: list.orientation == ListView.Vertical ? 120 : 10
height: list.orientation == ListView.Vertical ? 20 : 110
diff --git a/tests/auto/quick/qquicklistview/randomsortmodel.cpp b/tests/auto/quick/qquicklistview/randomsortmodel.cpp
index 7affb182c0..7375fe0dbe 100644
--- a/tests/auto/quick/qquicklistview/randomsortmodel.cpp
+++ b/tests/auto/quick/qquicklistview/randomsortmodel.cpp
@@ -27,6 +27,7 @@
****************************************************************************/
#include "randomsortmodel.h"
+#include <QRandomGenerator>
RandomSortModel::RandomSortModel(QObject* parent):
QAbstractListModel(parent)
@@ -73,14 +74,14 @@ QVariant RandomSortModel::data(const QModelIndex& index, int role) const
void RandomSortModel::randomize()
{
- const int row = qrand() % mData.count();
+ const int row = QRandomGenerator::global()->bounded(mData.count());
int random;
bool exists = false;
// Make sure we won't end up with two items with the same weight, as that
// would make unit-testing much harder
do {
exists = false;
- random = qrand() % (mData.count() * 10);
+ random = QRandomGenerator::global()->bounded(mData.count() * 10);
QList<QPair<QString, int> >::ConstIterator iter, end;
for (iter = mData.constBegin(), end = mData.constEnd(); iter != end; ++iter) {
if ((*iter).second == random) {
diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
index a7583129f9..dc8c727cbe 100644
--- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
+++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
@@ -8531,7 +8531,7 @@ void tst_QQuickListView::QTBUG_48870_fastModelUpdates()
QQuickItemViewPrivate *priv = QQuickItemViewPrivate::get(listview);
bool nonUnique;
- FxViewItem *item = Q_NULLPTR;
+ FxViewItem *item = nullptr;
int expectedIdx;
QVERIFY(testVisibleItems(priv, &nonUnique, &item, &expectedIdx));
diff --git a/tests/auto/quick/qquickloader/BLACKLIST b/tests/auto/quick/qquickloader/BLACKLIST
new file mode 100644
index 0000000000..a45a300607
--- /dev/null
+++ b/tests/auto/quick/qquickloader/BLACKLIST
@@ -0,0 +1,4 @@
+# Test fails on qemu when bound to one core, passes on real ARM
+# QTBUG-63049
+[asyncToSync1]
+b2qt
diff --git a/tests/auto/quick/qquickloader/data/bindings.qml b/tests/auto/quick/qquickloader/data/bindings.qml
new file mode 100644
index 0000000000..e0eae2a3e5
--- /dev/null
+++ b/tests/auto/quick/qquickloader/data/bindings.qml
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Item {
+ id: root
+
+ property alias game: theGame
+ property alias loader: theLoader
+
+ Item {
+ id: theGame
+
+ property bool isReady: false
+
+ onStateChanged: {
+ if (state == "invalid") {
+ // The Loader's active property is bound to isReady, so none of its bindings
+ // should be updated when isReady becomes false
+ isReady = false;
+
+ player.destroy();
+ player = null;
+ } else if (state == "running") {
+ player = Qt.createQmlObject("import QtQuick 2.0; Item { property color color: 'black' }", root);
+
+ isReady = true;
+ }
+ }
+
+ property Item player
+ }
+
+ Loader {
+ id: theLoader
+ active: theGame.isReady
+ sourceComponent: Rectangle {
+ width: 400
+ height: 400
+ color: game.player.color
+
+ property var game: theGame
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickloader/data/parentErrors.qml b/tests/auto/quick/qquickloader/data/parentErrors.qml
new file mode 100644
index 0000000000..36607e7f05
--- /dev/null
+++ b/tests/auto/quick/qquickloader/data/parentErrors.qml
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ width: 360
+ height: 360
+
+ property alias loader: loader
+
+ Loader {
+ id: loader
+ anchors.fill: parent
+ }
+
+ property Component component: Rectangle {
+ width: parent.width
+ height: parent.height
+ color: "pink"
+ }
+}
diff --git a/tests/auto/quick/qquickloader/qquickloader.pro b/tests/auto/quick/qquickloader/qquickloader.pro
index 06fb75793d..c754c78bec 100644
--- a/tests/auto/quick/qquickloader/qquickloader.pro
+++ b/tests/auto/quick/qquickloader/qquickloader.pro
@@ -2,7 +2,6 @@ CONFIG += testcase
TARGET = tst_qquickloader
macx:CONFIG -= app_bundle
-INCLUDEPATH += ../../shared/
HEADERS += ../../shared/testhttpserver.h
SOURCES += tst_qquickloader.cpp \
diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
index 582ba2aabc..65493f52e2 100644
--- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp
+++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
@@ -79,8 +79,6 @@ public:
tst_QQuickLoader();
private slots:
- void cleanup();
-
void sourceOrComponent();
void sourceOrComponent_data();
void clear();
@@ -123,19 +121,16 @@ private slots:
void sourceComponentGarbageCollection();
-private:
- QQmlEngine engine;
+ void bindings();
+ void parentErrors();
};
-void tst_QQuickLoader::cleanup()
-{
- // clear components. otherwise we even bypass the test server by using the cache.
- engine.clearComponentCache();
-}
+Q_DECLARE_METATYPE(QList<QQmlError>)
tst_QQuickLoader::tst_QQuickLoader()
{
qmlRegisterType<SlowComponent>("LoaderTest", 1, 0, "SlowComponent");
+ qRegisterMetaType<QList<QQmlError>>();
}
void tst_QQuickLoader::sourceOrComponent()
@@ -149,6 +144,7 @@ void tst_QQuickLoader::sourceOrComponent()
if (error)
QTest::ignoreMessage(QtWarningMsg, errorString.toUtf8().constData());
+ QQmlEngine engine;
QQmlComponent component(&engine);
component.setData(QByteArray(
"import QtQuick 2.0\n"
@@ -170,14 +166,14 @@ void tst_QQuickLoader::sourceOrComponent()
"}")
, dataDirectoryUrl());
- QQuickLoader *loader = qobject_cast<QQuickLoader*>(component.create());
+ QScopedPointer<QQuickLoader> loader(qobject_cast<QQuickLoader*>(component.create()));
QVERIFY(loader != 0);
QCOMPARE(loader->item() == 0, error);
QCOMPARE(loader->source(), sourceUrl);
QCOMPARE(loader->progress(), 1.0);
QCOMPARE(loader->status(), error ? QQuickLoader::Error : QQuickLoader::Ready);
- QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), error ? 0: 1);
+ QCOMPARE(static_cast<QQuickItem*>(loader.data())->childItems().count(), error ? 0: 1);
if (!error) {
bool sourceComponentIsChildOfLoader = false;
@@ -202,8 +198,6 @@ void tst_QQuickLoader::sourceOrComponent()
QCOMPARE(loader->property("onItemChangedCount").toInt(), 1);
QCOMPARE(loader->property("onLoadedCount").toInt(), error ? 0 : 1);
-
- delete loader;
}
void tst_QQuickLoader::sourceOrComponent_data()
@@ -225,6 +219,8 @@ void tst_QQuickLoader::sourceOrComponent_data()
void tst_QQuickLoader::clear()
{
+ QQmlEngine engine;
+
{
QQmlComponent component(&engine);
component.setData(QByteArray(
@@ -234,22 +230,20 @@ void tst_QQuickLoader::clear()
" Timer { interval: 200; running: true; onTriggered: loader.source = '' }\n"
" }")
, dataDirectoryUrl());
- QQuickLoader *loader = qobject_cast<QQuickLoader*>(component.create());
+ QScopedPointer<QQuickLoader> loader(qobject_cast<QQuickLoader*>(component.create()));
QVERIFY(loader != 0);
QVERIFY(loader->item());
QCOMPARE(loader->progress(), 1.0);
- QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 1);
+ QCOMPARE(static_cast<QQuickItem*>(loader.data())->childItems().count(), 1);
QTRY_VERIFY(!loader->item());
QCOMPARE(loader->progress(), 0.0);
QCOMPARE(loader->status(), QQuickLoader::Null);
- QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 0);
-
- delete loader;
+ QCOMPARE(static_cast<QQuickItem*>(loader.data())->childItems().count(), 0);
}
{
QQmlComponent component(&engine, testFileUrl("/SetSourceComponent.qml"));
- QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
+ QScopedPointer<QQuickItem> item(qobject_cast<QQuickItem*>(component.create()));
QVERIFY(item);
QQuickLoader *loader = qobject_cast<QQuickLoader*>(item->QQuickItem::childItems().at(0));
@@ -264,12 +258,10 @@ void tst_QQuickLoader::clear()
QCOMPARE(loader->progress(), 0.0);
QCOMPARE(loader->status(), QQuickLoader::Null);
QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 0);
-
- delete item;
}
{
QQmlComponent component(&engine, testFileUrl("/SetSourceComponent.qml"));
- QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
+ QScopedPointer<QQuickItem> item(qobject_cast<QQuickItem*>(component.create()));
QVERIFY(item);
QQuickLoader *loader = qobject_cast<QQuickLoader*>(item->QQuickItem::childItems().at(0));
@@ -278,19 +270,18 @@ void tst_QQuickLoader::clear()
QCOMPARE(loader->progress(), 1.0);
QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 1);
- QMetaObject::invokeMethod(item, "clear");
+ QMetaObject::invokeMethod(item.data(), "clear");
QVERIFY(!loader->item());
QCOMPARE(loader->progress(), 0.0);
QCOMPARE(loader->status(), QQuickLoader::Null);
QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 0);
-
- delete item;
}
}
void tst_QQuickLoader::urlToComponent()
{
+ QQmlEngine engine;
QQmlComponent component(&engine);
component.setData(QByteArray("import QtQuick 2.0\n"
"Loader {\n"
@@ -300,22 +291,21 @@ void tst_QQuickLoader::urlToComponent()
" Timer { interval: 100; running: true; onTriggered: loader.sourceComponent = myComp }\n"
"}" )
, dataDirectoryUrl());
- QQuickLoader *loader = qobject_cast<QQuickLoader*>(component.create());
+ QScopedPointer<QQuickLoader> loader(qobject_cast<QQuickLoader*>(component.create()));
QTest::qWait(200);
QTRY_VERIFY(loader != 0);
QVERIFY(loader->item());
QCOMPARE(loader->progress(), 1.0);
- QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 1);
+ QCOMPARE(static_cast<QQuickItem*>(loader.data())->childItems().count(), 1);
QCOMPARE(loader->width(), 10.0);
QCOMPARE(loader->height(), 10.0);
-
- delete loader;
}
void tst_QQuickLoader::componentToUrl()
{
+ QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("/SetSourceComponent.qml"));
- QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
+ QScopedPointer<QQuickItem> item(qobject_cast<QQuickItem*>(component.create()));
QVERIFY(item);
QQuickLoader *loader = qobject_cast<QQuickLoader*>(item->QQuickItem::childItems().at(0));
@@ -330,14 +320,13 @@ void tst_QQuickLoader::componentToUrl()
QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 1);
QCOMPARE(loader->width(), 120.0);
QCOMPARE(loader->height(), 60.0);
-
- delete item;
}
void tst_QQuickLoader::anchoredLoader()
{
+ QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("/AnchoredLoader.qml"));
- QQuickItem *rootItem = qobject_cast<QQuickItem*>(component.create());
+ QScopedPointer<QQuickItem> rootItem(qobject_cast<QQuickItem*>(component.create()));
QVERIFY(rootItem != 0);
QQuickItem *loader = rootItem->findChild<QQuickItem*>("loader");
QQuickItem *sourceElement = rootItem->findChild<QQuickItem*>("sourceElement");
@@ -357,8 +346,9 @@ void tst_QQuickLoader::anchoredLoader()
void tst_QQuickLoader::sizeLoaderToItem()
{
+ QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("/SizeToItem.qml"));
- QQuickLoader *loader = qobject_cast<QQuickLoader*>(component.create());
+ QScopedPointer<QQuickLoader> loader(qobject_cast<QQuickLoader*>(component.create()));
QVERIFY(loader != 0);
QCOMPARE(loader->width(), 120.0);
QCOMPARE(loader->height(), 60.0);
@@ -392,14 +382,13 @@ void tst_QQuickLoader::sizeLoaderToItem()
loader->setHeight(30);
QCOMPARE(rect->width(), 180.0);
QCOMPARE(rect->height(), 30.0);
-
- delete loader;
}
void tst_QQuickLoader::sizeItemToLoader()
{
+ QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("/SizeToLoader.qml"));
- QQuickLoader *loader = qobject_cast<QQuickLoader*>(component.create());
+ QScopedPointer<QQuickLoader> loader(qobject_cast<QQuickLoader*>(component.create()));
QVERIFY(loader != 0);
QCOMPARE(loader->width(), 200.0);
QCOMPARE(loader->height(), 80.0);
@@ -428,31 +417,29 @@ void tst_QQuickLoader::sizeItemToLoader()
rect->setHeight(45);
QCOMPARE(loader->width(), 160.0);
QCOMPARE(loader->height(), 45.0);
-
- delete loader;
}
void tst_QQuickLoader::noResize()
{
+ QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("/NoResize.qml"));
- QQuickItem* item = qobject_cast<QQuickItem*>(component.create());
+ QScopedPointer<QQuickItem> item(qobject_cast<QQuickItem*>(component.create()));
QVERIFY(item != 0);
QCOMPARE(item->width(), 200.0);
QCOMPARE(item->height(), 80.0);
-
- delete item;
}
void tst_QQuickLoader::networkRequestUrl()
{
ThreadedTestHTTPServer server(dataDirectory());
+ QQmlEngine engine;
QQmlComponent component(&engine);
const QString qml = "import QtQuick 2.0\nLoader { property int signalCount : 0; source: \"" + server.baseUrl().toString() + "/Rect120x60.qml\"; onLoaded: signalCount += 1 }";
component.setData(qml.toUtf8(), testFileUrl("../dummy.qml"));
if (component.isError())
qDebug() << component.errors();
- QQuickLoader *loader = qobject_cast<QQuickLoader*>(component.create());
+ QScopedPointer<QQuickLoader> loader(qobject_cast<QQuickLoader*>(component.create()));
QVERIFY(loader != 0);
QTRY_COMPARE(loader->status(), QQuickLoader::Ready);
@@ -460,9 +447,7 @@ void tst_QQuickLoader::networkRequestUrl()
QVERIFY(loader->item());
QCOMPARE(loader->progress(), 1.0);
QCOMPARE(loader->property("signalCount").toInt(), 1);
- QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 1);
-
- delete loader;
+ QCOMPARE(static_cast<QQuickItem*>(loader.data())->childItems().count(), 1);
}
/* XXX Component waits until all dependencies are loaded. Is this actually possible? */
@@ -470,6 +455,7 @@ void tst_QQuickLoader::networkComponent()
{
ThreadedTestHTTPServer server(dataDirectory(), TestHTTPServer::Delay);
+ QQmlEngine engine;
QQmlComponent component(&engine);
const QString qml = "import QtQuick 2.0\n"
"import \"" + server.baseUrl().toString() + "/\" as NW\n"
@@ -502,11 +488,12 @@ void tst_QQuickLoader::failNetworkRequest()
QTest::ignoreMessage(QtWarningMsg, QString(server.baseUrl().toString() + "/IDontExist.qml: File not found").toUtf8());
+ QQmlEngine engine;
QQmlComponent component(&engine);
const QString qml = "import QtQuick 2.0\nLoader { property int did_load: 123; source: \"" + server.baseUrl().toString() + "/IDontExist.qml\"; onLoaded: did_load=456 }";
component.setData(qml.toUtf8(), server.url("/dummy.qml"));
QTRY_COMPARE(component.status(), QQmlComponent::Ready);
- QQuickLoader *loader = qobject_cast<QQuickLoader*>(component.create());
+ QScopedPointer<QQuickLoader> loader(qobject_cast<QQuickLoader*>(component.create()));
QVERIFY(loader != 0);
QTRY_COMPARE(loader->status(), QQuickLoader::Error);
@@ -514,104 +501,94 @@ void tst_QQuickLoader::failNetworkRequest()
QVERIFY(!loader->item());
QCOMPARE(loader->progress(), 1.0);
QCOMPARE(loader->property("did_load").toInt(), 123);
- QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 0);
-
- delete loader;
+ QCOMPARE(static_cast<QQuickItem*>(loader.data())->childItems().count(), 0);
}
void tst_QQuickLoader::active()
{
+ QQmlEngine engine;
+
// check that the item isn't instantiated until active is set to true
{
QQmlComponent component(&engine, testFileUrl("active.1.qml"));
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != 0);
QQuickLoader *loader = object->findChild<QQuickLoader*>("loader");
QVERIFY(loader->active() == false); // set manually to false
QVERIFY(!loader->item());
- QMetaObject::invokeMethod(object, "doSetSourceComponent");
+ QMetaObject::invokeMethod(object.data(), "doSetSourceComponent");
QVERIFY(!loader->item());
- QMetaObject::invokeMethod(object, "doSetSource");
+ QMetaObject::invokeMethod(object.data(), "doSetSource");
QVERIFY(!loader->item());
- QMetaObject::invokeMethod(object, "doSetActive");
+ QMetaObject::invokeMethod(object.data(), "doSetActive");
QVERIFY(loader->item() != 0);
-
- delete object;
}
// check that the status is Null if active is set to false
{
QQmlComponent component(&engine, testFileUrl("active.2.qml"));
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != 0);
QQuickLoader *loader = object->findChild<QQuickLoader*>("loader");
QVERIFY(loader->active() == true); // active is true by default
QCOMPARE(loader->status(), QQuickLoader::Ready);
int currStatusChangedCount = loader->property("statusChangedCount").toInt();
- QMetaObject::invokeMethod(object, "doSetInactive");
+ QMetaObject::invokeMethod(object.data(), "doSetInactive");
QCOMPARE(loader->status(), QQuickLoader::Null);
QCOMPARE(loader->property("statusChangedCount").toInt(), (currStatusChangedCount+1));
-
- delete object;
}
// check that the source is not cleared if active is set to false
{
QQmlComponent component(&engine, testFileUrl("active.3.qml"));
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != 0);
QQuickLoader *loader = object->findChild<QQuickLoader*>("loader");
QVERIFY(loader->active() == true); // active is true by default
QVERIFY(!loader->source().isEmpty());
int currSourceChangedCount = loader->property("sourceChangedCount").toInt();
- QMetaObject::invokeMethod(object, "doSetInactive");
+ QMetaObject::invokeMethod(object.data(), "doSetInactive");
QVERIFY(!loader->source().isEmpty());
QCOMPARE(loader->property("sourceChangedCount").toInt(), currSourceChangedCount);
-
- delete object;
}
// check that the sourceComponent is not cleared if active is set to false
{
QQmlComponent component(&engine, testFileUrl("active.4.qml"));
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != 0);
QQuickLoader *loader = object->findChild<QQuickLoader*>("loader");
QVERIFY(loader->active() == true); // active is true by default
QVERIFY(loader->sourceComponent() != 0);
int currSourceComponentChangedCount = loader->property("sourceComponentChangedCount").toInt();
- QMetaObject::invokeMethod(object, "doSetInactive");
+ QMetaObject::invokeMethod(object.data(), "doSetInactive");
QVERIFY(loader->sourceComponent() != 0);
QCOMPARE(loader->property("sourceComponentChangedCount").toInt(), currSourceComponentChangedCount);
-
- delete object;
}
// check that the item is released if active is set to false
{
QQmlComponent component(&engine, testFileUrl("active.5.qml"));
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != 0);
QQuickLoader *loader = object->findChild<QQuickLoader*>("loader");
QVERIFY(loader->active() == true); // active is true by default
QVERIFY(loader->item() != 0);
int currItemChangedCount = loader->property("itemChangedCount").toInt();
- QMetaObject::invokeMethod(object, "doSetInactive");
+ QMetaObject::invokeMethod(object.data(), "doSetInactive");
QVERIFY(!loader->item());
QCOMPARE(loader->property("itemChangedCount").toInt(), (currItemChangedCount+1));
-
- delete object;
}
// check that the activeChanged signal is emitted correctly
{
QQmlComponent component(&engine, testFileUrl("active.6.qml"));
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != 0);
QQuickLoader *loader = object->findChild<QQuickLoader*>("loader");
@@ -626,34 +603,30 @@ void tst_QQuickLoader::active()
QCOMPARE(loader->property("activeChangedCount").toInt(), 2);
loader->setActive(false); // change signal should be emitted
QCOMPARE(loader->property("activeChangedCount").toInt(), 3);
- QMetaObject::invokeMethod(object, "doSetActive");
+ QMetaObject::invokeMethod(object.data(), "doSetActive");
QCOMPARE(loader->property("activeChangedCount").toInt(), 4);
- QMetaObject::invokeMethod(object, "doSetActive");
+ QMetaObject::invokeMethod(object.data(), "doSetActive");
QCOMPARE(loader->property("activeChangedCount").toInt(), 4);
- QMetaObject::invokeMethod(object, "doSetInactive");
+ QMetaObject::invokeMethod(object.data(), "doSetInactive");
QCOMPARE(loader->property("activeChangedCount").toInt(), 5);
loader->setActive(true); // change signal should be emitted
QCOMPARE(loader->property("activeChangedCount").toInt(), 6);
-
- delete object;
}
// check that the component isn't loaded until active is set to true
{
QQmlComponent component(&engine, testFileUrl("active.7.qml"));
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != 0);
QCOMPARE(object->property("success").toBool(), true);
- delete object;
}
// check that the component is loaded if active is not set (true by default)
{
QQmlComponent component(&engine, testFileUrl("active.8.qml"));
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != 0);
QCOMPARE(object->property("success").toBool(), true);
- delete object;
}
}
@@ -717,14 +690,15 @@ void tst_QQuickLoader::initialPropertyValues()
foreach (const QString &warning, expectedWarnings)
QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData());
+ QQmlEngine engine;
QQmlComponent component(&engine, qmlFile);
- QObject *object = component.beginCreate(engine.rootContext());
+ QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
QVERIFY(object != 0);
const int serverBaseUrlPropertyIndex = object->metaObject()->indexOfProperty("serverBaseUrl");
if (serverBaseUrlPropertyIndex != -1) {
QMetaProperty prop = object->metaObject()->property(serverBaseUrlPropertyIndex);
- QVERIFY(prop.write(object, server.baseUrl().toString()));
+ QVERIFY(prop.write(object.data(), server.baseUrl().toString()));
}
component.completeCreate();
@@ -735,20 +709,17 @@ void tst_QQuickLoader::initialPropertyValues()
for (int i = 0; i < propertyNames.size(); ++i)
QCOMPARE(object->property(propertyNames.at(i).toLatin1().constData()), propertyValues.at(i));
-
- delete object;
}
void tst_QQuickLoader::initialPropertyValuesBinding()
{
+ QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("initialPropertyValues.binding.qml"));
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != 0);
QVERIFY(object->setProperty("bindable", QVariant(8)));
QCOMPARE(object->property("canaryValue").toInt(), 8);
-
- delete object;
}
void tst_QQuickLoader::initialPropertyValuesError_data()
@@ -778,23 +749,24 @@ void tst_QQuickLoader::initialPropertyValuesError()
foreach (const QString &warning, expectedWarnings)
QTest::ignoreMessage(QtWarningMsg, warning.toUtf8().constData());
+ QQmlEngine engine;
QQmlComponent component(&engine, qmlFile);
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != 0);
QQuickLoader *loader = object->findChild<QQuickLoader*>("loader");
QVERIFY(loader != 0);
QVERIFY(!loader->item());
- delete object;
}
// QTBUG-9241
void tst_QQuickLoader::deleteComponentCrash()
{
+ QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("crash.qml"));
- QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
+ QScopedPointer<QQuickItem> item(qobject_cast<QQuickItem*>(component.create()));
QVERIFY(item);
- item->metaObject()->invokeMethod(item, "setLoaderSource");
+ item->metaObject()->invokeMethod(item.data(), "setLoaderSource");
QQuickLoader *loader = qobject_cast<QQuickLoader*>(item->QQuickItem::childItems().at(0));
QVERIFY(loader);
@@ -806,69 +778,64 @@ void tst_QQuickLoader::deleteComponentCrash()
QCoreApplication::processEvents();
QTRY_COMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 1);
QCOMPARE(loader->source(), testFileUrl("BlueRect.qml"));
-
- delete item;
}
void tst_QQuickLoader::nonItem()
{
+ QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("nonItem.qml"));
- QQuickLoader *loader = qobject_cast<QQuickLoader*>(component.create());
+ QScopedPointer<QQuickLoader> loader(qobject_cast<QQuickLoader*>(component.create()));
QVERIFY(loader);
QVERIFY(loader->item());
- QCOMPARE(loader, loader->item()->parent());
+ QCOMPARE(loader.data(), loader->item()->parent());
QPointer<QObject> item = loader->item();
loader->setActive(false);
QVERIFY(!loader->item());
QTRY_VERIFY(!item);
-
- delete loader;
}
void tst_QQuickLoader::vmeErrors()
{
+ QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("vmeErrors.qml"));
QString err = testFileUrl("VmeError.qml").toString() + ":6:26: Cannot assign object type QObject with no default method";
QTest::ignoreMessage(QtWarningMsg, err.toLatin1().constData());
- QQuickLoader *loader = qobject_cast<QQuickLoader*>(component.create());
+ QScopedPointer<QQuickLoader> loader(qobject_cast<QQuickLoader*>(component.create()));
QVERIFY(loader);
QVERIFY(!loader->item());
-
- delete loader;
}
// QTBUG-13481
void tst_QQuickLoader::creationContext()
{
+ QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("creationContext.qml"));
- QObject *o = component.create();
+ QScopedPointer<QObject> o(component.create());
QVERIFY(o != 0);
QCOMPARE(o->property("test").toBool(), true);
-
- delete o;
}
void tst_QQuickLoader::QTBUG_16928()
{
+ QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("QTBUG_16928.qml"));
- QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
+ QScopedPointer<QQuickItem> item(qobject_cast<QQuickItem*>(component.create()));
QVERIFY(item);
QCOMPARE(item->width(), 250.);
QCOMPARE(item->height(), 250.);
-
- delete item;
}
void tst_QQuickLoader::implicitSize()
{
+ QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("implicitSize.qml"));
- QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
+ QScopedPointer<QQuickItem> item(qobject_cast<QQuickItem*>(component.create()));
QVERIFY(item);
QCOMPARE(item->width(), 150.);
@@ -881,27 +848,24 @@ void tst_QQuickLoader::implicitSize()
QSignalSpy implWidthSpy(loader, SIGNAL(implicitWidthChanged()));
QSignalSpy implHeightSpy(loader, SIGNAL(implicitHeightChanged()));
- QMetaObject::invokeMethod(item, "changeImplicitSize");
+ QMetaObject::invokeMethod(item.data(), "changeImplicitSize");
QCOMPARE(loader->property("implicitWidth").toReal(), 200.);
QCOMPARE(loader->property("implicitHeight").toReal(), 300.);
QCOMPARE(implWidthSpy.count(), 1);
QCOMPARE(implHeightSpy.count(), 1);
-
- delete item;
}
void tst_QQuickLoader::QTBUG_17114()
{
+ QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("QTBUG_17114.qml"));
- QQuickItem *item = qobject_cast<QQuickItem*>(component.create());
+ QScopedPointer<QQuickItem> item(qobject_cast<QQuickItem*>(component.create()));
QVERIFY(item);
QCOMPARE(item->property("loaderWidth").toReal(), 32.);
QCOMPARE(item->property("loaderHeight").toReal(), 32.);
-
- delete item;
}
void tst_QQuickLoader::asynchronous_data()
@@ -924,13 +888,14 @@ void tst_QQuickLoader::asynchronous()
QFETCH(QUrl, qmlFile);
QFETCH(QStringList, expectedWarnings);
+ QQmlEngine engine;
PeriodicIncubationController *controller = new PeriodicIncubationController;
QQmlIncubationController *previous = engine.incubationController();
engine.setIncubationController(controller);
delete previous;
QQmlComponent component(&engine, testFileUrl("asynchronous.qml"));
- QQuickItem *root = qobject_cast<QQuickItem*>(component.create());
+ QScopedPointer<QQuickItem> root(qobject_cast<QQuickItem*>(component.create()));
QVERIFY(root);
QQuickLoader *loader = root->findChild<QQuickLoader*>("loader");
@@ -942,7 +907,7 @@ void tst_QQuickLoader::asynchronous()
QVERIFY(!loader->item());
QCOMPARE(loader->progress(), 0.0);
root->setProperty("comp", qmlFile.toString());
- QMetaObject::invokeMethod(root, "loadComponent");
+ QMetaObject::invokeMethod(root.data(), "loadComponent");
QVERIFY(!loader->item());
if (expectedWarnings.isEmpty()) {
@@ -958,19 +923,18 @@ void tst_QQuickLoader::asynchronous()
QTRY_COMPARE(loader->progress(), 1.0);
QTRY_COMPARE(loader->status(), QQuickLoader::Error);
}
-
- delete root;
}
void tst_QQuickLoader::asynchronous_clear()
{
+ QQmlEngine engine;
PeriodicIncubationController *controller = new PeriodicIncubationController;
QQmlIncubationController *previous = engine.incubationController();
engine.setIncubationController(controller);
delete previous;
QQmlComponent component(&engine, testFileUrl("asynchronous.qml"));
- QQuickItem *root = qobject_cast<QQuickItem*>(component.create());
+ QScopedPointer<QQuickItem> root(qobject_cast<QQuickItem*>(component.create()));
QVERIFY(root);
QQuickLoader *loader = root->findChild<QQuickLoader*>("loader");
@@ -978,7 +942,7 @@ void tst_QQuickLoader::asynchronous_clear()
QVERIFY(!loader->item());
root->setProperty("comp", "BigComponent.qml");
- QMetaObject::invokeMethod(root, "loadComponent");
+ QMetaObject::invokeMethod(root.data(), "loadComponent");
QVERIFY(!loader->item());
controller->start();
@@ -987,7 +951,7 @@ void tst_QQuickLoader::asynchronous_clear()
// clear before component created
root->setProperty("comp", "");
- QMetaObject::invokeMethod(root, "loadComponent");
+ QMetaObject::invokeMethod(root.data(), "loadComponent");
QVERIFY(!loader->item());
QCOMPARE(engine.incubationController()->incubatingObjectCount(), 0);
@@ -997,7 +961,7 @@ void tst_QQuickLoader::asynchronous_clear()
// check loading component
root->setProperty("comp", "BigComponent.qml");
- QMetaObject::invokeMethod(root, "loadComponent");
+ QMetaObject::invokeMethod(root.data(), "loadComponent");
QVERIFY(!loader->item());
QCOMPARE(loader->status(), QQuickLoader::Loading);
@@ -1007,19 +971,18 @@ void tst_QQuickLoader::asynchronous_clear()
QCOMPARE(loader->progress(), 1.0);
QCOMPARE(loader->status(), QQuickLoader::Ready);
QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 1);
-
- delete root;
}
void tst_QQuickLoader::simultaneousSyncAsync()
{
+ QQmlEngine engine;
PeriodicIncubationController *controller = new PeriodicIncubationController;
QQmlIncubationController *previous = engine.incubationController();
engine.setIncubationController(controller);
delete previous;
QQmlComponent component(&engine, testFileUrl("simultaneous.qml"));
- QQuickItem *root = qobject_cast<QQuickItem*>(component.create());
+ QScopedPointer<QQuickItem> root(qobject_cast<QQuickItem*>(component.create()));
QVERIFY(root);
QQuickLoader *asyncLoader = root->findChild<QQuickLoader*>("asyncLoader");
@@ -1029,7 +992,7 @@ void tst_QQuickLoader::simultaneousSyncAsync()
QVERIFY(!asyncLoader->item());
QVERIFY(!syncLoader->item());
- QMetaObject::invokeMethod(root, "loadComponents");
+ QMetaObject::invokeMethod(root.data(), "loadComponents");
QVERIFY(!asyncLoader->item());
QVERIFY(syncLoader->item());
@@ -1040,8 +1003,6 @@ void tst_QQuickLoader::simultaneousSyncAsync()
QTRY_VERIFY(asyncLoader->item());
QCOMPARE(asyncLoader->progress(), 1.0);
QCOMPARE(asyncLoader->status(), QQuickLoader::Ready);
-
- delete root;
}
void tst_QQuickLoader::asyncToSync1()
@@ -1053,7 +1014,7 @@ void tst_QQuickLoader::asyncToSync1()
delete previous;
QQmlComponent component(&engine, testFileUrl("asynchronous.qml"));
- QQuickItem *root = qobject_cast<QQuickItem*>(component.create());
+ QScopedPointer<QQuickItem> root(qobject_cast<QQuickItem*>(component.create()));
QVERIFY(root);
QQuickLoader *loader = root->findChild<QQuickLoader*>("loader");
@@ -1061,7 +1022,7 @@ void tst_QQuickLoader::asyncToSync1()
QVERIFY(!loader->item());
root->setProperty("comp", "BigComponent.qml");
- QMetaObject::invokeMethod(root, "loadComponent");
+ QMetaObject::invokeMethod(root.data(), "loadComponent");
QVERIFY(!loader->item());
controller->start();
@@ -1074,19 +1035,18 @@ void tst_QQuickLoader::asyncToSync1()
QCOMPARE(loader->progress(), 1.0);
QCOMPARE(loader->status(), QQuickLoader::Ready);
QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 1);
-
- delete root;
}
void tst_QQuickLoader::asyncToSync2()
{
+ QQmlEngine engine;
PeriodicIncubationController *controller = new PeriodicIncubationController;
QQmlIncubationController *previous = engine.incubationController();
engine.setIncubationController(controller);
delete previous;
QQmlComponent component(&engine, testFileUrl("asynchronous.qml"));
- QQuickItem *root = qobject_cast<QQuickItem*>(component.create());
+ QScopedPointer<QQuickItem> root(qobject_cast<QQuickItem*>(component.create()));
QVERIFY(root);
QQuickLoader *loader = root->findChild<QQuickLoader*>("loader");
@@ -1094,7 +1054,7 @@ void tst_QQuickLoader::asyncToSync2()
QVERIFY(!loader->item());
root->setProperty("comp", "BigComponent.qml");
- QMetaObject::invokeMethod(root, "loadComponent");
+ QMetaObject::invokeMethod(root.data(), "loadComponent");
QVERIFY(!loader->item());
controller->start();
@@ -1107,12 +1067,11 @@ void tst_QQuickLoader::asyncToSync2()
QCOMPARE(loader->progress(), 1.0);
QCOMPARE(loader->status(), QQuickLoader::Ready);
QCOMPARE(static_cast<QQuickItem*>(loader)->childItems().count(), 1);
-
- delete root;
}
void tst_QQuickLoader::loadedSignal()
{
+ QQmlEngine engine;
PeriodicIncubationController *controller = new PeriodicIncubationController;
QQmlIncubationController *previous = engine.incubationController();
engine.setIncubationController(controller);
@@ -1123,62 +1082,58 @@ void tst_QQuickLoader::loadedSignal()
// and then immediately setting active to false, causes the
// loader to be deactivated, including disabling the incubator.
QQmlComponent component(&engine, testFileUrl("loadedSignal.qml"));
- QObject *obj = component.create();
+ QScopedPointer<QObject> obj(component.create());
- QMetaObject::invokeMethod(obj, "triggerLoading");
+ QMetaObject::invokeMethod(obj.data(), "triggerLoading");
QTest::qWait(100); // ensure that loading would have finished if it wasn't deactivated
QCOMPARE(obj->property("loadCount").toInt(), 0);
QVERIFY(obj->property("success").toBool());
- QMetaObject::invokeMethod(obj, "triggerLoading");
+ QMetaObject::invokeMethod(obj.data(), "triggerLoading");
QTest::qWait(100);
QCOMPARE(obj->property("loadCount").toInt(), 0);
QVERIFY(obj->property("success").toBool());
- QMetaObject::invokeMethod(obj, "triggerMultipleLoad");
+ QMetaObject::invokeMethod(obj.data(), "triggerMultipleLoad");
controller->start();
QTest::qWait(100);
QTRY_COMPARE(obj->property("loadCount").toInt(), 1); // only one loaded signal should be emitted.
QVERIFY(obj->property("success").toBool());
-
- delete obj;
}
{
// ensure that an error doesn't result in the onLoaded signal being emitted.
QQmlComponent component(&engine, testFileUrl("loadedSignal.2.qml"));
- QObject *obj = component.create();
+ QScopedPointer<QObject> obj(component.create());
- QMetaObject::invokeMethod(obj, "triggerLoading");
+ QMetaObject::invokeMethod(obj.data(), "triggerLoading");
QTest::qWait(100);
QCOMPARE(obj->property("loadCount").toInt(), 0);
QVERIFY(obj->property("success").toBool());
-
- delete obj;
}
}
void tst_QQuickLoader::parented()
{
+ QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("parented.qml"));
- QQuickItem *root = qobject_cast<QQuickItem*>(component.create());
+ QScopedPointer<QQuickItem> root(qobject_cast<QQuickItem*>(component.create()));
QVERIFY(root);
QQuickItem *item = root->findChild<QQuickItem*>("comp");
QVERIFY(item);
- QCOMPARE(item->parentItem(), root);
+ QCOMPARE(item->parentItem(), root.data());
QCOMPARE(item->width(), 300.);
QCOMPARE(item->height(), 300.);
-
- delete root;
}
void tst_QQuickLoader::sizeBound()
{
+ QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("sizebound.qml"));
- QQuickItem *root = qobject_cast<QQuickItem*>(component.create());
+ QScopedPointer<QQuickItem> root(qobject_cast<QQuickItem*>(component.create()));
QVERIFY(root);
QQuickLoader *loader = root->findChild<QQuickLoader*>("loader");
QVERIFY(loader != 0);
@@ -1188,18 +1143,17 @@ void tst_QQuickLoader::sizeBound()
QCOMPARE(loader->width(), 50.0);
QCOMPARE(loader->height(), 60.0);
- QMetaObject::invokeMethod(root, "switchComponent");
+ QMetaObject::invokeMethod(root.data(), "switchComponent");
QCOMPARE(loader->width(), 80.0);
QCOMPARE(loader->height(), 90.0);
-
- delete root;
}
void tst_QQuickLoader::QTBUG_30183()
{
+ QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("/QTBUG_30183.qml"));
- QQuickLoader *loader = qobject_cast<QQuickLoader*>(component.create());
+ QScopedPointer<QQuickLoader> loader(qobject_cast<QQuickLoader*>(component.create()));
QVERIFY(loader != 0);
QCOMPARE(loader->width(), 240.0);
QCOMPARE(loader->height(), 120.0);
@@ -1209,8 +1163,6 @@ void tst_QQuickLoader::QTBUG_30183()
QVERIFY(rect);
QCOMPARE(rect->width(), 240.0);
QCOMPARE(rect->height(), 120.0);
-
- delete loader;
}
void tst_QQuickLoader::transientWindow() // QTBUG-52944
@@ -1295,6 +1247,7 @@ void tst_QQuickLoader::nestedTransientWindow() // QTBUG-52944
void tst_QQuickLoader::sourceComponentGarbageCollection()
{
+ QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("sourceComponentGarbageCollection.qml"));
QScopedPointer<QObject> obj(component.create());
QVERIFY(!obj.isNull());
@@ -1313,6 +1266,67 @@ void tst_QQuickLoader::sourceComponentGarbageCollection()
QCOMPARE(spy.count(), 1);
}
+// QTBUG-51995
+void tst_QQuickLoader::bindings()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("bindings.qml"));
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+
+ QQuickItem *game = object->property("game").value<QQuickItem*>();
+ QVERIFY(game);
+
+ QQuickLoader *loader = object->property("loader").value<QQuickLoader*>();
+ QVERIFY(loader);
+
+ QSignalSpy warningsSpy(&engine, SIGNAL(warnings(QList<QQmlError>)));
+
+ // Causes the Loader to become active
+ game->setState(QLatin1String("running"));
+ QTRY_VERIFY(loader->item());
+
+ // Causes the Loader to become inactive - should not cause binding errors
+ game->setState(QLatin1String("invalid"));
+ QTRY_VERIFY(!loader->item());
+
+ QString failureMessage;
+ if (!warningsSpy.isEmpty()) {
+ QDebug stream(&failureMessage);
+ stream << warningsSpy.first().first().value<QList<QQmlError>>();
+ }
+ QVERIFY2(warningsSpy.isEmpty(), qPrintable(failureMessage));
+}
+
+// QTBUG-47321
+void tst_QQuickLoader::parentErrors()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("parentErrors.qml"));
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+
+ QQuickLoader *loader = object->property("loader").value<QQuickLoader*>();
+ QVERIFY(loader);
+
+ QSignalSpy warningsSpy(&engine, SIGNAL(warnings(QList<QQmlError>)));
+
+ // Give the loader a component
+ loader->setSourceComponent(object->property("component").value<QQmlComponent*>());
+ QTRY_VERIFY(loader->item());
+
+ // Clear the loader's component; should not cause binding errors
+ loader->setSourceComponent(nullptr);
+ QTRY_VERIFY(!loader->item());
+
+ QString failureMessage;
+ if (!warningsSpy.isEmpty()) {
+ QDebug stream(&failureMessage);
+ stream << warningsSpy.first().first().value<QList<QQmlError>>();
+ }
+ QVERIFY2(warningsSpy.isEmpty(), qPrintable(failureMessage));
+}
+
QTEST_MAIN(tst_QQuickLoader)
#include "tst_qquickloader.moc"
diff --git a/tests/auto/quick/qquickmousearea/BLACKLIST b/tests/auto/quick/qquickmousearea/BLACKLIST
new file mode 100644
index 0000000000..817eb472a4
--- /dev/null
+++ b/tests/auto/quick/qquickmousearea/BLACKLIST
@@ -0,0 +1,3 @@
+# QTBUG-63786
+[pressedMultipleButtons]
+*
diff --git a/tests/auto/quick/qquickmousearea/data/mask.qml b/tests/auto/quick/qquickmousearea/data/mask.qml
new file mode 100644
index 0000000000..23e93f0310
--- /dev/null
+++ b/tests/auto/quick/qquickmousearea/data/mask.qml
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Ford Motor Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.11
+import Test 1.0
+
+Item {
+ id: root
+ property int clicked: 0
+ property int pressed: 0
+ property int released: 0
+
+ width: 200; height: 200
+
+ MouseArea {
+ id: mouseArea
+ width: 200; height: 200
+ onPressed: { root.pressed++ }
+ onClicked: { root.clicked++ }
+ onReleased: { root.released++ }
+
+ containsMask: CircleMask {
+ radius: mouseArea.width/2
+ }
+ }
+}
+
diff --git a/tests/auto/quick/qquickmousearea/qquickmousearea.pro b/tests/auto/quick/qquickmousearea/qquickmousearea.pro
index 3a4dfa946f..ee9d6dce2b 100644
--- a/tests/auto/quick/qquickmousearea/qquickmousearea.pro
+++ b/tests/auto/quick/qquickmousearea/qquickmousearea.pro
@@ -6,6 +6,8 @@ HEADERS += ../../shared/testhttpserver.h
SOURCES += tst_qquickmousearea.cpp \
../../shared/testhttpserver.cpp
+OTHER_FILES += $$files(data/*.qml)
+
include (../../shared/util.pri)
include (../shared/util.pri)
diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
index 12c6233ded..4fe01787fa 100644
--- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
+++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
@@ -68,16 +68,48 @@ static bool initView(QQuickView &v, const QUrl &url, bool moveMouseOut, QByteArr
return true;
}
+class CircleMask : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal radius READ radius WRITE setRadius NOTIFY radiusChanged)
+
+public:
+ virtual ~CircleMask() {}
+ qreal radius() const { return m_radius; }
+ void setRadius(qreal radius)
+ {
+ if (m_radius == radius)
+ return;
+ m_radius = radius;
+ emit radiusChanged();
+ }
+
+ Q_INVOKABLE bool contains(const QPointF &point) const
+ {
+ QPointF center(m_radius, m_radius);
+ QLineF line(center, point);
+ return line.length() <= m_radius;
+ }
+
+signals:
+ void radiusChanged();
+
+private:
+ qreal m_radius;
+};
+
class tst_QQuickMouseArea: public QQmlDataTest
{
Q_OBJECT
public:
tst_QQuickMouseArea()
: device(nullptr)
- {}
+ {
+ qmlRegisterType<CircleMask>("Test", 1, 0, "CircleMask");
+ }
private slots:
- void initTestCase() Q_DECL_OVERRIDE;
+ void initTestCase() override;
void dragProperties();
void resetDrag();
void dragging_data() { acceptedButton_data(); }
@@ -132,6 +164,7 @@ private slots:
void pressAndHold();
void pressOneAndTapAnother_data();
void pressOneAndTapAnother();
+ void mask();
private:
int startDragDistance() const {
@@ -1295,6 +1328,10 @@ void tst_QQuickMouseArea::hoverPropagation()
void tst_QQuickMouseArea::hoverVisible()
{
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+
QQuickView window;
QByteArray errorMessage;
QVERIFY2(initView(window, testFileUrl("hoverVisible.qml"), true, &errorMessage), errorMessage.constData());
@@ -2183,7 +2220,8 @@ void tst_QQuickMouseArea::pressOneAndTapAnother_data()
QTest::newRow("press mouse, tap touch, release mouse") << true << false; // QTBUG-64249 as written
QTest::newRow("press touch, press mouse, release touch, release mouse") << false << false;
QTest::newRow("press mouse, press touch, release mouse, release touch") << true << true;
- QTest::newRow("press touch, click mouse, release touch") << false << true;
+ // TODO fix in a separate patch after the 5.9->5.10 merge
+ // QTest::newRow("press touch, click mouse, release touch") << false << true;
}
void tst_QQuickMouseArea::pressOneAndTapAnother()
@@ -2242,6 +2280,34 @@ void tst_QQuickMouseArea::pressOneAndTapAnother()
}
}
+void tst_QQuickMouseArea::mask()
+{
+ QQuickView window;
+ QByteArray errorMessage;
+ QVERIFY2(initView(window, testFileUrl("mask.qml"), true, &errorMessage), errorMessage.constData());
+ window.show();
+ window.requestActivate();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+ QQuickItem *root = window.rootObject();
+ QVERIFY(root != 0);
+
+ // click inside the mask, and verify it registers
+ QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(100,100));
+ QTest::mouseRelease(&window, Qt::LeftButton, 0, QPoint(100,100));
+
+ QCOMPARE(window.rootObject()->property("pressed").toInt(), 1);
+ QCOMPARE(window.rootObject()->property("released").toInt(), 1);
+ QCOMPARE(window.rootObject()->property("clicked").toInt(), 1);
+
+ // click outside the mask (but inside the MouseArea), and verify it doesn't register
+ QTest::mousePress(&window, Qt::LeftButton, 0, QPoint(10,10));
+ QTest::mouseRelease(&window, Qt::LeftButton, 0, QPoint(10,10));
+
+ QCOMPARE(window.rootObject()->property("pressed").toInt(), 1);
+ QCOMPARE(window.rootObject()->property("released").toInt(), 1);
+ QCOMPARE(window.rootObject()->property("clicked").toInt(), 1);
+}
+
QTEST_MAIN(tst_QQuickMouseArea)
#include "tst_qquickmousearea.moc"
diff --git a/tests/auto/quick/qquickopenglinfo/BLACKLIST b/tests/auto/quick/qquickopenglinfo/BLACKLIST
new file mode 100644
index 0000000000..7ac31e1cd0
--- /dev/null
+++ b/tests/auto/quick/qquickopenglinfo/BLACKLIST
@@ -0,0 +1,3 @@
+# QTBUG-65615
+[testProperties]
+b2qt
diff --git a/tests/auto/quick/qquickpainteditem/BLACKLIST b/tests/auto/quick/qquickpainteditem/BLACKLIST
new file mode 100644
index 0000000000..9b58325f6c
--- /dev/null
+++ b/tests/auto/quick/qquickpainteditem/BLACKLIST
@@ -0,0 +1,27 @@
+# QTBUG-63053
+[opaquePainting]
+b2qt
+
+# QTBUG-63053
+[antialiasing]
+b2qt
+
+# QTBUG-63053
+[mipmap]
+b2qt
+
+# QTBUG-63053
+[performanceHints]
+b2qt
+
+# QTBUG-63053
+[contentScale]
+b2qt
+
+# QTBUG-63053
+[contentsBoundingRect]
+b2qt
+
+# QTBUG-63053
+[fillColor]
+b2qt
diff --git a/tests/auto/quick/qquickpath/data/anglearc.qml b/tests/auto/quick/qquickpath/data/anglearc.qml
new file mode 100644
index 0000000000..cbe41c1ac8
--- /dev/null
+++ b/tests/auto/quick/qquickpath/data/anglearc.qml
@@ -0,0 +1,12 @@
+import QtQuick 2.11
+
+Path {
+ PathAngleArc {
+ centerX: 100
+ centerY: 100
+ radiusX: 50
+ radiusY: 50
+ startAngle: 45
+ sweepAngle: 90
+ }
+}
diff --git a/tests/auto/quick/qquickpath/tst_qquickpath.cpp b/tests/auto/quick/qquickpath/tst_qquickpath.cpp
index 2ec95840e1..106d7afd85 100644
--- a/tests/auto/quick/qquickpath/tst_qquickpath.cpp
+++ b/tests/auto/quick/qquickpath/tst_qquickpath.cpp
@@ -41,6 +41,7 @@ public:
private slots:
void arc();
+ void angleArc();
void catmullromCurve();
void closedCatmullromCurve();
void svg();
@@ -82,6 +83,45 @@ void tst_QuickPath::arc()
QCOMPARE(pos, QPointF(100,100));
}
+void tst_QuickPath::angleArc()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("anglearc.qml"));
+ QQuickPath *obj = qobject_cast<QQuickPath*>(c.create());
+ QVERIFY(obj != 0);
+
+ QQmlListReference list(obj, "pathElements");
+ QCOMPARE(list.count(), 1);
+
+ QQuickPathAngleArc* arc = qobject_cast<QQuickPathAngleArc*>(list.at(0));
+ QVERIFY(arc != 0);
+ QCOMPARE(arc->centerX(), 100.);
+ QCOMPARE(arc->centerY(), 100.);
+ QCOMPARE(arc->radiusX(), 50.);
+ QCOMPARE(arc->radiusY(), 50.);
+ QCOMPARE(arc->startAngle(), 45.);
+ QCOMPARE(arc->sweepAngle(), 90.);
+ QCOMPARE(arc->moveToStart(), true);
+
+ QPainterPath path = obj->path();
+ QVERIFY(path != QPainterPath());
+
+ // using QPoint to do fuzzy compare
+ QPointF pos = obj->pointAt(0);
+ QCOMPARE(pos.toPoint(), QPoint(135,135));
+ pos = obj->pointAt(.25);
+ QCOMPARE(pos.toPoint(), QPoint(119,146));
+ pos = obj->pointAt(.75);
+ QCOMPARE(pos.toPoint(), QPoint(81,146));
+ pos = obj->pointAt(1);
+ QCOMPARE(pos.toPoint(), QPoint(65,135));
+
+ // if moveToStart is false, we should have a line starting from startX/Y
+ arc->setMoveToStart(false);
+ pos = obj->pointAt(0);
+ QCOMPARE(pos, QPointF(0,0));
+}
+
void tst_QuickPath::catmullromCurve()
{
QQmlEngine engine;
diff --git a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp
index cbef0fcc8d..061f71aeb0 100644
--- a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp
+++ b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp
@@ -2351,7 +2351,7 @@ void tst_QQuickPathView::qtbug37815()
QTest::qWait(1000);
QQuickPathView *pathView = findItem<QQuickPathView>(window->rootObject(), "pathView");
- QVERIFY(pathView != Q_NULLPTR);
+ QVERIFY(pathView != nullptr);
const int pathItemCount = pathView->pathItemCount();
const int cacheItemCount = pathView->cacheItemCount();
@@ -2421,7 +2421,7 @@ void tst_QQuickPathView::qtbug53464()
QVERIFY(QTest::qWaitForWindowActive(window.data()));
QQuickPathView *pathView = findItem<QQuickPathView>(window->rootObject(), "pathView");
- QVERIFY(pathView != Q_NULLPTR);
+ QVERIFY(pathView != nullptr);
const int currentIndex = pathView->currentIndex();
QCOMPARE(currentIndex, 8);
diff --git a/tests/auto/quick/qquickpixmapcache/qquickpixmapcache.pro b/tests/auto/quick/qquickpixmapcache/qquickpixmapcache.pro
index 185eb2c213..52b798e829 100644
--- a/tests/auto/quick/qquickpixmapcache/qquickpixmapcache.pro
+++ b/tests/auto/quick/qquickpixmapcache/qquickpixmapcache.pro
@@ -5,7 +5,6 @@ macx:CONFIG -= app_bundle
SOURCES += tst_qquickpixmapcache.cpp \
../../shared/testhttpserver.cpp
HEADERS += ../../shared/testhttpserver.h
-INCLUDEPATH += ../../shared/
include (../../shared/util.pri)
diff --git a/tests/auto/quick/qquickrectangle/data/gradient-multiple.qml b/tests/auto/quick/qquickrectangle/data/gradient-multiple.qml
new file mode 100644
index 0000000000..d58c857008
--- /dev/null
+++ b/tests/auto/quick/qquickrectangle/data/gradient-multiple.qml
@@ -0,0 +1,30 @@
+import QtQuick 2.0
+
+Item {
+ property alias firstRectangle: r1
+ property alias secondRectangle: r2
+ Rectangle {
+ id: r1
+ gradient: someObject.someGradient
+ anchors.fill: parent
+ }
+ Rectangle {
+ id: r2
+ gradient: someObject.someGradient
+ anchors.fill: parent
+ }
+
+ function changeGradient() {
+ firstStop.color = "red"
+ secondStop.color = "blue"
+ }
+
+ QtObject {
+ id: someObject
+ property Gradient someGradient: Gradient {
+ GradientStop { id: firstStop; position: 0.0; color: "gray" }
+ GradientStop { id: secondStop; position: 1.0; color: "white" }
+ }
+ }
+}
+
diff --git a/tests/auto/quick/qquickrectangle/data/gradient-separate.qml b/tests/auto/quick/qquickrectangle/data/gradient-separate.qml
new file mode 100644
index 0000000000..8ae3f3296b
--- /dev/null
+++ b/tests/auto/quick/qquickrectangle/data/gradient-separate.qml
@@ -0,0 +1,20 @@
+import QtQuick 2.0
+
+Rectangle {
+
+ function changeGradient() {
+ firstStop.color = "red"
+ secondStop.color = "blue"
+ }
+
+ QtObject {
+ id: someObject
+ property Gradient someGradient: Gradient {
+ GradientStop { id: firstStop; position: 0.0; color: "gray" }
+ GradientStop { id: secondStop; position: 1.0; color: "white" }
+ }
+ }
+
+ gradient: someObject.someGradient
+}
+
diff --git a/tests/auto/quick/qquickrectangle/tst_qquickrectangle.cpp b/tests/auto/quick/qquickrectangle/tst_qquickrectangle.cpp
index 65c7e387a0..2aaad867bf 100644
--- a/tests/auto/quick/qquickrectangle/tst_qquickrectangle.cpp
+++ b/tests/auto/quick/qquickrectangle/tst_qquickrectangle.cpp
@@ -32,6 +32,7 @@
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlcomponent.h>
#include <QtQuick/qquickview.h>
+#include <private/qquickitem_p.h>
#include <private/qquickrectangle_p.h>
#include "../../shared/util.h"
@@ -46,6 +47,8 @@ private slots:
void color();
void gradient();
void gradient_border();
+ void gradient_separate();
+ void gradient_multiple();
void antialiasing();
private:
@@ -67,6 +70,10 @@ void tst_qquickrectangle::color()
QVERIFY(QTest::qWaitForWindowExposed(&view));
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimimal platforms", Abort);
+
QImage image = view.grabWindow();
QVERIFY(image.pixel(0,0) == QColor("#020202").rgba());
}
@@ -111,6 +118,62 @@ void tst_qquickrectangle::gradient_border()
QVERIFY(QTest::qWaitForWindowExposed(&view));
}
+// A gradient not defined inline with the Rectangle using it should still change
+// that Rectangle.
+void tst_qquickrectangle::gradient_separate()
+{
+ QQuickView view;
+ view.setSource(testFileUrl("gradient-separate.qml"));
+ view.show();
+
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(view.rootObject());
+ QVERIFY(rect);
+
+ // Start off clean
+ QQuickItemPrivate *rectPriv = QQuickItemPrivate::get(rect);
+ bool isDirty = rectPriv->dirtyAttributes & QQuickItemPrivate::Content;
+ QVERIFY(!isDirty);
+
+ QMetaObject::invokeMethod(rect, "changeGradient");
+
+ // Changing the gradient should have scheduled an update of the item.
+ isDirty = rectPriv->dirtyAttributes & QQuickItemPrivate::Content;
+ QVERIFY(isDirty);
+}
+
+// When a gradient is changed, every Rectangle connected to it must update.
+void tst_qquickrectangle::gradient_multiple()
+{
+ QQuickView view;
+ view.setSource(testFileUrl("gradient-multiple.qml"));
+ view.show();
+
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ QQuickRectangle *firstRect = qobject_cast<QQuickRectangle*>(view.rootObject()->property("firstRectangle").value<QObject*>());
+ QQuickRectangle *secondRect = qobject_cast<QQuickRectangle*>(view.rootObject()->property("secondRectangle").value<QObject*>());
+ QVERIFY(firstRect);
+ QVERIFY(secondRect);
+
+ // Start off clean
+ QQuickItemPrivate *firstRectPriv = QQuickItemPrivate::get(firstRect);
+ QQuickItemPrivate *secondRectPriv = QQuickItemPrivate::get(secondRect);
+ bool firstIsDirty = firstRectPriv->dirtyAttributes & QQuickItemPrivate::Content;
+ bool secondIsDirty = secondRectPriv->dirtyAttributes & QQuickItemPrivate::Content;
+ QVERIFY(!firstIsDirty);
+ QVERIFY(!secondIsDirty);
+
+ QMetaObject::invokeMethod(view.rootObject(), "changeGradient");
+
+ // Changing the gradient should have scheduled an update of both items
+ firstIsDirty = firstRectPriv->dirtyAttributes & QQuickItemPrivate::Content;
+ secondIsDirty = secondRectPriv->dirtyAttributes & QQuickItemPrivate::Content;
+ QVERIFY(firstIsDirty);
+ QVERIFY(secondIsDirty);
+}
+
void tst_qquickrectangle::antialiasing()
{
QQmlComponent component(&engine);
diff --git a/tests/auto/quick/qquickscreen/tst_qquickscreen.cpp b/tests/auto/quick/qquickscreen/tst_qquickscreen.cpp
index 26b687a4a6..0a3796402a 100644
--- a/tests/auto/quick/qquickscreen/tst_qquickscreen.cpp
+++ b/tests/auto/quick/qquickscreen/tst_qquickscreen.cpp
@@ -113,6 +113,9 @@ void tst_qquickscreen::fullScreenList()
QQuickScreenInfo *info = qobject_cast<QQuickScreenInfo *>(screensArray.property(i).toQObject());
QVERIFY(info != nullptr);
QCOMPARE(screenList[i]->name(), info->name());
+ QCOMPARE(screenList[i]->manufacturer(), info->manufacturer());
+ QCOMPARE(screenList[i]->model(), info->model());
+ QCOMPARE(screenList[i]->serialNumber(), info->serialNumber());
QCOMPARE(screenList[i]->size().width(), info->width());
QCOMPARE(screenList[i]->size().height(), info->height());
QCOMPARE(screenList[i]->availableVirtualGeometry().width(), info->desktopAvailableWidth());
diff --git a/tests/auto/quick/qquickshape/BLACKLIST b/tests/auto/quick/qquickshape/BLACKLIST
new file mode 100644
index 0000000000..d0ebc2f505
--- /dev/null
+++ b/tests/auto/quick/qquickshape/BLACKLIST
@@ -0,0 +1,8 @@
+[render]
+osx ci
+[renderWithMultipleSp]
+osx ci
+[radialGrad]
+osx ci
+[conicalGrad]
+osx ci
diff --git a/tests/auto/quick/qquickshape/data/pathitem1.qml b/tests/auto/quick/qquickshape/data/pathitem1.qml
new file mode 100644
index 0000000000..29ca67b0bb
--- /dev/null
+++ b/tests/auto/quick/qquickshape/data/pathitem1.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.9
+import tst_qquickpathitem 1.0
+
+Shape {
+}
diff --git a/tests/auto/quick/qquickshape/data/pathitem2.qml b/tests/auto/quick/qquickshape/data/pathitem2.qml
new file mode 100644
index 0000000000..a255a37af6
--- /dev/null
+++ b/tests/auto/quick/qquickshape/data/pathitem2.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.9
+import tst_qquickpathitem 1.0
+
+Shape {
+ ShapePath { }
+ ShapePath { }
+}
diff --git a/tests/auto/quick/qquickshape/data/pathitem3.png b/tests/auto/quick/qquickshape/data/pathitem3.png
new file mode 100644
index 0000000000..a8b4483c96
--- /dev/null
+++ b/tests/auto/quick/qquickshape/data/pathitem3.png
Binary files differ
diff --git a/tests/auto/quick/qquickshape/data/pathitem3.qml b/tests/auto/quick/qquickshape/data/pathitem3.qml
new file mode 100644
index 0000000000..8328f2fc33
--- /dev/null
+++ b/tests/auto/quick/qquickshape/data/pathitem3.qml
@@ -0,0 +1,33 @@
+import QtQuick 2.9
+import tst_qquickpathitem 1.0
+
+Item {
+ width: 200
+ height: 150
+
+ Shape {
+ vendorExtensionsEnabled: false
+ objectName: "pathItem"
+ anchors.fill: parent
+
+ ShapePath {
+ strokeWidth: 4
+ strokeColor: "red"
+ fillGradient: LinearGradient {
+ x1: 20; y1: 20
+ x2: 180; y2: 130
+ GradientStop { position: 0; color: "blue" }
+ GradientStop { position: 0.2; color: "green" }
+ GradientStop { position: 0.4; color: "red" }
+ GradientStop { position: 0.6; color: "yellow" }
+ GradientStop { position: 1; color: "cyan" }
+ }
+ strokeStyle: ShapePath.DashLine
+ dashPattern: [ 1, 4 ]
+ startX: 20; startY: 20
+ PathLine { x: 180; y: 130 }
+ PathLine { x: 20; y: 130 }
+ PathLine { x: 20; y: 20 }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickshape/data/pathitem4.png b/tests/auto/quick/qquickshape/data/pathitem4.png
new file mode 100644
index 0000000000..3a988ba249
--- /dev/null
+++ b/tests/auto/quick/qquickshape/data/pathitem4.png
Binary files differ
diff --git a/tests/auto/quick/qquickshape/data/pathitem4.qml b/tests/auto/quick/qquickshape/data/pathitem4.qml
new file mode 100644
index 0000000000..635113416f
--- /dev/null
+++ b/tests/auto/quick/qquickshape/data/pathitem4.qml
@@ -0,0 +1,56 @@
+import QtQuick 2.9
+import tst_qquickpathitem 1.0
+
+Item {
+ width: 200
+ height: 150
+
+ Shape {
+ vendorExtensionsEnabled: false
+ objectName: "pathItem"
+ anchors.fill: parent
+
+ ShapePath {
+ strokeColor: "red"
+ fillColor: "green"
+ startX: 40; startY: 30
+ PathQuad { x: 50; y: 80; controlX: 0; controlY: 80 }
+ PathLine { x: 150; y: 80 }
+ PathQuad { x: 160; y: 30; controlX: 200; controlY: 80 }
+ }
+
+ ShapePath {
+ strokeWidth: 10
+ fillColor: "transparent"
+ strokeColor: "blue"
+ startX: 40; startY: 30
+ PathCubic { x: 50; y: 80; control1X: 0; control1Y: 80; control2X: 100; control2Y: 100 }
+ }
+
+ ShapePath {
+ fillGradient: LinearGradient {
+ y2: 150
+ GradientStop { position: 0; color: "yellow" }
+ GradientStop { position: 1; color: "green" }
+ }
+
+ startX: 10; startY: 100
+ PathArc {
+ relativeX: 50; y: 100
+ radiusX: 25; radiusY: 25
+ }
+ PathArc {
+ relativeX: 50; y: 100
+ radiusX: 25; radiusY: 35
+ }
+ PathArc {
+ relativeX: 50; y: 100
+ radiusX: 25; radiusY: 60
+ }
+ PathArc {
+ relativeX: 50; y: 100
+ radiusX: 50; radiusY: 120
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickshape/data/pathitem5.png b/tests/auto/quick/qquickshape/data/pathitem5.png
new file mode 100644
index 0000000000..cb5cfd25dc
--- /dev/null
+++ b/tests/auto/quick/qquickshape/data/pathitem5.png
Binary files differ
diff --git a/tests/auto/quick/qquickshape/data/pathitem5.qml b/tests/auto/quick/qquickshape/data/pathitem5.qml
new file mode 100644
index 0000000000..1bd465d5c0
--- /dev/null
+++ b/tests/auto/quick/qquickshape/data/pathitem5.qml
@@ -0,0 +1,37 @@
+import QtQuick 2.9
+import tst_qquickpathitem 1.0
+
+Item {
+ width: 200
+ height: 150
+
+ Shape {
+ vendorExtensionsEnabled: false
+ objectName: "pathItem"
+ anchors.fill: parent
+
+ ShapePath {
+ strokeWidth: 4
+ strokeColor: "red"
+ fillGradient: RadialGradient {
+ centerX: 100; centerY: 100; centerRadius: 100
+ focalX: 100; focalY: 100; focalRadius: 10
+ GradientStop { position: 0; color: "#ffffff" }
+ GradientStop { position: 0.11; color: "#f9ffa0" }
+ GradientStop { position: 0.13; color: "#f9ff99" }
+ GradientStop { position: 0.14; color: "#f3ff86" }
+ GradientStop { position: 0.49; color: "#93b353" }
+ GradientStop { position: 0.87; color: "#264619" }
+ GradientStop { position: 0.96; color: "#0c1306" }
+ GradientStop { position: 1; color: "#000000" }
+ }
+ fillColor: "blue" // ignored with the gradient set
+ strokeStyle: ShapePath.DashLine
+ dashPattern: [ 1, 4 ]
+ startX: 20; startY: 20
+ PathLine { x: 180; y: 130 }
+ PathLine { x: 20; y: 130 }
+ PathLine { x: 20; y: 20 }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickshape/data/pathitem6.png b/tests/auto/quick/qquickshape/data/pathitem6.png
new file mode 100644
index 0000000000..d9e53d6c00
--- /dev/null
+++ b/tests/auto/quick/qquickshape/data/pathitem6.png
Binary files differ
diff --git a/tests/auto/quick/qquickshape/data/pathitem6.qml b/tests/auto/quick/qquickshape/data/pathitem6.qml
new file mode 100644
index 0000000000..fafcc48196
--- /dev/null
+++ b/tests/auto/quick/qquickshape/data/pathitem6.qml
@@ -0,0 +1,35 @@
+import QtQuick 2.9
+import tst_qquickpathitem 1.0
+
+Item {
+ width: 200
+ height: 150
+
+ Shape {
+ vendorExtensionsEnabled: false
+ objectName: "pathItem"
+ anchors.fill: parent
+
+ ShapePath {
+ strokeWidth: 4
+ strokeColor: "red"
+ fillGradient: ConicalGradient {
+ centerX: 100; centerY: 100; angle: 45
+ GradientStop { position: 0; color: "#00000000" }
+ GradientStop { position: 0.10; color: "#ffe0cc73" }
+ GradientStop { position: 0.17; color: "#ffc6a006" }
+ GradientStop { position: 0.46; color: "#ff600659" }
+ GradientStop { position: 0.72; color: "#ff0680ac" }
+ GradientStop { position: 0.92; color: "#ffb9d9e6" }
+ GradientStop { position: 1.00; color: "#00000000" }
+ }
+ fillColor: "blue" // ignored with the gradient set
+ strokeStyle: ShapePath.DashLine
+ dashPattern: [ 1, 4 ]
+ startX: 20; startY: 20
+ PathLine { x: 180; y: 130 }
+ PathLine { x: 20; y: 130 }
+ PathLine { x: 20; y: 20 }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickshape/qquickshape.pro b/tests/auto/quick/qquickshape/qquickshape.pro
new file mode 100644
index 0000000000..29c3502b86
--- /dev/null
+++ b/tests/auto/quick/qquickshape/qquickshape.pro
@@ -0,0 +1,35 @@
+CONFIG += testcase
+TARGET = tst_qquickshape
+macos:CONFIG -= app_bundle
+
+SOURCES += tst_qquickshape.cpp
+
+include (../../shared/util.pri)
+include (../shared/util.pri)
+
+TESTDATA = data/*
+
+HEADERS += \
+ ../../../../src/imports/shapes/qquickshape_p.h \
+ ../../../../src/imports/shapes/qquickshape_p_p.h \
+ ../../../../src/imports/shapes/qquickshapegenericrenderer_p.h \
+ ../../../../src/imports/shapes/qquickshapesoftwarerenderer_p.h
+
+SOURCES += \
+ ../../../../src/imports/shapes/qquickshape.cpp \
+ ../../../../src/imports/shapes/qquickshapegenericrenderer.cpp \
+ ../../../../src/imports/shapes/qquickshapesoftwarerenderer.cpp
+
+qtConfig(opengl) {
+ HEADERS += \
+ ../../../../src/imports/shapes/qquicknvprfunctions_p.h \
+ ../../../../src/imports/shapes/qquicknvprfunctions_p_p.h \
+ ../../../../src/imports/shapes/qquickshapenvprrenderer_p.h
+
+ SOURCES += \
+ ../../../../src/imports/shapes/qquicknvprfunctions.cpp \
+ ../../../../src/imports/shapes/qquickshapenvprrenderer.cpp
+}
+
+QT += core-private gui-private qml-private quick-private testlib
+qtHaveModule(widgets): QT += widgets
diff --git a/tests/auto/quick/qquickshape/tst_qquickshape.cpp b/tests/auto/quick/qquickshape/tst_qquickshape.cpp
new file mode 100644
index 0000000000..2a349d2013
--- /dev/null
+++ b/tests/auto/quick/qquickshape/tst_qquickshape.cpp
@@ -0,0 +1,304 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QtQuick/qquickview.h>
+#include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlcomponent.h>
+#include <QtQml/qqmlcontext.h>
+#include <QtQml/qqmlexpression.h>
+#include <QtQml/qqmlincubator.h>
+#include "../../../../src/imports/shapes/qquickshape_p.h"
+
+#include "../../shared/util.h"
+#include "../shared/viewtestutil.h"
+#include "../shared/visualtestutil.h"
+
+using namespace QQuickViewTestUtil;
+using namespace QQuickVisualTestUtil;
+
+class tst_QQuickShape : public QQmlDataTest
+{
+ Q_OBJECT
+public:
+ tst_QQuickShape();
+
+private slots:
+ void initValues();
+ void vpInitValues();
+ void basicShape();
+ void changeSignals();
+ void render();
+ void renderWithMultipleSp();
+ void radialGrad();
+ void conicalGrad();
+};
+
+tst_QQuickShape::tst_QQuickShape()
+{
+ // Force the software backend to get reliable rendering results regardless of the hw and drivers.
+ QQuickWindow::setSceneGraphBackend(QSGRendererInterface::Software);
+
+ const char *uri = "tst_qquickpathitem";
+ qmlRegisterType<QQuickShape>(uri, 1, 0, "Shape");
+ qmlRegisterType<QQuickShapePath>(uri, 1, 0, "ShapePath");
+ qmlRegisterUncreatableType<QQuickShapeGradient>(uri, 1, 0, "ShapeGradient", QQuickShapeGradient::tr("ShapeGradient is an abstract base class"));
+ qmlRegisterType<QQuickShapeLinearGradient>(uri, 1, 0, "LinearGradient");
+ qmlRegisterType<QQuickShapeRadialGradient>(uri, 1, 0, "RadialGradient");
+ qmlRegisterType<QQuickShapeConicalGradient>(uri, 1, 0, "ConicalGradient");
+}
+
+void tst_QQuickShape::initValues()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("pathitem1.qml"));
+ QQuickShape *obj = qobject_cast<QQuickShape *>(c.create());
+
+ QVERIFY(obj != nullptr);
+ QVERIFY(obj->rendererType() == QQuickShape::UnknownRenderer);
+ QVERIFY(!obj->asynchronous());
+ QVERIFY(obj->vendorExtensionsEnabled());
+ QVERIFY(obj->status() == QQuickShape::Null);
+ auto vps = obj->data();
+ QVERIFY(vps.count(&vps) == 0);
+
+ delete obj;
+}
+
+void tst_QQuickShape::vpInitValues()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("pathitem2.qml"));
+ QQuickShape *obj = qobject_cast<QQuickShape *>(c.create());
+
+ QVERIFY(obj != nullptr);
+ QVERIFY(obj->rendererType() == QQuickShape::UnknownRenderer);
+ QVERIFY(!obj->asynchronous());
+ QVERIFY(obj->vendorExtensionsEnabled());
+ QVERIFY(obj->status() == QQuickShape::Null);
+ auto vps = obj->data();
+ QVERIFY(vps.count(&vps) == 2);
+
+ QQuickShapePath *vp = qobject_cast<QQuickShapePath *>(vps.at(&vps, 0));
+ QVERIFY(vp != nullptr);
+ QQmlListReference pathList(vp, "pathElements");
+ QCOMPARE(pathList.count(), 0);
+ QCOMPARE(vp->strokeColor(), QColor(Qt::white));
+ QCOMPARE(vp->strokeWidth(), 1.0f);
+ QCOMPARE(vp->fillColor(), QColor(Qt::white));
+ QCOMPARE(vp->fillRule(), QQuickShapePath::OddEvenFill);
+ QCOMPARE(vp->joinStyle(), QQuickShapePath::BevelJoin);
+ QCOMPARE(vp->miterLimit(), 2);
+ QCOMPARE(vp->capStyle(), QQuickShapePath::SquareCap);
+ QCOMPARE(vp->strokeStyle(), QQuickShapePath::SolidLine);
+ QCOMPARE(vp->dashOffset(), 0.0f);
+ QCOMPARE(vp->dashPattern(), QVector<qreal>() << 4 << 2);
+ QVERIFY(!vp->fillGradient());
+
+ delete obj;
+}
+
+void tst_QQuickShape::basicShape()
+{
+ QScopedPointer<QQuickView> window(createView());
+
+ window->setSource(testFileUrl("pathitem3.qml"));
+ qApp->processEvents();
+
+ QQuickShape *obj = findItem<QQuickShape>(window->rootObject(), "pathItem");
+ QVERIFY(obj != nullptr);
+ QQmlListReference list(obj, "data");
+ QCOMPARE(list.count(), 1);
+ QQuickShapePath *vp = qobject_cast<QQuickShapePath *>(list.at(0));
+ QVERIFY(vp != nullptr);
+ QCOMPARE(vp->strokeWidth(), 4.0f);
+ QVERIFY(vp->fillGradient() != nullptr);
+ QCOMPARE(vp->strokeStyle(), QQuickShapePath::DashLine);
+
+ vp->setStrokeWidth(5.0f);
+ QCOMPARE(vp->strokeWidth(), 5.0f);
+
+ QQuickShapeLinearGradient *lgrad = qobject_cast<QQuickShapeLinearGradient *>(vp->fillGradient());
+ QVERIFY(lgrad != nullptr);
+ QCOMPARE(lgrad->spread(), QQuickShapeGradient::PadSpread);
+ QCOMPARE(lgrad->x1(), 20.0f);
+ QQmlListReference stopList(lgrad, "stops");
+ QCOMPARE(stopList.count(), 5);
+ QVERIFY(stopList.at(2) != nullptr);
+
+ QQuickPath *path = vp;
+ QCOMPARE(path->startX(), 20.0f);
+ QQmlListReference pathList(path, "pathElements");
+ QCOMPARE(pathList.count(), 3);
+}
+
+void tst_QQuickShape::changeSignals()
+{
+ QScopedPointer<QQuickView> window(createView());
+
+ window->setSource(testFileUrl("pathitem3.qml"));
+ qApp->processEvents();
+
+ QQuickShape *obj = findItem<QQuickShape>(window->rootObject(), "pathItem");
+ QVERIFY(obj != nullptr);
+
+ QSignalSpy asyncPropSpy(obj, SIGNAL(asynchronousChanged()));
+ obj->setAsynchronous(true);
+ obj->setAsynchronous(false);
+ QCOMPARE(asyncPropSpy.count(), 2);
+
+ QQmlListReference list(obj, "data");
+ QQuickShapePath *vp = qobject_cast<QQuickShapePath *>(list.at(0));
+ QVERIFY(vp != nullptr);
+
+ // Verify that VisualPath property changes emit shapePathChanged().
+ QSignalSpy vpChangeSpy(vp, SIGNAL(shapePathChanged()));
+ QSignalSpy strokeColorPropSpy(vp, SIGNAL(strokeColorChanged()));
+ vp->setStrokeColor(Qt::blue);
+ vp->setStrokeWidth(1.0f);
+ QQuickShapeGradient *g = vp->fillGradient();
+ vp->setFillGradient(nullptr);
+ vp->setFillColor(Qt::yellow);
+ vp->setFillRule(QQuickShapePath::WindingFill);
+ vp->setJoinStyle(QQuickShapePath::MiterJoin);
+ vp->setMiterLimit(5);
+ vp->setCapStyle(QQuickShapePath::RoundCap);
+ vp->setDashOffset(10);
+ vp->setDashPattern(QVector<qreal>() << 1 << 2 << 3 << 4);
+ QCOMPARE(strokeColorPropSpy.count(), 1);
+ QCOMPARE(vpChangeSpy.count(), 10);
+
+ // Verify that property changes from Path and its elements bubble up and result in shapePathChanged().
+ QQuickPath *path = vp;
+ path->setStartX(30);
+ QCOMPARE(vpChangeSpy.count(), 11);
+ QQmlListReference pathList(path, "pathElements");
+ qobject_cast<QQuickPathLine *>(pathList.at(1))->setY(200);
+ QCOMPARE(vpChangeSpy.count(), 12);
+
+ // Verify that property changes from the gradient bubble up and result in shapePathChanged().
+ vp->setFillGradient(g);
+ QCOMPARE(vpChangeSpy.count(), 13);
+ QQuickShapeLinearGradient *lgrad = qobject_cast<QQuickShapeLinearGradient *>(g);
+ lgrad->setX2(200);
+ QCOMPARE(vpChangeSpy.count(), 14);
+ QQmlListReference stopList(lgrad, "stops");
+ QCOMPARE(stopList.count(), 5);
+ qobject_cast<QQuickGradientStop *>(stopList.at(1))->setPosition(0.3);
+ QCOMPARE(vpChangeSpy.count(), 15);
+ qobject_cast<QQuickGradientStop *>(stopList.at(1))->setColor(Qt::black);
+ QCOMPARE(vpChangeSpy.count(), 16);
+}
+
+void tst_QQuickShape::render()
+{
+ QScopedPointer<QQuickView> window(createView());
+
+ window->setSource(testFileUrl("pathitem3.qml"));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimimal platforms", Abort);
+
+ QImage img = window->grabWindow();
+ QVERIFY(!img.isNull());
+
+ QImage refImg(testFileUrl("pathitem3.png").toLocalFile());
+ QVERIFY(!refImg.isNull());
+
+ QVERIFY(QQuickVisualTestUtil::compareImages(img.convertToFormat(refImg.format()), refImg));
+}
+
+void tst_QQuickShape::renderWithMultipleSp()
+{
+ QScopedPointer<QQuickView> window(createView());
+
+ window->setSource(testFileUrl("pathitem4.qml"));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimimal platforms", Abort);
+
+ QImage img = window->grabWindow();
+ QVERIFY(!img.isNull());
+
+ QImage refImg(testFileUrl("pathitem4.png").toLocalFile());
+ QVERIFY(!refImg.isNull());
+
+ QVERIFY(QQuickVisualTestUtil::compareImages(img.convertToFormat(refImg.format()), refImg));
+}
+
+void tst_QQuickShape::radialGrad()
+{
+ QScopedPointer<QQuickView> window(createView());
+
+ window->setSource(testFileUrl("pathitem5.qml"));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimimal platforms", Abort);
+
+ QImage img = window->grabWindow();
+ QVERIFY(!img.isNull());
+
+ QImage refImg(testFileUrl("pathitem5.png").toLocalFile());
+ QVERIFY(!refImg.isNull());
+
+ QVERIFY(QQuickVisualTestUtil::compareImages(img.convertToFormat(refImg.format()), refImg));
+}
+
+void tst_QQuickShape::conicalGrad()
+{
+ QScopedPointer<QQuickView> window(createView());
+
+ window->setSource(testFileUrl("pathitem6.qml"));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimimal platforms", Abort);
+
+ QImage img = window->grabWindow();
+ QVERIFY(!img.isNull());
+
+ QImage refImg(testFileUrl("pathitem6.png").toLocalFile());
+ QVERIFY(!refImg.isNull());
+
+ QVERIFY(QQuickVisualTestUtil::compareImages(img.convertToFormat(refImg.format()), refImg));
+}
+
+QTEST_MAIN(tst_QQuickShape)
+
+#include "tst_qquickshape.moc"
diff --git a/tests/auto/quick/qquicktext/qquicktext.pro b/tests/auto/quick/qquicktext/qquicktext.pro
index 4f4b77ed7b..f76e8c95b2 100644
--- a/tests/auto/quick/qquicktext/qquicktext.pro
+++ b/tests/auto/quick/qquicktext/qquicktext.pro
@@ -4,7 +4,6 @@ macx:CONFIG -= app_bundle
SOURCES += tst_qquicktext.cpp
-INCLUDEPATH += ../../shared/
HEADERS += ../../shared/testhttpserver.h
SOURCES += ../../shared/testhttpserver.cpp
diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
index c5fa0e19fa..6fa898e9fb 100644
--- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp
+++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
@@ -723,6 +723,61 @@ void tst_qquicktext::textFormat()
QCOMPARE(text->textFormat(), QQuickText::AutoText);
QCOMPARE(spy.count(), 2);
}
+
+ {
+ QQmlComponent component(&engine);
+ component.setData("import QtQuick 2.0\n Text { text: \"<b>Hello</b>\" }", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QQuickText *text = qobject_cast<QQuickText *>(object.data());
+ QVERIFY(text);
+ QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(text);
+ QVERIFY(textPrivate);
+
+ QCOMPARE(text->textFormat(), QQuickText::AutoText);
+ QVERIFY(!textPrivate->layout.formats().isEmpty());
+
+ text->setTextFormat(QQuickText::StyledText);
+ QVERIFY(!textPrivate->layout.formats().isEmpty());
+
+ text->setTextFormat(QQuickText::PlainText);
+ QVERIFY(textPrivate->layout.formats().isEmpty());
+
+ text->setTextFormat(QQuickText::AutoText);
+ QVERIFY(!textPrivate->layout.formats().isEmpty());
+ }
+
+ {
+ QQmlComponent component(&engine);
+ component.setData("import QtQuick 2.0\nText { text: \"Hello\"; elide: Text.ElideRight }", QUrl::fromLocalFile(""));
+ QScopedPointer<QObject> object(component.create());
+ QQuickText *text = qobject_cast<QQuickText *>(object.data());
+ QVERIFY(text);
+ QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(text);
+ QVERIFY(textPrivate);
+
+ // underline a mnemonic
+ QVector<QTextLayout::FormatRange> formats;
+ QTextLayout::FormatRange range;
+ range.start = 0;
+ range.length = 1;
+ range.format.setFontUnderline(true);
+ formats << range;
+
+ // the mnemonic format should be retained
+ textPrivate->layout.setFormats(formats);
+ text->forceLayout();
+ QCOMPARE(textPrivate->layout.formats(), formats);
+
+ // and carried over to the elide layout
+ text->setWidth(text->implicitWidth() - 1);
+ QVERIFY(textPrivate->elideLayout);
+ QCOMPARE(textPrivate->elideLayout->formats(), formats);
+
+ // but cleared when the text changes
+ text->setText("Changed");
+ QVERIFY(textPrivate->elideLayout);
+ QVERIFY(textPrivate->layout.formats().isEmpty());
+ }
}
//the alignment tests may be trivial o.oa
@@ -903,9 +958,6 @@ static inline QByteArray msgNotLessThan(int n1, int n2)
void tst_qquicktext::hAlignImplicitWidth()
{
-#if defined(QT_OPENGL_ES_2_ANGLE) && _MSC_VER==1600
- QSKIP("QTBUG-40658");
-#endif
QQuickView view(testFileUrl("hAlignImplicitWidth.qml"));
view.setFlags(view.flags() | Qt::WindowStaysOnTopHint); // Prevent being obscured by other windows.
view.show();
@@ -929,6 +981,10 @@ void tst_qquicktext::hAlignImplicitWidth()
const int centeredSection3End = centeredSection3 + sectionWidth;
{
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimimal platforms", Abort);
+
// Left Align
QImage image = view.grabWindow();
const int left = numberOfNonWhitePixels(centeredSection1, centeredSection2, image);
diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
index f4fef1f946..d0031e397b 100644
--- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
+++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
@@ -905,6 +905,10 @@ void tst_qquicktextedit::hAlignVisual()
const int centeredSection3End = centeredSection3 + sectionWidth;
{
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimimal platforms", Abort);
+
// Left Align
QImage image = view.grabWindow();
const int left = numberOfNonWhitePixels(centeredSection1, centeredSection2, image);
diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
index 5b2c585a92..06b76d129c 100644
--- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
+++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
@@ -2677,7 +2677,7 @@ void tst_qquicktextinput::copyAndPaste()
QCOMPARE(clipboard->text(), QString("My password"));
clipboard->clear();
} else {
- QVERIFY(clipboard->text().isEmpty());
+ QVERIFY(!clipboard->ownsSelection() || clipboard->text().isEmpty());
}
index++;
}
@@ -2745,7 +2745,7 @@ void tst_qquicktextinput::copyAndPasteKeySequence()
QCOMPARE(clipboard->text(), QString("My password"));
clipboard->clear();
} else {
- QVERIFY(clipboard->text().isEmpty());
+ QVERIFY(!clipboard->ownsClipboard() || clipboard->text().isEmpty());
}
index++;
}
diff --git a/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp b/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp
index 2280f75518..bf43e976ab 100644
--- a/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp
+++ b/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp
@@ -2038,9 +2038,6 @@ void tst_qquickvisualdatamodel::get()
QQmlDelegateModelGroup *selectedItems = visualModel->findChild<QQmlDelegateModelGroup *>("selectedItems");
QVERIFY(selectedItems);
- QV8Engine *v8Engine = QQmlEnginePrivate::getV8Engine(ctxt->engine());
- QVERIFY(v8Engine);
-
const bool f = false;
const bool t = true;
diff --git a/tests/auto/quick/qquickwindow/BLACKLIST b/tests/auto/quick/qquickwindow/BLACKLIST
new file mode 100644
index 0000000000..bb9f403188
--- /dev/null
+++ b/tests/auto/quick/qquickwindow/BLACKLIST
@@ -0,0 +1,3 @@
+# QTBUG-62177
+[attachedProperty]
+osx
diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
index cb710e2c8e..fe9e8bb1fa 100644
--- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
+++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
@@ -37,6 +37,7 @@
#include <QtQml/QQmlComponent>
#include <QtQuick/private/qquickrectangle_p.h>
#include <QtQuick/private/qquickloader_p.h>
+#include <QtQuick/private/qquickmousearea_p.h>
#include "../../shared/util.h"
#include "../shared/visualtestutil.h"
#include "../shared/viewtestutil.h"
@@ -142,8 +143,9 @@ class TestTouchItem : public QQuickRectangle
public:
TestTouchItem(QQuickItem *parent = 0)
: QQuickRectangle(parent), acceptTouchEvents(true), acceptMouseEvents(true),
- mousePressId(0),
- spinLoopWhenPressed(false), touchEventCount(0)
+ mousePressCount(0), mouseMoveCount(0),
+ spinLoopWhenPressed(false), touchEventCount(0),
+ mouseUngrabEventCount(0)
{
border()->setWidth(1);
setAcceptedMouseButtons(Qt::LeftButton);
@@ -161,9 +163,11 @@ public:
lastMousePos = QPointF();
lastMouseCapabilityFlags = 0;
touchEventCount = 0;
+ mouseMoveCount = 0;
+ mouseUngrabEventCount = 0;
}
- static void clearMousePressCounter()
+ static void clearMouseEventCounters()
{
mousePressNum = mouseMoveNum = mouseReleaseNum = 0;
}
@@ -176,9 +180,11 @@ public:
bool acceptTouchEvents;
bool acceptMouseEvents;
TouchEventData lastEvent;
- int mousePressId;
+ int mousePressCount;
+ int mouseMoveCount;
bool spinLoopWhenPressed;
int touchEventCount;
+ int mouseUngrabEventCount;
QVector2D lastVelocity;
QVector2D lastVelocityFromMouseMove;
QPointF lastMousePos;
@@ -206,7 +212,7 @@ public:
e->ignore();
return;
}
- mousePressId = ++mousePressNum;
+ mousePressCount = ++mousePressNum;
lastMousePos = e->pos();
lastMouseCapabilityFlags = QGuiApplicationPrivate::mouseEventCaps(e);
}
@@ -216,7 +222,7 @@ public:
e->ignore();
return;
}
- ++mouseMoveNum;
+ mouseMoveCount = ++mouseMoveNum;
lastVelocityFromMouseMove = QGuiApplicationPrivate::mouseEventVelocity(e);
lastMouseCapabilityFlags = QGuiApplicationPrivate::mouseEventCaps(e);
lastMousePos = e->pos();
@@ -232,10 +238,23 @@ public:
lastMouseCapabilityFlags = QGuiApplicationPrivate::mouseEventCaps(e);
}
- bool childMouseEventFilter(QQuickItem *, QEvent *event) {
- // TODO Is it a bug if a QTouchEvent comes here?
- if (event->type() == QEvent::MouseButtonPress)
- mousePressId = ++mousePressNum;
+ void mouseUngrabEvent() {
+ ++mouseUngrabEventCount;
+ }
+
+ bool childMouseEventFilter(QQuickItem *item, QEvent *e) {
+ qCDebug(lcTests) << objectName() << "filtering" << e << "ahead of delivery to" << item->metaObject()->className() << item->objectName();
+ switch (e->type()) {
+ case QEvent::MouseButtonPress:
+ mousePressCount = ++mousePressNum;
+ break;
+ case QEvent::MouseMove:
+ mouseMoveCount = ++mouseMoveNum;
+ break;
+ default:
+ break;
+ }
+
return false;
}
@@ -367,6 +386,7 @@ private slots:
void touchEvent_propagation();
void touchEvent_propagation_data();
void touchEvent_cancel();
+ void touchEvent_cancelClearsMouseGrab();
void touchEvent_reentrant();
void touchEvent_velocity();
@@ -436,6 +456,7 @@ private slots:
void testHoverChildMouseEventFilter();
void testHoverTimestamp();
+ void test_circleMapItem();
void pointerEventTypeAndPointCount();
@@ -445,6 +466,9 @@ private slots:
void findChild();
+ void testChildMouseEventFilter();
+ void testChildMouseEventFilter_data();
+
private:
QTouchDevice *touchDevice;
QTouchDevice *touchDeviceWithVelocity;
@@ -575,7 +599,7 @@ void tst_qquickwindow::constantUpdatesOnWindow()
void tst_qquickwindow::touchEvent_basic()
{
- TestTouchItem::clearMousePressCounter();
+ TestTouchItem::clearMouseEventCounters();
QQuickWindow *window = new QQuickWindow;
QScopedPointer<QQuickWindow> cleanup(window);
@@ -704,7 +728,7 @@ void tst_qquickwindow::touchEvent_basic()
void tst_qquickwindow::touchEvent_propagation()
{
- TestTouchItem::clearMousePressCounter();
+ TestTouchItem::clearMouseEventCounters();
QFETCH(bool, acceptTouchEvents);
QFETCH(bool, acceptMouseEvents);
@@ -848,7 +872,7 @@ void tst_qquickwindow::touchEvent_propagation_data()
void tst_qquickwindow::touchEvent_cancel()
{
- TestTouchItem::clearMousePressCounter();
+ TestTouchItem::clearMouseEventCounters();
QQuickWindow *window = new QQuickWindow;
QScopedPointer<QQuickWindow> cleanup(window);
@@ -880,9 +904,41 @@ void tst_qquickwindow::touchEvent_cancel()
delete item;
}
+void tst_qquickwindow::touchEvent_cancelClearsMouseGrab()
+{
+ TestTouchItem::clearMouseEventCounters();
+
+ QQuickWindow *window = new QQuickWindow;
+ QScopedPointer<QQuickWindow> cleanup(window);
+
+ window->resize(250, 250);
+ window->setPosition(100, 100);
+ window->setTitle(QTest::currentTestFunction());
+ window->show();
+ QVERIFY(QTest::qWaitForWindowActive(window));
+
+ TestTouchItem *item = new TestTouchItem(window->contentItem());
+ item->setPosition(QPointF(50, 50));
+ item->setSize(QSizeF(150, 150));
+ item->acceptMouseEvents = true;
+ item->acceptTouchEvents = false;
+
+ QPointF pos(50, 50);
+ QTest::touchEvent(window, touchDevice).press(0, item->mapToScene(pos).toPoint(), window);
+ QCoreApplication::processEvents();
+
+ QTRY_COMPARE(item->mousePressCount, 1);
+ QTRY_COMPARE(item->mouseUngrabEventCount, 0);
+
+ QWindowSystemInterface::handleTouchCancelEvent(0, touchDevice);
+ QCoreApplication::processEvents();
+
+ QTRY_COMPARE(item->mouseUngrabEventCount, 1);
+}
+
void tst_qquickwindow::touchEvent_reentrant()
{
- TestTouchItem::clearMousePressCounter();
+ TestTouchItem::clearMouseEventCounters();
QQuickWindow *window = new QQuickWindow;
QScopedPointer<QQuickWindow> cleanup(window);
@@ -921,7 +977,7 @@ void tst_qquickwindow::touchEvent_reentrant()
void tst_qquickwindow::touchEvent_velocity()
{
- TestTouchItem::clearMousePressCounter();
+ TestTouchItem::clearMouseEventCounters();
QQuickWindow *window = new QQuickWindow;
QScopedPointer<QQuickWindow> cleanup(window);
@@ -1056,7 +1112,7 @@ void tst_qquickwindow::mouseFromTouch_basic()
// should result in sending mouse events generated from the touch
// with the new event propagation system.
- TestTouchItem::clearMousePressCounter();
+ TestTouchItem::clearMouseEventCounters();
QQuickWindow *window = new QQuickWindow;
QScopedPointer<QQuickWindow> cleanup(window);
window->resize(250, 250);
@@ -1196,7 +1252,7 @@ void tst_qquickwindow::clearWindow()
void tst_qquickwindow::mouseFiltering()
{
- TestTouchItem::clearMousePressCounter();
+ TestTouchItem::clearMouseEventCounters();
QQuickWindow *window = new QQuickWindow;
QScopedPointer<QQuickWindow> cleanup(window);
@@ -1210,6 +1266,11 @@ void tst_qquickwindow::mouseFiltering()
bottomItem->setObjectName("Bottom Item");
bottomItem->setSize(QSizeF(150, 150));
+ TestTouchItem *siblingItem = new TestTouchItem(bottomItem);
+ siblingItem->setObjectName("Sibling of Middle Item");
+ siblingItem->setPosition(QPointF(90, 25));
+ siblingItem->setSize(QSizeF(150, 150));
+
TestTouchItem *middleItem = new TestTouchItem(bottomItem);
middleItem->setObjectName("Middle Item");
middleItem->setPosition(QPointF(50, 50));
@@ -1229,9 +1290,41 @@ void tst_qquickwindow::mouseFiltering()
// 1. middleItem filters event
// 2. bottomItem filters event
// 3. topItem receives event
- QTRY_COMPARE(middleItem->mousePressId, 1);
- QTRY_COMPARE(bottomItem->mousePressId, 2);
- QTRY_COMPARE(topItem->mousePressId, 3);
+ QTRY_COMPARE(middleItem->mousePressCount, 1);
+ QTRY_COMPARE(bottomItem->mousePressCount, 2);
+ QTRY_COMPARE(topItem->mousePressCount, 3);
+ QCOMPARE(siblingItem->mousePressCount, 0);
+
+ QTest::mouseRelease(window, Qt::LeftButton, 0, pos);
+ topItem->clearMouseEventCounters();
+ middleItem->clearMouseEventCounters();
+ bottomItem->clearMouseEventCounters();
+ siblingItem->clearMouseEventCounters();
+
+ // Repeat, but this time have the top item accept the press
+ topItem->acceptMouseEvents = true;
+
+ QTest::mousePress(window, Qt::LeftButton, 0, pos);
+
+ // Mouse filtering propagates down the stack, so the
+ // correct order is
+ // 1. middleItem filters event
+ // 2. bottomItem filters event
+ // 3. topItem receives event
+ QTRY_COMPARE(middleItem->mousePressCount, 1);
+ QTRY_COMPARE(bottomItem->mousePressCount, 2);
+ QTRY_COMPARE(topItem->mousePressCount, 3);
+ QCOMPARE(siblingItem->mousePressCount, 0);
+
+ pos += QPoint(50, 50);
+ QTest::mouseMove(window, pos);
+
+ // The top item has grabbed, so the move goes there, but again
+ // all the ancestors can filter, even when the mouse is outside their bounds
+ QTRY_COMPARE(middleItem->mouseMoveCount, 1);
+ QTRY_COMPARE(bottomItem->mouseMoveCount, 2);
+ QTRY_COMPARE(topItem->mouseMoveCount, 3);
+ QCOMPARE(siblingItem->mouseMoveCount, 0);
// clean up mouse press state for the next tests
QTest::mouseRelease(window, Qt::LeftButton, 0, pos);
@@ -1319,6 +1412,10 @@ void tst_qquickwindow::grab_data()
void tst_qquickwindow::grab()
{
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+
QFETCH(bool, visible);
QFETCH(bool, alpha);
@@ -1478,12 +1575,6 @@ void tst_qquickwindow::headless()
if (isGL)
QVERIFY(!window->isSceneGraphInitialized());
}
-#if QT_CONFIG(opengl)
- if (QGuiApplication::platformName() == QLatin1String("windows")
- && QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) {
- QSKIP("Crashes on Windows/ANGLE, QTBUG-42967");
- }
-#endif
// Destroy the native windowing system buffers
window->destroy();
QVERIFY(!window->handle());
@@ -2409,6 +2500,9 @@ void tst_qquickwindow::testRenderJob()
window.scheduleRenderJob(new RenderJob(QQuickWindow::NoStage, &completedJobs),
QQuickWindow::NoStage);
QTRY_COMPARE(RenderJob::deleted, 1);
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QEXPECT_FAIL("", "NoStage job fails on offscreen/minimimal platforms", Continue);
QCOMPARE(completedJobs.size(), 1);
#if QT_CONFIG(opengl)
@@ -2477,13 +2571,13 @@ public:
m_childMouseEventFilterEventCount.clear();
}
protected:
- bool childMouseEventFilter(QQuickItem *, QEvent *event) Q_DECL_OVERRIDE
+ bool childMouseEventFilter(QQuickItem *, QEvent *event) override
{
m_childMouseEventFilterEventCount[event->type()]++;
return m_returnTrueForType.contains(event->type());
}
- bool event(QEvent *event) Q_DECL_OVERRIDE
+ bool event(QEvent *event) override
{
m_eventCount[event->type()]++;
return QQuickRectangle::event(event);
@@ -2640,6 +2734,84 @@ void tst_qquickwindow::testHoverTimestamp()
QCOMPARE(hoverConsumer->hoverTimestamps.last(), 5UL);
}
+class CircleItem : public QQuickRectangle
+{
+public:
+ CircleItem(QQuickItem *parent = 0) : QQuickRectangle(parent) { }
+
+ void setRadius(qreal radius) {
+ const qreal diameter = radius*2;
+ setWidth(diameter);
+ setHeight(diameter);
+ }
+
+ bool childMouseEventFilter(QQuickItem *item, QEvent *event) override
+ {
+ Q_UNUSED(item)
+ if (event->type() == QEvent::MouseButtonPress && !contains(static_cast<QMouseEvent*>(event)->pos())) {
+ // This is an evil hack: in case of items that are not rectangles, we never accept the event.
+ // Instead the events are now delivered to QDeclarativeGeoMapItemBase which doesn't to anything with them.
+ // The map below it still works since it filters events and steals the events at some point.
+ event->setAccepted(false);
+ return true;
+ }
+ return false;
+ }
+
+ bool contains(const QPointF &pos) const override {
+ // returns true if the point is inside the the embedded circle inside the (square) rect
+ const float radius = (float)width()/2;
+ const QVector2D center(radius, radius);
+ const QVector2D dx = QVector2D(pos) - center;
+ const bool ret = dx.lengthSquared() < radius*radius;
+ return ret;
+ }
+};
+
+void tst_qquickwindow::test_circleMapItem()
+{
+ QQuickWindow window;
+
+ window.resize(250, 250);
+ window.setPosition(100, 100);
+ window.setTitle(QTest::currentTestFunction());
+
+ QQuickItem *root = window.contentItem();
+ QQuickMouseArea *mab = new QQuickMouseArea(root);
+ mab->setObjectName("Bottom MouseArea");
+ mab->setSize(QSizeF(100, 100));
+
+ CircleItem *topItem = new CircleItem(root);
+ topItem->setFiltersChildMouseEvents(true);
+ topItem->setColor(Qt::green);
+ topItem->setObjectName("Top Item");
+ topItem->setPosition(QPointF(30, 30));
+ topItem->setRadius(20);
+ QQuickMouseArea *mat = new QQuickMouseArea(topItem);
+ mat->setObjectName("Top Item/MouseArea");
+ mat->setSize(QSizeF(40, 40));
+
+ QSignalSpy bottomSpy(mab, SIGNAL(clicked(QQuickMouseEvent *)));
+ QSignalSpy topSpy(mat, SIGNAL(clicked(QQuickMouseEvent *)));
+
+ window.show();
+ QTest::qWaitForWindowExposed(&window);
+ QTest::qWait(1000);
+
+ QPoint pos(50, 50);
+ QTest::mouseClick(&window, Qt::LeftButton, Qt::KeyboardModifiers(), pos);
+
+ QCOMPARE(topSpy.count(), 1);
+ QCOMPARE(bottomSpy.count(), 0);
+
+ // Outside the "Circles" "input area", but on top of the bottomItem rectangle
+ pos = QPoint(66, 66);
+ QTest::mouseClick(&window, Qt::LeftButton, Qt::KeyboardModifiers(), pos);
+
+ QCOMPARE(bottomSpy.count(), 1);
+ QCOMPARE(topSpy.count(), 1);
+}
+
void tst_qquickwindow::pointerEventTypeAndPointCount()
{
QPointF localPosition(33, 66);
@@ -2653,20 +2825,18 @@ void tst_qquickwindow::pointerEventTypeAndPointCount()
QQuickPointerMouseEvent pme;
pme.reset(&me);
- QVERIFY(pme.isValid());
QCOMPARE(pme.asMouseEvent(localPosition), &me);
QVERIFY(pme.asPointerMouseEvent());
QVERIFY(!pme.asPointerTouchEvent());
QVERIFY(!pme.asPointerTabletEvent());
// QVERIFY(!pe->asTabletEvent()); // TODO
QCOMPARE(pme.pointCount(), 1);
- QCOMPARE(pme.point(0)->scenePos(), scenePosition);
+ QCOMPARE(pme.point(0)->scenePosition(), scenePosition);
QCOMPARE(pme.asMouseEvent(localPosition)->localPos(), localPosition);
QCOMPARE(pme.asMouseEvent(localPosition)->screenPos(), screenPosition);
QQuickPointerTouchEvent pte;
pte.reset(&te);
- QVERIFY(pte.isValid());
QCOMPARE(pte.asTouchEvent(), &te);
QVERIFY(!pte.asPointerMouseEvent());
QVERIFY(pte.asPointerTouchEvent());
@@ -2986,6 +3156,365 @@ void tst_qquickwindow::findChild()
QCOMPARE(window.contentItem()->findChild<QObject *>("contentItemChild"), contentItemChild);
}
+class DeliveryRecord : public QPair<QString, QString>
+{
+public:
+ DeliveryRecord(const QString &filter, const QString &receiver) : QPair(filter, receiver) { }
+ DeliveryRecord(const QString &receiver) : QPair(QString(), receiver) { }
+ DeliveryRecord() : QPair() { }
+ QString toString() const {
+ if (second.isEmpty())
+ return QLatin1String("Delivery(no receiver)");
+ else if (first.isEmpty())
+ return QString(QLatin1String("Delivery(to '%1')")).arg(second);
+ else
+ return QString(QLatin1String("Delivery('%1' filtering for '%2')")).arg(first).arg(second);
+ }
+};
+
+Q_DECLARE_METATYPE(DeliveryRecord)
+
+QDebug operator<<(QDebug dbg, const DeliveryRecord &pair)
+{
+ dbg << pair.toString();
+ return dbg;
+}
+
+typedef QVector<DeliveryRecord> DeliveryRecordVector;
+
+class EventItem : public QQuickRectangle
+{
+ Q_OBJECT
+public:
+ EventItem(QQuickItem *parent)
+ : QQuickRectangle(parent)
+ , m_eventAccepts(true)
+ , m_filterReturns(true)
+ , m_filterAccepts(true)
+ , m_filterNotPreAccepted(false)
+ {
+ QSizeF psize(parent->width(), parent->height());
+ psize -= QSizeF(20, 20);
+ setWidth(psize.width());
+ setHeight(psize.height());
+ setPosition(QPointF(10, 10));
+ }
+
+ void setFilterReturns(bool filterReturns) { m_filterReturns = filterReturns; }
+ void setFilterAccepts(bool accepts) { m_filterAccepts = accepts; }
+ void setEventAccepts(bool accepts) { m_eventAccepts = accepts; }
+
+ /*!
+ * \internal
+ *
+ * returns false if any of the calls to childMouseEventFilter had the wrong
+ * preconditions. If all calls had the expected precondition, returns true.
+ */
+ bool testFilterPreConditions() const { return !m_filterNotPreAccepted; }
+ static QVector<DeliveryRecord> &deliveryList() { return m_deliveryList; }
+ static QSet<QEvent::Type> &includedEventTypes()
+ {
+ if (m_includedEventTypes.isEmpty())
+ m_includedEventTypes << QEvent::MouseButtonPress;
+ return m_includedEventTypes;
+ }
+ static void setExpectedDeliveryList(const QVector<DeliveryRecord> &v) { m_expectedDeliveryList = v; }
+
+protected:
+ bool childMouseEventFilter(QQuickItem *i, QEvent *e) override
+ {
+ appendEvent(this, i, e);
+ switch (e->type()) {
+ case QEvent::MouseButtonPress:
+ if (!e->isAccepted())
+ m_filterNotPreAccepted = true;
+ e->setAccepted(m_filterAccepts);
+ // qCDebug(lcTests) << objectName() << i->objectName();
+ return m_filterReturns;
+ default:
+ break;
+ }
+ return QQuickRectangle::childMouseEventFilter(i, e);
+ }
+
+ bool event(QEvent *e) override
+ {
+ appendEvent(nullptr, this, e);
+ switch (e->type()) {
+ case QEvent::MouseButtonPress:
+ // qCDebug(lcTests) << objectName();
+ e->setAccepted(m_eventAccepts);
+ return true;
+ default:
+ break;
+ }
+ return QQuickRectangle::event(e);
+ }
+
+private:
+ static void appendEvent(QQuickItem *filter, QQuickItem *receiver, QEvent *event) {
+ if (includedEventTypes().contains(event->type())) {
+ auto record = DeliveryRecord(filter ? filter->objectName() : QString(), receiver ? receiver->objectName() : QString());
+ int i = m_deliveryList.count();
+ if (m_expectedDeliveryList.count() > i && m_expectedDeliveryList[i] == record)
+ qCDebug(lcTests).noquote().nospace() << i << ": " << record;
+ else
+ qCDebug(lcTests).noquote().nospace() << i << ": " << record
+ << ", expected " << (m_expectedDeliveryList.count() > i ? m_expectedDeliveryList[i].toString() : QLatin1String("nothing")) << " <---";
+ m_deliveryList << record;
+ }
+ }
+ bool m_eventAccepts;
+ bool m_filterReturns;
+ bool m_filterAccepts;
+ bool m_filterNotPreAccepted;
+
+ // list of (filtering-parent . receiver) pairs
+ static DeliveryRecordVector m_expectedDeliveryList;
+ static DeliveryRecordVector m_deliveryList;
+ static QSet<QEvent::Type> m_includedEventTypes;
+};
+
+DeliveryRecordVector EventItem::m_expectedDeliveryList;
+DeliveryRecordVector EventItem::m_deliveryList;
+QSet<QEvent::Type> EventItem::m_includedEventTypes;
+
+typedef QVector<const char*> CharStarVector;
+
+Q_DECLARE_METATYPE(CharStarVector)
+
+struct InputState {
+ struct {
+ // event() behavior
+ bool eventAccepts;
+ // filterChildMouse behavior
+ bool returns;
+ bool accepts;
+ bool filtersChildMouseEvent;
+ } r[4];
+};
+
+Q_DECLARE_METATYPE(InputState)
+
+void tst_qquickwindow::testChildMouseEventFilter_data()
+{
+ // HIERARCHY:
+ // r0->r1->r2->r3
+ //
+ QTest::addColumn<QPoint>("mousePos");
+ QTest::addColumn<InputState>("inputState");
+ QTest::addColumn<DeliveryRecordVector>("expectedDeliveryOrder");
+
+ QTest::newRow("if filtered and rejected, do not deliver it to the item that filtered it")
+ << QPoint(100, 100)
+ << InputState({
+ // | event() | child mouse filter
+ // +---------+---------+---------+---------
+ { // | accepts | returns | accepts | filtersChildMouseEvent
+ { false, false, false, false},
+ { true, false, false, false},
+ { false, true, false, true},
+ { false, false, false, false}
+ }
+ })
+ << (DeliveryRecordVector()
+ << DeliveryRecord("r2", "r3")
+ //<< DeliveryRecord("r3") // it got filtered -> do not deliver
+ // DeliveryRecord("r2") // r2 filtered it -> do not deliver
+ << DeliveryRecord("r1")
+ );
+
+ QTest::newRow("no filtering, no accepting")
+ << QPoint(100, 100)
+ << InputState({
+ // | event() | child mouse filter
+ // +---------+---------+---------+---------
+ { // | accepts | returns | accepts | filtersChildMouseEvent
+ { false, false, false, false},
+ { false , false, false, false},
+ { false, false, false, false},
+ { false, false, false, false}
+ }
+ })
+ << (DeliveryRecordVector()
+ << DeliveryRecord("r3")
+ << DeliveryRecord("r2")
+ << DeliveryRecord("r1")
+ << DeliveryRecord("r0")
+ << DeliveryRecord("root")
+ );
+
+ QTest::newRow("all filtering, no accepting")
+ << QPoint(100, 100)
+ << InputState({
+ // | event() | child mouse filter
+ // +---------+---------+---------+---------
+ { // | accepts | returns | accepts | filtersChildMouseEvent
+ { false, false, false, true},
+ { false, false, false, true},
+ { false, false, false, true},
+ { false, false, false, true}
+ }
+ })
+ << (DeliveryRecordVector()
+ << DeliveryRecord("r2", "r3")
+ << DeliveryRecord("r1", "r3")
+ << DeliveryRecord("r0", "r3")
+ << DeliveryRecord("r3")
+ << DeliveryRecord("r1", "r2")
+ << DeliveryRecord("r0", "r2")
+ << DeliveryRecord("r2")
+ << DeliveryRecord("r0", "r1")
+ << DeliveryRecord("r1")
+ << DeliveryRecord("r0")
+ << DeliveryRecord("root")
+ );
+
+
+ QTest::newRow("some filtering, no accepting")
+ << QPoint(100, 100)
+ << InputState({
+ // | event() | child mouse filter
+ // +---------+---------+---------+---------
+ { // | accepts | returns | accepts | filtersChildMouseEvent
+ { false, false, false, true},
+ { false, false, false, true},
+ { false, false, false, false},
+ { false, false, false, false}
+ }
+ })
+ << (DeliveryRecordVector()
+ << DeliveryRecord("r1", "r3")
+ << DeliveryRecord("r0", "r3")
+ << DeliveryRecord("r3")
+ << DeliveryRecord("r1", "r2")
+ << DeliveryRecord("r0", "r2")
+ << DeliveryRecord("r2")
+ << DeliveryRecord("r0", "r1")
+ << DeliveryRecord("r1")
+ << DeliveryRecord("r0")
+ << DeliveryRecord("root")
+ );
+
+ QTest::newRow("r1 accepts")
+ << QPoint(100, 100)
+ << InputState({
+ // | event() | child mouse filter
+ // +---------+---------+---------+---------
+ { // | accepts | returns | accepts | filtersChildMouseEvent
+ { false, false, false, true},
+ { true , false, false, true},
+ { false, false, false, false},
+ { false, false, false, false}
+ }
+ })
+ << (DeliveryRecordVector()
+ << DeliveryRecord("r1", "r3")
+ << DeliveryRecord("r0", "r3")
+ << DeliveryRecord("r3")
+ << DeliveryRecord("r1", "r2")
+ << DeliveryRecord("r0", "r2")
+ << DeliveryRecord("r2")
+ << DeliveryRecord("r0", "r1")
+ << DeliveryRecord("r1")
+ );
+
+ QTest::newRow("r1 rejects and filters")
+ << QPoint(100, 100)
+ << InputState({
+ // | event() | child mouse filter
+ // +---------+---------+---------+---------
+ { // | accepts | returns | accepts | filtersChildMouseEvent
+ { false, false, false, true},
+ { false , true, false, true},
+ { false, false, false, false},
+ { false, false, false, false}
+ }
+ })
+ << (DeliveryRecordVector()
+ << DeliveryRecord("r1", "r3")
+ << DeliveryRecord("r0", "r3")
+// << DeliveryRecord("r3") // since it got filtered we don't deliver to r3
+ << DeliveryRecord("r1", "r2")
+ << DeliveryRecord("r0", "r2")
+// << DeliveryRecord("r2" // since it got filtered we don't deliver to r2
+ << DeliveryRecord("r0", "r1")
+// << DeliveryRecord("r1") // since it acted as a filter and returned true, we don't deliver to r1
+ << DeliveryRecord("r0")
+ << DeliveryRecord("root")
+ );
+
+}
+
+void tst_qquickwindow::testChildMouseEventFilter()
+{
+ QFETCH(QPoint, mousePos);
+ QFETCH(InputState, inputState);
+ QFETCH(DeliveryRecordVector, expectedDeliveryOrder);
+
+ EventItem::setExpectedDeliveryList(expectedDeliveryOrder);
+
+ QQuickWindow window;
+ window.resize(500, 809);
+ QQuickItem *root = window.contentItem();
+ root->setAcceptedMouseButtons(Qt::LeftButton);
+
+ root->setObjectName("root");
+ EventFilter *rootFilter = new EventFilter;
+ root->installEventFilter(rootFilter);
+
+ // Create 4 items; each item a child of the previous item.
+ EventItem *r[4];
+ r[0] = new EventItem(root);
+ r[0]->setColor(QColor(0x404040));
+ r[0]->setWidth(200);
+ r[0]->setHeight(200);
+
+ r[1] = new EventItem(r[0]);
+ r[1]->setColor(QColor(0x606060));
+
+ r[2] = new EventItem(r[1]);
+ r[2]->setColor(Qt::red);
+
+ r[3] = new EventItem(r[2]);
+ r[3]->setColor(Qt::green);
+
+ for (uint i = 0; i < sizeof(r)/sizeof(EventItem*); ++i) {
+ r[i]->setEventAccepts(inputState.r[i].eventAccepts);
+ r[i]->setFilterReturns(inputState.r[i].returns);
+ r[i]->setFilterAccepts(inputState.r[i].accepts);
+ r[i]->setFiltersChildMouseEvents(inputState.r[i].filtersChildMouseEvent);
+ r[i]->setObjectName(QString::fromLatin1("r%1").arg(i));
+ r[i]->setAcceptedMouseButtons(Qt::LeftButton);
+ }
+
+ window.show();
+ window.requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(&window));
+
+ DeliveryRecordVector &actualDeliveryOrder = EventItem::deliveryList();
+ actualDeliveryOrder.clear();
+ QTest::mousePress(&window, Qt::LeftButton, 0, mousePos);
+
+ // Check if event got delivered to the root item. If so, append it to the list of items the event got delivered to
+ if (rootFilter->events.contains(QEvent::MouseButtonPress))
+ actualDeliveryOrder.append(DeliveryRecord("root"));
+
+ for (int i = 0; i < qMax(actualDeliveryOrder.count(), expectedDeliveryOrder.count()); ++i) {
+ const DeliveryRecord expectedNames = expectedDeliveryOrder.value(i);
+ const DeliveryRecord actualNames = actualDeliveryOrder.value(i);
+ QCOMPARE(actualNames.toString(), expectedNames.toString());
+ }
+
+ for (EventItem *item : r) {
+ QVERIFY(item->testFilterPreConditions());
+ }
+
+ // "restore" mouse state
+ QTest::mouseRelease(&window, Qt::LeftButton, 0, mousePos);
+}
+
+
QTEST_MAIN(tst_qquickwindow)
#include "tst_qquickwindow.moc"
diff --git a/tests/auto/quick/quick.pro b/tests/auto/quick/quick.pro
index 4c1c667489..a54a707f4a 100644
--- a/tests/auto/quick/quick.pro
+++ b/tests/auto/quick/quick.pro
@@ -47,6 +47,7 @@ PRIVATETESTS += \
!qtHaveModule(xmlpatterns): PRIVATETESTS -= qquickxmllistmodel
QUICKTESTS += \
+ pointerhandlers \
qquickaccessible \
qquickanchors \
qquickanimatedimage \
@@ -69,6 +70,7 @@ QUICKTESTS += \
qquickmousearea \
qquickmultipointtoucharea \
qquickpainteditem \
+ qquickshape \
qquickpathview \
qquickpincharea \
qquickpositioners \
@@ -90,6 +92,9 @@ QUICKTESTS += \
SUBDIRS += $$PUBLICTESTS
+# Following tests are too slow on qemu + software backend
+boot2qt: QUICKTESTS -= qquickgridview qquicklistview qquickpositioners
+
!qtConfig(accessibility):QUICKTESTS -= qquickaccessible
qtConfig(private_tests) {
diff --git a/tests/auto/quick/rendernode/tst_rendernode.cpp b/tests/auto/quick/rendernode/tst_rendernode.cpp
index e0fe2c42fc..d6e1982b1e 100644
--- a/tests/auto/quick/rendernode/tst_rendernode.cpp
+++ b/tests/auto/quick/rendernode/tst_rendernode.cpp
@@ -213,6 +213,11 @@ void tst_rendernode::renderOrder()
{
if (QGuiApplication::primaryScreen()->depth() < 24)
QSKIP("This test does not work at display depths < 24");
+
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+
QImage fb = runTest("RenderOrder.qml");
const qreal scaleFactor = QGuiApplication::primaryScreen()->devicePixelRatio();
@@ -237,6 +242,11 @@ void tst_rendernode::messUpState()
{
if (QGuiApplication::primaryScreen()->depth() < 24)
QSKIP("This test does not work at display depths < 24");
+
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+
QImage fb = runTest("MessUpState.qml");
int x1 = 0;
int x2 = fb.width() / 2;
@@ -290,6 +300,10 @@ public:
void tst_rendernode::matrix()
{
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+
qmlRegisterType<StateRecordingRenderNodeItem>("RenderNode", 1, 0, "StateRecorder");
StateRecordingRenderNode::matrices.clear();
runTest("matrix.qml");
diff --git a/tests/auto/quick/scenegraph/tst_scenegraph.cpp b/tests/auto/quick/scenegraph/tst_scenegraph.cpp
index 2cd3a041c8..d8d9cd26e0 100644
--- a/tests/auto/quick/scenegraph/tst_scenegraph.cpp
+++ b/tests/auto/quick/scenegraph/tst_scenegraph.cpp
@@ -47,6 +47,9 @@
#include "../../shared/util.h"
#include "../shared/visualtestutil.h"
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/qpa/qplatformintegration.h>
+
using namespace QQuickVisualTestUtil;
class PerPixelRect : public QQuickItem
@@ -114,6 +117,7 @@ private slots:
private:
bool m_brokenMipmapSupport;
QQuickView *createView(const QString &file, QWindow *parent = 0, int x = -1, int y = -1, int w = -1, int h = -1);
+ bool isRunningOnOpenGL();
};
template <typename T> class ScopedList : public QList<T> {
@@ -131,38 +135,40 @@ void tst_SceneGraph::initTestCase()
qDebug() << "RenderLoop: " << loop;
#if QT_CONFIG(opengl)
- QOpenGLContext context;
- context.setFormat(loop->sceneGraphContext()->defaultSurfaceFormat());
- context.create();
- QSurfaceFormat format = context.format();
-
- QOffscreenSurface surface;
- surface.setFormat(format);
- surface.create();
- if (!context.makeCurrent(&surface))
- qFatal("Failed to create a GL context...");
-
- QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
- qDebug() << "R/G/B/A Buffers: " << format.redBufferSize() << format.greenBufferSize() << format.blueBufferSize() << format.alphaBufferSize();
- qDebug() << "Depth Buffer: " << format.depthBufferSize();
- qDebug() << "Stencil Buffer: " << format.stencilBufferSize();
- qDebug() << "Samples: " << format.samples();
- int textureSize;
- funcs->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &textureSize);
- qDebug() << "Max Texture Size: " << textureSize;
- qDebug() << "GL_VENDOR: " << (const char *) funcs->glGetString(GL_VENDOR);
- qDebug() << "GL_RENDERER: " << (const char *) funcs->glGetString(GL_RENDERER);
- QByteArray version = (const char *) funcs->glGetString(GL_VERSION);
- qDebug() << "GL_VERSION: " << version.constData();
- QSet<QByteArray> exts = context.extensions();
- QByteArray all;
- foreach (const QByteArray &e, exts) all += ' ' + e;
- qDebug() << "GL_EXTENSIONS: " << all.constData();
-
- m_brokenMipmapSupport = version.contains("Mesa 10.1") || version.contains("Mesa 9.");
- qDebug() << "Broken Mipmap: " << m_brokenMipmapSupport;
-
- context.doneCurrent();
+ if (QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)) {
+ QOpenGLContext context;
+ context.setFormat(loop->sceneGraphContext()->defaultSurfaceFormat());
+ context.create();
+ QSurfaceFormat format = context.format();
+
+ QOffscreenSurface surface;
+ surface.setFormat(format);
+ surface.create();
+ if (!context.makeCurrent(&surface))
+ qFatal("Failed to create a GL context...");
+
+ QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
+ qDebug() << "R/G/B/A Buffers: " << format.redBufferSize() << format.greenBufferSize() << format.blueBufferSize() << format.alphaBufferSize();
+ qDebug() << "Depth Buffer: " << format.depthBufferSize();
+ qDebug() << "Stencil Buffer: " << format.stencilBufferSize();
+ qDebug() << "Samples: " << format.samples();
+ int textureSize;
+ funcs->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &textureSize);
+ qDebug() << "Max Texture Size: " << textureSize;
+ qDebug() << "GL_VENDOR: " << (const char *) funcs->glGetString(GL_VENDOR);
+ qDebug() << "GL_RENDERER: " << (const char *) funcs->glGetString(GL_RENDERER);
+ QByteArray version = (const char *) funcs->glGetString(GL_VERSION);
+ qDebug() << "GL_VERSION: " << version.constData();
+ QSet<QByteArray> exts = context.extensions();
+ QByteArray all;
+ foreach (const QByteArray &e, exts) all += ' ' + e;
+ qDebug() << "GL_EXTENSIONS: " << all.constData();
+
+ m_brokenMipmapSupport = version.contains("Mesa 10.1") || version.contains("Mesa 9.");
+ qDebug() << "Broken Mipmap: " << m_brokenMipmapSupport;
+
+ context.doneCurrent();
+ }
#endif
}
@@ -231,6 +237,10 @@ public:
void tst_SceneGraph::manyWindows()
{
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+
QFETCH(QString, file);
QFETCH(bool, toplevel);
QFETCH(bool, shared);
@@ -430,12 +440,8 @@ void tst_SceneGraph::render_data()
void tst_SceneGraph::render()
{
- QQuickView dummy;
- dummy.show();
- QTest::qWaitForWindowExposed(&dummy);
- if (dummy.rendererInterface()->graphicsApi() != QSGRendererInterface::OpenGL)
+ if (!isRunningOnOpenGL())
QSKIP("Skipping complex rendering tests due to not running with OpenGL");
- dummy.hide();
QFETCH(QString, file);
QFETCH(QList<Sample>, baseStage);
@@ -485,6 +491,9 @@ void tst_SceneGraph::render()
// current on the other window.
void tst_SceneGraph::hideWithOtherContext()
{
+ if (!isRunningOnOpenGL())
+ QSKIP("Skipping OpenGL context test due to not running with OpenGL");
+
QWindow window;
window.setSurfaceType(QWindow::OpenGLSurface);
window.resize(100, 100);
@@ -500,9 +509,6 @@ void tst_SceneGraph::hideWithOtherContext()
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
- if (view.rendererInterface()->graphicsApi() != QSGRendererInterface::OpenGL)
- QSKIP("Skipping OpenGL context test due to not running with OpenGL");
-
renderingOnMainThread = view.openglContext()->thread() == QGuiApplication::instance()->thread();
// Make the local context current on the local window...
@@ -549,6 +555,17 @@ void tst_SceneGraph::createTextureFromImage()
QCOMPARE(texture->hasAlphaChannel(), expectedAlpha);
}
+bool tst_SceneGraph::isRunningOnOpenGL()
+{
+ bool retval = false;
+ QQuickView dummy;
+ dummy.show();
+ QTest::qWaitForWindowExposed(&dummy);
+ if (dummy.rendererInterface()->graphicsApi() == QSGRendererInterface::OpenGL)
+ retval = true;
+ dummy.hide();
+ return retval;
+}
#include "tst_scenegraph.moc"
diff --git a/tests/auto/quick/shared/viewtestutil.cpp b/tests/auto/quick/shared/viewtestutil.cpp
index cb2b8be97a..dc813b9d59 100644
--- a/tests/auto/quick/shared/viewtestutil.cpp
+++ b/tests/auto/quick/shared/viewtestutil.cpp
@@ -28,6 +28,7 @@
#include "viewtestutil.h"
+#include <QtCore/QRandomGenerator>
#include <QtQuick/QQuickView>
#include <QtQuick/QQuickView>
#include <QtGui/QScreen>
@@ -356,7 +357,6 @@ QQuickViewTestUtil::StressTestModel::StressTestModel()
t->setInterval(500);
t->start();
- qsrand(qHash(QDateTime::currentDateTime()));
connect(t, &QTimer::timeout, this, &StressTestModel::updateModel);
}
@@ -374,7 +374,7 @@ void QQuickViewTestUtil::StressTestModel::updateModel()
{
if (m_rowCount > 10) {
for (int i = 0; i < 10; ++i) {
- int rnum = qrand() % m_rowCount;
+ int rnum = QRandomGenerator::global()->bounded(m_rowCount);
beginRemoveRows(QModelIndex(), rnum, rnum);
m_rowCount--;
endRemoveRows();
@@ -382,7 +382,7 @@ void QQuickViewTestUtil::StressTestModel::updateModel()
}
if (m_rowCount < 20) {
for (int i = 0; i < 10; ++i) {
- int rnum = qrand() % m_rowCount;
+ int rnum = QRandomGenerator::global()->bounded(m_rowCount);
beginInsertRows(QModelIndex(), rnum, rnum);
m_rowCount++;
endInsertRows();
@@ -398,7 +398,7 @@ bool QQuickViewTestUtil::testVisibleItems(const QQuickItemViewPrivate *priv, boo
for (int i = 0; i < priv->visibleItems.count(); ++i) {
FxViewItem *item = priv->visibleItems.at(i);
if (!item) {
- *failItem = Q_NULLPTR;
+ *failItem = nullptr;
return false;
}
#if 0
diff --git a/tests/auto/quick/touchmouse/BLACKLIST b/tests/auto/quick/touchmouse/BLACKLIST
index b2ba52eca9..e0d4bff131 100644
--- a/tests/auto/quick/touchmouse/BLACKLIST
+++ b/tests/auto/quick/touchmouse/BLACKLIST
@@ -1,2 +1,5 @@
+# QTBUG-40856 hover regression on pointerhandler branch: TODO fix before merging to dev
+[hoverEnabled]
+*
[buttonOnDelayedPressFlickable]
windows gcc developer-build
diff --git a/tests/auto/quick/touchmouse/tst_touchmouse.cpp b/tests/auto/quick/touchmouse/tst_touchmouse.cpp
index 39f2961927..646317078b 100644
--- a/tests/auto/quick/touchmouse/tst_touchmouse.cpp
+++ b/tests/auto/quick/touchmouse/tst_touchmouse.cpp
@@ -30,6 +30,7 @@
#include <QtTest/QtTest>
#include <QtGui/qstylehints.h>
+#include <private/qdebug_p.h>
#include <QtQuick/qquickview.h>
#include <QtQuick/qquickitem.h>
@@ -62,6 +63,21 @@ struct Event
QList<QTouchEvent::TouchPoint> points;
};
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const struct Event &event) {
+ QDebugStateSaver saver(dbg);
+ dbg.nospace();
+ dbg << "Event(";
+ QtDebugUtils::formatQEnum(dbg, event.type);
+ if (event.points.isEmpty())
+ dbg << " @ " << event.mousePos << " global " << event.mousePosGlobal;
+ else
+ dbg << ", " << event.points.count() << " touchpoints: " << event.points;
+ dbg << ')';
+ return dbg;
+}
+#endif
+
class EventItem : public QQuickItem
{
Q_OBJECT
@@ -74,6 +90,9 @@ public:
: QQuickItem(parent), touchUngrabCount(0), acceptMouse(false), acceptTouch(false), filterTouch(false), point0(-1)
{
setAcceptedMouseButtons(Qt::LeftButton);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ setAcceptTouchEvents(true);
+#endif
}
void touchEvent(QTouchEvent *event)
@@ -572,7 +591,7 @@ void tst_TouchMouse::buttonOnFlickable()
QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window.data());
QVERIFY(windowPriv->touchMouseId != -1);
auto pointerEvent = windowPriv->pointerEventInstance(QQuickPointerDevice::touchDevices().at(0));
- QCOMPARE(pointerEvent->point(0)->grabber(), eventItem1);
+ QCOMPARE(pointerEvent->point(0)->exclusiveGrabber(), eventItem1);
QCOMPARE(window->mouseGrabberItem(), eventItem1);
int dragDelta = -qApp->styleHints()->startDragDistance();
@@ -594,7 +613,7 @@ void tst_TouchMouse::buttonOnFlickable()
QCOMPARE(window->mouseGrabberItem(), flickable);
QVERIFY(windowPriv->touchMouseId != -1);
- QCOMPARE(pointerEvent->point(0)->grabber(), flickable);
+ QCOMPARE(pointerEvent->point(0)->exclusiveGrabber(), flickable);
QVERIFY(flickable->isMovingVertically());
QTest::touchEvent(window.data(), device).release(0, p3, window.data());
@@ -633,7 +652,7 @@ void tst_TouchMouse::touchButtonOnFlickable()
QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window.data());
QVERIFY(windowPriv->touchMouseId == -1);
auto pointerEvent = windowPriv->pointerEventInstance(QQuickPointerDevice::touchDevices().at(0));
- QCOMPARE(pointerEvent->point(0)->grabber(), eventItem2);
+ QCOMPARE(pointerEvent->point(0)->grabberItem(), eventItem2);
QCOMPARE(window->mouseGrabberItem(), nullptr);
int dragDelta = qApp->styleHints()->startDragDistance() * -0.7;
@@ -654,7 +673,7 @@ void tst_TouchMouse::touchButtonOnFlickable()
QCOMPARE(eventItem2->touchUngrabCount, 1);
QCOMPARE(window->mouseGrabberItem(), flickable);
QVERIFY(windowPriv->touchMouseId != -1);
- QCOMPARE(pointerEvent->point(0)->grabber(), flickable);
+ QCOMPARE(pointerEvent->point(0)->grabberItem(), flickable);
QVERIFY(flickable->isMovingVertically());
QTest::touchEvent(window.data(), device).release(0, p3, window.data());
@@ -759,7 +778,7 @@ void tst_TouchMouse::buttonOnDelayedPressFlickable()
QCOMPARE(window->mouseGrabberItem(), flickable);
QVERIFY(windowPriv->touchMouseId != -1);
auto pointerEvent = windowPriv->pointerEventInstance(QQuickPointerDevice::touchDevices().at(0));
- QCOMPARE(pointerEvent->point(0)->grabber(), flickable);
+ QCOMPARE(pointerEvent->point(0)->grabberItem(), flickable);
QTest::touchEvent(window.data(), device).release(0, p3, window.data());
QQuickTouchUtils::flush(window.data());
diff --git a/tests/auto/quicktest/quicktest.pro b/tests/auto/quicktest/quicktest.pro
index 3b4ec23a64..9d909f1d16 100644
--- a/tests/auto/quicktest/quicktest.pro
+++ b/tests/auto/quicktest/quicktest.pro
@@ -1,3 +1,4 @@
TEMPLATE = subdirs
SUBDIRS = \
- signalspy
+ signalspy \
+ quicktestmainwithsetup
diff --git a/tests/auto/qmltest/tst_qmltest.cpp b/tests/auto/quicktest/quicktestmainwithsetup/data/tst_setup.qml
index 3387ce8ee9..0f5466998a 100644
--- a/tests/auto/qmltest/tst_qmltest.cpp
+++ b/tests/auto/quicktest/quicktestmainwithsetup/data/tst_setup.qml
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
@@ -26,5 +26,14 @@
**
****************************************************************************/
-#include <QtQuickTest/quicktest.h>
-QUICK_TEST_MAIN(qmltest) \ No newline at end of file
+import QtQuick 2.0
+import QtTest 1.2
+
+TestCase {
+ name: "setup"
+
+ function initTestCase()
+ {
+ verify(qmlEngineAvailableCalled)
+ }
+}
diff --git a/tests/auto/quicktest/quicktestmainwithsetup/quicktestmainwithsetup.pro b/tests/auto/quicktest/quicktestmainwithsetup/quicktestmainwithsetup.pro
new file mode 100644
index 0000000000..a8c1c6d36a
--- /dev/null
+++ b/tests/auto/quicktest/quicktestmainwithsetup/quicktestmainwithsetup.pro
@@ -0,0 +1,12 @@
+CONFIG += qmltestcase
+macos:CONFIG -= app_bundle
+TARGET = tst_quicktestmainwithsetup
+
+QT += testlib quick
+
+include (../../shared/util.pri)
+
+SOURCES += tst_quicktestmainwithsetup.cpp
+
+TESTDATA += \
+ $$PWD/data/*.qml
diff --git a/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/plugin.cpp b/tests/auto/quicktest/quicktestmainwithsetup/tst_quicktestmainwithsetup.cpp
index fe01507412..b0545d1a95 100644
--- a/tests/auto/qml/qqmlmoduleplugin/invalidStrictModule/plugin.cpp
+++ b/tests/auto/quicktest/quicktestmainwithsetup/tst_quicktestmainwithsetup.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
@@ -25,32 +25,30 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#include <QStringList>
-#include <QtQml/qqmlextensionplugin.h>
-#include <QtQml/qqml.h>
-#include <QDebug>
-class MyPluginType : public QObject
-{
- Q_OBJECT
-public:
- MyPluginType(QObject *parent=0) : QObject(parent) {}
-};
+#include <QtTest/qtest.h>
+#include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlcontext.h>
+#include <QtQuick/qquickitem.h>
+#include <QtQuick/qquickview.h>
+#include <QtQuickTest/quicktest.h>
+#include "../../shared/util.h"
-class MyPlugin : public QQmlExtensionPlugin
+class CustomTestSetup : public QObject
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
public:
- MyPlugin() {}
+ CustomTestSetup() {}
- void registerTypes(const char *uri)
+public slots:
+ void qmlEngineAvailable(QQmlEngine *qmlEngine)
{
- Q_ASSERT(QLatin1String(uri) == "org.qtproject.InvalidStrictModule");
- qmlRegisterType<MyPluginType>("org.qtproject.SomeOtherModule", 1, 0, "MyPluginType");
+ qmlEngine->rootContext()->setContextProperty("qmlEngineAvailableCalled", true);
}
};
-#include "plugin.moc"
+QUICK_TEST_MAIN_WITH_SETUP(qquicktestsetup, CustomTestSetup)
+
+#include "tst_quicktestmainwithsetup.moc"
diff --git a/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp b/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp
index 7163e3cebf..51755c8502 100644
--- a/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp
+++ b/tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp
@@ -38,7 +38,12 @@
#include <QtGui/QImage>
#include <QtCore/QDebug>
#include <QtQml/qqmlengine.h>
+
#include <QtCore/QLoggingCategory>
+
+#include <QtWidgets/QBoxLayout>
+#include <QtWidgets/QLabel>
+
#include <QtQuickWidgets/QQuickWidget>
Q_LOGGING_CATEGORY(lcTests, "qt.quick.tests")
@@ -120,6 +125,7 @@ private slots:
void reparentAfterShow();
void changeGeometry();
void resizemodeitem();
+ void layoutSizeChange();
void errors();
void engine();
void readback();
@@ -300,6 +306,39 @@ void tst_qquickwidget::resizemodeitem()
QCOMPARE(view->initialSize(), QSize(200, 200)); // initial object size
}
+void tst_qquickwidget::layoutSizeChange()
+{
+ QWidget window;
+ window.resize(400, 400);
+
+ QVBoxLayout *layout = new QVBoxLayout(&window);
+ layout->setContentsMargins(0,0,0,0);
+ layout->setSpacing(0);
+ QScopedPointer<QQuickWidget> view(new QQuickWidget);
+ layout->addWidget(view.data());
+ QLabel *label = new QLabel("Label");
+ layout->addWidget(label);
+ layout->addStretch(1);
+
+
+ view->resize(300,300);
+ view->setResizeMode(QQuickWidget::SizeViewToRootObject);
+ QCOMPARE(QSize(0,0), view->initialSize());
+ view->setSource(testFileUrl("rectangle.qml"));
+ QQuickItem* item = qobject_cast<QQuickItem*>(view->rootObject());
+ QVERIFY(item);
+ QCOMPARE(item->height(), 200.0);
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window, 5000));
+ QTRY_COMPARE(view->height(), 200);
+ QTRY_COMPARE(label->y(), 200);
+
+ item->setSize(QSizeF(100,100));
+ QCOMPARE(item->height(), 100.0);
+ QTRY_COMPARE(view->height(), 100);
+ QTRY_COMPARE(label->y(), 100);
+}
+
void tst_qquickwidget::errors()
{
QQuickWidget *view = new QQuickWidget;
@@ -406,6 +445,10 @@ void tst_qquickwidget::reparentToNewWindow()
QSignalSpy afterRenderingSpy(qqw->quickWindow(), &QQuickWindow::afterRendering);
qqw->setParent(&window2);
qqw->show();
+
+ if (QGuiApplication::platformName() == QLatin1String("offscreen"))
+ QEXPECT_FAIL("", "afterRendering not emitted after reparenting on offscreen", Continue);
+
QTRY_VERIFY(afterRenderingSpy.size() > 0);
QImage img = qqw->grabFramebuffer();
diff --git a/tests/auto/shared/util.pri b/tests/auto/shared/util.pri
index 8e82dcb33b..a05af4773d 100644
--- a/tests/auto/shared/util.pri
+++ b/tests/auto/shared/util.pri
@@ -1,4 +1,5 @@
+INCLUDEPATH += $$PWD
HEADERS += $$PWD/util.h
SOURCES += $$PWD/util.cpp
diff --git a/tests/benchmarks/qml/creation/tst_creation.cpp b/tests/benchmarks/qml/creation/tst_creation.cpp
index 30d7ef902e..ed2e52f869 100644
--- a/tests/benchmarks/qml/creation/tst_creation.cpp
+++ b/tests/benchmarks/qml/creation/tst_creation.cpp
@@ -204,19 +204,13 @@ void tst_creation::qobject_qmltype()
}
}
-struct QQmlGraphics_Derived : public QObject
-{
- void setParent_noEvent(QObject *parent) {
- bool sce = d_ptr->sendChildEvents;
- d_ptr->sendChildEvents = false;
- setParent(parent);
- d_ptr->sendChildEvents = sce;
- }
-};
-
inline void QQmlGraphics_setParent_noEvent(QObject *object, QObject *parent)
{
- static_cast<QQmlGraphics_Derived *>(object)->setParent_noEvent(parent);
+ QObjectPrivate *d_ptr = QObjectPrivate::get(object);
+ bool sce = d_ptr->sendChildEvents;
+ d_ptr->sendChildEvents = false;
+ object->setParent(parent);
+ d_ptr->sendChildEvents = sce;
}
void tst_creation::itemtree_notree_cpp()
@@ -385,7 +379,7 @@ void tst_creation::bindings_qml()
return;
}
- QQuickItem *obj = dynamic_cast<QQuickItem *>(component.create());
+ QQuickItem *obj = qobject_cast<QQuickItem *>(component.create());
QVERIFY(obj != nullptr);
int height = 0;
@@ -407,7 +401,7 @@ void tst_creation::bindings_parent_qml()
return;
}
- QQuickItem *obj = dynamic_cast<QQuickItem *>(component.create());
+ QQuickItem *obj = qobject_cast<QQuickItem *>(component.create());
QVERIFY(obj != nullptr);
int height = 0;
diff --git a/tests/benchmarks/qml/holistic/testtypes.h b/tests/benchmarks/qml/holistic/testtypes.h
index a752a8585b..6ff64c645d 100644
--- a/tests/benchmarks/qml/holistic/testtypes.h
+++ b/tests/benchmarks/qml/holistic/testtypes.h
@@ -34,6 +34,7 @@
#include <QtCore/qpoint.h>
#include <QtCore/qsize.h>
#include <QtQml/qqmllist.h>
+#include <QtCore/qrandom.h>
#include <QtCore/qrect.h>
#include <QtGui/qmatrix.h>
#include <QtGui/qcolor.h>
@@ -223,7 +224,7 @@ public:
{
QPixmap pv(150, 150);
pv.fill(Qt::green);
- int choice = qrand() % 4;
+ int choice = QRandomGenerator::global()->bounded(4);
switch (choice) {
case 0: setArbitraryVariant(QVariant(QString(QLatin1String("string variant value")))); break;
case 1: setArbitraryVariant(QVariant(QColor(110, 120, 130))); break;
@@ -253,7 +254,7 @@ public:
QVariant retn;
QPixmap pv(randomFactorOne % 300, randomFactorTwo % 300);
pv.fill(QColor(randomFactorOne % 256, randomFactorTwo % 256, randomFactorThree % 256));
- int choice = qrand() % 4;
+ int choice = QRandomGenerator::global()->bounded(4);
switch (choice) {
case 0: retn = QVariant(QString(QLatin1String("string variant value"))); break;
case 1: retn = QVariant(QColor(randomFactorThree % 256, randomFactorTwo % 256, randomFactorOne % 256)); break;
diff --git a/tests/benchmarks/qml/painting/paintbenchmark.cpp b/tests/benchmarks/qml/painting/paintbenchmark.cpp
index 0a9dee4664..d195675ab8 100644
--- a/tests/benchmarks/qml/painting/paintbenchmark.cpp
+++ b/tests/benchmarks/qml/painting/paintbenchmark.cpp
@@ -36,6 +36,7 @@
#include <QVBoxLayout>
#include <QTime>
#include <QDebug>
+#include <QRandomGenerator>
#include <QStaticText>
int iterations = 20;
@@ -321,7 +322,7 @@ public:
int len = strlen(chars);
for (int i = 0; i < lines; ++i) {
for (int j = 0; j < 60; j++) {
- strings[i] += QChar(chars[rand() % len]);
+ strings[i] += QChar(chars[QRandomGenerator::global()->bounded(len)]);
}
}
}
diff --git a/tests/manual/imagehandler/large.svg b/tests/manual/imagehandler/large.svg
new file mode 100644
index 0000000000..99b3b67616
--- /dev/null
+++ b/tests/manual/imagehandler/large.svg
@@ -0,0 +1,462 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.0"
+ width="128"
+ height="128"
+ viewBox="0 0 105.427 137.439"
+ id="Livello_1"
+ xml:space="preserve"
+ style="overflow:visible"><defs
+ id="defs2727"><linearGradient
+ x1="26.294399"
+ y1="11.6704"
+ x2="71.901901"
+ y2="133.0273"
+ id="linearGradient3352"
+ xlink:href="#XMLID_34_"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ x1="36.838902"
+ y1="7.7075"
+ x2="82.446297"
+ y2="129.0645"
+ id="linearGradient3354"
+ xlink:href="#XMLID_34_"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ x1="33.882301"
+ y1="23.583"
+ x2="39.972198"
+ y2="23.583"
+ id="XMLID_34_"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ id="stop2672"
+ style="stop-color:#ff5d5d;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop2674"
+ style="stop-color:#e20800;stop-opacity:1"
+ offset="1" />
+ </linearGradient><linearGradient
+ x1="33.882301"
+ y1="23.583"
+ x2="39.972198"
+ y2="23.583"
+ id="linearGradient3368"
+ xlink:href="#XMLID_34_"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ x1="54.356899"
+ y1="1.124"
+ x2="99.964401"
+ y2="122.481"
+ id="linearGradient3370"
+ xlink:href="#XMLID_34_"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ x1="15.8457"
+ y1="15.5972"
+ x2="61.453098"
+ y2="136.9541"
+ id="linearGradient3376"
+ xlink:href="#XMLID_34_"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ x1="43.438"
+ y1="5.2275"
+ x2="89.045403"
+ y2="126.5845"
+ id="linearGradient3382"
+ xlink:href="#XMLID_34_"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ x1="8.1176996"
+ y1="14.9019"
+ x2="70.759598"
+ y2="117.2331"
+ id="linearGradient3792"
+ xlink:href="#XMLID_30_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9991,-4.18e-2,4.18e-2,0.9991,-2.4309,1.195)" /><linearGradient
+ x1="10.5708"
+ y1="10.1548"
+ x2="73.2117"
+ y2="112.4844"
+ id="linearGradient3794"
+ xlink:href="#XMLID_30_"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ x1="6.2178001"
+ y1="72.223602"
+ x2="79.360802"
+ y2="72.223602"
+ id="XMLID_26_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,2.1512354)">
+ <stop
+ id="stop2578"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop2580"
+ style="stop-color:#eeeeec;stop-opacity:1"
+ offset="1" />
+ </linearGradient><filter
+ id="filter5869"><feGaussianBlur
+ id="feGaussianBlur5871"
+ stdDeviation="1.2254964"
+ inkscape:collect="always" /></filter><filter
+ id="filter5873"><feGaussianBlur
+ id="feGaussianBlur5875"
+ stdDeviation="1.3615922"
+ inkscape:collect="always" /></filter><filter
+ id="filter2854"><feGaussianBlur
+ id="feGaussianBlur2856"
+ stdDeviation="0.8944793"
+ inkscape:collect="always" /></filter></defs>
+<filter
+ id="AI_Sfocatura_1">
+ <feGaussianBlur
+ id="feGaussianBlur2545"
+ stdDeviation="1" />
+</filter>
+<g
+ transform="translate(-3.2052027,3.2058836)"
+ id="g2547">
+ <g
+ transform="matrix(0.9982563,0,0,0.9982563,-1.5492234e-2,0.2232388)"
+ id="g2549">
+ <g
+ id="g2551">
+ <linearGradient
+ x1="6.2178001"
+ y1="68.029297"
+ x2="79.360802"
+ y2="68.029297"
+ id="XMLID_24_"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ id="stop2554"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop2556"
+ style="stop-color:#eeeeec;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <path
+ d="M 9.542,121.224 C 7.713,121.224 6.217,119.728 6.217,117.9 L 6.217,18.16 C 6.217,16.331 7.713,14.835 9.542,14.835 L 76.036,14.835 C 77.864,14.835 79.36,16.331 79.36,18.16 L 79.36,117.9 C 79.36,119.728 77.864,121.224 76.036,121.224 L 9.542,121.224 z"
+ id="path2558"
+ style="fill:url(#XMLID_24_)" />
+ </g>
+ <g
+ id="g2560">
+ <linearGradient
+ x1="10.5718"
+ y1="15.3989"
+ x2="73.212097"
+ y2="117.7277"
+ id="XMLID_25_"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ id="stop2563"
+ style="stop-color:#77b753;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop2565"
+ style="stop-color:#00892c;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <path
+ d="M 11.204,18.159 C 10.29,18.159 9.542,18.907 9.542,19.821 L 9.542,116.237 C 9.542,117.151 10.29,117.899 11.204,117.899 L 74.375,117.899 C 75.289,117.899 76.037,117.151 76.037,116.237 L 76.037,19.821 C 76.037,18.907 75.289,18.159 74.375,18.159 L 11.204,18.159 z"
+ id="path2567"
+ style="fill:url(#XMLID_25_)" />
+ </g>
+ </g>
+ <g
+ transform="matrix(0.9982563,0,0,0.9982563,1.05825,0.2232388)"
+ id="g2569">
+ <path
+ d="M 11.639,126.468 C 9.811,126.468 8.314,124.972 8.314,123.143 L 8.314,23.403 C 8.314,21.574 9.811,20.078 11.639,20.078 L 78.134,20.078 C 79.962,20.078 81.458,21.574 81.458,23.403 L 81.458,123.143 C 81.458,124.972 79.962,126.468 78.134,126.468 L 23.696022,126.468 L 11.639,126.468 z"
+ transform="matrix(1.041449,0,0,1,-4.451967,3.1512354)"
+ id="path2575"
+ style="opacity:0.6;filter:url(#filter2854)" /><path
+ d="M 9.542,127.56924 C 7.714,127.56924 6.218,126.07324 6.218,124.24624 L 6.218,24.505236 C 6.218,22.677236 7.714,21.181236 9.542,21.181236 L 76.037,21.181236 C 77.865,21.181236 79.361,22.677236 79.361,24.505236 L 79.361,124.24624 C 79.361,126.07324 77.865,127.56924 76.037,127.56924 L 9.542,127.56924 z"
+ id="path2582"
+ style="fill:url(#XMLID_26_)" />
+ <g
+ transform="translate(0,2.1512354)"
+ id="g2584">
+ <g
+ transform="matrix(1.0276326,0,0,1,-2.2508995,0)"
+ id="g2586"
+ style="opacity:0.5;filter:url(#AI_Sfocatura_1)">
+ <path
+ d="M 11.639,123.321 C 9.811,123.321 8.314,121.824 8.314,119.997 L 81.458,119.997 C 81.458,121.824 79.962,123.321 78.134,123.321 L 11.639,123.321 z"
+ id="path2588" />
+ </g>
+ <linearGradient
+ x1="6.2178001"
+ y1="69.078102"
+ x2="79.360802"
+ y2="69.078102"
+ id="XMLID_27_"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ id="stop2591"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop2593"
+ style="stop-color:#eeeeec;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <path
+ d="M 9.542,122.272 C 7.714,122.272 6.218,120.776 6.218,118.947 L 6.218,19.207 C 6.218,17.378 7.714,15.882 9.542,15.882 L 76.037,15.882 C 77.865,15.882 79.361,17.378 79.361,19.207 L 79.361,118.947 C 79.361,120.776 77.865,122.272 76.037,122.272 L 9.542,122.272 z"
+ id="path2595"
+ style="fill:url(#XMLID_27_)" />
+ </g>
+ <g
+ transform="translate(0,3.2268531)"
+ id="g2597">
+ <g
+ transform="matrix(1.0368435,0,0,1,-3.0011994,-1.0756177)"
+ id="g2599"
+ style="opacity:0.5;filter:url(#AI_Sfocatura_1)">
+ <path
+ d="M 11.639,120.175 C 9.811,120.175 8.314,118.679 8.314,116.85 L 81.458,116.85 C 81.458,118.679 79.962,120.175 78.134,120.175 L 11.639,120.175 z"
+ id="path2601" />
+ </g>
+ <linearGradient
+ x1="6.2178001"
+ y1="65.931602"
+ x2="79.360802"
+ y2="65.931602"
+ id="XMLID_28_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,-1.0756177)">
+ <stop
+ id="stop2604"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop2606"
+ style="stop-color:#eeeeec;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <path
+ d="M 9.542,118.05038 C 7.714,118.05038 6.218,116.55438 6.218,114.72638 L 6.218,14.986382 C 6.218,13.157382 7.714,11.661382 9.542,11.661382 L 76.037,11.661382 C 77.865,11.661382 79.361,13.157382 79.361,14.986382 L 79.361,114.72638 C 79.361,116.55438 77.865,118.05038 76.037,118.05038 L 9.542,118.05038 z"
+ id="path2608"
+ style="fill:url(#XMLID_28_)" />
+ </g>
+ <g
+ transform="translate(0,1.8317954)"
+ id="g2610">
+ <g
+ transform="matrix(1.0184218,0,0,1.0158314,-1.4821779,-1.8527316)"
+ id="g2612"
+ style="opacity:0.5;filter:url(#AI_Sfocatura_1)">
+ <path
+ d="M 10.639,117.029 C 8.811,117.029 7.314,115.532 7.314,113.704 L 7.314,13.964 C 7.314,12.135 8.811,10.639 10.639,10.639 L 77.134,10.639 C 78.962,10.639 80.458,12.135 80.458,13.964 L 80.458,113.704 C 80.458,115.532 78.962,117.029 77.134,117.029 L 10.639,117.029 z"
+ id="path2614" />
+ </g>
+ <linearGradient
+ x1="6.2178001"
+ y1="62.785599"
+ x2="79.360802"
+ y2="62.785599"
+ id="XMLID_29_"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ id="stop2617"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop2619"
+ style="stop-color:#eeeeec;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <path
+ d="M 9.542,115.98 C 7.714,115.98 6.218,114.483 6.218,112.656 L 6.218,12.916 C 6.218,11.087 7.714,9.591 9.542,9.591 L 76.037,9.591 C 77.865,9.591 79.361,11.087 79.361,12.916 L 79.361,112.657 C 79.361,114.484 77.865,115.981 76.037,115.981 L 9.542,115.981 L 9.542,115.98 z"
+ id="path2621"
+ style="fill:url(#XMLID_29_)" />
+ <linearGradient
+ x1="10.5708"
+ y1="10.1548"
+ x2="73.2117"
+ y2="112.4844"
+ id="XMLID_30_"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ id="stop2624"
+ style="stop-color:#73bdf2;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop2626"
+ style="stop-color:#3592ee;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <path
+ d="M 11.204,12.916 C 10.289,12.916 9.541,13.664 9.541,14.578 L 9.541,110.994 C 9.541,111.909 10.289,112.657 11.204,112.657 L 74.373,112.657 C 75.288,112.657 76.036,111.909 76.036,110.994 L 76.036,14.578 C 76.036,13.664 75.288,12.916 74.373,12.916 L 11.204,12.916 L 11.204,12.916 z"
+ id="path2628"
+ style="fill:url(#linearGradient3794)" />
+ </g>
+ </g>
+ <g
+ transform="matrix(0.9961334,-6.5068755e-2,6.5068755e-2,0.9961334,-5.7493275,-6.3015051)"
+ id="g2630">
+ <g
+ transform="matrix(1.0311837,0,0,1.0154411,-2.8218065,-1.9088007)"
+ id="g2632"
+ style="opacity:0.6;filter:url(#filter5869)">
+ <path
+ d="M 10.744,123.615 C 8.917,123.691 7.36,122.259 7.283,120.432 L 3.118,20.779 C 3.042,18.952 4.474,17.395 6.301,17.319 L 72.737,14.542 C 74.563,14.465 76.121,15.898 76.198,17.725 L 80.363,117.377 C 80.439,119.204 79.007,120.761 77.181,120.839 L 10.744,123.615 z"
+ id="path2634" />
+ </g>
+ <g
+ id="g2636">
+
+ <linearGradient
+ x1="3.7607"
+ y1="67.532204"
+ x2="76.909698"
+ y2="67.532204"
+ id="XMLID_31_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9991,-4.18e-2,4.18e-2,0.9991,-2.4309,1.195)">
+ <stop
+ id="stop2639"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop2641"
+ style="stop-color:#eeeeec;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <path
+ d="M 9.695,121.518 C 7.868,121.595 6.311,120.163 6.234,118.335 L 2.069,18.682 C 1.993,16.855 3.425,15.298 5.252,15.222 L 71.688,12.444 C 73.514,12.368 75.072,13.8 75.149,15.627 L 79.314,115.28 C 79.391,117.106 77.959,118.663 76.131,118.741 L 9.695,121.518 z"
+ id="path2643"
+ style="fill:url(#XMLID_31_)" />
+ </g>
+ <path
+ d="M 7.051,18.474 C 6.138,18.513 5.422,19.291 5.46,20.204 L 9.486,116.535 C 9.525,117.448 10.303,118.164 11.217,118.126 L 74.331,115.489 C 75.244,115.451 75.96,114.672 75.922,113.759 L 71.897,17.427 C 71.859,16.513 71.08,15.797 70.167,15.836 L 7.051,18.474 z"
+ id="path2652"
+ style="fill:url(#linearGradient3792);fill-opacity:1" />
+ <path
+ d="M 9.5625,22.375 C 10.84375,52.927083 12.125,83.479167 13.40625,114.03125 C 32.885417,113.21875 52.364583,112.40625 71.84375,111.59375 C 70.5625,81.041667 69.28125,50.489583 68,19.9375 C 48.520833,20.75 29.041667,21.5625 9.5625,22.375 z"
+ id="path4189"
+ style="opacity:0.6;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:1.00000001, 1.00000001;stroke-dashoffset:0;stroke-opacity:1" /></g>
+ <g
+ transform="matrix(0.9982563,0,0,0.9982563,10.72193,-5.1454722)"
+ id="g2654">
+ <g
+ transform="translate(-4.2156998e-8,1.0756177)"
+ id="g2656"
+ style="opacity:0.6;filter:url(#filter5873)">
+ <path
+ d="M 10.854785,112.52047 C 9.0174891,112.09656 7.8676311,110.2731 8.2990859,108.46891 L 31.839177,9.9940152 C 32.271664,8.1888112 34.127539,7.0580233 35.964835,7.481942 L 102.78149,22.901224 C 104.61776,23.325142 105.76865,25.149615 105.33616,26.954819 L 81.79607,125.42768 C 81.364615,127.23289 79.507708,128.36368 77.671444,127.93976 L 10.854785,112.52047 z"
+ id="path2658" />
+ </g>
+ <g
+ id="g2660">
+
+ <linearGradient
+ x1="16.688499"
+ y1="-8.9546003"
+ x2="94.108398"
+ y2="105.6356"
+ id="XMLID_33_"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9735,0.2287,-0.2287,0.9735,14.4454,7.996)">
+ <stop
+ id="stop2663"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop2665"
+ style="stop-color:#eeeeec;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <path
+ d="M 12.707,111.688 C 10.927,111.271 9.813,109.472 10.231,107.692 L 33.037,10.593 C 33.455,8.813 35.254,7.698 37.034,8.116 L 101.767,23.32 C 103.546,23.738 104.661,25.537 104.243,27.317 L 81.436,124.415 C 81.019,126.195 79.219,127.31 77.44,126.892 L 12.707,111.688 z"
+ id="path2667"
+ style="fill:url(#XMLID_33_)" />
+ </g>
+ <path
+ d="M 33.925,25.17 L 35.435,25.3 C 35.369,25.76 35.413,26.134 35.567,26.422 C 35.721,26.71 35.941,26.887 36.226,26.954 C 36.538,27.027 36.832,26.947 37.114,26.715 C 37.396,26.483 37.594,26.116 37.712,25.615 C 37.821,25.149 37.805,24.759 37.661,24.445 C 37.517,24.132 37.298,23.939 37.004,23.87 C 36.811,23.825 36.571,23.817 36.281,23.846 L 36.797,22.386 C 37.187,22.487 37.522,22.455 37.801,22.292 C 38.076,22.127 38.26,21.847 38.353,21.451 C 38.431,21.12 38.41,20.843 38.291,20.618 C 38.172,20.392 37.984,20.25 37.729,20.19 C 37.473,20.13 37.226,20.187 36.987,20.358 C 36.749,20.531 36.562,20.825 36.427,21.24 L 35.104,20.624 C 35.455,19.78 35.886,19.208 36.401,18.909 C 36.915,18.61 37.492,18.536 38.131,18.686 C 38.85,18.855 39.36,19.244 39.663,19.853 C 39.967,20.462 40.045,21.076 39.9,21.695 C 39.802,22.113 39.618,22.468 39.35,22.758 C 39.081,23.049 38.726,23.276 38.287,23.439 C 38.699,23.661 38.996,24.004 39.18,24.471 C 39.362,24.937 39.383,25.471 39.242,26.073 C 39.036,26.949 38.604,27.613 37.948,28.064 C 37.29,28.515 36.601,28.655 35.88,28.486 C 35.189,28.323 34.661,27.944 34.297,27.347 C 33.931,26.751 33.808,26.025 33.925,25.17 z"
+ id="path2676"
+ style="fill:url(#linearGradient3368);fill-opacity:1" />
+ <linearGradient
+ x1="26.294399"
+ y1="11.6704"
+ x2="71.901901"
+ y2="133.0273"
+ id="XMLID_35_"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ id="stop2679"
+ style="stop-color:#ff8080;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop2681"
+ style="stop-color:#e20800;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <path
+ d="M 32.977,38.964 C 33.619,37.58 34.903,36.55 35.811,35.945 C 36.752,35.319 37.49,34.55 37.729,33.53 C 38.094,31.979 36.471,30.257 34.621,31.997 C 33.74,29.616 31.507,30.433 31.143,31.984 C 30.903,33.003 31.223,34.019 31.786,35 C 32.329,35.946 33.021,37.439 32.977,38.964 z"
+ id="path2683"
+ style="fill:url(#linearGradient3352);fill-opacity:1" />
+ <path
+ d="M 80.223,109.559 L 78.711,109.43 C 78.779,108.969 78.734,108.595 78.58,108.308 C 78.426,108.02 78.205,107.842 77.922,107.776 C 77.61,107.703 77.315,107.782 77.033,108.014 C 76.751,108.246 76.553,108.614 76.433,109.114 C 76.324,109.581 76.341,109.97 76.484,110.284 C 76.629,110.598 76.849,110.79 77.142,110.859 C 77.335,110.904 77.576,110.913 77.865,110.883 L 77.349,112.343 C 76.958,112.242 76.624,112.274 76.345,112.439 C 76.07,112.603 75.886,112.883 75.792,113.279 C 75.714,113.609 75.735,113.887 75.854,114.112 C 75.973,114.339 76.161,114.481 76.416,114.541 C 76.672,114.602 76.918,114.545 77.156,114.372 C 77.394,114.2 77.582,113.906 77.717,113.49 L 79.039,114.106 C 78.689,114.95 78.258,115.521 77.742,115.82 C 77.228,116.119 76.652,116.193 76.013,116.043 C 75.294,115.874 74.783,115.486 74.48,114.876 C 74.175,114.268 74.097,113.653 74.244,113.034 C 74.342,112.616 74.525,112.262 74.795,111.971 C 75.063,111.681 75.418,111.453 75.857,111.289 C 75.445,111.069 75.146,110.725 74.964,110.259 C 74.78,109.793 74.761,109.259 74.902,108.657 C 75.109,107.78 75.541,107.117 76.197,106.666 C 76.855,106.216 77.543,106.075 78.265,106.244 C 78.956,106.406 79.484,106.786 79.849,107.382 C 80.217,107.978 80.34,108.704 80.223,109.559 z"
+ id="path2694"
+ style="fill:#e20800;fill-opacity:1" /><path
+ d="M 81.063,95.83 C 80.422,97.214 79.138,98.244 78.23,98.85 C 77.29,99.477 76.55,100.246 76.311,101.264 C 75.947,102.815 77.57,104.536 79.419,102.797 C 80.301,105.178 82.533,104.361 82.898,102.811 C 83.138,101.791 82.819,100.776 82.255,99.795 C 81.711,98.849 81.021,97.355 81.063,95.83 z"
+ id="path2701"
+ style="fill:url(#linearGradient3382);fill-opacity:1" />
+ <linearGradient
+ x1="54.356899"
+ y1="1.124"
+ x2="99.964401"
+ y2="122.481"
+ id="XMLID_39_"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ id="stop2704"
+ style="stop-color:#ff8080;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop2706"
+ style="stop-color:#e20800;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <path
+ d="M 63.174,42.222 C 64.361,39.656 66.742,37.748 68.427,36.625 C 70.171,35.463 71.54,34.04 71.985,32.15 C 72.66,29.274 69.651,26.081 66.22,29.307 C 64.585,24.892 60.448,26.406 59.772,29.281 C 59.329,31.172 59.921,33.055 60.965,34.873 C 61.97,36.628 63.253,39.396 63.174,42.222 z"
+ id="path2708"
+ style="fill:url(#linearGradient3370);fill-opacity:1" />
+ <linearGradient
+ x1="36.838902"
+ y1="7.7075"
+ x2="82.446297"
+ y2="129.0645"
+ id="XMLID_40_"
+ xlink:href="#XMLID_39_"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ id="stop2711"
+ style="stop-color:#ff8080;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop2713"
+ style="stop-color:#e20800;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <path
+ d="M 55.486,74.959 C 56.672,72.393 59.054,70.485 60.737,69.362 C 62.481,68.2 63.851,66.777 64.296,64.886 C 64.97,62.01 61.962,58.818 58.532,62.043 C 56.897,57.628 52.759,59.142 52.082,62.018 C 51.638,63.908 52.23,65.792 53.275,67.609 C 54.281,69.364 55.565,72.132 55.486,74.959 z"
+ id="path2715"
+ style="fill:url(#linearGradient3354);fill-opacity:1" />
+ <path
+ d="M 51.37,92.488 C 50.182,95.054 47.801,96.961 46.117,98.084 C 44.373,99.246 43.004,100.67 42.559,102.561 C 41.884,105.436 44.893,108.627 48.323,105.404 C 49.958,109.82 54.096,108.304 54.772,105.428 C 55.217,103.538 54.623,101.655 53.579,99.836 C 52.573,98.082 51.291,95.314 51.37,92.488 z"
+ id="path2724"
+ style="fill:url(#linearGradient3376);fill-opacity:1" />
+ </g>
+</g>
+</svg>
diff --git a/tests/manual/imagehandler/main.qml b/tests/manual/imagehandler/main.qml
new file mode 100644
index 0000000000..55e5b89cae
--- /dev/null
+++ b/tests/manual/imagehandler/main.qml
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import QtQuick.Window 2.0
+
+Window {
+ id: root
+ width: 480
+ height: 480
+ visible: true
+ Image {
+ id: svgImage
+ source: "large.svg"
+ height: parent.height - column.height
+ width: parent.width
+ sourceSize.height: height
+ sourceSize.width: width
+ }
+ ListModel {
+ id: imageFillModeModel
+ ListElement { text: "Stretch"; fillMode: Image.Stretch }
+ ListElement { text: "Preserve Aspect Fit"; fillMode: Image.PreserveAspectFit }
+ ListElement { text: "Preserve Aspect Crop"; fillMode: Image.PreserveAspectCrop }
+ ListElement { text: "Tile"; fillMode: Image.Tile }
+ ListElement { text: "Tile Vertically"; fillMode: Image.TileVertically }
+ ListElement { text: "Tile Horizontally"; fillMode: Image.TileHorizontally }
+ ListElement { text: "Pad"; fillMode: Image.Pad }
+ }
+ Column {
+ id: column
+ height: 75
+ anchors.bottom: parent.bottom
+ Text {
+ text: "Click the options below to change the fill mode"
+ font.pointSize: 16
+ }
+
+ Row {
+ id: checkBoxesRow
+ width: parent.width
+ Repeater {
+ model: imageFillModeModel
+ Rectangle {
+ color: "lightGreen"
+ height: 50
+ width: 100
+ Text {
+ text: model.text
+ wrapMode: Text.Wrap
+ font.pointSize: 16
+ anchors.fill: parent
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ svgImage.fillMode = model.fillMode
+ if (svgImage.fillMode === Image.Tile || svgImage.fillMode === Image.TileHorizontally ||
+ svgImage.fillMode === Image.TileVertically)
+ svgImage.sourceSize.height = svgImage.sourceSize.width = 300
+ else {
+ svgImage.sourceSize.height = svgImage.height
+ svgImage.sourceSize.width = svgImage.width
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/tests/manual/mousearea/main.cpp b/tests/manual/mousearea/main.cpp
new file mode 100644
index 0000000000..ea41cb521a
--- /dev/null
+++ b/tests/manual/mousearea/main.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QGuiApplication>
+#include <QQmlApplicationEngine>
+#include <QQuickItem>
+#include <QQuickWindow>
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+ QGuiApplication app(argc, argv);
+
+ QQmlApplicationEngine engine;
+ engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
+ if (!app.arguments().isEmpty()) {
+ QQuickWindow *win = static_cast<QQuickWindow *>(engine.rootObjects().first());
+ auto lastArg = app.arguments().last();
+ if (lastArg.endsWith(QLatin1String(".qml"))) {
+ auto root = win->findChild<QQuickItem *>("LauncherList");
+ int showExampleIdx = -1;
+ for (int i = root->metaObject()->methodCount(); showExampleIdx < 0 && i >= 0; --i)
+ if (root->metaObject()->method(i).name() == QByteArray("showExample"))
+ showExampleIdx = i;
+ QMetaMethod showExampleFn = root->metaObject()->method(showExampleIdx);
+ showExampleFn.invoke(root, Q_ARG(QVariant, QVariant(QLatin1String("../../") + lastArg)));
+ }
+ }
+
+ return app.exec();
+}
diff --git a/tests/manual/mousearea/main.qml b/tests/manual/mousearea/main.qml
new file mode 100644
index 0000000000..6c284c3586
--- /dev/null
+++ b/tests/manual/mousearea/main.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import QtQuick.Window 2.2
+import Qt.labs.handlers 1.0
+import "qrc:/quick/shared/" as Examples
+
+Window {
+ width: 800
+ height: 600
+ visible: true
+ Examples.LauncherList {
+ id: ll
+ objectName: "LauncherList"
+ anchors.fill: parent
+ Component.onCompleted: {
+ addExample("plain mouse area", "Plain mouse area for testing flags passed from mouse event", Qt.resolvedUrl("plainMouseArea.qml"))
+ }
+ }
+}
diff --git a/tests/manual/mousearea/mousearea.pro b/tests/manual/mousearea/mousearea.pro
new file mode 100644
index 0000000000..3705d41df0
--- /dev/null
+++ b/tests/manual/mousearea/mousearea.pro
@@ -0,0 +1,7 @@
+TEMPLATE = app
+
+QT += qml quick
+
+SOURCES += main.cpp
+
+RESOURCES += qml.qrc ../../../examples/quick/shared/quick_shared.qrc
diff --git a/tests/manual/mousearea/plainMouseArea.qml b/tests/manual/mousearea/plainMouseArea.qml
new file mode 100644
index 0000000000..4f37b0635f
--- /dev/null
+++ b/tests/manual/mousearea/plainMouseArea.qml
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.11
+
+Rectangle {
+ id: root
+ width: 480
+ height: 480
+ color: "white"
+ Text {
+ id: pressedLabel
+ x: 0
+ y: 0
+ width: 480
+ height: 50
+ font.pointSize: 18
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onPressed: {
+ pressedLabel.text = "Pressed - " + (mouse.flags === Qt.MouseEventCreatedDoubleClick ?
+ "Press from double click" : "No flags")
+ }
+ }
+}
diff --git a/tests/manual/mousearea/qml.qrc b/tests/manual/mousearea/qml.qrc
new file mode 100644
index 0000000000..870b50ae92
--- /dev/null
+++ b/tests/manual/mousearea/qml.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/">
+ <file>main.qml</file>
+ <file>plainMouseArea.qml</file>
+ </qresource>
+</RCC>
diff --git a/tests/manual/pointer/content/FakeFlickable.qml b/tests/manual/pointer/content/FakeFlickable.qml
new file mode 100644
index 0000000000..dbcf48d2f7
--- /dev/null
+++ b/tests/manual/pointer/content/FakeFlickable.qml
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+
+Item {
+ id: root
+ default property alias data: __contentItem.data
+ property alias velocity: anim.velocity
+ property alias contentX: __contentItem.x // sign is reversed compared to Flickable.contentX
+ property alias contentY: __contentItem.y // sign is reversed compared to Flickable.contentY
+ property alias contentWidth: __contentItem.width
+ property alias contentHeight: __contentItem.height
+ signal flickStarted
+ signal flickEnded
+
+ Item {
+ id: __contentItem
+ objectName: "__contentItem"
+ width: childrenRect.width
+ height: childrenRect.height
+
+ property real xlimit: root.width - __contentItem.width
+ property real ylimit: root.height - __contentItem.height
+
+ function returnToBounds() {
+ if (x > 0) {
+ returnXAnim.to = 0
+ returnXAnim.start()
+ } else if (x < xlimit) {
+ returnXAnim.to = xlimit
+ returnXAnim.start()
+ }
+ if (y > 0) {
+ returnYAnim.to = 0
+ returnYAnim.start()
+ } else if (y < ylimit) {
+ returnYAnim.to = ylimit
+ returnYAnim.start()
+ }
+ }
+
+ DragHandler {
+ id: dragHandler
+ onActiveChanged: if (!active) anim.restart(point.velocity)
+ }
+ MomentumAnimation {
+ id: anim
+ target: __contentItem
+ onStarted: root.flickStarted()
+ onStopped: {
+ __contentItem.returnToBounds()
+ root.flickEnded()
+ }
+ }
+ NumberAnimation {
+ id: returnXAnim
+ target: __contentItem
+ property: "x"
+ duration: 200
+ easing.type: Easing.OutQuad
+ }
+ NumberAnimation {
+ id: returnYAnim
+ target: __contentItem
+ property: "y"
+ duration: 200
+ easing.type: Easing.OutQuad
+ }
+ }
+}
diff --git a/tests/manual/pointer/content/FlashAnimation.qml b/tests/manual/pointer/content/FlashAnimation.qml
new file mode 100644
index 0000000000..4b2935b52e
--- /dev/null
+++ b/tests/manual/pointer/content/FlashAnimation.qml
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+SequentialAnimation {
+ id: tapFlash
+ running: false
+ PropertyAction { value: false }
+ PauseAnimation { duration: 100 }
+ PropertyAction { value: true }
+ PauseAnimation { duration: 100 }
+ PropertyAction { value: false }
+ PauseAnimation { duration: 100 }
+ PropertyAction { value: true }
+ PauseAnimation { duration: 100 }
+ PropertyAction { value: false }
+ PauseAnimation { duration: 100 }
+ PropertyAction { value: true }
+}
diff --git a/tests/manual/pointer/content/MomentumAnimation.qml b/tests/manual/pointer/content/MomentumAnimation.qml
new file mode 100644
index 0000000000..bd21475970
--- /dev/null
+++ b/tests/manual/pointer/content/MomentumAnimation.qml
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+
+ParallelAnimation {
+ id: root
+ property Item target: null
+ property int duration: 500
+ property vector2d velocity: Qt.vector2d(0,0)
+
+ function restart(vel) {
+ stop()
+ velocity = vel
+ start()
+ }
+
+ NumberAnimation {
+ id: xAnim
+ target: root.target
+ property: "x"
+ to: target.x + velocity.x / duration * 100000
+ duration: root.duration
+ easing.type: Easing.OutQuad
+ }
+ NumberAnimation {
+ id: yAnim
+ target: root.target
+ property: "y"
+ to: target.y + velocity.y / duration * 100000
+ duration: root.duration
+ easing.type: Easing.OutQuad
+ }
+}
diff --git a/tests/manual/pointer/content/MouseAreaButton.qml b/tests/manual/pointer/content/MouseAreaButton.qml
new file mode 100644
index 0000000000..43337520a5
--- /dev/null
+++ b/tests/manual/pointer/content/MouseAreaButton.qml
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Window 2.1
+
+Item {
+ id: container
+
+ property alias text: buttonLabel.text
+ property alias label: buttonLabel
+ signal clicked
+ property alias containsMouse: mouseArea.containsMouse
+ property alias pressed: mouseArea.pressed
+ implicitHeight: Math.max(Screen.pixelDensity * 7, buttonLabel.implicitHeight * 1.2)
+ implicitWidth: Math.max(Screen.pixelDensity * 11, buttonLabel.implicitWidth * 1.3)
+ height: implicitHeight
+ width: implicitWidth
+
+ SystemPalette { id: palette }
+
+ Rectangle {
+ id: frame
+ anchors.fill: parent
+ color: palette.button
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: mouseArea.pressed ? Qt.darker(palette.button, 1.3) : palette.button }
+ GradientStop { position: 1.0; color: Qt.darker(palette.button, 1.3) }
+ }
+ antialiasing: true
+ radius: height / 6
+ border.color: Qt.darker(palette.button, 1.5)
+ border.width: 1
+ }
+
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ onClicked: container.clicked()
+ hoverEnabled: true
+ }
+
+ Text {
+ id: buttonLabel
+ text: container.text
+ color: palette.buttonText
+ anchors.centerIn: parent
+ }
+}
diff --git a/tests/manual/pointer/content/MouseAreaSlider.qml b/tests/manual/pointer/content/MouseAreaSlider.qml
new file mode 100644
index 0000000000..4e2cfee6a9
--- /dev/null
+++ b/tests/manual/pointer/content/MouseAreaSlider.qml
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.7
+
+Item {
+ id: root
+ property int value: 50
+ property int maximumValue: 99
+ property alias label: label.text
+
+ Rectangle {
+ id: slot
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ anchors.margins: 10
+ anchors.topMargin: 30
+ anchors.bottomMargin: 30
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: 10
+ color: "black"
+ radius: width / 2
+ smooth: true
+ }
+
+ Rectangle {
+ // RectangularGlow is better, but that's a different module
+ id: glow
+ anchors.fill: knob
+ anchors.margins: -5
+ anchors.leftMargin: -2
+ anchors.horizontalCenterOffset: 1
+ radius: 5
+ color: "#4400FFFF"
+ opacity: ma.pressed ? 1 : 0
+ }
+ Image {
+ id: knob
+ source: "../resources/mixer-knob.png"
+ antialiasing: true
+ x: slot.x - width / 2 + slot.width / 2
+ height: root.width / 2
+ width: implicitWidth / implicitHeight * height
+ property bool programmatic: false
+ property real multiplier: root.maximumValue / (ma.drag.maximumY - ma.drag.minimumY)
+ onYChanged: if (!programmatic) root.value = root.maximumValue - (knob.y - ma.drag.minimumY) * multiplier
+ transformOrigin: Item.Center
+ function setValue(value) { knob.y = ma.drag.maximumY - value / knob.multiplier }
+ MouseArea {
+ id: ma
+ anchors.fill: parent
+ drag.target: parent
+ drag.minimumX: knob.x
+ drag.maximumX: knob.x
+ drag.minimumY: slot.y
+ drag.maximumY: slot.height + slot.y - knob.height
+ }
+ }
+
+ Text {
+ font.pointSize: 16
+ color: "red"
+ anchors.bottom: parent.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ text: root.value
+ }
+
+ Text {
+ id: label
+ font.pointSize: 12
+ color: "red"
+ anchors.top: parent.top
+ anchors.topMargin: 5
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+
+ onHeightChanged: {
+ knob.programmatic = true
+ knob.setValue(root.value)
+ knob.programmatic = false
+ }
+}
diff --git a/tests/manual/pointer/content/MouseFeedbackSprite.qml b/tests/manual/pointer/content/MouseFeedbackSprite.qml
new file mode 100644
index 0000000000..c61a07b3ea
--- /dev/null
+++ b/tests/manual/pointer/content/MouseFeedbackSprite.qml
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+
+PointHandler {
+ id: handler
+ objectName: "mouse point"
+ acceptedDevices: PointerDevice.Mouse
+ acceptedButtons: Qt.AllButtons
+ target: Image {
+ objectName: "mouse sprite"
+ source: "../resources/mouse.png"
+ visible: handler.active
+ x: handler.point.position.x - width / 2
+ y: handler.point.position.y - height / 2
+ parent: handler.parent
+ Image {
+ source: "../resources/mouse_left.png"
+ visible: handler.point.pressedButtons & Qt.LeftButton
+ }
+ Image {
+ source: "../resources/mouse_middle.png"
+ visible: handler.point.pressedButtons & Qt.MiddleButton
+ }
+ Image {
+ source: "../resources/mouse_right.png"
+ visible: handler.point.pressedButtons & Qt.RightButton
+ }
+ }
+}
diff --git a/tests/manual/pointer/content/MptaButton.qml b/tests/manual/pointer/content/MptaButton.qml
new file mode 100644
index 0000000000..a35446632d
--- /dev/null
+++ b/tests/manual/pointer/content/MptaButton.qml
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.7
+import QtQuick.Window 2.1
+
+Item {
+ id: container
+
+ property alias text: buttonLabel.text
+ property alias label: buttonLabel
+ signal clicked
+ property alias pressed: point.pressed
+ implicitHeight: Math.max(Screen.pixelDensity * 7, buttonLabel.implicitHeight * 1.2)
+ implicitWidth: Math.max(Screen.pixelDensity * 11, buttonLabel.implicitWidth * 1.3)
+ height: implicitHeight
+ width: implicitWidth
+
+ SystemPalette { id: palette }
+
+ Rectangle {
+ id: frame
+ anchors.fill: parent
+ color: palette.button
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: container.pressed ? Qt.darker(palette.button, 1.3) : palette.button }
+ GradientStop { position: 1.0; color: Qt.darker(palette.button, 1.3) }
+ }
+ antialiasing: true
+ radius: height / 6
+ border.color: Qt.darker(palette.button, 1.5)
+ border.width: 1
+ }
+
+ MultiPointTouchArea {
+ id: mpta
+ anchors.fill: parent
+ touchPoints: [ TouchPoint {
+ id: point
+ onPressedChanged: if (!pressed) container.clicked()
+ } ]
+ }
+
+ Text {
+ id: buttonLabel
+ text: container.text
+ color: palette.buttonText
+ anchors.centerIn: parent
+ }
+}
diff --git a/tests/manual/pointer/content/MultiButton.qml b/tests/manual/pointer/content/MultiButton.qml
new file mode 100644
index 0000000000..2a41967a36
--- /dev/null
+++ b/tests/manual/pointer/content/MultiButton.qml
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+
+Rectangle {
+ id: root
+ property alias label: label.text
+ property alias pressed: tap.pressed
+ property bool checked: false
+ property alias gesturePolicy: tap.gesturePolicy
+ signal tapped
+
+ width: label.implicitWidth * 1.5; height: label.implicitHeight * 2.0
+ border.color: "#9f9d9a"; border.width: 1; radius: height / 4; antialiasing: true
+
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: tap.pressed ? "#b8b5b2" : "#efebe7" }
+ GradientStop { position: 1.0; color: "#b8b5b2" }
+ }
+
+ TapHandler {
+ id: tap
+ objectName: label.text
+ onTapped: {
+ tapFlash.start()
+ root.tapped()
+ }
+ }
+
+ Text {
+ id: label
+ font.pointSize: 14
+ text: "Button"
+ anchors.centerIn: parent
+ }
+
+ Rectangle {
+ anchors.fill: parent
+ color: "transparent"
+ border.width: 2; radius: root.radius; antialiasing: true
+ opacity: tapFlash.running ? 1 : 0
+ FlashAnimation on visible {
+ id: tapFlash
+ }
+ }
+}
diff --git a/tests/manual/pointer/content/ScrollBar.qml b/tests/manual/pointer/content/ScrollBar.qml
new file mode 100644
index 0000000000..e659c5d7af
--- /dev/null
+++ b/tests/manual/pointer/content/ScrollBar.qml
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+
+Rectangle {
+ id: root
+ property real contentHeight: 100
+ property FakeFlickable flick: null
+ property real position
+
+ onPositionChanged: if (flick && (drag.active || tap.active)) {
+ if (knob.state === "horizontal")
+ flick.contentX = position * knob.scrollDistance
+ else if (knob.state === "vertical")
+ flick.contentY = position * knob.scrollDistance
+ }
+
+ SystemPalette { id: palette }
+
+ color: palette.button
+ border.color: Qt.darker(palette.button, 1.5)
+ gradient: Gradient {
+ GradientStop { position: 0; color: Qt.darker(palette.button, 1.3) }
+ GradientStop { position: 1; color: palette.button }
+ }
+ antialiasing: true
+ radius: Math.min(width, height) / 6
+ width: 20
+ height: 20
+
+ TapHandler {
+ id: tap
+ onTapped: {
+ if (knob.state === "horizontal")
+ knob.x = position.x - knob.width / 2
+ else if (knob.state === "vertical")
+ knob.y = position.y - knob.height / 2
+ }
+ }
+
+ Rectangle {
+ id: knob
+ border.color: "black"
+ border.width: 1
+ gradient: Gradient {
+ GradientStop { position: 0; color: palette.button }
+ GradientStop { position: 1; color: Qt.darker(palette.button, 1.3) }
+ }
+ radius: 2
+ antialiasing: true
+ state: root.height > root.width ? "vertical" : root.height < root.width ? "horizontal" : ""
+ property real scrollDistance: 0
+ property real scrolledX: 0
+ property real scrolledY: 0
+ property real max: 0
+
+ Binding on x {
+ value: knob.scrolledX
+ when: !drag.active
+ }
+
+ Binding on y {
+ value: knob.scrolledY
+ when: !drag.active
+ }
+
+ states: [
+ // We will control the horizontal. We will control the vertical.
+ State {
+ name: "horizontal"
+ PropertyChanges {
+ target: knob
+ max: root.width - knob.width
+ scrolledX: Math.min(max, Math.max(0, max * flick.contentX / (flick.width - flick.contentWidth)))
+ scrolledY: 1
+ scrollDistance: flick.width - flick.contentWidth
+ width: flick.width * (flick.width / flick.contentWidth) - (height - anchors.margins) * 2
+ height: root.height - 2
+ }
+ PropertyChanges {
+ target: drag
+ xAxis.minimum: 0
+ xAxis.maximum: knob.max
+ yAxis.minimum: 1
+ yAxis.maximum: 1
+ }
+ PropertyChanges {
+ target: root
+ position: knob.x / drag.xAxis.maximum
+ }
+ },
+ State {
+ name: "vertical"
+ PropertyChanges {
+ target: knob
+ max: root.height - knob.height
+ scrolledX: 1
+ scrolledY: Math.min(max, Math.max(0, max * flick.contentY / (flick.height - flick.contentHeight)))
+ scrollDistance: flick.height - flick.contentHeight
+ width: root.width - 2
+ height: root.width - 2
+ }
+ PropertyChanges {
+ target: drag
+ xAxis.minimum: 1
+ xAxis.maximum: 1
+ yAxis.minimum: 0
+ yAxis.maximum: knob.max
+ }
+ PropertyChanges {
+ target: root
+ position: knob.y / drag.yAxis.maximum
+ }
+ }
+ ]
+
+ DragHandler {
+ id: drag
+ }
+ }
+}
diff --git a/tests/manual/pointer/content/Slider.qml b/tests/manual/pointer/content/Slider.qml
new file mode 100644
index 0000000000..1741fb1bc6
--- /dev/null
+++ b/tests/manual/pointer/content/Slider.qml
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+
+Item {
+ id: root
+ property int value: 50
+ property int maximumValue: 99
+ property alias label: label.text
+ property alias tapEnabled: tap.enabled
+ property alias pressed: tap.pressed
+ signal tapped
+
+ DragHandler {
+ id: dragHandler
+ objectName: label.text + " DragHandler"
+ target: knob
+ xAxis.enabled: false
+ yAxis.minimum: slot.y
+ yAxis.maximum: slot.height + slot.y - knob.height
+ }
+
+ Rectangle {
+ id: slot
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ anchors.margins: 10
+ anchors.topMargin: 30
+ anchors.bottomMargin: 30
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: 10
+ color: "black"
+ radius: width / 2
+ smooth: true
+ }
+
+ Rectangle {
+ // RectangularGlow is better, but that's a different module
+ id: glow
+ anchors.fill: knob
+ anchors.margins: -5
+ anchors.leftMargin: -2
+ anchors.horizontalCenterOffset: 1
+ radius: 5
+ color: "#4400FFFF"
+ opacity: tap.pressed || tapFlash.running ? 1 : 0
+ FlashAnimation on visible {
+ id: tapFlash
+ }
+ }
+ Image {
+ id: knob
+ source: "../resources/mixer-knob.png"
+ antialiasing: true
+ x: slot.x - width / 2 + slot.width / 2
+ height: root.width / 2
+ width: implicitWidth / implicitHeight * height
+ property bool programmatic: false
+ property real multiplier: root.maximumValue / (dragHandler.yAxis.maximum - dragHandler.yAxis.minimum)
+ onYChanged: if (!programmatic) root.value = root.maximumValue - (knob.y - dragHandler.yAxis.minimum) * multiplier
+ transformOrigin: Item.Center
+ function setValue(value) { knob.y = dragHandler.yAxis.maximum - value / knob.multiplier }
+ TapHandler {
+ id: tap
+ objectName: label.text + " TapHandler"
+ gesturePolicy: TapHandler.DragThreshold
+ onTapped: {
+ tapFlash.start()
+ root.tapped
+ }
+ }
+ }
+
+ Text {
+ font.pointSize: 16
+ color: "red"
+ anchors.bottom: parent.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ text: root.value
+ }
+
+ Text {
+ id: label
+ font.pointSize: 12
+ color: "red"
+ anchors.top: parent.top
+ anchors.topMargin: 5
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+
+ onHeightChanged: {
+ knob.programmatic = true
+ knob.setValue(root.value)
+ knob.programmatic = false
+ }
+}
diff --git a/tests/manual/pointer/content/TapHandlerButton.qml b/tests/manual/pointer/content/TapHandlerButton.qml
new file mode 100644
index 0000000000..28187044c2
--- /dev/null
+++ b/tests/manual/pointer/content/TapHandlerButton.qml
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.7
+import QtQuick.Window 2.1
+import Qt.labs.handlers 1.0
+
+Item {
+ id: container
+
+ property alias text: buttonLabel.text
+ property alias label: buttonLabel
+ signal clicked
+ property alias pressed: th.pressed
+ implicitHeight: Math.max(Screen.pixelDensity * 7, buttonLabel.implicitHeight * 1.2)
+ implicitWidth: Math.max(Screen.pixelDensity * 11, buttonLabel.implicitWidth * 1.3)
+ height: implicitHeight
+ width: implicitWidth
+
+ SystemPalette { id: palette }
+
+ Rectangle {
+ id: frame
+ anchors.fill: parent
+ color: palette.button
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: container.pressed ? Qt.darker(palette.button, 1.3) : palette.button }
+ GradientStop { position: 1.0; color: Qt.darker(palette.button, 1.3) }
+ }
+ antialiasing: true
+ radius: height / 6
+ border.color: Qt.darker(palette.button, 1.5)
+ border.width: 1
+ }
+
+ TapHandler {
+ id: th
+ onTapped: container.clicked()
+ }
+
+ Text {
+ id: buttonLabel
+ text: container.text
+ color: palette.buttonText
+ anchors.centerIn: parent
+ }
+}
diff --git a/tests/manual/pointer/content/TouchpointFeedbackSprite.qml b/tests/manual/pointer/content/TouchpointFeedbackSprite.qml
new file mode 100644
index 0000000000..ffcead59d4
--- /dev/null
+++ b/tests/manual/pointer/content/TouchpointFeedbackSprite.qml
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+
+PointHandler {
+ id: handler
+ objectName: "point " + handler.point.id.toString(16)
+ acceptedDevices: PointerDevice.TouchScreen | PointerDevice.TouchPad
+ target: AnimatedSprite {
+ objectName: "sprite " + handler.point.id.toString(16)
+ source: "../resources/fingersprite.png"
+ visible: handler.active
+ running: visible // QTBUG-64544: running defaults to true, but we don't see it animating if we don't toggle it like this
+ x: handler.point.position.x - 20
+ y: handler.point.position.y - 13
+ width: frameWidth
+ height: frameHeight
+ frameWidth: 43
+ frameHeight: 64
+ frameCount: 3
+ frameRate: 5
+ parent: handler.parent
+ }
+}
diff --git a/tests/manual/pointer/fakeFlickable.qml b/tests/manual/pointer/fakeFlickable.qml
new file mode 100644
index 0000000000..bde378c33d
--- /dev/null
+++ b/tests/manual/pointer/fakeFlickable.qml
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+import "content"
+
+Rectangle {
+ color: "#444"
+ width: 480
+ height: 480
+
+ FakeFlickable {
+ id: ff
+ anchors.fill: parent
+ anchors.rightMargin: rightSB.width
+ Row {
+ Item {
+ width: 100
+ height: 400
+ Slider {
+ id: slider
+ label: "font size"
+ anchors.fill: parent
+ maximumValue: 36
+ value: 14
+ }
+ }
+ Text {
+ id: text
+ color: "beige"
+ font.family: "mono"
+ font.pointSize: slider.value
+ onTextChanged: console.log("text geom " + width + "x" + height +
+ ", parent " + parent + " geom " + parent.width + "x" + parent.height)
+ }
+ }
+
+
+ onFlickStarted: console.log("flick started with velocity " + velocity)
+ onFlickEnded: console.log("flick ended with velocity " + velocity)
+
+ Component.onCompleted: {
+ var request = new XMLHttpRequest()
+ request.open('GET', 'content/FakeFlickable.qml')
+ request.onreadystatechange = function(event) {
+ if (request.readyState === XMLHttpRequest.DONE)
+ text.text = request.responseText
+ }
+ request.send()
+ }
+ }
+
+ ScrollBar {
+ id: rightSB
+ objectName: "rightSB"
+ flick: ff
+ height: parent.height - width
+ anchors.right: parent.right
+ }
+
+ ScrollBar {
+ id: bottomSB
+ objectName: "bottomSB"
+ flick: ff
+ width: parent.width - height
+ anchors.bottom: parent.bottom
+ }
+
+ Rectangle {
+ id: cornerCover
+ color: "lightgray"
+ width: rightSB.width
+ height: bottomSB.height
+ anchors {
+ right: parent.right
+ bottom: parent.bottom
+ }
+ }
+}
diff --git a/tests/manual/pointer/flickableWithHandlers.qml b/tests/manual/pointer/flickableWithHandlers.qml
new file mode 100644
index 0000000000..28009a7024
--- /dev/null
+++ b/tests/manual/pointer/flickableWithHandlers.qml
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.7
+import Qt.labs.handlers 1.0
+import "qrc:/quick/shared/" as Examples
+import "content"
+
+Rectangle {
+ id: root
+ width: 400
+ height: 400
+ objectName: "root"
+ color: "#222222"
+
+ Flickable {
+ anchors.fill: parent
+ anchors.margins: 10
+ anchors.topMargin: 40
+ contentHeight: 600
+ contentWidth: 600
+ pressDelay: pressDelayCB.checked ? 1000 : 0
+
+ Column {
+ spacing: 6
+ Rectangle {
+ radius: 5
+ width: parent.width - 12
+ height: pressDelayCB.implicitHeight + 12
+ x: 6
+ color: "lightgray"
+ Examples.CheckBox {
+ x: 6; y: 6
+ id: pressDelayCB
+ text: "press delay"
+ }
+ }
+
+
+ Row {
+ spacing: 6
+ Slider {
+ label: "DragHandler"
+ value: 49; width: 100; height: 400
+ }
+ MouseAreaSlider {
+ label: "MouseArea"
+ value: 49; width: 100; height: 400
+ }
+ Column {
+ spacing: 6
+ MouseAreaButton {
+ text: "MouseArea"
+ }
+ MptaButton {
+ text: "MultiPointTouchArea"
+ }
+ MptaButton {
+ text: "MultiPointTouchArea"
+ }
+ TapHandlerButton {
+ text: "TapHandler"
+ }
+ TapHandlerButton {
+ text: "TapHandler"
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/tests/manual/pointer/flingAnimation.qml b/tests/manual/pointer/flingAnimation.qml
new file mode 100644
index 0000000000..3b0d359530
--- /dev/null
+++ b/tests/manual/pointer/flingAnimation.qml
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+import "content"
+
+Rectangle {
+ id: root
+ width: 640
+ height: 480
+ color: "black"
+
+ Repeater {
+ model: 2
+
+ Image {
+ id: ball
+ objectName: "ball" + index
+ source: "resources/redball.png"
+ property real homeX: 200 + index * 200
+ property real homeY: 200
+ width: 80; height: 80; x: homeX; y: 200
+
+ Text {
+ anchors.centerIn: parent
+ color: "white"
+ text: momentum.velocity.x.toFixed(2) + "," + momentum.velocity.y.toFixed(2)
+ }
+
+ SequentialAnimation {
+ id: anim
+
+ function restart(vel) {
+ stop()
+ momentum.velocity = vel
+ start()
+ }
+
+ MomentumAnimation { id: momentum; target: ball }
+
+ PauseAnimation { duration: 500 }
+
+ ParallelAnimation {
+ id: ballReturn
+ NumberAnimation {
+ target: ball
+ property: "x"
+ to: homeX
+ duration: 1000
+ easing.period: 50
+ easing.type: Easing.OutElastic
+ }
+ NumberAnimation {
+ target: ball
+ property: "y"
+ to: homeY
+ duration: 1000
+ easing.type: Easing.OutElastic
+ }
+ }
+ }
+
+ DragHandler {
+ id: dragHandler
+ objectName: "dragHandler" + index
+ onActiveChanged: {
+ if (!active)
+ anim.restart(point.velocity)
+ }
+ }
+ Rectangle {
+ visible: dragHandler.active
+ anchors.fill: parent
+ anchors.margins: -5
+ radius: width / 2
+ opacity: 0.25
+ }
+
+ Rectangle {
+ visible: width > 0
+ width: dragHandler.point.velocity.length() * 100
+ height: 2
+ x: ball.width / 2
+ y: ball.height / 2
+ z: -1
+ rotation: Math.atan2(dragHandler.point.velocity.y, dragHandler.point.velocity.x) * 180 / Math.PI
+ transformOrigin: Item.BottomLeft
+ antialiasing: true
+
+ Image {
+ source: "resources/arrowhead.png"
+ anchors.right: parent.right
+ anchors.verticalCenter: parent.verticalCenter
+ width: 16
+ height: 12
+ antialiasing: true
+ }
+ }
+ }
+ }
+}
diff --git a/tests/manual/pointer/joystick.qml b/tests/manual/pointer/joystick.qml
new file mode 100644
index 0000000000..f5be17ddc9
--- /dev/null
+++ b/tests/manual/pointer/joystick.qml
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.10
+import Qt.labs.handlers 1.0
+
+Item {
+ width: image.implicitWidth; height: image.implicitHeight
+ Image {
+ id: image
+ anchors.centerIn: parent
+ source: "resources/joystick-outer-case-pov.jpg"
+ property real margin: 50
+
+ Image {
+ id: knob
+ source: "resources/redball.png"
+ DragHandler {
+ id: dragHandler
+ xAxis {
+ minimum: image.margin
+ maximum: image.width - image.margin - knob.width
+ }
+ yAxis {
+ minimum: image.margin
+ maximum: image.height - image.margin - knob.height
+ }
+ }
+
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ verticalCenter: parent.verticalCenter
+ }
+ states: [
+ State {
+ when: dragHandler.active
+ AnchorChanges {
+ target: knob
+ anchors.horizontalCenter: undefined
+ anchors.verticalCenter: undefined
+ }
+ }
+ ]
+ transitions: [
+ Transition {
+ AnchorAnimation { easing.type: Easing.OutElastic }
+ }
+ ]
+ }
+ }
+}
diff --git a/tests/manual/pointer/main.cpp b/tests/manual/pointer/main.cpp
new file mode 100644
index 0000000000..97d8422b69
--- /dev/null
+++ b/tests/manual/pointer/main.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QGuiApplication>
+#include <QQmlApplicationEngine>
+#include <QQuickItem>
+#include <QQuickWindow>
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+ QGuiApplication app(argc, argv);
+
+ QQmlApplicationEngine engine;
+ engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
+ if (!app.arguments().isEmpty()) {
+ QQuickWindow * win = static_cast<QQuickWindow *>(engine.rootObjects().first());
+ auto lastArg = app.arguments().last();
+ if (lastArg.endsWith(QLatin1String(".qml"))) {
+ auto root = win->findChild<QQuickItem *>("LauncherList");
+ int showExampleIdx = -1;
+ for (int i = root->metaObject()->methodCount(); showExampleIdx < 0 && i >= 0; --i)
+ if (root->metaObject()->method(i).name() == QByteArray("showExample"))
+ showExampleIdx = i;
+ QMetaMethod showExampleFn = root->metaObject()->method(showExampleIdx);
+ showExampleFn.invoke(root, Q_ARG(QVariant, QVariant(QLatin1String("../../") + lastArg)));
+ }
+ }
+
+ return app.exec();
+}
diff --git a/tests/manual/pointer/main.qml b/tests/manual/pointer/main.qml
new file mode 100644
index 0000000000..a50bfc3872
--- /dev/null
+++ b/tests/manual/pointer/main.qml
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import QtQuick.Window 2.2
+import Qt.labs.handlers 1.0
+import "qrc:/quick/shared/" as Examples
+import "content"
+
+Window {
+ width: 800
+ height: 600
+ visible: true
+ Examples.LauncherList {
+ id: ll
+ objectName: "LauncherList"
+ anchors.fill: parent
+ Component.onCompleted: {
+ addExample("single point handler", "QQuickPointerSingleHandler: test properties copied from events", Qt.resolvedUrl("singlePointHandlerProperties.qml"))
+ addExample("joystick", "DragHandler: move one item inside another with any pointing device", Qt.resolvedUrl("joystick.qml"))
+ addExample("mixer", "mixing console", Qt.resolvedUrl("mixer.qml"))
+ addExample("pinch", "PinchHandler: scale, rotate and drag", Qt.resolvedUrl("pinchHandler.qml"))
+ addExample("map", "scale and pan", Qt.resolvedUrl("map.qml"))
+ addExample("custom map", "scale and pan", Qt.resolvedUrl("map2.qml"))
+ addExample("fling animation", "DragHandler: after dragging, use an animation to simulate momentum", Qt.resolvedUrl("flingAnimation.qml"))
+ addExample("fake Flickable", "implementation of a simplified Flickable using only Items, DragHandler and MomentumAnimation", Qt.resolvedUrl("fakeFlickable.qml"))
+ addExample("photo surface", "re-implementation of the existing photo surface demo using Handlers", Qt.resolvedUrl("photosurface.qml"))
+ addExample("tap", "TapHandler: device-agnostic tap/click detection for buttons", Qt.resolvedUrl("tapHandler.qml"))
+ addExample("multibuttons", "TapHandler: gesturePolicy (99 red balloons)", Qt.resolvedUrl("multibuttons.qml"))
+ addExample("flickable with Handlers", "Flickable with buttons, sliders etc. implemented in various ways", Qt.resolvedUrl("flickableWithHandlers.qml"))
+ }
+ }
+ Item {
+ id: glassPane
+ objectName: "glassPane"
+ z: 10000
+ anchors.fill: parent
+
+ // TODO use Instantiator to create these... but we need to be able to set their parents to glassPane somehow (QTBUG-64546)
+ TouchpointFeedbackSprite { }
+ TouchpointFeedbackSprite { }
+ TouchpointFeedbackSprite { }
+ TouchpointFeedbackSprite { }
+ TouchpointFeedbackSprite { }
+ TouchpointFeedbackSprite { }
+
+ MouseFeedbackSprite { }
+ }
+}
diff --git a/tests/manual/pointer/map.qml b/tests/manual/pointer/map.qml
new file mode 100644
index 0000000000..6ab6badfd0
--- /dev/null
+++ b/tests/manual/pointer/map.qml
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+
+Item {
+ width: 640
+ height: 480
+
+ Rectangle {
+ id: map
+ color: "aqua"
+ x: (parent.width - width) / 2
+ y: (parent.height - height) / 2
+ width: image.width
+ height: image.height
+
+ Image {
+ id: image
+ anchors.centerIn: parent
+ fillMode: Image.PreserveAspectFit
+ source: "resources/map.svgz"
+ Component.onCompleted: { width = implicitWidth; height = implicitHeight }
+ }
+ }
+
+ PinchHandler {
+ id: pinch
+ target: map
+ minimumScale: 0.1
+ maximumScale: 10
+ onActiveChanged: if (!active) reRenderIfNecessary()
+ }
+
+ DragHandler {
+ target: map
+ }
+
+ function reRenderIfNecessary() {
+ var newSourceWidth = image.sourceSize.width * pinch.scale
+ var ratio = newSourceWidth / image.sourceSize.width
+ if (ratio > 1.1 || ratio < 0.9)
+ image.sourceSize.width = newSourceWidth
+ }
+}
diff --git a/tests/manual/pointer/map2.qml b/tests/manual/pointer/map2.qml
new file mode 100644
index 0000000000..4d8755b996
--- /dev/null
+++ b/tests/manual/pointer/map2.qml
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+
+Item {
+ width: 640
+ height: 480
+
+ Rectangle {
+ id: map
+ color: "aqua"
+ x: (parent.width - width) / 2
+ y: (parent.height - height) / 2
+ width: image.implicitWidth
+ height: image.implicitHeight
+ property point center : Qt.point(x + map.width/2, y + map.height/2)
+
+ function setCenter(xx, yy) {
+ map.x = xx - map.width/2
+ map.y = yy - map.height/2
+ }
+
+
+ Image {
+ id: image
+ anchors.centerIn: parent
+ fillMode: Image.PreserveAspectFit
+ source: "resources/map.svgz"
+ }
+ }
+
+ PinchHandler {
+ id: pinch
+ target: map
+ minimumScale: 0.1
+ maximumScale: 10
+ }
+
+ DragHandler {
+ property point startDrag
+ target: null
+ onActiveChanged: {
+ if (active)
+ startDrag = map.center
+ }
+
+ onTranslationChanged: {
+ if (!target)
+ map.setCenter(startDrag.x + translation.x, startDrag.y + translation.y)
+ }
+ }
+}
diff --git a/tests/manual/pointer/mixer.qml b/tests/manual/pointer/mixer.qml
new file mode 100644
index 0000000000..64c4b102d1
--- /dev/null
+++ b/tests/manual/pointer/mixer.qml
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+import "content"
+
+Rectangle {
+ id: root
+ width: 1280
+ height: 960
+ objectName: "root"
+ color: "#222222"
+
+ ListView {
+ id: list
+ objectName: "listView"
+ anchors.fill: parent
+ anchors.margins: 10
+ orientation: Qt.Horizontal
+
+ model: 20
+
+ delegate: Item {
+ objectName: "delegateItem" + index
+ width: 154
+ height: list.height
+
+ Slider {
+ anchors.fill: parent
+ label: "Channel " + (index + 1)
+ }
+ }
+ }
+}
diff --git a/tests/manual/pointer/multibuttons.qml b/tests/manual/pointer/multibuttons.qml
new file mode 100644
index 0000000000..cd7c5d0b19
--- /dev/null
+++ b/tests/manual/pointer/multibuttons.qml
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtQuick.Particles 2.0
+import QtQuick.Layouts 1.0
+import Qt.labs.handlers 1.0
+import "content"
+
+Item {
+ width: 800
+ height: 800
+ ColumnLayout {
+ anchors.right: parent.right
+ spacing: 20
+ Text { text: "protagonist"; font.pointSize: 12 }
+ MultiButton {
+ id: balloonsButton
+ label: "Launch Balloons"
+ Layout.fillWidth: true
+ gesturePolicy: TapHandler.WithinBounds
+ }
+ Text { text: "the goons"; font.pointSize: 12 }
+ MultiButton {
+ id: missilesButton
+ label: "Launch Missile"
+ Layout.fillWidth: true
+ gesturePolicy: TapHandler.ReleaseWithinBounds
+ onTapped: missileEmitter.burst(1)
+ }
+ MultiButton {
+ id: fightersButton
+ label: "Launch Fighters"
+ Layout.fillWidth: true
+ gesturePolicy: TapHandler.DragThreshold
+ }
+ }
+ ParticleSystem {
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ anchors.leftMargin: 150
+ ImageParticle { source: "resources/balloon.png" }
+ Emitter { anchors.bottom: parent.bottom; enabled: balloonsButton.pressed; lifeSpan: 5000; size: 64
+ maximumEmitted: 99
+ emitRate: 50; velocity: PointDirection { x: 10; y: -150; yVariation: 30; xVariation: 50 } } }
+ ParticleSystem {
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.right: parent.right
+ ImageParticle { source: "resources/fighter.png" }
+ Emitter { anchors.bottom: parent.bottom; enabled: fightersButton.pressed; lifeSpan: 15000; size: 204
+ emitRate: 3; velocity: PointDirection { x: -1000; y: -250; yVariation: 150; xVariation: 50 } } }
+ ParticleSystem {
+ anchors.bottom: parent.bottom
+ anchors.right: parent.right
+ anchors.rightMargin: 100
+ ImageParticle { source: "resources/missile.png"; autoRotation: true; rotation: 90 }
+ Emitter { id: missileEmitter; anchors.bottom: parent.bottom; lifeSpan: 5000; size: 128;
+ emitRate: 0; velocity: PointDirection { x: -200; y: -350; yVariation: 200; xVariation: 100 } } }
+}
diff --git a/tests/manual/pointer/photosurface.qml b/tests/manual/pointer/photosurface.qml
new file mode 100644
index 0000000000..04aef538f9
--- /dev/null
+++ b/tests/manual/pointer/photosurface.qml
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import QtQuick.Dialogs 1.0
+import Qt.labs.folderlistmodel 1.0
+import Qt.labs.handlers 1.0
+import "content"
+
+Rectangle {
+ id: root
+ visible: true
+ width: 1024; height: 600
+ color: "black"
+ property int highestZ: 0
+ property real defaultSize: 200
+ property real surfaceViewportRatio: 1.5
+
+ FileDialog {
+ id: fileDialog
+ title: "Choose a folder with some images"
+ selectFolder: true
+ onAccepted: folderModel.folder = fileUrl + "/"
+ }
+ Shortcut {
+ id: openShortcut
+ sequence: StandardKey.Open
+ onActivated: fileDialog.open()
+ }
+
+ FakeFlickable {
+ id: flick
+ anchors.fill: parent
+ contentWidth: width * 2
+ contentHeight: height * 2
+ Repeater {
+ model: FolderListModel {
+ id: folderModel
+ folder: "resources/"
+ objectName: "folderModel"
+ showDirs: false
+ nameFilters: ["*.png", "*.jpg", "*.gif"]
+ }
+ Rectangle {
+ id: photoFrame
+ objectName: "frame-" + fileName
+ width: image.width * (1 + 0.10 * image.height / image.width)
+ height: image.height * 1.10
+ scale: defaultSize / Math.max(image.sourceSize.width, image.sourceSize.height)
+ Behavior on scale { NumberAnimation { duration: 200 } }
+ Behavior on x { NumberAnimation { duration: 200 } }
+ Behavior on y { NumberAnimation { duration: 200 } }
+ border.color: pinchHandler.active || dragHandler.active ? "red" : "black"
+ border.width: 2
+ smooth: true
+ antialiasing: true
+ Component.onCompleted: {
+ x = Math.random() * root.width - width / 2
+ y = Math.random() * root.height - height / 2
+ rotation = Math.random() * 13 - 6
+ }
+ Image {
+ id: image
+ anchors.centerIn: parent
+ fillMode: Image.PreserveAspectFit
+ source: folderModel.folder + fileName
+ antialiasing: true
+ }
+
+ MomentumAnimation { id: anim; target: photoFrame }
+
+ DragHandler {
+ id: dragHandler
+ onActiveChanged: {
+ if (!active)
+ anim.restart(point.velocity)
+ }
+ }
+
+ PinchHandler {
+ id: pinchHandler
+ minimumRotation: -360
+ maximumRotation: 360
+ minimumScale: 0.1
+ maximumScale: 10
+ property real zRestore: 0
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ id: verticalScrollDecorator
+ anchors.right: parent.right
+ anchors.margins: 2
+ color: "cyan"
+ border.color: "black"
+ border.width: 1
+ width: 5
+ radius: 2
+ antialiasing: true
+ height: flick.height * (flick.height / flick.contentHeight) - (width - anchors.margins) * 2
+ y: -flick.contentY * (flick.height / flick.contentHeight)
+ NumberAnimation on opacity { id: vfade; to: 0; duration: 500 }
+ onYChanged: { opacity = 1.0; fadeTimer.restart() }
+ }
+
+ Rectangle {
+ id: horizontalScrollDecorator
+ anchors.bottom: parent.bottom
+ anchors.margins: 2
+ color: "cyan"
+ border.color: "black"
+ border.width: 1
+ height: 5
+ radius: 2
+ antialiasing: true
+ width: flick.width * (flick.width / flick.contentWidth) - (height - anchors.margins) * 2
+ x: -flick.contentX * (flick.width / flick.contentWidth)
+ NumberAnimation on opacity { id: hfade; to: 0; duration: 500 }
+ onXChanged: { opacity = 1.0; fadeTimer.restart() }
+ }
+
+ Timer { id: fadeTimer; interval: 1000; onTriggered: { hfade.start(); vfade.start() } }
+
+ Text {
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.margins: 10
+ color: "darkgrey"
+ wrapMode: Text.WordWrap
+ font.pointSize: 8
+ text: "Press " + openShortcut.nativeText + " to choose a different image folder\n" +
+ "On a touchscreen: use two fingers to zoom and rotate, one finger to drag\n" +
+ "With a mouse: drag normally"
+ }
+}
diff --git a/tests/manual/pointer/pinchDragFlingMPTA.qml b/tests/manual/pointer/pinchDragFlingMPTA.qml
new file mode 100644
index 0000000000..2578d62466
--- /dev/null
+++ b/tests/manual/pointer/pinchDragFlingMPTA.qml
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+import "content"
+
+Rectangle {
+ width: 1024; height: 600
+ color: "beige"
+ objectName: "beige root"
+
+ function getTransformationDetails(item, pinchhandler) {
+ return "scale:" + pinchhandler.scale.toFixed(2)
+ + " rotation:" + pinchhandler.rotation.toFixed(2)
+ + " translation:" + "(" + pinchhandler.translation.x.toFixed(2) + "," + pinchhandler.translation.y.toFixed(2) + ")"
+ }
+
+ Rectangle {
+ id: container
+ objectName: "container rect"
+ width: 600
+ height: 500
+ color: pinch3.active ? "red" : "black"
+ antialiasing: true
+ Loader {
+ source: "../touch/mpta-crosshairs.qml"
+ anchors.fill: parent
+ anchors.margins: 2
+ }
+ Item {
+ anchors.fill: parent
+ // In order for PinchHandler to get a chance to take a passive grab, it has to get the touchpoints first.
+ // In order to get the touchpoints first, it has to be on top of the Z order: i.e. come last in paintOrderChildItems().
+ // This is the opposite situation as with filtersChildMouseEvents: e.g. PinchArea would have wanted to be the parent,
+ // if it even knew that trick (which it doesn't).
+ PinchHandler {
+ id: pinch3
+ objectName: "3-finger pinch"
+ target: container
+ minimumPointCount: 3
+ minimumScale: 0.1
+ maximumScale: 10
+ onActiveChanged: if (!active) fling.restart(centroidVelocity)
+ }
+ DragHandler {
+ id: dragHandler
+ objectName: "DragHandler"
+ target: container
+ acceptedModifiers: Qt.MetaModifier
+ onActiveChanged: if (!active) fling.restart(point.velocity)
+ }
+ }
+ MomentumAnimation { id: fling; target: container }
+ }
+ Text {
+ anchors.bottom: parent.bottom
+ text: pinch3.active ? getTransformationDetails(container, pinch3) :
+ "Pinch with 3 fingers to scale, rotate and translate\nHold down Meta to drag with one finger or mouse"
+ }
+}
diff --git a/tests/manual/pointer/pinchHandler.qml b/tests/manual/pointer/pinchHandler.qml
new file mode 100644
index 0000000000..409b852b55
--- /dev/null
+++ b/tests/manual/pointer/pinchHandler.qml
@@ -0,0 +1,176 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+import "content"
+
+Rectangle {
+ width: 1024; height: 600
+ color: "#eee"
+
+ function getTransformationDetails(item, pinchhandler) {
+ return "\n\npinch.scale:" + pinchhandler.scale.toFixed(2)
+ + "\npinch.rotation:" + pinchhandler.rotation.toFixed(2)
+ + "\npinch.translation:" + "(" + pinchhandler.translation.x.toFixed(2) + "," + pinchhandler.translation.y.toFixed(2) + ")"
+ + "\nrect.scale: " + item.scale.toFixed(2)
+ + "\nrect.rotation: " + item.rotation.toFixed(2)
+ + "\nrect.position: " + "(" + item.x.toFixed(2) + "," + item.y.toFixed(2) + ")"
+ }
+
+ function activePincher() {
+ if (grandparentPinch.active)
+ return grandparentPinch
+ else if (parentPinch.active)
+ return parentPinch
+ else if (pinch2.active)
+ return pinch2
+ return pinch3 // always return a pinch handler, even when its inactive. The indicator will be invisble anyway.
+ }
+
+ Rectangle {
+ width: parent.width - 100; height: parent.height - 100; x: 50; y: 50
+ color: "beige"
+ border.width: grandparentPinch.active ? 2 : 0
+ border.color: border.width > 0 ? "red" : "transparent"
+ antialiasing: true
+
+ PinchHandler {
+ id: grandparentPinch
+ objectName: "grandparent pinch"
+ minimumScale: 0.5
+ maximumScale: 3
+ minimumPointCount: 3
+ }
+
+ Text {
+ text: "Pinch with 3 fingers to scale, rotate and translate"
+ + getTransformationDetails(parent, grandparentPinch)
+ }
+
+ Rectangle {
+ width: parent.width - 100; height: parent.height - 100; x: 50; y: 50
+ color: "#ffe0e0e0"
+ antialiasing: true
+
+ PinchHandler {
+ id: parentPinch
+ objectName: "parent pinch"
+ minimumScale: 0.5
+ maximumScale: 3
+ }
+
+ Text {
+ text: "Pinch with 2 fingers to scale, rotate and translate"
+ + getTransformationDetails(parent, parentPinch)
+ }
+
+ Rectangle {
+ id: rect2
+ width: 400
+ height: 300
+ color: "lightsteelblue"
+ antialiasing: true
+ x: 100
+ y: 200
+ rotation: 30
+ transformOrigin: Item.TopRight
+ border.width: (lsbDragHandler.active || pinch2.active) ? 2 : 0
+ border.color: border.width > 0 ? "red" : "transparent"
+
+ Text {
+ anchors.centerIn: parent
+ text: "Pinch with 2 fingers to scale, rotate and translate\nDrag with 1 finger"
+ + getTransformationDetails(rect2, pinch2) + "\nz " + rect2.z
+ }
+ DragHandler {
+ id: lsbDragHandler
+ objectName: "lightsteelblue drag"
+ }
+ PinchHandler {
+ id: pinch2
+ objectName: "lightsteelblue pinch"
+ minimumRotation: -45
+ maximumRotation: 45
+ minimumScale: 0.5
+ maximumScale: 3
+ minimumX: 0
+ maximumX: 600
+ // acceptedModifiers: Qt.ControlModifier
+ }
+ TapHandler { gesturePolicy: TapHandler.DragThreshold; onTapped: rect2.z = rect3.z + 1 }
+ }
+
+ Rectangle {
+ id: rect3
+ x: 500
+ width: 400
+ height: 300
+ color: "wheat"
+ antialiasing: true
+ border.width: (wheatDragHandler.active || pinch3.active) ? 2 : 0
+ border.color: border.width > 0 ? "red" : "transparent"
+
+ Text {
+ anchors.centerIn: parent
+ text: "Pinch with 3 fingers to scale, rotate and translate\nDrag with 1 finger"
+ + getTransformationDetails(rect3, pinch3) + "\nz " + rect3.z
+ }
+ DragHandler {
+ id: wheatDragHandler
+ objectName: "wheat drag"
+ }
+ PinchHandler {
+ id: pinch3
+ objectName: "wheat 3-finger pinch"
+ minimumPointCount: 3
+ minimumScale: 0.1
+ maximumScale: 10
+ onActiveChanged: {
+ if (!active)
+ anim.restart(centroidVelocity)
+ }
+ }
+ TapHandler { gesturePolicy: TapHandler.DragThreshold; onTapped: rect3.z = rect2.z + 1 }
+ MomentumAnimation { id: anim; target: rect3 }
+ }
+ }
+ }
+ Rectangle {
+ id: centroidIndicator
+ property QtObject pincher: activePincher()
+ x: pincher.centroid.x - radius
+ y: pincher.centroid.y - radius
+ z: 1
+ visible: pincher.active
+ radius: width / 2
+ width: 10
+ height: width
+ color: "red"
+ }
+}
diff --git a/tests/manual/pointer/pointer.pro b/tests/manual/pointer/pointer.pro
new file mode 100644
index 0000000000..79044a102e
--- /dev/null
+++ b/tests/manual/pointer/pointer.pro
@@ -0,0 +1,7 @@
+TEMPLATE = app
+
+QT += qml quick svg
+
+SOURCES += main.cpp
+
+RESOURCES += qml.qrc ../../../examples/quick/shared/quick_shared.qrc
diff --git a/tests/manual/pointer/qml.qrc b/tests/manual/pointer/qml.qrc
new file mode 100644
index 0000000000..f9d600b16c
--- /dev/null
+++ b/tests/manual/pointer/qml.qrc
@@ -0,0 +1,43 @@
+<RCC>
+ <qresource prefix="/">
+ <file>flingAnimation.qml</file>
+ <file>main.qml</file>
+ <file>fakeFlickable.qml</file>
+ <file>flickableWithHandlers.qml</file>
+ <file>joystick.qml</file>
+ <file>map.qml</file>
+ <file>mixer.qml</file>
+ <file>multibuttons.qml</file>
+ <file>photosurface.qml</file>
+ <file>pinchHandler.qml</file>
+ <file>singlePointHandlerProperties.qml</file>
+ <file>tapHandler.qml</file>
+ <file>content/FakeFlickable.qml</file>
+ <file>content/FlashAnimation.qml</file>
+ <file>content/MomentumAnimation.qml</file>
+ <file>content/MouseAreaButton.qml</file>
+ <file>content/MouseAreaSlider.qml</file>
+ <file>content/MouseFeedbackSprite.qml</file>
+ <file>content/MptaButton.qml</file>
+ <file>content/MultiButton.qml</file>
+ <file>content/ScrollBar.qml</file>
+ <file>content/Slider.qml</file>
+ <file>content/TapHandlerButton.qml</file>
+ <file>content/TouchpointFeedbackSprite.qml</file>
+ <file>resources/arrowhead.png</file>
+ <file>resources/balloon.png</file>
+ <file>resources/fighter.png</file>
+ <file>resources/fingersprite.png</file>
+ <file>resources/grabbing-location.svg</file>
+ <file>resources/joystick-outer-case-pov.jpg</file>
+ <file>resources/map.svgz</file>
+ <file>resources/missile.png</file>
+ <file>resources/mixer-knob.png</file>
+ <file>resources/mouse.png</file>
+ <file>resources/mouse_left.png</file>
+ <file>resources/mouse_middle.png</file>
+ <file>resources/mouse_right.png</file>
+ <file>resources/redball.png</file>
+ <file>map2.qml</file>
+ </qresource>
+</RCC>
diff --git a/tests/manual/pointer/resources/arrowhead.png b/tests/manual/pointer/resources/arrowhead.png
new file mode 100644
index 0000000000..7719bc6d6a
--- /dev/null
+++ b/tests/manual/pointer/resources/arrowhead.png
Binary files differ
diff --git a/tests/manual/pointer/resources/balloon.png b/tests/manual/pointer/resources/balloon.png
new file mode 100644
index 0000000000..6476facc49
--- /dev/null
+++ b/tests/manual/pointer/resources/balloon.png
Binary files differ
diff --git a/tests/manual/pointer/resources/fighter.png b/tests/manual/pointer/resources/fighter.png
new file mode 100644
index 0000000000..2acee43cba
--- /dev/null
+++ b/tests/manual/pointer/resources/fighter.png
Binary files differ
diff --git a/tests/manual/pointer/resources/fingersprite.png b/tests/manual/pointer/resources/fingersprite.png
new file mode 100644
index 0000000000..423d115fdf
--- /dev/null
+++ b/tests/manual/pointer/resources/fingersprite.png
Binary files differ
diff --git a/tests/manual/pointer/resources/grabbing-location.svg b/tests/manual/pointer/resources/grabbing-location.svg
new file mode 100644
index 0000000000..c26881e9ba
--- /dev/null
+++ b/tests/manual/pointer/resources/grabbing-location.svg
@@ -0,0 +1 @@
+<svg width="3408" height="3124"><path d="M1517 1562c0-126-93-229-208-229s-208 102-208 229c0 126 93 229 208 229s208-102 208-229zm123-172c-58-206-221-365-424-412l-270 531H380l203-223 219-241 346-380c42 14 82 32 121 54 232 128 402 375 449 671h-77zm-551-933c448 123 782 546 802 1055h1517C3386 673 2787 0 2050 0H696L0 1367h120l826-938 146 25c-1 1-2 2-3 4zm551 1277c-58 206-221 365-424 412l-270-531H380l203 223 219 241 346 380c42-14 82-32 121-54 232-128 402-375 449-671h-77zm-548 936l-146 25-826-938H0l696 1367h1354c737 0 1337-673 1358-1512H1891c-19 509-354 933-802 1055 1 1 2 2 3 4z" fill="#ee832b"/></svg>
diff --git a/tests/manual/pointer/resources/joystick-outer-case-pov.jpg b/tests/manual/pointer/resources/joystick-outer-case-pov.jpg
new file mode 100644
index 0000000000..01cd78fdcf
--- /dev/null
+++ b/tests/manual/pointer/resources/joystick-outer-case-pov.jpg
Binary files differ
diff --git a/tests/manual/pointer/resources/map.svgz b/tests/manual/pointer/resources/map.svgz
new file mode 100644
index 0000000000..64d509c106
--- /dev/null
+++ b/tests/manual/pointer/resources/map.svgz
Binary files differ
diff --git a/tests/manual/pointer/resources/missile.png b/tests/manual/pointer/resources/missile.png
new file mode 100644
index 0000000000..72c02d1fb9
--- /dev/null
+++ b/tests/manual/pointer/resources/missile.png
Binary files differ
diff --git a/tests/manual/pointer/resources/mixer-knob.png b/tests/manual/pointer/resources/mixer-knob.png
new file mode 100644
index 0000000000..b7d42ee3bd
--- /dev/null
+++ b/tests/manual/pointer/resources/mixer-knob.png
Binary files differ
diff --git a/tests/manual/pointer/resources/mouse.png b/tests/manual/pointer/resources/mouse.png
new file mode 100644
index 0000000000..268946df0a
--- /dev/null
+++ b/tests/manual/pointer/resources/mouse.png
Binary files differ
diff --git a/tests/manual/pointer/resources/mouse_left.png b/tests/manual/pointer/resources/mouse_left.png
new file mode 100644
index 0000000000..9292301b47
--- /dev/null
+++ b/tests/manual/pointer/resources/mouse_left.png
Binary files differ
diff --git a/tests/manual/pointer/resources/mouse_middle.png b/tests/manual/pointer/resources/mouse_middle.png
new file mode 100644
index 0000000000..064e8b9c16
--- /dev/null
+++ b/tests/manual/pointer/resources/mouse_middle.png
Binary files differ
diff --git a/tests/manual/pointer/resources/mouse_right.png b/tests/manual/pointer/resources/mouse_right.png
new file mode 100644
index 0000000000..cab1a36ba6
--- /dev/null
+++ b/tests/manual/pointer/resources/mouse_right.png
Binary files differ
diff --git a/tests/manual/pointer/resources/redball.png b/tests/manual/pointer/resources/redball.png
new file mode 100644
index 0000000000..68d2e1d638
--- /dev/null
+++ b/tests/manual/pointer/resources/redball.png
Binary files differ
diff --git a/tests/manual/pointer/singlePointHandlerProperties.qml b/tests/manual/pointer/singlePointHandlerProperties.qml
new file mode 100644
index 0000000000..c11042cf14
--- /dev/null
+++ b/tests/manual/pointer/singlePointHandlerProperties.qml
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+import Qt.labs.handlers 1.0
+
+Rectangle {
+ id: root
+ width: 480
+ height: 480
+ color: "black"
+
+ Item {
+ id: crosshairs
+ x: dragHandler.point.position.x - width / 2
+ y: dragHandler.point.position.y - height / 2
+ width: parent.width / 2; height: parent.height / 2
+ visible: dragHandler.active
+ rotation: dragHandler.point.rotation
+
+ Rectangle {
+ color: "goldenrod"
+ anchors.centerIn: parent
+ width: 2; height: parent.height
+ antialiasing: true
+ }
+ Rectangle {
+ color: "goldenrod"
+ anchors.centerIn: parent
+ width: parent.width; height: 2
+ antialiasing: true
+ }
+ Rectangle {
+ color: "goldenrod"
+ width: Math.max(2, 50 * dragHandler.point.pressure)
+ height: width
+ radius: width / 2
+ anchors.centerIn: parent
+ antialiasing: true
+ Rectangle {
+ y: -40
+ anchors.horizontalCenter: parent.horizontalCenter
+ color: "lightsteelblue"
+ implicitWidth: label.implicitWidth
+ implicitHeight: label.implicitHeight
+ Text {
+ id: label
+ text: 'id: ' + dragHandler.point.id.toString(16) + " uid: " + dragHandler.point.uniqueId.numericId +
+ '\npos: (' + dragHandler.point.position.x.toFixed(2) + ', ' + dragHandler.point.position.y.toFixed(2) + ')'
+ }
+ }
+ }
+ Rectangle {
+ color: "transparent"
+ border.color: "white"
+ antialiasing: true
+ width: dragHandler.point.ellipseDiameters.width
+ height: dragHandler.point.ellipseDiameters.height
+ radius: Math.min(width / 2, height / 2)
+ anchors.centerIn: parent
+ }
+ }
+ Rectangle {
+ id: velocityVector
+ visible: width > 0
+ width: dragHandler.point.velocity.length() * 100
+ height: 2
+ x: dragHandler.point.position.x
+ y: dragHandler.point.position.y
+ rotation: Math.atan2(dragHandler.point.velocity.y, dragHandler.point.velocity.x) * 180 / Math.PI
+ transformOrigin: Item.BottomLeft
+ antialiasing: true
+
+ Image {
+ source: "resources/arrowhead.png"
+ anchors.right: parent.right
+ anchors.verticalCenter: parent.verticalCenter
+ width: 16
+ height: 12
+ antialiasing: true
+ }
+ }
+
+ Component {
+ id: grabbingLocationIndicator
+ Image {
+ source: "resources/grabbing-location.svg"
+ sourceSize.width: 32
+ sourceSize.height: 32
+ }
+ }
+
+ Component {
+ id: mouseButtonIndicator
+ Image {
+ property int buttons
+ source: "resources/mouse.png"
+ Image {
+ source: "resources/mouse_left.png"
+ visible: buttons & Qt.LeftButton
+ }
+ Image {
+ source: "resources/mouse_middle.png"
+ visible: buttons & Qt.MidButton
+ }
+ Image {
+ source: "resources/mouse_right.png"
+ visible: buttons & Qt.RightButton
+ }
+ }
+ }
+
+ DragHandler {
+ id: dragHandler
+ target: null
+ acceptedButtons: Qt.AllButtons
+ onGrabChanged: if (active) { // 'point' is an implicit parameter referencing to a QQuickEventPoint instance
+ console.log("grabbed " + point.pointId + " @ " + point.sceneGrabPos)
+ grabbingLocationIndicator.createObject(root, {"x": point.sceneGrabPosition.x, "y": point.sceneGrabPosition.y - 16})
+ }
+ onPointChanged: {
+ // Here, 'point' is referring to the property of the DragHandler
+ if (point.pressedButtons)
+ mouseButtonIndicator.createObject(root, {"x": point.pressPosition.x - 44, "y": point.pressPosition.y - 64, "buttons": point.pressedButtons})
+ }
+ }
+}
diff --git a/tests/manual/pointer/tapHandler.qml b/tests/manual/pointer/tapHandler.qml
new file mode 100644
index 0000000000..94777c268c
--- /dev/null
+++ b/tests/manual/pointer/tapHandler.qml
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+import "qrc:/quick/shared/" as Examples
+
+Item {
+ width: 480
+ height: 320
+
+ Rectangle {
+ id: rect
+ anchors.fill: parent; anchors.margins: 40
+ border.width: 3; border.color: "transparent"
+ color: handler.pressed ? "lightsteelblue" : "darkgrey"
+
+ TapHandler {
+ id: handler
+ acceptedButtons: (leftAllowedCB.checked ? Qt.LeftButton : Qt.NoButton) |
+ (middleAllowedCB.checked ? Qt.MiddleButton : Qt.NoButton) |
+ (rightAllowedCB.checked ? Qt.RightButton : Qt.NoButton)
+ gesturePolicy: (policyDragThresholdCB.checked ? TapHandler.DragThreshold :
+ policyWithinBoundsCB.checked ? TapHandler.WithinBounds :
+ TapHandler.ReleaseWithinBounds)
+
+ onCanceled: {
+ console.log("canceled @ " + point.position)
+ borderBlink.blinkColor = "red"
+ borderBlink.start()
+ }
+ onTapped: { // 'point' is an implicit parameter referencing to a QQuickEventPoint instance
+ if (tapCount > 1) {
+ tapCountLabel.text = tapCount
+ flashAnimation.start()
+ } else {
+ borderBlink.start()
+ }
+ }
+ onLongPressed: longPressFeedback.createObject(rect,
+ {"x": point.position.x, "y": point.position.y,
+ "text": Math.round(handler.timeHeld).toFixed(3) + " sec",
+ "color": borderBlink.blinkColor})
+ }
+
+ Text {
+ id: tapCountLabel
+ anchors.centerIn: parent
+ font.pixelSize: 72
+ font.weight: Font.Black
+ SequentialAnimation {
+ id: flashAnimation
+ PropertyAction { target: tapCountLabel; property: "visible"; value: true }
+ PropertyAction { target: tapCountLabel; property: "opacity"; value: 1.0 }
+ PropertyAction { target: tapCountLabel; property: "scale"; value: 1.0 }
+ ParallelAnimation {
+ NumberAnimation {
+ target: tapCountLabel
+ property: "opacity"
+ to: 0
+ duration: 500
+ }
+ NumberAnimation {
+ target: tapCountLabel
+ property: "scale"
+ to: 1.5
+ duration: 500
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ id: expandingCircle
+ radius: handler.timeHeld * 100
+ visible: radius > 0 && handler.pressed
+ border.width: 3
+ border.color: borderBlink.blinkColor
+ color: "transparent"
+ width: radius * 2
+ height: radius * 2
+ x: handler.point.pressPosition.x - radius
+ y: handler.point.pressPosition.y - radius
+ opacity: 0.25
+ }
+
+ Component {
+ id: longPressFeedback
+ Text { }
+ }
+
+ SequentialAnimation {
+ id: borderBlink
+ property color blinkColor: (function(pbtns) {
+ switch (pbtns) {
+ case Qt.MiddleButton: return "orange";
+ case Qt.RightButton: return "magenta";
+ default: return "green";
+ }
+ })(handler.point.pressedButtons)
+ loops: 3
+ ScriptAction { script: rect.border.color = borderBlink.blinkColor }
+ PauseAnimation { duration: 100 }
+ ScriptAction { script: rect.border.color = "transparent" }
+ PauseAnimation { duration: 100 }
+ }
+ }
+
+ Row {
+ spacing: 6
+ Text { text: "accepted mouse clicks:"; anchors.verticalCenter: leftAllowedCB.verticalCenter }
+ Examples.CheckBox {
+ id: leftAllowedCB
+ checked: true
+ text: "left click"
+ }
+ Examples.CheckBox {
+ id: middleAllowedCB
+ text: "middle click"
+ }
+ Examples.CheckBox {
+ id: rightAllowedCB
+ text: "right click"
+ }
+ Text { text: " gesture policy:"; anchors.verticalCenter: leftAllowedCB.verticalCenter }
+ Examples.CheckBox {
+ id: policyDragThresholdCB
+ text: "drag threshold"
+ onCheckedChanged: if (checked) {
+ policyWithinBoundsCB.checked = false;
+ policyReleaseWithinBoundsCB.checked = false;
+ }
+ }
+ Examples.CheckBox {
+ id: policyWithinBoundsCB
+ text: "within bounds"
+ onCheckedChanged: if (checked) {
+ policyDragThresholdCB.checked = false;
+ policyReleaseWithinBoundsCB.checked = false;
+ }
+ }
+ Examples.CheckBox {
+ id: policyReleaseWithinBoundsCB
+ checked: true
+ text: "release within bounds"
+ onCheckedChanged: if (checked) {
+ policyDragThresholdCB.checked = false;
+ policyWithinBoundsCB.checked = false;
+ }
+ }
+ }
+}
diff --git a/tests/manual/pointer/tapWithModifiers.qml b/tests/manual/pointer/tapWithModifiers.qml
new file mode 100644
index 0000000000..74db33125d
--- /dev/null
+++ b/tests/manual/pointer/tapWithModifiers.qml
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import Qt.labs.handlers 1.0
+
+Item {
+ width: 200
+ height: 200
+ TapHandler {
+ acceptedModifiers: Qt.ControlModifier
+ onTapped: console.log("control-tapped")
+ }
+ TapHandler {
+ acceptedModifiers: Qt.NoModifier
+ onTapped: console.log("tapped with no modifiers")
+ }
+ TapHandler {
+ onTapped: console.log("tapped with modifiers " + point.event.modifiers)
+ }
+}
diff --git a/tests/manual/quickwidgetviewer/main.cpp b/tests/manual/quickwidgetviewer/main.cpp
new file mode 100644
index 0000000000..0f305b0328
--- /dev/null
+++ b/tests/manual/quickwidgetviewer/main.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+#include <QCommandLineOption>
+#include <QCommandLineParser>
+#include <QDebug>
+#include <QDir>
+#include <QFileDialog>
+#include <QOpenGLFunctions>
+#include <QOpenGLContext>
+#include <QQmlEngine>
+#include <QQuickWidget>
+#include <QUrl>
+
+#include <iostream>
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ QCoreApplication::setApplicationName("QQuickWidget Viewer");
+ QCoreApplication::setOrganizationName("QtProject");
+ QCoreApplication::setApplicationVersion(QT_VERSION_STR);
+ QCommandLineParser parser;
+ parser.addHelpOption();
+ parser.addVersionOption();
+ parser.addPositionalArgument("url", "The URL to open.");
+ parser.process(app);
+
+ QUrl url;
+ if (parser.positionalArguments().isEmpty()) {
+ QFileDialog fileDialog(nullptr, "Select QML File");
+ fileDialog.setMimeTypeFilters(QStringList("text/x-qml"));
+ if (fileDialog.exec() != QDialog::Accepted)
+ return 0;
+ url = fileDialog.selectedUrls().constFirst();
+ } else {
+ url = QUrl::fromUserInput(parser.positionalArguments().constFirst(),
+ QDir::currentPath(), QUrl::AssumeLocalFile);
+ if (!url.isValid()) {
+ std::cerr << qPrintable(url.errorString()) << '\n';
+ return -1;
+ }
+ }
+
+ QQuickWidget w(url);
+ w.setAttribute(Qt::WA_AcceptTouchEvents);
+ if (w.status() == QQuickWidget::Error)
+ return -1;
+ QObject::connect(w.engine(), &QQmlEngine::quit, &app, &QCoreApplication::quit);
+ w.show();
+
+ std::cout << "Qt " << QT_VERSION_STR << ' ' << qPrintable(app.platformName());
+ if (QOpenGLContext *openglContext = w.quickWindow()->openglContext()) {
+ QOpenGLFunctions *glFunctions = openglContext->functions();
+ std::cout << " OpenGL \"" << glFunctions->glGetString(GL_RENDERER)
+ << "\" \"" << glFunctions->glGetString(GL_VERSION) << '"';
+ }
+ const qreal devicePixelRatio = w.devicePixelRatioF();
+ if (!qFuzzyCompare(devicePixelRatio, qreal(1)))
+ std::cout << ", DPR=" << devicePixelRatio;
+ std::cout << '\n';
+
+ return app.exec();
+
+}
diff --git a/tests/manual/quickwidgetviewer/quickwidgetviewer.pro b/tests/manual/quickwidgetviewer/quickwidgetviewer.pro
new file mode 100644
index 0000000000..a32d05e174
--- /dev/null
+++ b/tests/manual/quickwidgetviewer/quickwidgetviewer.pro
@@ -0,0 +1,4 @@
+TEMPLATE = app
+QT += quickwidgets
+CONFIG += c++11 console
+SOURCES += main.cpp
diff --git a/tests/manual/scenegraph_lancelot/data/shape/shape_arc.qml b/tests/manual/scenegraph_lancelot/data/shape/shape_arc.qml
new file mode 100644
index 0000000000..0b2396012e
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/shape/shape_arc.qml
@@ -0,0 +1,112 @@
+import QtQuick 2.9
+import QtQuick.Shapes 1.0
+
+Item {
+ width: 320
+ height: 480
+
+ Column {
+ Item {
+ width: 200
+ height: 100
+
+ Repeater {
+ model: 2
+ Shape {
+ anchors.fill: parent
+ vendorExtensionsEnabled: false
+
+ ShapePath {
+ fillColor: "transparent"
+ strokeColor: model.index === 0 ? "red" : "blue"
+ strokeStyle: ShapePath.DashLine
+ strokeWidth: 4
+
+ startX: 4; startY: 4
+ PathArc {
+ id: arc
+ x: 96; y: 96
+ radiusX: 100; radiusY: 100
+ direction: model.index === 0 ? PathArc.Clockwise : PathArc.Counterclockwise
+ }
+ }
+ }
+ }
+ }
+
+ Item {
+ width: 200
+ height: 100
+
+ Repeater {
+ model: 2
+ Shape {
+ anchors.fill: parent
+ vendorExtensionsEnabled: false
+
+ ShapePath {
+ fillColor: "transparent"
+ strokeColor: model.index === 0 ? "red" : "blue"
+ strokeStyle: ShapePath.DashLine
+ strokeWidth: 4
+
+ startX: 50; startY: 100
+ PathArc {
+ x: 100; y: 150
+ radiusX: 50; radiusY: 50
+ useLargeArc: model.index === 1
+ }
+ }
+ }
+ }
+ }
+
+ Item {
+ width: 200
+ height: 100
+
+ Repeater {
+ model: 2
+ Shape {
+ anchors.fill: parent
+ vendorExtensionsEnabled: false
+
+ ShapePath {
+ fillColor: "transparent"
+ strokeColor: model.index === 0 ? "red" : "blue"
+ strokeStyle: ShapePath.DashLine
+ strokeWidth: 4
+
+ startX: 50; startY: 150
+ PathArc {
+ x: 150; y: 150
+ radiusX: 50; radiusY: 20
+ xAxisRotation: model.index === 0 ? 0 : 45
+ }
+ }
+ }
+ }
+
+ Repeater {
+ model: 2
+ Shape {
+ anchors.fill: parent
+ vendorExtensionsEnabled: false
+
+ ShapePath {
+ fillColor: "transparent"
+ strokeColor: model.index === 0 ? "red" : "blue"
+
+ startX: 50; startY: 150
+ PathArc {
+ x: 150; y: 150
+ radiusX: 50; radiusY: 20
+ xAxisRotation: model.index === 0 ? 0 : 45
+ direction: PathArc.Counterclockwise
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/tests/manual/scenegraph_lancelot/data/shape/shape_arc_fill.qml b/tests/manual/scenegraph_lancelot/data/shape/shape_arc_fill.qml
new file mode 100644
index 0000000000..fefc2ec3eb
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/shape/shape_arc_fill.qml
@@ -0,0 +1,112 @@
+import QtQuick 2.9
+import QtQuick.Shapes 1.0
+
+Item {
+ width: 320
+ height: 480
+
+ Column {
+ Item {
+ width: 200
+ height: 100
+
+ Repeater {
+ model: 2
+ Shape {
+ anchors.fill: parent
+ vendorExtensionsEnabled: false
+
+ ShapePath {
+ fillColor: "lightBlue"
+ strokeColor: model.index === 0 ? "red" : "blue"
+ strokeStyle: ShapePath.DashLine
+ strokeWidth: 4
+
+ startX: 4; startY: 4
+ PathArc {
+ id: arc
+ x: 96; y: 96
+ radiusX: 100; radiusY: 100
+ direction: model.index === 0 ? PathArc.Clockwise : PathArc.Counterclockwise
+ }
+ }
+ }
+ }
+ }
+
+ Item {
+ width: 200
+ height: 100
+
+ Repeater {
+ model: 2
+ Shape {
+ anchors.fill: parent
+ vendorExtensionsEnabled: false
+
+ ShapePath {
+ fillColor: "green"
+ strokeColor: model.index === 0 ? "red" : "blue"
+ strokeStyle: ShapePath.DashLine
+ strokeWidth: 4
+
+ startX: 50; startY: 100
+ PathArc {
+ x: 100; y: 150
+ radiusX: 50; radiusY: 50
+ useLargeArc: model.index === 1
+ }
+ }
+ }
+ }
+ }
+
+ Item {
+ width: 200
+ height: 100
+
+ Repeater {
+ model: 2
+ Shape {
+ anchors.fill: parent
+ vendorExtensionsEnabled: false
+
+ ShapePath {
+ fillColor: "gray"
+ strokeColor: model.index === 0 ? "red" : "blue"
+ strokeStyle: ShapePath.DashLine
+ strokeWidth: 4
+
+ startX: 50; startY: 150
+ PathArc {
+ x: 150; y: 150
+ radiusX: 50; radiusY: 20
+ xAxisRotation: model.index === 0 ? 0 : 45
+ }
+ }
+ }
+ }
+
+ Repeater {
+ model: 2
+ Shape {
+ anchors.fill: parent
+ vendorExtensionsEnabled: false
+
+ ShapePath {
+ fillColor: "lightGray"
+ strokeColor: model.index === 0 ? "red" : "blue"
+
+ startX: 50; startY: 150
+ PathArc {
+ x: 150; y: 150
+ radiusX: 50; radiusY: 20
+ xAxisRotation: model.index === 0 ? 0 : 45
+ direction: PathArc.Counterclockwise
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/tests/manual/scenegraph_lancelot/data/shape/shape_cubic.qml b/tests/manual/scenegraph_lancelot/data/shape/shape_cubic.qml
new file mode 100644
index 0000000000..1d2f9fd40d
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/shape/shape_cubic.qml
@@ -0,0 +1,35 @@
+import QtQuick 2.9
+import QtQuick.Shapes 1.0
+
+Item {
+ width: 320
+ height: 480
+
+ Column {
+ Repeater {
+ model: 4
+ Item {
+ width: 200
+ height: 100
+
+ Shape {
+ anchors.fill: parent
+ vendorExtensionsEnabled: false
+
+ ShapePath {
+ strokeWidth: (model.index + 2) * 2
+ strokeColor: "black"
+ fillColor: "lightBlue"
+
+ startX: 50; startY: 100
+ PathCubic {
+ x: 150; y: 100
+ control1X: model.index * 10; control1Y: model.index * 5
+ control2X: model.index * -10; control2Y: model.index * 10
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/tests/manual/scenegraph_lancelot/data/shape/shape_linear_gradient.qml b/tests/manual/scenegraph_lancelot/data/shape/shape_linear_gradient.qml
new file mode 100644
index 0000000000..1caaec7781
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/shape/shape_linear_gradient.qml
@@ -0,0 +1,33 @@
+import QtQuick 2.9
+import QtQuick.Shapes 1.0
+
+Item {
+ width: 320
+ height: 480
+
+ Shape {
+ vendorExtensionsEnabled: false
+
+ anchors.fill: parent
+
+ ShapePath {
+ strokeWidth: 4
+ strokeColor: "red"
+ fillGradient: LinearGradient {
+ x1: 20; y1: 20
+ x2: 180; y2: 130
+ GradientStop { position: 0; color: "blue" }
+ GradientStop { position: 0.2; color: "green" }
+ GradientStop { position: 0.4; color: "red" }
+ GradientStop { position: 0.6; color: "yellow" }
+ GradientStop { position: 1; color: "cyan" }
+ }
+ strokeStyle: ShapePath.DashLine
+ dashPattern: [ 1, 4 ]
+ startX: 20; startY: 20
+ PathLine { x: 180; y: 130 }
+ PathLine { x: 20; y: 130 }
+ PathLine { x: 20; y: 20 }
+ }
+ }
+}
diff --git a/tests/manual/scenegraph_lancelot/data/shape/shape_lines.qml b/tests/manual/scenegraph_lancelot/data/shape/shape_lines.qml
new file mode 100644
index 0000000000..56045cb5ae
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/shape/shape_lines.qml
@@ -0,0 +1,92 @@
+import QtQuick 2.9
+import QtQuick.Shapes 1.0
+
+Item {
+ width: 320
+ height: 480
+
+ Shape {
+ vendorExtensionsEnabled: false
+
+ anchors.fill: parent
+
+ ShapePath {
+ strokeWidth: 1
+ strokeColor: "red"
+ fillColor: "transparent"
+ PathLine { x: 50; y: 50 }
+ }
+ ShapePath {
+ strokeWidth: 2
+ strokeColor: "blue"
+ fillColor: "transparent"
+ startX: 20
+ PathLine { x: 70; y: 50 }
+ }
+ ShapePath {
+ strokeWidth: 3
+ strokeColor: "green"
+ fillColor: "transparent"
+ startX: 40
+ PathLine { x: 90; y: 50 }
+ }
+ ShapePath {
+ strokeWidth: 4
+ strokeColor: "yellow"
+ fillColor: "transparent"
+ startX: 60
+ PathLine { x: 110; y: 50 }
+ }
+ ShapePath {
+ strokeWidth: 5
+ strokeColor: "black"
+ fillColor: "transparent"
+ strokeStyle: ShapePath.DashLine
+ startX: 80
+ PathLine { x: 130; y: 50 }
+ }
+
+ ShapePath {
+ strokeWidth: 20
+ strokeColor: "gray"
+ fillColor: "transparent"
+ capStyle: ShapePath.RoundCap
+ startX: 120; startY: 20
+ PathLine { x: 200; y: 100 }
+ }
+
+ ShapePath {
+ strokeColor: "black"
+ strokeWidth: 16
+ fillColor: "transparent"
+ capStyle: ShapePath.RoundCap
+ joinStyle: ShapePath.BevelJoin
+ startX: 20
+ startY: 100
+ PathLine { x: 120; y: 200 }
+ PathLine { x: 50; y: 200 }
+ }
+ ShapePath {
+ strokeColor: "black"
+ strokeWidth: 16
+ fillColor: "transparent"
+ capStyle: ShapePath.RoundCap
+ joinStyle: ShapePath.MiterJoin
+ startX: 150
+ startY: 100
+ PathLine { x: 250; y: 200 }
+ PathLine { x: 180; y: 200 }
+ }
+ ShapePath {
+ strokeColor: "black"
+ strokeWidth: 16
+ fillColor: "transparent"
+ capStyle: ShapePath.RoundCap
+ joinStyle: ShapePath.RoundJoin
+ startX: 270
+ startY: 100
+ PathLine { x: 310; y: 200 }
+ PathLine { x: 280; y: 200 }
+ }
+ }
+}
diff --git a/tests/manual/scenegraph_lancelot/data/shape/shape_quad.qml b/tests/manual/scenegraph_lancelot/data/shape/shape_quad.qml
new file mode 100644
index 0000000000..a4c95f7c15
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/shape/shape_quad.qml
@@ -0,0 +1,34 @@
+import QtQuick 2.9
+import QtQuick.Shapes 1.0
+
+Item {
+ width: 320
+ height: 480
+
+ Column {
+ Repeater {
+ model: 4
+ Item {
+ width: 200
+ height: 100
+
+ Shape {
+ anchors.fill: parent
+ vendorExtensionsEnabled: false
+
+ ShapePath {
+ strokeWidth: (model.index + 2) * 2
+ strokeColor: "black"
+ fillColor: "lightBlue"
+
+ startX: 50; startY: 100
+ PathQuad {
+ x: 150; y: 100
+ controlX: model.index * 10; controlY: model.index * 5
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/tests/manual/scenegraph_lancelot/data/shape/shape_spread.qml b/tests/manual/scenegraph_lancelot/data/shape/shape_spread.qml
new file mode 100644
index 0000000000..f310f08773
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/shape/shape_spread.qml
@@ -0,0 +1,35 @@
+import QtQuick 2.9
+import QtQuick.Shapes 1.0
+
+Item {
+ width: 320
+ height: 480
+
+ Column {
+ Repeater {
+ model: 3
+ Shape {
+ vendorExtensionsEnabled: false
+ width: 200
+ height: 150
+ ShapePath {
+ strokeColor: "transparent"
+
+ fillGradient: LinearGradient {
+ id: grad
+ y1: 50; y2: 80
+ spread: model.index === 0 ? ShapeGradient.PadSpread : (model.index === 1 ? ShapeGradient.RepeatSpread : ShapeGradient.ReflectSpread)
+ GradientStop { position: 0; color: "black" }
+ GradientStop { position: 1; color: "red" }
+ }
+
+ startX: 10; startY: 10
+ PathLine { relativeX: 180; relativeY: 0 }
+ PathLine { relativeX: 0; relativeY: 100 }
+ PathLine { relativeX: -180; relativeY: 0 }
+ PathLine { relativeX: 0; relativeY: -100 }
+ }
+ }
+ }
+ }
+}
diff --git a/tests/manual/scenegraph_lancelot/data/text/text_advance_bidi_ltr.qml b/tests/manual/scenegraph_lancelot/data/text/text_advance_bidi_ltr.qml
new file mode 100644
index 0000000000..e5d230e309
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/text/text_advance_bidi_ltr.qml
@@ -0,0 +1,56 @@
+import QtQuick 2.10
+
+Item {
+ width: 320
+ height: 480
+
+ property string firstWord: "One, שתיים, "
+ property string secondWord: "Three"
+
+ Text {
+ id: referenceText
+ text: firstWord + secondWord
+ anchors.centerIn: parent
+ font.italic: true
+ font.pixelSize: 30
+ }
+
+ Text {
+ id: firstWordItem
+ anchors.left: referenceText.left
+ anchors.top: referenceText.bottom
+ text: firstWord
+ font: referenceText.font
+ }
+
+ Text {
+ id: secondWordItem
+ anchors.left: firstWordItem.left
+ anchors.leftMargin: firstWordItem.advance.width
+ anchors.baseline: firstWordItem.baseline
+ anchors.baselineOffset: firstWordItem.advance.height
+ text: secondWord
+ font: referenceText.font
+ }
+
+ Text {
+ id: firstWordItemRichText
+ anchors.left: referenceText.left
+ anchors.top: secondWordItem.bottom
+ text: firstWord
+ font: referenceText.font
+ textFormat: Text.RichText
+ }
+
+ Text {
+ id: secondWordItemRichText
+ anchors.left: firstWordItemRichText.left
+ anchors.leftMargin: firstWordItemRichText.advance.width
+ anchors.baseline: firstWordItemRichText.baseline
+ anchors.baselineOffset: firstWordItemRichText.advance.height
+ text: secondWord
+ font: referenceText.font
+ textFormat: Text.RichText
+ }
+
+}
diff --git a/tests/manual/scenegraph_lancelot/data/text/text_advance_hebrew.qml b/tests/manual/scenegraph_lancelot/data/text/text_advance_hebrew.qml
new file mode 100644
index 0000000000..000977f964
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/text/text_advance_hebrew.qml
@@ -0,0 +1,54 @@
+import QtQuick 2.10
+
+Item {
+ width: 320
+ height: 480
+
+ property string firstWord: "תורת רב־לשוני אנא "
+ property string secondWord: "של"
+
+ Text {
+ id: referenceText
+ text: firstWord + secondWord
+ anchors.centerIn: parent
+ font.italic: true
+ font.pixelSize: 30
+ }
+
+ Text {
+ id: firstWordItem
+ anchors.right: referenceText.right
+ anchors.top: referenceText.bottom
+ text: firstWord
+ font: referenceText.font
+ }
+
+ Text {
+ id: secondWordItem
+ anchors.right: firstWordItem.left
+ anchors.baseline: firstWordItem.baseline
+ anchors.baselineOffset: firstWordItem.advance.height
+ text: secondWord
+ font: referenceText.font
+ }
+
+ Text {
+ id: firstWordItemRichText
+ anchors.right: referenceText.right
+ anchors.top: secondWordItem.bottom
+ text: firstWord
+ font: referenceText.font
+ textFormat: Text.RichText
+ }
+
+ Text {
+ id: secondWordItemRichText
+ anchors.right: firstWordItemRichText.left
+ anchors.baseline: firstWordItemRichText.baseline
+ anchors.baselineOffset: firstWordItemRichText.advance.height
+ text: secondWord
+ font: referenceText.font
+ textFormat: Text.RichText
+ }
+
+}
diff --git a/tests/manual/scenegraph_lancelot/data/text/text_advance_latin.qml b/tests/manual/scenegraph_lancelot/data/text/text_advance_latin.qml
new file mode 100644
index 0000000000..f5fc501bb8
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/text/text_advance_latin.qml
@@ -0,0 +1,55 @@
+import QtQuick 2.10
+
+Item {
+ width: 320
+ height: 480
+
+ property string firstWord: "Hello "
+ property string secondWord: "World"
+
+ Text {
+ id: referenceText
+ text: firstWord + secondWord
+ anchors.centerIn: parent
+ font.italic: true
+ font.pixelSize: 30
+ }
+
+ Text {
+ id: firstWordItem
+ anchors.left: referenceText.left
+ anchors.top: referenceText.bottom
+ text: firstWord
+ font: referenceText.font
+ }
+
+ Text {
+ id: secondWordItem
+ anchors.left: firstWordItem.left
+ anchors.leftMargin: firstWordItem.advance.width
+ anchors.baseline: firstWordItem.baseline
+ anchors.baselineOffset: firstWordItem.advance.height
+ text: secondWord
+ font: referenceText.font
+ }
+
+ Text {
+ id: firstWordItemRichText
+ anchors.left: referenceText.left
+ anchors.top: secondWordItem.bottom
+ text: firstWord
+ font: referenceText.font
+ textFormat: Text.RichText
+ }
+
+ Text {
+ id: secondWordItemRichText
+ anchors.left: firstWordItemRichText.left
+ anchors.leftMargin: firstWordItemRichText.advance.width
+ anchors.baseline: firstWordItemRichText.baseline
+ anchors.baselineOffset: firstWordItemRichText.advance.height
+ text: secondWord
+ font: referenceText.font
+ textFormat: Text.RichText
+ }
+}
diff --git a/tests/manual/scenegraph_lancelot/data/text/text_advance_multiline.qml b/tests/manual/scenegraph_lancelot/data/text/text_advance_multiline.qml
new file mode 100644
index 0000000000..a58a7cb40c
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/text/text_advance_multiline.qml
@@ -0,0 +1,55 @@
+import QtQuick 2.10
+
+Item {
+ width: 320
+ height: 480
+
+ property string firstWord: "One,\nTwo, "
+ property string secondWord: "Three"
+
+ Text {
+ id: referenceText
+ text: firstWord + secondWord
+ anchors.centerIn: parent
+ font.italic: true
+ font.pixelSize: 30
+ }
+
+ Text {
+ id: firstWordItem
+ anchors.left: referenceText.left
+ anchors.top: referenceText.bottom
+ text: firstWord
+ font: referenceText.font
+ }
+
+ Text {
+ id: secondWordItem
+ anchors.left: firstWordItem.left
+ anchors.leftMargin: firstWordItem.advance.width
+ anchors.baseline: firstWordItem.baseline
+ anchors.baselineOffset: firstWordItem.advance.height
+ text: secondWord
+ font: referenceText.font
+ }
+
+ Text {
+ id: firstWordItemRichText
+ anchors.left: referenceText.left
+ anchors.top: secondWordItem.bottom
+ text: firstWord
+ font: referenceText.font
+ textFormat: Text.RichText
+ }
+
+ Text {
+ id: secondWordItemRichText
+ anchors.left: firstWordItemRichText.left
+ anchors.leftMargin: firstWordItemRichText.advance.width
+ anchors.baseline: firstWordItemRichText.baseline
+ anchors.baselineOffset: firstWordItemRichText.advance.height
+ text: secondWord
+ font: referenceText.font
+ textFormat: Text.RichText
+ }
+}
diff --git a/tests/manual/scenegraph_lancelot/data/text/text_advance_multiparagraph.qml b/tests/manual/scenegraph_lancelot/data/text/text_advance_multiparagraph.qml
new file mode 100644
index 0000000000..0627656ea6
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/text/text_advance_multiparagraph.qml
@@ -0,0 +1,39 @@
+import QtQuick 2.10
+
+Item {
+ width: 320
+ height: 480
+
+ property string firstWord: "<p>One,</p><p>Two, "
+ property string secondWord: "Three</p>"
+
+ Text {
+ id: referenceText
+ text: firstWord + secondWord
+ anchors.centerIn: parent
+ font.italic: true
+ font.pixelSize: 30
+ textFormat: Text.RichText
+ }
+
+
+ Text {
+ id: firstWordItemRichText
+ anchors.left: referenceText.left
+ anchors.top: referenceText.bottom
+ text: firstWord
+ font: referenceText.font
+ textFormat: Text.RichText
+ }
+
+ Text {
+ id: secondWordItemRichText
+ anchors.left: firstWordItemRichText.left
+ anchors.leftMargin: firstWordItemRichText.advance.width
+ anchors.baseline: firstWordItemRichText.baseline
+ anchors.baselineOffset: firstWordItemRichText.advance.height
+ text: secondWord
+ font: referenceText.font
+ textFormat: Text.RichText
+ }
+}
diff --git a/tests/manual/scenegraph_lancelot/data/text/text_advance_multiparagraph_multifontsizes.qml b/tests/manual/scenegraph_lancelot/data/text/text_advance_multiparagraph_multifontsizes.qml
new file mode 100644
index 0000000000..fb1f252148
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/text/text_advance_multiparagraph_multifontsizes.qml
@@ -0,0 +1,39 @@
+import QtQuick 2.10
+
+Item {
+ width: 320
+ height: 480
+
+ property string firstWord: "<p style=\"font-size: 40pt\">One,</p><p>Two, "
+ property string secondWord: "Three</p>"
+
+ Text {
+ id: referenceText
+ text: firstWord + secondWord
+ anchors.centerIn: parent
+ font.italic: true
+ font.pixelSize: 30
+ textFormat: Text.RichText
+ }
+
+
+ Text {
+ id: firstWordItemRichText
+ anchors.left: referenceText.left
+ anchors.top: referenceText.bottom
+ text: firstWord
+ font: referenceText.font
+ textFormat: Text.RichText
+ }
+
+ Text {
+ id: secondWordItemRichText
+ anchors.left: firstWordItemRichText.left
+ anchors.leftMargin: firstWordItemRichText.advance.width
+ anchors.baseline: firstWordItemRichText.baseline
+ anchors.baselineOffset: firstWordItemRichText.advance.height
+ text: secondWord
+ font: referenceText.font
+ textFormat: Text.RichText
+ }
+}
diff --git a/tests/manual/scenegraph_lancelot/data/text/text_bengali_noshaping.qml b/tests/manual/scenegraph_lancelot/data/text/text_bengali_noshaping.qml
new file mode 100644
index 0000000000..343d5768e4
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/text/text_bengali_noshaping.qml
@@ -0,0 +1,15 @@
+import QtQuick 2.0
+
+Item {
+ width: 320
+ height: 480
+
+ Text {
+ anchors.fill: parent
+ wrapMode: Text.WrapAtWordBoundaryOrAnywhere
+ font.family: "Arial" // Should use Lohit Bengali
+ font.pixelSize: 20
+ font.preferShaping: false
+ text: "ধারা ১: সমস্ত মানুষ স্বাধীনভাবে সমান মর্যাদা এবং অধিকার নিয়ে জন্মগ্রহণ করে। তাঁদের বিবেক এবং বুদ্ধি আছে; সুতরাং সকলেরই একে অপরের প্রতি ভ্রাতৃত্বসুলভ মনোভাব নিয়ে আচরণ করা উচিৎ।"
+ }
+}
diff --git a/tests/manual/scenegraph_lancelot/data/text/text_latin_noshaping.qml b/tests/manual/scenegraph_lancelot/data/text/text_latin_noshaping.qml
new file mode 100644
index 0000000000..6dc6c2f3d6
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/text/text_latin_noshaping.qml
@@ -0,0 +1,15 @@
+import QtQuick 2.0
+
+Item {
+ width: 320
+ height: 480
+
+ Text {
+ anchors.fill: parent
+ wrapMode: Text.WrapAtWordBoundaryOrAnywhere
+ font.family: "Arial"
+ font.pixelSize: 20
+ font.preferShaping: false
+ text: "Are griffins birds or mammals?"
+ }
+}
diff --git a/tests/manual/scenegraph_lancelot/data/text/text_nokerning_latin.qml b/tests/manual/scenegraph_lancelot/data/text/text_nokerning_latin.qml
new file mode 100644
index 0000000000..fd1d082c99
--- /dev/null
+++ b/tests/manual/scenegraph_lancelot/data/text/text_nokerning_latin.qml
@@ -0,0 +1,16 @@
+import QtQuick 2.0
+
+Item {
+ width: 320
+ height: 480
+
+ Text {
+ text: "OATS FLAVOUR WAY"
+ anchors.centerIn: parent
+
+ font.family: "Times New Roman"
+ font.italic: true
+ font.pixelSize: 30
+ font.kerning: false
+ }
+}
diff --git a/tests/manual/shapestest/main.cpp b/tests/manual/shapestest/main.cpp
new file mode 100644
index 0000000000..479ff0a1eb
--- /dev/null
+++ b/tests/manual/shapestest/main.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QGuiApplication>
+#include <QSurfaceFormat>
+#include <QQuickView>
+#include <QQmlEngine>
+
+int main(int argc, char **argv)
+{
+ QGuiApplication app(argc, argv);
+
+ QQuickView view;
+
+ QSurfaceFormat fmt;
+ fmt.setDepthBufferSize(24);
+ fmt.setStencilBufferSize(8);
+ if (app.arguments().contains(QStringLiteral("--multisample")))
+ fmt.setSamples(4);
+ if (app.arguments().contains(QStringLiteral("--coreprofile"))) {
+ fmt.setVersion(4, 3);
+ fmt.setProfile(QSurfaceFormat::CoreProfile);
+ }
+ view.setFormat(fmt);
+
+ view.setResizeMode(QQuickView::SizeRootObjectToView);
+ view.resize(1024, 768);
+ view.setSource(QUrl("qrc:/shapestest/shapestest.qml"));
+ view.show();
+
+ return app.exec();
+}
diff --git a/tests/manual/shapestest/shapestest.pro b/tests/manual/shapestest/shapestest.pro
new file mode 100644
index 0000000000..1776175134
--- /dev/null
+++ b/tests/manual/shapestest/shapestest.pro
@@ -0,0 +1,6 @@
+TEMPLATE = app
+
+QT += quick qml
+SOURCES += main.cpp
+RESOURCES += shapestest.qrc
+OTHER_FILES += shapestest.qml
diff --git a/tests/manual/shapestest/shapestest.qml b/tests/manual/shapestest/shapestest.qml
new file mode 100644
index 0000000000..de9e20b8f3
--- /dev/null
+++ b/tests/manual/shapestest/shapestest.qml
@@ -0,0 +1,452 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+import QtQuick.Shapes 1.0
+
+Rectangle {
+ id: root
+ width: 1024
+ height: 768
+
+ property color col: "lightsteelblue"
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: Qt.tint(root.col, "#20FFFFFF") }
+ GradientStop { position: 0.1; color: Qt.tint(root.col, "#20AAAAAA") }
+ GradientStop { position: 0.9; color: Qt.tint(root.col, "#20666666") }
+ GradientStop { position: 1.0; color: Qt.tint(root.col, "#20000000") }
+ }
+
+ Row {
+ anchors.top: parent.top
+ anchors.centerIn: parent
+ spacing: 20
+
+ Column {
+ spacing: 20
+
+ Rectangle {
+ border.color: "purple"
+ color: "transparent"
+ width: 200
+ height: 100
+ Shape {
+ id: triangle
+ anchors.fill: parent
+ ShapePath {
+ strokeWidth: 4
+ strokeColor: "red"
+ fillGradient: LinearGradient {
+ x1: 0; y1: 0
+ x2: 200; y2: 100
+ GradientStop { position: 0; color: "blue" }
+ GradientStop { position: 0.2; color: "green" }
+ GradientStop { position: 0.4; color: "red" }
+ GradientStop { position: 0.6; color: "yellow" }
+ GradientStop { position: 1; color: "cyan" }
+ }
+ fillColor: "blue" // ignored with the gradient set
+ strokeStyle: ShapePath.DashLine
+ dashPattern: [ 1, 4 ]
+ PathLine { x: 200; y: 100 }
+ PathLine { x: 0; y: 100 }
+ PathLine { x: 0; y: 0 }
+ }
+ transform: Rotation { origin.x: 100; origin.y: 50; axis { x: 0; y: 1; z: 0 }
+ SequentialAnimation on angle {
+ NumberAnimation { from: 0; to: 75; duration: 2000 }
+ NumberAnimation { from: 75; to: -75; duration: 4000 }
+ NumberAnimation { from: -75; to: 0; duration: 2000 }
+ loops: Animation.Infinite
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ border.color: "purple"
+ color: "transparent"
+ width: 200
+ height: 100
+ Shape {
+ anchors.fill: parent
+ ShapePath {
+ id: someCurve
+ property color sc: "gray"
+ strokeColor: sc
+ property color fc: "yellow"
+ fillColor: fc
+ startX: 20; startY: 10
+ PathQuad { x: 50; y: 80; controlX: 0; controlY: 80 }
+ PathLine { x: 150; y: 80 }
+ PathQuad { x: 180; y: 10; controlX: 200; controlY: 80 }
+ PathLine { x: 20; y: 10 }
+ // Dynamic changes via property bindings etc. all work but can
+ // be computationally expense with the generic backend for properties
+ // that need retriangulating on every change. Should be cheap with NVPR.
+ NumberAnimation on strokeWidth {
+ from: 1; to: 20; duration: 10000
+ }
+ }
+ }
+ // Changing colors for a solid stroke or fill is simple and
+ // (relatively) cheap. However, changing to/from transparent
+ // stroke/fill color and stroke width 0 are special as these
+ // change the scenegraph node tree (with the generic backend).
+ Timer {
+ interval: 2000
+ running: true
+ repeat: true
+ onTriggered: someCurve.fillColor = (someCurve.fillColor === someCurve.fc ? "transparent" : someCurve.fc)
+ }
+ Timer {
+ interval: 1000
+ running: true
+ repeat: true
+ onTriggered: someCurve.strokeColor = (someCurve.strokeColor === someCurve.sc ? "transparent" : someCurve.sc)
+ }
+ }
+
+ Rectangle {
+ border.color: "purple"
+ color: "transparent"
+ width: 300
+ height: 100
+ Shape {
+ id: linesAndMoves
+ anchors.fill: parent
+ ShapePath {
+ strokeColor: "black"
+ startX: 0; startY: 50
+ PathLine { relativeX: 100; y: 50 }
+ PathMove { relativeX: 100; y: 50 }
+ PathLine { relativeX: 100; y: 50 }
+ }
+ }
+ }
+
+ Rectangle {
+ border.color: "purple"
+ color: "transparent"
+ width: 200
+ height: 120
+ Shape {
+ anchors.fill: parent
+ ShapePath {
+ id: joinTest
+ strokeColor: "black"
+ strokeWidth: 16
+ fillColor: "transparent"
+ capStyle: ShapePath.RoundCap
+ startX: 30
+ startY: 30
+ PathLine { x: 100; y: 100 }
+ PathLine { x: 30; y: 100 }
+ }
+ }
+ Timer {
+ interval: 1000
+ repeat: true
+ running: true
+ property variant styles: [ ShapePath.BevelJoin, ShapePath.MiterJoin, ShapePath.RoundJoin ]
+ onTriggered: {
+ for (var i = 0; i < styles.length; ++i)
+ if (styles[i] === joinTest.joinStyle) {
+ joinTest.joinStyle = styles[(i + 1) % styles.length];
+ break;
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ border.color: "purple"
+ color: "transparent"
+ width: 200
+ height: 100
+ Shape {
+ anchors.fill: parent
+ ShapePath {
+ id: star
+ strokeColor: "blue"
+ fillColor: "lightGray"
+ strokeWidth: 2
+ PathMove { x: 90; y: 50 }
+ PathLine { x: 50 + 40 * Math.cos(0.8 * 1 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 1 * Math.PI) }
+ PathLine { x: 50 + 40 * Math.cos(0.8 * 2 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 2 * Math.PI) }
+ PathLine { x: 50 + 40 * Math.cos(0.8 * 3 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 3 * Math.PI) }
+ PathLine { x: 50 + 40 * Math.cos(0.8 * 4 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 4 * Math.PI) }
+ PathLine { x: 90; y: 50 }
+ }
+ }
+ Timer {
+ interval: 1000
+ onTriggered: star.fillRule = (star.fillRule === ShapePath.OddEvenFill ? ShapePath.WindingFill : ShapePath.OddEvenFill)
+ repeat: true
+ running: true
+ }
+ }
+
+ Rectangle {
+ border.color: "purple"
+ color: "transparent"
+ width: 200
+ height: 100
+ Shape {
+ anchors.fill: parent
+ ShapePath {
+ strokeWidth: 4
+ strokeColor: "black"
+ fillColor: "transparent"
+ startX: 20; startY: 10
+ PathCubic {
+ id: cb
+ x: 180; y: 10
+ control1X: -10; control1Y: 90; control2Y: 90
+ NumberAnimation on control2X { from: 400; to: 0; duration: 5000; loops: Animation.Infinite }
+ }
+ }
+ }
+ }
+ }
+
+ Column {
+ spacing: 20
+
+ Rectangle {
+ border.color: "purple"
+ color: "transparent"
+ width: 200
+ height: 100
+ Shape {
+ anchors.fill: parent
+ ShapePath {
+ fillColor: "transparent"
+ strokeColor: "red"
+ strokeWidth: 4
+ startX: 10; startY: 40
+ PathArc {
+ x: 10; y: 60
+ radiusX: 40; radiusY: 40
+ useLargeArc: true
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ border.color: "purple"
+ color: "transparent"
+ width: 200
+ height: 200
+ Rectangle {
+ anchors.centerIn: parent
+ // have a size smaller than 150x150
+ width: 100
+ height: 100
+ // and enable clipping. Normally this goes via scissoring, unless
+ // some transform triggers the stencil-based path. Ensure this via rotation.
+ clip: true
+ NumberAnimation on rotation {
+ from: 0; to: 360; duration: 5000; loops: Animation.Infinite
+ }
+
+ Shape {
+ width: 150
+ height: 150
+
+ ShapePath {
+ fillColor: "blue"
+ strokeColor: "red"
+ strokeWidth: 4
+ startX: 10; startY: 10
+ PathLine { x: 140; y: 140 }
+ PathLine { x: 10; y: 140 }
+ PathLine { x: 10; y: 10 }
+ }
+ }
+ }
+ }
+
+ // stencil clip test #2, something more complicated:
+ Rectangle {
+ border.color: "purple"
+ color: "transparent"
+ width: 150
+ height: 150
+ Rectangle {
+ anchors.centerIn: parent
+ width: 60
+ height: 60
+ clip: true
+ NumberAnimation on rotation {
+ from: 0; to: 360; duration: 5000; loops: Animation.Infinite
+ }
+ Shape {
+ width: 100
+ height: 100
+ ShapePath {
+ id: clippedStar
+ strokeColor: "blue"
+ fillColor: "lightGray"
+ strokeWidth: 2
+ PathMove { x: 90; y: 50 }
+ PathLine { x: 50 + 40 * Math.cos(0.8 * 1 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 1 * Math.PI) }
+ PathLine { x: 50 + 40 * Math.cos(0.8 * 2 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 2 * Math.PI) }
+ PathLine { x: 50 + 40 * Math.cos(0.8 * 3 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 3 * Math.PI) }
+ PathLine { x: 50 + 40 * Math.cos(0.8 * 4 * Math.PI); y: 50 + 40 * Math.sin(0.8 * 4 * Math.PI) }
+ PathLine { x: 90; y: 50 }
+ }
+ }
+ Timer {
+ interval: 1000
+ onTriggered: clippedStar.fillRule = (clippedStar.fillRule === ShapePath.OddEvenFill ? ShapePath.WindingFill : ShapePath.OddEvenFill)
+ repeat: true
+ running: true
+ }
+ }
+ }
+
+ Rectangle {
+ border.color: "purple"
+ color: "transparent"
+ width: 100
+ height: 100
+ Shape {
+ anchors.fill: parent
+ ShapePath {
+ strokeColor: "red"
+ PathLine { x: 100; y: 100 }
+ }
+ ShapePath {
+ strokeColor: "blue"
+ startX: 100; startY: 0
+ PathLine { x: 0; y: 100 }
+ }
+ }
+ }
+
+ Rectangle {
+ border.color: "purple"
+ color: "transparent"
+ width: 200
+ height: 100
+ Shape {
+ anchors.fill: parent
+ ShapePath {
+ strokeWidth: -1
+ strokeColor: "red"
+ fillGradient: RadialGradient {
+ centerX: 100; centerY: 50
+ focalX: centerX; focalY: centerY
+ centerRadius: 50
+ spread: RadialGradient.ReflectSpread
+ GradientStop { position: 0; color: "blue" }
+ GradientStop { position: 0.2; color: "green" }
+ GradientStop { position: 0.4; color: "red" }
+ GradientStop { position: 0.6; color: "yellow" }
+ GradientStop { position: 1; color: "cyan" }
+ }
+ PathLine { x: 0; y: 100 }
+ PathLine { x: 200; y: 100 }
+ PathLine { x: 200; y: 0 }
+ PathLine { x: 0; y: 0 }
+ }
+ }
+ }
+
+ Rectangle {
+ border.color: "purple"
+ color: "transparent"
+ width: 200
+ height: 100
+ Shape {
+ anchors.fill: parent
+ ShapePath {
+ strokeWidth: -1
+ strokeColor: "red"
+ fillGradient: ConicalGradient {
+ centerX: 100; centerY: 50
+ angle: 90
+ GradientStop { position: 0; color: "blue" }
+ GradientStop { position: 0.2; color: "green" }
+ GradientStop { position: 0.4; color: "red" }
+ GradientStop { position: 0.6; color: "yellow" }
+ GradientStop { position: 1; color: "cyan" }
+ }
+ PathLine { x: 0; y: 100 }
+ PathLine { x: 200; y: 100 }
+ PathLine { x: 200; y: 0 }
+ PathLine { x: 0; y: 0 }
+ }
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ id: stackTestRect
+ SequentialAnimation on opacity {
+ NumberAnimation { from: 0; to: 1; duration: 5000 }
+ PauseAnimation { duration: 2000 }
+ NumberAnimation { from: 1; to: 0; duration: 5000 }
+ PauseAnimation { duration: 2000 }
+ loops: Animation.Infinite
+ id: opAnim
+ }
+ color: "blue"
+ anchors.margins: 10
+ anchors.fill: parent
+ }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: stackTestRect.visible = !stackTestRect.visible
+ }
+}
diff --git a/tests/manual/shapestest/shapestest.qrc b/tests/manual/shapestest/shapestest.qrc
new file mode 100644
index 0000000000..6bfc953997
--- /dev/null
+++ b/tests/manual/shapestest/shapestest.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/shapestest">
+ <file>shapestest.qml</file>
+ </qresource>
+</RCC>
diff --git a/tests/manual/touch/mpta-crosshairs.qml b/tests/manual/touch/mpta-crosshairs.qml
index 9ea1b390a7..9fab8515ee 100644
--- a/tests/manual/touch/mpta-crosshairs.qml
+++ b/tests/manual/touch/mpta-crosshairs.qml
@@ -60,6 +60,7 @@ Rectangle {
MultiPointTouchArea {
id: mpta
anchors.fill: parent
+ //onGestureStarted: gesture.grab() // in case this is embedded in something that might steal
touchPoints: [
TouchPoint { property color color: "red" },
TouchPoint { property color color: "orange" },
diff --git a/tests/manual/v4/fact.2.js b/tests/manual/v4/fact.2.js
index d8f750b5a1..1696e8b80d 100644
--- a/tests/manual/v4/fact.2.js
+++ b/tests/manual/v4/fact.2.js
@@ -3,6 +3,6 @@ function fact(n) {
return n > 1 ? n * fact(n - 1) : 1
}
-for (var i = 0; i < 1000000; i = i + 1)
+for (var i = 0; i < 100000; i = i + 1)
fact(12)
diff --git a/tests/manual/v4/typedarrays.js b/tests/manual/v4/typedarrays.js
index 8cf2b8c75a..f727df7185 100644
--- a/tests/manual/v4/typedarrays.js
+++ b/tests/manual/v4/typedarrays.js
@@ -670,12 +670,12 @@ function TestDataViewConstructor() {
/* This is wrong according to ecma 6 and should throw:
- var d4 = new DataView(ab, 1, 3.1415926);
+ var d4 = new DataView(ab, 1, Math.PI);
assertSame(ab, d4.buffer);
assertSame(1, d4.byteOffset);
assertSame(3, d4.byteLength);
*/
- assertThrows(function() { new DataView(ab, 3.1415926); }, RangeError);
+ assertThrows(function() { new DataView(ab, Math.PI); }, RangeError);
// error cases
assertThrows(function() { new DataView(ab, -1); }, RangeError);
diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp
index 9b5fcc74c2..83680a5ba1 100644
--- a/tools/qml/main.cpp
+++ b/tools/qml/main.cpp
@@ -134,7 +134,7 @@ class LoaderApplication : public QGuiApplication
public:
LoaderApplication(int& argc, char **argv) : QGuiApplication(argc, argv) {}
- bool event(QEvent *ev)
+ bool event(QEvent *ev) override
{
if (ev->type() == QEvent::FileOpen) {
if (exitTimerId >= 0) {
@@ -148,7 +148,7 @@ public:
return true;
}
- void timerEvent(QTimerEvent *) {
+ void timerEvent(QTimerEvent *) override {
noFilesGiven();
}
};
diff --git a/tools/qml/qml.pro b/tools/qml/qml.pro
index d0083c0e78..04704f9314 100644
--- a/tools/qml/qml.pro
+++ b/tools/qml/qml.pro
@@ -6,14 +6,7 @@ HEADERS += conf.h
SOURCES += main.cpp
RESOURCES += qml.qrc
-QMAKE_TARGET_PRODUCT = qml
-QMAKE_TARGET_DESCRIPTION = Utility that loads and displays QML documents
-
-win32 {
- VERSION = $${QT_VERSION}.0
-} else {
- VERSION = $${QT_VERSION}
-}
+QMAKE_TARGET_DESCRIPTION = QML Runtime
mac {
OTHER_FILES += Info.plist
@@ -21,6 +14,6 @@ mac {
ICON = qml.icns
}
-!contains(QT_CONFIG, no-qml-debug): DEFINES += QT_QML_DEBUG_NO_WARNING
+qtConfig(qml-debug): DEFINES += QT_QML_DEBUG_NO_WARNING
load(qt_tool)
diff --git a/tools/qmlcachegen/Qt5QuickCompilerConfig.cmake b/tools/qmlcachegen/Qt5QuickCompilerConfig.cmake
new file mode 100644
index 0000000000..6fe1662995
--- /dev/null
+++ b/tools/qmlcachegen/Qt5QuickCompilerConfig.cmake
@@ -0,0 +1,73 @@
+include(CMakeParseArguments)
+
+function(QTQUICK_COMPILER_DETERMINE_OUTPUT_FILENAME outvariable filename)
+ file(RELATIVE_PATH relpath ${CMAKE_CURRENT_SOURCE_DIR} ${filename})
+ string(REPLACE ".qml" "_qml" relpath ${relpath})
+ string(REPLACE ".js" "_js" relpath ${relpath})
+ string(REPLACE "/" "_" relpath ${relpath})
+ set(${outvariable} ${CMAKE_CURRENT_BINARY_DIR}/${relpath}.cpp PARENT_SCOPE)
+endfunction()
+
+function(QTQUICK_COMPILER_ADD_RESOURCES outfiles)
+ set(options)
+ set(oneValueArgs)
+ set(multiValueArgs OPTIONS)
+
+ cmake_parse_arguments(_RCC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+ find_package(Qt5 COMPONENTS Qml Core)
+
+ set(compiler_path "${_qt5Core_install_prefix}/bin/qmlcachegen")
+
+ get_target_property(rcc_path ${Qt5Core_RCC_EXECUTABLE} IMPORTED_LOCATION)
+
+ set(rcc_files ${_RCC_UNPARSED_ARGUMENTS})
+ set(rcc_options ${_RCC_OPTIONS})
+ set(filtered_rcc_files)
+ set(compiler_output)
+ set(rcc_files_with_compilation_units)
+ set(loader_flags)
+
+ foreach(_resource ${rcc_files})
+ get_filename_component(resource_base ${_resource} NAME_WE)
+ set(new_resource_file ${CMAKE_CURRENT_BINARY_DIR}/${resource_base}_qmlcache.qrc)
+
+ get_filename_component(input_resource ${_resource} ABSOLUTE)
+
+ execute_process(COMMAND ${compiler_path} -filter-resource-file ${input_resource} -o ${new_resource_file} OUTPUT_VARIABLE remaining_files)
+ if(remaining_files)
+ list(APPEND filtered_rcc_files ${new_resource_file})
+ list(APPEND loader_flags "--resource-file-mapping=${_resource}=${new_resource_file}")
+ else()
+ list(APPEND loader_flags "--resource-file-mapping=${_resource}")
+ endif()
+
+ set(rcc_file_with_compilation_units)
+
+ exec_program(${rcc_path} ARGS -list ${input_resource} OUTPUT_VARIABLE rcc_contents)
+ string(REGEX REPLACE "[\r\n]+" ";" rcc_contents ${rcc_contents})
+ foreach(it ${rcc_contents})
+ get_filename_component(extension ${it} EXT)
+ if("x${extension}" STREQUAL "x.qml" OR "x${extension}" STREQUAL "x.js" OR "x${extension}" STREQUAL "x.ui.qml")
+ qtquick_compiler_determine_output_filename(output_file ${it})
+ add_custom_command(OUTPUT ${output_file} COMMAND ${compiler_path} ARGS --resource=${input_resource} ${it} -o ${output_file} DEPENDS ${it})
+ list(APPEND compiler_output ${output_file})
+ set(rcc_file_with_compilation_units ${input_resource})
+ endif()
+ endforeach()
+
+ if(rcc_file_with_compilation_units)
+ list(APPEND rcc_files_with_compilation_units ${rcc_file_with_compilation_units})
+ endif()
+ endforeach()
+
+ if(rcc_files_with_compilation_units)
+ set(loader_source ${CMAKE_CURRENT_BINARY_DIR}/qmlcache_loader.cpp)
+ add_custom_command(OUTPUT ${loader_source} COMMAND ${compiler_path} ARGS ${loader_flags} ${rcc_files_with_compilation_units} -o ${loader_source} DEPENDS ${rcc_files_with_compilation_units})
+ list(APPEND compiler_output ${loader_source})
+ endif()
+
+ qt5_add_resources(output_resources ${filtered_rcc_files} OPTIONS ${options})
+ set(${outfiles} ${output_resources} ${compiler_output} PARENT_SCOPE)
+endfunction()
+
diff --git a/tools/qmlcachegen/generateloader.cpp b/tools/qmlcachegen/generateloader.cpp
new file mode 100644
index 0000000000..083af29a2d
--- /dev/null
+++ b/tools/qmlcachegen/generateloader.cpp
@@ -0,0 +1,392 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QByteArray>
+#include <QString>
+#include <QStringList>
+#include <QTextStream>
+#include <QVector>
+#include <QtEndian>
+#include <QStack>
+#include <QFileInfo>
+#include <QSaveFile>
+
+QString symbolNamespaceForPath(const QString &relativePath)
+{
+ QFileInfo fi(relativePath);
+ QString symbol = fi.path();
+ if (symbol.length() == 1 && symbol.startsWith(QLatin1Char('.'))) {
+ symbol.clear();
+ } else {
+ symbol.replace(QLatin1Char('/'), QLatin1Char('_'));
+ symbol += QLatin1Char('_');
+ }
+ symbol += fi.baseName();
+ symbol += QLatin1Char('_');
+ symbol += fi.suffix();
+ symbol.replace(QLatin1Char('.'), QLatin1Char('_'));
+ symbol.replace(QLatin1Char('+'), QLatin1Char('_'));
+ symbol.replace(QLatin1Char('-'), QLatin1Char('_'));
+ return symbol;
+}
+
+struct VirtualDirectoryEntry
+{
+ QString name;
+ QVector<VirtualDirectoryEntry*> dirEntries;
+ int firstChildIndex; // node index inside generated data
+ bool isDirectory;
+
+ VirtualDirectoryEntry()
+ : firstChildIndex(-1)
+ , isDirectory(true)
+ {}
+
+ ~VirtualDirectoryEntry()
+ {
+ qDeleteAll(dirEntries);
+ }
+
+ VirtualDirectoryEntry *append(const QString &name)
+ {
+ for (QVector<VirtualDirectoryEntry*>::Iterator it = dirEntries.begin(), end = dirEntries.end();
+ it != end; ++it) {
+ if ((*it)->name == name)
+ return *it;
+ }
+
+ VirtualDirectoryEntry *subEntry = new VirtualDirectoryEntry;
+ subEntry->name = name;
+ dirEntries.append(subEntry);
+ return subEntry;
+ }
+
+ void appendEmptyFile(const QString &name)
+ {
+ VirtualDirectoryEntry *subEntry = new VirtualDirectoryEntry;
+ subEntry->name = name;
+ subEntry->isDirectory = false;
+ dirEntries.append(subEntry);
+ }
+
+ bool isEmpty() const { return dirEntries.isEmpty(); }
+};
+
+struct DataStream
+{
+ DataStream(QVector<unsigned char > *data = 0)
+ : data(data)
+ {}
+
+ qint64 currentOffset() const { return data->size(); }
+
+ DataStream &operator<<(quint16 value)
+ {
+ unsigned char d[2];
+ qToBigEndian(value, d);
+ data->append(d[0]);
+ data->append(d[1]);
+ return *this;
+ }
+ DataStream &operator<<(quint32 value)
+ {
+ unsigned char d[4];
+ qToBigEndian(value, d);
+ data->append(d[0]);
+ data->append(d[1]);
+ data->append(d[2]);
+ data->append(d[3]);
+ return *this;
+ }
+private:
+ QVector<unsigned char> *data;
+};
+
+static bool resource_sort_order(const VirtualDirectoryEntry *lhs, const VirtualDirectoryEntry *rhs)
+{
+ return qt_hash(lhs->name) < qt_hash(rhs->name);
+}
+
+struct ResourceTree
+{
+ ResourceTree()
+ {}
+
+ void serialize(VirtualDirectoryEntry &root, QVector<unsigned char> *treeData, QVector<unsigned char> *stringData)
+ {
+ treeStream = DataStream(treeData);
+ stringStream = DataStream(stringData);
+
+ QStack<VirtualDirectoryEntry *> directories;
+
+ {
+ directories.push(&root);
+ while (!directories.isEmpty()) {
+ VirtualDirectoryEntry *entry = directories.pop();
+ registerString(entry->name);
+ if (entry->isDirectory)
+ directories << entry->dirEntries;
+ }
+ }
+
+ {
+ quint32 currentDirectoryIndex = 1;
+ directories.push(&root);
+ while (!directories.isEmpty()) {
+ VirtualDirectoryEntry *entry = directories.pop();
+ entry->firstChildIndex = currentDirectoryIndex;
+ currentDirectoryIndex += entry->dirEntries.count();
+ std::sort(entry->dirEntries.begin(), entry->dirEntries.end(), resource_sort_order);
+
+ for (QVector<VirtualDirectoryEntry*>::ConstIterator child = entry->dirEntries.constBegin(), end = entry->dirEntries.constEnd();
+ child != end; ++child) {
+ if ((*child)->isDirectory)
+ directories << *child;
+ }
+ }
+ }
+
+ {
+ writeTreeEntry(&root);
+ directories.push(&root);
+ while (!directories.isEmpty()) {
+ VirtualDirectoryEntry *entry = directories.pop();
+
+ for (QVector<VirtualDirectoryEntry*>::ConstIterator child = entry->dirEntries.constBegin(), end = entry->dirEntries.constEnd();
+ child != end; ++child) {
+ writeTreeEntry(*child);
+ if ((*child)->isDirectory)
+ directories << (*child);
+ }
+ }
+ }
+ }
+
+private:
+ DataStream treeStream;
+ DataStream stringStream;
+ QHash<QString, qint64> stringOffsets;
+
+ void registerString(const QString &name)
+ {
+ if (stringOffsets.contains(name))
+ return;
+ const qint64 offset = stringStream.currentOffset();
+ stringOffsets.insert(name, offset);
+
+ stringStream << quint16(name.length())
+ << quint32(qt_hash(name));
+ for (int i = 0; i < name.length(); ++i)
+ stringStream << quint16(name.at(i).unicode());
+ }
+
+ void writeTreeEntry(VirtualDirectoryEntry *entry)
+ {
+ treeStream << quint32(stringOffsets.value(entry->name))
+ << quint16(entry->isDirectory ? 0x2 : 0x0); // Flags: File or Directory
+
+ if (entry->isDirectory) {
+ treeStream << quint32(entry->dirEntries.count())
+ << quint32(entry->firstChildIndex);
+ } else {
+ treeStream << quint16(QLocale::AnyCountry) << quint16(QLocale::C)
+ << quint32(0x0);
+ }
+ }
+};
+
+static QByteArray generateResourceDirectoryTree(QTextStream &code, const QStringList &qrcFiles)
+{
+ QByteArray call;
+ if (qrcFiles.isEmpty())
+ return call;
+
+ VirtualDirectoryEntry resourceDirs;
+ resourceDirs.name = QStringLiteral("/");
+
+ foreach (const QString &entry, qrcFiles) {
+ const QStringList segments = entry.split(QLatin1Char('/'), QString::SkipEmptyParts);
+
+ VirtualDirectoryEntry *dirEntry = &resourceDirs;
+
+ for (int i = 0; i < segments.count() - 1; ++i)
+ dirEntry = dirEntry->append(segments.at(i));
+ dirEntry->appendEmptyFile(segments.last());
+ }
+
+ if (resourceDirs.isEmpty())
+ return call;
+
+ QVector<unsigned char> names;
+ QVector<unsigned char> tree;
+ ResourceTree().serialize(resourceDirs, &tree, &names);
+
+ code << "static const unsigned char qt_resource_tree[] = {\n";
+ for (int i = 0; i < tree.count(); ++i) {
+ code << uint(tree.at(i));
+ if (i < tree.count() - 1)
+ code << ',';
+ if (i % 16 == 0)
+ code << '\n';
+ }
+ code << "};\n";
+
+ code << "static const unsigned char qt_resource_names[] = {\n";
+ for (int i = 0; i < names.count(); ++i) {
+ code << uint(names.at(i));
+ if (i < names.count() - 1)
+ code << ',';
+ if (i % 16 == 0)
+ code << '\n';
+ }
+ code << "};\n";
+
+ code << "static const unsigned char qt_resource_empty_payout[] = { 0, 0, 0, 0, 0 };\n";
+
+ code << "QT_BEGIN_NAMESPACE\n";
+ code << "extern Q_CORE_EXPORT bool qRegisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *);\n";
+ code << "QT_END_NAMESPACE\n";
+
+ call = "QT_PREPEND_NAMESPACE(qRegisterResourceData)(/*version*/0x01, qt_resource_tree, qt_resource_names, qt_resource_empty_payout);\n";
+
+ return call;
+}
+
+static QString qtResourceNameForFile(const QString &fileName)
+{
+ QFileInfo fi(fileName);
+ QString name = fi.completeBaseName();
+ if (name.isEmpty())
+ name = fi.fileName();
+ name.replace(QRegExp(QLatin1String("[^a-zA-Z0-9_]")), QLatin1String("_"));
+ return name;
+}
+
+bool generateLoader(const QStringList &compiledFiles, const QString &outputFileName, const QStringList &resourceFileMappings, QString *errorString)
+{
+ QByteArray generatedLoaderCode;
+
+ {
+ QTextStream stream(&generatedLoaderCode);
+ stream << "#include <QtQml/qqmlprivate.h>\n";
+ stream << "#include <QtCore/qdir.h>\n";
+ stream << "#include <QtCore/qurl.h>\n";
+ stream << "\n";
+
+ QByteArray resourceRegisterCall = generateResourceDirectoryTree(stream, compiledFiles);
+
+ stream << "namespace QmlCacheGeneratedCode {\n";
+ for (int i = 0; i < compiledFiles.count(); ++i) {
+ const QString compiledFile = compiledFiles.at(i);
+ const QString ns = symbolNamespaceForPath(compiledFile);
+ stream << "namespace " << symbolNamespaceForPath(compiledFile) << " { \n";
+ stream << " extern const unsigned char qmlData[];\n";
+ stream << " const QQmlPrivate::CachedQmlUnit unit = {\n";
+ stream << " reinterpret_cast<const QV4::CompiledData::Unit*>(&qmlData), nullptr, nullptr\n";
+ stream << " };\n";
+ stream << "}\n";
+ }
+
+ stream << "\n}\n";
+ stream << "namespace {\n";
+
+ stream << "struct Registry {\n";
+ stream << " Registry();\n";
+ stream << " QHash<QString, const QQmlPrivate::CachedQmlUnit*> resourcePathToCachedUnit;\n";
+ stream << " static const QQmlPrivate::CachedQmlUnit *lookupCachedUnit(const QUrl &url);\n";
+ stream << "};\n\n";
+ stream << "Q_GLOBAL_STATIC(Registry, unitRegistry);\n";
+ stream << "\n\n";
+
+ stream << "Registry::Registry() {\n";
+
+ for (int i = 0; i < compiledFiles.count(); ++i) {
+ const QString qrcFile = compiledFiles.at(i);
+ const QString ns = symbolNamespaceForPath(qrcFile);
+ stream << " resourcePathToCachedUnit.insert(QStringLiteral(\"" << qrcFile << "\"), &QmlCacheGeneratedCode::" << ns << "::unit);\n";
+ }
+
+ stream << " QQmlPrivate::RegisterQmlUnitCacheHook registration;\n";
+ stream << " registration.version = 0;\n";
+ stream << " registration.lookupCachedQmlUnit = &lookupCachedUnit;\n";
+ stream << " QQmlPrivate::qmlregister(QQmlPrivate::QmlUnitCacheHookRegistration, &registration);\n";
+
+ if (!resourceRegisterCall.isEmpty())
+ stream << resourceRegisterCall;
+
+ stream << "}\n";
+ stream << "const QQmlPrivate::CachedQmlUnit *Registry::lookupCachedUnit(const QUrl &url) {\n";
+ stream << " if (url.scheme() != QLatin1String(\"qrc\"))\n";
+ stream << " return nullptr;\n";
+ stream << " QString resourcePath = QDir::cleanPath(url.path());\n";
+ stream << " if (resourcePath.isEmpty())\n";
+ stream << " return nullptr;\n";
+ stream << " if (!resourcePath.startsWith(QLatin1Char('/')))\n";
+ stream << " resourcePath.prepend(QLatin1Char('/'));\n";
+ stream << " return unitRegistry()->resourcePathToCachedUnit.value(resourcePath, nullptr);\n";
+ stream << "}\n";
+ stream << "}\n";
+
+ for (const QString &mapping: resourceFileMappings) {
+ QString originalResourceFile = mapping;
+ QString newResourceFile;
+ const int mappingSplit = originalResourceFile.indexOf(QLatin1Char('='));
+ if (mappingSplit != -1) {
+ newResourceFile = originalResourceFile.mid(mappingSplit + 1);
+ originalResourceFile.truncate(mappingSplit);
+ }
+
+ const QString function = QLatin1String("qInitResources_") + qtResourceNameForFile(originalResourceFile);
+
+ stream << QStringLiteral("int QT_MANGLE_NAMESPACE(%1)() {\n").arg(function);
+ stream << " ::unitRegistry();\n";
+ if (!newResourceFile.isEmpty())
+ stream << " Q_INIT_RESOURCE(" << qtResourceNameForFile(newResourceFile) << ");\n";
+ stream << " return 1;\n";
+ stream << "}\n";
+ stream << "Q_CONSTRUCTOR_FUNCTION(QT_MANGLE_NAMESPACE(" << function << "));\n";
+ }
+ }
+
+ QSaveFile f(outputFileName);
+ if (!f.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
+ *errorString = f.errorString();
+ return false;
+ }
+
+ if (f.write(generatedLoaderCode) != generatedLoaderCode.size()) {
+ *errorString = f.errorString();
+ return false;
+ }
+
+ if (!f.commit()) {
+ *errorString = f.errorString();
+ return false;
+ }
+
+ return true;
+}
diff --git a/tools/qmlcachegen/qmlcache.prf b/tools/qmlcachegen/qmlcache.prf
index 330da358b7..537eaf62ea 100644
--- a/tools/qmlcachegen/qmlcache.prf
+++ b/tools/qmlcachegen/qmlcache.prf
@@ -3,28 +3,10 @@ static {
return()
}
-android {
- message("QML cache generation ahead of time is not supported on Android")
- return()
-}
-
qtPrepareTool(QML_CACHEGEN, qmlcachegen, _ARCH_CHECK)
isEmpty(TARGETPATH): error("Must set TARGETPATH (QML import name) for ahead-of-time QML cache generation")
-!isEmpty(QT_TARGET_ARCH):QML_CACHEGEN_ARCH=$$QT_TARGET_ARCH
-else:QML_CACHEGEN_ARCH=$$QT_ARCH
-
-!isEmpty(QT_TARGET_BUILDABI):QML_CACHEGEN_ABI=$$QT_TARGET_BUILDABI
-else:QML_CACHEGEN_ABI=$$QT_BUILDABI
-
-QML_CACHEGEN_ARGS=--target-architecture=$$QML_CACHEGEN_ARCH --target-abi=$$QML_CACHEGEN_ABI
-
-!system($$QML_CACHEGEN_ARCH_CHECK $$QML_CACHEGEN_ARGS --check-if-supported) {
- message("QML cache generation requested but target architecture $$QML_CACHEGEN_ARCH is not supported.")
- return()
-}
-
load(qt_build_paths)
prefix_build: QMLCACHE_DESTDIR = $$MODULE_BASE_OUTDIR/qml/$$TARGETPATH
@@ -50,7 +32,7 @@ qmlcacheinst.CONFIG = no_check_exist
qmlcachegen.input = CACHEGEN_FILES
qmlcachegen.output = ${QMAKE_FUNC_FILE_IN_qmlCacheOutputFileName}
qmlcachegen.CONFIG = no_link target_predeps
-qmlcachegen.commands = $$QML_CACHEGEN $$QML_CACHEGEN_ARGS -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
+qmlcachegen.commands = $$QML_CACHEGEN -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
qmlcachegen.name = Generate QML Cache ${QMAKE_FILE_IN}
qmlcachegen.variable_out = GENERATED_FILES
diff --git a/tools/qmlcachegen/qmlcachegen.cpp b/tools/qmlcachegen/qmlcachegen.cpp
index 8d59a34a28..7c04f69a2b 100644
--- a/tools/qmlcachegen/qmlcachegen.cpp
+++ b/tools/qmlcachegen/qmlcachegen.cpp
@@ -33,19 +33,16 @@
#include <QFileInfo>
#include <QDateTime>
#include <QHashFunctions>
+#include <QSaveFile>
#include <private/qqmlirbuilder_p.h>
-#include <private/qv4isel_moth_p.h>
#include <private/qqmljsparser_p.h>
-#include <private/qv4jssimplifier_p.h>
-QT_BEGIN_NAMESPACE
+#include "resourcefilemapper.h"
-namespace QV4 { namespace JIT {
-Q_QML_EXPORT QV4::EvalISelFactory *createISelForArchitecture(const QString &architecture);
-} }
-
-QT_END_NAMESPACE
+int filterResourceFile(const QString &input, const QString &output);
+bool generateLoader(const QStringList &compiledFiles, const QString &output, const QStringList &resourceFileMappings, QString *errorString);
+QString symbolNamespaceForPath(const QString &relativePath);
QSet<QString> illegalNames;
@@ -145,7 +142,7 @@ static bool checkArgumentsObjectUseInSignalHandlers(const QmlIR::Document &doc,
auto compiledFunction = doc.jsModule.functions.value(object->runtimeFunctionIndices.at(binding->value.compiledScriptIndex));
if (!compiledFunction)
continue;
- if (compiledFunction->usesArgumentsObject) {
+ if (compiledFunction->usesArgumentsObject == QV4::Compiler::Context::ArgumentsObjectUsed) {
error->message = QLatin1Char(':') + QString::number(compiledFunction->line) + QLatin1Char(':');
if (compiledFunction->column > 0)
error->message += QString::number(compiledFunction->column) + QLatin1Char(':');
@@ -162,10 +159,11 @@ static bool checkArgumentsObjectUseInSignalHandlers(const QmlIR::Document &doc,
return true;
}
-static bool compileQmlFile(const QString &inputFileName, const QString &outputFileName, QV4::EvalISelFactory *iselFactory, const QString &targetABI, Error *error)
+using SaveFunction = std::function<bool (QV4::CompiledData::CompilationUnit *, QString *)>;
+
+static bool compileQmlFile(const QString &inputFileName, SaveFunction saveFunction, Error *error)
{
QmlIR::Document irDocument(/*debugMode*/false);
- irDocument.jsModule.targetABI = targetABI;
QString sourceCode;
{
@@ -196,10 +194,11 @@ static bool compileQmlFile(const QString &inputFileName, const QString &outputFi
annotateListElements(&irDocument);
{
- QmlIR::JSCodeGen v4CodeGen(/*empty input file name*/QString(), QString(), irDocument.code,
- &irDocument.jsModule, &irDocument.jsParserEngine,
- irDocument.program, /*import cache*/0,
- &irDocument.jsGenerator.stringTable, illegalNames);
+ QmlIR::JSCodeGen v4CodeGen(irDocument.code,
+ &irDocument.jsGenerator, &irDocument.jsModule,
+ &irDocument.jsParserEngine, irDocument.program,
+ /*import cache*/0, &irDocument.jsGenerator.stringTable, illegalNames);
+ v4CodeGen.setUseFastLookups(false); // Disable lookups in non-standalone (aka QML) mode
for (QmlIR::Object *object: qAsConst(irDocument.objects)) {
if (object->functionsAndExpressions->count == 0)
continue;
@@ -229,23 +228,13 @@ static bool compileQmlFile(const QString &inputFileName, const QString &outputFi
}
QmlIR::QmlUnitGenerator generator;
-
- {
- QQmlJavaScriptBindingExpressionSimplificationPass pass(irDocument.objects, &irDocument.jsModule, &irDocument.jsGenerator);
- pass.reduceTranslationBindings();
- }
-
- QV4::ExecutableAllocator allocator;
- QScopedPointer<QV4::EvalInstructionSelection> isel(iselFactory->create(/*engine*/nullptr, &allocator, &irDocument.jsModule, &irDocument.jsGenerator));
- // Disable lookups in non-standalone (aka QML) mode
- isel->setUseFastLookups(false);
- irDocument.javaScriptCompilationUnit = isel->compile(/*generate unit*/false);
+ irDocument.javaScriptCompilationUnit = v4CodeGen.generateCompilationUnit(/*generate unit*/false);
QV4::CompiledData::Unit *unit = generator.generate(irDocument);
unit->flags |= QV4::CompiledData::Unit::StaticData;
unit->flags |= QV4::CompiledData::Unit::PendingTypeCompilation;
irDocument.javaScriptCompilationUnit->data = unit;
- if (!irDocument.javaScriptCompilationUnit->saveToDisk(outputFileName, &error->message))
+ if (!saveFunction(irDocument.javaScriptCompilationUnit, &error->message))
return false;
free(unit);
@@ -253,10 +242,9 @@ static bool compileQmlFile(const QString &inputFileName, const QString &outputFi
return true;
}
-static bool compileJSFile(const QString &inputFileName, const QString &outputFileName, QV4::EvalISelFactory *iselFactory, const QString &targetABI, Error *error)
+static bool compileJSFile(const QString &inputFileName, const QString &inputFileUrl, SaveFunction saveFunction, Error *error)
{
QmlIR::Document irDocument(/*debugMode*/false);
- irDocument.jsModule.targetABI = targetABI;
QString sourceCode;
{
@@ -308,12 +296,13 @@ static bool compileJSFile(const QString &inputFileName, const QString &outputFil
}
{
- QmlIR::JSCodeGen v4CodeGen(inputFileName, inputFileName,
- irDocument.code, &irDocument.jsModule,
- &irDocument.jsParserEngine, irDocument.program,
- /*import cache*/0, &irDocument.jsGenerator.stringTable, illegalNames);
- v4CodeGen.generateFromProgram(/*empty input file name*/QString(), QString(), sourceCode,
- program, &irDocument.jsModule, QQmlJS::Codegen::GlobalCode);
+ QmlIR::JSCodeGen v4CodeGen(irDocument.code, &irDocument.jsGenerator,
+ &irDocument.jsModule, &irDocument.jsParserEngine,
+ irDocument.program, /*import cache*/0,
+ &irDocument.jsGenerator.stringTable, illegalNames);
+ v4CodeGen.setUseFastLookups(false); // Disable lookups in non-standalone (aka QML) mode
+ v4CodeGen.generateFromProgram(inputFileName, inputFileUrl, sourceCode, program,
+ &irDocument.jsModule, QV4::Compiler::GlobalCode);
QList<QQmlJS::DiagnosticMessage> jsErrors = v4CodeGen.errors();
if (!jsErrors.isEmpty()) {
for (const QQmlJS::DiagnosticMessage &e: qAsConst(jsErrors)) {
@@ -327,16 +316,12 @@ static bool compileJSFile(const QString &inputFileName, const QString &outputFil
QmlIR::QmlUnitGenerator generator;
- QV4::ExecutableAllocator allocator;
- QScopedPointer<QV4::EvalInstructionSelection> isel(iselFactory->create(/*engine*/nullptr, &allocator, &irDocument.jsModule, &irDocument.jsGenerator));
- // Disable lookups in non-standalone (aka QML) mode
- isel->setUseFastLookups(false);
- irDocument.javaScriptCompilationUnit = isel->compile(/*generate unit*/false);
+ irDocument.javaScriptCompilationUnit = v4CodeGen.generateCompilationUnit(/*generate unit*/false);
QV4::CompiledData::Unit *unit = generator.generate(irDocument);
unit->flags |= QV4::CompiledData::Unit::StaticData;
irDocument.javaScriptCompilationUnit->data = unit;
- if (!irDocument.javaScriptCompilationUnit->saveToDisk(outputFileName, &error->message)) {
+ if (!saveFunction(irDocument.javaScriptCompilationUnit, &error->message)) {
engine->setDirectives(oldDirs);
return false;
}
@@ -347,6 +332,81 @@ static bool compileJSFile(const QString &inputFileName, const QString &outputFil
return true;
}
+static bool saveUnitAsCpp(const QString &inputFileName, const QString &outputFileName, QV4::CompiledData::CompilationUnit *unit, QString *errorString)
+{
+ QSaveFile f(outputFileName);
+ if (!f.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
+ *errorString = f.errorString();
+ return false;
+ }
+
+ auto writeStr = [&f, errorString](const QByteArray &data) {
+ if (f.write(data) != data.size()) {
+ *errorString = f.errorString();
+ return false;
+ }
+ return true;
+ };
+
+ if (!writeStr("// "))
+ return false;
+
+ if (!writeStr(inputFileName.toUtf8()))
+ return false;
+
+ if (!writeStr("\n"))
+ return false;
+
+ if (!writeStr(QByteArrayLiteral("namespace QmlCacheGeneratedCode {\nnamespace ")))
+ return false;
+
+ if (!writeStr(symbolNamespaceForPath(inputFileName).toUtf8()))
+ return false;
+
+ if (!writeStr(QByteArrayLiteral(" {\nextern const unsigned char qmlData alignas(16) [] = {\n")))
+ return false;
+
+ QByteArray hexifiedData;
+ {
+ QByteArray modifiedUnit;
+ modifiedUnit.resize(unit->data->unitSize);
+ memcpy(modifiedUnit.data(), unit->data, unit->data->unitSize);
+ const char *dataPtr = modifiedUnit.data();
+ QV4::CompiledData::Unit *unitPtr;
+ memcpy(&unitPtr, &dataPtr, sizeof(unitPtr));
+ unitPtr->flags |= QV4::CompiledData::Unit::StaticData;
+
+ QTextStream stream(&hexifiedData);
+ const uchar *begin = reinterpret_cast<const uchar *>(modifiedUnit.constData());
+ const uchar *end = begin + unit->data->unitSize;
+ stream << hex;
+ int col = 0;
+ for (const uchar *data = begin; data < end; ++data, ++col) {
+ if (data > begin)
+ stream << ',';
+ if (col % 8 == 0) {
+ stream << '\n';
+ col = 0;
+ }
+ stream << "0x" << *data;
+ }
+ stream << '\n';
+ };
+
+ if (!writeStr(hexifiedData))
+ return false;
+
+ if (!writeStr("};\n}\n}\n"))
+ return false;
+
+ if (!f.commit()) {
+ *errorString = f.errorString();
+ return false;
+ }
+
+ return true;
+}
+
int main(int argc, char **argv)
{
// Produce reliably the same output for the same input by disabling QHash's random seeding.
@@ -360,11 +420,14 @@ int main(int argc, char **argv)
parser.addHelpOption();
parser.addVersionOption();
- QCommandLineOption targetArchitectureOption(QStringLiteral("target-architecture"), QCoreApplication::translate("main", "Target architecture"), QCoreApplication::translate("main", "architecture"));
- parser.addOption(targetArchitectureOption);
-
- QCommandLineOption targetABIOption(QStringLiteral("target-abi"), QCoreApplication::translate("main", "Target architecture binary interface"), QCoreApplication::translate("main", "abi"));
- parser.addOption(targetABIOption);
+ QCommandLineOption filterResourceFileOption(QStringLiteral("filter-resource-file"), QCoreApplication::translate("main", "Filter out QML/JS files from a resource file that can be cached ahead of time instead"));
+ parser.addOption(filterResourceFileOption);
+ QCommandLineOption resourceFileMappingOption(QStringLiteral("resource-file-mapping"), QCoreApplication::translate("main", "Path from original resource file to new one"), QCoreApplication::translate("main", "old-name:new-name"));
+ parser.addOption(resourceFileMappingOption);
+ QCommandLineOption resourceOption(QStringLiteral("resource"), QCoreApplication::translate("main", "Qt resource file that might later contain one of the compiled files"), QCoreApplication::translate("main", "resource-file-name"));
+ parser.addOption(resourceOption);
+ QCommandLineOption resourcePathOption(QStringLiteral("resource-path"), QCoreApplication::translate("main", "Qt resource file path corresponding to the file being compiled"), QCoreApplication::translate("main", "resource-path"));
+ parser.addOption(resourcePathOption);
QCommandLineOption outputFileOption(QStringLiteral("o"), QCoreApplication::translate("main", "Output file name"), QCoreApplication::translate("main", "file name"));
parser.addOption(outputFileOption);
@@ -375,61 +438,119 @@ int main(int argc, char **argv)
parser.addPositionalArgument(QStringLiteral("[qml file]"),
QStringLiteral("QML source file to generate cache for."));
- parser.process(app);
+ parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
- if (!parser.isSet(targetArchitectureOption)) {
- fprintf(stderr, "Target architecture not specified. Please specify with --target-architecture=<arch>\n");
- parser.showHelp();
- return EXIT_FAILURE;
- }
+ parser.process(app);
- QScopedPointer<QV4::EvalISelFactory> isel;
- const QString targetArchitecture = parser.value(targetArchitectureOption);
+ enum Output {
+ GenerateCpp,
+ GenerateCacheFile,
+ GenerateLoader
+ } target = GenerateCacheFile;
- isel.reset(QV4::JIT::createISelForArchitecture(targetArchitecture));
+ QString outputFileName;
+ if (parser.isSet(outputFileOption))
+ outputFileName = parser.value(outputFileOption);
- if (parser.isSet(checkIfSupportedOption)) {
- if (isel.isNull())
- return EXIT_FAILURE;
- else
- return EXIT_SUCCESS;
+ if (outputFileName.endsWith(QLatin1String(".cpp"))) {
+ target = GenerateCpp;
+ if (outputFileName.endsWith(QLatin1String("qmlcache_loader.cpp")))
+ target = GenerateLoader;
}
const QStringList sources = parser.positionalArguments();
if (sources.isEmpty()){
parser.showHelp();
- } else if (sources.count() > 1) {
+ } else if (sources.count() > 1 && target != GenerateLoader) {
fprintf(stderr, "%s\n", qPrintable(QStringLiteral("Too many input files specified: '") + sources.join(QStringLiteral("' '")) + QLatin1Char('\'')));
return EXIT_FAILURE;
}
+
const QString inputFile = sources.first();
+ if (outputFileName.isEmpty())
+ outputFileName = inputFile + QLatin1Char('c');
- if (!isel)
- isel.reset(new QV4::Moth::ISelFactory);
+ if (parser.isSet(filterResourceFileOption)) {
+ return filterResourceFile(inputFile, outputFileName);
+ }
- Error error;
+ if (target == GenerateLoader) {
+ ResourceFileMapper mapper(sources);
- QString outputFileName = inputFile + QLatin1Char('c');
- if (parser.isSet(outputFileOption))
- outputFileName = parser.value(outputFileOption);
+ Error error;
+ if (!generateLoader(mapper.qmlCompilerFiles(), outputFileName, parser.values(resourceFileMappingOption), &error.message)) {
+ error.augment(QLatin1String("Error generating loader stub: ")).print();
+ return EXIT_FAILURE;
+ }
+ return EXIT_SUCCESS;
+ }
+
+ QString inputFileUrl = inputFile;
+
+ SaveFunction saveFunction;
+ if (target == GenerateCpp) {
+ ResourceFileMapper fileMapper(parser.values(resourceOption));
+ QString inputResourcePath = parser.value(resourcePathOption);
+
+ if (!inputResourcePath.isEmpty() && !fileMapper.isEmpty()) {
+ fprintf(stderr, "--%s and --%s are mutually exclusive.\n",
+ qPrintable(resourcePathOption.names().first()),
+ qPrintable(resourceOption.names().first()));
+ return EXIT_FAILURE;
+ }
+
+ // If the user didn't specify the resource path corresponding to the file on disk being
+ // compiled, try to determine it from the resource file, if one was supplied.
+ if (inputResourcePath.isEmpty()) {
+ const QStringList resourcePaths = fileMapper.resourcePaths(inputFile);
+ if (resourcePaths.isEmpty()) {
+ fprintf(stderr, "No resource path for file: %s\n", qPrintable(inputFile));
+ return EXIT_FAILURE;
+ }
+
+ if (resourcePaths.size() != 1) {
+ fprintf(stderr, "Multiple resource paths for file %s. "
+ "Use the --%s option to disambiguate:\n",
+ qPrintable(inputFile),
+ qPrintable(resourcePathOption.names().first()));
+ for (const QString &resourcePath: resourcePaths)
+ fprintf(stderr, "\t%s\n", qPrintable(resourcePath));
+ return EXIT_FAILURE;
+ }
+
+ inputResourcePath = resourcePaths.first();
+ }
+
+ inputFileUrl = QStringLiteral("qrc://") + inputResourcePath;
+
+ saveFunction = [inputResourcePath, outputFileName](QV4::CompiledData::CompilationUnit *unit, QString *errorString) {
+ return saveUnitAsCpp(inputResourcePath, outputFileName, unit, errorString);
+ };
+
+ } else {
+ saveFunction = [outputFileName](QV4::CompiledData::CompilationUnit *unit, QString *errorString) {
+ return unit->saveToDisk(outputFileName, errorString);
+ };
+ }
setupIllegalNames();
- const QString targetABI = parser.value(targetABIOption);
if (inputFile.endsWith(QLatin1String(".qml"))) {
- if (!compileQmlFile(inputFile, outputFileName, isel.data(), targetABI, &error)) {
+ Error error;
+ if (!compileQmlFile(inputFile, saveFunction, &error)) {
error.augment(QLatin1String("Error compiling qml file: ")).print();
return EXIT_FAILURE;
}
} else if (inputFile.endsWith(QLatin1String(".js"))) {
- if (!compileJSFile(inputFile, outputFileName, isel.data(), targetABI, &error)) {
+ Error error;
+ if (!compileJSFile(inputFile, inputFileUrl, saveFunction, &error)) {
error.augment(QLatin1String("Error compiling qml file: ")).print();
return EXIT_FAILURE;
}
} else {
- fprintf(stderr, "Ignoring %s input file as it is not QML source code - maybe remove from QML_FILES?\n", qPrintable(inputFile)); }
-
+ fprintf(stderr, "Ignoring %s input file as it is not QML source code - maybe remove from QML_FILES?\n", qPrintable(inputFile));
+ }
return EXIT_SUCCESS;
}
diff --git a/tools/qmlcachegen/qmlcachegen.pro b/tools/qmlcachegen/qmlcachegen.pro
index 25afc2860d..391f0c3889 100644
--- a/tools/qmlcachegen/qmlcachegen.pro
+++ b/tools/qmlcachegen/qmlcachegen.pro
@@ -3,12 +3,25 @@ option(host_build)
QT = qmldevtools-private
DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII
-SOURCES = qmlcachegen.cpp
+SOURCES = qmlcachegen.cpp \
+ resourcefilter.cpp \
+ generateloader.cpp \
+ resourcefilemapper.cpp
TARGET = qmlcachegen
-build_integration.files = qmlcache.prf
+build_integration.files = qmlcache.prf qtquickcompiler.prf
build_integration.path = $$[QT_HOST_DATA]/mkspecs/features
prefix_build: INSTALLS += build_integration
else: COPIES += build_integration
+cmake_build_integration.files = Qt5QuickCompilerConfig.cmake
+cmake_build_integration.path = $$[QT_INSTALL_LIBS]/cmake/Qt5QuickCompiler
+prefix_build: INSTALLS += cmake_build_integration
+else: COPIES += cmake_build_integration
+
+QMAKE_TARGET_DESCRIPTION = QML Cache Generator
+
load(qt_tool)
+
+HEADERS += \
+ resourcefilemapper.h
diff --git a/tools/qmlcachegen/qtquickcompiler.prf b/tools/qmlcachegen/qtquickcompiler.prf
new file mode 100644
index 0000000000..75e474ba70
--- /dev/null
+++ b/tools/qmlcachegen/qtquickcompiler.prf
@@ -0,0 +1,86 @@
+
+qtPrepareTool(QML_CACHEGEN, qmlcachegen, _FILTER)
+qtPrepareTool(QMAKE_RCC, rcc, _DEP)
+
+QMLCACHE_DIR = .qmlcache
+
+defineReplace(qmlCacheResourceFileOutputName) {
+ name = $$relative_path($$1, $$_PRO_FILE_PWD_)
+ name = $$replace(name,/,_)
+ name = $$replace(name, \\.qrc$, _qmlcache.qrc)
+ name = $$replace(name,\.\.,)
+ name = $$replace(name,-,_)
+ name = $$absolute_path($$name, $$OUT_PWD)
+ return($${name})
+}
+
+# Flatten RESOURCES that may contain individual files or objects
+load(resources)
+
+NEWRESOURCES =
+QMLCACHE_RESOURCE_FILES =
+
+for(res, RESOURCES) {
+ absRes = $$absolute_path($$res, $$_PRO_FILE_PWD_)
+ rccContents = $$system($$QMAKE_RCC_DEP -list $$absRes,lines)
+ contains(rccContents,.*\\.js$)|contains(rccContents,.*\\.qml$) {
+ new_resource = $$qmlCacheResourceFileOutputName($$res)
+ mkpath($$dirname(new_resource))
+ remaining_files = $$system($$QML_CACHEGEN_FILTER -filter-resource-file -o $$new_resource $$absRes,lines)
+ !isEmpty(remaining_files) {
+ NEWRESOURCES += $$new_resource
+ QMLCACHE_LOADER_FLAGS += --resource-file-mapping=$$absRes=$$new_resource
+ } else {
+ QMLCACHE_LOADER_FLAGS += --resource-file-mapping=$$absRes
+ }
+
+ QMLCACHE_RESOURCE_FILES += $$absRes
+
+ for(candidate, $$list($$rccContents)) {
+ contains(candidate,.*\\.js$)|contains(candidate,.*\\.qml$) {
+ QMLCACHE_FILES += $$candidate
+ }
+ }
+ } else {
+ NEWRESOURCES += $$res
+ }
+}
+
+RESOURCES = $$NEWRESOURCES
+
+QMLCACHE_RESOURCE_FLAGS =
+for(res, QMLCACHE_RESOURCE_FILES) {
+ QMLCACHE_RESOURCE_FLAGS += --resource=$$res
+}
+
+defineReplace(qmlCacheOutputName) {
+ name = $$absolute_path($$1, $$OUT_PWD)
+ name = $$relative_path($$name, $$_PRO_FILE_PWD_)
+ name = $$replace(name, \\.qml$, _qml)
+ name = $$replace(name, \\.js$, _js)
+ name = $$replace(name,/,_)
+ name = $$QMLCACHE_DIR/$${name}
+ return($${name})
+}
+
+qmlcache.input = QMLCACHE_FILES
+qmlcache.output = ${QMAKE_FUNC_FILE_IN_qmlCacheOutputName}$${first(QMAKE_EXT_CPP)}
+qmlcache.commands = $$QML_CACHEGEN $$QMLCACHE_RESOURCE_FLAGS $$QMLCACHE_FLAGS -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
+qmlcache.name = qmlcachegen ${QMAKE_FILE_IN}
+qmlcache.variable_out = GENERATED_SOURCES
+qmlcache.dependency_type = TYPE_C
+
+qmlcache_loader.input = QMLCACHE_RESOURCE_FILES
+qmlcache_loader.output = $$QMLCACHE_DIR/qmlcache_loader.cpp
+qmlcache_loader.commands = $$QML_CACHEGEN $$QMLCACHE_LOADER_FLAGS $$QMLCACHE_FLAGS -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
+qmlcache_loader.name = qmlcachengen_loader ${QMAKE_FILE_IN}
+qmlcache_loader.variable_out = SOURCES
+qmlcache_loader.dependency_type = TYPE_C
+qmlcache_loader.CONFIG = combine
+
+unix:!no_qmlcache_depend {
+ qmlcache.depends += $$QML_CACHEGEN
+ qmlcache_loader.depends += $$QML_CACHEGEN
+}
+
+QMAKE_EXTRA_COMPILERS += qmlcache qmlcache_loader
diff --git a/tools/qmlcachegen/resourcefilemapper.cpp b/tools/qmlcachegen/resourcefilemapper.cpp
new file mode 100644
index 0000000000..c2fd057541
--- /dev/null
+++ b/tools/qmlcachegen/resourcefilemapper.cpp
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "resourcefilemapper.h"
+
+#include <QFileInfo>
+#include <QDir>
+#include <QXmlStreamReader>
+
+ResourceFileMapper::ResourceFileMapper(const QStringList &resourceFiles)
+{
+ for (const QString &fileName: resourceFiles) {
+ QFile f(fileName);
+ if (!f.open(QIODevice::ReadOnly))
+ continue;
+ populateFromQrcFile(f);
+ }
+}
+
+bool ResourceFileMapper::isEmpty() const
+{
+ return qrcPathToFileSystemPath.isEmpty();
+}
+
+QStringList ResourceFileMapper::resourcePaths(const QString &fileName)
+{
+ const QString absPath = QDir::cleanPath(QDir::current().absoluteFilePath(fileName));
+ QHashIterator<QString, QString> it(qrcPathToFileSystemPath);
+ QStringList resourcePaths;
+ while (it.hasNext()) {
+ it.next();
+ if (QFileInfo(it.value()) == QFileInfo(absPath))
+ resourcePaths.append(it.key());
+ }
+ return resourcePaths;
+}
+
+QStringList ResourceFileMapper::qmlCompilerFiles() const
+{
+ QStringList files;
+ for (auto it = qrcPathToFileSystemPath.constBegin(), end = qrcPathToFileSystemPath.constEnd();
+ it != end; ++it) {
+ const QString &qrcPath = it.key();
+ const QString suffix = QFileInfo(qrcPath).suffix();
+ if (suffix != QStringLiteral("qml") && suffix != QStringLiteral("js"))
+ continue;
+ files << qrcPath;
+ }
+ return files;
+}
+
+void ResourceFileMapper::populateFromQrcFile(QFile &file)
+{
+ enum State {
+ InitialState,
+ InRCC,
+ InResource,
+ InFile
+ };
+ State state = InitialState;
+
+ QDir qrcDir = QFileInfo(file).absoluteDir();
+
+ QString prefix;
+ QString currentFileName;
+ QXmlStreamAttributes currentFileAttributes;
+
+ QXmlStreamReader reader(&file);
+ while (!reader.atEnd()) {
+ switch (reader.readNext()) {
+ case QXmlStreamReader::StartElement:
+ if (reader.name() == QStringLiteral("RCC")) {
+ if (state != InitialState)
+ return;
+ state = InRCC;
+ continue;
+ } else if (reader.name() == QStringLiteral("qresource")) {
+ if (state != InRCC)
+ return;
+ state = InResource;
+ QXmlStreamAttributes attributes = reader.attributes();
+ if (attributes.hasAttribute(QStringLiteral("prefix")))
+ prefix = attributes.value(QStringLiteral("prefix")).toString();
+ if (!prefix.startsWith(QLatin1Char('/')))
+ prefix.prepend(QLatin1Char('/'));
+ if (!prefix.endsWith(QLatin1Char('/')))
+ prefix.append(QLatin1Char('/'));
+ continue;
+ } else if (reader.name() == QStringLiteral("file")) {
+ if (state != InResource)
+ return;
+ state = InFile;
+ currentFileAttributes = reader.attributes();
+ continue;
+ }
+ return;
+
+ case QXmlStreamReader::EndElement:
+ if (reader.name() == QStringLiteral("file")) {
+ if (state != InFile)
+ return;
+ state = InResource;
+ continue;
+ } else if (reader.name() == QStringLiteral("qresource")) {
+ if (state != InResource)
+ return;
+ state = InRCC;
+ continue;
+ } else if (reader.name() == QStringLiteral("RCC")) {
+ if (state != InRCC)
+ return;
+ state = InitialState;
+ continue;
+ }
+ return;
+
+ case QXmlStreamReader::Characters: {
+ if (reader.isWhitespace())
+ break;
+ if (state != InFile)
+ return;
+ currentFileName = reader.text().toString();
+ if (currentFileName.isEmpty())
+ continue;
+
+ const QString fsPath = QDir::cleanPath(qrcDir.absoluteFilePath(currentFileName));
+
+ if (currentFileAttributes.hasAttribute(QStringLiteral("alias")))
+ currentFileName = currentFileAttributes.value(QStringLiteral("alias")).toString();
+
+ currentFileName = QDir::cleanPath(currentFileName);
+ while (currentFileName.startsWith(QLatin1String("../")))
+ currentFileName.remove(0, 3);
+
+ const QString qrcPath = prefix + currentFileName;
+ if (QFile::exists(fsPath))
+ qrcPathToFileSystemPath.insert(qrcPath, fsPath);
+ continue;
+ }
+
+ default: break;
+ }
+ }
+}
diff --git a/tools/qmlcachegen/resourcefilemapper.h b/tools/qmlcachegen/resourcefilemapper.h
new file mode 100644
index 0000000000..2e0ab45171
--- /dev/null
+++ b/tools/qmlcachegen/resourcefilemapper.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef RESOURCEFILEMAPPER_H
+#define RESOURCEFILEMAPPER_H
+
+#include <QStringList>
+#include <QHash>
+#include <QFile>
+
+struct ResourceFileMapper
+{
+ ResourceFileMapper(const QStringList &resourceFiles);
+
+ bool isEmpty() const;
+
+ QStringList resourcePaths(const QString &fileName);
+ QStringList qmlCompilerFiles() const;
+
+private:
+ void populateFromQrcFile(QFile &file);
+
+ QHash<QString, QString> qrcPathToFileSystemPath;
+};
+
+#endif // RESOURCEFILEMAPPER_H
diff --git a/tools/qmlcachegen/resourcefilter.cpp b/tools/qmlcachegen/resourcefilter.cpp
new file mode 100644
index 0000000000..196dbd4a75
--- /dev/null
+++ b/tools/qmlcachegen/resourcefilter.cpp
@@ -0,0 +1,183 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QString>
+#include <QXmlStreamReader>
+#include <QFile>
+#include <QDir>
+
+int filterResourceFile(const QString &input, const QString &output)
+{
+ enum State {
+ InitialState,
+ InRCC,
+ InResource,
+ InFile
+ };
+ State state = InitialState;
+
+ QString prefix;
+ QString currentFileName;
+ QXmlStreamAttributes fileAttributes;
+
+ QFile file(input);
+ if (!file.open(QIODevice::ReadOnly)) {
+ fprintf(stderr, "Cannot open %s for reading.\n", qPrintable(input));
+ return EXIT_FAILURE;
+ }
+
+ QDir inputDirectory = QFileInfo(file).absoluteDir();
+ QDir outputDirectory = QFileInfo(output).absoluteDir();
+
+ QString outputString;
+ QXmlStreamWriter writer(&outputString);
+ writer.setAutoFormatting(true);
+
+ QStringList remainingFiles;
+
+ QXmlStreamReader reader(&file);
+ while (!reader.atEnd()) {
+ switch (reader.readNext()) {
+ case QXmlStreamReader::StartDocument: {
+ QStringRef version = reader.documentVersion();
+ if (!version.isEmpty())
+ writer.writeStartDocument(version.toString());
+ else
+ writer.writeStartDocument();
+ break;
+ }
+ case QXmlStreamReader::EndDocument:
+ writer.writeEndDocument();
+ break;
+ case QXmlStreamReader::StartElement:
+ if (reader.name() == QStringLiteral("RCC")) {
+ if (state != InitialState) {
+ fprintf(stderr, "Unexpected RCC tag in line %d\n", int(reader.lineNumber()));
+ return EXIT_FAILURE;
+ }
+ state = InRCC;
+ } else if (reader.name() == QStringLiteral("qresource")) {
+ if (state != InRCC) {
+ fprintf(stderr, "Unexpected qresource tag in line %d\n", int(reader.lineNumber()));
+ return EXIT_FAILURE;
+ }
+ state = InResource;
+ QXmlStreamAttributes attributes = reader.attributes();
+ if (attributes.hasAttribute(QStringLiteral("prefix")))
+ prefix = attributes.value(QStringLiteral("prefix")).toString();
+ if (!prefix.startsWith(QLatin1Char('/')))
+ prefix.prepend(QLatin1Char('/'));
+ if (!prefix.endsWith(QLatin1Char('/')))
+ prefix.append(QLatin1Char('/'));
+ } else if (reader.name() == QStringLiteral("file")) {
+ if (state != InResource) {
+ fprintf(stderr, "Unexpected file tag in line %d\n", int(reader.lineNumber()));
+ return EXIT_FAILURE;
+ }
+ state = InFile;
+ fileAttributes = reader.attributes();
+ continue;
+ }
+ writer.writeStartElement(reader.name().toString());
+ writer.writeAttributes(reader.attributes());
+ continue;
+
+ case QXmlStreamReader::EndElement:
+ if (reader.name() == QStringLiteral("file")) {
+ if (state != InFile) {
+ fprintf(stderr, "Unexpected end of file tag in line %d\n", int(reader.lineNumber()));
+ return EXIT_FAILURE;
+ }
+ state = InResource;
+ continue;
+ } else if (reader.name() == QStringLiteral("qresource")) {
+ if (state != InResource) {
+ fprintf(stderr, "Unexpected end of qresource tag in line %d\n", int(reader.lineNumber()));
+ return EXIT_FAILURE;
+ }
+ state = InRCC;
+ } else if (reader.name() == QStringLiteral("RCC")) {
+ if (state != InRCC) {
+ fprintf(stderr, "Unexpected end of RCC tag in line %d\n", int(reader.lineNumber()));
+ return EXIT_FAILURE;
+ }
+ state = InitialState;
+ }
+ writer.writeEndElement();
+ continue;
+
+ case QXmlStreamReader::Characters:
+ if (reader.isWhitespace())
+ break;
+ if (state != InFile)
+ return EXIT_FAILURE;
+ currentFileName = reader.text().toString();
+ if (currentFileName.isEmpty())
+ continue;
+
+ if (!currentFileName.endsWith(QStringLiteral(".qml")) && !currentFileName.endsWith(QStringLiteral(".js"))) {
+ writer.writeStartElement(QStringLiteral("file"));
+
+ if (!fileAttributes.hasAttribute(QStringLiteral("alias")))
+ fileAttributes.append(QStringLiteral("alias"), currentFileName);
+
+ currentFileName = inputDirectory.absoluteFilePath(currentFileName);
+ currentFileName = outputDirectory.relativeFilePath(currentFileName);
+
+ remainingFiles << currentFileName;
+
+ writer.writeAttributes(fileAttributes);
+ writer.writeCharacters(currentFileName);
+ writer.writeEndElement();
+ }
+ continue;
+
+ default: break;
+ }
+ }
+
+ if (!remainingFiles.isEmpty()) {
+ QFile outputFile(output);
+ if (!outputFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
+ fprintf(stderr, "Cannot open %s for writing.\n", qPrintable(output));
+ return EXIT_FAILURE;
+ }
+ const QByteArray outputStringUtf8 = outputString.toUtf8();
+ if (outputFile.write(outputStringUtf8) != outputStringUtf8.size())
+ return EXIT_FAILURE;
+
+ outputFile.close();
+ if (outputFile.error() != QFileDevice::NoError)
+ return EXIT_FAILURE;
+
+ // The build system expects this output if we wrote a qrc file and no output
+ // if no files remain.
+ fprintf(stdout, "New resource file written with %d files.\n", remainingFiles.count());
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/tools/qmleasing/qmleasing.pro b/tools/qmleasing/qmleasing.pro
index 534bc9fe98..4267ecc5ad 100644
--- a/tools/qmleasing/qmleasing.pro
+++ b/tools/qmleasing/qmleasing.pro
@@ -17,13 +17,6 @@ FORMS += \
pane.ui \
import.ui
-QMAKE_TARGET_PRODUCT = qmleasing
-QMAKE_TARGET_DESCRIPTION = QML easing curve editor
-
-win32 {
- VERSION = $${QT_VERSION}.0
-} else {
- VERSION = $${QT_VERSION}
-}
+QMAKE_TARGET_DESCRIPTION = QML Easing Curve Editor
load(qt_app)
diff --git a/tools/qmlimportscanner/main.cpp b/tools/qmlimportscanner/main.cpp
index 37d244c5e5..d596613553 100644
--- a/tools/qmlimportscanner/main.cpp
+++ b/tools/qmlimportscanner/main.cpp
@@ -291,7 +291,7 @@ struct ImportCollector : public QQmlJS::Directives
{
QVariantList imports;
- virtual void importFile(const QString &jsfile, const QString &module, int line, int column)
+ void importFile(const QString &jsfile, const QString &module, int line, int column) override
{
QVariantMap entry;
entry[typeLiteral()] = QStringLiteral("javascript");
@@ -303,7 +303,7 @@ struct ImportCollector : public QQmlJS::Directives
Q_UNUSED(column);
}
- virtual void importModule(const QString &uri, const QString &version, const QString &module, int line, int column)
+ void importModule(const QString &uri, const QString &version, const QString &module, int line, int column) override
{
QVariantMap entry;
if (uri.contains(QLatin1Char('/'))) {
diff --git a/tools/qmlimportscanner/qmlimportscanner.pro b/tools/qmlimportscanner/qmlimportscanner.pro
index 363424f948..0b3a03abf3 100644
--- a/tools/qmlimportscanner/qmlimportscanner.pro
+++ b/tools/qmlimportscanner/qmlimportscanner.pro
@@ -5,13 +5,6 @@ DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII
SOURCES += main.cpp
-QMAKE_TARGET_PRODUCT = qmlimportscanner
-QMAKE_TARGET_DESCRIPTION = Tool to scan projects for QML imports
-
-win32 {
- VERSION = $${QT_VERSION}.0
-} else {
- VERSION = $${QT_VERSION}
-}
+QMAKE_TARGET_DESCRIPTION = QML Import Scanner
load(qt_tool)
diff --git a/tools/qmljs/qmljs.cpp b/tools/qmljs/qmljs.cpp
index a1a1200788..ea014f3beb 100644
--- a/tools/qmljs/qmljs.cpp
+++ b/tools/qmljs/qmljs.cpp
@@ -32,24 +32,13 @@
#include "private/qv4errorobject_p.h"
#include "private/qv4globalobject_p.h"
#include "private/qv4codegen_p.h"
-#if QT_CONFIG(qml_interpreter)
-#include "private/qv4isel_moth_p.h"
-#include "private/qv4vme_moth_p.h"
-#endif
#include "private/qv4objectproto_p.h"
-#include "private/qv4isel_p.h"
#include "private/qv4mm_p.h"
#include "private/qv4context_p.h"
#include "private/qv4script_p.h"
#include "private/qv4string_p.h"
#include "private/qqmlbuiltinfunctions_p.h"
-#ifdef V4_ENABLE_JIT
-# include "private/qv4isel_masm_p.h"
-#else
-QT_REQUIRE_CONFIG(qml_interpreter);
-#endif // V4_ENABLE_JIT
-
#include <QtCore/QCoreApplication>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
@@ -69,9 +58,7 @@ static void showException(QV4::ExecutionContext *ctx, const QV4::Value &exceptio
if (!e) {
std::cerr << "Uncaught exception: " << qPrintable(ex->toQString()) << std::endl;
} else {
- QV4::ScopedString m(scope, scope.engine->newString(QStringLiteral("message")));
- QV4::ScopedValue message(scope, e->get(m));
- std::cerr << "Uncaught exception: " << qPrintable(message->toQStringNoThrow()) << std::endl;
+ std::cerr << "Uncaught exception: " << qPrintable(e->toQStringNoThrow()) << std::endl;
}
for (const QV4::StackFrame &frame : trace) {
@@ -89,32 +76,10 @@ int main(int argc, char *argv[])
QStringList args = app.arguments();
args.removeFirst();
- enum {
- use_masm,
- use_moth
- } mode;
-#ifdef V4_ENABLE_JIT
- mode = use_masm;
-#else
- mode = use_moth;
-#endif
-
bool runAsQml = false;
bool cache = false;
if (!args.isEmpty()) {
- if (args.constFirst() == QLatin1String("--jit")) {
- mode = use_masm;
- args.removeFirst();
- }
-
-#if QT_CONFIG(qml_interpreter)
- if (args.constFirst() == QLatin1String("--interpret")) {
- mode = use_moth;
- args.removeFirst();
- }
-#endif
-
if (args.constFirst() == QLatin1String("--qml")) {
runAsQml = true;
args.removeFirst();
@@ -131,77 +96,65 @@ int main(int argc, char *argv[])
}
}
- switch (mode) {
- case use_masm:
- case use_moth: {
- QV4::EvalISelFactory* iSelFactory = 0;
- if (mode == use_moth) {
-#if QT_CONFIG(qml_interpreter)
- iSelFactory = new QV4::Moth::ISelFactory;
-#endif
-#ifdef V4_ENABLE_JIT
- } else {
- iSelFactory = new QV4::JIT::ISelFactory<>;
-#endif // V4_ENABLE_JIT
- }
-
- QV4::ExecutionEngine vm(iSelFactory);
+ QV4::ExecutionEngine vm;
- QV4::Scope scope(&vm);
- QV4::ScopedContext ctx(scope, vm.rootContext());
+ QV4::Scope scope(&vm);
+ QV4::ScopedContext ctx(scope, vm.rootContext());
- QV4::GlobalExtensions::init(vm.globalObject, QJSEngine::ConsoleExtension | QJSEngine::GarbageCollectionExtension);
+ QV4::GlobalExtensions::init(vm.globalObject, QJSEngine::ConsoleExtension | QJSEngine::GarbageCollectionExtension);
- for (const QString &fn : qAsConst(args)) {
- QFile file(fn);
- if (file.open(QFile::ReadOnly)) {
- QScopedPointer<QV4::Script> script;
- if (cache && QFile::exists(fn + QLatin1Char('c'))) {
- QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = iSelFactory->createUnitForLoading();
- QString error;
- if (unit->loadFromDisk(QUrl::fromLocalFile(fn), QFileInfo(fn).lastModified(), iSelFactory, &error)) {
- script.reset(new QV4::Script(&vm, nullptr, unit));
- } else {
- std::cout << "Error loading" << qPrintable(fn) << "from disk cache:" << qPrintable(error) << std::endl;
- }
+ for (const QString &fn : qAsConst(args)) {
+ QFile file(fn);
+ if (file.open(QFile::ReadOnly)) {
+ QScopedPointer<QV4::Script> script;
+ if (cache && QFile::exists(fn + QLatin1Char('c'))) {
+ QQmlRefPointer<QV4::CompiledData::CompilationUnit> unit = QV4::Compiler::Codegen::createUnitForLoading();
+ QString error;
+ if (unit->loadFromDisk(QUrl::fromLocalFile(fn), QFileInfo(fn).lastModified(), &error)) {
+ script.reset(new QV4::Script(&vm, nullptr, unit));
+ } else {
+ std::cout << "Error loading" << qPrintable(fn) << "from disk cache:" << qPrintable(error) << std::endl;
}
- if (!script) {
- const QString code = QString::fromUtf8(file.readAll());
- file.close();
+ }
+ if (!script) {
+ const QString code = QString::fromUtf8(file.readAll());
+ file.close();
- script.reset(new QV4::Script(ctx, code, fn));
- script->parseAsBinding = runAsQml;
- script->parse();
- }
- QV4::ScopedValue result(scope);
- if (!scope.engine->hasException) {
- const auto unit = script->compilationUnit;
- if (cache && unit && !(unit->data->flags & QV4::CompiledData::Unit::StaticData)) {
- if (unit->data->sourceTimeStamp == 0) {
- const_cast<QV4::CompiledData::Unit*>(unit->data)->sourceTimeStamp = QFileInfo(fn).lastModified().toMSecsSinceEpoch();
- }
- QString saveError;
- if (!unit->saveToDisk(QUrl::fromLocalFile(fn), &saveError)) {
- std::cout << "Error saving JS cache file: " << qPrintable(saveError) << std::endl;
- }
+ script.reset(new QV4::Script(ctx, QV4::Compiler::GlobalCode, code, fn));
+ script->parseAsBinding = runAsQml;
+ script->parse();
+ }
+ QV4::ScopedValue result(scope);
+ if (!scope.engine->hasException) {
+ const auto unit = script->compilationUnit;
+ if (cache && unit && !(unit->data->flags & QV4::CompiledData::Unit::StaticData)) {
+ if (unit->data->sourceTimeStamp == 0) {
+ const_cast<QV4::CompiledData::Unit*>(unit->data)->sourceTimeStamp = QFileInfo(fn).lastModified().toMSecsSinceEpoch();
+ }
+ QString saveError;
+ if (!unit->saveToDisk(QUrl::fromLocalFile(fn), &saveError)) {
+ std::cout << "Error saving JS cache file: " << qPrintable(saveError) << std::endl;
}
- result = script->run();
- }
- if (scope.engine->hasException) {
- QV4::StackTrace trace;
- QV4::ScopedValue ex(scope, scope.engine->catchException(&trace));
- showException(ctx, ex, trace);
- return EXIT_FAILURE;
- }
- if (!result->isUndefined()) {
- if (! qgetenv("SHOW_EXIT_VALUE").isEmpty())
- std::cout << "exit value: " << qPrintable(result->toQString()) << std::endl;
}
- } else {
- std::cerr << "Error: cannot open file " << fn.toUtf8().constData() << std::endl;
+// QElapsedTimer t; t.start();
+ result = script->run();
+// std::cout << t.elapsed() << " ms. elapsed" << std::endl;
+ }
+ if (scope.engine->hasException) {
+ QV4::StackTrace trace;
+ QV4::ScopedValue ex(scope, scope.engine->catchException(&trace));
+ showException(ctx, ex, trace);
return EXIT_FAILURE;
}
+ if (!result->isUndefined()) {
+ if (! qgetenv("SHOW_EXIT_VALUE").isEmpty())
+ std::cout << "exit value: " << qPrintable(result->toQString()) << std::endl;
+ }
+ } else {
+ std::cerr << "Error: cannot open file " << fn.toUtf8().constData() << std::endl;
+ return EXIT_FAILURE;
}
- } return EXIT_SUCCESS;
- } // switch (mode)
+ }
+
+ return EXIT_SUCCESS;
}
diff --git a/tools/qmljs/qmljs.pro b/tools/qmljs/qmljs.pro
index 9f82f48980..c2c4cb3cc4 100644
--- a/tools/qmljs/qmljs.pro
+++ b/tools/qmljs/qmljs.pro
@@ -5,13 +5,6 @@ SOURCES = qmljs.cpp
include($$PWD/../../src/3rdparty/masm/masm-defs.pri)
-QMAKE_TARGET_PRODUCT = qmljs
-QMAKE_TARGET_DESCRIPTION = QML Javascript tool
-
-win32 {
- VERSION = $${QT_VERSION}.0
-} else {
- VERSION = $${QT_VERSION}
-}
+QMAKE_TARGET_DESCRIPTION = QML JavaScript Tool
load(qt_tool)
diff --git a/tools/qmllint/qmllint.pro b/tools/qmllint/qmllint.pro
index 27af880c8c..91ab2f8afc 100644
--- a/tools/qmllint/qmllint.pro
+++ b/tools/qmllint/qmllint.pro
@@ -4,13 +4,6 @@ QT = core qmldevtools-private
SOURCES += main.cpp
-QMAKE_TARGET_PRODUCT = qmllint
-QMAKE_TARGET_DESCRIPTION = QML syntax verifier
-
-win32 {
- VERSION = $${QT_VERSION}.0
-} else {
- VERSION = $${QT_VERSION}
-}
+QMAKE_TARGET_DESCRIPTION = QML Syntax Verifier
load(qt_tool)
diff --git a/tools/qmlmin/main.cpp b/tools/qmlmin/main.cpp
index 6877ca7442..5641e6348e 100644
--- a/tools/qmlmin/main.cpp
+++ b/tools/qmlmin/main.cpp
@@ -83,12 +83,12 @@ public:
//
// Handle the .pragma/.import directives
//
- virtual void pragmaLibrary()
+ void pragmaLibrary() override
{
_directives += QLatin1String(".pragma library\n");
}
- virtual void importFile(const QString &jsfile, const QString &module, int line, int column)
+ void importFile(const QString &jsfile, const QString &module, int line, int column) override
{
_directives += QLatin1String(".import");
_directives += QLatin1Char('"');
@@ -101,7 +101,7 @@ public:
Q_UNUSED(column);
}
- virtual void importModule(const QString &uri, const QString &version, const QString &module, int line, int column)
+ void importModule(const QString &uri, const QString &version, const QString &module, int line, int column) override
{
_directives += QLatin1String(".import ");
_directives += uri;
@@ -201,7 +201,7 @@ public:
protected:
void append(const QString &s);
- bool parse(int startToken);
+ bool parse(int startToken) override;
void escape(const QChar &ch, QString *out);
};
@@ -409,7 +409,7 @@ public:
QStringList tokenStream() const;
protected:
- virtual bool parse(int startToken);
+ bool parse(int startToken) override;
};
Tokenize::Tokenize()
diff --git a/tools/qmlmin/qmlmin.pro b/tools/qmlmin/qmlmin.pro
index f5248e1b69..32d9e3343b 100644
--- a/tools/qmlmin/qmlmin.pro
+++ b/tools/qmlmin/qmlmin.pro
@@ -2,13 +2,6 @@ option(host_build)
QT = core qmldevtools-private
SOURCES += main.cpp
-QMAKE_TARGET_PRODUCT = qmlmin
-QMAKE_TARGET_DESCRIPTION = QML/JS minifier
-
-win32 {
- VERSION = $${QT_VERSION}.0
-} else {
- VERSION = $${QT_VERSION}
-}
+QMAKE_TARGET_DESCRIPTION = QML/JS Minifier
load(qt_tool)
diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp
index 42da681e82..422e37fd89 100644
--- a/tools/qmlplugindump/main.cpp
+++ b/tools/qmlplugindump/main.cpp
@@ -1009,6 +1009,7 @@ int main(int argc, char *argv[])
? new QApplication(argc, argv)
: new QGuiApplication(argc, argv));
#else
+ Q_UNUSED(useQApplication);
QScopedPointer<QCoreApplication> app(new QGuiApplication(argc, argv));
#endif // QT_WIDGETS_LIB
diff --git a/tools/qmlplugindump/qmlplugindump.pro b/tools/qmlplugindump/qmlplugindump.pro
index 2749ec943f..62b08e9334 100644
--- a/tools/qmlplugindump/qmlplugindump.pro
+++ b/tools/qmlplugindump/qmlplugindump.pro
@@ -22,13 +22,6 @@ macx {
CONFIG -= app_bundle
}
-QMAKE_TARGET_PRODUCT = qmlplugindump
-QMAKE_TARGET_DESCRIPTION = QML plugin dump tool
-
-win32 {
- VERSION = $${QT_VERSION}.0
-} else {
- VERSION = $${QT_VERSION}
-}
+QMAKE_TARGET_DESCRIPTION = QML Plugin Metadata Dumper
load(qt_tool)
diff --git a/tools/qmlprofiler/qmlprofiler.pro b/tools/qmlprofiler/qmlprofiler.pro
index b5bb1dcc46..a2522e9267 100644
--- a/tools/qmlprofiler/qmlprofiler.pro
+++ b/tools/qmlprofiler/qmlprofiler.pro
@@ -14,13 +14,6 @@ HEADERS += \
qmlprofilerdata.h \
qmlprofilerclient.h
-QMAKE_TARGET_PRODUCT = qmlprofiler
-QMAKE_TARGET_DESCRIPTION = QML profiler
-
-win32 {
- VERSION = $${QT_VERSION}.0
-} else {
- VERSION = $${QT_VERSION}
-}
+QMAKE_TARGET_DESCRIPTION = QML Profiler
load(qt_tool)
diff --git a/tools/qmlprofiler/qmlprofilerapplication.cpp b/tools/qmlprofiler/qmlprofilerapplication.cpp
index 33be8722c0..67e8769ac1 100644
--- a/tools/qmlprofiler/qmlprofilerapplication.cpp
+++ b/tools/qmlprofiler/qmlprofilerapplication.cpp
@@ -83,26 +83,29 @@ QmlProfilerApplication::QmlProfilerApplication(int &argc, char **argv) :
m_verbose(false),
m_recording(true),
m_interactive(false),
- m_qmlProfilerClient(&m_connection, &m_profilerData),
m_connectionAttempts(0)
{
+ m_connection.reset(new QQmlDebugConnection);
+ m_profilerData.reset(new QmlProfilerData);
+ m_qmlProfilerClient.reset(new QmlProfilerClient(m_connection.data(), m_profilerData.data()));
m_connectTimer.setInterval(1000);
connect(&m_connectTimer, &QTimer::timeout, this, &QmlProfilerApplication::tryToConnect);
- connect(&m_connection, &QQmlDebugConnection::connected,
+ connect(m_connection.data(), &QQmlDebugConnection::connected,
this, &QmlProfilerApplication::connected);
- connect(&m_connection, &QQmlDebugConnection::disconnected,
+ connect(m_connection.data(), &QQmlDebugConnection::disconnected,
this, &QmlProfilerApplication::disconnected);
- connect(&m_qmlProfilerClient, &QmlProfilerClient::enabledChanged,
+ connect(m_qmlProfilerClient.data(), &QmlProfilerClient::enabledChanged,
this, &QmlProfilerApplication::traceClientEnabledChanged);
- connect(&m_qmlProfilerClient, &QmlProfilerClient::recordingStarted,
+ connect(m_qmlProfilerClient.data(), &QmlProfilerClient::traceStarted,
this, &QmlProfilerApplication::notifyTraceStarted);
- connect(&m_qmlProfilerClient, &QmlProfilerClient::error,
+ connect(m_qmlProfilerClient.data(), &QmlProfilerClient::error,
this, &QmlProfilerApplication::logError);
- connect(&m_profilerData, &QmlProfilerData::error, this, &QmlProfilerApplication::logError);
- connect(&m_profilerData, &QmlProfilerData::dataReady,
+ connect(m_profilerData.data(), &QmlProfilerData::error,
+ this, &QmlProfilerApplication::logError);
+ connect(m_profilerData.data(), &QmlProfilerData::dataReady,
this, &QmlProfilerApplication::traceFinished);
}
@@ -241,7 +244,7 @@ void QmlProfilerApplication::parseArguments()
if (features == 0)
parser.showHelp(4);
- m_qmlProfilerClient.setFeatures(features);
+ m_qmlProfilerClient->setRequestedFeatures(features);
if (parser.isSet(verbose))
m_verbose = true;
@@ -297,10 +300,10 @@ void QmlProfilerApplication::flush()
{
if (m_recording) {
m_pendingRequest = REQUEST_FLUSH;
- m_qmlProfilerClient.sendRecordingStatus(false);
+ m_qmlProfilerClient->sendRecordingStatus(false);
} else {
- if (m_profilerData.save(m_interactiveOutputFile)) {
- m_profilerData.clear();
+ if (m_profilerData->save(m_interactiveOutputFile)) {
+ m_profilerData->clear();
if (!m_interactiveOutputFile.isEmpty())
prompt(tr("Data written to %1.").arg(m_interactiveOutputFile));
else
@@ -315,7 +318,7 @@ void QmlProfilerApplication::flush()
void QmlProfilerApplication::output()
{
- if (m_profilerData.save(m_interactiveOutputFile)) {
+ if (m_profilerData->save(m_interactiveOutputFile)) {
if (!m_interactiveOutputFile.isEmpty())
prompt(tr("Data written to %1.").arg(m_interactiveOutputFile));
else
@@ -387,12 +390,12 @@ void QmlProfilerApplication::userCommand(const QString &command)
if (cmd == Constants::CMD_RECORD || cmd == Constants::CMD_RECORD2) {
m_pendingRequest = REQUEST_TOGGLE_RECORDING;
- m_qmlProfilerClient.sendRecordingStatus(!m_recording);
+ m_qmlProfilerClient->sendRecordingStatus(!m_recording);
} else if (cmd == Constants::CMD_QUIT || cmd == Constants::CMD_QUIT2) {
m_pendingRequest = REQUEST_QUIT;
if (m_recording) {
prompt(tr("The application is still generating data. Really quit (y/n)?"));
- } else if (!m_profilerData.isEmpty()) {
+ } else if (!m_profilerData->isEmpty()) {
prompt(tr("There is still trace data in memory. Really quit (y/n)?"));
} else {
quit();
@@ -400,7 +403,7 @@ void QmlProfilerApplication::userCommand(const QString &command)
} else if (cmd == Constants::CMD_OUTPUT || cmd == Constants::CMD_OUTPUT2) {
if (m_recording) {
prompt(tr("Cannot output while recording data."));
- } else if (m_profilerData.isEmpty()) {
+ } else if (m_profilerData->isEmpty()) {
prompt(tr("No data was recorded so far."));
} else {
m_interactiveOutputFile = args.length() > 0 ? args.at(0).toString() : m_outputFile;
@@ -410,14 +413,14 @@ void QmlProfilerApplication::userCommand(const QString &command)
} else if (cmd == Constants::CMD_CLEAR || cmd == Constants::CMD_CLEAR2) {
if (m_recording) {
prompt(tr("Cannot clear data while recording."));
- } else if (m_profilerData.isEmpty()) {
+ } else if (m_profilerData->isEmpty()) {
prompt(tr("No data was recorded so far."));
} else {
- m_profilerData.clear();
+ m_profilerData->clear();
prompt(tr("Trace data cleared."));
}
} else if (cmd == Constants::CMD_FLUSH || cmd == Constants::CMD_FLUSH2) {
- if (!m_recording && m_profilerData.isEmpty()) {
+ if (!m_recording && m_profilerData->isEmpty()) {
prompt(tr("No data was recorded so far."));
} else {
m_interactiveOutputFile = args.length() > 0 ? args.at(0).toString() : m_outputFile;
@@ -445,9 +448,9 @@ void QmlProfilerApplication::notifyTraceStarted()
void QmlProfilerApplication::outputData()
{
- if (!m_profilerData.isEmpty()) {
- m_profilerData.save(m_outputFile);
- m_profilerData.clear();
+ if (!m_profilerData->isEmpty()) {
+ m_profilerData->save(m_outputFile);
+ m_profilerData->clear();
}
}
@@ -456,7 +459,7 @@ void QmlProfilerApplication::run()
if (m_runMode == LaunchMode) {
if (!m_socketFile.isEmpty()) {
logStatus(QString::fromLatin1("Listening on %1 ...").arg(m_socketFile));
- m_connection.startLocalServer(m_socketFile);
+ m_connection->startLocalServer(m_socketFile);
}
m_process = new QProcess(this);
QStringList arguments;
@@ -483,7 +486,7 @@ void QmlProfilerApplication::run()
void QmlProfilerApplication::tryToConnect()
{
- Q_ASSERT(!m_connection.isConnected());
+ Q_ASSERT(!m_connection->isConnected());
++ m_connectionAttempts;
if (!m_verbose && !(m_connectionAttempts % 5)) {// print every 5 seconds
@@ -499,7 +502,7 @@ void QmlProfilerApplication::tryToConnect()
if (m_socketFile.isEmpty()) {
logStatus(QString::fromLatin1("Connecting to %1:%2 ...").arg(m_hostName).arg(m_port));
- m_connection.connectToHost(m_hostName, m_port);
+ m_connection->connectToHost(m_hostName, m_port);
}
}
@@ -526,7 +529,7 @@ void QmlProfilerApplication::disconnected()
if (!m_interactive )
exit(exitCode);
else
- m_qmlProfilerClient.clearPendingData();
+ m_qmlProfilerClient->clearAll();
}
}
@@ -556,7 +559,7 @@ void QmlProfilerApplication::processFinished()
if (!m_interactive)
exit(exitCode);
else
- m_qmlProfilerClient.clearPendingData();
+ m_qmlProfilerClient->clearAll();
}
void QmlProfilerApplication::traceClientEnabledChanged(bool enabled)
@@ -565,7 +568,7 @@ void QmlProfilerApplication::traceClientEnabledChanged(bool enabled)
logStatus("Trace client is attached.");
// blocked server is waiting for recording message from both clients
// once the last one is connected, both messages should be sent
- m_qmlProfilerClient.sendRecordingStatus(m_recording);
+ m_qmlProfilerClient->setRecording(m_recording);
}
}
@@ -582,7 +585,7 @@ void QmlProfilerApplication::traceFinished()
prompt(tr("Application stopped recording."), false);
}
- m_qmlProfilerClient.clearPendingData();
+ m_qmlProfilerClient->clearEvents();
}
void QmlProfilerApplication::prompt(const QString &line, bool ready)
diff --git a/tools/qmlprofiler/qmlprofilerapplication.h b/tools/qmlprofiler/qmlprofilerapplication.h
index 4946622902..2d00e2b7c5 100644
--- a/tools/qmlprofiler/qmlprofilerapplication.h
+++ b/tools/qmlprofiler/qmlprofilerapplication.h
@@ -106,9 +106,9 @@ private:
bool m_recording;
bool m_interactive;
- QQmlDebugConnection m_connection;
- QmlProfilerClient m_qmlProfilerClient;
- QmlProfilerData m_profilerData;
+ QScopedPointer<QQmlDebugConnection> m_connection;
+ QScopedPointer<QmlProfilerClient> m_qmlProfilerClient;
+ QScopedPointer<QmlProfilerData> m_profilerData;
QTimer m_connectTimer;
uint m_connectionAttempts;
};
diff --git a/tools/qmlprofiler/qmlprofilerclient.cpp b/tools/qmlprofiler/qmlprofilerclient.cpp
index 0c031db914..b69c7e73e1 100644
--- a/tools/qmlprofiler/qmlprofilerclient.cpp
+++ b/tools/qmlprofiler/qmlprofilerclient.cpp
@@ -43,36 +43,26 @@ public:
QmlProfilerClientPrivate(QQmlDebugConnection *connection, QmlProfilerData *data);
QmlProfilerData *data;
-
- qint64 inProgressRanges;
- QStack<qint64> rangeStartTimes[QQmlProfilerDefinitions::MaximumRangeType];
- QStack<QStringList> rangeDatas[QQmlProfilerDefinitions::MaximumRangeType];
- QStack<QQmlEventLocation> rangeLocations[QQmlProfilerDefinitions::MaximumRangeType];
- int rangeCount[QQmlProfilerDefinitions::MaximumRangeType];
-
bool enabled;
};
QmlProfilerClientPrivate::QmlProfilerClientPrivate(QQmlDebugConnection *connection,
QmlProfilerData *data) :
- QQmlProfilerClientPrivate(connection), data(data), inProgressRanges(0), enabled(false)
+ QQmlProfilerClientPrivate(connection, data), data(data), enabled(false)
{
- ::memset(rangeCount, 0, QQmlProfilerDefinitions::MaximumRangeType * sizeof(int));
}
QmlProfilerClient::QmlProfilerClient(QQmlDebugConnection *connection, QmlProfilerData *data) :
QQmlProfilerClient(*(new QmlProfilerClientPrivate(connection, data)))
{
-}
-
-void QmlProfilerClient::clearPendingData()
-{
Q_D(QmlProfilerClient);
- for (int i = 0; i < QQmlProfilerDefinitions::MaximumRangeType; ++i) {
- d->rangeCount[i] = 0;
- d->rangeDatas[i].clear();
- d->rangeLocations[i].clear();
- }
+ setRequestedFeatures(std::numeric_limits<quint64>::max());
+ connect(this, &QQmlProfilerClient::traceStarted,
+ d->data, &QmlProfilerData::setTraceStartTime);
+ connect(this, &QQmlProfilerClient::traceFinished,
+ d->data, &QmlProfilerData::setTraceEndTime);
+ connect(this, &QQmlProfilerClient::complete,
+ d->data, &QmlProfilerData::complete);
}
void QmlProfilerClient::stateChanged(State state)
@@ -84,119 +74,4 @@ void QmlProfilerClient::stateChanged(State state)
}
}
-void QmlProfilerClient::traceStarted(qint64 time, int engineId)
-{
- Q_UNUSED(engineId);
- Q_D(QmlProfilerClient);
- d->data->setTraceStartTime(time);
- emit recordingStarted();
-}
-
-void QmlProfilerClient::traceFinished(qint64 time, int engineId)
-{
- Q_UNUSED(engineId);
- Q_D(QmlProfilerClient);
- d->data->setTraceEndTime(time);
-}
-
-void QmlProfilerClient::rangeStart(QQmlProfilerDefinitions::RangeType type, qint64 startTime)
-{
- Q_D(QmlProfilerClient);
- d->rangeStartTimes[type].push(startTime);
- d->inProgressRanges |= (static_cast<qint64>(1) << type);
- ++d->rangeCount[type];
-}
-
-void QmlProfilerClient::rangeData(QQmlProfilerDefinitions::RangeType type, qint64 time,
- const QString &data)
-{
- Q_UNUSED(time);
- Q_D(QmlProfilerClient);
- int count = d->rangeCount[type];
- if (count > 0) {
- while (d->rangeDatas[type].count() < count)
- d->rangeDatas[type].push(QStringList());
- d->rangeDatas[type][count - 1] << data;
- }
-}
-
-void QmlProfilerClient::rangeLocation(QQmlProfilerDefinitions::RangeType type, qint64 time,
- const QQmlEventLocation &location)
-{
- Q_UNUSED(time);
- Q_D(QmlProfilerClient);
- if (d->rangeCount[type] > 0)
- d->rangeLocations[type].push(location);
-}
-
-void QmlProfilerClient::rangeEnd(QQmlProfilerDefinitions::RangeType type, qint64 endTime)
-{
- Q_D(QmlProfilerClient);
-
- if (d->rangeCount[type] == 0) {
- emit error(tr("Spurious range end detected."));
- return;
- }
-
- --d->rangeCount[type];
- if (d->inProgressRanges & (static_cast<qint64>(1) << type))
- d->inProgressRanges &= ~(static_cast<qint64>(1) << type);
- QStringList data = d->rangeDatas[type].count() ? d->rangeDatas[type].pop() : QStringList();
- QQmlEventLocation location = d->rangeLocations[type].count() ? d->rangeLocations[type].pop() :
- QQmlEventLocation();
- qint64 startTime = d->rangeStartTimes[type].pop();
-
- if (d->rangeCount[type] == 0 && d->rangeDatas[type].count() + d->rangeStartTimes[type].count()
- + d->rangeLocations[type].count() != 0) {
- emit error(tr("Incorrectly nested range data"));
- return;
- }
-
- d->data->addQmlEvent(type, QQmlProfilerDefinitions::QmlBinding, startTime, endTime - startTime,
- data, location);
-}
-
-void QmlProfilerClient::animationFrame(qint64 time, int frameRate, int animationCount, int threadId)
-{
- Q_D(QmlProfilerClient);
- d->data->addFrameEvent(time, frameRate, animationCount, threadId);
-}
-
-void QmlProfilerClient::sceneGraphEvent(QQmlProfilerDefinitions::SceneGraphFrameType type,
- qint64 time, qint64 numericData1, qint64 numericData2,
- qint64 numericData3, qint64 numericData4,
- qint64 numericData5)
-{
- Q_D(QmlProfilerClient);
- d->data->addSceneGraphFrameEvent(type, time, numericData1, numericData2, numericData3,
- numericData4, numericData5);
-}
-
-void QmlProfilerClient::pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type, qint64 time,
- const QString &url, int numericData1, int numericData2)
-{
- Q_D(QmlProfilerClient);
- d->data->addPixmapCacheEvent(type, time, url, numericData1, numericData2);
-}
-
-void QmlProfilerClient::memoryAllocation(QQmlProfilerDefinitions::MemoryType type, qint64 time,
- qint64 amount)
-{
- Q_D(QmlProfilerClient);
- d->data->addMemoryEvent(type, time, amount);
-}
-
-void QmlProfilerClient::inputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time,
- int a, int b)
-{
- Q_D(QmlProfilerClient);
- d->data->addInputEvent(type, time, a, b);
-}
-
-void QmlProfilerClient::complete()
-{
- Q_D(QmlProfilerClient);
- d->data->complete();
-}
-
#include "moc_qmlprofilerclient.cpp"
diff --git a/tools/qmlprofiler/qmlprofilerclient.h b/tools/qmlprofiler/qmlprofilerclient.h
index a04a412bb0..b9d8ce241f 100644
--- a/tools/qmlprofiler/qmlprofilerclient.h
+++ b/tools/qmlprofiler/qmlprofilerclient.h
@@ -29,9 +29,9 @@
#ifndef QMLPROFILERCLIENT_H
#define QMLPROFILERCLIENT_H
-#include <private/qqmleventlocation_p.h>
#include <private/qqmlprofilerclient_p.h>
#include <private/qqmlprofilerdefinitions_p.h>
+#include <private/qqmlprofilereventlocation_p.h>
class QmlProfilerData;
class QmlProfilerClientPrivate;
@@ -42,32 +42,13 @@ class QmlProfilerClient : public QQmlProfilerClient
public:
QmlProfilerClient(QQmlDebugConnection *connection, QmlProfilerData *data);
- void clearPendingData();
signals:
void enabledChanged(bool enabled);
- void recordingStarted();
void error(const QString &error);
private:
void stateChanged(State state) override;
-
- void traceStarted(qint64 time, int engineId) override;
- void traceFinished(qint64 time, int engineId) override;
- void rangeStart(QQmlProfilerDefinitions::RangeType type, qint64 startTime) override;
- void rangeData(QQmlProfilerDefinitions::RangeType type, qint64 time, const QString &data) override;
- void rangeLocation(QQmlProfilerDefinitions::RangeType type, qint64 time,
- const QQmlEventLocation &location) override;
- void rangeEnd(QQmlProfilerDefinitions::RangeType type, qint64 endTime) override;
- void animationFrame(qint64 time, int frameRate, int animationCount, int threadId) override;
- void sceneGraphEvent(QQmlProfilerDefinitions::SceneGraphFrameType type, qint64 time,
- qint64 numericData1, qint64 numericData2, qint64 numericData3,
- qint64 numericData4, qint64 numericData5) override;
- void pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type, qint64 time,
- const QString &url, int numericData1, int numericData2) override;
- void memoryAllocation(QQmlProfilerDefinitions::MemoryType type, qint64 time, qint64 amount) override;
- void inputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time, int a, int b) override;
- void complete() override;
};
#endif // QMLPROFILERCLIENT_H
diff --git a/tools/qmlprofiler/qmlprofilerdata.cpp b/tools/qmlprofiler/qmlprofilerdata.cpp
index 0044af0b52..32e03298da 100644
--- a/tools/qmlprofiler/qmlprofilerdata.cpp
+++ b/tools/qmlprofiler/qmlprofilerdata.cpp
@@ -33,7 +33,9 @@
#include <QHash>
#include <QFile>
#include <QXmlStreamReader>
-#include <QRegExp>
+#include <QRegularExpression>
+#include <QQueue>
+#include <QStack>
#include <limits>
@@ -60,72 +62,13 @@ static const char *MESSAGE_STRINGS[] = {
"Complete",
"PixmapCache",
"SceneGraph",
- "MemoryAllocation"
+ "MemoryAllocation",
+ "DebugMessage"
};
Q_STATIC_ASSERT(sizeof(MESSAGE_STRINGS) ==
QQmlProfilerDefinitions::MaximumMessage * sizeof(const char *));
-struct QmlRangeEventData {
- QmlRangeEventData() {} // never called
- QmlRangeEventData(const QString &_displayName, int _detailType, const QString &_eventHashStr,
- const QQmlEventLocation &_location, const QString &_details,
- QQmlProfilerDefinitions::Message _message,
- QQmlProfilerDefinitions::RangeType _rangeType)
- : displayName(_displayName), eventHashStr(_eventHashStr), location(_location),
- details(_details), message(_message), rangeType(_rangeType), detailType(_detailType) {}
- QString displayName;
- QString eventHashStr;
- QQmlEventLocation location;
- QString details;
- QQmlProfilerDefinitions::Message message;
- QQmlProfilerDefinitions::RangeType rangeType;
- int detailType; // can be BindingType, PixmapCacheEventType or SceneGraphFrameType
-};
-
-struct QmlRangeEventStartInstance {
- QmlRangeEventStartInstance() {} // never called
- QmlRangeEventStartInstance(qint64 _startTime, qint64 _duration, int _frameRate,
- int _animationCount, int _threadId, QmlRangeEventData *_data)
- : startTime(_startTime), duration(_duration), frameRate(_frameRate),
- animationCount(_animationCount), threadId(_threadId), numericData4(-1), numericData5(-1),
- data(_data)
- { }
-
- QmlRangeEventStartInstance(qint64 _startTime, qint64 _numericData1, qint64 _numericData2,
- qint64 _numericData3, qint64 _numericData4, qint64 _numericData5,
- QmlRangeEventData *_data)
- : startTime(_startTime), duration(-1), numericData1(_numericData1),
- numericData2(_numericData2), numericData3(_numericData3), numericData4(_numericData4),
- numericData5(_numericData5), data(_data)
- { }
- qint64 startTime;
- qint64 duration;
- union {
- int frameRate;
- int inputType;
- qint64 numericData1;
- };
- union {
- int animationCount;
- int inputA;
- qint64 numericData2;
- };
- union {
- int threadId;
- int inputB;
- qint64 numericData3;
- };
- qint64 numericData4;
- qint64 numericData5;
- QmlRangeEventData *data;
-};
-
-QT_BEGIN_NAMESPACE
-Q_DECLARE_TYPEINFO(QmlRangeEventData, Q_MOVABLE_TYPE);
-Q_DECLARE_TYPEINFO(QmlRangeEventStartInstance, Q_MOVABLE_TYPE);
-QT_END_NAMESPACE
-
/////////////////////////////////////////////////////////////////
class QmlProfilerDataPrivate
{
@@ -133,8 +76,8 @@ public:
QmlProfilerDataPrivate(QmlProfilerData *qq){ Q_UNUSED(qq); }
// data storage
- QHash<QString, QmlRangeEventData *> eventDescriptions;
- QVector<QmlRangeEventStartInstance> startInstanceList;
+ QVector<QQmlProfilerEventType> eventTypes;
+ QVector<QQmlProfilerEvent> events;
qint64 traceStartTime;
qint64 traceEndTime;
@@ -146,7 +89,7 @@ public:
/////////////////////////////////////////////////////////////////
QmlProfilerData::QmlProfilerData(QObject *parent) :
- QObject(parent),d(new QmlProfilerDataPrivate(this))
+ QQmlProfilerEventReceiver(parent), d(new QmlProfilerDataPrivate(this))
{
d->state = Empty;
clear();
@@ -160,9 +103,8 @@ QmlProfilerData::~QmlProfilerData()
void QmlProfilerData::clear()
{
- qDeleteAll(d->eventDescriptions);
- d->eventDescriptions.clear();
- d->startInstanceList.clear();
+ d->eventTypes.clear();
+ d->events.clear();
d->traceEndTime = std::numeric_limits<qint64>::min();
d->traceStartTime = std::numeric_limits<qint64>::max();
@@ -171,15 +113,6 @@ void QmlProfilerData::clear()
setState(Empty);
}
-QString QmlProfilerData::getHashStringForQmlEvent(const QQmlEventLocation &location, int eventType)
-{
- return QString(QStringLiteral("%1:%2:%3:%4")).arg(
- location.filename,
- QString::number(location.line),
- QString::number(location.column),
- QString::number(eventType));
-}
-
QString QmlProfilerData::qmlRangeTypeAsString(QQmlProfilerDefinitions::RangeType type)
{
if (type * sizeof(char *) < sizeof(RANGE_TYPE_STRINGS))
@@ -218,246 +151,155 @@ qint64 QmlProfilerData::traceEndTime() const
return d->traceEndTime;
}
-void QmlProfilerData::addQmlEvent(QQmlProfilerDefinitions::RangeType type,
- QQmlProfilerDefinitions::BindingType bindingType,
- qint64 startTime,
- qint64 duration,
- const QStringList &data,
- const QQmlEventLocation &location)
+void QmlProfilerData::addEvent(const QQmlProfilerEvent &event)
{
setState(AcquiringData);
+ d->events.append(event);
+}
+
+void QmlProfilerData::addEventType(const QQmlProfilerEventType &type)
+{
+ QQmlProfilerEventType newType = type;
QString details;
// generate details string
- if (!data.isEmpty()) {
- details = data.join(QLatin1Char(' ')).replace(
- QLatin1Char('\n'), QLatin1Char(' ')).simplified();
- QRegExp rewrite(QStringLiteral("\\(function \\$(\\w+)\\(\\) \\{ (return |)(.+) \\}\\)"));
- bool match = rewrite.exactMatch(details);
- if (match) {
- details = rewrite.cap(1) +QLatin1String(": ") + rewrite.cap(3);
+ if (!type.data().isEmpty()) {
+ details = type.data().simplified();
+ QRegularExpression rewrite(QStringLiteral("^\\(function \\$(\\w+)\\(\\) \\{ (return |)(.+) \\}\\)$"));
+ QRegularExpressionMatch match = rewrite.match(details);
+ if (match.hasMatch()) {
+ details = match.captured(1) +QLatin1String(": ") + match.captured(3);
}
if (details.startsWith(QLatin1String("file://")))
details = details.mid(details.lastIndexOf(QLatin1Char('/')) + 1);
}
- QQmlEventLocation eventLocation = location;
- QString displayName, eventHashStr;
- // generate hash
- if (eventLocation.filename.isEmpty()) {
- displayName = tr("<bytecode>");
- eventHashStr = getHashStringForQmlEvent(eventLocation, type);
- } else {
- const QString filePath = QUrl(eventLocation.filename).path();
- displayName = filePath.midRef(
- filePath.lastIndexOf(QLatin1Char('/')) + 1) +
- QLatin1Char(':') + QString::number(eventLocation.line);
- eventHashStr = getHashStringForQmlEvent(eventLocation, type);
- }
-
- QmlRangeEventData *newEvent;
- if (d->eventDescriptions.contains(eventHashStr)) {
- newEvent = d->eventDescriptions[eventHashStr];
- } else {
- newEvent = new QmlRangeEventData(displayName, bindingType, eventHashStr, location, details,
- QQmlProfilerDefinitions::MaximumMessage, type);
- d->eventDescriptions.insert(eventHashStr, newEvent);
- }
-
- QmlRangeEventStartInstance rangeEventStartInstance(startTime, duration, -1, -1, -1, newEvent);
-
- d->startInstanceList.append(rangeEventStartInstance);
-}
-
-void QmlProfilerData::addFrameEvent(qint64 time, int framerate, int animationcount, int threadId)
-{
- setState(AcquiringData);
-
- QString details = tr("Animation Timer Update");
- QString displayName = tr("<Animation Update>");
- QString eventHashStr = displayName;
-
- QmlRangeEventData *newEvent;
- if (d->eventDescriptions.contains(eventHashStr)) {
- newEvent = d->eventDescriptions[eventHashStr];
- } else {
- newEvent = new QmlRangeEventData(displayName, QQmlProfilerDefinitions::AnimationFrame,
- eventHashStr,
- QQmlEventLocation(), details,
- QQmlProfilerDefinitions::Event,
- QQmlProfilerDefinitions::MaximumRangeType);
- d->eventDescriptions.insert(eventHashStr, newEvent);
- }
-
- QmlRangeEventStartInstance rangeEventStartInstance(time, -1, framerate, animationcount,
- threadId, newEvent);
-
- d->startInstanceList.append(rangeEventStartInstance);
-}
-
-void QmlProfilerData::addSceneGraphFrameEvent(QQmlProfilerDefinitions::SceneGraphFrameType type,
- qint64 time, qint64 numericData1, qint64 numericData2,
- qint64 numericData3, qint64 numericData4,
- qint64 numericData5)
-{
- setState(AcquiringData);
-
- QString eventHashStr = QString::fromLatin1("SceneGraph:%1").arg(type);
- QmlRangeEventData *newEvent;
- if (d->eventDescriptions.contains(eventHashStr)) {
- newEvent = d->eventDescriptions[eventHashStr];
- } else {
- newEvent = new QmlRangeEventData(QStringLiteral("<SceneGraph>"), type, eventHashStr,
- QQmlEventLocation(), QString(),
- QQmlProfilerDefinitions::SceneGraphFrame,
- QQmlProfilerDefinitions::MaximumRangeType);
- d->eventDescriptions.insert(eventHashStr, newEvent);
- }
+ newType.setData(details);
- QmlRangeEventStartInstance rangeEventStartInstance(time, numericData1, numericData2,
- numericData3, numericData4, numericData5,
- newEvent);
- d->startInstanceList.append(rangeEventStartInstance);
-}
-
-void QmlProfilerData::addPixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type,
- qint64 time, const QString &location,
- int numericData1, int numericData2)
-{
- setState(AcquiringData);
-
- QString filePath = QUrl(location).path();
-
- const QString eventHashStr = filePath.midRef(filePath.lastIndexOf(QLatin1Char('/')) + 1)
- + QLatin1Char(':') + QString::number(type);
- QmlRangeEventData *newEvent;
- if (d->eventDescriptions.contains(eventHashStr)) {
- newEvent = d->eventDescriptions[eventHashStr];
- } else {
- newEvent = new QmlRangeEventData(eventHashStr, type, eventHashStr,
- QQmlEventLocation(location, -1, -1), QString(),
- QQmlProfilerDefinitions::PixmapCacheEvent,
- QQmlProfilerDefinitions::MaximumRangeType);
- d->eventDescriptions.insert(eventHashStr, newEvent);
+ QString displayName;
+ switch (type.message()) {
+ case QQmlProfilerDefinitions::Event: {
+ switch (type.detailType()) {
+ case QQmlProfilerDefinitions::Mouse:
+ case QQmlProfilerDefinitions::Key:
+ displayName = QString::fromLatin1("Input:%1").arg(type.detailType());
+ break;
+ case QQmlProfilerDefinitions::AnimationFrame:
+ displayName = QString::fromLatin1("AnimationFrame");
+ break;
+ default:
+ displayName = QString::fromLatin1("Unknown");
+ }
+ break;
}
-
- QmlRangeEventStartInstance rangeEventStartInstance(time, numericData1, numericData2, 0, 0, 0,
- newEvent);
- d->startInstanceList.append(rangeEventStartInstance);
-}
-
-void QmlProfilerData::addMemoryEvent(QQmlProfilerDefinitions::MemoryType type, qint64 time,
- qint64 size)
-{
- setState(AcquiringData);
- QString eventHashStr = QString::fromLatin1("MemoryAllocation:%1").arg(type);
- QmlRangeEventData *newEvent;
- if (d->eventDescriptions.contains(eventHashStr)) {
- newEvent = d->eventDescriptions[eventHashStr];
- } else {
- newEvent = new QmlRangeEventData(eventHashStr, type, eventHashStr, QQmlEventLocation(),
- QString(), QQmlProfilerDefinitions::MemoryAllocation,
- QQmlProfilerDefinitions::MaximumRangeType);
- d->eventDescriptions.insert(eventHashStr, newEvent);
+ case QQmlProfilerDefinitions::RangeStart:
+ case QQmlProfilerDefinitions::RangeData:
+ case QQmlProfilerDefinitions::RangeLocation:
+ case QQmlProfilerDefinitions::RangeEnd:
+ case QQmlProfilerDefinitions::Complete:
+ Q_UNREACHABLE();
+ break;
+ case QQmlProfilerDefinitions::PixmapCacheEvent: {
+ const QString filePath = QUrl(type.location().filename()).path();
+ displayName = filePath.midRef(filePath.lastIndexOf(QLatin1Char('/')) + 1)
+ + QLatin1Char(':') + QString::number(type.detailType());
+ break;
}
- QmlRangeEventStartInstance rangeEventStartInstance(time, size, 0, 0, 0, 0, newEvent);
- d->startInstanceList.append(rangeEventStartInstance);
-}
-
-void QmlProfilerData::addInputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time,
- int a, int b)
-{
- setState(AcquiringData);
-
- QQmlProfilerDefinitions::EventType eventType;
- switch (type) {
- case QQmlProfilerDefinitions::InputKeyPress:
- case QQmlProfilerDefinitions::InputKeyRelease:
- case QQmlProfilerDefinitions::InputKeyUnknown:
- eventType = QQmlProfilerDefinitions::Key;
+ case QQmlProfilerDefinitions::SceneGraphFrame:
+ displayName = QString::fromLatin1("SceneGraph:%1").arg(type.detailType());
break;
- default:
- eventType = QQmlProfilerDefinitions::Mouse;
+ case QQmlProfilerDefinitions::MemoryAllocation:
+ displayName = QString::fromLatin1("MemoryAllocation:%1").arg(type.detailType());
+ break;
+ case QQmlProfilerDefinitions::DebugMessage:
+ displayName = QString::fromLatin1("DebugMessage:%1").arg(type.detailType());
+ break;
+ case QQmlProfilerDefinitions::MaximumMessage: {
+ const QQmlProfilerEventLocation eventLocation = type.location();
+ // generate hash
+ if (eventLocation.filename().isEmpty()) {
+ displayName = QString::fromLatin1("Unknown");
+ } else {
+ const QString filePath = QUrl(eventLocation.filename()).path();
+ displayName = filePath.midRef(
+ filePath.lastIndexOf(QLatin1Char('/')) + 1) +
+ QLatin1Char(':') + QString::number(eventLocation.line());
+ }
break;
}
-
- QString eventHashStr = QString::fromLatin1("Input:%1").arg(eventType);
-
- QmlRangeEventData *newEvent;
- if (d->eventDescriptions.contains(eventHashStr)) {
- newEvent = d->eventDescriptions[eventHashStr];
- } else {
- newEvent = new QmlRangeEventData(QString(), eventType, eventHashStr, QQmlEventLocation(),
- QString(), QQmlProfilerDefinitions::Event,
- QQmlProfilerDefinitions::MaximumRangeType);
- d->eventDescriptions.insert(eventHashStr, newEvent);
}
- d->startInstanceList.append(QmlRangeEventStartInstance(time, -1, type, a, b, newEvent));
+ newType.setDisplayName(displayName);
+ d->eventTypes.append(newType);
}
void QmlProfilerData::computeQmlTime()
{
// compute levels
- QHash<int, qint64> endtimesPerLevel;
- int minimumLevel = 1;
- int level = minimumLevel;
-
- for (int i = 0; i < d->startInstanceList.count(); i++) {
- qint64 st = d->startInstanceList.at(i).startTime;
+ qint64 level0Start = -1;
+ int level = 0;
- if (d->startInstanceList.at(i).data->rangeType == QQmlProfilerDefinitions::Painting) {
+ for (const QQmlProfilerEvent &event : qAsConst(d->events)) {
+ const QQmlProfilerEventType &type = d->eventTypes.at(event.typeIndex());
+ if (type.message() != QQmlProfilerDefinitions::MaximumMessage)
continue;
- }
-
- // general level
- if (endtimesPerLevel.value(level) > st) {
- level++;
- } else {
- while (level > minimumLevel && endtimesPerLevel[level-1] <= st)
- level--;
- }
- endtimesPerLevel[level] = st + d->startInstanceList.at(i).duration;
- if (level == minimumLevel) {
- d->qmlMeasuredTime += d->startInstanceList.at(i).duration;
+ switch (type.rangeType()) {
+ case QQmlProfilerDefinitions::Compiling:
+ case QQmlProfilerDefinitions::Creating:
+ case QQmlProfilerDefinitions::Binding:
+ case QQmlProfilerDefinitions::HandlingSignal:
+ case QQmlProfilerDefinitions::Javascript:
+ switch (event.rangeStage()) {
+ case QQmlProfilerDefinitions::RangeStart:
+ if (level++ == 0)
+ level0Start = event.timestamp();
+ break;
+ case QQmlProfilerDefinitions::RangeEnd:
+ if (--level == 0)
+ d->qmlMeasuredTime += event.timestamp() - level0Start;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
}
}
}
-bool compareStartTimes(const QmlRangeEventStartInstance &t1, const QmlRangeEventStartInstance &t2)
+bool compareStartTimes(const QQmlProfilerEvent &t1, const QQmlProfilerEvent &t2)
{
- return t1.startTime < t2.startTime;
+ return t1.timestamp() < t2.timestamp();
}
void QmlProfilerData::sortStartTimes()
{
- if (d->startInstanceList.count() < 2)
+ if (d->events.count() < 2)
return;
// assuming startTimes is partially sorted
// identify blocks of events and sort them with quicksort
- QVector<QmlRangeEventStartInstance>::iterator itFrom = d->startInstanceList.end() - 2;
- QVector<QmlRangeEventStartInstance>::iterator itTo = d->startInstanceList.end() - 1;
+ QVector<QQmlProfilerEvent>::iterator itFrom = d->events.end() - 2;
+ QVector<QQmlProfilerEvent>::iterator itTo = d->events.end() - 1;
- while (itFrom != d->startInstanceList.begin() && itTo != d->startInstanceList.begin()) {
+ while (itFrom != d->events.begin() && itTo != d->events.begin()) {
// find block to sort
- while ( itFrom != d->startInstanceList.begin()
- && itTo->startTime > itFrom->startTime ) {
+ while (itFrom != d->events.begin() && itTo->timestamp() > itFrom->timestamp()) {
--itTo;
itFrom = itTo - 1;
}
// if we're at the end of the list
- if (itFrom == d->startInstanceList.begin())
+ if (itFrom == d->events.begin())
break;
// find block length
- while ( itFrom != d->startInstanceList.begin()
- && itTo->startTime <= itFrom->startTime )
+ while (itFrom != d->events.begin() && itTo->timestamp() <= itFrom->timestamp())
--itFrom;
- if (itTo->startTime <= itFrom->startTime)
+ if (itTo->timestamp() <= itFrom->timestamp())
std::sort(itFrom, itTo + 1, compareStartTimes);
else
std::sort(itFrom + 1, itTo + 1, compareStartTimes);
@@ -479,9 +321,88 @@ void QmlProfilerData::complete()
bool QmlProfilerData::isEmpty() const
{
- return d->startInstanceList.isEmpty();
+ return d->events.isEmpty();
}
+struct StreamWriter {
+ QString error;
+
+ StreamWriter(const QString &filename)
+ {
+ if (!filename.isEmpty()) {
+ file.setFileName(filename);
+ if (!file.open(QIODevice::WriteOnly)) {
+ error = QmlProfilerData::tr("Could not open %1 for writing").arg(filename);
+ return;
+ }
+ } else {
+ if (!file.open(stdout, QIODevice::WriteOnly)) {
+ error = QmlProfilerData::tr("Could not open stdout for writing");
+ return;
+ }
+ }
+
+ stream.setDevice(&file);
+ stream.setAutoFormatting(true);
+ stream.writeStartDocument();
+ writeStartElement("trace");
+ }
+
+ ~StreamWriter() {
+ writeEndElement();
+ stream.writeEndDocument();
+ file.close();
+ }
+
+ template<typename Number>
+ void writeAttribute(const char *name, Number number)
+ {
+ stream.writeAttribute(QLatin1String(name), QString::number(number));
+ }
+
+ void writeAttribute(const char *name, const char *value)
+ {
+ stream.writeAttribute(QLatin1String(name), QLatin1String(value));
+ }
+
+ void writeAttribute(const char *name, const QQmlProfilerEvent &event, int i, bool printZero = true)
+ {
+ const qint64 number = event.number<qint64>(i);
+ if (printZero || number != 0)
+ writeAttribute(name, number);
+ }
+
+ template<typename Number>
+ void writeTextElement(const char *name, Number number)
+ {
+ writeTextElement(name, QString::number(number));
+ }
+
+ void writeTextElement(const char *name, const char *value)
+ {
+ stream.writeTextElement(QLatin1String(name), QLatin1String(value));
+ }
+
+ void writeTextElement(const char *name, const QString &value)
+ {
+ stream.writeTextElement(QLatin1String(name), value);
+ }
+
+ void writeStartElement(const char *name)
+ {
+ stream.writeStartElement(QLatin1String(name));
+ }
+
+ void writeEndElement()
+ {
+ stream.writeEndElement();
+ }
+
+private:
+ QFile file;
+ QXmlStreamWriter stream;
+};
+
bool QmlProfilerData::save(const QString &filename)
{
if (isEmpty()) {
@@ -489,157 +410,178 @@ bool QmlProfilerData::save(const QString &filename)
return false;
}
- QFile file;
- if (!filename.isEmpty()) {
- file.setFileName(filename);
- if (!file.open(QIODevice::WriteOnly)) {
- emit error(tr("Could not open %1 for writing").arg(filename));
- return false;
- }
- } else {
- if (!file.open(stdout, QIODevice::WriteOnly)) {
- emit error(tr("Could not open stdout for writing"));
- return false;
- }
+ StreamWriter stream(filename);
+ if (!stream.error.isEmpty()) {
+ emit error(stream.error);
+ return false;
}
- QXmlStreamWriter stream(&file);
- stream.setAutoFormatting(true);
- stream.writeStartDocument();
-
- stream.writeStartElement(QStringLiteral("trace"));
- stream.writeAttribute(QStringLiteral("version"), PROFILER_FILE_VERSION);
-
- stream.writeAttribute(QStringLiteral("traceStart"), QString::number(traceStartTime()));
- stream.writeAttribute(QStringLiteral("traceEnd"), QString::number(traceEndTime()));
-
- stream.writeStartElement(QStringLiteral("eventData"));
- stream.writeAttribute(QStringLiteral("totalTime"), QString::number(d->qmlMeasuredTime));
-
- const auto eventDescriptionsKeys = d->eventDescriptions.keys();
- for (auto it = d->eventDescriptions.cbegin(), end = d->eventDescriptions.cend();
- it != end; ++it) {
- const QmlRangeEventData *eventData = it.value();
- stream.writeStartElement(QStringLiteral("event"));
- stream.writeAttribute(QStringLiteral("index"), QString::number(
- eventDescriptionsKeys.indexOf(eventData->eventHashStr)));
- if (!eventData->displayName.isEmpty())
- stream.writeTextElement(QStringLiteral("displayname"), eventData->displayName);
- if (eventData->rangeType != QQmlProfilerDefinitions::MaximumRangeType)
- stream.writeTextElement(QStringLiteral("type"),
- qmlRangeTypeAsString(eventData->rangeType));
- else
- stream.writeTextElement(QStringLiteral("type"),
- qmlMessageAsString(eventData->message));
- if (!eventData->location.filename.isEmpty())
- stream.writeTextElement(QStringLiteral("filename"), eventData->location.filename);
- if (eventData->location.line >= 0)
- stream.writeTextElement(QStringLiteral("line"),
- QString::number(eventData->location.line));
- if (eventData->location.column >= 0)
- stream.writeTextElement(QStringLiteral("column"),
- QString::number(eventData->location.column));
- if (!eventData->details.isEmpty())
- stream.writeTextElement(QStringLiteral("details"), eventData->details);
- if (eventData->rangeType == QQmlProfilerDefinitions::Binding)
- stream.writeTextElement(QStringLiteral("bindingType"),
- QString::number((int)eventData->detailType));
- else if (eventData->message == QQmlProfilerDefinitions::Event) {
- switch (eventData->detailType) {
+ stream.writeAttribute("version", PROFILER_FILE_VERSION);
+ stream.writeAttribute("traceStart", traceStartTime());
+ stream.writeAttribute("traceEnd", traceEndTime());
+
+ stream.writeStartElement("eventData");
+ stream.writeAttribute("totalTime", d->qmlMeasuredTime);
+
+ for (int typeIndex = 0, end = d->eventTypes.size(); typeIndex < end; ++typeIndex) {
+ const QQmlProfilerEventType &eventData = d->eventTypes.at(typeIndex);
+ stream.writeStartElement("event");
+ stream.writeAttribute("index", typeIndex);
+ if (!eventData.displayName().isEmpty())
+ stream.writeTextElement("displayname", eventData.displayName());
+
+ stream.writeTextElement("type",
+ eventData.rangeType() == QQmlProfilerDefinitions::MaximumRangeType
+ ? qmlMessageAsString(eventData.message())
+ : qmlRangeTypeAsString(eventData.rangeType()));
+
+ const QQmlProfilerEventLocation location = eventData.location();
+ if (!location.filename().isEmpty())
+ stream.writeTextElement("filename", location.filename());
+ if (location.line() >= 0)
+ stream.writeTextElement("line", location.line());
+ if (location.column() >= 0)
+ stream.writeTextElement("column", location.column());
+ if (!eventData.data().isEmpty())
+ stream.writeTextElement("details", eventData.data());
+ if (eventData.rangeType() == QQmlProfilerDefinitions::Binding)
+ stream.writeTextElement("bindingType", eventData.detailType());
+ else if (eventData.message() == QQmlProfilerDefinitions::Event) {
+ switch (eventData.detailType()) {
case QQmlProfilerDefinitions::AnimationFrame:
- stream.writeTextElement(QStringLiteral("animationFrame"),
- QString::number((int)eventData->detailType));
+ stream.writeTextElement("animationFrame", eventData.detailType());
break;
case QQmlProfilerDefinitions::Key:
- stream.writeTextElement(QStringLiteral("keyEvent"),
- QString::number((int)eventData->detailType));
+ stream.writeTextElement("keyEvent", eventData.detailType());
break;
case QQmlProfilerDefinitions::Mouse:
- stream.writeTextElement(QStringLiteral("mouseEvent"),
- QString::number((int)eventData->detailType));
+ stream.writeTextElement("mouseEvent", eventData.detailType());
break;
}
- } else if (eventData->message == QQmlProfilerDefinitions::PixmapCacheEvent)
- stream.writeTextElement(QStringLiteral("cacheEventType"),
- QString::number((int)eventData->detailType));
- else if (eventData->message == QQmlProfilerDefinitions::SceneGraphFrame)
- stream.writeTextElement(QStringLiteral("sgEventType"),
- QString::number((int)eventData->detailType));
- else if (eventData->message == QQmlProfilerDefinitions::MemoryAllocation)
- stream.writeTextElement(QStringLiteral("memoryEventType"),
- QString::number((int)eventData->detailType));
+ } else if (eventData.message() == QQmlProfilerDefinitions::PixmapCacheEvent)
+ stream.writeTextElement("cacheEventType", eventData.detailType());
+ else if (eventData.message() == QQmlProfilerDefinitions::SceneGraphFrame)
+ stream.writeTextElement("sgEventType", eventData.detailType());
+ else if (eventData.message() == QQmlProfilerDefinitions::MemoryAllocation)
+ stream.writeTextElement("memoryEventType", eventData.detailType());
stream.writeEndElement();
}
stream.writeEndElement(); // eventData
- stream.writeStartElement(QStringLiteral("profilerDataModel"));
- for (const QmlRangeEventStartInstance &event : qAsConst(d->startInstanceList)) {
- stream.writeStartElement(QStringLiteral("range"));
- stream.writeAttribute(QStringLiteral("startTime"), QString::number(event.startTime));
- if (event.duration >= 0)
- stream.writeAttribute(QStringLiteral("duration"),
- QString::number(event.duration));
- stream.writeAttribute(QStringLiteral("eventIndex"), QString::number(
- eventDescriptionsKeys.indexOf(event.data->eventHashStr)));
- if (event.data->message == QQmlProfilerDefinitions::Event) {
- if (event.data->detailType == QQmlProfilerDefinitions::AnimationFrame) {
+ stream.writeStartElement("profilerDataModel");
+
+ auto sendEvent = [&](const QQmlProfilerEvent &event, qint64 duration = 0) {
+ const QQmlProfilerEventType &type = d->eventTypes.at(event.typeIndex());
+ stream.writeStartElement("range");
+ stream.writeAttribute("startTime", event.timestamp());
+ if (duration != 0)
+ stream.writeAttribute("duration", duration);
+ stream.writeAttribute("eventIndex", event.typeIndex());
+ if (type.message() == QQmlProfilerDefinitions::Event) {
+ if (type.detailType() == QQmlProfilerDefinitions::AnimationFrame) {
// special: animation frame
- stream.writeAttribute(QStringLiteral("framerate"), QString::number(event.frameRate));
- stream.writeAttribute(QStringLiteral("animationcount"),
- QString::number(event.animationCount));
- stream.writeAttribute(QStringLiteral("thread"), QString::number(event.threadId));
- } else if (event.data->detailType == QQmlProfilerDefinitions::Key ||
- event.data->detailType == QQmlProfilerDefinitions::Mouse) {
+ stream.writeAttribute("framerate", event, 0);
+ stream.writeAttribute("animationcount", event, 1);
+ stream.writeAttribute("thread", event, 2);
+ } else if (type.detailType() == QQmlProfilerDefinitions::Key ||
+ type.detailType() == QQmlProfilerDefinitions::Mouse) {
// numerical value here, to keep the format a bit more compact
- stream.writeAttribute(QStringLiteral("type"),
- QString::number(event.inputType));
- stream.writeAttribute(QStringLiteral("data1"),
- QString::number(event.inputA));
- stream.writeAttribute(QStringLiteral("data2"),
- QString::number(event.inputB));
+ stream.writeAttribute("type", event, 0);
+ stream.writeAttribute("data1", event, 1);
+ stream.writeAttribute("data2", event, 2);
}
- } else if (event.data->message == QQmlProfilerDefinitions::PixmapCacheEvent) {
+ } else if (type.message() == QQmlProfilerDefinitions::PixmapCacheEvent) {
// special: pixmap cache event
- if (event.data->detailType == QQmlProfilerDefinitions::PixmapSizeKnown) {
- stream.writeAttribute(QStringLiteral("width"),
- QString::number(event.numericData1));
- stream.writeAttribute(QStringLiteral("height"),
- QString::number(event.numericData2));
- } else if (event.data->detailType ==
- QQmlProfilerDefinitions::PixmapReferenceCountChanged ||
- event.data->detailType ==
- QQmlProfilerDefinitions::PixmapCacheCountChanged) {
- stream.writeAttribute(QStringLiteral("refCount"),
- QString::number(event.numericData1));
+ if (type.detailType() == QQmlProfilerDefinitions::PixmapSizeKnown) {
+ stream.writeAttribute("width", event, 0);
+ stream.writeAttribute("height", event, 1);
+ } else if (type.detailType() == QQmlProfilerDefinitions::PixmapReferenceCountChanged
+ || type.detailType() == QQmlProfilerDefinitions::PixmapCacheCountChanged) {
+ stream.writeAttribute("refCount", event, 1);
}
- } else if (event.data->message == QQmlProfilerDefinitions::SceneGraphFrame) {
- // special: scenegraph frame events
- if (event.numericData1 > 0)
- stream.writeAttribute(QStringLiteral("timing1"),
- QString::number(event.numericData1));
- if (event.numericData2 > 0)
- stream.writeAttribute(QStringLiteral("timing2"),
- QString::number(event.numericData2));
- if (event.numericData3 > 0)
- stream.writeAttribute(QStringLiteral("timing3"),
- QString::number(event.numericData3));
- if (event.numericData4 > 0)
- stream.writeAttribute(QStringLiteral("timing4"),
- QString::number(event.numericData4));
- if (event.numericData5 > 0)
- stream.writeAttribute(QStringLiteral("timing5"),
- QString::number(event.numericData5));
- } else if (event.data->message == QQmlProfilerDefinitions::MemoryAllocation) {
- stream.writeAttribute(QStringLiteral("amount"), QString::number(event.numericData1));
+ } else if (type.message() == QQmlProfilerDefinitions::SceneGraphFrame) {
+ stream.writeAttribute("timing1", event, 0, false);
+ stream.writeAttribute("timing2", event, 1, false);
+ stream.writeAttribute("timing3", event, 2, false);
+ stream.writeAttribute("timing4", event, 3, false);
+ stream.writeAttribute("timing5", event, 4, false);
+ } else if (type.message() == QQmlProfilerDefinitions::MemoryAllocation) {
+ stream.writeAttribute("amount", event, 0);
}
stream.writeEndElement();
+ };
+
+ QQueue<QQmlProfilerEvent> pointEvents;
+ QQueue<QQmlProfilerEvent> rangeStarts[QQmlProfilerDefinitions::MaximumRangeType];
+ QStack<qint64> rangeEnds[QQmlProfilerDefinitions::MaximumRangeType];
+ int level = 0;
+
+ auto sendPending = [&]() {
+ forever {
+ int minimum = QQmlProfilerDefinitions::MaximumRangeType;
+ qint64 minimumTime = std::numeric_limits<qint64>::max();
+ for (int i = 0; i < QQmlProfilerDefinitions::MaximumRangeType; ++i) {
+ const QQueue<QQmlProfilerEvent> &starts = rangeStarts[i];
+ if (starts.isEmpty())
+ continue;
+ if (starts.head().timestamp() < minimumTime) {
+ minimumTime = starts.head().timestamp();
+ minimum = i;
+ }
+ }
+ if (minimum == QQmlProfilerDefinitions::MaximumRangeType)
+ break;
+
+ while (!pointEvents.isEmpty() && pointEvents.front().timestamp() < minimumTime)
+ sendEvent(pointEvents.dequeue());
+
+ sendEvent(rangeStarts[minimum].dequeue(),
+ rangeEnds[minimum].pop() - minimumTime);
+ }
+ };
+
+ for (const QQmlProfilerEvent &event : qAsConst(d->events)) {
+ const QQmlProfilerEventType &type = d->eventTypes.at(event.typeIndex());
+
+ if (type.rangeType() != QQmlProfilerDefinitions::MaximumRangeType) {
+ QQueue<QQmlProfilerEvent> &starts = rangeStarts[type.rangeType()];
+ switch (event.rangeStage()) {
+ case QQmlProfilerDefinitions::RangeStart: {
+ ++level;
+ starts.enqueue(event);
+ break;
+ }
+ case QQmlProfilerDefinitions::RangeEnd: {
+ QStack<qint64> &ends = rangeEnds[type.rangeType()];
+ if (starts.length() > ends.length()) {
+ ends.push(event.timestamp());
+ if (--level == 0)
+ sendPending();
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ } else {
+ if (level == 0)
+ sendEvent(event);
+ else
+ pointEvents.enqueue(event);
+ }
}
- stream.writeEndElement(); // profilerDataModel
- stream.writeEndElement(); // trace
- stream.writeEndDocument();
+ for (int i = 0; i < QQmlProfilerDefinitions::MaximumRangeType; ++i) {
+ while (rangeEnds[i].length() < rangeStarts[i].length()) {
+ rangeEnds[i].push(d->traceEndTime);
+ --level;
+ }
+ }
+
+ sendPending();
+
+ stream.writeEndElement(); // profilerDataModel
- file.close();
return true;
}
@@ -683,4 +625,9 @@ void QmlProfilerData::setState(QmlProfilerData::State state)
return;
}
+int QmlProfilerData::numLoadedEventTypes() const
+{
+ return d->eventTypes.length();
+}
+
#include "moc_qmlprofilerdata.cpp"
diff --git a/tools/qmlprofiler/qmlprofilerdata.h b/tools/qmlprofiler/qmlprofilerdata.h
index 00ef037071..2be0b73aee 100644
--- a/tools/qmlprofiler/qmlprofilerdata.h
+++ b/tools/qmlprofiler/qmlprofilerdata.h
@@ -29,13 +29,14 @@
#ifndef QMLPROFILERDATA_H
#define QMLPROFILERDATA_H
-#include <private/qqmleventlocation_p.h>
#include <private/qqmlprofilerdefinitions_p.h>
+#include <private/qqmlprofilereventlocation_p.h>
+#include <private/qqmlprofilereventreceiver_p.h>
#include <QObject>
class QmlProfilerDataPrivate;
-class QmlProfilerData : public QObject
+class QmlProfilerData : public QQmlProfilerEventReceiver
{
Q_OBJECT
public:
@@ -49,7 +50,11 @@ public:
explicit QmlProfilerData(QObject *parent = 0);
~QmlProfilerData();
- static QString getHashStringForQmlEvent(const QQmlEventLocation &location, int eventType);
+ int numLoadedEventTypes() const override;
+ void addEventType(const QQmlProfilerEventType &type) override;
+ void addEvent(const QQmlProfilerEvent &event) override;
+
+ static QString getHashStringForQmlEvent(const QQmlProfilerEventLocation &location, int eventType);
static QString qmlRangeTypeAsString(QQmlProfilerDefinitions::RangeType type);
static QString qmlMessageAsString(QQmlProfilerDefinitions::Message type);
@@ -61,18 +66,6 @@ public:
void clear();
void setTraceEndTime(qint64 time);
void setTraceStartTime(qint64 time);
- void addQmlEvent(QQmlProfilerDefinitions::RangeType type,
- QQmlProfilerDefinitions::BindingType bindingType,
- qint64 startTime, qint64 duration, const QStringList &data,
- const QQmlEventLocation &location);
- void addFrameEvent(qint64 time, int framerate, int animationcount, int threadId);
- void addSceneGraphFrameEvent(QQmlProfilerDefinitions::SceneGraphFrameType type, qint64 time,
- qint64 numericData1, qint64 numericData2, qint64 numericData3,
- qint64 numericData4, qint64 numericData5);
- void addPixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type, qint64 time,
- const QString &location, int numericData1, int numericData2);
- void addMemoryEvent(QQmlProfilerDefinitions::MemoryType type, qint64 time, qint64 size);
- void addInputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time, int a, int b);
void complete();
bool save(const QString &filename);
diff --git a/tools/qmlscene/main.cpp b/tools/qmlscene/main.cpp
index 7741c4c45b..fc8b9c5292 100644
--- a/tools/qmlscene/main.cpp
+++ b/tools/qmlscene/main.cpp
@@ -33,7 +33,7 @@
#include <QtCore/qpointer.h>
#include <QtCore/qscopedpointer.h>
#include <QtCore/qtextstream.h>
-#include <QtCore/qregexp.h>
+#include <QtCore/qregularexpression.h>
#include <QtGui/QGuiApplication>
#include <QtGui/QOpenGLFunctions>
@@ -133,6 +133,17 @@ void RenderStatistics::printTotalStats()
struct Options
{
+ enum QmlApplicationType
+ {
+ QmlApplicationTypeGui,
+ QmlApplicationTypeWidget,
+#ifdef QT_WIDGETS_LIB
+ DefaultQmlApplicationType = QmlApplicationTypeWidget
+#else
+ DefaultQmlApplicationType = QmlApplicationTypeGui
+#endif
+ };
+
Options()
: originalQml(false)
, originalQmlRaster(false)
@@ -145,7 +156,10 @@ struct Options
, quitImmediately(false)
, resizeViewToRootItem(false)
, multisample(false)
+ , coreProfile(false)
, verbose(false)
+ , applicationType(DefaultQmlApplicationType)
+ , textRenderType(QQuickWindow::textRenderType())
{
// QtWebEngine needs a shared context in order for the GPU thread to
// upload textures.
@@ -164,9 +178,12 @@ struct Options
bool quitImmediately;
bool resizeViewToRootItem;
bool multisample;
+ bool coreProfile;
bool verbose;
QVector<Qt::ApplicationAttribute> applicationAttributes;
QString translationFile;
+ QmlApplicationType applicationType;
+ QQuickWindow::TextRenderType textRenderType;
};
#if defined(QMLSCENE_BUNDLE)
@@ -259,8 +276,8 @@ static bool checkVersion(const QUrl &url)
return false;
}
- QRegExp quick1("^\\s*import +QtQuick +1\\.\\w*");
- QRegExp qt47("^\\s*import +Qt +4\\.7");
+ QRegularExpression quick1("^\\s*import +QtQuick +1\\.\\w*");
+ QRegularExpression qt47("^\\s*import +Qt +4\\.7");
QTextStream stream(&f);
bool codeFound= false;
@@ -270,10 +287,11 @@ static bool checkVersion(const QUrl &url)
codeFound = true;
} else {
QString import;
- if (quick1.indexIn(line) >= 0)
- import = quick1.cap(0).trimmed();
- else if (qt47.indexIn(line) >= 0)
- import = qt47.cap(0).trimmed();
+ QRegularExpressionMatch match = quick1.match(line);
+ if (match.hasMatch())
+ import = match.captured(0).trimmed();
+ else if ((match = qt47.match(line)).hasMatch())
+ import = match.captured(0).trimmed();
if (!import.isNull()) {
fprintf(stderr, "qmlscene: '%s' is no longer supported.\n"
@@ -291,15 +309,17 @@ static bool checkVersion(const QUrl &url)
static void displayFileDialog(Options *options)
{
#if defined(QT_WIDGETS_LIB) && QT_CONFIG(filedialog)
- QString fileName = QFileDialog::getOpenFileName(0, "Open QML file", QString(), "QML Files (*.qml)");
- if (!fileName.isEmpty()) {
- QFileInfo fi(fileName);
- options->url = QUrl::fromLocalFile(fi.canonicalFilePath());
+ if (options->applicationType == Options::QmlApplicationTypeWidget) {
+ QString fileName = QFileDialog::getOpenFileName(0, "Open QML file", QString(), "QML Files (*.qml)");
+ if (!fileName.isEmpty()) {
+ QFileInfo fi(fileName);
+ options->url = QUrl::fromLocalFile(fi.canonicalFilePath());
+ }
+ return;
}
-#else
+#endif // QT_WIDGETS_LIB && QT_CONFIG(filedialog)
Q_UNUSED(options);
puts("No filename specified...");
-#endif
}
#if QT_CONFIG(translation)
@@ -343,6 +363,7 @@ static void usage()
puts(" --fullscreen ..................... Run fullscreen");
puts(" --transparent .................... Make the window transparent");
puts(" --multisample .................... Enable multisampling (OpenGL anti-aliasing)");
+ puts(" --core-profile ................... Request a core profile OpenGL context");
puts(" --no-version-detection ........... Do not try to detect the version of the .qml file");
puts(" --slow-animations ................ Run all animations in slow motion");
puts(" --resize-to-root ................. Resize the window to the size of the root item");
@@ -355,6 +376,10 @@ static void usage()
puts(" --scaling..........................Enable High DPI scaling (AA_EnableHighDpiScaling)");
puts(" --no-scaling.......................Disable High DPI scaling (AA_DisableHighDpiScaling)");
puts(" --verbose..........................Print version and graphical diagnostics for the run-time");
+#ifdef QT_WIDGETS_LIB
+ puts(" --apptype [gui|widgets] ...........Select which application class to use. Default is widgets.");
+#endif
+ puts(" --textrendertype [qt|native].......Select the default render type for text-like elements.");
puts(" -I <path> ........................ Add <path> to the list of import paths");
puts(" -P <path> ........................ Add <path> to the list of plugin paths");
puts(" -translation <translationfile> ... Set the language to run in");
@@ -434,6 +459,19 @@ static QUrl parseUrlArgument(const QString &arg)
return url;
}
+static QQuickWindow::TextRenderType parseTextRenderType(const QString &renderType)
+{
+ if (renderType == QLatin1String("qt"))
+ return QQuickWindow::QtTextRendering;
+ else if (renderType == QLatin1String("native"))
+ return QQuickWindow::NativeTextRendering;
+
+ usage();
+
+ Q_UNREACHABLE();
+ return QQuickWindow::QtTextRendering;
+}
+
int main(int argc, char ** argv)
{
Options options;
@@ -444,30 +482,38 @@ int main(int argc, char ** argv)
// Parse arguments for application attributes to be applied before Q[Gui]Application creation.
for (int i = 1; i < argc; ++i) {
const char *arg = argv[i];
- if (!qstrcmp(arg, "--disable-context-sharing"))
+ if (!qstrcmp(arg, "--disable-context-sharing")) {
options.applicationAttributes.removeAll(Qt::AA_ShareOpenGLContexts);
- else if (!qstrcmp(arg, "--gles"))
+ } else if (!qstrcmp(arg, "--gles")) {
options.applicationAttributes.append(Qt::AA_UseOpenGLES);
- else if (!qstrcmp(arg, "--software"))
+ } else if (!qstrcmp(arg, "--software")) {
options.applicationAttributes.append(Qt::AA_UseSoftwareOpenGL);
- else if (!qstrcmp(arg, "--desktop"))
+ } else if (!qstrcmp(arg, "--desktop")) {
options.applicationAttributes.append(Qt::AA_UseDesktopOpenGL);
- else if (!qstrcmp(arg, "--scaling"))
+ } else if (!qstrcmp(arg, "--scaling")) {
options.applicationAttributes.append(Qt::AA_EnableHighDpiScaling);
- else if (!qstrcmp(arg, "--no-scaling"))
+ } else if (!qstrcmp(arg, "--no-scaling")) {
options.applicationAttributes.append(Qt::AA_DisableHighDpiScaling);
+ } else if (!qstrcmp(arg, "--apptype")) {
+ if (++i >= argc)
+ usage();
+ if (!qstrcmp(argv[i], "gui"))
+ options.applicationType = Options::QmlApplicationTypeGui;
+ }
}
for (Qt::ApplicationAttribute a : qAsConst(options.applicationAttributes))
QCoreApplication::setAttribute(a);
+ QScopedPointer<QGuiApplication> app;
#ifdef QT_WIDGETS_LIB
- QApplication app(argc, argv);
-#else
- QGuiApplication app(argc, argv);
+ if (options.applicationType == Options::QmlApplicationTypeWidget)
+ app.reset(new QApplication(argc, argv));
#endif
- app.setApplicationName("QtQmlViewer");
- app.setOrganizationName("QtProject");
- app.setOrganizationDomain("qt-project.org");
+ if (app.isNull())
+ app.reset(new QGuiApplication(argc, argv));
+ QCoreApplication::setApplicationName(QStringLiteral("QtQmlViewer"));
+ QCoreApplication::setOrganizationName(QStringLiteral("QtProject"));
+ QCoreApplication::setOrganizationDomain(QStringLiteral("qt-project.org"));
QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR));
const QStringList arguments = QCoreApplication::arguments();
@@ -496,12 +542,18 @@ int main(int argc, char ** argv)
options.resizeViewToRootItem = true;
else if (lowerArgument == QLatin1String("--multisample"))
options.multisample = true;
+ else if (lowerArgument == QLatin1String("--core-profile"))
+ options.coreProfile = true;
else if (lowerArgument == QLatin1String("--verbose"))
options.verbose = true;
else if (lowerArgument == QLatin1String("-i") && i + 1 < size)
imports.append(arguments.at(++i));
else if (lowerArgument == QLatin1String("-p") && i + 1 < size)
pluginPaths.append(arguments.at(++i));
+ else if (lowerArgument == QLatin1String("--apptype"))
+ ++i; // Consume previously parsed argument
+ else if (lowerArgument == QLatin1String("--textrendertype") && i + 1 < size)
+ options.textRenderType = parseTextRenderType(arguments.at(++i));
else if (lowerArgument == QLatin1String("--help")
|| lowerArgument == QLatin1String("-help")
|| lowerArgument == QLatin1String("--h")
@@ -515,14 +567,14 @@ int main(int argc, char ** argv)
QTranslator qtTranslator;
QString sysLocale = QLocale::system().name();
if (qtTranslator.load(QLatin1String("qt_") + sysLocale, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
- app.installTranslator(&qtTranslator);
+ app->installTranslator(&qtTranslator);
if (translator.load(QLatin1String("qmlscene_") + sysLocale, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
- app.installTranslator(&translator);
+ app->installTranslator(&translator);
QTranslator qmlTranslator;
if (!options.translationFile.isEmpty()) {
if (qmlTranslator.load(options.translationFile)) {
- app.installTranslator(&qmlTranslator);
+ app->installTranslator(&qmlTranslator);
} else {
fprintf(stderr, "Could not load the translation file \"%s\"\n",
qPrintable(options.translationFile));
@@ -530,6 +582,8 @@ int main(int argc, char ** argv)
}
#endif
+ QQuickWindow::setTextRenderType(options.textRenderType);
+
QUnifiedTimer::instance()->setSlowModeEnabled(options.slowAnimations);
if (options.url.isEmpty())
@@ -612,6 +666,10 @@ int main(int argc, char ** argv)
window->setColor(QColor(Qt::transparent));
window->setFlags(Qt::FramelessWindowHint);
}
+ if (options.coreProfile) {
+ surfaceFormat.setVersion(4, 1);
+ surfaceFormat.setProfile(QSurfaceFormat::CoreProfile);
+ }
window->setFormat(surfaceFormat);
if (window->flags() == Qt::Window) // Fix window flags unless set by QML.
@@ -630,7 +688,7 @@ int main(int argc, char ** argv)
// Now would be a good time to inform the debug service to start listening.
- exitCode = app.exec();
+ exitCode = app->exec();
#ifdef QML_RUNTIME_TESTING
RenderStatistics::printTotalStats();
diff --git a/tools/qmlscene/qmlscene.pro b/tools/qmlscene/qmlscene.pro
index ec73f1871a..dcc46e17c7 100644
--- a/tools/qmlscene/qmlscene.pro
+++ b/tools/qmlscene/qmlscene.pro
@@ -5,15 +5,8 @@ CONFIG += no_import_scan
SOURCES += main.cpp
DEFINES += QML_RUNTIME_TESTING
-!contains(QT_CONFIG, no-qml-debug): DEFINES += QT_QML_DEBUG_NO_WARNING
+qtConfig(qml-debug): DEFINES += QT_QML_DEBUG_NO_WARNING
-QMAKE_TARGET_PRODUCT = qmlscene
-QMAKE_TARGET_DESCRIPTION = Utility that loads and displays QML documents
-
-win32 {
- VERSION = $${QT_VERSION}.0
-} else {
- VERSION = $${QT_VERSION}
-}
+QMAKE_TARGET_DESCRIPTION = QML Scene Viewer
load(qt_tool)
diff --git a/tools/qmltestrunner/qmltestrunner.pro b/tools/qmltestrunner/qmltestrunner.pro
index 505537480c..47b9637199 100644
--- a/tools/qmltestrunner/qmltestrunner.pro
+++ b/tools/qmltestrunner/qmltestrunner.pro
@@ -3,13 +3,6 @@ SOURCES += main.cpp
QT += qml qmltest
CONFIG += no_import_scan
-QMAKE_TARGET_PRODUCT = qmltestrunner
-QMAKE_TARGET_DESCRIPTION = QML test runner
-
-win32 {
- VERSION = $${QT_VERSION}.0
-} else {
- VERSION = $${QT_VERSION}
-}
+QMAKE_TARGET_DESCRIPTION = QML Test Runner
load(qt_tool)
diff --git a/tools/qmltime/qmltime.pro b/tools/qmltime/qmltime.pro
index ec1bcb5a03..04a5fd5957 100644
--- a/tools/qmltime/qmltime.pro
+++ b/tools/qmltime/qmltime.pro
@@ -4,13 +4,5 @@ QT += qml quick
QT += quick-private
macx:CONFIG -= app_bundle
-QMAKE_TARGET_PRODUCT = qmltime
-QMAKE_TARGET_DESCRIPTION = Tool for benchmarking the instantiation of a QML component
-
-win32 {
- VERSION = $${QT_VERSION}.0
-} else {
- VERSION = $${QT_VERSION}
-}
-
+QMAKE_TARGET_DESCRIPTION = QML Time
SOURCES += qmltime.cpp