Граф коммитов

574 Коммитов

Автор SHA1 Сообщение Дата
David Machaj fa079fb34b
Address variable name collisions in generated consume methods (#1455)
Why is this change being made?
Someone discovered a subtle compatibility issue with the cast result checking changes and certain projected methods. The variables in the consume_ method, such as the generically-named code variable, can shadow the parameters to the function. This led to a build break where a function took an int16_t named code and that was shadowed by the int32_t named code with the HRESULT in it. Fortunately the compiler had our back and flagged the size truncation as a build break so it was noticed.

Briefly summarize what changed
The variable names in these generated functions are now much uglier (and therefore less likely to collide by coincidence). They have an underscore prefix and then lowercase which should put them into an unofficial namespace that shouldn't collide with anything else. The code variable is now named _winrt_cast_result_code for example. While I was renaming everything I realized that my previous names mismatched the cppwinrt naming convention of snake_case so I fixed them up.
2024-11-19 16:25:25 -08:00
David Machaj 2aed347fb7
GitHub Actions workflow cannot build arm32 after updating Windows SDK (#1454)
arm32 is not supported anymore by Windows. There has not been a native arm32 OS since before Win11. The wow32 backcompat on arm64 devices to run arm32 programs was removed with Win11 24H2. Most notably, the ability to build arm32 with newer SDKs and toolsets has seemingly been removed. This is now breaking the CI build.

The easiest fix is to simply remove arm32 support.
2024-11-18 16:52:31 -08:00
David Machaj febda5dfa1
Try to fix the disabled/failing nuget test build step (#1451)
These failures were pointed out yesterday when the CLA policy was stuck. They are not blocking but have seemingly been failing for a long time and the failure is suppressed.

The issue seems to be that some of these test projects reference an old NuGet package while also referencing the props/targets that are about to go into the new NuGet package. Double-including essentially the same files twice is what caused the build breaks in these projects.

Some projects also had build breaks that seem to be related to a very old Windows SDK minimum version. I increased the floor to 10.0.18362.0 (early 2019; almost 6 years ago) and that fixed the remaining breaks. The random packages.config that downloaded random builds of cppwinrt from 2019 or 2020 have been deleted too.

This set of changes aims to fix the build breaks and un-suppress this failure. It now builds locally on my device but I'll need an official PR build to ensure that the GitHub Actions flow is also passing.
2024-11-15 16:12:21 -08:00
David Machaj 8da835950c
try_as casts should not store COM error context; consume method cast checking should use return codes directly (#1450)
Why is this change being made?
I have been trying to ingest the HEAD of cppwinrt for some large internal projects and one of them had some test failures with the new version. The failures are because there is a try_as cast in their code that fails and is handled fine, but it leaves a COM error context floating around on that thread. Subsequent code fails to originate an error because it sees a context already active on the thread and NOOP'ed.

What this boils down to is that try_as should not have a behavioral change to store context when the cast fails.

Briefly summarize what changed
To address this problem I am taking a PR suggestion from @oldnewthing to have a new try_as_with_reason method that returns both the cast result as well as the HRESULT. The error context logic was only there to smuggle the HRESULT out of a call without an HRESULT return value, so if it is a direct return we don't need that anymore. The new method directly returns the HRESULT so there is no ambiguity.

The previous approach relied on a cast operator to call try_as (or just addref when the type is already a match). Thanks to the recent if constexpr code gen change those cases are now separated out. We have a code block where we know a cast is needed so try_as_with_reason can be called unconditionally. The code path where no cast is needed already circumvents this and is nicely unaffected.

This also made check_cast_result equiavelnt to check_hresult so it was deleted in favor of just calling check_hresult.

How was this change tested?
I did local builds of cppwinrt (both Debug and Release) and ran the tests. I am also compiling some large internal projects with it to ensure that there are no obvious breaks or regressions. I am expecting minimal to no binary size impact from this change.
2024-11-15 11:27:27 -08:00
David Machaj d296af6a43
Reduce the code size of generated consume methods by skipping casts when the type is already a match (#1448)
Why is this change being made?
I have been doing some local builds of an internal component against the latest cppwinrt.exe, which includes the fixes in #1442. I have noticed some modest (1%) binary size grown when comparing the April 2024 release and the latest. Using SizeBench to analyze binary size differences I determined that the inlined code gen seems to explain the difference. This change eliminates that increase, at least for the binary I'm testing against, and even shrinks it a bit further.

Briefly summarize what changed
The various winrt::impl::consume_THING methods get heavily inlined in release builds. The current code gen has some casts for when the types don't match (and is an AddRef/Release when they do match). The small amount of new cast result checking ends up at many call sites and slowly adds up a bit. I think we can do better in the cases where the types already match.

This seems to have proven true in practice. Using if constexpr to determine if the type is a match allows us to skip any casts when this is true. In fact that is a net improvement over the original baseline because we don't need to AddRef/Release either. We can directly call the appropriate method. When a cast is necessary the code gen is identical to the previous baseline. The QueryInterface call is unavoidable and so is checking the result.

The code writer format string is definitely starting to creak under the weight of many arguments. I don't want to refactor that as part of this PR but it would be good to simplify in the future.

Also included is late feedback from the previous PR from @oldnewthing. The check_cast_result method can take void* instead of a template argument because it only null checks it. In my local measurements the optimizer already folded them so it makes no binary size difference but it is still a nice change to take.

How was this change tested?
Ran the full suite of cppwinrt tests locally. I also debugged into Windows.Foundation.IStringable.ToString for cases where it both is and is not the correct type. They run the expected code paths. I also checked the binary size of a large example to confirm the expected reduction. The disassembly for a Release build similarly matches expectations.
2024-11-11 16:09:14 -08:00
Ryan Shepherd 849498c617
Latest vpack has an extra cppwinrt folder (#1447) 2024-11-07 16:40:49 -08:00
David Machaj e53db0f9f6
WINRT_SOURCE_LOCATION has ODR checks that prevent mixing cpp17 and cpp20 static libraries (#1444)
Why is this change being made?
Someone is trying to upgrade the cppwinrt version used by a large project that has many static libraries using cppwinrt. Some binaries in that project are mixing static libs with different cpp language versions. (This seems like not a great idea generally but it is the state of the world so to some degree we have to live with it). In those binaries the ODR checks for cppwinrt source_location usage are breaking the build. For good reason, it is not safe to mix this functionality across language versions. This set of changes is aimed at making that upgrade process easier without losing any useful functionality.

Briefly summarize what changed
We already have winrt::impl::slim_source_location which is a lot like std::source_location, minus always containing the very impactful FUNCTION data. This type is powered by the same intrinsics as the STL version so it works as well as the STL library. The existence of this class means that we can avoid the ODR violations by always using winrt::impl::slim_source_location.

Some new macros are used to control what goes into the constructor. cpp20 code that does not suppress source_location will get valid source information passed in. Code that is cpp17, or suppresses this feature, will have zero's passed in. Furthermore, when compiling as _DEBUG this will also include the FUNCTION data, matching previous behavior.

The net result is that there is no more ODR violation because the function signatures are always the same.

How was this change tested?
build_test_all.cmd for both release and debug. I also created a little project that mixes cpp17 and cpp20 libraries. With the latest public release of cppwinrt this project does not build because of the ODR violations. With these changes it builds and runs as expected.
2024-11-04 14:53:42 -08:00
David Machaj b82340f3fc
Bug: Projected winrt::consume_ methods will nullptr crash if the underlying QueryInterface call fails (#1442)
# Why is this change being made?
The generated projection code for interfaces that the metadata declares as required for a runtimeclass assume that QueryInterface never fails. Assuming the metadata is correct in the first place, this is a valid assumption for inproc calls.

However, for cross-process calls the QI can fail even if the metadata is correct and the class really does implement all of the required interfaces. It can fail with E_ACCESSDENIED and a variety of other RPC error codes.

When this happens there is a nullptr crash in the generated consume method. This can be very painful to debug because the HRESULT is lost by the time it crashes.

# Briefly summarize what changed
This set of changes fixes the crash by detecting the QueryInterface error and throwing an exception when that occurs during one of these required casts. The try_as method was changed to capture COM error context when the QI fails. The code gen surrounding WINRT_IMPL_STUB was changed to save the result into a temporary variable and then pass it to a new check_cast_result method. check_cast_result is marked noinline so that the binary size impact of throwing exceptions is limited to a single function instead of inlining into high-volume generated code.

If the cast succeeded then nothing happens. If the cast failed, returning null, then the stored COM exception is retrieved. Assuming it is available the HRESULT is pulled out of it and it is thrown. This then propagates like any other exception. Callers are free to try and catch it or let it go uncaught and crash. Now they have the choice.

I also added a new file of test code that exercises this code path. The test_component IDL declares a runtimeclass that implements IStringable. And then the implementation fails to implement IStringable. When ToString is called on this object it hits the failure path. The cppwinrt code gen will not allow this to happen so I had to directly use winrt::implements.

# How was this change tested?
Besides the new test cases I also wrote a little console app that crashes this way. I built and ran it using the latest stable cppwinrt as well as my private new one. As expected the debugger blame is far more useful with these changes.
2024-10-30 09:54:35 -07:00
Ryan Shepherd 2744f5cc70
Value-init fields of WinRT structs (#1443) 2024-10-29 14:40:36 -07:00
Duncan Horn f9ec198608
Silence clang-tidy warnings (#1438) 2024-10-02 15:15:26 -07:00
Nate Thorn c5e0aaeb53
Clarify how InitializeComponent works in the template comment (#1435) 2024-09-16 13:33:55 -07:00
Manodasan Wignarajah 64d2a52dd5
Update NuGetCommand to use nuget.config (#1434) 2024-09-10 14:30:54 -07:00
Manodasan Wignarajah 2e4bdb05da
Add NuGet config with public feed (#1433) 2024-09-05 10:22:01 -07:00
Michael Maltsev 0deecf1ea4
Add missing `<exception>` to `base_includes.h` (#1427) 2024-07-31 10:54:05 -05:00
Felix Patschkowski 4834e605f4
Changed visibility of `observable_map_base::call_changed` to `protected` 2024-07-11 09:34:26 -05:00
Dependabot a22626ae6f Merge pull request 10563206 from dependabot/nuget/vsix/Newtonsoft.Json-13.0.1 into master 2024-04-16 19:50:15 +00:00
Josh Soref 881b5614b8
Spelling (#1412) 2024-04-06 07:17:18 -05:00
Josh Soref bc19737a14
Use latest cache action (#1411) 2024-04-05 17:27:02 -05:00
Scott Jones d2a66776bb
Remove references to stale winmd files to fix incremental builds (#1404)
The original attempt at a fix for this was too aggressive:
https://github.com/microsoft/cppwinrt/pull/1381/files

This fix is targeted specifically at removing references to stale winmd files that have yet to be copied from referenced projects (e.g., from a runtime component to an app).
2024-04-05 13:15:18 -07:00
Josh Soref e03bdc4e39
Use latest upload/download actions (#1410) 2024-04-05 13:16:37 -05:00
Kenny Kerr 17d095ac93
Fix build following dependabot updates (#1409) 2024-04-05 09:39:24 -05:00
Kenny Kerr 2b8fe6e000 Revert "Bump actions/upload-artifact from 3 to 4 (#1407)" 2024-04-05 08:35:15 -05:00
dependabot[bot] ea187691c1
Bump actions/download-artifact from 3 to 4 (#1408) 2024-04-05 08:11:19 -05:00
dependabot[bot] 6f7495288c
Bump actions/upload-artifact from 3 to 4 (#1407) 2024-04-05 07:59:41 -05:00
dependabot[bot] 523eda71a6
Bump actions/stale from 6 to 9 (#1405) 2024-04-05 07:56:22 -05:00
dependabot[bot] dfad7ed2ca
Bump actions/checkout from 3 to 4 (#1406) 2024-04-05 07:55:51 -05:00
Kenny Kerr f0ce6c6798
Create dependabot.yml 2024-04-05 07:52:22 -05:00
TDBuild adc6ef9318 TDBuild - updating localized resource files. 2024-03-31 05:01:31 +00:00
Ryan Shepherd bdf6dc462b
Merlinbot baseline (#1401)
* Merged PR 9973274: Auto-generated baselines by 1ES Pipeline Templates

This pull request includes baselines **with an expiration date of 180 days from now** automatically generated for your 1ES PT-based pipelines. Complete this pull request as soon as possible to make sure that your pipeline becomes compliant. Longer delays in completing this PR can trigger additional emails or S360 alerts in the future.

1ES PT Auto-baselining feature helps capture existing violations in your repo and ensures to break your pipeline only for newly introduced SDL violations after baselining. Running SDL tools in break mode is required for your pipeline to be compliant. Go to https://aka.ms/1espt-autobaselining for more details.

* Merged PR 9973274: Auto-generated baselines by 1ES Pipeline Templates

This pull request includes baselines **with an expiration date of 180 days from now** automatically generated for your 1ES PT-based pipelines. Complete this pull request as soon as possible to make sure that your pipeline becomes compliant. Longer delays in completing this PR can trigger additional emails or S360 alerts in the future.

1ES PT Auto-baselining feature helps capture existing violations in your repo and ensures to break your pipeline only for newly introduced SDL violations after baselining. Running SDL tools in break mode is required for your pipeline to be compliant. Go to https://aka.ms/1espt-autobaselining for more details.

---------

Co-authored-by: MerlinBot <MerlinBot>
2024-03-29 10:42:29 -07:00
Dan Legg 6dccf9ef88
Pipeline changes to build, publish, and test (#1400)
Co-authored-by: Dan Legg <dalegg@microsoft.com>
2024-03-28 18:06:25 -07:00
Kenny Kerr e69ff22721
Remove dead code related to Windows 7 support (#1390) 2024-02-08 12:46:38 -06:00
Charles Milette 91f485fbf2
Remove double forward (#1387)
* Remove double forward

* Fix compilation issues
2024-01-22 11:47:43 -08:00
Kenny Kerr 2bfcd7524a
Fail gracefully when error reporting is suppressed (#1386) 2024-01-16 13:00:38 -06:00
Ryan Shepherd 25a14f8965
Update build.yml for Azure Pipelines (#1384)
#1338 changed the NuGet version to a property, but didn't update the build.yml to do the same thing
2024-01-11 20:12:06 -08:00
Scott Jones cb674723b4
CppWinRTAddXamlReferences to not use outputs as inputs (#1381)
Incremental builds fail when a referenced project's winmd has been updated.  This is because the CppWinRT reference projection is properly using project's referenced winmds as inputs.  But the MarkupCompilePass2 target is using XamlReferencesToCompile, which has been set here to use previously copied output files.
2023-12-28 10:59:33 -08:00
David Machaj 5ef408f8b0
User/dmachaj/slim source location (#1379)
* First draft of slim_source_location

* Fix build breaks from first impl

* Fix failing test case
2023-12-22 11:47:37 -08:00
Manodasan Wignarajah 2511bf7fcb
Update pool (#1374) 2023-12-06 15:33:21 -08:00
Raymond Chen fc587f31f9
Allow delegates to be created with weak reference + lambda (#1372)
We have found that a very common pattern for event handlers is
to capture a weak reference into a lambda, and in the event handler,
try to upgrade the weak reference to a strong one, and if so, do some work:

```cpp
widget.Closed([weak = get_weak(), data](auto&& sender, auto&& args)
{
    if (auto strongThis = weak.get())
    {
        strongThis->do_all_the_things(data);
    }
});
```

This commit extends the existing delegate constructors to permit a
`winrt::weak_ref` + lambda (or `std::weak_ptr` + lambda), which
simplifies the above to

```cpp
widget.Closed({ get_weak(), [this, data](auto&& sender, auto&& args)
{
    do_all_the_things(data);
} });
```

## Implementation notes

A lambda and pointer to member function are hard to distinguish
in a template parameter list. In theory, we could use SFINAE or
partial specialization, but a simpler solution is to distinguish
the two inside the body of the constructor, via
`std::is_member_function_pointer_v`.

The `com_ptr` and `shared_ptr` variants of the test were
unified, since I found myself editing two nearly identical tests.

Fixes #1371

Co-authored-by: Jon Wiswall <jonwis@microsoft.com>
2023-11-25 23:18:59 -08:00
Jon Wiswall 912aa47ff4
Update GitHub action LLVM version to 17.0.5 (#1373)
* Maybe update tools version

* LLVM & Clang v17.0.5 now support source_location properly
2023-11-25 21:48:38 -08:00
Raymond Chen bf4459b25a
Allow resume_agile to be stored in a variable (#1358)
`resume_agile` exposes the ability to save the `await_adapter`
in a variable. This was not possible without `resume_agile` because
the `await_adapter` had previously been available only via
`operator co_await`, which means that it is created only in
response to an immediate attempt to `co_await` it, so we knew
that it would be consumed before its argument (possibly a temporary)
was destructed.

`resume_agile` returns the `await_adapter`, and we expect people
to await it immediately, but it's possible that they decide to
save it in a variable and await it later. In that case, we have
to record the `Async` as a value instead of a reference. We forward
the `resume_agile` argument into the `Async` so that it moves
if given an rvalue reference, or copies if given an lvalue reference.
This ensure that the common case where somebody does
`co_await resume_agile(DoSomething())`, we do not incur any additional
AddRefs or Releases.

Now that it's possible to `co_await` the `await_adapter` twice,
we have to worry about `await_suspend` being called twice. It had
previously assumed that `suspending` was true (since that's how it
was constructed), but that is no longer valid in the `resume_agile`
case if somebody tries to await the `resume_agile` twice. So we have
to force it to `true`. (Now, the second await will fail with
"illegal delegate assignment", but our failure to set `suspending`
to `true` led to double-resumption, which is super-bad.)
2023-09-14 16:19:23 -07:00
Raymond Chen fac72c82b0
Add `resume_agile` to allow coroutine to resume in any apartment (#1356) 2023-09-12 13:25:16 -05:00
David Lechner 23c4ced66a
Improve GCC compatibility (#1352) 2023-09-02 12:14:52 -05:00
Jon Wiswall 691f6f8c9d
Support for std::span for winrt::array_view and winrt::com_array (#1343)
* Implicit conversion between std::span and winrt::array_view

* Add testing and additional ctad for spans

* PR FB - yes, yes it does!

* PR FB

---------

Co-authored-by: Jaiganésh Kumaran <jaiganesh.kumaran@outlook.com>
Co-authored-by: Jon Wiswall <jonwis@ntdev.microsoft.com>
Co-authored-by: Kenny Kerr <kenny@kennykerr.ca>
2023-08-28 10:24:04 -07:00
Kenny Kerr de6ca88bd6
Remove old Windows 7 support code (#1348) 2023-08-28 08:35:09 -05:00
Jon Wiswall 9b453cfc51
Enable faster dev cycle in Visual Studio (#1340)
* Enable faster dev cycle in Visual Studio

* Oops, remove one more run

* Fix linux build temporarily - see also #1341

---------

Co-authored-by: Jon Wiswall <jonwis@ntdev.microsoft.com>
2023-08-17 15:51:08 -07:00
Jon Wiswall 4196e08bd2
Increase foldability of various templates (#1338)
* Add SDKReference-sourced WinMDs when building

* Add solution items so they're more easily edited

* Update development guidance slightly

* First attempt at template folding

* Make packages easier to build, remove warning about unreferenced static

* Lift delegate creation out for better folding

* More folding of events

* Another delegate folded

* PR feedback

* Speculative improvement for QueryInterface

* PR feedback

---------

Co-authored-by: Jon Wiswall <jdwiswall@hotmail.com>
Co-authored-by: Kenny Kerr <kekerr@microsoft.com>
Co-authored-by: Jon Wiswall <jonwis@ntdev.microsoft.com>
2023-08-09 23:40:40 -07:00
Charles Milette 0958cf3a4d
Hide protected and overridable members from public projections (#1319) 2023-07-11 21:38:42 -05:00
Charles Milette 953d65cc85
Register event handlers with `shared_ptr` and `weak_ptr` (#1330) 2023-07-10 17:16:10 -05:00
Charles Milette 297454ee28
Allow classic COM interfaces with get_self (#1314)
* Allow classic COM interfaces with get_self

Fixes #1312

* Fix mingw builds

---------

Co-authored-by: Kenny Kerr <kenny@kennykerr.ca>
2023-06-27 09:40:35 -07:00
David Machaj d3bb275464
Fix source location test failure resulting from newer compiler (#1326) 2023-06-22 12:39:33 -05:00