Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Directory.Build.Props
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@
<TreatWarningAsError>true</TreatWarningAsError>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard Condition="'$(CppWinRTLanguageStandard)'==''">stdcpp17</LanguageStandard>
<LanguageStandard Condition="'$(CppWinRTLanguageStandard)'=='' Or '$(CppWinRTLanguageStandard)'=='17'">stdcpp17</LanguageStandard>
<LanguageStandard Condition="'$(CppWinRTLanguageStandard)'=='20'">stdcpp20</LanguageStandard>
<LanguageStandard Condition="'$(CppWinRTLanguageStandard)'=='latest'">stdcpplatest</LanguageStandard>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<PreprocessorDefinitions>CPPWINRT_VERSION_STRING="$(CppWinRTBuildVersion)";%(PreprocessorDefinitions)</PreprocessorDefinitions>
Expand Down
58 changes: 48 additions & 10 deletions cppwinrt/code_writers.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,28 @@ namespace cppwinrt
}
}

static void write_parent_imports(writer& w, cache const& c, std::string_view const& type_namespace)
{
auto pos = type_namespace.rfind('.');

if (pos == std::string::npos)
{
return;
}

auto parent = type_namespace.substr(0, pos);
auto found = c.namespaces().find(parent);

if (found != c.namespaces().end() && has_projected_types(found->second))
{
w.write_import(parent);
}
else
{
write_parent_imports(w, c, parent);
}
}

static void write_pch(writer& w)
{
auto format = R"(#include "%"
Expand Down Expand Up @@ -313,11 +335,22 @@ namespace cppwinrt
return;
}

if (type_name == "Windows.Foundation.DateTime" ||
type_name == "Windows.Foundation.TimeSpan")
if (type_name.name_space == "Windows.Foundation")
{
// Don't forward declare these since they're not structs.
return;
if (type_name.name == "DateTime" ||
type_name.name == "TimeSpan")
{
// Don't forward declare these since they're not structs.
return;
}

if (type_name.name == "Point" ||
type_name.name == "Rect" ||
type_name.name == "Size")
{
// Don't forward declare these since they're already defined in base.h.
return;
}
}

if (type_name.name_space == "Windows.Foundation.Numerics")
Expand Down Expand Up @@ -2812,7 +2845,12 @@ struct WINRT_IMPL_EMPTY_BASES produce_dispatch_to_overridable<T, D, %>
}
}

static bool write_structs(writer& w, std::vector<TypeDef> const& types)
struct write_structs_result
{
bool promote = false;
};

static write_structs_result write_structs(writer& w, std::vector<TypeDef> const& types)
{
auto format = R"( struct %
{
Expand All @@ -2829,7 +2867,7 @@ struct WINRT_IMPL_EMPTY_BASES produce_dispatch_to_overridable<T, D, %>

if (types.empty())
{
return false;
return {};
}

struct complex_struct
Expand Down Expand Up @@ -2895,7 +2933,7 @@ struct WINRT_IMPL_EMPTY_BASES produce_dispatch_to_overridable<T, D, %>
}
}

bool promote = false;
write_structs_result result;
auto cpp_namespace = w.write_temp("@", w.type_namespace);

for (auto&& type : structs)
Expand All @@ -2921,14 +2959,14 @@ struct WINRT_IMPL_EMPTY_BASES produce_dispatch_to_overridable<T, D, %>
continue;
}

if (!starts_with(field.second, cpp_namespace))
if (!result.promote && !starts_with(field.second, cpp_namespace))
{
promote = true;
result.promote = true;
}
}
}

return promote;
return result;
}

