Skip to content

Commit b63aef1

Browse files
committed
Partial plumbing
1 parent 33dc362 commit b63aef1

File tree

4 files changed

+77
-13
lines changed

4 files changed

+77
-13
lines changed

natvis/cppwinrt_visualizer.cpp

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,9 @@ void LoadMetadata(DkmProcess* process, WCHAR const* processPath, std::string_vie
118118
}
119119
}
120120

121-
TypeDef FindType(DkmProcess* process, std::string_view const& typeName)
121+
TypeDef FindSimpleType(DkmProcess* process, std::string_view const& typeName)
122122
{
123+
XLANG_ASSERT(typeName.find('<') == std::string_view::npos);
123124
auto type = db_cache->find(typeName);
124125
if (!type)
125126
{
@@ -135,8 +136,9 @@ TypeDef FindType(DkmProcess* process, std::string_view const& typeName)
135136
return type;
136137
}
137138

138-
TypeDef FindType(DkmProcess* process, std::string_view const& typeNamespace, std::string_view const& typeName)
139+
TypeDef FindSimpleType(DkmProcess* process, std::string_view const& typeNamespace, std::string_view const& typeName)
139140
{
141+
XLANG_ASSERT(typeName.find('<') == std::string_view::npos);
140142
auto type = db_cache->find(typeNamespace, typeName);
141143
if (!type)
142144
{
@@ -148,6 +150,36 @@ TypeDef FindType(DkmProcess* process, std::string_view const& typeNamespace, std
148150
return type;
149151
}
150152

153+
TypeSig FindType(DkmProcess* process, std::string_view const& typeName)
154+
{
155+
auto paramIndex = typeName.find('<');
156+
if (paramIndex == std::string_view::npos)
157+
{
158+
return TypeSig{ FindSimpleType(process, typeName).coded_index<TypeDefOrRef>() };
159+
}
160+
else
161+
{
162+
XLANG_ASSERT(typeName.back() == '>');
163+
return TypeSig{ FindSimpleType(process, typeName.substr(0, paramIndex)).coded_index<TypeDefOrRef>() };
164+
// TODO: Assemble the GenericTypeInstSig
165+
}
166+
}
167+
168+
TypeSig FindType(DkmProcess* process, std::string_view const& typeNamespace, std::string_view const& typeName)
169+
{
170+
auto paramIndex = typeName.find('<');
171+
if (paramIndex == std::string_view::npos)
172+
{
173+
return TypeSig{ FindSimpleType(process, typeNamespace, typeName).coded_index<TypeDefOrRef>() };
174+
}
175+
else
176+
{
177+
XLANG_ASSERT(typeName.back() == '>');
178+
return TypeSig{ FindSimpleType(process, typeNamespace, typeName.substr(0, paramIndex)).coded_index<TypeDefOrRef>() };
179+
// TODO: Assemble the GenericTypeInstSig
180+
}
181+
}
182+
151183
cppwinrt_visualizer::cppwinrt_visualizer()
152184
{
153185
try

natvis/object_visualizer.cpp

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -348,11 +348,11 @@ struct property_type
348348

349349
void GetInterfaceData(
350350
Microsoft::VisualStudio::Debugger::DkmProcess* process,
351-
coded_index<TypeDefOrRef> index,
351+
TypeSig const& typeSig,
352352
_Inout_ std::vector<PropertyData>& propertyData,
353353
_Out_ bool& isStringable
354354
){
355-
auto [type, propIid] = ResolveTypeInterface(process, index);
355+
auto [type, propIid] = ResolveTypeInterface(process, typeSig);
356356
if (!type)
357357
{
358358
return;
@@ -493,10 +493,29 @@ void object_visualizer::GetPropertyData()
493493
GetTypeProperties(process, std::string_view{ rc.data() + 2, rc.length() - 3 });
494494
}
495495

496+
TypeSig ExpandInterfaceImplForType(coded_index<TypeDefOrRef> impl, TypeSig const& type)
497+
{
498+
if (std::holds_alternative<coded_index<TypeDefOrRef>>(type.Type()))
499+
{
500+
return TypeSig{ impl };
501+
}
502+
return TypeSig{ impl };
503+
}
504+
496505
void object_visualizer::GetTypeProperties(Microsoft::VisualStudio::Debugger::DkmProcess* process, std::string_view const& type_name)
497506
{
498507
// TODO: add support for direct generic interface implementations (e.g., key_value_pair)
499-
auto type = FindType(process, type_name);
508+
auto typeSig = FindType(process, type_name);
509+
TypeDef type{};
510+
if (auto const* index = std::get_if<coded_index<TypeDefOrRef>>(&typeSig.Type()))
511+
{
512+
type = index->TypeDef();
513+
}
514+
else if (auto const* genericInst = std::get_if<GenericTypeInstSig>(&typeSig.Type()))
515+
{
516+
type = genericInst->GenericType().TypeDef();
517+
}
518+
500519
if (!type)
501520
{
502521
return;
@@ -516,17 +535,17 @@ void object_visualizer::GetTypeProperties(Microsoft::VisualStudio::Debugger::Dkm
516535
auto impls = type.InterfaceImpl();
517536
for (auto&& impl : impls)
518537
{
519-
GetInterfaceData(process, impl.Interface(), m_propertyData, m_isStringable);
538+
GetInterfaceData(process, ExpandInterfaceImplForType(impl.Interface(), typeSig), m_propertyData, m_isStringable);
520539
}
521540
}
522541
else if (get_category(type) == category::interface_type)
523542
{
524543
auto impls = type.InterfaceImpl();
525544
for (auto&& impl : impls)
526545
{
527-
GetInterfaceData(process, impl.Interface(), m_propertyData, m_isStringable);
546+
GetInterfaceData(process, ExpandInterfaceImplForType(impl.Interface(), typeSig), m_propertyData, m_isStringable);
528547
}
529-
GetInterfaceData(process, type.coded_index<TypeDefOrRef>(), m_propertyData, m_isStringable);
548+
GetInterfaceData(process, typeSig, m_propertyData, m_isStringable);
530549
}
531550
}
532551

natvis/pch.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,10 @@ inline bool starts_with(std::string_view const& value, std::string_view const& m
9191
return 0 == value.compare(0, match.size(), match);
9292
}
9393

94-
winmd::reader::TypeDef FindType(Microsoft::VisualStudio::Debugger::DkmProcess* process, std::string_view const& typeName);
95-
winmd::reader::TypeDef FindType(Microsoft::VisualStudio::Debugger::DkmProcess* process, std::string_view const& typeNamespace, std::string_view const& typeName);
94+
winmd::reader::TypeDef FindSimpleType(Microsoft::VisualStudio::Debugger::DkmProcess* process, std::string_view const& typeName);
95+
winmd::reader::TypeDef FindSimpleType(Microsoft::VisualStudio::Debugger::DkmProcess* process, std::string_view const& typeNamespace, std::string_view const& typeName);
96+
winmd::reader::TypeSig FindType(Microsoft::VisualStudio::Debugger::DkmProcess* process, std::string_view const& typeName);
97+
winmd::reader::TypeSig FindType(Microsoft::VisualStudio::Debugger::DkmProcess* process, std::string_view const& typeNamespace, std::string_view const& typeName);
9698

9799
inline winmd::reader::TypeDef ResolveType(Microsoft::VisualStudio::Debugger::DkmProcess* process, winmd::reader::coded_index<winmd::reader::TypeDefOrRef> index) noexcept
98100
{
@@ -101,13 +103,13 @@ inline winmd::reader::TypeDef ResolveType(Microsoft::VisualStudio::Debugger::Dkm
101103
case winmd::reader::TypeDefOrRef::TypeDef:
102104
return index.TypeDef();
103105
case winmd::reader::TypeDefOrRef::TypeRef:
104-
return FindType(process, index.TypeRef().TypeNamespace(), index.TypeRef().TypeName());
106+
return FindSimpleType(process, index.TypeRef().TypeNamespace(), index.TypeRef().TypeName());
105107
default: //case TypeDefOrRef::TypeSpec:
106108
return winmd::reader::find_required(index.TypeSpec().Signature().
107109
GenericTypeInst().GenericType().TypeRef());
108110
}
109111
}
110112

111-
std::pair<winmd::reader::TypeDef, std::wstring> ResolveTypeInterface(Microsoft::VisualStudio::Debugger::DkmProcess* process, winmd::reader::coded_index<winmd::reader::TypeDefOrRef> index);
113+
std::pair<winmd::reader::TypeDef, std::wstring> ResolveTypeInterface(Microsoft::VisualStudio::Debugger::DkmProcess* process, winmd::reader::TypeSig const& typeSig);
112114

113115
void ClearTypeResolver();

natvis/type_resolver.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,8 +278,19 @@ static guid generate_guid(coded_index<TypeDefOrRef> const& type)
278278
return set_named_guid_fields(endian_swap(to_guid(calculate_sha1(buffer))));
279279
}
280280

281-
std::pair<TypeDef, std::wstring> ResolveTypeInterface(DkmProcess* process, coded_index<TypeDefOrRef> index)
281+
std::pair<TypeDef, std::wstring> ResolveTypeInterface(DkmProcess* process, winmd::reader::TypeSig const& typeSig)
282282
{
283+
coded_index<TypeDefOrRef> index;
284+
if (auto ptrIndex = std::get_if<coded_index<TypeDefOrRef>>(&typeSig.Type()))
285+
{
286+
index = *ptrIndex;
287+
}
288+
else if (auto* ptrGeneric = std::get_if<GenericTypeInstSig>(&typeSig.Type()))
289+
{
290+
index = ptrGeneric->GenericType();
291+
}
292+
293+
// TODO: Cache on the whole TypeSig, not just the generic index
283294
if (auto found = _cache.find(index); found != _cache.end())
284295
{
285296
return found->second;

0 commit comments

Comments
 (0)