def compute_merged_header_for_linking(main_module_name: str, object_file_content: ObjectFileContent, identifier_generator: Iterator[str], coverage_collection_enabled: bool): template_defns = [] check_if_error_specializations = [] toplevel_content = [] split_template_name_by_old_name_and_result_element_name: Dict[Tuple[ str, str], str] = dict() for module_info in object_file_content.modules_by_name.values(): template_defns += module_info.ir0_header.template_defns check_if_error_specializations += module_info.ir0_header.check_if_error_specializations toplevel_content += module_info.ir0_header.toplevel_content for key, value in module_info.ir0_header.split_template_name_by_old_name_and_result_element_name: split_template_name_by_old_name_and_result_element_name[ key] = value # template <typename> # struct CheckIfError { # using type = void; # }; check_if_error_template_main_definition = ir0.TemplateSpecialization( args=(ir0.TemplateArgDecl(expr_type=ir0.TypeType(), name='T', is_variadic=False), ), patterns=None, body=(ir0.Typedef(name='type', expr=ir0.AtomicTypeLiteral.for_nonlocal_type( 'void', may_be_alias=False)), ), is_metafunction=True) template_defns.append( ir0.TemplateDefn( main_definition=check_if_error_template_main_definition, specializations=tuple(check_if_error_specializations), name='CheckIfError', description='', result_element_names=frozenset(('type', )))) public_names = object_file_content.modules_by_name[ main_module_name].ir0_header.public_names.union(['CheckIfError']) merged_header = ir0.Header( template_defns=tuple(template_defns), check_if_error_specializations=(), toplevel_content=tuple(toplevel_content), split_template_name_by_old_name_and_result_element_name=tuple( (k, v) for k, v in split_template_name_by_old_name_and_result_element_name.items()), public_names=public_names) if coverage_collection_enabled: return merged_header return optimize_header(header=merged_header, context_object_file_content=ObjectFileContent({}), identifier_generator=identifier_generator, linking_final_header=True)
def typedef_to_cpp(typedef: ir0.Typedef, enclosing_function_defn_args: List[ir0.TemplateArgDecl], writer: Writer): if typedef.expr.expr_type.kind == ir0.ExprKind.TEMPLATE: assert not typedef.template_args template_args = [ir0.TemplateArgDecl(expr_type=arg.expr_type, name=writer.new_id(), is_variadic=arg.is_variadic) for arg in typedef.expr.expr_type.args] typedef = ir0.Typedef(name=typedef.name, expr=ir0.TemplateInstantiation(template_expr=typedef.expr, args=[ir0.AtomicTypeLiteral.for_local(expr_type=arg.expr_type, cpp_type=arg.name, is_variadic=arg.is_variadic) for arg in template_args], # TODO: use static analysis to determine when it's # safe to set this to False. instantiation_might_trigger_static_asserts=True), description=typedef.description, template_args=template_args) assert typedef.expr.expr_type.kind == ir0.ExprKind.TYPE, typedef.expr.expr_type.kind name = typedef.name cpp_meta_expr = expr_to_cpp(typedef.expr, enclosing_function_defn_args, writer) if typedef.description: description = '// ' + typedef.description + '\n' else: description = '' if not typedef.template_args: writer.write_template_body_elem('''\ {description}using {name} = {cpp_meta_expr}; '''.format(**locals())) else: template_args_decl = ', '.join(template_arg_decl_to_cpp(arg) for arg in typedef.template_args) writer.write_template_body_elem('''\ {description}template <{template_args_decl}> using {name} = {cpp_meta_expr}; '''.format(**locals()))
def _template_template_arg_decl(name: str, *args: ir0.TemplateArgType): return ir0.TemplateArgDecl(expr_type=ir0.TemplateType(args), name=name, is_variadic=False)
def _variadic_int64_arg_decl(name: str): return ir0.TemplateArgDecl(expr_type=ir0.Int64Type(), name=name, is_variadic=True)
def _variadic_bool_arg_decl(name: str): return ir0.TemplateArgDecl(expr_type=ir0.BoolType(), name=name, is_variadic=True)
def _type_arg_decl(name: str): return ir0.TemplateArgDecl(expr_type=ir0.TypeType(), name=name, is_variadic=False)