scripts: Include chain_size helper in struct_size
authorMark Lobodzinski <mark@lunarg.com>
Thu, 29 Dec 2016 21:04:15 +0000 (14:04 -0700)
committerMark Lobodzinski <mark@lunarg.com>
Tue, 10 Jan 2017 17:21:32 +0000 (10:21 -0700)
Change-Id: I1afcee1ab90ad18d758fdb476d2d0012a891bdfc

scripts/helper_file_generator.py

index 7ef8f8e1a3154a9704f903e5406a1050b1b25948..89d0788ca1f01b8a4ede8bf7eff5cf7631eb36d1 100644 (file)
@@ -318,18 +318,48 @@ class HelperFileOutputGenerator(OutputGenerator):
             declare_flag = True
         return string_var, declare_flag
     #
+    # Build the header of the get_struct_chain_size function
+    def GenerateChainSizePreamble(self):
+        preable = '\nsize_t get_struct_chain_size(const void* struct_ptr) {\n'
+        preable += '    // Use VkApplicationInfo as struct until actual type is resolved\n'
+        preable += '    VkApplicationInfo* pNext = (VkApplicationInfo*)struct_ptr;\n'
+        preable += '    size_t struct_size = 0;\n'
+        preable += '    while (pNext) {\n'
+        preable += '        switch (pNext->sType) {\n'
+        return preable
+    #
+    # Build the footer of the get_struct_chain_size function
+    def GenerateChainSizePostamble(self):
+        postamble  = '            default:\n'
+        postamble += '                assert(0);\n'
+        postamble += '                struct_size += 0;\n'
+        postamble += '        }\n'
+        postamble += '        pNext = (VkApplicationInfo*)pNext->pNext;\n'
+        postamble += '    }\n'
+        postamble += '    return struct_size;\n'
+        postamble += '}'
+        return postamble
+    #
     # struct_size_helper source -- create bodies of struct size helper functions
     def GenerateStructSizeSource(self):
-        outstring = ''
+        # Construct the body of the routine and get_struct_chain_size() simultaneously
+        struct_size_body = ''
+        chain_size  = self.GenerateChainSizePreamble()
         for item in self.structMembers:
-            outstring += '\n'
+            struct_size_body += '\n'
             lower_case_name = item.name.lower()
             if item.ifdef_protect != None:
-                outstring += '#ifdef %s\n' % item.ifdef_protect
-            outstring += 'size_t vk_size_%s(const %s* struct_ptr) {\n' % (item.name.lower(), item.name)
-            outstring += '    size_t struct_size = 0;\n'
-            outstring += '    if (struct_ptr) {\n'
-            outstring += '        struct_size = sizeof(%s);\n' % item.name
+                struct_size_body += '#ifdef %s\n' % item.ifdef_protect
+                chain_size += '#ifdef %s\n' % item.ifdef_protect
+            if item.name in self.structTypes:
+                chain_size += '            case %s: {\n' % self.structTypes[item.name].value
+                chain_size += '                struct_size += vk_size_%s((%s*)pNext);\n' % (item.name.lower(), item.name)
+                chain_size += '                break;\n'
+                chain_size += '            }\n'
+            struct_size_body += 'size_t vk_size_%s(const %s* struct_ptr) {\n' % (item.name.lower(), item.name)
+            struct_size_body += '    size_t struct_size = 0;\n'
+            struct_size_body += '    if (struct_ptr) {\n'
+            struct_size_body += '        struct_size = sizeof(%s);\n' % item.name
             counter_declared = False
             for member in item.members:
                 vulkan_type = next((i for i, v in enumerate(self.structMembers) if v[0] == member.type), None)
@@ -337,34 +367,38 @@ class HelperFileOutputGenerator(OutputGenerator):
                     if vulkan_type is not None:
                         # If this is another Vulkan structure call generated size function
                         if member.len is not None:
