Esempio n. 1
0
    def transform_select1st(self, args: Tuple[ir.Expr, ...]):
        lhs, rhs = args

        best_var = None
        # First preference to non-expanded variadic vars, to keep the Select1st* expression variadic if it is now.
        for var_name in compute_non_expanded_variadic_vars(rhs):
            [best_var] = (var for var in rhs.free_vars
                          if var.cpp_type == var_name)
            break

        # If there are none, then any non-variadic var is also ok.
        if not best_var:
            for var in rhs.free_vars:
                if not var.is_variadic and isinstance(
                        var.expr_type,
                    (ir.BoolType, ir.Int64Type, ir.TypeType)):
                    best_var = var
                    break

        if best_var:
            rhs = best_var

        return ir.ClassMemberAccess(inner_expr=ir.TemplateInstantiation(
            template_expr=select1st_literal(lhs.expr_type, rhs.expr_type),
            args=(lhs, rhs),
            instantiation_might_trigger_static_asserts=False),
                                    expr_type=lhs.expr_type,
                                    member_name='value')
Esempio n. 2
0
 def transform_get_first_error(self, args: Tuple[ir.Expr, ...]):
     new_args = []
     for arg in args:
         if isinstance(arg,
                       ir.AtomicTypeLiteral) and arg.cpp_type == 'void':
             pass
         elif (isinstance(arg, ir.VariadicTypeExpansion)
               and isinstance(arg.inner_expr, ir.ClassMemberAccess)
               and isinstance(arg.inner_expr.inner_expr,
                              ir.TemplateInstantiation)
               and isinstance(arg.inner_expr.inner_expr.template_expr,
                              ir.AtomicTypeLiteral) and arg.inner_expr.
               inner_expr.template_expr.cpp_type.startswith('Select1stType')
               and len(arg.inner_expr.inner_expr.args) == 2 and isinstance(
                   arg.inner_expr.inner_expr.args[0], ir.AtomicTypeLiteral)
               and arg.inner_expr.inner_expr.args[0].cpp_type == 'void'):
             # Select1stType*<void, expr>...
             pass
         else:
             new_args.append(arg)
     return ir.ClassMemberAccess(inner_expr=ir.TemplateInstantiation(
         template_expr=GlobalLiterals.GET_FIRST_ERROR,
         args=tuple(new_args),
         instantiation_might_trigger_static_asserts=False),
                                 expr_type=ir.TypeType(),
                                 member_name='type')
Esempio n. 3
0
 def _create_is_same_expr(self, lhs: ir.Expr, rhs: ir.Expr):
     return ir.ClassMemberAccess(inner_expr=ir.TemplateInstantiation(
         template_expr=GlobalLiterals.STD_IS_SAME,
         args=(lhs, rhs),
         instantiation_might_trigger_static_asserts=False),
                                 expr_type=ir.BoolType(),
                                 member_name='value')
Esempio n. 4
0
 def transform_class_member_access(
         self, class_member_access: ir.ClassMemberAccess):
     if (isinstance(class_member_access.inner_expr,
                    ir.TemplateInstantiation)
             and isinstance(class_member_access.inner_expr.template_expr,
                            ir.AtomicTypeLiteral)
             and (class_member_access.inner_expr.template_expr.cpp_type,
                  class_member_access.member_name) in
             self.split_template_name_by_old_name_and_result_element_name):
         split_template_name = self.split_template_name_by_old_name_and_result_element_name[
             (class_member_access.inner_expr.template_expr.cpp_type,
              class_member_access.member_name)]
         class_member_access = ir.ClassMemberAccess(
             inner_expr=ir.TemplateInstantiation(
                 template_expr=ir.AtomicTypeLiteral.for_nonlocal_template(
                     cpp_type=split_template_name,
                     args=class_member_access.inner_expr.template_expr.
                     expr_type.args,
                     is_metafunction_that_may_return_error=
                     class_member_access.inner_expr.template_expr.
                     is_metafunction_that_may_return_error,
                     may_be_alias=False),
                 args=class_member_access.inner_expr.args,
                 instantiation_might_trigger_static_asserts=
                 class_member_access.inner_expr.
                 instantiation_might_trigger_static_asserts),
             member_name=class_member_access.member_name,
             expr_type=class_member_access.expr_type)
     return super().transform_class_member_access(class_member_access)
Esempio n. 5
0
 def transform_template_instantiation(
         self, template_instantiation: ir.TemplateInstantiation) -> ir.Expr:
     [template_expr, *args] = self.transform_exprs([
         template_instantiation.template_expr, *template_instantiation.args
     ], template_instantiation)
     return ir.TemplateInstantiation(
         template_expr=template_expr,
         args=args,
         instantiation_might_trigger_static_asserts=template_instantiation.
         instantiation_might_trigger_static_asserts)
    def transform_template_instantiation(
            self, template_instantiation: ir.TemplateInstantiation):
        if isinstance(template_instantiation.template_expr,
                      ir.AtomicTypeLiteral):
            if _is_global_literal_that_cannot_trigger_static_asserts(
                    template_instantiation.template_expr):
                instantiation_might_trigger_static_asserts = False
            else:
                instantiation_might_trigger_static_asserts = self.template_instantiation_can_trigger_static_asserts.get(
                    template_instantiation.template_expr.cpp_type,
                    template_instantiation.
                    instantiation_might_trigger_static_asserts)
            return ir.TemplateInstantiation(
                template_expr=self.transform_expr(
                    template_instantiation.template_expr),
                args=self.transform_exprs(template_instantiation.args,
                                          template_instantiation),
                instantiation_might_trigger_static_asserts=
                instantiation_might_trigger_static_asserts)

        return super().transform_template_instantiation(template_instantiation)
