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)
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)
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'])
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)
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
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)))
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)
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
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
def array(ty, dim=None, quals=[]): return c_ast.ArrayDecl(ty, dim, quals)