def visit_FuncDef(self, node):
    # Skip if no loop counters exist
    if self.loop_counter_size == 0:
      return

    # Create loop_counter declaration/initialization
    constants = [c_ast.Constant("int", '0') for i in range(self.loop_counter_size)]
    init_list = c_ast.InitList(constants)
    identifier_type = c_ast.IdentifierType(["int"])
    type_decl = c_ast.TypeDecl("loop_counter", [], identifier_type)
    dim = c_ast.Constant("int", str(self.loop_counter_size))
    array_decl = c_ast.ArrayDecl(type_decl, dim, [])
    decl = c_ast.Decl("loop_counter", [], [], [], array_decl, init_list, None) 
    node.body.block_items.insert(0, decl)

    # Label for return values to goto
    start_label = c_ast.Label("print_loop_counter", c_ast.EmptyStatement())
    # Start and end labels used for inserting preprocessor commands for #if DEBUG_EN
    end_label = c_ast.Label("print_loop_counter_end", c_ast.EmptyStatement())

    # Write to file
    if self.write_to_file:
      stmt = c_ast.ID("write_array(loop_counter, %d)\n" % (self.loop_counter_size))
      compound = c_ast.Compound([start_label, stmt, end_label])
    # Print to stdout
    else:
      # Add printf to the end of function
      # Start of printing
      stmt_start = c_ast.ID("printf(\"loop counter = (\")")

      # For loop
      # int i;
      identifier_type = c_ast.IdentifierType(["int"])
      type_decl = c_ast.TypeDecl("i", [], identifier_type)
      for_decl = c_ast.Decl("i", [], [], [], type_decl, [], None)
      # i = 0
      init = c_ast.Assignment("=", c_ast.ID("i"), c_ast.Constant("int", '0'))
      # i < self.loop_counter_size
      cond = c_ast.BinaryOp("<", c_ast.ID("i"), c_ast.Constant("int", str(self.loop_counter_size)))
      # i++
      next_stmt = c_ast.UnaryOp("p++", c_ast.ID("i"))
      # printf in for
      stmt = c_ast.ID("printf(\"%d, \", loop_counter[i])")
      # Cosntruct for loop
      stmt_for = c_ast.For(init, cond, next_stmt, stmt)

      # End of printing
      stmt_end = c_ast.ID("printf(\")\\n\")")
      
      # Put it all together
      body = c_ast.Compound([stmt_start, for_decl, stmt_for, stmt_end])
      # Surround with labels
      compound = c_ast.Compound([start_label, body, end_label])
    node.body.block_items.append(compound)
예제 #2
0
 def __init__(self, func, variable_declaration, structs):
     self.func = func
     self.variable_declaration = variable_declaration
     if variable_declaration.storage is not None:
         variable_declaration.storage.append("static")
     else:
         variable_declaration.storage = ["static"]
     if self.variable_declaration.init is None:
         if "extern" in variable_declaration.storage:
             variable_declaration.storage.remove("extern")
         if type(self.variable_declaration.type) is c_ast.ArrayDecl or \
          any(x in structs for x in self.variable_declaration.type.type.names):
             self.variable_declaration.init = c_ast.InitList(
                 exprs=[c_ast.Constant(type="int", value="0")])
         else:
             self.variable_declaration.init = c_ast.Constant(type="int",
                                                             value="0")
예제 #3
0
def ConvertConvertAddressTakenScalarsToArray(ast, meta_info: meta.MetaInfo):
    """
    Rewrite address taken scalar vars as one element arrays

    After this transform we can keep all scalars in registers.
    """

    def IsAddressTakenScalarOrGlobalScalar(node, parent):
        if isinstance(node, c_ast.Decl) and IsScalarType(node.type):
            # return isinstance(parent, c_ast.FileAST)
            return (isinstance(parent, c_ast.FileAST) or
                    "static" in node.storage)

        if not isinstance(node, c_ast.UnaryOp): return False
        if node.op != "&": return False
        if not isinstance(node.expr, c_ast.ID): return False
        type = meta_info.type_links[node.expr]
        return IsScalarType(type)

    candidates = common.FindMatchingNodesPreOrder(ast, ast, IsAddressTakenScalarOrGlobalScalar)
    ids = set()
    for node, _ in candidates:
        if isinstance(node, c_ast.UnaryOp):
            ids.add(meta_info.sym_links[node.expr])
        else:
            ids.add(node)
    one = c_ast.Constant("int", "1")
    meta_info.type_links[one] = meta.INT_IDENTIFIER_TYPE

    for node in ids:
        assert isinstance(node, c_ast.Decl)
        node.type = c_ast.ArrayDecl(node.type, one, [])
        if node.init:
            node.init = c_ast.InitList([node.init])

    def IsAddressTakenScalarId(node, _):
        return isinstance(node, c_ast.ID) and meta_info.sym_links[node] in ids

    candidates = common.FindMatchingNodesPreOrder(ast, ast, IsAddressTakenScalarId)

    for node, parent in candidates:
        original_type = meta_info.type_links[node]
        meta_info.type_links[node] = meta.GetTypeForDecl(meta_info.sym_links[node].type)
        array_ref = c_ast.UnaryOp("*", node)
        meta_info.type_links[array_ref] = original_type
        common.ReplaceNode(parent, node, array_ref)
