Exemple #1
0
    def generate_server_es_defs(self, pkg_symbol_table, es, qname):
        """
        Write the package-wide definitions (enums, structs).
        """
        pkg_chpl = ChapelFile(qname)
        pkg_h = CFile(qname)
        pkg_h.genh(ir.Import('sidlType'))
        for es in self.pkg_enums_and_structs:
            es_ior = babel.lower_ir(pkg_symbol_table,
                                    es,
                                    header=pkg_h,
                                    qualify_names=True)
            es_chpl = es_ior
            if es[0] == sidlir.struct:
                es_ior = conv.ir_type_to_chpl(es_ior)
                es_chpl = conv.ir_type_to_chpl(es)

            pkg_h.gen(ir.Type_decl(es_ior))
            pkg_chpl.gen(ir.Type_decl(es_chpl))

        pkg_h.write()
        pkg_chpl.write()
Exemple #2
0
    def end_impl(self, qname):
        """
        Chapel Impl (server-side Chapel implementation template)

        Finish generating the module_Impl.chpl file in Chapel.
        """
        # write the Chapel skeleton to disk
        self.pkg_chpl_skel.write()

        # deal with the impl file
        if self.pkg_enums_and_structs:
            self.pkg_impl._header.append(chpl_gen(ir.Import(qname)))

        impl = qname + '_Impl.chpl'

        # Preserve code written by the user
        if os.path.isfile(impl):
            # FIXME: this is a possible race condition, we should
            # use a single file handle instead
            splicers = splicer.record(impl)
            lines = str(self.pkg_impl).split('\n')
            write_to(impl, splicer.apply_all(impl, lines, splicers))
        else:
            write_to(impl, str(self.pkg_impl))
