[dawn] minor generator refactors - Fold nullable_annotation with as_annotated_cType. This is a bit simpler than generating it via jinja macro. - Refactor decorate()/annotate(). - Make `Type`s know whether they are nullable. - Factor out render_c_function_args/render_c_method_args macros. - Factor out render_member_declaration macro. - Remove "2" suffix handling for methods. The only generation differences: - Adds WGPU_NULLABLE to wgpuDawnWireClientDeviceCreateBuffer()'s return type (in gen/include/dawn/wire/client/webgpu.h). - Removes extra blank lines in webgpu_cpp.h. - Add a spurious blank line that's in upstream to reduce the diff. Bug: 427657664, 42241461 Change-Id: Ie9209d5d8b18c9e5d78b3e55c976189650c885f0 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/250234 Reviewed-by: Loko Kung <lokokung@google.com> Auto-Submit: Kai Ninomiya <kainino@chromium.org> Commit-Queue: Loko Kung <lokokung@google.com>
diff --git a/generator/dawn_json_generator.py b/generator/dawn_json_generator.py index 062d268..f48e5e4 100644 --- a/generator/dawn_json_generator.py +++ b/generator/dawn_json_generator.py
@@ -108,6 +108,8 @@ self.dict_name = name self.name = Name(name, native=native) self.category = json_data['category'] + self.is_nullable_pointer = json_data.get('is nullable pointer', + self.category == 'object') self.is_wire_transparent = False def __lt__(self, other): @@ -947,23 +949,27 @@ annotation, arg) -def decorate(typ, arg, make_const=False): - maybe_const = ' const' if make_const else '' - if arg.annotation == 'value': - return typ + maybe_const - elif arg.annotation == '*': - return typ + ' *' + maybe_const - elif arg.annotation == 'const*': - return typ + ' const *' + maybe_const - elif arg.annotation == 'const*const*': - return 'const ' + typ + '* const *' + maybe_const - else: - assert False +def decorate(typ, arg, *, with_nullability): + s = typ + if arg.annotation != 'value' or arg.type.is_nullable_pointer: + if arg.annotation == '*': + s = typ + ' *' + elif arg.annotation == 'const*': + s = typ + ' const *' + elif arg.annotation == 'const*const*': + s = 'const ' + typ + '* const *' + if with_nullability: + nullability = 'WGPU_NULLABLE ' if arg.optional else '' + s = nullability + s + return s -def annotated(typ, arg, make_const=False): - result = decorate(typ, arg, make_const) - if isinstance(arg, RecordMember): result += ' ' + as_varName(arg.name) +def annotate(typ, arg, *, make_const_member=False, with_nullability=False): + result = decorate(typ, arg, with_nullability=with_nullability) + if isinstance(arg, RecordMember): + if make_const_member: + result += ' const' + result += ' ' + as_varName(arg.name) return result @@ -1125,10 +1131,12 @@ return { 'Name': lambda name: Name(name), + 'as_nullability_annotated_cType': \ + lambda arg: 'void' if arg is None else annotate(as_cTypeEnumSpecialCase(arg.type), arg, with_nullability=True), 'as_annotated_cType': \ - lambda arg, make_const=False: 'void' if arg is None else annotated(as_cTypeEnumSpecialCase(arg.type), arg, make_const), + lambda arg: 'void' if arg is None else annotate(as_cTypeEnumSpecialCase(arg.type), arg), 'as_annotated_cppType': \ - lambda arg, make_const=False: 'void' if arg is None else annotated(as_cppType(arg.type.name), arg, make_const), + lambda arg, make_const_member=False: 'void' if arg is None else annotate(as_cppType(arg.type.name), arg, make_const_member=make_const_member), 'as_cEnum': as_cEnum, 'as_cppEnum': as_cppEnum, 'as_cMethod': as_cMethod, @@ -1143,7 +1151,7 @@ 'as_wasmType': as_wasmType, 'convert_cType_to_cppType': convert_cType_to_cppType, 'as_varName': as_varName, - 'decorate': decorate, + 'decorate': lambda typ, arg: decorate(typ, arg, with_nullability=False), 'as_ktName': as_ktName, 'has_callbackInfoStruct': has_callbackInfoStruct, 'find_by_name': find_by_name, @@ -1368,7 +1376,7 @@ # TODO: as_frontendType and co. take a Type, not a Name :( 'as_frontendType': lambda typ: as_frontendType(metadata, typ), 'as_annotated_frontendType': \ - lambda arg: annotated(as_frontendType(metadata, arg.type), arg), + lambda arg: annotate(as_frontendType(metadata, arg.type), arg), } ] @@ -1465,7 +1473,7 @@ RENDER_PARAMS_BASE, params_dawn_wire, { 'as_wireType': lambda type : as_wireType(metadata, type), 'as_annotated_wireType': \ - lambda arg: annotated(as_wireType(metadata, arg.type), arg), + lambda arg: annotate(as_wireType(metadata, arg.type), arg), 'is_wire_serializable': lambda type : is_wire_serializable(type), }, additional_params ]
diff --git a/generator/templates/api.h b/generator/templates/api.h index 1b337bf..0bb4308 100644 --- a/generator/templates/api.h +++ b/generator/templates/api.h
@@ -128,14 +128,8 @@ {%- endif -%} {%- endmacro -%} -{%- macro nullable_annotation(record) -%} - {% if record and record.optional and (record.type.category == "object" or record.annotation != "value") -%} - {{API}}_NULLABLE{{" "}} - {%- endif %} -{%- endmacro -%} - //* The |render_c_struct_definition| macro renders both the struct definition and the init macros for a given struct. -{% macro render_c_struct_definition(type) -%} +{%- macro render_c_struct_definition(type) -%} {% for root in type.chain_roots %} // Can be chained in {{as_cType(root.name)}} {% endfor %} @@ -147,7 +141,7 @@ {{API}}ChainedStruct chain; {% endif %} {% for member in type.members %} - {{nullable_annotation(member)}}{{as_annotated_cType(member)}}; + {{as_nullability_annotated_cType(member)}}; {% endfor %} } {{as_cType(type.name)}} {{API}}_STRUCTURE_ATTRIBUTE; @@ -167,6 +161,20 @@ }) {%- endmacro %} +{%- macro render_c_function_args(args) %} + {% for arg in args -%} + {% if not loop.first %}, {% endif -%} + {{as_nullability_annotated_cType(arg)}} + {%- endfor %} +{%- endmacro %} + +{%- macro render_c_method_args(this, args) %} + {{as_cType(this.name)}} {{as_varName(this.name)}} + {%- if args -%} + , {{ render_c_function_args(args) }} + {%- endif %} +{%- endmacro %} + //* Special structures that require some custom code generation. {%- set SpecialStructures = ["string view"] %} //* ------------------------------------------------------------------------------------- @@ -277,21 +285,18 @@ {% endfor -%} {% for type in by_category["function pointer"] %} - typedef {{nullable_annotation(type.returns)}}{{as_annotated_cType(type.returns)}} (*{{as_cType(type.name)}})( + typedef {{as_nullability_annotated_cType(type.returns)}} (*{{as_cType(type.name)}})( {%- if type.arguments == [] -%} void {%- else -%} - {%- for arg in type.arguments -%} - {% if not loop.first %}, {% endif %} - {% if arg.type.category == "structure" %}struct {% endif %}{{as_annotated_cType(arg)}} - {%- endfor -%} + {{- render_c_function_args(type.arguments) -}} {%- endif -%} ) {{API}}_FUNCTION_ATTRIBUTE; {% endfor %} // Callback function pointers {% for type in by_category["callback function"] %} - typedef {{nullable_annotation(type.returns)}}{{as_annotated_cType(type.returns)}} (*{{as_cType(type.name)}})( + typedef {{as_annotated_cType(type.returns)}} (*{{as_cType(type.name)}})( {%- for arg in type.arguments -%} {% if arg.type.category == "structure" and arg.type.name.get() != "string view" %}struct {% endif %}{{as_annotated_cType(arg)}}{{", "}} {%- endfor -%} @@ -308,7 +313,7 @@ typedef struct {{as_cType(type.name)}} { {{API}}ChainedStruct * nextInChain; {% for member in type.members %} - {{as_annotated_cType(member)}}; + {{as_nullability_annotated_cType(member)}}; {% endfor %} {{API}}_NULLABLE void* userdata1; {{API}}_NULLABLE void* userdata2; @@ -347,22 +352,17 @@ {% endif %} // Global procs {% for function in by_category["function"] %} - typedef {{nullable_annotation(function.returns)}}{{as_annotated_cType(function.returns)}} (*{{as_cProc(None, function.name)}})( - {%- for arg in function.arguments -%} - {% if not loop.first %}, {% endif -%} - {{nullable_annotation(arg)}}{{as_annotated_cType(arg)}} - {%- endfor -%} - ) {{API}}_FUNCTION_ATTRIBUTE; + typedef {{as_nullability_annotated_cType(function.returns)}} (*{{as_cProc(None, function.name)}})( + {{- render_c_function_args(function.arguments) -}} + ) {{API}}_FUNCTION_ATTRIBUTE; {% endfor %} + {% for (type, methods) in c_methods_sorted_by_parent %} // Procs of {{type.name.CamelCase()}} {% for method in methods %} - typedef {{nullable_annotation(method.returns)}}{{as_annotated_cType(method.returns)}} (*{{as_cProc(type.name, method.name)}})( - {{-as_cType(type.name)}} {{as_varName(type.name)}} - {%- for arg in method.arguments -%} - , {{nullable_annotation(arg)}}{{as_annotated_cType(arg)}} - {%- endfor -%} + typedef {{as_nullability_annotated_cType(method.returns)}} (*{{as_cProc(type.name, method.name)}})( + {{- render_c_method_args(type, method.arguments) -}} ) {{API}}_FUNCTION_ATTRIBUTE; {% endfor %} @@ -371,22 +371,16 @@ #if !defined({{API}}_SKIP_DECLARATIONS) {% for function in by_category["function"] %} - {{API}}_EXPORT {{nullable_annotation(function.returns)}}{{as_annotated_cType(function.returns)}} {{as_cMethod(None, function.name)}}( - {%- for arg in function.arguments -%} - {% if not loop.first %}, {% endif -%} - {{nullable_annotation(arg)}}{{as_annotated_cType(arg)}} - {%- endfor -%} - ) {{API}}_FUNCTION_ATTRIBUTE; + {{API}}_EXPORT {{as_nullability_annotated_cType(function.returns)}} {{as_cMethod(None, function.name)}}( + {{- render_c_function_args(function.arguments) -}} + ) {{API}}_FUNCTION_ATTRIBUTE; {% endfor %} {% for (type, methods) in c_methods_sorted_by_parent %} // Methods of {{type.name.CamelCase()}} {% for method in methods %} - {{API}}_EXPORT {{nullable_annotation(method.returns)}}{{as_annotated_cType(method.returns)}} {{as_cMethod(type.name, method.name)}}( - {{-as_cType(type.name)}} {{as_varName(type.name)}} - {%- for arg in method.arguments -%} - , {{nullable_annotation(arg)}}{{as_annotated_cType(arg)}} - {%- endfor -%} + {{API}}_EXPORT {{as_nullability_annotated_cType(method.returns)}} {{as_cMethod(type.name, method.name)}}( + {{- render_c_method_args(type, method.arguments) -}} ) {{API}}_FUNCTION_ATTRIBUTE; {% endfor %}
diff --git a/generator/templates/api_cpp.h b/generator/templates/api_cpp.h index 2db58d2..02aba9d 100644 --- a/generator/templates/api_cpp.h +++ b/generator/templates/api_cpp.h
@@ -301,7 +301,7 @@ CType mHandle = nullptr; }; -{% macro render_cpp_default_value(member, is_struct, force_default=False, forced_default_value="") -%} +{%- macro render_cpp_default_value(member, is_struct, force_default=False, forced_default_value="") -%} {%- if forced_default_value -%} {{" "}}= {{forced_default_value}} {%- elif member.json_data.get("no_default", false) -%} @@ -349,14 +349,16 @@ {%- endif -%} {%- endmacro %} +{%- macro render_member_declaration(member, make_const_member, forced_default_value="") -%} + {{- as_annotated_cppType(member, make_const_member) }} + {{- render_cpp_default_value(member, True, make_const_member, forced_default_value) }} +{%- endmacro %} + //* This rendering macro should ONLY be used for callback info type functions. -{% macro render_cpp_callback_info_template_method_declaration(type, method, dfn=False) %} +{%- macro render_cpp_callback_info_template_method_declaration(type, method, dfn=False) %} {% set CppType = as_cppType(type.name) %} - {% set OriginalMethodName = method.name.CamelCase() %} - {% set MethodName = OriginalMethodName[:-1] if method.name.chunks[-1] == "2" else OriginalMethodName %} + {% set MethodName = method.name.CamelCase() %} {% set MethodName = CppType + "::" + MethodName if dfn else MethodName %} - //* Stripping the 2 at the end of the callback functions for now until we can deprecate old ones. - //* TODO: crbug.com/dawn/2509 - Remove name handling once old APIs are deprecated. {% set CallbackInfoType = (method.arguments|last).type %} {% set CallbackType = find_by_name(CallbackInfoType.members, "callback").type %} {% set SfinaeArg = " = std::enable_if_t<std::is_convertible_v<F, Cb*> || std::is_convertible_v<F, CbChar*>>" if not dfn else "" %} @@ -395,13 +397,10 @@ {%- endmacro %} //* This rendering macro should ONLY be used for callback info type functions. -{% macro render_cpp_callback_info_lambda_method_declaration(type, method, dfn=False) %} +{%- macro render_cpp_callback_info_lambda_method_declaration(type, method, dfn=False) %} {% set CppType = as_cppType(type.name) %} - {% set OriginalMethodName = method.name.CamelCase() %} - {% set MethodName = OriginalMethodName[:-1] if method.name.chunks[-1] == "2" else OriginalMethodName %} + {% set MethodName = method.name.CamelCase() %} {% set MethodName = CppType + "::" + MethodName if dfn else MethodName %} - //* Stripping the 2 at the end of the callback functions for now until we can deprecate old ones. - //* TODO: crbug.com/dawn/2509 - Remove name handling once old APIs are deprecated. {% set CallbackInfoType = (method.arguments|last).type %} {% set CallbackType = find_by_name(CallbackInfoType.members, "callback").type %} {% set SfinaeArg = " = std::enable_if_t<std::is_convertible_v<L, Cb> || std::is_convertible_v<L, CbChar>>" if not dfn else "" %} @@ -441,10 +440,9 @@ {%- endmacro %} //* This rendering macro should NOT be used for callback info type functions. -{% macro render_cpp_method_declaration(type, method, dfn=False) %} +{%- macro render_cpp_method_declaration(type, method, dfn=False) %} {% set CppType = as_cppType(type.name) %} - {% set OriginalMethodName = method.name.CamelCase() %} - {% set MethodName = OriginalMethodName[:-1] if method.name.chunks[-1] == "f" or method.name.chunks[-1] == "2" else OriginalMethodName %} + {% set MethodName = method.name.CamelCase() %} {% set MethodName = CppType + "::" + MethodName if dfn else MethodName %} {{"ConvertibleStatus" if method.returns and method.returns.type.name.get() == "status" else as_annotated_cppType(method.returns)}} {{MethodName}}( {%- for arg in method.arguments -%} @@ -800,7 +798,7 @@ {% set forced_default_value = "{ nullptr, StorageTextureAccess::BindingNotUsed, TextureFormat::Undefined, TextureViewDimension::e2D }" %} {% endif %} {% endif %} - {% set member_declaration = as_annotated_cppType(member, type.has_free_members_function) + render_cpp_default_value(member, True, type.has_free_members_function, forced_default_value) %} + {% set member_declaration = render_member_declaration(member, type.has_free_members_function, forced_default_value) %} {% if type.chained and loop.first %} //* Align the first member after ChainedStruct to match the C struct layout. //* It has to be aligned both to its natural and ChainedStruct's alignment. @@ -831,7 +829,7 @@ ChainedStruct const * nextInChain = nullptr; {% for member in type.members %} {% if member.type.category != "callback info" %} - {{as_annotated_cppType(member, type.has_free_members_function) + render_cpp_default_value(member, True, type.has_free_members_function)}}; + {{render_member_declaration(member, type.has_free_members_function)}}; {% else %} {{as_annotated_cType(member)}} = {{CAPI}}_{{member.name.SNAKE_CASE()}}_INIT; {% endif %} @@ -889,8 +887,7 @@ struct {{CppType}}::Init { ChainedStruct{{Out}} * {{const}} nextInChain; {% for member in type.members %} - {% set member_declaration = as_annotated_cppType(member, type.has_free_members_function) + render_cpp_default_value(member, True, type.has_free_members_function) %} - {{member_declaration}}; + {{render_member_declaration(member, type.has_free_members_function)}}; {% endfor %} }; {{CppType}}::{{CppType}}({{CppType}}::Init&& init) @@ -993,8 +990,7 @@ struct {{CppType}}::Init { ChainedStruct const * nextInChain; {% for member in type.members if member.type.category != "callback info" %} - {% set member_declaration = as_annotated_cppType(member, type.has_free_members_function) + render_cpp_default_value(member, True, type.has_free_members_function) %} - {{member_declaration}}; + {{render_member_declaration(member, type.has_free_members_function)}}; {% endfor %} }; @@ -1150,9 +1146,7 @@ // Free Functions {% for function in by_category["function"] if not function.no_cpp %} - //* TODO(crbug.com/42241188): Remove "2" suffix when WGPUStringView changes complete. - {% set OriginalFunctionName = as_cppType(function.name) %} - {% set FunctionName = OriginalFunctionName[:-1] if function.name.chunks[-1] == "2" else OriginalFunctionName %} + {% set FunctionName = as_cppType(function.name) %} static inline {{as_annotated_cppType(function.returns)}} {{FunctionName}}( {%- for arg in function.arguments -%} {%- if not loop.first %}, {% endif -%}
diff --git a/generator/templates/dawn/wire/client/api.h b/generator/templates/dawn/wire/client/api.h index 6aae89c..f61ba7b 100644 --- a/generator/templates/dawn/wire/client/api.h +++ b/generator/templates/dawn/wire/client/api.h
@@ -39,11 +39,10 @@ #endif {% for function in by_category["function"] %} - DAWN_WIRE_EXPORT {{as_annotated_cType(function.returns)}} {{as_cMethodNamespaced(None, function.name, Name('dawn wire client'))}}( + DAWN_WIRE_EXPORT {{as_nullability_annotated_cType(function.returns)}} {{as_cMethodNamespaced(None, function.name, Name('dawn wire client'))}}( {%- for arg in function.arguments -%} {% if not loop.first %}, {% endif -%} - {%- if arg.optional %}{{API}}_NULLABLE {% endif -%} - {{as_annotated_cType(arg)}} + {{as_nullability_annotated_cType(arg)}} {%- endfor -%} ) {{API}}_FUNCTION_ATTRIBUTE; {% endfor %} @@ -51,12 +50,10 @@ {% for (type, methods) in c_methods_sorted_by_parent %} // Methods of {{type.name.CamelCase()}} {% for method in methods %} - DAWN_WIRE_EXPORT {{as_annotated_cType(method.returns)}} {{as_cMethodNamespaced(type.name, method.name, Name('dawn wire client'))}}( + DAWN_WIRE_EXPORT {{as_nullability_annotated_cType(method.returns)}} {{as_cMethodNamespaced(type.name, method.name, Name('dawn wire client'))}}( {{-as_cType(type.name)}} {{as_varName(type.name)}} {%- for arg in method.arguments -%} - ,{{" "}} - {%- if arg.optional %}{{API}}_NULLABLE {% endif -%} - {{as_annotated_cType(arg)}} + , {{as_nullability_annotated_cType(arg)}} {%- endfor -%} ) {{API}}_FUNCTION_ATTRIBUTE; {% endfor %}
diff --git a/src/dawn/dawn.json b/src/dawn/dawn.json index 836a33a..5c9a2e1 100644 --- a/src/dawn/dawn.json +++ b/src/dawn/dawn.json
@@ -4371,10 +4371,12 @@ }, "void *": { "category": "native", + "is nullable pointer": true, "wasm type": "p" }, "void const *": { "category": "native", + "is nullable pointer": true, "wasm type": "p" }, "int": {
diff --git a/third_party/webgpu-headers/webgpu.h.diff b/third_party/webgpu-headers/webgpu.h.diff index 265d6ca..8ec1401 100644 --- a/third_party/webgpu-headers/webgpu.h.diff +++ b/third_party/webgpu-headers/webgpu.h.diff
@@ -7,10 +7,9 @@ +typedef WGPUProc (*WGPUProcGetProcAddress)(WGPUStringView procName) WGPU_FUNCTION_ATTRIBUTE; typedef WGPUBool (*WGPUProcHasInstanceFeature)(WGPUInstanceFeatureName feature) WGPU_FUNCTION_ATTRIBUTE; -typedef WGPUProc (*WGPUProcGetProcAddress)(WGPUStringView procName) WGPU_FUNCTION_ATTRIBUTE; -- + typedef void (*WGPUProcAdapterGetFeatures)(WGPUAdapter adapter, WGPUSupportedFeatures * features) WGPU_FUNCTION_ATTRIBUTE; - typedef WGPUStatus (*WGPUProcAdapterGetInfo)(WGPUAdapter adapter, WGPUAdapterInfo * info) WGPU_FUNCTION_ATTRIBUTE; @@ typedef WGPUBool (*WGPUProcInstanceHasWGSLLanguageFeature)(WGPUInstance instance, WGPUWGSLLanguageFeatureName feature) WGPU_FUNCTION_ATTRIBUTE; typedef void (*WGPUProcInstanceProcessEvents)(WGPUInstance instance) WGPU_FUNCTION_ATTRIBUTE;