-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Enable /Zc:preprocessor #10593
Enable /Zc:preprocessor #10593
Conversation
b521529
to
a949fd9
Compare
bf821dd
to
ffe7273
Compare
This comment has been minimized.
This comment has been minimized.
ffe7273
to
d09c3a2
Compare
@@ -212,7 +212,7 @@ constexpr bool operator!=(const TextAttribute& a, const TextAttribute& b) noexce | |||
#ifdef UNIT_TESTING | |||
|
|||
#define LOG_ATTR(attr) (Log::Comment(NoThrowString().Format( \ | |||
L#attr L"=%s", VerifyOutputTraits<TextAttribute>::ToString(attr).GetBuffer()))) | |||
L## #attr L"=%s", VerifyOutputTraits<TextAttribute>::ToString(attr).GetBuffer()))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
L#foo
used to turn it into a L"foo"
string, no matter what kind of literal foo
was.
With standard conform macros this doesn't work anymore and we have to cast foo
to a string using #foo
and then concatenate it with L
which forms L## #foo
.
{ \ | ||
std::vector<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry> name##List; \ | ||
_##name##Map = winrt::single_threaded_map<enumType, winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>(); \ | ||
auto enumMapping##name = winrt::Microsoft::Terminal::Settings::Model::EnumMappings::enumMappingsName(); \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can only suggest turning on white space suppressing in the GitHub diff viewer (append ?w=1
to the current url).
In standard conform macros ##
can only be used to concatenate valid symbols together. You can't concatenate with ::
. This change fixes the macro, but also ensures that local variables are eagerly released to the allocator by using a do-while scope.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious: why use do { ... } while(0);
instead of just { ... }
? Wouldn't that accomplish the same thing of adding a scope so that the variabels are released?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The do-while loop has the advantage that it cannot be used in any other statement, for instance within the conditional statement of a while loop or if condition. It forces the programmer to treat the macro as a regular statement that has no return value and that prevents additional misuse.
return sub && isProfilesDefaultsOrigin(sub.SourceProfile()); | ||
}; | ||
|
||
#define DUPLICATE_SETTING_MACRO(settingName) \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These macros were both invalid. Since I had to touch them anyways I fixed their COM overhead as a "drive by". We now use generic lambdas to abstract away as much work as possible from the macro. This doesn't just make debugging and reading easier (the macro looks a lot less scary without the diff), but also reduces code sizes after compilation, since the argument to our generic lambdas will always be the same type.
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage), | ||
TraceLoggingLevel(WINEVENT_LEVEL_ERROR), | ||
TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), | ||
TraceLoggingStruct(14, "wilResult", "wilResult"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Due to the strict macros, trailing commas in a macro are now forbidden. These can occur with variadic macros like
#define FOO(...) foo(123, __VA_ARGS__);
If you don't pass any arguments to FOO
it'll generate a trailing comma, which isn't valid C++ code. One might think trailing commas should be supported in C++, because why not, but they aren't. Instead there's a hackjob called __VA_OPT__
which lets you write
#define FOO(...) foo(123 __VA_OPT__(,) __VA_ARGS__);
Since MSVC doesn't support the official __VA_OPT__
, we have to write ## __VA_ARGS__
from now on, which isn't legit macro syntax, but it works despite using /Zc:preprocessor
.
In this case we don't control TraceLoggingStruct
, which doesn't use the ## __VA_ARGS__
trick.
As such we have to add a third argument (the "comment") to any TraceLoggingWrite parameters from now on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect that I can accept this. Thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can also set it to the empty string explicitly if we want to save on the .rodata segment. That's what used to happen with the previous non-conformant mode anyways (technically).
VERIFY_SUCCEEDED(StringCchCopy(szBuf, ARRAYSIZE(szBuf), L"(ev: ")); | ||
|
||
WEX::Common::NoThrowString str; | ||
str.Append(L"(ev: "); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is not needed. I did it before I realized I had to upgrade the entire TAEF package to make it work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's fine if you keep it in my opinion.
Replaces `KeyModifiers` with the pretty much equivalent `VirtualKeyModifiers` enum in winrt. After doing this I noticed #10593 which changes the KeyChords a lot, but it seems these PRs are still compatible The issue also mentions replacing Vkey with `Windows::System::VirtualKey`, but I chose not to because that enum only includes a subset of the keys terminal supports here (no VK_OEM_* keys) ## Validation Steps Performed Changed key bind in config, and confirmed it still works after restarting terminal Closes #877
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honestly, all of this looks good to me. I think the only thing I found was the duplicate copyright line haha.
That said, this seems like it's a bit too big in scope. I think it'd be nice if you split this into 3 PRs:
- Enable /Zc:preprocessor (Variadic Macro thing)
- (based off 1)
- Clean up KeyChordSerialization
- Add unit tests to til/string
Alternatively, I would be ok with you merging this PR without a squash, then just add a few more details on each commit/endeavor/scenario in the PR body.
@DHowett generally has more opinions regarding the repos commit history haha. Thoughts?
{ \ | ||
std::vector<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry> name##List; \ | ||
_##name##Map = winrt::single_threaded_map<enumType, winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>(); \ | ||
auto enumMapping##name = winrt::Microsoft::Terminal::Settings::Model::EnumMappings::enumMappingsName(); \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious: why use do { ... } while(0);
instead of just { ... }
? Wouldn't that accomplish the same thing of adding a scope so that the variabels are released?
<AdditionalOptions>%(AdditionalOptions) /permissive- /bigobj /Zc:twoPhase-</AdditionalOptions> | ||
<DisableSpecificWarnings>28204;%(DisableSpecificWarnings)</DisableSpecificWarnings> | ||
<ConformanceMode>true</ConformanceMode> | ||
<UseStandardPreprocessor>true</UseStandardPreprocessor> | ||
<AdditionalOptions>%(AdditionalOptions) /bigobj /Zc:twoPhase-</AdditionalOptions> | ||
<DisableSpecificWarnings>5104;5105;28204;%(DisableSpecificWarnings)</DisableSpecificWarnings> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems fine to me, but somebody with way more knowledge of our build system should double check that this is ok.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI the warnings are:
C5104: found 'L#foo' in macro replacement list, did you mean 'L""#foo'?
Which occurs in WRL, which we can't immediately fix. I suggest we migrate everything that uses WRL to WIL over time.C5105: macro expansion producing 'defined' has undefined behavior
This occurs in winbase.h, and is caused by Windows headers using conditional expressions inside definitions. They first declare something like#define FOO (_WIN32_WINNT >= 0x0502)
and then use it as#if FOO
, which isn't valid C/C++.
// Copyright (c) Microsoft Corporation. | ||
// Copyright (c) Microsoft Corporation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops
constexpr std::wstring_view CTRL_KEY{ L"ctrl" }; | ||
constexpr std::wstring_view SHIFT_KEY{ L"shift" }; | ||
constexpr std::wstring_view ALT_KEY{ L"alt" }; | ||
constexpr std::wstring_view WIN_KEY{ L"win" }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why don't these need to be static
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because constexpr
doesn't make any sense whatsoever. If you put a constexpr
in global scope it's behaving as if it was static automatically. I can add static
for consistency.
I'd left a comment on one of the commits, but I am not sure it shows up on the PR. Perhaps email? |
@DHowett Yes I saw it and fixed the issue. It was about the SCW (?) macro change being wrong which I then reverted. |
79c0f42
to
9360050
Compare
std::sort(begin(name##List), end(name##List), EnumEntryComparator<enumType>()); \ | ||
_##name##List = winrt::single_threaded_observable_vector<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>(std::move(name##List)); | ||
#define INITIALIZE_BINDABLE_ENUM_SETTING(name, enumMappingsName, enumType, resourceSectionAndType, resourceProperty) \ | ||
do \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you for taking the opportunity to fix this!
com_ptr<DeadPeasant> tombstone; | ||
tombstone.attach(new DeadPeasant()); | ||
m->_peasants[peasantID] = *tombstone; | ||
m->_peasants[peasantID] = *winrt::make_self<DeadPeasant>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
technically *make_self<T>()
should be equivalent to make<T>()
😄
type _##name{ __VA_ARGS__ }; \ | ||
void _set##name(const type& value) \ | ||
{ \ | ||
const_cast<type&>(_##name) = value; \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh hey! an old implementation detail we didn't need any more.
TRIVIA: The storage for an "observable" property used to be marked const
so that members of the class could not set it without calling _setX
which forced them to send a notification every time they changed it.
<ConformanceMode>true</ConformanceMode> | ||
<UseStandardPreprocessor>true</UseStandardPreprocessor> | ||
<AdditionalOptions>%(AdditionalOptions) /bigobj /Zc:twoPhase-</AdditionalOptions> | ||
<DisableSpecificWarnings>5104;5105;28204;%(DisableSpecificWarnings)</DisableSpecificWarnings> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are fine. They're reports about non-conforming macros that we have to suppress because we turned on the conforming preprocessor.
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage), | ||
TraceLoggingLevel(WINEVENT_LEVEL_ERROR), | ||
TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance), | ||
TraceLoggingStruct(14, "wilResult", "wilResult"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect that I can accept this. Thanks.
VERIFY_SUCCEEDED(StringCchCopy(szBuf, ARRAYSIZE(szBuf), L"(ev: ")); | ||
|
||
WEX::Common::NoThrowString str; | ||
str.Append(L"(ev: "); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's fine if you keep it in my opinion.
Hello @lhecker! Because this pull request has the p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (
|
This commit is a preparation for upcoming changes to KeyChordSerialization for #7539 and #10203. In order to support variadic macros, /Zc:preprocessor was enabled, which required changing unrelated parts of the project. * [x] I work here * [x] Tests added/passed * Project still compiles ✔️ (cherry picked from commit 32fbd4c)
This commit is a preparation for upcoming changes to KeyChordSerialization for #7539 and #10203.
In order to support variadic macros, /Zc:preprocessor was enabled, which required changing unrelated parts of the project.
PR Checklist
Validation Steps Performed