Exemple #3
0
def lower_ir(symbol_table,
             sidl_term,
             header=None,
             struct_suffix='__data',
             enum_suffix='__enum',
             lower_scoped_ids=True,
             qualify_names=True,
             qualify_enums=True,
             raw_ior_arrays=False,
             wrap_rarrays=False):
    """
    FIXME!! can we merge this with convert_arg??
    lower SIDL types into IR

    The idea is that no Chapel-specific code is in this function. It
    should provide a generic translation from SIDL -> IR.

    @param lower_scoped_ids  This is a broken design, but right now the
                             Chapel code generator accepts some sidl
                             node types such as array, rarray, and
                             class.  If False, then these types will
                             not be lowered.

    @param qualify_names     If \c True, enum values will get prefixed
                             with the full qualified name of the enum.
    """
    def low(sidl_term):
        return lower_ir(symbol_table, sidl_term, header, struct_suffix,
                        enum_suffix, lower_scoped_ids, qualify_names,
                        qualify_enums, raw_ior_arrays, wrap_rarrays)

    # print 'low(',sidl_term, ')'
    array_prefix = '/* IOR */ ' if raw_ior_arrays else ''

    with match(sidl_term):
        if (sidlir.arg, Attrs, Mode, (sidlir.scoped_id, _, _, _), Name):
            lowtype = low(sidl_term[3])
            if lowtype[0] == ir.struct and Mode == ir.in_:
                # struct arguments are passed as pointer, regardless of mode
                # unless they are a return value
                lowtype = ir.Pointer_type(lowtype)
            return (ir.arg, Attrs, Mode, lowtype, Name)

        elif (sidlir.arg, Attrs, Mode, Typ, Name):
            return (ir.arg, Attrs, Mode, low(Typ), Name)

        elif (sidlir.scoped_id, Prefix, Name, Ext):
            return low(symbol_table[sidl_term][1])

        elif (sidlir.void):
            return ir.pt_void
        elif (ir.void_ptr):
            return ir.void_ptr
        elif (sidlir.primitive_type, sidlir.opaque):
            return ir.Pointer_type(ir.pt_void)
        elif (sidlir.primitive_type, sidlir.string):
            return sidl_term  #ir.const_str
        elif (sidlir.primitive_type, Type):
            return ir.Primitive_type(Type)

        elif (sidlir.enum, Name, Enumerators, DocComment):
            # in the IOR enums are represented as int64
            if qualify_enums:
                es = lower_ir(
                    SymbolTable(symbol_table,
                                symbol_table.prefix + [Name]), Enumerators,
                    header, struct_suffix, enum_suffix, lower_scoped_ids,
                    qualify_names, qualify_enums, raw_ior_arrays, wrap_rarrays)
                return ir.Enum(
                    qual_name(symbol_table, sidl_term[1]) + enum_suffix, es,
                    DocComment)
            else:
                return ir.Enum(sidl_term[1], low(Enumerators), DocComment)

        elif (sidlir.enumerator, Name):
            if qualify_enums:
                return ir.Enumerator(qual_name(symbol_table, Name))
            else:
                return sidl_term

        elif (sidlir.enumerator_value, Name, Val):
            if qualify_enums:
                return ir.Enumerator_value(qual_name(symbol_table, Name), Val)
            else:
                return sidl_term

        elif (sidlir.struct, (sidlir.scoped_id, Prefix, Name, Ext), Items,
              DocComment):
            # a nested Struct
            return ir.Struct(
                qual_id(sidl_term[1]) + struct_suffix, low(Items), '')

        elif (sidlir.struct, Name, Items, DocComment):
            return ir.Struct(
                qual_name(symbol_table, Name) + struct_suffix, low(Items), '')

        elif (sidlir.struct_item, Type, Name):
            if Type[0] == sidlir.scoped_id:
                t = symbol_table[Type][1]
                if t[0] == sidlir.class_ or t[0] == sidlir.interface:
                    if header: header.genh(ir.Import(qual_id(t[1]) + '_IOR'))
                    t = ir_object_type(t[1][1], t[1][2])
                elif t[0] == sidlir.struct or t[0] == sidlir.enum:
                    return (ir.struct_item, low(t), Name)
                return (ir.struct_item, t, Name)
            return (ir.struct_item, low(Type), Name)

        # elif (sidlir.rarray, Scalar_type, Dimension, Extents):
        #     # Future optimization:
        #     # Direct-call version (r-array IOR)
        #     # return ir.Pointer_type(lower_type_ir(symbol_table, Scalar_type)) # FIXME
        #     # SIDL IOR version
        #     return ir.Typedef_type('sidl_%s__array'%Scalar_type[1])

        elif (sidlir.rarray, Scalar_type, Dimension, Extents):
            if wrap_rarrays:
                return ir.Pointer_type(
                    ir.Struct(
                        '%ssidl_%s__array' % (array_prefix, Scalar_type[1]),
                        [], ''))
            else:
                return ir.Rarray(low(Scalar_type), Dimension, Extents)

        elif (sidlir.array, [], [], []):
            #if not lower_scoped_ids: return sidl_term
            #return ir.Pointer_type(ir.pt_void)
            return ir.Pointer_type(ir.Struct('sidl__array', [], ''))

        elif (sidlir.array, Scalar_type, Dimension, Orientation):
            #if not lower_scoped_ids: return sidl_term
            if Scalar_type[0] == ir.scoped_id:
                # All object arrays are called sidl_interface__array
                t = 'interface'
                if header: header.genh(ir.Import('sidl_BaseInterface_IOR'))
            else:
                t = Scalar_type[1]
            if header: header.genh(ir.Import('sidl_' + t + '_IOR'))
            return ir.Pointer_type(
                ir.Struct('%ssidl_%s__array' % (array_prefix, t), [], ''))

        elif (sidlir.class_, ScopedId, _, _, _, _, _):
            if not lower_scoped_ids: return ScopedId
            else: return ir_object_type(ScopedId[1], ScopedId[2])

        elif (sidlir.interface, ScopedId, _, _, _, _):
            if not lower_scoped_ids: return ScopedId
            return ir_object_type(ScopedId[1], ScopedId[2])

        elif (Terms):
            if (isinstance(Terms, list)):
                return map(low, Terms)
            else:
                raise Exception("lower_ir: Not implemented: " + str(sidl_term))
        else:
            raise Exception("match error")
