api_cpp.h: Fix alignas declaration following ChainedStruct.

On 32bit Windows clang warns that alignas(ChainedStruct) uint64_t
forces the uint64_t to have a smaller alignment than it naturally has.
Fix this by making the alignas decoration take the max of
alignof(ChainedStruct) and alignof(first member).

Bug: dawn:1465
Change-Id: Ia5b73fc1be1fa56f36c5c360e719ef2a1dff7dd1
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/94940
Auto-Submit: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Takahiro <hogehoge@gachapin.jp>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Austin Eng <enga@chromium.org>
diff --git a/generator/templates/api_cpp.h b/generator/templates/api_cpp.h
index c3b21fb..6ef3316 100644
--- a/generator/templates/api_cpp.h
+++ b/generator/templates/api_cpp.h
@@ -27,6 +27,12 @@
 
 namespace {{metadata.namespace}} {
 
+    namespace detail {
+        constexpr size_t ConstexprMax(size_t a, size_t b) {
+            return a > b ? a : b;
+        }
+    }  // namespace detail
+
     {% set c_prefix = metadata.c_prefix %}
     {% for constant in by_category["constant"] %}
         {% set type = as_cppType(constant.type.name) %}
@@ -232,8 +238,10 @@
             {% for member in type.members %}
                 {% set member_declaration = as_annotated_cppType(member) + render_cpp_default_value(member) %}
                 {% if type.chained and loop.first %}
-                    //* Align the first member to ChainedStruct to match the C struct layout.
-                    alignas(ChainedStruct{{Out}}) {{member_declaration}};
+                    //* 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.
+                    static constexpr size_t kFirstMemberAlignment = detail::ConstexprMax(alignof(ChainedStruct{{out}}), alignof({{decorate("", as_cppType(member.type.name), member)}}));
+                    alignas(kFirstMemberAlignment) {{member_declaration}};
                 {% else %}
                     {{member_declaration}};
                 {% endif %}
diff --git a/generator/templates/dawn/native/api_structs.h b/generator/templates/dawn/native/api_structs.h
index d655344..232d286 100644
--- a/generator/templates/dawn/native/api_structs.h
+++ b/generator/templates/dawn/native/api_structs.h
@@ -64,8 +64,9 @@
             {% for member in type.members %}
                 {% set member_declaration = as_annotated_frontendType(member) + render_cpp_default_value(member) %}
                 {% if type.chained and loop.first %}
-                    //* Align the first member to ChainedStruct to match the C struct layout.
-                    alignas(ChainedStruct) {{member_declaration}};
+                    //* 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.
+                    alignas({{namespace}}::{{as_cppType(type.name)}}::kFirstMemberAlignment) {{member_declaration}};
                 {% else %}
                     {{member_declaration}};
                 {% endif %}