예제 #4
0
 def replace_enum_values(self, enum_object, storage_lvalue=None):
     constants = []
     for enum in enum_object.members.enumerators:
         constants.append(
             c_ast.Constant(type="int", value=str(enum.value.value)))
     init_list = c_ast.InitList(exprs=constants)
     init_count = c_ast.Constant(type="int", value=str(len(constants)))
     values = None
     values_len = None
     for node in self.get_nodes(self.ast):
         if type(node) == c_ast.Decl:
             if node.name == "values":
                 values = node
             if node.name == "values_len":
                 values_len = node
             if node.name == "idx":
                 idx = node
         if type(node) == c_ast.ID:
             if node.name == "values_len":
                 values_len_id = node
             if node.name == "values":
                 values_id = node
             if node.name == "idx":
                 idx_id = node
         if type(node) == c_ast.Assignment:
             if node.lvalue.expr.name == "storage":
                 storage_expr = node
     values.init = init_list
     new_values_name = values.name + str(nesting_context.values_count)
     values.name = new_values_name
     change_declname(values, new_values_name)
     values_id.name = new_values_name
     values_len.init = init_count
     new_values_len_name = values_len.name + str(
         nesting_context.values_count)
     values_len.name = new_values_len_name
     change_declname(values_len, new_values_len_name)
     values_len_id.name = new_values_len_name
     new_idx_name = idx.name + str(nesting_context.values_count)
     idx.name = new_values_name
     change_declname(idx, new_idx_name)
     idx_id.name = new_idx_name
     if storage_lvalue:
         storage_expr.lvalue = storage_lvalue
     nesting_context.values_count += 1
예제 #5
0
    def work(self, function_node):
        ret_num = len(self.rets)
        # if more than 1 return
        if ret_num > 1:
            if isinstance(function_node, c_ast.FuncDef):
                f_type = function_node.decl.type
                while not isinstance(f_type, c_ast.TypeDecl):
                    f_type = f_type.type
                new_type = copy.deepcopy(f_type)
                new_type.type.names = ['int']
                function_node.decl.type.type = c_ast.PtrDecl(type=new_type, quals=[])

                new_ret_decl = c_ast.Decl(name="CLEVER_RET", funcspec=[], bitsize=None, storage=[], quals=[], init=c_ast.InitList(exprs=self.ret_exps), type=c_ast.ArrayDecl(
                dim=c_ast.Constant(type='int', value=str(ret_num)), dim_quals=[], type=c_ast.TypeDecl(declname="CLEVER_RET", quals=[], type=c_ast.IdentifierType(names=['int']))))

                ret_state = c_ast.Return(expr=c_ast.ID(name=new_ret_decl.name))

                for node in self.rets:
                    function_node.body.block_items.remove(node)

                function_node.body.block_items.append(new_ret_decl)
                function_node.body.block_items.append(ret_state)

            return
예제 #6
0
파일: types.py 프로젝트: neophack/epanos
def initlist(arg):
    if type(arg) is not list:
        raise utils.BugError('non-list passed')
    return c_ast.InitList(arg)
예제 #7
0
 def new_ilist(self, exprs, parent=None):
     il = c_ast.InitList(exprs)
     il.parent = parent
     for e in exprs:
         e.parent = il
     return il
