layers: Separate OT pre-post and core routines

Split OT into core and pre/post modules.  Added pre and post defs.
Attempted to separate layer-related and validation-related defines.

Change-Id: I3f0d03180fad01c8990948db5316a4767d1e1ad2
diff --git a/scripts/object_tracker_generator.py b/scripts/object_tracker_generator.py
index ed923a7..3588c28 100644
--- a/scripts/object_tracker_generator.py
+++ b/scripts/object_tracker_generator.py
@@ -362,12 +362,26 @@
                     for l in v:
                         for s in self.ExtractVUIDs(l):
                             yield s
+    #
+    # Separate content for validation (utils) and core files
+    def otwrite(self, dest, formatstring):
+        if 'core' in self.genOpts.filename and (dest == 'core' or dest == 'both'):
+            write(formatstring, file=self.outFile)
+        elif 'utils' in self.genOpts.filename and (dest == 'util' or dest == 'both'):
+            write(formatstring, file=self.outFile)
 
     #
     # Called at beginning of processing as file is opened
     def beginFile(self, genOpts):
         OutputGenerator.beginFile(self, genOpts)
 
+        core_file = (genOpts.filename == 'object_tracker_utils_auto.cpp')
+        utils_file = (genOpts.filename == 'object_tracker_core_auto.cpp')
+
+        if not core_file and not utils_file:
+            print("Error: Output Filenames have changed, update generator source.\n")
+            sys.exit(1)
+
         self.valid_usage_path = genOpts.valid_usage_path
         vu_json_filename = os.path.join(self.valid_usage_path + os.sep, 'validusage.json')
         if os.path.isfile(vu_json_filename):
@@ -385,7 +399,7 @@
         # File Comment
         file_comment = '// *** THIS FILE IS GENERATED - DO NOT EDIT ***\n'
         file_comment += '// See object_tracker_generator.py for modifications\n'
-        write(file_comment, file=self.outFile)
+        self.otwrite('both', file_comment)
         # Copyright Statement
         copyright = ''
         copyright += '\n'
@@ -412,12 +426,17 @@
         copyright += ' * Author: Dave Houlton <daveh@lunarg.com>\n'
         copyright += ' *\n'
         copyright += ' ****************************************************************************/\n'
-        write(copyright, file=self.outFile)
+        self.otwrite('both', copyright)
         # Namespace
         self.newline()
-        write('#include "object_tracker.h"', file = self.outFile)
-        self.newline()
-        write('namespace object_tracker {', file = self.outFile)
+        self.otwrite('both', '#include "object_tracker.h"')
+        self.otwrite('both', '#include "object_lifetime_validation.h"')
+        self.otwrite('both', '\n')
+        self.otwrite('both', 'namespace object_tracker {')
+        self.otwrite('core', '#include "precall.h"')
+        self.otwrite('core', '#include "postcall.h"')
+        self.otwrite('core', '\n')
+
     #
     # Now that the data is all collected and complete, generate and output the object validation routines
     def endFile(self):
@@ -430,30 +449,33 @@
         self.newline()
         # Build undestroyed objects destruction function
         destroy_func = self.GenDestroyFunc()
-        self.newline()
-        write('// ObjectTracker undestroyed objects validation function', file=self.outFile)
-        write('%s' % report_func, file=self.outFile)
-        write('%s' % destroy_func, file=self.outFile)
+        self.otwrite('util', '\n')
+        self.otwrite('util', '// ObjectTracker undestroyed objects validation function')
+        self.otwrite('util', '%s' % report_func)
+        self.otwrite('util', '%s' % destroy_func)
         # Actually write the interface to the output file.
         if (self.emit):
             self.newline()
+            if self.featureExtraProtect is not None:
+                prot = '#ifdef %s' % self.featureExtraProtect
+                self.otwrite('both', '%s' % prot)
+            # Write the object_tracker code to the  file
+            if self.sections['command']:
+                source = ('\n'.join(self.sections['command']))
+                self.otwrite('both', '%s' % source)
             if (self.featureExtraProtect is not None):