static void write_class_requires(writer& w, TypeDef const& type)
Expand Down
2 changes: 2 additions & 0 deletions cppwinrt/cppwinrt.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,12 @@
<ClInclude Include="..\strings\base_macros.h" />
<ClInclude Include="..\strings\base_marshaler.h" />
<ClInclude Include="..\strings\base_meta.h" />
<ClInclude Include="..\strings\base_module.h" />
<ClInclude Include="..\strings\base_natvis.h" />
<ClInclude Include="..\strings\base_reference_produce.h" />
<ClInclude Include="..\strings\base_reference_produce_1.h" />
<ClInclude Include="..\strings\base_security.h" />
<ClInclude Include="..\strings\base_shared.h" />
<ClInclude Include="..\strings\base_std_hash.h" />
<ClInclude Include="..\strings\base_string.h" />
<ClInclude Include="..\strings\base_stringable_format.h" />
Expand Down
6 changes: 6 additions & 0 deletions cppwinrt/cppwinrt.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@
<ClInclude Include="..\strings\base_meta.h">
<Filter>strings</Filter>
</ClInclude>
<ClInclude Include="..\strings\base_module.h">
<Filter>strings</Filter>
</ClInclude>
<ClInclude Include="..\strings\base_natvis.h">
<Filter>strings</Filter>
</ClInclude>
Expand Down Expand Up @@ -187,6 +190,9 @@
<ClInclude Include="..\strings\base_stringable_to_hstring.h">
<Filter>strings</Filter>
</ClInclude>
<ClInclude Include="..\strings\base_shared.h">
<Filter>strings</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="$(OutDir)version.rc" />
Expand Down
83 changes: 80 additions & 3 deletions cppwinrt/file_writers.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace cppwinrt
auto wrap_file_guard = wrap_open_file_guard(w, "BASE");

w.write(strings::base_includes);
w.write_root_include("shared");
w.write(strings::base_macros);
w.write(strings::base_types);
w.write(strings::base_extern);
Expand Down Expand Up @@ -46,6 +47,26 @@ namespace cppwinrt
w.flush_to_file(settings.output_folder + "winrt/base.h");
}

static void write_shared_h()
{
writer w;
write_preamble(w);
w.write(strings::base_shared);
w.flush_to_file(settings.output_folder + "winrt/shared.h");
}

static void write_base_ixx()
{
writer ixx;
write_preamble(ixx);
ixx.write("module;\n");
ixx.write(strings::base_includes);
ixx.write_root_include("shared");
ixx.write(strings::base_module);
ixx.write_root_include("base");
ixx.flush_to_file(settings.output_folder + "winrt/ixx/base.ixx");
}

static void write_fast_forward_h(std::vector<TypeDef> const& classes)
{
writer w;
Expand All @@ -65,6 +86,48 @@ namespace cppwinrt
w.flush_to_file(settings.output_folder + "winrt/fast_forward.h");
}

static void write_namespace_ixx(cache const& c, writer const& header_writer, std::string_view const& ns, char import_impl, char impl = 0)
{
writer w;
w.type_namespace = ns;
write_preamble(w);
w.write("module;\n");
w.write_root_include("shared");
w.write("#define WINRT_EXPORT export\n");
w.write("#define WINRT_IMPL_MODULES\n");
if (impl)
{
w.write("export module winrt:%.%;\n", ns, module_friendly_impl(impl));
}
else
{
w.write("export module winrt:%;\n", ns);
}

w.write("import std;\n");

w.write_import("base");
if (!impl)
{
write_parent_imports(w, c, ns);
}

for (auto&& depends : header_writer.depends)
{
w.write_import(depends.first, import_impl);
}

if (impl != '0')
{
w.write("export ");
w.write_import(ns, impl ? impl - 1 : '2');
}

w.write_depends(ns, impl);

w.save_module(impl);
}

static void write_namespace_0_h(std::string_view const& ns, cache::namespace_members const& members)
{
writer w;
Expand Down Expand Up @@ -119,6 +182,8 @@ namespace cppwinrt
}

w.save_header('0');

write_namespace_ixx({}, {}, ns, 0, '0');
}

