Skip to content
Open
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
13 changes: 12 additions & 1 deletion cppwinrt/code_writers.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,20 @@ namespace cppwinrt
return { w, write_close_namespace };
}

[[nodiscard]] static finish_with wrap_impl_namespace_without_export(writer& w)
{
auto format = R"(extern "C++" namespace winrt::impl
{
)";

w.write(format);

return { w, write_close_namespace };
}

[[nodiscard]] static finish_with wrap_std_namespace(writer& w)
{
w.write(R"(WINRT_EXPORT namespace std
w.write(R"(extern "C++" namespace std
{
)");

Expand Down
75 changes: 30 additions & 45 deletions cppwinrt/file_writers.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ namespace cppwinrt
{
auto wrap_file_guard = wrap_open_file_guard(w, "BASE");

if (settings.modules)
{
w.write("#ifndef WINRT_CONSUME_MODULE\n");
}

{
// In module builds, generated projection headers must be "module-aware":
// When `WINRT_MODULE` is defined (inside a module interface unit), suppress textual includes so the
Expand Down Expand Up @@ -85,6 +90,11 @@ namespace cppwinrt
w.write(strings::base_coroutine_threadpool);
w.write(strings::base_natvis);
w.write(strings::base_version);

if (settings.modules)
{
w.write("#endif\n");
}
}
w.flush_to_file(settings.output_folder + "winrt/base.h");
}
Expand Down Expand Up @@ -142,7 +152,7 @@ namespace cppwinrt
w.write_each<write_forward>(members.contracts);
}
{
auto wrap_impl = wrap_impl_namespace(w);
auto wrap_impl = wrap_impl_namespace_without_export(w);
w.write_each<write_category>(members.interfaces, "interface_category");
w.write_each<write_category>(members.classes, "class_category");
w.write_each<write_category>(members.enums, "enum_category");
Expand All @@ -165,9 +175,12 @@ namespace cppwinrt
w.write_each<write_default_interface>(members.classes);
w.write_each<write_interface_abi>(members.interfaces);
w.write_each<write_delegate_abi>(members.delegates);
w.write_each<write_consume>(members.interfaces);
w.write_each<write_struct_abi>(members.structs);
}
{
auto wrap_impl = wrap_impl_namespace(w);
w.write_each<write_consume>(members.interfaces);
}

if (settings.modules)
{
Expand Down Expand Up @@ -319,66 +332,38 @@ namespace cppwinrt
#undef GetCurrentTime
#endif

// Include in advance so that all of numerics's dependencies can be in the global module fragment
#include <stdexcept>
#include <limits>
#if __has_include(<directxmath.h>) && __has_include(<windowsnumerics.impl.h>)
#include <directxmath.h>
#endif

export module winrt.base;

// Module dependencies:
// - std
// - winrt.numerics (re-exported when available)

import std;
export import winrt.numerics;

#if __has_include(<windowsnumerics.impl.h>)
#define WINRT_IMPL_NUMERICS
#endif

#include "winrt/base.h"
)");

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

static void write_numerics_ixx()
{
// Emits $(out)\winrt\winrt.numerics.ixx (export module winrt.numerics;)
// <windowsnumerics.impl.h> pulls in large, legacy headers that are hard to control and can trigger module
// diagnostics when textually included in a module purview.
// If the header does not exist, then the module exports nothing. To speed up module scanning, modules
// can't be controlled by preprocessor directives. Therefore, winrt.base cannot conditionally import it.
// In header builds we preserve the historical behavior (base headers include it), but in module builds we
// centralize it in this single module and have `winrt.base` re-export it.
// MSVC warns (C5244) when encountering textual includes inside a module purview; suppress for this file.
writer w;
write_preamble(w);
write_module_global_fragment(w);

w.write(R"(
export module winrt.numerics;

// Module dependencies:
// - (none)

#if __has_include(<windowsnumerics.impl.h>)
#ifdef _MSC_VER
#pragma warning(push)
// An MSVC warning whose cause cannot be analyzed
// warning C5244: '#include <windowsnumerics.impl.h>' in the purview of module 'winrt.base' appears erroneous. Consider moving that directive before the module declaration, or replace the textual inclusion with 'import <windowsnumerics.impl.h>;'.
#pragma warning(disable : 5244)
#endif
#include <directxmath.h>

#if __has_include(<windowsnumerics.impl.h>)
#define _WINDOWS_NUMERICS_NAMESPACE_ winrt::Windows::Foundation::Numerics
#define _WINDOWS_NUMERICS_BEGIN_NAMESPACE_ export extern "C++" namespace winrt::Windows::Foundation::Numerics
#define _WINDOWS_NUMERICS_BEGIN_NAMESPACE_ export extern "C++" namespace _WINDOWS_NUMERICS_NAMESPACE_
#define _WINDOWS_NUMERICS_END_NAMESPACE_
#include <windowsnumerics.impl.h>
#undef _WINDOWS_NUMERICS_NAMESPACE_
#undef _WINDOWS_NUMERICS_BEGIN_NAMESPACE_
#undef _WINDOWS_NUMERICS_END_NAMESPACE_
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#endif

#include "winrt/base.h"
)");

w.flush_to_file(settings.output_folder + "winrt/winrt.numerics.ixx");
w.flush_to_file(settings.output_folder + "winrt/winrt.base.ixx");
}

static void write_namespace_ixx(std::string_view const& ns, std::vector<std::string> const& imports)
Expand Down Expand Up @@ -581,7 +566,7 @@ export import winrt.base;
w.type_namespace = ns;

{
auto wrap_impl = wrap_impl_namespace(w);
auto wrap_impl = wrap_impl_namespace_without_export(w);
w.write_each<write_consume_definitions>(members.interfaces);
w.param_names = true;
w.write_each<write_delegate_implementation>(members.delegates);
Expand Down
1 change: 0 additions & 1 deletion cppwinrt/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,6 @@ R"( local Local ^%WinDir^%\System32\WinMetadata folder

if (settings.modules)
{
write_numerics_ixx();
write_base_ixx();
}

Expand Down
8 changes: 1 addition & 7 deletions cppwinrt/type_writers.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,13 +334,7 @@ namespace cppwinrt
{
if (ns == "Windows.Foundation.Numerics")
{
if (name == "Matrix3x2") { name = "float3x2"; }
else if (name == "Matrix4x4") { name = "float4x4"; }
else if (name == "Plane") { name = "plane"; }
else if (name == "Quaternion") { name = "quaternion"; }
else if (name == "Vector2") { name = "float2"; }
else if (name == "Vector3") { name = "float3"; }
else if (name == "Vector4") { name = "float4"; }
transform_special_numeric_type(name);

write("winrt::@::%", ns, name);
}
Expand Down
38 changes: 19 additions & 19 deletions strings/base_abi.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

WINRT_EXPORT namespace winrt::impl
extern "C++" namespace winrt::impl
{
template <> struct abi<Windows::Foundation::IUnknown>
{
Expand All @@ -11,7 +11,7 @@ WINRT_EXPORT namespace winrt::impl
};
};

using unknown_abi = abi_t<Windows::Foundation::IUnknown>;
WINRT_EXPORT using unknown_abi = abi_t<Windows::Foundation::IUnknown>;

template <> struct abi<Windows::Foundation::IInspectable>
{
Expand All @@ -23,7 +23,7 @@ WINRT_EXPORT namespace winrt::impl
};
};

using inspectable_abi = abi_t<Windows::Foundation::IInspectable>;
WINRT_EXPORT using inspectable_abi = abi_t<Windows::Foundation::IInspectable>;

template <> struct abi<Windows::Foundation::IActivationFactory>
{
Expand All @@ -33,14 +33,14 @@ WINRT_EXPORT namespace winrt::impl
};
};

struct WINRT_IMPL_ABI_DECL IAgileObject : unknown_abi {};
WINRT_EXPORT struct WINRT_IMPL_ABI_DECL IAgileObject : unknown_abi {};

struct WINRT_IMPL_ABI_DECL IAgileReference : unknown_abi
WINRT_EXPORT struct WINRT_IMPL_ABI_DECL IAgileReference : unknown_abi
{
virtual std::int32_t __stdcall Resolve(guid const& id, void** object) noexcept = 0;
};

struct WINRT_IMPL_ABI_DECL IMarshal : unknown_abi
WINRT_EXPORT struct WINRT_IMPL_ABI_DECL IMarshal : unknown_abi
{
virtual std::int32_t __stdcall GetUnmarshalClass(guid const& riid, void* pv, std::uint32_t dwDestContext, void* pvDestContext, std::uint32_t mshlflags, guid* pCid) noexcept = 0;
virtual std::int32_t __stdcall GetMarshalSizeMax(guid const& riid, void* pv, std::uint32_t dwDestContext, void* pvDestContext, std::uint32_t mshlflags, std::uint32_t* pSize) noexcept = 0;
Expand All @@ -50,20 +50,20 @@ WINRT_EXPORT namespace winrt::impl
virtual std::int32_t __stdcall DisconnectObject(std::uint32_t dwReserved) noexcept = 0;
};

struct WINRT_IMPL_ABI_DECL IGlobalInterfaceTable : unknown_abi
WINRT_EXPORT struct WINRT_IMPL_ABI_DECL IGlobalInterfaceTable : unknown_abi
{
virtual std::int32_t __stdcall RegisterInterfaceInGlobal(void* object, guid const& iid, std::uint32_t* cookie) noexcept = 0;
virtual std::int32_t __stdcall RevokeInterfaceFromGlobal(std::uint32_t cookie) noexcept = 0;
virtual std::int32_t __stdcall GetInterfaceFromGlobal(std::uint32_t cookie, guid const& iid, void** object) noexcept = 0;
};

struct WINRT_IMPL_ABI_DECL IStaticLifetime : inspectable_abi
WINRT_EXPORT struct WINRT_IMPL_ABI_DECL IStaticLifetime : inspectable_abi
{
virtual std::int32_t __stdcall unused() noexcept = 0;
virtual std::int32_t __stdcall GetCollection(void** value) noexcept = 0;
};

struct WINRT_IMPL_ABI_DECL IStaticLifetimeCollection : inspectable_abi
WINRT_EXPORT struct WINRT_IMPL_ABI_DECL IStaticLifetimeCollection : inspectable_abi
{
virtual std::int32_t __stdcall Lookup(void*, void**) noexcept = 0;
virtual std::int32_t __stdcall unused() noexcept = 0;
Expand All @@ -74,23 +74,23 @@ WINRT_EXPORT namespace winrt::impl
virtual std::int32_t __stdcall unused4() noexcept = 0;
};

struct WINRT_IMPL_ABI_DECL IWeakReference : unknown_abi
WINRT_EXPORT struct WINRT_IMPL_ABI_DECL IWeakReference : unknown_abi
{
virtual std::int32_t __stdcall Resolve(guid const& iid, void** objectReference) noexcept = 0;
};

struct WINRT_IMPL_ABI_DECL IWeakReferenceSource : unknown_abi
WINRT_EXPORT struct WINRT_IMPL_ABI_DECL IWeakReferenceSource : unknown_abi
{
virtual std::int32_t __stdcall GetWeakReference(IWeakReference** weakReference) noexcept = 0;
};

struct WINRT_IMPL_ABI_DECL IRestrictedErrorInfo : unknown_abi
WINRT_EXPORT struct WINRT_IMPL_ABI_DECL IRestrictedErrorInfo : unknown_abi
{
virtual std::int32_t __stdcall GetErrorDetails(bstr* description, std::int32_t* error, bstr* restrictedDescription, bstr* capabilitySid) noexcept = 0;
virtual std::int32_t __stdcall GetReference(bstr* reference) noexcept = 0;
};

struct WINRT_IMPL_ABI_DECL IErrorInfo : unknown_abi
WINRT_EXPORT struct WINRT_IMPL_ABI_DECL IErrorInfo : unknown_abi
{
virtual std::int32_t __stdcall GetGUID(guid* value) noexcept = 0;
virtual std::int32_t __stdcall GetSource(bstr* value) noexcept = 0;
Expand All @@ -99,35 +99,35 @@ WINRT_EXPORT namespace winrt::impl
virtual std::int32_t __stdcall GetHelpContext(std::uint32_t* value) noexcept = 0;
};

struct WINRT_IMPL_ABI_DECL ILanguageExceptionErrorInfo2 : unknown_abi
WINRT_EXPORT struct WINRT_IMPL_ABI_DECL ILanguageExceptionErrorInfo2 : unknown_abi
{
virtual std::int32_t __stdcall GetLanguageException(void** exception) noexcept = 0;
virtual std::int32_t __stdcall GetPreviousLanguageExceptionErrorInfo(ILanguageExceptionErrorInfo2** previous) noexcept = 0;
virtual std::int32_t __stdcall CapturePropagationContext(void* exception) noexcept = 0;
virtual std::int32_t __stdcall GetPropagationContextHead(ILanguageExceptionErrorInfo2** head) noexcept = 0;
};

struct ICallbackWithNoReentrancyToApplicationSTA;
WINRT_EXPORT struct ICallbackWithNoReentrancyToApplicationSTA;

struct WINRT_IMPL_ABI_DECL IContextCallback : unknown_abi
WINRT_EXPORT struct WINRT_IMPL_ABI_DECL IContextCallback : unknown_abi
{
virtual std::int32_t __stdcall ContextCallback(std::int32_t(__stdcall* callback)(com_callback_args*), com_callback_args* args, guid const& iid, int method, void* reserved) noexcept = 0;
};

struct WINRT_IMPL_ABI_DECL IServerSecurity : unknown_abi
WINRT_EXPORT struct WINRT_IMPL_ABI_DECL IServerSecurity : unknown_abi
{
virtual std::int32_t __stdcall QueryBlanket(std::uint32_t*, std::uint32_t*, wchar_t**, std::uint32_t*, std::uint32_t*, void**, std::uint32_t*) noexcept = 0;
virtual std::int32_t __stdcall ImpersonateClient() noexcept = 0;
virtual std::int32_t __stdcall RevertToSelf() noexcept = 0;
virtual std::int32_t __stdcall IsImpersonating() noexcept = 0;
};

struct WINRT_IMPL_ABI_DECL IBufferByteAccess : unknown_abi
WINRT_EXPORT struct WINRT_IMPL_ABI_DECL IBufferByteAccess : unknown_abi
{
virtual std::int32_t __stdcall Buffer(std::uint8_t** value) noexcept = 0;
};

struct WINRT_IMPL_ABI_DECL IMemoryBufferByteAccess : unknown_abi
WINRT_EXPORT struct WINRT_IMPL_ABI_DECL IMemoryBufferByteAccess : unknown_abi
{
virtual std::int32_t __stdcall GetBuffer(std::uint8_t** value, std::uint32_t* capacity) noexcept = 0;
};
Expand Down
Loading