Exemple #4
0
        def generate_ext_stub(cls):
            """
            shared code for class/interface
            """
            # Qualified name (C Version)
            qname = '_'.join(symbol_table.prefix + [cls.name])
            self.exts.append(qname)

            if self.config.verbose:
                import sys
                mod_name = '.'.join(symbol_table.prefix[1:] + [cls.name])
                sys.stdout.write('\r' + ' ' * 80)
                sys.stdout.write('\rgenerating glue code for %s' % mod_name)
                sys.stdout.flush()

            # Consolidate all methods, defined and inherited
            cls.scan_methods()

            # chpl_defs = ChapelScope(chpl_stub)
            ci = self.ClassInfo(cls)

            # if self.server:
            #     ci.impl = self.pkg_impl

            ci.stub.new_def(babel.externals(cls.get_scoped_id()))
            ci.stub.new_def(babel.builtin_stub_functions(cls.get_scoped_id()))

            has_contracts = ior_template.generateContractChecks(cls)
            self.gen_default_methods(cls, has_contracts, ci)

            #print qname, map(lambda x: x[2][1]+x[2][2], cls.all_methods)
            for method in cls.all_methods:
                (Method, Type, Name, Attrs, Args, Except, From, Requires,
                 Ensures, DocComment) = method
                ci.epv.add_method((method, Type, Name, Attrs,
                                   babel.drop_rarray_ext_args(Args), Except,
                                   From, Requires, Ensures, DocComment))

            # all the methods for which we would generate a server impl
            impl_methods = babel.builtins + cls.get_methods()
            impl_methods_names = [
                sidlir.method_method_name(m) for m in impl_methods
            ]

            # client
            for method in cls.all_methods:
                has_impl = sidlir.method_method_name(
                    method) in impl_methods_names
                self.generate_client_method(symbol_table, method, ci, has_impl)

            if self.server:
                class_methods = filter(sidlir.is_not_static, impl_methods)
                static_methods = filter(sidlir.is_static, impl_methods)

            #     # Class
            #     ci.impl.new_def(gen_doc_comment(cls.doc_comment, chpl_stub)+
            #                     'class %s_Impl {'%qname)
            #     splicer = '.'.join(cls.qualified_name+['Impl'])
            #     ci.impl.new_def('// DO-NOT-DELETE splicer.begin(%s)'%splicer)
            #     ci.impl.new_def('// DO-NOT-DELETE splicer.end(%s)'%splicer)
            #     for method in class_methods:
            #         self.generate_server_method(symbol_table, method, ci)

            #     ci.impl.new_def('} // class %s_Impl'%qname)
            #     ci.impl.new_def('')
            #     ci.impl.new_def('')

            #     # Static
            #     if static_methods:
            #         ci.impl.new_def('// all static member functions of '+qname)
            #         ci.impl.new_def(gen_doc_comment(cls.doc_comment, chpl_stub)+
            #                         '// FIXME: chpl allows only one module per library //'+
            #                         ' module %s_static_Impl {'%qname)

            #         for method in static_methods:
            #             self.generate_server_method(symbol_table, method, ci)

            #         ci.impl.new_def('//} // module %s_static_Impl'%qname)
            #         ci.impl.new_def('')
            #         ci.impl.new_def('')

            # # Chapel Stub (client-side Chapel bindings)
            # self.generate_chpl_stub(chpl_stub, qname, ci)

            # # Because of Chapel's implicit (filename-based) modules it
            # # is important for the Chapel stub to be one file, but we
            # # generate separate files for the cstubs
            # self.pkg_chpl_stub.new_def(chpl_stub)

            # Stub (in C), the order of these definitions is somewhat sensitive
            ci.stub.genh_top(ir.Import(qname + '_IOR'))
            ci.stub.gen(ir.Import(ci.stub._name))

            pkg_name = '_'.join(symbol_table.prefix)
            ci.stub.gen(ir.Import(pkg_name))
            ci.stub.write()

            # IOR
            ior_template.generate_ior(ci,
                                      with_ior_c=self.server,
                                      _braid_config=self.config)
            ci.ior.write()

            # Skeleton
            if self.server:
                self.generate_skeleton(ci, qname)

            # Convenience header
            ext_h = CFile(qname)
            ext_h.genh(ir.Import(qname + '_IOR'))
            ext_h.genh(ir.Import(qname + '_Stub'))
            ext_h.write()

            # Makefile
            self.classes.append(qname)