def _ensure_remains_variadic_if_it_was(original_expr: ir.Expr,
                                       transformed_expr: ir.Expr):
    non_expanded_vars_in_original = compute_non_expanded_variadic_vars(
        original_expr)
    if not non_expanded_vars_in_original:
        # No non-expanded variadic vars in the original expr, nothing to do.
        return transformed_expr

    if compute_non_expanded_variadic_vars(transformed_expr):
        # The transformed expr already contains non-expanded variadic vars, nothing to do.
        return transformed_expr

    variadic_var = next(iter(non_expanded_vars_in_original.values()))

    return ir.ClassMemberAccess(class_type_expr=ir.TemplateInstantiation(
        template_expr=select1st_literal(transformed_expr.expr_type,
                                        variadic_var.expr_type),
        args=[transformed_expr, variadic_var],
        instantiation_might_trigger_static_asserts=False),
                                member_type=transformed_expr.expr_type,
                                member_name='value')
Esempio n. 8
0
def split_template_defn_with_multiple_outputs(
    template_defn: ir.TemplateDefn,
    split_template_name_by_old_name_and_result_element_name: MutableMapping[
        Tuple[str, str], str], identifier_generator: Iterator[str]
) -> Tuple[Tuple[ir.TemplateDefn, ...], bool]:
    type_by_result_elem_name = {
        elem.name: elem.expr.expr_type
        for specialization in template_defn.all_definitions
        for elem in specialization.body
        if isinstance(elem, (ir.ConstantDef, ir.Typedef))
        and elem.name in template_defn.result_element_names
    }
    actual_result_elem_names = tuple(sorted(type_by_result_elem_name.keys()))
    if len(type_by_result_elem_name) <= 1 or any(
            not specialization.is_metafunction
            for specialization in template_defn.all_definitions):
        return (template_defn, ), False

    new_template_defns = []
    if template_defn.main_definition:
        args = template_defn.main_definition.args
    else:
        args = template_defn.args
    arg_decls = tuple(
        ir.TemplateArgType(expr_type=arg.expr_type,
                           is_variadic=arg.is_variadic) for arg in args)
    template_defn_by_result_elem_name = {
        result_elem: ir.TemplateDefn(
            main_definition=template_defn.main_definition,
            specializations=template_defn.specializations,
            name=split_template_name_by_old_name_and_result_element_name.
            setdefault((template_defn.name, result_elem),
                       next(identifier_generator)),
            description='Split that generates %s of: %s' %
            (result_elem, template_defn.description or template_defn.name),
            result_element_names=frozenset((result_elem, )),
            args=args)
        for result_elem in actual_result_elem_names
    }
    for new_template_defn in template_defn_by_result_elem_name.values():
        new_template_defns.append(new_template_defn)

    dispatcher_body = []
    for result_elem_name in actual_result_elem_names:
        expr_type = type_by_result_elem_name[result_elem_name]

        split_template_literal = ir.AtomicTypeLiteral.for_nonlocal_template(
            cpp_type=template_defn_by_result_elem_name[result_elem_name].name,
            args=arg_decls,
            is_metafunction_that_may_return_error=False,
            may_be_alias=False)
        inner_expr = ir.ClassMemberAccess(inner_expr=ir.TemplateInstantiation(
            template_expr=split_template_literal,
            args=tuple(
                ir.AtomicTypeLiteral.for_local(cpp_type=arg.name,
                                               expr_type=arg.expr_type,
                                               is_variadic=arg.is_variadic)
                for arg in args),
            instantiation_might_trigger_static_asserts=True),
                                          member_name=result_elem_name,
                                          expr_type=expr_type)
        if expr_type.kind in (ir.ExprKind.TYPE, ir.ExprKind.TEMPLATE):
            dispatcher_body.append(
                ir.Typedef(name=result_elem_name, expr=inner_expr))
        else:
            dispatcher_body.append(
                ir.ConstantDef(name=result_elem_name, expr=inner_expr))

    new_template_defns.append(
        ir.TemplateDefn(
            main_definition=ir.TemplateSpecialization(
                args=args,
                patterns=None,
                body=tuple(dispatcher_body),
                is_metafunction=True),
            specializations=(),
            name=template_defn.name,
            description=template_defn.description,
            result_element_names=frozenset(actual_result_elem_names),
            args=args))
    return tuple(new_template_defns), False