From 44591394d3d4e18ee873f79620dd68713d1dc206 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 17 Oct 2023 16:06:15 -0700 Subject: [PATCH 1/4] Simplify locale's category constants. We need to retain _Locbase and comment it as TRANSITION, ABI because it affects sizeof(locale) due to MSVC's deficient EBCO. (On x64, sizeof(locale) is 16, but removing _Locbase would shrink it to 8.) However, there appears to be nothing stopping us from moving the constants into locale, as depicted in the Standard. I've verified that the DLL's exports are unaffected, and they don't mention _Locbase at all. (They also don't mention the names of these constants, excluding std::collate, std::ctype, and std::messages which are different.) I don't believe we need `_PGLOBAL` - it's rarely used in the STL, and never for new code. crtdefs.h defines it to be `__declspec(process)` for `_M_CEE` (i.e. `/clr` and `/clr:pure`). https://learn.microsoft.com/en-us/cpp/cpp/process?view=msvc-170 explains "When compiling with `/clr`, global and static variables are per-process by default and do not need to use `__declspec(process)`." so this doesn't affect `/clr` at all, which is what matters. (As for `/clr:pure`, it's vanishingly unlikely to matter - these are *constants*, so if multiple application domains start getting multiple copies, who cares?) `using category = int;` is mandated by the Standard. We previously said `int` for the constants, but the Standard depicts `category`, so I'm following that now that the typedef is in scope. Finally, I'm upgrading `const` to `constexpr` - this is not depicted in the Standard, but I believe it's more consistent with the `static constexpr` variables we use everywhere these days. Note that \[constexpr.functions\] forbids constexpr-strengthening functions, but it doesn't care about variables. Using `static constexpr` is what allows the major improvement of dropping the out-of-line definitions - see GH 3381 which made that change to ios_base's base class _Iosb. --- stl/inc/xlocale | 38 ++++++++++---------------------------- 1 file changed, 10 insertions(+), 28 deletions(-) diff --git a/stl/inc/xlocale b/stl/inc/xlocale index d169357747f..0f3738223c6 100644 --- a/stl/inc/xlocale +++ b/stl/inc/xlocale @@ -23,34 +23,7 @@ _STL_DISABLE_CLANG_WARNINGS _STD_BEGIN template -class _Locbase { // define templatized category constants, instantiate on demand -public: - _PGLOBAL static const int collate = _M_COLLATE; - _PGLOBAL static const int ctype = _M_CTYPE; - _PGLOBAL static const int monetary = _M_MONETARY; - _PGLOBAL static const int numeric = _M_NUMERIC; - _PGLOBAL static const int time = _M_TIME; - _PGLOBAL static const int messages = _M_MESSAGES; - _PGLOBAL static const int all = _M_ALL; - _PGLOBAL static const int none = 0; -}; - -template -const int _Locbase<_Dummy>::collate; -template -const int _Locbase<_Dummy>::ctype; -template -const int _Locbase<_Dummy>::monetary; -template -const int _Locbase<_Dummy>::numeric; -template -const int _Locbase<_Dummy>::time; -template -const int _Locbase<_Dummy>::messages; -template -const int _Locbase<_Dummy>::all; -template -const int _Locbase<_Dummy>::none; +class _Locbase {}; // TRANSITION, ABI, affects sizeof(locale) _EXPORT_STD template class collate; @@ -90,6 +63,15 @@ _EXPORT_STD extern "C++" class locale : public _Locbase, public _Crt_new_de public: using category = int; + static constexpr category collate = _M_COLLATE; + static constexpr category ctype = _M_CTYPE; + static constexpr category monetary = _M_MONETARY; + static constexpr category numeric = _M_NUMERIC; + static constexpr category time = _M_TIME; + static constexpr category messages = _M_MESSAGES; + static constexpr category all = _M_ALL; + static constexpr category none = 0; + class _CRTIMP2_PURE_IMPORT id { // identifier stamp, unique for each distinct kind of facet public: __CLR_OR_THIS_CALL id(size_t _Val = 0) : _Id(_Val) {} From 5912090212f12e3e6d733bebe15155b61d4be7e3 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 17 Oct 2023 16:49:54 -0700 Subject: [PATCH 2/4] Drop _Iosb's unused enums and constants. Despite the TRANSITION, ABI comments, the DLL's exports don't mention any of `_Dummy_enum`, `_Dummy_enum_val`, `_Stdio`, `_Openmode`, `_Openmask`, `_Seekdir`, `_Seekbeg`, `_Seekcur`, `_Seekend`, `_Openprot`. `_Dummy_enum` was commented "don't ask" before I got here, and I never knew why. I remember that at some point I tried to mess with it and encountered trouble, which is when the "TRANSITION, ABI" comment was added, but I no longer remember what the problem was. I'm willing to try again, with our vastly increased knowledge of ABI concerns. The `_Seekdir` enumerators were being used exactly once; we can simply hardcode their values. --- stl/inc/xiosbase | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/stl/inc/xiosbase b/stl/inc/xiosbase index 363a51c9575..9b3f113e66b 100644 --- a/stl/inc/xiosbase +++ b/stl/inc/xiosbase @@ -22,7 +22,6 @@ _STD_BEGIN template class _Iosb { // define templatized bitmask/enumerated types, instantiate on demand public: - enum _Dummy_enum { _Dummy_enum_val = 1 }; // don't ask, TRANSITION, ABI enum _Fmtflags { // constants for formatting options _Fmtmask = 0xffff, _Fmtzero = 0 @@ -46,7 +45,6 @@ public: static constexpr int hexfloat = 0x3000; // TRANSITION, ABI, GH-3296 static constexpr int boolalpha = 0x4000; - static constexpr int _Stdio = 0x8000; static constexpr int adjustfield = 0x01C0; // left | right | internal static constexpr int basefield = 0x0E00; // dec | oct | hex static constexpr int floatfield = 0x3000; // scientific | fixed @@ -60,10 +58,6 @@ public: static constexpr int failbit = 0x2; static constexpr int badbit = 0x4; - enum _Openmode { // constants for file opening options - _Openmask = 0xff - }; - static constexpr int in = 0x01; static constexpr int out = 0x02; static constexpr int ate = 0x04; @@ -76,19 +70,9 @@ public: static constexpr int noreplace = _Noreplace; #endif - enum _Seekdir { // constants for file positioning options - _Seekbeg, - _Seekcur, - _Seekend - }; - - static constexpr int beg = _Seekbeg; - static constexpr int cur = _Seekcur; - static constexpr int end = _Seekend; - - enum { // TRANSITION, ABI - _Openprot = _SH_DENYNO - }; + static constexpr int beg = 0; + static constexpr int cur = 1; + static constexpr int end = 2; static constexpr int _Default_open_prot = _SH_DENYNO; // constant for default file opening protection }; From 3d3e971d24a607a9c23175753be7c7c661b3406a Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 24 Oct 2023 13:25:56 -0700 Subject: [PATCH 3/4] Simplify meowfield constants. Co-authored-by: Casey Carter --- stl/inc/xiosbase | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stl/inc/xiosbase b/stl/inc/xiosbase index 9b3f113e66b..c7e400350ba 100644 --- a/stl/inc/xiosbase +++ b/stl/inc/xiosbase @@ -45,9 +45,9 @@ public: static constexpr int hexfloat = 0x3000; // TRANSITION, ABI, GH-3296 static constexpr int boolalpha = 0x4000; - static constexpr int adjustfield = 0x01C0; // left | right | internal - static constexpr int basefield = 0x0E00; // dec | oct | hex - static constexpr int floatfield = 0x3000; // scientific | fixed + static constexpr int adjustfield = left | right | internal; + static constexpr int basefield = dec | oct | hex; + static constexpr int floatfield = scientific | fixed; enum _Iostate { // constants for stream states _Statmask = 0x17 From dfc951b9dda92a2b2c3fae403bd9bd8d4185d6b7 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 24 Oct 2023 18:11:47 -0700 Subject: [PATCH 4/4] Fix MaxMPDCompat. --- stl/inc/xiosbase | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/stl/inc/xiosbase b/stl/inc/xiosbase index c7e400350ba..a1b5ff24ae3 100644 --- a/stl/inc/xiosbase +++ b/stl/inc/xiosbase @@ -75,6 +75,13 @@ public: static constexpr int end = 2; static constexpr int _Default_open_prot = _SH_DENYNO; // constant for default file opening protection + + // TRANSITION, ABI: These enums don't appear in the STL DLL's export surface, but MaxMPDCompat + // in the MSVC-internal build detects that they appear in the CompatibilityData baseline. + enum _Dummy_enum { _Dummy_enum_val = 1 }; + enum _Openmode { _Openmask = 0xff }; + enum _Seekdir { _Seekbeg, _Seekcur, _Seekend }; + enum { _Openprot = _SH_DENYNO }; }; _EXPORT_STD extern "C++" class _CRTIMP2_PURE_IMPORT ios_base : public _Iosb { // base class for ios