Exemple #5
0
    def generate_glue_code(self, node, data, symbol_table):
        """
        Generate glue code for \c node .        
        """
        def gen(node):
            return self.generate_glue_code(node, data, symbol_table)

        def generate_ext_stub(cls):
            """
            shared code for class/interface
            """
            # Qualified name (C Version)
            qname = '_'.join(symbol_table.prefix + [cls.name])
            self.exts.append(qname)

            if self.config.verbose:
                import sys
                mod_name = '.'.join(symbol_table.prefix[1:] + [cls.name])
                sys.stdout.write('\r' + ' ' * 80)
                sys.stdout.write('\rgenerating glue code for %s' % mod_name)
                sys.stdout.flush()

            # Consolidate all methods, defined and inherited
            cls.scan_methods()

            # chpl_defs = ChapelScope(chpl_stub)
            ci = self.ClassInfo(cls)

            # if self.server:
            #     ci.impl = self.pkg_impl

            ci.stub.new_def(babel.externals(cls.get_scoped_id()))
            ci.stub.new_def(babel.builtin_stub_functions(cls.get_scoped_id()))

            has_contracts = ior_template.generateContractChecks(cls)
            self.gen_default_methods(cls, has_contracts, ci)

            #print qname, map(lambda x: x[2][1]+x[2][2], cls.all_methods)
            for method in cls.all_methods:
                (Method, Type, Name, Attrs, Args, Except, From, Requires,
                 Ensures, DocComment) = method
                ci.epv.add_method((method, Type, Name, Attrs,
                                   babel.drop_rarray_ext_args(Args), Except,
                                   From, Requires, Ensures, DocComment))

            # all the methods for which we would generate a server impl
            impl_methods = babel.builtins + cls.get_methods()
            impl_methods_names = [
                sidlir.method_method_name(m) for m in impl_methods
            ]

            # client
            for method in cls.all_methods:
                has_impl = sidlir.method_method_name(
                    method) in impl_methods_names
                self.generate_client_method(symbol_table, method, ci, has_impl)

            if self.server:
                class_methods = filter(sidlir.is_not_static, impl_methods)
                static_methods = filter(sidlir.is_static, impl_methods)

            #     # Class
            #     ci.impl.new_def(gen_doc_comment(cls.doc_comment, chpl_stub)+
            #                     'class %s_Impl {'%qname)
            #     splicer = '.'.join(cls.qualified_name+['Impl'])
            #     ci.impl.new_def('// DO-NOT-DELETE splicer.begin(%s)'%splicer)
            #     ci.impl.new_def('// DO-NOT-DELETE splicer.end(%s)'%splicer)
            #     for method in class_methods:
            #         self.generate_server_method(symbol_table, method, ci)

            #     ci.impl.new_def('} // class %s_Impl'%qname)
            #     ci.impl.new_def('')
            #     ci.impl.new_def('')

            #     # Static
            #     if static_methods:
            #         ci.impl.new_def('// all static member functions of '+qname)
            #         ci.impl.new_def(gen_doc_comment(cls.doc_comment, chpl_stub)+
            #                         '// FIXME: chpl allows only one module per library //'+
            #                         ' module %s_static_Impl {'%qname)

            #         for method in static_methods:
            #             self.generate_server_method(symbol_table, method, ci)

            #         ci.impl.new_def('//} // module %s_static_Impl'%qname)
            #         ci.impl.new_def('')
            #         ci.impl.new_def('')

            # # Chapel Stub (client-side Chapel bindings)
            # self.generate_chpl_stub(chpl_stub, qname, ci)

            # # Because of Chapel's implicit (filename-based) modules it
            # # is important for the Chapel stub to be one file, but we
            # # generate separate files for the cstubs
            # self.pkg_chpl_stub.new_def(chpl_stub)

            # Stub (in C), the order of these definitions is somewhat sensitive
            ci.stub.genh_top(ir.Import(qname + '_IOR'))
            ci.stub.gen(ir.Import(ci.stub._name))

            pkg_name = '_'.join(symbol_table.prefix)
            ci.stub.gen(ir.Import(pkg_name))
            ci.stub.write()

            # IOR
            ior_template.generate_ior(ci,
                                      with_ior_c=self.server,
                                      _braid_config=self.config)
            ci.ior.write()

            # Skeleton
            if self.server:
                self.generate_skeleton(ci, qname)

            # Convenience header
            ext_h = CFile(qname)
            ext_h.genh(ir.Import(qname + '_IOR'))
            ext_h.genh(ir.Import(qname + '_Stub'))
            ext_h.write()

            # Makefile
            self.classes.append(qname)

        if not symbol_table:
            raise Exception()

        with match(node):
            if (sidlir.class_, (Name), Extends, Implements, Invariants,
                    Methods, DocComment):
                expect(data, None)
                generate_ext_stub(
                    sidlobjects.Class(symbol_table, node, self.class_attrs))

            elif (sidlir.struct, (Name), Items, DocComment):
                # Generate Chapel stub
                # self.pkg_chpl_stub.gen(ir.Type_decl(lower_ir(symbol_table, node, struct_suffix='')))

                # record it for later, when the package is being finished
                self.pkg_enums_and_structs.append(struct_ior_names(node))

            elif (sidlir.interface, (Name), Extends, Invariants, Methods,
                  DocComment):
                # Interfaces also have an IOR to be generated
                expect(data, None)
                generate_ext_stub(
                    sidlobjects.Interface(symbol_table, node,
                                          self.class_attrs))

            elif (sidlir.enum, Name, Items, DocComment):
                # Generate Chapel stub
                # self.pkg_chpl_stub.gen(ir.Type_decl(node))

                # record it for later, when the package is being finished
                self.pkg_enums_and_structs.append(node)

            elif (sidlir.package, Name, Version, UserTypes, DocComment):
                # Generate the chapel stub
                qname = '_'.join(symbol_table.prefix + [Name])
                _, pkg_symbol_table = symbol_table[sidlir.Scoped_id([], Name,
                                                                    '')]

                if self.in_package:
                    # nested modules are generated in-line
                    # self.pkg_chpl_stub.new_def('module %s {'%Name)
                    self.generate_glue_code(UserTypes, data, pkg_symbol_table)
                    # self.pkg_chpl_stub.new_def('}')
                else:
                    # server-side Chapel implementation template
                    if self.server: self.begin_impl(qname)

                    # new file for the toplevel package
                    # self.pkg_chpl_stub = ChapelFile(relative_indent=0)
                    self.pkg_enums_and_structs = []
                    self.in_package = True

                    # recursion!
                    self.generate_glue_code(UserTypes, data, pkg_symbol_table)
                    # write_to(qname+'.chpl', str(self.pkg_chpl_stub))

                    # server-side Chapel implementation template
                    if self.server: self.end_impl(qname)

                    # Makefile
                    self.pkgs.append(qname)

                pkg_h = CFile(qname)
                pkg_h = pkg_h
                pkg_h.genh(ir.Import('sidl_header'))
                for es in self.pkg_enums_and_structs:
                    es_ior = babel.lower_ir(pkg_symbol_table,
                                            es,
                                            header=pkg_h,
                                            qualify_names=True)
                    pkg_h.gen(ir.Type_decl(es_ior))

                for ext in self.exts:
                    pkg_h.genh(ir.Import(ext))

                pkg_h.write()

            elif (sidlir.user_type, Attrs, Cipse):
                self.class_attrs = Attrs
                gen(Cipse)

            elif (sidlir.file, Requires, Imports, UserTypes):
                self.in_package = False
                gen(UserTypes)

            elif A:
                if (isinstance(A, list)):
                    for defn in A:
                        gen(defn)
                else:
                    raise Exception("NOT HANDLED:" + repr(A))
            else:
                raise Exception("match error")
        return data
