def visit_Return(self, node): align, _ = _DistanceGenerator(self._types).visit(node.expr) if align != '0': raise ReturnDistanceNotZero(node.coord, _code_generator.visit(node.expr), align) # insert assert(__SHADOWDP_v_epsilon <= epsilon); epsilon, *_ = self._parameters if self._set_epsilon and self._set_epsilon.isdigit(): epsilon_node = c_ast.Constant(type='float', value=self._set_epsilon) elif self._set_epsilon and not self._set_epsilon.isdigit(): epsilon_node = c_ast.ID(name=self._set_epsilon) else: epsilon_node = c_ast.ID(epsilon) if self._set_goal: assert_node = c_ast.FuncCall( c_ast.ID(self._func_map['assert']), args=c_ast.ExprList( [c_ast.BinaryOp('<=', c_ast.ID(name='__SHADOWDP_v_epsilon'), c_ast.BinaryOp(op='*', left=epsilon_node, right=convert_to_ast(self._set_goal)))])) else: assert_node = c_ast.FuncCall(c_ast.ID(self._func_map['assert']), args=c_ast.ExprList([c_ast.BinaryOp('<=', c_ast.ID('__SHADOWDP_v_epsilon'), epsilon_node)])) self._parents[node].block_items.insert(self._parents[node].block_items.index(node), assert_node) self._inserted.add(assert_node) # because we have inserted a statement before Return statement while iterating, it will be a forever loop # add the current node to the set to not visit this same node again self._inserted.add(node)
def __malloc(self, depth: int) -> c_ast.FuncCall: """ A helper function to generate the call of malloc function with proper arguments. Note that a constant of 2 is added to the number of allocated cells. This is meant to compensate minor errors in size estimation. Example: malloc((N + 2) * sizeof(int*)) :param depth: Which dimension of the array we want to allocate. Used to generate the argument of sizeof(). :return: c_ast.FuncCall """ size_expr = \ c_ast.BinaryOp( '+', self.sizes[depth], c_ast.Constant('int', '2') ) sizeof = \ c_ast.FuncCall( c_ast.ID('sizeof'), c_ast.ExprList([c_ast.ID(self.dtype.name + '*' * (len(self.sizes) - depth - 1))]) ) arg = c_ast.BinaryOp('*', size_expr, sizeof) return c_ast.FuncCall(c_ast.ID('malloc'), c_ast.ExprList([arg]))
def add_to_expression(self, expression: c_ast.Node, operator: str, addition: c_ast.ExprList = None): """ Adds the additional expression to the given expression, concatenated with the given operator. If the additional expression is None, the operator is assumed to be unary. :param expression: The expression to add to. :param operator: An operator on expression, e.g. "&&" or "!". :param addition: The expression to add. :return: The merged expression. :rtype: c_ast.ExprList """ expressions = [] if type(expression) is c_ast.ExprList: for expr in expression.exprs: if addition is None: expressions.append( c_ast.UnaryOp(operator, copy.deepcopy(expr))) else: expressions.append( c_ast.BinaryOp(operator, copy.deepcopy(expr), addition)) else: if addition is None: expressions.append( c_ast.UnaryOp(operator, copy.deepcopy(expression))) else: expressions.append( c_ast.BinaryOp(operator, copy.deepcopy(expression), addition)) return c_ast.ExprList(expressions)
def test_scalar_children(self): b1 = c_ast.BinaryOp( op='+', left=c_ast.Constant(type='int', value='6'), right=c_ast.ID(name='joe')) cv = self.ConstantVisitor() cv.visit(b1) self.assertEqual(cv.values, ['6']) b2 = c_ast.BinaryOp( op='*', left=c_ast.Constant(type='int', value='111'), right=b1) b3 = c_ast.BinaryOp( op='^', left=b2, right=b1) cv = self.ConstantVisitor() cv.visit(b3) self.assertEqual(cv.values, ['111', '6', '6'])
def FixNodeRequiringBoolInt(ast: c_ast.Node, meta_info): candidates = common.FindMatchingNodesPostOrder(ast, ast, IsNodeRequiringBoolInt) meta_info.type_links[CONST_ZERO] = meta.INT_IDENTIFIER_TYPE for node, parent in candidates: if isinstance(node, c_ast.If): if not IsExprOfTypeBoolInt(node.cond): node.cond = c_ast.BinaryOp("!=", node.cond, CONST_ZERO) meta_info.type_links[node.cond] = meta.INT_IDENTIFIER_TYPE elif isinstance(node, c_ast.For) and node.cond: if not IsExprOfTypeBoolInt(node.cond): node.cond = c_ast.BinaryOp("!=", node.cond, CONST_ZERO) meta_info.type_links[node.cond] = meta.INT_IDENTIFIER_TYPE elif isinstance(node, c_ast.UnaryOp) and node.op == "!": if not IsExprOfTypeBoolInt(node.expr): node = c_ast.BinaryOp( "==", node.expr, CONST_ZERO) # note: we are replacing the "!" node meta_info.type_links[node] = meta.INT_IDENTIFIER_TYPE elif isinstance( node, c_ast.BinaryOp) and node.op in common.SHORT_CIRCUIT_OPS: if not IsExprOfTypeBoolInt(node.left): node.left = c_ast.BinaryOp("!=", node.left, CONST_ZERO) meta_info.type_links[node.left] = meta.INT_IDENTIFIER_TYPE if not IsExprOfTypeBoolInt(node.right): node.right = c_ast.BinaryOp("!=", node.right, CONST_ZERO) meta_info.type_links[node.right] = meta.INT_IDENTIFIER_TYPE
def insertTest(self,block,functionName,varVals,varTypes,timer,preOut,testId): #Fork call cFork=c_ast.Assignment( lvalue=c_ast.ID(name='child_pid'), op='=', rvalue=c_ast.FuncCall( c_ast.ID(name='fork'), args=None)) #Child ##stdout = freopen("out.txt", "w", stdout); if self.functype=='int': printLeft=c_ast.Constant(type="char",value='"'+"%d" +'"') elif self.functype=='float' or self.functype=='double': printLeft=c_ast.Constant(type="char",value='"'+"%f" +'"') else: printLeft=c_ast.Constant(type="char",value='"'+"%d" +'"') fileOut=c_ast.Constant(type="char",value='"'+preOut +'.' +testId+".out.txt" +'"') fileW=c_ast.Constant(type="char",value='"'+"w" +'"') fileStdout=c_ast.ID(name='stdout') expressList = [fileOut,fileW,fileStdout] freopenC = c_ast.FuncCall(c_ast.ID(name="freopen"),c_ast.ExprList(expressList)) outReassign=c_ast.Assignment( lvalue=fileStdout, op='=', rvalue=freopenC) ##mainfake() expressList = list(c_ast.Constant(type=varTypes[i],value=str(varVals[i])) for i in range(len(varVals))) funcCall = c_ast.FuncCall(c_ast.ID(name=functionName),c_ast.ExprList(expressList)) expressList = [printLeft,funcCall] funcCall = c_ast.FuncCall(c_ast.ID(name="printf"),c_ast.ExprList(expressList)) ##exit(0) funcCall2 = c_ast.FuncCall(c_ast.ID(name="exit"),c_ast.ExprList([c_ast.Constant(type='int',value='0')])) #Parent cAlarm=c_ast.FuncCall( c_ast.ID(name='alarm'),c_ast.ExprList([c_ast.Constant(type='int',value=str(timer))])) cWait=c_ast.FuncCall( c_ast.ID(name='wait'),c_ast.ExprList([c_ast.ID(name='0')])) #IFs if_false= c_ast.If( c_ast.BinaryOp(left=c_ast.ID(name='child_pid'),op='==',right= c_ast.Constant(type='int',value='0')), c_ast.Compound([outReassign,funcCall,funcCall2]),iffalse=None) if_ini=c_ast.If( c_ast.BinaryOp(left=c_ast.ID(name='child_pid'),op='>',right= c_ast.Constant(type='int',value='0')), c_ast.Compound([cAlarm,cWait]),iffalse=if_false) block.body.block_items.insert(1,if_ini) block.body.block_items.insert(1,cFork)
def insertTest(self,block,functionName,varVals,varTypes,timer): #Fork call cFork=c_ast.Assignment( lvalue=c_ast.ID(name='child_pid'), op='=', rvalue=c_ast.FuncCall( c_ast.ID(name='fork'), args=None)) #Child if self.functype=='int' or self.functype=="bool": printLeft=c_ast.Constant(type="char",value='"'+"%d" +'"') elif self.functype=='float' or self.functype=='double': printLeft=c_ast.Constant(type="char",value='"'+"%f" +'"') else: printLeft=c_ast.Constant(type="char",value='"'+"%d" +'"') expressList = list(c_ast.Constant(type=varTypes[i],value=str(varVals[i])) for i in range(len(varVals))) funcCall = c_ast.FuncCall(c_ast.ID(name=functionName),c_ast.ExprList(expressList)) expressList = [printLeft,funcCall] funcCall = c_ast.FuncCall(c_ast.ID(name="printf"),c_ast.ExprList(expressList)) funcCall2 = c_ast.FuncCall(c_ast.ID(name="exit"),c_ast.ExprList([c_ast.Constant(type='int',value='0')])) #Parent cAlarm=c_ast.FuncCall( c_ast.ID(name='alarm'),c_ast.ExprList([c_ast.Constant(type='int',value=str(timer))])) cWait=c_ast.FuncCall( c_ast.ID(name='wait'),c_ast.ExprList([c_ast.ID(name='0')])) #IFs if_false= c_ast.If( c_ast.BinaryOp(left=c_ast.ID(name='child_pid'),op='==',right= c_ast.Constant(type='int',value='0')), c_ast.Compound([funcCall,funcCall2]),iffalse=None) if_ini=c_ast.If( c_ast.BinaryOp(left=c_ast.ID(name='child_pid'),op='>',right= c_ast.Constant(type='int',value='0')), c_ast.Compound([cAlarm,cWait]),iffalse=if_false) block.body.block_items.insert(1,if_ini) block.body.block_items.insert(1,cFork)
def _assign(self, variable: Union[c_ast.ID, c_ast.ArrayRef], expression: ExprType, node: c_ast.Node): """T-Asgn rule, which can be re-used both in Assignment node and Decl node""" # get new distance from the assignment expression (T-Asgn) variable_name = variable.name if isinstance( variable, c_ast.ID) else variable.name.name var_aligned, var_shadow, *_ = self._type_system.get_types( variable_name) aligned, shadow = DistanceGenerator( self._type_system).visit(expression) if self._loop_level == 0: # insert x^align = n^align if x^aligned is * if var_aligned == '*' or aligned != '0': self._insert_at( node, parse( f'{constants.ALIGNED_DISTANCE}_{variable_name} = {aligned}' ), after=True) if self._enable_shadow: # generate x^shadow = x + x^shadow - e according to (T-Asgn) if self._pc: if isinstance(variable, c_ast.ID): shadow_distance = c_ast.ID( name=f'{constants.SHADOW_DISTANCE}_{variable_name}' ) elif isinstance(variable, c_ast.ArrayRef): shadow_distance = c_ast.ArrayRef( name=f'{constants.SHADOW_DISTANCE}_{variable_name}', subscript=variable.subscript) else: raise NotImplementedError( f'Assigned value type not supported {type(variable)}' ) # insert x^shadow = x + x^shadow - e; insert_node = c_ast.Assignment( op='=', lvalue=shadow_distance, rvalue=c_ast.BinaryOp(op='-', left=c_ast.BinaryOp( op='+', left=variable, right=shadow_distance), right=expression)) self._insert_at(node, insert_node, after=False) # insert x^shadow = n^shadow if n^shadow is not 0 elif var_shadow == '*' or shadow != '0': self._insert_at( node, parse( f'{constants.SHADOW_DISTANCE}_{variable_name} = {shadow}' ), after=True) shadow_distance = '*' if self._pc or shadow != '0' or var_shadow == '*' else '0' aligned_distance = '*' if aligned != '0' or var_aligned == '*' else '0' self._type_system.update_distance(variable_name, aligned_distance, shadow_distance)
def add_jump_guard(ast_to_guard, phase_var, round_var, label): guarded_ast = c_ast.If( c_ast.BinaryOp( '&&', c_ast.BinaryOp('==', c_ast.ID(phase_var), c_ast.ID('PHASE')), c_ast.BinaryOp('==', c_ast.ID(round_var), c_ast.ID(label))), ast_to_guard, None) return c_ast.Compound([guarded_ast])
def tests_list_children(self): c1 = c_ast.Constant(type='float', value='5.6') c2 = c_ast.Constant(type='char', value='t') b1 = c_ast.BinaryOp(op='+', left=c1, right=c2) b2 = c_ast.BinaryOp(op='-', left=b1, right=c2) comp = c_ast.Compound(block_items=[b1, b2, c1, c2]) cv = self.ConstantVisitor() cv.visit(comp) self.assertEqual(cv.values, ['5.6', 't', '5.6', 't', 't', '5.6', 't'])
def visit_Assignment(self, node): if self.inner_for: self.remove_node() if self.begin: if not self.inner_begin_block: self.inner_begin_block = c_ast.Compound([]) code = c_ast.If(c_ast.BinaryOp("==", self.inner_index, c_ast.Constant('int', '0')), self.inner_begin_block, None) self.inner_for.stmt.block_items.insert(0, code) self.inner_begin_block.block_items.append(node) else: if not self.inner_end_block: self.inner_end_block = c_ast.Compound([]) code = c_ast.If(c_ast.BinaryOp("==", self.inner_index, c_ast.BinaryOp('-', self.inner_limit, c_ast.Constant('int', '1'))), self.inner_end_block, None) self.inner_for.stmt.block_items.append(code) self.inner_end_block.block_items.append(node)
def _replace(self, node): if not isinstance(node, (c_ast.ArrayRef, c_ast.ID)): raise NotImplementedError('Expression type {} currently not supported.'.format(type(node))) varname = node.name.name if isinstance(node, c_ast.ArrayRef) else node.name alignd, shadow = self._types.get_distance(varname) distance = alignd if self._is_aligned else shadow if distance == '0': return node elif distance == '*': distance_varname = '__SHADOWDP_{}_DISTANCE_{}'.format('ALIGNED' if self._is_aligned else 'SHADOW', varname) distance_var = c_ast.ArrayRef(name=c_ast.ID(name=distance_varname), subscript=node.subscript) \ if isinstance(node, c_ast.ArrayRef) else c_ast.ID(name=distance_varname) return c_ast.BinaryOp(op='+', left=node, right=distance_var) else: return c_ast.BinaryOp(op='+', left=node, right=convert_to_ast(distance))
def __for_loop(self, depth: int) -> c_ast.For: """ A helper function to construct a for loop corresponding to allocating one dimension of an array. Recursively calls itself to generate next levels or generates an initialisation line if it is the last level. Example: for(i_2 = 0; i_2 < N; i_2++) { ... } :param depth: :return: C-ast.For """ i = self.counter_prefix + str(depth) init = c_ast.DeclList([ c_ast.Decl(c_ast.ID(i), [], [], [], c_ast.TypeDecl(i, [], c_ast.IdentifierType(['int'])), c_ast.Constant('int', '0'), '') ]) cond = c_ast.BinaryOp('<', c_ast.ID(i), self.sizes[depth]) nxt = c_ast.Assignment('++', c_ast.ID(i), None) stmt = c_ast.Compound([]) if depth < len(self.sizes) - 1: stmt.block_items = [ self.__malloc_assign(depth + 1), self.__for_loop(depth + 1) ] else: stmt.block_items = [self.initialiser(depth + 1)] return c_ast.For(init, cond, nxt, stmt)
def _replace(self, node): if not isinstance(node, (c_ast.ArrayRef, c_ast.ID)): raise NotImplementedError(f'Expression type {type(node)} currently not supported.') varname = node.name.name if isinstance(node, c_ast.ArrayRef) else node.name alignd, shadow, *_ = self._types.get_types(varname) distance = alignd if self._is_aligned else shadow if distance == '0': return node elif distance == '*': distance_varname = \ f'{constants.ALIGNED_DISTANCE if self._is_aligned else constants.SHADOW_DISTANCE}_{varname}' distance_var = c_ast.ArrayRef(name=c_ast.ID(name=distance_varname), subscript=node.subscript) \ if isinstance(node, c_ast.ArrayRef) else c_ast.ID(name=distance_varname) return c_ast.BinaryOp(op='+', left=node, right=distance_var) else: return c_ast.BinaryOp(op='+', left=node, right=parse(distance))
def check_value(ast_tree, ext_index, bock_item_index, var_name, func_name): Cast = c_ast.Cast( c_ast.Typename( None, [], c_ast.PtrDecl([], c_ast.TypeDecl(None, [], c_ast.IdentifierType(['void'])))), c_ast.ID(var_name)) func_call = c_ast.FuncCall( c_ast.ID('check_value'), c_ast.ExprList([ c_ast.UnaryOp('&', c_ast.ID('global_log')), Cast, c_ast.Constant('string', '"' + var_name + '"'), c_ast.Constant('string', '"' + func_name + '"'), c_ast.Constant('int', str(len(var_name))), c_ast.Constant('int', str(len(func_name))) ])) new_node = c_ast.If( c_ast.BinaryOp('==', func_call, c_ast.Constant('int', '0')), c_ast.Compound([ c_ast.FuncCall( c_ast.ID('printf'), c_ast.ExprList([ c_ast.Constant('string', '"%s\\n"'), c_ast.Constant('string', '"Attack Detected"') ])), c_ast.FuncCall(c_ast.ID('exit'), c_ast.ExprList([c_ast.Constant('int', '1')])) ]), None) return merge_ast_tree(ast_tree, ext_index, bock_item_index, new_node, "insert_before")
def nested_for_loop(node, inner_loop_body, loop_iterator_base, rename_index=0): """ Recursively create nested for loops for copying a multi-dimensional array. """ if isinstance(node.type.type, c_ast.ArrayDecl): # Multi-dimensional array, recurse to generate inner loop for_loop_body = nested_for_loop(node.type, inner_loop_body, loop_iterator_base, rename_index + 1) else: # Single or last dimension of array for_loop_body = [inner_loop_body] # Declare iterator loop_iterator = c_ast.ID("%s_i%d" % (loop_iterator_base, rename_index)) loop_iterator_decl = c_ast.Decl( loop_iterator.name, [], [], [], c_ast.TypeDecl(loop_iterator.name, [], c_ast.IdentifierType(["int"])), None, None) # For loop array_size = node.type.dim for_loop = c_ast.For( c_ast.Assignment('=', loop_iterator, c_ast.Constant("int", "0")), c_ast.BinaryOp('<', loop_iterator, array_size), c_ast.UnaryOp('p++', loop_iterator), c_ast.Compound(for_loop_body)) return [loop_iterator_decl, for_loop]
def astVeriNon(): veryidt = c_ast.IdentifierType(['int']) verytype = c_ast.TypeDecl('rand', [], veryidt) bifunc = c_ast.FuncCall(c_ast.ID('__VERIFIER_nondet'), None) verybina = c_ast.BinaryOp('%', bifunc, c_ast.ID('N')) simdecl = c_ast.Decl('rand', [], [], [], verytype, verybina, None, None) return simdecl
def perm_add_mask(fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random) -> bool: """Add a mask of 0xFF[FFFFFFFFFFFFFF] to a random expression of integer type. In some cases this mask is optimized out but affects regalloc.""" typemap = build_typemap(ast) # Find expression to add the mask to cands: List[Expression] = get_block_expressions(fn.body, region) if not cands: return False expr = random.choice(cands) type: SimpleType = decayed_expr_type(expr, typemap) if not allowed_simple_type( type, typemap, ["int", "char", "long", "short", "signed", "unsigned"]): return False # Mask as if restricting the value to 8, 16, 32, or 64-bit width. # Sometimes use an unsigned mask like '0xFFu' masks: List[str] = ["0xFF", "0xFFFF", "0xFFFFFFFF", "0xFFFFFFFFFFFFFFFF"] mask = random.choice(masks) + random.choice(["", "u"]) visit_replace( fn.body, lambda n, _: ca.BinaryOp("&", expr, ca.Constant("int", mask)) if n is expr else None, ) return True
def _build_handle_function(functions): """ Wraps the switch statement in a function definition """ case_statement = _build_case(functions) available_check = c_ast.If( c_ast.BinaryOp( '<', c_ast.FuncCall( c_ast.ID('mailbox_available'), c_ast.ExprList([c_ast.Constant('int', '2')]) ), c_ast.Constant('int', '4') ), c_ast.Return(None), None ) handle_decl = c_ast.FuncDecl( None, c_ast.TypeDecl('_handle_events', [], c_ast.IdentifierType(['void'])), ) command_decl = c_ast.Decl('command', [], [], [], c_ast.TypeDecl('command', [], c_ast.IdentifierType(['int'])), [], []) command_read = _generate_read('command') body = c_ast.Compound([available_check, command_decl, command_read, case_statement]) return c_ast.FuncDef(handle_decl, [], body)
def unify_if_predicates(predicates): if len(predicates) == 1: return predicates[0] else: return c_ast.BinaryOp('&&', predicates[0], unify_if_predicates(predicates[1:]))
def ConvertArrayIndexToPointerDereference(ast, meta_info): """ Eliminates multi-dimensional arrays Phase 1: a[1][2] = b; -> *(a + 1 * 10 + 2) = b; Phase 2: fun (int a[5][10]) -> fun (int a[][10]) Phase 3: int a[5][10]; -> int a[50]; """ def IsArrayRefChainHead(node, parent): if not isinstance(node, c_ast.ArrayRef): return False name_type = meta_info.type_links[node.name] # int **b = a; # printf("%d\n", b[1][1]); if not isinstance(name_type, c_ast.ArrayDecl): return True if not isinstance(parent, c_ast.ArrayRef): return True return False ref_chains = common.FindMatchingNodesPostOrder(ast, ast, IsArrayRefChainHead) for chain_head, parent in ref_chains: name, s = MakeCombinedSubscript(chain_head, meta_info) if s is None: addr = name else: addr = c_ast.BinaryOp("+", name, s) head_type = meta_info.type_links[chain_head] # TODO: low confidence - double check this meta_info.type_links[addr] = meta_info.type_links[name] if isinstance(head_type, c_ast.ArrayDecl): # the array ref sequence only partially indexes the array, so the result is just an address common.ReplaceNode(parent, chain_head, addr) else: deref = c_ast.UnaryOp("*", addr) meta_info.type_links[deref] = meta_info.type_links[chain_head] # expression has not changed common.ReplaceNode(parent, chain_head, deref) # Phase 2 def IsArrayDeclParam(node, parent): if not isinstance(parent, c_ast.ParamList): return False if isinstance(node, c_ast.EllipsisParam): return False return isinstance(node.type, c_ast.ArrayDecl) decl_params = common.FindMatchingNodesPreOrder( ast, ast, IsArrayDeclParam) for param, _ in decl_params: t = param.type t.dim = None # Phase 3 def IsArrayDeclChainHead(node, parent): if not isinstance(node, c_ast.ArrayDecl): return False return not isinstance(parent, c_ast.ArrayDecl) decl_chains = common.FindMatchingNodesPreOrder( ast, ast, IsArrayDeclChainHead) for chain_head, parent in decl_chains: CollapseArrayDeclChain(chain_head)
def exprs_prod(exprs: List[c_ast.Node]) -> c_ast.Node: """ Product of a list of c_ast expressions :param exprs: Expressions :return: c_ast.Node representing the product """ # noinspection PyTypeChecker return reduce(lambda a, b: c_ast.BinaryOp('*', a, b), exprs)
def do_op(**kw): #{rd} = {rs} {subst} {rt} # XXX this is a mess lvalue = c_ast.BinaryOp(kw['subst'], kw['rs'], kw['rt']) try: cast_with = slot_to_typename[kw['result']] except KeyError: return do_assign(rt=kw['rd'], op=lvalue) else: return do_assign(rt=kw['rd'], op=simple_cast(cast_with, lvalue))
def createOutputIf(self, expr): expressList = [c_ast.Constant(type='int', value='0')] funcCall = c_ast.FuncCall(c_ast.ID(name="assert"), c_ast.ExprList(expressList)) if_all = c_ast.If(c_ast.BinaryOp(left=c_ast.ID(name='__out_var'), op='==', right=expr), c_ast.Compound([funcCall]), iffalse=None) return (if_all)
def test_repr(self): c1 = c_ast.Constant(type='float', value='5.6') c2 = c_ast.Constant(type='char', value='t') b1 = c_ast.BinaryOp(op='+', left=c1, right=c2) b2 = c_ast.BinaryOp(op='-', left=b1, right=c2) comp = c_ast.Compound(block_items=[b1, b2, c1, c2]) expected = ( "Compound(block_items=[BinaryOp(op='+',\n" " left=Constant(type='float',\n" " value='5.6'\n" " ),\n" " right=Constant(type='char',\n" " value='t'\n" " )\n" " ),\n" " BinaryOp(op='-',\n" " left=BinaryOp(op='+',\n" " left=Constant(type='float',\n" " value='5.6'\n" " ),\n" " right=Constant(type='char',\n" " value='t'\n" " )\n" " ),\n" " right=Constant(type='char',\n" " value='t'\n" " )\n" " ),\n" " Constant(type='float',\n" " value='5.6'\n" " ),\n" " Constant(type='char',\n" " value='t'\n" " )\n" " ]\n" " )") self.assertEqual(repr(comp), expected)
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 __polybench_init(self, depth: int) -> c_ast.Node: """ Generates a polybench-style array element initialisation. :param depth: Example: A[i_0][i_1] = (double) (i_0 * i_1 + 1) / N; """ subs = self.__subs(depth) left = self.__array_ref(subs) right = \ c_ast.Cast( self.dtype, c_ast.BinaryOp('/', c_ast.BinaryOp('+', exprs_prod(subs), c_ast.Constant('int', '1')), self.sizes[0] ) ) return c_ast.Assignment('=', left, right)
def test_BinaryOp(self): b1 = c_ast.BinaryOp(op='+', left=c_ast.Constant(type='int', value='6'), right=c_ast.ID(name='joe')) self.failUnless(isinstance(b1.left, c_ast.Constant)) self.assertEqual(b1.left.type, 'int') self.assertEqual(b1.left.value, '6') self.failUnless(isinstance(b1.right, c_ast.ID)) self.assertEqual(b1.right.name, 'joe')
def __init__(self, layout, start, end, stride, leading_dim): self.end = end self.stride = stride if layout == "fortran" and start is None: start = c_ast.Constant("int", 1) self.start = start if leading_dim is None and end is not None: if start is None: leading_dim = end else: if layout == "fortran": leading_dim = c_ast.BinaryOp( "+", c_ast.BinaryOp("-", end, start), c_ast.Constant("int", 1)) else: leading_dim = c_ast.BinaryOp("-", end, start) self.leading_dim = leading_dim
def swap_compare_operands(cond): reversed_operator = { '>': '<', '<': '>', '>=': '<=', '<=': '>=', '==': '==', '!=': '!=', } new_op = reversed_operator[cond.op] # Normal order is (left, right), but we're swapping. return c_ast.BinaryOp(new_op, cond.right, cond.left, cond.coord)