[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 2db58d20..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;