コード例 #1
0
ファイル: optimize_ir0.py プロジェクト: DalavanCloud/tmppy
 def transform_typedef(self, typedef: ir0.Typedef,
                       writer: transform_ir0.Writer):
     writer.write(
         ir0.Typedef(
             name=typedef.name,
             expr=self.transform_expr(typedef.expr,
                                      writer,
                                      split_nontrivial_exprs=False)))
コード例 #2
0
ファイル: optimize_ir0.py プロジェクト: DalavanCloud/tmppy
def create_var_to_var_assignment(lhs: str, rhs: str, type: ir0.ExprType):
    if type.kind in (ir0.ExprKind.BOOL, ir0.ExprKind.INT64):
        return ir0.ConstantDef(name=lhs,
                               expr=ir0.AtomicTypeLiteral.for_local(
                                   cpp_type=rhs, type=type))
    elif type.kind in (ir0.ExprKind.TYPE, ir0.ExprKind.TEMPLATE):
        return ir0.Typedef(name=lhs,
                           expr=ir0.AtomicTypeLiteral.for_local(cpp_type=rhs,
                                                                type=type))
    else:
        # TODO: consider handling VARIADIC_TYPE too.
        raise NotImplementedError('Unexpected kind: %s' % str(type.kind))
コード例 #3
0
    def new_constant_or_typedef(self, expr: ir0.Expr) -> ir0.AtomicTypeLiteral:
        id = self.new_id()
        if expr.type.kind in (ir0.ExprKind.BOOL, ir0.ExprKind.INT64):
            self.write(ir0.ConstantDef(name=id, expr=expr))
        elif expr.type.kind in (ir0.ExprKind.TYPE, ir0.ExprKind.TEMPLATE):
            self.write(ir0.Typedef(name=id, expr=expr))
        else:
            # TODO: consider handling VARIADIC_TYPE too.
            raise NotImplementedError('Unexpected kind: ' +
                                      str(expr.type.kind))

        return ir0.AtomicTypeLiteral.for_local(cpp_type=id, type=expr.type)
