There are cases in StructConversionFunction.definition where we will generate copy code for extension struct members, without emitting the definition of the "in_ext" variable used in the copy code.
This issue is triggered by mismatches in the condition that guards the generation of the "in_ext" definition, and the condition(s) that govern the generation of the member copy code (e.g., in StructConversionFunction.member_needs_copy and VkMember.needs_conversion).
In order to avoid such mismatches and the burden of having to keep the conditions in sync, this commit generates the definition on demand, by checking if it's actually needed by the member copy code.
Signed-off-by: Alexandros Frantzis alexandros.frantzis@collabora.com
--
Some more details in case a different solution becomes apparent.
An example of the aforementioned issue can be triggered if we make VK_EXT_image_drm_format_modifier an UNEXPOSED extension in `make_vulkan`:
``` ../wine/dlls/winevulkan/vulkan_thunks.c: In function ‘convert_VkFormatProperties2_win32_to_host’: ../wine/dlls/winevulkan/vulkan_thunks.c:10214:119: error: ‘in_ext’ undeclared (first use in this function); did you mean ‘index’? 10214 | out_ext->pDrmFormatModifierProperties = convert_VkDrmFormatModifierPropertiesEXT_array_win32_to_host(ctx, in_ext->pDrmFormatModifierProperties, in_ext->drmFormatModifierCount); | ^~~~~~ | index ```
In this particular case the mismatch happens because for the `VkDrmFormatModifierPropertiesListEXT` (returnedonly=true) struct in the INPUT direction the current check doesn't emit `in_ext`:
``` if self.direction == Direction.OUTPUT or not ext.returnedonly: # Not triggered body += ident + "{0} *in_ext = ({0} *)in_header;\n".format(in_type) ```
but `self.member_needs_copy(ext, m)` below for the "pDrmFormatModifierProperties" member returns `True`, requiring `in_ext`. The flow is:
``` * self.member_needs_copy(ext, m) => True if m.name != "sType" and struct.returnedonly and not m.needs_conversion(self.conv, self.unwrap, Direction.INPUT, self.const): # Not triggered return False return True * m.needs_conversion(self.conv, self.unwrap, Direction.INPUT, self.const) => True # if pointer member needs output conversion, it also needs input conversion # to allocate the pointer if direction == Direction.INPUT and self.is_pointer() and \ self.needs_conversion(conv, unwrap, Direction.OUTPUT, struct_const): return True ```
From: Alexandros Frantzis alexandros.frantzis@collabora.com
There are cases in StructConversionFunction.definition where we will generate copy code for extension struct members, without emitting the definition of "in_ext" variable used in the copy code.
This issue is triggered by mismatches in the condition that guards the generation of the "in_ext" definitions, and the condition(s) that govern the generation of the member copy code (e.g., in StructConversionFunction.member_needs_copy and VkMember.needs_conversion).
In order to avoid such mismatches and the burden of having to keep the conditions in sync, this commit generates the definition on demand, by checking if it's actually needed by the member copy code.
Signed-off-by: Alexandros Frantzis alexandros.frantzis@collabora.com --- dlls/winevulkan/make_vulkan | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan index 3257481b746..8c0cd7bc8ec 100755 --- a/dlls/winevulkan/make_vulkan +++ b/dlls/winevulkan/make_vulkan @@ -2199,20 +2199,25 @@ class StructConversionFunction(object): body += ident + "{0} *out_ext = conversion_context_alloc(ctx, sizeof(*out_ext));\n".format(out_type) else: body += ident + "{0} *out_ext = find_next_struct(out_header, {1});\n".format(out_type, stype) - if self.direction == Direction.OUTPUT or not ext.returnedonly: - body += ident + "{0} *in_ext = ({0} *)in_header;\n".format(in_type) + + copy_body = ""
for m in ext: if m.name == "sType": - body += ident + "out_ext->sType = {0};\n".format(stype) + copy_body += ident + "out_ext->sType = {0};\n".format(stype) continue if not self.member_needs_copy(ext, m): continue if m.name == "pNext": - body += ident + "out_ext->pNext = NULL;\n" + copy_body += ident + "out_ext->pNext = NULL;\n" continue
- body += ident + m.copy("in_ext->", "out_ext->", self.direction, self.conv, True) + copy_body += ident + m.copy("in_ext->", "out_ext->", self.direction, self.conv, True) + + # Generate the definition of "in_ext" if we need it + if "in_ext->" in copy_body: + body += ident + "{0} *in_ext = ({0} *)in_header;\n".format(in_type) + body += copy_body
if self.direction == Direction.INPUT: body += ident + "out_header->pNext = (void *)out_ext;\n"
This merge request was approved by Jacek Caban.