Exemple #1
0
    def createMain(self):
        #Main Function
        #Declaration
        z1 = c_ast.TypeDecl('args',[],c_ast.IdentifierType(['int']))
        args = c_ast.Decl('args',[],[],[],z1,None,None)
        z2= c_ast.PtrDecl([],c_ast.TypeDecl('argv',[],c_ast.IdentifierType(['char'])))
        z3=c_ast.ArrayDecl(z2,None,[])
        argv = c_ast.Decl('argv',[],[],[],z3,None,None)
        params=c_ast.ParamList([args,argv])
        mainDec=c_ast.FuncDecl(params,c_ast.TypeDecl('main',[],c_ast.IdentifierType(['int'])))
#        insertTest(functionName,varVals,varTypes)
        #Body
        ##Signal
        sigalrm=c_ast.ID(name="14")
        funcCast=c_ast.TypeDecl(declname = None,quals=[],type=c_ast.IdentifierType(['void']))
        paramCast=c_ast.ParamList([c_ast.Typename(name=None,quals=[],type=c_ast.TypeDecl(declname = None,quals=[],type=c_ast.IdentifierType(['int'])))])
        typeFunc=c_ast.PtrDecl(type=c_ast.FuncDecl(paramCast,funcCast),quals=[])        
        kchild=c_ast.Cast(to_type=c_ast.Typename(name=None, quals=[],type=typeFunc),expr=c_ast.ID(name="kill_child"))
        expressList = [sigalrm,kchild]
        signalStmt=c_ast.FuncCall(c_ast.ID(name="signal"),c_ast.ExprList(expressList))

        ##Return
        returnStmt=c_ast.Return(c_ast.Constant(type="int",value="0"))
        comp=c_ast.Compound([signalStmt,returnStmt])
        return c_ast.FuncDef(mainDec,None,comp)
Exemple #2
0
def _generate_arraydecl(name, decl, length):
    """ Generates a new declaration with an array type
    base on an existing declaration

    """
    typedecl = c_ast.TypeDecl(name, [], decl.type)
    arraydecl = c_ast.ArrayDecl(typedecl, length, [])
    return c_ast.Decl(name, [], [], [], arraydecl, [], [])
  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)
Exemple #4
0
def createTest(block,functionName,varVals,varTypes):
   #Main Function
   #Declaration
   z1 = c_ast.TypeDecl('args',[],c_ast.IdentifierType(['int']))
   args = c_ast.Decl('args',[],[],[],z1,None,None)
   z2= c_ast.PtrDecl([],c_ast.TypeDecl('argv',[],c_ast.IdentifierType(['char'])))
   z3=c_ast.ArrayDecl(z2,None,[])
   argv = c_ast.Decl('argv',[],[],[],z3,None,None)
   params=c_ast.ParamList([args,argv])
   mainDec=c_ast.FuncDecl(params,c_ast.TypeDecl('main',[],c_ast.IdentifierType(['int'])))
   insertTest(functionName,varVals,varTypes)
   #Body
   returnStmt=c_ast.Return(c_ast.Constant(type="int",value="0"))
   comp=c_ast.Compound([returnStmt])
   main= c_ast.FuncDef(mainDec,None,comp)
   insertTest(main,"func",['1','2'],['int','int'])
Exemple #5
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)
Exemple #6
0
        def annotate_struct(a, n, ext):

            if not isinstance(n.type, c_ast.Struct):
                raise ExpansionError(
                    a, n, 'Cannot expand annotation @{0} on {1}'.format(
                        a.name, n.__class__.__name__))

            json_annotations = {}
            if a.name == 'json' and a.content != '':
                json_annotations = json.loads(a.content)
                json_annotations['@root'] = a
                if not isinstance(json_annotations, dict):
                    raise ExpansionError(
                        a, n,
                        'Expected @json content to be empty or a JSON object.\nGot {0}'
                        .format(a.content))
            name = n.type.name
            struct = n.type
            annotated_struct = AnnotatedStruct(self, struct, json_annotations,
                                               ext)
            properties = c_ast.Decl(
                self.PROPERTIES_NAME(name),
                [],  #quals
                [],  #storage
                [],  #funcspec
                # type
                c_ast.ArrayDecl(
                    c_ast.TypeDecl(self.PROPERTIES_NAME(name), [],
                                   struct_object_property_decl),
                    None,  # dim
                    []  # dim_quals
                ),
                annotated_struct.init_list,  # init
                None  # bitsize
            )

            struct.decls = annotated_struct.decls
            if not ext.seek(n):
                raise ExpansionError(a, n, "Couldn't seek to node")
            ext.insert(properties)
            return True
Exemple #7
0
 def p_direct_abstract_no_dim_array_declarator_with_parens_2(self, p):
     """ direct_abstract_declarator  : LBRACKET LPAREN RPAREN RBRACKET
     """
     p[0] = c_ast.ArrayDecl(type=c_ast.TypeDecl(None, None, None),
                            dim=None,
                            coord=self._coord(p.lineno(1)))
Exemple #8
0
    def p_direct_abstract_no_dim_array_declarator_with_parens(self, p):
        """ direct_abstract_declarator  : direct_abstract_declarator LBRACKET LPAREN RPAREN RBRACKET
        """
        arr = c_ast.ArrayDecl(type=None, dim=None, coord=p[1].coord)

        p[0] = self._type_modify_decl(decl=p[1], modifier=arr)
