Skip to content

Commit e436ad2

Browse files
committed
Handle generics in InterfaceImpl
1 parent d222652 commit e436ad2

File tree

2 files changed

+31
-5
lines changed

2 files changed

+31
-5
lines changed

natvis/object_visualizer.cpp

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -697,11 +697,37 @@ void object_visualizer::GetPropertyData()
697697
GetTypeProperties(process, std::string_view{ rc.data() + 2, rc.length() - 3 });
698698
}
699699

700+
GenericTypeInstSig ReplaceGenericIndices(GenericTypeInstSig const& sig, std::vector<TypeSig> const& genericArgs)
701+
{
702+
std::vector<TypeSig> replacementArgs;
703+
for (auto&& arg : sig.GenericArgs())
704+
{
705+
if (auto pGenericSig = std::get_if<GenericTypeInstSig>(&arg.Type()))
706+
{
707+
replacementArgs.emplace_back(ReplaceGenericIndices(*pGenericSig, genericArgs));
708+
}
709+
else if (auto pGenericIndex = std::get_if<GenericTypeIndex>(&arg.Type()))
710+
{
711+
replacementArgs.push_back(genericArgs[pGenericIndex->index]);
712+
}
713+
else
714+
{
715+
replacementArgs.push_back(arg);
716+
}
717+
}
718+
return GenericTypeInstSig{ sig.GenericType(), std::move(replacementArgs) };
719+
}
720+
700721
TypeSig ExpandInterfaceImplForType(coded_index<TypeDefOrRef> impl, TypeSig const& type)
701722
{
702-
if (std::holds_alternative<coded_index<TypeDefOrRef>>(type.Type()))
723+
if (auto pGenericInst = std::get_if<GenericTypeInstSig>(&type.Type()))
703724
{
704-
return TypeSig{ impl };
725+
if (impl.type() == TypeDefOrRef::TypeSpec)
726+
{
727+
auto const& genericArgs = pGenericInst->GenericArgs();
728+
auto newSig = ReplaceGenericIndices(impl.TypeSpec().Signature().GenericTypeInst(), std::vector<TypeSig>{ genericArgs.first, genericArgs.second });
729+
return TypeSig{ newSig };
730+
}
705731
}
706732
return TypeSig{ impl };
707733
}
@@ -713,11 +739,11 @@ void object_visualizer::GetTypeProperties(Microsoft::VisualStudio::Debugger::Dkm
713739
TypeDef type{};
714740
if (auto const* index = std::get_if<coded_index<TypeDefOrRef>>(&typeSig.Type()))
715741
{
716-
type = index->TypeDef();
742+
type = ResolveType(process, *index);
717743
}
718744
else if (auto const* genericInst = std::get_if<GenericTypeInstSig>(&typeSig.Type()))
719745
{
720-
type = genericInst->GenericType().TypeDef();
746+
type = ResolveType(process, genericInst->GenericType());
721747
}
722748

723749
if (!type)

natvis/type_resolver.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ std::pair<TypeDef, std::wstring> ResolveTypeInterface(DkmProcess* process, winmd
307307
{
308308
index = ptrGeneric->GenericType();
309309
auto guid = format_guid(generate_guid(*ptrGeneric));
310-
return { index.TypeDef(), guid };
310+
return { ResolveType(process, index), guid };
311311
}
312312
return {};
313313
};

0 commit comments

Comments
 (0)