Skip to content

Commit 5fc993f

Browse files
authored
Cleanup WINRT_EXPORT (#64)
1 parent a41c57b commit 5fc993f

3 files changed

Lines changed: 110 additions & 42 deletions

File tree

cppwinrt/code_writers.h

Lines changed: 63 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,18 @@ namespace cppwinrt
194194

195195
[[nodiscard]] static finish_with wrap_impl_namespace(writer& w)
196196
{
197-
auto format = R"(WINRT_EXPORT namespace winrt::impl
197+
auto format = R"(WINRT_EXPORT extern "C++" namespace winrt::impl
198+
{
199+
)";
200+
201+
w.write(format);
202+
203+
return { w, write_close_namespace };
204+
}
205+
206+
[[nodiscard]] static finish_with wrap_impl_namespace_without_export(writer& w)
207+
{
208+
auto format = R"(extern "C++" namespace winrt::impl
198209
{
199210
)";
200211

@@ -205,7 +216,7 @@ namespace cppwinrt
205216

206217
[[nodiscard]] static finish_with wrap_std_namespace(writer& w)
207218
{
208-
w.write(R"(WINRT_EXPORT namespace std
219+
w.write(R"(extern "C++" namespace std
209220
{
210221
)");
211222

@@ -214,7 +225,7 @@ namespace cppwinrt
214225

215226
[[nodiscard]] static finish_with wrap_type_namespace(writer& w, std::string_view const& ns)
216227
{
217-
auto format = R"(WINRT_EXPORT namespace winrt::@
228+
auto format = R"(WINRT_EXPORT extern "C++" namespace winrt::@
218229
{
219230
)";
220231

@@ -225,7 +236,7 @@ namespace cppwinrt
225236

226237
[[nodiscard]] static finish_with wrap_type_namespace_without_export(writer& w, std::string_view const& ns)
227238
{
228-
auto format = R"(namespace winrt::@
239+
auto format = R"(extern "C++" namespace winrt::@
229240
{
230241
)";
231242

@@ -1548,7 +1559,7 @@ namespace cppwinrt
15481559
}
15491560
}
15501561

1551-
static void write_consume(writer& w, TypeDef const& type)
1562+
static void write_consume_type(writer& w, TypeDef const& type)
15521563
{
15531564
auto generics = type.GenericParam();
15541565
auto guard{ w.push_generic_params(generics) };
@@ -1561,51 +1572,71 @@ namespace cppwinrt
15611572

15621573
auto type_namespace = type.TypeNamespace();
15631574
auto impl_name = get_impl_name(type_namespace, type_name);
1564-
1575+
15651576
if (empty(generics))
15661577
{
1567-
auto format = R"( template <typename D>
1578+
auto format = R"( template <typename D>
15681579
struct consume_%
15691580
{
15701581
%%% };
1571-
template <> struct consume<%>
1572-
{
1573-
template <typename D> using type = consume_%<D>;
1574-
};
15751582
)";
1576-
1577-
15781583
w.write(format,
1579-
impl_name,
1580-
bind_each<write_consume_declaration>(type.MethodList()),
1581-
bind<write_fast_consume_declarations>(type),
1582-
bind<write_consume_extensions>(type),
1583-
type,
1584-
impl_name);
1584+
impl_name,
1585+
bind_each<write_consume_declaration>(type.MethodList()),
1586+
bind<write_fast_consume_declarations>(type),
1587+
bind<write_consume_extensions>(type));
15851588
}
15861589
else
15871590
{
1588-
auto format = R"( template <typename D, %>
1591+
auto format = R"( template <typename D, %>
15891592
struct consume_%
15901593
{
15911594
%%% };
1592-
template <%> struct consume<%>
1595+
)";
1596+
w.write(format,
1597+
bind<write_generic_typenames>(generics),
1598+
impl_name,
1599+
bind_each<write_consume_declaration>(type.MethodList()),
1600+
bind<write_fast_consume_declarations>(type),
1601+
bind<write_consume_extensions>(type));
1602+
}
1603+
}
1604+
1605+
static void write_consume_specialization(writer& w, TypeDef const& type)
1606+
{
1607+
auto generics = type.GenericParam();
1608+
auto guard{ w.push_generic_params(generics) };
1609+
auto type_name = type.TypeName();
1610+
1611+
if (!empty(generics))
1612+
{
1613+
type_name = remove_tick(type_name);
1614+
}
1615+
1616+
auto type_namespace = type.TypeNamespace();
1617+
auto impl_name = get_impl_name(type_namespace, type_name);
1618+
1619+
if (empty(generics))
1620+
{
1621+
auto format = R"( template <> struct consume<%>
1622+
{
1623+
template <typename D> using type = consume_%<D>;
1624+
};
1625+
)";
1626+
w.write(format, type, impl_name);
1627+
}
1628+
else
1629+
{
1630+
auto format = R"( template <%> struct consume<%>
15931631
{
15941632
template <typename D> using type = consume_%<D, %>;
15951633
};
15961634
)";
1597-
1598-
15991635
w.write(format,
1600-
bind<write_generic_typenames>(generics),
1601-
impl_name,
1602-
bind_each<write_consume_declaration>(type.MethodList()),
1603-
bind<write_fast_consume_declarations>(type),
1604-
bind<write_consume_extensions>(type),
1605-
bind<write_generic_typenames>(generics),
1606-
type,
1607-
impl_name,
1608-
bind_list(", ", generics));
1636+
bind<write_generic_typenames>(generics),
1637+
type,
1638+
impl_name,
1639+
bind_list(", ", generics));
16091640
}
16101641
}
16111642