Exemple #9
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
Exemple #10
0
    def visit_FuncDef(self, node):
        # the start of the transformation
        self._types.clear()
        logger.info('Start transforming function {} ...'.format(node.decl.name))

        # first pickup the annotation for parameters
        assume_statement, type_statement = node.body.block_items.pop(0), node.body.block_items.pop(0)
        if not all((isinstance(assume_statement, c_ast.Constant),
                   assume_statement.type == 'string',
                   isinstance(type_statement, c_ast.Constant),
                   type_statement.type == 'string')):
            raise NoParameterAnnotationError(assume_statement.coord)
        sensitivity, *other_assumes = assume_statement.value[1:-1].strip().split(';')
        if sensitivity not in ('ALL_DIFFER', 'ONE_DIFFER'):
            raise ValueError('Annotation for sensitivity should be either \'ALL_DIFFER\' or \'ONE_DIFFER\'')

        # get distances from annotation string and store to type system
        parameter_distances = type_statement.value[1:-1].strip().split(';')
        for parameter in parameter_distances:
            results = re.findall(r'([a-zA-Z_]+):\s*<([*a-zA-Z0-9\[\]]+),\s*([*a-zA-Z0-9\[\]]+)>', parameter)
            if len(results) == 0:
                raise ValueError('Illegal annotation for parameter: {}'.format(parameter))
            else:
                name, align, shadow = results[0]
                if align != shadow:
                    raise ValueError('Annotated distances must be identical. {}'.format(parameter))
                else:
                    self._types.update_distance(name, align, shadow)

        self._one_differ = True if sensitivity == 'ONE_DIFFER' else False

        # visit children
        self.generic_visit(node)

        # get the names of parameters
        epsilon, size, q, *_ = self._parameters

        insert_statements = [
            # insert assume(epsilon > 0)
            c_ast.FuncCall(c_ast.ID(self._func_map['assume']),
                           args=c_ast.ExprList([c_ast.BinaryOp('>', c_ast.ID(epsilon),
                                                               c_ast.Constant('int', 0))])),
            # insert assume(size > 0)
            c_ast.FuncCall(c_ast.ID(self._func_map['assume']),
                           args=c_ast.ExprList([c_ast.BinaryOp('>', c_ast.ID(size),
                                                               c_ast.Constant('int', 0))])),
        ]

        # add user-defined assume
        regex = re.compile(r'assume\(([\sa-zA-Z+\-*\\0-9_><=&|]+)\)')
        for assume in other_assumes:
            if 'assume' in assume:
                for expression in regex.findall(assume):
                    insert_statements.append(c_ast.FuncCall(c_ast.ID(self._func_map['assume']),
                                                            args=convert_to_ast(expression)))

        insert_statements.append(
            # insert float __SHADOWDP_v_epsilon = 0;
            c_ast.Decl(name='__SHADOWDP_v_epsilon',
                       type=c_ast.TypeDecl(declname='__SHADOWDP_v_epsilon',
                                           type=c_ast.IdentifierType(names=['float']),
                                           quals=[]),
                       init=c_ast.Constant('int', '0'),
                       quals=[], funcspec=[], bitsize=[], storage=[])
        )

        # setup different sensitivity settings
        if self._one_differ:
            insert_statements.append(
                # insert assume(__SHADOWDP_index >= 0);
                c_ast.FuncCall(c_ast.ID(self._func_map['assume']),
                               args=c_ast.ExprList([c_ast.BinaryOp('>=', c_ast.ID('__SHADOWDP_index'),
                                                                   c_ast.Constant('int', 0))])),
            )
            insert_statements.append(
                # insert assume(__SHADOWDP_index < size);
                c_ast.FuncCall(c_ast.ID(self._func_map['assume']),
                               args=c_ast.ExprList([c_ast.BinaryOp('<', c_ast.ID('__SHADOWDP_index'),
                                                                   c_ast.ID(size))]))
            )
            # insert parameter __SHADOWDP_index
            node.decl.type.args.params.append(
                c_ast.Decl(name='__SHADOWDP_index',
                           type=c_ast.TypeDecl(declname='__SHADOWDP_index',
                                               type=c_ast.IdentifierType(names=['int']),
                                               quals=[]),
                           init=None,
                           quals=[], funcspec=[], bitsize=[], storage=[])
            )

        # add declarations / new parameters for dynamically tracked variables
        for name, distances in self._types.variables():
            for index, distance in enumerate(distances):
                version = 'ALIGNED' if index == 0 else 'SHADOW'
                if distance == '*' or distance == '__SHADOWDP_{}_DISTANCE_{}'.format(version, name):
                    # if it is a dynamically tracked local variable, add declarations
                    if name not in self._parameters:
                        varname = '__SHADOWDP_{}_DISTANCE_{}'.format(version, name)
                        insert_statements.append(
                            c_ast.Decl(name=varname,
                                       type=c_ast.TypeDecl(declname=varname,
                                                           type=c_ast.IdentifierType(names=['float']), quals=[]),
                                       init=c_ast.Constant('int', '0'), quals=[], funcspec=[], bitsize=[], storage=[]))
                    # if it is a dynamically tracked parameter, add new parameters
                    else:
                        # TODO: should be able to detect the type of parameters
                        if name != q:
                            raise NotImplementedError('Currently only supports * types for query variables')
                        varname = '__SHADOWDP_{}_DISTANCE_{}'.format(version, q)
                        node.decl.type.args.params.append(
                            c_ast.Decl(name=varname,
                                       type=c_ast.ArrayDecl(
                                           type=c_ast.TypeDecl(declname=varname, type=c_ast.IdentifierType(
                                               names=['float']), quals=[]), dim=None, dim_quals=[]),
                                       init=None,
                                       quals=[], funcspec=[], bitsize=[], storage=[])
                        )

        # prepend the inserted statements
        node.body.block_items[:0] = insert_statements
Exemple #11
0
def array(ty, dim=None, quals=[]):
    return c_ast.ArrayDecl(ty, dim, quals)