aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarsten Heimrich <karsten.heimrich@qt.io>2022-04-12 14:20:35 +0200
committerKarsten Heimrich <karsten.heimrich@qt.io>2022-05-11 05:30:19 +0000
commitb282cd2bbbd44acd46303a3a31a6daafc703728d (patch)
tree61fdfc1a47eddf65b006acd1089939cd356b75f5
parenteb956731dee8ecd4d0393021c9f52ed2314eb14b (diff)
Implement MSBuild natvis handling
Implements both global and project-specific Qt settings. The Natvis File (Qt5/Qt6) is selected according to the Qt version of the project used. Task-number: QTVSADDINBUG-996 Change-Id: Iac0d90a6cae3b341f6b4fd4fed7afe53ebb4559b Reviewed-by: Miguel Costa <miguel.costa@qt.io>
-rw-r--r--QtMSBuild/QtMSBuild.csproj6
-rw-r--r--QtMSBuild/QtMsBuild/qt5.natvis.xml835
-rw-r--r--QtMSBuild/QtMsBuild/qt6.natvis.xml406
-rw-r--r--QtMSBuild/QtMsBuild/qt_globals.targets25
-rw-r--r--QtMSBuild/QtMsBuild/qt_private.props40
-rw-r--r--QtMSBuild/QtMsBuild/qt_settings.xml13
-rw-r--r--QtVsTools.Package/Options/QtOptionsPage.cs19
-rw-r--r--QtVsTools.Package/Package/DteEventsHandler.cs10
-rw-r--r--QtVsTools.Package/QtVsToolsPackage.cs49
9 files changed, 1360 insertions, 43 deletions
diff --git a/QtMSBuild/QtMSBuild.csproj b/QtMSBuild/QtMSBuild.csproj
index 9eebe7f3..3e2a0e0e 100644
--- a/QtMSBuild/QtMSBuild.csproj
+++ b/QtMSBuild/QtMSBuild.csproj
@@ -130,6 +130,12 @@
<DesignTime>True</DesignTime>
<DependentUpon>AssemblyInfo.cs</DependentUpon>
</Compile>
+ <Content Include="QtMSBuild\qt5.natvis.xml">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
+ <Content Include="QtMSBuild\qt6.natvis.xml">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
<!--
///////////////////////////////////////////////////////////////////////////////////////////////
// Qt/MSBuild common property pages and targets
diff --git a/QtMSBuild/QtMsBuild/qt5.natvis.xml b/QtMSBuild/QtMsBuild/qt5.natvis.xml
new file mode 100644
index 00000000..9ade6ae0
--- /dev/null
+++ b/QtMSBuild/QtMsBuild/qt5.natvis.xml
@@ -0,0 +1,835 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ****************************************************************************
+ **
+ ** Copyright (C) 2022 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the Qt VS Tools.
+ **
+ ** $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$
+ **
+ ****************************************************************************
+-->
+
+<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
+
+ <Type Name="##NAMESPACE##::QPoint">
+ <AlternativeType Name="##NAMESPACE##::QPointF"/>
+ <DisplayString>{{ x = {xp}, y = {yp} }}</DisplayString>
+ <Expand>
+ <Item Name="[x]">xp</Item>
+ <Item Name="[y]">yp</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QRect">
+ <DisplayString>{{ x = {x1}, y = {y1}, width = {x2 - x1 + 1}, height = {y2 - y1 + 1} }}</DisplayString>
+ <Expand>
+ <Item Name="[x]">x1</Item>
+ <Item Name="[y]">y1</Item>
+ <Item Name="[width]">x2 - x1 + 1</Item>
+ <Item Name="[height]">y2 - y1 + 1</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QRectF">
+ <DisplayString>{{ x = {xp}, y = {yp}, width = {w}, height = {h} }}</DisplayString>
+ <Expand>
+ <Item Name="[x]">xp</Item>
+ <Item Name="[y]">yp</Item>
+ <Item Name="[width]">w</Item>
+ <Item Name="[height]">h</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QSize">
+ <AlternativeType Name="##NAMESPACE##::QSizeF"/>
+ <DisplayString>{{ width = {wd}, height = {ht} }}</DisplayString>
+ <Expand>
+ <Item Name="[width]">wd</Item>
+ <Item Name="[height]">ht</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QLine">
+ <AlternativeType Name="##NAMESPACE##::QLineF"/>
+ <DisplayString>{{ start point = {pt1}, end point = {pt2} }}</DisplayString>
+ <Expand>
+ <Synthetic Name="[start point]">
+ <DisplayString>{pt1}</DisplayString>
+ <Expand>
+ <ExpandedItem>pt1</ExpandedItem>
+ </Expand>
+ </Synthetic>
+ <Synthetic Name="[end point]">
+ <DisplayString>{pt2}</DisplayString>
+ <Expand>
+ <ExpandedItem>pt2</ExpandedItem>
+ </Expand>
+ </Synthetic>
+
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QPolygon">
+ <DisplayString>{{ size = {d-&gt;size} }}</DisplayString>
+ <Expand>
+ <Item Name="[referenced]">d-&gt;ref.atomic._q_value</Item>
+ <ArrayItems>
+ <Size>d-&gt;size</Size>
+ <ValuePointer>(##NAMESPACE##::QPoint*)((reinterpret_cast&lt;char*&gt;(d)) + d-&gt;offset)</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QPolygonF">
+ <DisplayString>{{ size = {d-&gt;size} }}</DisplayString>
+ <Expand>
+ <Item Name="[closed]">
+ d-&gt;size &gt; 0
+ &amp;&amp; ((((##NAMESPACE##::QPointF*)((reinterpret_cast&lt;char*&gt;(d)) + d-&gt;offset)[0]).xp
+ == (((##NAMESPACE##::QPointF*)((reinterpret_cast&lt;char*&gt;(d)) + d-&gt;offset)[d-&gt;size - 1]).xp)
+ &amp;&amp; ((((##NAMESPACE##::QPointF*)((reinterpret_cast&lt;char*&gt;(d)) + d-&gt;offset)[0]).yp
+ == (((##NAMESPACE##::QPointF*)((reinterpret_cast&lt;char*&gt;(d)) + d-&gt;offset)[d-&gt;size - 1]).yp)
+ </Item>
+ <Item Name="[referenced]">d-&gt;ref.atomic._q_value</Item>
+ <ArrayItems>
+ <Size>d-&gt;size</Size>
+ <ValuePointer>(##NAMESPACE##::QPointF*)((reinterpret_cast&lt;char*&gt;(d)) + d-&gt;offset)</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name ="##NAMESPACE##::QVector2D">
+ <DisplayString>{{ x = {xp}, y = {yp} }}</DisplayString>
+ <Expand>
+ <Item Name="[x]">xp</Item>
+ <Item Name="[y]">yp</Item>
+ </Expand>
+ </Type>
+
+ <Type Name ="##NAMESPACE##::QVector3D">
+ <DisplayString>{{ x = {xp}, y = {yp}, z = {zp} }}</DisplayString>
+ <Expand>
+ <Item Name="[x]">xp</Item>
+ <Item Name="[y]">yp</Item>
+ <Item Name="[z]">zp</Item>
+ </Expand>
+ </Type>
+
+ <Type Name ="##NAMESPACE##::QVector4D">
+ <DisplayString>{{ x = {xp}, y = {yp}, z = {zp}, w = {wp} }}</DisplayString>
+ <Expand>
+ <Item Name="[x]">xp</Item>
+ <Item Name="[y]">yp</Item>
+ <Item Name="[z]">zp</Item>
+ <Item Name="[w]">wp</Item>
+ </Expand>
+ </Type>
+
+ <Type Name ="##NAMESPACE##::QMatrix">
+ <DisplayString>
+ {{ m11 = {_m11}, m12 = {_m12}, m21 = {_m21}, m22 = {_m22}, ... }}
+ </DisplayString>
+ <Expand>
+ <Item Name="[m11]">_m11</Item>
+ <Item Name="[m12]">_m12</Item>
+ <Item Name="[m21]">_m21</Item>
+ <Item Name="[m22]">_m22</Item>
+ <Item Name="[dx]">_dx</Item>
+ <Item Name="[dy]">_dy</Item>
+ </Expand>
+ </Type>
+
+ <Type Name ="##NAMESPACE##::QMatrix4x4">
+ <DisplayString>
+ {{ m11 = {m[0][0]}, m12 = {m[1][0]}, m13 = {m[2][0]}, m14 = {m[3][0]}, ... }}
+ </DisplayString>
+ <Expand>
+ <Item Name="[m11]">m[0][0]</Item>
+ <Item Name="[m12]">m[1][0]</Item>
+ <Item Name="[m13]">m[2][0]</Item>
+ <Item Name="[m14]">m[3][0]</Item>
+ <Item Name="[m21]">m[0][1]</Item>
+ <Item Name="[m22]">m[1][1]</Item>
+ <Item Name="[m23]">m[2][1]</Item>
+ <Item Name="[m24]">m[3][1]</Item>
+ <Item Name="[m31]">m[0][2]</Item>
+ <Item Name="[m32]">m[1][2]</Item>
+ <Item Name="[m33]">m[2][2]</Item>
+ <Item Name="[m34]">m[3][2]</Item>
+ <Item Name="[m41]">m[0][3]</Item>
+ <Item Name="[m42]">m[1][3]</Item>
+ <Item Name="[m43]">m[2][3]</Item>
+ <Item Name="[m44]">m[3][3]</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QSizePolicy">
+ <DisplayString>
+ {{ horizontal = {static_cast&lt;Policy&gt;(bits.horPolicy)}, vertical = {static_cast&lt;Policy&gt;(bits.verPolicy)}, type = {ControlType(1 &lt;&lt; bits.ctype)} }}
+ </DisplayString>
+ <Expand>
+ <Synthetic Name="[vertical policy]">
+ <DisplayString>##NAMESPACE##::QSizePolicy::Policy::{static_cast&lt;Policy&gt;(bits.verPolicy)}</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[horizontal policy]">
+ <DisplayString>##NAMESPACE##::QSizePolicy::Policy::{static_cast&lt;Policy&gt;(bits.horPolicy)}</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[control type]">
+ <DisplayString>##NAMESPACE##::QSizePolicy::ControlType::{ControlType(1 &lt;&lt; bits.ctype)}</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[expanding directions]">
+ <DisplayString
+ Condition="(static_cast&lt;Policy&gt;(bits.verPolicy) &amp; ExpandFlag)">
+ ##NAMESPACE##::Qt::Vertical (2)
+ </DisplayString>
+ <DisplayString
+ Condition="(static_cast&lt;Policy&gt;(bits.horPolicy) &amp; ExpandFlag)">
+ ##NAMESPACE##::Qt::Horizontal (1)
+ </DisplayString>
+ </Synthetic>
+ <Item Name="[vertical stretch]">static_cast&lt;int&gt;(bits.verStretch)</Item>
+ <Item Name="[horizontal stretch]">static_cast&lt;int&gt;(bits.horStretch)</Item>
+ <Item Name="[has height for width]">bits.hfw == 1</Item>
+ <Item Name="[has width for height]">bits.wfh == 1</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QChar">
+ <DisplayString>{ucs,c}</DisplayString>
+ <StringView>ucs,c</StringView>
+ <Expand>
+ <Item Name="[latin 1]">ucs > 0xff ? '\0' : char(ucs),c</Item>
+ <Item Name="[unicode]">ucs,c</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QString">
+ <DisplayString>{((reinterpret_cast&lt;unsigned short*&gt;(d)) + d-&gt;offset / 2),sub}</DisplayString>
+ <StringView>((reinterpret_cast&lt;unsigned short*&gt;(d)) + d-&gt;offset / 2),sub</StringView>
+ <Expand>
+ <Item Name="[size]">d-&gt;size</Item>
+ <Item Name="[referenced]">d-&gt;ref.atomic._q_value</Item>
+ <ArrayItems>
+ <Size>d-&gt;size</Size>
+ <ValuePointer>((reinterpret_cast&lt;unsigned short*&gt;(d)) + d-&gt;offset / 2),c</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QStringRef">
+ <Intrinsic Name="offset" Expression="(reinterpret_cast&lt;char16_t*&gt;(m_string-&gt;d))
+ + m_string-&gt;d->offset / 2" />
+ <DisplayString Condition="m_string == nullptr">{m_string,[m_size]} u""</DisplayString>
+ <DisplayString Condition="m_string != nullptr">{offset() + m_position,[m_size]}</DisplayString>
+ <Expand>
+ <Item Name="[position]" ExcludeView="simple">m_position</Item>
+ <Item Name="[size]" ExcludeView="simple">m_size</Item>
+ <ArrayItems Condition="m_string != nullptr">
+ <Size>m_size</Size>
+ <ValuePointer>offset()+m_position</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QStringView">
+ <DisplayString>{m_data,[m_size]}</DisplayString>
+ <StringView>m_data,[m_size]</StringView>
+ <Expand>
+ <Item Name="[size]" ExcludeView="simple">m_size</Item>
+ <ArrayItems>
+ <Size>m_size</Size>
+ <ValuePointer>m_data</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QByteArray">
+ <DisplayString>{((reinterpret_cast&lt;char*&gt;(d)) + d-&gt;offset),sb}</DisplayString>
+ <StringView>((reinterpret_cast&lt;char*&gt;(d)) + d-&gt;offset),sb</StringView>
+ <Expand>
+ <Item Name="[size]">d-&gt;size</Item>
+ <Item Name="[referenced]">d-&gt;ref.atomic._q_value</Item>
+ <ArrayItems>
+ <Size>d-&gt;size</Size>
+ <ValuePointer>((reinterpret_cast&lt;char*&gt;(d)) + d-&gt;offset),c</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QUrl">
+ <Intrinsic Name="isEmpty" Expression="size==0">
+ <Parameter Name="size" Type="int"/>
+ </Intrinsic>
+ <Intrinsic Name="memberOffset" Expression="sizeof(QAtomicInt) + sizeof(int) + (sizeof(QString) * count)">
+ <Parameter Name="count" Type="int"/>
+ </Intrinsic>
+ <Intrinsic Name="scheme" Expression="*((QString*)(((char*)(d) + memberOffset(0))))" />
+ <Intrinsic Name="username" Expression="*((QString*)(((char*)(d) + memberOffset(1))))" />
+ <Intrinsic Name="password" Expression="*((QString*)(((char*)(d) + memberOffset(2))))" />
+ <Intrinsic Name="host" Expression="*((QString*)(((char*)(d) + memberOffset(3))))" />
+ <Intrinsic Name="path" Expression="*((QString*)(((char*)(d) + memberOffset(4))))" />
+ <Intrinsic Name="query" Expression="*((QString*)(((char*)(d) + memberOffset(5))))" />
+ <Intrinsic Name="fragment" Expression="*((QString*)(((char*)(d) + memberOffset(6))))" />
+
+ <DisplayString Condition="!isEmpty(scheme().d-&gt;size)">{scheme()}://{host()}{path()}</DisplayString>
+ <DisplayString Condition="isEmpty(scheme().d-&gt;size)">{path()}</DisplayString>
+ <Expand>
+ <Item Name="[scheme]">scheme()</Item>
+ <Item Name="[username]">username()</Item>
+ <Item Name="[password]">password()</Item>
+ <Item Name="[host]">host()</Item>
+ <Item Name="[path]">path()</Item>
+ <Item Name="[query]">query()</Item>
+ <Item Name="[fragment]">fragment()</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QBitArray">
+ <DisplayString>{{ size = {(d.d-&gt;size &lt;&lt; 3) - *((reinterpret_cast&lt;char*&gt;(d.d)) + d.d-&gt;offset)} }}</DisplayString>
+ <Expand>
+ <Item Name="[referenced]">d.d-&gt;ref.atomic._q_value</Item>
+ <IndexListItems>
+ <Size>(d.d-&gt;size &lt;&lt; 3) - *((reinterpret_cast&lt;char*&gt;(d.d)) + d.d-&gt;offset)</Size>
+ <ValueNode>
+ (*(reinterpret_cast&lt;const unsigned char*&gt;((reinterpret_cast&lt;char*&gt;(d.d)) + d.d-&gt;offset) + 1
+ + ($i &gt;&gt; 3)) &amp; (1 &lt;&lt; ($i &amp; 7))) != 0
+ </ValueNode>
+ </IndexListItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QVarLengthArray&lt;*&gt;">
+ <AlternativeType Name="##NAMESPACE##::QVarLengthArray&lt;*, int&gt;"/>
+ <DisplayString>{{ size = {s} }}</DisplayString>
+ <Expand>
+ <Item Name="[capacity]">a</Item>
+ <ArrayItems>
+ <Size>s</Size>
+ <ValuePointer>ptr</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QDate">
+ <DisplayString>{{ julian day = {jd} }}</DisplayString>
+ <Expand></Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QTime">
+ <DisplayString
+ Condition="mds == 1">{{ millisecond = {mds} }}</DisplayString>
+ <DisplayString
+ Condition="mds != 1">{{ milliseconds = {mds} }}</DisplayString>
+ <Expand>
+ <Item Name="[hour]"
+ Condition="(mds / 3600000) == 1">mds / 3600000, d</Item>
+ <Item Name="[hours]"
+ Condition="(mds / 3600000) != 1">mds / 3600000, d</Item>
+ <Item Name="[minute]"
+ Condition="((mds % 3600000) / 60000) == 1">(mds % 3600000) / 60000, d</Item>
+ <Item Name="[minutes]"
+ Condition="((mds % 3600000) / 60000) != 1">(mds % 3600000) / 60000, d</Item>
+ <Item Name="[second]"
+ Condition="((mds / 1000) % 60) == 1">(mds / 1000) % 60, d</Item>
+ <Item Name="[seconds]"
+ Condition="((mds / 1000) % 60) != 1">(mds / 1000) % 60, d</Item>
+ <Item Name="[millisecond]"
+ Condition="(mds % 1000) == 1">mds % 1000, d</Item>
+ <Item Name="[milliseconds]"
+ Condition="(mds % 1000) != 1">mds % 1000, d</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QRegularExpression">
+ <DisplayString>{d.pattern}</DisplayString>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QSharedData">
+ <Expand>
+ <Item Name="[referenced]">ref._q_value</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QSharedPointer&lt;*&gt;">
+ <DisplayString>strong reference to shared pointer of type {"$T1"}</DisplayString>
+ <Expand>
+ <Item Name="[is null]">value == 0</Item>
+ <Item Name="[weak referenced]">d-&gt;weakref._q_value</Item>
+ <Item Name="[strong referenced]">d-&gt;strongref._q_value</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QSharedDataPointer&lt;*&gt;">
+ <DisplayString>pointer to implicit shared object of type {"$T1"}</DisplayString>
+ <Expand>
+ <ExpandedItem>d</ExpandedItem>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QExplicitlySharedDataPointer&lt;*&gt;">
+ <DisplayString>pointer to explicit shared object of type {"$T1"}</DisplayString>
+ <Expand>
+ <ExpandedItem>d</ExpandedItem>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QPointer&lt;*&gt;">
+ <DisplayString>guarded pointer to subclass of QObject of type {"$T1"}</DisplayString>
+ <Expand>
+ <Item Name="[is null]">wp.d == 0 || wp.d-&gt;strongref._q_value == 0 || wp.value == 0</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QWeakPointer&lt;*&gt;">
+ <DisplayString>weak reference to shared pointer of type {"$T1"}</DisplayString>
+ <Expand>
+ <Item Name="[is null]">d == 0 || d-&gt;strongref._q_value == 0 || value == 0</Item>
+ <Item Name="[weak referenced]">d-&gt;weakref._q_value</Item>
+ <Item Name="[strong referenced]">d-&gt;strongref._q_value</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QScopedPointer&lt;*&gt;">
+ <DisplayString>scoped pointer to a dynamically allocated object of type {"$T1"}</DisplayString>
+ <Expand>
+ <Item Name="[is null]">!d</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QScopedArrayPointer&lt;*&gt;">
+ <DisplayString>scoped pointer to dynamically allocated array of objects of type {"$T1"}</DisplayString>
+ <Expand>
+ <Item Name="[is null]">!d</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QPair&lt;*,*&gt;">
+ <DisplayString>({first}, {second})</DisplayString>
+ <Expand>
+ <Item Name="[first]">first</Item>
+ <Item Name="[second]">second</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QVector&lt;*&gt;">
+ <AlternativeType Name="##NAMESPACE##::QStack&lt;*&gt;"></AlternativeType>
+ <DisplayString>{{ size = {d-&gt;size} }}</DisplayString>
+ <Expand>
+ <Item Name="[referenced]">d-&gt;ref.atomic._q_value</Item>
+ <ArrayItems>
+ <Size>d-&gt;size</Size>
+ <ValuePointer>($T1*)((reinterpret_cast&lt;char*&gt;(d)) + d-&gt;offset)</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QList&lt;*&gt;">
+ <AlternativeType Name="##NAMESPACE##::QQueue&lt;*&gt;"></AlternativeType>
+ <DisplayString>{{ size = {d-&gt;end - d-&gt;begin} }}</DisplayString>
+ <Expand>
+ <Item Name="[referenced]">d-&gt;ref.atomic._q_value</Item>
+ <IndexListItems>
+ <Size>d-&gt;end - d-&gt;begin</Size>
+ <ValueNode>*reinterpret_cast&lt;$T1*&gt;((sizeof($T1) &gt; sizeof(void*))
+ ? reinterpret_cast&lt;Node*&gt;(d-&gt;array + d-&gt;begin + $i)-&gt;v
+ : reinterpret_cast&lt;$T1*&gt;(d-&gt;array + d-&gt;begin + $i))
+ </ValueNode>
+ </IndexListItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QStringList">
+ <DisplayString>{{ size = {d-&gt;end - d-&gt;begin} }}</DisplayString>
+ <Expand>
+ <Item Name="[referenced]">d-&gt;ref.atomic._q_value</Item>
+ <IndexListItems>
+ <Size>d-&gt;end - d-&gt;begin</Size>
+ <ValueNode>
+ *reinterpret_cast&lt;QString*&gt;((sizeof(QString) &gt; sizeof(void*))
+ ? reinterpret_cast&lt;Node*&gt;(d-&gt;array + d-&gt;begin + $i)-&gt;v
+ : reinterpret_cast&lt;QString*&gt;(d-&gt;array + d-&gt;begin + $i))
+ </ValueNode>
+ </IndexListItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QList&lt;QVariant&gt;">
+ <DisplayString>{{ size = {d-&gt;end - d-&gt;begin} }}</DisplayString>
+ <Expand>
+ <Item Name="[referenced]">d-&gt;ref.atomic._q_value</Item>
+ <IndexListItems>
+ <Size>d-&gt;end - d-&gt;begin</Size>
+ <ValueNode>
+ *reinterpret_cast&lt;QVariant*&gt;((sizeof(QVariant) &gt; sizeof(void*))
+ ? reinterpret_cast&lt;Node*&gt;(d-&gt;array + d-&gt;begin + $i)-&gt;v
+ : reinterpret_cast&lt;QVariant*&gt;(d-&gt;array + d-&gt;begin + $i))
+ </ValueNode>
+ </IndexListItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QLinkedList&lt;*&gt;">
+ <DisplayString>{{ size = {d-&gt;size} }}</DisplayString>
+ <Expand>
+ <Item Name="[referenced]">d-&gt;ref.atomic._q_value</Item>
+ <LinkedListItems>
+ <Size>d-&gt;size</Size>
+ <HeadPointer>d-&gt;n</HeadPointer>
+ <NextPointer>n</NextPointer>
+ <ValueNode>(*(##NAMESPACE##::QLinkedListNode&lt;$T1&gt;*)this).t</ValueNode>
+ </LinkedListItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QMapNode&lt;*,*&gt;">
+ <DisplayString>({key}, {value})</DisplayString>
+ <Expand>
+ <Item Name="[key]">key</Item>
+ <Item Name="[value]">value</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QMap&lt;*,*&gt;">
+ <AlternativeType Name="##NAMESPACE##::QMultiMap&lt;*,*&gt;"/>
+ <DisplayString>{{ size = {d-&gt;size} }}</DisplayString>
+ <Expand>
+ <Item Name="[referenced]">d-&gt;ref.atomic._q_value</Item>
+ <TreeItems>
+ <Size>d-&gt;size</Size>
+ <HeadPointer>d-&gt;header.left</HeadPointer>
+ <LeftPointer>left</LeftPointer>
+ <RightPointer>right</RightPointer>
+ <ValueNode>*((##NAMESPACE##::QMapNode&lt;$T1,$T2&gt;*)this)</ValueNode>
+ </TreeItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QHashNode&lt;*,*&gt;">
+ <DisplayString Condition="next == 0">(empty)</DisplayString>
+ <DisplayString Condition="next != 0">({key}, {value})</DisplayString>
+ <Expand>
+ <Item Name="[key]" Condition="next != 0">key</Item>
+ <Item Name="[value]" Condition="next != 0">value</Item>
+ <Item Name="[next]" Condition="next != 0">next</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QHash&lt;*,*&gt;">
+ <AlternativeType Name="##NAMESPACE##::QMultiHash&lt;*,*&gt;"/>
+ <DisplayString>{{ size = {d-&gt;size} }}</DisplayString>
+ <Expand>
+ <ArrayItems IncludeView="buckets">
+ <Size>d-&gt;numBuckets</Size>
+ <ValuePointer>reinterpret_cast&lt;Node **&gt;(d-&gt;buckets)</ValuePointer>
+ </ArrayItems>
+ <CustomListItems ExcludeView="buckets">
+ <Variable Name="n" InitialValue="d-&gt;numBuckets"/>
+ <Variable Name="bucket" InitialValue="d-&gt;buckets"/>
+ <Variable Name="node" InitialValue="d-&gt;buckets[0]"/>
+ <Variable Name="keyValuePair" InitialValue="reinterpret_cast&lt;Node *&gt;(0)"/>
+ <Size>d-&gt;size</Size>
+ <Loop>
+ <Break Condition="n == 0"/>
+ <Exec>node = *(bucket++)</Exec>
+ <Exec>--n</Exec>
+ <Loop>
+ <Break Condition="!node || !node-&gt;next"/>
+ <Exec>keyValuePair = reinterpret_cast&lt;Node *&gt;(node)</Exec>
+ <Item Name="[{keyValuePair-&gt;key}]">keyValuePair-&gt;value</Item>
+ <Exec>node = node-&gt;next</Exec>
+ </Loop>
+ </Loop>
+ </CustomListItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QHashNode&lt;*,##NAMESPACE##::QHashDummyValue&gt;">
+ <DisplayString Condition="next == 0">(empty)</DisplayString>
+ <DisplayString Condition="next != 0">({key})</DisplayString>
+ <Expand>
+ <Item Name="[key]" Condition="next != 0">key</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QSet&lt;*&gt;">
+ <DisplayString>{{ size = {q_hash.d-&gt;size} }}</DisplayString>
+ <Expand>
+ <ExpandedItem>q_hash</ExpandedItem>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QCache&lt;*,*&gt;::Node">
+ <DisplayString>({*keyPtr}, {*t})</DisplayString>
+ <Expand>
+ <Item Name="[key]">*keyPtr</Item>
+ <Item Name="[value]">*t</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QCache&lt;*,*&gt;">
+ <DisplayString>{{ size = {hash.d-&gt;size} }}</DisplayString>
+ <Expand>
+ <Item Name="[max coast]">mx</Item>
+ <Item Name="[total coast]">total</Item>
+ <Item Name="[referenced]">hash.d-&gt;ref.atomic._q_value</Item>
+ <LinkedListItems>
+ <Size>hash.d-&gt;size</Size>
+ <HeadPointer>f</HeadPointer>
+ <NextPointer>n</NextPointer>
+ <ValueNode>*((Node*)this)</ValueNode>
+ </LinkedListItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QStandardItemPrivate">
+ <Intrinsic Name="memberOffset" Expression="sizeof(QStandardItemModel *)
+ + sizeof(QStandardItem *)
+ + sizeof(int *)
+ + sizeof(int *)
+ + (sizeof(int) * count)">
+ <Parameter Name="count" Type="int"/>
+ </Intrinsic>
+ <Intrinsic Name="rows" Expression="*((int*)(((char*)(this)) + memberOffset(0)))" />
+ <Intrinsic Name="columns" Expression="*((int*)(((char*)(this)) + memberOffset(1)))" />
+ </Type>
+
+ <Type Name="##NAMESPACE##::QStandardItem">
+ <DisplayString>{{ row count = {(*d_ptr.d).rows()}, column count = {(*d_ptr.d).columns()} }}</DisplayString>
+ <Expand>
+ <Item Name="[d]">d_ptr.d,!</Item>
+ <Item Name="[row count]">(*d_ptr.d).rows()</Item>
+ <Item Name="[column count]">(*d_ptr.d).columns()</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QVariant">
+ <!--Region DisplayString QVariant-->
+
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::UnknownType">Invalid</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::Bool">{d.data.b}</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::Int">{d.data.i}</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::UInt">{d.data.u}</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::LongLong">{d.data.ll}</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::ULongLong">{d.data.ull}</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::Double">{d.data.d}</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QChar">{d.data.c}</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QVariantMap">
+ {*((##NAMESPACE##::QMap&lt;##NAMESPACE##::QString,##NAMESPACE##::QVariant&gt;*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QVariantList">
+ {*((##NAMESPACE##::QList&lt;##NAMESPACE##::QVariant&gt;*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QString">
+ {*((##NAMESPACE##::QString*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QStringList">
+ {*((##NAMESPACE##::QStringList*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QByteArray">
+ {*((##NAMESPACE##::QByteArray*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QBitArray">
+ {*((##NAMESPACE##::QBitArray*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QDate">
+ {*((##NAMESPACE##::QDate*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QTime">
+ {*((##NAMESPACE##::QTime*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QDateTime">DateTime</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QUrl">Url</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QLocale">Locale</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QRect">
+ {*((##NAMESPACE##::QRect*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QRectF">
+ {*((##NAMESPACE##::QRectF*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QSize">
+ {*((##NAMESPACE##::QSize*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QSizeF">
+ {*((##NAMESPACE##::QSizeF*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QLine">
+ {*((##NAMESPACE##::QLine*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QLineF">
+ {*((##NAMESPACE##::QLineF*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QPoint">
+ {*((##NAMESPACE##::QPoint*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QPointF">
+ {*((##NAMESPACE##::QPointF*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QRegExp">RegExp</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QRegularExpression">RegularExpression</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QVariantHash">
+ {*((##NAMESPACE##::QHash&lt;##NAMESPACE##::QString,##NAMESPACE##::QVariant&gt;*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))}
+ </DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QEasingCurve">EasingCurve</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QUuid">Uuid</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QModelIndex">ModelIndex</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::LastCoreType">LastCoreType</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QFont">Font</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QPixmap">Pixmap</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QBrush">Brush</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QColor">Color</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QPalette">Palette</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QImage">Image</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QPolygon">Polygon</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QRegion">Region</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QBitmap">Bitmap</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QCursor">Cursor</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QKeySequence">KeySequence</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QPen">Pen</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QTextLength">TextLength</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QTextFormat">TextFormat</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QMatrix">Matrix</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QTransform">Transform</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QMatrix4x4">Matrix4x4</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QVector2D">Vector2D</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QVector3D">Vector3D</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QVector4D">Vector4D</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QQuaternion">Quaternion</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QPolygonF">PolygonF</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QIcon">Icon</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::LastGuiType">LastGuiType</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::QSizePolicy">SizePolicy</DisplayString>
+ <DisplayString Condition="d.type == ##NAMESPACE##::QMetaType::User">UserType</DisplayString>
+ <DisplayString Condition="d.type == 0xffffffff">LastType</DisplayString>
+
+ <!--End region DisplayString QVariant-->
+
+ <!--Region DisplayView QVariant-->
+
+ <StringView Condition="d.type == ##NAMESPACE##::QMetaType::QChar">d.data.c</StringView>
+
+ <StringView Condition="d.type == ##NAMESPACE##::QMetaType::QString">
+ *((##NAMESPACE##::QString*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
+ </StringView>
+
+ <StringView Condition="d.type == ##NAMESPACE##::QMetaType::QByteArray">
+ *((##NAMESPACE##::QByteArray*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
+ </StringView>
+
+ <!--End region DisplayView QVariant-->
+
+ <!--Region Expand QVariant-->
+
+ <Expand>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QVariantMap">
+ *((##NAMESPACE##::QMap&lt;##NAMESPACE##::QString,##NAMESPACE##::QVariant&gt;*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QVariantList">
+ *((##NAMESPACE##::QList&lt;##NAMESPACE##::QVariant&gt;*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QString">
+ *((##NAMESPACE##::QString*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QStringList">
+ *((##NAMESPACE##::QStringList*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QByteArray">
+ *((##NAMESPACE##::QByteArray*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QBitArray">
+ *((##NAMESPACE##::QBitArray*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QDate">
+ *((##NAMESPACE##::QDate*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QTime">
+ *((##NAMESPACE##::QTime*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QRect">
+ *((##NAMESPACE##::QRect*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QRectF">
+ *((##NAMESPACE##::QRectF*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QSize">
+ *((##NAMESPACE##::QSize*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QSizeF">
+ *((##NAMESPACE##::QSizeF*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QLine">
+ *((##NAMESPACE##::QLine*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QLineF">
+ *((##NAMESPACE##::QLineF*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QPoint">
+ *((##NAMESPACE##::QPoint*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QPointF">
+ *((##NAMESPACE##::QPointF*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
+ </ExpandedItem>
+ <ExpandedItem Condition="d.type == ##NAMESPACE##::QMetaType::QVariantHash">
+ *((##NAMESPACE##::QHash&lt;##NAMESPACE##::QString,##NAMESPACE##::QVariant&gt;*)(d.is_shared ? d.data.shared-&gt;ptr
+ : reinterpret_cast&lt;const void *&gt;(&amp;d.data.ptr)))
+ </ExpandedItem>
+ </Expand>
+
+ <!--End region Expand QVariant-->
+ </Type>
+
+</AutoVisualizer>
diff --git a/QtMSBuild/QtMsBuild/qt6.natvis.xml b/QtMSBuild/QtMsBuild/qt6.natvis.xml
new file mode 100644
index 00000000..96ecb7e7
--- /dev/null
+++ b/QtMSBuild/QtMsBuild/qt6.natvis.xml
@@ -0,0 +1,406 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ****************************************************************************
+ **
+ ** Copyright (C) 2022 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the Qt VS Tools.
+ **
+ ** $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$
+ **
+ ****************************************************************************
+-->
+
+<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
+
+ <Type Name="##NAMESPACE##::QSpecialInteger&lt;*&gt;">
+ <DisplayString>{val}</DisplayString>
+ <Expand>
+ <Item Name="[value]">val</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QBasicAtomicInteger&lt;*&gt;">
+ <DisplayString>{_q_value}</DisplayString>
+ <Expand>
+ <Item Name="[value]">_q_value</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QBasicAtomicPointer&lt;*&gt;">
+ <Intrinsic Name="isNull" Expression="value()==0" />
+ <Intrinsic Name="value" Expression="_q_value.value()" />
+ <DisplayString Condition="isNull()">empty</DisplayString>
+ <DisplayString Condition="!isNull()">{_q_value}</DisplayString>
+ <Expand>
+ <Item Name=" " Condition="!isNull()">*value()</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QPoint">
+ <AlternativeType Name="##NAMESPACE##::QPointF"/>
+ <DisplayString>{{ x = {xp}, y = {yp} }}</DisplayString>
+ <Expand>
+ <Item Name="[x]">xp</Item>
+ <Item Name="[y]">yp</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QRect">
+ <DisplayString>{{ x = {x1}, y = {y1}, width = {x2 - x1 + 1}, height = {y2 - y1 + 1} }}</DisplayString>
+ <Expand>
+ <Item Name="[x]">x1</Item>
+ <Item Name="[y]">y1</Item>
+ <Item Name="[width]">x2 - x1 + 1</Item>
+ <Item Name="[height]">y2 - y1 + 1</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QRectF">
+ <DisplayString>{{ x = {xp}, y = {yp}, width = {w}, height = {h} }}</DisplayString>
+ <Expand>
+ <Item Name="[x]">xp</Item>
+ <Item Name="[y]">yp</Item>
+ <Item Name="[width]">w</Item>
+ <Item Name="[height]">h</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QSize">
+ <AlternativeType Name="##NAMESPACE##::QSizeF"/>
+ <DisplayString>{{ width = {wd}, height = {ht} }}</DisplayString>
+ <Expand>
+ <Item Name="[width]">wd</Item>
+ <Item Name="[height]">ht</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QLine">
+ <AlternativeType Name="##NAMESPACE##::QLineF"/>
+ <DisplayString>{{ start point = {pt1}, end point = {pt2} }}</DisplayString>
+ <Expand>
+ <Synthetic Name="[start point]">
+ <DisplayString>{pt1}</DisplayString>
+ <Expand>
+ <ExpandedItem>pt1</ExpandedItem>
+ </Expand>
+ </Synthetic>
+ <Synthetic Name="[end point]">
+ <DisplayString>{pt2}</DisplayString>
+ <Expand>
+ <ExpandedItem>pt2</ExpandedItem>
+ </Expand>
+ </Synthetic>
+
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QPolygon">
+ <DisplayString>{{ size={d-&gt;size} }}</DisplayString>
+ <Expand>
+ <Item Name="[referenced]">d-&gt;ref.atomic._q_value</Item>
+ <ArrayItems>
+ <Size>d-&gt;size</Size>
+ <ValuePointer>(QPoint*)((reinterpret_cast&lt;char*&gt;(d)) + d-&gt;offset)</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QPolygonF">
+ <DisplayString>{{ size={d-&gt;size} }}</DisplayString>
+ <Expand>
+ <Item Name="[closed]">
+ d-&gt;size &gt; 0
+ &amp;&amp; ((((QPointF*)((reinterpret_cast&lt;char*&gt;(d)) + d-&gt;offset)[0]).xp
+ == (((QPointF*)((reinterpret_cast&lt;char*&gt;(d)) + d-&gt;offset)[d-&gt;size - 1]).xp)
+ &amp;&amp; ((((QPointF*)((reinterpret_cast&lt;char*&gt;(d)) + d-&gt;offset)[0]).yp
+ == (((QPointF*)((reinterpret_cast&lt;char*&gt;(d)) + d-&gt;offset)[d-&gt;size - 1]).yp)
+ </Item>
+ <Item Name="[referenced]">d-&gt;ref.atomic._q_value</Item>
+ <ArrayItems>
+ <Size>d-&gt;size</Size>
+ <ValuePointer>(QPointF*)((reinterpret_cast&lt;char*&gt;(d)) + d-&gt;offset)</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QVector2D">
+ <DisplayString>{{ x = {xp}, y = {yp} }}</DisplayString>
+ <Expand>
+ <Item Name="[x]">xp</Item>
+ <Item Name="[y]">yp</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QVector3D">
+ <DisplayString>{{ x = {xp}, y = {yp}, z = {zp} }}</DisplayString>
+ <Expand>
+ <Item Name="[x]">xp</Item>
+ <Item Name="[y]">yp</Item>
+ <Item Name="[z]">zp</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QVector4D">
+ <DisplayString>{{ x = {xp}, y = {yp}, z = {zp}, w = {wp} }}</DisplayString>
+ <Expand>
+ <Item Name="[x]">xp</Item>
+ <Item Name="[y]">yp</Item>
+ <Item Name="[z]">zp</Item>
+ <Item Name="[w]">wp</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QMatrix">
+ <DisplayString>
+ {{ m11 = {_m11}, m12 = {_m12}, m21 = {_m21}, m22 = {_m22}, ... }}
+ </DisplayString>
+ <Expand>
+ <Item Name="[m11]">_m11</Item>
+ <Item Name="[m12]">_m12</Item>
+ <Item Name="[m21]">_m21</Item>
+ <Item Name="[m22]">_m22</Item>
+ <Item Name="[dx]">_dx</Item>
+ <Item Name="[dy]">_dy</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QMatrix4x4">
+ <DisplayString>
+ {{ m11 = {m[0][0]}, m12 = {m[1][0]}, m13 = {m[2][0]}, m14 = {m[3][0]}, ... }}
+ </DisplayString>
+ <Expand>
+ <Item Name="[m11]">m[0][0]</Item>
+ <Item Name="[m12]">m[1][0]</Item>
+ <Item Name="[m13]">m[2][0]</Item>
+ <Item Name="[m14]">m[3][0]</Item>
+ <Item Name="[m21]">m[0][1]</Item>
+ <Item Name="[m22]">m[1][1]</Item>
+ <Item Name="[m23]">m[2][1]</Item>
+ <Item Name="[m24]">m[3][1]</Item>
+ <Item Name="[m31]">m[0][2]</Item>
+ <Item Name="[m32]">m[1][2]</Item>
+ <Item Name="[m33]">m[2][2]</Item>
+ <Item Name="[m34]">m[3][2]</Item>
+ <Item Name="[m41]">m[0][3]</Item>
+ <Item Name="[m42]">m[1][3]</Item>
+ <Item Name="[m43]">m[2][3]</Item>
+ <Item Name="[m44]">m[3][3]</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QSizePolicy">
+ <DisplayString>
+ {{ horizontal = {static_cast&lt;Policy&gt;(bits.horPolicy)}, vertical = {static_cast&lt;Policy&gt;(bits.verPolicy)}, type = {ControlType(1 &lt;&lt; bits.ctype)} }}
+ </DisplayString>
+ <Expand>
+ <Synthetic Name="[vertical policy]">
+ <DisplayString>QSizePolicy::Policy::{static_cast&lt;Policy&gt;(bits.verPolicy)}</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[horizontal policy]">
+ <DisplayString>QSizePolicy::Policy::{static_cast&lt;Policy&gt;(bits.horPolicy)}</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[control type]">
+ <DisplayString>QSizePolicy::ControlType::{ControlType(1 &lt;&lt; bits.ctype)}</DisplayString>
+ </Synthetic>
+ <Synthetic Name="[expanding directions]">
+ <DisplayString
+ Condition="(static_cast&lt;Policy&gt;(bits.verPolicy) &amp; ExpandFlag)">
+ Qt::Vertical (2)
+ </DisplayString>
+ <DisplayString
+ Condition="(static_cast&lt;Policy&gt;(bits.horPolicy) &amp; ExpandFlag)">
+ Qt::Horizontal (1)
+ </DisplayString>
+ </Synthetic>
+ <Item Name="[vertical stretch]">static_cast&lt;int&gt;(bits.verStretch)</Item>
+ <Item Name="[horizontal stretch]">static_cast&lt;int&gt;(bits.horStretch)</Item>
+ <Item Name="[has height for width]">bits.hfw == 1</Item>
+ <Item Name="[has width for height]">bits.wfh == 1</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QChar">
+ <DisplayString>{ucs,c}</DisplayString>
+ <StringView>ucs,c</StringView>
+ <Expand>
+ <Item Name="[latin 1]">ucs > 0xff ? '\0' : char(ucs),c</Item>
+ <Item Name="[unicode]">ucs,c</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QString">
+ <DisplayString>&quot;{(reinterpret_cast&lt;unsigned short*&gt;(d.ptr)),sub}&quot;</DisplayString>
+ <StringView>(reinterpret_cast&lt;unsigned short*&gt;(d.ptr)),sub</StringView>
+ <Expand>
+ <Item Name="[size]">d.size</Item>
+ <ArrayItems>
+ <Size>d.size</Size>
+ <ValuePointer>d.ptr</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QStringRef">
+ <DisplayString Condition="m_string == nullptr">{m_string,[m_size]} u""</DisplayString>
+ <DisplayString Condition="m_string != nullptr">{m_string-&gt;d.ptr+m_position,[m_size]}</DisplayString>
+ <StringView Condition="m_string == nullptr">""</StringView>
+ <StringView Condition="m_string != nullptr">m_string,[m_position+m_size]</StringView>
+ <Expand>
+ <Item Name="[position]" ExcludeView="simple">m_position</Item>
+ <Item Name="[size]" ExcludeView="simple">m_size</Item>
+ <ArrayItems Condition="m_string != nullptr">
+ <Size>m_size</Size>
+ <ValuePointer>m_string-&gt;d.ptr+m_position</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QStringView">
+ <DisplayString>{m_data,[m_size]}</DisplayString>
+ <StringView>m_data,[m_size]</StringView>
+ <Expand>
+ <Item Name="[size]" ExcludeView="simple">m_size</Item>
+ <ArrayItems>
+ <Size>m_size</Size>
+ <ValuePointer>m_data</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QByteArray">
+ <DisplayString>&quot;{((reinterpret_cast&lt;char*&gt;(d.ptr))),sb}&quot;</DisplayString>
+ <StringView>((reinterpret_cast&lt;char*&gt;(d.ptr))),sb</StringView>
+ <Expand>
+ <Item Name="[size]">d.size</Item>
+ <ArrayItems>
+ <Size>d.size</Size>
+ <ValuePointer>d.ptr</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QUrl">
+ <Intrinsic Name="isEmpty" Expression="size==0">
+ <Parameter Name="size" Type="int"/>
+ </Intrinsic>
+ <Intrinsic Name="memberOffset" Expression="sizeof(QAtomicInt) + sizeof(int) + (sizeof(QString) * count)">
+ <Parameter Name="count" Type="int"/>
+ </Intrinsic>
+ <Intrinsic Name="scheme" Expression="*((QString*)(((char*)(d) + memberOffset(0))))" />
+ <Intrinsic Name="username" Expression="*((QString*)(((char*)(d) + memberOffset(1))))" />
+ <Intrinsic Name="password" Expression="*((QString*)(((char*)(d) + memberOffset(2))))" />
+ <Intrinsic Name="host" Expression="*((QString*)(((char*)(d) + memberOffset(3))))" />
+ <Intrinsic Name="path" Expression="*((QString*)(((char*)(d) + memberOffset(4))))" />
+ <Intrinsic Name="query" Expression="*((QString*)(((char*)(d) + memberOffset(5))))" />
+ <Intrinsic Name="fragment" Expression="*((QString*)(((char*)(d) + memberOffset(6))))" />
+
+ <DisplayString Condition="!isEmpty(scheme().d-&gt;size)">{scheme()}://{host()}{path()}</DisplayString>
+ <DisplayString Condition="isEmpty(scheme().d-&gt;size)">{path()}</DisplayString>
+ <Expand>
+ <Item Name="[scheme]">scheme()</Item>
+ <Item Name="[username]">username()</Item>
+ <Item Name="[password]">password()</Item>
+ <Item Name="[host]">host()</Item>
+ <Item Name="[path]">path()</Item>
+ <Item Name="[query]">query()</Item>
+ <Item Name="[fragment]">fragment()</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QDate">
+ <DisplayString>{{ julian day = {jd} }}</DisplayString>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QTime">
+ <Intrinsic Name="hour" Expression="mds / 3600000" />
+ <Intrinsic Name="minute" Expression="(mds % 3600000) / 60000" />
+ <Intrinsic Name="second" Expression="(mds / 1000) % 60" />
+ <Intrinsic Name="millisecond" Expression="mds % 1000" />
+ <DisplayString Condition="mds == 1">{{ millisecond = {mds} }}</DisplayString>
+ <DisplayString Condition="mds != 1">{{ milliseconds = {mds} }}</DisplayString>
+ <Expand>
+ <Item Name="[hour]"
+ Condition="(mds / 3600000) == 1">hour(), d</Item>
+ <Item Name="[hours]"
+ Condition="(mds / 3600000) != 1">hour(), d</Item>
+ <Item Name="[minute]"
+ Condition="((mds % 3600000) / 60000) == 1">minute(), d</Item>
+ <Item Name="[minutes]"
+ Condition="((mds % 3600000) / 60000) != 1">minute(), d</Item>
+ <Item Name="[second]"
+ Condition="((mds / 1000) % 60) == 1">second(), d</Item>
+ <Item Name="[seconds]"
+ Condition="((mds / 1000) % 60) != 1">second(), d</Item>
+ <Item Name="[millisecond]"
+ Condition="(mds % 1000) == 1">millisecond(), d</Item>
+ <Item Name="[milliseconds]"
+ Condition="(mds % 1000) != 1">millisecond(), d</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QPair&lt;*,*&gt;">
+ <DisplayString>({first}, {second})</DisplayString>
+ <Expand>
+ <Item Name="[first]">first</Item>
+ <Item Name="[second]">second</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QList&lt;*&gt;">
+ <AlternativeType Name="##NAMESPACE##::QVector&lt;*&gt;"/>
+ <DisplayString>{{ size={d.size} }}</DisplayString>
+ <Expand>
+ <ArrayItems>
+ <Size>d.size</Size>
+ <ValuePointer>reinterpret_cast&lt;$T1*&gt;(d.ptr)</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QVarLengthArray&lt;*&gt;">
+ <DisplayString>{{ size={s} }}</DisplayString>
+ <Expand>
+ <Item Name="[capacity]">a</Item>
+ <ArrayItems>
+ <Size>s</Size>
+ <ValuePointer>ptr</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QMap&lt;*,*&gt;">
+ <AlternativeType Name="##NAMESPACE##::QMultiMap&lt;*,*&gt;"/>
+ <DisplayString>{{ size={d.d-&gt;m._Mypair._Myval2._Myval2._Mysize} }}</DisplayString>
+ <Expand>
+ <Item Name="[std::map]">d.d-&gt;m</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="##NAMESPACE##::QHash&lt;*,*&gt;">
+ <AlternativeType Name="##NAMESPACE##::QMultiHash&lt;*,*&gt;"/>
+ <DisplayString>{{ size = {d-&gt;size} }}</DisplayString>
+ <Expand>
+ <Item Name="[referenced]">d-&gt;ref.atomic._q_value</Item>
+ </Expand>
+ </Type>
+
+</AutoVisualizer>
diff --git a/QtMSBuild/QtMsBuild/qt_globals.targets b/QtMSBuild/QtMsBuild/qt_globals.targets
index 94d64d9a..661bc144 100644
--- a/QtMSBuild/QtMsBuild/qt_globals.targets
+++ b/QtMSBuild/QtMsBuild/qt_globals.targets
@@ -776,4 +776,29 @@
<Target Name="QtLeaveCriticalSection_OnError">
<CriticalSection Lock="false" Name="$(ProjectGuid)" />
</Target>
+
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ /// TARGET QtNatvis
+ /////////////////////////////////////////////////////////////////////////////////////////////////
+ // Copies the .natvis file matching the Qt version and replaces the namespace placeholder
+ // -->
+ <Target Name="QtNatvis" BeforeTargets="Link"
+ Condition="'$(Configuration)' == 'Debug' AND '$(LinkNatvisFile)' == 'true'"
+ Inputs="$(MSBuildProjectFile);$(QtMsBuild)\qt$(QtVersionMajor).natvis.xml"
+ Outputs="$(IntDir)\qt.natvis">
+ <PropertyGroup>
+ <InputFile>$(QtMsBuild)\qt$(QtVersionMajor).natvis.xml</InputFile>
+ <NatvisLinkFile>$(IntDir)\qt.natvis</NatvisLinkFile>
+ </PropertyGroup>
+ <WriteLinesToFile Condition="'$(QtNamespace)' == ''"
+ Overwrite="true"
+ File="$(NatvisLinkFile)"
+ Lines="$([System.IO.File]::ReadAllText($(InputFile)).Replace('##NAMESPACE##::',''))" />
+ <WriteLinesToFile Condition="'$(QtNamespace)' != ''"
+ Overwrite="true"
+ File="$(NatvisLinkFile)"
+ Lines="$([System.IO.File]::ReadAllText($(InputFile)).Replace('##NAMESPACE##','$(QtNamespace)'))" />
+ </Target>
+
</Project>
diff --git a/QtMSBuild/QtMsBuild/qt_private.props b/QtMSBuild/QtMsBuild/qt_private.props
index 30cc52c6..f688ae1e 100644
--- a/QtMSBuild/QtMsBuild/qt_private.props
+++ b/QtMSBuild/QtMsBuild/qt_private.props
@@ -196,6 +196,43 @@
<!--
/////////////////////////////////////////////////////////////////////////////////////////////////
+ // Figure out depending on the user settings if we need to link the .natvis file into the PDB
+ // file. Reads the content of qconfig.pri to find Qt's namespace if set. Predefines the path to
+ // the .natvis file used during link which corresponds to the final output generated by the
+ // QtNatvis target.
+ // Evaluation order: first look at the project settings, if empty take from the global settings.
+ // -->
+ <PropertyGroup>
+ <LinkNatvisFile>$(QtLinkNatvisFile)</LinkNatvisFile>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(QtLinkNatvisFile)' == ''">
+ <LinkNatvisRegValue>$([MSBuild]::GetRegistryValue(
+ 'HKEY_CURRENT_USER\SOFTWARE\Digia\Qt5VS2017','LinkNatvis'
+ ))</LinkNatvisRegValue>
+ <LinkNatvisFile>true</LinkNatvisFile>
+ <LinkNatvisFile Condition="'$(LinkNatvisRegValue)' == '0'">false</LinkNatvisFile>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)' == 'Debug' AND '$(LinkNatvisFile)' == 'true'">
+ <NatvisLinkFile>$(IntDir)\qt.natvis</NatvisLinkFile>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)' == 'Debug'
+ AND '$(LinkNatvisFile)' == 'true' AND '$(QtInstallDir)' != ''">
+ <QConfigPriPath>$([System.IO.Path]::Combine('$(QtInstallDir)',
+ 'mkspecs', 'qconfig.pri'
+ ))</QConfigPriPath>
+ <QConfigPriContent>$([MSBuild]::Unescape(
+ $([System.IO.File]::ReadAllText('$(QConfigPriPath)')
+ .Replace('&#xD;&#xA;', ';')
+ .Replace(' =', '=')
+ .Replace('= ', '='))
+ ));</QConfigPriContent>
+ <QtNamespace>$([System.Text.RegularExpressions.Regex]::Match($(QConfigPriContent),
+ 'QT_NAMESPACE=([a-zA-Z0-9]+);').get_Groups().get_Item(1)
+ )</QtNamespace>
+ </PropertyGroup>
+
+ <!--
+ /////////////////////////////////////////////////////////////////////////////////////////////////
// Default item metadata
// -->
<ItemDefinitionGroup>
@@ -222,7 +259,10 @@
>%(SharedLibrarySearchPath);$(Qt_LIBPATH_)</SharedLibrarySearchPath>
<AdditionalOptions Condition="'$(Qt_LINK_OPTIONS_)' != ''"
>$(Qt_LINK_OPTIONS_) %(AdditionalOptions)</AdditionalOptions>
+ <AdditionalOptions Condition="'$(Configuration)' == 'Debug' AND '$(LinkNatvisFile)' == 'true'"
+ >/NATVIS:$(NatvisLinkFile) %(AdditionalOptions)</AdditionalOptions>
</Link>
+
</ItemDefinitionGroup>
<!--
diff --git a/QtMSBuild/QtMsBuild/qt_settings.xml b/QtMSBuild/QtMsBuild/qt_settings.xml
index ba654200..9c1b2549 100644
--- a/QtMSBuild/QtMsBuild/qt_settings.xml
+++ b/QtMSBuild/QtMsBuild/qt_settings.xml
@@ -44,6 +44,7 @@
<Category Name="QtSettings_03_QMake" DisplayName="qmake"/>
<Category Name="QtSettings_04_QML" DisplayName="QML"/>
<Category Name="QtSettings_05_AdditionalOptions" DisplayName="Qt Additional Compiler Options"/>
+ <Category Name="QtSettings_06_AdditionalLinkOptions" DisplayName="Qt Additional Linker Options"/>
</Rule.Categories>
<EnumProperty
Name="Keyword"
@@ -168,4 +169,16 @@ with '/' or '-', and separate them with spaces." />
DisplayName="Show in Build Log"
Description="
Print to the build log the list of additional options passed to the compiler." />
+ <EnumProperty
+ Name="QtLinkNatvisFile"
+ Category="QtSettings_06_AdditionalLinkOptions"
+ DisplayName="Embed .natvis file into PDB"
+ Description=
+"Embeds the debugger visualizations (.natvis file) into the PDB file
+generated by LINK. The user-specific Natvis directory (for example,
+%USERPROFILE%\\Documents\\Visual Studio 2022\\Visualizers) still takes precedence
+over the embedded one.">
+ <EnumValue Name="false" DisplayName="No" />
+ <EnumValue Name="true" DisplayName="Yes" />
+ </EnumProperty>
</Rule>
diff --git a/QtVsTools.Package/Options/QtOptionsPage.cs b/QtVsTools.Package/Options/QtOptionsPage.cs
index 3551b55b..f1612bf2 100644
--- a/QtVsTools.Package/Options/QtOptionsPage.cs
+++ b/QtVsTools.Package/Options/QtOptionsPage.cs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2020 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -92,6 +92,11 @@ namespace QtVsTools.Options
[String("Notifications_Installed")] Installed,
}
+ public enum Natvis
+ {
+ [String("LinkNatvis")] Link,
+ }
+
public enum Timeout : uint { Disabled = 0 }
class TimeoutConverter : EnumConverter
@@ -233,6 +238,15 @@ namespace QtVsTools.Options
[TypeConverter(typeof(EnableDisableConverter))]
public bool NotifyInstalled { get; set; }
+ [Category("Natvis")]
+ [DisplayName("Embed .natvis file into PDB")]
+ [Description("Embeds the debugger visualizations (.natvis file) into the PDB file"
+ + " generated by LINK. The user-specific Natvis directory (for example,"
+ + " %USERPROFILE%\\Documents\\Visual Studio 2022\\Visualizers) still takes precedence"
+ + " over the embedded one.")]
+ [TypeConverter(typeof(EnableDisableConverter))]
+ public bool LinkNatvis { get; set; }
+
public override void ResetSettings()
{
ThreadHelper.ThrowIfNotOnUIThread();
@@ -248,6 +262,7 @@ namespace QtVsTools.Options
BuildDebugInformation = false;
BuildLoggerVerbosity = LoggerVerbosity.Quiet;
NotifyInstalled = true;
+ LinkNatvis = true;
////////
// Get Qt Help keyboard shortcut
@@ -288,6 +303,7 @@ namespace QtVsTools.Options
Load(() => BuildDebugInformation, key, BkgBuild.DebugInfo);
Load(() => BuildLoggerVerbosity, key, BkgBuild.LoggerVerbosity);
Load(() => NotifyInstalled, key, Notifications.Installed);
+ Load(() => LinkNatvis, key, Natvis.Link);
}
} catch (Exception exception) {
Messages.Print(
@@ -322,6 +338,7 @@ namespace QtVsTools.Options
Save(BuildDebugInformation, key, BkgBuild.DebugInfo);
Save(BuildLoggerVerbosity, key, BkgBuild.LoggerVerbosity);
Save(NotifyInstalled, key, Notifications.Installed);
+ Save(LinkNatvis, key, Natvis.Link);
}
} catch (Exception exception) {
Messages.Print(
diff --git a/QtVsTools.Package/Package/DteEventsHandler.cs b/QtVsTools.Package/Package/DteEventsHandler.cs
index 735abb16..30ca31c0 100644
--- a/QtVsTools.Package/Package/DteEventsHandler.cs
+++ b/QtVsTools.Package/Package/DteEventsHandler.cs
@@ -138,15 +138,7 @@ namespace QtVsTools
if (selectedProject != null) {
if (QtProject.GetFormatVersion(selectedProject) >= Resources.qtMinFormatVersion_Settings)
return;
- var qtProject = QtProject.Create(selectedProject);
- if (qtProject != null) {
- qtProject.SetQtEnvironment();
-
- var qtVersion = qtProject.GetQtVersion();
- var versionInfo = QtVersionManager.The().GetVersionInfo(qtVersion);
- if (!string.IsNullOrEmpty(versionInfo.Namespace()))
- QtVsToolsPackage.Instance.CopyNatvisFiles(versionInfo.Namespace());
- }
+ QtProject.Create(selectedProject)?.SetQtEnvironment();
}
}
diff --git a/QtVsTools.Package/QtVsToolsPackage.cs b/QtVsTools.Package/QtVsToolsPackage.cs
index b3801d71..d4437f33 100644
--- a/QtVsTools.Package/QtVsToolsPackage.cs
+++ b/QtVsTools.Package/QtVsToolsPackage.cs
@@ -279,7 +279,7 @@ namespace QtVsTools
}
CopyTextMateLanguageFiles();
- CopyNatvisFiles();
+ DeleteNatvisFiles();
Messages.Print(string.Format("\r\n"
+ "== Qt Visual Studio Tools version {0}\r\n"
@@ -379,33 +379,7 @@ namespace QtVsTools
}
}
- private void CopyNatvisFile(string filename, string qtNamespace)
- {
- try {
- string natvis = File.ReadAllText(Path.Combine(PkgInstallPath, filename));
-
- string natvisFile;
- if (string.IsNullOrEmpty(qtNamespace)) {
- natvis = natvis.Replace("##NAMESPACE##::", string.Empty);
- natvisFile = Path.GetFileNameWithoutExtension(filename);
- } else {
- natvis = natvis.Replace("##NAMESPACE##", qtNamespace);
- natvisFile = string.Format(filename.Substring(0, filename.IndexOf('.'))
- + "_{0}.natvis", qtNamespace.Replace("::", "_"));
- }
-
- if (!Directory.Exists(visualizersPath))
- Directory.CreateDirectory(visualizersPath);
-
- File.WriteAllText(Path.Combine(visualizersPath, natvisFile),
- natvis, System.Text.Encoding.UTF8);
- } catch (Exception e) {
- Messages.Print(
- e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
- }
- }
-
- public string GetNatvisPath()
+ public void GetNatvisPath()
{
ThreadHelper.ThrowIfNotOnUIThread();
@@ -427,14 +401,23 @@ namespace QtVsTools
@"Visual Studio 2017\Visualizers\");
#endif
}
- return visualizersPath;
}
- public void CopyNatvisFiles(string qtNamespace = null)
+ private void DeleteNatvisFiles()
{
- string[] files = { "qt5.natvis.xml", "qt6.natvis.xml" };
- foreach (var file in files)
- CopyNatvisFile(file, qtNamespace);
+ try {
+ if (!Directory.Exists(visualizersPath))
+ return;
+
+ string[] names = { "qt5.natvis", "qt6.natvis" };
+ foreach (var name in names) {
+ var file = Path.Combine(visualizersPath, name);
+ if (File.Exists(file))
+ File.Delete(file);
+ }
+ } catch (Exception e) {
+ Messages.Print(e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace);
+ }
}
public I GetService<T, I>()