Skip to content

Commit cf96df5

Browse files
authored
Fix overloads coming from overridable interfaces (#1458)
* Fix overloads coming from overridable interfaces Fixes #1457 * PR feedback
1 parent fa079fb commit cf96df5

File tree

6 files changed

+125
-6
lines changed

6 files changed

+125
-6
lines changed

cppwinrt/code_writers.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2150,6 +2150,10 @@ struct WINRT_IMPL_EMPTY_BASES produce_dispatch_to_overridable<T, D, %>
21502150
w.write("\n friend impl::consume_t<D, %>;", name);
21512151
w.write("\n friend impl::require_one<D, %>;", name);
21522152
}
2153+
else if (info.overridable)
2154+
{
2155+
w.write("\n friend impl::produce<D, %>;", name);
2156+
}
21532157
}
21542158
}
21552159

@@ -2275,13 +2279,13 @@ struct WINRT_IMPL_EMPTY_BASES produce_dispatch_to_overridable<T, D, %>
22752279

22762280
static void write_class_override_usings(writer& w, get_interfaces_t const& required_interfaces)
22772281
{
2278-
std::map<std::string_view, std::set<std::string>> method_usage;
2282+
std::map<std::string_view, std::map<std::string, interface_info>> method_usage;
22792283

2280-
for (auto&& [interface_name, info] : required_interfaces)
2284+
for (auto&& interface_desc : required_interfaces)
22812285
{
2282-
for (auto&& method : info.type.MethodList())
2286+
for (auto&& method : interface_desc.second.type.MethodList())
22832287
{
2284-
method_usage[get_name(method)].insert(interface_name);
2288+
method_usage[get_name(method)].insert(interface_desc);
22852289
}
22862290
}
22872291

@@ -2292,9 +2296,11 @@ struct WINRT_IMPL_EMPTY_BASES produce_dispatch_to_overridable<T, D, %>
22922296
continue;
22932297
}
22942298

2295-
for (auto&& interface_name : interfaces)
2299+
for (auto&& [interface_name, info] : interfaces)
22962300
{
2297-
w.write(" using impl::consume_t<D, %>::%;\n",
2301+
w.write(info.overridable
2302+
? " using %T<D>::%;\n"
2303+
: " using impl::consume_t<D, %>::%;\n",
22982304
interface_name,
22992305
method_name);
23002306
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include "pch.h"
2+
#include "OverloadClass.h"
3+
#include "OverloadClass.g.cpp"
4+
5+
namespace winrt::test_component::implementation
6+
{
7+
void OverloadClass::Overload()
8+
{
9+
throw hresult_not_implemented();
10+
}
11+
void OverloadClass::Overload(int a)
12+
{
13+
throw hresult_not_implemented();
14+
}
15+
void OverloadClass::Overload(int a, int b)
16+
{
17+
throw hresult_not_implemented();
18+
}
19+
void OverloadClass::Overload(int a, int b, int c)
20+
{
21+
throw hresult_not_implemented();
22+
}
23+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#pragma once
2+
#include "OverloadClass.g.h"
3+
4+
namespace winrt::test_component::implementation
5+
{
6+
struct OverloadClass : OverloadClassT<OverloadClass>
7+
{
8+
OverloadClass() = default;
9+
10+
void Overload();
11+
void Overload(int a);
12+
void Overload(int a, int b);
13+
void Overload(int a, int b, int c);
14+
};
15+
}
16+
namespace winrt::test_component::factory_implementation
17+
{
18+
struct OverloadClass : OverloadClassT<OverloadClass, implementation::OverloadClass>
19+
{
20+
};
21+
}

test/test_component/test_component.idl

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,4 +334,51 @@ namespace test_component
334334

335335
delegate void Delegate();
336336
}
337+
338+
[exclusiveto(test_component.OverloadClass)]
339+
[version(1), uuid(EF902013-00F3-4549-9032-49E86D536C07)]
340+
interface IOverloadClass : IInspectable
341+
{
342+
HRESULT Overload();
343+
}
344+
345+
[exclusiveto(test_component.OverloadClass)]
346+
[version(1), uuid(DFDFFB61-EA72-4977-B1A7-3F0D2C32BB58)]
347+
interface IOverloadClassFactory : IInspectable
348+
{
349+
HRESULT CreateInstance([in] IInspectable* baseInterface, [out] IInspectable** innerInterface, [out][retval] test_component.OverloadClass** value);
350+
}
351+
352+
[exclusiveto(test_component.OverloadClass)]
353+
[version(1), uuid(32510F72-9229-4C69-95BD-DE7B8189C85C)]
354+
interface IOverloadClassOverrides : IInspectable
355+
{
356+
[overload("Overload")] HRESULT OverloadWithOne(int a);
357+
}
358+
359+
[exclusiveto(test_component.OverloadClass)]
360+
[version(1), uuid(50205BCE-FAD3-4C66-801F-17AAD007B26C)]
361+
interface IOverloadClassOverrides2 : IInspectable
362+
{
363+
[overload("Overload")] HRESULT OverloadWithTwo(int a, int b);
364+
}
365+
366+
[exclusiveto(test_component.OverloadClass)]
367+
[version(1), uuid(6EDD1A3F-2616-45B7-9731-F84DA9CCECA1)]
368+
interface IOverloadClassProtected : IInspectable
369+
{
370+
[overload("Overload")] HRESULT OverloadWithThree(int a, int b, int c);
371+
}
372+
373+
[composable(test_component.IOverloadClassFactory, public, 1)]
374+
[marshaling_behavior(agile)]
375+
[threading(both)]
376+
[version(1)]
377+
runtimeclass OverloadClass
378+
{
379+
[default] interface test_component.IOverloadClass;
380+
[protected] interface test_component.IOverloadClassProtected;
381+
[overridable] interface test_component.IOverloadClassOverrides;
382+
[overridable] interface test_component.IOverloadClassOverrides2;
383+
}
337384
}

test/test_component/test_component.vcxproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,8 @@
384384
<ClCompile Include="Generated Files\module.g.cpp" />
385385
<ClCompile Include="module.cpp" />
386386
<ClCompile Include="Optional.cpp" />
387+
<ClCompile Include="OverloadClass.cpp" />
388+
<ClCompile Include="test_overload.cpp" />
387389
<ClCompile Include="pch.cpp">
388390
<PrecompiledHeader>Create</PrecompiledHeader>
389391
</ClCompile>
@@ -397,6 +399,7 @@
397399
<ItemGroup>
398400
<ClInclude Include="Class.h" />
399401
<ClInclude Include="Optional.h" />
402+
<ClInclude Include="OverloadClass.h" />
400403
<ClInclude Include="pch.h" />
401404
<ClInclude Include="Simple.h" />
402405
<ClInclude Include="Velocity.Class1.h" />
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include "pch.h"
2+
#include "winrt/test_component.h"
3+
4+
// Simple compile-only test to validate overloads coming from overridable interfaces compile.
5+
6+
using namespace winrt;
7+
using namespace test_component;
8+
9+
struct DerivedClass : OverloadClassT<DerivedClass>
10+
{
11+
void Foo()
12+
{
13+
// make sure we can actually call the overloads (no ambiguous call errors)
14+
Overload();
15+
Overload(1);
16+
Overload(1, 2);
17+
Overload(1, 2, 3);
18+
}
19+
};

0 commit comments

Comments
 (0)