Exemple #6
0
    def generate_skeleton(self, ci, qname):
        """
        Chapel Skeleton (client-side Chapel bindings)

        Generate a Skeleton in Chapel.
        """
        symbol_table = ci.epv.symbol_table
        cls = ci.co

        # Skeleton (in Chapel)
        self.pkg_chpl_skel.gen(ir.Import('.'.join(symbol_table.prefix)))

        self.pkg_chpl_skel.new_def('use sidl;')
        objname = '.'.join(ci.epv.symbol_table.prefix +
                           [ci.epv.name]) + '_Impl'

        self.pkg_chpl_skel.new_def(
            'extern record %s__object { var d_data: opaque; };' %
            qname)  #,objname))
        self.pkg_chpl_skel.new_def('extern proc %s__createObject(' % qname +
                                   'd_data: int, ' +
                                   'out ex: sidl_BaseInterface__object)' +
                                   ': %s__object;' % qname)
        self.pkg_chpl_skel.new_def(ci.chpl_skel)

        # Skeleton (in C)
        cskel = ci.chpl_skel.cstub
        cskel._name = qname + '_Skel'
        cskel.gen(ir.Import('stdint'))
        cskel.gen(ir.Import('stdio'))
        cskel.gen(ir.Import(cskel._name))
        cskel.gen(ir.Import(qname + '_IOR'))
        cskel.gen(
            ir.Fn_defn([], ir.pt_void, qname + '__call_load', [],
                       [ir.Comment("FIXME: [ir.Stmt(ir.Call('_load', []))")],
                       ''))

        # set_epv ... Setup the entry-point vectors (EPV)s
        #
        # there are 2*3 types of EPVs:
        #    epv: regular methods
        #    sepv: static methods
        #    pre_(s)epv: pre-hooks
        #    post_(s)epv: post-hooks
        epv_t = ci.epv.get_ir()
        sepv_t = ci.epv.get_sepv_ir()
        pre_epv_t = ci.epv.get_pre_epv_ir()
        pre_sepv_t = ci.epv.get_pre_sepv_ir()
        post_epv_t = ci.epv.get_post_epv_ir()
        post_sepv_t = ci.epv.get_post_sepv_ir()
        cskel.gen(ir.Fn_decl([], ir.pt_void, 'ctor', [], ''))
        cskel.gen(ir.Fn_decl([], ir.pt_void, 'dtor', [], ''))

        epv_init = []
        sepv_init = []
        for m in builtins + cls.get_methods():
            fname = m[2][1] + m[2][2]
            attrs = sidlir.method_method_attrs(m)
            static = member_chk(sidlir.static, attrs)

            def entry(stmts, epv_t, table, field, pointer):
                stmts.append(
                    ir.Set_struct_item_stmt(epv_t, ir.Deref(table), field,
                                            pointer))

            if static:
                entry(sepv_init, sepv_t, 'sepv', 'f_' + fname,
                      '%s_%s_skel' % (qname, fname))
            else:
                entry(epv_init, epv_t, 'epv', 'f_' + fname,
                      '%s_%s_skel' % (qname, fname))

            builtin_names = ['_ctor', '_ctor2', '_dtor']
            with_hooks = member_chk(ir.hooks, attrs)
            if fname not in builtin_names and with_hooks:
                if static:
                    entry(sepv_init, pre_sepv_t, 'pre_sepv',
                          'f_%s_pre' % fname, 'NULL')
                else:
                    entry(epv_init, pre_epv_t, 'pre_epv', 'f_%s_pre' % fname,
                          'NULL')
                if static:
                    entry(sepv_init, post_sepv_t, 'post_sepv',
                          'f_%s_post' % fname, 'NULL')
                else:
                    entry(epv_init, post_epv_t, 'post_epv',
                          'f_%s_post' % fname, 'NULL')

        pkgname = '_'.join(ci.epv.symbol_table.prefix)

        dummyargv = '''
  char* argv[] = { 
    babel_program_name,
    "-nl", /* number of locales */
    "",
    "-v", /* verbose chapel runtime */
    NULL
  };
  argv[2] = getenv("SLURM_NTASKS");
  if (argv[2] == NULL) {
    fprintf(stdout, "**ERROR: please set the SLURM_NTASKS environment variable\\n"
                    "         to the desired number of Chapel locales.");
    argv[2] = "0";
  }
  int ignored = setenv("GASNET_BACKTRACE", "1", 1);
'''
        cskel.genh(ir.Import('stdlib'))
        cskel.pre_def('extern int chpl_init_library(int argc, char* argv[]);')
        cskel.pre_def(
            '// You can set this to argv[0] in main() to get better debugging output'
        )
        cskel.pre_def(
            'char* __attribute__((weak)) babel_program_name = "BRAID_LIBRARY";'
        )
        # These are now called by chpl_init_library -> chpl_gen_init
        #cskel.pre_def('extern void chpl__init_chpl__Program(int, const char*);')
        #cskel.pre_def('extern void chpl__init_%s_Impl(int, const char*);'%pkgname)
        init_code = [
            dummyargv,
            'int locale_id = chpl_init_library(4, argv)',
            #         'chpl__init_chpl__Program(__LINE__, __FILE__)',
            #         'chpl__init_%s_Impl(__LINE__, __FILE__)'%pkgname
        ]
        init_code = map(lambda x: (ir.stmt, x), init_code)
        epv_init.extend(init_code)
        sepv_init.extend(init_code)

        cskel.gen(
            ir.Fn_defn([], ir.pt_void, qname + '__set_epv', [
                ir.Arg([], ir.out, epv_t, 'epv'),
                ir.Arg([], ir.out, pre_epv_t, 'pre_epv'),
                ir.Arg([], ir.out, post_epv_t, 'post_epv')
            ], epv_init, ''))

        if sepv_t:
            cskel.gen(
                ir.Fn_defn([], ir.pt_void, qname + '__set_sepv', [
                    ir.Arg([], ir.out, sepv_t, 'sepv'),
                    ir.Arg([], ir.out, pre_sepv_t, 'pre_sepv'),
                    ir.Arg([], ir.out, post_sepv_t, 'post_sepv')
                ], sepv_init, ''))

        # C Skel
        for code in cskel.optional:
            cskel.new_global_def(code)
        cskel.write()