cppwinrt/file_writers.h

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ namespace cppwinrt
4444
{
4545
auto wrap_file_guard = wrap_open_file_guard(w, "BASE");
4646

47+
if (settings.modules)
48+
{
49+
w.write("#ifndef WINRT_CONSUME_MODULE\n");
50+
}
51+
4752
{
4853
// In module builds, generated projection headers must be "module-aware":
4954
// When `WINRT_MODULE` is defined (inside a module interface unit), suppress textual includes so the
@@ -52,6 +57,13 @@ namespace cppwinrt
5257
auto wrap_includes_guard = wrap_module_aware_includes_guard(w, settings.modules);
5358
w.write(strings::base_includes);
5459
}
60+
if (settings.modules)
61+
{
62+
w.write(R"(
63+
extern "C++"
64+
{
65+
)");
66+
}
5567

5668
w.write(strings::base_macros);
5769
w.write(strings::base_types);
@@ -85,6 +97,18 @@ namespace cppwinrt
8597
w.write(strings::base_coroutine_threadpool);
8698
w.write(strings::base_natvis);
8799
w.write(strings::base_version);
100+
101+
if (settings.modules)
102+
{
103+
w.write(R"(
104+
} // extern "C++"
105+
)");
106+
}
107+
108+
if (settings.modules)
109+
{
110+
w.write("#endif\n");
111+
}
88112
}
89113
w.flush_to_file(settings.output_folder + "winrt/base.h");
90114
}
@@ -142,7 +166,7 @@ namespace cppwinrt
142166
w.write_each<write_forward>(members.contracts);
143167
}
144168
{
145-
auto wrap_impl = wrap_impl_namespace(w);
169+
auto wrap_impl = wrap_impl_namespace_without_export(w);
146170
w.write_each<write_category>(members.interfaces, "interface_category");
147171
w.write_each<write_category>(members.classes, "class_category");
148172
w.write_each<write_category>(members.enums, "enum_category");
@@ -165,10 +189,19 @@ namespace cppwinrt
165189
w.write_each<write_default_interface>(members.classes);
166190
w.write_each<write_interface_abi>(members.interfaces);
167191
w.write_each<write_delegate_abi>(members.delegates);
168-
w.write_each<write_consume>(members.interfaces);
169192
w.write_each<write_struct_abi>(members.structs);
170193
}
171194

195+
{
196+
auto wrap_impl = wrap_impl_namespace(w);
197+
w.write_each<write_consume_type>(members.interfaces);
198+
}
199+
200+
{
201+
auto wrap_impl = wrap_impl_namespace_without_export(w);
202+
w.write_each<write_consume_specialization>(members.interfaces);
203+
}
204+
172205
if (settings.modules)
173206
{
174207
get_namespace_module_imports(c, ns, w, module_imports);
@@ -353,22 +386,28 @@ export import winrt.numerics;
353386
write_module_global_fragment(w);
354387

355388
w.write(R"(
389+
// Include in advance so that all of numerics's dependencies can be in the global module fragment
390+
#if __has_include(<directxmath.h>) && __has_include(<windowsnumerics.impl.h>)
391+
#include <stdexcept>
392+
#include <limits>
393+
#include <directxmath.h>
394+
#endif
395+
356396
export module winrt.numerics;
357397
358398
// Module dependencies:
359399
// - (none)
360400
361-
#if __has_include(<windowsnumerics.impl.h>)
401+
#if __has_include(<directxmath.h>) && __has_include(<windowsnumerics.impl.h>)
362402
#ifdef _MSC_VER
363403
#pragma warning(push)
364404
#pragma warning(disable : 5244)
365405
#endif
366-
#include <directxmath.h>
367-
368406
#define _WINDOWS_NUMERICS_NAMESPACE_ winrt::Windows::Foundation::Numerics
369407
#define _WINDOWS_NUMERICS_BEGIN_NAMESPACE_ export extern "C++" namespace winrt::Windows::Foundation::Numerics
370408
#define _WINDOWS_NUMERICS_END_NAMESPACE_
371-
#include <windowsnumerics.impl.h>
409+
// Double quotes are intentionally used because compilers (MSVC and Clang) consider system headers should not be module implementation files.
410+
#include "windowsnumerics.impl.h"
372411
#undef _WINDOWS_NUMERICS_NAMESPACE_
373412
#undef _WINDOWS_NUMERICS_BEGIN_NAMESPACE_
374413
#undef _WINDOWS_NUMERICS_END_NAMESPACE_

strings/base_macros.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,19 @@
2727
#pragma warning(disable : 4630)
2828
#endif
2929

30-
#ifndef WINRT_EXPORT
3130
#ifdef WINRT_MODULE
32-
#define WINRT_EXPORT export extern "C++"
31+
#define WINRT_EXPORT export
3332
#else
3433
#define WINRT_EXPORT
3534
#endif
36-
#endif
3735

3836
// <windowsnumerics.impl.h> pulls in large, hard-to-control legacy headers. In header builds we keep the
3937
// existing behavior, but in module builds it's provided by the winrt.numerics module.
4038
#if !(defined(WINRT_MODULE) || defined(WINRT_CONSUME_MODULE))
4139

4240
#ifdef WINRT_IMPL_NUMERICS
4341
#define _WINDOWS_NUMERICS_NAMESPACE_ winrt::Windows::Foundation::Numerics
44-
#define _WINDOWS_NUMERICS_BEGIN_NAMESPACE_ WINRT_EXPORT namespace winrt::Windows::Foundation::Numerics
42+
#define _WINDOWS_NUMERICS_BEGIN_NAMESPACE_ extern "C++" namespace winrt::Windows::Foundation::Numerics
4543
#define _WINDOWS_NUMERICS_END_NAMESPACE_
4644
#include <windowsnumerics.impl.h>
4745
#undef _WINDOWS_NUMERICS_NAMESPACE_

0 commit comments

Comments
 (0)