예제 #8
0
    def __init__(self, annotations, struct, json_annotations, ext):
        """
        Describes the property list for a struct
        Also create a list of c_ast.Decl to append to the struct decls
        """
        self.json_annotations = json_annotations
        self.annotated_properties = None
        self.annotations = annotations
        self.ext = ext
        self.init_list = None
        self.decls = None
        self.struct = struct
        self.extra_decls = None

        def make_extra_decl(name, t):
            idtype = c_ast.IdentifierType([t])
            td = c_ast.TypeDecl(name, [], idtype)
            return c_ast.Decl(
                name,
                [],  # quals
                [],  # storage
                [],  # funcspec
                td,  # type
                None,  # init
                None,  # bitsize
            )

        fi = getframeinfo(currentframe())
        annotated_properties = [
            AnnotatedProperty(self, d) for d in struct.decls
        ]

        out_ap = []
        for ap in annotated_properties:
            inline_annotation = ap.values.get('inline', False)
            if inline_annotation:
                astruct = self.inline_struct_annotated(inline_annotation,
                                                       ap.decl)
                out_ap += astruct.annotated_properties
            else:
                out_ap.append(ap)

        self.annotated_properties = out_ap

        init_lists = [
            ap.init_list for ap in out_ap
            # 'private' and 'inline' have no init_list
            if ap.init_list is not None
        ]

        # NULL terminator
        init_lists.append(c_ast.InitList([c_ast.Constant('int', '0')]))

        self.init_list = c_ast.InitList(init_lists,
                                        Coord(fi.filename, fi.lineno))

        decls = [ap.decl for ap in out_ap]

        extra_decls = chain.from_iterable(
            (ap.extra_decls.iteritems() for ap in out_ap))
        extra_decls = [make_extra_decl(name, t) for name, t in extra_decls]

        decls += extra_decls

        self.decls = decls
예제 #9
0
    def __init__(self, annotated_struct, decl):
        self.init_list = None
        self.decl = decl
        self.extra_decls = {}
        self.values = {}
        init_exprs = []

        self.struct = annotated_struct

        annotations = self.struct.annotations.get(decl,
                                                  self.struct.json_annotations)
        try:
            for a in annotations:
                expr = self.expand_annotation(a, self.values)
                if expr is not None:
                    init_exprs.append(expr)
        except StopIteration:
            name = a.name
            a = next(annotations, None)
            if a is not None:
                raise ExpansionError(a, decl,
                                     'Unexpected annotation after ' + name)
            return
        init_list = []

        prop_name = type_find(decl, c_ast.TypeDecl).declname

        # name the property if it hasn't already been named
        if 'name' not in self.values:
            self.values['name'] = prop_name

        # add string initializers
        for init_name in ('name', 'schema'):
            if init_name in self.values:
                literal = str_literal(self.values[init_name])
                init_exprs.append(
                    c_ast.NamedInitializer([c_ast.ID(init_name)],
                                           c_ast.Constant('string', literal)))

        # assign types
        type_annotations = {
            name: t
            for name, t in self.values.iteritems()
            if isinstance(t, Annotation)
        }
        types, arraydecl = self.struct.annotations.get_types(
            decl, type_annotations)
        type_inits = [
            c_ast.NamedInitializer([c_ast.ID(ttype)], c_ast.ID(t))
            for ttype, t in types.iteritems()
        ]
        fi = getframeinfo(currentframe())
        init_exprs.append(
            c_ast.NamedInitializer([c_ast.ID('type')],
                                   c_ast.InitList(
                                       type_inits,
                                       Coord(fi.filename, fi.lineno))))
        struct = annotated_struct.struct
        # calculate struct offset
        init_exprs.append(
            c_ast.NamedInitializer([c_ast.ID('offset')],
                                   self.offsetof(struct.name, prop_name)))
        if 'nullable' in self.values and self.values['nullable']:
            self.extra_decls[AnnotatedProperty.NULLABLE_NAME(
                decl.name)] = 'bool'
            init_exprs.append(
                c_ast.NamedInitializer(
                    [c_ast.ID('null_offset')],
                    self.offsetof(struct.name,
                                  AnnotatedProperty.NULLABLE_NAME(prop_name))))
        if arraydecl:
            # static array
            init_exprs.append(
                c_ast.NamedInitializer([c_ast.ID('length')], arraydecl.dim))
        elif types['json'] == 'json_type_array':
            # calculate length offset
            len_prop = AnnotatedProperty.LENGTH_NAME(prop_name)
            self.extra_decls[len_prop] = 'int'
            init_exprs.append(
                c_ast.NamedInitializer([c_ast.ID('length_offset')],
                                       self.offsetof(struct.name, len_prop)))
            init_exprs.append(
                c_ast.NamedInitializer([c_ast.ID('dereference')],
                                       c_ast.Constant('int', '1')))

        if types['json'] == 'json_type_array':
            # assume PtrDecl for now
            init_exprs.append(
                c_ast.NamedInitializer([c_ast.ID('stride')],
                                       self.sizeof(decl.type.type)))

        fi = getframeinfo(currentframe())
        self.init_list = c_ast.InitList(init_exprs,
                                        Coord(fi.filename, fi.lineno))