Add *FreeMembers functions for out structs with non-value members
The function is called automatically in the dtor of the C++ structs.
The C++ structs are also made non-copyable to prevent a double-free.
Bug: dawn:1959
Change-Id: Idfebdc1ea144d69543de8ed7671657a0617e3b82
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/141501
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Loko Kung <lokokung@google.com>
Commit-Queue: Austin Eng <enga@chromium.org>
diff --git a/generator/dawn_json_generator.py b/generator/dawn_json_generator.py
index daaec67..91c8ee7 100644
--- a/generator/dawn_json_generator.py
+++ b/generator/dawn_json_generator.py
@@ -273,6 +273,15 @@
def output(self):
return self.chained == "out" or self.extensible == "out"
+ @property
+ def has_free_members_function(self):
+ if not self.output:
+ return False
+ for m in self.members:
+ if m.annotation != 'value':
+ return True
+ return False
+
class ConstantDefinition():
def __init__(self, is_enabled, name, json_data):
@@ -283,11 +292,12 @@
class FunctionDeclaration():
- def __init__(self, is_enabled, name, json_data):
+ def __init__(self, is_enabled, name, json_data, no_cpp=False):
self.return_type = None
self.arguments = []
self.json_data = json_data
self.name = Name(name)
+ self.no_cpp = no_cpp
class Command(Record):
@@ -474,6 +484,23 @@
for struct in by_category['structure']:
link_structure(struct, types)
+ if struct.has_free_members_function:
+ name = struct.name.get() + " free members"
+ func_decl = FunctionDeclaration(
+ True,
+ name, {
+ "returns":
+ "void",
+ "args": [{
+ "name": "value",
+ "type": struct.name.get(),
+ "annotation": "value",
+ }]
+ },
+ no_cpp=True)
+ types[name] = func_decl
+ by_category['function'].append(func_decl)
+
for function_pointer in by_category['function pointer']:
link_function_pointer(function_pointer, types)
@@ -753,22 +780,23 @@
annotation, arg)
-def decorate(name, typ, arg):
+def decorate(name, typ, arg, make_const=False):
+ maybe_const = ' const ' if make_const else ' '
if arg.annotation == 'value':
- return typ + ' ' + name
+ return typ + maybe_const + name
elif arg.annotation == '*':
- return typ + ' * ' + name
+ return typ + ' *' + maybe_const + name
elif arg.annotation == 'const*':
- return typ + ' const * ' + name
+ return typ + ' const *' + maybe_const + name
elif arg.annotation == 'const*const*':
- return 'const ' + typ + '* const * ' + name
+ return 'const ' + typ + '* const *' + maybe_const + name
else:
assert False
-def annotated(typ, arg):
+def annotated(typ, arg, make_const=False):
name = as_varName(arg.name)
- return decorate(name, typ, arg)
+ return decorate(name, typ, arg, make_const)
def item_is_enabled(enabled_tags, json_data):
@@ -876,9 +904,9 @@
return {
'Name': lambda name: Name(name),
'as_annotated_cType': \
- lambda arg: annotated(as_cTypeEnumSpecialCase(arg.type), arg),
+ lambda arg, make_const=False: annotated(as_cTypeEnumSpecialCase(arg.type), arg, make_const),
'as_annotated_cppType': \
- lambda arg: annotated(as_cppType(arg.type.name), arg),
+ lambda arg, make_const=False: annotated(as_cppType(arg.type.name), arg, make_const),
'as_cEnum': as_cEnum,
'as_cppEnum': as_cppEnum,
'as_cMethod': as_cMethod,