static void write_namespace_1_h(std::string_view const& ns, cache::namespace_members const& members)
Expand All @@ -137,25 +202,29 @@ namespace cppwinrt
write_preamble(w);
write_open_file_guard(w, ns, '1');

w.write("#ifndef WINRT_IMPL_MODULES\n");
for (auto&& depends : w.depends)
{
w.write_depends(depends.first, '0');
}

w.write_depends(w.type_namespace, '0');
w.write("#endif\n");
w.save_header('1');

write_namespace_ixx({}, w, ns, '0', '1');
}

static void write_namespace_2_h(std::string_view const& ns, cache::namespace_members const& members)
{
writer w;
w.type_namespace = ns;

bool promote;
write_structs_result structs_info;
{
auto wrap_type = wrap_type_namespace(w, ns);
w.write_each<write_delegate>(members.delegates);
promote = write_structs(w, members.structs);
structs_info = write_structs(w, members.structs);
w.write_each<write_class>(members.classes);
w.write_each<write_interface_override>(members.classes);
}
Expand All @@ -165,15 +234,19 @@ namespace cppwinrt
write_preamble(w);
write_open_file_guard(w, ns, '2');

char const impl = promote ? '2' : '1';
char const impl = structs_info.promote ? '2' : '1';

w.write("#ifndef WINRT_IMPL_MODULES\n");
for (auto&& depends : w.depends)
{
w.write_depends(depends.first, impl);
}

w.write_depends(w.type_namespace, '1');
w.write("#endif\n");
w.save_header('2');

write_namespace_ixx({}, w, ns, impl, '2');
}

static void write_namespace_h(cache const& c, std::string_view const& ns, cache::namespace_members const& members)
Expand Down Expand Up @@ -219,6 +292,7 @@ namespace cppwinrt
w.swap();
write_preamble(w);
write_open_file_guard(w, ns);
w.write("#ifndef WINRT_IMPL_MODULES\n");
write_version_assert(w);
write_parent_depends(w, c, ns);

Expand All @@ -228,7 +302,10 @@ namespace cppwinrt
}

w.write_depends(w.type_namespace, '2');
w.write("#endif\n");
w.save_header();

write_namespace_ixx(c, w, ns, '2');
}

static void write_module_g_cpp(std::vector<TypeDef> const& classes)
Expand Down
16 changes: 11 additions & 5 deletions cppwinrt/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ R"( local Local ^%WinDir^%\System32\WinMetadata folder

path output_folder = args.value("output", ".");
create_directories(output_folder / "winrt/impl");
create_directories(output_folder / "winrt/ixx");
settings.output_folder = canonical(output_folder).string();
settings.output_folder += std::filesystem::path::preferred_separator;

Expand Down Expand Up @@ -344,9 +345,9 @@ R"( local Local ^%WinDir^%\System32\WinMetadata folder
group.synchronous(args.exists("synchronous"));
writer ixx;
write_preamble(ixx);
ixx.write("module;\n");
ixx.write(strings::base_includes);
ixx.write("\nexport module winrt;\n#define WINRT_EXPORT export\n\n");
ixx.write("export module winrt;\n");
ixx.write("export ");
ixx.write_import("base");

for (auto&&[ns, members] : c.namespaces())
{
Expand All @@ -355,7 +356,8 @@ R"( local Local ^%WinDir^%\System32\WinMetadata folder
continue;
}

ixx.write("#include \"winrt/%.h\"\n", ns);
ixx.write("export ");
ixx.write_import(ns);

group.add([&, &ns = ns, &members = members]
{
Expand All @@ -366,10 +368,14 @@ R"( local Local ^%WinDir^%\System32\WinMetadata folder
});
}

ixx.flush_to_file(settings.output_folder + "winrt/ixx/winrt.ixx");

write_shared_h();

if (settings.base)
{
write_base_h();
ixx.flush_to_file(settings.output_folder + "winrt/winrt.ixx");
write_base_ixx();
}

if (settings.component)
Expand Down
Loading