-                write('#ifdef', self.featureExtraProtect, file=self.outFile)
-            # Write the object_tracker code to the file
-            if (self.sections['command']):
-                write('\n'.join(self.sections['command']), end=u'', file=self.outFile)
-            if (self.featureExtraProtect is not None):
-                write('\n#endif //', self.featureExtraProtect, file=self.outFile)
+                prot = '\n#endif // %s', self.featureExtraProtect
+                self.otwrite('both', prot)
             else:
-                self.newline()
+                self.otwrite('both', '\n')
 
         # Record intercepted procedures
-        write('// Map of all APIs to be intercepted by this layer', file=self.outFile)
-        write('const std::unordered_map<std::string, void*> name_to_funcptr_map = {', file=self.outFile)
-        write('\n'.join(self.intercepts), file=self.outFile)
-        write('};\n', file=self.outFile)
-        self.newline()
-        write('} // namespace object_tracker', file=self.outFile)
+        self.otwrite('core', '// Map of all APIs to be intercepted by this layer')
+        self.otwrite('core', 'const std::unordered_map<std::string, void*> name_to_funcptr_map = {')
+        intercepts = '\n'.join(self.intercepts)
+        self.otwrite('core', '%s' % intercepts)
+        self.otwrite('core', '};\n\n')
+        self.otwrite('both', '} // namespace object_tracker')
         # Finish processing in superclass
         OutputGenerator.endFile(self)
     #
@@ -741,8 +763,8 @@
                     if dispobj == 'VkInstance' or dispobj == 'VkPhysicalDevice':
                         calltype = 'Instance'
                     # Call Destroy a single time
-                    validate_code += '%s    skip |= %sValidateDestroyObject(%s, %s, %s, pAllocator, %s, %s);\n' % (indent, calltype, cmd_info[0].name, cmd_info[param].name, self.GetVulkanObjType(cmd_info[param].type), compatalloc_vuid, nullalloc_vuid)
-                    record_code += '%s    %sRecordDestroyObject(%s, %s, %s);\n' % (indent, calltype, cmd_info[0].name, cmd_info[param].name, self.GetVulkanObjType(cmd_info[param].type))
+                    validate_code += '%sskip |= %sValidateDestroyObject(%s, %s, %s, pAllocator, %s, %s);\n' % (indent, calltype, cmd_info[0].name, cmd_info[param].name, self.GetVulkanObjType(cmd_info[param].type), compatalloc_vuid, nullalloc_vuid)
+                    record_code += '%s%sRecordDestroyObject(%s, %s, %s);\n' % (indent, calltype, cmd_info[0].name, cmd_info[param].name, self.GetVulkanObjType(cmd_info[param].type))
         return object_array, validate_code, record_code
     #
     # Output validation for a single object (obj_count is NULL) or a counted list of objects
@@ -760,13 +782,13 @@
         if disp_name == 'instance' or disp_name == 'physicalDevice':
             calltype = 'Instance'
         if obj_count is not None:
-            pre_call_code += '%s    for (uint32_t %s = 0; %s < %s; ++%s) {\n' % (indent, index, index, obj_count, index)
+            pre_call_code += '%sfor (uint32_t %s = 0; %s < %s; ++%s) {\n' % (indent, index, index, obj_count, index)
             indent = self.incIndent(indent)
-            pre_call_code += '%s    skip |= %sValidateObject(%s, %s%s[%s], %s, %s, %s, %s);\n' % (indent, calltype, disp_name, prefix, obj_name, index, self.GetVulkanObjType(obj_type), null_allowed, param_vuid, parent_vuid)
+            pre_call_code += '%sskip |= %sValidateObject(%s, %s%s[%s], %s, %s, %s, %s);\n' % (indent, calltype, disp_name, prefix, obj_name, index, self.GetVulkanObjType(obj_type), null_allowed, param_vuid, parent_vuid)
             indent = self.decIndent(indent)
-            pre_call_code += '%s    }\n' % indent
+            pre_call_code += '%s}\n' % indent
         else:
-            pre_call_code += '%s    skip |= %sValidateObject(%s, %s%s, %s, %s, %s, %s);\n' % (indent, calltype, disp_name, prefix, obj_name, self.GetVulkanObjType(obj_type), null_allowed, param_vuid, parent_vuid)
+            pre_call_code += '%sskip |= %sValidateObject(%s, %s%s, %s, %s, %s, %s);\n' % (indent, calltype, disp_name, prefix, obj_name, self.GetVulkanObjType(obj_type), null_allowed, param_vuid, parent_vuid)
         return pre_call_code
     #
     # first_level_param indicates if elements are passed directly into the function else they're below a ptr/struct