コード例 #4
0
ファイル: ir0_to_cpp.py プロジェクト: DalavanCloud/tmppy
def template_instantiation_to_cpp(
        instantiation_expr: ir0.TemplateInstantiation,
        enclosing_function_defn_args: List[ir0.TemplateArgDecl],
        writer: Writer,
        omit_typename=False):
    args = instantiation_expr.args

    if instantiation_expr.instantiation_might_trigger_static_asserts and enclosing_function_defn_args:
        bound_variables = {
            arg_decl.name
            for arg_decl in enclosing_function_defn_args
        }
        assert bound_variables

        # TODO: We could avoid adding a param dependency in more cases by checking for references to local variables
        # that depend (directly or indirectly) on a param.
        if not any(arg.references_any_of(bound_variables) for arg in args):
            # All template arguments are (or might be) constants, we need to add a reference to a variable bound in this
            # function to prevent the instantiation from happening early, potentially triggering static asserts.

            arg_decl = _select_best_arg_decl_for_select1st(
                enclosing_function_defn_args)
            arg_index = _select_best_arg_expr_index_for_select1st(args)
            arg_to_replace = args[arg_index]

            if arg_decl.type.kind != ir0.ExprKind.TEMPLATE and arg_to_replace.type.kind != ir0.ExprKind.TEMPLATE:
                # We use lambdas here just to make sure we collect code coverage of each "branch". They are not necessary.
                # Note that we use the *Type variants for variadic types too. That's ok, since e.g.
                # Select1stBoolType<b, Args> will be expanded as e.g. Select1stBoolType<b, Args>... so it's exactly what
                # we want in the variadic case too.
                select1st_variant = {
                    (ir0.ExprKind.BOOL, ir0.ExprKind.BOOL):
                    lambda: 'Select1stBoolBool',
                    (ir0.ExprKind.BOOL, ir0.ExprKind.INT64):
                    lambda: 'Select1stBoolInt64',
                    (ir0.ExprKind.BOOL, ir0.ExprKind.TYPE):
                    lambda: 'Select1stBoolType',
                    (ir0.ExprKind.BOOL, ir0.ExprKind.VARIADIC_TYPE):
                    lambda: 'Select1stBoolType',
                    (ir0.ExprKind.INT64, ir0.ExprKind.BOOL):
                    lambda: 'Select1stInt64Bool',
                    (ir0.ExprKind.INT64, ir0.ExprKind.INT64):
                    lambda: 'Select1stInt64Int64',
                    (ir0.ExprKind.INT64, ir0.ExprKind.TYPE):
                    lambda: 'Select1stInt64Type',
                    (ir0.ExprKind.INT64, ir0.ExprKind.VARIADIC_TYPE):
                    lambda: 'Select1stInt64TypeType',
                    (ir0.ExprKind.TYPE, ir0.ExprKind.BOOL):
                    lambda: 'Select1stTypeBool',
                    (ir0.ExprKind.TYPE, ir0.ExprKind.INT64):
                    lambda: 'Select1stTypeInt64',
                    (ir0.ExprKind.TYPE, ir0.ExprKind.TYPE):
                    lambda: 'Select1stTypeType',
                    (ir0.ExprKind.TYPE, ir0.ExprKind.VARIADIC_TYPE):
                    lambda: 'Select1stTypeType',
                }[(arg_to_replace.type.kind, arg_decl.type.kind)]()
            else:
                # We need to define a new Select1st variant for the desired function type.
                select1st_variant = writer.new_id()
                forwarded_param_id = writer.new_id()
                template_param_decl1 = _type_to_template_param_declaration(
                    type=arg_to_replace.type)
                template_param_decl2 = _type_to_template_param_declaration(
                    type=arg_decl.type)

                select1st_variant_body_writer = TemplateElemWriter(
                    writer.get_toplevel_writer())
                if arg_to_replace.type.kind in (ir0.ExprKind.BOOL,
                                                ir0.ExprKind.INT64):
                    select1st_variant_body = ir0.ConstantDef(
                        name='value',
                        expr=ir0.AtomicTypeLiteral.for_local(
                            cpp_type=forwarded_param_id,
                            type=arg_to_replace.type))
                    constant_def_to_cpp(select1st_variant_body,
                                        enclosing_function_defn_args,
                                        select1st_variant_body_writer)
                else:
                    replaced_type = arg_to_replace.type
                    if replaced_type.kind == ir0.ExprKind.VARIADIC_TYPE:
                        replaced_type = ir0.TypeType()
                    assert replaced_type.kind in (ir0.ExprKind.TYPE,
                                                  ir0.ExprKind.TEMPLATE)
                    select1st_variant_body = ir0.Typedef(
                        name='value',
                        expr=ir0.AtomicTypeLiteral.for_local(
                            cpp_type=forwarded_param_id, type=replaced_type))
                    typedef_to_cpp(select1st_variant_body,
                                   enclosing_function_defn_args,
                                   select1st_variant_body_writer)

                select1st_variant_body_str = ''.join(
                    select1st_variant_body_writer.strings)

                writer.write_template_body_elem('''
                    // Custom Select1st* template
                    template <{template_param_decl1} {forwarded_param_id}, {template_param_decl2}>
                    struct {select1st_variant} {{
                      {select1st_variant_body_str}
                    }};
                    '''.format(**locals()))

            select1st_type = ir0.TemplateType(
                argtypes=[arg_to_replace.type, arg_decl.type])
            select1st_instantiation = ir0.TemplateInstantiation(
                template_expr=ir0.AtomicTypeLiteral.for_local(
                    cpp_type=select1st_variant, type=select1st_type),
                args=[
                    arg_to_replace,
                    ir0.AtomicTypeLiteral.for_local(cpp_type=arg_decl.name,
                                                    type=arg_decl.type)
                ],
                instantiation_might_trigger_static_asserts=False)
            new_arg = ir0.ClassMemberAccess(
                class_type_expr=select1st_instantiation,
                member_name='value',
                member_type=arg_to_replace.type)

            args = args[:arg_index] + (new_arg, ) + args[arg_index + 1:]

    template_params = ', '.join(
        expr_to_cpp(arg, enclosing_function_defn_args, writer) for arg in args)

    if isinstance(instantiation_expr.template_expr, ir0.ClassMemberAccess):
        cpp_fun = class_member_access_to_cpp(
            instantiation_expr.template_expr,
            enclosing_function_defn_args,
            writer,
            omit_typename=omit_typename,
            parent_expr_is_template_instantiation=True)
    else:
        cpp_fun = expr_to_cpp(instantiation_expr.template_expr,
                              enclosing_function_defn_args, writer)

    return '{cpp_fun}<{template_params}>'.format(**locals())
コード例 #5
0
ファイル: optimize_ir0.py プロジェクト: DalavanCloud/tmppy
 def transform_typedef(self, typedef: ir0.Typedef,
                       writer: transform_ir0.Writer):
     writer.write(
         ir0.Typedef(name=self._transform_name(typedef.name),
                     expr=self.transform_expr(typedef.expr, writer)))
コード例 #6
0
 def transform_typedef(self, typedef: ir0.Typedef, writer: Writer):
     writer.write(
         ir0.Typedef(name=typedef.name,
                     expr=self.transform_expr(typedef.expr, writer)))