Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standard Library Modules: Fix time_put<wchar_t> linker errors #3232

Merged
merged 4 commits into from
Nov 18, 2022
Merged
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
18 changes: 9 additions & 9 deletions stl/inc/xlocale
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ _NODISCARD int _Codecvt_do_length(

enum _Codecvt_mode { _Consume_header = 4, _Generate_header = 2 };

template <>
extern "C++" template <>
class _CRTIMP2_PURE_IMPORT_UNLESS_CODECVT_ID_SATELLITE _CXX20_DEPRECATE_CODECVT_FACETS
codecvt<char16_t, char, mbstate_t> : public codecvt_base {
// facet for converting between char16_t and UTF-8 byte sequences
Expand Down Expand Up @@ -1141,7 +1141,7 @@ private:
_Codecvt_mode _Mode; // default: _Consume_header
};

template <>
extern "C++" template <>
class _CRTIMP2_PURE_IMPORT_UNLESS_CODECVT_ID_SATELLITE _CXX20_DEPRECATE_CODECVT_FACETS
codecvt<char32_t, char, mbstate_t> : public codecvt_base {
// facet for converting between char32_t and UTF-8 byte sequences
Expand Down Expand Up @@ -1395,7 +1395,7 @@ struct _NODISCARD _Codecvt_guard {
}
};

template <>
extern "C++" template <>
class codecvt<char16_t, char8_t, mbstate_t> : public codecvt_base {
// facet for converting between UTF-16 and UTF-8 sequences
public:
Expand Down Expand Up @@ -1676,7 +1676,7 @@ protected:
}
};

template <>
extern "C++" template <>
class codecvt<char32_t, char8_t, mbstate_t> : public codecvt_base {
// facet for converting between UTF-32 and UTF-8 sequences
public:
Expand Down Expand Up @@ -1919,7 +1919,7 @@ protected:
};
#endif // defined(__cpp_char8_t) && !defined(_M_CEE_PURE)

template <>
extern "C++" template <>
class _CRTIMP2_PURE_IMPORT codecvt<wchar_t, char, mbstate_t> : public codecvt_base {
// facet for converting between wchar_t and char (_Byte) sequences
public:
Expand Down Expand Up @@ -2118,7 +2118,7 @@ private:
};

#if defined(_NATIVE_WCHAR_T_DEFINED) && !_ENFORCE_FACET_SPECIALIZATIONS
template <>
extern "C++" template <>
class _CRTIMP2_PURE_IMPORT codecvt<unsigned short, char, mbstate_t> : public codecvt_base {
// facet for converting between unsigned short and char sequences
public:
Expand Down Expand Up @@ -2615,7 +2615,7 @@ locale::id ctype<_Elem>::id;
#pragma clang diagnostic pop
#endif // __clang__

template <>
extern "C++" template <>
class _CRTIMP2_PURE_IMPORT ctype<char> : public ctype_base { // facet for classifying char elements, converting cases
public:
using _Elem = char;
Expand Down Expand Up @@ -2805,7 +2805,7 @@ private:
_Locinfo::_Ctypevec _Ctype; // information
};

template <>
extern "C++" template <>
class _CRTIMP2_PURE_IMPORT ctype<wchar_t>
: public ctype_base { // facet for classifying wchar_t elements, converting cases
public:
Expand Down Expand Up @@ -3006,7 +3006,7 @@ private:
};

#if defined(_NATIVE_WCHAR_T_DEFINED) && !_ENFORCE_FACET_SPECIALIZATIONS
template <>
extern "C++" template <>
class _CRTIMP2_PURE_IMPORT ctype<unsigned short>
: public ctype_base { // facet for classifying unsigned short elements, converting cases
public:
Expand Down
9 changes: 4 additions & 5 deletions stl/inc/xloctime
Original file line number Diff line number Diff line change
Expand Up @@ -772,9 +772,8 @@ __PURE_APPDOMAIN_GLOBAL locale::id time_put<_Elem, _OutIt>::id;
#pragma clang diagnostic pop
#endif // __clang__

template <class _OutIt>
class _CRTIMP2_PURE_IMPORT time_put<wchar_t, _OutIt>
: public locale::facet { // facet for converting encoded times to wchar_t text
extern "C++" template <class _OutIt>
class time_put<wchar_t, _OutIt> : public locale::facet { // facet for converting encoded times to wchar_t text
public:
using _Elem = wchar_t;
using char_type = _Elem;
Expand Down Expand Up @@ -905,8 +904,8 @@ __PURE_APPDOMAIN_GLOBAL locale::id time_put<wchar_t, _OutIt>::id;

#if defined(_CRTBLD)

template <class _OutIt>
class _CRTIMP2_PURE_IMPORT time_put<unsigned short, _OutIt>
extern "C++" template <class _OutIt>
class time_put<unsigned short, _OutIt>
: public locale::facet { // facet for converting encoded times to unsigned short text
public:
using _Elem = unsigned short;
Expand Down
37 changes: 37 additions & 0 deletions tests/std/include/test_header_units_and_modules.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1004,6 +1004,41 @@ void test_version() {
#endif // ^^^ named modules ^^^
}

// VSO-1593165 "Standard Library Modules: time_put<wchar_t> emits bogus error LNK2019: unresolved external symbol"
void test_VSO_1593165() {
using namespace std;
puts("Testing VSO-1593165.");

// Originally from the Dev11_0494593_time_put_wchar_t test:
using Facet = time_put<wchar_t, wstring::iterator>;

const tm t = [] {
tm ret{};

ret.tm_sec = 57;
ret.tm_min = 42;
ret.tm_hour = 20;
ret.tm_mday = 28;
ret.tm_mon = 3;
ret.tm_year = 108;
ret.tm_wday = 1;
ret.tm_yday = 118;
ret.tm_isdst = 0;

return ret;
}();
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved

const locale l;
wstring s(15, L'x');
wstringstream stream;
const wchar_t fill = L' ';
const wchar_t pattern[] = L"%Y.%m.%d";
const wstring::iterator ret = use_facet<Facet>(l).put(s.begin(), stream, fill, &t, begin(pattern), end(pattern));
assert(ret == s.begin() + 11);
const wstring correct(L"2008.04.28\0xxxx", 15);
assert(s == correct);
}

void all_cpp_header_tests() {
test_algorithm();
test_any();
Expand Down Expand Up @@ -1085,4 +1120,6 @@ void all_cpp_header_tests() {
test_variant();
test_vector();
test_version();

test_VSO_1593165();
}