@@ -797,35 +819,35 @@
                     if member.len is not None:
                         # Update struct prefix
                         new_prefix = '%s%s' % (prefix, member.name)
-                        pre_code += '%s    if (%s%s) {\n' % (indent, prefix, member.name)
+                        pre_code += '%sif (%s%s) {\n' % (indent, prefix, member.name)
                         indent = self.incIndent(indent)
-                        pre_code += '%s    for (uint32_t %s = 0; %s < %s%s; ++%s) {\n' % (indent, index, index, prefix, member.len, index)
+                        pre_code += '%sfor (uint32_t %s = 0; %s < %s%s; ++%s) {\n' % (indent, index, index, prefix, member.len, index)
                         indent = self.incIndent(indent)
                         local_prefix = '%s[%s].' % (new_prefix, index)
                         # Process sub-structs in this struct
                         tmp_pre = self.validate_objects(struct_info, indent, local_prefix, array_index, disp_name, member.type, False)
                         pre_code += tmp_pre
                         indent = self.decIndent(indent)
-                        pre_code += '%s    }\n' % indent
+                        pre_code += '%s}\n' % indent
                         indent = self.decIndent(indent)
-                        pre_code += '%s    }\n' % indent
+                        pre_code += '%s}\n' % indent
                     # Single Struct
                     elif ispointer:
                         # Update struct prefix
                         new_prefix = '%s%s->' % (prefix, member.name)
                         # Declare safe_VarType for struct
-                        pre_code += '%s    if (%s%s) {\n' % (indent, prefix, member.name)
+                        pre_code += '%sif (%s%s) {\n' % (indent, prefix, member.name)
                         indent = self.incIndent(indent)
                         # Process sub-structs in this struct
                         tmp_pre = self.validate_objects(struct_info, indent, new_prefix, array_index, disp_name, member.type, False)
                         pre_code += tmp_pre
                         indent = self.decIndent(indent)
-                        pre_code += '%s    }\n' % indent
+                        pre_code += '%s}\n' % indent
         return pre_code
     #
     # For a particular API, generate the object handling code
     def generate_wrapping_code(self, cmd):
-        indent = ''
+        indent = '    '
         pre_call_validate = ''
         pre_call_record = ''
         post_call_record = ''
@@ -921,11 +943,12 @@
             if cmdname in self.interface_functions:
                 continue
             if cmdname in self.no_autogen_list:
-                decls = self.makeCDecls(cmdinfo.elem)
-                self.appendSection('command', '')
-                self.appendSection('command', '// Declare only')
-                self.appendSection('command', decls[0])
-                self.intercepts += [ '    {"%s", (void *)%s},' % (cmdname,cmdname[2:]) ]
+                if 'core' in self.genOpts.filename:
+                    decls = self.makeCDecls(cmdinfo.elem)
+                    self.appendSection('command', '')
+                    self.appendSection('command', '// Declare only')
+                    self.appendSection('command', decls[0])
+                    self.intercepts += [ '    {"%s", (void *)%s},' % (cmdname,cmdname[2:]) ]
                 continue
             # Generate object handling code
             (pre_call_validate, pre_call_record, post_call_record) = self.generate_wrapping_code(cmdinfo.elem)
@@ -955,103 +978,105 @@
             func_decl_template = decls[0][:-1].split('VKAPI_CALL ')
             func_decl_template = func_decl_template[1] + ' {'
 
