microsoft / cppwinrt

C++/WinRT
MIT License
1.64k stars 238 forks source link

Bug: Composible base type B is missing from generated .g.h file #1275

Closed hereafter closed 1 year ago

hereafter commented 1 year ago

Version

2.0.230207.1

Summary

Within a Cpp/Winrt project

create an unsealed class BaseObject, then create a class ExtendedObject extends BaseObject

the generated codes failed to compile, complaining

Reproducible example

BaseObject.idl

namespace App1
{
    [default_interface]
    unsealed runtimeclass BaseObject : Microsoft.UI.Xaml.Controls.Control
    {
        BaseObject();
    }
}

ExtendedObject.idl
import "BaseObject.idl";

namespace App1
{
    [bindable]
    [default_interface]
    runtimeclass ExtendedObject : BaseObject
    {
        ExtendedObject();
        Int32 MyProperty;
    }
}

ExtendedObject.h

namespace winrt::App1::implementation
{
    struct ExtendedObject : ExtendedObjectT<ExtendedObject>
    {
        ExtendedObject() = default;

        int32_t MyProperty();
        void MyProperty(int32_t value);
    };
}

Expected behavior

compiles successfully

Actual behavior

Build started... 1>------ Build started: Project: App1, Configuration: Debug x64 ------ 1>ExtendedObject.cpp 1>D:\Temp\App1\App1\Generated Files\ExtendedObject.g.h(52,29): error C2976: 'winrt::App1::implementation::ExtendedObject_base': too few template arguments 1>D:\Temp\App1\App1\Generated Files\ExtendedObject.g.h(11,56): message : see declaration of 'winrt::App1::implementation::ExtendedObject_base' 1>D:\Temp\App1\App1\ExtendedObject.h(7,29): message : see reference to alias template instantiation 'winrt::App1::implementation::ExtendedObjectT<winrt::App1::implementation::ExtendedObject,>' being compiled 1>D:\Temp\App1\App1\ExtendedObject.h(8,5): error C3770: 'unknown-type': is not a valid base class 1>D:\Temp\App1\App1\Generated Files\winrt\base.h(6888,69): error C2794: 'implements_type': is not a member of any direct or indirect base class of 'winrt::App1::implementation::ExtendedObject' 1>D:\Temp\App1\App1\Generated Files\winrt\base.h(6908,58): message : see reference to alias template instantiation 'winrt::impl::implemented_interfaces' being compiled 1> with 1> [ 1> T=winrt::App1::implementation::ExtendedObject 1> ] 1>D:\Temp\App1\App1\Generated Files\winrt\base.h(7915,5): message : see reference to class template instantiation 'winrt::impl::implements_default_interface<D,void>' being compiled 1> with 1> [ 1> D=winrt::App1::implementation::ExtendedObject 1> ] 1>D:\Temp\App1\App1\Generated Files\ExtendedObject.g.cpp(10,67): message : see reference to function template instantiation 'auto winrt::make<winrt::App1::implementation::ExtendedObject,>(void)' being compiled 1>D:\Temp\App1\App1\Generated Files\winrt\base.h(6908,1): error C2938: 'winrt::impl::implemented_interfaces' : Failed to specialize alias template 1>D:\Temp\App1\App1\Generated Files\winrt\base.h(6908,1): error C2062: type 'unknown-type' unexpected 1>D:\Temp\App1\App1\Generated Files\winrt\base.h(6908,85): error C2039: 'first_interface': is not a member of 'global namespace'' 1>D:\Temp\App1\App1\Generated Files\winrt\base.h(6908,103): error C2039: 'type': is not a member of 'global namespace'' 1>D:\Temp\App1\App1\Generated Files\winrt\base.h(6908,1): error C2146: syntax error: missing ';' before identifier 'type' 1>D:\Temp\App1\App1\Generated Files\winrt\base.h(6908,1): error C2602: 'winrt::impl::implements_default_interface<D,void>::type' is not a member of a base class of 'winrt::impl::implements_default_interface<D,void>' 1> with 1> [ 1> D=winrt::App1::implementation::ExtendedObject 1> ] 1>D:\Temp\App1\App1\Generated Files\winrt\base.h(6908,15): message : see declaration of 'winrt::impl::implements_default_interface<D,void>::type' 1> with 1> [ 1> D=winrt::App1::implementation::ExtendedObject 1> ] 1>D:\Temp\App1\App1\Generated Files\winrt\base.h(7922,34): message : see declaration of 'winrt::impl::implements_default_interface<D,void>' 1> with 1> [ 1> D=winrt::App1::implementation::ExtendedObject 1> ] 1>D:\Temp\App1\App1\Generated Files\winrt\base.h(7924,81): error C2059: syntax error: ')' 1>D:\Temp\App1\App1\Generated Files\winrt\base.h(7915,5): error C2143: syntax error: missing ';' before '{' 1>D:\Temp\App1\App1\Generated Files\winrt\base.h(7927,26): error C2672: 'winrt::impl::make_factory': no matching overloaded function found 1>D:\Temp\App1\App1\Generated Files\winrt\base.h(7865,10): message : could be 'impl::implements_default_interface<T,void>::type winrt::impl::make_factory(void)' 1>D:\Temp\App1\App1\Generated Files\winrt\base.h(7927,26): message : Failed to specialize function template 'impl::implements_default_interface<T,void>::type winrt::impl::make_factory(void)' 1>D:\Temp\App1\App1\Generated Files\winrt\base.h(7927,26): message : With the following template arguments: 1>D:\Temp\App1\App1\Generated Files\winrt\base.h(7927,26): message : 'D=D' 1>D:\Temp\App1\App1\Generated Files\winrt\base.h(7915,5): error C2181: illegal else without matching if 1>D:\Temp\App1\App1\Generated Files\winrt\base.h(7915,5): error C2062: type 'unknown-type' unexpected 1>D:\Temp\App1\App1\Generated Files\winrt\base.h(7943,5): error C2059: syntax error: '}' 1>D:\Temp\App1\App1\Generated Files\ExtendedObject.g.cpp(10,68): error C2059: syntax error: ')' 1>D:\Temp\App1\App1\Generated Files\ExtendedObject.g.cpp(11,5): error C2143: syntax error: missing ';' before '{' 1>D:\Temp\App1\App1\Generated Files\ExtendedObject.g.cpp(11,5): error C2447: '{': missing function header (old-style formal list?) 1>D:\Temp\App1\App1\Generated Files\ExtendedObject.g.cpp(13,1): error C2059: syntax error: '}' 1>D:\Temp\App1\App1\Generated Files\ExtendedObject.g.cpp(13,1): error C2143: syntax error: missing ';' before '}' 1>D:\Temp\App1\App1\ExtendedObject.cpp(8,1): error C2143: syntax error: missing ';' before '{' 1>D:\Temp\App1\App1\ExtendedObject.cpp(8,1): error C2447: '{': missing function header (old-style formal list?) 1>D:\Temp\App1\App1\ExtendedObject.cpp(19,1): fatal error C1903: unable to recover from previous error(s); stopping compilation 1>Done building project "App1.vcxproj" -- FAILED.

Additional comments

With futher inspection,

Inside the generated "ExtendedObject.g.h"

namespace winrt::App1::implementation
{
    template <typename D, typename... I>
    using ExtendedObjectT = ExtendedObject_base<D, I...>;
}

should be

namespace winrt::App1::implementation
{
    template <typename D, typename... I>
    using ExtendedObjectT = ExtendedObject_base<D, winrt::App1::BaseObject, I...>;
}

Full Project attached for reference

App1.zip

sylveon commented 1 year ago

You need #include "BaseObject.h" in ExtendedObject.h

hereafter commented 1 year ago

You need #include "BaseObject.h" in ExtendedObject.h

Thanks

After i clone this repo, i browse through test codes


namespace winrt::App1::implementation
{
    struct ExtendedObject : ExtendedObjectT<ExtendedObject, implementation::BaseObject>
    {
        ExtendedObject() = default;

        int32_t MyProperty();
        void MyProperty(int32_t value);
    };
}

apparently, i need to put implementation base object in. My confusion

Thank you.