-                            outstring, counter_declared = self.DeclareCounter(outstring, counter_declared)
-                            outstring += '        for (i = 0; i < pStruct->%s; i++) {\n' % member.len
-                            outstring += '            struct_size += vk_size_%s(&struct_ptr->%s[i]);\n' % (member.type.lower(), member.name)
-                            outstring += '        }\n'
+                            struct_size_body, counter_declared = self.DeclareCounter(struct_size_body, counter_declared)
+                            struct_size_body += '        for (i = 0; i < struct_ptr->%s; i++) {\n' % member.len
+                            struct_size_body += '            struct_size += vk_size_%s(&struct_ptr->%s[i]);\n' % (member.type.lower(), member.name)
+                            struct_size_body += '        }\n'
                         else:
-                            outstring += '        struct_size += vk_size_%s(struct_ptr->%s);\n' % (member.type.lower(), member.name)
+                            struct_size_body += '        struct_size += vk_size_%s(struct_ptr->%s);\n' % (member.type.lower(), member.name)
                     else:
                         if member.type == 'char':
                             # Deal with sizes of character strings
                             if member.len is not None:
-                                outstring, counter_declared = self.DeclareCounter(outstring, counter_declared)
-                                outstring += '        for (i = 0; i < pStruct->%s; i++) {\n' % member.len
-                                outstring += '            struct_size += (sizeof(char*) + (sizeof(char) * (1 + strlen(pStruct->%s[i]))));\n' % (member.name)
-                                outstring += '        }\n'
+                                struct_size_body, counter_declared = self.DeclareCounter(struct_size_body, counter_declared)
+                                struct_size_body += '        for (i = 0; i < struct_ptr->%s; i++) {\n' % member.len
+                                struct_size_body += '            struct_size += (sizeof(char*) + (sizeof(char) * (1 + strlen(struct_ptr->%s[i]))));\n' % (member.name)
+                                struct_size_body += '        }\n'
                             else:
-                                outstring += '        struct_size += (struct_ptr->%s != NULL) ? sizeof(char)*(1+strlen(struct_ptr->%s)) : 0;\n' % (member.name, member.name)
+                                struct_size_body += '        struct_size += (struct_ptr->%s != NULL) ? sizeof(char)*(1+strlen(struct_ptr->%s)) : 0;\n' % (member.name, member.name)
                         else:
                             if member.len is not None:
-                                outstring += '        struct_size += struct_ptr->%s * sizeof(%s);\n' % (member.len, member.name)
-            outstring += '    }\n'
-            outstring += '    return struct_size\n'
-            outstring += '}\n'
+                                # Avoid using 'sizeof(void)', which generates compile-time warnings/errors
+                                checked_type = member.type
+                                if checked_type == 'void':
+                                    checked_type = 'void*'
+                                struct_size_body += '        struct_size += struct_ptr->%s * sizeof(%s);\n' % (member.len, checked_type)
+            struct_size_body += '    }\n'
+            struct_size_body += '    return struct_size;\n'
+            struct_size_body += '}\n'
             if item.ifdef_protect != None:
-                outstring += '#endif // %s\n' % item.ifdef_protect
-        outstring += '#ifdef __cplusplus\n'
-        outstring += '}\n'
-        outstring += '#endif'
-        return outstring
+                struct_size_body += '#endif // %s\n' % item.ifdef_protect
+                chain_size += '#endif // %s\n' % item.ifdef_protect
+        chain_size += self.GenerateChainSizePostamble()
+        struct_size_body += chain_size;
+        return struct_size_body
     #
     # Combine struct size helper source file preamble with body text and return
     def GenerateStructSizeHelperSource(self):
@@ -386,4 +420,5 @@ class HelperFileOutputGenerator(OutputGenerator):
         elif self.helper_file_type == 'struct_size_source':
             return self.GenerateStructSizeHelperSource()
         else:
-            return 'Bad Helper Generator Option %s' % self.helper_file_type
\ No newline at end of file
+            return 'Bad Helper Generator Option %s' % self.helper_file_type
+