-            # Output PreCallValidateAPI function if necessary
-            if pre_call_validate:
-                pre_cv_func_decl = 'static bool PreCallValidate' + func_decl_template
+            if 'utils' in self.genOpts.filename:
+                # Output PreCallValidateAPI function if necessary
+                if pre_call_validate:
+                    pre_cv_func_decl = 'bool PreCallValidate' + func_decl_template
+                    self.appendSection('command', '')
+                    self.appendSection('command', pre_cv_func_decl)
+                    self.appendSection('command', '    bool skip = false;')
+                    self.appendSection('command', pre_call_validate)
+                    self.appendSection('command', '    return skip;')
+                    self.appendSection('command', '}')
+
+                # Output PreCallRecordAPI function if necessary
+                if pre_call_record:
+                    pre_cr_func_decl = 'void PreCallRecord' + func_decl_template
+                    self.appendSection('command', '')
+                    self.appendSection('command', pre_cr_func_decl)
+                    self.appendSection('command', pre_call_record)
+                    self.appendSection('command', '}')
+
+                # Output PosCallRecordAPI function if necessary
+                if post_call_record:
+                    post_cr_func_decl = 'void PostCallRecord' + func_decl_template
+                    self.appendSection('command', '')
+                    self.appendSection('command', post_cr_func_decl)
+                    self.appendSection('command', post_call_record)
+                    self.appendSection('command', '}')
+
+            if 'core' in self.genOpts.filename:
+                # Output API function:
                 self.appendSection('command', '')
-                self.appendSection('command', pre_cv_func_decl)
-                self.appendSection('command', '    bool skip = false;')
-                self.appendSection('command', pre_call_validate)
-                self.appendSection('command', '    return skip;')
-                self.appendSection('command', '}')
+                self.appendSection('command', decls[0][:-1])
+                self.appendSection('command', '{')
 
-            # Output PreCallRecordAPI function if necessary
-            if pre_call_record:
-                pre_cr_func_decl = 'static void PreCallRecord' + func_decl_template
-                self.appendSection('command', '')
-                self.appendSection('command', pre_cr_func_decl)
-                self.appendSection('command', pre_call_record)
-                self.appendSection('command', '}')
-
-            # Output PosCallRecordAPI function if necessary
-            if post_call_record:
-                post_cr_func_decl = 'static void PostCallRecord' + func_decl_template
-                self.appendSection('command', '')
-                self.appendSection('command', post_cr_func_decl)
-                self.appendSection('command', post_call_record)
-                self.appendSection('command', '}')
-
-            # Output API function:
-            self.appendSection('command', '')
-            self.appendSection('command', decls[0][:-1])
-            self.appendSection('command', '{')
-
-            # Handle return values, if any
-            resulttype = cmdinfo.elem.find('proto/type')
-            if (resulttype is not None and resulttype.text == 'void'):
-              resulttype = None
-            if (resulttype is not None):
-                assignresult = resulttype.text + ' result = '
-            else:
-                assignresult = ''
-
-            # Output all pre-API-call source
-            if pre_call_validate:
-                self.appendSection('command', '    bool skip = false;')
-            if pre_call_validate or pre_call_record:
-                self.appendSection('command', '    {')
-                self.appendSection('command', '        std::lock_guard<std::mutex> lock(global_lock);')
-            # If necessary, add call to PreCallValidateApi(...);
-            if pre_call_validate:
-                pcv_call = fcn_call.replace('TOKEN', '        skip |= PreCallValidate', 1)
-                self.appendSection('command', pcv_call)
-                if assignresult != '':
-                    if resulttype.text == 'VkResult':
-                        self.appendSection('command', '        if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;')
-                    elif resulttype.text == 'VkBool32':
-                        self.appendSection('command', '        if (skip) return VK_FALSE;')
-                    else:
-                        raise Exception('Unknown result type ' + resulttype.text)
+                # Handle return values, if any
+                resulttype = cmdinfo.elem.find('proto/type')
+                if (resulttype is not None and resulttype.text == 'void'):
+                  resulttype = None
+                if (resulttype is not None):
+                    assignresult = resulttype.text + ' result = '
                 else:
-                    self.appendSection('command', '        if (skip) return;')
-            # If necessary, add call to PreCallRecordApi(...);
-            if pre_call_record:
-                pre_cr_call = fcn_call.replace('TOKEN', '        PreCallRecord', 1)
-                self.appendSection('command', pre_cr_call)
+                    assignresult = ''
 
