diff --git a/DeThunk/src/header_processor.py b/DeThunk/src/header_processor.py index 4440262..377fe00 100644 --- a/DeThunk/src/header_processor.py +++ b/DeThunk/src/header_processor.py @@ -3,71 +3,12 @@ import re import header_preprocessor as HeaderPreProcessor +from options import Options + import util.cpp_language as CppUtil import util.string as StrUtil -class Options: - base_dir = str() - - # functions - remove_constructor_thunk = bool() - remove_destructor_thunk = bool() - remove_virtual_function_thunk = bool() - - # variables - remove_virtual_table_pointer_thunk = bool() - restore_static_variable = bool() - restore_member_variable = bool() - - # others - # * only takes effect for TypedStorage, since the TypedStorage wrapper makes the full type unnecessary. - fix_includes_for_member_variables = True - # * template definitions cannot be generated for headergen and may be wrong. class sizes may be wrong if - # * empty templates are used in TypedStorage. - # * this option will erase the type of the empty template (convert to uchar[size]). - fix_size_for_type_with_empty_template_class = True - # * this option will and add sizeof & alignof static assertions to members. (only takes effect for TypedStorage) - add_sizeof_alignof_static_assertions = True - - # * some types of template definitions are not accurate. - erase_extra_invalid_types = True - - # * in msvc, 'const' object must be initialized if not 'extern' (c2734) - # * see also https://reviews.llvm.org/D45978 - fix_msvc_c2734 = True - - # * try to initialize each class dynamically to ensure that the generated debug information is complete. - # * this will ENSURE that all classes have a default constructor. - add_trivial_dynamic_initializer = True - - def __init__(self, args): - self.base_dir = args.path - self.remove_constructor_thunk = args.remove_constructor_thunk - self.remove_destructor_thunk = args.remove_destructor_thunk - self.remove_virtual_function_thunk = args.remove_virtual_function_thunk - self.remove_virtual_table_pointer_thunk = args.remove_virtual_table_pointer_thunk - self.restore_static_variable = args.restore_static_variable - self.restore_member_variable = args.restore_member_variable - - if args.all: - self.set_all(True) - - def set_function(self, opt: bool): - self.remove_constructor_thunk = opt - self.remove_destructor_thunk = opt - self.remove_virtual_function_thunk = opt - - def set_variable(self, opt: bool): - self.remove_virtual_table_pointer_thunk = opt - self.restore_static_variable = opt - self.restore_member_variable = opt - - def set_all(self, opt: bool): - self.set_function(opt) - self.set_variable(opt) - - def try_translate_forward_declaration( decl: str, typeset: list ) -> HeaderPreProcessor.ClassDefine | None: @@ -184,7 +125,10 @@ def process(path_to_file: str, args: Options): type_name = matched[3] var_name = matched[4] - if not StrUtil.endswith_m(type_name, '&', '*'): + if ( + not StrUtil.endswith_m(type_name, '&', '*') + and args.fix_size_for_type_with_empty_template_class + ): for empty_class in HeaderPreProcessor.empty_class_all_names: if empty_class in type_name or ( args.erase_extra_invalid_types @@ -197,11 +141,11 @@ def process(path_to_file: str, args: Options): args.add_trivial_dynamic_initializer and '::std::variant<' in type_name # TODO: ... ) - or { + or ( args.add_trivial_dynamic_initializer and type_name # unique_ptr with user deleter, TODO: ... == '::std::unique_ptr<::RakNet::RakPeerInterface, void (*)(::RakNet::RakPeerInterface*)>' - } + ) ) ): # print(f'erased: {type_name}') @@ -367,14 +311,19 @@ def process(path_to_file: str, args: Options): if ns: full_name += '::' full_name += cl - if full_name in [ - 'Json::ValueIteratorBase', # std::vector::iterator - 'Json::ValueConstIterator', - 'Json::ValueIterator', - 'MemoryStream', # std::istream - 'Bedrock::UniqueOwnerPointer', # bug? - 'CommandRegistry::Overload', # circular references - ]: + if ( + full_name + in [ + 'Json::ValueIteratorBase', # std::vector::iterator + 'Json::ValueConstIterator', + 'Json::ValueIterator', + 'MemoryStream', # std::istream + 'Core::FileStream', # ::std::iostream + 'CommandRegistry::Overload', # circular references + 'Bedrock::UniqueOwnerPointer', # bug? + 'MovementDataExtractionUtility::StorageStorage::StorageTupleT', # shit template + ] + ): continue is_modified = True content += f'\ninline {full_name} {var_name};' diff --git a/DeThunk/src/main.py b/DeThunk/src/main.py index e04a5af..b546628 100644 --- a/DeThunk/src/main.py +++ b/DeThunk/src/main.py @@ -17,6 +17,9 @@ def main(): parser.add_argument('--all', action='store_true', help='Apply all remove/restore options.') + parser.add_argument('--preset-extract-names', action='store_true') + parser.add_argument('--preset-extract-types', action='store_true') + args = parser.parse_args() HeaderProcessor.iterate(HeaderProcessor.Options(args)) diff --git a/DeThunk/src/options.py b/DeThunk/src/options.py new file mode 100644 index 0000000..e9d8e52 --- /dev/null +++ b/DeThunk/src/options.py @@ -0,0 +1,95 @@ +""" +Runtime Options +""" + + +class Options: + base_dir = str() + + # functions + remove_constructor_thunk = bool() + remove_destructor_thunk = bool() + remove_virtual_function_thunk = bool() + + # variables + remove_virtual_table_pointer_thunk = bool() + restore_static_variable = bool() + restore_member_variable = bool() + + # others (for class member variable) + + # * only takes effect for TypedStorage, since the TypedStorage wrapper makes the full type unnecessary. + fix_includes_for_member_variables = True + # * template definitions cannot be generated for headergen and may be wrong. class sizes may be wrong if + # * empty templates are used in TypedStorage. + # * this option will erase the type of the empty template (convert to uchar[size]). + fix_size_for_type_with_empty_template_class = True + # * this option will and add sizeof & alignof static assertions to members. (only takes effect for TypedStorage) + add_sizeof_alignof_static_assertions = True + # * some types of template definitions are not accurate. + erase_extra_invalid_types = True + # * try to initialize each class dynamically to ensure that the generated debug information is complete. + # * this will ENSURE that all classes have a default constructor. + add_trivial_dynamic_initializer = True + + # others (for static class member viriable) + + # * in msvc, 'const' object must be initialized if not 'extern' (c2734) + # * see also https://reviews.llvm.org/D45978 + fix_msvc_c2734 = True + + def __init__(self, args): + self.base_dir = args.path + self.remove_constructor_thunk = args.remove_constructor_thunk + self.remove_destructor_thunk = args.remove_destructor_thunk + self.remove_virtual_function_thunk = args.remove_virtual_function_thunk + self.remove_virtual_table_pointer_thunk = args.remove_virtual_table_pointer_thunk + self.restore_static_variable = args.restore_static_variable + self.restore_member_variable = args.restore_member_variable + + if args.preset_extract_functions: + self.apply_preset_extract_functions() + + if args.preset_extract_types: + self.apply_preset_extract_types() + + if args.all: + self.set_all(True) + + # others + self.judge_other_options() + + def set_function(self, opt: bool): + self.remove_constructor_thunk = opt + self.remove_destructor_thunk = opt + self.remove_virtual_function_thunk = opt + + def set_variable(self, opt: bool): + self.remove_virtual_table_pointer_thunk = opt + self.restore_static_variable = opt + self.restore_member_variable = opt + + def set_all(self, opt: bool): + self.set_function(opt) + self.set_variable(opt) + + def apply_preset_extract_functions(self): + self.remove_constructor_thunk = True + self.remove_destructor_thunk = True + self.remove_virtual_function_thunk = True + self.remove_virtual_table_pointer_thunk = True + self.restore_static_variable = True + + def apply_preset_extract_types(self): + self.restore_member_variable = True + + def judge_other_options(self): + if not self.restore_member_variable: + self.fix_includes_for_member_variables = False + self.fix_size_for_type_with_empty_template_class = False + self.add_sizeof_alignof_static_assertions = False + self.erase_extra_invalid_types = False + self.add_trivial_dynamic_initializer = False + + if not self.restore_static_variable: + self.fix_msvc_c2734 = False