-            if pre_call_validate or pre_call_record:
-                self.appendSection('command', '    }')
+                # Output all pre-API-call source
+                if pre_call_validate:
+                    self.appendSection('command', '    bool skip = false;')
+                if pre_call_validate or pre_call_record:
+                    self.appendSection('command', '    {')
+                    self.appendSection('command', '        std::lock_guard<std::mutex> lock(global_lock);')
+                # If necessary, add call to PreCallValidateApi(...);
+                if pre_call_validate:
+                    pcv_call = fcn_call.replace('TOKEN', '        skip |= PreCallValidate', 1)
+                    self.appendSection('command', pcv_call)
+                    if assignresult != '':
+                        if resulttype.text == 'VkResult':
+                            self.appendSection('command', '        if (skip) return VK_ERROR_VALIDATION_FAILED_EXT;')
+                        elif resulttype.text == 'VkBool32':
+                            self.appendSection('command', '        if (skip) return VK_FALSE;')
+                        else:
+                            raise Exception('Unknown result type ' + resulttype.text)
+                    else:
+                        self.appendSection('command', '        if (skip) return;')
+                # If necessary, add call to PreCallRecordApi(...);
+                if pre_call_record:
+                    pre_cr_call = fcn_call.replace('TOKEN', '        PreCallRecord', 1)
+                    self.appendSection('command', pre_cr_call)
 
-            # Build down-chain call strings and output source
-            # Use correct dispatch table
-            disp_name = cmdinfo.elem.find('param/name').text
-            disp_type = cmdinfo.elem.find('param/type').text
-            map_type = ''
-            if disp_type in ["VkInstance", "VkPhysicalDevice"] or cmdname == 'vkCreateInstance':
-                object_type = 'instance'
-                map_type = 'instance_'
-            else:
-                object_type = 'device'
-            dispatch_table = 'GetLayerDataPtr(get_dispatch_key(%s), %slayer_data_map)->%s_dispatch_table.' % (disp_name, map_type, object_type)
-            down_chain_call = fcn_call.replace('TOKEN', dispatch_table, 1)
-            self.appendSection('command', '    ' + assignresult + down_chain_call)
+                if pre_call_validate or pre_call_record:
+                    self.appendSection('command', '    }')
 
-            # If necessary, add call to PostCallRecordApi(...);
-            if post_call_record:
-                if assignresult:
-                    if resulttype.text == 'VkResult':
-                        self.appendSection('command', '    if (VK_SUCCESS == result) {')
-                    elif resulttype.text == 'VkBool32':
-                        self.appendSection('command', '    if (VK_TRUE == result) {')
-                self.appendSection('command', '        std::lock_guard<std::mutex> lock(global_lock);')
-                post_cr_call = fcn_call.replace('TOKEN', '        PostCallRecord', 1)
-                self.appendSection('command', post_cr_call)
-                self.appendSection('command', '    }')
+                # Build down-chain call strings and output source
+                # Use correct dispatch table
+                disp_name = cmdinfo.elem.find('param/name').text
+                disp_type = cmdinfo.elem.find('param/type').text
+                map_type = ''
+                if disp_type in ["VkInstance", "VkPhysicalDevice"] or cmdname == 'vkCreateInstance':
+                    object_type = 'instance'
+                    map_type = 'instance_'
+                else:
+                    object_type = 'device'
+                dispatch_table = 'GetLayerDataPtr(get_dispatch_key(%s), %slayer_data_map)->%s_dispatch_table.' % (disp_name, map_type, object_type)
+                down_chain_call = fcn_call.replace('TOKEN', dispatch_table, 1)
+                self.appendSection('command', '    ' + assignresult + down_chain_call)
 
-            # Handle the return result variable, if any
-            if (resulttype is not None):
-                self.appendSection('command', '    return result;')
-            self.appendSection('command', '}')
+                # If necessary, add call to PostCallRecordApi(...);
+                if post_call_record:
+                    if assignresult:
+                        if resulttype.text == 'VkResult':
+                            self.appendSection('command', '    if (VK_SUCCESS == result) {')
+                        elif resulttype.text == 'VkBool32':
+                            self.appendSection('command', '    if (VK_TRUE == result) {')
+                    self.appendSection('command', '        std::lock_guard<std::mutex> lock(global_lock);')
+                    post_cr_call = fcn_call.replace('TOKEN', '        PostCallRecord', 1)
+                    self.appendSection('command', post_cr_call)
+                    self.appendSection('command', '    }')
+
+                # Handle the return result variable, if any
+                if (resulttype is not None):
+                    self.appendSection('command', '    return result;')
+                self.appendSection('command', '}')
             if (feature_extra_protect is not None):
                 self.appendSection('command', '#endif // '+ feature_extra_protect)
                 self.intercepts += [ '#endif' ]